Coverage Report

Created: 2026-10-17 07:11

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-10-15 09:03:13 -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 <cstddef>
9
#include <cstdint>
10
#include <string_view>
11
12
namespace ada::checkers {
13
14
0
ada_really_inline constexpr bool is_ipv4(std::string_view view) noexcept {
15
  // The string is not empty and does not contain upper case ASCII characters.
16
0
  if (!last_label_may_be_a_number(view)) {
17
0
    return false;
18
0
  }
19
  // If the address ends with a dot, we need to prune it (special case).
20
0
  if (view.ends_with('.')) {
21
0
    view.remove_suffix(1);
22
0
  }
23
  // From the last character, find the last dot.
24
0
  size_t last_dot = view.rfind('.');
25
0
  if (last_dot != std::string_view::npos) {
26
    // We have at least one dot.
27
0
    view.remove_prefix(last_dot + 1);
28
0
  }
29
  /** Optimization opportunity: we have basically identified the last number of
30
     the ipv4 if we return true here. We might as well parse it and have at
31
     least one number parsed when we get to parse_ipv4. */
32
0
  if (std::ranges::all_of(view, ada::checkers::is_digit)) {
33
0
    return true;
34
0
  }
35
  // It could be hex (0x), but not if there is a single character.
36
0
  if (view.size() == 1) {
37
0
    return false;
38
0
  }
39
  // It must start with 0x.
40
0
  if (!view.starts_with("0x")) {
41
0
    return false;
42
0
  }
43
  // We must allow "0x".
44
0
  if (view.size() == 2) {
45
0
    return true;
46
0
  }
47
  // We have 0x followed by some characters, we need to check that they are
48
  // hexadecimals.
49
0
  view.remove_prefix(2);
50
0
  return std::ranges::all_of(view, ada::unicode::is_lowercase_hex);
51
0
}
52
53
// for use with path_signature, we include all characters that need percent
54
// encoding.
55
static constexpr std::array<uint8_t, 256> path_signature_table =
56
    []() consteval {
57
      std::array<uint8_t, 256> result{};
58
      for (size_t i = 0; i < 256; i++) {
59
        if (i <= 0x20 || i == 0x22 || i == 0x23 || i == 0x3c || i == 0x3e ||
60
            i == 0x3f || i == 0x5e || i == 0x60 || i == 0x7b || i == 0x7d ||
61
            i > 0x7e) {
62
          result[i] = 1;
63
        } else if (i == 0x25) {
64
          result[i] = 8;
65
        } else if (i == 0x2e) {
66
          result[i] = 4;
67
        } else if (i == 0x5c) {
68
          result[i] = 2;
69
        } else {
70
          result[i] = 0;
71
        }
72
      }
73
      return result;
74
    }();
75
76
ada_really_inline constexpr uint8_t path_signature(
77
0
    std::string_view input) noexcept {
78
  // The path percent-encode set is the query percent-encode set and U+003F (?),
79
  // U+0060 (`), U+007B ({), and U+007D (}). The query percent-encode set is the
80
  // C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#),
81
  // U+003C (<), and U+003E (>). The C0 control percent-encode set are the C0
82
  // controls and all code points greater than U+007E (~).
83
0
  size_t i = 0;
84
0
  uint8_t accumulator{};
85
0
  for (; i + 7 < input.size(); i += 8) {
86
0
    accumulator |= uint8_t(path_signature_table[uint8_t(input[i])] |
87
0
                           path_signature_table[uint8_t(input[i + 1])] |
88
0
                           path_signature_table[uint8_t(input[i + 2])] |
89
0
                           path_signature_table[uint8_t(input[i + 3])] |
90
0
                           path_signature_table[uint8_t(input[i + 4])] |
91
0
                           path_signature_table[uint8_t(input[i + 5])] |
92
0
                           path_signature_table[uint8_t(input[i + 6])] |
93
0
                           path_signature_table[uint8_t(input[i + 7])]);
94
0
  }
95
0
  for (; i < input.size(); i++) {
96
0
    accumulator |= uint8_t(path_signature_table[uint8_t(input[i])]);
97
0
  }
98
0
  return accumulator;
99
0
}
100
101
ada_really_inline constexpr bool verify_dns_length(
102
0
    std::string_view input) noexcept {
103
0
  if (input.empty()) return false;
104
0
  if (input.back() == '.') {
105
0
    if (input.size() > 254) return false;
106
0
  } else if (input.size() > 253)
107
0
    return false;
108
109
0
  size_t start = 0;
110
0
  while (start < input.size()) {
111
0
    auto dot_location = input.find('.', start);
112
    // If not found, it's likely the end of the domain
113
0
    if (dot_location == std::string_view::npos) dot_location = input.size();
114
115
0
    auto label_size = dot_location - start;
116
0
    if (label_size > 63 || label_size == 0) return false;
117
118
0
    start = dot_location + 1;
119
0
  }
120
121
0
  return true;
122
0
}
123
124
}  // namespace ada::checkers
125
/* end file src/checkers.cpp */
126
/* begin file src/unicode.cpp */
127
128
129
ADA_PUSH_DISABLE_ALL_WARNINGS
130
/* begin file src/ada_idna.cpp */
131
/* auto-generated on 2026-10-09 11:29:39 -0400. Do not edit! */
132
/* begin file src/idna.cpp */
133
/* begin file src/unicode_transcoding.cpp */
134
/* begin file include/ada/idna/unicode_transcoding.h */
135
#ifndef ADA_IDNA_UNICODE_TRANSCODING_H
136
#define ADA_IDNA_UNICODE_TRANSCODING_H
137
138
#include <string>
139
#include <string_view>
140
141
namespace ada::idna {
142
143
size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output);
144
145
size_t utf8_length_from_utf32(const char32_t* buf, size_t len);
146
147
size_t utf32_length_from_utf8(const char* buf, size_t len);
148
149
size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output);
150
151
}  // namespace ada::idna
152
153
#endif  // ADA_IDNA_UNICODE_TRANSCODING_H
154
/* end file include/ada/idna/unicode_transcoding.h */
155
156
#include <algorithm>
157
#include <cstdint>
158
#include <cstring>
159
160
namespace ada::idna {
161
162
2.61k
size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) {
163
2.61k
  const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);
164
2.61k
  size_t pos = 0;
165
2.61k
  const char32_t* start{utf32_output};
166
19.3k
  while (pos < len) {
167
    // try to convert the next block of 16 ASCII bytes
168
16.8k
    if (pos + 16 <= len) {  // if it is safe to read 16 more
169
                            // bytes, check that they are ascii
170
4.03k
      uint64_t v1;
171
4.03k
      std::memcpy(&v1, data + pos, sizeof(uint64_t));
172
4.03k
      uint64_t v2;
173
4.03k
      std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
174
4.03k
      uint64_t v{v1 | v2};
175
4.03k
      if ((v & 0x8080808080808080) == 0) {
176
226
        size_t final_pos = pos + 16;
177
3.84k
        while (pos < final_pos) {
178
3.61k
          *utf32_output++ = char32_t(buf[pos]);
179
3.61k
          pos++;
180
3.61k
        }
181
226
        continue;
182
226
      }
183
4.03k
    }
184
16.6k
    uint8_t leading_byte = data[pos];  // leading byte
185
16.6k
    if (leading_byte < 0b10000000) {
186
      // converting one ASCII byte !!!
187
10.1k
      *utf32_output++ = char32_t(leading_byte);
188
10.1k
      pos++;
189
10.1k
    } else if ((leading_byte & 0b11100000) == 0b11000000) {
190
      // We have a two-byte UTF-8
191
2.84k
      if (pos + 1 >= len) {
192
11
        return 0;
193
11
      }  // minimal bound checking
194
2.83k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
195
14
        return 0;
196
14
      }
197
      // range check
198
2.82k
      uint32_t code_point =
199
2.82k
          (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
200
2.82k
      if (code_point < 0x80 || 0x7ff < code_point) {
201
3
        return 0;
202
3
      }
203
2.82k
      *utf32_output++ = char32_t(code_point);
204
2.82k
      pos += 2;
205
3.68k
    } else if ((leading_byte & 0b11110000) == 0b11100000) {
206
      // We have a three-byte UTF-8
207
3.21k
      if (pos + 2 >= len) {
208
5
        return 0;
209
5
      }  // minimal bound checking
210
211
3.21k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
212
12
        return 0;
213
12
      }
214
3.20k
      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
215
2
        return 0;
216
2
      }
217
      // range check
218
3.19k
      uint32_t code_point = (leading_byte & 0b00001111) << 12 |
219
3.19k
                            (data[pos + 1] & 0b00111111) << 6 |
220
3.19k
                            (data[pos + 2] & 0b00111111);
221
3.19k
      if (code_point < 0x800 || 0xffff < code_point ||
222
3.19k
          (0xd7ff < code_point && code_point < 0xe000)) {
223
8
        return 0;
224
8
      }
225
3.19k
      *utf32_output++ = char32_t(code_point);
226
3.19k
      pos += 3;
227
3.19k
    } else if ((leading_byte & 0b11111000) == 0b11110000) {  // 0b11110000
228
      // we have a 4-byte UTF-8 word.
229
419
      if (pos + 3 >= len) {
230
9
        return 0;
231
9
      }  // minimal bound checking
232
410
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
233
3
        return 0;
234
3
      }
235
407
      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
236
2
        return 0;
237
2
      }
238
405
      if ((data[pos + 3] & 0b11000000) != 0b10000000) {
239
3
        return 0;
240
3
      }
241
242
      // range check
243
402
      uint32_t code_point = (leading_byte & 0b00000111) << 18 |
244
402
                            (data[pos + 1] & 0b00111111) << 12 |
245
402
                            (data[pos + 2] & 0b00111111) << 6 |
246
402
                            (data[pos + 3] & 0b00111111);
247
402
      if (code_point <= 0xffff || 0x10ffff < code_point) {
248
6
        return 0;
249
6
      }
250
396
      *utf32_output++ = char32_t(code_point);
251
396
      pos += 4;
252
396
    } else {
253
50
      return 0;
254
50
    }
255
16.6k
  }
256
2.48k
  return utf32_output - start;
257
2.61k
}
258
259
0
size_t utf8_length_from_utf32(const char32_t* buf, size_t len) {
260
  // We are not BOM aware.
261
0
  const uint32_t* p = reinterpret_cast<const uint32_t*>(buf);
262
0
  size_t counter{0};
263
0
  for (size_t i = 0; i != len; ++i) {
264
0
    ++counter;                                      // ASCII
265
0
    counter += static_cast<size_t>(p[i] > 0x7F);    // two-byte
266
0
    counter += static_cast<size_t>(p[i] > 0x7FF);   // three-byte
267
0
    counter += static_cast<size_t>(p[i] > 0xFFFF);  // four-bytes
268
0
  }
269
0
  return counter;
270
0
}
271
272
2.63k
size_t utf32_length_from_utf8(const char* buf, size_t len) {
273
2.63k
  const int8_t* p = reinterpret_cast<const int8_t*>(buf);
274
31.3k
  return std::count_if(p, std::next(p, len), [](int8_t c) {
275
    // -65 is 0b10111111, anything larger in two-complement's
276
    // should start a new code point.
277
31.3k
    return c > -65;
278
31.3k
  });
279
2.63k
}
280
281
0
size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) {
282
0
  const uint32_t* data = reinterpret_cast<const uint32_t*>(buf);
283
0
  size_t pos = 0;
284
0
  const char* start{utf8_output};
285
0
  while (pos < len) {
286
    // try to convert the next block of 2 ASCII characters
287
0
    if (pos + 2 <= len) {  // if it is safe to read 8 more
288
                           // bytes, check that they are ascii
289
0
      uint64_t v;
290
0
      std::memcpy(&v, data + pos, sizeof(uint64_t));
291
0
      if ((v & 0xFFFFFF80FFFFFF80) == 0) {
292
0
        *utf8_output++ = char(buf[pos]);
293
0
        *utf8_output++ = char(buf[pos + 1]);
294
0
        pos += 2;
295
0
        continue;
296
0
      }
297
0
    }
298
0
    uint32_t word = data[pos];
299
0
    if ((word & 0xFFFFFF80) == 0) {
300
      // will generate one UTF-8 bytes
301
0
      *utf8_output++ = char(word);
302
0
      pos++;
303
0
    } else if ((word & 0xFFFFF800) == 0) {
304
      // will generate two UTF-8 bytes
305
      // we have 0b110XXXXX 0b10XXXXXX
306
0
      *utf8_output++ = char((word >> 6) | 0b11000000);
307
0
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
308
0
      pos++;
309
0
    } else if ((word & 0xFFFF0000) == 0) {
310
      // will generate three UTF-8 bytes
311
      // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX
312
0
      if (word >= 0xD800 && word <= 0xDFFF) {
313
0
        return 0;
314
0
      }
315
0
      *utf8_output++ = char((word >> 12) | 0b11100000);
316
0
      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
317
0
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
318
0
      pos++;
319
0
    } else {
320
      // will generate four UTF-8 bytes
321
      // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX
322
      // 0b10XXXXXX
323
0
      if (word > 0x10FFFF) {
324
0
        return 0;
325
0
      }
326
0
      *utf8_output++ = char((word >> 18) | 0b11110000);
327
0
      *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000);
328
0
      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
329
0
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
330
0
      pos++;
331
0
    }
332
0
  }
333
0
  return utf8_output - start;
334
0
}
335
}  // namespace ada::idna
336
/* end file src/unicode_transcoding.cpp */
337
/* begin file src/mapping.cpp */
338
/* begin file include/ada/idna/mapping.h */
339
#ifndef ADA_IDNA_MAPPING_H
340
#define ADA_IDNA_MAPPING_H
341
342
#include <string>
343
#include <string_view>
344
345
namespace ada::idna {
346
347
// If the input is ascii, then the mapping is just -> lower case.
348
void ascii_map(char* input, size_t length);
349
// Map the characters according to IDNA, returning the empty string on error.
350
std::u32string map(std::u32string_view input);
351
// Map into an existing buffer (cleared on entry). Returns false if any code
352
// point is disallowed. Reusing the buffer avoids repeated heap allocations
353
// when called in a loop over multiple labels.
354
bool map(std::u32string_view input, std::u32string& out);
355
356
}  // namespace ada::idna
357
358
#endif
359
/* end file include/ada/idna/mapping.h */
360
361
#include <array>
362
#include <cstring>
363
#include <cstdint>
364
#include <string>
365
366
/* begin file src/table_store.hpp */
367
// Runtime store for compressed Unicode/IDNA tables.
368
// Large tables are DEFLATE-compressed (read-only) and expanded once on first
369
// use into a heap buffer so the working set does not bloat the on-disk binary.
370
// Hot-path lookups use the same O(1) multi-stage layout as the pre-compression
371
// code; compression only affects on-disk size and one-time init.
372
//
373
// Thread-safe without mutex: atomic CAS + spin-wait. ensure_tables() returns
374
// false if initialization fails (OOM, corrupt blob); callers must treat that
375
// as a hard error and not touch table pointers.
376
377
/* begin file src/raw_inflate.hpp */
378
// Minimal raw DEFLATE inflater (RFC 1951), enough for zlib raw streams.
379
// Returns number of output bytes written, or 0 on failure.
380
#include <cstdint>
381
#include <cstring>
382
383
namespace ada::idna::deflate {
384
385
struct BitReader {
386
  const uint8_t* p;
387
  const uint8_t* end;
388
  uint32_t acc = 0;
389
  int bits = 0;
390
391
  explicit BitReader(const uint8_t* data, size_t len)
392
1
      : p(data), end(data + len) {}
393
394
475k
  bool ensure(int n) {
395
540k
    while (bits < n) {
396
65.3k
      if (p >= end) return false;
397
65.3k
      acc |= uint32_t(*p++) << bits;
398
65.3k
      bits += 8;
399
65.3k
    }
400
475k
    return true;
401
475k
  }
402
475k
  uint32_t get(int n) {
403
475k
    if (!ensure(n)) return UINT32_MAX;
404
475k
    uint32_t v = acc & ((1u << n) - 1);
405
475k
    acc >>= n;
406
475k
    bits -= n;
407
475k
    return v;
408
475k
  }
409
0
  void align_byte() {
410
0
    acc >>= (bits & 7);
411
0
    bits -= (bits & 7);
412
0
  }
413
};
414
415
struct Huff {
416
  // canonical codes: for each length, list of symbols
417
  // Fast path: table for codes up to max_bits
418
  static constexpr int MAXBITS = 15;
419
  uint8_t lengths[288]{};
420
  int counts[MAXBITS + 1]{};
421
  int first_code[MAXBITS + 1]{};
422
  int16_t symbols[288]{};
423
  int nsymbols = 0;
424
  int max_bits = 0;
425
426
  // Base index into symbols[] for each code length (used by decode).
427
  int base_idx[MAXBITS + 1]{};
428
429
16
  bool build(const uint8_t* lens, int n) {
430
16
    std::memset(counts, 0, sizeof(counts));
431
16
    std::memset(first_code, 0, sizeof(first_code));
432
16
    std::memset(base_idx, 0, sizeof(base_idx));
433
16
    nsymbols = n;
434
16
    max_bits = 0;
435
1.99k
    for (int i = 0; i < n; i++) {
436
1.97k
      lengths[i] = lens[i];
437
1.97k
      if (lens[i]) {
438
1.93k
        counts[lens[i]]++;
439
1.93k
        if (lens[i] > max_bits) max_bits = lens[i];
440
1.93k
      }
441
1.97k
    }
442
    // Canonical first code for each bit length (RFC 1951).
443
16
    int code = 0;
444
256
    for (int bits = 1; bits <= MAXBITS; bits++) {
445
240
      code = (code + counts[bits - 1]) << 1;
446
240
      first_code[bits] = code;
447
240
    }
448
16
    int idx = 0;
449
159
    for (int bits = 1; bits <= max_bits; bits++) {
450
143
      base_idx[bits] = idx;
451
      // assign symbols in symbol order for codes of this length
452
21.8k
      for (int sym = 0; sym < n; sym++) {
453
21.6k
        if (lengths[sym] == bits) {
454
1.93k
          symbols[idx++] = static_cast<int16_t>(sym);
455
1.93k
        }
456
21.6k
      }
457
143
    }
458
16
    return true;
459
16
  }
460
461
71.4k
  int decode(BitReader& br) const {
462
71.4k
    if (max_bits == 0) return -1;
463
71.4k
    int code = 0;
464
442k
    for (int len = 1; len <= max_bits; len++) {
465
442k
      uint32_t b = br.get(1);
466
442k
      if (b == UINT32_MAX) return -1;
467
442k
      code = (code << 1) | int(b);
468
442k
      int first = first_code[len];
469
442k
      int cnt = counts[len];
470
442k
      if (cnt && code - first < cnt) {
471
71.4k
        return symbols[base_idx[len] + (code - first)];
472
71.4k
      }
473
442k
    }
474
0
    return -1;
475
71.4k
  }
476
};
477
478
// Fixed Huffman tables are built once at dynamic initialization (before main /
479
// single-threaded), so concurrent first-use of inflate cannot race.
480
2
inline Huff make_fixed_litlen_huff() {
481
2
  Huff h;
482
2
  uint8_t lens[288];
483
  // Fixed Huffman: 0-143:8, 144-255:9, 256-279:7, 280-287:8
484
290
  for (int i = 0; i <= 143; i++) lens[i] = 8;
485
226
  for (int i = 144; i <= 255; i++) lens[i] = 9;
486
50
  for (int i = 256; i <= 279; i++) lens[i] = 7;
487
18
  for (int i = 280; i <= 287; i++) lens[i] = 8;
488
2
  h.build(lens, 288);
489
2
  return h;
490
2
}
491
492
2
inline Huff make_fixed_dist_huff() {
493
2
  Huff h;
494
2
  uint8_t lens[32];
495
66
  for (int i = 0; i < 32; i++) lens[i] = 5;
496
2
  h.build(lens, 32);
497
2
  return h;
498
2
}
499
500
// NOLINTNEXTLINE(cert-err58-cpp) -- intentional process-lifetime tables
501
inline const Huff kFixedLitLenHuff = make_fixed_litlen_huff();
502
// NOLINTNEXTLINE(cert-err58-cpp)
503
inline const Huff kFixedDistHuff = make_fixed_dist_huff();
504
505
0
inline int fixed_litlen(BitReader& br) { return kFixedLitLenHuff.decode(br); }
506
507
0
inline int fixed_dist(BitReader& br) { return kFixedDistHuff.decode(br); }
508
509
// length and distance base tables
510
static const uint16_t len_base[29] = {
511
    3,  4,  5,  6,  7,  8,  9,  10, 11,  13,  15,  17,  19,  23, 27,
512
    31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
513
static const uint8_t len_extra[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
514
                                      1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
515
                                      4, 4, 4, 4, 5, 5, 5, 5, 0};
516
static const uint16_t dist_base[30] = {
517
    1,    2,    3,    4,    5,    7,    9,    13,    17,    25,
518
    33,   49,   65,   97,   129,  193,  257,  385,   513,   769,
519
    1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
520
static const uint8_t dist_extra[30] = {0, 0, 0,  0,  1,  1,  2,  2,  3,  3,
521
                                       4, 4, 5,  5,  6,  6,  7,  7,  8,  8,
522
                                       9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
523
524
inline size_t inflate_raw(const uint8_t* src, size_t src_len, uint8_t* dst,
525
1
                          size_t dst_cap) {
526
1
  BitReader br(src, src_len);
527
1
  size_t out = 0;
528
4
  for (;;) {
529
4
    uint32_t bfinal = br.get(1);
530
4
    uint32_t btype = br.get(2);
531
4
    if (bfinal == UINT32_MAX || btype == UINT32_MAX) return 0;
532
4
    if (btype == 0) {
533
      // stored
534
0
      br.align_byte();
535
0
      if (!br.ensure(16)) return 0;
536
      // read 16+16 from bit buffer awkwardly - use byte path
537
      // Align: bits is multiple of 8
538
      // Get len from remaining bits then bytes
539
0
      uint32_t len = br.get(16);
540
0
      uint32_t nlen = br.get(16);
541
0
      if (len == UINT32_MAX || nlen == UINT32_MAX) return 0;
542
0
      if ((len ^ 0xFFFF) != nlen) return 0;
543
      // After get, may have bits in acc from previous - for stored, should be
544
      // byte aligned Copy len bytes from p
545
0
      if (br.bits != 0) {
546
        // leftover bits should be 0 if aligned
547
0
      }
548
0
      if (size_t(br.end - br.p) < len) return 0;
549
0
      if (out + len > dst_cap) return 0;
550
0
      std::memcpy(dst + out, br.p, len);
551
0
      br.p += len;
552
0
      out += len;
553
4
    } else if (btype == 1 || btype == 2) {
554
4
      Huff lit, dist;
555
4
      if (btype == 1) {
556
        // use fixed via functions
557
4
      } else {
558
        // dynamic
559
4
        uint32_t hlit = br.get(5);
560
4
        if (hlit == UINT32_MAX) return 0;
561
4
        hlit += 257;
562
4
        uint32_t hdist = br.get(5);
563
4
        if (hdist == UINT32_MAX) return 0;
564
4
        hdist += 1;
565
4
        uint32_t hclen = br.get(4);
566
4
        if (hclen == UINT32_MAX) return 0;
567
4
        hclen += 4;
568
4
        static const int order[19] = {16, 17, 18, 0, 8,  7, 9,  6, 10, 5,
569
4
                                      11, 4,  12, 3, 13, 2, 14, 1, 15};
570
4
        uint8_t clen[19]{};
571
69
        for (uint32_t i = 0; i < hclen; i++) {
572
65
          uint32_t v = br.get(3);
573
65
          if (v == UINT32_MAX) return 0;
574
65
          clen[order[i]] = uint8_t(v);
575
65
        }
576
4
        Huff cl;
577
4
        if (!cl.build(clen, 19)) return 0;
578
4
        uint8_t lens[288 + 32]{};
579
4
        uint32_t n = hlit + hdist;
580
1.04k
        for (uint32_t i = 0; i < n;) {
581
1.03k
          int sym = cl.decode(br);
582
1.03k
          if (sym < 0) return 0;
583
1.03k
          if (sym < 16) {
584
973
            lens[i++] = uint8_t(sym);
585
973
          } else if (sym == 16) {
586
63
            uint32_t rep = br.get(2);
587
63
            if (rep == UINT32_MAX) return 0;
588
63
            rep += 3;
589
63
            if (i == 0) return 0;
590
63
            uint8_t v = lens[i - 1];
591
350
            while (rep--) lens[i++] = v;
592
63
          } else if (sym == 17) {
593
0
            uint32_t rep = br.get(3);
594
0
            if (rep == UINT32_MAX) return 0;
595
0
            rep += 3;
596
0
            while (rep--) lens[i++] = 0;
597
0
          } else if (sym == 18) {
598
0
            uint32_t rep = br.get(7);
599
0
            if (rep == UINT32_MAX) return 0;
600
0
            rep += 11;
601
0
            while (rep--) lens[i++] = 0;
602
0
          } else
603
0
            return 0;
604
1.03k
        }
605
4
        if (!lit.build(lens, int(hlit))) return 0;
606
4
        if (!dist.build(lens + hlit, int(hdist))) return 0;
607
4
      }
608
54.4k
      for (;;) {
609
54.4k
        int sym;
610
54.4k
        if (btype == 1)
611
0
          sym = fixed_litlen(br);
612
54.4k
        else
613
54.4k
          sym = lit.decode(br);
614
54.4k
        if (sym < 0) return 0;
615
54.4k
        if (sym < 256) {
616
38.5k
          if (out >= dst_cap) return 0;
617
38.5k
          dst[out++] = uint8_t(sym);
618
38.5k
        } else if (sym == 256) {
619
4
          break;
620
15.9k
        } else {
621
15.9k
          int len_code = sym - 257;
622
15.9k
          if (len_code < 0 || len_code > 28) return 0;
623
15.9k
          uint32_t extra = br.get(len_extra[len_code]);
624
15.9k
          if (len_extra[len_code] && extra == UINT32_MAX) return 0;
625
15.9k
          uint32_t length =
626
15.9k
              len_base[len_code] + (len_extra[len_code] ? extra : 0);
627
15.9k
          int dsym;
628
15.9k
          if (btype == 1)
629
0
            dsym = fixed_dist(br);
630
15.9k
          else
631
15.9k
            dsym = dist.decode(br);
632
15.9k
          if (dsym < 0 || dsym > 29) return 0;
633
15.9k
          uint32_t dextra = br.get(dist_extra[dsym]);
634
15.9k
          if (dist_extra[dsym] && dextra == UINT32_MAX) return 0;
635
15.9k
          uint32_t distance = dist_base[dsym] + (dist_extra[dsym] ? dextra : 0);
636
15.9k
          if (distance > out || out + length > dst_cap) return 0;
637
193k
          for (uint32_t k = 0; k < length; k++) {
638
177k
            dst[out] = dst[out - distance];
639
177k
            out++;
640
177k
          }
641
15.9k
        }
642
54.4k
      }
643
4
    } else {
644
0
      return 0;  // reserved
645
0
    }
646
4
    if (bfinal) break;
647
4
  }
648
1
  return out;
649
1
}
650
651
}  // namespace ada::idna::deflate
652
/* end file src/raw_inflate.hpp */
653
/* begin file src/table_blob.inc */
654
// Auto-generated by scripts/pack_tables.py - do not edit.
655
// Compressed Unicode/IDNA tables (raw DEFLATE).
656
// clang-format off
657
#ifndef ADA_IDNA_TABLE_BLOB_H
658
#define ADA_IDNA_TABLE_BLOB_H
659
#include <cstdint>
660
#include <cstddef>
661
namespace ada::idna::table_blob {
662
constexpr size_t uncompressed_size = 216077;
663
constexpr size_t compressed_size = 65331;
664
constexpr uint32_t uncompressed_crc32 = 0xC16EA7DEu;
665
constexpr size_t decomposition_block_rows = 70;
666
constexpr size_t decomposition_block_cols = 257;
667
constexpr size_t ccc_block_rows = 69;
668
constexpr size_t ccc_block_cols = 256;
669
constexpr size_t composition_block_rows = 27;
670
constexpr size_t composition_block_cols = 257;
671
constexpr size_t id_continue_count = 1437;
672
constexpr size_t id_start_count = 789;
673
constexpr size_t dir_table_count = 1608;
674
constexpr size_t combining_range_count = 333;
675
constexpr size_t joining_table_count = 533;
676
// Offsets into the decompressed buffer:
677
constexpr size_t off_idna_stage1 = 0;
678
constexpr size_t count_idna_stage1 = 4081;
679
constexpr size_t off_idna_stage2 = 8162;
680
constexpr size_t count_idna_stage2 = 11712;
681
constexpr size_t off_idna_bool_blocks = 31592;
682
constexpr size_t count_idna_bool_blocks = 225;
683
constexpr size_t off_idna_utf8_mappings = 33392;
684
constexpr size_t count_idna_utf8_mappings = 17651;
685
constexpr size_t off_decomposition_index = 51043;
686
constexpr size_t count_decomposition_index = 4352;
687
constexpr size_t off_decomposition_block = 55396;
688
constexpr size_t count_decomposition_block = 17990;
689
constexpr size_t off_decomposition_data = 91376;
690
constexpr size_t count_decomposition_data = 9255;
691
constexpr size_t off_ccc_index = 128396;
692
constexpr size_t count_ccc_index = 4352;
693
constexpr size_t off_ccc_block = 132748;
694
constexpr size_t count_ccc_block = 17664;
695
constexpr size_t off_composition_index = 150412;
696
constexpr size_t count_composition_index = 4352;
697
constexpr size_t off_composition_block = 154764;
698
constexpr size_t count_composition_block = 6939;
699
constexpr size_t off_composition_data = 168644;
700
constexpr size_t count_composition_data = 1923;
701
constexpr size_t off_id_continue_flat = 176336;
702
constexpr size_t count_id_continue_flat = 2874;
703
constexpr size_t off_id_start_flat = 187832;
704
constexpr size_t count_id_start_flat = 1578;
705
constexpr size_t off_dir_start = 194144;
706
constexpr size_t count_dir_start = 1608;
707
constexpr size_t off_dir_final = 200576;
708
constexpr size_t count_dir_final = 1608;
709
constexpr size_t off_dir_value = 207008;
710
constexpr size_t count_dir_value = 1608;
711
constexpr size_t off_combining_flat = 208616;
712
constexpr size_t count_combining_flat = 666;
713
constexpr size_t off_joining_start = 211280;
714
constexpr size_t count_joining_start = 533;
715
constexpr size_t off_joining_final = 213412;
716
constexpr size_t count_joining_final = 533;
717
constexpr size_t off_joining_value = 215544;
718
constexpr size_t count_joining_value = 533;
719
alignas(8) inline constexpr uint8_t compressed[] = {
720
0xec,0x9c,0x09,0x40,0x54,0x55,0xfb,0xff,0x1f,0x18,0x59,0x94,0x65,0x9c,0x19,0xb6,
721
0x51,0x61,0x10,0x18,0x98,0x61,0x9f,0x19,0x18,0x76,0x66,0x58,0xda,0xcb,0xb6,0xb7,
722
0x3d,0x2b,0xf7,0xdc,0xb7,0xb4,0xb4,0xd2,0xcb,0x2e,0x28,0xe0,0x86,0x0a,0xb2,0x08,
723
0x8a,0x1b,0xa2,0x02,0xa2,0xec,0x60,0x88,0x8a,0xa5,0x88,0x88,0x65,0x6f,0x96,0x9a,
724
0x20,0x58,0x5a,0x56,0xb6,0x58,0x32,0xff,0xef,0xbd,0x33,0xa0,0x99,0xbd,0xf5,0x96,
725
0xbd,0xbf,0xdf,0xfb,0xfb,0x37,0x0f,0x9f,0x73,0xce,0x3d,0xf7,0x9c,0xf3,0x3c,0xe7,
726
0xb9,0xe7,0x9e,0x7b,0xce,0x1d,0x80,0x18,0x22,0x2d,0x31,0xd4,0x44,0x64,0xa4,0x35,
727
0x62,0x8c,0x9a,0x8c,0xc8,0x58,0x6b,0xcc,0x18,0x13,0xd3,0x64,0x4c,0x3c,0x2d,0x8f,
728
0xe1,0x35,0xf1,0x68,0x90,0x76,0x10,0x33,0xa8,0x69,0x10,0x99,0x18,0x31,0xc6,0x8c,
729
0xd6,0x84,0x18,0x1e,0x33,0x88,0x31,0x61,0x4c,0x19,0x33,0xc6,0x9c,0x19,0xcc,0x0c,
730
0x61,0x2c,0x18,0x62,0x18,0x13,0x4b,0xa6,0xc9,0x84,0x4c,0xb5,0xa6,0x56,0x8c,0x35,
731
0xc3,0x67,0x18,0xd3,0xa1,0x8c,0x80,0x11,0x32,0x22,0xc6,0x86,0xb1,0x65,0xec,0x18,
732
0x7b,0xc6,0x81,0x11,0x33,0x4d,0xa6,0xc3,0x18,0x32,0xd3,0x9a,0x31,0x66,0x4d,0x66,
733
0x64,0x3e,0x1c,0xf5,0x88,0xd1,0x9a,0x33,0xe6,0xd0,0x67,0x4e,0xdc,0xd1,0x08,0xc6,
734
0x91,0x71,0x62,0x24,0x8c,0x33,0x33,0x92,0xa1,0xc1,0xfa,0xbc,0x9f,0x8b,0x0b,0xe3,
735
0xca,0xb8,0x31,0x52,0x46,0x3b,0xd8,0x9d,0x61,0x06,0xbb,0x32,0x1e,0x8c,0x8c,0x91,
736
0x33,0x9e,0x8c,0x17,0xe3,0xcd,0xf8,0x30,0xbe,0x8c,0x1f,0xe3,0x8f,0x52,0x0a,0xa0,
737
0x64,0x54,0x4c,0x00,0xd3,0x34,0x38,0x90,0xa1,0x21,0xda,0x21,0xcc,0x10,0x68,0x19,
738
0x42,0x16,0x5a,0x0b,0xc6,0xa2,0xc9,0x82,0x2c,0xb5,0x96,0x8c,0x65,0x93,0x25,0x59,
739
0x69,0xad,0xd4,0x0c,0x63,0xd5,0x64,0x45,0xd6,0xb0,0xc5,0x5a,0xaf,0x83,0x31,0xc4,
740
0x41,0x4c,0x93,0x35,0xf1,0xb5,0xfc,0x3b,0xd9,0x71,0x27,0x61,0xf8,0x4d,0x6c,0xd9,
741
0xa1,0xc4,0x04,0xeb,0xfb,0x36,0x94,0x19,0xda,0x34,0x94,0x04,0x21,0x8c,0x56,0x10,
742
0xca,0x84,0x21,0x27,0x9c,0x61,0x04,0x4d,0x02,0x12,0x6a,0x85,0x8c,0xb0,0x49,0x48,
743
0xa2,0x08,0x46,0x2b,0x62,0x44,0x4d,0x22,0xb2,0xd1,0xda,0x44,0x32,0x8c,0x4d,0x93,
744
0x0d,0xd9,0x6a,0x6d,0x19,0xdb,0x26,0x5b,0xb2,0xd3,0xda,0xfd,0x5e,0xbd,0x7f,0xcb,
745
0xdf,0xf2,0xb7,0xfc,0x35,0xa2,0x61,0xb4,0x03,0xe9,0x28,0x86,0xb1,0x6b,0xb2,0x8b,
746
0x66,0xc8,0x5e,0x6b,0xcf,0xd8,0x37,0xd9,0xc7,0x30,0x48,0x33,0xb1,0xe0,0x1e,0x70,
747
0x2f,0x73,0x1f,0x73,0x3f,0xe2,0x07,0x98,0x07,0x19,0x72,0xd0,0x3a,0x3c,0xf4,0xb7,
748
0xf7,0xfe,0x42,0x79,0x98,0x79,0x84,0x19,0xf5,0xb7,0x70,0xc2,0x38,0x34,0x39,0x90,
749
0x58,0x2b,0x66,0xc4,0x4d,0x62,0x1a,0xa6,0x1d,0xc6,0x0c,0x6b,0x1a,0x46,0xc3,0xb5,
750
0xc3,0x99,0xe1,0x4d,0xc3,0x69,0x84,0x76,0x04,0x33,0xa2,0x69,0x04,0x39,0x6a,0x1d,
751
0x19,0xc7,0x26,0x47,0x72,0xd2,0x3a,0x31,0x4e,0x4d,0x4e,0x24,0xd1,0x4a,0x1e,0x65,
752
0x1e,0x83,0x27,0x1f,0x67,0x9e,0x40,0xf8,0x24,0xf3,0x0f,0xae,0xad,0xa7,0x98,0xa7,
753
0x99,0x67,0x98,0x67,0x99,0xe7,0x98,0xe7,0x19,0x46,0x82,0x67,0xa6,0x84,0x9c,0x5f,
754
0x60,0xb4,0xce,0x8c,0xf3,0x8b,0x03,0xbe,0xbf,0x8f,0x19,0xcd,0x34,0x39,0x8f,0x62,
755
0x5e,0x62,0x5e,0x66,0x5e,0x61,0xc6,0x30,0x63,0x99,0x71,0xcc,0x78,0x66,0x02,0x33,
756
0x91,0x99,0xc4,0xbc,0xca,0x4c,0x66,0xa6,0x30,0x53,0x99,0x69,0x68,0x8b,0x98,0xe9,
757
0x0c,0x8d,0x9c,0xc1,0xcc,0x64,0xb4,0x23,0x67,0x71,0xad,0xcf,0x66,0xe6,0x30,0x73,
758
0x99,0x17,0x98,0xd7,0x98,0x79,0xcc,0x7c,0x9c,0x7f,0x9d,0x79,0x83,0x59,0xc0,0x2c,
759
0x64,0xde,0x44,0xfa,0x2d,0xe6,0x6d,0x66,0x11,0xb3,0x98,0x61,0x98,0x38,0x26,0x9e,
760
0x49,0x60,0x12,0x91,0x97,0x04,0x92,0xb9,0x9a,0x29,0xcc,0x12,0xa4,0x53,0x99,0x34,
761
0x66,0x29,0xb3,0x8c,0x49,0xe7,0xf2,0x32,0xd8,0xbe,0x8f,0xcc,0x64,0x96,0x33,0x2b,
762
0x98,0x95,0xcc,0x2a,0x9c,0x5f,0xcd,0x64,0x61,0x7d,0xb0,0x86,0x59,0x8b,0x33,0xeb,
763
0x98,0x6c,0x26,0x87,0x59,0x8f,0x54,0x2e,0x93,0xc7,0xe4,0x33,0x05,0x06,0x6f,0x6d,
764
0x60,0x0a,0x99,0x22,0x66,0x23,0xb3,0xe9,0x5f,0x8e,0xaf,0x71,0x9c,0xfd,0xfd,0x52,
765
0x3c,0x90,0x4a,0xbf,0x4b,0xd7,0x6c,0x33,0xb3,0xe5,0x37,0xc7,0xf8,0x56,0x66,0xdb,
766
0xff,0xe0,0x1d,0xf6,0xf8,0x1d,0xf2,0xd2,0xff,0x4f,0xde,0x3f,0x69,0x7f,0xb0,0xde,
767
0xed,0xde,0x71,0x65,0xb6,0x33,0x25,0xcc,0x0e,0xa4,0x4a,0x99,0x9d,0x77,0xd4,0xd0,
768
0x34,0x92,0x5c,0x76,0xe1,0xfc,0x6e,0xa6,0x8c,0x29,0xff,0xff,0x64,0xa6,0xae,0x60,
769
0xf6,0x70,0xbe,0xfa,0xd7,0xe3,0xbd,0x92,0xd9,0xfb,0xff,0xd9,0xac,0xbd,0x6f,0xa0,
770
0xef,0x5a,0x97,0xaa,0x5b,0x3c,0x91,0x71,0xd7,0x34,0x10,0x53,0xcd,0x30,0x2e,0xff,
771
0x73,0x3d,0xd4,0xf7,0xa7,0xc9,0xe5,0xd6,0xeb,0x5c,0xc3,0xd4,0x32,0x75,0xdc,0x9a,
772
0xaa,0xde,0x90,0x23,0x63,0x43,0x57,0xad,0x2b,0xe3,0x4a,0x4c,0x03,0x9e,0x00,0x8d,
773
0x6c,0x1d,0xfd,0xdd,0xe2,0x4a,0x6e,0x5a,0x37,0xc6,0xad,0xc9,0x8d,0xa4,0x5a,0x29,
774
0x23,0x6d,0x92,0x92,0xbb,0xd6,0x9d,0x71,0x6f,0x72,0x27,0x0f,0xad,0x07,0xe3,0x71,
775
0xa7,0x71,0xb4,0x1f,0xf5,0xde,0xf9,0x4d,0xbb,0x9a,0x3c,0x48,0xa6,0x95,0x31,0xb2,
776
0x26,0x59,0x33,0x8e,0x0f,0x30,0x2d,0x03,0xe7,0x0e,0x32,0x87,0x6e,0x2b,0x7d,0xd8,
777
0x10,0xb7,0x1a,0xe2,0x23,0x86,0xf8,0x5d,0x83,0xc6,0xf7,0x18,0x92,0x1f,0xfd,0x15,
778
0x4d,0xc7,0x98,0x36,0x84,0xc7,0x0d,0x47,0x5a,0x39,0x23,0x6f,0x92,0xb7,0x0f,0x9c,
779
0xf5,0x42,0xed,0x13,0x4c,0x07,0x43,0x9e,0x5a,0x4f,0xc6,0xf3,0x24,0xd3,0xe4,0x49,
780
0x5e,0x77,0x9a,0x57,0x7e,0x2e,0x9d,0x86,0xf8,0x14,0xf3,0x3e,0xf3,0x01,0x73,0x9a,
781
0xf9,0xf0,0x96,0x73,0xff,0x04,0x1f,0x71,0xa9,0x33,0x8c,0xd6,0xeb,0xdf,0x9d,0xbf,
782
0xfe,0x96,0xbf,0xe5,0x6f,0xf9,0x5b,0xfe,0x96,0x7f,0x25,0xaf,0xfe,0xaf,0xb1,0xe4,
783
0xe3,0xff,0x42,0xef,0xd5,0xfd,0x7f,0x33,0x4e,0x3e,0xb9,0x43,0xde,0x92,0xbb,0xbb,
784
0xef,0xf7,0x6a,0xf2,0x22,0x6f,0xad,0x37,0xe3,0xdd,0xe4,0x4d,0x3e,0x5a,0x1f,0xc6,
785
0xe7,0xcf,0xed,0x5f,0xfe,0xf7,0xc8,0xd9,0xbf,0xe7,0x19,0x4e,0xd2,0xfe,0x7e,0xbb,
786
0xf5,0xb7,0xfc,0x2d,0x7f,0xcb,0xff,0x49,0xf9,0x7b,0x7e,0xff,0xab,0x45,0xa7,0x33,
787
0x22,0x1e,0x99,0x90,0x19,0x0d,0x26,0x0b,0xb2,0x22,0x3e,0x09,0x48,0x44,0xb6,0x64,
788
0x4f,0x62,0x1a,0x4e,0x8e,0x24,0xa1,0x91,0xe4,0x4a,0x52,0xf2,0x20,0x39,0x79,0x91,
789
0x0f,0xf9,0x91,0x82,0x54,0xa4,0xbb,0x6b,0x9f,0xbe,0x3f,0x29,0x81,0xb7,0xd9,0x12,
790
0x44,0x6c,0x8f,0xd8,0x14,0x21,0x0c,0xe3,0x52,0x1a,0x8a,0xa2,0x18,0xba,0x8f,0x4b,
791
0x3f,0x48,0xa3,0xd0,0x2b,0x9d,0xee,0x31,0x7a,0x9a,0x5e,0x44,0x3c,0x96,0x26,0xd0,
792
0xab,0x34,0x95,0x66,0xd0,0x6c,0x7a,0x8d,0x5e,0xa7,0x85,0xf4,0x36,0xdc,0x92,0x40,
793
0xc9,0x94,0x4a,0xcb,0x28,0x93,0x56,0x52,0x16,0xad,0xa3,0xf5,0x94,0x4f,0x85,0xb4,
794
0x09,0xe5,0xb7,0xd0,0x76,0x2a,0xa5,0xdd,0x54,0x41,0x7b,0xa9,0xfa,0x2e,0xf8,0xa1,
795
0x0e,0x6d,0x34,0x82,0x77,0x40,0x0b,0x38,0x0c,0xde,0x05,0xc7,0x40,0x3b,0x38,0x09,
796
0xde,0x07,0x1f,0x82,0x33,0xe0,0x2c,0xf8,0x14,0x74,0x83,0x5e,0xf0,0x39,0xf8,0x02,
797
0x7c,0x05,0xae,0x81,0xef,0xc1,0x8f,0xa0,0x8f,0xf5,0x83,0x91,0x4e,0x37,0x08,0x98,
798
0x1b,0x99,0x1b,0x59,0x20,0xb6,0x36,0x62,0x35,0x0a,0x10,0xda,0x00,0x7b,0x30,0xcc,
799
0x68,0x98,0x91,0x13,0xe2,0x91,0xc0,0x0d,0x78,0x00,0x4f,0x23,0x5f,0x84,0x0a,0x10,
800
0x00,0x82,0x40,0x28,0x88,0x00,0x5a,0x10,0x03,0xee,0x05,0x0f,0x80,0x87,0xc1,0xa3,
801
0xe0,0x09,0xf0,0x14,0x78,0x16,0xbc,0x00,0x5e,0x02,0x63,0xc0,0x78,0x30,0x09,0x4c,
802
0x01,0xd3,0xc1,0x2c,0x30,0xd7,0x68,0x3e,0xc2,0x05,0xe0,0x2d,0x20,0x85,0x95,0x8b,
803
0x8d,0xe2,0x91,0x4a,0x02,0x4b,0x8c,0x96,0x22,0xcc,0x30,0x5a,0x61,0xb4,0x9a,0xb3,
804
0x74,0xad,0x51,0x8e,0x51,0x9e,0xd1,0x06,0xa4,0x37,0x1a,0x6d,0x46,0xb8,0xcd,0x68,
805
0x87,0xd1,0x2e,0x23,0xbd,0xdf,0xca,0x8d,0x2a,0x91,0xaa,0x32,0xaa,0x45,0xd8,0x00,
806
0xf6,0x83,0x03,0x46,0x87,0x10,0x1e,0xe1,0x4a,0x1c,0x45,0x78,0xdc,0xa8,0x03,0xe1,
807
0x29,0xa3,0xd3,0x46,0x1f,0x21,0xfe,0x04,0x9c,0x37,0xea,0x32,0xd4,0xef,0x31,0xfa,
808
0xf9,0x75,0xf8,0xcc,0x88,0x95,0x2f,0x38,0xf9,0x8a,0x93,0x6b,0x28,0xf1,0x3d,0xf8,
809
0x11,0xf4,0x01,0x23,0x63,0x78,0x13,0x98,0x81,0x21,0xc6,0x6c,0x1d,0x2b,0x84,0x43,
810
0x81,0x08,0xd8,0x01,0x31,0x18,0x01,0x24,0xc0,0x05,0x48,0xb9,0x52,0x32,0x63,0x56,
811
0xbc,0x90,0xf6,0x35,0x56,0x18,0x07,0x20,0x0e,0x02,0xa1,0x20,0x02,0x68,0x41,0x0c,
812
0xb8,0x17,0x3c,0x00,0x1e,0x06,0x8f,0x82,0x27,0xc0,0x53,0xe0,0x59,0xf0,0x02,0x78,
813
0x09,0x8c,0x01,0xe3,0xc1,0x24,0x30,0x05,0x4c,0x07,0xb3,0xc0,0x5c,0x30,0x1f,0x2c,
814
0x00,0x6f,0x81,0xc5,0x20,0x1e,0x24,0x81,0x25,0x60,0xa9,0xf1,0xcf,0xfb,0x9a,0x61,
815
0xbc,0x12,0x39,0x59,0xc6,0xeb,0xb8,0xfc,0x5c,0x84,0x05,0xc6,0x45,0xc6,0xc5,0xc6,
816
0x5b,0x91,0x2a,0x01,0x3b,0x41,0x19,0xd8,0x63,0xac,0xfb,0xaf,0xff,0xf0,0x69,0x9f,
817
0xb1,0x08,0x33,0x58,0x8d,0x71,0xbd,0x71,0x93,0xb1,0x0f,0x66,0xaf,0x3f,0xd7,0x5e,
818
0xb3,0xf1,0x21,0xe3,0x77,0x8d,0xdb,0x8c,0x3b,0x8c,0xdf,0xe7,0xbc,0xb3,0xd9,0xc8,
819
0x1e,0xb3,0xa3,0x1f,0xfd,0xf3,0x0f,0xfa,0xea,0x63,0xe3,0x73,0xa8,0x79,0xc1,0xf8,
820
0xa2,0xf1,0xe7,0x77,0x68,0x81,0xfe,0xf4,0x0c,0xf3,0x05,0x5a,0xfd,0x0a,0x5c,0x03,
821
0xdf,0x1b,0xeb,0xe7,0xdb,0x1f,0xfb,0x35,0x19,0x1b,0xf1,0xfa,0xe7,0xd1,0x18,0x1a,
822
0xc4,0x1b,0xc2,0xb3,0xe2,0x0d,0xe5,0x89,0x78,0x76,0xc8,0x15,0x83,0x11,0x3c,0x09,
823
0x0f,0x23,0x99,0x27,0xe5,0xc9,0x78,0x5e,0x3c,0x5f,0x9e,0x82,0x17,0xc0,0x0b,0xe2,
824
0x7d,0x6e,0x1c,0xca,0x8b,0xe0,0xdd,0x47,0x5a,0x5e,0x0c,0xef,0x5e,0xde,0x03,0xbc,
825
0x87,0x51,0xf2,0x51,0xde,0x13,0xbc,0xa7,0x78,0xcf,0xf2,0x5e,0xe0,0xbd,0xc4,0x1b,
826
0xc3,0x1b,0xcf,0x9b,0xc4,0xbb,0x3b,0x57,0x6f,0x0a,0x74,0x07,0xa1,0xe5,0x11,0x68,
827
0xf1,0x59,0xe8,0xc2,0x98,0x07,0xb3,0xc0,0x5c,0x30,0x1f,0x2c,0x00,0x6f,0x81,0xc5,
828
0x20,0x1e,0x24,0x81,0x25,0x60,0x29,0xc8,0x00,0xa1,0xb0,0xef,0x51,0xc4,0x41,0xb0,
829
0x5f,0xa7,0x5b,0x01,0x1e,0xe5,0xad,0xe6,0xac,0x5b,0xcb,0xcb,0xe1,0xe5,0xf1,0x36,
830
0xf0,0x36,0xf2,0x36,0xf3,0xb6,0xf1,0x76,0xf0,0x76,0xf1,0xca,0x79,0x95,0xbc,0x2a,
831
0x5e,0x2d,0xaf,0x81,0xb7,0x9f,0x77,0x80,0x77,0x88,0x77,0x84,0x77,0x94,0x77,0x9c,
832
0xd7,0xc1,0x3b,0xc5,0x3b,0xcd,0xfb,0x88,0xf7,0x09,0xef,0x3c,0xaf,0x8b,0xd7,0xc3,
833
0xfb,0x8c,0x77,0x85,0x77,0x95,0xf7,0x0d,0xef,0x3b,0xde,0x75,0xde,0x0d,0x1e,0xdc,
834
0x36,0xc8,0x74,0xd0,0xe0,0x41,0x96,0x83,0xf8,0x83,0x84,0x83,0x6c,0x07,0x39,0x0c,
835
0x1a,0x3e,0xc8,0x69,0xd0,0xc8,0x41,0x6e,0x83,0x3c,0x06,0x79,0x0e,0xf2,0x19,0xf4,
836
0x57,0x8f,0x6f,0x7f,0x68,0x50,0x01,0x35,0x08,0x01,0xe1,0x40,0x03,0xa2,0xc1,0x3d,
837
0xe0,0x7e,0xf0,0x10,0x18,0x05,0x1e,0x07,0xff,0x00,0xcf,0x80,0xe7,0xc1,0x68,0xf0,
838
0xca,0x1d,0x2c,0x1c,0x87,0xbc,0x89,0x60,0x32,0x98,0x06,0x66,0x82,0x39,0x60,0x1e,
839
0x78,0x03,0xbc,0x09,0x16,0x81,0x38,0x90,0x08,0x52,0x40,0x1a,0x48,0x07,0xcb,0xc1,
840
0x2a,0xb0,0x06,0x64,0x83,0x5c,0x50,0x00,0x8a,0x40,0x31,0xd8,0x0a,0x4a,0xc0,0x4e,
841
0x50,0x06,0xf6,0x0c,0xda,0x87,0xb0,0x06,0xd4,0x83,0x26,0xd0,0x0c,0x0e,0x82,0x56,
842
0xce,0xb2,0xf7,0x10,0xb6,0x81,0x13,0xa0,0x13,0x7c,0x00,0xfe,0x09,0x3e,0x06,0xe7,
843
0xc0,0x05,0x70,0x11,0x5c,0x02,0x97,0xc1,0x97,0xe0,0x6b,0xf0,0x2d,0xf8,0x01,0xfc,
844
0xc4,0xb6,0x02,0x8c,0x4d,0x74,0x3a,0x13,0x60,0x0e,0x2c,0x80,0x35,0x10,0x00,0x1b,
845
0x60,0x0f,0x86,0x01,0x47,0xe0,0x0c,0x5c,0x81,0x3b,0x90,0x03,0x6f,0xe0,0x07,0x94,
846
0x20,0x10,0x04,0x83,0x30,0x10,0x09,0xa2,0x40,0x2c,0xb8,0x0f,0x3c,0x08,0x1e,0x01,
847
0x8f,0x81,0x27,0xc1,0xd3,0xe0,0x39,0x13,0xf6,0x7e,0x7b,0xd1,0xe4,0x65,0x93,0xb1,
848
0x26,0x13,0x4c,0x5e,0x35,0x99,0x6a,0x32,0xc3,0x64,0xb6,0xc9,0x6b,0x26,0xaf,0x9b,
849
0x2c,0x34,0x79,0xdb,0x84,0x31,0x49,0x30,0x49,0x36,0x49,0x35,0x59,0x66,0x92,0x69,
850
0xb2,0xd2,0x24,0xcb,0x64,0x9d,0xc9,0x7a,0x93,0x7c,0x93,0x42,0x93,0x4d,0x26,0x5b,
851
0x4c,0xb6,0x9b,0x94,0x9a,0xec,0x36,0xa9,0x30,0xd9,0x6b,0x52,0x6d,0x52,0x67,0xd2,
852
0x68,0xf2,0x8e,0x49,0x8b,0xc9,0x61,0x93,0x77,0x4d,0xfa,0x74,0x33,0x4c,0xfe,0xca,
853
0xd1,0x74,0xcc,0xd0,0xfa,0x42,0x58,0xd3,0xbf,0x3e,0xfb,0xbf,0xf2,0xe9,0x30,0xf9,
854
0xc0,0xe4,0x8c,0xc9,0xf9,0x3f,0xe9,0xbf,0x8b,0x26,0x57,0x4c,0xae,0x99,0xfc,0x64,
855
0xc2,0x33,0x1d,0x62,0x2a,0x30,0x75,0x30,0xbd,0xbb,0x2b,0xe1,0x5b,0xe3,0x3b,0xad,
856
0x8e,0x6f,0xe6,0x48,0x4c,0xdd,0x4d,0xfb,0x74,0x3e,0xa6,0xb7,0xd7,0xfe,0x63,0x3a,
857
0x6f,0xbf,0xce,0x37,0xf5,0xfd,0xfb,0x2d,0xf7,0xdd,0xe1,0x38,0xc0,0x94,0x0d,0xc3,
858
0x4c,0x6f,0x6d,0xb1,0xef,0x37,0xf5,0xdd,0xde,0x67,0xbd,0x44,0x9b,0x3e,0x60,0xfa,
859
0x98,0x29,0x9b,0xfb,0x8c,0xe9,0xed,0xde,0xf9,0xf7,0x77,0x1b,0xff,0xca,0xff,0xbf,
860
0x56,0x8a,0x95,0x97,0x4c,0x27,0x98,0xf6,0xdd,0xd1,0x93,0x7f,0xdc,0x82,0xbf,0xee,
861
0x33,0xcd,0x54,0xf7,0x2b,0xd7,0xb7,0x6f,0xe0,0x1a,0xf5,0xfd,0x8b,0x6b,0xf8,0xfb,
862
0xae,0xfa,0xaf,0xd7,0x9a,0x6b,0xfa,0xaf,0x47,0xdf,0xaf,0xb5,0xd0,0xf7,0xab,0x3e,
863
0x5c,0x68,0x1a,0x67,0x7a,0x37,0xf6,0x8f,0xbf,0xf6,0x59,0x62,0xfa,0x9f,0x9c,0x9b,
864
0x96,0x99,0xfe,0xb2,0xc7,0xab,0x06,0xf2,0x72,0x06,0x52,0x85,0x03,0xa9,0xad,0xbf,
865
0x6a,0xdf,0x2e,0xd3,0x5f,0xde,0x53,0x7b,0x91,0x57,0x6f,0x7a,0xc0,0xf4,0x5d,0xd3,
866
0x4e,0xd3,0x8f,0x6e,0xab,0xd9,0xfd,0x3b,0x7a,0x7a,0xf9,0x0e,0xf6,0x7d,0x33,0x90,
867
0xf7,0xe3,0x40,0xca,0xd8,0xac,0x3f,0x35,0xd8,0xec,0xd7,0xda,0x1a,0x6a,0x76,0x37,
868
0x9f,0x2c,0xf6,0x66,0xc3,0xcd,0x24,0x66,0xae,0x66,0x1e,0x66,0x5e,0x66,0x7e,0x66,
869
0x2a,0xb3,0x20,0xb3,0x30,0x33,0x8d,0x59,0x8c,0xd9,0x7d,0x66,0x0f,0x99,0x3d,0x6a,
870
0xf6,0xa4,0xd9,0x33,0x66,0x2f,0x98,0xbd,0x6c,0x36,0xce,0x6c,0x92,0xd9,0x54,0xb3,
871
0x99,0x66,0x73,0xcd,0x5e,0x37,0x7b,0xd3,0x6c,0xb1,0x59,0x82,0x59,0x8a,0xd9,0x52,
872
0xb3,0x4c,0xb3,0x55,0x66,0x6b,0xcd,0xd6,0x9b,0x15,0x98,0x6d,0x34,0xdb,0x62,0x56,
873
0x62,0xd6,0xa7,0xdb,0x65,0x76,0x73,0x64,0x54,0x98,0xfd,0x95,0x77,0xe7,0x3e,0xb3,
874
0xbb,0xd1,0x0a,0x11,0x91,0xee,0xbf,0xe6,0xc3,0xfa,0xb3,0xd6,0xac,0xd1,0xac,0xd9,
875
0xec,0x90,0xd9,0xbb,0x66,0x6d,0x66,0x7d,0xff,0xc1,0xd5,0xc5,0xbf,0xe7,0x29,0x1a,
876
0xf8,0xfc,0xd6,0x1c,0xfe,0x67,0x3f,0xa7,0xb0,0xb3,0xb8,0xce,0x63,0xf7,0x10,0xa6,
877
0xd8,0x37,0xa8,0x06,0x75,0x98,0xbd,0x6f,0x76,0xab,0x86,0x7f,0x9a,0x7d,0x62,0xf6,
878
0xa9,0xd9,0x45,0xb3,0xcf,0xcc,0xbe,0x30,0xfb,0xda,0xec,0x3b,0xb3,0x1f,0xcd,0x74,
879
0x66,0x3c,0x73,0x33,0xf3,0x7d,0x66,0x16,0xe6,0x7c,0x73,0x91,0xb9,0xbd,0xf9,0x70,
880
0x73,0x89,0xb9,0xab,0xb9,0x87,0xb9,0x97,0xb9,0x9f,0xb9,0xca,0x3c,0xc8,0x3c,0xcc,
881
0x5c,0x63,0x1e,0x63,0x7e,0x9f,0xf9,0x43,0xe6,0x8f,0x9a,0x3f,0x69,0xfe,0x8c,0xf9,
882
0x0b,0xe6,0x2f,0x9b,0x8f,0x33,0x9f,0x64,0x3e,0xd5,0x7c,0xa6,0xf9,0x5c,0xf3,0xd7,
883
0xcd,0xdf,0x34,0x5f,0x6c,0xce,0xb6,0x9c,0x60,0x9e,0x62,0xbe,0xd4,0xfc,0xaf,0xf2,
884
0xb7,0x11,0xbd,0x46,0x3c,0x78,0x8f,0x7d,0xaf,0xb8,0xd6,0xe8,0xf6,0xf7,0x8a,0x58,
885
0x6b,0xd3,0x5c,0x63,0x09,0xf6,0xe5,0xec,0x7b,0x45,0x1f,0x32,0xa2,0x4c,0xf3,0x95,
886
0xe6,0x59,0xe6,0x3c,0xee,0x3d,0x24,0xfb,0xd6,0x27,0xdb,0xdc,0x0a,0xa5,0x6c,0x51,
887
0xda,0xd7,0xc8,0x91,0x96,0x18,0xe5,0x9a,0x6f,0x30,0x97,0x70,0xa5,0x37,0x99,0x97,
888
0x1b,0x79,0xd1,0x56,0x73,0xfd,0xae,0x94,0xdd,0x73,0x0a,0xd0,0x0e,0xfb,0x76,0x92,
889
0xcd,0x79,0x98,0xcb,0xf9,0x75,0xbb,0xbe,0xbb,0x2b,0x3b,0xd3,0x1d,0xe6,0x26,0xb4,
890
0xcb,0x7c,0x25,0x65,0x9b,0x5b,0x50,0xb9,0x79,0xa5,0x79,0x95,0xf9,0x0e,0xa3,0x6d,
891
0x46,0xb5,0xe6,0x0d,0xe6,0xef,0x98,0xb7,0x98,0x1f,0x36,0x7f,0xcf,0xbc,0xcd,0xfc,
892
0x84,0x79,0xa5,0x51,0xa7,0xf9,0x07,0xe6,0x55,0x46,0xff,0x34,0xff,0xd8,0xfc,0x88,
893
0xd1,0x39,0xf3,0x22,0xe3,0x53,0x46,0x17,0xcc,0x4f,0x1b,0x15,0x1b,0xab,0xa8,0xc7,
894
0xfc,0x33,0xf3,0xf3,0x46,0x41,0xbc,0x2b,0xb8,0x02,0x5f,0x81,0x6f,0xc1,0x75,0xd0,
895
0x07,0x8c,0x07,0xeb,0x74,0xa6,0x60,0x08,0xb0,0x06,0x42,0x60,0x07,0x86,0x01,0x27,
896
0xe0,0x02,0xdc,0x81,0x27,0xf0,0x05,0x4a,0xa0,0x06,0xa1,0x20,0x12,0x44,0x83,0x7b,
897
0xc1,0x83,0x60,0x14,0x78,0x02,0x3c,0x0d,0x9e,0x07,0x2f,0x81,0xb1,0x60,0x22,0x98,
898
0x02,0x66,0x80,0x39,0x60,0x3e,0x58,0x08,0x16,0x81,0x78,0x90,0x0c,0xd2,0x40,0x06,
899
0x58,0x09,0xd6,0x80,0x1c,0x90,0x0f,0x8a,0xc0,0x66,0xb0,0x1d,0xec,0x04,0xe5,0x60,
900
0x2f,0xa8,0x01,0x0d,0xe0,0x1d,0x70,0x10,0x1c,0x01,0xc7,0xc0,0x09,0x70,0x0a,0x7c,
901
0x08,0x3e,0x06,0xe7,0x41,0x37,0xb8,0x04,0xae,0x80,0xaf,0xc0,0xb7,0xe0,0x3a,0xe8,
902
0x03,0xc6,0x43,0xd0,0x7f,0x30,0x04,0x58,0x03,0x21,0xb0,0x1b,0x72,0xd3,0xfb,0xc3,
903
0x86,0xb0,0x5a,0xe1,0x0b,0xe4,0x8d,0x04,0x52,0x20,0x07,0x3e,0x40,0x01,0x02,0x41,
904
0x08,0x88,0x00,0x51,0xe0,0x1e,0xf0,0x00,0x78,0x04,0x3c,0x0e,0x9e,0x02,0xcf,0x81,
905
0xd1,0x60,0x0c,0x98,0x00,0x26,0x83,0xe9,0x60,0x36,0x98,0x07,0x16,0x80,0xb7,0x41,
906
0x1c,0x48,0x02,0xa9,0x20,0x1d,0xac,0x00,0x59,0x20,0x1b,0xe4,0x81,0x42,0x50,0x0c,
907
0xb6,0x81,0x52,0x50,0x06,0x2a,0x41,0x35,0xa8,0x07,0xfb,0x41,0x0b,0x68,0x05,0x47,
908
0x41,0x3b,0xe8,0x04,0xa7,0xc1,0x99,0x21,0xbf,0x1c,0x59,0xe7,0x86,0x74,0x0d,0xe9,
909
0x1d,0x72,0x79,0xc8,0xd5,0x21,0xd7,0x86,0xfc,0x30,0xe4,0xc6,0x90,0xdb,0xe7,0x1d,
910
0x23,0x0b,0x13,0x8b,0xc1,0x16,0x56,0x16,0x02,0x0b,0x5b,0x8b,0x3b,0xcd,0x3f,0x62,
911
0x0b,0x47,0x8b,0x91,0x16,0x52,0x0b,0xb9,0x85,0x8f,0x85,0xc2,0x22,0xd0,0xe2,0xf6,
912
0xf3,0x21,0x16,0x11,0x16,0x51,0x16,0xf7,0x58,0x3c,0x60,0xf1,0x88,0xc5,0xe3,0x16,
913
0x4f,0x59,0xdc,0xde,0xfe,0x73,0x16,0xa3,0x2d,0xc6,0x58,0x4c,0xb0,0x98,0x6c,0x31,
914
0xfd,0x8e,0xed,0xf7,0xe9,0x66,0x23,0x7f,0x1e,0x58,0x00,0xde,0xfe,0x45,0xfb,0x71,
915
0x16,0x49,0x16,0xa9,0x16,0xe9,0x16,0x2b,0x2c,0xb2,0x2c,0xb2,0x2d,0xf2,0x70,0x7e,
916
0x08,0xee,0xb8,0xa1,0x40,0x04,0xec,0x80,0x18,0x8c,0x00,0x12,0xee,0xdd,0x53,0xa1,
917
0xc5,0x16,0x8b,0x52,0x8b,0x0a,0x8b,0x6a,0x8b,0x46,0x8b,0x16,0x8b,0x77,0x2d,0x6e,
918
0x3f,0x6e,0xb7,0x78,0xdf,0xe2,0x8c,0xc5,0xa7,0x16,0xbd,0x16,0x5f,0x58,0x5c,0xb3,
919
0xf8,0xf1,0x17,0xc7,0x46,0x96,0x66,0x96,0x56,0x96,0x22,0x4b,0xb1,0xa5,0xc4,0x52,
920
0x6a,0xe9,0x65,0x79,0xfb,0x31,0x6b,0x93,0xc2,0x32,0xc8,0x32,0xdc,0x92,0xed,0x4b,
921
0x94,0xe5,0x7d,0x96,0x0f,0x59,0x3e,0x6a,0x39,0x84,0x17,0x64,0xf9,0xa4,0xe5,0xe7,
922
0xc6,0x4f,0x5a,0x3e,0x63,0xf9,0x82,0xe5,0x18,0xcb,0x49,0x96,0xd3,0xb8,0xf3,0xb3,
923
0x2d,0x5f,0xb7,0x1c,0xca,0x7b,0xd3,0x52,0xc4,0x9b,0x64,0xb9,0xd8,0x32,0xc9,0x72,
924
0xa9,0xa5,0xbe,0x57,0x2b,0x2c,0xfb,0x7d,0xb1,0xda,0x72,0x9d,0x65,0xae,0x25,0xfb,
925
0x86,0x6c,0x83,0xe5,0x66,0xcb,0x1d,0x86,0xf3,0xe5,0x96,0xfd,0xfd,0xaf,0xb4,0xac,
926
0xb6,0xac,0xb7,0x1c,0xc1,0xdb,0x6f,0xd9,0x62,0x39,0x88,0xf7,0x2e,0x57,0xef,0xa8,
927
0x65,0x87,0xe5,0x07,0x5c,0xfb,0x67,0x2c,0x3f,0xb5,0x14,0xf3,0x2e,0x5a,0x4a,0x78,
928
0x1d,0x96,0x31,0xf4,0x99,0x25,0xfb,0xfd,0xc5,0x9d,0x44,0xff,0xdc,0xd1,0xeb,0xfc,
929
0xc2,0xf2,0xa6,0x77,0xbf,0xb6,0xfc,0xd7,0xfb,0x0a,0xdd,0xaf,0x7c,0x3b,0xf2,0x9d,
930
0x65,0x1f,0x6a,0x9a,0x5b,0xf1,0xad,0x06,0xc6,0x09,0x52,0x23,0xac,0x6e,0x6f,0xc5,
931
0xd9,0xca,0xd5,0xca,0xdd,0xea,0xd7,0xe7,0x3d,0xf9,0x6d,0xe7,0x02,0x6f,0x3e,0x28,
932
0xe9,0xa6,0xd6,0x5b,0x32,0x49,0x6d,0x25,0xe0,0xce,0x04,0x5b,0x85,0x5a,0x85,0x5b,
933
0x45,0x5a,0x69,0xad,0xa2,0xad,0x62,0xad,0xee,0xb5,0x7a,0xd0,0xea,0x61,0xab,0x51,
934
0x56,0xc3,0x71,0x7e,0x14,0xb1,0xdf,0xcf,0xdc,0xf9,0x3c,0xfb,0x1c,0x19,0x4c,0x8e,
935
0xe4,0x87,0x67,0x02,0x7f,0xe0,0xe9,0x21,0xe1,0xbe,0x8f,0xf2,0xb9,0xe3,0x37,0x51,
936
0x8f,0x59,0xfd,0x7b,0x33,0xf9,0x93,0x56,0xcf,0x58,0x99,0xd0,0x0b,0xa8,0xf5,0xb2,
937
0xd5,0x38,0xab,0x3c,0xf6,0x1b,0x0b,0x2b,0xf6,0x69,0xa5,0x97,0x6b,0x78,0x6a,0x09,
938
0xa0,0xd5,0x1e,0x7a,0x86,0xd3,0x54,0xae,0x6d,0xfd,0x37,0x62,0xac,0xb0,0x47,0x33,
939
0xac,0x66,0x5b,0xcd,0x43,0x3e,0x6b,0xc9,0x18,0x9e,0x3e,0xb6,0xa5,0xd9,0xdc,0x77,
940
0x6a,0x58,0x05,0x73,0xdf,0xaa,0xbd,0x61,0x25,0x46,0x1f,0xde,0xb2,0x5a,0x6c,0x15,
941
0x6f,0x95,0x04,0x7f,0x60,0x77,0x61,0xf5,0x00,0x9e,0x55,0x32,0xde,0x03,0xbc,0x65,
942
0x03,0xf6,0x9a,0x71,0xcf,0x3e,0xf6,0x29,0x79,0xab,0x7d,0xcb,0xad,0xd6,0x58,0xe5,
943
0x5a,0x6d,0xb4,0xda,0x66,0xb5,0xcb,0xaa,0xd2,0xaa,0xd6,0x6a,0xbf,0xd5,0x21,0xab,
944
0xa3,0x56,0x1d,0x56,0xa7,0xad,0x3e,0xb1,0xea,0xb2,0xfa,0x0c,0xad,0x7d,0x69,0xf5,
945
0xb5,0xd5,0x77,0x56,0x5e,0x74,0xdd,0xea,0x86,0x95,0x91,0xb5,0xa9,0xb5,0x1f,0x0d,
946
0xb6,0xb6,0xb4,0xb6,0xe7,0xbe,0xd3,0x13,0xd3,0x6f,0x9d,0x37,0xac,0xc9,0xad,0x6f,
947
0x6a,0xb4,0xb1,0xbe,0x7d,0xf7,0xf0,0xdf,0xf8,0x19,0x66,0x3d,0x12,0xfd,0xf0,0xb2,
948
0x56,0x5a,0xff,0xa7,0x35,0x87,0x5b,0x6b,0xff,0xb4,0xce,0xdf,0xbf,0x7f,0xbd,0xc3,
949
0xdd,0x63,0x7d,0x9f,0xf5,0x83,0xd6,0x8f,0x58,0x3f,0x66,0xfd,0xa4,0xf5,0xd3,0xd6,
950
0xcf,0x59,0xbf,0x68,0xfd,0xb2,0xf5,0x58,0xeb,0x09,0xd6,0x93,0xad,0xa7,0x5b,0xcf,
951
0xb6,0x9e,0x67,0xbd,0xc0,0xfa,0x6d,0xeb,0x38,0xeb,0x24,0xeb,0x54,0xeb,0x0c,0xeb,
952
0x55,0xd6,0xeb,0xac,0xf3,0xac,0x8b,0xac,0xb7,0x58,0xef,0xb0,0x2e,0xb3,0xde,0x6b,
953
0x5d,0x6b,0xfd,0x7b,0xf5,0x36,0x59,0x1f,0xb0,0x3e,0x6c,0xfd,0x9e,0xf5,0x71,0xeb,
954
0x93,0xd6,0x1f,0x58,0x7f,0x64,0x7d,0xd6,0xfa,0x82,0x75,0x8f,0xf5,0xe7,0xd6,0x5f,
955
0x5a,0x7f,0x63,0xfd,0xbd,0xf5,0x4f,0xd6,0xc4,0x1f,0xc4,0x37,0xe7,0x5b,0xf2,0x87,
956
0xf2,0x6d,0xf8,0x0e,0xfc,0x11,0x7c,0x67,0xbe,0x1b,0xff,0x8f,0x7c,0xd3,0xfc,0x47,
957
0xea,0xa8,0xad,0xfe,0xfc,0x55,0x94,0xf1,0x75,0xff,0xa7,0x3e,0x81,0xfc,0x10,0x7e,
958
0xf8,0x5d,0xec,0x93,0xf6,0x2e,0xb5,0x75,0x2f,0xff,0x41,0xfe,0x28,0xfe,0x13,0xfc,
959
0xa7,0xf9,0xcf,0xf3,0x5f,0xe2,0x8f,0xe5,0x4f,0xe4,0x4f,0xe1,0xcf,0xe0,0xcf,0xe1,
960
0xcf,0xe7,0x2f,0xe4,0x2f,0xe2,0xc7,0xf3,0x93,0xf9,0x69,0xfc,0x0c,0xfe,0x4a,0xfe,
961
0x1a,0x7e,0x0e,0x3f,0x9f,0x5f,0xc4,0xdf,0xcc,0xdf,0xce,0xdf,0xc9,0x2f,0xe7,0xef,
962
0xe5,0xd7,0xf0,0x1b,0xf8,0xef,0xf0,0x0f,0xf2,0x8f,0xf0,0x8f,0xf1,0x4f,0xf0,0x4f,
963
0xf1,0x3f,0xe4,0x7f,0xcc,0x3f,0xcf,0xef,0xe6,0x5f,0xe2,0x5f,0xe1,0x7f,0xc5,0xff,
964
0x96,0x7f,0x9d,0xdf,0xc7,0x37,0x1e,0xfa,0x57,0xfb,0xd5,0x14,0x1a,0x86,0x0c,0xb5,
965
0x1a,0x2a,0xe0,0x34,0xd9,0x20,0x74,0x00,0x23,0xc0,0x4a,0xec,0x01,0x32,0xcd,0x77,
966
0x60,0x3d,0xef,0xcc,0x9d,0x73,0xfb,0x99,0x2d,0x22,0x8c,0x57,0xd9,0x50,0xaf,0xa1,
967
0xbe,0xc8,0x55,0x02,0x35,0x08,0x05,0x91,0x20,0x1a,0xdc,0x0b,0x1e,0x04,0xa3,0xc0,
968
0x13,0xe0,0x69,0xf0,0x3c,0x78,0x09,0x8c,0x05,0x13,0xc1,0x14,0x30,0x03,0xcc,0x01,
969
0xf3,0xc1,0x42,0xb0,0x08,0xc4,0x83,0x64,0x90,0x06,0x32,0x58,0x4b,0xc0,0x1a,0x90,
970
0x03,0xf2,0x41,0x11,0xd8,0x0c,0xb6,0x83,0x9d,0xa0,0x1c,0xec,0x05,0x35,0xa0,0x01,
971
0xbc,0x03,0x0e,0x82,0x23,0xe0,0x18,0x38,0x01,0x4e,0x81,0x0f,0xc1,0xc7,0xe0,0x3c,
972
0xe8,0x06,0x97,0xc0,0x15,0xf0,0xd5,0x2f,0xbc,0xfc,0x2d,0x72,0xae,0x0f,0xe4,0xf6,
973
0x0d,0xd5,0xfd,0xc7,0xde,0x77,0xfe,0x7c,0x96,0x32,0x16,0xe8,0xfe,0xd0,0xdb,0xbf,
974
0xdf,0xfb,0x86,0xdb,0x54,0xf0,0xdf,0x71,0xf7,0x0f,0x11,0xfc,0x9a,0x07,0xac,0x05,
975
0x42,0x81,0x9d,0x60,0x98,0xc0,0x49,0xe0,0x22,0x70,0x17,0x78,0x0a,0x7c,0x05,0x4a,
976
0x81,0x5a,0x10,0x2a,0x88,0x14,0x44,0x0b,0xee,0x15,0x3c,0x28,0x18,0x25,0x78,0x42,
977
0xf0,0xb4,0xe0,0x79,0xc1,0x4b,0x82,0xb1,0x82,0x89,0x82,0x29,0x82,0x19,0x82,0x39,
978
0x82,0xf9,0x82,0x85,0x82,0x45,0x82,0x78,0x41,0xb2,0x20,0x4d,0x90,0x21,0x58,0x29,
979
0x58,0x23,0xc8,0x11,0xe4,0x0b,0x8a,0x04,0x9b,0x05,0xdb,0x05,0x3b,0x05,0xe5,0x82,
980
0xbd,0x82,0x1a,0x41,0x83,0xe0,0x1d,0xc1,0x41,0xc1,0x11,0xc1,0x31,0xc1,0x09,0xc1,
981
0x29,0xc1,0x87,0x82,0x8f,0x05,0xe7,0x05,0xdd,0x82,0x4b,0x82,0x2b,0x82,0xaf,0x04,
982
0xdf,0x0a,0xae,0x0b,0xfa,0x04,0xc6,0x42,0x53,0xe1,0x10,0xa1,0xb5,0x50,0x28,0xb4,
983
0x13,0x0e,0x13,0x3a,0x09,0x5d,0x84,0xee,0x42,0x4f,0xa1,0xaf,0x50,0x29,0x54,0x0b,
984
0x43,0x85,0x91,0xc2,0x68,0xe1,0xbd,0xc2,0x07,0x85,0xa3,0x84,0x4f,0x08,0x9f,0x16,
985
0x3e,0x2f,0x7c,0x49,0x38,0x56,0x38,0x51,0x38,0x45,0x38,0x43,0x38,0x47,0x38,0x5f,
986
0xb8,0x50,0xb8,0x48,0x18,0x2f,0x4c,0x16,0xa6,0x09,0x33,0x84,0x2b,0x85,0x6b,0x84,
987
0x39,0xc2,0x7c,0x61,0x91,0x70,0xb3,0x70,0xbb,0x70,0xa7,0xb0,0x5c,0xb8,0x57,0x58,
988
0x23,0x6c,0x10,0xbe,0x23,0x3c,0x28,0x3c,0x22,0x3c,0x26,0x3c,0x21,0x3c,0x25,0xfc,
989
0x50,0xf8,0xb1,0xf0,0xbc,0xb0,0x5b,0x78,0x49,0x78,0x45,0xf8,0x95,0xf0,0x5b,0xe1,
990
0x75,0x61,0x9f,0xd0,0x58,0x64,0x2a,0x1a,0x22,0xb2,0x16,0x09,0x45,0x76,0xa2,0x61,
991
0x22,0x27,0x91,0x8b,0xc8,0x5d,0xe4,0x29,0xf2,0x15,0x29,0x45,0x6a,0x51,0xa8,0x28,
992
0x52,0x14,0x2d,0xba,0x57,0xf4,0xa0,0x68,0x94,0xe8,0x09,0xd1,0xd3,0xa2,0xe7,0x45,
993
0x2f,0x89,0xc6,0x8a,0x26,0x8a,0xa6,0x88,0x66,0x88,0xe6,0x88,0xe6,0x8b,0x16,0x8a,
994
0x16,0x89,0xe2,0x45,0xc9,0xa2,0x34,0x51,0x86,0x68,0xa5,0x68,0x8d,0x28,0x47,0x94,
995
0x2f,0x2a,0x12,0x6d,0x16,0x6d,0x17,0xed,0x14,0x95,0x8b,0xf6,0x8a,0x6a,0x44,0x0d,
996
0xa2,0x77,0x44,0x07,0x45,0x47,0x44,0xc7,0x44,0x27,0x44,0xa7,0x44,0x1f,0x8a,0x3e,
997
0x16,0x9d,0x17,0x75,0x8b,0x2e,0x89,0xae,0x88,0xbe,0x12,0x7d,0x2b,0xba,0x2e,0xea,
998
0x13,0x19,0xdb,0x98,0xda,0x0c,0xb1,0xb1,0xb6,0x11,0xda,0xd8,0xd9,0x0c,0xb3,0x71,
999
0xb2,0x71,0xb1,0x71,0xb7,0xf1,0xb4,0xf1,0xb5,0x51,0xda,0xa8,0x6d,0x42,0x6d,0x22,
1000
0x6d,0xa2,0x6d,0xee,0xb5,0x79,0xd0,0x66,0x94,0xcd,0x13,0x36,0x4f,0xdb,0x3c,0x6f,
1001
0xf3,0x92,0xcd,0x58,0x9b,0x3e,0xdd,0xdd,0x17,0x76,0x87,0x30,0xd1,0xe6,0x3f,0x33,
1002
0x0a,0x5f,0x85,0x9e,0x29,0x82,0x69,0x36,0xb3,0x6c,0xfe,0xcc,0xdd,0xcd,0x7e,0x5e,
1003
0xb3,0x59,0xc0,0xb5,0xb1,0xc8,0xe6,0xbf,0xfb,0xa9,0x9c,0x64,0xf3,0x57,0xcf,0x8b,
1004
0x7d,0xba,0x65,0x36,0xcb,0x6d,0x56,0xdb,0xac,0xb3,0xc9,0xb5,0xd9,0x60,0xb3,0xc9,
1005
0x66,0xab,0xcd,0x0e,0x9b,0xdd,0x36,0x7b,0x6c,0xaa,0x6c,0xea,0x6c,0x9a,0x6c,0x0e,
1006
0xd8,0x1c,0xb6,0x79,0xcf,0xe6,0xb8,0xcd,0x49,0x9b,0x0f,0x6c,0x3e,0xb2,0x39,0x6b,
1007
0x73,0xc1,0xa6,0xc7,0xe6,0x73,0x9b,0x2f,0x6d,0xbe,0xb1,0xf9,0xde,0xe6,0x27,0x1b,
1008
0xb2,0x1d,0x64,0x6b,0x6e,0x6b,0x69,0x3b,0xd4,0xd6,0xc6,0xd6,0xc1,0x76,0x84,0xad,
1009
0xb3,0xad,0x9b,0xad,0xcc,0xd6,0xdb,0xd6,0xdf,0x36,0xc0,0x36,0xd8,0x36,0xdc,0x56,
1010
0x6b,0x1b,0x6b,0x7b,0xbf,0xed,0xc3,0xb6,0x8f,0xd9,0xfe,0xc3,0x96,0xe8,0x59,0xdb,
1011
0x17,0x6d,0x5f,0xb1,0x1d,0x6f,0xfb,0xaa,0xed,0x34,0xdb,0x59,0xb6,0xaf,0xd9,0xbe,
1012
0x61,0xfb,0x96,0x2d,0x63,0x9b,0x68,0xbb,0xc4,0x76,0x99,0xed,0x72,0xdb,0xd5,0xb6,
1013
0xeb,0x6c,0x73,0x6d,0x37,0xd8,0x6e,0xb2,0xdd,0x6a,0xbb,0xc3,0x76,0xb7,0xed,0x1e,
1014
0xdb,0x2a,0xdb,0x3a,0xdb,0x26,0xdb,0x03,0xb6,0x87,0x6d,0xdf,0xb3,0x3d,0x6e,0x7b,
1015
0xd2,0xf6,0x03,0xdb,0x8f,0x6c,0xcf,0xda,0x5e,0xb0,0xed,0xb1,0xfd,0xdc,0xf6,0x4b,
1016
0xdb,0x6f,0x6c,0xbf,0xb7,0xfd,0xc9,0x56,0xef,0x15,0x6b,0xcc,0x4c,0x64,0x37,0xc8,
1017
0xce,0xdc,0xce,0xd2,0x6e,0xa8,0x9d,0x8d,0x9d,0x93,0xc0,0xc1,0x6e,0x84,0x9d,0xb3,
1018
0x9d,0x9b,0x9d,0xef,0x9f,0x9e,0x7f,0x65,0x76,0xbe,0x76,0x01,0x76,0xa1,0x76,0x5a,
1019
0xbb,0x7b,0xed,0x1e,0xb6,0x7b,0xc2,0xee,0x59,0xbb,0x97,0xec,0xc6,0xdb,0x4d,0xb1,
1020
0x9b,0x65,0x37,0xdf,0xee,0x2d,0xbb,0x78,0xbb,0x25,0x76,0x19,0x76,0xab,0xed,0x72,
1021
0xec,0x36,0xd8,0x6d,0xb6,0xdb,0x61,0x57,0x6e,0x57,0x65,0xd7,0x60,0x77,0xc0,0xee,
1022
0x88,0xdd,0x71,0xbb,0x53,0x76,0x9f,0xd8,0xf5,0xe9,0x7a,0xec,0xae,0xd8,0x7d,0x63,
1023
0x77,0xdd,0x8e,0xec,0x4d,0xed,0x2d,0xed,0x85,0xf6,0x0e,0xf6,0x4e,0xf6,0x6e,0xf6,
1024
0x9e,0xf6,0xfe,0xf6,0x6a,0xfb,0x70,0xfb,0x68,0xfb,0xfb,0xed,0x47,0xd9,0xff,0xc3,
1025
0xfe,0x79,0xfb,0x57,0xec,0x27,0xda,0x4f,0xb3,0x9f,0x63,0xff,0x86,0xfd,0x22,0xfb,
1026
0x44,0xfb,0x34,0xfb,0xe5,0xf6,0x6b,0xec,0x73,0xed,0x8b,0xec,0xb7,0xda,0xef,0xb4,
1027
0xdf,0x63,0x5f,0x63,0xdf,0x64,0x7f,0xc0,0xde,0x4e,0x78,0xd8,0xfe,0x76,0xfb,0xde,
1028
0xb3,0x3f,0x6e,0xdf,0x61,0x7f,0xca,0xfe,0xb4,0xfd,0x47,0xf6,0x9f,0xd8,0x9f,0xb7,
1029
0xef,0xb2,0xef,0xb1,0xff,0xcc,0xfe,0x8a,0xfd,0x55,0xfb,0x6f,0xec,0xbf,0xb3,0xbf,
1030
0x6e,0xbf,0x0c,0x57,0x76,0x13,0xae,0x29,0x7b,0x15,0x3f,0xe2,0xae,0xdf,0xcd,0xab,
1031
0x77,0xc3,0xde,0xc8,0xc1,0xc4,0x61,0xb0,0x83,0x95,0x83,0xc0,0xc1,0xd6,0x41,0xec,
1032
0xe0,0xe8,0x30,0xd2,0x41,0xea,0x20,0x77,0xf0,0x71,0x50,0x38,0x04,0x3a,0x84,0x3b,
1033
0xc4,0x38,0xdc,0xf4,0xed,0x7d,0x0e,0x0f,0x39,0x3c,0xea,0x10,0x2a,0x78,0xd2,0x61,
1034
0x8a,0x40,0x89,0xb9,0xf6,0x25,0xcc,0xc2,0x9b,0x45,0x69,0x02,0x4f,0xe1,0x33,0x0e,
1035
0x2f,0x38,0xbc,0xec,0x30,0xce,0x61,0x92,0xc3,0x54,0x87,0x99,0x0e,0x73,0x1d,0x5e,
1036
0x77,0x78,0xd3,0xa1,0x48,0xb0,0xd8,0x21,0xc1,0x21,0xc5,0x61,0xa9,0x43,0xa6,0xc3,
1037
0x2a,0x87,0xb5,0x0e,0xeb,0x1d,0xf4,0xd7,0xa6,0xc0,0x61,0xa3,0xc3,0x16,0x87,0x12,
1038
0x87,0x5d,0x0e,0x15,0x0e,0xfb,0x1c,0x6a,0x1d,0x1a,0x1d,0x9a,0x1d,0x0e,0x39,0x1c,
1039
0x71,0x38,0xea,0x70,0xdc,0xa1,0xc3,0xe1,0x94,0xc3,0x69,0x87,0x8f,0x1c,0x3e,0x71,
1040
0x38,0xef,0xd0,0xe5,0xd0,0xe3,0xf0,0x99,0xc3,0x15,0x87,0xab,0x0e,0xdf,0x38,0xfc,
1041
0xe0,0xd0,0xe7,0xc0,0x13,0x9b,0x8b,0xad,0xc4,0x42,0xb1,0xbd,0x78,0x84,0x78,0xa4,
1042
0xd8,0x43,0xec,0x23,0x56,0x89,0xd5,0xe2,0x50,0x71,0x84,0x38,0x4a,0x7c,0x8f,0xf8,
1043
0x01,0xf1,0x23,0xe2,0xc7,0xc5,0x4f,0x89,0x9f,0x13,0x8f,0x16,0x8f,0x11,0x4f,0x10,
1044
0x4f,0x16,0x4f,0x17,0xcf,0x16,0xcf,0x13,0x2f,0x10,0xbf,0x2d,0x8e,0x13,0x27,0x89,
1045
0x53,0xc5,0xe9,0xe2,0x15,0xe2,0x2c,0x71,0xb6,0x38,0x4f,0x5c,0x28,0x2e,0x16,0x6f,
1046
0x13,0x97,0x8a,0xcb,0xc4,0x95,0xe2,0x6a,0x71,0xbd,0x78,0xbf,0xb8,0x45,0xdc,0x2a,
1047
0x3e,0x2a,0x6e,0x17,0x77,0x8a,0x4f,0x8b,0xcf,0x88,0xcf,0x89,0xbb,0xc4,0xbd,0xe2,
1048
0xcb,0xe2,0xab,0xe2,0x6b,0xe2,0x1f,0xc4,0x37,0xc4,0x83,0x86,0x09,0x86,0x39,0x0d,
1049
0xf3,0x1a,0x16,0x38,0x2c,0x7a,0xd8,0xc3,0xc3,0x9e,0x1e,0x36,0x71,0xd8,0xdc,0x61,
1050
0x6f,0x0f,0x4b,0x19,0xb6,0x62,0x58,0xfe,0xb0,0x92,0x61,0x95,0xc3,0x1a,0x87,0x1d,
1051
0x1c,0x76,0x7c,0xd8,0x99,0x61,0x97,0x86,0x5d,0x1d,0x66,0x34,0xdc,0x66,0xb8,0xdb,
1052
0x70,0xdf,0xe1,0x91,0xc3,0x47,0x0d,0x7f,0x61,0xf8,0x84,0xe1,0x33,0x87,0x2f,0x18,
1053
0x9e,0x3c,0x7c,0xcd,0xf0,0x8d,0xc3,0x4b,0x87,0xef,0x1b,0xbe,0x7f,0xf8,0xe1,0xe1,
1054
0x6d,0xc3,0x4f,0x0d,0x3f,0x33,0xfc,0xe2,0xf0,0xab,0xc3,0x8d,0x46,0x58,0x8c,0x70,
1055
0x18,0x21,0x1b,0xa1,0x1c,0x11,0x32,0x42,0x3b,0xe2,0xb1,0x11,0xa3,0x47,0x4c,0x1f,
1056
0xf1,0xfa,0x88,0x94,0x11,0x19,0x23,0xd6,0x8d,0x28,0x1a,0xb1,0x63,0xc4,0xde,0x11,
1057
0x4d,0x23,0x8e,0x8e,0x78,0x7f,0xc4,0xc7,0x23,0x7a,0x46,0x7c,0x35,0xe2,0xa7,0x11,
1058
0x83,0x1d,0x45,0x8e,0x8e,0x8e,0x1e,0x8e,0x41,0x8e,0xb1,0x8e,0x0f,0x39,0xbe,0xe0,
1059
0x38,0xd6,0x71,0xa6,0xe3,0x5b,0x8e,0xc9,0x8e,0xcb,0x1d,0x73,0x1c,0xb7,0x38,0xee,
1060
0x74,0xac,0x72,0x6c,0x71,0x7c,0xcf,0xf1,0x23,0xc7,0x6e,0xc7,0xcf,0x1c,0xbf,0x74,
1061
0xbc,0xe6,0x78,0xdd,0x51,0xe7,0x38,0xc8,0x69,0xb0,0x93,0xb5,0x93,0xc8,0xc9,0xc1,
1062
0xc9,0xc9,0xc9,0xcd,0xc9,0xd3,0xc9,0xdf,0x49,0xed,0x14,0xee,0x14,0xed,0x74,0xbf,
1063
0xd3,0x28,0xa7,0x7f,0x38,0x3d,0xef,0xf4,0x8a,0xd3,0x44,0xa7,0x69,0x4e,0x73,0x9c,
1064
0xe6,0x3b,0x2d,0x70,0x7a,0xcb,0x89,0x71,0x4a,0x70,0x4a,0x76,0x4a,0x75,0x4a,0x77,
1065
0x5a,0xe1,0xb4,0xda,0x69,0xbd,0x53,0x91,0xd3,0x36,0xa7,0xdd,0x4e,0xf5,0x4e,0x4d,
1066
0x4e,0xcd,0x4e,0x87,0x9c,0x8e,0x38,0x1d,0x75,0x3a,0xee,0xd4,0xe1,0x74,0xca,0xe9,
1067
0x43,0xa7,0x4f,0x9c,0xce,0x3b,0x75,0x39,0xf5,0x3a,0x5d,0x76,0xfa,0xd2,0xe9,0x6b,
1068
0xa7,0x6f,0x9d,0xae,0x3b,0xf5,0x39,0x19,0x4b,0x4c,0x25,0x43,0x24,0x56,0x92,0xa1,
1069
0x12,0x91,0xc4,0x4e,0x22,0x96,0x38,0x4a,0x9c,0x25,0xae,0x12,0x77,0x89,0xa7,0xc4,
1070
0x57,0xa2,0x90,0x04,0x4a,0x42,0x24,0x11,0x12,0xad,0x24,0x56,0xf2,0xa0,0xa4,0xde,
1071
0xe9,0x71,0xc9,0x53,0x92,0xe7,0x24,0xa3,0x25,0x63,0x24,0x93,0x25,0x73,0x24,0xf3,
1072
0x24,0x6f,0x48,0xde,0x92,0x2c,0x96,0xc4,0x4b,0x92,0x24,0xa9,0x92,0x65,0x20,0x53,
1073
0xb2,0x52,0x92,0x25,0xc9,0x96,0xe4,0x82,0x02,0xc9,0x46,0x49,0x9f,0x6e,0x8b,0x64,
1074
0xbb,0xa4,0x54,0xb2,0x1b,0xa9,0x7d,0x92,0x1a,0x49,0xbd,0xa4,0x49,0xd2,0x2c,0x39,
1075
0x88,0xf6,0x5b,0x25,0xef,0x49,0xda,0x24,0x27,0x24,0xa7,0x24,0xc7,0x9d,0x4e,0x4b,
1076
0xce,0x48,0xce,0xa1,0xc4,0x05,0x49,0x8f,0xe4,0x33,0xc9,0x15,0xc9,0x55,0xc9,0x37,
1077
0x92,0xeb,0x12,0x72,0x36,0x71,0x1e,0xe2,0xcc,0x77,0xb6,0x71,0x16,0x3b,0x3b,0x39,
1078
0xbb,0x3a,0xcb,0x9c,0x7d,0x9c,0x55,0xce,0x21,0xce,0x1a,0xe7,0x7b,0x9c,0x1f,0x72,
1079
0x7e,0xdc,0xf9,0x19,0xe7,0xd1,0xce,0xe3,0x9c,0x27,0x3b,0xcf,0x74,0x9e,0xe7,0xfc,
1080
0xa6,0x73,0x9c,0x73,0x8a,0x73,0xba,0xf3,0x2a,0xe7,0x6c,0xe7,0x02,0xe7,0x62,0xe7,
1081
0x12,0xe7,0x32,0xe7,0x4a,0x67,0x9d,0xae,0x1a,0xd4,0x83,0xfd,0xa0,0x05,0x74,0x98,
1082
0xe9,0x74,0xad,0x88,0x8f,0x82,0x76,0xd0,0x09,0x4e,0x83,0x33,0xe0,0x1c,0xe8,0x02,
1083
0xbd,0xe0,0x32,0xb8,0x0a,0xae,0x81,0x1f,0xc0,0x0d,0x60,0x34,0x52,0xa7,0x33,0x01,
1084
0x83,0x47,0xfe,0xbe,0xf9,0xc7,0x0a,0xe5,0x04,0xc0,0x16,0x88,0x81,0x23,0x18,0x09,
1085
0xa4,0x40,0x0e,0x7c,0x80,0x02,0x04,0x82,0x10,0x10,0x01,0xa2,0x80,0xd3,0x20,0xb7,
1086
0x41,0xff,0x5b,0x9e,0x62,0xf7,0xc0,0x9e,0x07,0xc0,0x23,0xe0,0x71,0xf0,0x14,0x78,
1087
0x0e,0x8c,0x36,0xf8,0x60,0x0c,0xe2,0x09,0x60,0x32,0x98,0x0e,0x66,0x83,0x79,0x60,
1088
0x01,0x78,0x1b,0xc4,0x81,0x24,0x90,0x0a,0xd2,0xc1,0x0a,0x90,0x05,0xb2,0x41,0x1e,
1089
0x28,0x04,0xc5,0x60,0x1b,0x28,0x05,0x65,0xa0,0x12,0x54,0x83,0x7a,0xb0,0x1f,0xb4,
1090
0x80,0x56,0x70,0x14,0xb4,0x83,0x4e,0x70,0xda,0xc0,0xcf,0x3f,0x67,0x90,0x73,0x0e,
1091
0x74,0x8d,0xec,0x45,0x78,0x19,0x5c,0x05,0xd7,0xc0,0x0f,0x03,0x65,0x6f,0x20,0x55,
1092
0xc5,0x7d,0x37,0x66,0xe4,0x82,0xeb,0xe9,0x62,0xf8,0x4e,0x1b,0xb1,0x15,0x10,0x00,
1093
0x5b,0x20,0x06,0x8e,0x60,0x24,0x90,0x02,0x39,0xf0,0x01,0xfb,0x8c,0xb3,0xcd,0x2b,
1094
0xcd,0x15,0x2e,0xb5,0x68,0x21,0xc0,0x25,0xc8,0xe5,0x1d,0xf3,0x50,0x97,0x48,0xe4,
1095
0x47,0x83,0x7b,0xc1,0x83,0x60,0x14,0x78,0x02,0x3c,0x0d,0x9e,0x07,0x2f,0xb9,0x7c,
1096
0x6c,0x3e,0xd6,0x65,0x22,0x52,0x53,0xc0,0x0c,0x97,0xd9,0x08,0xe7,0x81,0x05,0xe0,
1097
0x6d,0x10,0x07,0x92,0x40,0x2a,0x48,0x07,0x2b,0x5c,0x56,0xbb,0xf4,0xaf,0x1c,0xd6,
1098
0xba,0xfc,0xab,0x15,0x9e,0x94,0x4c,0xc8,0x82,0x46,0x52,0x0e,0xd7,0x8b,0x6b,0x14,
1099
0x6a,0x74,0x37,0xae,0xf9,0x23,0x23,0xf3,0x5d,0x86,0x0c,0x2d,0x72,0xf9,0xe5,0x99,
1100
0xcd,0x5c,0xde,0x36,0x97,0x52,0xce,0xaa,0x32,0x97,0x4a,0x97,0x6a,0x97,0x7a,0x97,
1101
0xfd,0x2e,0x2d,0x2e,0xad,0x2e,0x47,0x5d,0xda,0x5d,0x3a,0x5d,0x4e,0xbb,0x9c,0x71,
1102
0x39,0xe7,0xd2,0xe5,0xd2,0xeb,0x72,0xd9,0xe5,0xaa,0xcb,0x35,0x97,0x1f,0x5c,0x6e,
1103
0xb8,0x18,0xb9,0x9a,0xb8,0x0e,0x76,0xb5,0x72,0x15,0xb8,0xda,0xba,0x8a,0x5d,0x1d,
1104
0x5d,0x47,0xba,0x4a,0x5d,0xe5,0xae,0x3e,0xae,0x0a,0xd7,0x40,0xd7,0x10,0xd7,0x08,
1105
0xd7,0x28,0xd7,0x7b,0x5c,0x1f,0x70,0x7d,0xc4,0xf5,0x71,0xd7,0xa7,0x5c,0x9f,0x73,
1106
0x1d,0xed,0x3a,0xc6,0x75,0x82,0xeb,0x64,0xd7,0xe9,0xae,0xb3,0x5d,0xe7,0xb9,0x2e,
1107
0x70,0x7d,0xdb,0x35,0xce,0x35,0xc9,0x35,0xd5,0x35,0xdd,0x75,0x85,0x6b,0x96,0x6b,
1108
0xb6,0x6b,0x9e,0x6b,0xa1,0x6b,0xb1,0xeb,0x36,0xd7,0x52,0xd7,0x32,0xd7,0x4a,0xd7,
1109
0x6a,0xd7,0x7a,0xd7,0xfd,0xae,0x2d,0xae,0xad,0xae,0x47,0x5d,0xdb,0x5d,0x3b,0x5d,
1110
0x4f,0xbb,0x9e,0x71,0x3d,0xe7,0xda,0xe5,0xda,0xeb,0x7a,0xd9,0xf5,0xaa,0xeb,0x35,
1111
0xd7,0x64,0xd1,0x0f,0xae,0x37,0x5c,0x8d,0xdc,0x4c,0xdc,0x5e,0xc2,0x3a,0x7b,0xb0,
1112
0xdb,0x66,0x91,0x95,0x9b,0xc0,0xcd,0xd6,0x4d,0xec,0xe6,0xe8,0x36,0xd2,0x4d,0xea,
1113
0x26,0x77,0xf3,0x71,0x53,0xb8,0x05,0xba,0x85,0xb8,0x45,0xb8,0x45,0xb9,0xdd,0xe3,
1114
0xf6,0x80,0xdb,0x23,0x6e,0x8f,0xbb,0x3d,0xe5,0xf6,0x9c,0xdb,0x68,0xb7,0x31,0x6e,
1115
0x13,0xdc,0x26,0xbb,0x4d,0x77,0x9b,0xed,0x36,0xcf,0x6d,0x81,0xdb,0xdb,0x6e,0x71,
1116
0x6e,0x49,0x6e,0xa9,0x6e,0xe9,0x6e,0x2b,0xdc,0xb2,0xdc,0xb2,0xdd,0xf2,0xdc,0x0a,
1117
0xdd,0x8a,0xdd,0xb6,0xb9,0x95,0xba,0xf5,0x09,0xcb,0xdc,0x2a,0xdd,0xaa,0xdd,0xea,
1118
0xdd,0xf6,0xbb,0xb5,0xb8,0xb5,0xba,0x1d,0x75,0x6b,0x77,0xeb,0x74,0x3b,0xed,0xe6,
1119
0x62,0x73,0xc6,0xed,0x9c,0x5b,0x97,0x5b,0xaf,0xdb,0x65,0xb7,0xab,0x6e,0xd7,0xdc,
1120
0x7e,0x70,0xbb,0xe1,0x66,0x24,0x35,0x91,0x0e,0x96,0x5a,0x49,0x05,0x52,0x5b,0xa9,
1121
0x58,0xea,0x28,0x1d,0x29,0x95,0x4a,0xe5,0x52,0x1f,0xa9,0x42,0x1a,0x28,0x0d,0x91,
1122
0x46,0x48,0xa3,0xa4,0xf7,0x48,0x15,0x6e,0x0f,0x48,0x1f,0x91,0x3e,0x2e,0x7d,0x4a,
1123
0xfa,0x9c,0x74,0xb4,0x74,0x8c,0x74,0x82,0x74,0xb2,0x74,0xba,0x74,0xb6,0x74,0x9e,
1124
0x74,0x81,0xf4,0x6d,0x69,0x9c,0x34,0x49,0x9a,0x2a,0x4d,0x97,0xae,0x90,0x66,0x49,
1125
0x33,0x44,0xd9,0xd2,0x3c,0x69,0xa1,0xb4,0x58,0xba,0x4d,0x5a,0x2a,0x2d,0x93,0x56,
1126
0x4a,0xab,0xa5,0xf5,0xd2,0xfd,0xd2,0x16,0x69,0xab,0xf4,0xa8,0xb4,0x5d,0x5a,0x24,
1127
0xe8,0x94,0x9e,0x96,0x9e,0x91,0x9e,0x93,0x76,0x49,0x7b,0xa5,0x97,0xa5,0x57,0xa5,
1128
0x4f,0x0b,0xae,0x49,0x7f,0x90,0xde,0x90,0x1a,0xb9,0x9b,0xb8,0x0f,0x76,0xb7,0x72,
1129
0x17,0xb8,0xdb,0xba,0x8b,0xdd,0x1d,0xdd,0x47,0xba,0x4b,0xdd,0xe5,0xee,0x3e,0xee,
1130
0x0a,0xf7,0x40,0xf7,0x10,0xf7,0x08,0xf7,0x28,0xf7,0x7b,0xdc,0x1f,0x70,0x5f,0x21,
1131
0x7d,0xc4,0xfd,0x71,0xf7,0xa7,0xdc,0x9f,0x73,0x1f,0xed,0x3e,0xc6,0x7d,0x82,0xfb,
1132
0x64,0xf7,0xc7,0xa5,0xd3,0xdd,0x67,0xbb,0xcf,0x73,0x5f,0xe0,0xfe,0xb6,0x7b,0x9c,
1133
0x7b,0x92,0x7b,0xaa,0x7b,0xba,0xfb,0x0a,0xf7,0x2c,0xf7,0x6c,0xf7,0x3c,0xf7,0x42,
1134
0xf7,0x62,0xf7,0x6d,0xee,0xa5,0xee,0x65,0xee,0x95,0xee,0xd5,0xee,0x0a,0xb7,0x7a,
1135
0xf7,0xfd,0xee,0x2d,0xee,0xad,0xee,0xcf,0xdb,0x1c,0x75,0x6f,0x77,0xef,0x74,0x3f,
1136
0xed,0x7e,0xc6,0xfd,0x9c,0x7b,0x97,0x7b,0xaf,0xfb,0x65,0xf7,0xab,0xee,0xd7,0xdc,
1137
0x7f,0x70,0x7f,0xc8,0xe1,0x86,0xbb,0x91,0x87,0x89,0xc7,0x60,0x0f,0x2b,0x0f,0x81,
1138
0x87,0xad,0x87,0xd8,0xc3,0xd1,0xe3,0x39,0xe9,0x48,0x0f,0xa9,0x87,0xdc,0xc3,0xc7,
1139
0x43,0xe1,0x11,0xe8,0x11,0xe2,0x11,0xe1,0x11,0xe5,0x71,0x8f,0xc7,0x03,0x1e,0x8f,
1140
0x78,0x3c,0xee,0x51,0x24,0x7a,0xca,0xe3,0x39,0x8f,0xd1,0x1e,0x63,0x3c,0x26,0x78,
1141
0x4c,0xf6,0x98,0xee,0x31,0xdb,0x63,0x9e,0xc7,0x02,0x8f,0xb7,0x3d,0xe2,0x3c,0x92,
1142
0x3c,0x3e,0x16,0xa6,0x7a,0xa4,0x7b,0xac,0xf0,0xc8,0xf2,0xc8,0xf6,0xc8,0xf3,0x28,
1143
0xf4,0x28,0xf6,0xd8,0xe6,0x51,0xea,0x51,0xe6,0x51,0xe9,0x51,0xed,0x51,0xef,0xb1,
1144
0xdf,0xa3,0xc5,0xe3,0x41,0x51,0xab,0xc7,0xd3,0xa2,0xa3,0x1e,0xed,0x1e,0x9d,0x1e,
1145
0xec,0x38,0x3e,0x8d,0xf0,0x0c,0x97,0x3a,0xe7,0xd1,0xe5,0xd1,0xeb,0x71,0xd9,0xe3,
1146
0xaa,0xc7,0x35,0x8f,0x1f,0x3c,0x6e,0x78,0x18,0xc9,0xae,0x0b,0x31,0x37,0xc8,0x30,
1147
0x2f,0xc8,0xb8,0x99,0x5c,0x26,0x90,0xe9,0xef,0x00,0x5b,0x99,0x58,0xe6,0x28,0x1b,
1148
0x29,0x93,0xca,0xe4,0x32,0x1f,0x99,0x42,0x16,0x28,0x0b,0x91,0x45,0xc8,0xa2,0x64,
1149
0xf7,0xc8,0x1e,0x90,0x3d,0x22,0x7b,0x5c,0xf6,0x94,0xec,0x39,0x59,0x83,0x60,0xb4,
1150
0x6c,0x8c,0x6c,0x82,0x6c,0xb2,0x6c,0xba,0x6c,0xb6,0x6c,0x9e,0x6c,0x81,0xec,0x6d,
1151
0x59,0x9c,0x2c,0x49,0x96,0x2a,0x4b,0x97,0xad,0x90,0x65,0xc9,0x5e,0x76,0xc8,0x96,
1152
0xe5,0xc9,0x0a,0x65,0xc5,0xb2,0x99,0x0e,0xdb,0x64,0xa5,0xb2,0x32,0x59,0xa5,0xac,
1153
0x5a,0x36,0xd2,0xbd,0x5e,0xb6,0x5f,0xd6,0x22,0x6b,0x95,0x1d,0x95,0xb5,0x43,0x3a,
1154
0x65,0xa7,0x65,0x67,0x64,0xe7,0x64,0x5d,0xb2,0x5e,0xd9,0x65,0xd9,0x55,0x99,0x95,
1155
0xec,0x9a,0xec,0x07,0xd9,0x0d,0x99,0x91,0xdc,0x44,0x3e,0x44,0xce,0xed,0xef,0xe5,
1156
0x42,0xb9,0x9d,0x7c,0x98,0xdc,0x49,0xee,0x22,0x77,0x97,0x7b,0xca,0xef,0x91,0xf9,
1157
0xca,0x95,0x72,0xb5,0xfc,0xb4,0x47,0xa8,0x3c,0x52,0x1e,0x2d,0xbf,0x57,0xfe,0xa0,
1158
0x7c,0x94,0xfc,0x09,0xf9,0xd3,0xf2,0xe7,0xe5,0x2f,0xc9,0xc7,0xca,0x27,0xca,0x27,
1159
0xc8,0xa6,0xc8,0x27,0xcb,0x66,0xc8,0xe7,0xc8,0xe7,0xcb,0x17,0xca,0x17,0xc9,0xcf,
1160
0x78,0x24,0xb9,0xc5,0xcb,0x93,0xe5,0xd1,0xc2,0x2c,0xe9,0x39,0xf7,0x34,0x79,0x86,
1161
0x3c,0x49,0xb6,0x52,0x9e,0x2a,0x5b,0x23,0xcf,0x91,0xe7,0xcb,0xbb,0x3c,0x8a,0xe4,
1162
0x9b,0xe5,0xdb,0xe5,0x3b,0xe5,0xe5,0xf2,0x5e,0x8f,0xbd,0xf2,0x1a,0x79,0x83,0xfc,
1163
0x1d,0xf9,0x41,0xf9,0x11,0x79,0xb5,0xec,0x98,0xfc,0x84,0x7c,0xa4,0xfb,0x29,0x79,
1164
0xab,0xec,0x43,0xf9,0xc7,0xf2,0xf3,0xf2,0x6e,0xf9,0x25,0xf9,0x19,0xd9,0x15,0xf9,
1165
0x60,0xd9,0x57,0xf2,0x73,0xb2,0x07,0xa4,0xdf,0xca,0xbb,0x64,0xd7,0xe5,0x97,0x65,
1166
0x7d,0x72,0x63,0x4f,0x53,0xcf,0x21,0x9e,0xd6,0x9e,0xd7,0x64,0x37,0x3c,0x84,0x9e,
1167
0x3f,0xc8,0xec,0x3c,0x6f,0xc8,0x86,0x79,0xbe,0x64,0xe3,0xe4,0xe9,0xea,0x29,0xf3,
1168
0xf4,0xf1,0x54,0x78,0x06,0x7a,0x86,0x78,0x46,0x7a,0xc6,0x78,0xde,0xef,0xf9,0xb0,
1169
0xe7,0xdd,0xdc,0xff,0x3e,0xe6,0xf9,0xa4,0xe7,0xd3,0x9e,0xcf,0x79,0x8e,0xf6,0x1c,
1170
0x03,0xf9,0xb5,0x52,0xe3,0x3d,0x27,0x7b,0xce,0xf0,0x9c,0xeb,0xf9,0xc6,0x2d,0x25,
1171
0xde,0xf6,0xd4,0xe9,0xe2,0x3d,0x53,0x3c,0xdf,0xb2,0x4a,0xb2,0x4a,0xf3,0x4c,0xf7,
1172
0x5c,0xee,0xb9,0xca,0x73,0x8d,0x67,0xb6,0x67,0xac,0x55,0xae,0x67,0xa1,0xe7,0x66,
1173
0xcf,0x52,0xcf,0x3d,0x9e,0xd5,0x9e,0x0d,0x9e,0xcd,0x9e,0x87,0x3d,0x8f,0x7a,0x9e,
1174
0xf0,0x7c,0xdf,0xf3,0x23,0xd4,0x3e,0xe7,0xd9,0xed,0xf9,0x99,0xe7,0x97,0x9e,0xd7,
1175
0x90,0xbe,0x0e,0x74,0x9e,0x83,0xbc,0xfa,0x74,0x83,0xbd,0xac,0x11,0x8a,0xbc,0x1c,
1176
0xbc,0x1c,0xbd,0x5c,0xbc,0x3c,0xbc,0xbc,0xbd,0x14,0x5e,0x6a,0xaf,0x30,0x2f,0xad,
1177
0xd7,0x3d,0x90,0xfb,0x0d,0xf2,0x90,0x41,0x46,0x19,0xe4,0x71,0x83,0xfc,0xc3,0x20,
1178
0xcf,0x18,0xe4,0x79,0x83,0x8c,0x36,0xc8,0x2b,0x06,0x19,0x67,0x90,0x89,0x06,0x99,
1179
0x6c,0x90,0x69,0x90,0x99,0x90,0x39,0x90,0x79,0x90,0x37,0x20,0x6f,0x42,0x16,0x19,
1180
0x24,0xce,0x20,0x89,0x06,0x49,0x31,0x48,0x1a,0x24,0xdd,0x20,0xcb,0x21,0xab,0x0c,
1181
0xb2,0xc6,0x20,0xd9,0x90,0x5c,0xc8,0x9f,0x7f,0xda,0x14,0x78,0xe9,0xa5,0x08,0x52,
1182
0x0c,0xd9,0x0a,0x39,0x63,0x52,0xe2,0x55,0xe2,0xb5,0x13,0x52,0x06,0xd9,0x63,0x90,
1183
0x7d,0x90,0x1a,0x48,0x23,0xe4,0x00,0xa4,0x15,0x72,0x0c,0xd2,0x01,0xf9,0x80,0x93,
1184
0x33,0x9c,0x9c,0x37,0x48,0x97,0xd7,0x25,0xaf,0x2f,0x70,0xfc,0x8d,0xd7,0x0f,0x5e,
1185
0x7d,0x5e,0x3c,0x6f,0x73,0x6f,0x2b,0x6f,0xa1,0xb7,0xbd,0xf7,0x08,0xef,0x91,0xde,
1186
0xee,0xde,0x5e,0xde,0xfe,0xde,0x81,0xde,0xa1,0xde,0x1a,0xef,0x58,0xef,0x07,0xbc,
1187
0x47,0x79,0x3f,0xe9,0xfd,0xac,0xf7,0x68,0xef,0xb1,0xde,0x93,0xbc,0xa7,0x79,0xcf,
1188
0xf6,0x9e,0xef,0xfd,0xa6,0x37,0xe3,0x9d,0xe4,0x9d,0xe6,0x9d,0xe9,0xbd,0xda,0x3b,
1189
0xdb,0x3b,0xdf,0x7b,0xa3,0xf7,0x56,0xef,0x52,0xef,0x72,0xef,0x7d,0xde,0x75,0xde,
1190
0xfb,0xbd,0x0f,0x7a,0xbf,0xeb,0x7d,0xdc,0xbb,0xd3,0xfb,0x43,0xef,0x4f,0xbc,0x2f,
1191
0x78,0xf7,0x7a,0x5f,0xf1,0xfe,0xda,0xfb,0x7b,0xef,0x1b,0xde,0xc6,0x3e,0x66,0x3e,
1192
0x96,0x3e,0x02,0x1f,0x3b,0x9f,0xe1,0x3e,0xce,0x3e,0x52,0x1f,0x4f,0x1f,0x3f,0x9f,
1193
0x00,0x9f,0x10,0x9f,0x48,0x9f,0x18,0x9f,0xfb,0x7d,0x1e,0xf1,0x79,0xc2,0xe7,0x19,
1194
0x9f,0x17,0x7d,0xc6,0xf8,0x4c,0xf4,0x99,0xea,0x33,0xcb,0x67,0x9e,0xcf,0x42,0x9f,
1195
0xc5,0x3e,0x89,0x3e,0xa9,0x3e,0x19,0x3e,0xab,0x7c,0xd6,0xf9,0xe4,0xf9,0x14,0xf9,
1196
0x6c,0xf1,0xd9,0xe1,0x53,0xe6,0xb3,0xd7,0xa7,0xce,0xe7,0x1d,0x9f,0xc3,0x3e,0xc7,
1197
0x7c,0x4e,0xfa,0x7c,0xe8,0xf3,0x89,0xcf,0x17,0x5e,0x17,0x7c,0xd8,0x9e,0xf4,0xfa,
1198
0x5c,0xf1,0x31,0xf7,0xfe,0xda,0x87,0xed,0xc9,0xf7,0x3e,0x37,0x7c,0xdc,0xbd,0x8d,
1199
0x7d,0xd9,0x9e,0x98,0xf9,0x5a,0xfa,0x86,0x7a,0x0b,0x7c,0xd9,0xde,0xb0,0x56,0xe9,
1200
0x2d,0xea,0xb7,0x45,0x6f,0x85,0x9d,0xef,0xfd,0x3e,0xc3,0x7d,0x9d,0x7d,0x27,0xfa,
1201
0x48,0x7d,0x59,0xed,0x65,0x3e,0x9e,0xbe,0x7e,0xbe,0xeb,0x7c,0x02,0x7c,0x59,0xbd,
1202
0xac,0xb7,0x42,0x7c,0xbf,0xf0,0x8a,0xf4,0xed,0xf7,0x56,0x8c,0x6f,0xbf,0xaf,0xee,
1203
0x47,0xdb,0x37,0x7d,0x74,0xab,0x87,0x1e,0xf1,0xbd,0xd5,0x47,0xbf,0xf4,0x10,0xeb,
1204
0x9d,0x9b,0x7e,0xe9,0xf7,0xc9,0x13,0xbe,0xfd,0x1e,0xe9,0xf7,0xc6,0x33,0xbe,0xac,
1205
0x2f,0x5e,0xf4,0xed,0xf7,0xc4,0x18,0xce,0x12,0xd6,0x06,0xbd,0xf6,0x89,0xbe,0x6f,
1206
0x7a,0x4f,0xf5,0x9d,0xe5,0x3b,0xcf,0x97,0x6d,0xc7,0x93,0xab,0xc1,0x96,0x5a,0xe8,
1207
0x1b,0xe7,0xbb,0xc4,0x37,0xd3,0x77,0xb5,0x6f,0xb6,0x6f,0xbe,0xef,0x46,0xdf,0xad,
1208
0xbe,0xa5,0xbe,0xe5,0xbe,0xfb,0x7c,0xeb,0x7c,0xf7,0xfb,0x1e,0xf4,0x7d,0xd7,0xf7,
1209
0xb8,0x6f,0xa7,0xef,0x87,0xbe,0x9f,0xf8,0x5e,0xf0,0xed,0xf5,0xbd,0xe2,0xfb,0xb5,
1210
0xef,0xf7,0xbe,0x37,0xd0,0x8a,0xb1,0x9f,0x99,0x9f,0xa5,0x9f,0xc0,0xef,0x8f,0xd6,
1211
0xeb,0x3f,0x9e,0x0a,0x7b,0x36,0x1a,0xbc,0xa1,0xcf,0x63,0x47,0x89,0x9d,0x9f,0x9d,
1212
0xdf,0xef,0x19,0xf9,0xc3,0xfd,0x5c,0x20,0x72,0x3f,0x7f,0xbf,0x20,0xbf,0x48,0xbf,
1213
0x7b,0xfc,0x1e,0x86,0x3c,0xe9,0xf7,0xbc,0xdf,0x18,0xbf,0x57,0xfd,0x66,0xfa,0xcd,
1214
0x87,0xbc,0xed,0x97,0x08,0x59,0x0a,0x59,0xe9,0x97,0x0d,0xd9,0xe0,0xb7,0x05,0xb2,
1215
0x13,0x52,0xe9,0x57,0x07,0x69,0x86,0x1c,0xf1,0x6b,0xf7,0xfb,0xc0,0xef,0x13,0x48,
1216
0xb7,0xdf,0x65,0xbf,0x6f,0xfc,0x7e,0xf4,0x33,0xf6,0x37,0xf6,0x1f,0xec,0x3f,0xd4,
1217
0xdf,0xde,0xdf,0xc9,0x5f,0xea,0x8f,0xc1,0xe1,0xaf,0x82,0x84,0x42,0xa2,0xfc,0xef,
1218
0xf7,0x7f,0xd4,0xff,0x69,0xff,0xd1,0xfe,0xe3,0xfd,0xa7,0xfa,0xb3,0x36,0xcc,0xf1,
1219
0x5f,0xe0,0xcf,0xf8,0xa7,0xf8,0x67,0xf8,0x67,0x41,0x72,0xfd,0x37,0xfa,0x6f,0xf7,
1220
0x2f,0x83,0x54,0xf9,0x37,0xfa,0x1f,0xf4,0x3f,0xea,0x7f,0xd2,0xff,0x9f,0xfe,0xe7,
1221
0xfd,0x7b,0xfd,0xbf,0xf4,0xff,0xce,0xbf,0xcf,0xdf,0x44,0x61,0xa9,0x10,0x29,0x86,
1222
0x29,0x46,0x2a,0x64,0x0a,0x3f,0x85,0x5a,0x11,0xa1,0x88,0x55,0x3c,0xa4,0x18,0x0c,
1223
0x4d,0x4f,0x28,0x9e,0x53,0xbc,0xa2,0x98,0xa4,0x98,0xa1,0x98,0x07,0x5e,0x51,0xbc,
1224
0xa5,0x48,0x50,0xa4,0x29,0x56,0x28,0xd6,0xe1,0xf8,0x03,0x58,0x5f,0xa0,0xd8,0xac,
1225
0xf8,0xe3,0xdf,0x84,0xde,0x59,0x4a,0x15,0x7b,0x14,0xb5,0x8a,0x03,0x8a,0xa3,0x8a,
1226
0x53,0x8a,0x4f,0x14,0x3d,0x8a,0xab,0x8a,0xeb,0x0a,0x23,0xa5,0xab,0x52,0xa5,0xbc,
1227
0xfd,0x37,0xfd,0xee,0xfc,0x09,0x57,0x46,0x2a,0xfb,0x74,0xd1,0x4a,0x9d,0x71,0xac,
1228
0xf2,0x5e,0xe5,0xfd,0xca,0x87,0x95,0xff,0xde,0x37,0x08,0x78,0xc2,0x28,0xff,0xa1,
1229
0x7c,0x16,0xc2,0xfe,0x3e,0xc3,0xf3,0xca,0x17,0x95,0x2f,0x29,0xc7,0x2a,0x27,0x2a,
1230
0xa7,0x28,0x67,0x28,0xe7,0x28,0xd9,0xef,0x8a,0xe7,0x2b,0x17,0x2a,0x17,0x29,0xe3,
1231
0x39,0x7b,0x92,0x95,0x4b,0x94,0x23,0xac,0xf4,0xf2,0x2c,0x57,0x4b,0xaf,0x1f,0x7a,
1232
0x8c,0xa3,0xa1,0x3f,0x56,0xf9,0xd8,0xcf,0xda,0x49,0x53,0x2e,0x53,0x66,0x28,0x63,
1233
0xad,0x96,0x2b,0x57,0x2a,0x57,0x2b,0x1f,0xb4,0xea,0xd3,0xad,0x51,0xae,0x53,0xe6,
1234
0x28,0x73,0x07,0xac,0xcc,0x57,0x16,0x29,0xb7,0xa0,0xed,0x12,0xe4,0xec,0x52,0x56,
1235
0x28,0xab,0x94,0x75,0xca,0xfd,0xca,0x16,0xe5,0x11,0xe5,0x31,0x65,0x87,0xf2,0x7d,
1236
0xe5,0x47,0xca,0x4f,0x20,0xe7,0x21,0x5d,0x90,0x1e,0xc8,0x67,0x06,0xb9,0x02,0xb9,
1237
0x6a,0x90,0x6f,0x20,0xdf,0x19,0xe4,0xba,0x41,0x6e,0x18,0x84,0x54,0x7a,0xe1,0x19,
1238
0xc4,0x14,0x32,0x18,0x62,0x09,0xe1,0x43,0x84,0x06,0xb1,0x35,0x88,0x83,0x41,0x86,
1239
0x1b,0xc4,0xc9,0x20,0x23,0x0d,0xe2,0x66,0x10,0x0f,0x83,0x78,0x1a,0xc4,0xc7,0x20,
1240
0xfe,0x06,0xe9,0xff,0xa8,0x0d,0x12,0x62,0x90,0x70,0x83,0x68,0x20,0xec,0xd3,0x20,
1241
0x5a,0xa5,0x97,0x7b,0x20,0x0f,0x42,0x1e,0x85,0xfc,0x03,0xa2,0xff,0x4d,0x95,0x3e,
1242
0x5d,0xac,0xf2,0x39,0x55,0x1a,0xe7,0xb5,0x65,0xca,0x17,0x54,0xac,0x77,0x59,0x8f,
1243
0x86,0x2b,0x97,0x2b,0x27,0xda,0x8c,0x56,0xdd,0xe9,0xf7,0x53,0xd8,0xd1,0xb0,0x12,
1244
0xde,0x5e,0x8d,0x2b,0x92,0xab,0xfc,0x23,0xdf,0x50,0x27,0x2b,0xd7,0xe0,0x4a,0xbf,
1245
0xac,0x7a,0x56,0xf9,0xae,0xe5,0x1f,0xa9,0xff,0xbc,0x72,0x8c,0xea,0x45,0xe5,0x38,
1246
0xd5,0x04,0xd5,0x64,0xd5,0x44,0x1b,0x76,0x04,0x45,0x2a,0xa7,0xab,0x7e,0x10,0xcf,
1247
0x56,0xcd,0x53,0x2d,0x50,0xbd,0xad,0x8a,0x53,0x25,0xa9,0x52,0x55,0xe9,0xaa,0x15,
1248
0xaa,0x2c,0xd5,0x5f,0xf5,0x06,0x2d,0x5b,0x95,0xa7,0x2a,0x54,0x11,0xfd,0x99,0xf7,
1249
0xcb,0xfa,0x31,0x7a,0xeb,0x5b,0x66,0xf6,0xf8,0xd6,0x37,0xcd,0xec,0xf1,0xad,0x6f,
1250
0x9b,0xd9,0x63,0xfd,0x1b,0x67,0x7d,0xdd,0x62,0xd5,0x56,0x55,0x89,0x2a,0x8c,0x76,
1251
0xaa,0xca,0x54,0x7b,0x70,0x4d,0xab,0x54,0x75,0xaa,0x26,0xd5,0x01,0xd5,0x61,0xd5,
1252
0x7b,0xaa,0xe3,0xaa,0xdf,0x9e,0x1f,0x4e,0xaa,0x4e,0xab,0x3e,0x56,0x7d,0xaa,0xea,
1253
0x51,0x5d,0x56,0x7d,0xa5,0xfa,0x4e,0xf5,0x93,0xca,0x28,0xc0,0x34,0xc0,0x22,0x60,
1254
0x68,0x80,0x6d,0xc0,0xb0,0x00,0x49,0x80,0x5b,0x80,0x3c,0xc0,0x37,0x40,0x15,0x10,
1255
0x1c,0x10,0x11,0x10,0x1d,0x70,0x5f,0xc0,0xc3,0x01,0x8f,0x07,0x3c,0x1d,0xf0,0x42,
1256
0xc0,0x2b,0x01,0x13,0x02,0xa6,0x04,0xcc,0x0c,0x78,0x2d,0x60,0x41,0xc0,0xa2,0x80,
1257
0x84,0x80,0x25,0x01,0xe9,0x01,0x2b,0x03,0xd6,0x06,0xfc,0xa7,0x7f,0x9f,0xfa,0xb7,
1258
0xbe,0x03,0xcd,0x0d,0x28,0x0c,0xd8,0x1c,0x50,0x12,0xb0,0x3b,0xa0,0x32,0xa0,0x26,
1259
0xa0,0x31,0xe0,0x40,0x40,0x6b,0xc0,0xb1,0x80,0x8e,0x80,0x0f,0x02,0xce,0x04,0x9c,
1260
0x0f,0xb8,0x18,0xf0,0x79,0xc0,0xd5,0x80,0x6f,0x03,0x7e,0x0c,0xa0,0x40,0x93,0xc0,
1261
0x21,0x81,0xfc,0x40,0x9b,0x40,0x71,0xa0,0x53,0xa0,0x6b,0xa0,0x2c,0xd0,0x27,0x50,
1262
0x19,0x18,0x14,0x18,0x1e,0x18,0x15,0x78,0x6f,0xe0,0x43,0x81,0x77,0xfb,0x5b,0x8a,
1263
0xbf,0xaa,0xbd,0xdb,0x67,0xe7,0xc7,0x02,0x9f,0x0a,0x7c,0x3e,0xf0,0xe5,0xc0,0xf1,
1264
0x81,0x93,0x03,0x67,0x04,0xce,0x0d,0x7c,0x23,0xf0,0xed,0xc0,0x78,0xf4,0x26,0x25,
1265
0x70,0x59,0xe0,0x8a,0xc0,0x35,0x81,0xeb,0x03,0x37,0x04,0x16,0x07,0x6e,0x0f,0xdc,
1266
0x15,0xb8,0x27,0xb0,0x3a,0xb0,0x21,0xb0,0x39,0xf0,0x70,0xe0,0x51,0x9c,0x3f,0x11,
1267
0xf8,0x7e,0xe0,0x47,0x81,0xe7,0x02,0xbb,0x03,0x3f,0x0b,0xfc,0x12,0xc7,0xd7,0x02,
1268
0xaf,0x07,0xf6,0xfd,0xe6,0xf7,0xc1,0xbf,0xef,0x7c,0xdf,0xcf,0x7e,0x63,0x4f,0x17,
1269
0x68,0xac,0x7e,0x8d,0x4c,0xd4,0x8b,0x8d,0xfa,0x74,0xe6,0x6a,0x0b,0x35,0x5f,0x2d,
1270
0x54,0xb3,0x7f,0x03,0x6f,0xab,0x16,0xab,0x47,0xa8,0x25,0xea,0x19,0x2e,0x2e,0xea,
1271
0x8d,0x46,0x52,0xf5,0x35,0x92,0xa9,0xbd,0xd4,0xbe,0x6a,0x85,0x3a,0x40,0xad,0x70,
1272
0x09,0x52,0x87,0xab,0xb5,0xea,0x18,0xf5,0xfd,0xea,0x87,0xd4,0x5b,0xe8,0x31,0xf5,
1273
0x6a,0x97,0x91,0xf4,0xa4,0xfa,0x69,0xb5,0x60,0xe8,0x0b,0xea,0x03,0x46,0x2f,0xa9,
1274
0xc7,0xa8,0xc7,0xab,0x5f,0x55,0x1f,0x37,0x9a,0xaa,0xee,0xd3,0xcd,0x54,0xcf,0x51,
1275
0xcf,0x53,0xbf,0xa1,0x7e,0x53,0xbd,0x48,0x1d,0xa7,0x4e,0x54,0xa7,0xaa,0x83,0x5c,
1276
0x32,0xd4,0x2b,0xd4,0x01,0x2e,0xab,0xd5,0xd9,0xea,0x7c,0xf5,0x46,0xf5,0x56,0x75,
1277
0xa9,0xba,0x5c,0xbd,0x4f,0x5d,0xa7,0xde,0xaf,0x3e,0xa8,0x7e,0x57,0x7d,0x5c,0xdd,
1278
0xa9,0xfe,0x50,0xfd,0x89,0xfa,0x82,0xba,0x57,0x7d,0x45,0xfd,0xb5,0xfa,0x7b,0xf5,
1279
0x0d,0xb5,0x71,0x90,0x59,0x90,0x65,0x90,0x20,0xc8,0x2e,0x68,0x78,0x90,0x73,0x90,
1280
0x34,0xc8,0x33,0xc8,0x2f,0x28,0x20,0x28,0x24,0x28,0x32,0x28,0x26,0xe8,0xfe,0xa0,
1281
0x47,0x82,0x9e,0x08,0x7a,0x26,0xe8,0xc5,0xa0,0x31,0x41,0x13,0x83,0xa6,0x06,0xcd,
1282
0x0a,0x9a,0x17,0xb4,0x30,0x68,0x71,0x50,0x62,0x50,0x6a,0x50,0x46,0xd0,0xaa,0xa0,
1283
0x3f,0xfe,0x0d,0xfc,0xba,0xa0,0xbc,0xa0,0xa2,0xa0,0x2d,0x41,0x3b,0x82,0xca,0x82,
1284
0xf6,0x06,0xd5,0x06,0x35,0x05,0xb5,0x04,0x1d,0x09,0x6a,0x0b,0x3a,0x19,0x74,0x3a,
1285
0xe8,0xe3,0xa0,0x4f,0x83,0x7a,0x82,0x2e,0x07,0x7d,0x15,0xf4,0x5d,0xd0,0x4f,0x41,
1286
0x46,0xc1,0x7f,0x64,0x44,0xfd,0xd9,0xf5,0x85,0x69,0xb0,0x45,0xf0,0xd0,0x60,0xdb,
1287
0xe0,0x61,0xc1,0x92,0x60,0xb7,0x60,0x79,0xb0,0x6f,0xb0,0x2a,0x38,0x38,0x38,0x22,
1288
0x38,0x3a,0xf8,0xbe,0xe0,0x87,0x83,0x1f,0x0f,0x7e,0x3a,0xf8,0x85,0xe0,0x57,0x82,
1289
0x27,0x04,0x4f,0x09,0x9e,0x19,0xfc,0x5a,0xf0,0x82,0xe0,0x45,0xc1,0x09,0xc1,0x4b,
1290
0x82,0xd3,0x83,0x57,0x06,0xaf,0x0d,0xce,0x0d,0x2e,0x0c,0xde,0x1c,0x5c,0x12,0xbc,
1291
0x3b,0xb8,0x32,0xb8,0x26,0xb8,0x31,0xf8,0x40,0x70,0x6b,0xf0,0xb1,0xe0,0x8e,0xe0,
1292
0x0f,0x82,0xcf,0x04,0x9f,0x0f,0xbe,0x18,0xfc,0x79,0xf0,0xd5,0xe0,0x6f,0x83,0x7f,
1293
0x0c,0xa6,0x10,0x93,0x90,0x21,0x21,0xfc,0x10,0x9b,0x10,0x71,0x88,0x53,0x88,0x6b,
1294
0x88,0x2c,0xc4,0x27,0x44,0x19,0x12,0x14,0x12,0x1e,0x12,0x15,0xf2,0x3f,0xf7,0x97,
1295
0x1c,0x7a,0xb9,0x37,0xe4,0xa1,0x90,0xc7,0x42,0x9e,0x0a,0x79,0x3e,0xe4,0xe5,0x90,
1296
0xf1,0x21,0x93,0x43,0x66,0x84,0xcc,0x0d,0x79,0x23,0xe4,0xed,0x90,0xf8,0x90,0x94,
1297
0x90,0x65,0x21,0x2b,0x42,0xd6,0x84,0xac,0x0f,0xd9,0x10,0x52,0x1c,0xb2,0x3d,0x64,
1298
0x57,0xc8,0x9e,0x90,0xea,0x90,0x86,0x90,0xbf,0xe2,0xbb,0xce,0xe6,0x90,0x23,0x21,
1299
0xed,0x21,0x1f,0x84,0xdc,0xf9,0x8a,0xea,0xfe,0xad,0xdf,0x00,0xf9,0xed,0xf1,0x79,
1300
0x6b,0xfe,0x2f,0x7f,0xfb,0xf5,0xee,0xfc,0xfd,0xd9,0x9d,0xff,0xa6,0xe2,0x8f,0xfc,
1301
0x2e,0xdc,0x2f,0xd7,0x2f,0x3f,0xff,0x8d,0xe1,0x3f,0xfe,0xf9,0x24,0xa4,0x27,0xe4,
1302
0x6a,0x48,0x5f,0x88,0x45,0xa8,0x43,0xa8,0x34,0xf4,0xf7,0xfd,0x3d,0xcd,0xaf,0xff,
1303
0x55,0xcd,0x7f,0xf2,0xa3,0x0c,0x0d,0x0b,0x8d,0x0d,0x7d,0x3c,0xf4,0xa5,0xd0,0xa9,
1304
0xa1,0xff,0xb3,0x96,0xfc,0xa7,0x7e,0x27,0xf2,0xcf,0xd7,0xe9,0xd3,0xfd,0xef,0xb2,
1305
0xad,0x4f,0xc7,0xd6,0x61,0xc7,0xb0,0x15,0x17,0xb2,0x75,0xd8,0xb8,0xbf,0x0e,0xfb,
1306
0xcd,0xc7,0x9d,0xf5,0xf4,0xe9,0x2c,0xc0,0xcf,0xf5,0xf4,0xe9,0xfe,0xe7,0x7d,0xdd,
1307
0xa7,0xbb,0xe9,0x6b,0x7d,0x7f,0x6e,0xad,0x73,0x7b,0x7f,0xfa,0x74,0x77,0x43,0xcf,
1308
0xcd,0x3a,0x7d,0x3a,0x47,0xea,0xff,0xc6,0xe8,0xee,0xe8,0xf9,0xbb,0xce,0xdf,0x75,
1309
0xfe,0x53,0x75,0xde,0x08,0x7d,0x33,0x74,0x51,0x68,0xdf,0xef,0xf8,0x6f,0x35,0x41,
1310
0xbc,0x9f,0xff,0xb7,0x9a,0xb8,0xd0,0xdf,0xae,0xf3,0xe8,0x6d,0x75,0x92,0x42,0x7d,
1311
0x51,0x2e,0x14,0xc7,0x0f,0xe3,0xfc,0xdf,0x3a,0xff,0x6f,0xe9,0x9c,0x0b,0x61,0xe7,
1312
0xc1,0x3b,0xad,0x9d,0xee,0x76,0x5e,0xea,0x6d,0xeb,0x8f,0x0c,0x1c,0xaf,0xe2,0xf2,
1313
0xd6,0x19,0xce,0xe4,0xfd,0x5b,0x2b,0x94,0x22,0x94,0xde,0x02,0x76,0x80,0x32,0x43,
1314
0xcd,0xbd,0x88,0x6b,0x41,0x13,0x68,0x01,0x47,0x40,0x1b,0x38,0x19,0xfa,0xdb,0x7b,
1315
0xa0,0x9b,0x9f,0x45,0xa1,0x3a,0x5d,0xdf,0x7f,0x50,0x4e,0x87,0x7e,0x1c,0xfa,0x69,
1316
0xe8,0x66,0xa3,0x9e,0xd0,0x02,0xe3,0x93,0x64,0x67,0xec,0x64,0x94,0x65,0xfc,0x79,
1317
0xe8,0xd5,0xd0,0x12,0xe3,0x6f,0x43,0xaf,0x87,0xce,0x32,0x5e,0xeb,0xa2,0x0b,0x35,
1318
0x0e,0x33,0x09,0x1b,0x12,0xc6,0x0f,0x13,0x86,0xd9,0x85,0x0d,0x0f,0x73,0x0e,0x73,
1319
0x0d,0xf3,0x08,0xf3,0x0a,0xf3,0x0b,0x53,0x85,0xa9,0xc3,0x42,0xc2,0xc2,0xc3,0x34,
1320
0x61,0xd1,0x61,0xf7,0x84,0xdd,0x1f,0xc6,0x5e,0xe3,0x87,0xc2,0x1e,0x0d,0x7b,0x32,
1321
0xec,0x99,0xb0,0xb1,0x2e,0x4b,0x8d,0x76,0x19,0xed,0x37,0x7a,0x21,0xec,0xa8,0xd1,
1322
0x4b,0x61,0xff,0xde,0x4e,0xfe,0xce,0x6f,0x5d,0xfa,0x7e,0x51,0xf7,0x66,0x2f,0x7e,
1323
0xf9,0xff,0xa3,0xf4,0xff,0x3d,0xea,0xce,0xff,0x3b,0x6a,0x24,0xf7,0x5f,0xa3,0x1c,
1324
0x47,0x7e,0x30,0xa8,0x9c,0x57,0xc5,0xfb,0x72,0x50,0xf6,0xa0,0x3d,0x83,0xee,0xdc,
1325
0x02,0x5b,0x9f,0xf7,0xb3,0xba,0xec,0x7f,0x9d,0x9a,0x86,0x7a,0xbb,0x78,0x47,0x79,
1326
0xab,0x06,0xb5,0x3b,0xe7,0x0e,0xfa,0x3d,0x5e,0x1e,0x17,0xf6,0x6a,0xd8,0xf4,0xb0,
1327
0x39,0x61,0xaf,0x87,0xbd,0x15,0x16,0x17,0x96,0x1c,0xb6,0x34,0x6c,0x79,0x58,0x56,
1328
0x58,0x4e,0x58,0x41,0xd8,0xa6,0xb0,0x6d,0x61,0x3b,0xc3,0x2a,0xc2,0xaa,0xc2,0xea,
1329
0xc3,0xde,0x09,0x3b,0x14,0xf6,0x5e,0x58,0x7b,0xd8,0xa9,0xb0,0x7f,0x86,0x9d,0x0d,
1330
0xeb,0x0a,0xbb,0x14,0xf6,0x45,0xd8,0x37,0x61,0x3f,0x84,0xf5,0x85,0xf1,0xc2,0xcd,
1331
0xc3,0xff,0xcc,0xfa,0x97,0x7d,0xc7,0x7c,0x43,0x69,0xaa,0xea,0xd3,0x69,0x54,0x7c,
1332
0x15,0xa9,0x9c,0x54,0xd1,0xdc,0xbb,0x5d,0xf6,0x7d,0xae,0x50,0xe5,0xa6,0xf2,0x54,
1333
0x39,0xa8,0x7c,0x54,0x96,0x2a,0x5b,0x15,0xfb,0xe6,0x99,0xa7,0x1a,0xac,0x1a,0xae,
1334
0x1a,0xa9,0xf2,0x50,0x59,0x85,0xa7,0x79,0x0d,0x0d,0x17,0x85,0xf7,0xe9,0xd8,0xfa,
1335
0x7d,0xba,0x70,0xfd,0xfb,0x5c,0x84,0x77,0xaa,0xdf,0xa7,0xeb,0xaf,0x8f,0xf5,0x21,
1336
0xf0,0xf8,0xd9,0x9b,0xc1,0x1b,0x03,0x6f,0xcb,0xf5,0xf5,0xfb,0x74,0x2a,0xa0,0xaf,
1337
0xdf,0xa7,0xeb,0xaf,0xcf,0x9e,0xbf,0xb5,0x7e,0x1a,0xfb,0x8d,0xed,0x2f,0xf4,0xeb,
1338
0xed,0xc7,0xdc,0xf1,0x2f,0xf4,0xeb,0xed,0xef,0xd3,0x0d,0x05,0xfd,0xfd,0x67,0xdf,
1339
0x57,0xf7,0xf7,0x9f,0xd5,0xff,0x5b,0xfd,0xbf,0x69,0xfd,0x2f,0xfd,0xf7,0xef,0xd5,
1340
0xb7,0x0b,0x17,0x87,0x8f,0x08,0x97,0x84,0xbb,0x84,0x4b,0xc3,0x65,0xe1,0x5e,0xe1,
1341
0xbe,0xe1,0x8a,0x5b,0xae,0xe8,0x1f,0xf9,0x3b,0xaf,0x80,0x70,0x13,0x3c,0xa1,0x4b,
1342
0x25,0xe1,0xe1,0x7f,0x6c,0x7f,0xa3,0x09,0x4f,0x95,0x44,0x87,0x2f,0x0a,0xbd,0x27,
1343
0xfc,0x81,0x3f,0x34,0xb6,0x1e,0x0e,0x7f,0x34,0xfc,0x89,0xf0,0xbb,0xb3,0x3f,0x7b,
1344
0x2a,0xfc,0xee,0xbc,0x27,0xf9,0x35,0x79,0x36,0xfc,0xe5,0xf0,0xc9,0xe2,0x5f,0x3f,
1345
0x3f,0x44,0x38,0x31,0x7c,0x4a,0xf8,0x8c,0x70,0x77,0xc1,0x9c,0xf0,0xf9,0xe1,0xce,
1346
0x76,0x0b,0xc3,0x17,0x85,0xc7,0x87,0x57,0xbb,0x27,0x87,0xa7,0x85,0x67,0x84,0xaf,
1347
0x0c,0x5f,0x13,0x9e,0x13,0x9e,0x23,0xcc,0x0f,0x2f,0x0a,0xdf,0x1c,0xbe,0x3d,0x7c,
1348
0x67,0x78,0x79,0xb8,0xb5,0x80,0xec,0xf6,0x86,0x17,0x38,0x58,0xda,0x6d,0x74,0xa8,
1349
0x09,0x5f,0x28,0x6a,0x08,0x7f,0x27,0xfc,0x60,0xf8,0x91,0xf0,0x63,0xe1,0x2f,0x38,
1350
0x28,0x85,0x27,0xc2,0x4f,0x85,0x7f,0x18,0xfe,0x71,0x78,0x7f,0xfb,0xe7,0xc3,0x3f,
1351
0x0f,0xff,0x36,0x9c,0x22,0x86,0x44,0xd8,0x44,0x38,0x45,0xc8,0x22,0x94,0x11,0x3f,
1352
0xd7,0x1f,0x1e,0xa1,0x8d,0xf8,0xbd,0xef,0x2f,0xfe,0xea,0xf7,0x1f,0x7f,0xe4,0x73,
1353
0xe7,0xf7,0x1f,0x37,0xf5,0xc7,0x46,0xdc,0x1f,0xf1,0x70,0xc4,0x63,0x11,0x4f,0x45,
1354
0xf8,0xc8,0x9e,0x8b,0x18,0x1d,0x31,0x26,0x62,0x42,0x84,0x42,0x36,0x39,0x62,0x7a,
1355
0xc4,0xec,0x88,0x40,0xd9,0xfc,0x88,0x85,0x11,0x8b,0x22,0xe2,0x23,0x52,0x22,0x96,
1356
0x46,0x64,0x84,0x67,0x46,0xac,0x8e,0x58,0x17,0x91,0x1b,0xb1,0x21,0x42,0x28,0xdf,
1357
0x14,0x31,0x4a,0xb0,0x2d,0xa2,0x34,0xa2,0x2c,0xa2,0x32,0xe2,0x54,0x78,0x75,0x44,
1358
0x7d,0x84,0xbb,0x9c,0xfd,0x2d,0x1f,0x4f,0xf9,0xfe,0x88,0x96,0x88,0x31,0xd2,0xd6,
1359
0x88,0x28,0xd9,0xd1,0x88,0xf6,0x88,0xce,0x88,0xd3,0x9c,0x9c,0x89,0x38,0x1f,0xd1,
1360
0x1d,0x71,0x29,0xe2,0x4a,0xc4,0xd7,0x11,0xdf,0x45,0xfc,0x18,0xa1,0x8b,0xe0,0x45,
1361
0x9a,0x45,0x5a,0x44,0xf2,0x23,0x45,0x91,0xf6,0x91,0xc3,0x23,0x25,0x91,0xae,0x10,
1362
0xa5,0xdc,0x23,0xd2,0x2b,0xd2,0x2f,0x52,0x15,0xf9,0x80,0x2c,0x28,0x32,0x2c,0x52,
1363
0x13,0xb9,0xcd,0x23,0x26,0xf2,0xbe,0xc8,0x87,0x22,0x1f,0x8d,0x7c,0x32,0xf2,0x99,
1364
0xc8,0x17,0x22,0x5f,0x8e,0x1c,0x17,0xf9,0x6a,0xe4,0xb4,0xc8,0x59,0x91,0x73,0xc2,
1365
0x5f,0x8b,0x7c,0x23,0xf2,0xad,0xc8,0xb8,0xc8,0xe4,0xc8,0xb4,0xc8,0x8c,0xc8,0x95,
1366
0x91,0x6b,0x22,0x73,0x22,0xf3,0x23,0x8b,0x22,0x37,0x43,0xb6,0x47,0xee,0x8a,0xac,
1367
0x88,0x7c,0x5c,0xba,0x2f,0xb2,0x36,0xb2,0x29,0xf2,0x40,0xe4,0xe1,0xc8,0xbd,0x82,
1368
0xf7,0x22,0x8f,0x47,0x36,0x08,0x4e,0x46,0x7e,0x10,0xf9,0x51,0xe4,0xb9,0xc8,0xae,
1369
0xc8,0x4b,0x91,0x57,0x22,0xbf,0x8a,0xfc,0x36,0xf2,0x7a,0x64,0x5f,0xa4,0xb1,0xc6,
1370
0x54,0x33,0x44,0x63,0xad,0x11,0x6a,0xec,0x34,0xc3,0x35,0x12,0x8d,0xab,0xc6,0x43,
1371
0x13,0xe7,0xe6,0xa5,0xe9,0x16,0xf8,0x6b,0xfc,0x35,0x81,0x9a,0x10,0x48,0x84,0x26,
1372
0x4a,0x73,0xaf,0xe6,0x21,0xcd,0xa3,0x9a,0x27,0x35,0xcf,0x68,0x5e,0xd0,0xbc,0xac,
1373
0x19,0xa7,0x99,0xa4,0x99,0xaa,0x99,0xa9,0x19,0x2d,0x9b,0xab,0x79,0x43,0xf3,0x96,
1374
0x86,0xd1,0x8c,0x95,0x33,0x9a,0x44,0xcd,0x04,0xd9,0x12,0xcd,0x32,0xcd,0x72,0xcd,
1375
0x6a,0xcd,0x64,0x99,0xad,0xdb,0x3a,0x4d,0xae,0x66,0x83,0x66,0x93,0x66,0xab,0x66,
1376
0x87,0x66,0xb7,0xa6,0x52,0x53,0xad,0xa9,0xd7,0xec,0xd7,0xb4,0x68,0x5a,0x35,0xc7,
1377
0x34,0x27,0x34,0xa7,0x34,0x1f,0x6a,0x3e,0xd6,0x9c,0xd7,0x74,0x6b,0x2e,0x69,0xae,
1378
0x68,0xa6,0xcb,0xbe,0xd2,0x7c,0xab,0xf9,0x51,0xa3,0xd3,0xf0,0xb4,0x66,0xda,0x79,
1379
0x32,0x0b,0x2d,0x5f,0x2b,0xd2,0xda,0x6b,0x87,0x6b,0x25,0x5a,0x57,0xad,0x87,0x96,
1380
0xfd,0x5d,0x24,0x2f,0xad,0x9f,0x56,0xa5,0x0d,0xd2,0x86,0x6b,0xb5,0xda,0x58,0xed,
1381
0xfd,0xda,0x05,0xb2,0x87,0xb5,0x8f,0x6b,0x9f,0xd2,0x3e,0xa7,0xf5,0xf1,0x1c,0xad,
1382
0x1d,0xa3,0x9d,0xa0,0x9d,0xac,0x9d,0xae,0x9d,0xa3,0x9d,0xaf,0x5d,0xa8,0x5d,0xa4,
1383
0x4d,0xd0,0xa6,0x68,0x97,0x6a,0x33,0xb5,0x59,0xd2,0x55,0xda,0xb5,0xda,0x5c,0x6d,
1384
0xa1,0x76,0xb3,0x76,0xbb,0x76,0x97,0xb6,0x42,0xbb,0x4f,0x5b,0xab,0x6d,0xd4,0xbe,
1385
0x2d,0x3b,0xe7,0xde,0xac,0x3d,0xa4,0x7d,0x57,0xdb,0xa6,0x3d,0xa9,0xfd,0x40,0xfb,
1386
0x91,0xf6,0xac,0x36,0x43,0x7e,0x41,0xdb,0xa3,0xbd,0xac,0xbd,0xaa,0xbd,0xa6,0xbd,
1387
0xae,0xd5,0x69,0x79,0x51,0x2b,0xe5,0x66,0x51,0x16,0x51,0xfc,0x28,0x51,0x94,0x7d,
1388
0xd4,0xf0,0x28,0x49,0x94,0x5b,0x94,0x2c,0xca,0x27,0x4a,0x11,0xa5,0x8e,0xca,0x91,
1389
0x87,0x46,0x45,0x46,0xc5,0x44,0xdd,0x17,0xf5,0x50,0xd4,0x63,0x51,0x4f,0x45,0x3d,
1390
0x17,0x35,0x3a,0x6a,0x4c,0xd4,0x04,0xc8,0xe4,0xa8,0xe9,0x51,0x45,0xf2,0xd9,0x51,
1391
0xf3,0xa2,0x16,0x44,0xbd,0x1d,0x15,0x17,0x95,0x1c,0x95,0x16,0x35,0x5a,0x9a,0x19,
1392
0xb5,0x3a,0x6a,0x5d,0x54,0x5e,0x54,0x51,0xd4,0x96,0xa8,0x92,0xa8,0x1a,0xf9,0xae,
1393
0xa8,0x3d,0x51,0xd5,0x51,0x0d,0x51,0xcd,0x51,0x87,0x20,0x0d,0xf2,0x40,0xcf,0x77,
1394
0xa3,0xda,0xa2,0x3a,0xa2,0xde,0x8f,0xfa,0x28,0xaa,0xd5,0xed,0xa0,0xfc,0x6c,0xd4,
1395
0x85,0xa8,0x62,0x59,0x6f,0xd4,0x95,0xa8,0x1f,0x3c,0xbe,0x8e,0xfa,0x2e,0xaa,0x4c,
1396
0xf6,0x63,0x94,0x2e,0x8a,0x17,0x6d,0x0e,0xb1,0x8a,0x16,0x44,0xdb,0x46,0x0f,0x8b,
1397
0x76,0x8a,0x76,0x89,0x76,0x8f,0xf6,0x8a,0xf6,0x8b,0x56,0x45,0x07,0x45,0x87,0x45,
1398
0x6b,0xa2,0x63,0xa3,0xef,0x8f,0x7e,0x38,0xfa,0xb1,0xe8,0x7f,0x44,0x3f,0x1b,0xfd,
1399
0x62,0xf4,0x98,0xe8,0x89,0xd1,0x53,0xa2,0x67,0x46,0xcf,0x8d,0x7e,0x23,0xfa,0xad,
1400
0xe8,0x56,0x19,0x13,0x9d,0x14,0x9d,0x16,0x9d,0x11,0xbd,0x2a,0x7a,0x6d,0x74,0x6e,
1401
0xf4,0x86,0xe8,0x4d,0xd1,0x5b,0xa3,0x77,0x44,0xef,0x8e,0xde,0x13,0x5d,0x1d,0xdd,
1402
0x10,0xdd,0x1c,0x1d,0xa8,0x39,0x1c,0xfd,0x5e,0xf4,0xf1,0xe8,0x93,0xd1,0x1f,0x44,
1403
0x7f,0x14,0x7d,0x36,0xfa,0x42,0x74,0x4f,0xf4,0xe7,0xd1,0x5f,0x46,0x7f,0x13,0x5d,
1404
0x28,0xfd,0x21,0xfa,0x46,0xb4,0x51,0x8c,0x49,0xcc,0xe0,0x18,0xab,0x98,0x4e,0x99,
1405
0x20,0xc6,0x36,0x46,0x1c,0xe3,0x18,0x33,0x32,0xc6,0x3d,0xc6,0x2b,0xc6,0x3f,0x26,
1406
0x20,0x26,0x38,0x26,0x3c,0x46,0x1b,0x73,0x4f,0xcc,0x03,0x31,0xa3,0x62,0x9e,0x88,
1407
0x79,0x3a,0xe6,0x85,0x98,0x57,0x62,0xc6,0xc7,0x54,0xba,0xbd,0x1a,0x33,0x2d,0x66,
1408
0x56,0xcc,0x6b,0x31,0x6f,0xc4,0xbc,0x15,0x73,0x5e,0xce,0xc4,0x24,0xc6,0x2c,0x89,
1409
0x59,0x16,0xb3,0x3c,0x66,0x75,0xcc,0xba,0x98,0xdc,0x98,0x51,0xa2,0x0d,0x31,0xc5,
1410
0x31,0xdb,0x62,0x4a,0x63,0xca,0x62,0x2a,0x63,0xaa,0x63,0x1a,0x62,0x9a,0x63,0x0e,
1411
0xc5,0xbc,0x1b,0xf3,0xad,0xfc,0xba,0x7c,0x8a,0xa8,0x2d,0xe6,0x64,0xcc,0x07,0x31,
1412
0x1f,0xc5,0x9c,0x8d,0xb9,0x10,0xd3,0x1b,0x73,0x25,0xe6,0xab,0x98,0x6f,0x63,0xae,
1413
0xc7,0xe8,0x62,0xfa,0xe4,0xbc,0x58,0xf3,0x58,0xab,0x58,0x41,0xac,0x6d,0xac,0x38,
1414
0xd6,0x29,0xd6,0x25,0xd6,0x3d,0xd6,0x33,0xd6,0x37,0x56,0x19,0xab,0x8e,0x0d,0x8d,
1415
0xd5,0xc4,0xc6,0xc4,0xde,0x17,0xfb,0x50,0xec,0x63,0xb1,0xff,0x88,0x7d,0x36,0xf6,
1416
0xc5,0xd8,0x57,0x62,0x27,0xc4,0x4e,0x89,0x9d,0x11,0x3b,0x27,0x76,0x7e,0xec,0x9b,
1417
0xb1,0x8b,0x63,0xed,0x3c,0xed,0x3c,0x13,0x63,0x97,0xc4,0xa6,0xc7,0xae,0x88,0xcd,
1418
0x8a,0xcd,0x8e,0xcd,0x8b,0x2d,0x8c,0x2d,0x8e,0xdd,0x16,0x3b,0xcc,0x73,0x67,0x6c,
1419
0x79,0xec,0xde,0xd8,0x9a,0xd8,0x86,0xd8,0x77,0x62,0x0f,0xc5,0xbe,0x1b,0x7b,0x3c,
1420
0xb6,0x33,0xd6,0xd3,0xe6,0xc3,0xd8,0x50,0x9b,0x8f,0x63,0xcf,0xc7,0x76,0xc7,0x5e,
1421
0x8a,0x1d,0x65,0x73,0x25,0xf6,0x6e,0xac,0x72,0x6f,0x7b,0x1f,0xca,0xfe,0x77,0x9a,
1422
0x14,0x09,0x35,0xe9,0x74,0x5f,0xf4,0xbf,0x64,0xe5,0x42,0x8d,0xe1,0xe8,0xe2,0xad,
1423
0x73,0x1b,0x8f,0x7e,0x96,0xab,0xd1,0x2d,0x46,0xf8,0xa8,0x8e,0xfb,0xcf,0x52,0xcc,
1424
0x40,0xa9,0x1f,0xd9,0xff,0x21,0x51,0xf0,0x83,0x4e,0x77,0xa3,0xe5,0xeb,0x2b,0x8d,
1425
0x38,0xba,0x71,0xf9,0xeb,0xc6,0x30,0x23,0x6a,0xd3,0xf1,0xfa,0xae,0x70,0xf9,0x97,
1426
0xbf,0xfe,0xfc,0x50,0xc4,0x29,0x87,0x43,0xba,0xe6,0x43,0x11,0x71,0xac,0x6e,0x33,
1427
0xdd,0x27,0x37,0x90,0xaf,0xfb,0xfa,0x93,0x88,0x57,0x82,0xda,0xd8,0xb6,0xb8,0xe3,
1428
0x2f,0xd8,0xe3,0x59,0x6d,0x3a,0x6b,0xe2,0x8e,0x59,0xe3,0x6e,0x7c,0xa9,0x6b,0x63,
1429
0x57,0x71,0xba,0xc5,0x3f,0x41,0x93,0xdf,0xe2,0xc4,0x97,0x75,0x4d,0xba,0x11,0xac,
1430
0x5d,0x7c,0xae,0x5f,0x9f,0xe8,0xcc,0xb8,0x38,0x62,0x71,0x04,0x57,0x81,0x0b,0xd9,
1431
0x83,0xc5,0x06,0xeb,0x22,0x74,0xb7,0xf4,0x41,0x62,0xf0,0x00,0xfb,0x5c,0x90,0xdc,
1432
0xfa,0x92,0x14,0x9d,0x83,0x11,0x8b,0x89,0x6d,0x56,0xf7,0x09,0xfb,0x9f,0x81,0xd0,
1433
0x5b,0x9e,0xbe,0xac,0x6e,0xe0,0x3f,0x69,0x69,0xd8,0xfc,0xc5,0x3a,0xbe,0x8e,0x7f,
1434
0x95,0x3b,0x94,0xe8,0xfd,0xc3,0xe7,0x5a,0x3d,0x64,0x28,0xd4,0x66,0x88,0x59,0x03,
1435
0x0a,0xb8,0x36,0x34,0x37,0xdf,0xc5,0x1a,0xbc,0x6d,0xf8,0xf0,0xbf,0x34,0x24,0xbe,
1436
0xd7,0x7d,0xda,0xff,0x22,0x5b,0xaf,0x51,0xdf,0xb2,0xfe,0xff,0x8c,0xe3,0x32,0xd0,
1437
0xad,0x4d,0x37,0x3a,0x73,0xcd,0xd3,0x62,0xc3,0xa7,0xdf,0x38,0x3e,0xf7,0x2d,0xc1,
1438
0xcd,0x0f,0x67,0xad,0xa1,0x97,0x8b,0x6f,0x7d,0x23,0xce,0x1f,0x18,0x0f,0xfa,0x58,
1439
0xa2,0xe3,0x69,0x9a,0x0c,0x7d,0xd5,0xf1,0x19,0x2e,0xa7,0x51,0xd7,0x6c,0xe8,0x83,
1440
0xbe,0xb6,0x46,0xf7,0xb5,0xfe,0x7f,0x48,0xd0,0xf7,0xec,0xf1,0xa2,0x45,0x8b,0xe8,
1441
0xa6,0x66,0x7d,0x5d,0x3e,0xfb,0xbf,0xb6,0xbf,0xef,0xd7,0x60,0x18,0x77,0x5f,0x70,
1442
0x8d,0xec,0x43,0x19,0xcd,0x2d,0xe3,0xd0,0x2c,0x85,0x8b,0x32,0xd9,0x93,0x12,0xa3,
1443
0x9b,0x23,0x54,0x73,0xd3,0x62,0xae,0xef,0xdc,0xdf,0x80,0xf3,0xcf,0x0e,0x5c,0x03,
1444
0x36,0x6c,0xd4,0xbb,0x5c,0x73,0xb3,0x16,0xdd,0xec,0x18,0xd7,0x6b,0xe4,0x6b,0xb8,
1445
0xe1,0xd3,0xb8,0xc2,0x50,0x9c,0xeb,0x04,0x33,0x70,0x2f,0x04,0x7d,0xaf,0x57,0xae,
1446
0x4b,0xd0,0x7b,0x77,0xc0,0x2e,0x5c,0x8f,0x9f,0xb8,0xc4,0xcc,0x2f,0xbf,0x80,0x2b,
1447
0x35,0x29,0x18,0x19,0x46,0xb7,0x7e,0xc7,0xc0,0x35,0xf4,0x7d,0xbf,0x37,0x35,0x7d,
1448
0x7a,0x93,0x59,0xb3,0x78,0x4e,0xd4,0x87,0xf3,0x46,0xb7,0xde,0x6f,0x66,0x3f,0x19,
1449
0xec,0x83,0x7f,0x7f,0xf6,0xdd,0x84,0xde,0x73,0x61,0x3c,0xfa,0xa9,0x6f,0xe0,0x48,
1450
0x7f,0x95,0xfb,0xad,0xe1,0xae,0x11,0xeb,0x77,0xb6,0x09,0x4d,0xff,0xcd,0xf6,0x89,
1451
0x19,0x71,0xa3,0x95,0x37,0x70,0xeb,0xd2,0xcd,0xab,0xcb,0xbe,0x61,0xd6,0xdf,0x8d,
1452
0x86,0x66,0xf0,0x59,0x5c,0x0f,0x07,0xf4,0xff,0x47,0x2a,0x33,0x1d,0x4f,0x7f,0x9f,
1453
0x5e,0xfe,0xb1,0x20,0x24,0xee,0x6c,0x9b,0x04,0xe5,0x1f,0xe2,0xfc,0xa4,0x2b,0xfe,
1454
0xae,0xd1,0xc8,0x54,0xaf,0xf9,0x0b,0xb6,0x2e,0x6b,0xf3,0xcd,0x7e,0x68,0xf4,0xc3,
1455
0x09,0x1f,0xd4,0xe0,0x41,0x0d,0x0d,0xcc,0x26,0x3c,0xfd,0xc5,0xe6,0xee,0x2f,0x3e,
1456
0x6b,0xc9,0xcf,0xe6,0x1b,0xc3,0xdf,0xf0,0x9b,0x31,0x8b,0xbf,0x9a,0xc9,0xea,0xf9,
1457
0x61,0x31,0x0d,0x98,0x46,0x06,0x57,0xff,0x24,0xd1,0xeb,0x1b,0xf8,0x70,0x7d,0x34,
1458
0xbb,0xc5,0x5f,0x86,0xf6,0x78,0xac,0xee,0x1b,0xfa,0x5b,0xeb,0xe6,0xd8,0x46,0x23,
1459
0x7d,0xb8,0x17,0xb8,0x6e,0x2f,0xde,0xc3,0xda,0xdd,0xc8,0x96,0x59,0xfc,0x63,0xbf,
1460
0x97,0xf8,0x3a,0x1e,0xaf,0xdf,0x26,0x23,0x9d,0xbe,0x81,0x43,0x3f,0xd7,0x60,0xb8,
1461
0xcf,0x74,0x3c,0x86,0x4f,0xfd,0xd7,0xfa,0xd6,0xfb,0xd4,0xec,0x96,0x5c,0x0d,0x0d,
1462
0xdc,0xdf,0xcd,0x03,0x05,0x16,0x73,0xba,0x34,0x1a,0xac,0x04,0x75,0x3f,0xc2,0x94,
1463
0xb3,0xba,0x81,0xb1,0xa6,0xbf,0x15,0x74,0x29,0x86,0x92,0xcc,0xcd,0xef,0xaa,0x24,
1464
0xb4,0xb8,0xbf,0xa7,0x8c,0x7e,0xc4,0xb3,0xe5,0xfb,0xe7,0xdc,0x5b,0xcc,0xa3,0x2f,
1465
0x66,0x12,0x76,0x30,0x5f,0x1a,0x0d,0x5c,0x47,0xc3,0x3d,0xc2,0x47,0xe7,0x1d,0xcf,
1466
0x0e,0xcc,0xde,0x9a,0x9b,0x37,0x9e,0xe6,0x67,0xf7,0x04,0x9f,0x0c,0x63,0xc4,0x08,
1467
0xc9,0xef,0xfb,0xf4,0xbd,0x93,0x70,0x05,0x99,0x5b,0xae,0x97,0x04,0x2d,0x34,0xdf,
1468
0x3a,0x4a,0x07,0xbc,0x90,0x40,0x3f,0x9f,0x89,0x52,0xf4,0xa3,0x56,0x3f,0xaa,0x17,
1469
0xcf,0xd4,0x2d,0x2e,0x30,0x5c,0x79,0x78,0xbb,0xf9,0xd6,0xff,0xd8,0xa3,0xff,0x48,
1470
0xfa,0x53,0xfa,0x9b,0x96,0xfb,0xbf,0x6d,0xb0,0x69,0x71,0xff,0x0a,0x5d,0x9f,0xdd,
1471
0xa4,0x2f,0xf3,0x35,0xec,0x90,0x70,0xd7,0x8d,0x7f,0x73,0x04,0xb1,0xd7,0x75,0xe0,
1472
0x5e,0xd7,0xe8,0xf8,0x3c,0xc3,0x9d,0xc6,0xe5,0x68,0x74,0x92,0xc5,0x57,0x31,0x88,
1473
0x33,0xd9,0x1b,0xf1,0x3b,0xdd,0x2d,0xf3,0xef,0xcd,0x99,0xc4,0x30,0x87,0xd3,0x18,
1474
0x1a,0x4b,0xe3,0x68,0x3c,0x4d,0xa0,0x89,0x34,0x89,0x5e,0xa5,0xc9,0x34,0x85,0xa6,
1475
0xd2,0x34,0x9a,0x4e,0x33,0x68,0x26,0xcd,0xa2,0xd9,0x34,0x87,0xe6,0xd2,0x6b,0x34,
1476
0x8f,0xe6,0xd3,0xeb,0xf4,0x06,0x2d,0xa0,0x85,0xe4,0x4c,0xce,0xef,0x2d,0x01,0x89,
1477
0xc4,0xfe,0x2e,0x9a,0xf3,0x7b,0x71,0x74,0xac,0x0e,0xd1,0x16,0xec,0x25,0x15,0xe7,
1478
0xe3,0x12,0x03,0xb8,0x10,0xa7,0xb8,0x74,0xf3,0x06,0x6a,0x2e,0xa4,0xe6,0x22,0x6a,
1479
0xde,0x48,0xcd,0x9b,0xa8,0xb9,0x98,0x9a,0x37,0x53,0xf3,0x16,0x6a,0xde,0x4a,0xcd,
1480
0xdb,0xa8,0x79,0x3b,0x35,0x97,0x50,0xf3,0x0e,0x6a,0x2e,0xa5,0xe6,0x9d,0xd4,0xbc,
1481
0x8b,0x9a,0x77,0x53,0x73,0x19,0x35,0x97,0x53,0x73,0x05,0x35,0xef,0xa1,0xe6,0x4a,
1482
0x6a,0xde,0x4b,0xcd,0x55,0xd4,0x5c,0x4d,0xcd,0x35,0xd4,0x5c,0x4b,0xcd,0x75,0xd4,
1483
0x5c,0x4f,0xcd,0x0d,0x74,0x20,0x8e,0x0e,0x24,0xd0,0x81,0x24,0x3a,0x90,0x42,0x07,
1484
0x52,0xe9,0xc0,0x52,0x3a,0x90,0x4e,0x07,0x32,0xe9,0xc0,0x0a,0x3a,0xb0,0x8a,0x0e,
1485
0x64,0xd1,0x81,0xb5,0x74,0x20,0x9b,0x0e,0xac,0xa7,0x03,0x79,0x74,0xa0,0x80,0x0e,
1486
0x14,0xd2,0x81,0x8d,0x74,0xa0,0x98,0x0e,0x6c,0xa1,0x03,0xdb,0xe8,0x40,0x09,0x1d,
1487
0x28,0xa5,0x03,0xbb,0x68,0xf2,0x7b,0x29,0x34,0x79,0x0a,0x1d,0xa8,0xa4,0x03,0xfb,
1488
0xe8,0x40,0x0d,0x1d,0xa8,0xa3,0x03,0x0d,0x34,0xed,0x9d,0x7d,0xd4,0x12,0x4f,0x2d,
1489
0x89,0xd4,0x92,0x4c,0x2d,0x4b,0xe8,0x48,0xdd,0x0c,0x6a,0x59,0x4a,0x2d,0xe9,0xd4,
1490
0x92,0x49,0x2d,0x2b,0xa8,0x65,0x15,0xb5,0x64,0x51,0xcb,0x5a,0x6a,0xc9,0xa6,0x96,
1491
0xf5,0xd4,0x92,0x47,0x2d,0x05,0xd4,0x52,0x48,0x2d,0x1b,0xa9,0xa5,0x98,0x5a,0xb6,
1492
0x50,0xcb,0x36,0x6a,0x29,0xa1,0x96,0x52,0x6a,0xd9,0x45,0x2d,0x65,0xd4,0x52,0x41,
1493
0x2d,0x95,0xd4,0xb2,0x8f,0x9a,0x1b,0xa9,0xa5,0x86,0x5a,0xea,0xa8,0xa5,0x81,0x5a,
1494
0x57,0xd1,0xc1,0x04,0x3a,0x98,0x44,0xad,0xab,0xe9,0xe0,0x12,0x6a,0x5d,0x43,0xad,
1495
0x6b,0xe9,0xe0,0x32,0x3a,0x94,0x47,0xad,0xd9,0xd4,0xba,0x9e,0x0e,0xae,0xa4,0xd6,
1496
0x0d,0xd4,0xba,0x91,0x5a,0xb7,0x51,0xeb,0x56,0x3a,0x88,0xcc,0x5d,0xd4,0x5a,0x4e,
1497
0xad,0x95,0x74,0xb0,0x90,0x0e,0x6e,0xa4,0x83,0xc5,0x74,0x84,0xa1,0x83,0x5b,0xe9,
1498
0x08,0xda,0x29,0xa5,0x23,0x4b,0xe8,0xe0,0x6e,0x3a,0x92,0x46,0x47,0x96,0xd2,0xc1,
1499
0x3d,0x74,0x70,0x2f,0x1d,0x59,0x49,0x07,0xab,0xe9,0x60,0x3d,0x8d,0x87,0xbe,0x69,
1500
0x53,0x68,0xc6,0x14,0x3a,0x94,0x41,0x87,0x96,0xd3,0xa1,0x95,0x74,0x68,0x35,0x1d,
1501
0x5a,0x43,0x87,0xd6,0xd1,0xa1,0x1c,0x3a,0x94,0x4b,0x87,0x0a,0xe8,0x50,0x21,0x1d,
1502
0xda,0x48,0x87,0x8a,0xe9,0xd0,0x16,0x3a,0xb4,0x8d,0x0e,0x95,0xd0,0xa1,0x52,0x3a,
1503
0xb4,0x8b,0xc6,0x2f,0xa4,0x43,0x50,0x99,0x45,0x07,0x1b,0xe9,0x50,0x35,0x1d,0xaa,
1504
0xa5,0x43,0xf5,0x74,0xa8,0x91,0x0e,0xc7,0xd1,0xe1,0x04,0x3a,0x9c,0x44,0x87,0x53,
1505
0xe8,0x70,0x2a,0x1d,0x5e,0x4a,0x87,0xd3,0xe9,0x70,0x26,0x1d,0x5e,0x41,0x87,0x57,
1506
0xd1,0xe1,0x2c,0x3a,0xbc,0x96,0x0e,0x67,0xd3,0xe1,0xf5,0x74,0x38,0x8f,0x0e,0x17,
1507
0xd0,0xc1,0x7c,0x3a,0xbc,0x91,0x0e,0x17,0xd3,0xe1,0x2d,0x74,0x78,0x1b,0x1d,0x2e,
1508
0xa1,0xc3,0xa5,0x74,0x78,0x17,0x1d,0x2e,0xa3,0xc3,0x15,0x74,0xbe,0x0c,0x27,0xea,
1509
0xe8,0x60,0x0e,0x52,0x9b,0xa9,0x35,0x9e,0x0e,0x32,0x74,0x24,0x95,0x8e,0x2c,0xa3,
1510
0xd6,0x14,0x6a,0x4d,0xa5,0xd6,0xa5,0xd4,0x9a,0x4e,0xad,0x99,0xd4,0x8a,0xb3,0xd5,
1511
0xd4,0x5a,0x4b,0x47,0xe2,0x30,0xf0,0x92,0x41,0x0a,0x48,0x03,0x5b,0x41,0x02,0x58,
1512
0x4a,0x47,0xb2,0xe8,0x3d,0x86,0x30,0x38,0xdf,0x5b,0x45,0xef,0x2d,0x61,0x07,0x69,
1513
0x35,0x1d,0x2d,0xa3,0xa3,0x15,0x74,0x04,0x89,0x7d,0xe4,0x8c,0xe3,0x30,0x6a,0xab,
1514
0x60,0x07,0x33,0x7b,0x76,0x07,0xe1,0x8a,0x1f,0x2b,0xa5,0x63,0x3b,0xe9,0xd8,0x2e,
1515
0x6a,0x5b,0x46,0x6d,0xe9,0xd4,0x96,0x41,0xc7,0xca,0xe8,0x58,0x39,0x1d,0xab,0xa0,
1516
0x63,0x7b,0xe8,0x58,0x25,0x1d,0xdb,0x4b,0xc7,0x50,0xac,0x8a,0x8e,0xd5,0xd0,0xb1,
1517
0x5a,0x3a,0x56,0x4f,0xc7,0x1a,0xe8,0x58,0x23,0xb5,0x31,0xd4,0x16,0x47,0x6d,0x09,
1518
0xd4,0x96,0x48,0x6d,0x49,0xd4,0x96,0x4c,0x6d,0x29,0xd4,0xb6,0x84,0xda,0x52,0xa9,
1519
0x2d,0x8d,0xda,0x96,0x52,0xdb,0x5a,0x6a,0xcb,0xa6,0xb6,0xf5,0xd4,0x96,0x47,0x6d,
1520
0x05,0xd4,0x56,0x48,0x6d,0x1b,0xa9,0xad,0x98,0xda,0xb6,0x50,0xdb,0x36,0x6a,0x2b,
1521
0xa1,0xb6,0x52,0x6a,0x83,0xde,0x2a,0x6a,0xab,0xa5,0xa3,0xf8,0xa9,0xa3,0xa3,0xf5,
1522
0xd4,0xbe,0x9c,0xda,0x57,0x50,0xfb,0x4a,0x6a,0x5f,0x45,0xed,0xab,0xa9,0x3d,0x8b,
1523
0xda,0xd7,0x50,0xfb,0x5a,0x6a,0x5f,0x47,0xed,0xd9,0xd4,0x9e,0x43,0xed,0xeb,0xa9,
1524
0x3d,0x97,0xda,0xf3,0xa8,0x3d,0x9f,0xda,0x0b,0xe8,0xf8,0x6e,0x3a,0x5e,0x46,0xc7,
1525
0xcb,0xe9,0x78,0x05,0x1d,0xdf,0x43,0xc7,0x2b,0xe9,0xf8,0x5e,0x3a,0xbe,0x8f,0x8e,
1526
0x57,0xd1,0xf1,0x6a,0x3a,0x5e,0x43,0xc7,0x6b,0xe9,0x78,0x1d,0x1d,0xaf,0xa7,0xe3,
1527
0x0d,0x74,0xbc,0x91,0xda,0x19,0x6a,0x8f,0xa3,0xf6,0x78,0x6a,0x4f,0xa0,0xf6,0x44,
1528
0x6a,0x4f,0xa2,0xf6,0x64,0x6a,0x4f,0xa1,0xf6,0x25,0xd4,0x9e,0x4a,0xed,0x69,0xd4,
1529
0xbe,0x94,0xda,0x97,0x51,0x7b,0x3a,0xb5,0x67,0x50,0x7b,0x26,0xb5,0x17,0x52,0xfb,
1530
0x46,0x6a,0x2f,0xa6,0xf6,0x2d,0xd4,0xbe,0x8d,0xda,0x4b,0xa8,0xbd,0x94,0xda,0x77,
1531
0x51,0x7b,0x19,0xb5,0x57,0x50,0x7b,0x25,0xb5,0xef,0xa3,0xf6,0x6a,0x6a,0xaf,0xa5,
1532
0x76,0x18,0xdf,0x48,0x27,0xe2,0xe8,0xc4,0x52,0x3a,0x91,0x4e,0x27,0x32,0xe9,0xc4,
1533
0x0a,0x3a,0xb1,0x8a,0x4e,0x64,0xd1,0x89,0xb5,0x74,0x22,0x9b,0x4e,0xac,0xa7,0x13,
1534
0x79,0x74,0xa2,0x80,0x4e,0x14,0xd2,0x89,0x8d,0x74,0xa2,0x98,0x4e,0x6c,0xa1,0x13,
1535
0xdb,0xe8,0x44,0x09,0x9d,0x28,0xa5,0x13,0xbb,0xe8,0x44,0x19,0x9d,0xa8,0xa0,0x13,
1536
0x95,0x74,0x62,0x1f,0x9d,0xa8,0xa6,0x13,0xb5,0x74,0xa2,0x9e,0x4e,0x34,0x52,0x47,
1537
0x26,0x75,0xc4,0x53,0x47,0x22,0x75,0x24,0x53,0xc7,0x12,0xea,0x48,0xa3,0x8e,0x65,
1538
0xd4,0x91,0x41,0x1d,0x2b,0xa8,0x63,0x15,0x75,0x64,0x51,0xc7,0x5a,0xea,0xc8,0xa6,
1539
0x8e,0xf5,0xd4,0x91,0x47,0x1d,0x05,0xd4,0x51,0x48,0x1d,0x1b,0xa9,0xa3,0x98,0x3a,
1540
0xb6,0x50,0xc7,0x36,0xea,0x28,0xa1,0x8e,0x52,0xea,0xd8,0x45,0x1d,0x65,0xd4,0x51,
1541
0x41,0x1d,0x95,0xd4,0xb1,0x8f,0x3a,0xaa,0xa9,0xa3,0x96,0x3a,0xea,0xa9,0xa3,0x91,
1542
0x4e,0xc6,0xd1,0xc9,0x04,0x3a,0x99,0x44,0x27,0x53,0xe8,0x64,0x2a,0x9d,0x5c,0x4a,
1543
0x27,0xd3,0xe9,0x64,0x26,0x9d,0x5c,0x41,0x27,0x57,0xd1,0xc9,0x2c,0x3a,0xb9,0x96,
1544
0x4e,0x66,0xd3,0xc9,0xf5,0x74,0x32,0x8f,0x4e,0x16,0xd0,0xc9,0x42,0x3a,0xb9,0x91,
1545
0x4e,0x16,0xd3,0xc9,0x2d,0x74,0x72,0x1b,0x9d,0x2c,0xa1,0x93,0xa5,0x74,0x72,0x17,
1546
0x75,0x16,0x52,0x67,0x11,0x75,0x6e,0xa4,0xce,0x4d,0xd4,0x59,0x4c,0x9d,0x9b,0xa9,
1547
0x73,0x0b,0x75,0x6e,0xa5,0xce,0x6d,0xd4,0xb9,0x9d,0x3a,0x4b,0xa8,0x73,0x07,0x75,
1548
0x96,0x52,0xe7,0x4e,0xea,0x44,0xe1,0xdd,0xd4,0x59,0x46,0x9d,0xe5,0xd4,0x59,0x41,
1549
0x9d,0x7b,0xa8,0xb3,0x92,0x3a,0xf7,0x52,0xe7,0x3e,0xea,0xac,0xa2,0xce,0x6a,0xea,
1550
0xac,0xa1,0xce,0x5a,0xea,0xac,0xa3,0xce,0x7a,0xea,0x6c,0xa0,0xce,0x46,0x3a,0xc5,
1551
0xd0,0xa9,0x38,0x3a,0x15,0x4f,0xa7,0x12,0xe8,0x54,0x22,0x9d,0x4a,0xa2,0x53,0xc9,
1552
0xd0,0x82,0x8c,0x0f,0xb6,0x9c,0xde,0x43,0xa7,0x97,0x20,0xf8,0x67,0x0a,0x9b,0x4a,
1553
0x43,0x70,0x76,0x53,0xd6,0xd9,0x4d,0x75,0x88,0xd6,0xe8,0xa3,0xb5,0xfa,0x28,0x57,
1554
0x1f,0x15,0xea,0xa3,0x22,0x7d,0x54,0xa2,0x8f,0x76,0x71,0xd1,0xe6,0xc2,0xb3,0x9b,
1555
0xd9,0xa8,0x48,0x1f,0xed,0xe2,0xa2,0xad,0xe5,0x67,0xb7,0xb2,0x51,0x95,0x3e,0x5a,
1556
0xa3,0x8f,0xd6,0xea,0xa3,0x5c,0x7d,0x54,0xc2,0x45,0x3b,0x0a,0xcf,0xee,0x60,0xa3,
1557
0x22,0x2e,0xaa,0x4e,0x3f,0x5b,0x55,0x4e,0x67,0x6b,0xd3,0xcf,0xd6,0x20,0xaa,0x29,
1558
0x39,0x5b,0x93,0xad,0x8f,0x0a,0xe9,0x6c,0xdd,0x52,0x3a,0x5b,0x1f,0x7f,0xb6,0x61,
1559
0x1f,0xa2,0x65,0xfa,0x68,0x85,0x3e,0x5a,0xa3,0x8f,0xd6,0xeb,0x23,0xe6,0x6c,0x43,
1560
0x25,0xa2,0xb2,0xb3,0xf5,0xe5,0xfa,0x08,0x9d,0x6b,0x28,0x3f,0xdb,0xc0,0x70,0x11,
1561
0x32,0xb8,0x54,0x45,0x7f,0x64,0xc8,0xe8,0xcf,0x5f,0xc9,0x35,0xd2,0x90,0xab,0x8f,
1562
0x0a,0xf5,0xd1,0x66,0x7d,0x54,0xa2,0x8f,0x96,0xb3,0x0a,0xce,0xef,0x61,0x40,0x1c,
1563
0x88,0x07,0x09,0x20,0x11,0x24,0x81,0x64,0x90,0x02,0x96,0x80,0x54,0x90,0x06,0x96,
1564
0x82,0x65,0x20,0x1d,0x64,0x80,0x4c,0xb0,0x1c,0xac,0x00,0x2b,0xc1,0x2a,0xb0,0x1a,
1565
0x64,0x81,0x35,0x60,0x2d,0x58,0x07,0xb2,0x01,0xa6,0xba,0x3d,0xeb,0x41,0x2e,0xc8,
1566
0x03,0xf9,0xa0,0x00,0x6c,0x00,0x85,0xa0,0x08,0x6c,0x04,0x9b,0x40,0x31,0xd8,0x02,
1567
0x4a,0xe9,0x5c,0x42,0x2e,0x9d,0xcb,0xdc,0x0d,0xca,0x40,0x39,0xa8,0x00,0x7b,0x40,
1568
0x25,0x5d,0xca,0x5e,0x4a,0xe7,0xca,0xd3,0x50,0x66,0x39,0x58,0x01,0x56,0x82,0x55,
1569
0x60,0x35,0xc8,0x02,0x6b,0xc0,0x5a,0xb0,0x0e,0x64,0x83,0x1c,0xb0,0x1e,0xe4,0x81,
1570
0x7c,0x50,0x00,0x36,0x80,0x42,0x50,0x04,0x36,0x82,0x4d,0xa0,0x18,0x6c,0x06,0x5b,
1571
0xc0,0x56,0xb0,0x0d,0x6c,0x07,0x25,0x60,0x07,0x60,0xed,0xda,0x09,0x76,0x01,0xd8,
1572
0x96,0x00,0xdb,0x12,0x60,0x5b,0x02,0x6c,0x4b,0x80,0x6d,0x09,0x95,0x60,0x2f,0xd8,
1573
0x07,0xaa,0x40,0x35,0xa8,0x01,0xf5,0xa0,0x01,0x34,0x52,0xeb,0x72,0x6a,0x85,0xc5,
1574
0xf0,0x7a,0x2b,0x3a,0x08,0x67,0x9d,0x83,0xb3,0xce,0xc1,0x31,0xe7,0xd0,0xf9,0x56,
1575
0x3c,0x0b,0xb3,0xa8,0xb5,0x80,0x5a,0x0b,0xa9,0x15,0x87,0x50,0x5d,0x89,0x27,0x00,
1576
0x1e,0x95,0x50,0xbc,0x37,0x89,0x8e,0xe0,0x4c,0x19,0xb5,0xee,0xa6,0xd6,0x0a,0x6a,
1577
0xdd,0x43,0xad,0x55,0x74,0x04,0x4f,0x10,0x18,0x07,0xe7,0x1e,0x59,0x4e,0x47,0xd0,
1578
0x70,0x55,0x1c,0x48,0x00,0x49,0x20,0x05,0xa4,0x02,0xb8,0xab,0x2a,0x1d,0x64,0x02,
1579
0xb6,0x0c,0x5c,0x55,0x05,0x37,0x55,0x41,0x73,0x15,0xdc,0x53,0x05,0xd7,0x54,0xc1,
1580
0x82,0x2a,0xb8,0xa5,0x0a,0x2e,0xa9,0x82,0x3b,0xaa,0xe0,0x8a,0x2a,0xb8,0xa1,0x0a,
1581
0x2e,0xa8,0x82,0x86,0x2a,0x58,0x50,0x85,0x6e,0x57,0xa1,0xcb,0x55,0xe8,0x6e,0x15,
1582
0xba,0x5a,0x85,0x6e,0x56,0xa1,0x8b,0x55,0xb5,0x00,0x5d,0xac,0x6a,0xa4,0x73,0xd5,
1583
0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,
1584
0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,
1585
0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,
1586
0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,
1587
0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0xd5,0xd0,0x5f,0x0d,0xfd,0x35,
1588
0xd0,0x5f,0x03,0xfd,0x35,0xd0,0x5f,0x03,0xfd,0x35,0xd0,0x5f,0x03,0xfd,0x35,0xd0,
1589
0x5f,0x03,0xfd,0x35,0xd0,0x5f,0x03,0xfd,0x35,0x59,0x34,0xe6,0x48,0x03,0x35,0x43,
1590
0x25,0x6e,0xce,0x73,0x35,0x50,0x59,0x03,0x95,0x35,0x50,0x59,0x03,0x95,0x35,0x50,
1591
0x59,0x03,0x95,0x35,0x50,0x59,0x03,0x95,0x35,0x50,0x59,0x03,0x95,0x35,0x50,0x59,
1592
0x03,0x95,0x35,0x50,0x59,0x03,0x95,0x35,0x50,0x59,0x0b,0x95,0xb5,0x50,0x59,0x0b,
1593
0x95,0xb5,0x50,0x59,0x0b,0x95,0xb5,0x50,0x59,0x0b,0x95,0xb5,0x50,0x59,0x0b,0x95,
1594
0xb5,0x50,0x59,0x8b,0x2e,0xd7,0xa2,0xcb,0xb5,0xe8,0x72,0x2d,0xba,0x5c,0x8b,0x2e,
1595
0xd7,0x42,0x7f,0x2d,0xf4,0xd7,0x42,0x7f,0x2d,0xf4,0xd7,0x42,0x7f,0x2d,0xf4,0xd7,
1596
0x42,0x7f,0x2d,0xf4,0xd7,0x42,0x7f,0x2d,0xf4,0xd7,0x42,0x7f,0x2d,0xf4,0xd7,0x42,
1597
0x7f,0x2d,0xf4,0xd7,0x42,0x7f,0x2d,0xf4,0xd7,0x42,0x7f,0x1d,0x03,0x60,0x43,0x5d,
1598
0x3c,0x80,0x1d,0x75,0x89,0x00,0xb6,0xd4,0x25,0x03,0xd8,0x53,0x87,0xbb,0xa4,0x0e,
1599
0x36,0xd4,0xe1,0x2e,0xa9,0x83,0x1d,0x75,0xb8,0x4b,0xea,0x60,0x4b,0x1d,0xee,0x80,
1600
0x3a,0xe8,0xae,0xc3,0x1d,0x50,0x07,0xfd,0x75,0xb8,0x03,0xea,0x60,0x43,0x1d,0xee,
1601
0x80,0x3a,0xd8,0x51,0x87,0x11,0x5e,0x07,0xdd,0x75,0x18,0xe1,0x75,0xd0,0x5f,0x87,
1602
0x11,0x5e,0x07,0x1b,0xea,0x30,0xc2,0xeb,0x60,0x47,0x3d,0xf4,0xd6,0x43,0x6f,0x3d,
1603
0xf4,0xd6,0x43,0x6f,0x3d,0xf4,0xd6,0x43,0x6f,0x3d,0x74,0xd5,0x43,0x4f,0x3d,0x74,
1604
0xd4,0xa3,0xbf,0xf5,0xd0,0x53,0x0f,0x3d,0xf5,0xd0,0x53,0x0f,0x3d,0xf5,0xd0,0x53,
1605
0x0f,0x3d,0xf5,0xd0,0x53,0xcf,0xea,0x61,0xb0,0x4e,0x41,0x0f,0xb8,0x30,0x9e,0x0b,
1606
0x13,0xb8,0x30,0x91,0x0b,0x93,0xb8,0x30,0x99,0x0b,0x53,0xb8,0x70,0x03,0x17,0x16,
1607
0x72,0x61,0x11,0x17,0x6e,0xe4,0xc2,0x4d,0x5c,0x58,0xcc,0x85,0x9b,0xb9,0x70,0x0b,
1608
0x1b,0xd6,0x73,0xe5,0xeb,0xb9,0xf2,0xf5,0x5c,0xf9,0x7a,0xae,0x7c,0x3d,0x57,0xbe,
1609
0x9e,0x2b,0x5f,0xcf,0x95,0xaf,0xd7,0x97,0xdf,0x8d,0xf0,0x58,0x19,0x1b,0xec,0x60,
1610
0x8f,0x1b,0xf6,0x72,0x21,0xbc,0xd1,0x50,0xc6,0x9e,0xc5,0x72,0x6a,0x15,0x39,0x1f,
1611
0x8d,0x67,0x97,0x55,0x47,0xd9,0xbe,0xef,0x61,0x8b,0xee,0x63,0x83,0x9d,0x6c,0xc9,
1612
0x46,0xce,0x56,0xcc,0xde,0x38,0xc3,0x96,0xc5,0x1a,0x8d,0x0d,0xd9,0x75,0xdc,0x2a,
1613
0x94,0x3f,0x86,0xcb,0xd1,0xc8,0xc2,0xba,0x69,0x2f,0x32,0x57,0x73,0x05,0x56,0x73,
1614
0x05,0x56,0xb3,0x05,0xa0,0xa9,0x11,0x3e,0x6b,0x64,0x7d,0x86,0xd9,0xa3,0xb1,0x98,
1615
0x5b,0xc0,0x31,0xf4,0x0a,0x8e,0xeb,0xd0,0x76,0x5b,0x2a,0x1b,0x64,0x70,0xba,0x38,
1616
0xdb,0xea,0xab,0xd8,0x33,0x6c,0x75,0x3a,0xcf,0x2c,0x47,0x8c,0x85,0x26,0x53,0x8e,
1617
0x1f,0x43,0xa4,0x4f,0x55,0xe2,0xc7,0x10,0xb1,0xa9,0x91,0x23,0x51,0x30,0x89,0xd8,
1618
0x2d,0xec,0x48,0x1a,0xa9,0xb9,0x59,0x94,0x2d,0xed,0x4f,0x01,0x14,0x48,0x6a,0x0a,
1619
0xa2,0x60,0x0a,0x21,0x2f,0x3a,0xbf,0x64,0x25,0x45,0x90,0x8c,0xe4,0x34,0x67,0x2e,
1620
0x8d,0xf1,0x1b,0x07,0xe6,0xd2,0x3b,0xbb,0xc7,0xd1,0x38,0xbf,0x99,0x60,0x1e,0xd2,
1621
0x13,0x69,0xc6,0x4c,0x9a,0x3b,0x9d,0x5e,0x9b,0x30,0x8d,0x5e,0x9b,0x4e,0xe7,0x93,
1622
0x32,0xe8,0xfd,0xe5,0xf4,0xfe,0x0a,0x7a,0x7f,0x25,0xbd,0xbf,0x8a,0x26,0x8e,0x79,
1623
0x03,0xad,0xac,0xe0,0x76,0x4e,0x41,0x5c,0x18,0xc2,0x85,0x0a,0x7f,0x2e,0x52,0x91,
1624
0x92,0x0b,0xd9,0x74,0x20,0x97,0x0e,0xe4,0xb6,0x57,0x81,0x14,0xc0,0x85,0x6c,0xbe,
1625
0x9a,0x02,0xb9,0x90,0x4d,0x07,0x73,0x67,0x83,0xb9,0x9c,0x60,0x0a,0xe2,0x42,0x36,
1626
0x9f,0x26,0x4f,0xc6,0x0f,0x98,0x4f,0xf3,0x27,0xe3,0x87,0x03,0x87,0x6f,0xd0,0x1b,
1627
0x93,0xf1,0x33,0x99,0xce,0x27,0x27,0x92,0x3f,0xa7,0xea,0xfc,0x92,0x12,0xfc,0x18,
1628
0x22,0x7d,0x6a,0x27,0x7e,0x0c,0x11,0x9b,0xfa,0x94,0x59,0x02,0x52,0x89,0xb5,0x11,
1629
0x3b,0x3f,0x25,0x29,0x60,0x20,0x36,0x7f,0x30,0x07,0x56,0xa0,0x17,0xd0,0x19,0x42,
1630
0x4a,0x7f,0x92,0x29,0xe4,0x24,0x53,0x02,0x15,0x08,0x00,0x81,0x40,0x0d,0x82,0x40,
1631
0x30,0x08,0x01,0x0a,0x7f,0x36,0x60,0x4b,0x2a,0xd8,0xa2,0x0a,0xb6,0xac,0x82,0x2d,
1632
0xac,0x60,0x4b,0x2b,0xd8,0xe2,0x0a,0xb6,0xbc,0x82,0xad,0xa0,0x60,0x6b,0x28,0xd9,
1633
0x1a,0x63,0xc0,0x58,0x30,0x0e,0x8c,0x07,0x13,0xc0,0x44,0x30,0x09,0xbc,0x0a,0x26,
1634
0x83,0x29,0x60,0x2a,0x98,0x06,0xa6,0x83,0x19,0x60,0x26,0x98,0x05,0x66,0x83,0x39,
1635
0x60,0x2e,0x78,0x0d,0xcc,0x03,0xf3,0xc1,0xeb,0xe0,0x0d,0xb0,0x00,0x2c,0x94,0xdf,
1636
0x74,0x03,0xeb,0x89,0xd0,0xd0,0x08,0x8a,0x60,0x7f,0x22,0xe8,0x7c,0x49,0xde,0x7b,
1637
0x55,0x74,0x7e,0xf7,0x6e,0x50,0x06,0x30,0x92,0x76,0x63,0x78,0xed,0xde,0x03,0x30,
1638
0x9c,0x76,0xef,0x05,0xfb,0x00,0x5b,0xa6,0x1a,0xd4,0x80,0x5a,0x50,0x07,0xea,0x41,
1639
0x03,0x68,0xc4,0x6e,0x07,0xcb,0x8d,0x32,0x2c,0x37,0xca,0xb0,0xdc,0x28,0xc3,0x72,
1640
0xa3,0x0c,0xcb,0x8d,0x32,0x2c,0x37,0xca,0xb0,0xdc,0x28,0xc3,0x72,0xa3,0x0c,0xcb,
1641
0x8d,0x32,0x2c,0x37,0xca,0xb0,0xdc,0x28,0xc3,0x72,0xa3,0x0c,0xcb,0x8d,0x32,0x2c,
1642
0x37,0xca,0xb0,0xdc,0x28,0xc3,0x72,0xa3,0x0c,0xcb,0x8d,0x32,0x2c,0x37,0xca,0xb0,
1643
0xdc,0x28,0xc3,0x72,0xa3,0x0c,0x43,0xbd,0x0c,0xcb,0x8d,0x32,0x2c,0x37,0xca,0xb0,
1644
0xdc,0x28,0xc3,0x72,0xa3,0x0c,0xcb,0x8d,0x32,0x76,0x67,0x85,0xe5,0x46,0x19,0x96,
1645
0x1b,0x65,0x58,0x6e,0x94,0x61,0xb9,0x51,0x86,0xe5,0x46,0x19,0x9e,0xa8,0x98,0x53,
1646
0x2b,0xeb,0xa9,0x15,0x56,0x95,0x6d,0x05,0xdb,0xc1,0x0e,0xc0,0xee,0xca,0xf6,0xd2,
1647
0x61,0x3c,0x9b,0x61,0x63,0x39,0x6c,0x2c,0x87,0x7d,0xe5,0xb0,0xad,0x1c,0x76,0x95,
1648
0xc3,0xa6,0x72,0xd8,0x53,0x0e,0x5b,0xca,0x61,0x47,0x39,0x6c,0x28,0x87,0xfe,0x72,
1649
0xe8,0x2e,0x87,0xde,0x72,0xe8,0x2c,0x87,0xbe,0x72,0xe8,0x2a,0x87,0x9e,0x72,0x2c,
1650
0x69,0xca,0xb1,0x9c,0x29,0xc7,0x52,0xa6,0x1c,0x4b,0x99,0xf2,0x6d,0x00,0x43,0xab,
1651
0xbc,0x14,0xec,0x02,0xf0,0x61,0x39,0x34,0x96,0xc3,0x77,0xe5,0xf0,0x5b,0x39,0x7c,
1652
0x56,0x0e,0x7f,0x95,0xc3,0xaa,0x72,0xf8,0xa9,0x02,0xfa,0x2b,0xa0,0xbf,0x02,0xfa,
1653
0x2b,0xa0,0xbf,0x02,0xfa,0x2b,0xa0,0xbf,0x02,0xfa,0x2b,0xa0,0xbf,0x02,0xfa,0x2b,
1654
0xa0,0xbf,0x02,0xfa,0x2b,0xa0,0xbf,0x02,0xfa,0x2b,0xa0,0xbf,0x02,0xfa,0x2b,0xa0,
1655
0xbf,0x02,0xfa,0x2b,0xa0,0xbf,0x02,0x3d,0xab,0xc0,0x58,0xae,0x80,0xae,0xca,0x42,
1656
0xea,0xde,0x95,0x4e,0xbd,0x0d,0x05,0x74,0xa1,0x8a,0x01,0x5b,0xc1,0x5e,0xd0,0x48,
1657
0x17,0xf0,0xfc,0xbd,0x80,0x67,0xe5,0x85,0x9a,0x65,0x60,0x03,0xa8,0xa1,0xae,0xc4,
1658
0x46,0xea,0x4a,0x2a,0x06,0x25,0xd4,0x95,0x1c,0x0f,0xd6,0x00,0xa4,0x53,0x36,0x80,
1659
0x4a,0xea,0x5a,0xc2,0x50,0x57,0xda,0x7a,0xea,0x5a,0x5a,0x4d,0x5d,0xcb,0xb2,0x40,
1660
0x0e,0xa8,0xa2,0xae,0xf4,0x38,0x90,0x0b,0xb6,0x51,0x57,0x06,0xea,0x65,0xec,0xa5,
1661
0xae,0xcc,0x25,0x60,0x23,0x75,0xad,0x5f,0x4b,0x5d,0xb9,0x05,0xd4,0xb5,0x11,0xed,
1662
0x6c,0xc2,0xb9,0x4d,0x69,0x00,0x75,0x37,0x6d,0xa1,0xae,0xe2,0x0a,0xea,0x2a,0x5d,
1663
0x4e,0x5d,0x3b,0xd1,0xee,0x2e,0xb4,0xb3,0x3b,0x13,0x14,0x01,0xa4,0xcb,0x76,0x82,
1664
0x32,0xea,0xda,0x07,0x7d,0xfb,0x60,0xd3,0x3e,0x36,0xdd,0x40,0x5d,0xd5,0xe5,0x00,
1665
0xb6,0xe2,0x99,0xdf,0x55,0xbb,0x07,0x20,0x0f,0x2b,0xec,0x2e,0x3c,0xe0,0xba,0xea,
1666
0xd1,0x16,0x1e,0x38,0x5d,0xf5,0x68,0xb7,0x31,0x81,0xba,0x97,0x2c,0x01,0x7b,0xa9,
1667
0x3b,0x75,0x29,0x75,0xaf,0xde,0x05,0xf6,0x50,0xf7,0x9a,0x14,0xb0,0x16,0x6c,0x02,
1668
0xd5,0xd4,0xbd,0x76,0x03,0x28,0xa6,0xee,0xf5,0xbb,0xa9,0x3b,0x17,0xe5,0x73,0xb7,
1669
0x52,0xf7,0x0e,0xe4,0x95,0x16,0x01,0x9c,0xdf,0x59,0x01,0x1f,0xa2,0xfe,0xae,0xd5,
1670
0x60,0x3d,0x75,0xc3,0xc6,0xee,0xdd,0x48,0xe3,0x3e,0xb8,0x18,0x57,0x42,0x17,0x97,
1671
0x6c,0x07,0x7b,0x41,0x2d,0x68,0xa4,0x8b,0xa9,0x29,0x20,0x1b,0xac,0xa7,0x8b,0x69,
1672
0x3b,0xe8,0x62,0x46,0x22,0x48,0xa5,0x8b,0xab,0x72,0xc1,0x66,0xba,0xb8,0x7a,0x1d,
1673
0x28,0x00,0x5b,0xc1,0x6e,0xba,0xb8,0x66,0x29,0x58,0x49,0x17,0xb3,0xd1,0x46,0x76,
1674
0x3d,0x5d,0xcc,0xd9,0x09,0xd0,0xce,0x7a,0xc4,0x05,0x68,0xa3,0xa0,0x08,0x54,0xd0,
1675
0xc5,0x4d,0x35,0x74,0x71,0x73,0x15,0x68,0xa0,0x8b,0xdb,0xa0,0xbb,0x04,0xf5,0x4a,
1676
0xaa,0xe9,0x22,0x46,0xf1,0xc5,0x0a,0xe4,0xe3,0xe1,0x7c,0x11,0x0f,0xe0,0x8b,0x0d,
1677
0x69,0xa0,0x9e,0x7a,0x98,0x38,0xb0,0x0c,0xac,0x04,0x15,0xd4,0x13,0xd7,0x48,0x3d,
1678
0xf1,0xa9,0xd4,0x93,0xb2,0x11,0x6c,0x07,0xc8,0x4b,0xa9,0xa3,0x9e,0x25,0x28,0xb3,
1679
0x64,0x3d,0x28,0xa0,0x9e,0xd4,0x9d,0xa0,0x1c,0x54,0x51,0x4f,0x76,0x3a,0x28,0xa1,
1680
0x9e,0x42,0x06,0xa0,0x4c,0x21,0xea,0x15,0x37,0x50,0xcf,0xe6,0xa5,0xd4,0xb3,0x05,
1681
0x6d,0x6e,0x45,0x3e,0xee,0xff,0x1e,0xdc,0xc7,0x3d,0xb8,0x1f,0x7b,0xca,0x50,0x07,
1682
0xf7,0x42,0x4f,0xe5,0x26,0xb0,0x9b,0x7a,0xf6,0xa2,0x7d,0x2c,0xa6,0x7a,0x6a,0xd3,
1683
0xa8,0xa7,0x01,0xed,0xe3,0x31,0xda,0x83,0xed,0x47,0x6f,0xfc,0x0a,0xea,0x4d,0x4a,
1684
0xa5,0xde,0x94,0x64,0xb0,0x0c,0xe0,0x38,0x6b,0x1f,0xf5,0xae,0x61,0xa8,0x77,0x5d,
1685
0x2e,0xf5,0xe6,0xec,0x05,0xd5,0xd4,0xbb,0x7e,0x2b,0xf5,0xe6,0xe1,0x5c,0x5e,0x3e,
1686
0x28,0x02,0xdb,0xa8,0xb7,0x60,0x29,0x28,0x05,0x15,0xd4,0xbb,0x21,0x8e,0x7a,0x8b,
1687
0x50,0x66,0xe3,0x7a,0x50,0x40,0xbd,0x9b,0xd7,0x80,0x6c,0xb0,0x83,0x7a,0xb7,0x23,
1688
0xbf,0x64,0x1d,0x40,0xfe,0x8e,0x62,0xb0,0x0b,0x94,0x83,0x3a,0xea,0x2d,0xcd,0xa1,
1689
0xde,0x0a,0xe4,0x61,0x1d,0xd9,0x8b,0x31,0xd4,0x8b,0xc5,0x5f,0x2f,0x16,0x75,0xbd,
1690
0x58,0xc8,0xf5,0x62,0xe1,0xd6,0x8b,0x45,0x5b,0x2f,0x16,0x5a,0xbd,0x58,0x64,0xf5,
1691
0xd6,0x65,0x80,0x55,0x60,0x03,0x40,0x99,0xfa,0x34,0xb0,0x12,0xf7,0x13,0x7b,0x4f,
1692
0xc1,0xd6,0x86,0x0d,0xe4,0x8b,0xe7,0xc4,0x4a,0x8c,0xfc,0x44,0x90,0x44,0xce,0x9f,
1693
0xc6,0x67,0xb3,0x41,0x0e,0x7d,0x1a,0xbf,0xe4,0xd3,0xf8,0x34,0x44,0x15,0x9f,0x26,
1694
0x2c,0xa1,0x73,0x89,0x58,0x32,0x25,0x62,0xc9,0x94,0x8c,0x95,0x7d,0x22,0x96,0x0e,
1695
0xc9,0xd8,0x54,0x24,0x63,0x99,0x97,0x88,0xe5,0x53,0x22,0x96,0x4f,0x89,0x58,0x3e,
1696
0x25,0xe3,0xf1,0x9f,0x8c,0x85,0x46,0x32,0x16,0x10,0xc9,0x58,0x76,0x25,0x63,0xd9,
1697
0x95,0x8c,0x65,0x57,0x22,0x36,0x31,0x89,0x58,0xd2,0x25,0x62,0x49,0x97,0xc8,0xb6,
1698
0x85,0xe5,0x41,0x22,0x96,0x9a,0x89,0xd8,0x08,0x25,0x62,0xb9,0x99,0xb8,0x0c,0x60,
1699
0xc9,0x99,0x98,0x01,0xb0,0xec,0x4c,0xc4,0x1a,0x23,0x11,0x6b,0x8c,0x44,0x2c,0xfb,
1700
0x92,0x50,0x36,0x09,0xcb,0xaf,0x24,0x2c,0xbf,0x92,0xb0,0xfc,0xc2,0xdd,0x7d,0x2e,
1701
0x09,0xcb,0xaf,0x24,0x2c,0xbf,0x92,0xb0,0xd1,0x49,0xc2,0x92,0x33,0x09,0x36,0xe1,
1702
0x8e,0x3f,0x97,0x04,0x9b,0x92,0x60,0x53,0x12,0x36,0x3a,0x49,0x58,0x7e,0x26,0xc1,
1703
0x9e,0x24,0xd8,0x93,0x04,0x7b,0x92,0x60,0x4f,0x12,0xec,0x49,0x62,0xed,0xc1,0x32,
1704
0x32,0x11,0x4b,0xbc,0x14,0xd8,0x93,0x02,0x7b,0x70,0x15,0xcf,0xa5,0x40,0x77,0x0a,
1705
0x96,0x7e,0x29,0x58,0xf6,0xa5,0x60,0x99,0x9b,0x88,0x3d,0x4e,0x0a,0x96,0xb9,0x29,
1706
0x58,0xe6,0x26,0x22,0x4e,0xc4,0xe6,0x2b,0x11,0x4b,0x9b,0x44,0xd8,0x92,0x08,0x5b,
1707
0x12,0xa1,0x3f,0x11,0xba,0x13,0xa1,0x37,0x11,0x7a,0x13,0x59,0x5f,0x40,0x6f,0x22,
1708
0xf4,0x26,0x42,0x5f,0x22,0x96,0x9a,0x49,0xf0,0x59,0x12,0x74,0x24,0xb1,0xed,0xc3,
1709
0x8e,0x14,0xd6,0x0e,0xb4,0x9f,0x84,0xcd,0x5d,0x12,0x74,0xe0,0x79,0x7e,0x2e,0x99,
1710
0xf5,0x1b,0x6c,0x48,0x46,0x7f,0x93,0xd1,0xdf,0x64,0xd8,0x96,0x0c,0x5d,0xc9,0x85,
1711
0x98,0xe5,0x52,0x31,0xfb,0xac,0x47,0x9c,0x06,0x4a,0x01,0xee,0x98,0xd5,0xe5,0x88,
1712
0x31,0xf3,0x61,0xb7,0xd4,0xb5,0x09,0xb3,0x55,0xee,0x6e,0x92,0xe1,0xe2,0xc8,0xd9,
1713
0x30,0x9e,0x0b,0x13,0xb8,0x30,0x89,0x0b,0x93,0xb9,0x30,0x85,0x0b,0x53,0xb9,0x70,
1714
0x29,0x17,0x2e,0xe3,0xc2,0x0c,0x2e,0xcc,0xe4,0xc2,0xe5,0x5c,0xb8,0x82,0x0b,0x57,
1715
0x22,0xbc,0xb4,0x9b,0x6d,0xf3,0xb3,0xf8,0x75,0x6c,0xb8,0x74,0x13,0x1b,0xe6,0xd5,
1716
0xb1,0xe1,0x96,0x25,0x6c,0xb8,0x7b,0x35,0xc2,0xcf,0xe3,0x77,0xb0,0x61,0x56,0x22,
1717
0x1b,0xe6,0xb3,0x2d,0x7c,0xbe,0x7b,0x2b,0x1b,0x56,0xef,0x41,0x78,0x39,0x81,0x6d,
1718
0xe1,0xf2,0x32,0x56,0xd7,0xe5,0x2c,0xb6,0x9d,0xcf,0x37,0xb2,0x2d,0x7c,0xbe,0x6e,
1719
0xd3,0xe7,0x1b,0x12,0xf5,0x89,0xcb,0xeb,0xd9,0x04,0xa6,0x76,0x36,0xac,0x59,0xc6,
1720
0xa5,0x59,0x3b,0xd1,0x6d,0x2e,0x87,0xd5,0xd2,0x95,0x54,0xca,0xe5,0x27,0x70,0xe9,
1721
0x12,0x36,0x5d,0x9d,0xc7,0xa6,0xd3,0xe3,0x10,0x62,0xca,0x43,0x88,0x89,0x8c,0x4d,
1722
0xef,0xde,0xc3,0xe5,0xb0,0x36,0xe0,0xb6,0x64,0xcb,0xe4,0x16,0xb0,0x39,0x6b,0x8b,
1723
0xd9,0x70,0xc3,0x76,0xee,0x2c,0xdb,0xfe,0xc5,0x4d,0x0d,0xec,0xd9,0xe5,0xe9,0x6c,
1724
0x3a,0xb5,0x1a,0x61,0x4f,0x79,0x21,0x9b,0x2e,0xe6,0x5a,0x4e,0x63,0xdb,0xb9,0x50,
1725
0xbb,0x91,0x4d,0xaf,0x60,0x6d,0xee,0x2a,0xdd,0xcc,0x9e,0x5d,0xcf,0xe6,0x5c,0xa8,
1726
0x63,0xf5,0xf6,0x54,0xa4,0x70,0x36,0xac,0xe6,0x6a,0x71,0x16,0xd6,0xb1,0x1a,0x31,
1727
0x35,0x71,0x61,0x85,0x9c,0xba,0xb2,0xf0,0x34,0xa8,0xae,0xa3,0x8b,0x3b,0x33,0x69,
1728
0xd6,0x6b,0x13,0x48,0xa9,0x20,0xa5,0x92,0x94,0x58,0x2f,0x06,0x90,0x12,0x2b,0x45,
1729
0x35,0x29,0x83,0x48,0x19,0x4c,0xca,0x10,0x52,0xf9,0x93,0x4a,0x41,0x2a,0x25,0xa9,
1730
0x54,0xa4,0x0a,0x20,0x55,0x20,0xc1,0xff,0x04,0xef,0x13,0x7c,0x4f,0xf0,0x3c,0xc1,
1731
0xef,0x04,0xaf,0x13,0x7c,0x4e,0xf0,0x38,0xc1,0xdf,0x04,0x6f,0x13,0x7c,0x4d,0xf0,
1732
0x34,0xc1,0xcf,0x04,0x2f,0x23,0xaf,0xea,0x52,0xc5,0x06,0x82,0xab,0x3f,0xcf,0xc3,
1733
0x51,0xce,0x6e,0x3c,0x18,0x57,0xe3,0x81,0xc8,0x0e,0x9f,0x04,0x3c,0x34,0xf3,0x08,
1734
0x7e,0xc0,0x43,0x02,0x13,0xfa,0x26,0x3c,0x78,0x96,0xa7,0x63,0xa2,0xaf,0xc6,0xc4,
1735
0x57,0x48,0xe8,0x3b,0x1e,0x8e,0x98,0x98,0xb7,0xb0,0x13,0x3c,0x26,0xb4,0x38,0x0c,
1736
0xaf,0xc4,0xed,0x98,0x16,0xf0,0x60,0xa9,0xc0,0x84,0xb4,0x01,0x0f,0x5b,0xec,0xc6,
1737
0xba,0x92,0xb3,0xf1,0x60,0xc1,0x83,0x71,0xdf,0x66,0x3c,0x20,0xf1,0xa0,0x5a,0x56,
1738
0x8b,0x07,0x20,0x1e,0x92,0xa5,0x78,0x38,0xac,0xdf,0x88,0x32,0x98,0xb8,0xb1,0x00,
1739
0x80,0x6f,0x30,0x44,0x73,0x49,0xa5,0x26,0x55,0x10,0xa9,0xb0,0xec,0x0d,0xa1,0x00,
1740
0xac,0xce,0x15,0x14,0xa0,0xa4,0x00,0x15,0x05,0x04,0x50,0x00,0xd6,0xc8,0x6a,0x0a,
1741
0x08,0xa2,0x80,0x60,0x0a,0x08,0xa1,0x40,0x2c,0x56,0xd9,0x47,0x98,0x92,0x0d,0x54,
1742
0x6c,0x10,0xc0,0x06,0x81,0x6c,0xa0,0x66,0x83,0x20,0x36,0x08,0x66,0x83,0x10,0x36,
1743
0x50,0xf8,0x73,0x21,0x57,0x47,0xc1,0x55,0x7a,0x75,0x12,0x4d,0x98,0x03,0xe6,0xd3,
1744
0xb4,0xd7,0xc6,0x63,0xee,0x2a,0x02,0x9b,0xc0,0x66,0xb0,0x15,0x6c,0x07,0x25,0xa0,
1745
0x14,0xec,0x02,0x65,0xec,0xfc,0x06,0x2a,0xc1,0x3e,0x50,0x0d,0x6a,0x41,0x3d,0x68,
1746
0xa4,0x4f,0x13,0xe2,0x40,0x22,0x48,0x26,0x76,0x12,0xfc,0x34,0x01,0xf3,0x61,0xc2,
1747
0x52,0xb0,0x0c,0xa4,0x83,0x0c,0x90,0x09,0x56,0x82,0x2c,0xb0,0x0e,0xac,0x07,0xf9,
1748
0xa0,0x00,0x6c,0x00,0x85,0x00,0x76,0x24,0xc0,0x8e,0x04,0xd8,0x91,0x00,0x3b,0x12,
1749
0xb6,0x01,0xd8,0x92,0x00,0x5b,0x12,0x76,0x00,0xd8,0x93,0x00,0x7b,0x12,0x76,0x03,
1750
0xd8,0x94,0x80,0x9b,0xbc,0x76,0x53,0xd7,0xca,0x65,0x6c,0x17,0x3e,0x4d,0x58,0xf1,
1751
0x69,0x42,0x1d,0xa7,0x9f,0x3d,0x28,0x81,0xa6,0x4f,0xe3,0x0b,0xf5,0x07,0x98,0x9b,
1752
0x73,0xf4,0xbd,0x2c,0xe2,0xca,0xb0,0x7d,0xdb,0x04,0x13,0xd9,0x33,0xf1,0xbb,0xf5,
1753
0x07,0x15,0x5c,0x37,0xe2,0x37,0x7f,0x1a,0xbf,0x0d,0x07,0xac,0x23,0xd0,0x4f,0x74,
1754
0x9f,0xab,0x90,0xca,0x1d,0x23,0x15,0x8f,0x76,0xeb,0x58,0x0f,0x71,0x55,0xab,0xf5,
1755
0xa9,0x3a,0xae,0x07,0x38,0xc5,0xb6,0xc3,0xf9,0x0e,0xa6,0x7f,0x9a,0x90,0xa0,0x37,
1756
0x06,0x07,0xa5,0xc8,0xd6,0xd7,0xdb,0xc1,0x1d,0x54,0xe8,0x53,0x15,0x9c,0x07,0xe2,
1757
0x77,0xe2,0x80,0x8b,0x58,0x83,0xd8,0x42,0x28,0x51,0x3c,0x50,0x63,0x27,0xd7,0x17,
1758
0x66,0xe0,0x4c,0xa9,0x21,0x82,0xe1,0x9c,0x96,0x0d,0xfd,0xc7,0x09,0x85,0xfa,0xfe,
1759
0xeb,0xbb,0xa7,0xcf,0xda,0x35,0x60,0xc5,0xcd,0xc2,0x86,0x14,0x57,0x92,0x35,0x64,
1760
0x17,0xab,0x20,0xbe,0x8e,0x33,0xbe,0x54,0x7f,0x5c,0xca,0xb5,0x94,0xce,0x5e,0x79,
1761
0xae,0xd3,0xd5,0xfa,0xe7,0x5b,0x09,0x77,0x65,0xd9,0x14,0xce,0xe6,0xb1,0xe3,0x81,
1762
0xad,0xc4,0x35,0xc0,0x1d,0x70,0x3e,0x1c,0x70,0xc7,0x3e,0xae,0x0b,0x06,0x07,0xd7,
1763
0x0e,0x38,0x58,0x9f,0x62,0x47,0x09,0xd3,0xdf,0x76,0x42,0x0a,0x37,0xac,0x12,0x52,
1764
0xf5,0x57,0x5a,0x6f,0x57,0x42,0x9a,0x7e,0xdc,0x64,0xf4,0x77,0x21,0x21,0x93,0x33,
1765
0x91,0x1d,0x67,0xdc,0x95,0xbe,0xa5,0x25,0xfd,0x95,0x67,0xcf,0x2c,0xe7,0x52,0x3b,
1766
0xf4,0x0d,0xad,0x66,0xaf,0x37,0x2e,0xa2,0xc1,0x27,0xec,0xf1,0xae,0x81,0x14,0xab,
1767
0x62,0x95,0xfe,0x88,0x1d,0x28,0xfd,0x57,0x2c,0x55,0x7f,0xbc,0xb1,0x7f,0x2c,0x25,
1768
0xac,0x61,0xb3,0xd1,0x99,0xf8,0x2d,0xfd,0x85,0x13,0xf4,0x03,0x24,0x61,0x1d,0xdb,
1769
0x5c,0x7c,0x63,0xff,0x88,0x62,0x87,0x58,0x3d,0x17,0xb1,0xd7,0x71,0x25,0x57,0x80,
1770
0x75,0x59,0xa2,0x3e,0x4f,0x3f,0x5c,0xd8,0x14,0x4c,0xaf,0x42,0x2a,0x9b,0x4b,0xb1,
1771
0xb7,0x4f,0x5e,0xff,0x00,0x64,0xf5,0xe5,0x72,0x95,0xd8,0xd4,0x7a,0xbd,0x9a,0x3c,
1772
0xee,0x54,0xaa,0x3e,0xc3,0xa0,0x4a,0x9f,0x62,0xcf,0xe6,0xf7,0x5f,0x82,0xd2,0xfe,
1773
0x03,0xae,0x40,0x3e,0xd7,0x99,0x4c,0x7d,0xaa,0x84,0xbb,0x8b,0xd9,0x54,0x05,0x77,
1774
0x59,0xb6,0xe8,0xab,0x16,0xf4,0x5f,0x6b,0xfd,0x01,0x77,0xa7,0x15,0x70,0x17,0x6d,
1775
0xf9,0x80,0xa2,0x42,0x6e,0x6c,0x72,0xd1,0xc0,0x85,0xb9,0x75,0x9c,0x25,0x6c,0xea,
1776
0xbf,0x3f,0x0c,0x29,0x36,0x6f,0xb3,0xfe,0xa6,0x23,0xae,0xad,0x84,0x81,0xa2,0xdb,
1777
0xf5,0x37,0x74,0x09,0xeb,0x7e,0x76,0x34,0xb3,0xa9,0x3a,0xce,0xc1,0xdc,0xfd,0xad,
1778
0x9f,0x06,0xf4,0xb7,0x05,0xd6,0x54,0xe5,0xfa,0x16,0xfa,0x47,0xb0,0xff,0x45,0xb8,
1779
0x4f,0xc1,0x06,0x4a,0x36,0x50,0xb1,0x41,0x00,0x1b,0x04,0xb2,0x81,0x9a,0x0d,0x82,
1780
0xd8,0x20,0x98,0x0d,0x42,0xb8,0xc2,0xfa,0x2a,0x5c,0x1d,0x05,0x57,0x49,0xc1,0xd5,
1781
0x52,0x70,0xd5,0x14,0x5c,0x3d,0x05,0x57,0x51,0xc1,0xd5,0x54,0x70,0x55,0x15,0x5c,
1782
0x5d,0x25,0x57,0x57,0xa9,0xd7,0xc7,0xd5,0x55,0x72,0x75,0x95,0x5c,0xdd,0x57,0x67,
1783
0x8d,0xa1,0xf1,0x63,0x68,0xcc,0x3c,0x1a,0x3b,0x66,0x0e,0xcd,0x9c,0x4f,0xb3,0xc6,
1784
0xd1,0xf8,0xe9,0xf8,0x51,0x02,0x15,0x4d,0x9e,0x87,0xe7,0x59,0x45,0xf7,0x92,0xe5,
1785
0xd4,0xbd,0xae,0x94,0x9d,0x9d,0xb0,0x07,0x62,0x9f,0x04,0xdd,0xeb,0x32,0xba,0xb1,
1786
0x13,0xc4,0x83,0xa5,0xab,0x2e,0xf3,0x42,0x5d,0x0e,0xfb,0x64,0x41,0x4b,0x33,0xc6,
1787
0xd0,0xb1,0xba,0x31,0x34,0x7d,0x0c,0x4d,0xc5,0xcf,0x58,0x9a,0x3e,0x96,0x26,0x8d,
1788
0xa5,0x71,0x63,0xa6,0xd1,0x54,0x36,0x98,0x35,0x91,0x66,0x4c,0x44,0x09,0x96,0x49,
1789
0x34,0x7d,0x12,0x4d,0x9d,0x44,0xaf,0x2e,0xa4,0xa9,0x60,0x3a,0x98,0x04,0x5e,0x03,
1790
0xc7,0xea,0xa6,0xd1,0xf4,0x69,0x34,0x1e,0xb5,0xa6,0xd1,0xc4,0xe9,0x34,0x63,0x3a,
1791
0xb2,0xa6,0xd3,0xf4,0xe9,0x34,0x6e,0x3a,0x4d,0x65,0x13,0x4a,0xa4,0x94,0x84,0x9f,
1792
0xa9,0x6c,0x04,0x3b,0xc7,0x01,0xfc,0x4c,0x65,0xa3,0xf3,0x4b,0xb2,0xe6,0xea,0x43,
1793
0x9c,0x87,0x51,0xd3,0xc1,0x24,0x30,0x67,0xcc,0x78,0x16,0xee,0xb4,0x21,0x56,0xd2,
1794
0xac,0xb9,0x34,0x63,0x2e,0x9a,0x47,0x8d,0xb9,0x34,0x6b,0x3e,0xcd,0x98,0x8f,0x83,
1795
0xf9,0x34,0x7d,0x3e,0x4d,0x85,0x2f,0x5e,0xa7,0x19,0xaf,0xe3,0xf8,0x75,0x9a,0xfe,
1796
0x3a,0x4d,0xc5,0x4f,0x5b,0x2a,0x4d,0x07,0x63,0x67,0xd3,0xb8,0x71,0x34,0x6e,0x3c,
1797
0x8d,0x43,0x23,0xe8,0xc3,0x78,0x74,0x73,0x01,0xbd,0x3a,0x06,0xde,0xa4,0xc9,0x33,
1798
0x68,0xea,0x54,0x9a,0xfa,0x1a,0x4d,0x9b,0x4e,0xd3,0x66,0xd0,0xb4,0x99,0x93,0x68,
1799
0xda,0x1b,0x34,0x7d,0x32,0xba,0x34,0x13,0x1e,0x78,0x95,0x66,0xcd,0x9a,0x4e,0xb3,
1800
0xe6,0xd0,0x5c,0xfc,0xcc,0xa7,0xd7,0xc7,0xd2,0x7c,0xb4,0x31,0x9d,0xc6,0x70,0xa1,
1801
0x82,0xdd,0xd6,0x29,0xd9,0x40,0xc5,0x06,0x01,0x6c,0x10,0xc8,0x06,0x6a,0x36,0x08,
1802
0x62,0x83,0x60,0x36,0x08,0x61,0x03,0x3c,0x0b,0xd9,0x90,0xab,0xa3,0xe0,0x2a,0x29,
1803
0xb8,0x5a,0x0a,0xae,0x9a,0x82,0xab,0xa7,0xe0,0x2a,0x2a,0xb8,0x9a,0x0a,0xae,0xaa,
1804
0x82,0xab,0xab,0xe4,0xea,0x2a,0xf5,0xfa,0xb8,0xba,0x4a,0xae,0xae,0x92,0xab,0xab,
1805
0xe4,0xea,0x2a,0xb9,0xba,0x4a,0xae,0xae,0x92,0xab,0xab,0xe4,0xea,0xaa,0xb8,0xba,
1806
0x2a,0xae,0xee,0x24,0x5c,0xd5,0x4b,0xd9,0x71,0x20,0x01,0x24,0x81,0x14,0x90,0x0a,
1807
0xd2,0x41,0x26,0x58,0x01,0x56,0x81,0x2c,0xb0,0x16,0x64,0x83,0xf5,0x20,0x0f,0x14,
1808
0x80,0x42,0xb0,0x11,0x14,0x83,0x2d,0x60,0x1b,0x28,0x01,0xa5,0x74,0x29,0x07,0xed,
1809
0xe6,0xa0,0xdd,0x1c,0xb4,0x9b,0x83,0x76,0x73,0xd0,0x6e,0xce,0x52,0x80,0xb6,0x73,
1810
0xd0,0x76,0x0e,0xda,0xce,0x41,0xdb,0x39,0x68,0x3b,0x07,0x6d,0xe7,0xa0,0xed,0x1c,
1811
0xb4,0x9d,0x8b,0xf6,0x72,0xd1,0x5e,0x2e,0xda,0xcb,0x45,0x7b,0xb9,0x68,0x2f,0x17,
1812
0xed,0xe5,0xee,0x02,0x15,0xa0,0x12,0xec,0x03,0xd5,0xa0,0x16,0xd4,0x83,0x46,0xba,
1813
0x94,0x07,0x7d,0x79,0xd0,0x97,0x07,0x7d,0x79,0xd0,0x97,0x07,0x7d,0x79,0xd0,0x97,
1814
0x07,0x7d,0x79,0xd0,0x87,0xad,0xdd,0xa5,0x3c,0xe8,0xcb,0x83,0xbe,0x3c,0xe8,0xcb,
1815
0x83,0xbe,0x3c,0xe8,0xcb,0x43,0x5f,0xf2,0xd0,0x97,0x3c,0xf4,0x25,0x0f,0xba,0xf3,
1816
0xa0,0x3b,0x0f,0xba,0xb1,0xfd,0xbb,0x94,0x07,0xdd,0x79,0xd0,0x9d,0x07,0xdd,0x79,
1817
0x35,0xa0,0x8e,0xce,0x55,0x42,0x6f,0x1e,0xf4,0xe5,0x43,0x5f,0x3e,0xf4,0xe5,0x43,
1818
0x5f,0x3e,0xf4,0xe5,0x2f,0x03,0xd0,0x91,0x0f,0x1d,0xf9,0x68,0x3f,0x1f,0xed,0xe7,
1819
0xa3,0xfd,0x7c,0xb4,0x9f,0x8f,0xf6,0xf3,0xd1,0x7e,0x3e,0xda,0xcf,0x47,0xfb,0xf9,
1820
0x68,0x3f,0x7f,0x1b,0xb5,0xee,0xa0,0x23,0xf9,0x74,0x04,0x95,0x4b,0xd9,0x4a,0xe8,
1821
0x58,0x3e,0x3a,0x96,0x0f,0x05,0xf9,0xe8,0x58,0x3e,0x3a,0x96,0x0f,0x45,0x05,0x50,
1822
0x54,0xc0,0x2a,0xc2,0x4e,0x63,0x6f,0x06,0xd2,0x4b,0x40,0x1a,0xb5,0x6e,0x42,0x84,
1823
0xbe,0x15,0xa0,0x6f,0x05,0xd0,0x5b,0x80,0x26,0x0a,0xd0,0xb7,0x02,0xe8,0x2e,0x80,
1824
0x6e,0x6c,0xe5,0x0f,0xae,0xa7,0xd6,0x7d,0xd4,0x5a,0x87,0x83,0xbd,0x74,0x69,0x07,
1825
0xda,0x2e,0x5d,0x49,0x47,0x50,0xa7,0x14,0x7e,0x29,0xc5,0x26,0x27,0x03,0x1b,0xa4,
1826
0x0c,0x6c,0xd8,0x32,0xb0,0x49,0xca,0xc0,0x26,0x29,0x03,0x1b,0xb6,0x0c,0x6c,0xd8,
1827
0x32,0xb0,0x61,0xcb,0xc0,0x86,0x29,0x03,0x1b,0xb6,0x0c,0x6c,0x9a,0x32,0xb0,0x61,
1828
0xcb,0xc0,0xc6,0x29,0x03,0x1b,0xa7,0x0c,0x6c,0x9c,0x32,0xb0,0x71,0xca,0xc0,0xc6,
1829
0x29,0x03,0x1b,0xb6,0x0c,0x6c,0x94,0x32,0xb0,0x51,0xca,0xc0,0x86,0x2d,0x03,0x1b,
1830
0xb6,0x0c,0x6c,0xd8,0x32,0xb0,0x99,0xca,0xd8,0x07,0xaa,0x40,0x35,0xa8,0x01,0xb5,
1831
0x00,0xfe,0xcb,0xa8,0x07,0x0d,0xa0,0x91,0xce,0x65,0x62,0xc3,0x95,0x89,0x4d,0x6a,
1832
0x26,0x36,0xa8,0x99,0xd8,0x98,0x66,0x62,0x83,0x95,0x89,0x0d,0x56,0x26,0x36,0x9f,
1833
0x99,0xd8,0x88,0x65,0x62,0xa3,0x95,0x89,0x8d,0x67,0x26,0x36,0x9e,0x99,0xd8,0x78,
1834
0x66,0xc2,0xe6,0x4c,0x6c,0x3c,0x33,0xb1,0xf9,0xcb,0xc4,0xc6,0x33,0x13,0x1b,0xcf,
1835
0x4c,0x6c,0xc4,0x32,0xb1,0x11,0xcb,0xc4,0x66,0x30,0x13,0x2e,0xca,0xc4,0x46,0x31,
1836
0x73,0x0d,0xc0,0xc6,0x2d,0x13,0x1b,0xb7,0x4c,0x6c,0xdc,0x32,0xb1,0xa1,0xcd,0x5c,
1837
0x0f,0xd8,0x6f,0xfa,0xb0,0x39,0xcc,0xc4,0x86,0x2d,0x13,0x1b,0xc5,0x4c,0xf4,0x3f,
1838
0x13,0xfd,0xcf,0x44,0xff,0x33,0xd1,0xff,0x4c,0xf4,0x3f,0x13,0xfd,0xcf,0x44,0xff,
1839
0x33,0xd1,0xff,0x4c,0xf4,0x3f,0x13,0xfd,0xcf,0x44,0xff,0x33,0xd1,0xff,0x4c,0xf4,
1840
0x3f,0x13,0xfd,0xcf,0x44,0xff,0x33,0x77,0x51,0x4f,0xd9,0x12,0xea,0x5e,0xbf,0x07,
1841
0xab,0x67,0xc4,0xd8,0xc6,0x5f,0xa8,0x2a,0xc7,0x0a,0xbb,0x98,0xba,0x8a,0xb1,0xea,
1842
0x5e,0x83,0x15,0x75,0x31,0xf2,0x53,0xd8,0xd7,0x2c,0xdb,0xe8,0x62,0x43,0x12,0xf5,
1843
0xac,0x6b,0xa4,0x9e,0xfc,0x1a,0xea,0xd9,0x58,0x45,0xbd,0xf1,0x99,0xd4,0xbd,0x35,
1844
0x9e,0xba,0xf7,0xac,0xa7,0x8b,0x09,0xd9,0x74,0x11,0x36,0xf5,0x2c,0xaf,0xa7,0x5e,
1845
0x6c,0x8e,0x7b,0xb7,0x94,0x61,0x17,0x10,0x8f,0x15,0x79,0x25,0x75,0xef,0x48,0xa4,
1846
0x8b,0xec,0xeb,0x92,0x75,0xa5,0xd4,0x5b,0x95,0x4f,0x5d,0x95,0x98,0xcd,0x1b,0x4b,
1847
0xa8,0x67,0x6d,0x3a,0xf5,0x14,0x6f,0xa2,0xee,0xa5,0xec,0x2b,0x96,0x75,0xd4,0xb3,
1848
0xa1,0x80,0xba,0x6a,0xd3,0xb0,0x53,0x58,0x4b,0xdd,0x95,0xdb,0xe9,0xe2,0xd2,0x3a,
1849
0xea,0xc5,0xba,0xe5,0x42,0x43,0x32,0x76,0x00,0xfb,0xa8,0x6b,0x69,0x3e,0x75,0xaf,
1850
0x4a,0xa4,0xee,0x92,0x55,0x68,0x6f,0x39,0x56,0xfe,0x5b,0xd0,0x66,0x32,0xf5,0x64,
1851
0xe7,0x52,0xcf,0xbe,0x5d,0xd4,0x9b,0x5b,0x4e,0xbd,0xa5,0x88,0xf7,0xd5,0xd0,0xc5,
1852
0xa2,0x65,0xd8,0x5d,0x34,0xd2,0xc5,0xbd,0x1b,0xa8,0x07,0xfe,0xef,0x5d,0x96,0x48,
1853
0x3d,0x25,0x6b,0xa8,0x6b,0x23,0x74,0xd4,0xc1,0x9e,0x32,0xe4,0xc7,0x35,0x60,0x27,
1854
0x52,0x44,0x17,0x37,0xa6,0xa1,0xff,0xf1,0xd4,0xbb,0x1e,0x3a,0x36,0xae,0xa3,0xae,
1855
0xb2,0x22,0xf4,0x6b,0x15,0x75,0xef,0xcb,0xa1,0xee,0xba,0x4c,0xba,0xb8,0x67,0x17,
1856
0x5d,0xac,0xc2,0xee,0x24,0x7b,0x29,0x6c,0x58,0x49,0x3d,0xf1,0x88,0x53,0x72,0x01,
1857
0x74,0x6c,0xcd,0x85,0x8e,0x06,0xe8,0x28,0xc3,0xf9,0x4a,0xea,0xd9,0xc9,0xa0,0x3f,
1858
0x99,0xd0,0xd5,0x00,0x5f,0x56,0x53,0xd7,0xae,0x2d,0xd4,0xcd,0xac,0xa4,0x8b,0x19,
1859
0x29,0x74,0x31,0x6b,0x37,0x76,0x2e,0x6b,0xa1,0xaf,0x16,0x7d,0x6a,0xa4,0xae,0x86,
1860
0x6d,0x28,0x93,0x8e,0x9d,0xce,0x32,0xea,0xce,0xaa,0x82,0x9e,0x22,0xf8,0x3e,0x81,
1861
0xba,0x0a,0xf3,0xe9,0x62,0x2e,0x76,0x34,0x2b,0xe0,0x97,0xed,0xd8,0x39,0xed,0xac,
1862
0xa1,0xee,0x72,0x5c,0x87,0xa5,0xd0,0xb3,0xb4,0x98,0xba,0x31,0xe6,0x2f,0x66,0x15,
1863
0xc3,0xbf,0x3b,0xb1,0xcb,0xc2,0x8e,0x29,0x25,0x95,0xba,0x8b,0xe2,0xe8,0x62,0x05,
1864
0xfc,0x91,0x8a,0x6b,0x5a,0xb2,0x92,0x7a,0x53,0xb0,0x11,0x5c,0x5a,0x49,0x5d,0x2b,
1865
0x70,0x0d,0x6a,0x77,0x50,0xf7,0xda,0x24,0xf8,0x1c,0xfd,0xdd,0x84,0x6b,0xb3,0x06,
1866
0xd7,0x61,0x1b,0xe2,0x9a,0xb5,0xd4,0x5b,0x9b,0x81,0xeb,0x9f,0x8c,0xdd,0xd5,0x3e,
1867
0xea,0xa9,0x87,0x7e,0xec,0xed,0xba,0x93,0x71,0x7d,0x96,0xa0,0x1f,0x2b,0xd9,0xfe,
1868
0x6f,0xa4,0x8b,0x49,0xd8,0xb9,0xad,0x04,0x5b,0xd2,0xe8,0xe2,0xff,0x63,0xd7,0x6d,
1869
0x80,0x9a,0xba,0xd6,0xfd,0xff,0x85,0x82,0x12,0x0b,0x05,0x94,0x28,0x58,0xb0,0xa0,
1870
0x44,0xc5,0x12,0x48,0x4e,0x93,0x96,0x60,0x68,0x45,0x41,0x09,0x24,0xbc,0xa3,0xa0,
1871
0xa0,0xd2,0x02,0x26,0x90,0x28,0x81,0x04,0x08,0x24,0x90,0x57,0x48,0x42,0xc2,0x4b,
1872
0x05,0x0a,0x15,0x5a,0x50,0x50,0xb0,0x60,0x45,0x88,0x82,0x05,0x2b,0x77,0x64,0xae,
1873
0xf4,0x27,0x33,0x32,0x23,0xb7,0xd2,0xca,0x8c,0x9c,0x12,0x24,0x77,0x64,0x06,0x7e,
1874
0x23,0xff,0x29,0xff,0x91,0x99,0xff,0xb3,0x42,0xdb,0x7f,0xcf,0xb9,0xe7,0xdc,0xf3,
1875
0xd6,0xd3,0x7b,0x7b,0x4a,0x3e,0xac,0xef,0x5e,0x7b,0xad,0xbd,0xd7,0x5e,0xeb,0x79,
1876
0x9e,0xb5,0xf6,0xde,0x24,0xb7,0x20,0x56,0x14,0x70,0x8d,0xc1,0xcb,0x68,0xee,0xfc,
1877
0x35,0x64,0x91,0x5f,0x42,0x16,0xa3,0x1e,0x99,0xb5,0xf0,0x36,0xa6,0x87,0x37,0xb4,
1878
0x0f,0x86,0x20,0x16,0xb4,0x10,0x1f,0xf8,0xba,0x3a,0x64,0xfe,0x02,0xfc,0x6f,0x84,
1879
0x1b,0xf5,0xb5,0x6b,0xe8,0xd9,0x75,0xb8,0x3e,0xc4,0x03,0xbc,0x67,0x20,0xf3,0x05,
1880
0xb0,0xcd,0x4d,0x18,0x97,0x1c,0xec,0x07,0x73,0xef,0x59,0x0d,0x8e,0xaf,0x8f,0xa0,
1881
0xed,0x32,0x64,0xd1,0xf6,0x81,0x2f,0x6e,0x22,0x4b,0xb3,0x16,0xde,0x00,0x1b,0xc0,
1882
0x56,0x15,0xe8,0xd9,0x65,0xb8,0x56,0x19,0x94,0x7f,0xd4,0x8f,0x66,0xe1,0xfd,0x66,
1883
0xe6,0x36,0xc4,0x84,0xea,0x23,0xb0,0x2f,0xd8,0xe0,0xfa,0x17,0x68,0xb6,0x1e,0xe2,
1884
0xaf,0xbc,0x12,0xe2,0x54,0x09,0xfd,0x82,0xb8,0x51,0x0c,0xa2,0xd9,0x8f,0xe0,0xfc,
1885
0x06,0xa8,0xd7,0x83,0x7d,0x9a,0xa1,0x0f,0x9f,0xf4,0x42,0x5c,0x29,0xd0,0xec,0x6d,
1886
0xb8,0x66,0x35,0x8c,0xa7,0x0e,0xce,0x69,0xfd,0x14,0xec,0x5e,0x8d,0x2c,0x60,0xf3,
1887
0x59,0x2d,0x5c,0xa3,0xb1,0x1f,0x99,0xe5,0x9f,0x22,0x73,0x1f,0xbc,0x71,0xde,0xba,
1888
0x0a,0xe3,0x84,0xb7,0x51,0xb8,0xfe,0xac,0x06,0xe2,0xae,0x05,0xec,0xf5,0x11,0x5c,
1889
0x57,0x0b,0x36,0xaf,0x06,0xfb,0xf6,0x80,0x2f,0x1a,0x20,0x4e,0x9a,0xc1,0x86,0x17,
1890
0x3b,0xc0,0x8f,0xed,0xd0,0x6e,0x19,0x7a,0xf6,0x21,0xc4,0xd4,0x10,0xbc,0xe1,0x5e,
1891
0x82,0x38,0xb8,0xd4,0x0a,0x63,0x01,0xbb,0x1a,0xa0,0x8f,0xf8,0xdf,0xc5,0xd5,0xcd,
1892
0xd0,0x4f,0x88,0xdd,0x0f,0x20,0xde,0x3f,0xbc,0x0d,0xed,0x81,0xfd,0x7a,0xa0,0xdd,
1893
0xdb,0x9f,0xa0,0x59,0x58,0x73,0x67,0x6f,0x55,0xc0,0x5c,0xe8,0x40,0xcf,0xba,0xc0,
1894
0xc7,0x37,0x20,0x6e,0x2a,0xe4,0xe8,0x99,0xb2,0x11,0xcd,0x75,0x83,0x1d,0x3e,0x97,
1895
0xa3,0x39,0xc3,0x4d,0xb8,0x3e,0xb4,0xa3,0x85,0xb9,0x79,0xfb,0x32,0xc4,0x04,0xcc,
1896
0x85,0x5e,0x88,0xeb,0x6b,0xe0,0xdf,0x3e,0x18,0xc3,0x47,0xe0,0x1f,0xfc,0x6f,0x37,
1897
0xb8,0xff,0x99,0x3f,0x3f,0x0f,0xf1,0x21,0x47,0xe6,0x0f,0x21,0xb5,0x82,0x2f,0x1b,
1898
0xfb,0x20,0x56,0x20,0xb6,0x0c,0x30,0xb7,0x2e,0x80,0x2f,0xdb,0x06,0x61,0x8e,0xc0,
1899
0x7e,0x3b,0xf4,0xfb,0x72,0x15,0xd8,0xbb,0x1e,0xae,0x09,0x31,0xd6,0x00,0x31,0xfe,
1900
0x29,0xcc,0x6f,0x39,0x24,0x15,0xcc,0xe7,0x4b,0x30,0xa7,0x2e,0x81,0x4d,0xdb,0xe0,
1901
0x8d,0xfc,0x26,0xf8,0x00,0xde,0xb4,0x2c,0x1f,0xdd,0x02,0xbf,0x80,0x6d,0x55,0x57,
1902
0xe0,0x1a,0x70,0x2d,0x98,0xc3,0xe6,0x0a,0xf0,0xab,0x11,0xaf,0x1b,0xf0,0x56,0x0f,
1903
0xf3,0xd2,0xdc,0xd8,0x01,0xd7,0x85,0x6b,0x83,0x6d,0xcc,0x3d,0x30,0xcf,0x95,0xb5,
1904
0x60,0x47,0xb0,0x53,0x19,0xd8,0xab,0xfc,0x06,0xc4,0x3c,0xac,0x1f,0x60,0xab,0x59,
1905
0xb8,0x8f,0xce,0x5e,0x84,0xfe,0x9b,0x6e,0xa1,0xd9,0x7e,0x1c,0x73,0x60,0x3f,0x0d,
1906
0xc4,0x8b,0x16,0x7c,0x53,0x0d,0xf9,0x8b,0x35,0xd0,0x47,0xf0,0x17,0xac,0x45,0xcf,
1907
0xda,0xc1,0x76,0xed,0xd0,0xcf,0xcb,0x46,0x48,0xe0,0xef,0x4e,0xb0,0xcf,0x55,0x88,
1908
0xfd,0xcf,0x60,0xdb,0x0f,0xc7,0x0c,0x40,0x7e,0xe8,0x06,0x9a,0x93,0xc3,0x5a,0x55,
1909
0xde,0x0d,0xf3,0x01,0xfc,0x50,0xf3,0x21,0x9a,0x6b,0xab,0x46,0x73,0x97,0xeb,0xd1,
1910
0x5c,0x17,0xcc,0xab,0x2e,0x28,0xeb,0x3d,0x8f,0xe6,0xfa,0x20,0x4e,0xef,0x40,0x9c,
1911
0x5d,0x00,0x1f,0x7c,0xf2,0x05,0xc4,0x1a,0xc4,0x88,0xc2,0x84,0x16,0xda,0x2a,0xae,
1912
0xa1,0x39,0x2d,0x18,0xbc,0xff,0x32,0x2c,0x3c,0x30,0x89,0xa0,0xd3,0x33,0x77,0x60,
1913
0x20,0x1a,0x0d,0xec,0xc3,0xb6,0x02,0x8c,0x5f,0x01,0x4e,0xa8,0xab,0x83,0xc1,0x36,
1914
0x82,0x81,0xc1,0xc1,0x17,0x7b,0x61,0xb1,0x54,0x43,0xaa,0x45,0xe6,0x4e,0xd8,0xef,
1915
0x82,0x41,0x7f,0xfe,0x01,0x24,0xa8,0x1f,0x82,0x80,0xb9,0xd3,0x0d,0x81,0xdb,0x00,
1916
0x06,0x80,0xc1,0xab,0x61,0x32,0x6b,0x5a,0x20,0xe0,0x60,0xb2,0xc1,0x0d,0x63,0xb6,
1917
0xba,0x09,0xcd,0xd6,0x7c,0x00,0x06,0xa9,0x87,0xc5,0xef,0x02,0x04,0x14,0x6c,0x3f,
1918
0x87,0xed,0xe7,0x10,0xf8,0x72,0x70,0x10,0xdc,0x6c,0x9f,0x69,0x4d,0xe8,0x99,0x1e,
1919
0x16,0xa2,0x9a,0x1e,0xf4,0xac,0x16,0x82,0xac,0xf6,0x73,0xf4,0xac,0x01,0x82,0xa9,
1920
0xe1,0x13,0x70,0x26,0x2c,0xc0,0xb0,0x88,0x3f,0x6b,0x06,0xa7,0x36,0x83,0x21,0x2e,
1921
0xc1,0xc2,0x74,0x15,0x8e,0xeb,0x81,0x63,0x4c,0x50,0x37,0x08,0x4e,0x35,0x82,0x53,
1922
0xf1,0x82,0xdf,0x0c,0x83,0x6f,0x07,0x23,0x5c,0x86,0x85,0xf3,0x2a,0x2c,0xe6,0x9f,
1923
0x42,0xc0,0x7d,0x0a,0x86,0xba,0x06,0x8b,0xe0,0x20,0x38,0x5c,0x01,0x8b,0x68,0x59,
1924
0x23,0xb2,0xe8,0xc0,0x30,0x8d,0xe0,0x74,0xb8,0x09,0x5b,0x5a,0x2a,0x90,0xa5,0xeb,
1925
0x03,0xb4,0x70,0xb1,0x55,0x8f,0x45,0x8d,0x16,0x2e,0xc1,0x3d,0xea,0xdb,0x6b,0xcd,
1926
0x68,0x46,0x0e,0x66,0x92,0x0f,0xa0,0x85,0x76,0x9d,0x0e,0xa4,0xb7,0x1a,0x2d,0x5c,
1927
0x81,0xb0,0xb3,0x0c,0xa9,0x90,0xe5,0x4e,0x25,0xca,0xcc,0x44,0x99,0x3c,0x94,0x09,
1928
0x4f,0xd1,0x78,0x03,0xdb,0x3c,0x11,0x9a,0xe8,0xc3,0x3f,0x65,0xea,0xc3,0x3f,0x81,
1929
0xea,0xc3,0xbf,0x7a,0xba,0xb3,0xba,0xdb,0x8d,0xbe,0x6a,0xfc,0x8f,0x3e,0xf4,0xd5,
1930
0x8d,0xff,0xb8,0x85,0xbe,0xba,0x88,0xbe,0xaa,0x45,0x5f,0x5d,0x40,0x5f,0x35,0xa1,
1931
0xaf,0x9a,0xd1,0x57,0x1d,0xe8,0xab,0xab,0xe8,0xab,0xce,0xaf,0x14,0x58,0x94,0x20,
1932
0xff,0x31,0x68,0xcd,0xc3,0x06,0xf6,0xaa,0xf1,0x19,0xd5,0xff,0xd1,0x8f,0x65,0x10,
1933
0x7d,0x55,0x83,0xe5,0x03,0x2c,0xe7,0xb1,0xd4,0x62,0xa9,0xc3,0x52,0x8f,0xa5,0x01,
1934
0x4b,0x23,0x96,0x8f,0xb0,0x5c,0xc0,0xd2,0x84,0xe5,0x63,0x2c,0x2d,0x58,0x5a,0xb1,
1935
0x5c,0xc2,0xd2,0x86,0xe5,0x32,0x96,0x2b,0x58,0x3a,0xb0,0x74,0x62,0xb9,0xba,0xda,
1936
0xe8,0x00,0xbe,0xda,0x17,0xb8,0x95,0x2f,0xf0,0xc1,0x20,0xd5,0xd0,0xe3,0xc9,0x1e,
1937
0x34,0xf9,0x39,0x9a,0xbc,0x83,0xbe,0x96,0xa3,0xc9,0xdb,0x68,0xf2,0x0b,0x34,0x39,
1938
0x80,0xbe,0x6e,0x43,0x5f,0x5f,0x46,0x5f,0xab,0xd1,0xd7,0x2a,0xf4,0x75,0x19,0xfa,
1939
0xba,0x1c,0x7d,0x6d,0x44,0x5f,0x1b,0xd0,0xd7,0x95,0xe8,0x6b,0x2d,0xfa,0xba,0x01,
1940
0x7d,0x5d,0x83,0xbe,0xee,0x44,0x5f,0x7f,0x86,0xbe,0xee,0x45,0x5f,0xf7,0xa0,0xaf,
1941
0x6f,0xa3,0xaf,0x3f,0x47,0xdf,0xc8,0xd1,0x37,0x0a,0xf4,0xf5,0x1d,0xf4,0xcd,0x07,
1942
0xe8,0x9b,0xf3,0xe8,0xeb,0x6e,0xf4,0x4d,0x39,0xfa,0xa6,0x0c,0x7d,0xa3,0x45,0xdf,
1943
0x54,0xa0,0x6f,0x34,0xe8,0x1b,0x1d,0xfa,0xa6,0x1a,0x4d,0xea,0xd0,0xe3,0xcb,0x8f,
1944
0xaf,0x80,0x7c,0x53,0x07,0x32,0xa9,0xc5,0xb9,0x72,0x2c,0x65,0x58,0xac,0xbb,0xd5,
1945
0xb8,0x02,0x8e,0x36,0xe0,0x43,0xbb,0xb0,0x74,0xe3,0x12,0x0d,0x16,0x3d,0x7a,0xdc,
1946
0x81,0xcb,0x3a,0x70,0x59,0xc7,0xe3,0x6b,0x20,0xb8,0xa2,0x03,0xb7,0xdb,0x81,0x6b,
1947
0xaf,0xe2,0xda,0xab,0xb8,0xf6,0x2a,0xae,0xbd,0x8a,0x6b,0xaf,0xe2,0xda,0xab,0xb8,
1948
0xf6,0x53,0x5c,0xfb,0x29,0x2e,0xfb,0x14,0x97,0x7d,0x8a,0xcb,0xba,0xf0,0xc1,0x5d,
1949
0xb8,0xac,0x1b,0xd7,0x76,0xe3,0xdc,0x35,0x9c,0xbb,0x86,0x2b,0xae,0xe1,0xdd,0x5e,
1950
0xbc,0xdb,0x8b,0x77,0x7b,0x71,0xa3,0xbd,0xb8,0xcc,0x84,0x77,0x4d,0x38,0x77,0x13,
1951
0xd7,0xde,0xc4,0xbb,0x37,0x71,0xed,0x4d,0x5c,0x76,0x0b,0xef,0xde,0xc2,0xb9,0x7e,
1952
0x2c,0x03,0xf8,0x90,0x01,0x9c,0xbb,0x8d,0x73,0xb7,0x21,0x37,0xa9,0x80,0x1c,0x48,
1953
0x37,0x96,0x6b,0x20,0xd6,0x32,0xe8,0x15,0x88,0x1e,0x4d,0x2a,0x71,0x85,0x12,0x97,
1954
0x29,0x71,0x99,0x12,0x97,0xa9,0xc0,0x70,0x20,0x5d,0x58,0xba,0xb1,0xc0,0x69,0xaa,
1955
0x49,0x35,0x16,0x0d,0x16,0x1d,0x16,0x38,0x4e,0x8d,0x0f,0x51,0xe3,0x43,0xd4,0xf8,
1956
0x10,0x35,0xae,0x55,0xe3,0x5a,0x35,0xae,0xd5,0xe0,0x5a,0x0d,0xae,0xd5,0xe0,0x5a,
1957
0x0d,0xae,0xd5,0xe0,0x5a,0x0d,0xae,0x2d,0xc3,0xb5,0x65,0xb8,0xb6,0x0c,0xd7,0x96,
1958
0xe1,0xda,0x32,0x5c,0x5b,0x86,0x6b,0xcb,0x71,0x6d,0x39,0x2e,0x2b,0xc7,0x65,0xe5,
1959
0xb8,0x4c,0x8f,0xcb,0xf4,0xf8,0x0c,0x3d,0x3e,0x43,0x8f,0x6b,0xf5,0xb8,0x56,0x8f,
1960
0xad,0x7b,0x7d,0xf2,0x3a,0x7a,0xdc,0x03,0x32,0xa9,0x03,0xf1,0x9a,0x34,0x4c,0xd6,
1961
0x80,0x1a,0xad,0x5a,0x69,0xd5,0x2a,0xab,0x56,0x5b,0xb5,0x06,0x1f,0x7d,0xf9,0x71,
1962
0x0f,0x96,0x1b,0xd8,0xdf,0x65,0xd8,0xcb,0x3d,0x58,0x6e,0x60,0x07,0x97,0x61,0xb7,
1963
0xf6,0x60,0xb9,0x81,0x3d,0x5a,0x86,0x3d,0xda,0x83,0xe5,0x06,0x76,0x66,0x19,0x1e,
1964
0xd2,0x15,0xdc,0xf3,0x1e,0x2c,0x37,0x70,0xa7,0xcb,0x70,0xb7,0x7a,0xb0,0xdc,0xc0,
1965
0x3d,0xc2,0x51,0x86,0x9d,0x74,0x79,0xb2,0x1c,0xb7,0x57,0x8e,0x5b,0x29,0xc7,0xce,
1966
0xb4,0xda,0xa9,0x1c,0x9f,0x51,0x8e,0xc7,0x75,0x1d,0x1f,0x5c,0x8e,0x1b,0x2d,0xc7,
1967
0xfe,0x06,0xe9,0xc3,0xde,0xeb,0xc3,0xb5,0x72,0x6b,0xc7,0x61,0x53,0xb5,0xba,0xc1,
1968
0x5d,0x07,0x5f,0xeb,0xb0,0xe8,0xb1,0x9b,0x75,0x58,0xf4,0xd8,0xcd,0x3a,0x2c,0x7a,
1969
0xdc,0x82,0x0e,0x8b,0x1e,0xb7,0xa0,0xc3,0xa2,0xc7,0x81,0xa6,0xc3,0x82,0x23,0x10,
1970
0xe7,0xba,0x70,0xee,0x1a,0xce,0x5d,0xc3,0x39,0x13,0xce,0x99,0x70,0xee,0x26,0xce,
1971
0xdd,0xb4,0x9e,0x8b,0x63,0xa7,0x0f,0x47,0x56,0x1f,0x1e,0x43,0x1f,0x1e,0x7a,0x2f,
1972
0x16,0x13,0x96,0x9b,0x58,0xae,0x4c,0x56,0x58,0xe7,0x80,0x35,0xec,0x57,0x03,0xfa,
1973
0xea,0x6a,0x48,0x5f,0x5d,0x0d,0xe5,0xab,0x56,0xff,0x5b,0x37,0xdd,0xab,0x9b,0x6b,
1974
0xd6,0xe8,0xc7,0x7b,0xdd,0xd6,0x10,0xb0,0x6e,0x74,0xd6,0x78,0x5f,0x0d,0xfb,0xae,
1975
0xd5,0xc0,0xef,0x5a,0x1d,0x83,0xf5,0xc8,0xde,0xd5,0x56,0x7a,0xad,0xd1,0x83,0xa7,
1976
0xc2,0xf7,0x93,0xc1,0x6a,0xa3,0xd5,0xeb,0xf5,0xad,0x8e,0xa8,0x6f,0xf5,0x0a,0x7d,
1977
0xab,0x75,0x37,0x57,0x47,0x7d,0x73,0xb5,0x2f,0xb7,0x56,0x1b,0xbb,0xb5,0x5a,0x77,
1978
0x6b,0xf5,0xea,0x03,0xab,0x9d,0x1f,0x58,0x2d,0x1c,0x58,0xed,0xcb,0xed,0xd5,0xbd,
1979
0xdb,0xab,0x87,0xdc,0x5e,0x8d,0x57,0x85,0xb5,0x15,0x3c,0x49,0xbe,0x9f,0x2b,0xd6,
1980
0x38,0xb7,0x5e,0xdd,0xba,0xd1,0xaf,0x6e,0x74,0xd6,0x09,0xb1,0x3a,0x25,0xae,0xad,
1981
0x4e,0x85,0xef,0xa3,0xbf,0xfb,0xfb,0x99,0x60,0x9d,0x01,0xab,0x27,0x68,0xac,0xa3,
1982
0xc5,0x9b,0xd5,0xc2,0x6b,0xab,0x87,0x5c,0x5b,0xdd,0xeb,0xc2,0x61,0x52,0xbe,0x3a,
1983
0x83,0xca,0x57,0xaf,0x57,0xb6,0x7a,0x7a,0xd9,0xea,0x85,0xca,0x56,0xcf,0x2b,0xb3,
1984
0x1a,0x0b,0x4f,0x1e,0xeb,0x94,0x5a,0xed,0xae,0x7e,0x75,0x0c,0x1d,0xab,0xfe,0xbd,
1985
0xba,0x6a,0x9e,0xab,0xab,0x66,0xbd,0xfa,0x43,0xe1,0xb5,0xd5,0xa5,0xca,0x3a,0xcc,
1986
0xab,0xab,0x63,0xef,0x5a,0xdd,0xeb,0x5a,0x35,0x5d,0xd7,0x0f,0xce,0xb1,0x1e,0x69,
1987
0x5a,0x0d,0xa0,0xbe,0xd5,0xcd,0xcd,0x1f,0x06,0xdd,0x65,0xdd,0xac,0x5e,0x5d,0xbf,
1988
0x5a,0xa8,0x5f,0x2d,0xd4,0xaf,0x16,0x6a,0x56,0x37,0xca,0x1f,0xe6,0x7c,0xf7,0x6a,
1989
0xe0,0x5a,0xf7,0x54,0x3f,0x2e,0x04,0xdf,0xaf,0x11,0x3f,0xb4,0xa9,0x59,0xad,0xd3,
1990
0xac,0xf6,0x45,0x6f,0x5d,0x2f,0xbf,0xb7,0x19,0xde,0x28,0x56,0xfb,0xd9,0xb1,0x5a,
1991
0xd7,0xbb,0x7a,0x5e,0xd9,0xea,0x30,0x4d,0x93,0x6a,0xb8,0x2f,0xc0,0xf5,0xf0,0x06,
1992
0x82,0x54,0x6d,0x9d,0x6c,0x90,0x51,0x59,0xa7,0xf7,0xaa,0x13,0x1e,0x7f,0x66,0x3d,
1993
0x70,0x75,0x9d,0xec,0x81,0xe0,0xd2,0xc2,0xda,0x06,0x7b,0x6a,0xeb,0x54,0x9c,0xd4,
1994
0x42,0x89,0xda,0x1a,0x6e,0xd6,0xc5,0x6c,0x75,0xe3,0xf5,0x43,0x63,0x5e,0x3f,0x1c,
1995
0xe8,0xf5,0xff,0x1f,0xd8,0x35,0xa9,0xf6,0xc2,0x62,0x3d,0x06,0x2e,0xd7,0xf3,0x8d,
1996
0x01,0x67,0x91,0x1f,0xfa,0x56,0xae,0x40,0x41,0xc8,0x1b,0xbd,0x0b,0xb9,0x7a,0x48,
1997
0x1f,0xa2,0xdf,0xcb,0xf1,0x8f,0xac,0xce,0xa3,0x53,0xa8,0x18,0xc9,0xa0,0xa4,0x16,
1998
0x12,0x3c,0x38,0xc8,0xab,0x21,0xd5,0x40,0xd2,0x43,0xaa,0x80,0x64,0x80,0x64,0x84,
1999
0x54,0x09,0xa9,0x0a,0x9d,0x40,0xa9,0x68,0x17,0xda,0x8d,0xf6,0x21,0x32,0x62,0xa2,
2000
0x77,0x50,0x0a,0xf2,0x41,0x24,0x74,0x00,0x56,0xb2,0x0a,0xbc,0x32,0x54,0xe0,0x05,
2001
0x0f,0x2f,0x77,0x78,0xb1,0xb3,0x2e,0x1c,0x78,0xbd,0xb3,0x2e,0x1d,0x78,0xc9,0xb3,
2002
0x2e,0x1e,0x78,0xd5,0xc3,0x19,0xbc,0xfc,0x7d,0x80,0x33,0x60,0xa0,0x56,0xf4,0xf8,
2003
0x22,0x7a,0x7c,0x09,0x3d,0x6e,0x43,0x8f,0xdb,0x61,0xb1,0x42,0xf8,0x8e,0xd9,0x81,
2004
0x1e,0x77,0x42,0x50,0xc0,0x9a,0x84,0xac,0xf7,0x29,0x84,0xe7,0x15,0x98,0x0c,0xaf,
2005
0xaf,0x08,0x2f,0x80,0xbd,0x10,0x08,0x60,0x16,0x88,0x03,0x98,0x4c,0x70,0xe3,0x01,
2006
0xdb,0xc1,0x5c,0x01,0xc7,0x80,0xe1,0xc1,0x75,0x08,0xdf,0x29,0x70,0x70,0x22,0xab,
2007
0x35,0xd1,0xaa,0x5b,0x2f,0x62,0xb9,0x84,0xa5,0x1d,0xcb,0x15,0xb4,0x13,0xed,0x41,
2008
0x01,0xe8,0x24,0x92,0xa2,0x12,0xf4,0xfb,0xcb,0x1a,0x48,0xf8,0xfb,0x1d,0xfc,0xbd,
2009
0x0f,0xfe,0x5a,0xe5,0x12,0xa4,0x76,0x48,0x57,0x20,0xe1,0x7f,0xeb,0xc2,0xbe,0x0a,
2010
0xf6,0xe1,0xd9,0xfa,0x5b,0x95,0x0a,0xad,0xfe,0x83,0x17,0x7f,0xbd,0xd0,0x88,0xf0,
2011
0xd7,0xe4,0xff,0x76,0x11,0xfd,0xdb,0x25,0xf4,0x6f,0x5d,0xe8,0xdf,0x2e,0xa3,0x7f,
2012
0x6b,0x47,0xbf,0x87,0x53,0x7e,0x5f,0xab,0x44,0xbf,0x87,0xd7,0xb6,0xdf,0x97,0xd5,
2013
0x40,0xfa,0x00,0xd2,0x79,0xf4,0xfb,0xfa,0x16,0xf4,0xfb,0x0f,0x2b,0xd0,0x42,0x75,
2014
0x75,0x07,0x96,0x4e,0x2c,0x57,0xb1,0x7c,0x8a,0xa5,0x0b,0x4b,0x37,0x96,0x6b,0x58,
2015
0x3e,0xc3,0x72,0x1d,0x4b,0x0f,0x96,0x1b,0x58,0x7a,0xb1,0xf4,0x61,0x31,0x61,0xb9,
2016
0x89,0xe5,0x16,0x96,0x7e,0x2c,0x03,0x58,0x6e,0x63,0xf9,0x1c,0xcb,0x20,0x96,0x21,
2017
0x2c,0x77,0xb0,0x7c,0x01,0x52,0x23,0xc7,0xa2,0xc0,0xa2,0xc4,0xa2,0xc2,0xa2,0xc6,
2018
0xa2,0xc1,0x52,0x86,0xa5,0x1c,0x8b,0x16,0x8b,0x0e,0x8b,0x1e,0x0b,0xee,0x73,0x8d,
2019
0x01,0x8b,0x11,0x4b,0x25,0x96,0x2a,0x90,0xf3,0x0d,0x58,0x1a,0xb1,0x7c,0x84,0xe5,
2020
0x02,0x96,0x26,0x2c,0xcd,0x58,0x3e,0xc6,0xf2,0x09,0x96,0x16,0x2c,0xad,0x58,0x2e,
2021
0x62,0xb9,0x84,0xa5,0x0d,0x4b,0x3b,0x96,0xcb,0x58,0xae,0x60,0xc1,0x76,0x39,0x8f,
2022
0xed,0x72,0x1e,0xdb,0xe5,0x3c,0xb6,0xcb,0x79,0x6c,0x97,0xf3,0xd8,0x2e,0xe7,0xb1,
2023
0x5d,0xce,0x63,0xbb,0x9c,0xc7,0x76,0x39,0x8f,0xed,0x72,0x1e,0xdb,0xe5,0x3c,0xb6,
2024
0xcb,0x79,0x6c,0x97,0xf3,0xd8,0x2e,0xe7,0xb1,0x5d,0xce,0x63,0xbb,0x9c,0xc7,0x76,
2025
0x39,0x8f,0xed,0x72,0x1e,0xdb,0xe5,0x3c,0xb6,0x4b,0xfd,0x87,0x58,0x70,0xc7,0xeb,
2026
0x71,0xc7,0xeb,0x71,0xc7,0xeb,0x71,0xc7,0xeb,0x71,0xc7,0xeb,0x71,0xc7,0xeb,0x71,
2027
0xc7,0xeb,0x71,0xc7,0xeb,0x71,0xc7,0xeb,0x71,0xc7,0xeb,0x71,0x9f,0xeb,0x71,0x9f,
2028
0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,
2029
0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,
2030
0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x9f,0xeb,0x71,0x77,0xeb,0x71,0x77,0xeb,0x71,0x77,
2031
0xeb,0x71,0x77,0xeb,0x71,0x77,0xeb,0x71,0x77,0xeb,0x71,0x77,0xeb,0xad,0x3d,0x1d,
2032
0x44,0xff,0xa7,0x1a,0xfd,0x9f,0x1a,0xf4,0x65,0x23,0xfa,0xf2,0x12,0xfa,0xcf,0xee,
2033
0xcb,0xe8,0xcb,0x76,0xf4,0x65,0x1b,0x9a,0xbe,0x59,0x83,0x46,0x1b,0xd0,0xe8,0xc7,
2034
0xe8,0xcb,0x4e,0x34,0x7a,0x11,0x7d,0x79,0x01,0x7d,0xd9,0x84,0x46,0xaf,0xa0,0x2f,
2035
0xd5,0xe8,0xcb,0xab,0xe8,0x4b,0xe8,0x42,0xf3,0xa0,0x1a,0xfd,0xe7,0xc7,0x95,0x68,
2036
0xf4,0x1a,0xce,0x6b,0xd0,0x97,0x95,0x78,0x5b,0x86,0x46,0x6f,0xa2,0xd1,0xdb,0x38,
2037
0xab,0x45,0xa3,0x77,0xd0,0x97,0x1d,0xe8,0xcb,0xcb,0xd0,0x30,0x9c,0x79,0x05,0xfd,
2038
0xbe,0xa7,0x07,0x7d,0x59,0x85,0xbe,0x6c,0x45,0x5f,0x42,0x93,0x0d,0xe8,0xdf,0xe5,
2039
0xe8,0xdf,0x15,0xe8,0xdf,0x95,0xf8,0x68,0x3d,0x16,0xb8,0x5c,0x3d,0xfa,0xf2,0x43,
2040
0x9c,0xc5,0x01,0xd1,0x8b,0x83,0xa9,0x17,0x07,0x53,0x2f,0x0e,0xa6,0x5e,0x1c,0x4c,
2041
0xbd,0x38,0x98,0x7a,0x71,0x30,0xf5,0xe2,0x60,0xea,0xc5,0xc1,0xd4,0x8b,0x83,0xa9,
2042
0x17,0x07,0x53,0x2f,0x0e,0xa6,0x5e,0xeb,0xb9,0x38,0x98,0x7a,0x71,0x30,0xf5,0xe2,
2043
0x60,0xea,0xc5,0xc1,0x84,0x5f,0x55,0xaa,0x7b,0x6b,0xb0,0x7c,0x80,0xe5,0x3c,0x96,
2044
0x5a,0x2c,0x75,0x58,0xea,0xb1,0x60,0xdf,0xf5,0x62,0xdf,0xf5,0x62,0xdf,0xf5,0x62,
2045
0xdf,0xf5,0x62,0xdf,0xf5,0x62,0xdf,0xf5,0x62,0xdf,0xf5,0x62,0xdf,0xf5,0x62,0xdf,
2046
0xf5,0x62,0xdf,0xf5,0x62,0xdf,0xf5,0xe2,0xa0,0xeb,0xc5,0x0e,0xec,0xc5,0x0e,0xec,
2047
0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,
2048
0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x0e,
2049
0xec,0xc5,0x0e,0xec,0xc5,0x0e,0xec,0xc5,0x41,0x67,0xc2,0xbb,0x26,0xbc,0x6b,0xb2,
2050
0xee,0x62,0xa7,0x9a,0xb0,0x53,0x4d,0xd8,0xa9,0x26,0xec,0x54,0x13,0x76,0xaa,0x09,
2051
0x3b,0xd5,0x84,0x9d,0x6a,0xc2,0x31,0x68,0xc2,0x9e,0x35,0xe1,0xb9,0x69,0xc2,0x73,
2052
0xd3,0x84,0xe7,0xa6,0x09,0xcf,0xcd,0x9b,0xd8,0x9c,0x37,0xb1,0x39,0x6f,0x62,0x73,
2053
0xde,0xc4,0xe6,0xbc,0x89,0xcd,0x79,0x13,0xcc,0x59,0x73,0x49,0x8e,0x45,0x81,0x45,
2054
0x89,0x45,0x85,0x45,0x8d,0xc5,0x5a,0x5b,0x86,0xa5,0x1c,0x8b,0x16,0x8b,0x0e,0x8b,
2055
0x1e,0x4b,0x05,0x16,0x03,0x16,0x23,0x96,0x4a,0x2c,0x55,0x58,0xaa,0xb1,0xd4,0x60,
2056
0xf9,0x00,0xcb,0x79,0x2c,0xb5,0x58,0xea,0xb0,0xd4,0x63,0xf9,0x10,0x4b,0x03,0x96,
2057
0x46,0x2c,0x1f,0x61,0xb9,0x80,0xa5,0x09,0x4b,0x33,0x96,0x8f,0xb1,0x80,0xb1,0xeb,
2058
0x07,0x5a,0xb0,0xb4,0x62,0xb9,0x88,0xe5,0x12,0x96,0x36,0x2c,0xed,0x58,0x2e,0x63,
2059
0xb9,0x82,0xa5,0x03,0x4b,0x27,0x96,0xab,0x58,0x3e,0xc5,0xd2,0x85,0xa5,0x1b,0xcb,
2060
0x35,0x2c,0x9f,0x61,0xb9,0x8e,0xa5,0x07,0xcb,0x0d,0x2c,0xbd,0x58,0xfa,0xb0,0x98,
2061
0xb0,0xdc,0xc4,0x72,0x0b,0x4b,0x3f,0x96,0x01,0x2c,0xb7,0xb1,0x7c,0x8e,0x65,0x10,
2062
0xcb,0x10,0x96,0x3b,0x58,0xc0,0xba,0xf5,0xb7,0x71,0xc5,0x6d,0x5c,0x71,0x1b,0x57,
2063
0xdc,0xc6,0x15,0xb7,0x71,0xc5,0xe7,0x72,0x2c,0x0a,0x2c,0x4a,0x2c,0x2a,0x2c,0x6a,
2064
0x2c,0x1a,0x2c,0x65,0x58,0xca,0xb1,0x68,0xb1,0xe8,0xb0,0xe8,0xb1,0x54,0x60,0x31,
2065
0x60,0x31,0x62,0xa9,0xc4,0x52,0x85,0xa5,0x1a,0x4b,0x0d,0x96,0x0f,0xb0,0x9c,0x47,
2066
0xdf,0x2a,0xce,0x7f,0xab,0xe8,0xb0,0x7e,0xf5,0x8b,0x7f,0x73,0x80,0xbf,0x30,0xc4,
2067
0xb7,0x9a,0x0e,0xfc,0x9d,0xe4,0x42,0xb3,0xe6,0x43,0x48,0xed,0x38,0xd3,0xf0,0x07,
2068
0x19,0x48,0xd7,0x7e,0xba,0xf3,0xd9,0x4f,0x77,0xae,0xff,0x74,0xa7,0xe7,0xa7,0x3b,
2069
0x60,0xac,0xe6,0xb2,0x81,0xef,0x5b,0x2a,0xbb,0xfd,0x43,0x66,0xe0,0x27,0x4d,0xae,
2070
0x96,0xfe,0xb0,0x33,0xf0,0x93,0xf6,0x7f,0xac,0xf9,0x0c,0xdd,0xeb,0x41,0xf7,0x6f,
2071
0xa1,0xbc,0x3c,0xf4,0x7b,0x6d,0x39,0x24,0xbc,0x08,0x0c,0x29,0xb0,0xe8,0xb0,0x54,
2072
0x60,0xc1,0x2b,0xca,0xd0,0x07,0x58,0x3a,0xb1,0xe0,0x45,0x67,0xa8,0x1b,0x0b,0x6e,
2073
0x6a,0xa8,0x17,0x8b,0x09,0xcb,0x2d,0x2c,0x03,0x58,0x3e,0xc7,0x32,0x84,0xe5,0x0b,
2074
0x2c,0x78,0x25,0x19,0x6a,0xc0,0xd2,0x88,0xa6,0xfb,0xac,0x99,0x6a,0xbc,0xb8,0xdc,
2075
0x41,0xd3,0x78,0x46,0x34,0x0f,0x7e,0x81,0xee,0xf7,0xa3,0xfb,0xf8,0xd4,0x41,0xeb,
2076
0x92,0x06,0xcb,0x60,0x19,0x2c,0x7e,0xf8,0xc8,0xc1,0x2e,0x2c,0x4d,0xe8,0xcb,0xf3,
2077
0x50,0xf0,0x11,0x9c,0xae,0x81,0x24,0x87,0x54,0x8e,0x46,0xbf,0x40,0x5f,0xc2,0x82,
2078
0x77,0x0d,0x7d,0xf9,0x19,0xba,0xdf,0x8a,0xee,0xf7,0xa1,0xfb,0x26,0x74,0xff,0x26,
2079
0x1c,0x87,0xbf,0x5d,0xa9,0x83,0x6d,0x39,0x24,0x3d,0xfa,0xb2,0x05,0x37,0x01,0xe3,
2080
0xf9,0xb8,0xed,0x22,0x96,0x4b,0x58,0xda,0xb0,0xb4,0x63,0xb9,0x8c,0xe5,0x0a,0x96,
2081
0x0e,0x2c,0x9d,0x58,0xae,0x62,0xf9,0x14,0x4b,0x17,0x96,0x6e,0x2c,0xd7,0xb0,0x7c,
2082
0x86,0xe5,0x3a,0x96,0x1e,0x2c,0x37,0xb0,0xf4,0x62,0xe9,0xc3,0x62,0xc2,0x72,0x13,
2083
0xcb,0x2d,0x2c,0xfd,0x58,0x06,0xb0,0xdc,0xc6,0xf2,0x39,0x96,0x41,0x2c,0x43,0x58,
2084
0xee,0x60,0x81,0xe1,0x7f,0xdc,0x2e,0xc7,0xa2,0xc0,0xa2,0xc4,0x02,0x4f,0x36,0xd7,
2085
0xd0,0xd7,0xad,0x68,0xf2,0x33,0x44,0xf1,0x43,0x54,0x3f,0xf4,0x3b,0x3f,0xf4,0xa6,
2086
0x1f,0xa2,0xf9,0x21,0xba,0x1f,0x7a,0xcb,0x0f,0xbd,0xed,0x87,0x02,0xfd,0x10,0x03,
2087
0x3f,0xf5,0xd5,0xe6,0xe1,0xa7,0xba,0x82,0x22,0xc4,0xcd,0x47,0x79,0xe9,0x28,0x27,
2088
0x27,0x1f,0x15,0xbc,0x8f,0x04,0xf0,0x97,0x8e,0x04,0xb9,0x28,0x3d,0x0b,0x82,0xf2,
2089
0xf3,0x6f,0x15,0x15,0xd6,0xdf,0x3b,0x28,0xf1,0xef,0x57,0x3f,0x44,0xe6,0x2a,0xfc,
2090
0x83,0x96,0x72,0x64,0x6e,0xfb,0x08,0xcd,0x5d,0xb9,0x84,0x66,0x6e,0xb7,0xa1,0xd9,
2091
0x86,0x16,0xf4,0x4c,0xdd,0x8a,0xcc,0x3a,0x23,0x32,0xdf,0x31,0x20,0x73,0x99,0x11,
2092
0xcd,0xc2,0x8d,0xcc,0xac,0x6d,0x46,0xcf,0x4c,0x4a,0x34,0x77,0xa3,0x13,0x99,0x2f,
2093
0xc1,0x3e,0x3c,0x7b,0xcc,0x0e,0xd6,0xa2,0x59,0x7d,0x1d,0x9a,0x35,0xd6,0x21,0x8b,
2094
0x42,0x8f,0x66,0x0d,0xe5,0x68,0x56,0x77,0x1e,0x3d,0xbb,0xac,0x40,0xcf,0x3a,0xf1,
2095
0x3f,0x5a,0xb5,0x68,0xf6,0xb6,0x1c,0x3d,0xab,0x85,0xeb,0xe9,0x6e,0x20,0x33,0xdc,
2096
0xf7,0x2c,0x1a,0xfc,0x8c,0x59,0x3b,0xdb,0xd4,0xb5,0xfa,0x14,0x5a,0x3b,0xd3,0xaf,
2097
0xfb,0x21,0x77,0xdb,0xf0,0x7d,0xce,0x7c,0xed,0x87,0xb2,0x67,0xca,0x81,0xef,0x73,
2098
0xd0,0xf0,0x0f,0x65,0x17,0x3e,0xfc,0xe1,0xb8,0x8a,0xe6,0x1f,0x6a,0xeb,0xac,0x65,
2099
0xe6,0x3b,0x78,0x54,0x9f,0xa1,0x99,0xfe,0x21,0x48,0xfd,0x68,0x66,0x00,0x8c,0xd9,
2100
0xa2,0xbe,0x88,0x66,0x86,0x5a,0xd0,0xcc,0x9d,0xcf,0x91,0x59,0xae,0x44,0x66,0x05,
2101
0x74,0x0d,0x9e,0xe3,0xcc,0xf8,0xf7,0x04,0x1f,0xc0,0x7a,0xd6,0xd2,0x00,0x05,0x1a,
2102
0xfc,0x73,0xa9,0x36,0x48,0xe0,0xb0,0x96,0xda,0x26,0xa8,0x19,0x80,0x1d,0x88,0x86,
2103
0x96,0xba,0x0a,0xb0,0x02,0xb4,0x5b,0xd6,0x86,0x66,0x3e,0xc7,0x16,0x81,0x48,0xe8,
2104
0x2c,0xff,0x04,0x4c,0x02,0xcf,0x85,0xe7,0xf1,0x16,0xda,0xd5,0x95,0x41,0xba,0x85,
2105
0xbe,0xad,0xc5,0x3f,0x2f,0xd6,0x40,0x82,0x7d,0xa3,0x0e,0xd2,0x47,0x90,0x60,0xf8,
2106
0xc6,0x21,0x48,0xe0,0xe3,0x96,0x8e,0x2e,0xf4,0x4c,0x01,0xf6,0xab,0xd2,0x43,0x82,
2107
0x75,0xb4,0x05,0xff,0xa6,0xaa,0xea,0x53,0x48,0x3d,0x60,0x30,0x38,0x0b,0x7a,0x64,
2108
0x86,0xa7,0x3b,0x33,0x3c,0x91,0x99,0x6b,0x3a,0x60,0xff,0x22,0x32,0xc3,0xf3,0x8d,
2109
0xb9,0xb6,0x1a,0x99,0xeb,0xce,0x43,0x82,0xe3,0xeb,0xd5,0x90,0xe0,0x1c,0x78,0xae,
2110
0x30,0x7f,0x08,0x23,0x6a,0xaa,0x87,0x04,0x5d,0x6c,0xac,0x81,0xd4,0x07,0x0e,0xba,
2111
0x86,0xcc,0x9f,0x54,0x42,0x82,0x7c,0x0b,0x38,0xf2,0x63,0x18,0x42,0x0b,0x38,0xa0,
2112
0x05,0xae,0x71,0x11,0xba,0xdf,0x0a,0x8f,0x62,0xe6,0x4b,0x50,0x70,0xe9,0x16,0x78,
2113
0x1f,0x2e,0x0a,0xf3,0xc1,0xdc,0x0e,0x73,0xa2,0xf5,0x23,0x08,0xfd,0xd6,0x0b,0x57,
2114
0x91,0xf9,0x4a,0x17,0x32,0x77,0x5c,0x80,0x74,0x05,0xf2,0x0d,0xc8,0xdc,0x79,0x19,
2115
0x7d,0x7b,0xe1,0x1a,0xa4,0x41,0x64,0xee,0x82,0xae,0x75,0x41,0xd4,0xb6,0x5e,0x81,
2116
0xcc,0x67,0x2a,0x48,0x70,0xc0,0x67,0x10,0xfd,0xad,0x5d,0x38,0xf3,0x05,0x32,0x5f,
2117
0x87,0x36,0x87,0x60,0x21,0xfc,0x58,0x81,0xcc,0x3d,0x2d,0xc8,0x0c,0x4f,0x0e,0xe6,
2118
0x1b,0xb0,0x6c,0xb6,0xde,0x82,0x0b,0x9b,0x54,0x38,0x73,0x19,0x32,0xd0,0x4d,0x13,
2119
0x0c,0x03,0x6e,0x8e,0xe6,0x5b,0x10,0x73,0xb7,0x2e,0xa2,0x6f,0x5b,0x3e,0x83,0x2d,
2120
0x18,0xab,0x1f,0x86,0x0e,0x5e,0x34,0xc3,0x9d,0xe3,0xdb,0x56,0xe8,0xd9,0xc5,0x32,
2121
0xb0,0x76,0x2b,0x1c,0x78,0x1b,0x8c,0x77,0x1b,0xc6,0x7d,0x1b,0xa6,0xd7,0xd5,0x4a,
2122
0xfc,0x1f,0x51,0x43,0x0f,0x9a,0xd3,0xc2,0x85,0x06,0xe1,0x74,0x7c,0x4b,0xbc,0xa4,
2123
0x87,0xf9,0x76,0xb9,0x1c,0x2c,0x8f,0xbf,0x4d,0x81,0x65,0xea,0xdb,0x4b,0x60,0xb3,
2124
0x3b,0xb0,0xff,0x05,0xd8,0xe2,0x0b,0xb0,0xd3,0x17,0x10,0xbc,0x4a,0x05,0xfa,0x16,
2125
0xa6,0xe3,0xb7,0x6d,0x70,0x6f,0xbb,0x78,0x01,0x22,0x19,0x66,0xc2,0xac,0x06,0xff,
2126
0x57,0xd8,0x00,0xe9,0x36,0x9a,0x2d,0xbb,0x01,0x09,0x66,0x44,0xd9,0x67,0x68,0xb6,
2127
0x1c,0x7f,0x35,0x81,0xbf,0x92,0xb9,0x00,0x11,0xde,0x0c,0x51,0xdf,0x83,0x66,0x2b,
2128
0xe0,0x1c,0x23,0x2c,0x5f,0x17,0xbb,0xe0,0x04,0xc3,0x10,0x14,0x0c,0x42,0x41,0x07,
2129
0x9a,0xad,0x54,0xa1,0xd9,0x2a,0x58,0x56,0x2e,0x7e,0x06,0x47,0x55,0x5f,0x84,0x1d,
2130
0x0d,0x14,0xc2,0x38,0x3a,0xae,0xa1,0xd9,0x9a,0x4e,0x48,0x77,0xd0,0xec,0x07,0xd0,
2131
0x4a,0x0d,0x04,0x4c,0x67,0x17,0x9a,0xad,0x03,0x97,0x5c,0x82,0x17,0xb1,0xd9,0x0f,
2132
0x2f,0xa1,0xd9,0x0b,0xfd,0x68,0xb6,0x51,0x87,0xbe,0xed,0x82,0x37,0x0d,0x30,0xf4,
2133
0xb7,0x9f,0x82,0xc5,0xe0,0x75,0xc2,0x5c,0x06,0x13,0xad,0x49,0x8e,0x66,0x3f,0x6a,
2134
0x42,0x73,0x70,0x57,0x99,0xa9,0x6a,0x84,0xfd,0x56,0x34,0xdb,0x0c,0x5d,0x6b,0x3e,
2135
0x8f,0xff,0x1d,0x0c,0x06,0xea,0xd6,0xa1,0xd9,0x4f,0xa0,0xef,0x1f,0xc3,0x15,0x5b,
2136
0xc1,0x36,0x97,0x6a,0xba,0xd1,0xec,0xc5,0x4a,0x34,0xdb,0xf2,0x09,0x9a,0x6d,0x83,
2137
0x0e,0xc3,0xc2,0x32,0x7b,0x19,0xae,0x72,0xe5,0x2a,0x9a,0xbd,0x0a,0xbe,0xbe,0xf4,
2138
0x11,0xec,0x7c,0x7a,0x01,0x7d,0x7b,0xbd,0x01,0xcd,0x76,0xc1,0xdd,0xfc,0xd2,0xc5,
2139
0x2b,0x68,0xb6,0x1b,0x5e,0x12,0x7b,0xe0,0xac,0x6e,0x30,0xc1,0x35,0x38,0xf3,0x1a,
2140
0xac,0x58,0x97,0xae,0x62,0xff,0xf5,0xc1,0x8d,0xe0,0xd2,0xa7,0x70,0x05,0xa8,0x5e,
2141
0xb8,0x74,0x03,0x46,0x7c,0xe3,0x0b,0x34,0x0b,0xcf,0x75,0xb3,0x3d,0x70,0x5e,0x5f,
2142
0x3d,0x24,0x18,0x9c,0x09,0x06,0x09,0x4f,0x41,0xb3,0xf8,0x41,0xe6,0x12,0xfe,0x4a,
2143
0xa4,0xaf,0x0f,0xcd,0xf6,0x83,0x1d,0xe1,0x76,0xff,0x6d,0x5f,0x2f,0x9a,0xc5,0x37,
2144
0xd8,0x4b,0x70,0xcf,0x9c,0xbd,0x05,0x9e,0x18,0x82,0x05,0xf5,0xd2,0x10,0x4c,0xc4,
2145
0x4b,0x77,0xe0,0x9a,0x5f,0x94,0xa1,0x67,0xf2,0x01,0x48,0xd0,0xa9,0x9b,0xf5,0x30,
2146
0x59,0xf4,0x90,0x86,0x20,0xdd,0x42,0xcf,0x60,0xdc,0x30,0x39,0xdb,0xd1,0x33,0x0d,
2147
0x34,0xdc,0xa6,0xbb,0x84,0x9e,0x95,0x81,0xf7,0xda,0x2a,0xf1,0xef,0xd9,0x3b,0xd0,
2148
0x33,0x1d,0x78,0xa3,0xad,0x41,0x8b,0x9e,0xe9,0x61,0xd1,0x81,0x85,0x69,0xa1,0xad,
2149
0x09,0x7f,0x95,0xd0,0x52,0x8b,0x9e,0x19,0x6f,0xa3,0x67,0x95,0xb0,0xfa,0xdd,0xc6,
2150
0x3f,0x6d,0x87,0xf7,0xba,0xdb,0xfd,0xe8,0x19,0xbc,0xf8,0x3c,0xab,0x69,0x42,0xcf,
2151
0x3e,0xd0,0xa0,0x67,0xe7,0xe1,0x35,0x78,0xf0,0x02,0x2c,0x55,0xe0,0xb7,0xb6,0xeb,
2152
0x37,0x21,0x03,0xf1,0xdd,0x76,0x03,0x87,0x57,0xd9,0x27,0xe8,0x59,0x03,0x6e,0xf9,
2153
0x4e,0x2b,0x16,0x88,0xad,0x76,0x85,0x1a,0x7d,0xfb,0xc5,0x20,0x9a,0x91,0xc3,0x23,
2154
0x42,0x3b,0xbc,0x16,0x82,0xc0,0x0d,0xa0,0x5d,0xdd,0x88,0xa5,0x17,0x3d,0x6b,0xc2,
2155
0xdf,0x1e,0xc2,0x69,0x30,0xef,0x66,0x14,0x65,0x68,0x46,0x09,0x4f,0x57,0xed,0xf8,
2156
0x6b,0xa7,0xd6,0x4a,0x34,0x03,0xaf,0x96,0x0b,0xed,0x0d,0x70,0xb3,0x69,0xff,0x08,
2157
0x1e,0xb0,0xda,0x2f,0xc0,0xd5,0xaf,0x7c,0x8a,0x66,0xd4,0x9f,0xc1,0xa2,0x09,0x63,
2158
0xed,0x84,0x67,0x8a,0xf6,0x76,0xb8,0x3b,0xb4,0x5f,0xbd,0x82,0x9e,0x7d,0x7a,0x0d,
2159
0xcd,0xe0,0x7b,0x71,0xfb,0x35,0x18,0xe3,0x67,0x60,0x9a,0xcf,0x74,0x50,0x00,0xcb,
2160
0x52,0xfb,0x0d,0x18,0x23,0x3c,0x36,0xcf,0xe8,0x61,0xc1,0x86,0x07,0xda,0x67,0xf0,
2161
0xb4,0xfb,0x0c,0xee,0x87,0x0b,0xed,0x77,0xe0,0x28,0x13,0xac,0xe6,0x06,0x58,0x85,
2162
0x6f,0xc1,0x10,0xfb,0x95,0xe8,0xd9,0x80,0x06,0xf6,0xe1,0xce,0x74,0x19,0xcc,0xb4,
2163
0x70,0x59,0x57,0x8e,0x66,0x8c,0xd0,0xd7,0xcb,0x15,0x8d,0xe8,0xd9,0x10,0xdc,0x92,
2164
0x2e,0x1b,0xee,0xa0,0x67,0x77,0xea,0xd0,0xb3,0x2f,0xf0,0x0e,0x7e,0xb3,0xbb,0x5c,
2165
0x7b,0x09,0xcd,0x29,0xe0,0x7e,0x79,0x19,0xde,0x76,0xe6,0x60,0xc1,0x5a,0xb8,0x64,
2166
0xfc,0x04,0x82,0xae,0x0e,0x82,0xef,0x06,0x9a,0x53,0xab,0xd0,0x4c,0x75,0x05,0x6c,
2167
0xef,0x20,0xf3,0x55,0xb0,0xf1,0xe5,0x8f,0xaf,0x60,0x81,0xdc,0xa5,0x4a,0x1c,0x8b,
2168
0x95,0x10,0xa4,0x5a,0x35,0x9a,0xbb,0xf3,0x31,0x9a,0xa9,0xf9,0x14,0xcd,0xe9,0x6b,
2169
0x20,0xc1,0xf1,0x7a,0xfc,0x63,0xd3,0x5e,0xd8,0xc2,0x94,0xb5,0x6e,0x87,0xd0,0x5c,
2170
0x05,0x98,0xe2,0x72,0xd7,0x20,0x9a,0x33,0x34,0xa3,0x39,0x23,0x5c,0xb6,0xb2,0x1b,
2171
0xf2,0x78,0x0b,0x95,0x55,0x57,0xa0,0xec,0x3c,0x6c,0xf5,0x90,0x0c,0x90,0xc0,0xdf,
2172
0x97,0xc1,0x3f,0x0b,0x97,0x61,0xe1,0x58,0xb8,0x0c,0x2f,0x0a,0x33,0xb5,0xd0,0x3e,
2173
0xbc,0x19,0xce,0xc1,0x3b,0xe1,0x5c,0x2d,0x18,0xfa,0x0a,0x3e,0xb6,0x0e,0xfc,0x78,
2174
0x19,0x1e,0x19,0x66,0xea,0x9a,0x21,0x81,0xe3,0x2e,0xdf,0x81,0xfb,0xf4,0x15,0x15,
2175
0x18,0xac,0x0e,0x8e,0x6f,0xac,0x86,0x04,0x4d,0x37,0x76,0xa2,0xb9,0x8f,0x70,0xd2,
2176
0xa2,0xb9,0xa6,0x4a,0x34,0x77,0xe1,0x22,0x6c,0x61,0xc0,0xcd,0x70,0xcc,0xc7,0xe0,
2177
0xb8,0x0f,0x3f,0x44,0x73,0x9f,0xb4,0xa2,0xb9,0x16,0x05,0xe4,0x07,0xd0,0x5c,0x2b,
2178
0x58,0xe4,0x0a,0x3e,0x11,0x1e,0x95,0xe7,0xe0,0x59,0x78,0xa6,0xc1,0x04,0x5b,0x58,
2179
0x45,0x3e,0x80,0x19,0x72,0xe5,0x22,0x04,0xf2,0x95,0xf6,0xcb,0x68,0xe6,0xa3,0x3b,
2180
0x68,0xe6,0x42,0x39,0x9a,0xbb,0x8a,0x0f,0xbf,0x01,0xed,0xdd,0x80,0xf6,0xe0,0xc5,
2181
0x69,0xae,0xef,0x02,0x9a,0xc3,0xef,0x08,0x57,0x06,0xe1,0xf9,0xa1,0xa5,0x05,0x2c,
2182
0x84,0xbf,0x6c,0xbc,0x09,0x83,0xbf,0x05,0x26,0x6e,0x81,0x16,0xe7,0x3e,0x87,0x67,
2183
0xf2,0x8e,0x0f,0x3f,0xc0,0xd2,0x8d,0x2c,0xca,0x5a,0x64,0x51,0xf5,0x20,0x8b,0x1a,
2184
0x9e,0x2f,0x3b,0x9a,0xae,0x41,0xe6,0x02,0xb2,0x68,0xfb,0x91,0xa5,0xe2,0x43,0x48,
2185
0x0d,0xc8,0xa2,0x1b,0x44,0x96,0xaa,0x01,0x64,0xa9,0x86,0x70,0xef,0xf8,0xec,0x36,
2186
0xb2,0xd4,0x43,0xcc,0x5d,0x86,0x1b,0x32,0x7e,0xbf,0xec,0x80,0x6b,0xcd,0x5c,0xb9,
2187
0x8c,0x2c,0x17,0x60,0x91,0xbe,0x79,0x03,0x59,0x9a,0x20,0xf6,0x3a,0xf1,0xe4,0xe9,
2188
0xd4,0x7e,0x84,0x66,0x3a,0x21,0xb8,0x3a,0xe1,0x9e,0xfc,0x09,0x74,0xb3,0xb3,0x5a,
2189
0x8f,0x66,0xae,0x42,0x14,0x77,0x7e,0x50,0x8f,0x2c,0x2d,0xf0,0xf0,0xd3,0x89,0x6f,
2190
0xd7,0x97,0xe0,0xde,0xd9,0xd5,0x8b,0x2c,0xf0,0x34,0x64,0xb9,0x7c,0x05,0x59,0xae,
2191
0x28,0x21,0xc1,0xe8,0x3e,0x83,0xe9,0xdf,0xd9,0x75,0x1d,0x59,0x7a,0xe4,0xc8,0xd2,
2192
0x0b,0x77,0x5b,0x78,0xab,0x9b,0x81,0xd7,0x27,0x8b,0x09,0x02,0xe1,0x2a,0xfe,0xc5,
2193
0x40,0x2f,0x4c,0x94,0xab,0x6a,0xb8,0xd4,0x55,0x2d,0x1c,0x7b,0x15,0x22,0x60,0xc6,
2194
0x04,0x2d,0x7f,0x7e,0x07,0x59,0xe0,0xed,0xd4,0x32,0x58,0x05,0x09,0xbc,0x75,0xb5,
2195
0x41,0x8e,0x90,0xcd,0xba,0xf5,0xb6,0x76,0x1b,0x36,0x6e,0xb4,0x27,0x6c,0x7a,0xc5,
2196
0xc1,0xf1,0x55,0xa7,0x8d,0x3f,0x7e,0x9c,0x37,0xba,0x6c,0xde,0xe2,0x4a,0xdc,0xba,
2197
0xcd,0xcd,0xba,0xeb,0xbe,0x71,0xfb,0x6b,0x1e,0x9e,0x3b,0x5e,0xf7,0xf2,0xde,0xf8,
2198
0x8b,0x7f,0x76,0xee,0x02,0xf1,0xf9,0x59,0x9b,0x24,0xed,0xde,0xb3,0xd7,0x77,0xdf,
2199
0x1b,0xd6,0xbc,0xdf,0x46,0xf2,0x0f,0xc5,0xfe,0x01,0x1b,0x29,0xd4,0xdf,0x41,0xe6,
2200
0xcd,0x9f,0xe9,0x3a,0xb4,0x9f,0xe4,0xe9,0x3f,0x43,0x7b,0x6f,0xfd,0xf9,0xaa,0xb7,
2201
0xb1,0x04,0x6e,0xdc,0xc8,0x08,0xda,0xcf,0xfc,0xbe,0x28,0xf8,0x9d,0x3f,0x38,0xe2,
2202
0xdd,0x8d,0x1b,0x0f,0x84,0xfc,0xb0,0x73,0x70,0xe3,0x6f,0xf8,0x73,0x28,0x34,0x6c,
2203
0xe3,0xda,0x67,0xed,0xb3,0xf6,0x59,0xfb,0xac,0x7d,0xd6,0x3e,0x6b,0x9f,0xb5,0xcf,
2204
0xda,0x67,0xed,0xb3,0xf6,0x59,0xfb,0xac,0x7d,0x7e,0x3b,0x1f,0x64,0xbb,0xc6,0x3f,
2205
0x84,0x1d,0xb2,0xff,0x03,0x08,0xc8,0x19,0xb9,0x20,0xd7,0xef,0x21,0x22,0x0f,0xc0,
2206
0x13,0x79,0x23,0x12,0x22,0x23,0x0a,0x40,0x45,0x0c,0x14,0x8c,0x0e,0xa0,0x10,0xc4,
2207
0x41,0xc9,0x28,0x1d,0xe0,0x23,0x11,0x92,0x22,0x35,0x32,0xa0,0x5a,0xa0,0x09,0xb5,
2208
0xa1,0x2e,0xd4,0x87,0x06,0xd1,0x3d,0xf4,0x00,0x3d,0x42,0x4f,0x80,0x19,0xf4,0x1c,
2209
0xbd,0x40,0x2f,0x91,0xad,0x8d,0x83,0x15,0x57,0x1b,0x0f,0x1b,0x1f,0x1b,0x3f,0x1b,
2210
0x9a,0x15,0xa6,0x4d,0xa8,0x0d,0xdb,0x26,0xc1,0x26,0xc5,0x26,0x1d,0xe0,0xdb,0x88,
2211
0x6c,0xa4,0x36,0x6a,0x1b,0x83,0x4d,0xad,0x4d,0x93,0x4d,0x9b,0x4d,0x17,0xd0,0x67,
2212
0x33,0x68,0x73,0xcf,0xe6,0x81,0xcd,0x23,0x9b,0x27,0x56,0x66,0x6c,0x9e,0xdb,0xbc,
2213
0xb0,0x79,0x69,0x63,0xbb,0xce,0x76,0x9d,0x03,0xe0,0xba,0xce,0x63,0x9d,0xcf,0x3a,
2214
0xbf,0x75,0xb4,0x75,0xcc,0x75,0xa1,0xeb,0xd8,0xeb,0x12,0xd6,0xa5,0xac,0x4b,0x5f,
2215
0xc7,0x5f,0x27,0x5a,0x27,0x5d,0xa7,0x5e,0x67,0xb0,0x52,0xbb,0xae,0x69,0x5d,0xdb,
2216
0xba,0xae,0x75,0x7d,0xeb,0x06,0xd7,0xdd,0x5b,0xf7,0x60,0xdd,0xa3,0x75,0x4f,0xd6,
2217
0xcd,0xac,0x7b,0xbe,0xee,0xc5,0xba,0x97,0xeb,0x6c,0xd7,0x3b,0xac,0x77,0x5d,0xef,
2218
0xb1,0xde,0x67,0xbd,0x9f,0x15,0xda,0x7a,0xe6,0xfa,0xd0,0xf5,0xec,0xf5,0x09,0xeb,
2219
0x53,0xd6,0xa7,0xaf,0xe7,0xaf,0x17,0xad,0x17,0xaf,0x97,0xad,0x57,0xaf,0x37,0xac,
2220
0xaf,0x5d,0xdf,0xb4,0xbe,0x0d,0xe8,0x5a,0xdf,0xb7,0x7e,0x70,0xfd,0xbd,0xf5,0x0f,
2221
0xd6,0x4f,0xac,0x9f,0x5a,0x3f,0x63,0xe5,0xf9,0xfa,0x17,0xeb,0x5f,0xae,0xb7,0xb5,
2222
0x75,0xb0,0x25,0xda,0x7a,0x58,0xf1,0xb1,0xf5,0xb3,0xa5,0xd9,0x32,0x6d,0x43,0x6d,
2223
0xd9,0x56,0x12,0x6c,0x53,0x6c,0xd3,0x6d,0xf9,0xb6,0x22,0x5b,0xa9,0xad,0xda,0xd6,
2224
0x60,0x5b,0x6b,0xdb,0x64,0xdb,0x66,0xdb,0x65,0xdb,0x67,0x3b,0x68,0x7b,0xcf,0xf6,
2225
0x81,0xed,0x23,0xdb,0x27,0x56,0x66,0x6c,0x9f,0xdb,0xbe,0xb0,0x7d,0x69,0x6b,0x6b,
2226
0xe7,0x60,0xe7,0x6a,0xe7,0x61,0xe7,0x63,0xe7,0x67,0x47,0xb3,0x63,0xda,0x85,0xda,
2227
0xb1,0xed,0x12,0xec,0x52,0xec,0xd2,0xed,0xf8,0x76,0x22,0x3b,0xa9,0x9d,0xda,0xce,
2228
0x60,0x57,0x67,0xd7,0xf0,0x0f,0xd3,0x62,0xd7,0xf1,0xdf,0x70,0xdd,0xae,0xff,0xaf,
2229
0x62,0xc0,0x6e,0xc4,0x6e,0xdc,0x6e,0xca,0xce,0x6c,0x37,0x6f,0xb7,0x64,0xb7,0x62,
2230
0x67,0xb7,0xc1,0x61,0x83,0xeb,0x06,0x8f,0x0d,0x3e,0x1b,0xfc,0x36,0xd0,0x36,0x30,
2231
0x37,0x84,0x6e,0x60,0x6f,0x48,0xda,0x90,0xbe,0x21,0x67,0x83,0x74,0x83,0x76,0x43,
2232
0xed,0x86,0x96,0x0d,0x5d,0x40,0xff,0x86,0x7b,0x1b,0x1e,0x6e,0x78,0xb2,0x61,0x66,
2233
0xc3,0x73,0x2b,0x2f,0x36,0xbc,0xdc,0x60,0xbb,0xd1,0x61,0xa3,0xeb,0x46,0x8f,0x8d,
2234
0x7b,0x37,0xd2,0x36,0x32,0x37,0x86,0x6e,0xe4,0x6c,0x4c,0xdc,0x98,0xba,0x31,0x7d,
2235
0x23,0x7f,0xa3,0xc8,0x8a,0x74,0xa3,0x7a,0x63,0xf5,0xc6,0xa6,0x8d,0x6d,0x1b,0xbb,
2236
0x36,0xf6,0x6d,0x1c,0x04,0xee,0x6d,0x7c,0xb0,0xf1,0xd1,0xc6,0x27,0x1b,0x67,0x36,
2237
0x3e,0xdf,0xf8,0x62,0xe3,0xcb,0x8d,0xb6,0xf6,0x0e,0xf6,0xae,0xf6,0x1e,0xf6,0x3e,
2238
0xf6,0x7e,0xf6,0x34,0x7b,0xa6,0x7d,0xa8,0x3d,0xdb,0x3e,0xc1,0x3e,0xc5,0x3e,0xdd,
2239
0x9e,0x6f,0x2f,0xb2,0x97,0xda,0xab,0xed,0x0d,0xf6,0xb5,0xf6,0x4d,0x56,0xda,0xec,
2240
0xbb,0xfe,0x80,0x3e,0xfb,0x41,0xfb,0x7b,0xf6,0x0f,0xec,0x1f,0xdb,0xcf,0xd8,0x2f,
2241
0xd8,0xbf,0xb4,0xb7,0x25,0x38,0x10,0xdc,0x08,0x3e,0x04,0x3f,0x02,0xed,0x37,0x0a,
2242
0x9d,0xc0,0x20,0x04,0x13,0x42,0x08,0x61,0x04,0x16,0x81,0x43,0x88,0x25,0x24,0x12,
2243
0x92,0xfe,0x21,0x92,0x09,0x69,0x04,0x1e,0x41,0x48,0x90,0x10,0x14,0x04,0x2d,0xa0,
2244
0x23,0x18,0x09,0x35,0x84,0x3a,0x42,0x23,0xa1,0xe9,0x57,0x4b,0x0b,0xa1,0x0d,0xe8,
2245
0x20,0x5c,0xff,0x27,0xd3,0xf7,0x23,0x26,0xc2,0xe0,0xf7,0xdc,0xfd,0x91,0x61,0xc2,
2246
0x97,0x84,0x87,0x84,0xc7,0x84,0x27,0x84,0x19,0xc2,0x73,0xc2,0x0b,0xe0,0x25,0x60,
2247
0xbb,0xc9,0x61,0x93,0xdb,0xdf,0x81,0xd7,0xa6,0xbd,0x9b,0x28,0x9b,0x02,0x37,0x1d,
2248
0xd8,0x14,0xbe,0x29,0xe1,0xef,0x20,0x65,0x53,0xfa,0x26,0xfe,0x26,0xd1,0x26,0xe9,
2249
0x26,0xd9,0x26,0xc5,0x26,0xcd,0x26,0xfd,0xa6,0x0f,0x36,0x35,0x6e,0x6a,0xde,0xd4,
2250
0xf2,0x37,0xd3,0xba,0xa9,0x7d,0x53,0xe7,0xa6,0xae,0x4d,0xdd,0x9b,0x7a,0x36,0xf5,
2251
0x59,0x31,0x6d,0xea,0xff,0x23,0xee,0x6e,0xba,0x0f,0x3c,0xfc,0x9e,0xc7,0x3f,0xf2,
2252
0x74,0xd3,0xdc,0xa6,0x85,0x3f,0xc9,0x77,0xff,0x20,0xe8,0x95,0xbf,0x05,0xfb,0x57,
2253
0x9c,0x01,0xb7,0xef,0xf1,0xfa,0x91,0xbd,0xaf,0x50,0x5e,0x09,0xfc,0x1b,0x39,0xf0,
2254
0x4a,0xf8,0xff,0x42,0x62,0x5e,0x49,0xfa,0x6f,0x38,0xfd,0x0a,0xf7,0x95,0x9c,0x57,
2255
0x0a,0xad,0xc8,0x5f,0xd1,0x5a,0xa9,0x7e,0xa5,0xe1,0x95,0x96,0x57,0x3a,0x5e,0xb9,
2256
0xfe,0x4a,0xbf,0x95,0xbb,0xaf,0xdc,0x7f,0xe5,0xe1,0x2b,0x8f,0x5f,0x79,0xfa,0xca,
2257
0x9c,0x95,0x85,0x57,0xbe,0x7b,0x05,0x39,0xd8,0x3b,0x38,0x3b,0xb8,0x39,0x78,0x39,
2258
0xec,0x75,0xa0,0x38,0x04,0x3a,0x1c,0x70,0x08,0xb7,0x12,0xe3,0x90,0xf4,0xab,0x26,
2259
0xd9,0x21,0xe5,0x9f,0x48,0xaa,0x43,0xba,0x95,0x0c,0x07,0x9e,0x03,0x7f,0x8d,0xbf,
2260
0x01,0x91,0x83,0xd4,0x41,0xed,0x60,0x70,0xa8,0xfd,0x5f,0x4c,0x9d,0x43,0xb3,0x43,
2261
0xbb,0x43,0xb7,0x43,0xdf,0xff,0x32,0x06,0x81,0x7b,0x7f,0x91,0x07,0xff,0x34,0xd0,
2262
0xda,0xe7,0x37,0xfe,0xf9,0x67,0x44,0xd5,0xa3,0x3f,0xe2,0x89,0x95,0x99,0x9f,0x89,
2263
0xe7,0x0e,0x2f,0x1c,0x5e,0x3a,0xd8,0x3a,0x3a,0x38,0xba,0x3a,0x7a,0x38,0xfa,0xfc,
2264
0x8b,0xe2,0xe7,0x48,0xfb,0x0b,0x30,0x1d,0x43,0x01,0xf6,0xaf,0x86,0x04,0x2b,0x29,
2265
0x3f,0x0b,0xe9,0x8e,0x7c,0x47,0x91,0x15,0xe9,0x1a,0xff,0x82,0xa8,0xad,0x18,0x1c,
2266
0x6b,0xff,0x02,0x4d,0x8e,0x6d,0xbf,0x28,0x5d,0xbf,0x20,0x7d,0x8e,0x83,0x8e,0xf7,
2267
0x7e,0xb3,0x3c,0xf8,0x8d,0xf1,0xe8,0x0f,0x78,0xe2,0x38,0x03,0x3c,0x77,0xfc,0xee,
2268
0x37,0x0e,0x7a,0xd5,0xfe,0x55,0xe7,0x35,0xfe,0x2c,0x6e,0x80,0xd7,0xab,0x7e,0xaf,
2269
0xd2,0x7e,0x35,0xd0,0x5f,0x65,0xfe,0xa6,0x09,0x7e,0x35,0xf4,0x67,0x26,0xec,0x55,
2270
0xce,0xab,0x09,0xff,0x54,0x12,0x5f,0x4d,0xfa,0x45,0x39,0xfd,0x27,0xe0,0xfe,0x48,
2271
0xce,0x8f,0x14,0xfe,0x88,0xfc,0xcf,0xa2,0xfd,0x13,0x54,0x03,0x0d,0xaf,0xb6,0xbe,
2272
0xda,0xf5,0xaa,0xe9,0xd5,0xbb,0x7f,0xc4,0xfd,0xbf,0x82,0x87,0x7f,0x82,0xc7,0x3f,
2273
0xf2,0xf4,0x47,0xe6,0x7e,0x64,0xe1,0xcf,0xf2,0xdd,0xbf,0x30,0xc8,0x69,0x8d,0x5f,
2274
0x07,0x36,0x4e,0xb6,0x7f,0x12,0x07,0xc0,0x15,0xf0,0x00,0x7c,0x00,0xbf,0xef,0xa1,
2275
0xfd,0xec,0x30,0x81,0x50,0x2b,0x6c,0xa7,0x04,0x20,0x65,0x8d,0x7f,0x31,0x52,0x9d,
2276
0xd2,0x9c,0x32,0x9c,0xb8,0x4e,0x3c,0x27,0x81,0x93,0xd0,0x49,0xec,0x24,0x71,0x92,
2277
0x39,0x29,0x9c,0x34,0x4e,0x3a,0x27,0xa3,0x53,0x8d,0x53,0xad,0x53,0x9d,0x53,0xa3,
2278
0x53,0xb3,0x53,0xab,0x53,0xbb,0x53,0xa7,0x53,0xb7,0x53,0x8f,0x93,0xc9,0x69,0xc0,
2279
0x69,0xc8,0x69,0xd8,0x69,0xc4,0x69,0xd4,0x69,0xcc,0x69,0xdc,0x69,0xc2,0x69,0xd2,
2280
0xe9,0x89,0xd3,0x94,0xd3,0xb4,0x93,0xd9,0xc9,0xe2,0x34,0xef,0xb4,0xe8,0xb4,0xe4,
2281
0xb4,0xec,0xb4,0xe2,0x64,0xe3,0x6c,0xe7,0x4c,0x70,0x76,0x74,0x76,0x71,0x26,0x3a,
2282
0xbb,0x3b,0x7b,0x3a,0x7b,0x3b,0x93,0x9c,0x7d,0x9d,0xc9,0xce,0x54,0x67,0xba,0x33,
2283
0xc3,0x39,0xd8,0x39,0xc4,0x39,0xcc,0x99,0xe5,0xcc,0xfe,0xb3,0x70,0x9c,0x63,0x7e,
2284
0x06,0x62,0x9d,0x13,0x9d,0x93,0x9d,0x53,0x9d,0xd3,0x9c,0x33,0x9c,0x79,0xce,0x02,
2285
0x67,0xa1,0xb3,0xd8,0x59,0xe2,0x2c,0x73,0x56,0x38,0x6b,0x9c,0x75,0xce,0x46,0xe7,
2286
0x1a,0xe7,0x3a,0xe7,0x46,0xe7,0x66,0xe7,0x56,0xe7,0x76,0xe7,0x4e,0xe7,0x6e,0xe7,
2287
0x1e,0x67,0x93,0xf3,0x80,0xf3,0x90,0xf3,0xb0,0xf3,0x88,0xf3,0xa8,0xf3,0x98,0xf3,
2288
0xb8,0xf3,0x84,0xf3,0xa4,0xf3,0x94,0xf3,0xb4,0xf3,0xcc,0xff,0x02,0x9e,0x3b,0xbf,
2289
0x70,0x7e,0xe9,0x6c,0xeb,0xe2,0xe0,0xe2,0xea,0xe2,0xe1,0xe2,0xe3,0x42,0x71,0x61,
2290
0xba,0x84,0xba,0xb0,0x5d,0x12,0x5c,0x52,0x5c,0xd2,0x5d,0xf8,0x2e,0x22,0x17,0xa9,
2291
0x8b,0xda,0xc5,0xe0,0xd2,0xe0,0xd2,0xe6,0x72,0xdd,0x65,0xd0,0xe5,0x9e,0xcb,0x03,
2292
0x97,0x47,0x2e,0x4f,0x5c,0xe6,0x5c,0x5e,0xb8,0xbc,0x74,0xb1,0xdd,0xec,0xb0,0xd9,
2293
0x75,0xb3,0xc7,0x66,0x9f,0xcd,0x7e,0x9b,0x69,0x9b,0x99,0x9b,0x43,0x37,0xb3,0x37,
2294
0x27,0x6c,0x4e,0xd9,0x9c,0xbe,0x99,0xbf,0x59,0xb4,0x59,0xbe,0xd9,0xb0,0xb9,0x76,
2295
0x73,0xd3,0xe6,0xb6,0xcd,0x5d,0x9b,0xfb,0x36,0x0f,0x6e,0xbe,0xb7,0xf9,0xc1,0xe6,
2296
0xc7,0x9b,0x67,0x36,0x3f,0xdf,0xfc,0x62,0xf3,0xcb,0xcd,0xb6,0x5b,0x1c,0xb6,0xb8,
2297
0x6e,0xf1,0xd8,0xe2,0xb3,0xc5,0x6f,0x0b,0x6d,0x0b,0x73,0x4b,0xe8,0x16,0xf6,0x96,
2298
0x84,0x2d,0x29,0x5b,0xd2,0xb7,0xf0,0xb7,0x88,0xb6,0xc8,0xb7,0x18,0xb6,0x34,0x6c,
2299
0x69,0xdb,0x72,0x7d,0xcb,0xe0,0x96,0xfb,0x5b,0x1e,0x6d,0x79,0xb2,0x65,0x66,0xcb,
2300
0xf3,0x2d,0x2f,0xb6,0xbc,0xdc,0x62,0xeb,0xea,0xe0,0xea,0xea,0xea,0xe5,0xea,0xe7,
2301
0x4a,0x73,0x65,0xba,0x86,0xba,0xb2,0x5d,0x13,0x5c,0x53,0x5c,0xb9,0xae,0x22,0x57,
2302
0xb9,0xab,0xc1,0xb5,0xc1,0xb5,0xcd,0xb5,0xcb,0xb5,0xcf,0x75,0xd0,0xf5,0x9e,0xeb,
2303
0x03,0xd7,0x47,0xae,0x4f,0x5c,0x67,0x5c,0x9f,0xbb,0xbe,0x70,0x7d,0xe9,0x6a,0x4b,
2304
0x74,0x20,0xba,0x12,0xbd,0x88,0x7e,0xc4,0x40,0x62,0x28,0x91,0x4d,0x4c,0x20,0xa6,
2305
0x10,0xd3,0x89,0x7c,0xa2,0x88,0x28,0x25,0xaa,0x89,0x06,0x62,0x2d,0xb1,0x89,0xd8,
2306
0x46,0xec,0x22,0xf6,0x11,0x07,0x89,0xf7,0x88,0x0f,0x88,0x8f,0x88,0x4f,0x88,0x33,
2307
0xc4,0xe7,0xc4,0x17,0xc4,0x97,0x44,0xdb,0xad,0x0e,0x5b,0x5d,0xb7,0x7a,0x6c,0xf5,
2308
0xd9,0xea,0xb7,0x95,0xbe,0xf5,0x9d,0xad,0xa1,0x3f,0xc2,0xde,0x9a,0xb0,0x35,0x65,
2309
0x6b,0xfa,0xd6,0x9c,0xad,0xd2,0xad,0xda,0xad,0xb5,0x5b,0x5b,0xb6,0x76,0x6d,0xed,
2310
0xdf,0x7a,0x6f,0xeb,0xc3,0xad,0x4f,0xb6,0xce,0x6d,0x7d,0xb1,0x15,0x6d,0x73,0xd8,
2311
0xe6,0xb6,0xcd,0x67,0x1b,0x65,0x1b,0x73,0x5b,0xf8,0xb6,0x84,0x6d,0x29,0xdb,0xd2,
2312
0xb7,0xf1,0xb7,0x89,0xb6,0x49,0xb7,0xa9,0xb7,0x55,0x6f,0x6b,0xda,0xd6,0xb1,0xad,
2313
0x6f,0xdb,0xdd,0x6d,0x0f,0xb6,0x3d,0xde,0x36,0xb3,0x6d,0x61,0xdb,0xcb,0x6d,0xb6,
2314
0x6e,0x0e,0x6e,0xae,0x6e,0x1e,0x6e,0x3e,0x6e,0x7e,0x6e,0x34,0x37,0xa6,0x5b,0xb8,
2315
0x5b,0x82,0xdb,0x69,0x37,0xbe,0x5b,0xa1,0x9b,0xda,0xad,0xda,0xad,0xc9,0xad,0xc3,
2316
0xad,0xcf,0xed,0xae,0xdb,0x03,0xb7,0xc7,0x6e,0x33,0x6e,0x0b,0x6e,0x2f,0xdd,0xec,
2317
0xdd,0x5d,0xdd,0xbd,0xdc,0xfd,0xdc,0x69,0xee,0x4c,0xf7,0x50,0x77,0xb6,0x7b,0x92,
2318
0x7b,0xba,0x7b,0x8e,0xbb,0xd4,0x5d,0xeb,0x5e,0xeb,0xde,0xe2,0xde,0xe5,0xde,0xef,
2319
0x7e,0xcf,0xfd,0x81,0xfb,0x23,0xf7,0x27,0xee,0x33,0xee,0xcf,0xdd,0x5f,0xb8,0xbf,
2320
0x74,0xb7,0xdd,0xfe,0x87,0x38,0x6c,0x77,0xdd,0xee,0xb5,0xdd,0x6f,0x7b,0xe0,0xf6,
2321
0xd0,0xed,0x31,0xdb,0x53,0xb6,0xa7,0x6f,0xe7,0x6f,0x2f,0xdc,0xae,0xde,0x5e,0xbd,
2322
0xbd,0x69,0x7b,0xc7,0xf6,0xbe,0xed,0x83,0xdb,0xef,0x6d,0x7f,0xb8,0xfd,0xc9,0xf6,
2323
0xb9,0xed,0x2f,0xac,0xbc,0xdc,0x6e,0xfb,0x9a,0xf3,0x6b,0x1e,0xaf,0xed,0x7d,0x8d,
2324
0x66,0x85,0xf9,0x5a,0xe8,0x6b,0x31,0xaf,0xa5,0xbc,0xc6,0x7d,0x4d,0xf4,0x9a,0xfc,
2325
0x35,0xc3,0x6b,0xb5,0xaf,0x35,0xbd,0xd6,0xf1,0x5a,0xdf,0x6b,0x77,0x5f,0x7b,0xf0,
2326
0xda,0xe3,0xd7,0x66,0x5e,0x7b,0xfe,0xda,0x8b,0xd7,0x90,0x87,0x83,0x87,0x9b,0x87,
2327
0x8f,0x07,0xc5,0x83,0xe9,0x11,0xea,0xc1,0xf6,0x48,0xf2,0x48,0xf7,0xc8,0xf1,0x90,
2328
0x7a,0x68,0x3d,0x6a,0x3d,0x9a,0x3c,0xda,0x3c,0xae,0x7b,0x0c,0x7a,0xdc,0xf7,0x78,
2329
0x64,0xe5,0x89,0xc7,0x8c,0xc7,0x82,0xc7,0x4b,0x0f,0x7b,0x4f,0x57,0x2b,0x1e,0x9e,
2330
0x3e,0x9e,0x14,0x4f,0xa6,0x67,0xb8,0x67,0x82,0xe7,0x69,0x4f,0x3e,0x20,0x02,0xe4,
2331
0x80,0x01,0x68,0xf0,0x6c,0xf1,0xec,0xf0,0xec,0xf3,0xbc,0xeb,0xf9,0xc0,0xf3,0xb1,
2332
0xe7,0x8c,0xe7,0x82,0xe7,0x77,0x9e,0x68,0x87,0xc3,0x0e,0xb7,0x1d,0x3e,0x3b,0x28,
2333
0x3b,0x98,0x3b,0xc2,0x77,0xc4,0xec,0x48,0xda,0x71,0x7a,0x07,0x77,0x47,0xce,0x8e,
2334
0xc2,0x1d,0xf2,0x1d,0xda,0x1d,0xd5,0x3b,0x1a,0x76,0xb4,0xec,0xe8,0xd8,0x71,0x7d,
2335
0x47,0xbf,0x95,0x7b,0x3b,0x1e,0xee,0x78,0xba,0x63,0x61,0x07,0x7a,0xdd,0xf9,0x75,
2336
0xaf,0xd7,0x29,0xaf,0x33,0x5f,0x0f,0x7f,0x3d,0xe9,0x75,0xee,0xeb,0x85,0xaf,0x6b,
2337
0x5f,0x6f,0x78,0xbd,0xe3,0xf5,0xbe,0xd7,0xef,0xbe,0xfe,0xf0,0xf5,0xa7,0xaf,0x2f,
2338
0xbc,0x8e,0xbc,0x9c,0xbd,0xbc,0xbc,0xfc,0xbc,0x02,0xbd,0xc2,0xbd,0x92,0xbc,0xb8,
2339
0x5e,0x85,0x5e,0x5a,0xaf,0x06,0xaf,0x36,0xaf,0xeb,0x5e,0x77,0xbd,0x1e,0x7a,0x3d,
2340
0xf5,0x5a,0xf0,0x42,0xde,0xce,0xde,0x1e,0xde,0x7b,0xbd,0x03,0xbd,0xc3,0xbd,0x93,
2341
0xbc,0xb9,0xde,0x85,0xde,0x5a,0xef,0x6a,0xef,0x06,0xef,0x36,0xef,0x2e,0xef,0x7e,
2342
0xe0,0xae,0xf7,0x03,0xef,0x47,0xde,0x4f,0xbc,0x67,0xbc,0x9f,0x7b,0x2f,0x79,0xbf,
2343
0xf4,0xb6,0xd9,0x49,0xd8,0xb9,0x79,0xa7,0xdb,0x4e,0x9f,0x9d,0x7e,0x3b,0x03,0x81,
2344
0x03,0x3b,0xd9,0x3b,0x13,0x76,0xa6,0xec,0x4c,0xdf,0xc9,0xdf,0x99,0xbf,0xb3,0x64,
2345
0x67,0xd9,0x4e,0xc3,0xce,0xda,0x9d,0x4d,0x3b,0x3b,0x76,0xf6,0x59,0x19,0xdc,0x79,
2346
0x7f,0xe7,0xc3,0x9d,0x8f,0x77,0x3e,0xdd,0x39,0xb7,0xf3,0x3f,0x77,0xfe,0xdf,0x9d,
2347
0xff,0xef,0x4e,0xb4,0xcb,0x7e,0x97,0xf3,0x2e,0x8f,0x5d,0x7b,0x77,0x51,0x76,0x05,
2348
0xee,0x3a,0xb0,0x8b,0xbd,0x2b,0x61,0x57,0xca,0xae,0xf4,0x5d,0xfc,0x5d,0xf9,0xbb,
2349
0x4a,0x76,0xa9,0x77,0x69,0xad,0xd4,0xee,0x6a,0xda,0xd5,0x01,0x5c,0xdf,0x35,0xb8,
2350
0xeb,0xde,0xae,0x07,0xbb,0x1e,0xed,0x7a,0xb2,0x6b,0x76,0x97,0x65,0xd7,0xc2,0xae,
2351
0xff,0x0b,0xfc,0x3f,0xbb,0x96,0x77,0xad,0xec,0xb2,0xf1,0xb1,0xf3,0x21,0xf8,0x38,
2352
0xfa,0xb8,0xf8,0x10,0x7d,0xdc,0x7d,0x3c,0x7e,0x82,0xa7,0x8f,0xd7,0x8f,0x78,0xfb,
2353
0xec,0xfd,0x33,0xf8,0xfa,0x90,0x7d,0xe8,0x3e,0x07,0xfe,0x88,0x10,0x9f,0x50,0x2b,
2354
0x61,0x3e,0x1c,0x9f,0x24,0x9f,0x64,0x9f,0x34,0x1f,0xfe,0xf7,0x08,0x7c,0x44,0x3e,
2355
0x62,0x1f,0xe9,0x1f,0x21,0xf3,0xd1,0xf8,0x18,0x7d,0x6a,0xff,0x2c,0x75,0x3e,0x6d,
2356
0x7f,0x40,0xbb,0x4f,0xc7,0x5f,0xa0,0xd3,0xa7,0xdb,0xe7,0x3a,0xd0,0xe3,0x63,0xf2,
2357
0x19,0xf0,0x19,0xf2,0x19,0xf6,0x19,0xf1,0x19,0xf5,0x19,0xf3,0x19,0xf7,0x99,0xf0,
2358
0x99,0xf4,0x99,0xf2,0x99,0xf6,0x31,0xfb,0x58,0x7c,0xe6,0x7d,0x16,0x7d,0x96,0x7c,
2359
0x96,0x7d,0x56,0x7c,0x6c,0x48,0x76,0x24,0x02,0xc9,0x91,0xe4,0x42,0x22,0x92,0xdc,
2360
0x49,0x1e,0x24,0x4f,0x92,0x37,0x89,0x44,0xf2,0x25,0x91,0x49,0x54,0x12,0x9d,0xc4,
2361
0x20,0x05,0x93,0x42,0x48,0x61,0x24,0x16,0x89,0x43,0x8a,0x25,0x25,0x92,0x92,0x49,
2362
0x29,0x7f,0x44,0x2a,0x29,0xfd,0x57,0x45,0x06,0x20,0x24,0xc9,0x48,0x0a,0x92,0x96,
2363
0xa4,0x23,0xd5,0x91,0x5a,0x49,0x6d,0xa4,0x76,0x52,0x37,0xa9,0x87,0x64,0x22,0x0d,
2364
0x90,0x86,0x48,0xc3,0xa4,0x11,0xd2,0x28,0x69,0x8c,0x34,0x4e,0x7a,0x44,0x9a,0x20,
2365
0x4d,0x92,0x9e,0x02,0xd3,0x24,0x33,0xc9,0x42,0x9a,0x27,0x2d,0x92,0x5e,0x00,0x4b,
2366
0xa4,0x15,0x12,0x61,0xb7,0xf3,0x6e,0x97,0xdd,0xae,0x80,0xdb,0x6e,0xf7,0xdd,0x1e,
2367
0x80,0xd7,0x6e,0xdf,0xdd,0xe4,0xdd,0x94,0xdd,0xd4,0xdd,0xf4,0xdd,0x8c,0xdd,0xcc,
2368
0xdd,0xc1,0xbb,0x43,0x76,0x87,0xed,0x66,0xed,0xe6,0xec,0x8e,0xdd,0x9d,0xb8,0x3b,
2369
0x69,0x77,0xf2,0xee,0x8c,0xdd,0xbc,0xdd,0x82,0xdd,0xc2,0xdd,0xe2,0xdd,0x85,0xdf,
2370
0x23,0xd9,0x2d,0xdb,0xad,0xd8,0xad,0xd9,0xad,0xdb,0x6d,0xf8,0x09,0xc6,0xdd,0x8d,
2371
0xbb,0xdb,0x77,0x9b,0x76,0x0f,0xef,0x1e,0xdb,0x3d,0xb9,0xdb,0xbc,0x7b,0x71,0xf7,
2372
0xca,0x6e,0xc2,0x1e,0xe2,0x1e,0xef,0x3d,0xe4,0x3d,0x8c,0x3d,0x61,0x7b,0x38,0x7b,
2373
0x62,0xf7,0x24,0xef,0xc9,0xd8,0x23,0xd8,0x23,0xdc,0x23,0xd9,0xa3,0xd9,0x53,0xb7,
2374
0xa7,0x79,0x4f,0xeb,0x9e,0xce,0x3d,0xa6,0x3d,0x03,0x7b,0x86,0xf6,0x0c,0xef,0x19,
2375
0xd9,0x33,0xba,0x67,0x7c,0xcf,0xd4,0x1e,0xf3,0x1e,0xcb,0x9e,0xc5,0x3d,0x2b,0x7b,
2376
0x1c,0xf7,0x12,0xf7,0xba,0xef,0xf5,0xde,0x4b,0xde,0x4b,0xdd,0x4b,0xdf,0xcb,0xd8,
2377
0xcb,0xfc,0x2f,0x04,0xef,0x0d,0xff,0x8b,0xc4,0xec,0x4d,0xfa,0xab,0x38,0xfd,0x0f,
2378
0xc1,0xdd,0x9b,0xb3,0xb7,0xf0,0x17,0x44,0xfe,0x23,0x5a,0x2b,0xd5,0x7f,0x23,0x0d,
2379
0x40,0xcb,0x8f,0xb4,0xee,0xed,0xdc,0xdb,0xb7,0xd7,0xb4,0x77,0x68,0xef,0xfd,0xbf,
2380
0xc8,0x43,0x2b,0x8f,0xad,0x3c,0x05,0xe6,0xfe,0x26,0x16,0x80,0xef,0xfe,0x24,0xc8,
2381
0xd7,0xde,0xd7,0xd9,0xd7,0xcd,0xd7,0xcb,0xca,0x5e,0x5f,0x8a,0x95,0x40,0xdf,0x03,
2382
0x7f,0x40,0xb8,0x6f,0x8c,0x95,0x24,0xdf,0xd3,0x56,0xb8,0xbe,0x39,0x3f,0x0b,0x85,
2383
0xbe,0x72,0x5f,0xad,0x6f,0xf5,0x3f,0x9d,0x06,0xdf,0x16,0xdf,0x0e,0xdf,0xeb,0x7f,
2384
0x40,0xbf,0xef,0x5d,0xdf,0xfb,0xbe,0x0f,0xff,0xc7,0x78,0xe4,0xfb,0x78,0x8d,0x35,
2385
0x7e,0x21,0x26,0x7d,0xa7,0x7c,0xa7,0x7d,0xcd,0xbe,0x16,0xdf,0x79,0xdf,0x45,0xdf,
2386
0x25,0xdf,0x65,0xdf,0x15,0x5f,0xbb,0x7d,0x8e,0xfb,0x88,0xfb,0x3c,0xf7,0x91,0xf6,
2387
0x91,0xf7,0xd1,0xf7,0x05,0xef,0x0b,0xdb,0xc7,0xd9,0x97,0xb8,0x2f,0x6d,0x9f,0x60,
2388
0x9f,0x64,0x9f,0x66,0x5f,0xcd,0xbe,0xe6,0x7d,0x9d,0xfb,0x4c,0xfb,0x86,0xf7,0x8d,
2389
0xef,0x9b,0xde,0xb7,0xb8,0xcf,0xe6,0x0d,0x97,0x37,0xbc,0xdf,0xa0,0xbe,0x11,0xf2,
2390
0x46,0xec,0x1b,0x69,0x6f,0x08,0xdf,0x90,0xbc,0xa1,0x78,0x43,0xf7,0x46,0xcd,0x1b,
2391
0x8d,0x6f,0xb4,0xbe,0xd1,0xf9,0x46,0xcf,0x1b,0x03,0x6f,0x8c,0xbc,0x31,0xfe,0xc6,
2392
0xd4,0x1b,0x96,0x37,0x96,0xde,0xb0,0xf1,0x73,0xf4,0x73,0xf7,0x23,0xf9,0x51,0xfd,
2393
0x82,0xfd,0x58,0x7e,0x89,0x7e,0x69,0x7e,0x02,0x3f,0x89,0x9f,0xc6,0xaf,0xc6,0xaf,
2394
0xd9,0xaf,0xd3,0xcf,0xe4,0x37,0xec,0x37,0xe6,0x37,0xe9,0x67,0xf6,0x5b,0xf4,0x5b,
2395
0xf1,0x23,0x90,0x89,0x64,0x6f,0x32,0x99,0xcc,0x20,0x87,0x91,0x63,0xc9,0xa9,0x64,
2396
0x1e,0x59,0x4c,0x96,0x90,0x65,0x64,0x05,0x59,0x43,0xd6,0x91,0x8d,0xe4,0x1a,0x72,
2397
0x1d,0xb9,0x91,0xdc,0x4c,0x6e,0x25,0xb7,0x93,0x3b,0xc9,0xdd,0xe4,0x1e,0xb2,0x89,
2398
0x3c,0x40,0x1e,0x22,0x0f,0x93,0x47,0xc8,0xa3,0xe4,0x31,0xf2,0x38,0x79,0x82,0x3c,
2399
0x49,0x9e,0x22,0x4f,0x93,0xcd,0x64,0x0b,0x79,0x9e,0xbc,0x48,0x5e,0x22,0x2f,0x93,
2400
0x57,0xc8,0x36,0xfe,0x76,0xfe,0x04,0x7f,0x47,0x7f,0x17,0x7f,0xa2,0xbf,0xbb,0xbf,
2401
0xa7,0xbf,0xb7,0x3f,0xc9,0xdf,0xd7,0x9f,0xec,0x4f,0xf5,0xa7,0xfb,0x33,0xfc,0x83,
2402
0xfd,0x43,0xfc,0xc3,0xfc,0xc3,0x7f,0x06,0x58,0xfe,0x49,0xff,0x52,0x24,0xfb,0x67,
2403
0xf8,0x0b,0xfc,0x0b,0xff,0x85,0x90,0xaf,0xf1,0x0f,0xa1,0xf0,0xd7,0xf8,0x6b,0xd7,
2404
0xf8,0x97,0x47,0xe7,0x6f,0x58,0x63,0x8d,0x7f,0x22,0x46,0xff,0xea,0x5f,0x05,0x35,
2405
0xfe,0xb5,0x7f,0x86,0x3a,0xa0,0xd1,0xbf,0xd9,0xbf,0xd5,0xbf,0xdd,0xbf,0xd3,0xbf,
2406
0xdb,0xbf,0xc7,0xdf,0xe4,0x3f,0xe0,0x3f,0xe4,0x3f,0xec,0x3f,0xe2,0x3f,0xea,0x3f,
2407
0xe6,0x3f,0xee,0x3f,0xe1,0x3f,0xe9,0x3f,0xe5,0x3f,0xed,0x6f,0xf6,0xb7,0xf8,0xcf,
2408
0xfb,0x2f,0xfa,0x2f,0xf9,0x2f,0xfb,0xaf,0xf8,0xdb,0x04,0xd8,0x05,0x10,0x02,0x1c,
2409
0x03,0x5c,0x02,0x88,0x01,0xee,0x01,0x9e,0x01,0xde,0x01,0xa4,0x00,0xdf,0x00,0x72,
2410
0x00,0x35,0x80,0x1e,0xc0,0x08,0x08,0x0e,0x08,0x09,0x08,0x0b,0x60,0x05,0x70,0x02,
2411
0x62,0x03,0x12,0x03,0x92,0x03,0x52,0x03,0xd2,0x02,0x32,0x02,0x78,0x01,0x82,0x00,
2412
0x61,0x80,0x38,0x40,0x12,0x20,0x0b,0x50,0x04,0x68,0x02,0x74,0x01,0xc6,0x80,0x9a,
2413
0x80,0xba,0x80,0xc6,0x80,0xe6,0x80,0xd6,0x80,0xf6,0x80,0xce,0x80,0xee,0x80,0x9e,
2414
0x00,0x53,0xc0,0x40,0xc0,0x50,0xc0,0x70,0xc0,0x48,0xc0,0x68,0xc0,0x58,0xc0,0x78,
2415
0xc0,0x44,0xc0,0x64,0xc0,0x54,0xc0,0x74,0x80,0x39,0xc0,0x12,0x30,0x1f,0xb0,0x18,
2416
0xb0,0x14,0xb0,0x1c,0xb0,0x12,0x60,0x43,0xb1,0xa3,0x10,0x28,0x8e,0x14,0x17,0x0a,
2417
0x91,0xe2,0x4e,0xf1,0xa4,0x78,0x53,0x48,0xf0,0xa2,0x47,0xa6,0x50,0x29,0x74,0x0a,
2418
0x83,0x12,0x4c,0x09,0xa1,0x84,0x51,0x58,0x14,0x0e,0x25,0x96,0x92,0x48,0x49,0xa6,
2419
0xa4,0x52,0xd2,0x28,0x19,0x14,0x1e,0x45,0x40,0x11,0x52,0xc4,0x14,0x09,0x45,0x46,
2420
0x51,0x50,0x34,0x14,0x1d,0xc5,0x48,0xa9,0xa1,0xd4,0x51,0x1a,0x29,0xcd,0x94,0x56,
2421
0x4a,0x3b,0xa5,0x93,0xd2,0x4d,0xe9,0xa1,0x98,0x28,0x03,0x94,0x21,0xca,0x30,0x65,
2422
0x84,0x32,0x4a,0x19,0xa3,0x8c,0x53,0x26,0x28,0x93,0x94,0x29,0xca,0x34,0xc5,0x4c,
2423
0xb1,0x50,0xe6,0x29,0x8b,0x94,0x25,0xca,0x32,0x65,0x85,0x62,0x43,0xb5,0xa3,0x12,
2424
0xa8,0x8e,0x54,0x17,0x2a,0x91,0xea,0x4e,0xf5,0xa4,0x7a,0x53,0x49,0x54,0x5f,0x2a,
2425
0x99,0x4a,0xa5,0xd2,0xa9,0x0c,0x6a,0x30,0x35,0x84,0x1a,0x46,0x65,0x51,0x39,0xd4,
2426
0x58,0x6a,0x22,0x35,0x99,0x9a,0x4a,0x4d,0xa3,0x66,0x50,0x79,0x54,0x01,0x55,0x48,
2427
0x15,0x53,0x25,0x54,0x19,0x55,0x41,0xd5,0x50,0x75,0x54,0x23,0xb5,0x86,0x5a,0x47,
2428
0x6d,0xa4,0x36,0x53,0x5b,0xa9,0xed,0xd4,0x4e,0x6a,0x37,0xb5,0x87,0x6a,0xa2,0x0e,
2429
0x50,0x87,0xa8,0xc3,0xd4,0x11,0xea,0x28,0x75,0x8c,0x3a,0x4e,0x9d,0xa0,0x4e,0x52,
2430
0xa7,0xa8,0xd3,0x54,0x33,0xd5,0x42,0x7d,0xfe,0x4f,0x60,0x1e,0x58,0xf8,0xc5,0x58,
2431
0xa4,0xbe,0xa0,0x2e,0x51,0x97,0xa9,0x2b,0x54,0xf4,0xbb,0xbf,0x8c,0x3d,0xe0,0x0c,
2432
0xb8,0x01,0x5e,0xc0,0x5e,0x80,0x02,0x04,0x02,0x07,0x80,0x70,0x20,0x06,0x48,0x02,
2433
0x4e,0x5b,0xe1,0x02,0x39,0x40,0xe1,0x1f,0x20,0xff,0x9d,0x16,0xa8,0xfe,0x5d,0x03,
2434
0xd0,0xf2,0xbb,0x0e,0xe0,0xfa,0xef,0xfa,0x81,0xbb,0xbf,0xbb,0xff,0x37,0xf1,0xf0,
2435
0x27,0x8c,0xff,0x6e,0xf2,0x77,0x4f,0x01,0xcb,0xef,0x16,0xfe,0x2c,0xdf,0x01,0xe8,
2436
0x4d,0xf4,0xa6,0x3d,0xe0,0x0c,0xb8,0x01,0x5e,0xc0,0x5e,0x80,0x02,0x04,0x02,0x07,
2437
0x80,0x70,0x20,0xc6,0x4a,0x12,0x70,0x1a,0xe0,0xfe,0x01,0x39,0x6f,0x16,0x02,0xf2,
2438
0x37,0xb5,0x40,0xf5,0x9b,0x0d,0x40,0xcb,0x9b,0x1d,0xc0,0xf5,0x37,0xfb,0xff,0x26,
2439
0xee,0x5a,0xb9,0xff,0xe6,0xc3,0x37,0x1f,0xbf,0xf9,0xf4,0x7b,0x2c,0x6f,0x2e,0xfc,
2440
0x02,0x2c,0xbe,0xb9,0xf4,0xe6,0xf2,0x9b,0x2b,0x6f,0xda,0xd0,0xec,0x68,0x04,0x9a,
2441
0x23,0xcd,0x85,0x46,0xa4,0xb9,0xd3,0x3c,0x69,0xde,0x34,0x12,0xcd,0x97,0x46,0xa6,
2442
0x51,0x69,0x74,0x1a,0x83,0x16,0x4c,0x0b,0xa1,0x85,0xd1,0x58,0x34,0x0e,0x2d,0x96,
2443
0x96,0x48,0x4b,0xa6,0xa5,0xd2,0xd2,0x68,0x19,0x34,0x1e,0x4d,0x40,0x13,0xd2,0xc4,
2444
0x34,0x09,0x4d,0x46,0x53,0xd0,0x34,0x34,0x1d,0xcd,0x48,0xab,0xa1,0xd5,0xd1,0x1a,
2445
0x69,0xcd,0xb4,0x56,0x5a,0x3b,0xad,0x93,0xd6,0x4d,0xeb,0xa1,0x99,0x68,0x03,0xb4,
2446
0x21,0xda,0x30,0x6d,0x84,0x36,0x4a,0x1b,0xa3,0x8d,0xd3,0x26,0x68,0x93,0xb4,0x29,
2447
0xda,0x34,0xcd,0x4c,0xb3,0xd0,0xe6,0x69,0x8b,0xb4,0x25,0xda,0x32,0x6d,0x85,0x66,
2448
0x43,0xb7,0xa3,0x13,0xe8,0x8e,0x74,0x17,0x3a,0x91,0xee,0x4e,0xf7,0xa4,0x7b,0xd3,
2449
0x49,0x74,0x5f,0x3a,0x99,0x4e,0xa5,0xd3,0xe9,0x0c,0x7a,0x30,0x3d,0x84,0x1e,0x46,
2450
0x67,0xd1,0x39,0xf4,0x58,0x7a,0x22,0x3d,0x99,0x9e,0x4a,0x4f,0xa3,0x67,0xd0,0xb9,
2451
0x56,0x78,0x74,0x01,0x5d,0x48,0x17,0xd3,0x25,0x74,0x19,0x5d,0x41,0xd7,0xd0,0x75,
2452
0x74,0x23,0xbd,0x86,0x5e,0x47,0x6f,0xa4,0x37,0xd3,0x5b,0x7e,0xe5,0xb4,0x02,0xdd,
2453
0xf4,0x01,0xfa,0x08,0x7d,0x9c,0x3e,0x45,0xb7,0xd0,0x97,0xe8,0x36,0x6f,0x39,0xbe,
2454
0xe5,0xfe,0x16,0xe9,0x2d,0xea,0x5b,0xc1,0x6f,0xb1,0xde,0x4a,0x7e,0x8b,0xf7,0x96,
2455
0xe4,0x2d,0xdd,0x5b,0x8d,0x6f,0x75,0xbe,0x35,0xf0,0xd6,0xe8,0x5b,0x93,0x6f,0x59,
2456
0xde,0x5a,0x7e,0x8b,0xf0,0xb6,0xfb,0xdb,0xbe,0x6f,0x33,0xde,0x4e,0x7c,0x9b,0xff,
2457
0xb6,0xe0,0x6d,0xc9,0xdb,0x9a,0xb7,0x6b,0xde,0x6e,0x7e,0xbb,0xf3,0x6d,0xd3,0xdb,
2458
0xc3,0x6f,0x8f,0xbd,0x3d,0xf9,0xb6,0xf9,0xed,0xc5,0xb7,0x57,0xde,0x26,0x04,0x12,
2459
0x03,0xbd,0x03,0xc9,0x81,0x8c,0xc0,0xb0,0xc0,0xd8,0xc0,0xd4,0x40,0x5e,0xa0,0x38,
2460
0x50,0x11,0x68,0x0c,0x6c,0x0c,0x6c,0x0f,0xec,0x09,0x1c,0x0a,0x1c,0x0d,0x9c,0x08,
2461
0x9c,0x0e,0x9c,0x0f,0x5c,0x0e,0xb4,0x63,0xb8,0x30,0x3c,0x19,0xde,0x0c,0x12,0xc3,
2462
0x97,0xe1,0xf7,0x47,0x90,0x19,0x0c,0x46,0x08,0x83,0xc5,0x88,0x65,0x24,0x33,0xd2,
2463
0x18,0x3c,0x86,0x90,0x21,0x61,0x28,0x18,0x3a,0x46,0x0d,0xa3,0x91,0xd1,0xca,0xe8,
2464
0x64,0xf4,0x30,0x4c,0x8c,0x01,0xc6,0x10,0x63,0x98,0x31,0xc2,0x18,0x65,0x8c,0x31,
2465
0xc6,0x19,0x13,0x8c,0x49,0xc6,0x14,0x63,0x9a,0x61,0x66,0x58,0x18,0x8b,0x8c,0x65,
2466
0x86,0x4d,0x10,0x21,0xc8,0x25,0xc8,0x3d,0xc8,0x3b,0xc8,0x37,0x88,0x1a,0xc4,0x08,
2467
0x0a,0x09,0x62,0x05,0xc5,0x06,0x25,0x07,0x09,0x82,0x64,0x41,0xea,0x20,0x4d,0x90,
2468
0x2e,0xc8,0x18,0x54,0x13,0x54,0x17,0xd4,0x18,0xd4,0x1c,0xd4,0x1a,0xd4,0x1e,0xd4,
2469
0x19,0xd4,0x1d,0xd4,0x13,0x64,0x0a,0x1a,0x08,0x1a,0x0a,0x1a,0x0e,0x1a,0x09,0x1a,
2470
0x0d,0x1a,0x0b,0x1a,0x0f,0x9a,0x08,0x9a,0x0c,0x9a,0x0a,0x9a,0x0e,0x32,0x07,0x59,
2471
0x82,0xe6,0x83,0x16,0x83,0x96,0x82,0x96,0x83,0x56,0x82,0x6c,0xf6,0xdb,0xed,0x27,
2472
0xec,0x77,0xdc,0xef,0xb2,0x9f,0xb8,0xdf,0x7d,0xbf,0xe7,0x7e,0xef,0xfd,0xa4,0xfd,
2473
0xbe,0xfb,0xc9,0xfb,0xa9,0xfb,0xe9,0xfb,0x19,0xfb,0x83,0xf7,0x87,0xec,0x0f,0xdb,
2474
0xcf,0xda,0x1f,0xbb,0x3f,0x79,0x7f,0xda,0x7e,0xde,0x7e,0xe1,0x7e,0xc9,0x7e,0xc5,
2475
0x7e,0xdd,0xfe,0x9a,0xfd,0x8d,0xfb,0x5b,0xf7,0x77,0xee,0xef,0xd9,0x3f,0xb0,0x7f,
2476
0x78,0xff,0xe8,0xfe,0xf1,0xfd,0x93,0xfb,0xa7,0xf7,0x5b,0xf6,0x2f,0xee,0x5f,0xde,
2477
0x6f,0xc3,0x24,0x30,0x89,0x4c,0x6f,0x26,0x99,0x49,0x67,0x86,0x30,0x59,0xcc,0x44,
2478
0x66,0x32,0x33,0x95,0x99,0xc6,0xcc,0x60,0xf2,0x98,0x02,0xa6,0x90,0x29,0x66,0x4a,
2479
0x98,0x32,0xa6,0x82,0xa9,0x61,0xea,0x98,0x46,0x66,0x0d,0xb3,0x8e,0xd9,0xc8,0x6c,
2480
0x66,0xb6,0x32,0xdb,0x99,0x9d,0xcc,0x6e,0x66,0x0f,0xd3,0xc4,0x1c,0x60,0x0e,0x31,
2481
0x87,0x99,0x23,0xcc,0x51,0xe6,0x18,0x73,0x9c,0x39,0xc1,0x9c,0x64,0x4e,0x31,0xa7,
2482
0x99,0x66,0xa6,0x85,0x39,0xcf,0x5c,0x64,0x2e,0x31,0x97,0x99,0x2b,0x4c,0x9b,0x60,
2483
0xbb,0x60,0x42,0xb0,0x63,0xb0,0x4b,0xb0,0x3b,0x40,0x0e,0x0e,0x0e,0x8e,0x0d,0x4e,
2484
0x0d,0x16,0x06,0xcb,0x82,0x75,0xc1,0xad,0xc1,0x3d,0xc1,0x43,0xc1,0xa3,0xc1,0x13,
2485
0xc1,0xe6,0xe0,0xa5,0x60,0xbb,0x77,0x88,0xef,0x90,0xde,0xa1,0xbf,0x13,0xf6,0x4e,
2486
0xea,0x3b,0x19,0xef,0xc8,0xde,0xa9,0x7b,0xa7,0xf3,0x9d,0x81,0x77,0xc6,0xdf,0xb1,
2487
0xbc,0xb3,0xfc,0x8e,0xdd,0xbb,0x2e,0xef,0x7a,0xbf,0x4b,0x7d,0x37,0xec,0xdd,0xe4,
2488
0x77,0x33,0xde,0x15,0xbe,0xab,0x78,0xd7,0xf8,0x6e,0xe3,0xbb,0xad,0xef,0x76,0xbe,
2489
0x6b,0x7a,0x77,0xf8,0xdd,0xc9,0x77,0x2d,0xef,0xae,0xbc,0x4b,0x3c,0x40,0x3a,0x40,
2490
0x3d,0x10,0x7c,0x20,0xf1,0x40,0xc6,0x01,0xd9,0x01,0xdd,0x81,0xe6,0x03,0x9d,0x07,
2491
0x06,0x0e,0x8c,0x1c,0x98,0x38,0x60,0x39,0xb0,0x7c,0xc0,0x31,0xc4,0x33,0x84,0x14,
2492
0xc2,0x08,0x09,0x0b,0x89,0x0d,0x49,0x0b,0x11,0x84,0x48,0x42,0x34,0x21,0x8d,0x21,
2493
0x9d,0x21,0x3d,0x21,0xa3,0x21,0x13,0x21,0x96,0x90,0xe5,0x10,0xc2,0x41,0xe2,0x41,
2494
0xef,0x83,0xd4,0x83,0x8c,0x83,0xac,0x83,0xa9,0x07,0x33,0x0e,0xca,0x0e,0xea,0x0e,
2495
0xd6,0x1c,0x6c,0x3c,0xd8,0x7a,0xb0,0xf3,0x60,0xcf,0xc1,0x81,0x83,0xc3,0x07,0x47,
2496
0x0f,0x8e,0x1f,0x9c,0x3c,0x68,0x3e,0xb8,0x78,0x70,0xe5,0x20,0xe1,0x10,0xf1,0x90,
2497
0xf7,0x21,0xf2,0x21,0xc6,0xa1,0xb0,0x43,0xb1,0x87,0x52,0x0f,0xf1,0x0e,0x89,0x0f,
2498
0x29,0x0e,0x19,0x0f,0x35,0x1e,0x6a,0x3d,0xd4,0x79,0xc8,0x74,0x68,0xe8,0xd0,0xc8,
2499
0xa1,0xb1,0x43,0x93,0x87,0xcc,0x87,0xe6,0x0f,0x2d,0x1d,0x5a,0x39,0x64,0x17,0xea,
2500
0x18,0xea,0x19,0x4a,0x0a,0x25,0x87,0xd2,0x43,0x83,0x43,0xc3,0x42,0x39,0xa1,0x89,
2501
0xa1,0xa9,0xa1,0xbc,0x50,0x49,0xa8,0x22,0x54,0x17,0x5a,0x13,0xda,0x18,0xda,0x1a,
2502
0xda,0x19,0xda,0x13,0x3a,0x14,0x3a,0x1a,0x3a,0x11,0x3a,0x1d,0x6a,0x09,0x5d,0x0c,
2503
0x5d,0x0e,0xb5,0x09,0x23,0x84,0xb9,0x84,0xb9,0x87,0x79,0x87,0xf9,0x86,0x51,0xc3,
2504
0x82,0xc3,0x58,0x61,0xb1,0x61,0xa9,0x61,0xbc,0x30,0x71,0x98,0x2c,0x4c,0x17,0x56,
2505
0x17,0xd6,0x1e,0xd6,0x1d,0x36,0x10,0x36,0x12,0x36,0x1e,0x36,0x15,0xb6,0x18,0x46,
2506
0x38,0xec,0x72,0xd8,0xfd,0xb0,0xf7,0x61,0xdf,0xc3,0xd4,0xc3,0x8c,0xc3,0x21,0x87,
2507
0x59,0x87,0x63,0x0f,0x27,0x1f,0x4e,0x3b,0xcc,0x3b,0x2c,0x3c,0x2c,0x39,0xac,0x38,
2508
0xac,0x3b,0x5c,0x73,0xb8,0xf1,0x70,0xe7,0xe1,0x9e,0xc3,0x03,0x87,0x87,0x0f,0x8f,
2509
0x1f,0x9e,0x3a,0x6c,0x3e,0x3c,0x7f,0x78,0xe9,0xf0,0xca,0x61,0xbb,0x23,0x8e,0x47,
2510
0x88,0x47,0x3c,0x8f,0x90,0x8e,0x90,0x8f,0x30,0x8e,0x84,0x1c,0x61,0x1d,0x49,0x3c,
2511
0x92,0x76,0x84,0x77,0x44,0x72,0x44,0x73,0xc4,0x78,0xa4,0xee,0x48,0xf3,0x91,0xf6,
2512
0x23,0x3d,0x47,0x86,0x8e,0x8c,0x1c,0x19,0x3b,0x32,0x71,0x64,0xea,0x88,0xf9,0xc8,
2513
0xfc,0x91,0xa5,0x23,0x2b,0x47,0xec,0xc2,0x5d,0xc2,0x3d,0xc3,0x7d,0xc3,0xe9,0xe1,
2514
0x21,0xe1,0x9c,0xf0,0xe4,0xf0,0x8c,0x70,0x61,0xb8,0x2c,0x5c,0x17,0x5e,0x17,0xde,
2515
0x1a,0xde,0x1d,0x3e,0x10,0x3e,0x12,0x3e,0x1e,0x3e,0x15,0x6e,0x09,0x5f,0x0a,0xb7,
2516
0x61,0x39,0xb2,0xdc,0xd6,0xf8,0x3b,0x71,0x67,0x79,0xb2,0xbc,0xd6,0xf8,0x15,0xe0,
2517
0xcd,0xf2,0xf9,0x8d,0x43,0x62,0xf9,0xb2,0xc8,0x2c,0x2a,0x8b,0x66,0x85,0xce,0x62,
2518
0xb0,0x98,0xff,0x12,0x04,0xb3,0x42,0x58,0x61,0x2c,0x16,0x8b,0xfd,0x5f,0xe0,0xb0,
2519
0x62,0xd6,0xf8,0x9b,0x48,0x60,0x25,0xb1,0x52,0x58,0xa7,0x59,0xe9,0x2c,0x2e,0x8b,
2520
0xcf,0xca,0x61,0x89,0x58,0x85,0x2c,0x29,0x4b,0xce,0x52,0xb3,0xb4,0x2c,0x03,0xab,
2521
0x9a,0x55,0xcb,0x6a,0x60,0x35,0xb1,0x5a,0x58,0x6d,0xac,0x0e,0x56,0x17,0xeb,0x3a,
2522
0xab,0x8f,0xd5,0xcf,0x1a,0x64,0xdd,0x65,0xdd,0x63,0xdd,0x67,0x3d,0x60,0x3d,0x64,
2523
0x3d,0x62,0x3d,0x66,0x3d,0x61,0x3d,0x65,0xcd,0xb0,0xe6,0x58,0xcf,0x59,0x0b,0xac,
2524
0x17,0xac,0xef,0x58,0x2f,0x59,0x28,0xc2,0x36,0xc2,0x3e,0xc2,0x21,0xc2,0x39,0xc2,
2525
0x35,0xc2,0x2d,0xc2,0x23,0xc2,0x2b,0xc2,0x27,0x62,0x6f,0x84,0x5f,0x04,0x25,0x82,
2526
0x16,0x11,0x18,0xc1,0x8c,0x38,0x10,0x11,0x1a,0x11,0x1e,0xc1,0x8e,0x88,0x89,0x48,
2527
0x88,0x48,0x8a,0x48,0x89,0x38,0x1d,0x91,0x1e,0xc1,0x8d,0xe0,0x47,0xe4,0x44,0x88,
2528
0x22,0x0a,0x23,0xa4,0x11,0xf2,0x08,0x75,0x84,0x36,0xc2,0x10,0x51,0x1d,0x51,0x1b,
2529
0xd1,0x10,0xd1,0x14,0xd1,0x12,0xd1,0x16,0xd1,0x11,0xd1,0x15,0x71,0x3d,0xa2,0x2f,
2530
0xa2,0x3f,0x62,0x30,0xe2,0x6e,0xc4,0xbd,0x88,0xfb,0x11,0x0f,0x22,0x1e,0x46,0x3c,
2531
0x8a,0x78,0x1c,0xf1,0x24,0xe2,0x69,0xc4,0x4c,0xc4,0x5c,0xc4,0xf3,0x88,0x85,0x88,
2532
0x17,0x11,0xdf,0x45,0xbc,0x8c,0x40,0x91,0xb6,0x91,0xf6,0x91,0x0e,0x91,0xce,0x91,
2533
0xae,0x91,0x6e,0x91,0x1e,0x91,0x5e,0x91,0x3e,0x91,0x7b,0x23,0xfd,0x22,0x29,0x91,
2534
0xb4,0xc8,0xc0,0x48,0x66,0xe4,0x81,0xc8,0xd0,0xc8,0xf0,0x48,0x76,0x64,0x4c,0x64,
2535
0x42,0x64,0x52,0x64,0x4a,0xe4,0xe9,0xc8,0xf4,0x48,0x6e,0x24,0x3f,0x32,0x27,0x52,
2536
0x14,0x59,0x18,0x29,0x8d,0x94,0x47,0xaa,0x23,0xb5,0x91,0x86,0xc8,0xea,0xc8,0xda,
2537
0xc8,0x86,0xc8,0xa6,0xc8,0x96,0xc8,0xb6,0xc8,0x8e,0xc8,0xae,0xc8,0xeb,0x91,0x7d,
2538
0x91,0xfd,0x91,0x83,0x91,0x77,0x23,0xef,0x45,0xde,0x8f,0x7c,0x10,0xf9,0x30,0xf2,
2539
0x51,0xe4,0xe3,0xc8,0x27,0x91,0x4f,0x23,0x67,0x22,0xe7,0x22,0x9f,0x47,0x2e,0x44,
2540
0xbe,0x88,0xfc,0x2e,0xf2,0x65,0x24,0x62,0xdb,0xb2,0xed,0xd9,0x0e,0x6c,0x67,0xb6,
2541
0x2b,0xdb,0x8d,0xed,0xc1,0xf6,0x62,0xfb,0xb0,0xf7,0xb2,0xfd,0xd8,0x14,0x36,0x8d,
2542
0x1d,0xc8,0x66,0xb2,0x0f,0xb0,0x43,0xd9,0xe1,0x6c,0x36,0x3b,0x86,0x9d,0xc0,0x4e,
2543
0x62,0xa7,0xb0,0x4f,0xb3,0xd3,0xd9,0x5c,0x36,0x9f,0x9d,0xc3,0x16,0xb1,0x0b,0xd9,
2544
0x52,0xb6,0x9c,0xad,0x66,0x6b,0xd9,0x06,0x76,0x35,0xbb,0x96,0xdd,0xc0,0x6e,0x62,
2545
0xb7,0xb0,0xdb,0xd8,0x1d,0xec,0x2e,0xf6,0x75,0x76,0x1f,0xbb,0x9f,0x3d,0xc8,0xbe,
2546
0xcb,0xbe,0xc7,0xbe,0xcf,0x7e,0xc0,0x7e,0xc8,0x7e,0xc4,0x7e,0xcc,0x7e,0xc2,0x7e,
2547
0xca,0x9e,0x61,0xcf,0xb1,0x9f,0xb3,0x17,0xd8,0x2f,0xd8,0xdf,0xb1,0x5f,0xb2,0x11,
2548
0xc7,0x96,0x63,0xcf,0x71,0xe0,0x38,0x73,0x5c,0x39,0x6e,0x1c,0x0f,0x8e,0x17,0xc7,
2549
0x87,0xb3,0x97,0xe3,0xc7,0xa1,0x70,0x68,0x9c,0x40,0x0e,0x93,0x73,0x80,0x13,0xca,
2550
0x09,0xe7,0xb0,0x39,0x31,0x40,0x02,0x27,0x89,0x93,0xc2,0x39,0xcd,0x49,0xe7,0x70,
2551
0x39,0x7c,0x4e,0x0e,0x47,0xc4,0x29,0xe4,0x48,0x39,0x72,0x8e,0x9a,0xa3,0xb5,0x62,
2552
0x00,0xaa,0xad,0xd4,0x72,0x1a,0x38,0x4d,0x9c,0x16,0x4e,0x1b,0xa7,0x83,0xd3,0xc5,
2553
0xb9,0xce,0xe9,0xe3,0xf4,0x03,0x83,0xc0,0x5d,0x2b,0xf7,0x38,0xf7,0xbf,0xe7,0x01,
2554
0xe7,0x21,0xe7,0x11,0xe7,0x31,0xe7,0x09,0xe7,0x29,0x67,0x86,0x33,0xc7,0x79,0xce,
2555
0x59,0xe0,0xbc,0xe0,0x7c,0xc7,0x79,0xc9,0x41,0x51,0xb6,0x51,0xf6,0x51,0x0e,0x51,
2556
0xce,0x51,0xae,0x51,0x6e,0x51,0x1e,0x51,0x5e,0x51,0x3e,0x51,0x7b,0xa3,0xfc,0xa2,
2557
0x28,0x51,0xb4,0xa8,0xc0,0x28,0x66,0xd4,0x81,0xa8,0xd0,0xa8,0xf0,0x28,0x76,0x54,
2558
0x4c,0x54,0x42,0x54,0x52,0x54,0x4a,0xd4,0xe9,0xa8,0xf4,0x28,0x6e,0x14,0x3f,0x2a,
2559
0x27,0x4a,0x14,0x55,0x18,0x25,0x8d,0x92,0x47,0xa9,0xa3,0xb4,0x51,0x86,0xa8,0xea,
2560
0xa8,0xda,0xa8,0x86,0xa8,0xa6,0xa8,0x96,0xa8,0xb6,0xa8,0x8e,0xa8,0xae,0xa8,0xeb,
2561
0x51,0x7d,0x51,0xfd,0x51,0x83,0x51,0x77,0xa3,0xee,0x45,0xdd,0x8f,0x7a,0x10,0xf5,
2562
0x30,0xea,0x51,0xd4,0x63,0x2b,0x4f,0xa2,0x9e,0x46,0xcd,0x44,0xcd,0x45,0x3d,0x8f,
2563
0x5a,0x88,0x7a,0x11,0xf5,0x5d,0xd4,0xcb,0x28,0x14,0x6d,0x1b,0x6d,0x1f,0xed,0x10,
2564
0xed,0x1c,0xed,0x1a,0xed,0x16,0xed,0x11,0xed,0x15,0xed,0x13,0xbd,0x37,0xda,0x2f,
2565
0x9a,0x12,0x4d,0x8b,0x0e,0x8c,0x66,0x46,0x1f,0x88,0x0e,0x8d,0x0e,0x8f,0x66,0x47,
2566
0xc7,0x44,0x27,0x44,0x27,0x45,0xa7,0x44,0x9f,0x8e,0x4e,0x8f,0xe6,0x46,0xf3,0xa3,
2567
0x73,0xa2,0x45,0xd1,0x85,0xd1,0xd2,0x68,0x79,0xb4,0x3a,0x5a,0x1b,0x6d,0x88,0xae,
2568
0x8e,0xae,0x8d,0x6e,0x88,0x6e,0x8a,0x6e,0x89,0x6e,0x8b,0xee,0x88,0xee,0x8a,0xbe,
2569
0x1e,0xdd,0x17,0xdd,0x1f,0x3d,0x18,0x7d,0x37,0xfa,0x5e,0xf4,0xfd,0xe8,0x07,0xd1,
2570
0x0f,0xa3,0x1f,0x45,0x3f,0x8e,0x7e,0x12,0xfd,0x34,0x7a,0x26,0x7a,0x2e,0xfa,0x79,
2571
0xf4,0x42,0xf4,0x8b,0xe8,0xef,0xa2,0x5f,0x46,0xa3,0x18,0xdb,0x18,0xfb,0x18,0x87,
2572
0x18,0xe7,0x18,0xd7,0x18,0xb7,0x18,0x8f,0x18,0xaf,0x18,0x9f,0x98,0xbd,0x31,0x7e,
2573
0x31,0x94,0x18,0x5a,0x4c,0x60,0x0c,0x33,0xe6,0x40,0x4c,0x68,0x4c,0x78,0x0c,0x3b,
2574
0x26,0x26,0x26,0x21,0x26,0x29,0x26,0x25,0xe6,0x74,0x4c,0x7a,0x0c,0x37,0x86,0x1f,
2575
0x93,0x13,0x23,0x8a,0x29,0x8c,0x91,0xc6,0xc8,0x7f,0x46,0x14,0x80,0x2e,0xa6,0x26,
2576
0xa6,0x31,0xa6,0x3d,0xa6,0x27,0x66,0x20,0xe6,0xee,0x9f,0x61,0x38,0x66,0x34,0x66,
2577
0x3c,0x66,0x32,0x66,0x3a,0x66,0xee,0x27,0x2c,0x00,0xcb,0x31,0x2b,0x31,0x36,0xb1,
2578
0x76,0xb1,0x84,0x58,0xc7,0x58,0x97,0x58,0x62,0xac,0x7b,0xac,0x67,0xac,0x57,0xec,
2579
0xde,0x58,0x4a,0x2c,0x33,0x36,0x3c,0x36,0x26,0x36,0x29,0xf6,0x74,0x2c,0x37,0x36,
2580
0x27,0xb6,0x30,0x56,0x1e,0xab,0x8d,0xad,0x06,0x1a,0x62,0x5b,0x62,0x3b,0x62,0xaf,
2581
0xc7,0xf6,0x03,0x77,0x81,0xfb,0xb1,0x0f,0x81,0xc7,0xb1,0x4f,0x81,0xb9,0xd8,0x85,
2582
0xd8,0xef,0x62,0x51,0x9c,0x7d,0x9c,0x73,0x9c,0x5b,0x9c,0x57,0x9c,0x6f,0x1c,0x35,
2583
0x8e,0x1e,0xc7,0x88,0x0b,0x8e,0x0b,0x89,0x0b,0x8b,0x63,0xc5,0x71,0xe2,0x62,0xe3,
2584
0x12,0xe3,0x92,0xe3,0x52,0xe3,0xd2,0xe2,0x32,0xe2,0x78,0x71,0x82,0x38,0x61,0x9c,
2585
0x38,0x4e,0x12,0x27,0x8b,0x53,0xc4,0x69,0xe2,0x74,0x71,0xc6,0xb8,0x9a,0xb8,0xba,
2586
0xb8,0xc6,0xb8,0xe6,0xb8,0xd6,0xb8,0xf6,0xb8,0xce,0xb8,0xee,0xb8,0x9e,0x38,0x53,
2587
0xdc,0x40,0xdc,0x50,0xdc,0x70,0xdc,0x48,0xdc,0x68,0xdc,0x58,0xdc,0x78,0xdc,0x44,
2588
0xdc,0x64,0xdc,0x54,0xdc,0x74,0x9c,0x39,0xce,0x12,0x37,0x1f,0xb7,0x18,0xb7,0x14,
2589
0xb7,0x1c,0xb7,0x12,0x67,0x13,0x6f,0x17,0x4f,0x88,0x77,0x8c,0x77,0x89,0x27,0xc6,
2590
0xbb,0xc7,0x7b,0xc6,0x7b,0xc7,0x93,0xe2,0x7d,0xe3,0xc9,0xf1,0xd4,0x78,0x7a,0x3c,
2591
0x23,0x3e,0x38,0x3e,0x24,0x3e,0x2c,0x9e,0x15,0xcf,0x89,0x8f,0x8d,0x4f,0x8c,0x4f,
2592
0x8e,0x4f,0x8d,0x4f,0x8b,0xcf,0x88,0xe7,0xc5,0x0b,0xe2,0x85,0xf1,0xe2,0x78,0x49,
2593
0xbc,0x2c,0x5e,0x11,0xaf,0x8b,0xaf,0x89,0xaf,0x8b,0x6f,0x8c,0x6f,0x8e,0x6f,0x8d,
2594
0x6f,0x8f,0xef,0x8c,0xef,0x8e,0xef,0x89,0x37,0xc5,0x0f,0xc4,0x0f,0xc7,0xdf,0xff,
2595
0x87,0x19,0x8d,0x1f,0x8b,0x1f,0x8f,0x9f,0x88,0x9f,0x8c,0x9f,0x8a,0x9f,0x8e,0x37,
2596
0xc7,0x5b,0xe2,0xe7,0xe3,0x17,0xe3,0x97,0xe3,0x57,0xe2,0x6d,0x12,0xec,0x12,0x08,
2597
0x09,0x8e,0x09,0x2e,0x09,0xc4,0x04,0xf7,0x04,0xcf,0x04,0xef,0x04,0x52,0x82,0x6f,
2598
0x02,0x3d,0x21,0x24,0x81,0x93,0x90,0x9c,0x90,0x91,0x20,0x4c,0x90,0x25,0xe8,0x12,
2599
0xea,0x12,0x5a,0x13,0xba,0x13,0x06,0x12,0x46,0x12,0xc6,0x13,0xa6,0x12,0x2c,0x09,
2600
0x4b,0x09,0x36,0x89,0x76,0x89,0x84,0x44,0xc7,0x44,0x17,0xc0,0x33,0xd1,0x37,0x91,
2601
0x9e,0x18,0x92,0xc8,0x49,0x4c,0x4c,0x4c,0x4d,0xcc,0x48,0x14,0x24,0x8a,0x13,0x65,
2602
0x89,0x9a,0x44,0x63,0x62,0x5d,0x62,0x73,0x62,0x7b,0x62,0x77,0xa2,0x29,0x71,0x28,
2603
0x71,0x24,0x71,0x2c,0x71,0x22,0x71,0x2a,0xd1,0x9c,0x38,0x9f,0xb8,0x94,0xb8,0x92,
2604
0x68,0x77,0xd4,0xf1,0x28,0xf1,0xa8,0xe7,0x51,0xd2,0x51,0xf2,0x51,0xfa,0xd1,0xe0,
2605
0xa3,0x61,0x47,0x39,0x47,0x13,0x8f,0xa6,0x1e,0xcd,0x38,0x2a,0x38,0x2a,0x3e,0x2a,
2606
0x3b,0xaa,0x39,0x6a,0x3c,0x5a,0x77,0xb4,0xf9,0x68,0xfb,0xd1,0xee,0xa3,0xa6,0xa3,
2607
0x43,0x47,0x47,0x8e,0x8e,0x1d,0x9d,0x38,0x3a,0x75,0xd4,0x7c,0x74,0xfe,0xe8,0xd2,
2608
0xd1,0x95,0xa3,0x76,0xc7,0x1c,0x8f,0x11,0x8f,0x79,0x1e,0x23,0x1d,0x23,0x1f,0xa3,
2609
0x1f,0x0b,0x3e,0x16,0x76,0x8c,0x73,0x2c,0xf1,0x58,0xea,0xb1,0x8c,0x63,0x82,0x63,
2610
0xe2,0x63,0xb2,0x63,0x9a,0x63,0xc6,0x63,0x75,0xc7,0x9a,0x8f,0xb5,0x1f,0xeb,0x3e,
2611
0x66,0x3a,0x36,0x74,0x6c,0xe4,0xd8,0xd8,0xb1,0x89,0x63,0x53,0xc7,0xcc,0xc7,0xe6,
2612
0x8f,0x2d,0x1d,0x5b,0x39,0x66,0x97,0xe4,0x98,0x44,0x4c,0xf2,0x4e,0x22,0x27,0x31,
2613
0x92,0xc2,0x92,0x62,0x93,0x52,0x93,0x78,0x49,0xe2,0x24,0x45,0x92,0x31,0xa9,0x31,
2614
0xa9,0x3d,0xa9,0x3b,0xc9,0x94,0x34,0x94,0x34,0x92,0x34,0x96,0x34,0x91,0x34,0x95,
2615
0x64,0x4e,0x9a,0x4f,0x5a,0x4a,0x5a,0x49,0xb2,0x4b,0x76,0x4c,0x26,0x26,0x7b,0x26,
2616
0x93,0x92,0xc9,0xc9,0xf4,0xe4,0xe0,0xe4,0xb0,0x64,0x4e,0x72,0x62,0x72,0x6a,0x72,
2617
0x46,0xb2,0x20,0x59,0x9c,0x2c,0x4b,0xd6,0x24,0x1b,0x93,0xeb,0x92,0x9b,0x93,0xdb,
2618
0x93,0xbb,0x93,0x4d,0xc9,0x43,0xc9,0x23,0xc9,0x63,0xc9,0x13,0xc9,0x53,0xc9,0xe6,
2619
0xe4,0xf9,0xe4,0xa5,0xe4,0x95,0x64,0xbb,0xe3,0x8e,0xc7,0xdd,0x8f,0x93,0x8e,0x53,
2620
0x8f,0x07,0x1f,0x67,0x1d,0x8f,0x3d,0x9e,0x7c,0x3c,0xed,0x38,0xef,0xb8,0xf0,0xb8,
2621
0xe4,0xb8,0xe2,0xb8,0xee,0x78,0xcd,0xf1,0xc6,0xe3,0xad,0xc7,0x3b,0x8f,0xf7,0x1c,
2622
0x1f,0x38,0x3e,0x7c,0x7c,0xf4,0xf8,0xf8,0xf1,0xc9,0xe3,0xd3,0xc7,0x2d,0xc7,0x17,
2623
0x8f,0x2f,0x1f,0xb7,0x39,0x41,0x38,0xe1,0x72,0xc2,0xfd,0x84,0xf7,0x09,0xdf,0x13,
2624
0xd4,0x13,0x8c,0x13,0x21,0x27,0x58,0x27,0x62,0x4f,0x24,0x9f,0x48,0x3b,0xc1,0x3b,
2625
0x21,0x3c,0x21,0x39,0xa1,0x38,0xa1,0x3b,0x51,0x73,0xa2,0xf1,0x44,0xeb,0x89,0xce,
2626
0x13,0x3d,0x27,0x06,0x4e,0x0c,0x9f,0x18,0x3d,0x31,0x7e,0x62,0xf2,0xc4,0xf4,0x09,
2627
0xcb,0x89,0xc5,0x13,0xcb,0x27,0x6c,0x52,0x08,0x29,0x2e,0x29,0xee,0x29,0xde,0x29,
2628
0xbe,0x29,0xd4,0x14,0x46,0x4a,0x48,0x0a,0x2b,0x25,0x36,0x25,0x39,0x25,0x2d,0x45,
2629
0x90,0x22,0x49,0x51,0xa4,0xe8,0x52,0x6a,0x52,0x1a,0x53,0x5a,0x53,0x3a,0x53,0x7a,
2630
0x52,0x06,0x52,0x86,0x53,0x46,0x53,0xc6,0x53,0x26,0x53,0xa6,0x53,0x2c,0x29,0x8b,
2631
0x29,0xcb,0x29,0x36,0xa9,0x8e,0xa9,0xee,0xa9,0xa4,0x54,0x72,0x2a,0x3d,0x35,0x38,
2632
0x35,0x2c,0x95,0x93,0x9a,0x98,0x9a,0x9a,0x9a,0x91,0x2a,0x48,0x15,0xa7,0xca,0x00,
2633
0x4d,0xaa,0x31,0xb5,0x2e,0xb5,0x39,0xb5,0x3d,0xb5,0x3b,0xd5,0x94,0x3a,0x94,0x3a,
2634
0x92,0x3a,0x96,0x3a,0x91,0x3a,0x95,0x6a,0x4e,0x9d,0x4f,0x5d,0x4a,0x5d,0x49,0xb5,
2635
0x3b,0xe9,0x78,0x92,0x78,0xd2,0xf3,0x24,0xe9,0x24,0xf9,0x24,0xfd,0x64,0xf0,0xc9,
2636
0xb0,0x93,0x9c,0x93,0x89,0x27,0x53,0x4f,0x66,0x9c,0x14,0x9c,0x14,0x9f,0x94,0x9d,
2637
0xd4,0x9c,0x34,0x9e,0xac,0x3b,0xd9,0x7c,0xb2,0xfd,0x64,0xf7,0x49,0xd3,0xc9,0xa1,
2638
0x93,0x23,0x27,0xc7,0x4e,0x4e,0x9c,0x9c,0x3a,0x69,0x3e,0x39,0x7f,0x72,0xe9,0xe4,
2639
0xca,0x49,0xbb,0x53,0x8e,0xa7,0x88,0xa7,0x3c,0x4f,0x91,0x4e,0x91,0x4f,0xd1,0x4f,
2640
0x05,0x9f,0x0a,0x3b,0xc5,0x39,0x95,0x78,0x2a,0xf5,0x54,0xc6,0x29,0xfe,0x5f,0x81,
2641
0xe0,0x94,0xe4,0x94,0xe6,0x54,0xcd,0xa9,0xe6,0x53,0x9d,0xa7,0x4c,0xa7,0x86,0x4f,
2642
0x8d,0x9d,0x9a,0x3c,0x65,0x3e,0xb5,0x78,0x6a,0xe5,0x14,0xe1,0x34,0xf1,0xb4,0xf7,
2643
0x69,0xf2,0x69,0xc6,0xe9,0xb0,0xd3,0xb1,0xa7,0x53,0x4f,0xf3,0x4e,0x8b,0x4f,0x2b,
2644
0x4e,0x1b,0x4f,0x37,0x9e,0x6e,0x3f,0xdd,0x73,0x7a,0xe8,0xf4,0xe8,0xe9,0x89,0xd3,
2645
0xd3,0xa7,0xe7,0x4f,0x2f,0x9f,0xb6,0x4b,0x73,0x49,0xf3,0x4c,0xf3,0x4d,0xa3,0xa7,
2646
0x85,0xa4,0x71,0xd2,0x92,0xd3,0x32,0xd2,0x84,0x69,0xb2,0x34,0x5d,0x5a,0x5d,0x5a,
2647
0x6b,0x5a,0x77,0xda,0x40,0xda,0x48,0xda,0x78,0xda,0x54,0x9a,0x25,0x6d,0x29,0xcd,
2648
0xe6,0x3d,0xc7,0xf7,0xdc,0xdf,0x23,0xbd,0x47,0x7d,0x2f,0xf8,0x3d,0xd6,0x7b,0x89,
2649
0xef,0xa5,0xbd,0xc7,0x07,0x04,0xef,0x49,0xde,0xd3,0xbc,0x57,0xf3,0x5e,0xf3,0x7b,
2650
0x9d,0xef,0x99,0xde,0x1b,0x7e,0x6f,0xec,0xbd,0xc9,0xf7,0xcc,0xef,0x2d,0xbe,0xb7,
2651
0xf2,0x1e,0xe1,0x7d,0xe2,0xfb,0xde,0xef,0x93,0xdf,0x67,0xbc,0x1f,0xf6,0x7e,0xec,
2652
0xfb,0xa9,0xef,0xf3,0xde,0x17,0xbf,0xaf,0x78,0xdf,0xf8,0x7e,0xe3,0xfb,0xed,0xef,
2653
0xf7,0xbc,0x3f,0xf4,0xfe,0xe8,0xfb,0x13,0xef,0x4f,0xbf,0x3f,0xff,0xfe,0xf2,0xfb,
2654
0x76,0xe9,0x2e,0xe9,0x9e,0xe9,0xbe,0xe9,0xf4,0xf4,0x90,0x74,0x4e,0x7a,0x72,0x7a,
2655
0x46,0xba,0x30,0x5d,0x96,0xae,0x4b,0xaf,0x4b,0x6f,0x4d,0xef,0x4e,0x1f,0x48,0x1f,
2656
0x49,0x1f,0x4f,0x9f,0x4a,0xb7,0xa4,0xbf,0xf8,0x99,0x59,0x4a,0xb7,0xc9,0x70,0xcc,
2657
0xf0,0xcc,0x20,0x67,0x04,0x67,0x70,0x32,0x52,0x33,0x04,0x19,0xb2,0x0c,0x5d,0xc6,
2658
0x78,0xc6,0x62,0x06,0xca,0xfc,0xeb,0xb0,0xc9,0xb4,0xcb,0x24,0x64,0x3a,0x66,0xba,
2659
0x64,0x12,0x33,0xdd,0x33,0x3d,0x33,0xbd,0x33,0x49,0x99,0x94,0xbf,0x01,0x6a,0x26,
2660
0x23,0x33,0x38,0x33,0x24,0x33,0x2c,0x93,0x95,0xc9,0xc9,0x8c,0xcd,0x4c,0xcc,0x4c,
2661
0xce,0x4c,0xcd,0x4c,0xcb,0xcc,0xc8,0xe4,0x65,0x0a,0x32,0x85,0x99,0xe2,0x4c,0x49,
2662
0xa6,0x2c,0x53,0x91,0xa9,0xc9,0xd4,0x02,0xba,0x4c,0x63,0x66,0x4d,0x66,0x63,0x66,
2663
0x6b,0x66,0x67,0x66,0x4f,0xa6,0x29,0x73,0x20,0x73,0x28,0x73,0x38,0x73,0x24,0xf3,
2664
0x7e,0xe6,0x68,0xe6,0x58,0xe6,0x78,0xe6,0x44,0xe6,0x64,0xe6,0x54,0xe6,0x74,0xa6,
2665
0x39,0xd3,0x92,0x39,0x9f,0xb9,0x98,0xb9,0x94,0xb9,0x9c,0xb9,0x92,0x69,0x73,0xc6,
2666
0xee,0x0c,0xe1,0x8c,0xe3,0x19,0x97,0x33,0xae,0x67,0x88,0x67,0xdc,0xcf,0x78,0x9e,
2667
0xf1,0x3e,0xe3,0xf3,0x3d,0xa4,0x33,0xe4,0x33,0xf4,0x33,0xcc,0x33,0xc1,0x67,0x42,
2668
0xcf,0x84,0x9d,0xe1,0x9c,0x49,0x3c,0x93,0x7a,0x26,0xe3,0x8c,0xe0,0x8c,0xf8,0x8c,
2669
0xec,0x8c,0xe6,0x8c,0xf1,0x4c,0xdd,0x99,0xc6,0x33,0xad,0x67,0x3a,0xcf,0xf4,0x9c,
2670
0x19,0x38,0x33,0x7c,0x66,0xf4,0xcc,0xf8,0x99,0xc9,0x33,0xd3,0x67,0x2c,0x67,0x16,
2671
0xcf,0x2c,0x9f,0x59,0x39,0x63,0xc3,0xb5,0xe3,0x12,0xb8,0x8e,0x5c,0x17,0x2e,0x91,
2672
0xeb,0xce,0xf5,0xe4,0x7a,0x73,0x49,0x5c,0x5f,0x2e,0x99,0x4b,0xe5,0xd2,0xb9,0x0c,
2673
0x6e,0x30,0x37,0x84,0x1b,0xc6,0x65,0x71,0x39,0xdc,0x58,0x6e,0x22,0x37,0x99,0x9b,
2674
0xca,0x4d,0xe3,0x66,0x70,0x79,0x5c,0x01,0x57,0xc8,0x15,0x73,0x25,0x5c,0x19,0x57,
2675
0xc1,0xd5,0x70,0x75,0x5c,0x23,0xb7,0x86,0x5b,0xc7,0x6d,0xe4,0x36,0x73,0x5b,0xb9,
2676
0xed,0xdc,0x4e,0x6e,0x37,0xb7,0x87,0x6b,0xe2,0x0e,0x70,0x87,0xb8,0xc3,0xdc,0x11,
2677
0xee,0x28,0x77,0x8c,0x3b,0xce,0x9d,0xe0,0x4e,0x72,0xa7,0xb8,0xd3,0x5c,0x33,0xd7,
2678
0xc2,0x9d,0xe7,0x2e,0x72,0x97,0xb8,0xcb,0xdc,0x15,0xae,0x0d,0xcf,0x8e,0x47,0xe0,
2679
0x39,0xf2,0x5c,0x78,0x44,0x9e,0x3b,0xcf,0x93,0xe7,0xcd,0x23,0xf1,0x7c,0x79,0x64,
2680
0x1e,0x95,0x47,0xe7,0x31,0x78,0xc1,0xbc,0x10,0x5e,0x18,0x8f,0xc5,0xe3,0xf0,0x62,
2681
0x79,0x89,0xbc,0x64,0x5e,0x2a,0x2f,0x8d,0x97,0xc1,0xe3,0xf1,0x04,0x3c,0x21,0x4f,
2682
0xcc,0x93,0xf0,0x64,0x3c,0x05,0x4f,0xc3,0xd3,0xf1,0x8c,0xbc,0x1a,0x5e,0x1d,0xaf,
2683
0x91,0xd7,0xce,0xeb,0xe1,0x0d,0xf1,0x46,0x79,0x13,0xbc,0x69,0x9e,0x85,0xb7,0xf0,
2684
0x23,0x8b,0xbc,0x25,0xde,0x32,0x6f,0x85,0x67,0x93,0x65,0x97,0x45,0xc8,0x72,0xcc,
2685
0x72,0xc9,0x22,0x66,0xb9,0x67,0x79,0x66,0x79,0x67,0x91,0xb2,0x7c,0xb3,0xc8,0x59,
2686
0xd4,0x2c,0x7a,0x16,0x23,0x2b,0x38,0x2b,0x24,0x2b,0x2c,0x8b,0x95,0xc5,0xc9,0x8a,
2687
0xcd,0x4a,0xcc,0x4a,0xce,0x4a,0xcd,0x4a,0xcb,0xca,0xc8,0xe2,0x65,0x09,0xb2,0x84,
2688
0x59,0xe2,0x2c,0x49,0x96,0x2c,0x4b,0x91,0xa5,0xc9,0xd2,0x65,0x19,0xb3,0x6a,0xb2,
2689
0xea,0xb2,0x1a,0xb3,0x9a,0xb3,0x5a,0xb3,0xda,0xb3,0x3a,0xb3,0xba,0xb3,0x7a,0xb2,
2690
0x4c,0x59,0x03,0x59,0x43,0x59,0xc3,0x59,0x23,0x59,0xa3,0x59,0x63,0x59,0xe3,0x59,
2691
0x13,0x59,0x93,0x59,0x53,0x59,0xd3,0x59,0xe6,0x2c,0x4b,0xd6,0x7c,0xd6,0x62,0xd6,
2692
0x52,0xd6,0x72,0xd6,0x4a,0x96,0x4d,0xb6,0x5d,0x36,0x21,0xdb,0x31,0xdb,0x25,0x9b,
2693
0x98,0xed,0x9e,0xed,0x99,0xed,0x9d,0x4d,0xca,0xf6,0xcd,0x26,0x67,0x53,0xb3,0xe9,
2694
0xd9,0x8c,0xec,0xe0,0xec,0x90,0xec,0xb0,0x6c,0x56,0x36,0x27,0x3b,0x36,0x3b,0x31,
2695
0x3b,0x39,0x3b,0x35,0x3b,0x2d,0x3b,0x23,0x9b,0x97,0x2d,0xc8,0x16,0x66,0x8b,0xb3,
2696
0x25,0xd9,0xb2,0x6c,0x45,0xb6,0x26,0x5b,0x97,0x6d,0xcc,0xae,0xc9,0xae,0xcb,0x6e,
2697
0xcc,0x6e,0xce,0x6e,0xcd,0x6e,0xcf,0xee,0xcc,0xee,0xce,0xee,0xc9,0x36,0x65,0x0f,
2698
0x64,0x0f,0x65,0x0f,0x67,0x8f,0x64,0x8f,0x66,0x8f,0x65,0x8f,0x67,0x4f,0x64,0x4f,
2699
0x66,0x4f,0x65,0x4f,0x67,0x9b,0xb3,0x2d,0xd9,0xf3,0xd9,0x8b,0xd9,0x4b,0xd9,0xcb,
2700
0xd9,0x2b,0xd9,0x36,0x7c,0x3b,0x3e,0x81,0xef,0xc8,0x77,0xe1,0x13,0xf9,0xee,0x7c,
2701
0x4f,0xbe,0x37,0x9f,0xc4,0xf7,0xe5,0x93,0xf9,0x54,0x3e,0x9d,0xcf,0xe0,0x07,0xf3,
2702
0x43,0xf8,0x61,0x7c,0x16,0x9f,0xc3,0x8f,0xe5,0x27,0xf2,0x93,0xf9,0xa9,0xfc,0x34,
2703
0x7e,0x06,0x9f,0xc7,0x17,0xf0,0x85,0x7c,0x31,0x5f,0xc2,0x97,0xf1,0x15,0x7c,0x0d,
2704
0x5f,0xc7,0x37,0xf2,0x6b,0xf8,0x75,0xfc,0x46,0x7e,0x33,0xbf,0x95,0xdf,0xce,0xef,
2705
0xe4,0x77,0xf3,0x7b,0xf8,0x26,0xfe,0x00,0x7f,0x88,0x3f,0xcc,0x1f,0xe1,0x8f,0xf2,
2706
0xc7,0xf8,0xe3,0xfc,0x09,0xfe,0x24,0x7f,0x8a,0x3f,0xcd,0x37,0xf3,0xe7,0xac,0x58,
2707
0xf8,0xf3,0xfc,0x45,0xfe,0x12,0x7f,0x99,0xbf,0xc2,0x47,0x02,0x24,0xb0,0x11,0xd8,
2708
0x09,0x08,0x02,0x47,0x81,0x8b,0x80,0x28,0x70,0x03,0xdc,0x05,0x9e,0x02,0x6f,0x01,
2709
0x49,0xe0,0x2b,0x20,0x0b,0x28,0x00,0x55,0x40,0x17,0x30,0x04,0x4c,0x2b,0xc1,0x82,
2710
0x10,0x41,0x98,0x80,0x25,0x88,0x15,0x24,0x0a,0x92,0x05,0x29,0x82,0x54,0x41,0x9a,
2711
0x20,0x43,0xc0,0x13,0x08,0x04,0x42,0x81,0x58,0x50,0xb8,0xc6,0xaf,0x12,0xf9,0xdf,
2712
0x85,0x76,0x8d,0xbf,0x13,0x9d,0xc0,0x28,0xa8,0x11,0xd4,0x09,0x1a,0x05,0x4d,0x82,
2713
0x66,0x41,0xab,0xa0,0x5d,0xd0,0x29,0xe8,0x16,0xf4,0x08,0x4c,0x82,0x01,0xc1,0x90,
2714
0x60,0x58,0x30,0x22,0x18,0x15,0x8c,0x09,0xc6,0x05,0x13,0x82,0x49,0xc1,0x94,0x60,
2715
0x5a,0x60,0x16,0x58,0x04,0xf3,0x82,0x45,0xc1,0x92,0x60,0x59,0xb0,0x22,0xb0,0x39,
2716
0x6b,0x77,0x96,0x70,0xd6,0xf1,0xac,0xcb,0x59,0xe2,0x59,0xf7,0xb3,0x9e,0x67,0xbd,
2717
0xcf,0x92,0xce,0xfa,0x9e,0x25,0x9f,0xa5,0x9e,0xa5,0x9f,0x65,0x9c,0x0d,0x3e,0x1b,
2718
0x72,0x36,0xf4,0x6c,0xd8,0x59,0xd6,0x59,0xce,0xd9,0xd8,0xb3,0x89,0x67,0x93,0xcf,
2719
0xa6,0x9e,0x4d,0x3b,0x9b,0x71,0x96,0x77,0x56,0x70,0x56,0x78,0x56,0x7c,0x56,0x72,
2720
0x56,0xba,0xc6,0xaf,0x12,0x35,0x60,0xf8,0x6f,0xa9,0x5d,0xc3,0x4a,0xd3,0xd9,0xb6,
2721
0x35,0xd6,0xf8,0xbb,0xe8,0x3a,0xdb,0xf7,0x8b,0x32,0x08,0xdc,0xfb,0x2f,0x3c,0xb0,
2722
0xf2,0xe8,0x17,0xe2,0x09,0x30,0x73,0xf6,0xf9,0x1a,0xbf,0x09,0x5e,0x9c,0x7d,0x09,
2723
0xd8,0x9e,0x5b,0xe3,0xb7,0x89,0xc3,0x39,0xd7,0xdf,0x30,0x1e,0x6b,0xfc,0xcb,0xe1,
2724
0x73,0xce,0xef,0x1c,0xed,0x1c,0xf3,0x5c,0xe8,0xb9,0x98,0x73,0x29,0xe7,0xb8,0x6b,
2725
0xac,0xf1,0x3f,0x4a,0xce,0xb9,0xc2,0x73,0xea,0x35,0x7e,0x61,0x34,0xe7,0x8c,0xe7,
2726
0xea,0xce,0x35,0x9f,0x6b,0x5b,0x63,0x8d,0x35,0xfe,0x69,0xb4,0x9f,0xeb,0x3c,0xd7,
2727
0x7d,0xae,0xe7,0x9c,0xe9,0xdc,0xc0,0xb9,0xa1,0x73,0xc3,0xe7,0x46,0xce,0x8d,0x9e,
2728
0x1b,0x3b,0x37,0x7e,0x6e,0xe2,0xdc,0xe4,0xb9,0xa9,0x73,0xd3,0xe7,0xcc,0xe7,0x2c,
2729
0xe7,0xe6,0xcf,0x2d,0x9e,0x5b,0x3a,0xb7,0x7c,0x6e,0xe5,0x9c,0x4d,0x8e,0x5d,0x0e,
2730
0x21,0xc7,0x31,0xc7,0x25,0x87,0x98,0xe3,0x9e,0xe3,0x99,0xe3,0x9d,0x43,0xca,0xf1,
2731
0xcd,0x21,0xe7,0x50,0x73,0x68,0xff,0x42,0x30,0x73,0x42,0x73,0x62,0x72,0x52,0x72,
2732
0xb8,0x39,0xa2,0x1c,0xf9,0xaf,0x0a,0x6d,0x4e,0x75,0x4e,0x53,0x4e,0x47,0x4e,0x5f,
2733
0xce,0xdd,0xff,0x61,0x86,0x73,0x46,0x72,0x46,0x73,0xc6,0x72,0xc6,0x73,0x26,0x72,
2734
0x26,0x73,0xa6,0x72,0xa6,0x73,0xcc,0x39,0x96,0x9c,0xf9,0x9c,0xc5,0x9c,0xa5,0x9c,
2735
0xe5,0x9c,0x95,0x1c,0x1b,0xa1,0x9d,0x90,0x20,0x74,0x14,0xba,0x08,0x89,0x42,0x77,
2736
0xa1,0xa7,0xd0,0x5b,0x48,0x12,0xfa,0x0a,0xc9,0x42,0xaa,0x90,0x2e,0x64,0x08,0x83,
2737
0x85,0x21,0xc2,0x30,0x21,0x4b,0xc8,0x11,0xc6,0x0a,0x13,0x85,0xc9,0xc2,0x54,0x61,
2738
0x9a,0x30,0x43,0xc8,0x13,0x0a,0x84,0x42,0xa1,0x58,0x28,0x11,0xca,0x84,0x0a,0xa1,
2739
0x46,0xa8,0x13,0x1a,0x85,0x35,0xc2,0x3a,0x61,0xa3,0xb0,0x59,0xd8,0x2a,0x6c,0x17,
2740
0x76,0x0a,0xbb,0x85,0x3d,0x42,0x93,0x70,0x40,0x38,0x24,0x1c,0x16,0x8e,0x08,0x47,
2741
0x85,0x63,0xc2,0x71,0xe1,0x84,0x70,0x52,0x38,0x25,0x9c,0x16,0x9a,0x85,0x16,0xe1,
2742
0xbc,0x70,0x51,0xb8,0x24,0x5c,0x16,0xae,0x08,0x6d,0x72,0xed,0x72,0x09,0xb9,0x8e,
2743
0xb9,0x2e,0xb9,0xae,0xb9,0xc4,0x5c,0xf7,0x5c,0xcf,0x5c,0xef,0x5c,0x52,0xae,0x6f,
2744
0x2e,0x39,0x97,0x9a,0x4b,0xcf,0x65,0xe4,0x06,0xe7,0x86,0xe4,0x86,0xe5,0xb2,0x72,
2745
0x39,0xb9,0xb1,0xb9,0x89,0xb9,0xc9,0xb9,0xa9,0xb9,0x69,0xb9,0x19,0xb9,0xbc,0x5c,
2746
0x41,0xae,0x30,0x57,0x9c,0x2b,0xc9,0x95,0xe5,0x2a,0x72,0x35,0xb9,0xba,0x5c,0x63,
2747
0x6e,0x4d,0x6e,0x5d,0x6e,0x63,0x6e,0x73,0x6e,0x6b,0x6e,0x7b,0x6e,0x67,0x6e,0x77,
2748
0x6e,0x4f,0xae,0x29,0x77,0x20,0x77,0x28,0x77,0x38,0x77,0x24,0x77,0x34,0x77,0x2c,
2749
0x77,0x3c,0x77,0x22,0x77,0x32,0x77,0x2a,0x77,0x3a,0xd7,0x9c,0x6b,0xc9,0x9d,0xcf,
2750
0x5d,0xcc,0x5d,0xca,0x5d,0xce,0x5d,0xc9,0xb5,0xc9,0xb3,0xcb,0x23,0xe4,0x39,0xe6,
2751
0xb9,0xe4,0x11,0xf3,0xdc,0xf3,0x3c,0xf3,0xbc,0xf3,0x48,0x79,0xbe,0x79,0xe4,0x3c,
2752
0x4a,0x1e,0x35,0x8f,0x9e,0x17,0x08,0x30,0xf2,0x98,0x40,0x70,0x5e,0x48,0x5e,0x28,
2753
0x10,0x96,0xc7,0xca,0xe3,0xe4,0xc5,0xe6,0x25,0xe4,0x25,0xe6,0x25,0xe7,0xa5,0xe6,
2754
0xa5,0xe5,0x65,0xe4,0xf1,0xf2,0x04,0x79,0xc2,0x3c,0x71,0x9e,0x24,0x4f,0x96,0xa7,
2755
0xc8,0x53,0xe7,0x69,0xf2,0xb4,0x79,0xba,0x3c,0x63,0x5e,0x4d,0x5e,0x5d,0x5e,0x63,
2756
0x5e,0x73,0x5e,0x6b,0x5e,0x5b,0x5e,0x7b,0x5e,0x67,0x5e,0x77,0x5e,0x4f,0x9e,0x29,
2757
0x6f,0x20,0x6f,0x28,0x6f,0x38,0x6f,0x24,0x6f,0x34,0x6f,0x2c,0x6f,0x3c,0x6f,0x22,
2758
0x6f,0x32,0x6f,0x2a,0x6f,0x3a,0xcf,0x9c,0x67,0xc9,0x9b,0xcf,0x5b,0xcc,0x5b,0xca,
2759
0x5b,0xce,0x5b,0xc9,0xb3,0x11,0xd9,0x89,0x08,0x22,0x47,0x91,0x8b,0x88,0x28,0x72,
2760
0x17,0x79,0x8a,0xbc,0x45,0x24,0x91,0xaf,0x88,0x2c,0xa2,0x8a,0xe8,0x22,0x86,0x28,
2761
0x58,0x14,0x22,0x0a,0x13,0xb1,0x44,0x1c,0x51,0xac,0x28,0x51,0x94,0x2c,0x4a,0x15,
2762
0xa5,0x89,0x32,0x44,0x3c,0x91,0x40,0x24,0x14,0x89,0x45,0x12,0x91,0x4c,0xa4,0x10,
2763
0x69,0x44,0x3a,0x91,0x51,0x54,0x03,0xd4,0x89,0x1a,0x45,0xcd,0xa2,0x56,0x51,0xbb,
2764
0xa8,0x43,0xd4,0x29,0xea,0x16,0xf5,0x88,0x4c,0xa2,0x7e,0x60,0x40,0x34,0x24,0x1a,
2765
0x16,0x8d,0x88,0x46,0x45,0x63,0xa2,0x71,0xd1,0x84,0xe8,0xb1,0x68,0x52,0x34,0x25,
2766
0x9a,0x16,0x99,0x45,0x16,0xd1,0xbc,0x68,0x51,0xf4,0x42,0xb4,0x24,0x5a,0x16,0xad,
2767
0x88,0x6c,0xc4,0x76,0x62,0x82,0xd8,0x51,0xec,0x22,0x26,0x8a,0xdd,0xc5,0x9e,0x62,
2768
0x6f,0x31,0x49,0xec,0x2b,0x26,0x8b,0xa9,0x62,0xba,0x98,0x21,0x0e,0x16,0x87,0x88,
2769
0xc3,0xc4,0x2c,0x31,0x47,0x1c,0x2b,0x4e,0x14,0x27,0x8b,0x53,0xc5,0x69,0xe2,0x74,
2770
0x71,0x86,0x98,0x27,0x16,0x88,0x85,0x62,0x91,0x58,0x2c,0x96,0x88,0x65,0x62,0x85,
2771
0x58,0x23,0xd6,0x8a,0x75,0x62,0x83,0x15,0xa3,0xb8,0x46,0x5c,0x27,0x6e,0x14,0x37,
2772
0x8b,0x5b,0xc5,0xed,0xe2,0x0e,0x71,0xa7,0xb8,0x5b,0xdc,0x23,0x36,0x89,0x07,0xc4,
2773
0x43,0xe2,0x61,0xf1,0x88,0x78,0x54,0x3c,0x26,0x1e,0x17,0x4f,0x88,0x27,0xc5,0x53,
2774
0xe2,0x69,0xb1,0x59,0x6c,0x11,0xcf,0x8b,0x17,0xc5,0x4b,0xe2,0x65,0xf1,0x8a,0xd8,
2775
0x26,0xdf,0x2e,0x9f,0x90,0xef,0x98,0xef,0x92,0x4f,0xcc,0x77,0xcf,0xf7,0xcc,0xf7,
2776
0xce,0x27,0xe5,0xfb,0xe6,0x93,0xf3,0xa9,0xf9,0xf4,0x7c,0x46,0x7e,0x70,0x7e,0x48,
2777
0x7e,0x58,0x3e,0x2b,0x9f,0x93,0x1f,0x9b,0x9f,0x98,0x9f,0x9c,0x9f,0x9a,0x9f,0x96,
2778
0x9f,0x91,0xcf,0xcb,0x17,0xe4,0x0b,0xf3,0xc5,0xf9,0x92,0x7c,0x59,0xbe,0x22,0x5f,
2779
0x93,0xaf,0xcb,0x37,0xe6,0xd7,0xe4,0xd7,0xe5,0x37,0xe6,0x37,0xe7,0xb7,0xe6,0xb7,
2780
0xe7,0x77,0xe6,0x77,0xe7,0xf7,0xe4,0x9b,0xf2,0x07,0xf2,0x87,0xf2,0x87,0xf3,0x47,
2781
0xf2,0x47,0xf3,0xc7,0xf2,0xc7,0xf3,0x27,0xf2,0x27,0xf3,0xa7,0xf2,0xa7,0xf3,0xcd,
2782
0xf9,0x96,0xfc,0xf9,0xfc,0xc5,0xfc,0xa5,0xfc,0xe5,0xfc,0x95,0x7c,0x9b,0x02,0xbb,
2783
0x02,0x42,0x81,0x63,0x81,0x4b,0x01,0xb1,0xc0,0xbd,0xc0,0xb3,0xc0,0xbb,0x80,0x54,
2784
0xe0,0x5b,0x40,0x2e,0xa0,0x16,0xd0,0x0b,0x18,0x05,0xc1,0x05,0x21,0x05,0x61,0x05,
2785
0xac,0x02,0x4e,0x41,0x6c,0x41,0x62,0x41,0x72,0x41,0x6a,0x41,0x5a,0x41,0x46,0x01,
2786
0xaf,0x40,0x50,0x20,0x2c,0x10,0x17,0x48,0x0a,0x64,0x05,0x8a,0x02,0x4d,0x81,0xae,
2787
0xc0,0x58,0x50,0x53,0x50,0x57,0xd0,0x58,0xd0,0x5c,0xd0,0x5a,0xd0,0x5e,0xd0,0x59,
2788
0xd0,0x5d,0xd0,0x53,0x60,0x2a,0x18,0x28,0x18,0x2a,0x18,0x2e,0x18,0x29,0x18,0x2d,
2789
0x18,0x2b,0x18,0x2f,0x98,0x28,0x98,0x2c,0x98,0x2a,0x98,0x2e,0x30,0x17,0x58,0x0a,
2790
0xe6,0x0b,0x16,0x0b,0x96,0x0a,0x96,0x0b,0x56,0x0a,0x6c,0x0a,0xed,0x0a,0x09,0x85,
2791
0x8e,0x85,0x2e,0x85,0xc4,0x42,0xf7,0x42,0xcf,0x42,0xef,0x42,0x52,0xa1,0x6f,0x21,
2792
0xb9,0x90,0x5a,0x48,0x2f,0x64,0x14,0x06,0x17,0x86,0x14,0x86,0x15,0xb2,0x0a,0x39,
2793
0x85,0xb1,0x85,0x89,0x85,0xc9,0x85,0xa9,0x85,0x69,0x40,0x46,0x21,0xaf,0x50,0x50,
2794
0x28,0x2c,0x14,0x17,0x4a,0x0a,0x65,0x85,0x8a,0x42,0x4d,0xa1,0xae,0xd0,0x58,0x58,
2795
0x53,0x58,0x57,0xd8,0x58,0xd8,0x5c,0xd8,0x5a,0xd8,0x5e,0xd8,0x59,0xd8,0x5d,0xd8,
2796
0x53,0x68,0x2a,0x1c,0x28,0x1c,0x2a,0x1c,0x2e,0x1c,0x29,0x1c,0x2d,0x1c,0x2b,0x1c,
2797
0x2f,0x9c,0x28,0x9c,0x2c,0x9c,0x2a,0x9c,0x2e,0x34,0x17,0x5a,0x0a,0xe7,0x0b,0x17,
2798
0x0b,0x97,0x0a,0x97,0x0b,0x57,0x0a,0x6d,0x24,0x76,0x12,0x82,0xc4,0x51,0xe2,0x22,
2799
0x21,0x4a,0xdc,0x25,0x9e,0x12,0x6f,0x09,0x49,0xe2,0x2b,0x21,0x4b,0xa8,0x12,0xba,
2800
0x84,0x21,0x09,0x96,0x84,0x48,0xc2,0x24,0x2c,0x09,0x47,0x12,0x2b,0x49,0x94,0x24,
2801
0x4b,0x52,0x25,0x69,0x92,0x0c,0x09,0x4f,0x22,0x90,0x08,0x25,0x62,0x89,0x44,0x22,
2802
0x93,0x28,0x24,0x1a,0x89,0x4e,0x62,0x94,0xd4,0x48,0xea,0x24,0x8d,0x92,0x66,0x49,
2803
0xab,0xa4,0x5d,0xd2,0x29,0xe9,0x96,0xf4,0x48,0x4c,0x92,0x01,0xc9,0x90,0x64,0x58,
2804
0x32,0x22,0x19,0x95,0x8c,0x49,0xc6,0x25,0x13,0x92,0x49,0xc9,0x94,0x64,0x5a,0x62,
2805
0x96,0x58,0x24,0xf3,0x92,0x45,0xc9,0x92,0x64,0x59,0xb2,0x22,0xb1,0x29,0xb2,0x2b,
2806
0x22,0x14,0x39,0x16,0xb9,0x14,0x11,0x8b,0xdc,0x8b,0x3c,0x8b,0xbc,0x8b,0x48,0x45,
2807
0xbe,0x45,0xe4,0x22,0x6a,0x11,0xbd,0x88,0x51,0x14,0x5c,0x14,0x52,0x14,0x56,0xc4,
2808
0x2a,0xe2,0x14,0xc5,0x16,0x25,0x16,0x25,0x17,0xa5,0x16,0xa5,0x15,0x65,0x14,0xf1,
2809
0x8a,0x04,0x45,0xc2,0x22,0x71,0x91,0xa4,0x48,0x56,0xa4,0x28,0xd2,0x14,0xe9,0x8a,
2810
0x8c,0x45,0x35,0x45,0x75,0x45,0x8d,0x45,0xcd,0x45,0xad,0x45,0xed,0x45,0x9d,0x45,
2811
0xdd,0x45,0x3d,0x45,0xa6,0xa2,0x81,0xa2,0xa1,0xa2,0xe1,0xa2,0x91,0xa2,0xd1,0xa2,
2812
0xb1,0xa2,0xf1,0xa2,0x89,0xa2,0xc9,0xa2,0xa9,0xa2,0xe9,0x22,0x73,0x91,0xa5,0x68,
2813
0xbe,0x68,0xb1,0x68,0xa9,0x68,0xb9,0xe8,0x65,0xd1,0x4a,0x91,0x4d,0xb1,0x5d,0x31,
2814
0xa1,0xd8,0xb1,0xd8,0xa5,0x98,0x58,0xec,0x5e,0xec,0x59,0xec,0x5d,0x4c,0x2a,0xf6,
2815
0x2d,0x26,0x17,0x53,0x8b,0xe9,0xc5,0x8c,0xe2,0xe0,0xe2,0x90,0xe2,0xb0,0x62,0x56,
2816
0x31,0xa7,0x38,0xb6,0x38,0xb1,0x38,0xb9,0x38,0xb5,0x38,0xad,0x38,0xa3,0x98,0x57,
2817
0x2c,0x28,0x16,0x16,0x8b,0x8b,0x25,0xc5,0xb2,0x62,0x45,0xb1,0xa6,0x58,0x57,0x6c,
2818
0x2c,0xae,0x29,0xae,0x2b,0x6e,0x2c,0x6e,0x2e,0x6e,0x2d,0x6e,0x2f,0xee,0x2c,0xee,
2819
0x2e,0xee,0x29,0x36,0x15,0x0f,0x14,0x0f,0x15,0x0f,0x17,0x8f,0x14,0x8f,0x16,0x8f,
2820
0x15,0x8f,0x17,0x4f,0x14,0x4f,0x16,0x4f,0x15,0x4f,0x17,0x9b,0x8b,0x2d,0xc5,0xf3,
2821
0xc5,0x8b,0xc5,0x4b,0xc5,0xcb,0xc5,0x2b,0xc5,0x36,0x52,0x3b,0x29,0x41,0xea,0x28,
2822
0x75,0x91,0x12,0xa5,0xee,0x52,0x4f,0xa9,0xb7,0x94,0x24,0xf5,0x95,0x92,0xa5,0x54,
2823
0x29,0x5d,0xca,0x90,0x06,0x4b,0x43,0xa4,0x61,0x52,0x96,0x94,0x23,0x8d,0x95,0x26,
2824
0x4a,0x93,0xa5,0xa9,0x40,0x9a,0x34,0x43,0xca,0x93,0x0a,0xa4,0x42,0xa9,0x58,0x2a,
2825
0x91,0xca,0xa4,0x0a,0xa9,0x46,0xaa,0x93,0x1a,0xa5,0x35,0xd2,0x3a,0x69,0xa3,0xb4,
2826
0x59,0xda,0x2a,0x6d,0x97,0x76,0x4a,0xbb,0xa5,0x3d,0x52,0x93,0x74,0x40,0x3a,0x24,
2827
0x1d,0x96,0x8e,0x48,0x47,0xa5,0x63,0xd2,0x71,0xe9,0x84,0x74,0x52,0x3a,0x25,0x9d,
2828
0x96,0x9a,0xa5,0x16,0xe9,0xbc,0x74,0x51,0xba,0x24,0x5d,0x96,0xae,0x48,0x6d,0x64,
2829
0x76,0x32,0x82,0xcc,0x51,0xe6,0x22,0x23,0xca,0xdc,0x65,0x9e,0x32,0x6f,0x19,0x49,
2830
0xe6,0x2b,0x23,0xcb,0xa8,0x32,0xba,0x8c,0x21,0x0b,0x96,0x85,0xc8,0xc2,0x64,0x2c,
2831
0x19,0x47,0x16,0x2b,0x4b,0x94,0x25,0xcb,0x52,0x65,0x69,0xb2,0x0c,0x19,0x4f,0x26,
2832
0x90,0x09,0x65,0x62,0x99,0x44,0x26,0x93,0x29,0x64,0x1a,0x99,0x4e,0x66,0x94,0xd5,
2833
0xc8,0xea,0x64,0x8d,0xb2,0x66,0x59,0xab,0xac,0x5d,0xd6,0x29,0xeb,0x96,0xf5,0xc8,
2834
0x4c,0xb2,0x01,0xd9,0x90,0x6c,0x58,0x36,0x22,0x1b,0x95,0x8d,0xc9,0xc6,0x65,0x13,
2835
0xb2,0x49,0xd9,0x94,0x6c,0x5a,0x66,0x96,0x59,0x64,0xf3,0xb2,0x45,0xd9,0x92,0x6c,
2836
0x59,0xb6,0x22,0xb3,0x29,0xb1,0x2b,0x21,0x94,0x38,0x96,0xb8,0x94,0x10,0x4b,0xdc,
2837
0x4b,0x3c,0x4b,0xbc,0x4b,0x48,0x25,0xbe,0x25,0xe4,0x12,0x6a,0x09,0xbd,0x84,0x51,
2838
0x12,0x5c,0x12,0x52,0x12,0x56,0xc2,0x2a,0xe1,0x94,0xc4,0x96,0x24,0x96,0x24,0x97,
2839
0xa4,0x96,0xa4,0x95,0x64,0x94,0xf0,0x4a,0x04,0x25,0xc2,0x12,0x71,0x89,0xa4,0x44,
2840
0x56,0xa2,0x28,0xd1,0x94,0xe8,0x4a,0x8c,0x25,0x35,0x25,0x75,0x25,0x8d,0x25,0xcd,
2841
0x25,0xad,0x25,0xed,0x25,0x9d,0x25,0xdd,0x25,0x3d,0x25,0xa6,0x92,0x81,0x92,0xa1,
2842
0x92,0xe1,0x92,0x91,0x92,0xd1,0x92,0xb1,0x92,0xf1,0x92,0x89,0x92,0xc9,0x92,0xa9,
2843
0x92,0xe9,0x12,0x73,0x89,0xa5,0x64,0xbe,0x64,0xb1,0x64,0xa9,0x64,0xb9,0x64,0xa5,
2844
0xc4,0xa6,0xd4,0xae,0x94,0x50,0xea,0x58,0xea,0x52,0x4a,0x2c,0x75,0x2f,0xf5,0x2c,
2845
0xf5,0x2e,0x25,0x95,0xfa,0x96,0x92,0x4b,0xa9,0xa5,0xf4,0x52,0x46,0x69,0x70,0x69,
2846
0x48,0x69,0x58,0x29,0xab,0x94,0x53,0x1a,0x5b,0x9a,0x58,0x9a,0x5c,0x9a,0x5a,0x9a,
2847
0x56,0x9a,0x51,0xca,0x2b,0x15,0x94,0x0a,0x4b,0xc5,0xa5,0x92,0x52,0x59,0xa9,0xa2,
2848
0x54,0x53,0xaa,0x2b,0x35,0x00,0xc6,0xd2,0x9a,0xd2,0xba,0xd2,0xc6,0xd2,0xe6,0xd2,
2849
0xd6,0xd2,0xf6,0xd2,0xce,0xd2,0xee,0xd2,0x9e,0x52,0x53,0xe9,0x40,0xe9,0x50,0xe9,
2850
0x70,0xe9,0x48,0xe9,0x68,0xe9,0x58,0xe9,0x78,0xe9,0x44,0xe9,0x64,0xe9,0x54,0xe9,
2851
0x74,0xa9,0xb9,0xd4,0x52,0x3a,0x5f,0xba,0x58,0xba,0x54,0xba,0x5c,0xba,0x52,0x6a,
2852
0x23,0xb7,0x93,0x13,0xe4,0x8e,0x72,0x17,0x39,0x51,0xee,0x2e,0xf7,0x94,0x7b,0xcb,
2853
0x49,0x72,0x5f,0x39,0x59,0x4e,0x95,0xd3,0xe5,0x0c,0x79,0xb0,0x3c,0x44,0x1e,0x26,
2854
0x67,0xc9,0x39,0xf2,0x58,0x79,0xc2,0x1a,0x7f,0x35,0x89,0xf2,0xa4,0x5f,0x94,0x64,
2855
0x79,0xaa,0x3c,0x4d,0x9e,0x21,0xe7,0xc9,0x05,0x72,0xa1,0x5c,0x2c,0x97,0xc8,0x65,
2856
0x72,0x85,0x5c,0x23,0xd7,0xc9,0x8d,0xf2,0x1a,0x79,0x9d,0xbc,0x51,0xde,0x2c,0x6f,
2857
0x95,0xb7,0xcb,0x3b,0xe5,0xdd,0xf2,0x1e,0xb9,0x49,0x3e,0x20,0x1f,0x92,0x0f,0xcb,
2858
0x47,0xe4,0xa3,0xf2,0x31,0xf9,0xb8,0x7c,0x42,0x3e,0x29,0x9f,0x92,0x4f,0xcb,0xcd,
2859
0x72,0x8b,0x7c,0x5e,0xbe,0x28,0x5f,0x92,0x2f,0xcb,0x57,0xe4,0x36,0x0a,0x3b,0x05,
2860
0x41,0xe1,0xa8,0x70,0x51,0x10,0x15,0xee,0x0a,0x4f,0x85,0xb7,0xc2,0xe7,0x9f,0x0e,
2861
0x49,0xe1,0xab,0x20,0x2b,0xa8,0x0a,0xba,0x82,0xa1,0x08,0x56,0x84,0x28,0xc2,0x14,
2862
0x2c,0x05,0x47,0x11,0xab,0x48,0x54,0x24,0x2b,0x52,0x15,0x69,0x8a,0x0c,0x05,0x4f,
2863
0x21,0x50,0x08,0x15,0x62,0x85,0x44,0x21,0x53,0x28,0x14,0x1a,0x85,0x4e,0x61,0x54,
2864
0xd4,0x28,0xea,0x14,0x8d,0x8a,0x66,0x45,0xab,0xa2,0x5d,0xd1,0xa9,0xe8,0x56,0xf4,
2865
0x28,0x4c,0x8a,0x01,0xc5,0x90,0x62,0x58,0x31,0xa2,0x18,0x55,0x8c,0x29,0xc6,0x15,
2866
0x13,0x8a,0x49,0xc5,0x94,0x62,0x5a,0x61,0x56,0x58,0x14,0xf3,0x8a,0x45,0xc5,0x92,
2867
0x62,0x59,0xb1,0xa2,0xb0,0x51,0xda,0x29,0x09,0x4a,0x47,0xa5,0x8b,0x92,0xa8,0x74,
2868
0x57,0x7a,0xac,0xf1,0x57,0xe0,0xa9,0xf4,0x56,0x92,0x94,0xbe,0x4a,0x3f,0x25,0x59,
2869
0x49,0x55,0xd2,0x95,0x0c,0x65,0xb0,0x32,0x44,0x19,0xa6,0x64,0x29,0x39,0xca,0x58,
2870
0x65,0xa2,0x32,0x59,0x99,0xaa,0x4c,0x53,0x66,0x28,0x79,0x4a,0x81,0x52,0xa8,0x14,
2871
0x2b,0x25,0x4a,0x99,0x52,0xa1,0xd4,0x28,0x75,0x4a,0xa3,0xb2,0x46,0x59,0xa7,0x6c,
2872
0x50,0x36,0x2a,0x9b,0x95,0x2d,0xca,0x56,0x65,0x1b,0xd0,0xae,0xec,0x50,0x76,0x2a,
2873
0xbb,0x95,0x3d,0x4a,0x93,0x72,0x40,0x39,0xa4,0x1c,0x56,0x8e,0x28,0x47,0x95,0x63,
2874
0xca,0x87,0xca,0x71,0xe5,0x84,0x72,0x52,0x39,0xa5,0x7c,0xaa,0x9c,0x56,0xce,0x28,
2875
0xcd,0xca,0xb9,0x9f,0x60,0x51,0x3e,0xff,0x9e,0x79,0xe5,0x82,0x72,0x51,0xf9,0x42,
2876
0xb9,0xa4,0xfc,0x4e,0xb9,0xac,0x5c,0x51,0xda,0xa8,0x6c,0x55,0x76,0x2a,0x82,0xca,
2877
0x41,0xe5,0xa8,0x72,0x06,0x5c,0x54,0xae,0x2a,0xa2,0xca,0x4d,0xe5,0xae,0xf2,0x50,
2878
0x79,0xaa,0xbc,0x54,0xde,0x2a,0x1f,0x15,0x49,0xe5,0xab,0xf2,0x53,0x91,0x55,0x14,
2879
0x80,0xaa,0xa2,0xab,0x18,0xaa,0x60,0xd5,0x01,0x55,0x88,0x2a,0x4c,0xc5,0x52,0x71,
2880
0x54,0xb1,0xaa,0x44,0x55,0xb2,0x2a,0x45,0x95,0xaa,0x4a,0x53,0x65,0xa8,0x78,0x2a,
2881
0xbe,0x4a,0xa0,0x12,0xaa,0xc4,0x2a,0x89,0x4a,0xaa,0x92,0xa9,0xe4,0x2a,0x85,0x4a,
2882
0xa3,0xd2,0xa9,0x8c,0xaa,0x1a,0x55,0x9d,0xaa,0x51,0xd5,0xac,0x6a,0x55,0xb5,0xab,
2883
0x3a,0x54,0x9d,0xaa,0x6e,0x55,0x8f,0xca,0xa4,0x1a,0x50,0x0d,0xa9,0x86,0x55,0x23,
2884
0xaa,0x51,0xd5,0x98,0x6a,0x5c,0x35,0xa1,0x9a,0x54,0x4d,0xa9,0xa6,0x55,0x66,0x95,
2885
0x45,0xf5,0xfc,0x47,0xe6,0x55,0x8b,0xaa,0x25,0xd5,0x77,0xaa,0x65,0xd5,0x8a,0xca,
2886
0x46,0x6d,0xa7,0x26,0xa8,0x1d,0xd4,0x8e,0x6a,0x17,0x35,0x51,0xed,0xae,0xf6,0x54,
2887
0x7b,0xab,0x49,0x6a,0x5f,0x35,0x59,0x4d,0x55,0xd3,0xd5,0x0c,0x75,0xb0,0x3a,0x44,
2888
0x1d,0xa6,0x66,0xa9,0x39,0xea,0x98,0xff,0x35,0xc4,0xaa,0x93,0xd5,0x69,0x6a,0x9e,
2889
0x5a,0xa8,0x96,0xa8,0x15,0x6a,0x9d,0xba,0x46,0xdd,0xa8,0x6e,0x55,0x77,0xfc,0x48,
2890
0xa7,0xda,0xa4,0x1e,0x56,0x8f,0xa9,0x27,0xd5,0x66,0xf5,0xa2,0x7a,0x45,0x4d,0xd0,
2891
0x10,0x35,0xde,0x1a,0xb2,0x86,0xa1,0x09,0xd3,0xc4,0x6a,0x52,0x35,0x3c,0x8d,0x58,
2892
0xa3,0xd0,0x18,0x35,0x8d,0x9a,0x76,0x4d,0x8f,0x66,0x48,0x33,0xaa,0x99,0xd0,0x4c,
2893
0x6b,0xe6,0x35,0x8b,0x9a,0x25,0xcd,0x8a,0xc6,0xb6,0xcc,0xae,0x8c,0x50,0xe6,0x58,
2894
0xe6,0x52,0x46,0x2c,0x73,0x2f,0xf3,0x2c,0xf3,0x2e,0x23,0x95,0xf9,0x96,0x91,0xcb,
2895
0xa8,0x65,0xf4,0x32,0x46,0x59,0x70,0x59,0x48,0x59,0x58,0x19,0xab,0x8c,0x53,0x16,
2896
0x5b,0x96,0x58,0x96,0x5c,0x96,0x5a,0x96,0x56,0x96,0x51,0xc6,0x2b,0x13,0x94,0x89,
2897
0xcb,0x64,0x65,0x9a,0x32,0x63,0x59,0x63,0x59,0xcb,0xdf,0x41,0x6b,0x59,0x67,0x59,
2898
0x4f,0x59,0xff,0xcf,0xc2,0x40,0xd9,0xdd,0x7f,0x69,0x86,0x81,0xd1,0xb2,0xf1,0xb2,
2899
0x47,0x7f,0x96,0x89,0xb2,0xc9,0xb2,0xa9,0xb2,0xe9,0x32,0x4b,0xd9,0x7c,0xd9,0x62,
2900
0xd9,0x52,0xd9,0x72,0xd9,0x4a,0x99,0x4d,0xb9,0x5d,0x39,0xa1,0xdc,0xb1,0xdc,0xa5,
2901
0x9c,0x58,0xee,0x5e,0xee,0x59,0xee,0x5d,0x4e,0x2a,0xf7,0x2d,0x27,0x97,0x53,0xcb,
2902
0xe9,0xe5,0x8c,0xf2,0xe0,0xf2,0x90,0xf2,0xb0,0x72,0x56,0x39,0xa7,0x3c,0xb6,0x3c,
2903
0xb1,0x3c,0xb9,0x3c,0xb5,0x3c,0xad,0x3c,0xa3,0x9c,0x57,0x2e,0x28,0x17,0x96,0x8b,
2904
0xcb,0x25,0xe5,0xb2,0x72,0x45,0xb9,0xa6,0x5c,0xfb,0x3d,0xba,0xf2,0xba,0xf2,0xd6,
2905
0xf2,0xee,0xf2,0x81,0xf2,0x91,0xf2,0xf1,0xf2,0xa9,0x72,0x4b,0xf9,0x8b,0x3f,0x60,
2906
0xa9,0x7c,0xb9,0xfc,0xe5,0x1a,0x6b,0xac,0xf1,0x77,0xb2,0x52,0x6e,0xa3,0xb5,0xd3,
2907
0x12,0xb4,0x8e,0x5a,0x17,0x2d,0x51,0xeb,0xae,0xf5,0xd4,0x7a,0x6b,0x7d,0xfe,0x88,
2908
0xbd,0x5a,0x3f,0x2d,0x45,0x4b,0xd3,0x06,0x6a,0x99,0xda,0x03,0xda,0x50,0x6d,0xb8,
2909
0x96,0xad,0x8d,0xd1,0x26,0x68,0x93,0xb4,0x29,0xda,0xd3,0xda,0x74,0x2d,0x57,0xcb,
2910
0xd7,0xe6,0x68,0x45,0xda,0x42,0xad,0x54,0x2b,0xd7,0xaa,0xb5,0x5a,0xad,0x41,0x5b,
2911
0xad,0xad,0xd5,0x36,0x68,0x9b,0xb4,0x2d,0xda,0x36,0x6d,0x87,0xb6,0x4b,0x7b,0x5d,
2912
0xdb,0xa7,0xed,0xd7,0x0e,0x6a,0xef,0x6a,0xef,0x69,0xef,0x6b,0x1f,0x68,0x1f,0x6a,
2913
0x1f,0x69,0x1f,0x6b,0x9f,0x68,0x9f,0x6a,0x67,0xb4,0x73,0xda,0xe7,0xda,0x05,0xed,
2914
0x0b,0xed,0x77,0xda,0x97,0x5a,0xa4,0xb3,0xd5,0xd9,0xeb,0x1c,0x74,0xce,0x3a,0x57,
2915
0x9d,0x9b,0xce,0x43,0xe7,0xa5,0xf3,0xd1,0xed,0xd5,0xf9,0xe9,0x28,0x3a,0x9a,0x2e,
2916
0x50,0xc7,0xd4,0x1d,0xd0,0x85,0xea,0xc2,0x75,0x6c,0x5d,0x8c,0x2e,0x41,0x97,0xa4,
2917
0x4b,0xd1,0x9d,0xd6,0xa5,0xeb,0xb8,0x3a,0xbe,0x2e,0x47,0x27,0xd2,0x15,0xea,0xa4,
2918
0x3a,0xb9,0x4e,0xad,0xd3,0xea,0x0c,0xba,0x6a,0x5d,0xad,0xae,0x41,0xd7,0xa4,0x6b,
2919
0xd1,0xb5,0xe9,0x3a,0x74,0x5d,0xba,0xeb,0xba,0x3e,0x5d,0xbf,0x6e,0x50,0x77,0x57,
2920
0x77,0x4f,0x77,0x5f,0xf7,0x40,0xf7,0x50,0xf7,0x48,0xf7,0x58,0xf7,0x44,0xf7,0x54,
2921
0x37,0xa3,0x9b,0xd3,0x3d,0xd7,0x2d,0xe8,0x5e,0xe8,0xbe,0xd3,0xbd,0xd4,0x21,0xbd,
2922
0xad,0xde,0x5e,0xef,0xa0,0x77,0xd6,0xbb,0xea,0xdd,0xf4,0x1e,0x7a,0x2f,0xbd,0x8f,
2923
0x7e,0xaf,0xde,0x4f,0x4f,0xd1,0xd3,0xf4,0x81,0x7a,0xa6,0xfe,0x80,0x3e,0x54,0x1f,
2924
0xae,0x67,0xeb,0x63,0xf4,0x09,0xfa,0x24,0x7d,0x8a,0xfe,0xb4,0x3e,0x5d,0xcf,0xd5,
2925
0xf3,0xf5,0x39,0x7a,0x91,0xbe,0x50,0x2f,0xd5,0xcb,0xf5,0x6a,0xbd,0x56,0x6f,0xd0,
2926
0x57,0xeb,0x6b,0xf5,0x0d,0xfa,0x26,0x7d,0x8b,0xbe,0x4d,0xdf,0xa1,0xef,0xd2,0x5f,
2927
0xd7,0xf7,0xe9,0xfb,0xf5,0x83,0xfa,0xbb,0xfa,0x7b,0xfa,0xfb,0xfa,0x07,0xfa,0x87,
2928
0xfa,0x47,0xfa,0xc7,0xfa,0x27,0xfa,0xa7,0xfa,0x19,0xfd,0x9c,0xfe,0xb9,0x7e,0x41,
2929
0xff,0x42,0xff,0x9d,0xfe,0xa5,0x1e,0x55,0xd8,0x56,0xd8,0x57,0x38,0x54,0x38,0x57,
2930
0xb8,0x56,0xb8,0x55,0x78,0x54,0x78,0x55,0xf8,0x54,0xec,0xad,0xf0,0xab,0xa0,0x54,
2931
0xd0,0x2a,0x02,0x2b,0x98,0x15,0x07,0x2a,0x42,0x2b,0xc2,0x2b,0xd8,0x15,0x31,0x15,
2932
0x09,0x15,0x49,0x15,0x29,0x15,0xa7,0x2b,0xd2,0x2b,0xb8,0x15,0xfc,0x8a,0x9c,0x0a,
2933
0x51,0x45,0x61,0x85,0xb4,0x42,0x5e,0xa1,0xae,0xd0,0x56,0x18,0x2a,0xaa,0x2b,0x6a,
2934
0x2b,0x1a,0x2a,0x9a,0x2a,0x5a,0x2a,0xda,0x2a,0x3a,0x2a,0xba,0x2a,0xae,0x57,0xf4,
2935
0x55,0xf4,0x57,0x0c,0x56,0xdc,0xad,0xb8,0x57,0x71,0xbf,0xe2,0x41,0xc5,0xc3,0x8a,
2936
0x47,0x15,0x8f,0x2b,0x9e,0x54,0x3c,0xad,0x98,0xa9,0x98,0xab,0x78,0x5e,0xb1,0x50,
2937
0xf1,0xa2,0xe2,0xbb,0x8a,0x97,0x15,0xc8,0x60,0x6b,0xb0,0x37,0x38,0x18,0x9c,0x0d,
2938
0xae,0x06,0x37,0x83,0x87,0xc1,0xcb,0xe0,0x03,0xec,0x35,0xf8,0x19,0x28,0x06,0x9a,
2939
0x21,0xd0,0xc0,0x34,0x1c,0x30,0x84,0x1a,0xc2,0x0d,0x6c,0x43,0x8c,0x21,0xc1,0x90,
2940
0x64,0x48,0x31,0x9c,0x36,0xa4,0x1b,0xb8,0x06,0xbe,0x21,0xc7,0x20,0x32,0x14,0x1a,
2941
0xa4,0x06,0xb9,0x41,0x6d,0xd0,0x1a,0x0c,0x86,0x6a,0x43,0xad,0xa1,0xc1,0xd0,0x64,
2942
0x68,0x31,0xb4,0x19,0x3a,0x0c,0x5d,0x86,0xeb,0x86,0x3e,0x43,0xbf,0x61,0xd0,0x70,
2943
0xd7,0x70,0xcf,0x70,0xdf,0xf0,0xc0,0xf0,0xd0,0xf0,0xc8,0xf0,0xd8,0xf0,0xc4,0xf0,
2944
0xd4,0x30,0x63,0x98,0x33,0x3c,0x37,0x2c,0x18,0x5e,0x18,0xbe,0x33,0xbc,0x34,0x20,
2945
0xa3,0xad,0xd1,0xde,0xe8,0x60,0x74,0x36,0xba,0x1a,0xdd,0x8c,0x1e,0x46,0x2f,0xa3,
2946
0x8f,0x71,0xaf,0xd1,0xcf,0x48,0x31,0xd2,0x8c,0x81,0x46,0xa6,0xf1,0x80,0x31,0xd4,
2947
0x18,0x6e,0x64,0x1b,0x63,0x8c,0x09,0xc6,0x24,0x63,0x8a,0xf1,0xb4,0x31,0xdd,0xc8,
2948
0x35,0xf2,0x8d,0x39,0x46,0x91,0xb1,0xd0,0x28,0x35,0xca,0x8d,0x6a,0xa3,0xd6,0x68,
2949
0x30,0x56,0x1b,0x6b,0x8d,0x0d,0xc6,0x26,0x63,0x8b,0xb1,0xcd,0xd8,0x61,0xec,0x32,
2950
0x5e,0x37,0xf6,0x19,0xfb,0x8d,0x83,0xc6,0xbb,0xc6,0x7b,0xc6,0xfb,0xc6,0x07,0xc6,
2951
0x87,0xc6,0x47,0xc6,0xc7,0xc6,0x27,0xc6,0xa7,0xc6,0x19,0xe3,0x9c,0xf1,0xb9,0x71,
2952
0xc1,0xf8,0xc2,0xf8,0x9d,0xf1,0xa5,0x11,0x55,0xda,0x56,0xda,0x57,0x3a,0x54,0x3a,
2953
0x57,0xba,0x56,0xba,0x55,0x7a,0x54,0x7a,0x55,0xfa,0x54,0xee,0xad,0xf4,0xab,0xa4,
2954
0x54,0xd2,0x2a,0x03,0x2b,0x99,0x95,0x07,0x2a,0x43,0x2b,0xc3,0x2b,0xd9,0x95,0x31,
2955
0x95,0x09,0x95,0x49,0x95,0x29,0x95,0xa7,0x2b,0xd3,0x2b,0xb9,0x95,0xfc,0xca,0x9c,
2956
0x4a,0x51,0x65,0x61,0xa5,0xb4,0x52,0x5e,0xa9,0xae,0xd4,0x56,0x1a,0x2a,0xab,0x2b,
2957
0x6b,0x2b,0x1b,0x2a,0x9b,0x2a,0x5b,0x2a,0xdb,0x2a,0x3b,0x2a,0xbb,0x2a,0xaf,0x57,
2958
0xf6,0x55,0xf6,0x57,0x0e,0x56,0xde,0xad,0xbc,0x57,0x79,0xbf,0xf2,0x41,0xe5,0xc3,
2959
0xca,0x47,0x95,0x8f,0x2b,0x9f,0x54,0x3e,0xad,0x9c,0xa9,0x9c,0xab,0x7c,0x5e,0xb9,
2960
0x50,0xf9,0xa2,0xf2,0xbb,0xca,0x97,0x95,0xa8,0xca,0xb6,0xca,0xbe,0xca,0xa1,0xca,
2961
0xb9,0xca,0xb5,0xca,0xad,0xca,0xa3,0xca,0xab,0xca,0xa7,0x6a,0x6f,0x95,0x5f,0x15,
2962
0xa5,0x8a,0x56,0x15,0x58,0xc5,0xac,0x3a,0x50,0x15,0x5a,0x15,0x5e,0xc5,0xae,0x8a,
2963
0xa9,0x4a,0xa8,0x4a,0xaa,0x4a,0xa9,0x3a,0x5d,0x95,0x5e,0xc5,0xad,0xe2,0x57,0xe5,
2964
0x54,0x89,0xaa,0x0a,0xab,0xa4,0x55,0xf2,0x2a,0x75,0x95,0xb6,0xca,0x50,0x55,0x5d,
2965
0x55,0x5b,0xd5,0x50,0xd5,0x54,0xd5,0x52,0xd5,0x56,0xd5,0x51,0xd5,0x55,0x75,0xbd,
2966
0xaa,0xaf,0xaa,0xbf,0xea,0xff,0x63,0xef,0x4c,0x00,0x74,0xaa,0x1a,0x3e,0x7e,0x9f,
2967
0x67,0xe6,0x99,0x31,0x28,0x84,0x4a,0xb2,0x4e,0x96,0x30,0x63,0x76,0xc6,0x3a,0x86,
2968
0xc7,0x18,0xc2,0xc8,0x96,0xb4,0x18,0xb2,0x65,0xdf,0x97,0x54,0x96,0x44,0xab,0x51,
2969
0xa9,0xb4,0xd2,0x4a,0x2a,0x5b,0x92,0xb2,0x57,0x88,0x94,0x68,0x51,0xa6,0x08,0x49,
2970
0x24,0xa4,0xde,0x37,0xa5,0xfa,0x7e,0x67,0xee,0xff,0xe6,0x78,0x3e,0xde,0xf4,0xd6,
2971
0xdb,0x3a,0xcf,0xf1,0xf3,0x3f,0xe7,0xdc,0x73,0xcf,0x7e,0xce,0x3d,0x77,0x9d,0xa5,
2972
0x53,0x56,0x4e,0x79,0x65,0xca,0xba,0x29,0xaf,0x4f,0xd9,0x34,0xe5,0xed,0x29,0x5b,
2973
0xa7,0xe4,0x4e,0xd9,0x31,0x65,0xf7,0x94,0xbd,0x53,0x3e,0x9f,0x72,0x68,0xca,0x57,
2974
0x53,0xbe,0x99,0x72,0x6c,0x8a,0x93,0x13,0x9e,0x53,0x20,0xa7,0x70,0x4e,0xd1,0x9c,
2975
0x12,0x39,0xe7,0xe6,0x9c,0x9f,0x53,0x3e,0xe7,0x02,0x4c,0xd5,0x9c,0x1a,0x39,0x71,
2976
0x39,0x49,0x39,0xb5,0x73,0xea,0xe5,0xa4,0xe5,0x34,0xc9,0x69,0x96,0x73,0x51,0x4e,
2977
0x56,0x4e,0xbb,0x9c,0x4b,0x72,0x2e,0xcb,0xe9,0x92,0x73,0x55,0x4e,0xaf,0x9c,0xbe,
2978
0x39,0x03,0x73,0x86,0xe6,0x8c,0xcc,0x19,0x93,0x33,0x36,0xe7,0x86,0x9c,0xc9,0x39,
2979
0xb7,0xe6,0xe4,0xe4,0xdc,0x95,0x73,0x6f,0xce,0x03,0xf9,0xe6,0x6f,0x60,0xcc,0xdf,
2980
0x1f,0x2f,0x2f,0x0a,0x84,0x39,0x4e,0xb6,0xec,0xe1,0xd8,0x13,0xd0,0x44,0xb9,0x7d,
2981
0xb8,0x97,0x86,0xb9,0xf6,0x2a,0x68,0x3c,0x3a,0xc0,0x71,0xb5,0x09,0x9e,0x49,0x96,
2982
0xdd,0xdb,0xcf,0xf3,0x6f,0x64,0x12,0x09,0x73,0xd5,0x27,0xf5,0x4b,0xc3,0xa4,0x05,
2983
0xa4,0x05,0xd1,0xc6,0x4a,0x23,0xa8,0xfd,0x82,0xda,0x2f,0xa8,0xfd,0x82,0x0a,0x9f,
2984
0xa9,0xed,0x99,0xda,0x9e,0xa9,0xed,0x99,0xda,0xde,0x4a,0xf1,0xb7,0x56,0xb8,0xd6,
2985
0x0a,0xd7,0x5a,0xe1,0x5a,0x5b,0xdb,0x4d,0xf8,0xf6,0x0a,0xd7,0x5e,0xe1,0xda,0x2b,
2986
0x5c,0x7b,0x6d,0xef,0x24,0xff,0x6c,0x85,0xcb,0xb6,0xdc,0x7e,0x69,0x98,0xd4,0xab,
2987
0x4b,0x53,0x9e,0x6e,0x2a,0x4f,0x77,0xed,0xd7,0x5d,0xfb,0x75,0xd7,0x7e,0xdd,0x15,
2988
0xbe,0xb7,0xb6,0xf7,0xd6,0xf6,0xde,0xda,0xde,0x5b,0xdb,0xfb,0x2b,0xfe,0x01,0x0a,
2989
0x37,0x40,0xe1,0x06,0x28,0xdc,0x00,0x6b,0xbb,0x09,0x3f,0x4c,0xe1,0x86,0x29,0xdc,
2990
0x30,0x85,0x1b,0xa6,0xed,0xa3,0xe4,0x3f,0xca,0xaa,0xff,0x70,0xe5,0x3b,0x5c,0xee,
2991
0x08,0xb9,0x23,0xe4,0xae,0x2a,0x77,0x55,0xb5,0x93,0x4f,0xe5,0xf3,0xc9,0xed,0x97,
2992
0xdb,0x2f,0x77,0xa4,0xdc,0x91,0x72,0x17,0x96,0xdb,0x68,0x13,0xe9,0x55,0xd2,0xa0,
2993
0xd2,0xed,0x2e,0x0d,0x2a,0xdd,0xee,0xd2,0xa0,0xe2,0xe9,0x2e,0x0d,0x2a,0x1f,0xdd,
2994
0xa5,0x41,0xc5,0xd3,0x5d,0x9a,0xa1,0x7c,0xf4,0x94,0x66,0x28,0x9e,0x9e,0xd2,0x0c,
2995
0xc5,0xd3,0x53,0x9a,0xa1,0x76,0xea,0x29,0x6d,0xa6,0xfd,0x7a,0x59,0xfd,0x2a,0x4c,
2996
0xed,0x11,0x26,0x77,0xb8,0xdc,0xe1,0x72,0x47,0xc8,0x1d,0x21,0x77,0x55,0xb9,0xab,
2997
0xca,0x1d,0x29,0x6d,0xee,0xb8,0xfe,0x57,0xcb,0x6e,0xe2,0xbf,0x5a,0xda,0x42,0xe9,
2998
0xf7,0x91,0x5e,0xa4,0xfa,0xed,0x2b,0xbd,0x48,0xfe,0x7d,0xad,0xed,0x85,0xe5,0x2e,
2999
0x2c,0xf7,0x62,0xc7,0x75,0x1b,0x6d,0xa5,0xfd,0xfa,0x4b,0x5b,0x69,0xbf,0xfe,0xd2,
3000
0x56,0xda,0xaf,0xbf,0x74,0xa9,0xdf,0xb5,0xb7,0x56,0xb9,0x06,0x48,0x5b,0xab,0x5c,
3001
0x03,0xa4,0xc6,0x5d,0x48,0x6e,0xa3,0x17,0x2b,0xfe,0xc1,0xd2,0x8b,0x15,0xff,0x60,
3002
0xe9,0xc5,0x8a,0x7f,0xb0,0xb4,0xad,0xc2,0x0d,0x91,0xb6,0x55,0xf9,0x87,0x48,0xdb,
3003
0x6a,0xbf,0x21,0xd2,0xb6,0xda,0x6f,0x88,0xb4,0x9d,0xfc,0x87,0x4a,0xdb,0xc9,0x7f,
3004
0xa8,0xb4,0xbd,0xda,0x69,0x98,0xb4,0xbd,0xca,0x31,0x4c,0xda,0x5e,0xe5,0x18,0x26,
3005
0x6d,0xaf,0xf1,0x3a,0x4c,0xda,0x5e,0xe5,0x1a,0x26,0x6d,0xaf,0x76,0x1c,0x26,0xed,
3006
0xa8,0x7c,0x8e,0x90,0x76,0x92,0x8e,0xb2,0xdc,0x66,0x5c,0x5d,0xaa,0xf2,0x8d,0x96,
3007
0x5e,0xaa,0x7e,0x30,0x5a,0x7a,0xa9,0xf2,0x3b,0xda,0x2a,0x9f,0xa9,0xdb,0xd2,0xaa,
3008
0xdb,0xd2,0x4a,0xbb,0xb4,0xd2,0x2e,0xad,0xb1,0x73,0xa9,0x35,0x8e,0x46,0x5b,0x63,
3009
0x69,0xb4,0xd5,0x0f,0x4c,0xdf,0xba,0x48,0xfd,0xac,0xaf,0xb4,0x95,0xfc,0x5b,0xc9,
3010
0xdd,0x5f,0xda,0x48,0xfb,0x65,0x4b,0x33,0xa5,0xbd,0xa5,0xad,0xa5,0x03,0xac,0xfa,
3011
0x2d,0xac,0x3c,0x15,0xb6,0xe6,0xc9,0x70,0x6b,0x8e,0x09,0xb7,0xfc,0x7d,0x96,0xbf,
3012
0xcf,0xf2,0x2f,0x6c,0xf9,0xdb,0xf1,0x38,0x96,0xbf,0x63,0x1d,0x27,0xc2,0xad,0x39,
3013
0xd6,0x9b,0xa7,0x22,0x2d,0x7f,0xcf,0xbe,0x46,0xed,0xbc,0x47,0x9a,0xa1,0x7c,0xf6,
3014
0x94,0xb6,0x90,0xf6,0xb1,0xca,0x57,0x55,0xe5,0xab,0x6a,0xb9,0xc3,0x2d,0x3f,0x63,
3015
0x5f,0xec,0x73,0xc3,0xdf,0xe1,0x77,0xf5,0x6a,0xab,0x1d,0x4c,0x9b,0x78,0xed,0xe1,
3016
0xb5,0x45,0x86,0xda,0xbd,0xa7,0x35,0xfe,0x1c,0x8d,0x37,0xc7,0x3a,0xee,0xf9,0xac,
3017
0x63,0x86,0x4f,0xf9,0xf7,0x29,0xff,0x46,0xb7,0x4a,0xbf,0xb1,0x8e,0xa3,0x45,0xb4,
3018
0x4f,0x11,0xb9,0x8b,0xc9,0x5d,0x4c,0xf3,0x61,0x11,0xcd,0x87,0x45,0xe4,0x2e,0x26,
3019
0x77,0x31,0xb5,0x6f,0x11,0xb5,0x6f,0x11,0xb9,0x8b,0xc9,0x5d,0x4c,0xe5,0x2f,0xa2,
3020
0xb2,0x17,0x91,0xbb,0x98,0xdc,0xc5,0x34,0x9e,0x8b,0x68,0x3c,0x17,0x91,0xbb,0x98,
3021
0xdc,0xc5,0xd4,0x8e,0x45,0xd4,0x86,0x45,0xe4,0x2e,0x26,0x77,0x31,0x8d,0xe7,0xca,
3022
0xea,0xef,0x95,0x35,0x7e,0x2b,0x6b,0xfc,0x56,0xd6,0xfc,0x5b,0x58,0xf3,0x6f,0x61,
3023
0xab,0x9d,0xb3,0xad,0xf9,0xdf,0x3b,0xae,0x56,0xb1,0x8e,0xe3,0xe1,0xd6,0x31,0x30,
3024
0xdc,0x3a,0xce,0x87,0x5b,0xc7,0x48,0xcf,0x3f,0x52,0x7e,0x91,0x96,0x3b,0xdc,0xf2,
3025
0x0b,0xd7,0x38,0x0e,0xd7,0xb8,0x0e,0x57,0x7e,0x7a,0xf8,0xdd,0x76,0x37,0x65,0x1d,
3026
0x85,0xfd,0x1a,0x18,0xe7,0x77,0xe7,0x82,0x51,0x5a,0x33,0x45,0x68,0xbd,0x14,0x29,
3027
0x2d,0x28,0xad,0x2a,0x0d,0x93,0x9a,0xb9,0xa5,0x9b,0xdf,0x1d,0x9f,0xa6,0x2e,0x46,
3028
0xc2,0x34,0xbf,0xdb,0x37,0x4c,0x3b,0x17,0x0f,0x3b,0x3e,0x66,0x96,0xf8,0xdd,0x7d,
3029
0x82,0xd8,0xeb,0x5a,0x6b,0xb3,0x59,0xd2,0xa9,0x0a,0x67,0xe6,0xfd,0x69,0xb2,0xdf,
3030
0x23,0x9d,0x2e,0x7d,0x58,0xfa,0xb8,0x74,0xb6,0x17,0xb7,0x95,0xce,0x74,0xd9,0x1f,
3031
0x97,0xce,0x97,0xff,0x22,0x2f,0x7e,0x6b,0x1f,0xa3,0xaf,0xda,0x79,0x94,0xdd,0xf3,
3032
0x5b,0x61,0x85,0x31,0xfa,0x9a,0x74,0x01,0xbc,0xa0,0x34,0x36,0xcb,0x6f,0xb3,0xf6,
3033
0x59,0x03,0x2b,0xe1,0x45,0x58,0x05,0xab,0xe1,0x5e,0xa5,0xff,0x28,0x94,0x0c,0x77,
3034
0xeb,0xc7,0xa8,0x09,0x5f,0x3c,0xdc,0xdd,0x3f,0x42,0xee,0xf3,0xe4,0x3e,0x57,0xe1,
3035
0xa2,0xc3,0xdd,0xf6,0x38,0x57,0x5a,0x5b,0x9a,0xac,0xed,0xc9,0xda,0x2f,0x51,0xfb,
3036
0x75,0x90,0xbb,0x8e,0xdc,0xb5,0x15,0xae,0xb1,0xf6,0x1b,0x1a,0xae,0xbe,0x2d,0x3d,
3037
0x5b,0xfe,0x29,0xd2,0xa2,0xd2,0x38,0xcb,0x5d,0x40,0xee,0x02,0xca,0xb7,0x97,0xbe,
3038
0xd1,0xad,0xf2,0x7f,0x5f,0x7a,0xb6,0x34,0x45,0x7a,0x8e,0xb4,0x96,0xd4,0x94,0x23,
3039
0x5c,0xf9,0x0a,0x97,0xbb,0x80,0xdc,0x46,0xcb,0x4a,0x1b,0x48,0xf7,0x4a,0x3f,0x93,
3040
0xc6,0x48,0x5b,0x4a,0xa3,0x15,0x4f,0x63,0x69,0xb4,0xfc,0x1b,0x5b,0xdb,0x0b,0xc9,
3041
0x6d,0xb4,0x8a,0xfc,0x33,0xa4,0xd5,0xa5,0x2d,0xa4,0x3d,0x03,0x8c,0x4b,0x18,0x0f,
3042
0x7d,0x60,0x18,0x54,0x89,0x60,0xcc,0x47,0xb8,0xda,0x0e,0x9a,0x49,0x8d,0xbb,0x3d,
3043
0x34,0xb7,0xdc,0x43,0xb5,0xdd,0xe8,0x5a,0x69,0x73,0xe9,0x3b,0x0a,0xb7,0x4a,0xba,
3044
0x59,0x5a,0x35,0xca,0x71,0xea,0x41,0x9c,0x34,0x51,0x5a,0x52,0x7a,0xb6,0xf4,0x1c,
3045
0xe9,0xf9,0xd2,0x0a,0xd2,0x8a,0xd2,0xea,0xd2,0x9a,0xd2,0xb5,0xb0,0x5c,0xfa,0x1e,
3046
0xcc,0x84,0xa5,0xf0,0x88,0x74,0xae,0x34,0xa1,0x20,0xe1,0xa1,0xb6,0xf4,0x6c,0xe9,
3047
0x39,0xd2,0xf3,0xa5,0xd5,0xa5,0x19,0x85,0xe8,0x67,0x85,0x5c,0x6d,0x20,0xed,0x08,
3048
0x15,0xa0,0x1e,0x54,0x94,0xde,0x01,0xef,0xc1,0x1a,0x58,0x0e,0x6b,0xa5,0x6b,0xe4,
3049
0xdf,0xb4,0x30,0xf1,0xc0,0x0a,0x78,0x07,0xd6,0x58,0xfa,0xae,0x74,0xb5,0xa5,0x66,
3050
0x5b,0xd3,0x33,0x48,0x13,0x32,0xa4,0xc6,0xdd,0x11,0xde,0x87,0xf5,0xd2,0x37,0x2d,
3051
0xf5,0xfc,0xb6,0x43,0xcb,0x33,0x29,0x2b,0x6c,0x84,0x05,0x30,0x07,0xa6,0x4b,0x67,
3052
0x42,0xa1,0x22,0x8e,0x93,0x0e,0x8b,0xe1,0x22,0x69,0x1b,0x69,0x07,0x69,0x67,0x69,
3053
0x1a,0x2c,0x82,0x41,0x30,0x58,0x3a,0x14,0x16,0xc0,0x58,0xe9,0x20,0xd9,0x17,0x5a,
3054
0xea,0xf9,0x79,0x7a,0x87,0xe2,0x7b,0x40,0x3a,0x53,0xfa,0x84,0x74,0x8e,0x34,0x47,
3055
0xe9,0x55,0x2a,0xea,0x38,0xb1,0x90,0x0b,0x81,0xd2,0x8c,0x43,0x88,0x94,0x46,0x49,
3056
0x0b,0x49,0xcf,0x90,0x16,0x93,0xd6,0x91,0xd6,0x93,0x36,0x90,0x36,0x94,0xa6,0x4b,
3057
0xcd,0xf1,0xca,0x1c,0xc3,0xd3,0xb5,0x26,0x30,0xc7,0xab,0xdb,0x7d,0xee,0x7a,0xc0,
3058
0x1c,0xdb,0xbc,0xf3,0x80,0x16,0x5a,0xa3,0xb5,0xd4,0x9a,0xcc,0x1c,0x87,0x2a,0x32,
3059
0xcf,0x67,0x39,0xee,0x31,0xd5,0x1c,0x17,0xcd,0xb1,0xd3,0xac,0x37,0xcd,0xb1,0x2f,
3060
0x8b,0x6d,0x6d,0xc0,0x5f,0xc6,0x71,0xba,0x6a,0x9d,0x61,0x8e,0x81,0x9d,0xf0,0xeb,
3061
0x0c,0x97,0xf9,0xdd,0xb5,0x86,0x59,0xd7,0xf4,0x33,0xf1,0xfb,0xdc,0xe3,0x59,0x3b,
3062
0xfc,0xcf,0x66,0x9f,0x73,0x60,0xa0,0xe3,0x1e,0x67,0xcd,0xb1,0xb8,0x0c,0xee,0x01,
3063
0x6c,0x1b,0x8e,0xbd,0x52,0x19,0x77,0x5e,0x5e,0x08,0xcf,0x69,0x1e,0x5e,0xab,0x35,
3064
0xc1,0x60,0x85,0x37,0xe1,0xbc,0x30,0xab,0xac,0x30,0xf5,0x19,0xfb,0x17,0xfb,0xdd,
3065
0xf3,0xbb,0xf6,0xe8,0x21,0xc7,0xcd,0x4b,0x0f,0xf4,0x4a,0x34,0x1b,0xba,0x43,0x2f,
3066
0xe8,0x6d,0x8e,0x9f,0xe6,0xb8,0x49,0x7a,0x0f,0xa2,0xfd,0x60,0x22,0xf6,0x87,0xd1,
3067
0x41,0x30,0x10,0x06,0xc3,0x10,0x18,0x0a,0xc3,0x60,0x24,0x8c,0x87,0x09,0x30,0x87,
3068
0x32,0xdd,0x84,0xde,0x0c,0xe7,0xb3,0xdf,0x2d,0xe8,0xad,0x7e,0x77,0xbd,0x95,0x83,
3069
0x4e,0xf5,0xbb,0xeb,0xb3,0x17,0xb4,0x6e,0xa8,0xa4,0x75,0x83,0xd1,0x74,0x1d,0x93,
3070
0xbb,0x4a,0x8d,0x3b,0x5a,0xee,0x68,0xb9,0xe3,0xe5,0x8e,0xb7,0xae,0x47,0xf8,0xac,
3071
0x73,0x79,0x9f,0xd6,0x7b,0x91,0x5a,0x73,0x47,0xca,0x1d,0x2d,0x77,0xb4,0xdc,0xf1,
3072
0x72,0xc7,0xcb,0x5d,0x45,0xee,0x2a,0x72,0xc7,0xc8,0x1d,0x63,0x9d,0xff,0x3a,0xd6,
3073
0x39,0xb0,0x63,0xf9,0xfb,0x2c,0x7f,0xef,0x7a,0x48,0x8c,0xfc,0xbc,0xfd,0xe3,0xe4,
3074
0x8e,0xb3,0xd6,0x47,0x11,0xd6,0x1a,0xc9,0xd8,0x9b,0x2a,0xbf,0x3d,0xac,0xf3,0xde,
3075
0x70,0xad,0x4f,0xc3,0xb5,0xee,0x8a,0xd4,0x3a,0x27,0x52,0xee,0x68,0xb9,0xa3,0xe5,
3076
0x2e,0x20,0x77,0x01,0xb9,0xab,0xc8,0xed,0x9d,0x37,0xc7,0xca,0x1d,0xab,0x75,0x65,
3077
0x9c,0xfa,0x50,0x9c,0x75,0x7d,0xc6,0x67,0x5d,0xdb,0xf0,0x69,0x3d,0xee,0xd3,0x7a,
3078
0xdc,0x73,0x47,0xcb,0x1d,0x2d,0x77,0xbc,0xdc,0xf1,0x3a,0xbf,0x89,0xd6,0x79,0x6f,
3079
0xb4,0xe5,0x0e,0xb7,0xfc,0xc2,0xe5,0x1f,0x2f,0x3f,0x6f,0xbf,0x18,0xb9,0x8d,0xb6,
3080
0x54,0x7a,0xfd,0xa4,0x2d,0x55,0xee,0x7e,0xd2,0x96,0x8a,0xab,0x9f,0xb4,0x95,0xfc,
3081
0xfb,0x4b,0x5b,0xc9,0xbf,0xbf,0xb5,0x3d,0x5e,0xee,0x78,0xb9,0x63,0xe4,0x8e,0xb1,
3082
0xd6,0xa3,0x3e,0x6b,0x3d,0xea,0xb3,0xfc,0x0b,0x58,0xfe,0x05,0xc2,0x8e,0x9f,0x87,
3083
0x3b,0xd6,0xb9,0xb8,0x63,0xf9,0xfb,0x2c,0x7f,0x63,0xcf,0x52,0x39,0x06,0x3a,0xc7,
3084
0xdd,0x91,0x72,0x47,0x6a,0x9d,0x1e,0xa9,0x75,0xba,0xe7,0x8e,0x96,0x3b,0xda,0x72,
3085
0x87,0x5b,0x7e,0xe1,0xf2,0x8f,0x97,0x5f,0xbc,0xd6,0xef,0x91,0x5a,0xbf,0x47,0xca,
3086
0x1d,0x2d,0x77,0xb4,0x75,0x7e,0x1f,0x69,0x9d,0xe3,0x47,0x5a,0xe7,0xf1,0x91,0xd6,
3087
0xb9,0xbc,0xbd,0x7f,0xa4,0x15,0x47,0xa4,0xce,0x0b,0x22,0x75,0x5e,0xe0,0xb9,0xa3,
3088
0xe5,0x8e,0x96,0x3b,0x5e,0xee,0x78,0xb9,0x63,0xe4,0x8e,0xd1,0x79,0xc7,0x05,0x3a,
3089
0xef,0xb8,0x40,0xee,0x38,0xb9,0xe3,0xe4,0x8e,0x91,0x3b,0xc6,0xba,0x6e,0xe0,0xb3,
3090
0xae,0x1d,0xf8,0xac,0xeb,0x07,0x05,0xac,0x6b,0x08,0xc6,0xde,0x41,0x61,0x86,0x4b,
3091
0x3b,0x28,0x5f,0xc3,0xa5,0x1d,0x75,0x9e,0x37,0x42,0xda,0x51,0x75,0x31,0x42,0xda,
3092
0x51,0x63,0x60,0x84,0xb4,0xa3,0xca,0x39,0x42,0xda,0x51,0xf1,0x8c,0x90,0x5e,0x22,
3093
0xff,0x91,0xd2,0x4b,0xb4,0xdf,0x48,0xeb,0x3a,0x65,0xa4,0xce,0x57,0xbc,0xeb,0x0b,
3094
0x7e,0x5d,0x5f,0xf0,0xcb,0x1d,0x2d,0x77,0xb4,0xdc,0xf1,0x72,0xc7,0x6b,0xdc,0x7a,
3095
0xf5,0xe9,0xe5,0xab,0xa0,0xe2,0x2b,0xa8,0x79,0x74,0x39,0x73,0xeb,0xf5,0x3e,0x37,
3096
0xfe,0x46,0x8a,0x27,0x5b,0x6a,0xdc,0x51,0x72,0x47,0x59,0xd7,0x7b,0xed,0x6b,0xa5,
3097
0xf6,0x75,0x60,0xc7,0xf2,0x77,0x2c,0xff,0x28,0xcb,0xdf,0x8e,0x27,0xcc,0xf2,0x0f,
3098
0xb3,0xd2,0xf7,0x5b,0x79,0xf0,0x5b,0xd7,0x2f,0x7d,0xd6,0x35,0x4c,0x9f,0xe5,0xef,
3099
0x58,0xfe,0x8e,0xe5,0x1f,0x65,0xf9,0x47,0x59,0xfe,0x61,0x96,0xbf,0x9d,0x6e,0x84,
3100
0x95,0xae,0x77,0x9d,0x32,0x5a,0x73,0x6e,0xb4,0xdc,0x51,0x72,0x47,0xc9,0x1d,0x26,
3101
0x77,0x98,0x75,0x5d,0xdb,0xbe,0x26,0x6c,0x5f,0xef,0x76,0x2c,0x7f,0xc7,0xf2,0x8f,
3102
0xb2,0xfc,0xa3,0x2c,0xff,0x30,0xcb,0x3f,0xcc,0xca,0x8f,0xdf,0xca,0x93,0x77,0x3d,
3103
0x33,0x4a,0x73,0x70,0x94,0xdc,0xd1,0x72,0x47,0x6b,0x7e,0x89,0xd6,0xdc,0xe2,0xb9,
3104
0xa3,0xe4,0x8e,0xb2,0xae,0xa3,0xdb,0xd7,0xa0,0xed,0xeb,0xeb,0x8e,0xe5,0xef,0x58,
3105
0xfe,0x51,0x96,0xbf,0x1d,0x4f,0x98,0xe5,0x1f,0x66,0xa5,0xef,0xb7,0xf2,0xe0,0x5d,
3106
0xb7,0x2f,0x6d,0xa5,0x5b,0xda,0x4a,0xb7,0xb4,0x95,0x6e,0x69,0x2b,0xdd,0xd2,0x56,
3107
0xba,0xa5,0xad,0x74,0x4b,0x5b,0xe9,0x96,0xb6,0xd2,0x35,0xf6,0x68,0xcb,0x3f,0x5a,
3108
0xe3,0x3f,0x5a,0x63,0xdf,0x73,0x47,0xc9,0x1d,0x65,0x5d,0xa3,0xf3,0x59,0xd7,0xe9,
3109
0x7c,0x96,0xbf,0x63,0xf9,0x3b,0x96,0x7f,0x94,0xe5,0x6f,0xc7,0x13,0x66,0xf9,0x87,
3110
0x59,0xfe,0xd1,0x96,0x7f,0xb4,0xc6,0xbb,0xa3,0xf1,0xe9,0xc8,0x1d,0x2d,0xb7,0xb7,
3111
0x3d,0x4a,0xee,0x28,0xb9,0xc3,0xe4,0x0e,0xd3,0xb9,0x7d,0x71,0x69,0x09,0xcb,0xed,
3112
0x58,0x7e,0x8e,0xe5,0xef,0xb3,0xfc,0x7d,0x96,0x7f,0xba,0xe5,0x9f,0xae,0x6b,0x11,
3113
0xc5,0xa5,0x25,0x2c,0xb7,0x63,0xf9,0x39,0x96,0xbf,0xcf,0xf2,0xf7,0x59,0xfe,0xe9,
3114
0x96,0x7f,0xba,0xae,0x01,0x14,0x97,0x96,0xb0,0xdc,0x8e,0xe5,0xe7,0x58,0xfe,0x3e,
3115
0xcb,0xdf,0xd8,0xa7,0xc9,0x7f,0x9a,0xfc,0xa6,0x59,0xfb,0x4f,0xb3,0xf6,0x9f,0x66,
3116
0xed,0x3f,0xcd,0xda,0x7f,0xb1,0xfc,0x17,0xcb,0x6f,0xb1,0xb5,0xff,0x62,0x6b,0xff,
3117
0xc5,0xd6,0xfe,0x8b,0x4f,0xb2,0x7f,0xba,0xe5,0x9f,0xae,0xeb,0x34,0xc5,0xa5,0x25,
3118
0x2c,0xb7,0x63,0xf9,0x39,0x96,0xbf,0xcf,0xf2,0xf7,0x59,0xfe,0xe9,0x96,0x7f,0xba,
3119
0xae,0xc7,0x14,0x97,0x96,0xb0,0xdc,0x8e,0xe5,0xe7,0x58,0xfe,0x3e,0xcb,0xdf,0x67,
3120
0xf9,0xa7,0x5b,0xfe,0xe9,0xba,0x46,0x54,0x5c,0x5a,0xc2,0x72,0x3b,0x96,0x9f,0x63,
3121
0xf9,0xfb,0x2c,0x7f,0x9f,0xe5,0x9f,0x6e,0xf9,0xa7,0xeb,0x7a,0x51,0x71,0x69,0x09,
3122
0xcb,0xed,0x58,0x7e,0x8e,0xe5,0xef,0xb3,0xfc,0xbd,0xeb,0x5b,0xc5,0xa5,0x25,0x2c,
3123
0xb7,0x63,0xf9,0x39,0x96,0xbf,0xcf,0xf2,0xf7,0xae,0x53,0x15,0x97,0x96,0xb0,0xdc,
3124
0x8e,0xe5,0xe7,0x58,0xfe,0x3e,0xcb,0xdf,0xde,0x3f,0xdd,0xf2,0x4f,0xd7,0x75,0xae,
3125
0x12,0x96,0x3a,0x96,0xdd,0x67,0xd9,0xd3,0x75,0x8d,0xac,0xb8,0xb4,0x84,0xe5,0x76,
3126
0x2c,0x3f,0xc7,0xf2,0xf7,0x59,0xfe,0x3e,0xcb,0x3f,0xdd,0xf2,0x4f,0xd7,0xb5,0xbe,
3127
0xe2,0xd2,0x12,0x96,0xdb,0xb1,0xfc,0x1c,0xcb,0xdf,0x67,0xf9,0xfb,0x2c,0xff,0x74,
3128
0xcb,0xdf,0x1b,0xf7,0x4e,0xc8,0x75,0x42,0x27,0xe4,0x7a,0xa1,0x13,0x72,0xdd,0xd0,
3129
0xb1,0xae,0x1f,0xae,0xb0,0xda,0xd4,0xab,0x43,0x27,0xe4,0x9a,0xa1,0x63,0x5d,0x3b,
3130
0xf4,0xe6,0x9c,0xa0,0x35,0xe7,0x04,0x43,0xe6,0xae,0x60,0xc8,0xfc,0x15,0x0c,0x99,
3131
0xc3,0x82,0x21,0xf3,0x58,0x30,0x64,0x2e,0x0b,0x86,0xcc,0x67,0x41,0x6b,0x4e,0x0a,
3132
0x5a,0x73,0x52,0x30,0x64,0x6e,0x0b,0x86,0xcc,0x6f,0xc1,0x90,0x39,0x2e,0x18,0x32,
3133
0xcf,0x05,0x43,0xe6,0xba,0x60,0xc8,0x7c,0x17,0xb4,0xe6,0x8c,0xa0,0x35,0x67,0x04,
3134
0x43,0xe6,0x9e,0x60,0xc8,0xfc,0x13,0x0c,0x99,0x83,0x82,0x21,0xf3,0x50,0x30,0x64,
3135
0x2e,0x0a,0x86,0xcc,0x47,0x41,0x6b,0x4e,0x09,0x5a,0x73,0x4a,0x30,0x64,0x6e,0x0a,
3136
0x86,0xcc,0x4f,0xc1,0x90,0x39,0x2a,0x18,0x32,0x4f,0x05,0x43,0xe6,0xaa,0x60,0xc8,
3137
0x7c,0x15,0xb4,0xfa,0x6f,0xd0,0xea,0xbf,0xc1,0x90,0x71,0x10,0x0c,0x19,0x0b,0xc1,
3138
0x90,0xf1,0x10,0x0c,0x19,0x13,0xc1,0x90,0x71,0x11,0x0c,0x19,0x1b,0x41,0xab,0x7f,
3139
0x07,0xad,0xfe,0x1d,0x0c,0x19,0x27,0xc1,0x90,0xb1,0x12,0x0c,0x19,0x2f,0xc1,0x90,
3140
0x31,0x13,0x0c,0x19,0x37,0xc1,0x90,0xb1,0xe3,0xf5,0xb3,0x08,0x69,0xb8,0x35,0x9e,
3141
0xbc,0x6d,0x41,0x6b,0x6c,0x79,0xf6,0x74,0x4b,0xbd,0x3e,0x13,0x21,0x0d,0x97,0x3a,
3142
0xd6,0x3d,0x81,0xa9,0x0a,0x67,0xee,0x19,0x78,0xc7,0x03,0xcf,0x6e,0x34,0x5d,0xf7,
3143
0x11,0xd2,0xad,0xf1,0xea,0xf5,0x89,0xa0,0x35,0x76,0x3d,0x7b,0xba,0xa5,0x41,0x1d,
3144
0x23,0xbd,0xe3,0xa6,0x77,0x3c,0x72,0xac,0xfb,0x0f,0xf7,0x28,0xdc,0x8a,0x72,0x1a,
3145
0xeb,0xe5,0x34,0xf6,0xcb,0x1d,0x3f,0xb6,0x44,0x48,0xc3,0xad,0xfb,0x08,0x4e,0xc8,
3146
0xbd,0x89,0x25,0xd6,0xb1,0xa8,0x80,0x75,0xfc,0x88,0x90,0x86,0x4b,0x1d,0xeb,0x9e,
3147
0xc7,0x0f,0x4a,0xf3,0x87,0x72,0xc7,0xdd,0xde,0xfc,0x1c,0x21,0x0d,0xb7,0xee,0x59,
3148
0x38,0x21,0xf7,0x34,0x56,0xa9,0xfd,0x56,0x59,0xc7,0x84,0x74,0x2b,0x8c,0x37,0xbf,
3149
0x47,0x48,0xc3,0xa5,0x8e,0x75,0x9f,0x65,0xa6,0xf6,0x9d,0xa5,0x75,0x9a,0x77,0xcf,
3150
0xa6,0x8b,0x73,0x7c,0x7e,0xf3,0xfa,0x64,0xd0,0x9a,0xeb,0x3c,0x7b,0xba,0xa5,0x41,
3151
0x1d,0xb3,0x1c,0xeb,0x7e,0xce,0x6c,0x6b,0xee,0xf6,0xdc,0x26,0xdc,0x73,0xba,0x4f,
3152
0x64,0xd2,0xf6,0x63,0x09,0x2b,0x7f,0xfc,0x99,0x9f,0xff,0x44,0x51,0x85,0x4b,0x64,
3153
0xbf,0x58,0xe7,0xe4,0x98,0xed,0x09,0xe5,0xff,0x3f,0xc9,0x27,0xa1,0x82,0xe3,0x62,
3154
0xf6,0x09,0x10,0x67,0x43,0xe7,0x38,0xde,0xb6,0x86,0x27,0x89,0xcf,0x84,0x8f,0xd3,
3155
0xf3,0x12,0xe6,0x79,0xa2,0x64,0x48,0x81,0x5a,0x50,0x1b,0x52,0xa1,0x3a,0x9c,0x55,
3156
0xd1,0x71,0xea,0x9b,0xfb,0x6b,0x70,0xa1,0xee,0x6b,0xc7,0xe9,0xb9,0x24,0xef,0x99,
3157
0xa4,0x5f,0xb2,0x7f,0xb6,0xae,0xab,0x0e,0xd0,0x3d,0x39,0x73,0x7d,0xb5,0x97,0xae,
3158
0xab,0xf6,0xd5,0xb5,0x55,0x93,0xc6,0x40,0xdd,0xb7,0x33,0xe7,0xcb,0xde,0xfd,0xbf,
3159
0xd1,0xba,0x76,0x3b,0x44,0xf1,0xd4,0x74,0xdc,0x6b,0x87,0x9e,0xdd,0xf8,0x9b,0xeb,
3160
0x8a,0xf3,0xa4,0xdd,0xe4,0x3f,0xc0,0xb2,0x9b,0x35,0x7e,0x8e,0xcf,0x0d,0x63,0xae,
3161
0xd9,0xf5,0xd4,0x75,0x63,0x8f,0xbc,0xeb,0x6d,0x3e,0xf7,0xbc,0x2d,0x53,0xd7,0x90,
3162
0xfb,0xea,0x1a,0x72,0x2b,0xc5,0x65,0xae,0xfd,0xb4,0x51,0x5e,0x3c,0xda,0xea,0x5a,
3163
0x73,0x3b,0x5d,0x93,0xbe,0x48,0xf6,0x96,0xba,0x7f,0x3d,0x5b,0xd7,0x04,0x5a,0x38,
3164
0xc7,0xef,0x4d,0xa7,0x2b,0x9f,0xdd,0xb5,0x4f,0x53,0x85,0x37,0x69,0x6c,0x0a,0x38,
3165
0xce,0x5b,0xb0,0x19,0xb6,0x04,0xdc,0x76,0x6a,0xaa,0x7d,0xcd,0xb5,0x89,0x95,0xba,
3166
0x56,0x7c,0x27,0xcc,0x80,0x62,0x15,0xdd,0x6b,0x9f,0xde,0x75,0x6b,0xef,0x39,0x18,
3167
0xef,0xf9,0xb1,0x5a,0x96,0x3d,0xd5,0xb2,0xc7,0x5b,0xed,0x69,0xdc,0x89,0x6a,0x57,
3168
0xcf,0xee,0xf9,0x27,0x5b,0xfe,0xc9,0xd6,0xb3,0x68,0xc9,0x6a,0x7f,0xcf,0xee,0x85,
3169
0x4f,0x51,0x9f,0xf0,0xec,0x9e,0x7f,0x6d,0x6b,0xdf,0xda,0x56,0x98,0xda,0xea,0x3b,
3170
0x9e,0xdd,0x0b,0xef,0xb5,0xc3,0xc9,0xe8,0x60,0x91,0x69,0x69,0xa8,0xdd,0xe3,0x12,
3171
0x8b,0x4c,0x4b,0xbd,0x76,0x6e,0xac,0x7b,0x0a,0x2d,0x55,0x7f,0xa7,0x62,0xb8,0x45,
3172
0x6f,0x4b,0x43,0xed,0x1e,0x23,0x2d,0x7a,0x5b,0xda,0x5b,0x7d,0xab,0x9b,0xda,0xad,
3173
0x9f,0xda,0xc2,0xab,0xfb,0x1c,0x06,0x6f,0x6d,0xf3,0x4c,0x84,0xf4,0x2e,0xe9,0x26,
3174
0xe9,0xdb,0xd2,0xcd,0xd2,0xb0,0x8a,0xae,0x16,0x90,0x16,0x92,0x46,0x4b,0x2b,0x49,
3175
0xab,0x57,0xfc,0xff,0xc4,0x9e,0x84,0x7a,0x0a,0xdf,0x58,0x1a,0x94,0x36,0x93,0x9a,
3176
0x71,0x6d,0x34,0x5b,0xee,0x96,0xd2,0x7a,0xf2,0x6f,0x20,0xbd,0x4a,0xfe,0xdd,0xa5,
3177
0x83,0xa5,0x43,0xa4,0xc3,0xa5,0x23,0xa4,0xa3,0xa5,0xd7,0x48,0xc7,0x4b,0x27,0x48,
3178
0x6f,0x94,0x4e,0x92,0x3e,0x22,0x9d,0x25,0x9d,0x2d,0x9d,0x23,0x1d,0x23,0xbd,0x56,
3179
0x3a,0x55,0x7a,0x87,0x74,0x81,0x74,0xa1,0xf4,0x39,0xe9,0x22,0xaf,0x3e,0x69,0x94,
3180
0xa8,0xb8,0xd3,0x9b,0xf3,0xec,0xf1,0x14,0x6f,0xcd,0x93,0xf1,0xce,0xf1,0xf1,0xe4,
3181
0x3d,0xd7,0xe9,0x8d,0x17,0x6f,0x7c,0x78,0x63,0xd4,0xeb,0xff,0xa9,0xda,0x37,0x4e,
3182
0xf3,0x67,0xbc,0xe6,0xd0,0xaa,0xf2,0xf7,0xec,0x89,0x96,0x3d,0xc9,0xb2,0x27,0x5b,
3183
0xf6,0x14,0xcb,0x5e,0xcb,0xb2,0xd7,0xb6,0xec,0xa9,0x96,0xdd,0x2b,0x87,0xed,0x8e,
3184
0x0f,0x71,0x27,0x84,0xb8,0x13,0x43,0xdc,0x49,0x21,0xee,0xe4,0x10,0x77,0x4a,0x88,
3185
0xbb,0x56,0x88,0xbb,0x76,0x88,0x3b,0x35,0xa4,0xfc,0x5e,0xfe,0xe2,0x75,0xdc,0x4c,
3186
0x90,0x26,0x4a,0x93,0xa4,0xc9,0xd2,0x14,0x69,0x2d,0x69,0x6d,0x69,0xaa,0xd4,0x2b,
3187
0x73,0xac,0x55,0xde,0x58,0xab,0xac,0xb1,0x56,0x39,0x63,0xad,0x32,0xc6,0x5a,0xe5,
3188
0x8b,0xb5,0xca,0x16,0x6b,0x95,0x2b,0xd6,0x2a,0x53,0xac,0x55,0x9e,0x58,0xab,0x2c,
3189
0xb1,0x2a,0x5b,0xb6,0x55,0xce,0xae,0x96,0xbd,0x9b,0x65,0xbf,0xca,0xb2,0x77,0xb7,
3190
0xec,0x3d,0x2c,0x7b,0x4f,0xcb,0xde,0xcb,0xb2,0xf7,0xb6,0xec,0x57,0x5b,0xf6,0x3e,
3191
0x96,0xbd,0xaf,0x65,0xef,0x67,0xd9,0xfb,0x5b,0xf6,0x01,0x96,0x7d,0xa0,0x65,0x1f,
3192
0x64,0xd9,0x07,0x5b,0xf6,0x21,0x96,0x7d,0xa8,0x65,0x1f,0x66,0xd9,0x87,0x5b,0xf6,
3193
0x11,0x96,0x7d,0xa4,0x65,0x1f,0x65,0xd9,0x47,0xcb,0xde,0xc8,0x39,0x7e,0x3c,0x6d,
3194
0x62,0x1d,0x4f,0x4f,0xe7,0xbe,0xb0,0x7d,0x3c,0x6f,0x6b,0xdd,0x1b,0xee,0xa0,0xfb,
3195
0xc3,0xe6,0x38,0xd1,0x49,0xc7,0xf1,0x6c,0xb5,0x49,0x37,0xeb,0x58,0xdb,0x43,0x75,
3196
0xdd,0xcb,0x3a,0xee,0x86,0xae,0x67,0x06,0xa8,0x8e,0x06,0xa9,0x4e,0x86,0x58,0xf7,
3197
0x8a,0x87,0xab,0xac,0x23,0xad,0x75,0x8e,0xe9,0x0f,0xa1,0x73,0x74,0x1d,0xc7,0xa5,
3198
0xfe,0x29,0xf8,0xb0,0x9a,0x3b,0x5f,0x5d,0xad,0xbc,0x67,0xc7,0x38,0xce,0x46,0x32,
3199
0xf2,0xf0,0xc3,0x6e,0x61,0xab,0x42,0x0a,0x34,0x84,0x4e,0x30,0x11,0x6e,0x85,0x19,
3200
0xf0,0xa2,0xf1,0xa7,0x12,0xba,0x43,0x1f,0x18,0x0f,0x77,0xc3,0x1c,0xd8,0x01,0x5f,
3201
0xab,0x82,0xee,0x87,0xa3,0x50,0x92,0x8a,0x3a,0x0f,0x6a,0x43,0x23,0xb8,0x0c,0x7a,
3202
0xc3,0x78,0x78,0x1e,0xd6,0xc1,0x2e,0x78,0x8f,0x8c,0x94,0xa3,0x12,0xf7,0x53,0x89,
3203
0x7e,0x2a,0xb1,0x20,0x94,0x84,0x2a,0x30,0x04,0xb2,0x3a,0x3b,0xce,0x58,0xf8,0x06,
3204
0x8a,0x5c,0xe6,0x38,0x15,0xa1,0x36,0xf4,0x87,0x41,0xb0,0xed,0x72,0xc7,0xf9,0x04,
3205
0x0e,0xc3,0x0f,0x30,0xf8,0x0a,0xea,0x07,0xae,0x87,0xaf,0xe0,0x07,0x28,0x74,0x25,
3206
0xe7,0x11,0x90,0x05,0xd9,0x30,0x04,0x5e,0x86,0x02,0x34,0x54,0x0a,0xb4,0x80,0x9a,
3207
0x34,0x54,0x12,0x4c,0x82,0x7b,0xe0,0x31,0x58,0x02,0x3b,0xe0,0x13,0x38,0x44,0x23,
3208
0x16,0xa0,0x11,0xab,0x42,0x79,0xea,0xac,0x2b,0x8c,0x82,0x85,0xb0,0x01,0xde,0x86,
3209
0x6d,0x50,0x84,0x46,0x2d,0x01,0x49,0xd0,0x87,0x06,0xad,0x46,0x63,0xa6,0x40,0x5d,
3210
0x68,0x08,0x19,0xd0,0x09,0x3a,0xc3,0xd3,0x70,0x03,0x0d,0x7d,0x13,0xe4,0xd2,0xd8,
3211
0x7b,0xe0,0x5c,0x1a,0xbc,0x1c,0x54,0x85,0x38,0xb8,0x05,0xee,0x80,0xe1,0x74,0x82,
3212
0x6b,0xe1,0x59,0x58,0x01,0x5f,0xc0,0x36,0x3a,0xc5,0x4e,0x38,0x02,0x75,0xe8,0x18,
3213
0x2f,0xc0,0x72,0x18,0x4a,0x07,0xd9,0x00,0x47,0x61,0xc8,0x18,0xea,0x0e,0x52,0xae,
3214
0xa7,0x0f,0xc3,0xcd,0xb0,0x0c,0x7c,0x63,0x1d,0xa7,0x30,0x9c,0x05,0x89,0x70,0x3d,
3215
0xdc,0x04,0xbb,0xc6,0x39,0xce,0x3e,0x38,0x02,0xc7,0xa0,0xf0,0x78,0xc7,0x29,0x0d,
3216
0xe5,0xa0,0x3f,0x0c,0x86,0x91,0xd0,0xf2,0x46,0xca,0x07,0x69,0x93,0x19,0x2f,0xd0,
3217
0x0d,0xae,0xbb,0x89,0xfc,0xc2,0x66,0x70,0x6e,0x66,0x5e,0xbb,0x95,0x31,0x06,0xed,
3218
0x61,0x24,0x3c,0x08,0x57,0xdd,0x46,0x3f,0x87,0x85,0x30,0xe7,0x76,0xc7,0x59,0x0f,
3219
0xf7,0x4f,0x61,0xbd,0x0d,0x8b,0x60,0x6a,0x0e,0x63,0x71,0xaa,0xe3,0xac,0x81,0xd7,
3220
0xe1,0x2d,0x18,0x31,0x8d,0x3e,0x00,0xe7,0xdf,0x4d,0xdf,0x81,0x25,0xb0,0x17,0xda,
3221
0xdc,0xe3,0x38,0x57,0x40,0x57,0xe8,0x0d,0x1b,0xe0,0x00,0x1c,0x01,0xdf,0xbd,0x1c,
3222
0xef,0x61,0x1b,0x6c,0x87,0xbb,0xa7,0x73,0x5e,0x0a,0x4f,0xc3,0xac,0xfb,0x1c,0x67,
3223
0x2b,0x6c,0x87,0x4a,0xf7,0xd3,0xf6,0x90,0x00,0xf5,0xe0,0x52,0xf8,0xe4,0x01,0xc6,
3224
0xdd,0x43,0xd4,0x09,0x3c,0x0e,0x2f,0xc1,0xcb,0xb0,0x11,0xde,0x82,0xa3,0xf0,0x3d,
3225
0x9c,0xc9,0xb8,0x29,0x0e,0xe5,0xa1,0x2e,0x34,0x87,0x8b,0xe1,0x36,0x78,0x00,0x66,
3226
0x3c,0xec,0x9e,0x47,0x9d,0x15,0xe7,0x8e,0x81,0x26,0x10,0x84,0x16,0xb8,0xa7,0x43,
3227
0x4b,0x69,0x6b,0x69,0x1b,0x69,0x5b,0x69,0x7b,0x69,0x47,0x69,0x27,0x69,0x67,0xe9,
3228
0xe5,0xd2,0x2b,0xa5,0xd9,0xd2,0xab,0xa4,0x3d,0xa4,0xbd,0xa4,0x03,0x2c,0xbd,0x0f,
3229
0x06,0xcb,0x3d,0x58,0xee,0x61,0x72,0x0f,0x93,0x7b,0xa4,0xdc,0x23,0xe5,0xbe,0x46,
3230
0xee,0x6b,0xe4,0x6e,0x2a,0xb7,0x29,0xa3,0xa7,0xc6,0xff,0x41,0xf9,0x4f,0x86,0x9b,
3231
0x61,0x8e,0xdc,0xcf,0x48,0xe7,0x4a,0xe7,0x4b,0x17,0x4a,0x17,0x49,0x17,0x4b,0x97,
3232
0x48,0x5f,0x92,0x2e,0x93,0xae,0x90,0xae,0x92,0xbe,0x22,0x5d,0x23,0x5d,0x27,0x7d,
3233
0xd3,0x52,0x93,0xaf,0xcd,0x72,0x6f,0x96,0xfb,0x1d,0xb9,0xdf,0x91,0x7b,0xab,0xdc,
3234
0x5b,0xe5,0xde,0x26,0xf7,0x36,0xb9,0x9f,0x90,0xfb,0xa0,0xf4,0x90,0xf4,0xb0,0xf4,
3235
0x4b,0xe9,0xf7,0x56,0xb9,0x4c,0x5e,0x9c,0x62,0xf4,0x47,0x78,0x0a,0xfc,0xf0,0x34,
3236
0x3c,0x03,0x61,0x10,0x0e,0x01,0x98,0x07,0xf3,0x61,0x01,0x2c,0x84,0xe7,0x60,0x11,
3237
0x9c,0x07,0x11,0x10,0x09,0x05,0xa0,0x02,0x44,0x41,0x41,0x28,0x04,0x85,0xe1,0x0c,
3238
0x38,0x13,0x8a,0x40,0x51,0x28,0x06,0x67,0x41,0x36,0x74,0x85,0x6e,0x70,0x15,0x74,
3239
0x87,0x1e,0xd0,0x13,0x7a,0x41,0x6f,0xb8,0x1a,0xfa,0x40,0x5f,0xe8,0x07,0xfd,0x61,
3240
0x00,0x0c,0x84,0x41,0x30,0x18,0x86,0xc0,0x50,0x18,0x06,0x5d,0xa0,0x04,0x94,0x84,
3241
0xb5,0xb0,0x0e,0x5e,0x87,0x37,0x60,0x0b,0xbc,0x07,0xef,0xc3,0xf9,0xf0,0x21,0x6c,
3242
0x87,0x32,0x50,0x16,0xca,0x43,0x45,0x88,0x86,0x2a,0x70,0x21,0x54,0x87,0x1a,0x10,
3243
0x03,0xb1,0x50,0x13,0x12,0x20,0x05,0xd2,0x20,0x03,0x2e,0x82,0xc3,0xf0,0x25,0x74,
3244
0x84,0x4b,0xa0,0x13,0xdc,0x00,0x13,0x61,0x32,0x4c,0x85,0x3b,0xe0,0x2e,0x78,0x08,
3245
0x66,0x16,0x73,0x8f,0x69,0xe6,0xf8,0x15,0x05,0xdb,0x38,0xce,0x14,0x44,0x63,0xa0,
3246
0x10,0x24,0x0c,0x73,0x8f,0x71,0xa5,0xc0,0x07,0x17,0x72,0xac,0x89,0xeb,0xe8,0x1e,
3247
0xe7,0xcc,0xba,0xc1,0xb4,0x99,0xb7,0x86,0xf0,0x5b,0xf6,0x30,0xcb,0x1e,0xb0,0xec,
3248
0x11,0x96,0x3d,0xd2,0xb2,0x47,0x59,0xf6,0x42,0x96,0xbd,0xb0,0x65,0x3f,0xd3,0xb2,
3249
0x17,0xb1,0xec,0x45,0x2d,0x7b,0x31,0xcb,0x7e,0x96,0x65,0x77,0xd4,0xce,0x76,0x5e,
3250
0xb3,0x43,0xf2,0x9b,0x1d,0x92,0xe7,0xec,0x90,0x7c,0x67,0x87,0xe4,0x3d,0x3b,0x24,
3251
0xff,0xd9,0x21,0x65,0xc8,0x0e,0x29,0x47,0x76,0x48,0x59,0xb2,0x43,0xca,0x93,0x1d,
3252
0x52,0xa6,0xec,0x90,0x72,0x65,0x87,0x94,0x2d,0x34,0xfe,0xfe,0x21,0xe9,0xf7,0x56,
3253
0xbf,0x37,0xfd,0x79,0xce,0x49,0xb6,0x9d,0x15,0xb2,0x8f,0xe9,0x07,0x9e,0xfd,0x56,
3254
0xcb,0x1e,0x65,0xd9,0x4d,0xff,0xf0,0xec,0x77,0x59,0xfe,0xfd,0xda,0x58,0x75,0x69,
3255
0xf9,0xf7,0xb1,0xfc,0x2f,0xb7,0xfc,0xcd,0x3c,0xef,0xd9,0xcd,0x7a,0xe1,0xa7,0xf0,
3256
0x03,0xad,0x73,0xb0,0xbe,0xc7,0xed,0x55,0xad,0x30,0xe6,0x58,0xe7,0xd9,0xcd,0x9a,
3257
0xc8,0xb3,0x9b,0xf5,0x87,0x67,0xaf,0xd6,0xcb,0xca,0xbf,0xb5,0x6f,0x83,0x51,0xc7,
3258
0xed,0x67,0xb4,0xb3,0xd6,0xc2,0x83,0x8f,0xdb,0x67,0xde,0x6a,0xe5,0xd9,0x0a,0xff,
3259
0xdc,0xc5,0xc7,0xed,0xbb,0xac,0xb2,0x8c,0xb1,0xe2,0xe9,0xd1,0xd9,0x0a,0x33,0xfc,
3260
0xb8,0xdd,0xd7,0xfa,0xb8,0x7d,0xad,0x15,0x7f,0x3b,0xab,0x1e,0xfa,0x59,0x69,0x15,
3261
0xb3,0xc2,0x9b,0x75,0x86,0x67,0x3f,0x22,0x7b,0x6b,0x16,0xd6,0x63,0xae,0x70,0xd7,
3262
0x61,0x53,0xae,0x71,0xd7,0xde,0xde,0x35,0xb3,0x04,0xeb,0x5c,0x2b,0xc1,0x3a,0xd7,
3263
0x4e,0xd0,0x79,0x56,0x82,0x73,0xfc,0x3a,0x54,0x8a,0xb4,0x96,0xb4,0xb6,0x34,0x55,
3264
0xfb,0xc4,0x59,0xe7,0xdb,0x89,0x56,0x5c,0x89,0xd6,0xf9,0x7b,0xa2,0xe2,0x73,0x34,
3265
0x6f,0x87,0x69,0xae,0xf6,0xe6,0xe3,0x28,0x6b,0x0e,0x3e,0xd9,0xfc,0xeb,0x8d,0x4d,
3266
0x6f,0x4c,0x7a,0x63,0xd1,0x1b,0x83,0xde,0xd8,0xf3,0xc6,0x9c,0x37,0xd6,0xbc,0x31,
3267
0xe6,0x8d,0x2d,0x6f,0x4c,0x79,0x63,0xc9,0x1b,0x43,0xde,0xd8,0x39,0x2b,0x24,0xdc,
3268
0x62,0xa5,0xed,0x8d,0x93,0xfe,0x8a,0x73,0xa8,0xb4,0xff,0x49,0xe6,0x46,0xd3,0xe7,
3269
0x4d,0x5f,0x37,0x7d,0xdc,0xf4,0x6d,0xd3,0xa7,0x4d,0x5f,0x36,0x7d,0xd8,0xf4,0x5d,
3270
0xd3,0x67,0x4d,0x5f,0x35,0x7d,0xd4,0xf4,0x4d,0xd3,0x27,0x4d,0x5f,0x34,0x7d,0xd0,
3271
0xf4,0x3d,0xd3,0xe7,0x4c,0x5f,0x33,0x7d,0xcc,0xf4,0x2d,0xd3,0xa7,0xb6,0xa2,0xb5,
3272
0x86,0xb9,0xeb,0xf8,0xde,0xac,0xeb,0xaa,0x11,0xef,0x40,0xe2,0xdc,0x4b,0x5c,0x81,
3273
0x7b,0xdd,0xbe,0x30,0x1d,0xbf,0x6e,0x7d,0x4e,0x9c,0x9b,0xf7,0xb0,0x8e,0x3f,0x42,
3274
0xb8,0xba,0x70,0x4f,0x67,0xb7,0xef,0x99,0x3e,0x67,0xfa,0x9a,0xe9,0x63,0xa6,0x6f,
3275
0x9d,0xdf,0xc9,0x6d,0x9f,0x14,0xb5,0x53,0x2d,0xa9,0x77,0xfd,0x30,0x55,0x6d,0x18,
3276
0x67,0x5d,0x4f,0x49,0xb2,0xfa,0x8a,0xd7,0xc6,0x49,0xd6,0xb5,0x9a,0x24,0xc5,0x97,
3277
0xa4,0xf8,0x92,0x14,0x5f,0x92,0xe2,0x4b,0xb6,0xae,0xdd,0x98,0x7a,0x49,0x90,0x26,
3278
0x4a,0x93,0xa4,0xc9,0xd2,0x14,0x69,0x2d,0x69,0x6d,0x69,0xaa,0xd4,0xbb,0x9e,0xe0,
3279
0xd9,0xe3,0x2d,0xbb,0x17,0x77,0x33,0x9d,0x3b,0x76,0xd7,0x79,0xa1,0x67,0xef,0x60,
3280
0x5d,0x43,0x36,0xe7,0xb3,0x8f,0x10,0xd1,0x63,0x5a,0xa3,0xcc,0x82,0xa7,0xb4,0xee,
3281
0x7a,0x46,0xeb,0xad,0xf9,0x5a,0x8f,0x2c,0xd2,0xfa,0x6a,0x89,0xd6,0x55,0xcb,0xb4,
3282
0x9e,0x5a,0xa5,0x75,0xd4,0x1a,0xad,0x59,0xd6,0xc3,0x06,0x78,0x1d,0x36,0xc2,0x1b,
3283
0x5a,0x47,0x6d,0xd6,0x7a,0x69,0xab,0xd6,0x45,0x1f,0xc1,0x76,0xd8,0x01,0x1f,0xc3,
3284
0x4e,0xd8,0x0d,0x7b,0x60,0x2f,0x7c,0x06,0xfb,0x60,0x3f,0x7c,0x0e,0x07,0xb4,0x7e,
3285
0x3a,0xa4,0x75,0x93,0x59,0x33,0xed,0x36,0x7d,0xb1,0x9d,0x5b,0x06,0x6f,0xad,0x76,
3286
0x4c,0xf9,0x78,0x44,0xfb,0x9a,0x34,0x67,0xca,0x7d,0xc4,0x5a,0xa3,0x3d,0x22,0x8e,
3287
0x29,0xdc,0x63,0xca,0xf7,0x11,0x6b,0x9d,0xf9,0x98,0xdc,0xab,0x54,0x3f,0xb3,0xe5,
3288
0x9e,0xa5,0x7a,0x98,0x6b,0xa5,0x37,0x5d,0xfe,0xc7,0x54,0x7f,0xc7,0x54,0x97,0x47,
3289
0x14,0xf6,0x29,0xf9,0xed,0xd0,0xf6,0xc7,0x54,0xbe,0x39,0x2a,0xeb,0xcb,0x8a,0x67,
3290
0x8e,0xca,0xba,0xcf,0x8a,0x6b,0xba,0xfc,0x8e,0x58,0xee,0x23,0xaa,0x43,0x6f,0x6d,
3291
0x1c,0xba,0x56,0xde,0xa0,0xfd,0x8d,0xfb,0x13,0x2b,0x3e,0x6f,0xfb,0x7e,0x6b,0x3d,
3292
0xec,0xf9,0x1f,0xb0,0xd4,0xab,0x83,0xcf,0x94,0x67,0xcf,0xff,0x63,0xab,0xcc,0xfb,
3293
0x2d,0xff,0x83,0x56,0x19,0x42,0xf7,0x0d,0x75,0xaf,0xb3,0xea,0x79,0xbf,0xb5,0x4e,
3294
0x7f,0xcc,0x4a,0xfb,0x80,0xd2,0xd9,0xa8,0x3e,0x78,0x4c,0xf5,0xb8,0x50,0xfb,0xac,
3295
0x97,0xfd,0x98,0xb5,0xce,0x5e,0xa4,0x38,0xbc,0x78,0x17,0x59,0xed,0xe7,0xd5,0xfd,
3296
0x62,0xd5,0x85,0xdd,0xce,0x2f,0x59,0xe1,0x3c,0xfb,0xba,0x90,0xfa,0x59,0x62,0x9d,
3297
0x27,0x2c,0xb6,0xda,0x7c,0xbf,0x55,0x9e,0xf5,0xea,0xef,0x6f,0x58,0x75,0xf1,0xa6,
3298
0xf2,0xf4,0x4a,0x48,0x1f,0xb5,0xd3,0xb1,0xfd,0x5f,0xb1,0xce,0x3f,0x8e,0xa9,0xef,
3299
0xef,0xb7,0xce,0x3d,0x1e,0x51,0x5e,0xd6,0x85,0xf8,0xcf,0x0d,0x71,0x2f,0xb4,0xce,
3300
0x5b,0xec,0x71,0x60,0xf7,0x35,0xef,0x1c,0xe6,0x51,0xab,0x4d,0xbd,0x73,0x9b,0x97,
3301
0x55,0xce,0x27,0xad,0xfd,0x3f,0xb3,0xc6,0xd0,0x5c,0xd5,0x8f,0x37,0x7e,0xbc,0x71,
3302
0xb5,0xcc,0xb2,0x6f,0x50,0x1e,0xb6,0x2a,0xcc,0x2b,0xd6,0x36,0x6f,0x5c,0x6c,0xb5,
3303
0xca,0xbe,0xd8,0x3a,0x8f,0xf2,0xca,0xbf,0xc2,0x6a,0xdf,0xc7,0xac,0x3a,0xdb,0x16,
3304
0x52,0xff,0xdb,0xb4,0x6d,0x9b,0x15,0xff,0x3a,0xeb,0x3c,0xcc,0xcb,0xa7,0x67,0xf7,
3305
0xc6,0xcf,0x63,0x56,0x7f,0xf3,0xdc,0xfb,0x65,0x7f,0x59,0x6d,0xf1,0x91,0xfc,0xe6,
3306
0xca,0x7e,0x44,0x79,0xfd,0x54,0xf6,0xed,0x56,0x1c,0x9e,0x7b,0x9f,0xa5,0x76,0x7b,
3307
0xee,0xd7,0x18,0xf2,0xc6,0xab,0x6d,0xf7,0xfa,0x51,0xe8,0x18,0xdb,0x1d,0x32,0xcf,
3308
0xec,0xb6,0xe2,0xda,0x63,0xcd,0x6d,0xfb,0xac,0xb6,0xdd,0x2f,0xf7,0x67,0x21,0xfd,
3309
0xc2,0xdb,0xef,0x98,0xd5,0xd6,0xde,0x1c,0xbb,0x43,0xea,0xd5,0xdd,0x7c,0x6b,0xae,
3310
0xb1,0xc7,0xb7,0x39,0xf6,0x2c,0x19,0xe8,0x1e,0x6f,0x8c,0x26,0x48,0x13,0xa5,0x49,
3311
0xd2,0x64,0x69,0x8a,0xb4,0x96,0xb4,0xb6,0x34,0xd5,0x8a,0xc7,0x8e,0x33,0xde,0xb2,
3312
0x27,0x58,0xf6,0x44,0xcb,0x9e,0x64,0xd9,0x93,0x2d,0x7b,0x8a,0x65,0xaf,0x65,0xd9,
3313
0x6b,0x5b,0xf6,0x54,0x2b,0xdf,0x71,0x96,0xdd,0x2e,0x4f,0x82,0x65,0x4f,0xb4,0xec,
3314
0x5e,0xba,0xbd,0x74,0x7d,0x37,0x5b,0xd7,0x6b,0xb3,0x75,0xad,0xb8,0xbd,0xae,0xe3,
3315
0x66,0xeb,0xb8,0x3b,0x40,0xc7,0xdc,0x81,0x21,0xf7,0xe3,0x3c,0x4d,0xb0,0xec,0x89,
3316
0xba,0x9e,0x6c,0xe2,0x18,0xc2,0x5a,0xb6,0x28,0x11,0xc5,0xf4,0x70,0x8f,0x71,0xe6,
3317
0xba,0xa6,0x59,0xef,0x9c,0x89,0xfb,0xa5,0xbe,0xee,0x1a,0xaa,0xc8,0x95,0x9c,0xe7,
3318
0xb7,0x76,0xd7,0x51,0x03,0x95,0x7e,0x7f,0xe9,0x52,0x3d,0xf3,0xdc,0x4f,0xee,0x3e,
3319
0xd2,0x16,0xba,0x9e,0xdd,0x52,0x9a,0x21,0xf5,0xee,0x77,0xf7,0x55,0x58,0xdb,0x3d,
3320
0x50,0xd7,0xbc,0xfb,0x4b,0x97,0x86,0x1d,0xd7,0x9e,0x4a,0xc3,0x7b,0x87,0xc9,0xbb,
3321
0xef,0x3d,0x5a,0x6e,0xcf,0xde,0xd2,0xb2,0x67,0x58,0xf6,0x76,0x96,0x7d,0x69,0xd8,
3322
0xf1,0x6b,0xdb,0x7d,0x55,0x2f,0x7d,0xad,0x6b,0xde,0x3d,0xac,0xeb,0xde,0xfd,0x14,
3323
0xbe,0x9f,0x73,0x9c,0x6e,0xd2,0x3e,0xce,0x89,0xfe,0x09,0xd6,0xb6,0x04,0x4b,0xfb,
3324
0x84,0xf8,0x79,0x6d,0xd0,0xcd,0xb2,0x7b,0xda,0x27,0xc4,0xaf,0x64,0x45,0xf7,0x5a,
3325
0xbb,0x6d,0x4f,0xb0,0xfa,0x44,0x1f,0xcb,0xde,0xd2,0xb2,0x67,0x58,0xf6,0xc1,0x56,
3326
0xff,0xb1,0xed,0x5e,0x7c,0x27,0xf3,0x4b,0xb0,0x9e,0x61,0xe8,0x2f,0x5d,0x1a,0x76,
3327
0x3c,0x2f,0x43,0xb4,0xbd,0x83,0xb6,0x77,0xd0,0xf6,0x0e,0xda,0xde,0x41,0x79,0xeb,
3328
0xa0,0x7c,0x79,0x7d,0xb3,0xa3,0xc2,0x77,0x54,0xf8,0x8e,0x0a,0xdf,0x51,0xe1,0x3b,
3329
0x2a,0xbc,0xe7,0x9e,0xad,0x77,0x6d,0x66,0xeb,0x79,0xfa,0x58,0x85,0x8f,0x55,0x7f,
3330
0x1a,0xa4,0x7a,0xec,0x66,0xf5,0xfb,0xc6,0x2a,0x87,0xd7,0x4f,0x1a,0x6b,0x7c,0xc4,
3331
0x6a,0xbb,0xd7,0x1f,0x47,0xe9,0x9e,0x47,0xb6,0xfa,0x46,0x96,0xee,0x7f,0xf4,0x57,
3332
0xff,0xf5,0x68,0xa9,0xbc,0x0c,0x75,0x4e,0xec,0x37,0xfd,0xa5,0x03,0x94,0x4e,0x5f,
3333
0xdd,0x03,0xe9,0xa7,0xb1,0xd9,0xcf,0xba,0x47,0xde,0x4f,0xe1,0xfa,0x2a,0x9d,0x66,
3334
0xaa,0x0f,0xbb,0x3c,0x59,0xc2,0x6b,0x47,0xef,0x59,0x91,0xc1,0xba,0xaf,0x33,0x5c,
3335
0xf5,0xd2,0x55,0xf5,0x69,0xca,0xe8,0x8d,0x3b,0xcf,0x1e,0xaf,0xf3,0xf1,0x04,0x69,
3336
0xa2,0x34,0x49,0x9a,0x2c,0x4d,0x91,0xd6,0x92,0xd6,0x96,0xa6,0x4a,0xbd,0xb9,0xd2,
3337
0xb3,0xc7,0x5b,0xf6,0x04,0xcb,0x9e,0x68,0xd9,0x93,0x2c,0x7b,0xb2,0x65,0x4f,0xb1,
3338
0xec,0xb5,0x2c,0x7b,0x6d,0xcb,0x9e,0x6a,0xe5,0x3b,0xce,0xb2,0xdb,0xe5,0x49,0xb0,
3339
0xec,0x89,0x96,0x3d,0xc9,0xb2,0x27,0x5b,0xf6,0x14,0xcb,0x5e,0xcb,0xb2,0xd7,0xb6,
3340
0xec,0xa9,0x56,0x3d,0xc5,0x59,0x76,0x2f,0xdd,0x9e,0xd6,0xfc,0xd4,0x3c,0x9c,0x73,
3341
0x1a,0x18,0xf0,0xa4,0xdb,0x1e,0x8d,0x35,0x4f,0x99,0x5b,0x4b,0x95,0x7d,0xf8,0x41,
3342
0x15,0xb6,0xd5,0x9a,0x43,0x7f,0xf1,0xd3,0x7e,0xe8,0x6d,0x68,0x33,0xce,0x09,0xbf,
3343
0xea,0xe1,0xde,0x4b,0x58,0x87,0xfd,0x2d,0x3a,0x4e,0x02,0xe7,0x14,0x9f,0xb4,0x75,
3344
0xaf,0xc3,0x1b,0xda,0x74,0x72,0xcf,0x5d,0x27,0x31,0x29,0x37,0xc3,0xfe,0x2f,0x12,
3345
0xed,0x4d,0x83,0x4f,0xbc,0xde,0x71,0x1a,0xde,0xe8,0x38,0x2f,0x4e,0x72,0x9c,0x6f,
3346
0x26,0x3b,0xce,0x14,0xce,0x53,0xfd,0x57,0x3b,0x4e,0x69,0x1a,0xfb,0x7d,0x3a,0xd0,
3347
0x47,0x74,0x90,0xfa,0x37,0x38,0xce,0xd5,0xec,0x7b,0x78,0xba,0xe3,0x8c,0x27,0xde,
3348
0x61,0xc4,0x1b,0x4e,0x87,0x2d,0x4d,0xc7,0x89,0x61,0xdf,0xb2,0x0f,0xd1,0x9f,0x38,
3349
0x67,0xdd,0x4f,0x07,0xdc,0x38,0x91,0x31,0x70,0x93,0xe3,0xbc,0x46,0x27,0xda,0x3a,
3350
0x8e,0x73,0x65,0xe2,0x5c,0xcf,0x31,0xe0,0x1c,0x0a,0x7a,0x35,0x71,0x1e,0x63,0x9f,
3351
0x37,0x48,0xe3,0x46,0xe6,0xfb,0xc5,0x14,0xec,0x23,0x3a,0xe1,0x2b,0x0c,0x9a,0x2d,
3352
0xa4,0x59,0x94,0x6d,0x9f,0x0e,0x77,0xef,0xcd,0x44,0x10,0xef,0x65,0x70,0xf0,0x36,
3353
0xca,0x72,0x0f,0x75,0x72,0xbf,0xe3,0x7c,0xfb,0x20,0xc7,0x10,0x06,0xc0,0xf5,0x0c,
3354
0xac,0x19,0xd7,0x92,0xc6,0x04,0xf2,0x71,0xa7,0x7b,0x9f,0xe2,0xdd,0x9b,0x59,0xa7,
3355
0x5c,0x82,0x9b,0x63,0x49,0x97,0x31,0x8e,0x73,0x1d,0x71,0x74,0x25,0xbe,0xf5,0x84,
3356
0x5f,0x4d,0x9d,0xfc,0xfb,0x6e,0xf2,0xc3,0xf6,0xae,0x97,0x39,0x4e,0x71,0xd2,0xfa,
3357
0x80,0xbc,0x14,0x21,0xbf,0x35,0x89,0xa7,0xd6,0x75,0x8c,0x43,0xb6,0x6f,0x26,0x2f,
3358
0xb7,0xb0,0x5f,0x2e,0xf9,0x7a,0x1d,0xce,0x67,0x32,0x5f,0xce,0xf6,0xc3,0xa4,0x33,
3359
0x8c,0xed,0x63,0x6f,0x61,0x0d,0xd4,0xd5,0xad,0x9f,0x1f,0x48,0x2f,0x95,0xba,0xf8,
3360
0x94,0x73,0xf3,0xb3,0xba,0x50,0xaf,0xd4,0xd3,0x40,0xce,0xf5,0xcf,0xa1,0x6e,0xbe,
3361
0x23,0xcd,0x15,0x94,0x6f,0x36,0x79,0x39,0x83,0x30,0xaf,0xd3,0xb8,0x23,0x69,0xeb,
3362
0x8a,0xc4,0xf5,0x32,0xdb,0xaf,0x20,0x1f,0xbe,0x11,0x1c,0x23,0xa9,0xd7,0xa7,0x88,
3363
0xe7,0xc5,0x3e,0xee,0xfd,0x9f,0xc9,0x84,0xfb,0x81,0xf8,0x3f,0x19,0x4f,0xf9,0x98,
3364
0x6c,0xba,0x13,0xdf,0xb3,0xec,0xdf,0x9b,0xbc,0xbc,0x06,0xe3,0x98,0x4c,0x3e,0xa5,
3365
0x6c,0x03,0xd8,0xbe,0x99,0xfd,0xde,0xa4,0x4d,0xbe,0x26,0xcf,0xe9,0xed,0xdc,0x6b,
3366
0x0c,0x9f,0x53,0xcf,0xaf,0x92,0xce,0x0f,0x94,0xab,0x1a,0x75,0xf4,0xcc,0x34,0xea,
3367
0xfc,0x3e,0xc7,0xb9,0x87,0xfa,0x79,0xe3,0x21,0xf7,0xde,0xe4,0x1a,0xfa,0xc9,0x08,
3368
0x73,0xff,0x8e,0xf4,0x86,0x12,0x3e,0x47,0x37,0x6c,0xef,0xa3,0x0d,0xa2,0xd9,0x2f,
3369
0x93,0x09,0xef,0x26,0x26,0xa2,0xf5,0xec,0xff,0x15,0xf9,0x1d,0x40,0x7d,0x54,0x26,
3370
0xec,0x17,0xe4,0x35,0x9a,0x76,0x6b,0x4e,0x7d,0x9f,0x43,0x3c,0x8f,0xc2,0x32,0xd2,
3371
0x5d,0x47,0x1f,0x59,0x3d,0xd9,0x2d,0xc7,0x6b,0xc4,0xf7,0x35,0x65,0xbe,0x86,0xbc,
3372
0x3f,0x4b,0x1a,0x0d,0xc8,0xeb,0xb0,0x21,0xee,0xf9,0xed,0xd1,0x0e,0x6e,0x5d,0xbd,
3373
0x48,0x3f,0x39,0x9f,0xfa,0x5a,0x80,0x7f,0x6f,0xd2,0xb9,0x8f,0xfe,0xd7,0x94,0x34,
3374
0x92,0xee,0xa0,0x4f,0x52,0xc7,0xcd,0x68,0xeb,0x73,0xef,0xa5,0x1d,0xa8,0xbf,0x67,
3375
0xcd,0x75,0x14,0xca,0xf8,0x02,0xfe,0x1f,0xb3,0xcf,0x8d,0xc4,0xf3,0x01,0x13,0xd7,
3376
0x17,0xc4,0xd3,0x90,0x76,0x9c,0xde,0xdd,0x6d,0x8b,0x37,0xc8,0x73,0x3a,0xfd,0xe6,
3377
0x18,0x79,0x1c,0x93,0xe3,0xde,0x7f,0x9a,0x4c,0x39,0x63,0xd9,0xef,0x26,0xf2,0x79,
3378
0x0d,0x7d,0xef,0x08,0x34,0xa2,0xcd,0x1f,0x60,0x6c,0x44,0x91,0x6e,0x27,0xea,0xb6,
3379
0x0f,0xed,0x54,0x94,0x32,0x5e,0x71,0xaf,0x7b,0xed,0x27,0x96,0x7a,0x18,0xc9,0x3e,
3380
0xd5,0x49,0xa3,0x14,0xf9,0xdc,0x47,0xf8,0x6a,0x94,0xfd,0x16,0xca,0xd4,0x84,0x7a,
3381
0x3a,0xa7,0x97,0xdb,0xce,0x37,0x12,0xe6,0x42,0xe2,0x2d,0x42,0xf9,0xbb,0x9b,0xfe,
3382
0x44,0x5a,0xad,0x88,0x7f,0x16,0xdb,0x3f,0xa1,0x0d,0x23,0x88,0x7f,0x27,0xf1,0x8f,
3383
0xa2,0x6c,0x6f,0x52,0x37,0x1f,0x4f,0x76,0xef,0xe5,0xed,0x64,0xbf,0x86,0xb4,0xff,
3384
0x8b,0xe4,0xa1,0x0c,0xfb,0x6e,0x22,0xdf,0xf7,0x12,0xf6,0x5b,0xc6,0xcc,0xa3,0x6c,
3385
0xeb,0xf8,0x80,0xe3,0x3c,0x4c,0x3b,0xdd,0x43,0x5c,0x1b,0x48,0x7b,0xef,0x38,0xf7,
3386
0x3e,0x66,0xf9,0x6b,0x1c,0xe7,0x0e,0xea,0x72,0x25,0xfd,0x79,0x3a,0xf5,0x7d,0x09,
3387
0xfd,0x70,0xa5,0xb9,0x57,0x4d,0xbf,0xac,0x43,0x3e,0x22,0xe1,0x09,0xea,0x7e,0x0b,
3388
0xf9,0x7f,0x97,0x70,0x13,0xa9,0x9f,0xb2,0xec,0xff,0x1c,0xf9,0xaa,0x3b,0xc5,0xbd,
3389
0x3f,0xd9,0xf2,0x6e,0xf7,0xde,0xe4,0x16,0xc2,0xa5,0x51,0xd6,0x95,0xcc,0x03,0x97,
3390
0xd2,0x0f,0x87,0x12,0xe6,0x23,0xdc,0xd5,0x28,0xd7,0x7a,0xea,0xb0,0x1e,0x75,0x7e,
3391
0x05,0x74,0x87,0x29,0xd0,0x81,0xf6,0x58,0x3e,0xc6,0xbd,0x67,0x7a,0x16,0xe3,0xf1,
3392
0x1b,0xda,0xb9,0x36,0x75,0xfc,0x3d,0x1c,0xa4,0xde,0x8e,0x41,0x55,0xe6,0x85,0xe7,
3393
0x18,0x9b,0x1f,0xe1,0xb7,0x98,0x74,0x9e,0xa5,0xed,0x3e,0xa5,0x0e,0x5b,0x9a,0x7e,
3394
0x4b,0xde,0x76,0x43,0x1b,0xca,0xfd,0x20,0x69,0x46,0xd0,0x0f,0x7a,0x41,0x1a,0x69,
3395
0xcf,0x82,0xab,0x74,0x2f,0xfb,0x2e,0xda,0xb7,0x17,0x75,0x7c,0x3b,0x7c,0x09,0xad,
3396
0x69,0xdb,0x9d,0x30,0x95,0xfc,0x4d,0xa4,0x5e,0x47,0x50,0x9e,0xf3,0xa8,0xb7,0x8a,
3397
0xf4,0xd1,0xfe,0xd4,0x5b,0x75,0xea,0xa2,0x22,0x75,0x37,0x75,0xa4,0xbb,0x6e,0xcc,
3398
0x84,0x66,0x90,0x65,0xf2,0x3c,0xca,0xbd,0x06,0x77,0x1b,0xdc,0x0e,0x69,0xd4,0xe1,
3399
0x38,0x58,0x79,0x8d,0xdb,0xa7,0xa3,0x18,0xef,0x8d,0x60,0x30,0x65,0x0a,0xd0,0xf7,
3400
0x0e,0x50,0xcf,0xa3,0xc6,0xbb,0x74,0xa4,0x0f,0x15,0xa5,0x9e,0xee,0x06,0x1f,0xf5,
3401
0x9c,0x0a,0x5b,0x98,0x3f,0x0a,0x30,0x0f,0x3d,0x3f,0xc5,0x2d,0xfb,0x2e,0xca,0xf8,
3402
0x23,0xf5,0x52,0x97,0xb2,0x0f,0x23,0xdf,0x5f,0xa4,0xfb,0x9d,0x73,0xd9,0xb7,0x32,
3403
0x6d,0xb2,0x88,0x32,0xf7,0x82,0xb1,0xd4,0x41,0xd0,0x28,0xac,0xa5,0xfc,0xdf,0x5e,
3404
0xec,0x96,0xbf,0x3d,0x4c,0x87,0x9d,0xaa,0xff,0x85,0xd0,0x84,0xb1,0xdb,0x0e,0xba,
3405
0x5e,0x4a,0x5d,0xd2,0x76,0x9b,0x69,0xa3,0xf7,0xa1,0x37,0xfd,0xee,0x19,0xd8,0x4a,
3406
0x1a,0xad,0xa8,0x93,0x02,0xaa,0x9f,0x2e,0xaa,0xa3,0x24,0xda,0xfb,0x15,0xc6,0xda,
3407
0xf9,0x8c,0xdd,0x8b,0xa1,0x43,0x77,0xb7,0x3d,0xcd,0x5c,0x5b,0x1a,0x3a,0xf4,0x74,
3408
0xef,0xd1,0x9b,0xf9,0xc5,0xf4,0xfd,0x6d,0xd4,0xdf,0x06,0xd5,0x61,0xd9,0x81,0x6e,
3409
0x3d,0x3e,0xc9,0x3c,0x94,0x4c,0x5d,0xce,0x1d,0xec,0xf6,0x81,0x41,0xd4,0x69,0x04,
3410
0x7d,0xb7,0x2e,0x94,0xa1,0x3f,0x94,0x1b,0xee,0xf6,0x8b,0x6d,0xf0,0x15,0x34,0x27,
3411
0x7c,0x1a,0xbc,0x4e,0xbd,0xcf,0x57,0x9d,0x5e,0x43,0xff,0xe8,0x7c,0xad,0x5b,0xb7,
3412
0x0d,0x54,0xa7,0x17,0xd3,0x37,0x0f,0xc2,0x28,0x8e,0x2b,0x8d,0xa8,0xcb,0x1b,0x55,
3413
0xa7,0x2b,0x6e,0x76,0xfb,0xd0,0x86,0x9b,0xdd,0xfa,0x35,0xf3,0xe8,0x81,0x9b,0xdd,
3414
0x7a,0xbe,0xf9,0x16,0xb7,0x9e,0x6b,0x53,0xcf,0x83,0xa9,0xe7,0xe9,0x8c,0x99,0xe1,
3415
0xcc,0x0b,0x63,0xee,0x76,0xeb,0xdc,0xf4,0xc5,0x6d,0xf7,0xb8,0x75,0x5f,0xe8,0x5e,
3416
0xb7,0xfe,0xcf,0xba,0xdf,0x3d,0xbe,0x35,0xaf,0xea,0x77,0x9a,0xc0,0x3b,0x89,0x7e,
3417
0xe7,0xc1,0xba,0xcc,0x21,0x69,0xc4,0x09,0x99,0x17,0xfb,0x9d,0x4d,0x97,0xf9,0x9d,
3418
0x2d,0xd7,0xf9,0x9d,0xc6,0x84,0xbb,0xfd,0x61,0x77,0xfd,0xed,0xd1,0x5b,0xda,0xf7,
3419
0x24,0x7e,0x9e,0xbf,0xf7,0x2c,0x8a,0xa7,0x43,0x03,0xe4,0x2b,0xe0,0x6a,0x77,0xa9,
3420
0xf9,0xde,0xc8,0x75,0x96,0x7f,0x3f,0x78,0x1f,0x9e,0x83,0x2f,0x61,0x31,0xec,0x0c,
3421
0xb8,0xcf,0xad,0x9a,0xe7,0x55,0xdf,0x86,0x6d,0x90,0x0b,0x1f,0xc2,0x5e,0xd8,0x17,
3422
0x70,0x9f,0x09,0xfe,0x0c,0x5d,0x15,0x70,0x75,0xb5,0x74,0xa9,0xe5,0xb7,0x54,0xfe,
3423
0x9b,0x14,0xaf,0xd1,0x17,0xa4,0x4b,0xf5,0x5c,0xec,0x52,0x3d,0x1b,0xbb,0x54,0xe9,
3424
0x2d,0x55,0x9a,0x46,0xdf,0x91,0xbe,0x2b,0xdd,0x2a,0x7d,0x5f,0xfa,0x81,0x74,0x9b,
3425
0x34,0x57,0xfa,0x91,0x74,0x87,0xf4,0x63,0xe9,0x2e,0xe9,0x6e,0xe9,0x1e,0xe9,0xa7,
3426
0xd2,0xbd,0x52,0x2f,0xef,0xfb,0xac,0x7c,0x2c,0x51,0x7e,0x57,0x28,0xbd,0x15,0x8a,
3427
0x67,0x85,0xca,0x63,0xd2,0x1e,0x14,0xe1,0x72,0x4d,0x08,0xd7,0x85,0x30,0x36,0x84,
3428
0xd1,0x21,0x5c,0x1f,0xc2,0xa8,0x10,0x1e,0x0b,0xe1,0x89,0x10,0x6e,0x08,0x61,0x42,
3429
0x08,0x37,0x86,0x30,0x29,0x84,0xdb,0xc4,0xad,0xe2,0x76,0x31,0x59,0xdc,0x2b,0xa6,
3430
0x8a,0xd9,0x21,0xcc,0x0d,0x61,0x61,0x08,0xf3,0x43,0x78,0x51,0xbc,0x14,0x82,0xf7,
3431
0x2d,0x1b,0xfb,0x9b,0x36,0x36,0xcb,0x43,0xd8,0x6c,0x61,0x7f,0xfb,0xe6,0x99,0x10,
3432
0xd6,0x8a,0x35,0x62,0x9d,0xf0,0xbe,0xa5,0xb3,0x41,0xbc,0x2a,0x5e,0x13,0x9b,0x42,
3433
0xc8,0x14,0xf6,0xb7,0x79,0x4e,0x66,0x7f,0xe7,0x14,0xf6,0x66,0xa7,0xb0,0xaf,0x3d,
3434
0x85,0x7d,0xcd,0x29,0xec,0xeb,0x4e,0x61,0xdf,0x74,0x1a,0xf6,0xcc,0xff,0x60,0x7f,
3435
0x3d,0x04,0x6f,0x5b,0x0d,0xcb,0x1e,0x63,0xd9,0x83,0xa7,0x88,0xcb,0x68,0x55,0xed,
3436
0x57,0x55,0xfb,0x18,0x8d,0x95,0x06,0xa5,0x99,0x52,0x13,0xbe,0x9a,0xc2,0x57,0x53,
3437
0xf8,0x6a,0x0a,0x5f,0x4d,0xe1,0xab,0x29,0x7c,0x35,0x85,0xaf,0xae,0xf0,0xd5,0xb5,
3438
0xbd,0xba,0xb6,0x57,0xd7,0xf6,0x1a,0x8a,0xa7,0x86,0xb6,0xc7,0x58,0x7e,0x41,0xc5,
3439
0x5d,0x43,0x1a,0x23,0x35,0xfe,0x89,0xf2,0x4f,0x94,0x7f,0xa2,0xb6,0x25,0x6a,0x7b,
3440
0xb2,0xfc,0x93,0xe5,0x4e,0x51,0xf8,0x14,0xf9,0xa7,0x28,0x7c,0x8a,0xb6,0xd7,0x92,
3441
0x7f,0x2d,0xb9,0x6b,0x4b,0x53,0xb5,0x5f,0xaa,0xdc,0x75,0xe4,0xae,0x23,0x77,0x23,
3442
0xb9,0x1b,0x69,0xff,0x46,0x8a,0xb7,0x91,0xb5,0x3d,0x53,0x6a,0xca,0x9b,0xae,0x70,
3443
0xe9,0xda,0x9e,0xae,0xed,0xe9,0xda,0xde,0x58,0x7d,0xb4,0xb1,0xe2,0x6d,0xac,0xf0,
3444
0x8d,0x15,0xaf,0xd1,0x26,0xd2,0xa0,0x34,0x53,0xda,0x5c,0xdb,0x6a,0x48,0x63,0xa4,
3445
0xb1,0xd2,0xa0,0x34,0x53,0xda,0x5c,0x7e,0x76,0xdd,0x07,0xad,0x3a,0xf6,0xc8,0xb4,
3446
0xfa,0x50,0x53,0x85,0x6f,0xaa,0xf0,0x4d,0x15,0xbe,0xa9,0xc2,0x34,0x55,0xf8,0xa6,
3447
0x0a,0x9f,0xa1,0xf0,0x19,0xda,0x9e,0xa1,0xed,0x19,0xda,0xde,0xdc,0xea,0xb7,0x5e,
3448
0x9f,0x8d,0xb5,0xf2,0xd6,0xdc,0xea,0xb3,0x86,0x38,0x18,0x08,0xf1,0xd2,0x4c,0xa9,
3449
0x79,0x76,0xea,0x22,0xb4,0x8d,0xec,0x2d,0x2d,0x7b,0x2b,0xcb,0xde,0xda,0xb2,0x67,
3450
0x59,0xf6,0x36,0x8a,0xc7,0x1b,0x1b,0xf1,0x96,0x3d,0xe1,0x14,0x63,0xa9,0xe9,0xcf,
3451
0x8c,0xab,0x78,0x69,0x42,0xc8,0x78,0x6a,0x7a,0x8a,0x71,0x15,0x2f,0x4d,0x08,0x19,
3452
0x4f,0x4d,0x4f,0x31,0xae,0xe2,0xa5,0x09,0x21,0xe3,0xab,0xe9,0x49,0xc6,0xd9,0xc9,
3453
0xfa,0xe1,0xa9,0xfa,0xdd,0xcf,0xf5,0xaf,0x53,0xf5,0xa3,0x2a,0x56,0x9f,0x69,0xaa,
3454
0xfc,0x35,0x55,0xfe,0xec,0xfe,0xd1,0xf4,0x24,0xfd,0x24,0xd3,0xaa,0x7f,0xaf,0xee,
3455
0x13,0x42,0xfa,0x41,0xd3,0x93,0xf4,0x87,0x9f,0x9b,0xfb,0x62,0x4f,0xd1,0x76,0x19,
3456
0xa7,0x39,0xf7,0x65,0x9c,0xe6,0x9c,0x97,0x61,0xb5,0xc1,0x2f,0x99,0xd3,0x7e,0xe9,
3457
0x5c,0x16,0xfb,0x5f,0xcc,0x69,0xbf,0xd5,0x5c,0x16,0x3a,0x77,0x9d,0xee,0x1c,0x75,
3458
0x3a,0x73,0x52,0xc6,0x69,0xcc,0x45,0xa7,0x33,0xf7,0x64,0x9c,0x62,0xce,0x19,0x78,
3459
0x9a,0x73,0x4d,0xc6,0xcf,0xf4,0x97,0xd0,0x7e,0x71,0xb2,0xf6,0xaf,0x2e,0x77,0xa2,
3460
0xd5,0xbe,0xc6,0x9d,0x24,0x77,0x92,0xdc,0x27,0xab,0xa7,0xe0,0x49,0xca,0x13,0x9a,
3461
0xbf,0xb4,0x88,0xe3,0x73,0x9a,0xb1,0xb7,0xb6,0xec,0xde,0x9c,0x56,0x4b,0xe3,0xa4,
3462
0x96,0xf6,0x4b,0x95,0x3b,0x55,0xee,0x3a,0x72,0xd7,0x91,0x3b,0x51,0xee,0x44,0xb9,
3463
0x93,0xe4,0x4e,0xb2,0xea,0x2b,0xd3,0xaa,0xb7,0x1a,0x72,0xd7,0xb0,0xea,0x31,0xd3,
3464
0xaa,0xcf,0x64,0xb9,0x93,0xe5,0x4e,0x91,0x3b,0xc5,0x8a,0xbf,0x86,0x34,0x46,0x1a,
3465
0x1b,0x52,0x47,0xf1,0xca,0x4f,0xbc,0xe2,0x89,0xd7,0xfe,0xf1,0xff,0x80,0xf2,0xfd,
3466
0xdc,0xfe,0x76,0x9f,0xca,0xb0,0xd6,0x2d,0xa7,0x9a,0x4b,0x4e,0x15,0x5f,0xe8,0x7a,
3467
0xc7,0xcc,0xe1,0x2d,0x2c,0xad,0x66,0x8d,0xc9,0x6a,0xd6,0x5c,0x76,0x32,0x7b,0xd0,
3468
0x9a,0x1b,0x83,0xd6,0xf8,0xa8,0x61,0xd9,0x63,0x2c,0x7b,0xec,0x49,0xe6,0x48,0xcf,
3469
0x1e,0x63,0xf5,0xf9,0x18,0x6b,0x1d,0x92,0x68,0x85,0x4d,0xb4,0xe6,0xd5,0x44,0xab,
3470
0xcd,0x12,0xad,0x78,0x4e,0x66,0xaf,0x61,0xd9,0x83,0x21,0xf6,0x64,0x2b,0xfd,0x50,
3471
0x7b,0xd0,0x6a,0xbb,0x98,0x53,0xd8,0x6b,0x58,0xed,0x1f,0x0c,0x69,0x33,0xdb,0x1e,
3472
0x0c,0xb1,0xa7,0x58,0x7d,0x30,0xc5,0xaa,0x43,0xdb,0x5e,0xcb,0x2a,0xcb,0xc9,0xec,
3473
0x76,0x98,0xe6,0xd6,0x7c,0x1f,0xb4,0xe6,0xfc,0x53,0xd9,0x33,0xad,0xe3,0x40,0xd0,
3474
0xb2,0x37,0xb7,0xec,0x99,0xd6,0x31,0x21,0x18,0x62,0x4f,0xb7,0xf2,0x93,0x6e,0xc5,
3475
0xd3,0xc4,0xaa,0x9f,0x26,0xd6,0xf8,0x6a,0x62,0x95,0xd7,0x3b,0x3e,0xd4,0x38,0x89,
3476
0x3d,0xd6,0xda,0x37,0x36,0x64,0x9e,0x8c,0x09,0xb1,0x9f,0xac,0x1f,0x05,0x2d,0x7b,
3477
0xf3,0x90,0xe3,0xb3,0x7d,0xbc,0x09,0xed,0x8f,0xf6,0x71,0xc7,0x3b,0x56,0xdb,0xc7,
3478
0xa8,0x8c,0x90,0xe3,0x52,0x4c,0x88,0x3d,0xd3,0x3a,0x5e,0x05,0x4f,0x61,0xcf,0xb4,
3479
0xe6,0xfa,0xe6,0x96,0x3d,0xd3,0xca,0x6b,0x30,0xc4,0x5e,0xd5,0x9a,0x83,0xaa,0x59,
3480
0xfd,0xad,0x9a,0x15,0x67,0xb5,0x90,0x30,0xb1,0x96,0x7f,0xd0,0xf2,0x0f,0x5a,0x73,
3481
0x5c,0x30,0xe4,0x7c,0xcc,0xf6,0xcf,0xb4,0xe6,0x91,0x4c,0x6b,0x5c,0x34,0xb7,0xfa,
3482
0x7f,0x73,0xab,0x0f,0xdb,0xe7,0x21,0xf6,0x9a,0xb1,0x79,0xc8,0xb1,0xd7,0x3e,0x1e,
3483
0x37,0x3f,0x49,0x59,0x9b,0x5b,0x7d,0xa9,0xb9,0x55,0xb7,0xcd,0x43,0xfa,0x9b,0xdd,
3484
0xc7,0x52,0xad,0xf0,0x8d,0x4f,0x72,0xde,0x62,0xaf,0x2b,0xec,0x7c,0x06,0xad,0xf0,
3485
0xc1,0x10,0xff,0xa6,0x21,0x6b,0xba,0x18,0xab,0x1c,0x35,0x42,0xfa,0x55,0x73,0x6b,
3486
0xbd,0xd4,0xdc,0x5a,0x5b,0x36,0x0f,0x89,0xdf,0x1e,0x9b,0xc9,0x21,0x73,0x51,0x6c,
3487
0x48,0x9e,0xbd,0xe3,0x4d,0x13,0x5d,0x3b,0x49,0xb7,0xec,0x55,0x64,0xf7,0xd6,0x50,
3488
0xde,0x1a,0xde,0x3b,0xff,0xb0,0xc7,0x41,0x4d,0x2b,0x1e,0xaf,0x9e,0xbc,0x63,0x50,
3489
0x33,0xcb,0xbf,0x89,0xb5,0xd6,0x68,0xa6,0xed,0x4d,0xac,0xbc,0x36,0xb1,0xfa,0x81,
3490
0x67,0xcf,0xfb,0x1b,0x2b,0x21,0x79,0x31,0x7e,0xa1,0xf1,0x19,0xbf,0xd0,0x38,0xbd,
3491
0xb1,0x6e,0xb6,0x79,0xf6,0x2a,0x56,0x3c,0xf1,0xba,0xce,0xe1,0xf9,0xd5,0x30,0xcf,
3492
0x4d,0xc7,0x39,0x8e,0x3f,0xce,0x7d,0x5f,0xaf,0xae,0xf5,0x1d,0x86,0xb3,0xf1,0x3b,
3493
0x27,0xee,0xe4,0xdf,0x7d,0x28,0x41,0x02,0xc5,0xe1,0x4a,0xc7,0xc5,0xfb,0x66,0xc2,
3494
0x35,0x70,0xad,0xd9,0xce,0x7e,0x25,0xa1,0x28,0x14,0x83,0x82,0x50,0x28,0xee,0xf8,
3495
0xfb,0xc9,0x85,0xe1,0x0c,0x38,0x13,0x8a,0x98,0xf7,0x88,0xcc,0x73,0xe0,0xd6,0xb7,
3496
0x21,0x4e,0xa5,0x5e,0x7a,0x06,0x2f,0xef,0xb1,0xca,0x77,0x1d,0xeb,0x5b,0x12,0x26,
3497
0x7f,0xa7,0xca,0x53,0xb4,0xb9,0x87,0x6b,0x9e,0x5f,0xd7,0x77,0x1f,0x62,0x1c,0xf7,
3498
0x3d,0xf0,0x06,0x7a,0x37,0xf1,0x32,0xf3,0x9d,0x48,0xf3,0xad,0x58,0x48,0x53,0x9e,
3499
0x5a,0x68,0x4d,0xd8,0xc2,0x3a,0x3f,0xf6,0xce,0x8d,0xbd,0xf3,0x62,0x6f,0x2d,0xe9,
3500
0x9d,0x1b,0x7b,0xeb,0x49,0xef,0xfc,0xd8,0x5b,0x53,0x7a,0xe7,0xc8,0x69,0xd6,0x39,
3501
0xf3,0xc5,0x72,0x1b,0xad,0x10,0x71,0xe2,0xb7,0xb2,0xed,0x6f,0x66,0x87,0x7e,0x3b,
3502
0x3b,0xf4,0x1b,0xda,0xa1,0xdf,0xd2,0x3e,0x95,0x56,0x11,0x55,0x43,0xb8,0x50,0x54,
3503
0x0b,0xa1,0x7a,0x08,0x35,0x42,0x88,0x09,0x21,0x36,0x84,0x9a,0x22,0x4e,0xc4,0x8b,
3504
0x04,0x91,0x18,0x42,0x52,0x08,0xc9,0x21,0xa4,0x84,0x50,0x2b,0x84,0xda,0x21,0xa4,
3505
0x86,0x50,0x27,0x84,0x46,0x21,0xa4,0x87,0xd0,0x38,0x84,0x26,0x21,0x04,0x43,0x68,
3506
0x1a,0x42,0x46,0x08,0xcd,0x44,0xe6,0x49,0xce,0xc1,0x9b,0x5b,0xe3,0xb6,0xed,0x29,
3507
0xec,0xed,0x4e,0x61,0x6f,0x7f,0x0a,0xbb,0xa7,0x66,0x6c,0x54,0x74,0xdc,0x31,0xe0,
3508
0xf5,0x71,0x33,0x16,0xaa,0x58,0x63,0xd8,0x1b,0x17,0x35,0x34,0x36,0x62,0xf5,0x3d,
3509
0x92,0xd3,0xfd,0x96,0x8a,0x37,0x8f,0xd4,0xd3,0x78,0x6a,0xa0,0x71,0x99,0xf6,0x3b,
3510
0xbe,0xfb,0xdc,0x59,0xe3,0xd8,0xcc,0x29,0x57,0x68,0xbe,0xe8,0xf2,0x3b,0xbe,0x13,
3511
0x6d,0xe6,0x9c,0x31,0x9a,0x77,0xae,0x83,0x89,0x54,0xec,0x8d,0x17,0xba,0xf3,0xac,
3512
0x37,0xf7,0x99,0xb9,0xeb,0x3b,0x3d,0x77,0x3e,0x53,0xcf,0xcc,0x3e,0xae,0xe7,0x63,
3513
0xcd,0x73,0xe1,0xbb,0xf4,0x9c,0xf5,0xa7,0x7a,0x4e,0xf2,0x58,0xdc,0x5f,0xef,0xd9,
3514
0xfa,0x23,0x7a,0xde,0xd3,0x3c,0x27,0xda,0xa5,0xd8,0xdf,0xeb,0xfd,0xc3,0x47,0x28,
3515
0xce,0xa3,0xf0,0xb4,0xf5,0x37,0xd3,0x9e,0x40,0x1f,0x37,0xcf,0xb0,0xe1,0xe1,0xaf,
3516
0xe4,0x7e,0x17,0x65,0x6a,0x05,0xf7,0xbb,0x28,0x77,0xc2,0x0c,0xfc,0x36,0x54,0x32,
3517
0xf7,0x03,0x7d,0x79,0xdf,0xce,0xfd,0x40,0xba,0xc9,0xef,0x38,0x6f,0xf9,0xdd,0xbf,
3518
0xf5,0x32,0x1d,0x6d,0x0b,0x8f,0x9a,0x6f,0xa7,0xcf,0x21,0x3e,0xf4,0x31,0xe8,0x00,
3519
0x1d,0xcd,0xb7,0xcd,0xcb,0xd0,0xd7,0xd1,0x2b,0x60,0x36,0x5c,0x05,0x5d,0xa1,0x0b,
3520
0xdc,0xef,0x77,0xbf,0x09,0xf4,0x80,0xf9,0x06,0x3c,0xdc,0x00,0x4f,0x99,0xef,0xa5,
3521
0x9b,0xbf,0x2f,0x02,0xe1,0xdb,0x7d,0xce,0xed,0x4f,0x52,0x36,0xec,0x01,0x63,0x47,
3522
0x23,0x50,0xf3,0x37,0x65,0x86,0x9b,0xbf,0x5f,0xe2,0x77,0xfb,0xf8,0x68,0xb4,0x00,
3523
0xfe,0xd7,0xa2,0xd7,0xc1,0x58,0x98,0x05,0x4f,0x98,0x78,0xc9,0xd3,0x93,0xe8,0x64,
3524
0x13,0x96,0x49,0x62,0x0a,0x3a,0x13,0x1e,0x81,0x7b,0x61,0x25,0xe9,0xaf,0x82,0xd5,
3525
0x50,0x90,0x38,0xca,0xc2,0x24,0xfc,0xef,0x86,0x7b,0xe0,0x21,0x28,0x84,0xdf,0xf4,
3526
0xa2,0x3e,0xe7,0x45,0xb8,0x5f,0xfa,0xb8,0x34,0xbe,0x98,0xcf,0xa9,0x02,0x09,0xd2,
3527
0x8c,0xe2,0x3e,0xa7,0x41,0x71,0x57,0x3b,0xc2,0x78,0x78,0x0d,0x6e,0x80,0x97,0xe0,
3528
0x16,0x58,0x0d,0x39,0xf2,0x5f,0x6d,0xf1,0x82,0xd4,0xf8,0x2f,0x29,0x41,0xfc,0x25,
3529
0x5c,0x9d,0x27,0x5d,0x06,0x2f,0x94,0xf4,0x39,0x73,0x61,0x89,0x34,0xb9,0x94,0xcf,
3530
0x89,0x83,0xb2,0xd9,0xc7,0xb9,0x50,0x5a,0x4e,0xf6,0x72,0x72,0x97,0xb7,0xc2,0x94,
3531
0xb3,0xc2,0x96,0xb3,0xfc,0x4d,0x98,0x9e,0xfd,0x5c,0xba,0x85,0xa8,0xa1,0xad,0xde,
3532
0x8b,0x5e,0xa7,0x71,0xbc,0x4e,0xe3,0x73,0xaf,0xc6,0xd4,0xef,0x35,0x67,0x9e,0xee,
3533
0xfc,0xde,0xf1,0x2d,0x9f,0xd3,0x1d,0x2e,0x09,0xd1,0xfe,0x96,0x7d,0x80,0x65,0x1f,
3534
0x68,0xd9,0x07,0x59,0xf6,0xc1,0xb0,0x44,0xf6,0x17,0xa5,0x4b,0xac,0xb8,0x5e,0xb4,
3535
0xec,0x4b,0xac,0x78,0x5f,0xb4,0xec,0x7f,0xb7,0x6f,0x69,0xfc,0x19,0xca,0xf3,0x77,
3536
0x2a,0xcb,0x6f,0xdd,0x36,0x5e,0x59,0x32,0xac,0xbc,0x87,0xe6,0xf9,0x97,0xe6,0xb7,
3537
0xc7,0xcf,0xe4,0xf3,0x9f,0x5e,0xe7,0xe9,0x27,0x29,0xcb,0xcf,0x95,0xe1,0x3f,0xe5,
3538
0xff,0x8f,0xce,0xfb,0xc9,0xda,0xa0,0xf5,0x9f,0x2c,0xcf,0xf9,0xf3,0x69,0x7e,0x79,
3539
0xf2,0xcb,0x93,0x5f,0x9e,0xbf,0x5b,0x79,0xe2,0x39,0x27,0xa9,0xc5,0xf9,0xc7,0x76,
3540
0xc7,0xfd,0x1e,0xf2,0x1d,0xfa,0x2e,0xe9,0x5d,0xfa,0x6e,0xf1,0xdd,0xfa,0x4e,0xf1,
3541
0xbd,0xfa,0x76,0xf0,0x7d,0x70,0x3f,0x3c,0x00,0x0f,0xc2,0x43,0xfa,0xde,0xee,0x0c,
3542
0x7d,0xcf,0xf7,0x5e,0xfd,0x3d,0xc2,0xc7,0xf4,0x9d,0xdf,0x27,0xe0,0x49,0xf3,0x7d,
3543
0x47,0x7d,0x7f,0x37,0xb2,0xa2,0xfb,0x8d,0x66,0xfb,0x6f,0x6a,0x99,0x6f,0xa2,0x3f,
3544
0xaf,0x6f,0x27,0xbf,0xa0,0xef,0x18,0x9b,0xbf,0x73,0xf8,0x92,0xfe,0xc6,0xf6,0x32,
3545
0x58,0xae,0x6f,0xa1,0xaf,0xb4,0xfe,0xfe,0xe1,0xcb,0xf0,0x8a,0xbe,0x39,0xec,0xfd,
3546
0xcd,0xad,0x75,0xfa,0x26,0xb0,0xbf,0xa2,0x1b,0xef,0x0b,0x8a,0x6b,0x8d,0xf6,0x5b,
3547
0x19,0x96,0x5f,0xce,0xfc,0x72,0xe6,0x97,0xf3,0xcf,0x5c,0xce,0x5c,0xf8,0x30,0xec,
3548
0xf4,0xcf,0xbf,0xff,0xec,0xe1,0xcc,0xdc,0xda,0x71,0x3b,0xe7,0xf9,0xd0,0x09,0xcc,
3549
0xdf,0xb6,0x3d,0xb7,0x8c,0xe3,0x8c,0x65,0xee,0x2d,0x06,0x9f,0x40,0x3a,0xdc,0x07,
3550
0x59,0x6c,0x6f,0x00,0x99,0xe6,0xef,0x49,0x11,0xa6,0x21,0xf6,0x87,0xf0,0x1f,0x83,
3551
0xbb,0x36,0xa4,0x42,0x75,0xfc,0x4a,0xc1,0x8d,0xe6,0xfa,0x12,0x61,0x6a,0x60,0x3f,
3552
0x1f,0xee,0xc4,0x7d,0x1f,0xee,0x40,0x19,0xf3,0x47,0x0c,0x69,0x4b,0xb8,0xde,0xfc,
3553
0x1d,0x41,0x78,0x16,0xe6,0x42,0x05,0x48,0x82,0x64,0x48,0xf1,0x1f,0x6f,0x8f,0x71,
3554
0x84,0x9d,0xf6,0xa4,0xe3,0x4c,0x42,0x6f,0x86,0xdb,0x61,0x32,0xe9,0x4e,0x87,0xc7,
3555
0x61,0x06,0x61,0x9f,0x41,0xa3,0x48,0xc7,0xfc,0xcd,0xd6,0x78,0x48,0x08,0x77,0xff,
3556
0x3e,0x6c,0x52,0xb8,0xfb,0x77,0x5b,0xcd,0xdf,0x66,0x35,0x7f,0x8f,0xd5,0xfc,0xcd,
3557
0x55,0xf3,0x77,0x62,0xeb,0x42,0xbd,0x70,0xf7,0x6f,0xae,0x36,0x84,0x34,0x68,0x04,
3558
0xe9,0xe1,0xee,0xdf,0x4d,0x6d,0x02,0x41,0x68,0x1a,0xee,0xfe,0xdd,0xd4,0x66,0xe1,
3559
0xee,0xdf,0x4b,0x35,0x7f,0x83,0xb5,0x15,0xdc,0xf4,0x84,0xfb,0xf7,0x5f,0xcd,0xdf,
3560
0x9e,0xbd,0x24,0xdc,0xfd,0x5b,0xad,0x73,0xe1,0xcd,0x70,0xe7,0x17,0xe5,0xc1,0x4b,
3561
0xbf,0xd1,0x7f,0x48,0xb7,0xb9,0xd2,0x9e,0xaa,0xf4,0xda,0xc3,0x95,0x30,0x07,0xda,
3562
0x90,0x8f,0xf9,0xe1,0xc7,0xef,0x0f,0xd5,0xd0,0xbd,0x9b,0x66,0xba,0x57,0x13,0x63,
3563
0x3d,0x2b,0xd4,0x38,0xe4,0x59,0xab,0x44,0xdd,0x5f,0x69,0xa4,0xfb,0x34,0xe9,0xd6,
3564
0x33,0x38,0xde,0x7d,0xa4,0x58,0xdd,0x03,0x4a,0xd1,0xbd,0x19,0x73,0xff,0xa5,0xbf,
3565
0x9e,0x8f,0x9f,0x09,0x03,0xac,0x74,0x33,0x42,0xee,0xf9,0xfe,0x5c,0x5a,0xa1,0xe9,
3566
0xa4,0x58,0xcf,0xe6,0xd9,0xf7,0xd3,0xed,0xfd,0xed,0x7d,0xed,0x7d,0x5e,0x3c,0x45,
3567
0x5e,0x6a,0x85,0xdc,0x83,0xfe,0x25,0x79,0xb1,0xcb,0x3b,0x33,0xe2,0xff,0xd7,0x71,
3568
0xc6,0x29,0xea,0xf9,0xb7,0xa8,0xe3,0x9f,0x6b,0xcb,0xdf,0x22,0x0d,0xef,0xdb,0xc0,
3569
0x71,0xba,0x7f,0x14,0x2f,0x4d,0x90,0x26,0x4a,0x93,0xa4,0xc9,0xd2,0x14,0x69,0x2d,
3570
0x69,0x6d,0x69,0xaa,0xb4,0xaa,0xd6,0xa2,0xde,0x37,0xba,0xd2,0x2d,0x7b,0x63,0xcb,
3571
0xde,0xc4,0xb2,0x07,0x2d,0x7b,0x53,0xcb,0x9e,0x61,0xd9,0x9b,0x59,0xf6,0x4c,0xcb,
3572
0xde,0xdc,0xb2,0xb7,0xb0,0xec,0x17,0x59,0xf6,0x96,0x96,0xbd,0x95,0x65,0x6f,0x6d,
3573
0xd9,0xb3,0x2c,0x7b,0x1b,0xcb,0x7e,0xb1,0x65,0x6f,0x6b,0xd9,0xdb,0x59,0xf6,0xf6,
3574
0x96,0xbd,0x83,0x65,0xef,0x68,0xd9,0x2f,0xb1,0xec,0x9d,0x2c,0xfb,0xa5,0xb2,0x9b,
3575
0x7b,0xde,0x26,0x7e,0x73,0xdf,0xbb,0xb1,0xd2,0xf5,0xd6,0xf2,0x1d,0x15,0xee,0xf7,
3576
0x5a,0xe3,0x37,0x0b,0xf9,0x46,0x40,0x5b,0xa5,0xd7,0x56,0x78,0xef,0xc4,0x7b,0xfb,
3577
0x36,0x56,0x58,0x4f,0xbd,0xef,0xdd,0x5f,0x2c,0xbb,0xc9,0x93,0xf9,0xfe,0x67,0x0b,
3578
0xdd,0xf3,0xf2,0xee,0x7b,0x99,0x6f,0xe8,0x76,0xec,0xec,0x38,0xaf,0xb7,0x3d,0xfe,
3579
0x7d,0x1d,0xf3,0x7d,0xb1,0xf3,0xc8,0xc8,0xae,0x9b,0xdc,0xef,0x2b,0x3e,0x86,0xbb,
3580
0x3c,0x27,0x18,0x15,0x06,0xb9,0xef,0xae,0xb6,0x24,0xd2,0x5b,0xaf,0x74,0x9c,0xdb,
3581
0x28,0xcc,0x3c,0xdc,0x65,0xcc,0xbb,0xbc,0xd7,0xba,0xdf,0xbf,0x9d,0x7d,0xab,0xe3,
3582
0x1c,0xa2,0x20,0xa9,0x14,0xae,0x04,0x27,0x1c,0xd3,0x88,0xbf,0x7d,0x37,0xb7,0x12,
3583
0xcc,0x37,0xcb,0x9a,0xe7,0xb8,0xdf,0x09,0x33,0xdf,0x0c,0x33,0xdf,0x0a,0x8b,0xec,
3584
0xe6,0x7e,0x57,0xb6,0x2d,0xe1,0xc6,0x71,0xe2,0x31,0x9a,0x13,0x8f,0x02,0xec,0x3b,
3585
0xb6,0xbf,0xfb,0x8d,0xb2,0xbc,0xef,0x74,0x11,0xef,0x60,0xd2,0x78,0x9e,0xca,0x6a,
3586
0x39,0xd5,0x6d,0xa7,0x1a,0x3d,0xdd,0x76,0x32,0x76,0x13,0xaf,0x67,0xbf,0xd5,0xb2,
3587
0xdf,0xd4,0xf9,0xb8,0xdd,0x7c,0x33,0xc4,0xb3,0x9b,0xb4,0x3c,0xfb,0x7b,0xc3,0x8f,
3588
0xdb,0x3f,0xbc,0xf8,0xb8,0xbd,0x63,0x77,0xd7,0x7e,0x0f,0xe5,0x3c,0xd8,0xf6,0xf4,
3589
0x8f,0xe7,0xf5,0x49,0xbf,0xb6,0xf9,0x06,0x1b,0x54,0xf4,0xf9,0x9d,0x2e,0xad,0xdd,
3590
0xf7,0x4a,0x5f,0x02,0x3f,0x0d,0x36,0x1a,0xa6,0x67,0xb9,0xef,0x99,0xbe,0x09,0x0f,
3591
0x25,0x99,0xb9,0xc0,0x9f,0xf7,0xce,0x69,0x3b,0xb8,0x0a,0x46,0x98,0x77,0xb8,0x03,
3592
0x7e,0x67,0x09,0xdb,0x7a,0xb6,0x71,0xeb,0xb9,0x05,0xee,0x7b,0xd0,0xc7,0xcc,0x3b,
3593
0xde,0xc4,0xfd,0x74,0x1b,0xf7,0x9d,0xcd,0xed,0x53,0xfd,0x79,0xdf,0x70,0x0e,0x23,
3594
0xef,0xdb,0x09,0x5f,0x17,0x6d,0x7a,0xb1,0x5b,0x5f,0x23,0x4c,0x79,0x92,0xdd,0xf7,
3595
0x38,0xbd,0xf7,0x59,0xcd,0xfb,0x9c,0x01,0xca,0x13,0xd1,0xd6,0x7d,0xe7,0x3b,0xb3,
3596
0xad,0xfb,0x8e,0xeb,0xa5,0x30,0x04,0xae,0x85,0xeb,0x2d,0x6a,0x14,0xf4,0x3b,0x03,
3597
0xa9,0xbb,0xf5,0xd8,0xb7,0x43,0xb7,0x42,0x7e,0x67,0x3f,0x7a,0xd8,0xc4,0x41,0x3b,
3598
0x3d,0x04,0xb5,0xa1,0x19,0xf4,0x32,0xdf,0x02,0x83,0x7f,0x41,0x51,0xda,0xaa,0x2d,
3599
0x74,0x83,0x1b,0x84,0x79,0x7f,0x74,0x0e,0x2c,0x84,0xd5,0x70,0x76,0x47,0xf7,0xbd,
3600
0xda,0x73,0xd0,0x36,0xe8,0xd0,0x0e,0xee,0x3b,0xc1,0x5f,0xd0,0x7f,0xde,0xc0,0xef,
3601
0x2b,0x38,0x03,0xfb,0x2d,0x68,0x02,0x1a,0x0f,0x4f,0xc3,0xee,0x12,0x7e,0xe7,0x4b,
3602
0xf4,0xdf,0x10,0xd1,0xc9,0xed,0xab,0x15,0xcd,0x7b,0xa8,0x30,0xeb,0x6c,0xbf,0xb3,
3603
0x0f,0x3e,0xc7,0x5e,0x9a,0x81,0x54,0x05,0xb6,0x62,0xef,0x81,0x7e,0x41,0x63,0x1d,
3604
0x83,0x02,0xf4,0x8b,0x06,0x62,0x5d,0x29,0xbf,0xf3,0x32,0xba,0xb5,0xb3,0xfb,0x9e,
3605
0xf7,0x11,0x38,0xb7,0xb4,0xdf,0xf9,0x11,0x8d,0xb8,0x8c,0x32,0x5c,0xe9,0x7e,0xbb,
3606
0x7a,0x1c,0x8d,0xdc,0x45,0xef,0xfc,0xae,0x84,0xdb,0x60,0x77,0x19,0xbf,0xd3,0x98,
3607
0xbe,0xbc,0x07,0xed,0x8f,0xf6,0x81,0x31,0xf0,0x31,0xec,0x84,0x9a,0x74,0x8a,0xef,
3608
0xd1,0xaa,0x57,0xd0,0x2f,0xcc,0x7b,0xb1,0xd0,0x15,0xbf,0x09,0x2c,0xb4,0xc6,0xa0,
3609
0xf3,0x70,0x2f,0x84,0xe7,0xaf,0x70,0xbf,0x35,0x70,0xc7,0xa3,0xfe,0xbc,0xef,0x5e,
3610
0xc7,0x47,0xfb,0xf3,0xf0,0x8d,0x27,0xed,0x2b,0x5d,0xd6,0x12,0xfe,0x85,0x04,0xbf,
3611
0xf3,0x41,0xb6,0xdf,0xe9,0x8a,0xbb,0x0f,0xec,0xc2,0xef,0x3e,0x74,0x23,0xbc,0x07,
3612
0x47,0x61,0x5c,0x17,0xfa,0x13,0x1d,0xf1,0xfc,0x54,0xf7,0xdd,0xe4,0xb7,0x2b,0xfb,
3613
0x9d,0xb5,0x68,0xb3,0x6c,0xe6,0xa3,0x6c,0xf7,0x7d,0x5c,0xa3,0xa3,0xf5,0x4e,0xee,
3614
0x02,0x78,0x0c,0xe6,0xc2,0x47,0x7a,0x3f,0xd7,0x7c,0x63,0xc1,0x7c,0xfb,0xa6,0x34,
3615
0x5c,0x0e,0xf3,0xe1,0x6d,0xc8,0x62,0xac,0x16,0xae,0xee,0x77,0xea,0xa3,0xc7,0x70,
3616
0xf7,0x42,0x27,0xc0,0x6e,0x38,0x8c,0x7f,0xc5,0xab,0x58,0xcf,0x63,0x9f,0x0d,0xb1,
3617
0x75,0x28,0x2f,0xee,0xeb,0xe0,0x41,0x18,0x01,0x7d,0xeb,0xb8,0xef,0x47,0xf7,0xed,
3618
0x6e,0x9e,0x71,0xf2,0x3b,0xbb,0xd0,0x6f,0x98,0x57,0x32,0xa1,0x54,0x5d,0xf7,0x9d,
3619
0xe9,0x02,0xe8,0x6e,0xc2,0xdd,0x41,0x9f,0x9e,0xd6,0xc6,0xbd,0xa8,0xf1,0x00,0xfe,
3620
0xcf,0x8c,0x65,0xbd,0xd7,0xf8,0xf8,0x3b,0xc2,0x15,0xe0,0x0a,0x68,0x0b,0x2f,0x27,
3621
0xfa,0x9d,0x4c,0xf6,0xfb,0x16,0xfb,0x44,0xb8,0xb8,0x97,0xfb,0xee,0x75,0x3f,0x16,
3622
0xb3,0xb7,0xa3,0xe5,0xa0,0x44,0x6f,0x27,0xef,0xfd,0xda,0x74,0xf4,0x51,0xd8,0x07,
3623
0xb3,0xae,0xc6,0xce,0x42,0x77,0x1b,0x7a,0x6e,0x3d,0xe2,0xec,0xc3,0xf9,0x0e,0x0b,
3624
0xe9,0x76,0x68,0x2b,0xdc,0x83,0xcd,0x37,0xd6,0xf5,0x1e,0xf2,0x4b,0x70,0x5b,0x1d,
3625
0xbf,0x53,0x88,0xb6,0xfe,0x16,0x6d,0xd5,0x97,0xf3,0x9b,0x7a,0x7e,0x67,0x05,0xba,
3626
0x11,0x7a,0xc2,0xd9,0xfd,0xe8,0x53,0xfd,0xdc,0x77,0xbe,0xcd,0x7b,0xcb,0xbd,0x61,
3627
0x24,0x4c,0x84,0xb2,0xf5,0xfd,0x4e,0x12,0x5a,0x93,0x79,0xad,0x3f,0x24,0xd6,0x77,
3628
0xdf,0x69,0x5e,0x0b,0x6f,0x35,0xf0,0x3b,0x47,0xd9,0xd6,0x9f,0xf9,0xf2,0x8a,0x86,
3629
0xe4,0x19,0xd6,0x60,0x4f,0x1d,0xe8,0xbe,0xef,0x5c,0x1a,0xee,0x26,0x7c,0x73,0xf4,
3630
0x5a,0x18,0x01,0xcf,0x40,0x25,0xe6,0x84,0x20,0x73,0x72,0xb7,0x74,0xbf,0xf3,0x00,
3631
0x3a,0xa7,0xb1,0xdf,0xa9,0x3a,0xd8,0x7d,0x2f,0x3a,0x0b,0x0a,0x34,0xf5,0x3b,0x63,
3632
0xd1,0x69,0xc6,0x2f,0xc3,0xef,0x94,0x68,0xe6,0x77,0x46,0x0f,0x61,0x3c,0xc1,0xd3,
3633
0x0d,0x58,0xbb,0xa3,0x2f,0x34,0x70,0xc9,0x18,0xea,0x38,0x97,0x0d,0x75,0xdf,0xa3,
3634
0x9e,0x68,0xbe,0xa3,0x00,0xa5,0x1b,0x3a,0xce,0x05,0xcc,0xbd,0x29,0x17,0xf9,0x9d,
3635
0x06,0xe6,0x7b,0xe6,0xa8,0xf9,0x56,0xc4,0xc3,0xf4,0xdf,0xa2,0xcc,0x9b,0x33,0x5b,
3636
0xfb,0x9d,0x17,0xa0,0x49,0x96,0xdf,0x39,0x46,0xd8,0x02,0x69,0xee,0xbb,0xd6,0x47,
3637
0x70,0x7f,0x09,0xa5,0xda,0xf8,0x9d,0x44,0x28,0x3b,0x82,0x36,0x10,0xe6,0x3d,0x6c,
3638
0xf3,0x7e,0xf3,0x2d,0x68,0x53,0xf4,0xee,0x34,0xf3,0x4d,0x01,0xea,0x73,0xa4,0xfb,
3639
0x8d,0x0c,0xf3,0x7e,0xf6,0x2e,0xfc,0x2a,0x77,0xf0,0xe7,0xbd,0x0f,0x7f,0x1f,0xfa,
3640
0x2a,0x98,0x77,0xfa,0xf7,0x43,0xcd,0x46,0xee,0x7b,0xf1,0xcd,0xa1,0x35,0x8c,0xe9,
3641
0xe4,0x77,0x9e,0xbc,0xd4,0xe5,0x0b,0xdc,0x7e,0x0e,0xce,0x73,0x3a,0x53,0x7f,0xd7,
3642
0x30,0xe7,0x41,0x15,0xdc,0x63,0x2f,0xf3,0x3b,0x9b,0xc7,0x70,0x9e,0x82,0x7d,0x2f,
3643
0xba,0x4b,0x0f,0x9b,0xdc,0x78,0xa5,0xdf,0xe9,0x86,0xfa,0xe8,0x57,0x6b,0x51,0xff,
3644
0x75,0x1c,0xcf,0x21,0x09,0x77,0xd5,0xae,0x7e,0x27,0x03,0x3a,0x61,0x7f,0x1f,0x1d,
3645
0x7d,0x3d,0x6d,0xcb,0xc9,0xd9,0x34,0xf4,0x5b,0xbd,0x2b,0xfe,0xc1,0x55,0x7e,0x27,
3646
0xba,0x3b,0x73,0x3c,0xf6,0x59,0xe8,0x40,0xf4,0x4a,0xfa,0xe2,0x3b,0xec,0xb3,0x00,
3647
0x7b,0xd8,0x38,0xc7,0x29,0xc4,0xc1,0xb7,0x01,0xba,0x88,0xf9,0xe7,0xc9,0x9e,0x7e,
3648
0x67,0x11,0xdc,0x49,0x98,0x07,0x12,0xdd,0xf1,0x1d,0x0e,0x0f,0x4d,0x61,0x3c,0x13,
3649
0x6e,0x2a,0xf6,0x5b,0xe0,0x41,0x58,0xc8,0x3c,0x38,0xdf,0x28,0x2c,0x83,0x3d,0x50,
3650
0xaf,0x8f,0x3f,0xef,0x1b,0x1b,0x65,0x26,0xd0,0xe6,0xf0,0x0c,0x44,0xc3,0x32,0xf8,
3651
0x74,0x82,0xfb,0x0d,0x80,0xb6,0xe8,0x7a,0x78,0x1d,0x72,0x21,0xa5,0xaf,0xdf,0xe9,
3652
0xd3,0x8f,0x3c,0xa1,0xd5,0x59,0xac,0x1c,0x26,0xcc,0x11,0x38,0x7b,0x22,0xe1,0x86,
3653
0xf8,0x9d,0xab,0xd0,0x1a,0x03,0xfc,0xce,0xe5,0x6c,0xcb,0x86,0xf9,0xd8,0x37,0x0f,
3654
0x64,0x1f,0xec,0x59,0xfa,0x96,0x49,0x4f,0xe8,0x0d,0xb3,0x61,0x32,0x9c,0x39,0x89,
3655
0xf9,0xed,0x46,0xf7,0x1d,0xf9,0xaa,0xd0,0x07,0x6e,0x84,0xf7,0xd8,0xe7,0x63,0xd4,
3656
0x37,0x99,0xb9,0x08,0x7b,0x17,0x7d,0x5f,0xbe,0xe7,0x70,0xbf,0xf3,0x1e,0xfa,0x11,
3657
0x24,0xb3,0x58,0xfa,0x16,0x7d,0x89,0x63,0xd5,0xb3,0x23,0xfd,0x4e,0x8f,0x51,0x7e,
3658
0x67,0x39,0x7e,0x6b,0x61,0x86,0xde,0xa9,0x37,0xef,0xd3,0x9b,0x6f,0xcf,0xcf,0xe2,
3659
0xc4,0x76,0x0e,0xba,0x0a,0x4a,0xb3,0x46,0x18,0x01,0x35,0x39,0x69,0x0d,0x2f,0xe0,
3660
0x77,0x36,0x60,0x5f,0x0a,0x87,0xe0,0x23,0xdc,0x6f,0xdf,0xee,0xbe,0x7f,0xbf,0x99,
3661
0x13,0xda,0x03,0x70,0x17,0xeb,0x8c,0xc3,0x50,0x8c,0xf5,0x42,0xec,0x24,0xbf,0x53,
3662
0x1a,0xad,0x7d,0x07,0x79,0x84,0xad,0xe6,0xdd,0x7c,0x38,0x7a,0x27,0xc7,0xc7,0xbb,
3663
0xc8,0xcf,0x2d,0x7e,0xe7,0x96,0x69,0x8c,0x13,0x16,0x6f,0x8b,0xa7,0x99,0x74,0xfc,
3664
0xce,0x1e,0xec,0x2f,0xdf,0x4d,0x3b,0x32,0x7f,0x47,0xdf,0x43,0xbf,0xe0,0x38,0x7b,
3665
0xde,0x1d,0xcc,0xf3,0x2c,0xa4,0x86,0xc3,0x0e,0xfc,0x0a,0xde,0xe5,0x77,0x16,0x60,
3666
0xbf,0x1b,0x35,0xef,0xf5,0x1b,0x2e,0x84,0xe7,0xa7,0xf9,0x9d,0x9d,0x68,0x22,0x8b,
3667
0xc0,0x0b,0xa7,0xd3,0xee,0xb0,0x1a,0x7e,0x80,0x37,0xf0,0x8b,0xbb,0xdf,0x9f,0xf7,
3668
0xfe,0x7f,0xda,0x03,0x1c,0x1f,0xe0,0x0d,0x16,0x8a,0x07,0xa0,0xe7,0x83,0xd8,0x39,
3669
0x99,0xfe,0x06,0x7b,0x60,0xa6,0xdf,0x39,0xf3,0x11,0xbf,0x33,0x15,0xcc,0x77,0xec,
3670
0x3b,0xb4,0x74,0xbf,0x5f,0xff,0x03,0x04,0x1e,0x76,0x9c,0x22,0x70,0xb6,0xbe,0x5f,
3671
0x9f,0xf7,0xa0,0x09,0xd5,0xee,0x0f,0x0b,0x0f,0x44,0x44,0x16,0x88,0x2a,0x58,0xa8,
3672
0xf0,0x19,0x67,0x12,0x24,0xef,0xb3,0xcd,0x67,0x15,0x2f,0x51,0xf2,0x6c,0xe6,0x4d,
3673
0xe7,0xf8,0xef,0xdc,0x52,0x1c,0x33,0x9d,0x3f,0xe2,0x57,0xda,0x39,0xbf,0x4c,0xd9,
3674
0x72,0xbf,0x71,0xa4,0xee,0x5f,0x4b,0xab,0x18,0x7d,0x81,0xeb,0xac,0xc4,0xe4,0x51,
3675
0xa5,0xea,0x85,0xd5,0xaa,0xd7,0x88,0x89,0xad,0x19,0x17,0x9f,0x90,0xe8,0x24,0x25,
3676
0xe7,0x2d,0xd3,0x7e,0xdd,0xaf,0x96,0x67,0xa9,0xed,0x3d,0xb6,0xf7,0x9b,0xfd,0xea,
3677
0x9e,0xcc,0xb3,0x5e,0xfd,0x13,0x9c,0x0d,0x52,0x1b,0x3a,0x69,0x8d,0xd2,0x9d,0xc6,
3678
0x4d,0x9c,0xfc,0x5f,0xfe,0x2f,0xff,0x97,0xff,0xcb,0xff,0xe5,0xff,0xf2,0x7f,0xf9,
3679
0xbf,0xfc,0x5f,0xfe,0x2f,0xff,0x97,0xff,0xcb,0xff,0xe5,0xff,0xf2,0x7f,0xff,0xd0,
3680
0xdf,0x9e,0x93,0xfd,0xf6,0xe6,0xf2,0xdb,0xbb,0xd5,0xfc,0x9f,0xbb,0x7e,0xfd,0xf1,
3681
0xff,0xf5,0xf3,0x99,0x9f,0xb1,0x78,0xe1,0x0f,0xed,0x71,0x1d,0xb9,0xb9,0x4e,0xde,
3682
0xff,0x38,0x88,0x62,0xcf,0x67,0xfb,0xf6,0x99,0x7f,0x27,0x44,0x9d,0x5f,0xe3,0x27,
3683
0x6f,0x82,0xfc,0x6a,0xd0,0x2f,0xaf,0x53,0x99,0xff,0x3e,0x52,0xf7,0x72,0xfb,0x5c,
3684
0x9e,0xdf,0x47,0xbb,0xf7,0xe4,0x5d,0xa3,0x2c,0x62,0x2e,0x4f,0xe6,0x5d,0x9f,0x3c,
3685
0xc7,0x5c,0x94,0xdc,0x93,0xeb,0x9c,0x55,0xb0,0xe4,0x6f,0x3b,0x1e,0xca,0x96,0x2b,
3686
0xff,0x4b,0x77,0x2d,0x6d,0xae,0x51,0x96,0xaf,0x50,0xd1,0x64,0x79,0x8f,0x4a,0x91,
3687
0x1b,0x1a,0x28,0xfa,0xf7,0x1c,0xd5,0xae,0x25,0x37,0x4f,0x9d,0x93,0xe5,0xe6,0x24,
3688
0xbf,0x0b,0x7e,0x26,0x66,0xb7,0x25,0x4c,0x8b,0x98,0x7f,0x79,0xd1,0xbb,0x66,0xcf,
3689
0x5f,0x64,0xaa,0xcb,0x3d,0x9e,0xd1,0xdc,0xff,0x14,0xf4,0xf8,0xd4,0xe8,0xfc,0xe4,
3690
0xfa,0x25,0xfd,0x38,0x37,0xf7,0x57,0xe5,0x55,0xd3,0xeb,0x2f,0x2c,0x5e,0xae,0x3d,
3691
0x2d,0x2b,0xf7,0x6a,0x31,0x77,0x2b,0x9d,0x54,0x3d,0x33,0xf7,0x57,0xcf,0x3b,0x91,
3692
0xa1,0x1e,0x51,0xea,0x20,0xbf,0x53,0x83,0x9e,0x34,0xfd,0x5f,0x56,0xcd,0x7f,0x70,
3693
0xfa,0x4e,0x7e,0xfa,0xbf,0xe5,0xef,0xcf,0x52,0xfe,0x76,0x9d,0xff,0x09,0xf5,0x1f,
3694
0x15,0xf5,0xa7,0x6a,0xff,0xdf,0x37,0xf1,0x9e,0x3d,0x4f,0x4c,0xaf,0x0f,0xbf,0xdf,
3695
0x33,0xfd,0xe1,0xc3,0x4f,0x4c,0x7f,0xf4,0x68,0xf3,0x04,0xdc,0x6f,0xb8,0x0c,0xfb,
3696
0x4f,0x47,0xaf,0x5c,0xcc,0xd6,0xff,0x32,0xe2,0x71,0xe3,0x9d,0x1b,0xf2,0x2c,0xe3,
3697
0xf9,0xf1,0x3f,0xc7,0xad,0x28,0xe7,0xd7,0x1e,0x32,0x72,0x7f,0xef,0xce,0x16,0x79,
3698
0x92,0xde,0xff,0x1b,0x54,0xfa,0xdf,0xef,0xcc,0xe6,0xaf,0x98,0xed,0x9f,0x6b,0xda,
3699
0xa8,0x3f,0x77,0xee,0x7f,0xab,0xe5,0xcd,0x9f,0xeb,0xb7,0xfb,0x4f,0x96,0x9f,0x8f,
3700
0xf6,0xfc,0xdd,0x46,0xeb,0x89,0xa7,0x79,0xff,0xcb,0xa3,0xf2,0xf1,0x8b,0x41,0xbf,
3701
0x38,0x99,0x13,0x2f,0x09,0x38,0xb9,0xb9,0xf6,0xd9,0x76,0xe8,0x2f,0xf7,0x04,0xcb,
3702
0xbe,0xbc,0xa0,0xff,0x83,0x75,0x57,0xd4,0xe9,0xd6,0xe9,0xaf,0xba,0x06,0xf6,0x6b,
3703
0x0e,0x38,0x91,0xbf,0x51,0x3c,0xa7,0x5e,0x7a,0xfe,0x99,0x0e,0x39,0x3e,0xaf,0x7b,
3704
0x98,0xff,0x1d,0x9f,0xfb,0xb3,0x8e,0xaf,0x7b,0xf2,0xc2,0xfd,0x5d,0x0e,0xb1,0xb9,
3705
0xc7,0xfb,0xf8,0xbe,0x77,0x73,0xd7,0xef,0x39,0x9d,0xdf,0xde,0xdd,0xbb,0x73,0x3f,
3706
0xd8,0xf3,0x59,0xee,0xdf,0x6f,0x0e,0xdb,0xb3,0xc7,0xe7,0x33,0x25,0xf4,0x19,0xf1,
3707
0x1a,0x1b,0x7b,0xee,0x1e,0x5d,0xb2,0x76,0xfe,0xd1,0xbf,0x3f,0xdb,0x8a,0x2c,0xea,
3708
0x77,0x28,0xf0,0x7f,0xfc,0x9d,0x7e,0x4c,0x1f,0xec,0xde,0xfb,0xd1,0x8e,0x1d,0xbf,
3709
0x5b,0xcd,0x14,0x28,0xf0,0xb7,0xec,0x7f,0x27,0xb6,0xc9,0xcf,0xb7,0xde,0x6f,0xdf,
3710
0x1f,0xfe,0xfb,0x6e,0xf8,0x67,0x5d,0xf7,0x47,0xfd,0xa2,0xfe,0xff,0x2b,0x2e,0x09,
3711
0xe4,0xfe,0x29,0xaa,0x29,0xf2,0xaf,0x73,0x2e,0xf6,0xbf,0x18,0x40,0x79,0xb7,0x71,
3712
0xd4,0x8c,0xe6,0xbe,0xc4,0x9f,0x72,0xda,0xfd,0xeb,0x0d,0x94,0x93,0xfe,0xce,0x73,
3713
0xfe,0xe9,0xbf,0x3d,0xf6,0x4d,0xd8,0xdc,0xfc,0xfb,0xd4,0x7f,0xab,0x5f,0x6e,0x7e,
3714
0x11,0xff,0xc0,0x51,0xf5,0x67,0xac,0xac,0xd3,0xce,0xd4,0x1e,0x5f,0xee,0x5f,0xe7,
3715
0x40,0xf2,0x2b,0x4f,0x73,0x7f,0x93,0xc6,0xca,0x7f,0xca,0xe7,0x7f,0xb3,0x74,0xb7,
3716
0x5b,0xf9,0x34,0x8e,0x4f,0x79,0x0f,0xae,0xe8,0x61,0x88,0x5f,0xf9,0x8c,0xc6,0x09,
3717
0xb1,0xba,0x0f,0xc2,0xfc,0x37,0x11,0xee,0xf9,0x1b,0x5c,0x85,0x89,0xfa,0x6f,0x43,
3718
0xfe,0xf7,0xf3,0x47,0x54,0xe4,0x6f,0xd4,0xa9,0x7e,0xf1,0xa0,0xfc,0xb5,0x17,0x50,
3719
0x23,0xff,0x37,0x35,0xff,0x3b,0x5e,0x92,0x8d,0x8a,0xfc,0xeb,0x75,0xd1,0xc8,0xdf,
3720
0xfc,0x50,0x15,0x79,0xfa,0xcf,0x5f,0x1c,0x3f,0xf5,0xfe,0xdf,0x1e,0x06,0xa2,0xa2,
3721
0xa2,0xfe,0x90,0xb1,0x1f,0x79,0xca,0xb3,0xd5,0xfc,0xce,0xf8,0xb7,0x2e,0x7c,0xd4,
3722
0x3f,0xa8,0xd8,0x51,0x4e,0xfe,0x2f,0x7f,0xd8,0xfd,0xff,0x95,0xc0,0x9f,0xba,0x22,
3723
0xa2,0x7e,0x9f,0x38,0xa3,0xfe,0xa1,0xa3,0x2d,0x7f,0x4e,0xf8,0xdf,0x3c,0x0a,0x17,
3724
0xf5,0x17,0x9b,0x03,0xfe,0x31,0x33,0x5e,0x7e,0x7f,0xff,0x6b,0xff,0x7e,0x7a,0x16,
3725
0xe6,0xbf,0x3f,0x5f,0xce,0xbf,0x90,0xf5,0x17,0xfe,0x45,0x44,0xfc,0xa5,0x7a,0xeb,
3726
0x9f,0x25,0x23,0xbf,0xee,0x42,0xe1,0xd6,0xad,0xee,0xa0,0xdb,0xb9,0xd5,0xfc,0x8e,
3727
0xc7,0xe9,0xfe,0x7e,0x7a,0xa8,0xf1,0xe7,0x47,0xde,0x9f,0xb1,0x8d,0x4e,0xcc,0x96,
3728
0x55,0x3e,0x53,0xe4,0xad,0x3f,0x5f,0x35,0x7f,0x78,0xee,0x4f,0x7c,0xd9,0x6f,0xcf,
3729
0x09,0xef,0x4e,0xba,0x9b,0x7e,0xbf,0x8b,0xf7,0xf9,0x13,0xeb,0xff,0xb0,0x7a,0xfe,
3730
0xe9,0x07,0xae,0xbd,0x7b,0xff,0xf1,0x8f,0x3f,0xe6,0xfe,0x33,0x07,0xcd,0x9e,0x9f,
3731
0x46,0xc0,0xdf,0x7d,0x96,0xf9,0xe9,0x98,0xfa,0xbb,0x1f,0x43,0xfe,0xa2,0xd7,0xc3,
3732
0xdc,0xaf,0xbf,0x06,0x02,0x91,0x81,0x02,0x51,0x05,0x03,0x81,0x42,0x81,0x9f,0x7e,
3733
0x85,0x03,0x81,0x33,0xce,0x0c,0x14,0x29,0x1a,0xb0,0x7f,0xc5,0x02,0x7f,0xc3,0xdf,
3734
0x59,0xc7,0xad,0xc5,0x4b,0x04,0x4a,0x9e,0x7d,0x0e,0x96,0x73,0x7f,0xa3,0xb8,0x4b,
3735
0x59,0xf6,0xf3,0x02,0xf9,0xbf,0xfc,0x5f,0xfe,0x2f,0xff,0x97,0xff,0xcb,0xff,0xe5,
3736
0xff,0xf2,0x7f,0xf9,0xbf,0xfc,0x5f,0xfe,0x2f,0xff,0x97,0xff,0xcb,0xff,0xe5,0xff,
3737
0xfe,0x80,0x9f,0xcf,0xf9,0xa3,0x4c,0x98,0x13,0x70,0x22,0xf3,0x4c,0x15,0x27,0xc6,
3738
0xa9,0xe5,0x34,0x76,0xba,0x3b,0x3d,0x9d,0x61,0xce,0x04,0x67,0xa6,0xf3,0xa8,0xf3,
3739
0x8c,0xb3,0xc4,0x59,0xe1,0xbc,0xe5,0x1c,0x76,0xbe,0xc6,0x04,0x7c,0xc5,0x7d,0x15,
3740
0x7c,0x19,0xbe,0x16,0xbe,0x8e,0xbe,0xce,0xbe,0x7e,0xbe,0x51,0x27,0x98,0xe9,0xbe,
3741
0x87,0x7d,0xb3,0x7d,0x8b,0x7c,0xef,0xf9,0xde,0xf7,0x7d,0xea,0xfb,0xb7,0xaf,0xb8,
3742
0xff,0x1c,0x7f,0x05,0x7f,0x8c,0x3f,0xd1,0x1f,0xf4,0x77,0xf7,0xf7,0xc6,0x8c,0xf2,
3743
0x4f,0xf2,0xdf,0xe3,0x5f,0xe6,0x5f,0xe5,0x7f,0xd3,0xbf,0xc5,0xff,0xa9,0xff,0xc8,
3744
0xff,0xd0,0x1c,0xfd,0x2f,0x8c,0x2f,0xcc,0x17,0x16,0x16,0x16,0x08,0x8b,0x0a,0x2b,
3745
0x94,0x67,0x8a,0xff,0x64,0x4a,0xfe,0x64,0xca,0x84,0x45,0x87,0x55,0xc2,0x54,0x91,
3746
0xa9,0x69,0x99,0x5a,0x98,0xd4,0xb0,0xba,0x61,0x0d,0xc3,0x1a,0xe5,0x99,0xcc,0x9f,
3747
0x4c,0x8b,0x9f,0x4c,0xdb,0xb0,0x4e,0x61,0x9d,0x31,0x97,0xcb,0x74,0x3f,0xc1,0xf4,
3748
0x0b,0x1b,0xf6,0x1f,0xcd,0xa8,0xb0,0x6b,0x7f,0x77,0x33,0x2e,0x6c,0xe2,0x29,0xcd,
3749
0xa4,0xb0,0x9b,0x7e,0x32,0xb7,0x84,0xdd,0x76,0x82,0x99,0x12,0x36,0x35,0xec,0xce,
3750
0xb0,0x69,0xa7,0x69,0xee,0xf9,0xd5,0x66,0x66,0xd8,0x9c,0xff,0x60,0x16,0x85,0xad,
3751
0x38,0xc1,0xac,0xfa,0x5d,0xcc,0xcb,0x61,0xaf,0xfe,0x41,0x66,0x6d,0xd8,0x6b,0x61,
3752
0x1b,0xc2,0x36,0xfe,0x64,0xde,0x0c,0x7b,0xeb,0x6f,0x61,0xb6,0xe4,0x9b,0x7f,0xb4,
3753
0xf9,0x58,0xe6,0x33,0xcc,0x11,0x8c,0x2f,0xfc,0xb8,0x89,0xc2,0x14,0x92,0x39,0x47,
3754
0xa6,0x42,0x9e,0x89,0xc6,0x54,0xca,0x33,0xc9,0x32,0xf5,0x31,0x99,0x98,0x4e,0x96,
3755
0xc9,0xc6,0x74,0x97,0x19,0x26,0x33,0x2e,0x7c,0x52,0xf8,0x6d,0x79,0x66,0x8a,0xcc,
3756
0x9d,0xbf,0x9b,0x99,0x76,0x12,0x33,0x3d,0xcf,0xdc,0x8f,0x99,0x19,0xfe,0x78,0xf8,
3757
0x93,0xe1,0x73,0x31,0xf3,0x65,0x16,0xfe,0x64,0x5e,0x92,0x59,0x26,0xb3,0x02,0xb3,
3758
0x2a,0xcf,0xbc,0x9a,0x67,0xd6,0x62,0x36,0x86,0xbf,0x15,0xbe,0x25,0x7c,0x1b,0xe6,
3759
0x43,0x99,0xed,0x3f,0x99,0x4f,0x65,0x3e,0x93,0xd9,0x8f,0x39,0xf0,0xff,0xcc,0xc1,
3760
0x5f,0x61,0x0e,0x87,0x1f,0xf9,0x5b,0x98,0xaf,0xc3,0xff,0xfd,0x1f,0xcd,0xd1,0xf0,
3761
0xef,0x7e,0x91,0xc9,0x7f,0xba,0xe2,0x9f,0xfe,0xfb,0x2e,0xfc,0xb7,0x35,0xbe,0xc0,
3762
0xaf,0x35,0x2c,0x89,0xff,0x61,0xe7,0x63,0x91,0x3f,0x6b,0xa2,0xf2,0x4c,0xa1,0xbf,
3763
0x88,0x39,0x23,0xc4,0x14,0xc9,0x33,0xc5,0xf2,0xcd,0x69,0x99,0x92,0xff,0x78,0x53,
3764
0xfa,0x4f,0x69,0xca,0xfc,0x4e,0xa6,0x42,0x20,0xfa,0x1f,0x6e,0x2a,0xfd,0xe3,0x4c,
3765
0x95,0x13,0x4c,0x8c,0x4c,0xcd,0x7f,0xac,0x49,0x0c,0x24,0xe7,0x9b,0x9f,0x35,0x75,
3766
0xf3,0x4c,0xfd,0x3f,0xa1,0x69,0x98,0x6f,0xfe,0xe2,0xa6,0x11,0xa6,0x31,0x26,0x88,
3767
0xc9,0xc0,0x64,0xca,0xb4,0xf8,0xcd,0x4d,0x4b,0x4c,0x6b,0x4c,0x9b,0x40,0xdb,0x3c,
3768
0xd3,0x3e,0xdf,0xfc,0x43,0x4c,0xc7,0x40,0xa7,0xdf,0xc4,0x74,0x0e,0x5c,0x7e,0x82,
3769
0xb9,0x32,0x90,0xfd,0x87,0x99,0xee,0x81,0xde,0xbf,0xc8,0xf4,0x09,0xf4,0x3b,0x2d,
3770
0x33,0x20,0x30,0xe8,0x77,0x32,0xa3,0x02,0xe3,0x02,0x13,0x02,0x13,0x03,0x93,0x02,
3771
0x37,0x05,0x6e,0x09,0xdc,0x16,0x98,0x16,0x78,0x30,0xf0,0x70,0x60,0x66,0xe0,0xd1,
3772
0xc0,0xe3,0x81,0x27,0x03,0xb3,0x03,0xcf,0x04,0xe6,0x9f,0x60,0x16,0x05,0x96,0x9c,
3773
0x60,0x56,0x05,0x5e,0x0b,0x6c,0x08,0x6c,0x0c,0xbc,0x19,0x78,0x2b,0xb0,0x25,0xf0,
3774
0x4e,0xe0,0xc3,0xc0,0x27,0x81,0x4f,0x03,0x9f,0x05,0xf6,0x07,0x0e,0x04,0x0e,0x06,
3775
0x0e,0x07,0xfe,0x1d,0xf8,0xfe,0x04,0x13,0x16,0x11,0x75,0x82,0x39,0x23,0xa2,0xd8,
3776
0x09,0xa6,0x64,0x44,0xa9,0x13,0x4c,0xb9,0x88,0x4a,0x21,0xa6,0xfa,0x09,0x26,0x31,
3777
0xa2,0x6e,0x44,0xfd,0x88,0x86,0x11,0x8d,0x22,0x1a,0x47,0x04,0x23,0x32,0x22,0x5a,
3778
0x47,0x74,0x8c,0xe8,0x14,0xd1,0x39,0xe2,0xf2,0x88,0x2b,0x23,0xb2,0x23,0xba,0x45,
3779
0x74,0x97,0xe9,0x19,0x62,0x7a,0xff,0x01,0xa6,0xcf,0xff,0x33,0x83,0x4e,0x30,0x43,
3780
0xfe,0xc7,0x66,0x58,0x88,0xb9,0x26,0xdf,0x9c,0x86,0xb9,0x16,0x73,0x3d,0x66,0xdc,
3781
0x1f,0x64,0x26,0x60,0x26,0x62,0x26,0xfd,0x8f,0xcd,0x4d,0x3f,0x99,0x5b,0xf2,0xcc,
3782
0x6d,0xbf,0xd0,0x4c,0xc1,0x4c,0xfd,0x45,0xe6,0xce,0x13,0xcc,0x34,0xcc,0x3d,0x79,
3783
0x66,0xfa,0x4f,0xe6,0xfe,0xd3,0x34,0x0f,0xe6,0x99,0x87,0x23,0x66,0x9e,0xd2,0x3c,
3784
0x1a,0xf1,0x78,0x9e,0x79,0x32,0x62,0x76,0x9e,0x99,0x13,0xf1,0x4c,0xc4,0xdc,0x88,
3785
0xf9,0x3f,0x99,0x85,0x11,0x8b,0xf2,0xcc,0xe2,0x88,0x25,0x27,0x31,0x2f,0x45,0x2c,
3786
0xfb,0x19,0xb3,0xc2,0x32,0xab,0x22,0x5e,0xc6,0xbc,0x7a,0x82,0x59,0x1b,0xf1,0x5a,
3787
0xc4,0x86,0x88,0x8d,0xf9,0xe6,0x67,0xcd,0x9b,0x3f,0x99,0xb7,0x30,0x5b,0x30,0xef,
3788
0x60,0xde,0xc3,0xbc,0x8f,0xd9,0x86,0xf9,0x10,0xb3,0x1d,0xf3,0x31,0x66,0x17,0xe6,
3789
0x13,0xcc,0xa7,0x79,0xe6,0x33,0xcc,0x7e,0xcc,0x81,0x13,0xcc,0xe1,0x3c,0xf3,0x75,
3790
0x9e,0x39,0x9a,0x67,0xbe,0xcf,0x33,0xbe,0xc8,0x5f,0x6f,0xc2,0xfe,0x9f,0x39,0x7e,
3791
0x21,0xd7,0xfc,0xa2,0x30,0x85,0x30,0x67,0x60,0x8a,0x60,0x8a,0x61,0x8a,0x63,0x4a,
3792
0x62,0xce,0xc1,0x94,0xc2,0x94,0xc6,0x94,0xc9,0x33,0xe5,0x30,0x15,0x30,0xd1,0x27,
3793
0x98,0x2a,0x79,0xa6,0x7a,0x9e,0xa9,0x99,0x67,0x12,0xf3,0x4c,0xad,0xd3,0x34,0xa9,
3794
0x91,0x75,0x23,0xeb,0x47,0x36,0x3c,0xa9,0x69,0x94,0x6f,0xfe,0x32,0xa6,0x71,0x88,
3795
0x09,0xe6,0x9b,0x3f,0xd4,0x64,0x60,0x32,0x4f,0x62,0x5a,0xe4,0x9b,0x53,0x98,0x96,
3796
0x91,0xad,0xf3,0x4d,0xbe,0x39,0x4d,0xd3,0xf6,0x0f,0x31,0xed,0x31,0x1d,0x4f,0x30,
3797
0x9d,0x7e,0x32,0x9d,0x7f,0x07,0x93,0x9d,0x6f,0xfe,0x51,0xa6,0x67,0xbe,0xf9,0x47,
3798
0x9b,0xde,0x91,0x7d,0xfe,0xb1,0xa6,0x5f,0xbe,0xf9,0xdb,0x99,0x61,0x79,0x66,0x54,
3799
0xe4,0x35,0x27,0x98,0x6b,0xf3,0x4d,0xbe,0xf9,0xdd,0xcd,0xf5,0x32,0xe3,0x30,0x13,
3800
0xf2,0xcd,0x2f,0x30,0xee,0xf3,0xa2,0xb5,0xc3,0x1c,0xa7,0x7f,0x45,0x57,0xbb,0x48,
3801
0x07,0xa0,0x0e,0xba,0xd2,0x7c,0x5a,0x07,0x5d,0x85,0xfa,0xd1,0xd5,0xc6,0x1b,0x7d,
3802
0x19,0x0d,0x0f,0x73,0x3f,0x6d,0x18,0x81,0xfa,0xd1,0x48,0xb4,0xb2,0xdf,0x71,0x0a,
3803
0xa0,0xaf,0x98,0x8f,0xac,0xa2,0x8f,0x94,0x75,0x9c,0x82,0xe8,0xab,0xb8,0x0b,0xa3,
3804
0x1b,0x09,0x57,0xc4,0xec,0x47,0xb8,0x62,0x66,0x3f,0x34,0x1a,0x9d,0x41,0xb8,0x4a,
3805
0xc6,0x1f,0xad,0x8a,0x86,0x2b,0x3e,0x7f,0x59,0x77,0x7b,0x38,0x1a,0x8f,0x46,0x94,
3806
0x75,0xf3,0x13,0xe1,0x73,0xf3,0x53,0x40,0xe1,0x0a,0xfa,0xdc,0xf8,0x0b,0xa3,0x55,
3807
0xd0,0xb5,0x8e,0xfc,0xcb,0xba,0xfe,0x67,0xfa,0xdc,0x78,0x0a,0x97,0x75,0xb7,0x17,
3808
0x45,0x63,0xd0,0xb3,0x14,0xef,0x99,0x65,0xdd,0xf2,0xae,0x53,0x79,0x5f,0x53,0x79,
3809
0xd7,0xab,0xbc,0x4b,0xcb,0xba,0xe5,0x3d,0x4b,0xe5,0x2d,0xa1,0x74,0xcf,0xf6,0xb9,
3810
0xe5,0xdd,0xa0,0xf2,0xbe,0xa8,0xf4,0xce,0x53,0x39,0xc3,0x55,0xce,0x08,0x95,0xf3,
3811
0x05,0xa5,0x5f,0xd5,0xef,0x96,0xf3,0x5c,0x9f,0x9b,0x8f,0x73,0xf1,0x8f,0x33,0xfb,
3812
0x95,0x75,0xe3,0x2d,0xab,0x72,0x7e,0xa5,0x72,0x9e,0xef,0x73,0xd3,0x2f,0x5f,0xd6,
3813
0x4d,0xbf,0xac,0xd2,0x2f,0xaf,0x72,0xef,0x51,0xb9,0x2b,0x2a,0xfc,0x05,0xda,0x5e,
3814
0xb1,0xac,0x9b,0xbf,0xca,0xca,0x57,0x59,0xe5,0xe3,0x02,0x2f,0x1f,0x68,0x2c,0x5a,
3815
0x4d,0xe5,0x7f,0x5d,0xe5,0xdf,0xa8,0xf2,0xbf,0xa1,0xf2,0x57,0x55,0xfa,0xd5,0x54,
3816
0xfe,0x1a,0x8a,0x3f,0x4e,0xe5,0x7f,0x53,0xe5,0x5f,0xa7,0x74,0xde,0x54,0xf9,0x0b,
3817
0xa8,0xfc,0x05,0x95,0xee,0x7a,0xb5,0x6f,0xac,0xcf,0x2d,0x6f,0x8d,0xb2,0x6e,0x3a,
3818
0x49,0x3e,0x37,0xdd,0x38,0xed,0xbf,0x57,0xed,0x95,0xa0,0x7c,0xa6,0xf8,0xdc,0x76,
3819
0x4a,0x52,0xbd,0xa4,0xaa,0xdc,0xf5,0x15,0x2e,0x45,0xe1,0xea,0xaa,0x3e,0xeb,0xa9,
3820
0x5d,0xeb,0x28,0x7c,0x03,0xd5,0x6b,0x9a,0xfa,0x53,0xba,0xca,0xfb,0x8d,0xd2,0x6d,
3821
0xec,0x73,0xcb,0xf9,0x96,0xfa,0x4d,0x13,0xe5,0x23,0x43,0xf1,0x37,0x55,0xfc,0x41,
3822
0xc5,0xdf,0x5c,0xf1,0x37,0x53,0x3c,0x9b,0x55,0x6f,0x5b,0x54,0x6f,0x6f,0xab,0xde,
3823
0xde,0xd1,0x38,0xb9,0x48,0xf5,0xd6,0x4a,0xf5,0x16,0xab,0x71,0xf2,0xae,0xea,0xed,
3824
0x0d,0xe2,0x29,0x84,0x66,0xa9,0x5c,0x6f,0xa9,0xfe,0x0a,0xab,0xfe,0xce,0x44,0x4b,
3825
0x9b,0x71,0xa2,0xfc,0xbc,0xae,0x7a,0xdc,0xa7,0xfc,0xb7,0x53,0xf9,0x3a,0xa8,0xbc,
3826
0xed,0x94,0xce,0x25,0x2a,0xc7,0x25,0x8a,0xaf,0xa8,0xe2,0x3b,0x4b,0xed,0x71,0xa9,
3827
0xca,0xd5,0x41,0xf5,0x7b,0x85,0xf6,0xbf,0x54,0xfd,0xe8,0x32,0xc5,0xd3,0x45,0xf1,
3828
0x74,0x51,0xfa,0x5d,0x71,0x57,0x36,0xfd,0xd6,0xef,0xee,0x7f,0x85,0xc2,0x5d,0xad,
3829
0x70,0x57,0x29,0x5c,0x5f,0x85,0x3b,0x4f,0xe1,0xba,0xaa,0xfe,0x06,0xaa,0xfe,0xfa,
3830
0xab,0xfe,0xde,0x57,0xfd,0x7d,0xa0,0xfa,0xdb,0xa6,0xfa,0xeb,0xa5,0x7e,0x77,0xb5,
3831
0xea,0xaf,0xaf,0xfa,0x5b,0xae,0xea,0x6d,0x8f,0xe6,0x97,0xfe,0x3e,0xb7,0xfe,0x06,
3832
0xaa,0xfe,0xb6,0xa8,0xbc,0x25,0x54,0xde,0xb3,0x55,0x7f,0x73,0x95,0xaf,0xdd,0xec,
3833
0x77,0x01,0x3a,0x58,0xf5,0x38,0x58,0xf9,0x1a,0xae,0x71,0x38,0xb4,0xac,0x9b,0xfe,
3834
0x18,0xf5,0x97,0xeb,0x94,0xcf,0xb1,0xaa,0x9f,0xf1,0xea,0xb7,0x43,0x55,0xee,0x1b,
3835
0x35,0xce,0x6e,0x50,0xf8,0xc9,0x6a,0x8f,0x9b,0xe5,0x7f,0xab,0xf6,0xff,0x52,0xfb,
3836
0x7f,0xa8,0x72,0x0e,0x57,0xbf,0xfb,0x46,0xf3,0x4b,0x82,0xdf,0xdd,0xef,0x76,0xed,
3837
0x37,0xd2,0xe7,0x96,0xf3,0x5f,0x8a,0xf7,0x2b,0xed,0x3f,0x4a,0xed,0x93,0xa3,0x74,
3838
0xae,0x51,0xb9,0xaf,0x55,0xf9,0xee,0x50,0xfd,0xde,0xa5,0x74,0x77,0xa8,0x7e,0x3f,
3839
0x56,0xba,0x3b,0x55,0xbf,0xbb,0xd4,0x3f,0x7d,0xaa,0xdf,0x30,0x95,0xa7,0x8a,0xfa,
3840
0xe7,0x6e,0xd5,0xf3,0xa3,0xaa,0xe7,0x4f,0x34,0x8f,0xbf,0xa1,0xfa,0xf5,0xa9,0x7e,
3841
0xc3,0xd4,0x9f,0x66,0x6a,0x1e,0xf7,0xa9,0x5e,0x03,0x8a,0x2f,0x4c,0xf9,0x0f,0x28,
3842
0x5f,0x91,0x2a,0x47,0xa4,0xca,0x11,0xa5,0x70,0x85,0x54,0x8e,0x33,0x34,0x9f,0x7d,
3843
0xaa,0xf1,0x58,0x48,0xfd,0xaa,0x88,0xca,0x77,0x86,0xfa,0x6d,0x31,0xcd,0xe3,0xc5,
3844
0x15,0x6f,0x11,0x95,0x77,0xaf,0xca,0xfb,0x99,0xca,0xbb,0x4f,0xe5,0x5d,0xa6,0x7a,
3845
0x2e,0xae,0xf2,0x96,0x54,0xba,0xe7,0xa8,0x5f,0xed,0x57,0x79,0x5f,0x52,0x7a,0xa5,
3846
0x55,0xce,0x80,0xca,0x19,0xa9,0x72,0x2e,0x51,0xfa,0x17,0x6a,0x1e,0x2f,0xa5,0xfe,
3847
0x53,0x4a,0xfd,0xa7,0xb4,0xda,0xa5,0x9c,0xca,0xf9,0xb5,0xca,0x59,0x46,0xfd,0xb9,
3848
0x82,0xe6,0xf1,0x72,0x4a,0xbf,0x82,0xca,0xfd,0xa9,0xca,0x1d,0xad,0xf0,0x95,0xb4,
3849
0x3d,0x5a,0xfd,0xa1,0x8a,0xf2,0x55,0x4e,0xf9,0xa8,0xe4,0xe5,0x43,0xf3,0x78,0x75,
3850
0xd5,0xc3,0xdd,0xaa,0x87,0xcf,0x55,0x0f,0x07,0x54,0x0f,0x5f,0xa8,0x1e,0x2e,0x54,
3851
0x3e,0xaa,0xab,0x1e,0x62,0x54,0xfe,0x83,0x2a,0xff,0x6b,0x4a,0x67,0x93,0xca,0x1f,
3852
0xa5,0xf2,0x17,0x52,0xba,0x1b,0xd4,0xbe,0x35,0x35,0x8f,0xc7,0x68,0x3c,0x24,0xab,
3853
0x1c,0x87,0x34,0x2f,0xc5,0x2b,0x9e,0xcf,0xd4,0x6e,0x89,0xca,0x6f,0x2d,0xcd,0x37,
3854
0xc9,0xaa,0x9f,0x3a,0xda,0xaf,0x81,0xc2,0xd5,0x52,0xb8,0x7a,0xaa,0xd7,0xfa,0x2a,
3855
0x57,0x5d,0x85,0x6f,0xa8,0xfa,0x6d,0xa4,0x7e,0xd5,0x58,0xe5,0x3d,0xaa,0x74,0x9b,
3856
0x68,0x5c,0x1d,0x56,0xff,0x09,0x2a,0x1f,0xcd,0x14,0x7f,0x86,0xe2,0x6f,0xaa,0xf8,
3857
0x5b,0x28,0xfe,0x4c,0x6f,0x9c,0xaa,0xde,0x8e,0xa8,0xde,0xbe,0x52,0xbd,0x7d,0xad,
3858
0xf1,0xd2,0x52,0xf5,0xd6,0x5a,0xed,0x53,0x53,0xe3,0xe5,0x5f,0xaa,0xbf,0x37,0x35,
3859
0x9f,0xb7,0x51,0xb9,0x36,0xab,0x1e,0xcf,0x50,0x3d,0x16,0xd1,0x7c,0x34,0x53,0xf9,
3860
0xd9,0xa8,0xfa,0xdc,0xaf,0xfc,0xb7,0x57,0xf9,0x3a,0xaa,0xbc,0xed,0x95,0x4e,0x27,
3861
0x95,0xa3,0x93,0xe2,0x2b,0xa6,0xf8,0x8a,0xab,0x5d,0x3a,0xab,0x5c,0x1d,0x55,0xbf,
3862
0x57,0x6a,0xff,0xce,0xea,0x4f,0x97,0x2b,0x9e,0x6c,0xc5,0x93,0xad,0xf4,0xbb,0x69,
3863
0x9e,0x2e,0xa5,0x79,0xfa,0x4a,0x85,0xeb,0xa3,0x7e,0x77,0x8f,0xc2,0x77,0x57,0xf8,
3864
0x7e,0x0a,0x5f,0x5a,0xe1,0xbb,0xa9,0x1e,0x07,0xa9,0x1e,0x07,0x78,0xed,0xa1,0x7a,
3865
0xfc,0x56,0xf5,0xf8,0x9d,0xea,0xb1,0xb7,0xfa,0x5f,0x1f,0xd5,0x63,0x3f,0xf5,0xbf,
3866
0x63,0xaa,0xbf,0x4f,0x35,0xdf,0x0c,0xd0,0xbc,0x3e,0x48,0xf5,0xf8,0xb6,0xca,0x5d,
3867
0x52,0xe5,0x3e,0x47,0xf5,0x38,0x4f,0xf9,0xfa,0x44,0xf3,0xfa,0x10,0xd5,0xe7,0x10,
3868
0xe5,0x6b,0x84,0xc6,0xe5,0x30,0xcd,0xeb,0xd7,0xaa,0xdf,0x5c,0xaf,0x7c,0x8e,0x53,
3869
0x3d,0x4d,0x50,0x3f,0x1e,0xa6,0xf2,0x4f,0x52,0xf9,0x27,0x2a,0x3f,0xf7,0x6a,0xbf,
3870
0x9b,0xd4,0x3e,0xb7,0x68,0xfb,0x6d,0x8a,0xe7,0x88,0xe2,0xf9,0x5e,0xe5,0x1d,0xa1,
3871
0x7e,0x78,0x54,0xf3,0x4e,0xa2,0xe6,0xf7,0x29,0xda,0xef,0x47,0x95,0xf7,0xdf,0x8a,
3872
0x7f,0xba,0xe2,0xff,0x5a,0xf1,0x8c,0x56,0xbb,0x4d,0x55,0x7a,0x63,0x54,0x0f,0xd7,
3873
0xa9,0xbc,0x77,0xaa,0xbe,0xa7,0x29,0xfd,0x03,0xe5,0xdc,0xfd,0x26,0x9a,0x35,0x8e,
3874
0x59,0xb7,0x97,0x73,0xfd,0x9f,0x50,0x7c,0x8f,0xa9,0xfc,0x4f,0x95,0x75,0xd3,0x9d,
3875
0xa5,0x7c,0x7d,0xa4,0x7e,0xf7,0xad,0xf4,0x98,0xda,0x67,0xa7,0xdc,0x05,0x14,0xff,
3876
0x4a,0xc5,0xb3,0x5c,0xf1,0xbc,0xa2,0x78,0x56,0xcb,0x3f,0xd6,0x5b,0x0f,0xc9,0xbd,
3877
0x49,0xe1,0xde,0x55,0xb8,0xb7,0xe5,0x7f,0x91,0xd2,0xad,0xa1,0x71,0xd3,0x4a,0xee,
3878
0x6a,0x7e,0x77,0xfb,0x0f,0x3e,0x37,0x9e,0x6d,0x4a,0xff,0x3d,0xe5,0xe7,0x1d,0x95,
3879
0xff,0x7d,0x6d,0x7f,0x52,0xf1,0x3d,0xae,0x74,0xe6,0x28,0x9d,0xd9,0x8a,0x6f,0xbb,
3880
0xf6,0xff,0x4e,0xfa,0xbd,0xe2,0xd9,0x25,0x77,0x94,0xf2,0xbb,0x4a,0xf1,0xac,0x50,
3881
0x3c,0xaf,0x2a,0x9e,0x97,0xe5,0x5f,0x53,0xe1,0xb6,0xc8,0xfd,0x96,0xc2,0xbd,0xa7,
3882
0x70,0xef,0xc8,0xbf,0xa5,0xd2,0x8d,0x51,0xb9,0x5a,0xcb,0x5d,0x5d,0xe5,0xfa,0x51,
3883
0xf9,0xce,0x55,0xfa,0x5b,0x95,0x9f,0x77,0x55,0xae,0x0f,0xb4,0x7d,0x9e,0xe2,0x7b,
3884
0x56,0xe9,0x3c,0xa7,0x74,0x16,0x28,0x1f,0xf3,0xb5,0x7d,0xae,0xb6,0x2f,0xd2,0xf6,
3885
0x85,0xda,0x5e,0x42,0xdb,0xcf,0x96,0xbb,0xa4,0xdc,0xe7,0xc8,0x9d,0x25,0xf7,0xc5,
3886
0x72,0xb7,0x91,0xbb,0xad,0xfa,0xd9,0x55,0xd2,0xee,0xd2,0x1e,0xd2,0x9e,0x0a,0x37,
3887
0xd2,0x5b,0x87,0xa8,0x1f,0x8f,0x96,0x5e,0xa3,0x70,0xf7,0x2b,0xde,0x5c,0x85,0xfb,
3888
0x40,0xf9,0xdc,0xa1,0x7c,0x7e,0xa4,0x7e,0xbe,0x53,0xe1,0x3e,0x54,0xb8,0x6d,0x0a,
3889
0xf7,0xb1,0xc2,0x6d,0x57,0xb8,0x5d,0x0a,0xb7,0x4f,0xe1,0xf6,0x2a,0xdc,0x17,0x0a,
3890
0xf7,0xb9,0xc2,0x1d,0x52,0xb8,0xfd,0x0a,0xf7,0x99,0xc2,0x1d,0x54,0xb8,0x03,0x0a,
3891
0x77,0x58,0xf3,0xd9,0x17,0xaa,0xff,0xcf,0xa5,0x07,0xa4,0x3b,0xa4,0x1f,0x6b,0x7e,
3892
0x3a,0x5f,0xc7,0xeb,0x32,0x6a,0xcf,0x38,0xbf,0xab,0xf1,0x7e,0x37,0x9e,0x83,0x6a,
3893
0xb7,0x17,0x35,0xfe,0x6e,0x0c,0x73,0xb7,0x2f,0x29,0xe7,0xee,0xf7,0x02,0x5a,0xdc,
3894
0x8c,0x23,0xb4,0x84,0xe9,0x77,0x68,0xd0,0x9c,0x57,0x6a,0x7c,0xae,0xd3,0x7e,0x93,
3895
0xc3,0xdc,0x70,0xe7,0x2a,0x5c,0x29,0x6d,0x5f,0xaf,0xed,0x37,0x69,0x7b,0x55,0x6d,
3896
0xbf,0x50,0xf1,0xbc,0xae,0x70,0x1f,0x28,0xdc,0xcd,0x4a,0xff,0x7d,0xa5,0xbf,0xb5,
3897
0x9c,0xdb,0x3e,0x4f,0x69,0xff,0xda,0xda,0x3f,0x55,0xfb,0x7d,0xa3,0xfd,0x6e,0xd5,
3898
0xf6,0x66,0xda,0x9e,0x29,0xfd,0x5c,0xe1,0xf6,0x29,0xdc,0xed,0x8a,0xff,0x33,0xc5,
3899
0xbf,0x57,0xf1,0xcf,0x09,0x73,0xc3,0x77,0x52,0xf8,0x6f,0x15,0x7e,0x8a,0xe2,0xed,
3900
0xa5,0xf8,0x7a,0x2b,0xdf,0xc7,0xa4,0xcf,0x49,0x5f,0xd1,0x7e,0x03,0xb5,0xdf,0xd3,
3901
0x4a,0x67,0xbe,0xd2,0x99,0xa7,0x7a,0x74,0x14,0x8f,0xaf,0x9c,0x3b,0xcf,0x3d,0xaf,
3902
0xfd,0x17,0x6a,0xff,0xc1,0xda,0xff,0x19,0xa5,0x5b,0x54,0xe1,0x8b,0x69,0xfb,0x50,
3903
0x6d,0x7f,0x56,0xdb,0xcb,0x6b,0x7b,0x05,0xc5,0xb7,0x46,0xf1,0xbd,0xac,0xf0,0xc3,
3904
0x15,0x7e,0xae,0xf2,0xf3,0x96,0xf2,0xb3,0x49,0xe5,0x5e,0xaf,0x78,0xe2,0x14,0x4f,
3905
0xbc,0xe2,0x79,0x57,0xfb,0x8f,0xd4,0xfe,0xaf,0x2b,0x5c,0x9a,0xc2,0x35,0x52,0x79,
3906
0x76,0xcb,0xfd,0x89,0xc2,0x8f,0x56,0xf8,0x8d,0x4a,0xef,0x63,0xa5,0xb7,0x43,0xe9,
3907
0x6d,0x50,0x3c,0x59,0xda,0xaf,0x8d,0xd2,0xdb,0xa3,0xfd,0xc7,0x68,0xff,0x37,0x14,
3908
0xae,0x8b,0xc2,0x65,0x2b,0xdc,0xbf,0x54,0xbe,0x23,0x0a,0xbf,0x59,0xe1,0x73,0x74,
3909
0xdc,0x78,0x4f,0xfe,0x3b,0xe5,0x3f,0x4f,0xfe,0x9f,0x6a,0xbf,0xaf,0xe4,0xbf,0x25,
3910
0xcc,0xcd,0xcf,0xdb,0xd2,0xc8,0x70,0xd5,0x4b,0xb8,0xeb,0xde,0x1c,0xee,0x86,0x0b,
3911
0x0b,0x77,0xe3,0x73,0xb4,0xfd,0x5d,0x6d,0xf7,0xc9,0xbd,0x4a,0xee,0x5c,0xe9,0x47,
3912
0x0a,0x7f,0x46,0xb8,0x8e,0x43,0x0a,0x57,0x4a,0xdb,0x77,0x2b,0xde,0xc2,0x72,0xef,
3913
0x51,0xb8,0x2f,0x14,0xee,0x4c,0xf9,0x1f,0x0a,0x77,0xd7,0x0f,0x5f,0xca,0xfd,0x95,
3914
0xf4,0x1b,0xe9,0xe7,0x0a,0xff,0x96,0xdc,0x5b,0x14,0x6f,0x5b,0xa5,0x9f,0xa5,0xed,
3915
0xef,0x69,0x7b,0x1b,0xb9,0x57,0xcb,0xfd,0xa1,0x74,0xbb,0xc2,0x5f,0xae,0x7c,0xec,
3916
0x52,0xb8,0x54,0x6d,0xff,0x44,0xf1,0x5e,0x26,0xf7,0xa7,0x0a,0x77,0x50,0xe1,0xae,
3917
0x90,0xff,0x61,0xe5,0xf7,0x88,0xdc,0x5f,0x4b,0x8f,0x4a,0x0f,0x48,0x3b,0x86,0xbb,
3918
0xeb,0xa0,0xe1,0xd2,0x11,0xf2,0xff,0x40,0xba,0x4d,0xba,0x4f,0xba,0x1f,0x6d,0x1b,
3919
0xe1,0x38,0x15,0xa1,0x1d,0x44,0x43,0x7b,0xa8,0x24,0xf7,0x05,0xd2,0xca,0xd2,0xd5,
3920
0xd2,0x2d,0xd2,0x95,0x50,0x2f,0x8a,0xf9,0x26,0xca,0xd5,0x78,0x69,0x12,0x2c,0x87,
3921
0x0d,0xf0,0x1e,0xbc,0x0e,0x0d,0x0a,0xb1,0x9e,0x86,0x0e,0xd0,0x0c,0x3a,0xc2,0x45,
3922
0xf0,0x1e,0xdc,0x05,0xcb,0x61,0xbd,0xdc,0xaf,0xcb,0xbd,0xc1,0x84,0x2f,0x4c,0x78,
3923
0x78,0x07,0x56,0xc2,0x6a,0x58,0x2f,0xf7,0x5a,0x78,0x17,0xd6,0xc9,0xbd,0x01,0x1a,
3924
0x9c,0xe1,0x38,0xcd,0xa1,0x23,0x5c,0x74,0x86,0xeb,0x6e,0x01,0xeb,0xe1,0x03,0x78,
3925
0x13,0x72,0x61,0x3b,0x7c,0x24,0xff,0x0f,0x21,0xb6,0x28,0xe5,0x84,0xe4,0xd2,0xd4,
3926
0x7d,0x69,0x57,0x0b,0x48,0x0b,0x4a,0x0b,0x4b,0xcf,0x94,0x9e,0x25,0xad,0x2b,0xad,
3927
0x2f,0x4d,0x93,0x36,0x92,0x36,0x2e,0xed,0xb6,0x6b,0x6d,0x1d,0x27,0x52,0xa5,0x97,
3928
0x49,0x2f,0xd7,0xf1,0xb1,0x97,0xb4,0xb7,0xd6,0x9b,0x4f,0xeb,0xf8,0xf2,0xbc,0xdc,
3929
0xcf,0xc8,0xbd,0x58,0xee,0x35,0xd2,0xb5,0xd2,0xad,0xd2,0xf7,0x75,0xbc,0xf3,0x6b,
3930
0x3c,0x86,0x6b,0x7c,0x47,0x68,0x9c,0x8e,0xd5,0x38,0x0e,0xd3,0xf6,0x80,0xb6,0x47,
3931
0x6a,0xfb,0x38,0xe9,0x78,0xe9,0x04,0xe9,0x0d,0xd2,0x89,0xd2,0x1b,0xa5,0x93,0x14,
3932
0x5f,0x41,0xc5,0x57,0x58,0xf1,0x9d,0xa9,0xed,0x93,0xb5,0xbd,0x90,0xb6,0x9f,0xa1,
3933
0xed,0x45,0xb4,0xfd,0x26,0xe9,0xcd,0xd2,0x5b,0xa4,0xb7,0x4a,0x6f,0x93,0xde,0x2e,
3934
0x9d,0xa2,0xf8,0xce,0x52,0x7c,0x25,0xe4,0x2e,0x2e,0x77,0x49,0xb9,0xcf,0x93,0xfb,
3935
0x7c,0xb9,0x4b,0xcb,0x5d,0x46,0xee,0x8a,0x72,0x5f,0xa0,0xfc,0x54,0x56,0xfc,0x39,
3936
0xda,0x1e,0xad,0xed,0x95,0xb4,0xbd,0x8a,0xb6,0x4f,0x95,0xde,0x21,0xbd,0x53,0x7a,
3937
0x97,0x74,0x9a,0xf4,0x6e,0xe9,0x3d,0x8a,0xaf,0x9a,0xe2,0xab,0xa1,0xf8,0x62,0xb5,
3938
0xfd,0x5e,0x6d,0xaf,0xae,0xed,0x31,0xda,0x5e,0x53,0xdb,0xa7,0x4b,0xef,0x93,0xde,
3939
0x2f,0x7d,0x40,0xfa,0xa0,0xf4,0x21,0xe9,0xc3,0x8a,0x2f,0x41,0xf1,0x25,0x29,0xbe,
3940
0x14,0xf9,0x27,0xca,0x3f,0x59,0xfe,0xb5,0xe4,0x5f,0x47,0xfe,0xf5,0xe4,0xdf,0x40,
3941
0xfe,0x75,0xe5,0x5f,0x5f,0xfe,0x0d,0xe5,0x9f,0x2e,0xff,0x26,0x72,0x37,0x96,0x3b,
3942
0x28,0x77,0x73,0xb9,0x2f,0x92,0xbb,0x85,0xdc,0x2d,0xe5,0xbe,0x58,0xee,0x76,0x8a,
3943
0xb7,0x83,0xfc,0xdb,0xca,0xbf,0xbd,0xfc,0x3b,0xca,0xbf,0xb3,0xfc,0x2f,0x97,0xff,
3944
0x95,0xf2,0xef,0x2a,0xff,0xab,0xe4,0xdf,0x43,0xf5,0x30,0x43,0xdb,0xbb,0x69,0x7b,
3945
0x77,0x6d,0xef,0xa9,0xed,0x33,0xa5,0x8f,0x48,0x1f,0x95,0x3e,0x26,0x7d,0x5c,0xfa,
3946
0x84,0xf4,0x49,0xc5,0x77,0xb5,0xe2,0xeb,0xab,0xf8,0xfa,0x6b,0xfb,0x2c,0x6d,0xef,
3947
0xa3,0xed,0xfd,0xb4,0x7d,0x80,0xb6,0xcf,0x96,0x3e,0x25,0x9d,0x23,0x7d,0x5a,0xfa,
3948
0x8c,0xf4,0x59,0xe9,0x5c,0xe9,0x02,0xe9,0x6a,0xe9,0x97,0xd2,0xc5,0x4a,0x6f,0xa3,
3949
0x77,0x5c,0x57,0x7a,0x6f,0x6a,0xfb,0x5a,0xe9,0xbf,0x15,0xee,0x43,0x85,0xfb,0x48,
3950
0xe1,0xb6,0x97,0x73,0xef,0xeb,0xdc,0x57,0xc1,0xd5,0xfb,0xa5,0xcf,0x4a,0x37,0x4a,
3951
0xdf,0x94,0xbe,0x21,0x0d,0xd7,0xfd,0xa0,0x28,0x69,0x61,0xe9,0x05,0xd2,0xca,0xd2,
3952
0x46,0xd2,0x26,0xd2,0x0c,0x69,0xa6,0xb4,0x9f,0xb4,0xab,0x74,0xa0,0x74,0x90,0x74,
3953
0xa8,0x74,0x98,0x74,0xa4,0x74,0x94,0x74,0xac,0x74,0x9c,0x74,0x87,0xf4,0x63,0xe9,
3954
0x0d,0xd2,0x89,0xd2,0xc9,0xd2,0x9b,0xa4,0x3b,0xa5,0xbb,0xa4,0x4f,0x4b,0x9f,0x91,
3955
0x3e,0x2b,0x9d,0x2b,0xdd,0x27,0xdd,0x2f,0xfd,0x5c,0x7a,0x00,0x9d,0x1e,0xc7,0xf8,
3956
0x8f,0x73,0xf5,0x22,0x69,0x2b,0x69,0x96,0xf4,0x62,0x69,0x3b,0x69,0x07,0xe9,0x25,
3957
0xd2,0x4b,0xa5,0x97,0x49,0xaf,0x90,0x76,0x91,0x76,0x95,0x76,0x97,0xf6,0x94,0xf6,
3958
0x96,0x0e,0x84,0xfb,0x60,0x90,0xdc,0x43,0xe4,0x1e,0x2a,0xf7,0x70,0xb9,0x47,0xc8,
3959
0x3d,0x4a,0xee,0xd1,0x72,0x8f,0x91,0xfb,0x5a,0xb9,0x1f,0x92,0x7e,0x25,0x7d,0x5a,
3960
0xfa,0xac,0x74,0x9e,0x74,0x81,0xf4,0x39,0xe9,0xf3,0xd2,0x17,0xa4,0x2f,0x4a,0x97,
3961
0x4a,0x97,0x4b,0x57,0x4a,0x57,0x4b,0x5f,0x95,0xae,0x95,0xbe,0x26,0xdd,0xa4,0x7c,
3962
0xbd,0x25,0xf7,0x16,0xb9,0xdf,0x96,0xfb,0x5d,0xb9,0xdf,0x93,0xfb,0x7d,0xb9,0x3f,
3963
0x90,0x3b,0x57,0xee,0x0f,0xe5,0xfe,0xb7,0xf4,0x1b,0xe9,0x51,0xe9,0xb7,0xd2,0x1f,
3964
0xe2,0xdc,0xe3,0xf0,0x6b,0x01,0x5f,0x9e,0xee,0x46,0x5f,0x2c,0xea,0x73,0xee,0x2b,
3965
0xea,0xea,0x03,0xd2,0x39,0x50,0xa5,0x98,0xcf,0x89,0x2d,0xe6,0x6a,0x4d,0x68,0x50,
3966
0xdc,0xe7,0xb4,0x80,0x8e,0x70,0x11,0xbc,0x06,0x13,0xe0,0x25,0x98,0x08,0xab,0xe1,
3967
0x76,0xf9,0x4f,0x85,0x17,0x60,0xad,0xfc,0x5f,0x95,0xff,0x3a,0x98,0x57,0xc2,0xe7,
3968
0x2c,0x85,0x17,0xe1,0x25,0x58,0x06,0xcb,0x61,0x6e,0x49,0xfc,0x4a,0xba,0xfa,0x12,
3969
0xc4,0x95,0xf2,0x39,0xb5,0xa1,0x6c,0xb6,0xcf,0xa9,0x00,0xe5,0x20,0x1a,0xca,0x43,
3970
0x25,0xb8,0x10,0x2a,0xca,0xbf,0xb2,0xfc,0xab,0xca,0x5d,0x45,0x7a,0x01,0xf4,0xec,
3971
0xe7,0x73,0x7a,0xf7,0x73,0xb5,0x97,0xf4,0x6a,0xa0,0x2a,0x9c,0x54,0x68,0x04,0x97,
3972
0xc2,0x95,0x22,0x1b,0x46,0xc3,0x53,0x62,0x91,0x58,0x2c,0x5e,0x14,0xe6,0x5e,0xb1,
3973
0xb9,0x9f,0x65,0xfe,0x14,0x9a,0xb9,0x0e,0xfa,0x8d,0xf1,0xe7,0xbc,0xf8,0x25,0xb1,
3974
0x14,0x56,0xc0,0x4a,0x78,0x19,0x5e,0x81,0x3b,0x39,0x7f,0xbe,0x0b,0xa6,0xc1,0xdd,
3975
0x30,0x17,0xe6,0xc1,0x2a,0x58,0x03,0x6f,0xc1,0x0e,0xd8,0x0d,0x9f,0x8b,0x2f,0x84,
3976
0x99,0xe7,0x06,0x98,0xb9,0xc4,0x5c,0xe7,0x33,0x73,0x88,0x18,0x6e,0xd6,0xc3,0xe6,
3977
0x1c,0x4a,0x5c,0x63,0xae,0xf7,0x99,0x6b,0x7d,0xe2,0x46,0x31,0x49,0x4c,0xd6,0xf9,
3978
0xf2,0xad,0xc2,0x9c,0xdb,0xce,0x34,0xc7,0x08,0xb3,0xfe,0x36,0x73,0xaa,0x99,0x77,
3979
0x58,0x3f,0x4f,0x80,0x49,0x70,0x33,0xd4,0x0c,0xb0,0x06,0x86,0x0e,0x70,0x09,0x74,
3980
0x82,0x2e,0x30,0x19,0x6e,0x81,0x5b,0x61,0x2a,0x2c,0x83,0x15,0x62,0x15,0xac,0x86,
3981
0x57,0xe0,0x55,0x58,0x1b,0x30,0xfd,0x8e,0x3e,0x0f,0xfb,0xe0,0x20,0x7c,0x09,0x45,
3982
0x59,0x6b,0x9f,0x07,0xe5,0xa1,0x21,0xa4,0x89,0x46,0xd0,0x1c,0x5a,0xc0,0x95,0xd0,
3983
0x05,0x7a,0x43,0x7f,0x18,0x00,0x03,0xc5,0x20,0xad,0xdb,0xdf,0x11,0xef,0x42,0x2e,
3984
0x6c,0x87,0xdd,0xf0,0x09,0xec,0x81,0x4f,0x61,0x2f,0xec,0x83,0x03,0xf0,0x05,0x1c,
3985
0x84,0x43,0x70,0x14,0xbe,0x85,0x63,0xf0,0xa3,0x28,0x1a,0xe9,0x52,0x4c,0x9c,0x05,
3986
0x35,0x21,0x0e,0x9a,0x43,0x4b,0x78,0x1c,0x9e,0x80,0x79,0x30,0x5f,0xac,0x84,0xd7,
3987
0x60,0x3d,0xec,0x83,0xfd,0x70,0x04,0xbe,0x82,0xaf,0xe1,0x5b,0xf1,0xbd,0x70,0x0a,
3988
0xb0,0xae,0x83,0xb3,0xa1,0x14,0x9c,0x27,0x4a,0x43,0x34,0x5c,0x20,0x2a,0x41,0x15,
3989
0xa8,0x2a,0x2e,0x84,0x18,0x48,0x83,0x4b,0xa0,0x13,0x74,0x86,0x2e,0x70,0x35,0x0c,
3990
0x84,0x49,0x70,0x13,0x4c,0x81,0x7b,0xe0,0x61,0x98,0x01,0xeb,0xe0,0x35,0xb1,0x1e,
3991
0x3e,0x86,0x5d,0xe0,0xe7,0x7c,0x26,0x4c,0x84,0x43,0x2a,0xd4,0x11,0x75,0x45,0x3d,
3992
0x51,0x5f,0x34,0x80,0x34,0x68,0x04,0xcd,0x20,0x13,0x2e,0x82,0x96,0xa2,0x15,0xb4,
3993
0x86,0x2c,0xd1,0x06,0x3a,0xc2,0x25,0x90,0x0d,0x5d,0xa1,0x1b,0xf4,0x80,0x01,0x30,
3994
0x48,0x0c,0x86,0xb1,0x30,0x4e,0x8c,0x87,0x09,0x30,0x11,0x6e,0x85,0x29,0x90,0x03,
3995
0x77,0xc2,0x2c,0x78,0x0a,0xe6,0xc1,0x02,0xf1,0x3c,0x2c,0x81,0xa5,0x62,0x99,0x30,
3996
0xe7,0x6f,0x2b,0x61,0x15,0xbc,0x02,0x6b,0x61,0x9d,0xce,0xe9,0xcc,0xf9,0xdc,0x46,
3997
0xf1,0x86,0x78,0x4f,0xe4,0xc2,0x87,0xb0,0x1d,0x3e,0x86,0x9d,0xb0,0x0b,0xf6,0xc0,
3998
0x41,0x38,0x04,0x87,0xe1,0x98,0xf8,0x41,0xf8,0x0a,0x52,0xaf,0x10,0x26,0x02,0x50,
3999
0x10,0x8a,0x40,0x51,0x28,0x0e,0x55,0xa1,0x1a,0xc4,0x41,0x02,0x24,0x42,0x32,0xa4,
4000
0x40,0x6d,0x48,0x85,0x7a,0xa2,0x01,0xa4,0x41,0x23,0x48,0x87,0x0c,0x68,0x06,0x2d,
4001
0xa0,0x25,0xb4,0x11,0x9d,0xe0,0x32,0xb8,0x42,0xf4,0x80,0x01,0x30,0x10,0x06,0xc1,
4002
0x60,0x18,0x0a,0xc3,0xc4,0x38,0x18,0x0f,0x13,0xc4,0x44,0xb8,0x0d,0xa6,0xc0,0x54,
4003
0xb8,0x13,0x66,0xc1,0x53,0x30,0x0f,0x16,0xc0,0x42,0x58,0x04,0x4b,0x60,0xa9,0x58,
4004
0x26,0x96,0xc3,0x4a,0x58,0x05,0xaf,0xc2,0x5a,0x58,0x07,0xaf,0x89,0x0d,0xf0,0x3a,
4005
0x6c,0x14,0x9b,0xc4,0x0e,0xf8,0x18,0x76,0xc2,0x2e,0xd8,0x03,0x07,0xe1,0xa8,0xf8,
4006
0x16,0x7e,0x04,0x5f,0x21,0x17,0x3f,0x84,0x41,0x00,0x0a,0x43,0x11,0x28,0x0a,0xc5,
4007
0xa1,0x2a,0x54,0x83,0x38,0x48,0x80,0x44,0x48,0x86,0x54,0xa8,0x27,0xea,0x8b,0x06,
4008
0xa2,0xa1,0x48,0x13,0x8d,0xa0,0x09,0x64,0xe8,0xfc,0xbe,0x85,0xce,0xef,0x5b,0x8a,
4009
0xb6,0x3a,0xf7,0xef,0x28,0x2e,0x83,0xcb,0xe1,0x4a,0xc8,0x86,0xae,0xd0,0x0d,0x7a,
4010
0xc0,0x00,0x18,0x24,0xc6,0x8b,0x09,0x62,0x22,0xdc,0x0c,0xb7,0x43,0x0e,0xdc,0x01,
4011
0xd3,0x60,0x3a,0xdc,0x07,0x0f,0x88,0x87,0xe0,0x61,0x78,0x14,0x1e,0x83,0x59,0xf0,
4012
0x14,0x3c,0x0b,0x4b,0x74,0x7d,0x61,0x05,0xac,0x14,0xab,0x60,0x35,0xac,0x81,0x75,
4013
0xba,0x16,0x61,0xae,0x43,0x6c,0x14,0x9b,0xc4,0x7b,0x62,0x0f,0x1c,0x2c,0x64,0x6e,
4014
0x7c,0xbb,0xf8,0x20,0x0c,0xc2,0x45,0x00,0x0a,0xc3,0x99,0x50,0x14,0xce,0x82,0xaa,
4015
0x50,0x0d,0x52,0xa1,0x9e,0xa8,0x2f,0x1a,0x40,0x1a,0x34,0x82,0x26,0xd0,0x54,0xd7,
4016
0x3d,0x9a,0x43,0x4b,0x68,0x5f,0xd8,0xbd,0x16,0x72,0x09,0x5c,0x0a,0x97,0xc1,0xe5,
4017
0xd0,0x05,0xb2,0xa1,0x2b,0x74,0x83,0x1e,0x30,0x00,0xc6,0x8a,0x71,0x62,0x3c,0x4c,
4018
0x80,0x89,0x70,0x2b,0xdc,0x0e,0x39,0x70,0x07,0xcc,0x82,0xa7,0x60,0x21,0x2c,0x82,
4019
0x25,0xb0,0x54,0x2c,0x13,0xcb,0xc5,0x0a,0x61,0xae,0xc5,0xbc,0x02,0x6b,0xc4,0x5a,
4020
0x5d,0x87,0x59,0xaf,0xeb,0x30,0xaf,0xc3,0x46,0x5d,0x97,0x31,0xd7,0x68,0x72,0xe1,
4021
0x23,0xd8,0x01,0x1f,0xc3,0x4e,0xd8,0x05,0x7b,0xe0,0x20,0x1c,0x86,0x2f,0xe1,0x88,
4022
0x70,0xce,0xa0,0x4e,0xc1,0x0f,0x61,0x10,0x0e,0x85,0xe1,0x4c,0x28,0x0a,0x67,0x41,
4023
0x1d,0xa8,0x0b,0xf5,0xa0,0xbe,0x30,0xd7,0x7b,0xd2,0xa0,0x11,0x34,0x81,0xa6,0xd0,
4024
0x4c,0xd7,0x84,0xcc,0xf5,0xa0,0x96,0xa2,0x95,0x68,0x07,0x1d,0x74,0xbd,0xc8,0x70,
4025
0x25,0x64,0x43,0x57,0xe8,0x06,0x3d,0x60,0x00,0x8c,0x86,0xeb,0x61,0x9c,0x18,0x0f,
4026
0x13,0x60,0x22,0xdc,0x0d,0xf7,0xc1,0x7c,0x58,0x08,0x2f,0xc1,0x32,0xb1,0x12,0xd6,
4027
0xe8,0x3a,0xd3,0x7a,0x5d,0x7f,0x7a,0x0b,0x36,0xc3,0xdb,0xf0,0xae,0xd8,0xaa,0x6b,
4028
0x52,0x7b,0xe0,0x20,0x7c,0x09,0x47,0x4c,0x1d,0x9c,0xc9,0xb8,0x84,0x78,0x91,0x00,
4029
0x89,0x90,0x04,0x75,0x20,0x0d,0x82,0xd0,0x54,0x64,0x40,0x2b,0xc8,0x82,0x4e,0x30,
4030
0x0e,0xc6,0xc3,0x0d,0xe2,0x46,0xb8,0x19,0x6e,0x85,0x47,0xe1,0x71,0xf1,0x24,0xcc,
4031
0x83,0xf9,0x62,0x01,0x2c,0x84,0xe7,0x60,0x29,0x2c,0x13,0x2b,0xe1,0x15,0x58,0x23,
4032
0xd6,0xc1,0x1b,0xb0,0x09,0xde,0x87,0x5c,0xd8,0x0e,0x4e,0x11,0x97,0x73,0xa1,0x14,
4033
0x94,0x87,0x0b,0x21,0x59,0xd4,0x12,0xa9,0xa2,0x01,0x34,0x84,0x34,0xc8,0x80,0x4c,
4034
0xe8,0x0b,0x83,0xe0,0x3a,0xb8,0x5e,0x8c,0x85,0x1b,0xe0,0x46,0x98,0x04,0x93,0xe1,
4035
0x56,0xb8,0x0d,0xee,0x81,0xe9,0xb0,0x14,0xd6,0x08,0xa7,0x28,0x63,0x0e,0xaa,0x43,
4036
0x0d,0x88,0x81,0x38,0x88,0x17,0x09,0x50,0x0b,0x6a,0x8b,0x54,0xa8,0x03,0x75,0xa1,
4037
0x1e,0xd4,0x87,0x06,0xd0,0x50,0xa4,0x41,0x26,0x64,0x41,0x7b,0xe8,0x00,0x1d,0xe1,
4038
0x12,0xe8,0x04,0x97,0xc2,0xe5,0x70,0x05,0x74,0x81,0x6c,0xd1,0x15,0xae,0x82,0xee,
4039
0xd0,0x03,0x7a,0x42,0x3f,0xe8,0x0f,0x03,0x61,0x10,0x0c,0x85,0x61,0x30,0x0e,0xc6,
4040
0x8b,0x09,0x70,0x03,0x4c,0x84,0x1b,0x61,0x12,0xdc,0x0a,0xb7,0x89,0xdb,0xc5,0x14,
4041
0x91,0x03,0xd3,0xe1,0x3e,0x78,0x00,0x1e,0x14,0x33,0xe0,0x55,0x58,0x2b,0x36,0x8a,
4042
0x4d,0xf0,0x2d,0x1c,0x13,0xdf,0xc3,0x8f,0xe0,0x14,0x63,0xdc,0x9c,0xc5,0xb8,0x81,
4043
0x96,0x90,0x05,0x1d,0xe0,0x12,0x71,0x29,0x5c,0x0e,0x5d,0x60,0x32,0xdc,0x0c,0xb7,
4044
0x41,0x0e,0xcc,0x83,0x05,0xb0,0x08,0x5e,0x80,0xe5,0xb0,0x52,0xac,0x86,0x57,0x61,
4045
0x1d,0xbc,0x0b,0x5b,0xa1,0x68,0x71,0xc6,0x33,0x94,0x84,0x73,0xe1,0x52,0xb8,0x1c,
4046
0xae,0x84,0xde,0x30,0x08,0xc6,0xc2,0x14,0x98,0x01,0x5f,0xc3,0x37,0xf0,0x3d,0xf8,
4047
0x4a,0xd0,0x4f,0xce,0x66,0x8c,0xc2,0xf5,0x30,0x0e,0xee,0x83,0x19,0xb0,0x0f,0xbe,
4048
0x80,0x43,0x70,0x18,0xbe,0x01,0xe7,0x1c,0x8a,0x06,0x67,0x41,0x09,0x28,0x29,0xca,
4049
0x41,0x3c,0x24,0x40,0x22,0x24,0x89,0x34,0x68,0x03,0x17,0x43,0x5b,0xe8,0x02,0x7d,
4050
0xa1,0x3f,0x0c,0x84,0xc1,0x30,0x04,0xc6,0xc2,0x42,0x78,0x0e,0x16,0xc1,0xf3,0x62,
4051
0x31,0x2c,0x83,0xe5,0xf0,0x2a,0xac,0x11,0x6b,0x61,0x1d,0xbc,0x06,0x5b,0xe0,0x3d,
4052
0x91,0x2b,0x3e,0x14,0x3b,0xe0,0x33,0x28,0x74,0x2e,0x53,0x22,0x14,0x11,0x45,0xa1,
4053
0x14,0x94,0x87,0x74,0x68,0x2c,0x9a,0xc0,0x48,0x18,0x0b,0x37,0xc0,0x44,0xb8,0x11,
4054
0x26,0xc1,0x2c,0x98,0x2d,0x9e,0x12,0xf3,0xe0,0x6b,0x70,0x4a,0x39,0x4e,0x59,0x28,
4055
0x0f,0x15,0x21,0x1a,0x2a,0x43,0x15,0xa8,0x0a,0x17,0x42,0x75,0x88,0x83,0x78,0x48,
4056
0x10,0x89,0x50,0x1b,0x52,0xa1,0x2e,0x34,0x85,0xd6,0x90,0x05,0xfd,0x60,0x20,0x0c,
4057
0x85,0xb1,0x30,0x07,0xe6,0xc1,0x6b,0xb0,0x09,0xde,0x87,0x0f,0x84,0x73,0x1e,0x6b,
4058
0x7b,0x38,0x07,0xce,0x85,0x52,0x70,0x1e,0x94,0x16,0xe5,0xa1,0x1d,0xb4,0x17,0x1d,
4059
0x44,0x47,0x71,0x09,0x5c,0x01,0x5d,0x44,0xb6,0xe8,0x2a,0xba,0xc1,0x55,0xd0,0x1d,
4060
0xfa,0x42,0x3f,0x18,0x0c,0x43,0x60,0x0c,0x5c,0x2f,0xc6,0xc2,0x4d,0x90,0x03,0xd3,
4061
0xe1,0x49,0x31,0x0f,0x96,0xc1,0x0a,0x38,0x04,0x4e,0x69,0x8e,0x4b,0xe6,0xba,0xbe,
4062
0x08,0x40,0x22,0x24,0x89,0x64,0x91,0x02,0x75,0x74,0x8f,0xc0,0x50,0x4f,0xd4,0xd7,
4063
0xfd,0x81,0x74,0x61,0xee,0x11,0x34,0x81,0x20,0x5c,0x04,0x59,0xd0,0x09,0xfa,0xc0,
4064
0x10,0x18,0x0b,0xe3,0x60,0xbc,0x98,0x00,0x33,0x60,0xa6,0x78,0x04,0x1e,0x87,0x27,
4065
0xe0,0x49,0x98,0x05,0xb3,0xe1,0x29,0x31,0x07,0x9e,0x81,0x67,0x61,0x2e,0xcc,0x83,
4066
0x25,0xf0,0x22,0x7c,0x02,0x7b,0xc4,0xa7,0x62,0x2f,0x7c,0x06,0xfb,0xe0,0x73,0x38,
4067
0x20,0xbe,0x10,0x07,0xe1,0x30,0x7c,0x09,0x47,0xc0,0x39,0x9f,0x3e,0x03,0x17,0x40,
4068
0x75,0xa8,0x01,0x89,0x90,0x04,0xc9,0x90,0x02,0xb5,0x20,0x0d,0x32,0xa1,0x25,0xb4,
4069
0x86,0x2c,0xe8,0x04,0x97,0xc2,0x08,0x18,0x09,0xd7,0xc2,0x58,0xb8,0x19,0x72,0xe0,
4070
0x45,0x58,0x06,0x2b,0x60,0x13,0x6c,0x86,0xb7,0x61,0x07,0x7c,0x2c,0x76,0xc2,0x5e,
4071
0xf8,0x0c,0x3e,0x87,0x03,0xe2,0x0b,0x38,0x02,0x5f,0x89,0xaf,0xe1,0x5f,0xf0,0x6f,
4072
0xf1,0x0d,0x1c,0x85,0x6f,0x85,0x53,0x86,0xfc,0x43,0x0d,0xb8,0x1a,0xfa,0xc0,0x08,
4073
0x18,0x29,0x46,0xc1,0x7d,0x70,0x3f,0xac,0x80,0x95,0xf0,0x63,0x19,0xf7,0x19,0x75,
4074
0x73,0xdf,0xc1,0xdc,0xa3,0x37,0xf7,0x17,0xcc,0xbd,0x63,0x73,0x1d,0xdc,0xdc,0x33,
4075
0x37,0xd7,0xbb,0xcd,0x3d,0x59,0x73,0x1d,0xbb,0x93,0xe8,0x2c,0x2e,0x17,0xe6,0x5a,
4076
0xf6,0xb5,0xe5,0xdc,0x7b,0x33,0xe6,0xbe,0xb7,0xb9,0x77,0x6d,0x9e,0x03,0x58,0x2e,
4077
0xcc,0xb5,0x5f,0x73,0x1f,0xdc,0xdc,0x83,0x36,0xf7,0xf5,0xcd,0x3d,0xe6,0x2d,0xe5,
4078
0xdc,0x7b,0xc9,0xdb,0xca,0xb9,0xf7,0x80,0xcd,0xfd,0x78,0x73,0x6d,0xd8,0xdc,0x87,
4079
0x35,0xf7,0x72,0xcd,0x7d,0xf4,0xc2,0xe5,0x99,0x37,0xa0,0x21,0xa4,0x41,0x3b,0x31,
4080
0x48,0x5c,0x2f,0xa6,0xc0,0xc3,0xb0,0x09,0x72,0xe1,0x63,0xf1,0x09,0x1c,0x02,0x7f,
4081
0x05,0x97,0x48,0x51,0x10,0x8a,0x43,0x49,0x71,0xae,0x28,0x05,0x65,0xe0,0x02,0x51,
4082
0x59,0x54,0x15,0xd5,0x20,0x06,0x62,0x45,0x4d,0x48,0x82,0x64,0x73,0x6d,0x19,0x52,
4083
0x45,0x3d,0x68,0x08,0x41,0xc8,0x84,0x56,0xa2,0x0b,0x8c,0x87,0x09,0x70,0x03,0x4c,
4084
0x84,0xc9,0xe0,0xd4,0x70,0x9c,0x6b,0x60,0x0c,0x5c,0x0b,0xd7,0xc1,0x6e,0xd8,0x0f,
4085
0x5f,0xc0,0x41,0x38,0x0c,0x5f,0xc2,0x11,0x70,0x62,0x1c,0xa7,0x12,0x54,0x11,0x31,
4086
0x22,0x0e,0x7a,0xc2,0x00,0x71,0xbd,0x18,0x0b,0x77,0xc3,0x0c,0x78,0x02,0x66,0xc1,
4087
0xb3,0x30,0x0f,0x9e,0x87,0x17,0x60,0x39,0xac,0x84,0x35,0xb0,0x0e,0xde,0x80,0x4d,
4088
0xf0,0x2e,0x6c,0x85,0x8f,0x60,0x07,0xfc,0x08,0x81,0x38,0x97,0x08,0x11,0x29,0x2a,
4089
0xc0,0x85,0x50,0x0d,0x62,0x20,0x16,0x6a,0x42,0x3c,0x24,0x43,0x6d,0xa8,0x03,0x75,
4090
0x45,0x3d,0xd1,0x08,0xee,0xd6,0xf5,0x4b,0x73,0xad,0xf3,0x7e,0x78,0x00,0x1e,0xd4,
4091
0x75,0xdc,0x87,0xc5,0x4c,0x5d,0xe7,0xfc,0x4e,0x1c,0xd3,0xf5,0xce,0x1f,0x45,0x20,
4092
0x9e,0xf4,0x20,0x1e,0x6e,0x87,0x19,0xb0,0x02,0x0e,0xc1,0x8f,0xe0,0x24,0xe1,0x6e,
4093
0x89,0xb6,0xe2,0xf8,0x39,0x83,0xb6,0x17,0x67,0xc3,0xad,0x8f,0x51,0x5e,0xf8,0x37,
4094
0x7c,0x03,0xdf,0x83,0xf3,0x38,0xc7,0xae,0x27,0xe8,0x87,0xa2,0x28,0x94,0x83,0xf2,
4095
0x70,0x21,0x54,0x83,0xea,0x90,0x06,0xfd,0xa0,0xbf,0x18,0x20,0x86,0xc2,0xb5,0x70,
4096
0xbd,0x18,0x0b,0xf7,0xc3,0x03,0xf0,0x20,0x3c,0x04,0x0f,0xc3,0x0c,0xf8,0x04,0xf6,
4097
0xc0,0x41,0x38,0x04,0x87,0xe1,0x9c,0x27,0x49,0x0f,0x2a,0xc2,0x00,0x18,0x28,0x06,
4098
0xc1,0x24,0x98,0x2c,0x6e,0x81,0xdb,0x61,0x8a,0xc8,0x81,0x0f,0x61,0xa7,0x38,0x0c,
4099
0x5f,0xc1,0xd7,0xf0,0x2f,0xf8,0xb7,0xf8,0x06,0x8e,0xc2,0xb7,0xe2,0x3b,0xf0,0xcd,
4100
0x62,0xac,0x88,0x30,0x08,0x40,0x84,0x88,0x84,0x82,0x50,0x48,0x14,0x86,0x8a,0x10,
4101
0x0d,0x17,0x40,0x25,0xa8,0x0c,0x55,0x44,0x0d,0x91,0x06,0x43,0x60,0x2c,0x8c,0x83,
4102
0xf1,0xb0,0x10,0x9e,0x83,0x97,0xe1,0x15,0x78,0x15,0x36,0xc1,0xfb,0xb0,0x03,0x0e,
4103
0xc3,0x97,0xf0,0x6f,0xf8,0x4e,0x7c,0x0f,0x3f,0xc0,0x8f,0xc2,0x99,0xed,0x38,0x51,
4104
0x50,0x10,0x2a,0x41,0x65,0x88,0x81,0x38,0x68,0x0a,0x19,0xd0,0x06,0x2e,0x86,0xb6,
4105
0xd0,0x05,0xc6,0xc0,0x58,0x18,0x0f,0x13,0xc4,0x0d,0xb0,0x00,0x16,0x8a,0xe7,0x60,
4106
0x11,0x3c,0x0f,0x4b,0xe0,0x45,0x78,0x09,0x96,0xc2,0x32,0x58,0x0e,0x2b,0xe1,0x4d,
4107
0xb1,0x09,0xde,0x87,0x1d,0xb0,0x1b,0x3e,0x11,0x7b,0xc4,0xa7,0x70,0x10,0x0e,0xc1,
4108
0x51,0xf8,0x16,0x7e,0x98,0xed,0x5e,0x7c,0xae,0x0a,0x17,0x42,0x2c,0xd4,0x84,0x38,
4109
0x88,0x87,0x04,0x48,0x84,0x24,0x48,0x86,0x14,0x48,0x83,0x74,0x68,0x2c,0x9a,0x40,
4110
0x0b,0xb8,0x48,0xb4,0x14,0x59,0xd0,0x09,0xba,0xc0,0x00,0x18,0x28,0x06,0xc1,0x70,
4111
0x18,0x2d,0xae,0x11,0x63,0xc4,0xb5,0xe2,0x3a,0x98,0x0b,0xf3,0xc4,0x7c,0xb1,0x00,
4112
0x9e,0x83,0x45,0xf0,0x3c,0x2c,0x86,0x17,0x60,0x09,0x2c,0x83,0xe5,0xb0,0x02,0x56,
4113
0x8a,0x55,0x62,0xb5,0xd8,0x06,0xb9,0xf0,0xa1,0xd8,0x01,0xfb,0x60,0xbf,0xf8,0x1c,
4114
0x0e,0xc0,0x17,0x70,0x10,0xbe,0x14,0x47,0xe0,0x2b,0xf8,0x5a,0xfc,0x4b,0xf8,0xe6,
4115
0xd0,0x2f,0x21,0x0a,0xce,0x84,0x62,0x70,0x36,0x94,0x87,0xca,0x50,0x15,0x62,0x21,
4116
0x0e,0x2e,0x85,0xcb,0xe0,0x4a,0xe8,0x02,0xbd,0xa0,0xb7,0xe8,0x0b,0xfd,0x60,0x20,
4117
0xac,0x80,0x95,0xb0,0x13,0x76,0xc1,0x6e,0xf8,0x44,0xec,0x81,0x4f,0x61,0xaf,0xf8,
4118
0x0c,0xf6,0xc1,0xe7,0xe2,0x80,0x38,0x04,0x47,0xc1,0x79,0x9a,0xf3,0xd4,0xf7,0xa8,
4119
0x43,0x58,0x03,0x1b,0xe0,0x3b,0x30,0x0f,0x11,0xf7,0xfb,0x96,0xf4,0xe0,0x7d,0xf3,
4120
0x20,0xf1,0x77,0x94,0x03,0x8a,0xc3,0x39,0x50,0x46,0x94,0x15,0xe5,0xa0,0x2a,0x54,
4121
0x83,0x14,0xa8,0x0d,0xf5,0xa0,0x81,0x48,0x83,0x46,0xd0,0x18,0x9a,0x40,0x53,0x98,
4122
0x0f,0x5b,0xa0,0xfe,0xf7,0xf4,0x07,0x98,0x02,0x77,0xc0,0x5a,0x38,0x04,0xdf,0x99,
4123
0x07,0x7a,0x7f,0x60,0x3d,0x0e,0xe5,0xa1,0x26,0x24,0x42,0x12,0xb4,0x84,0xd6,0x30,
4124
0x10,0x86,0xc2,0x70,0x38,0x06,0x45,0x7f,0xe4,0x18,0x09,0x15,0xa0,0x0e,0x34,0x14,
4125
0x8d,0xe0,0x52,0xe8,0x2e,0x7a,0xc0,0x00,0x18,0x28,0x06,0xc1,0x83,0xf0,0x10,0x3c,
4126
0x0c,0x33,0x60,0x39,0xac,0x86,0xb5,0xb0,0x1e,0xde,0x84,0xcd,0xf0,0x1e,0x7c,0x00,
4127
0xb9,0xe6,0x41,0x62,0xc7,0xe7,0x14,0x82,0x33,0xa0,0x32,0x54,0x85,0x3a,0x50,0x0f,
4128
0xea,0x43,0x43,0x68,0x09,0x59,0x70,0x39,0x8c,0x85,0x6f,0x21,0xcd,0xe7,0x73,0x86,
4129
0xc2,0xf7,0x62,0xac,0xdf,0xe7,0x3c,0x00,0x33,0x60,0x13,0xec,0x10,0xe6,0xe5,0x90,
4130
0x72,0x10,0x03,0x69,0xd0,0x48,0xa4,0x43,0x26,0x34,0x17,0x59,0x30,0x0c,0x86,0xc3,
4131
0x68,0x18,0x0b,0x0f,0xc2,0x0c,0x78,0x19,0xd6,0xc1,0x9b,0xf0,0x16,0xbc,0x63,0x5e,
4132
0x38,0x09,0xf7,0x39,0xad,0x21,0x0b,0x1e,0x84,0x19,0x30,0x1b,0xe6,0xc1,0x16,0xd8,
4133
0x0a,0xdf,0x99,0x17,0x02,0x03,0x3e,0xa7,0x0a,0xc4,0x41,0x37,0x18,0x08,0xa3,0x61,
4134
0x0c,0xdc,0x0c,0xb7,0xc2,0x1d,0x70,0x17,0x4c,0x83,0x7b,0x60,0x26,0x3c,0x0a,0xf3,
4135
0x61,0x21,0x2c,0x81,0x97,0x60,0x29,0xac,0x84,0x23,0xe6,0x05,0x95,0x08,0x9f,0x93,
4136
0x12,0x49,0x99,0xa0,0x3d,0x74,0x81,0x9e,0x30,0x16,0x26,0xc2,0x24,0x98,0x07,0x0b,
4137
0x60,0x85,0x79,0x61,0xa5,0x80,0xcf,0x09,0x40,0x01,0x51,0x10,0x92,0xa1,0x16,0xd4,
4138
0x86,0x7a,0xa2,0x21,0xb4,0x87,0x2e,0x30,0x1c,0xc6,0xc2,0x43,0xb0,0x03,0xbe,0x84,
4139
0xaf,0xe0,0x6b,0xf3,0x02,0x63,0x94,0xcf,0x29,0x09,0xe5,0x21,0x15,0xd2,0xa0,0x13,
4140
0x8c,0x85,0xc5,0xb0,0x1c,0x56,0x98,0x17,0x64,0x0a,0xba,0xf8,0x20,0x0c,0x02,0x10,
4141
0x01,0x85,0xa1,0x08,0x14,0x85,0xe2,0x50,0x12,0xce,0x81,0x52,0x90,0x0c,0xb5,0xa1,
4142
0x0e,0x34,0x14,0x5d,0x60,0x0c,0x8c,0x85,0x07,0x60,0x25,0xac,0x85,0xd7,0x60,0x37,
4143
0x7c,0x02,0x7b,0x4c,0x5a,0x85,0xd8,0x1f,0xd2,0xa0,0x3d,0x74,0x81,0xc1,0x30,0x16,
4144
0xa6,0xe6,0xbd,0xa8,0xe3,0x73,0x9a,0xc1,0x58,0x58,0x00,0x2b,0xe1,0x4b,0xf3,0x02,
4145
0xe6,0x19,0x3e,0x27,0x1a,0x2e,0x80,0x2a,0x10,0x07,0xa9,0x90,0x06,0x99,0xd0,0x1c,
4146
0x5a,0x42,0x2b,0xd1,0x5a,0x64,0x41,0x77,0xe8,0x0d,0xfd,0x60,0x80,0x18,0x08,0x13,
4147
0x61,0xec,0x99,0xf4,0x0b,0x98,0x03,0x4f,0xc3,0x3c,0x98,0x0f,0xab,0xe1,0x15,0x78,
4148
0x55,0xac,0x81,0xb5,0xb0,0x01,0xde,0x84,0xf7,0xe1,0x0b,0x38,0x04,0x3f,0x9a,0x17,
4149
0x41,0x8b,0xf8,0x9c,0xf3,0xa1,0x8a,0x88,0x83,0x20,0x34,0x85,0x2c,0x18,0x08,0xe3,
4150
0x60,0x3c,0x4c,0x84,0x79,0xf0,0x0a,0xec,0x80,0x7f,0x99,0x17,0x90,0x8a,0xba,0xf8,
4151
0x84,0x5f,0x84,0x41,0x2d,0xa8,0x0d,0x4d,0xa1,0x07,0x0c,0x80,0x81,0x62,0x10,0x0c,
4152
0x86,0x21,0x30,0x14,0x86,0x89,0xeb,0x61,0x1c,0x8c,0x17,0x13,0x60,0x2e,0xcc,0x83,
4153
0x05,0xb0,0x10,0x9e,0x87,0xc5,0xf0,0x02,0x2c,0xd1,0x3d,0xe9,0xd5,0x62,0x13,0xec,
4154
0x85,0x43,0x70,0xd4,0xe4,0xad,0x18,0xf9,0x81,0x30,0xa8,0xac,0xfb,0xd5,0xd5,0xa1,
4155
0x86,0x88,0x81,0x24,0x48,0x81,0x86,0xd0,0x44,0x04,0xa1,0x29,0x64,0x88,0x2c,0x18,
4156
0x0c,0x43,0xc4,0x70,0x31,0x16,0xc6,0xc1,0x78,0x31,0x01,0x16,0xc0,0x42,0x58,0x04,
4157
0xcf,0xc3,0x72,0x58,0x01,0x2b,0x61,0x15,0xbc,0x02,0xaf,0xc1,0xeb,0xf0,0x86,0x78,
4158
0x53,0x6c,0x82,0xf7,0xe1,0x03,0x91,0x2b,0xcc,0xcb,0xb6,0xc5,0xa0,0x38,0x54,0x87,
4159
0x1a,0x10,0x0b,0x35,0x21,0x1e,0x12,0x20,0x11,0x92,0x44,0xb2,0x48,0x81,0x5a,0xd0,
4160
0x40,0x34,0x84,0x34,0x68,0x24,0xc6,0xc2,0x8d,0x30,0x59,0xdc,0x0c,0xb7,0xc1,0x14,
4161
0x78,0x10,0x1e,0x86,0x59,0x30,0x0f,0x3e,0x82,0xed,0x62,0x07,0xec,0x84,0x5d,0xb0,
4162
0x0f,0x0e,0xc1,0x51,0xf3,0x42,0x70,0x71,0xfa,0x01,0xf8,0x21,0x0c,0x02,0x50,0x18,
4163
0x8a,0x40,0x51,0x28,0x0e,0x55,0xa1,0x1a,0xc4,0x41,0x02,0x24,0x42,0x32,0xa4,0x42,
4164
0x5d,0xa8,0x07,0xf5,0x85,0x79,0xae,0xa0,0x21,0xa4,0x89,0x46,0xd0,0x04,0x32,0xa0,
4165
0x99,0x9e,0x39,0x68,0x09,0x59,0xa2,0xa3,0xb8,0x1c,0xb2,0xa1,0x2b,0x74,0x83,0x1e,
4166
0xd0,0x17,0x06,0xc2,0x50,0x18,0x0b,0x37,0xc1,0x2d,0xe2,0x76,0x91,0x03,0x8b,0x60,
4167
0xb1,0x30,0xcf,0x29,0xbc,0xa8,0xe7,0x18,0x56,0xea,0x79,0x05,0xef,0x99,0x85,0x57,
4168
0xf5,0x0c,0xc3,0x7a,0x78,0x1d,0x36,0xc2,0x1b,0xe2,0x4d,0xb1,0x49,0xbc,0x25,0x36,
4169
0x8b,0x2d,0xe2,0x63,0xd8,0x69,0x5e,0xc0,0x2b,0x41,0xbb,0x41,0x32,0xd4,0x82,0xda,
4170
0xd0,0x10,0xd2,0xa0,0x11,0xa4,0x43,0x13,0x08,0x8a,0xa6,0x22,0x03,0x9a,0x43,0x16,
4171
0x74,0x82,0x2b,0xc4,0x95,0x90,0x0d,0x63,0xcd,0xb3,0x13,0x25,0xdc,0xe7,0x2a,0x16,
4172
0xc0,0x42,0x78,0x01,0x96,0x88,0x17,0xad,0x67,0x2d,0xcc,0x73,0x16,0x2b,0x60,0x25,
4173
0xac,0x12,0xab,0xe1,0x65,0x78,0x05,0x5e,0x85,0xb5,0x62,0x13,0xbc,0x6f,0xe2,0x2f,
4174
0xe9,0x73,0x9e,0xd5,0x73,0x19,0xf3,0x61,0x01,0x2c,0x82,0x17,0xf4,0x9c,0xc6,0x52,
4175
0x58,0x06,0xcb,0xc5,0x0a,0x58,0x09,0x5b,0x61,0x1b,0xe4,0xc2,0x87,0xe6,0xc5,0xc3,
4176
0xb3,0xe9,0xcb,0x10,0x07,0x09,0x90,0x08,0x75,0xa0,0x2e,0xd4,0x83,0xfa,0xa2,0x81,
4177
0x68,0x08,0x69,0xd0,0x44,0x64,0x41,0x27,0x18,0x0b,0x4f,0xc1,0x1c,0xf1,0xb4,0x78,
4178
0x46,0x3c,0x0b,0x73,0x61,0x1e,0x2c,0x82,0xe7,0xc5,0x62,0xf1,0x82,0x58,0x09,0xaf,
4179
0xc1,0x26,0xd8,0x65,0x5e,0x6c,0x3f,0xc7,0xe7,0x9c,0x07,0x65,0x44,0x59,0x51,0x4e,
4180
0x94,0x87,0x0a,0x50,0x11,0x2a,0x41,0x65,0x51,0x05,0xaa,0x43,0x1c,0xa4,0x42,0x1a,
4181
0x34,0x35,0x2f,0x58,0x9e,0x8b,0x3f,0xd4,0x80,0x58,0xa8,0x09,0xb5,0xa0,0xb6,0x48,
4182
0x85,0x3a,0x30,0x03,0xb6,0xc3,0x0e,0xf8,0x0c,0x7e,0x84,0x88,0x52,0x3e,0x27,0x4a,
4183
0x14,0x86,0xe2,0x50,0x12,0xce,0x86,0x73,0xa1,0x66,0x29,0xf7,0xf9,0x98,0x64,0xa8,
4184
0xa5,0xe7,0x64,0xea,0x42,0x3d,0xa8,0x2f,0x1a,0x88,0x86,0x22,0x4d,0x34,0x12,0xe9,
4185
0xa2,0xb1,0xc8,0x82,0x4e,0x30,0x03,0x9e,0x84,0xa7,0x60,0x13,0xbc,0x05,0x5b,0xe0,
4186
0x6d,0x78,0x0f,0x3e,0x80,0x6d,0x90,0x0b,0xdb,0x61,0x87,0xf8,0x58,0xec,0x12,0xbb,
4187
0x45,0xde,0xc7,0x01,0xc0,0x07,0x05,0xa1,0x10,0x24,0x40,0x22,0xd4,0x86,0x54,0x51,
4188
0x47,0xd4,0x85,0x06,0x90,0x21,0xb2,0x44,0x1b,0xe8,0x00,0x1d,0xe1,0x12,0xe8,0x04,
4189
0x9d,0xe1,0x32,0xb8,0x09,0x6e,0x86,0xbb,0xe1,0x1e,0x71,0x2f,0x4c,0x87,0x07,0xc5,
4190
0x3c,0xf8,0xc6,0xe4,0xa1,0xb4,0x4b,0x17,0x91,0x2d,0xba,0xc2,0x55,0xd0,0x5d,0xf4,
4191
0x10,0x3d,0xc5,0x4a,0xd8,0x01,0x87,0xe0,0xa8,0x79,0x51,0xf6,0x7c,0xd6,0x43,0x50,
4192
0x10,0x62,0xa1,0xa6,0x88,0x83,0x14,0xa8,0x0d,0xf5,0xa1,0x81,0x68,0x28,0xd2,0x44,
4193
0x16,0x74,0x82,0xc1,0x30,0x05,0xee,0x80,0x27,0x61,0xb6,0x78,0x0a,0xe6,0xc1,0x7c,
4194
0xb1,0x00,0x16,0xc2,0x73,0x62,0x11,0x3c,0x6f,0x3e,0x94,0x50,0x86,0xfe,0x02,0x05,
4195
0x20,0x0a,0x0a,0x41,0x1c,0xc4,0x43,0x0a,0xd4,0x11,0xf5,0xa0,0x3e,0x34,0x84,0x20,
4196
0x34,0x15,0x19,0x22,0x0b,0x3a,0x41,0x17,0xe8,0x0e,0x3d,0xa1,0x17,0x5c,0x0d,0x37,
4197
0xc1,0xcd,0x70,0x3b,0xe4,0xc0,0x54,0xb8,0x13,0xee,0x82,0x69,0xe2,0x6e,0x71,0x8f,
4198
0xb8,0x57,0xcc,0x80,0xd9,0x30,0x0f,0xb6,0xc2,0xfb,0xe2,0x03,0xd8,0x06,0x3b,0xe0,
4199
0x33,0x38,0x24,0x0e,0x8b,0x1d,0x65,0x59,0x5f,0xc1,0x11,0xf8,0x0a,0xbe,0x86,0x7f,
4200
0x99,0x0f,0x41,0x94,0xa3,0x2f,0x81,0x5f,0x84,0x89,0x70,0x28,0x0a,0x67,0x41,0x22,
4201
0x24,0x41,0x32,0xa4,0x40,0x1d,0x68,0x00,0x0d,0x21,0x4d,0x34,0x12,0xe9,0x22,0x0b,
4202
0x3a,0xc1,0xa5,0x62,0x9e,0x30,0x1f,0x9d,0x98,0x6e,0x5e,0x50,0xbe,0x80,0xf5,0x0d,
4203
0x0c,0x83,0xeb,0x61,0x2c,0x34,0xae,0xc4,0x7e,0x70,0x63,0x65,0xea,0xa5,0x26,0xf9,
4204
0xcf,0x7b,0x41,0x98,0x7e,0x90,0x44,0x1a,0xa2,0x11,0x34,0x85,0x0c,0x68,0x0f,0x5d,
4205
0xe0,0x5b,0xf3,0x01,0x86,0x26,0xf8,0x9b,0x17,0x72,0xb3,0x99,0x6f,0xb2,0xdd,0xe7,
4206
0xdc,0xcc,0x33,0x6d,0xd5,0xa0,0x06,0xc4,0x40,0x4d,0x88,0x83,0x54,0xf3,0xe2,0x6a,
4207
0x2f,0xfa,0xd4,0xd5,0xc4,0x09,0x57,0x40,0x17,0xe8,0x0d,0x03,0x61,0x39,0xac,0x84,
4208
0xd7,0x60,0x13,0x1c,0x80,0x43,0xf0,0x95,0xf9,0x90,0x40,0x1f,0xe2,0x81,0x38,0x48,
4209
0x81,0x34,0x68,0x0c,0x59,0xd0,0x09,0xba,0xc1,0x08,0xb8,0x16,0xa6,0x98,0xed,0xfd,
4210
0xa8,0x0f,0x68,0xac,0xe7,0xe4,0xfa,0x40,0x5f,0x18,0x08,0xa3,0x20,0xad,0x3f,0xe5,
4211
0x87,0x19,0xf0,0x02,0xbc,0x04,0x5b,0xcc,0x07,0x09,0x06,0x70,0x9c,0x82,0xd6,0x22,
4212
0x4b,0xb4,0x81,0x49,0x30,0x05,0xee,0x80,0x3b,0xe1,0x61,0xd8,0x01,0x1f,0xc3,0x2e,
4213
0xb1,0x5b,0x1c,0x82,0xc3,0xf0,0x25,0x1c,0x81,0xaf,0xe0,0x5f,0xe6,0xc5,0xd8,0x81,
4214
0xf4,0x99,0x5b,0x99,0x1f,0xa1,0xfc,0x6d,0xd4,0x3f,0x7c,0x09,0xce,0xed,0xf4,0xc7,
4215
0xa9,0xe4,0x07,0x36,0xc3,0xa1,0xb9,0xec,0x07,0x5f,0xc3,0x77,0xf0,0x3d,0xfc,0x60,
4216
0x3e,0x84,0x30,0x8f,0x75,0xc9,0x7c,0xe6,0x1e,0x91,0x05,0x17,0x43,0x7b,0x71,0x15,
4217
0xf4,0x82,0x81,0xf0,0xdd,0x02,0xf7,0x01,0xbe,0xab,0x61,0x20,0x8c,0x81,0xb1,0x30,
4218
0x19,0x72,0x60,0x3a,0x3c,0x08,0x0f,0xc1,0xa1,0xd7,0x99,0x0f,0xc0,0x7c,0x04,0x24,
4219
0x06,0xe2,0xa0,0x29,0x54,0x79,0x8b,0xf4,0xa0,0x3b,0xf4,0x80,0x9e,0xd0,0x1b,0xfa,
4220
0xc1,0x60,0xb8,0x06,0xc6,0xc3,0x44,0xb8,0x05,0x9e,0x82,0x67,0x20,0x7d,0x33,0xc7,
4221
0x3b,0xc8,0x82,0x8b,0xa1,0x33,0x5c,0x06,0x57,0x8a,0xb1,0x30,0xce,0xbc,0x60,0xfd,
4222
0xb6,0xcf,0x69,0x07,0x1d,0xe0,0x01,0x78,0x08,0x1e,0x86,0x47,0xc4,0xe3,0xf0,0x04,
4223
0xcc,0x86,0xa7,0xe1,0x59,0x58,0x02,0x2f,0x89,0x65,0xf0,0x32,0xbc,0x0a,0x81,0x77,
4224
0x7c,0x4e,0x24,0x14,0x84,0x33,0xa0,0x04,0x9c,0x0d,0xe7,0x43,0x59,0x48,0x85,0xba,
4225
0xd0,0x00,0xd2,0xa0,0x09,0x34,0x15,0xcd,0x21,0x0b,0x2e,0x86,0x27,0xde,0x65,0x2d,
4226
0x09,0x2b,0x61,0x35,0x7c,0x00,0xb9,0xf0,0x2d,0x1c,0x83,0x12,0xef,0x11,0x2f,0x24,
4227
0x41,0x0a,0xb4,0x82,0x2c,0xe8,0x0f,0x03,0x61,0x32,0xdc,0x0c,0xb3,0xe0,0x29,0x58,
4228
0x0d,0xaf,0xc0,0x06,0x78,0x03,0x7e,0x34,0x2f,0xc6,0x7e,0xc0,0xbe,0x50,0x17,0xfa,
4229
0xc2,0x30,0x71,0x83,0xb8,0x1f,0x1e,0x86,0x99,0x30,0xd7,0xbc,0x60,0xba,0x9d,0x79,
4230
0x11,0x0a,0x8a,0x42,0x70,0x3d,0x8c,0x85,0x71,0x90,0x03,0x77,0xc3,0x46,0xf8,0xd1,
4231
0xbc,0x40,0xbb,0x83,0xf9,0x14,0x0a,0xc0,0xb9,0x50,0x1a,0x2a,0x40,0x34,0x5c,0x00,
4232
0x95,0xa1,0x1a,0xc4,0x41,0x3f,0x98,0x22,0xcc,0xcb,0x93,0x35,0x20,0x0e,0x52,0xa0,
4233
0x16,0xd4,0x87,0x34,0xc8,0x84,0x56,0x22,0x67,0x27,0xed,0x0c,0xcf,0x8a,0x95,0xb0,
4234
0x1f,0x3e,0x87,0x83,0x70,0x08,0x8e,0xc2,0xa6,0xdd,0xac,0xbb,0x61,0xbf,0xf8,0x1c,
4235
0x0e,0xc2,0x21,0x38,0x0a,0x9b,0x3e,0x61,0x9c,0xc3,0x17,0x70,0x10,0x0e,0x89,0xc3,
4236
0xf0,0x2d,0xac,0xdc,0xc3,0x7a,0x1e,0x76,0xc0,0x4e,0xd8,0x25,0x76,0xc3,0x27,0xb0,
4237
0x47,0x7c,0x0a,0x07,0xe0,0x0b,0x38,0x08,0x87,0xe0,0x2b,0xf8,0x5a,0xfc,0x20,0x7e,
4238
0x14,0x3b,0x3e,0x65,0x3f,0xd8,0x0b,0xfb,0xe1,0x00,0x7c,0x01,0x87,0xe0,0x07,0xf3,
4239
0x41,0x87,0xbd,0xb4,0x19,0x6c,0x82,0x77,0xcd,0x87,0x6d,0x3e,0x63,0x2e,0x81,0x26,
4240
0xd0,0x1c,0x5a,0x88,0x2c,0xe8,0x64,0x3e,0x94,0xf0,0x05,0xf3,0xf7,0xff,0xb5,0x77,
4241
0x1e,0xf0,0x55,0x97,0x67,0x1b,0x3e,0xe7,0xe4,0xe4,0x70,0x92,0x20,0xe0,0xc0,0x2d,
4242
0x6e,0xd9,0x10,0x99,0x0a,0x08,0x41,0x51,0x1c,0x1f,0x05,0xdc,0x48,0x15,0xc4,0x8d,
4243
0x03,0x04,0xdc,0x16,0x11,0x44,0xc5,0x89,0x6d,0xb5,0x9f,0xa3,0x8a,0xf5,0x73,0xa0,
4244
0x82,0x51,0xd0,0x82,0x20,0x04,0x71,0xcb,0x12,0x5c,0x75,0x31,0xac,0x7e,0x28,0x22,
4245
0xcb,0x09,0x6a,0xbe,0xfb,0x3d,0xff,0xeb,0x21,0x0f,0x7f,0x73,0x04,0xac,0xfd,0xd5,
4246
0xfe,0xbe,0x26,0xbd,0x01,0x43,0x20,0x83,0x24,0x7d,0xf2,0x5e,0xcf,0x75,0xbf,0x4a,
4247
0xa1,0xb2,0xab,0xb2,0xbb,0xb2,0x87,0xb2,0x17,0xa9,0x4f,0x1a,0x2a,0x2d,0x94,0x56,
4248
0x4a,0x5b,0x65,0x7f,0xd2,0x9e,0x1c,0x48,0xba,0x92,0xc3,0xc8,0x11,0xa4,0x9b,0xd2,
4249
0x5d,0xe9,0xa9,0x1c,0xa9,0x1c,0x4d,0x8e,0x23,0xbd,0x48,0x6f,0x72,0x22,0xe9,0x43,
4250
0x4e,0x56,0xfa,0x29,0xa7,0x92,0x33,0x94,0xfe,0xca,0x39,0xca,0x20,0x65,0x88,0x72,
4251
0x91,0x72,0x89,0x72,0xb9,0x32,0x94,0x0c,0x53,0x46,0x29,0xd7,0x2b,0x77,0x2a,0xf7,
4252
0x2a,0xf7,0x29,0xf7,0x2b,0x63,0x95,0x47,0x94,0x29,0xca,0xca,0x75,0xfa,0x77,0x0d,
4253
0xe2,0x76,0x22,0x95,0x58,0xf8,0x40,0x2a,0x91,0x78,0x30,0x95,0xa8,0x37,0x29,0x95,
4254
0xd8,0x4d,0x19,0x37,0x27,0x95,0x28,0x57,0x16,0x2d,0x4b,0x25,0x56,0x2a,0x27,0x86,
4255
0x85,0xe0,0x6f,0x52,0x89,0x5d,0xd6,0x46,0x8b,0xc1,0x87,0x6f,0x5d,0xa0,0xef,0x8d,
4256
0x0a,0x12,0x97,0xb4,0x0a,0x32,0x62,0x41,0xa2,0xd3,0x77,0x05,0xb9,0x05,0x9b,0x15,
4257
0x8a,0xed,0x37,0xe7,0xdb,0x6b,0xfe,0x57,0xed,0x33,0xff,0xdc,0x3d,0xe6,0x4d,0xdd,
4258
0x5f,0xde,0xd4,0xbd,0xe5,0xf8,0x3e,0x72,0xbe,0x3d,0x64,0xdb,0x3b,0x8e,0xef,0x1b,
4259
0xdb,0x7e,0xb1,0xed,0x13,0xe7,0xdb,0x23,0xb6,0xfd,0x61,0xdb,0x1b,0xb6,0x7d,0x61,
4260
0xdb,0x13,0x8e,0xef,0x07,0xdb,0x5e,0xb0,0xed,0x03,0xdb,0x1e,0xb0,0xed,0xff,0xda,
4261
0xde,0x6f,0xbe,0x7d,0xdf,0xf8,0x9e,0xaf,0xed,0xf3,0xda,0xde,0xae,0xed,0xe3,0xda,
4262
0x1e,0x6e,0x7c,0xef,0x76,0x73,0xf7,0x6c,0x6d,0xbf,0xd6,0xf6,0x66,0xe3,0xfb,0xb2,
4263
0xf1,0xfd,0xd8,0x9f,0xbb,0x07,0x1b,0xdf,0x6b,0xb5,0x3d,0xd6,0xcd,0xdd,0x57,0xb5,
4264
0x3d,0xd5,0xf8,0xde,0xa9,0xed,0x99,0x6e,0xee,0x3e,0xa9,0xed,0x91,0xc6,0xf7,0x3f,
4265
0x6d,0xdf,0xf3,0x97,0xde,0xf3,0xb4,0xbd,0xcd,0x8d,0xed,0x63,0xda,0x1e,0x66,0xbe,
4266
0xfd,0x4a,0xdb,0xa7,0xdc,0xd4,0xfd,0x49,0xdb,0x9b,0x8c,0xef,0x3d,0xda,0x9e,0x63,
4267
0xbe,0x7d,0x46,0xdb,0x63,0x8c,0xef,0x27,0xda,0x5e,0xa2,0xed,0x21,0x6e,0xea,0xde,
4268
0xa1,0xed,0x0f,0xda,0xde,0x60,0x7c,0x5f,0x70,0x73,0xf7,0x03,0x6d,0x2f,0x30,0xdf,
4269
0x3e,0x60,0x7c,0xff,0x2f,0xbe,0xcf,0x67,0xfb,0x7a,0xb6,0x97,0x67,0x7b,0x75,0xb6,
4270
0x4f,0x67,0xfb,0x73,0xb6,0x37,0x67,0xfb,0x72,0xb6,0x27,0x67,0xfb,0x71,0xb6,0xf7,
4271
0xf6,0xef,0xb6,0xd7,0xf6,0x4b,0xef,0xb1,0xd9,0xde,0x9a,0xed,0xa9,0xc5,0xf7,0xd3,
4272
0x6c,0x2f,0x2d,0xbe,0x5f,0xb6,0xb9,0x7b,0x63,0xf9,0xf6,0xc5,0x36,0xb6,0xe7,0x65,
4273
0x7b,0x5d,0xb6,0xbf,0x65,0xfb,0x54,0xb6,0x2f,0x65,0xfb,0x4e,0xb6,0xcf,0x64,0xfb,
4274
0x49,0xb6,0x97,0x64,0x7b,0x45,0xb6,0x2f,0xb4,0xa9,0x7b,0x42,0xb6,0x07,0x64,0xfb,
4275
0x3f,0xb6,0xf7,0xf3,0x73,0xf7,0x7c,0x7e,0xad,0xfb,0x3d,0xf9,0xf6,0x78,0xfe,0xdd,
4276
0xf7,0x75,0x36,0x77,0x4f,0xe7,0x97,0xda,0xcf,0xd9,0xd8,0x5e,0xce,0xa6,0xee,0xe1,
4277
0x6c,0x6c,0xff,0xe6,0x5f,0xb5,0x77,0x93,0x6f,0xdf,0x26,0xdf,0x7e,0x4d,0x7c,0xaf,
4278
0xe6,0x5f,0xb5,0x4f,0x63,0x7b,0x34,0xb6,0x3f,0x63,0x7b,0x33,0xb6,0x17,0x63,0xfb,
4279
0x30,0xf9,0xf6,0x5d,0x6c,0xbf,0xc5,0xf6,0x5a,0x6c,0x8f,0xc5,0xf6,0x56,0x6c,0x0f,
4280
0xc5,0xf6,0x4f,0xe2,0x7b,0x27,0xf1,0x7d,0x13,0xdb,0x23,0xb1,0xfd,0x91,0x8d,0xed,
4281
0x89,0xd8,0x3e,0x88,0xed,0x81,0xd8,0xfe,0x87,0xed,0x7d,0xd8,0xbe,0xc7,0xc6,0xf6,
4282
0x3c,0xe2,0xfb,0x1c,0xff,0xec,0xfd,0x8d,0x7f,0x74,0xff,0xe2,0x9f,0xb5,0x77,0x11,
4283
0xdf,0xab,0xb0,0x7d,0x0a,0xdb,0xa3,0xf8,0xb5,0xec,0x4f,0xc4,0xf7,0x26,0x36,0x77,
4284
0x5f,0x62,0x73,0xf7,0x24,0xfe,0xb3,0x1f,0x51,0xfd,0x7e,0x44,0xbe,0x3d,0x88,0x8d,
4285
0xed,0x3d,0xfc,0xa3,0xfb,0x0e,0x1b,0xdb,0x6b,0xc8,0xb7,0xcf,0xb0,0xb1,0x3d,0x06,
4286
0xdb,0x5f,0xc8,0xb7,0xb7,0x60,0xfb,0x0a,0xf1,0x3d,0x05,0xdb,0x47,0xb0,0xbd,0x03,
4287
0xdb,0x37,0xb0,0xfd,0x02,0xdb,0x1b,0xb0,0x3d,0x01,0xdb,0x03,0x88,0xf3,0x7f,0xe3,
4288
0xfe,0xc6,0xf9,0x8d,0xe7,0x6f,0x8c,0xd7,0x1b,0x77,0xdf,0x5c,0xde,0xbe,0xb9,0xfc,
4289
0xdc,0xb8,0xb9,0xf1,0x70,0xe3,0xe0,0x9b,0xca,0xbb,0x8d,0x53,0x1b,0x9f,0x36,0x2e,
4290
0x6d,0x9c,0x39,0xce,0x95,0xe3,0x5c,0xd8,0x78,0xb0,0xf1,0x5d,0xe3,0xba,0xc6,0x69,
4291
0x8d,0xcf,0x1a,0x67,0x35,0xae,0x1a,0xe7,0xa2,0xc6,0x3d,0x37,0x95,0x77,0x1a,0xc7,
4292
0x34,0x7e,0x19,0xe7,0x94,0x71,0xfe,0x68,0xdc,0xd1,0x78,0xa3,0xf1,0x45,0xe3,0x89,
4293
0xc6,0x0d,0xf3,0xf1,0x41,0xe3,0x7d,0x71,0xce,0x67,0xfc,0xce,0xb8,0x5d,0x3e,0xfe,
4294
0x66,0x7c,0x2d,0x1f,0x4f,0x33,0x3e,0x96,0x8f,0x8b,0xc5,0x39,0x98,0xf1,0xae,0x38,
4295
0xe7,0xfa,0x47,0x39,0x95,0xf1,0xa9,0x7c,0x5c,0x2a,0xce,0x9d,0x8c,0x37,0x19,0x67,
4296
0x32,0xbe,0x64,0x5c,0x69,0x53,0x79,0xd2,0xc6,0x38,0x92,0xf1,0xa3,0x7c,0xbc,0xe8,
4297
0xd7,0xce,0x87,0xfe,0xbf,0xf1,0x99,0xcd,0xe5,0x2c,0xc6,0x4f,0x8c,0x9b,0x18,0x2f,
4298
0x89,0x73,0x12,0xe3,0x23,0x71,0x1e,0x62,0xfc,0xc3,0xb8,0x47,0x9c,0x77,0x18,0xe7,
4299
0x30,0xbe,0x61,0x5c,0xe3,0xe7,0xf2,0x0c,0xe3,0x18,0xc6,0x2f,0xfe,0xc3,0x2d,0x22,
4300
0x6e,0xf1,0x8b,0xf1,0x8a,0xd0,0x0d,0xac,0x14,0x2b,0xa6,0x9f,0x6f,0xa1,0xd4,0x8a,
4301
0x8e,0x4a,0x42,0x05,0x66,0x42,0xdf,0xfe,0x27,0xc2,0xb7,0xd8,0x7b,0x2a,0xfb,0x28,
4302
0x8d,0xa3,0x6f,0xb7,0xc3,0xb7,0xd2,0x89,0x66,0x4a,0xe8,0x74,0x69,0xa7,0xb4,0xa7,
4303
0xd7,0xa5,0x37,0xdc,0xe3,0x32,0xe5,0x0a,0x65,0xa4,0x72,0xb5,0xa2,0x6f,0x2d,0x13,
4304
0xf7,0x2a,0x7f,0x51,0x1e,0x80,0x87,0x84,0x6f,0x09,0xc6,0x29,0xe3,0x95,0x72,0xe5,
4305
0x09,0x65,0x22,0x8c,0xe4,0x29,0x65,0x32,0x9c,0x64,0x0a,0xac,0xe4,0x2d,0x58,0xc9,
4306
0xd7,0xb0,0x92,0xc9,0x7a,0xd3,0xa6,0x28,0xcf,0x2a,0xf3,0x94,0xf9,0xb0,0x8f,0x8f,
4307
0xe0,0x1d,0x2b,0xe8,0x70,0x19,0xe8,0x78,0x47,0xe0,0x1c,0x43,0xe1,0x1b,0x57,0xb9,
4308
0x9e,0x96,0x6b,0x1d,0xdb,0x08,0x5c,0xe3,0x2b,0xb8,0xc6,0x08,0xb8,0xc6,0xbe,0xf0,
4309
0x8c,0xeb,0xe0,0x18,0x37,0x2a,0x37,0xd3,0xc1,0x32,0x8d,0xfe,0x95,0x0a,0x3a,0x58,
4310
0x66,0xd2,0xc1,0xf2,0x02,0x1d,0x2c,0xf3,0x60,0x1d,0x89,0x8c,0xfe,0xa7,0x64,0x95,
4311
0x22,0xa5,0x44,0xa9,0xa9,0x6c,0xa1,0xd4,0xca,0x44,0xbd,0x2c,0x3b,0xd1,0xbf,0x12,
4312
0xba,0x57,0xfa,0x2b,0x67,0x2b,0xe7,0xba,0xde,0x95,0xd0,0xb5,0xf2,0xbe,0xf2,0x01,
4313
0x7d,0x2b,0x1f,0xd1,0xb3,0xf2,0x09,0x3d,0x2b,0x9f,0xd3,0xaf,0x12,0x98,0x48,0x6d,
4314
0xd7,0xa3,0x52,0x0a,0x07,0x79,0xc0,0x75,0xa6,0x2c,0x83,0x81,0x7c,0xe5,0xfa,0x51,
4315
0x7e,0xa8,0x11,0xf5,0xa2,0x58,0x1f,0x8a,0xf5,0xa0,0x58,0xff,0x49,0x29,0x1c,0x24,
4316
0x74,0x9f,0x9c,0x04,0x0b,0x09,0x1c,0x64,0x34,0x7d,0x27,0x63,0xe8,0x37,0x59,0x42,
4317
0xbf,0x49,0x81,0xeb,0x32,0xb1,0x0e,0x93,0xce,0x74,0x96,0x58,0x57,0x49,0x4f,0x98,
4318
0x48,0xe8,0x25,0x39,0xd5,0x75,0x8f,0x8c,0x84,0x85,0xfc,0x01,0x06,0x62,0xec,0xc3,
4319
0xba,0x45,0x66,0xd0,0x25,0xf2,0xaa,0xeb,0x0f,0xb1,0xde,0x90,0x85,0xf4,0x85,0x84,
4320
0xae,0x90,0xd5,0xca,0x17,0xca,0x3a,0xd7,0x13,0x92,0x74,0xdd,0x20,0xb5,0x61,0x21,
4321
0x8d,0x60,0x20,0xad,0x61,0x1f,0xd6,0xfd,0xd1,0x99,0xce,0x8f,0x23,0x5c,0xcf,0x87,
4322
0xf5,0x7b,0x0c,0x84,0x87,0x84,0x3e,0x8f,0x0b,0xe9,0xf4,0xb0,0x2e,0x8f,0x9b,0x61,
4323
0x22,0x0f,0xc3,0x42,0x9e,0x74,0x7d,0x1d,0x33,0xe8,0xe7,0xb0,0x5e,0x8e,0xd9,0x8e,
4324
0x89,0x2c,0xa1,0x83,0x63,0x95,0xeb,0xdf,0xb0,0xde,0x8d,0x42,0xf8,0xc8,0xd6,0x70,
4325
0x91,0x16,0xf0,0x10,0xeb,0xd5,0xe8,0xe4,0x3a,0x34,0xba,0xd2,0x9d,0x61,0x9d,0x19,
4326
0xd6,0x95,0xd1,0x87,0x8e,0x8c,0xd3,0x5d,0x1f,0xc6,0x48,0xf8,0xc8,0xef,0xe1,0x22,
4327
0xc6,0x43,0xee,0x83,0x83,0x8c,0xa7,0xe7,0xc2,0xfa,0x2d,0x5e,0xa0,0xd7,0x62,0xb6,
4328
0xeb,0xb2,0x08,0x3d,0x16,0x6b,0x94,0x6f,0x95,0xb5,0x25,0x55,0x5d,0x16,0xd6,0x61,
4329
0x51,0x0b,0x56,0xd2,0xc8,0xf5,0x55,0x74,0xa4,0xa7,0xe2,0x10,0xfa,0x29,0x8e,0x81,
4330
0x9b,0xfc,0x16,0x5e,0xd2,0x8f,0x1e,0x8a,0x8b,0x94,0x8b,0x95,0x2b,0x5c,0x07,0xc5,
4331
0x4d,0x30,0x93,0x87,0x61,0x25,0xd6,0x31,0xf1,0x02,0xdd,0x11,0xb3,0xe8,0x8c,0x78,
4332
0x0f,0x66,0xb2,0x84,0x8e,0x88,0x55,0x7c,0xa1,0x4b,0xc1,0x4c,0xb6,0xa2,0xfb,0xe1,
4333
0x00,0xba,0x1e,0x0e,0xa1,0xe3,0xa1,0x9b,0xe3,0x26,0xfd,0xe8,0x6f,0xb0,0xbe,0x86,
4334
0x91,0xf0,0x92,0x09,0x8e,0x91,0x58,0x27,0xc3,0x7c,0xd7,0xc3,0xf0,0x31,0xfd,0x0b,
4335
0x49,0xd7,0xb9,0x10,0xfa,0x16,0x3a,0xc1,0x4f,0x42,0xc7,0x42,0x77,0xd8,0x89,0x31,
4336
0x93,0x1b,0x1c,0x27,0xb1,0xfe,0x84,0x89,0x8e,0x91,0x58,0x57,0xc2,0x3c,0x18,0x89,
4337
0x75,0x23,0xec,0x48,0x1f,0x42,0x1b,0xfa,0x10,0xf6,0xa3,0x0f,0xa1,0x1d,0x9d,0x08,
4338
0x87,0xd1,0x81,0x60,0xdd,0x07,0x23,0xe9,0x3e,0xb8,0x96,0xce,0x83,0xd0,0x77,0x30,
4339
0x8d,0xae,0x83,0x17,0x95,0x39,0xb0,0x95,0xa6,0xae,0xdf,0xc0,0x7a,0x0d,0xda,0xd3,
4340
0x67,0xd0,0x89,0xbe,0x82,0x13,0xe8,0x29,0x38,0x99,0xfe,0x81,0x0b,0x5c,0xe7,0xc0,
4341
0x48,0xba,0x06,0xac,0x63,0x20,0x74,0x08,0xdc,0xed,0x18,0x4b,0xe0,0x2b,0x87,0xc3,
4342
0x4f,0x8c,0x9b,0xf4,0x85,0x97,0x8c,0x86,0x93,0x4c,0x72,0x6c,0xe4,0x25,0x98,0xc8,
4343
0x56,0xb0,0x90,0xe0,0xf7,0xf7,0x85,0x87,0x8c,0x86,0x87,0x04,0x16,0x92,0xd8,0x26,
4344
0x62,0x21,0xc3,0x60,0x20,0x77,0xc2,0x40,0x12,0x38,0xfb,0xe6,0xea,0xb7,0x70,0x7e,
4345
0xfe,0x91,0x70,0x8f,0xf3,0xf0,0xf1,0x87,0xe1,0xe1,0x9b,0x7f,0x3f,0xcd,0x39,0xf7,
4346
0xc1,0xb7,0x7f,0x5d,0x79,0xd7,0x79,0xf6,0xc1,0xb1,0x5f,0xa9,0x24,0xb6,0x8f,0x3c,
4347
0xfb,0x5a,0xce,0xb1,0xdf,0x0d,0x26,0x32,0x12,0x16,0x32,0xd6,0x71,0x90,0x04,0xbe,
4348
0xfc,0x9e,0x78,0xf2,0x0d,0xf1,0xe3,0xcd,0x8b,0x0f,0x4e,0x7c,0x99,0xd2,0x05,0x2f,
4349
0x7e,0x20,0x7c,0xa4,0x1c,0xff,0xfd,0x03,0xf8,0xc8,0x76,0xf8,0xee,0xc1,0x73,0xaf,
4350
0xe7,0xbc,0xf6,0xe3,0x9d,0xcb,0x6e,0x0e,0xfb,0x69,0xb8,0xeb,0x83,0x9d,0xaf,0x1e,
4351
0x5c,0xf5,0x31,0x38,0xea,0x09,0x7c,0xf4,0x56,0x31,0xff,0xfc,0x37,0xb8,0xe4,0x43,
4352
0x70,0xc9,0x87,0xe3,0x8c,0x3f,0x80,0x2b,0x6e,0x8e,0xf8,0x78,0xe7,0x81,0x2f,0xc5,
4353
0xff,0x5e,0xee,0x9c,0xef,0xe0,0x7b,0x7f,0xb7,0x53,0xe4,0x77,0xb7,0xc2,0xeb,0x6e,
4354
0x0f,0x9f,0x19,0x0d,0x7f,0x09,0x8e,0xf6,0x02,0x1c,0x6d,0x73,0xb3,0x3f,0x71,0x3e,
4355
0xb6,0x79,0xd8,0xdf,0x38,0x16,0x53,0x01,0x63,0xd9,0x1e,0xb6,0x72,0x28,0x4c,0xa5,
4356
0x97,0xe3,0x28,0x7d,0xe0,0x27,0x81,0x9d,0x3c,0x03,0x37,0x99,0x0e,0x3b,0x09,0xdc,
4357
0x64,0x36,0xdc,0x24,0x30,0x93,0xf7,0x61,0x26,0xcb,0x61,0x26,0x81,0x97,0x7c,0xcf,
4358
0x70,0x54,0xa2,0xd4,0x52,0x6a,0x2b,0x75,0x94,0x06,0x4a,0x43,0xa5,0x91,0xd2,0x58,
4359
0x69,0xa2,0x34,0x55,0x9a,0x29,0xcd,0x95,0x52,0xa5,0xb5,0xd2,0x45,0x39,0x58,0xe9,
4360
0xa3,0xf4,0x55,0x4e,0x57,0xce,0x50,0xce,0x54,0xce,0x52,0xfa,0x2b,0x03,0xe1,0x31,
4361
0x43,0x94,0x4b,0x95,0xcb,0xe1,0x32,0xc3,0x94,0xeb,0x94,0x1b,0x94,0xd1,0xca,0x18,
4362
0x5c,0xeb,0x04,0x9c,0xa6,0x00,0x4e,0x93,0x85,0xd5,0x6c,0x03,0xa7,0xd9,0x16,0x46,
4363
0x53,0x0f,0x3e,0xb3,0x37,0x7c,0xa6,0x3e,0x7c,0xa6,0x21,0x8c,0xc6,0xd8,0x4c,0x3b,
4364
0x58,0x4c,0x19,0x2c,0xe6,0x70,0x38,0x4c,0x0f,0x58,0xcc,0x28,0x65,0xb4,0xb2,0xd5,
4365
0x1e,0xfa,0xff,0x23,0x65,0x1b,0xa5,0x8d,0x06,0xc5,0xcb,0x94,0x5b,0x95,0xdb,0x94,
4366
0xb2,0xbd,0xf4,0xbc,0xca,0xb5,0xca,0x5d,0xca,0xa7,0xca,0xa3,0x1a,0x24,0xc7,0x85,
4367
0x61,0xb2,0x81,0xd2,0x50,0xff,0xbf,0xc9,0x50,0xf9,0x11,0xcc,0x66,0x05,0xcc,0xe6,
4368
0x5b,0x06,0xcd,0xfa,0x8e,0xd3,0x0c,0x70,0x0e,0xf5,0x18,0xd8,0x4c,0x39,0x4c,0xa6,
4369
0x02,0x16,0x33,0x0f,0x06,0xb3,0x88,0x21,0xb5,0xaf,0x32,0x4c,0xb9,0x33,0x0c,0xac,
4370
0xcd,0xf5,0xf9,0xd9,0x3c,0x1a,0x5c,0x93,0xf0,0x99,0x2c,0x4c,0xa6,0x11,0x8e,0x74,
4371
0x29,0x6c,0xa6,0x0d,0x6c,0xe6,0x00,0x58,0xcc,0xed,0xb0,0x98,0xc0,0x61,0xc6,0xc0,
4372
0x5f,0xcc,0x7b,0x2e,0x84,0xb7,0x8c,0x56,0x2a,0x94,0x15,0xf0,0x96,0x5d,0x5a,0xe8,
4373
0xc3,0x44,0xe9,0xa1,0xf4,0x55,0x2e,0x57,0xae,0x50,0x1e,0x57,0x2a,0x94,0x59,0xca,
4374
0x3c,0xe5,0xa2,0x96,0x7a,0xbf,0x29,0x1f,0x28,0x8b,0x94,0xca,0x96,0x11,0xa7,0xa9,
4375
0x80,0xd3,0x8c,0x86,0xcb,0x6c,0x01,0x7f,0x29,0xc3,0x69,0x1e,0x8c,0xd7,0x3c,0x14,
4376
0xde,0x72,0x37,0x9c,0x25,0x38,0xcb,0xab,0xc3,0xa0,0x0d,0x5f,0x09,0x1c,0x65,0x94,
4377
0xe3,0x25,0xe6,0x13,0x9b,0x47,0x6c,0xfe,0xf0,0xde,0xb8,0xc2,0x0d,0x70,0x85,0x4b,
4378
0x95,0xfd,0x60,0x23,0x43,0x70,0x86,0x83,0x1f,0x3c,0x07,0x2f,0x78,0xb5,0x73,0x7f,
4379
0x83,0xef,0xdb,0x0c,0xcf,0x37,0x38,0xbe,0x7d,0x70,0x7b,0x47,0x38,0x8f,0xf7,0x29,
4380
0xfc,0xdd,0xa9,0x78,0xbb,0x81,0x93,0x7c,0xe0,0xfc,0xdc,0x04,0xfe,0x6d,0x73,0xbc,
4381
0xdb,0x96,0xf8,0xb6,0x65,0xce,0xb1,0xfd,0x2f,0xe7,0xd5,0xfe,0xd6,0xb9,0xb2,0xe5,
4382
0xce,0x8b,0x7d,0x12,0x1f,0x76,0x32,0x1e,0x6c,0x85,0x73,0x5f,0xdf,0xc5,0x6d,0xfd,
4383
0xdc,0x79,0xab,0x45,0xf0,0x8e,0xdd,0xe0,0x1c,0x81,0x71,0xf4,0x87,0x65,0x0c,0x74,
4384
0xbe,0xa9,0x79,0xa6,0xe6,0x95,0x06,0xa6,0x51,0x0e,0xcb,0x08,0xdf,0x9c,0x0c,0x84,
4385
0x5f,0x6c,0xed,0x9c,0xd1,0xc0,0x2d,0x1a,0xc2,0x2d,0xf6,0x73,0xac,0xe2,0x20,0x18,
4386
0x45,0x0f,0x65,0x26,0x9c,0xa2,0x23,0x9c,0x62,0x34,0x9c,0xe2,0x25,0x38,0xc5,0xf7,
4387
0xf8,0xa1,0x75,0xf0,0x43,0x4b,0x95,0x1e,0x4a,0x4f,0xe5,0x48,0xe5,0x68,0xe5,0x18,
4388
0xe5,0x58,0xa5,0x8f,0xd2,0x57,0xe9,0xa7,0x9c,0xaa,0x9c,0xa9,0x9c,0xa5,0x9c,0x8d,
4389
0x43,0x1a,0x38,0x47,0xa5,0x92,0xac,0xd4,0xc7,0x80,0x92,0x51,0x4a,0x94,0x9a,0xca,
4390
0x16,0x4a,0xad,0xca,0xc8,0x2d,0xdd,0x51,0xd9,0x09,0xbf,0xb4,0x3d,0x3c,0xa4,0x37,
4391
0x3c,0xe4,0x59,0x38,0xc7,0x7c,0xf8,0xc6,0x22,0x65,0x89,0xf2,0x91,0xb2,0x54,0xf9,
4392
0x16,0xde,0xb1,0x05,0x9c,0xa3,0x03,0x7c,0xa3,0x07,0x5c,0x23,0x5c,0x08,0x96,0x54,
4393
0x52,0x4a,0x0d,0xa5,0x6d,0x32,0xe2,0x1c,0x37,0x2a,0xa3,0x95,0x31,0xca,0x3c,0xe7,
4394
0x8b,0x8e,0xc1,0x11,0x5d,0x0c,0xf7,0x68,0x0a,0xd7,0xb8,0x10,0xae,0x71,0x0f,0x3c,
4395
0x23,0x81,0xdf,0x59,0x0e,0xb7,0x48,0xc0,0x2b,0x06,0xc0,0x29,0x6e,0x80,0x4f,0xfc,
4396
0x09,0x2e,0x31,0x01,0x1e,0x51,0x01,0x87,0x28,0x83,0x3f,0x0c,0x83,0x3b,0x3c,0x01,
4397
0x6f,0x30,0xce,0xd0,0xd6,0xb1,0x85,0xe3,0x94,0x07,0xe1,0x09,0x81,0x25,0xac,0x53,
4398
0x76,0x85,0x23,0x74,0x82,0x1f,0x4c,0x55,0xe6,0x17,0x45,0x4e,0x65,0x21,0x2e,0x65,
4399
0x1d,0xd8,0xc1,0x0e,0xb8,0x93,0xc1,0x99,0x2c,0x53,0x7a,0xc0,0x10,0x2a,0x70,0x24,
4400
0x97,0xc1,0x0c,0xf6,0x87,0x19,0x1c,0xaf,0x5c,0xac,0xdc,0xae,0x8c,0x85,0x17,0x0c,
4401
0x83,0x13,0xac,0x85,0x13,0xec,0x85,0x0f,0x59,0x06,0x2f,0x08,0xae,0xe3,0x79,0x70,
4402
0x81,0x9b,0x94,0xbe,0xb5,0x22,0x2e,0x10,0x1c,0xc7,0x71,0xb0,0x81,0xc0,0x05,0x5e,
4403
0xc6,0x67,0x9c,0x07,0x0f,0x58,0x09,0x0f,0x28,0xc5,0x5b,0xec,0x09,0x07,0x08,0xce,
4404
0xe2,0xd5,0xb0,0x80,0x45,0xb5,0xab,0x3c,0xc5,0x14,0x5e,0x62,0x57,0xe5,0x48,0xdc,
4405
0x44,0x73,0x12,0x07,0x3b,0x0f,0x71,0x38,0xbe,0xe1,0x5f,0xf1,0x0c,0xa7,0xe0,0x18,
4406
0xce,0x86,0x17,0xac,0xc4,0x2f,0x2c,0xc0,0x2b,0x34,0x9f,0xb0,0x0d,0xbc,0x20,0x78,
4407
0x82,0x43,0x70,0x04,0x87,0xe3,0x02,0x4e,0xc7,0xfd,0x9b,0xed,0x7c,0xbf,0xc5,0xf0,
4408
0x82,0xad,0xf1,0xf9,0x5a,0x38,0x87,0x2f,0xf8,0x7b,0xfb,0x39,0x77,0xcf,0x9c,0x3d,
4409
0x63,0x07,0x37,0xc3,0x0c,0xca,0x9d,0x97,0xf7,0x21,0x3e,0x5e,0x02,0x0f,0xaf,0x10,
4410
0x7e,0xb0,0x35,0xdc,0xa0,0x05,0xbc,0xa0,0x3d,0xac,0xc0,0xbc,0xba,0xae,0xf8,0x74,
4411
0x3d,0x9c,0x43,0x77,0x3a,0xce,0xdc,0x30,0xc7,0x0d,0x46,0xc3,0x0a,0xa6,0x38,0x17,
4412
0xee,0x45,0x1c,0xb8,0x39,0xce,0x7b,0x7b,0xcd,0xb9,0x6e,0x6f,0xe1,0xba,0x25,0x70,
4413
0xdb,0xca,0x70,0xda,0x0e,0x76,0x1e,0xdb,0x89,0xce,0x5d,0x1b,0x86,0xab,0x36,0xd9,
4414
0xf9,0x69,0xd3,0x9d,0x93,0xf6,0x1c,0x0e,0xda,0x30,0x9c,0xb3,0x49,0xb8,0x66,0xe6,
4415
0x98,0xcd,0xc0,0x2d,0x4b,0xe0,0x92,0xb5,0x77,0xfe,0x58,0x70,0xc7,0x3a,0xe3,0x8c,
4416
0xf5,0x85,0x49,0x3c,0xe2,0x3c,0xb1,0xf1,0xf8,0x61,0x4f,0x39,0x27,0xac,0x02,0x17,
4417
0x2c,0xe1,0xfc,0x2f,0xf3,0xbe,0xf6,0x70,0xae,0x57,0x29,0x0c,0xa3,0xb9,0xf3,0xb8,
4418
0xda,0xc3,0x33,0x02,0xcb,0x30,0x86,0x51,0x17,0x76,0xd1,0x16,0x37,0xeb,0x00,0xe7,
4419
0x63,0x05,0xdf,0xaa,0x0b,0xce,0xd5,0x18,0x18,0xc6,0xeb,0xb8,0x55,0xef,0x39,0x9f,
4420
0xca,0xbc,0xa9,0x1a,0x4a,0x11,0x2c,0xa3,0x25,0xbe,0x54,0xf0,0xa4,0x3a,0x39,0x47,
4421
0xaa,0x27,0x6e,0x54,0x2f,0xd8,0xc6,0x75,0xce,0x83,0xba,0x03,0xbe,0x91,0x70,0xce,
4422
0x53,0x3f,0xe7,0x39,0x99,0xdf,0xb4,0x12,0xde,0x51,0x8c,0xc7,0xb4,0x1f,0xee,0x52,
4423
0x70,0x95,0x06,0xe2,0x28,0x99,0x9b,0x64,0x4e,0x92,0xb9,0x48,0x09,0x18,0x48,0x09,
4424
0xee,0x91,0x39,0x47,0x9d,0x9c,0x67,0xd4,0x03,0x1e,0x72,0x06,0x1c,0x64,0x34,0x1e,
4425
0xd1,0xad,0xce,0x1d,0x32,0x67,0xa8,0x1c,0x37,0x68,0xa5,0xe3,0x20,0x6b,0xf0,0x80,
4426
0x12,0xb0,0x90,0xad,0xf0,0x7b,0x3a,0x3a,0xa7,0x27,0xb8,0x3c,0x07,0x39,0x87,0xa7,
4427
0x42,0x79,0x43,0x79,0x5f,0x59,0xac,0x54,0xee,0x1a,0x31,0x92,0xc0,0x43,0x46,0xc3,
4428
0x41,0xcc,0xd3,0xe9,0x0a,0x07,0xc9,0x5d,0xa8,0x87,0x93,0xd3,0x08,0x17,0xa7,0x14,
4429
0x16,0x52,0x86,0x7b,0x73,0x1e,0xce,0xcd,0x3c,0x5c,0x9b,0x2f,0x61,0x21,0xc1,0xb3,
4430
0x69,0x8b,0x5f,0xd3,0x1b,0x1e,0xf2,0x3b,0x38,0x48,0x19,0xbc,0x63,0x0a,0x9c,0xc3,
4431
0x3c,0x99,0x9b,0xe1,0x1c,0x81,0x71,0x2c,0x71,0x3e,0xcc,0x4a,0xb8,0x46,0x60,0x1a,
4432
0xc3,0x60,0x19,0x63,0x60,0x18,0x5f,0xc2,0x2e,0x02,0xb7,0x30,0x5e,0x61,0x9c,0x22,
4433
0x30,0x8a,0x04,0x6c,0x62,0x18,0x4c,0xe2,0x2e,0x9c,0x95,0x7b,0x94,0x31,0x81,0x4f,
4434
0xcc,0x4a,0x26,0xde,0x9c,0x15,0xf9,0x2b,0x6b,0x83,0xbf,0x32,0x5b,0x9f,0x87,0x73,
4435
0xf4,0xf9,0xac,0xbc,0x3f,0x27,0xf2,0x59,0x82,0xcb,0xd2,0x23,0x5c,0x6e,0x1b,0x2e,
4436
0x46,0x7c,0x2d,0x72,0x5a,0x1a,0xe2,0xb2,0xf4,0x57,0x06,0xe3,0xb1,0x8c,0xc0,0x63,
4437
0xb9,0x01,0x8f,0x65,0xbc,0xf2,0x89,0xb2,0x2c,0x5c,0xec,0x3a,0x3f,0x72,0x5a,0x0e,
4438
0xc6,0x69,0x09,0x3e,0xcb,0x89,0x4a,0x85,0xb2,0x28,0x78,0x2c,0x0b,0xf4,0xfe,0x5c,
4439
0x10,0xf1,0x92,0x63,0xe1,0x24,0xc6,0x47,0xc6,0xc2,0x45,0x8c,0x87,0x04,0x16,0x52,
4440
0x03,0x06,0xb2,0x2d,0xec,0xa3,0x3d,0xcc,0xc3,0x58,0x47,0xe0,0x1c,0x81,0x71,0xcc,
4441
0x80,0x71,0xbc,0x0b,0xe3,0x58,0x07,0xe3,0xa8,0x0b,0xe3,0x68,0x0d,0xe3,0xe8,0x0e,
4442
0xe3,0x18,0x00,0xe3,0x18,0x05,0xe3,0x18,0x0b,0xe3,0x98,0x09,0xe3,0x08,0xfe,0x49,
4443
0xee,0x02,0xb3,0x77,0xf4,0xef,0x8b,0x7f,0x72,0x2e,0xee,0xc9,0x85,0xb8,0x27,0x23,
4444
0xf1,0x4f,0x82,0x7b,0x92,0xbb,0xcc,0x0d,0xee,0x31,0x1b,0xaf,0x24,0x8b,0x4f,0xb2,
4445
0x27,0x1e,0x49,0xa9,0x73,0x47,0x4a,0x61,0x20,0x65,0x8e,0x7f,0x98,0x1f,0xf2,0x19,
4446
0x5e,0x48,0x25,0x1c,0xe4,0x33,0x3c,0x90,0x79,0xf8,0x1f,0x81,0x7f,0x54,0xc2,0x40,
4447
0x16,0x39,0xcf,0xc3,0xfc,0x8e,0xcf,0xe1,0x1f,0xe6,0x73,0x2c,0x82,0x77,0x2c,0x87,
4448
0x73,0x04,0xc6,0xf1,0x22,0xce,0x46,0x02,0x57,0xc3,0x1c,0x8d,0x93,0x94,0xf3,0x3f,
4449
0xd3,0xd7,0xa1,0xe5,0x11,0xf3,0x28,0x84,0x75,0xec,0xe5,0xf8,0x46,0x2b,0xc7,0x34,
4450
0x0e,0x74,0x1c,0xc3,0xf8,0x45,0x4f,0xc7,0x2c,0x7a,0x39,0x4e,0x61,0x7c,0xc2,0xb8,
4451
0xc4,0x39,0xf0,0x88,0x4b,0x1c,0x83,0xb8,0x1e,0xf6,0x70,0x3f,0xcc,0x61,0x65,0x60,
4452
0x0e,0x2b,0xf5,0xfe,0x52,0xc6,0x28,0x8f,0x2b,0x33,0x94,0xd7,0xc2,0x25,0x9c,0xab,
4453
0xf4,0xf5,0x47,0xa9,0xa3,0x34,0x57,0x4a,0x95,0xfe,0xca,0x40,0x65,0x9c,0x32,0x5e,
4454
0xf9,0x38,0xfc,0xfe,0x6a,0xbd,0x9f,0x95,0x1e,0x4a,0x5f,0x25,0xb1,0x46,0x1f,0x23,
4455
0x5f,0xe9,0xef,0x56,0x12,0x5f,0xeb,0xeb,0xb0,0xf2,0xae,0xb2,0x48,0x59,0xa9,0xd4,
4456
0xf9,0x46,0xcf,0xab,0xf4,0x55,0x46,0x2b,0xe5,0x4a,0x85,0x32,0x2f,0x5c,0xa8,0xfc,
4457
0xad,0x9e,0xbe,0x56,0x2f,0x43,0x19,0xa6,0xbc,0xa4,0xcc,0x52,0x16,0x2a,0x2b,0xc2,
4458
0x05,0x83,0xeb,0x34,0xe3,0xad,0x8b,0xfc,0x8e,0xb5,0xf8,0x1d,0x81,0x95,0x04,0x4e,
4459
0x12,0x18,0x49,0xe0,0x23,0x81,0x8d,0x04,0x38,0x10,0x98,0x48,0xe0,0x21,0xc9,0x44,
4460
0x2d,0x7d,0x3b,0x5f,0x2b,0x3a,0xa8,0x4b,0x44,0x07,0x5f,0xd9,0x3c,0x7c,0x64,0xa7,
4461
0xe8,0x78,0x61,0x3d,0x1f,0x09,0x57,0x99,0xef,0xad,0x34,0x8a,0xf1,0x91,0xe6,0xf4,
4462
0xdd,0x07,0x3e,0x52,0x86,0x13,0xd2,0x17,0x27,0x64,0xa8,0x72,0x15,0x7c,0xe4,0x1e,
4463
0xc7,0x47,0xee,0x8f,0xbe,0x95,0xca,0xf1,0x91,0x47,0xe1,0x23,0x8f,0x29,0x8f,0x2b,
4464
0x13,0x1c,0x1f,0x99,0xe4,0xf8,0xc8,0x74,0x3c,0x92,0xb7,0xf0,0x48,0x02,0x1f,0xd1,
4465
0x9b,0x9a,0x78,0x1a,0x2f,0x64,0x2e,0x5e,0xc8,0x42,0xbc,0x90,0xe5,0xf0,0x91,0xca,
4466
0x54,0xd4,0x6f,0x1f,0x9c,0x90,0x0b,0x70,0x41,0x7e,0xe7,0xf8,0xc8,0x48,0xc7,0x47,
4467
0xcc,0xff,0xb8,0x17,0xe7,0x23,0xf0,0x91,0xe1,0x69,0x7d,0x4f,0x89,0xf3,0x11,0x7c,
4468
0x8f,0x51,0xf0,0x91,0xe0,0x78,0xdc,0x04,0x1f,0x79,0x26,0xc6,0x47,0x9e,0x85,0x8f,
4469
0x3c,0x0f,0x1f,0x79,0x19,0x17,0xe4,0x0b,0xa5,0x30,0xa3,0xef,0x45,0xe1,0x23,0xc5,
4470
0x31,0x3e,0x52,0x9b,0xce,0xfa,0xc3,0xe9,0xa6,0x3f,0x0b,0x3e,0x72,0x8e,0xeb,0xa6,
4471
0x7f,0x83,0x1e,0x7a,0xe3,0x23,0x7f,0xc7,0x13,0x59,0x0a,0x1f,0x59,0x8e,0x2f,0x12,
4472
0xba,0xe7,0xb7,0x70,0x5d,0xf3,0xcd,0xe9,0x97,0xbf,0xdf,0xf5,0xca,0x7f,0x4a,0x87,
4473
0x7c,0xf0,0x43,0xbe,0x75,0x7c,0xa4,0xae,0xeb,0x8c,0xb7,0xae,0x78,0xeb,0x88,0x0f,
4474
0xdd,0xf0,0x1d,0x71,0x44,0x7a,0xc3,0x47,0xfa,0xe3,0x86,0xdc,0x42,0x17,0xfc,0xcb,
4475
0x74,0xbf,0x2f,0xa1,0xfb,0x7d,0xff,0x18,0x1f,0x29,0xa3,0xd3,0xdd,0xfa,0xdc,0x7b,
4476
0xd0,0xdd,0x7e,0x32,0x9d,0xed,0xd6,0xcf,0x3e,0x02,0x57,0x64,0x34,0x8e,0x88,0xf9,
4477
0x21,0xd6,0xbf,0x5e,0x41,0xd7,0xfa,0x4b,0xae,0x63,0xdd,0xf8,0xc8,0xfb,0xf8,0x21,
4478
0x1f,0xe2,0x87,0xac,0x51,0xd6,0xc2,0x47,0xbe,0x87,0x8f,0x58,0x7f,0x7a,0x31,0xae,
4479
0x48,0x03,0x1c,0x91,0x96,0xb8,0x21,0xd6,0x8f,0x5e,0x46,0x27,0xfa,0xa1,0xae,0x0b,
4480
0xdd,0x5c,0x91,0x01,0xf4,0x9e,0x0f,0x71,0x7c,0xc4,0xfa,0xce,0x6f,0xc4,0x19,0x79,
4481
0x08,0x57,0x64,0x82,0xeb,0x34,0xaf,0xa0,0xbf,0xdc,0xba,0xcb,0x67,0x39,0x3e,0xb2,
4482
0x98,0x8e,0xf2,0x95,0x8e,0x8f,0x58,0x37,0x79,0x01,0xfe,0x48,0x1d,0xbc,0x91,0x52,
4483
0x7c,0x11,0xeb,0x1e,0xef,0xe8,0xf8,0x48,0x17,0xba,0xc5,0xad,0x57,0xdc,0xfa,0xc4,
4484
0x4f,0xc4,0x21,0x09,0xfd,0xe1,0x17,0x39,0x3e,0x72,0x1d,0xee,0xc8,0xad,0xce,0x19,
4485
0xb9,0x07,0x4f,0xe4,0x61,0xfc,0x10,0xeb,0x00,0x7f,0x96,0xde,0xef,0x59,0x31,0x3e,
4486
0xb2,0x5a,0xf9,0x26,0xc6,0x47,0xac,0xe7,0xbb,0x26,0x2e,0x49,0x03,0xd7,0xe9,0x7d,
4487
0x00,0x3d,0xde,0x5d,0xe8,0xef,0xee,0x46,0x6f,0xf7,0x09,0xf8,0x24,0x27,0xd3,0xd3,
4488
0x3d,0x00,0x3e,0x32,0xd4,0xf5,0x74,0xdf,0x80,0x53,0xf2,0x10,0x2e,0x89,0xf5,0x70,
4489
0x3f,0x47,0xb7,0xf6,0xab,0x74,0x6a,0xbf,0x89,0x53,0xb2,0x98,0x0e,0xed,0x15,0x74,
4490
0x66,0x27,0x71,0x4a,0xea,0xe0,0x92,0x74,0xa0,0x0b,0xbb,0x0b,0x1d,0xd8,0xd6,0x7f,
4491
0xdd,0x1d,0x97,0xe4,0x14,0xd7,0x69,0x3d,0x02,0x9f,0xe4,0x71,0xe7,0x91,0x58,0x6f,
4492
0xf5,0x6b,0xae,0xab,0x7a,0x21,0xfd,0xd4,0x5f,0x6c,0x51,0xd5,0x4b,0xdd,0x92,0x2e,
4493
0xea,0x4e,0x38,0x25,0xa1,0x7f,0xba,0xb7,0xf3,0x4a,0xae,0x73,0x2e,0x89,0x75,0x4c,
4494
0x4f,0x70,0xbd,0xd2,0xe6,0x8f,0xcc,0xa1,0x43,0x3a,0xf8,0x23,0xdb,0xd1,0x1b,0xdd,
4495
0x2a,0x0f,0x1f,0x39,0x00,0xaf,0xe4,0x1c,0xd7,0x0f,0x7d,0x15,0x7c,0xe4,0x1a,0x1c,
4496
0x93,0x3f,0xd1,0x05,0xfd,0x3c,0x7c,0x64,0x96,0xf2,0x4e,0xed,0xa8,0x07,0xda,0x3a,
4497
0xa0,0xad,0xfb,0xb9,0x1d,0x7d,0xcf,0x1d,0xe9,0x73,0xee,0x85,0x87,0xd2,0x17,0xef,
4498
0x64,0x88,0xeb,0x65,0xbe,0x8a,0x2e,0x66,0xeb,0x61,0xb6,0x9e,0xe5,0xe7,0x1d,0x1f,
4499
0x39,0x14,0xbf,0xc4,0xdc,0x92,0x13,0xf1,0x49,0x6e,0xc4,0x23,0x79,0xd2,0xf9,0x23,
4500
0xcf,0xe3,0x8c,0xd4,0xc1,0x15,0x39,0x81,0xee,0xe3,0xcb,0x71,0x45,0x6e,0xc7,0x15,
4501
0xf9,0x1e,0x3e,0x12,0xfc,0x90,0x61,0xf8,0x21,0x77,0xe1,0x83,0x6c,0xe9,0xfa,0x8c,
4502
0xf7,0xa5,0xc3,0xb8,0x0d,0x4e,0xc8,0x51,0x38,0x21,0x03,0xe9,0x2a,0x9e,0xe0,0x3a,
4503
0x8a,0x9f,0x71,0xbd,0xc4,0x2f,0xd1,0x45,0xfc,0x4e,0x8c,0x8f,0x84,0xfe,0xe1,0x6f,
4504
0x95,0x62,0x3a,0x88,0x8d,0x8f,0xec,0x80,0x33,0x72,0x15,0xae,0xc8,0x43,0x8e,0x8f,
4505
0x04,0x47,0xa4,0x1e,0x5d,0xc2,0xfb,0xd0,0x21,0xdc,0xd8,0x75,0x07,0xef,0x47,0x5f,
4506
0x70,0xe0,0x23,0x07,0xe3,0x90,0x0c,0xc1,0x1d,0x79,0x99,0x4e,0xe0,0xca,0x1d,0x22,
4507
0x77,0x64,0x7b,0xd7,0x05,0x7c,0x8c,0xe3,0x23,0x27,0xc5,0xf8,0xc8,0xa9,0x74,0xfb,
4508
0x0e,0x72,0x9d,0xbe,0xa3,0xe8,0xf1,0x1d,0x47,0x6f,0x6f,0x81,0xeb,0xe9,0x0d,0x7c,
4509
0x64,0x7f,0xfc,0x93,0xfe,0xf4,0xec,0x5e,0x41,0xcf,0xee,0xbd,0xf4,0xe9,0x3e,0xe8,
4510
0x7a,0x74,0xc7,0xb9,0xae,0xdc,0xff,0xa5,0x1f,0xf7,0x33,0xc7,0x47,0x56,0xd1,0x85,
4511
0xdb,0x98,0xee,0xdb,0xd6,0x74,0xde,0x1e,0x86,0xa3,0x12,0xfc,0x94,0x17,0xe9,0xaf,
4512
0x5d,0xe0,0xfa,0x6b,0x97,0xba,0xce,0x5a,0xeb,0xaa,0xfd,0xda,0xf5,0xd2,0x4e,0xa7,
4513
0x63,0xb6,0x2e,0xee,0xc9,0xc1,0x38,0x27,0xc7,0xc5,0xf8,0xc8,0xef,0x70,0x4b,0xa6,
4514
0x3a,0x3e,0x32,0x03,0xaf,0x24,0x38,0x25,0x73,0x71,0x4a,0x82,0x4f,0xb2,0x10,0x9f,
4515
0x64,0x05,0x3e,0x49,0x70,0x49,0x7e,0x50,0x8a,0xe9,0x8b,0x35,0x3e,0x52,0x7f,0x13,
4516
0xf8,0x48,0x2b,0xe5,0x20,0xf8,0xc8,0x49,0xf0,0x91,0x53,0xab,0xe1,0x23,0x03,0x1c,
4517
0x1f,0xb9,0x44,0xb9,0x4c,0x19,0x0a,0x1f,0x19,0xa5,0x5c,0xef,0xfc,0x95,0xe7,0xe8,
4518
0x9d,0x4d,0xc2,0x47,0x32,0xf0,0x91,0x22,0x3c,0x96,0x6d,0x9c,0xc7,0x12,0xfc,0x95,
4519
0x3d,0x7f,0x82,0x8f,0x98,0xbf,0x12,0x3c,0x95,0xf6,0x78,0x2a,0x5d,0xf0,0x54,0xba,
4520
0x29,0xdd,0x95,0x3e,0x78,0x29,0xd7,0x2b,0x5b,0xee,0x51,0xc5,0x47,0x5a,0xef,0xa9,
4521
0xd9,0x4f,0xf9,0x23,0x7c,0xa4,0xe1,0x5e,0x9a,0x3b,0x94,0x6b,0x94,0x3b,0x95,0x4f,
4522
0x94,0x47,0xf6,0x89,0xf8,0x48,0x65,0x7d,0xa5,0x81,0x3e,0x8e,0x34,0x50,0x56,0x36,
4523
0x8e,0x7c,0x96,0x4f,0xf1,0x59,0x56,0xe1,0xb3,0x54,0x36,0xa9,0xf2,0x59,0x9a,0xe2,
4524
0xb0,0x0c,0x84,0x8f,0xdc,0x86,0xbb,0x32,0x1e,0x67,0x65,0x1a,0xae,0xca,0x1c,0x1c,
4525
0x95,0x0f,0xe8,0x8e,0x3d,0xb1,0x99,0xbe,0x76,0x2b,0xb7,0x2b,0x6b,0x94,0x37,0x34,
4526
0xb4,0x56,0xc2,0x47,0xd2,0xf8,0x2a,0xbb,0xe1,0xab,0x34,0xa5,0x3f,0xb6,0x14,0x6f,
4527
0xa5,0x2d,0x9e,0x4a,0x27,0x3c,0x95,0x3b,0xf0,0x54,0xee,0x81,0x8f,0x58,0x37,0x6c,
4528
0x70,0x52,0x9a,0xe3,0xa2,0x04,0x0f,0xe5,0x23,0xf8,0xc8,0xce,0x2d,0xf4,0x79,0xad,
4529
0x74,0x57,0xfa,0x28,0x97,0x29,0x43,0x95,0x72,0x65,0xba,0xf2,0xaa,0x32,0x57,0xb9,
4530
0xb0,0xa5,0xde,0x6f,0xca,0xfb,0xca,0x42,0xe5,0x07,0xf8,0x48,0x70,0x58,0x2a,0xbb,
4531
0x45,0xce,0xca,0x0b,0xff,0x13,0xb9,0x29,0xb5,0x71,0x52,0x82,0x87,0x32,0x08,0x3e,
4532
0x62,0x9d,0xaf,0x7f,0xa6,0xdf,0x75,0x05,0x7d,0xae,0x5f,0x2b,0xbb,0x3b,0xd7,0xc4,
4533
0x9c,0x12,0xeb,0x5c,0xb5,0xae,0x55,0xeb,0x58,0xdd,0xcb,0xf5,0xa9,0x36,0x86,0x8f,
4534
0xb4,0x55,0xf6,0xc7,0x1b,0xb9,0x88,0xfe,0xd4,0xe7,0xe9,0x4d,0x5d,0xe5,0xfa,0x51,
4535
0xf7,0xa6,0x0b,0xf5,0x10,0x3a,0x50,0x8f,0xc2,0x19,0x19,0xee,0xba,0x4e,0x9f,0xa4,
4536
0xdf,0x74,0x0a,0xbd,0xa6,0xb3,0xe9,0x31,0xb5,0x0e,0xd3,0xe0,0x8c,0x34,0xa0,0x9b,
4537
0xb4,0x94,0x4e,0xd2,0x56,0x74,0x91,0x5a,0x0f,0xe9,0x11,0x8e,0x8f,0xf4,0x72,0x7d,
4538
0xa2,0x8f,0x39,0x3e,0x32,0x11,0x5f,0x64,0x12,0xbe,0xc8,0xf4,0x18,0x1f,0x59,0x46,
4539
0xef,0xa7,0x75,0x7b,0x66,0xf0,0x41,0xb6,0xc5,0x03,0x69,0x86,0xe7,0x71,0x36,0x9e,
4540
0x87,0x75,0x72,0x5a,0x17,0xa7,0x75,0x6f,0x86,0xce,0xcd,0xfb,0x70,0x3d,0x82,0xe7,
4541
0x71,0x2e,0x7e,0x47,0xc6,0x79,0x1d,0xf5,0x70,0x3a,0x1a,0xe2,0x74,0x98,0xcf,0xd1,
4542
0x19,0x87,0xa3,0xbb,0xf2,0xac,0x32,0x1f,0x87,0xa3,0x3b,0x0e,0xc7,0x2d,0x38,0x1c,
4543
0x73,0x95,0xef,0x94,0xca,0xef,0xa3,0xee,0xcc,0x1d,0xe8,0xce,0xec,0x9e,0x87,0x8f,
4544
0x9c,0x04,0x1f,0x39,0x59,0x39,0x45,0x39,0x1d,0x3e,0xd2,0x1f,0x3e,0x32,0x04,0x07,
4545
0x24,0xf0,0x91,0x54,0xa5,0x3e,0x06,0x94,0xe2,0x18,0x1f,0xa9,0x4d,0xef,0x66,0xe0,
4546
0x23,0xbb,0xe1,0x8a,0x94,0xb9,0xce,0xcd,0x69,0x78,0x20,0x73,0xf1,0x3f,0x82,0xfb,
4547
0xb1,0x58,0xf9,0xbb,0xf2,0xb1,0xf2,0xb9,0xf2,0x7d,0xf8,0x3b,0xf1,0x40,0xda,0xe1,
4548
0x7f,0x74,0xc3,0xfb,0x58,0x1b,0xe3,0x23,0x2d,0x95,0x4e,0xca,0x0d,0xca,0x4d,0xca,
4549
0x5d,0xf0,0x91,0xef,0xe0,0x23,0x77,0xb9,0x1e,0xcd,0x75,0xca,0x9e,0x78,0x1f,0x17,
4550
0xd0,0x8f,0xf9,0x67,0x7c,0x8f,0xe0,0x78,0xfc,0x99,0xee,0xcb,0x05,0x38,0x1d,0xf5,
4551
0x71,0x39,0x2e,0xc5,0xe1,0xf8,0x3d,0xee,0xc6,0xbd,0x38,0x1b,0x93,0x71,0x35,0x82,
4552
0xa7,0xd1,0x06,0x3f,0xe3,0x0c,0xbc,0x8c,0x72,0x7c,0x0c,0x73,0x31,0x5a,0x3b,0xff,
4553
0xe2,0x18,0x5c,0x8b,0xc7,0x70,0x2d,0x82,0x67,0xb1,0x53,0x51,0xc4,0x47,0xf6,0xc7,
4554
0xaf,0x08,0x6e,0xc5,0x5c,0xbc,0x8a,0x02,0xba,0x26,0x6b,0xe3,0x56,0x6c,0x87,0x53,
4555
0x61,0xbd,0x92,0x87,0x2a,0xc7,0x2b,0xf7,0xe0,0x52,0x84,0xfe,0xc8,0xaf,0x8a,0x23,
4556
0x9f,0xa2,0x13,0x3e,0xc5,0x20,0x3c,0x8a,0xbb,0x94,0xc7,0x4a,0x22,0x97,0xe2,0x09,
4557
0x1c,0x8a,0xca,0x9a,0x91,0x43,0x51,0x9f,0xae,0xc8,0xc3,0x70,0x26,0xce,0x85,0x8f,
4558
0x04,0x5f,0xe2,0x66,0x65,0x28,0xce,0xc4,0xa3,0xf0,0x91,0xc7,0x71,0x24,0x5e,0xa1,
4559
0xeb,0xf1,0x6d,0x5c,0x89,0xd0,0xf3,0x58,0x1f,0x3f,0x22,0x74,0x3a,0xf6,0xc2,0x91,
4560
0x08,0x7d,0x8e,0xa3,0x94,0x57,0x5d,0x97,0x63,0x12,0x4f,0x22,0x74,0x36,0x76,0x53,
4561
0x4e,0x73,0xbd,0x8d,0x83,0x5c,0x57,0xe3,0x95,0xf4,0x31,0x3e,0x45,0x0f,0x63,0xe8,
4562
0x60,0x9c,0xe1,0xf8,0xc8,0x52,0xfa,0x17,0x53,0xf8,0x14,0xd6,0xb9,0xd8,0x0a,0x9f,
4563
0x62,0x90,0xeb,0x51,0xbc,0x92,0xae,0xc4,0xd0,0x93,0xf8,0x92,0xeb,0x45,0x0c,0x7c,
4564
0x64,0xa1,0xf2,0xc5,0x96,0x91,0x4b,0xd1,0x8c,0xae,0xc3,0x96,0x8e,0x8f,0x84,0x6e,
4565
0xc3,0x03,0xe0,0x23,0xd6,0x6b,0x68,0x7e,0xc5,0x8d,0x38,0x15,0x63,0x5d,0x77,0xe1,
4566
0x12,0xfa,0x0a,0x43,0x57,0x61,0x92,0x8e,0xc2,0x9a,0xb8,0x15,0x0d,0x70,0x2a,0x5a,
4567
0xe2,0x52,0x74,0x70,0xdd,0x83,0x5d,0xe8,0x1b,0xec,0xe6,0xf8,0xc8,0x29,0x74,0x0a,
4568
0x0e,0x71,0x6e,0xc5,0x4d,0xf8,0x14,0x4f,0xbb,0xbe,0xc0,0xe7,0xe9,0x08,0x9c,0x9d,
4569
0x87,0x8f,0xbc,0xa1,0xbc,0x4d,0x0f,0x60,0x5b,0x7a,0xff,0x3a,0xbb,0xbe,0xbf,0xc0,
4570
0x47,0x7a,0x3b,0x3e,0x72,0x32,0x5d,0x7e,0x93,0x1c,0x1f,0x99,0xe6,0x7a,0xfb,0x66,
4571
0xe2,0x62,0x84,0x7e,0xbe,0xc7,0xe9,0xe3,0x9b,0xe2,0x7a,0xf8,0x2a,0x70,0x33,0x42,
4572
0xef,0x5e,0x0b,0x7a,0xf6,0x3a,0x38,0x3e,0x62,0xbd,0x7a,0xa1,0x4f,0xef,0x1c,0xd7,
4573
0xa7,0x67,0x7c,0xe4,0x31,0xd7,0x9d,0x17,0xf8,0xc8,0x64,0xba,0xf2,0x42,0x4f,0xde,
4574
0x8e,0x31,0x3e,0xb2,0xbb,0xeb,0xc3,0x6b,0x8c,0xe3,0xd1,0xcc,0x75,0xdd,0xb5,0x83,
4575
0x8f,0xac,0x76,0x9e,0xc7,0xd6,0xb8,0x1d,0xad,0xe9,0xae,0xeb,0xe0,0xf8,0x88,0x75,
4576
0xd2,0x1d,0x42,0x1f,0xdd,0x83,0xf4,0xcf,0xbd,0x45,0xef,0x9c,0x75,0xce,0x59,0xb7,
4577
0x5c,0x46,0xc9,0xd2,0x2d,0xd7,0x82,0x4e,0xb9,0x76,0x74,0xc8,0x1d,0xe2,0xf8,0xc8,
4578
0xb1,0xf4,0xc6,0xf5,0xc6,0xfb,0xb0,0xae,0xb8,0xd0,0x11,0xf7,0x17,0xe7,0x7e,0x18,
4579
0x1f,0x39,0x35,0xc6,0x47,0x16,0xd3,0xfb,0x96,0xa5,0xe7,0xad,0x0d,0xfd,0x6e,0x07,
4580
0x2b,0xe7,0xe0,0x82,0x58,0x7f,0x9b,0xf5,0xb6,0x59,0x5f,0x5b,0xe8,0x69,0xcb,0xe0,
4581
0x87,0x94,0xba,0x5e,0xb6,0x03,0x5c,0x17,0x5b,0x57,0xfa,0xd7,0x4e,0xc3,0x13,0xb9,
4582
0x89,0x9e,0xb5,0x3f,0x56,0xc3,0x47,0xc6,0xe2,0x88,0x7c,0xe2,0xf8,0xc8,0x6a,0x7a,
4583
0xd2,0xbe,0xa9,0x17,0xf5,0xa3,0xd5,0xa1,0xff,0xac,0x9d,0xeb,0x3d,0x33,0x3e,0xd2,
4584
0xcb,0xf1,0x91,0xd7,0x95,0xf7,0x94,0x45,0xca,0xaa,0x5d,0x23,0x87,0xe4,0x20,0x5c,
4585
0x91,0xd5,0xcd,0xf5,0x67,0xe9,0x31,0x3b,0x84,0xfe,0xb2,0xe0,0x88,0x04,0x3f,0x64,
4586
0x17,0xfa,0xca,0x9a,0xd0,0x53,0x16,0x3a,0xca,0xf6,0xc3,0x11,0x39,0x0b,0x47,0xe4,
4587
0x65,0x1c,0x91,0x2f,0xe0,0x23,0xcd,0xe9,0x20,0x3b,0x98,0xee,0xb1,0x93,0x71,0x45,
4588
0x82,0x27,0x12,0xba,0xc5,0xee,0xc0,0x05,0x09,0x1e,0x88,0x75,0x89,0x5d,0x43,0x6f,
4589
0xd8,0x3d,0xf8,0x1f,0x9e,0x8f,0x04,0xef,0xe3,0x1d,0x7c,0x8f,0xe0,0x7a,0xdc,0x82,
4590
0xe3,0xb1,0x06,0xb7,0x23,0x78,0x1d,0xe6,0x74,0x98,0xcb,0x71,0x26,0xfe,0x46,0x7f,
4591
0xbc,0x8d,0x6b,0xf1,0x35,0xee,0xa2,0xcf,0x2b,0xf0,0x91,0xfb,0x94,0x37,0x66,0x25,
4592
0x13,0x2b,0xe8,0xf6,0xfa,0x4e,0x99,0x30,0x47,0x9f,0xd3,0xca,0xeb,0xca,0xf7,0x73,
4593
0xa2,0xae,0xaf,0xd0,0xf3,0x35,0x53,0xf9,0x72,0x9e,0x3e,0xfe,0xe9,0xfb,0x3a,0x9d,
4594
0x9e,0xaf,0xd0,0xf1,0x75,0x29,0x1d,0x5f,0x57,0xd1,0xf1,0x35,0x96,0x8e,0xaf,0xa5,
4595
0xca,0xa7,0x4a,0xa5,0xd2,0x99,0xbe,0xaf,0xc0,0x47,0x4e,0xa0,0xeb,0x2b,0xf4,0x7b,
4596
0x2d,0x50,0xd6,0x28,0xc7,0x2e,0x48,0x26,0x2e,0x5e,0x10,0xb9,0x24,0x77,0x39,0x87,
4597
0xe4,0x01,0xbc,0x11,0x73,0x46,0x66,0xe2,0x89,0x14,0xe3,0x87,0xec,0x8c,0x17,0xd2,
4598
0xd1,0xf9,0x20,0x3d,0x70,0x40,0x2a,0xe0,0x23,0xef,0xc0,0x47,0xd6,0xc2,0x47,0x82,
4599
0xff,0x51,0x17,0xff,0xa3,0x35,0xfe,0x47,0x77,0xfc,0x8f,0x01,0xf8,0x1f,0xa3,0xf0,
4600
0x3f,0xc6,0xe2,0x7f,0xcc,0xc4,0xff,0x08,0xdd,0x5c,0x95,0x7f,0x8b,0xba,0xb9,0xda,
4601
0xd1,0xcd,0x35,0x04,0x3e,0x32,0x02,0x3e,0x72,0x3d,0xdd,0x5c,0xa1,0x97,0x6b,0xe7,
4602
0x77,0x23,0x2f,0xe4,0x36,0x7c,0x90,0x0c,0x7d,0x5b,0xbb,0xd3,0xb3,0xd5,0xc8,0xf5,
4603
0x6b,0x35,0xa1,0x53,0xeb,0x00,0xba,0xb4,0xba,0x2f,0xae,0xea,0xd0,0x5a,0x46,0x6f,
4604
0xd6,0xb7,0xf0,0x91,0x65,0xf4,0x64,0x85,0x8e,0xac,0xe5,0x74,0x63,0xad,0x85,0x8f,
4605
0x7c,0xe0,0xba,0xb0,0xac,0x03,0x6b,0x39,0xbd,0x57,0xd6,0x79,0x15,0x9c,0x90,0x8f,
4606
0x71,0x41,0x3e,0xc7,0x01,0x09,0xfe,0xc7,0x5c,0xfa,0xac,0x0e,0x72,0x3d,0x56,0xa1,
4607
0xbf,0xaa,0x8f,0x32,0xf1,0x33,0xbd,0x6e,0xcb,0x23,0x1f,0x64,0x57,0xe7,0x81,0xd4,
4608
0xc7,0xfd,0x68,0xfb,0x13,0x7c,0xa4,0xbb,0xf3,0x3a,0xaa,0xe3,0x23,0xe6,0x6e,0xf4,
4609
0xc7,0xd7,0xb8,0xc8,0x79,0x1a,0xa3,0x70,0x33,0xee,0xc3,0xc9,0x08,0x3e,0xc6,0x2a,
4610
0xa5,0xf1,0xca,0x64,0xe2,0x0f,0xca,0x78,0x65,0xba,0x32,0x57,0xf9,0x52,0x29,0x5e,
4611
0xa5,0x99,0x46,0x69,0x06,0x1f,0x39,0x4b,0x19,0xa0,0x3c,0xea,0xf8,0x48,0x6a,0xb5,
4612
0x5e,0x4f,0xe5,0x50,0xa5,0xa7,0x72,0x9a,0xf2,0xb7,0xaf,0x92,0x89,0xcf,0x94,0xef,
4613
0x94,0xbf,0x39,0x3e,0xb2,0x4c,0x29,0xf9,0x46,0x6f,0x8f,0xd2,0x4b,0xb9,0x46,0x19,
4614
0xa7,0x4c,0x51,0x66,0x28,0x6f,0x2b,0xc7,0xad,0xd5,0xbf,0xa3,0x72,0xb9,0xf2,0x02,
4615
0x7c,0xe4,0x7d,0x65,0x99,0xb2,0x56,0xf9,0xfd,0x3a,0xbd,0xff,0xe9,0xbe,0x0a,0x7c,
4616
0x24,0xb8,0x24,0xf5,0x70,0x48,0x16,0xe1,0x8e,0x04,0x6f,0xe4,0x70,0x7c,0x91,0xe0,
4617
0x8a,0x04,0x3e,0x72,0x45,0x22,0xea,0xb7,0xfa,0xbe,0xb2,0xb6,0x52,0x27,0x91,0xdc,
4618
0xb6,0xee,0xb6,0x35,0xeb,0x26,0xf5,0x43,0xba,0x24,0x5d,0x90,0x2a,0x48,0x15,0xa6,
4619
0xd2,0x19,0x3d,0x26,0xeb,0x26,0x53,0x7a,0x8a,0x7e,0x91,0x2e,0x29,0xd4,0x4f,0x85,
4620
0x99,0xf4,0x86,0x8f,0x59,0xfd,0xc0,0xaf,0x33,0xe1,0x17,0xd9,0xdc,0x8f,0xe9,0x92,
4621
0x6c,0x0d,0x7b,0xac,0x51,0x9c,0x2e,0x2a,0x29,0x4a,0x15,0xa5,0xb3,0x45,0xd9,0xe2,
4622
0x92,0xe2,0xa2,0xf0,0x53,0xf8,0xb5,0x52,0x58,0x14,0xfe,0x4b,0x8f,0x7a,0xb6,0x74,
4623
0x0d,0xf7,0x47,0xb2,0x35,0x8a,0x8a,0x8a,0xc3,0x33,0x66,0x33,0x1b,0x3e,0x46,0x0f,
4624
0xb9,0x5f,0x65,0xa3,0x5f,0x95,0xe8,0x31,0x6b,0xbf,0x11,0x7e,0x27,0x9b,0xfb,0xaf,
4625
0xd8,0xb3,0x47,0xcf,0x9f,0xf5,0xcf,0xcb,0x73,0xac,0x7f,0xee,0xaa,0x87,0x2c,0xd1,
4626
0x1b,0x9e,0xb5,0x17,0x93,0xfb,0x8b,0xa3,0xa7,0xa7,0x79,0xe6,0x6c,0x55,0xb2,0xee,
4627
0x95,0x5a,0xff,0x77,0x65,0x79,0x59,0xfa,0xb9,0x64,0xc3,0x57,0x3d,0x53,0xf5,0x1a,
4628
0x66,0xd3,0xeb,0x7f,0x95,0xf5,0x4f,0xae,0xf6,0xed,0xce,0x6c,0xf8,0x4a,0xe6,0xde,
4629
0xf3,0x35,0x33,0xe9,0xcc,0xfa,0x97,0xec,0xfe,0x44,0x78,0x91,0xe9,0x74,0x36,0x99,
4630
0x75,0x2f,0x34,0x7a,0x86,0x74,0xee,0x9f,0x2a,0xf7,0x66,0xac,0x7f,0xb9,0xbc,0xae,
4631
0xd9,0xec,0xfa,0xe7,0x8a,0xbf,0x02,0xfe,0x3d,0x51,0xf5,0xb4,0xaa,0x87,0x74,0xf4,
4632
0xea,0xf0,0x73,0xcd,0x64,0xa6,0x46,0xba,0x66,0xdd,0xed,0xea,0xd4,0xae,0xb5,0x45,
4633
0xaa,0x24,0x9d,0xd2,0x13,0xb6,0xd9,0x72,0xab,0xad,0x93,0x85,0x99,0xc2,0x82,0x74,
4634
0x2e,0x25,0xd9,0x74,0xfc,0x63,0x49,0xaf,0xf3,0xfa,0x5f,0xa7,0x0b,0x4a,0xa2,0x9f,
4635
0xed,0x43,0x2e,0x9d,0x7b,0x85,0xd3,0xeb,0xdf,0xf3,0xbc,0x17,0xd2,0xb9,0x87,0x9a,
4636
0xf6,0xbb,0xb9,0x9f,0xab,0x3e,0x1c,0x7f,0xfc,0x22,0xf8,0x3d,0x7d,0xf4,0x45,0x6f,
4637
0x7f,0xf4,0x9c,0xf6,0x16,0xa5,0xb3,0xb9,0xd7,0x21,0xf6,0x66,0x67,0xab,0xfe,0x99,
4638
0xfd,0x7f,0xfe,0xf8,0x9d,0x93,0xc9,0xa4,0x37,0xfc,0xc8,0xcb,0xe8,0x23,0xb9,0xa0,
4639
0x46,0xee,0xa1,0x28,0x6d,0x8f,0xe1,0x65,0xa7,0x72,0x8f,0xfa,0x54,0x4b,0xeb,0x87,
4640
0xa2,0xa2,0xe4,0x86,0x9f,0x75,0xb9,0x3f,0x5a,0xa2,0xa7,0xa5,0xab,0xde,0xbb,0x99,
4641
0xe8,0x9d,0x10,0x5e,0x58,0x61,0x26,0x53,0xed,0x87,0x44,0xf4,0x12,0xab,0x1e,0xd2,
4642
0xb9,0x1f,0xf5,0x71,0x9b,0xfb,0x31,0xf7,0x6b,0x7b,0x62,0xee,0x35,0xca,0x16,0x17,
4643
0xd7,0xc8,0xea,0xbf,0x8b,0xc3,0xd3,0xf5,0xa9,0x98,0x2e,0xd2,0xe7,0x5d,0xee,0x93,
4644
0xb1,0x46,0x0d,0xde,0x39,0xd9,0x6a,0xde,0xe6,0x0d,0x3f,0x2c,0x63,0x1f,0xa3,0x3f,
4645
0xfa,0x34,0xcd,0x64,0x32,0xf6,0x39,0x97,0xcd,0xfc,0xf8,0xef,0x88,0xbf,0x8f,0x37,
4646
0x78,0x81,0xe9,0xea,0x5e,0x90,0x7f,0xf7,0x56,0xfd,0x66,0xbe,0x0f,0x5b,0xf7,0x0a,
4647
0x65,0xfd,0x4b,0xc8,0x44,0x5f,0x28,0xb2,0x1b,0xfe,0x2d,0x99,0xd8,0x2b,0x17,0xbe,
4648
0xf4,0x65,0x36,0xfc,0x04,0xca,0x64,0xaa,0x3e,0xe5,0xfd,0xdb,0x99,0xae,0xfe,0x9f,
4649
0x24,0x9b,0x49,0xea,0xe3,0x3d,0xf7,0x41,0xba,0xfe,0xe5,0x27,0xb3,0xf6,0xa1,0x97,
4650
0xb5,0x2f,0x98,0xd5,0x3d,0x54,0xf7,0x81,0x5b,0x58,0xf5,0xb6,0x65,0xd3,0xbc,0x11,
4651
0x1b,0xbc,0x87,0x4a,0xdc,0x97,0xc6,0xaa,0x37,0xbd,0x46,0xf4,0x65,0x55,0xff,0xc8,
4652
0x1b,0x7d,0x88,0x3e,0xa1,0xd2,0x85,0xe9,0xaa,0xaf,0xea,0x99,0xdc,0x53,0x32,0xe9,
4653
0x6a,0x1e,0x0a,0xab,0x5e,0xf5,0x64,0xf8,0x52,0x63,0xf7,0xac,0x8f,0x80,0x27,0x6f,
4654
0xea,0xbd,0xe6,0x76,0x8f,0xb9,0xdd,0x57,0x6e,0xf7,0x93,0xc7,0xef,0x23,0x8f,0xdf,
4655
0x43,0x6e,0xf7,0x8b,0xdb,0xbd,0xe2,0x76,0x9f,0xb8,0xdd,0x1b,0x6e,0xf7,0x84,0xdb,
4656
0xfd,0xe0,0x76,0x2f,0xb8,0xdd,0x07,0x6e,0xf7,0x80,0xdb,0xfd,0xdf,0x76,0xcf,0xb7,
4657
0xbf,0xd7,0xdb,0xbc,0xb7,0x0e,0xdc,0xd7,0xdd,0xdd,0xdd,0xc3,0x6d,0xf7,0x6f,0x1b,
4658
0xc7,0xb5,0xfb,0xb2,0xa7,0x55,0x73,0x3f,0xf6,0x6c,0x77,0x1f,0xb6,0xdd,0x7f,0xfd,
4659
0x43,0xcc,0x61,0xf3,0xf7,0x54,0xff,0xd4,0xfd,0xd4,0x76,0x0f,0xb5,0xbf,0x7f,0x7a,
4660
0x84,0xbb,0x47,0x7a,0x9a,0xbb,0x37,0xda,0x7b,0x69,0x76,0x2f,0xf4,0xda,0x18,0x6b,
4661
0xed,0xe0,0xb8,0x6a,0xfc,0xbe,0x66,0xef,0x9c,0xd9,0x7d,0xcc,0x76,0xff,0xf2,0xb4,
4662
0x6a,0xee,0x47,0x9e,0xed,0xee,0x43,0x4e,0xc0,0x44,0xed,0x5e,0xe3,0x8e,0x1b,0xb9,
4663
0xc7,0xd8,0xee,0x2b,0xbe,0x92,0x7b,0x89,0xed,0xbe,0xe1,0x69,0xee,0x5e,0x61,0xbb,
4664
0x4f,0xd8,0xdf,0x23,0x6c,0xf7,0x06,0xfb,0x7b,0x82,0x0b,0xdc,0x3d,0xc0,0x1d,0xab,
4665
0xb9,0xf7,0xb7,0x9b,0xbb,0xdf,0xd7,0xee,0xf5,0x35,0xe6,0xe9,0xef,0xe5,0xad,0xee,
4666
0x3e,0x5e,0xbb,0x87,0xd7,0xee,0xdf,0xb5,0x7b,0x77,0xed,0x9e,0x5d,0xbb,0x2f,0xd7,
4667
0xee,0xc9,0xb5,0xfb,0x70,0xed,0xde,0xdb,0x8d,0xdd,0x77,0x7b,0x7e,0xec,0x3e,0xdb,
4668
0x7c,0xf7,0xd8,0x36,0x86,0x4d,0x1e,0x0b,0x9b,0xb4,0xfb,0x65,0xed,0x5e,0x59,0xbb,
4669
0x4f,0xd6,0xee,0x91,0x1d,0x0e,0x9b,0xb4,0x7b,0x61,0xef,0x80,0x51,0xda,0xbd,0xaa,
4670
0xe6,0x52,0x99,0x47,0x65,0xf7,0x9b,0xda,0x7d,0xa6,0x13,0x61,0x81,0x76,0x0f,0x69,
4671
0xfc,0xfe,0x51,0xeb,0x87,0xb3,0xfb,0x44,0x77,0x73,0xf7,0x83,0x06,0xae,0xb7,0x9d,
4672
0xe3,0x75,0xc6,0xe9,0xfc,0x3d,0x9b,0xe5,0xee,0x1e,0x4d,0xf3,0x95,0xba,0xc4,0xee,
4673
0xbb,0x1c,0x0e,0x87,0x1b,0x07,0x73,0x0b,0x6c,0x6d,0x2f,0x98,0x9a,0xbf,0x07,0x72,
4674
0xa9,0xbb,0xef,0xf1,0x8b,0x18,0x3f,0xb3,0xfb,0x19,0xe7,0xc1,0x93,0xec,0x1e,0x40,
4675
0xbb,0xd7,0xcf,0xee,0xe3,0x6b,0x04,0x27,0xb1,0xfb,0xf3,0x06,0xc0,0x22,0xec,0xfe,
4676
0x39,0xbb,0x67,0xce,0xee,0x95,0xb3,0xfb,0xdd,0xec,0x5e,0x37,0xbb,0xcf,0x6d,0xcf,
4677
0xd8,0xbd,0x6d,0x76,0x5f,0xdb,0x44,0x18,0x83,0xdd,0xcb,0x66,0xf7,0xaf,0xd9,0x7d,
4678
0x6b,0x5d,0xe1,0x0b,0xde,0xbd,0xa8,0x70,0xf7,0xa0,0x35,0x84,0x19,0xd8,0xbd,0x65,
4679
0xc6,0x0b,0x2e,0x73,0x1e,0x45,0xb9,0xbb,0x5f,0xcc,0xee,0x15,0xb3,0xfb,0xc4,0xec,
4680
0x1e,0xb1,0x65,0xdc,0x0b,0x66,0x9c,0xe0,0x43,0x77,0xff,0x56,0x38,0xff,0xb7,0xfb,
4681
0xb2,0xe2,0xf7,0x5a,0xd9,0x3d,0x50,0x76,0xef,0x93,0xdd,0xe3,0x94,0xef,0xde,0xa1,
4682
0xf8,0xfd,0x42,0x76,0x7f,0x90,0xdd,0xff,0x63,0xf7,0xf9,0xd8,0xbd,0x3d,0x76,0x2f,
4683
0x8f,0xdd,0xc7,0x63,0xf7,0xee,0xd8,0x7d,0x3b,0x09,0xb7,0xaf,0x7e,0x88,0xbb,0x3f,
4684
0xc7,0xee,0xcd,0xb1,0x3d,0xf5,0xf2,0xd8,0x3d,0x38,0x76,0xef,0x4d,0x7d,0xce,0x5c,
4685
0xed,0x3e,0x1b,0xbb,0xbf,0xc6,0x76,0xd2,0x27,0x70,0x2f,0xcd,0xcb,0xb1,0x73,0xd7,
4686
0x26,0xb1,0x7b,0x63,0xec,0xbe,0x98,0x85,0x9c,0x9f,0x26,0x38,0x3b,0xb5,0xfb,0x5a,
4687
0x3a,0xe6,0xb9,0x97,0xc5,0xee,0x63,0xc9,0x77,0x0f,0xcb,0xa4,0x4d,0xb8,0x57,0x65,
4688
0x9e,0xbb,0x37,0xc5,0xee,0x4b,0x69,0xcd,0xb9,0xa8,0xdd,0x77,0x52,0xce,0xb9,0xe7,
4689
0x63,0xee,0xfe,0x91,0x0a,0x77,0xbf,0x48,0x29,0xe7,0x9a,0x8f,0x70,0x66,0xb9,0x0b,
4690
0xe7,0x91,0x4d,0x38,0x83,0xac,0xee,0xbe,0x8c,0x8e,0xee,0x5e,0x0c,0x3b,0x77,0x7c,
4691
0xcd,0xdd,0x73,0xb1,0xc8,0xdd,0x63,0x61,0xf7,0x57,0xf8,0xfd,0x6b,0x7f,0x4f,0x45,
4692
0x4f,0xce,0x16,0xaf,0xe3,0x4c,0xb1,0x2f,0xe7,0x86,0xcd,0xdd,0x7d,0x10,0x9d,0x62,
4693
0xf7,0x3c,0x84,0x73,0xc1,0x8d,0xdd,0xd3,0x60,0xf7,0x33,0x54,0x77,0xff,0xc2,0x9f,
4694
0xdc,0xbd,0x09,0x6b,0x62,0xf7,0x23,0xd8,0xbd,0x08,0xad,0xdc,0xfd,0x07,0x07,0xba,
4695
0xfb,0x0d,0xec,0x7e,0x02,0xbb,0x97,0xa0,0x1e,0xe7,0x78,0x76,0x6f,0x80,0xdd,0x17,
4696
0x60,0x7d,0xfe,0xf1,0x1e,0xff,0x78,0x5f,0xbf,0xf5,0xe1,0xff,0x54,0x0f,0xfe,0x2f,
4697
0xda,0x7f,0xbf,0xb9,0x3d,0xf0,0x9b,0xd8,0xeb,0x6e,0x7d,0xee,0xd6,0xe3,0x6e,0x3d,
4698
0xed,0xd6,0xcf,0x6e,0x3d,0xec,0xd6,0xbb,0x6e,0xbd,0xea,0xd6,0xa7,0x6e,0x3d,0xea,
4699
0xd6,0x9f,0x6e,0x3d,0xe8,0xd6,0x7f,0x6e,0xbd,0xdc,0x61,0x97,0x32,0xc1,0x9c,0x79,
4700
0x8b,0x9b,0x2d,0x9f,0x63,0xa6,0x0c,0xf3,0xe4,0xce,0x99,0xa8,0x8f,0x7a,0x0f,0x65,
4701
0x1f,0xa5,0xbe,0xd2,0x40,0x69,0xa8,0x34,0x52,0x9a,0x2b,0x2d,0x5d,0x4f,0xf5,0xa1,
4702
0xca,0x61,0xcc,0xa0,0xe7,0xb9,0x9e,0x86,0x0b,0x94,0x8b,0x95,0x6b,0x95,0x3b,0x94,
4703
0x0a,0x65,0x86,0x32,0x53,0x99,0xa5,0xcc,0x56,0xe6,0x28,0x73,0x95,0x79,0xca,0x7c,
4704
0xf6,0x17,0xdf,0x64,0x6e,0xfd,0x5f,0xd7,0xe7,0xb0,0x96,0x5e,0xeb,0xda,0x6e,0x67,
4705
0x31,0x74,0x3a,0xd4,0x55,0x76,0x54,0xea,0x29,0xbb,0x2a,0x0d,0x94,0x86,0x4a,0x23,
4706
0xa5,0xb1,0xd2,0x44,0x69,0xca,0x7e,0xa3,0xf5,0x3f,0xfc,0x46,0xe9,0xa5,0xfc,0x56,
4707
0x39,0x5b,0x39,0x57,0x39,0x5f,0x19,0xa4,0x0c,0x56,0x2e,0x50,0x2e,0x56,0x2e,0x65,
4708
0x2e,0x7e,0x85,0xb9,0x78,0xad,0x9b,0x89,0x77,0x62,0x16,0x6e,0x48,0x17,0x44,0x67,
4709
0xe5,0x10,0xe5,0x50,0xe5,0x30,0xe5,0x70,0xe5,0x68,0xe5,0x18,0xe5,0x58,0xe6,0xe4,
4710
0xd0,0x13,0xd1,0x4f,0x39,0x43,0x39,0x53,0x39,0x8b,0xde,0x88,0x11,0xca,0xd5,0x74,
4711
0x68,0xdf,0xc4,0xae,0xa4,0xf5,0x48,0x3c,0xac,0x8c,0x57,0x1e,0x53,0x1e,0x57,0x26,
4712
0x28,0x93,0x95,0xa7,0x99,0xb5,0xc3,0x9c,0x6d,0x33,0x76,0x67,0xf6,0x25,0x7b,0x32,
4713
0x5f,0x5f,0xc9,0x4c,0x3d,0x83,0x19,0x7a,0x89,0x9b,0x99,0x3b,0x54,0xd3,0xe9,0x30,
4714
0xd0,0xcd,0xc4,0x53,0x5d,0x3f,0x83,0xcd,0xbf,0xd6,0xc1,0xd0,0x81,0x1d,0xc2,0xce,
4715
0x6e,0xc6,0xed,0xc7,0x5c,0x5b,0xc1,0x1c,0xeb,0xe7,0xd7,0x8e,0xb1,0x6e,0x83,0x7e,
4716
0xcc,0xa9,0x61,0x3e,0x9d,0xce,0x6c,0x3a,0x8b,0x59,0x34,0xc1,0xec,0xd9,0x99,0x39,
4717
0xb3,0x1f,0xb3,0xe5,0x2b,0xae,0x53,0xc0,0xe6,0xc6,0xae,0x6e,0x56,0x7c,0x89,0x19,
4718
0xb1,0xb5,0x9b,0x0b,0xcf,0xc7,0xf1,0xbf,0xda,0xb9,0xfd,0x61,0xf6,0x6b,0x8a,0xc7,
4719
0xbf,0x3f,0xfe,0xfe,0xf1,0xcc,0x7f,0xe7,0x33,0xe7,0x8d,0x64,0xd6,0xb3,0xf9,0x6e,
4720
0x2b,0xe6,0xba,0x23,0x99,0xe7,0x26,0xe2,0xc1,0xbf,0x80,0xff,0x1e,0xe6,0xb9,0x1a,
4721
0xdb,0x47,0xfb,0x5c,0x25,0xcc,0x73,0xbb,0x55,0xe3,0xb8,0xef,0x86,0xd7,0xde,0x02,
4722
0x97,0xdd,0x66,0xba,0x63,0x9d,0x9b,0xde,0x0f,0x27,0x7d,0xb0,0x9b,0xeb,0x12,0xcc,
4723
0x73,0x6d,0xb8,0xeb,0xfc,0x40,0xe6,0xba,0x61,0x38,0xe7,0x0f,0xe1,0x9a,0x7f,0x8c,
4724
0x63,0xbe,0x1c,0xb7,0xbc,0x09,0x3e,0xf9,0x3c,0xe6,0xba,0x25,0x6e,0xa6,0xfb,0x86,
4725
0x59,0xae,0xc4,0xed,0x27,0x35,0xc2,0xc3,0xee,0x8f,0x4b,0xbd,0xa2,0x49,0xd5,0x4c,
4726
0xd7,0x88,0x59,0xce,0xee,0x10,0xbe,0x9b,0xd9,0x2d,0xe5,0xe6,0xb5,0xbd,0xdd,0xdd,
4727
0xba,0x83,0x70,0x64,0x17,0xb9,0xb9,0xac,0x2b,0xf3,0xd8,0x04,0x1c,0xd8,0xa9,0x6e,
4728
0x16,0xdb,0x17,0xc7,0xd5,0x66,0xb1,0xcb,0xdd,0xfc,0xf5,0x57,0xe6,0xae,0x19,0x38,
4729
0xab,0x61,0xce,0xfa,0x88,0x3d,0x0b,0x9b,0xb1,0x12,0xcc,0x56,0x61,0x67,0x21,0x78,
4730
0x97,0x36,0x5b,0x5d,0x58,0xb0,0xa1,0x77,0x68,0xae,0x61,0xf0,0x0b,0x9f,0x77,0xdd,
4731
0x84,0xb3,0x95,0x39,0xca,0x02,0xe5,0x2d,0xe5,0x6d,0xe5,0x7d,0xe5,0x03,0x65,0xb1,
4732
0xbb,0xb3,0x31,0xf8,0x88,0x2b,0x8a,0xa3,0xbe,0xc2,0x2b,0x95,0xe1,0xca,0x08,0xe5,
4733
0x6a,0x65,0x94,0x72,0x9d,0x72,0x83,0x72,0xa3,0x72,0x93,0x32,0x1a,0x1e,0x1f,0x5c,
4734
0xc5,0x71,0x25,0x91,0x9f,0x98,0x54,0xf6,0x70,0xf7,0x37,0x9e,0xc5,0xdc,0x16,0x1c,
4735
0xc4,0x99,0x74,0x12,0xbe,0xea,0x1c,0xc4,0xe0,0x1f,0xb6,0x54,0x5a,0x39,0x0f,0xf1,
4736
0x68,0x5c,0xc4,0x21,0xca,0x85,0xcc,0x75,0xc1,0x47,0x7c,0x42,0x99,0xa8,0x4c,0x52,
4737
0x26,0x2b,0x53,0x94,0x67,0x94,0x69,0xca,0x0c,0xe5,0x59,0xfa,0x0b,0x5f,0x56,0x5e,
4738
0x81,0xd1,0x27,0x99,0x03,0x6d,0xfe,0xbb,0x02,0x3f,0x71,0xb2,0x9b,0xf9,0xea,0xe3,
4739
0x20,0xda,0x8c,0xf7,0x14,0xb3,0x5d,0x98,0xe9,0x9a,0xc3,0xcd,0xdb,0xb8,0x99,0x6e,
4740
0x21,0xbe,0x60,0x82,0x59,0xae,0xcc,0x39,0x7f,0x53,0xe0,0xd5,0xf3,0xdc,0xec,0xb5,
4741
0x1f,0xde,0x9e,0xcd,0x5e,0x13,0xe0,0xcf,0xd3,0xf1,0xf2,0x9e,0xc0,0xc3,0x9b,0xce,
4742
0xec,0xd5,0x12,0xae,0xdc,0x89,0xd9,0x6b,0x1c,0x6e,0x9d,0xcd,0x60,0xbb,0xe2,0xcf,
4743
0x05,0x77,0xae,0xb9,0xf9,0x72,0xcc,0x5e,0x07,0x39,0xef,0x6d,0x11,0x33,0x56,0x4b,
4744
0x66,0x2b,0x9b,0xa9,0x7a,0x31,0x53,0xfd,0x37,0x33,0x55,0x3f,0x98,0x6c,0x69,0x6c,
4745
0xa6,0x7a,0x18,0x1f,0xed,0xc9,0x9d,0x7f,0xec,0x9f,0x75,0x65,0x6e,0xba,0xd5,0xcd,
4746
0x4c,0x6b,0x98,0x95,0xda,0xc0,0x46,0x6d,0x36,0x2a,0x65,0x26,0xaa,0x87,0xf7,0xb5,
4747
0x92,0x59,0xa8,0x3b,0xb3,0xcf,0xdf,0x99,0x75,0xc6,0x4c,0xad,0x72,0xa4,0xea,0xe3,
4748
0x44,0x0d,0x66,0x9e,0x79,0x98,0x39,0xa6,0x37,0x73,0x4a,0x7b,0x37,0x9b,0xac,0xf7,
4749
0x83,0xaa,0xf1,0x81,0x6c,0xee,0xb0,0x79,0xe3,0x33,0xe6,0x8c,0x0f,0xdd,0x6c,0x61,
4750
0x33,0x85,0x79,0x3a,0xde,0x15,0x09,0x33,0x45,0x38,0xbb,0x0a,0xe7,0x56,0x76,0x66,
4751
0xf5,0x2c,0xe7,0x54,0xe1,0x8c,0x6a,0x47,0x37,0x53,0xec,0x5d,0xcd,0x4c,0xd1,0x4c,
4752
0x69,0xe1,0xee,0xbf,0xe8,0xca,0x4c,0x61,0x9e,0x83,0xb9,0x0d,0x83,0x95,0x8b,0x94,
4753
0x6b,0x94,0xdb,0x95,0xe9,0xcc,0x14,0xcf,0x2a,0xaf,0x56,0x33,0x53,0xbc,0xe6,0xee,
4754
0xcc,0x78,0x8f,0x73,0xb0,0xa5,0xce,0x81,0xf8,0xae,0x9a,0x99,0x62,0x1b,0x65,0x07,
4755
0x65,0x17,0x66,0x8a,0xfa,0x79,0x66,0x8a,0x66,0xce,0x99,0x08,0x33,0xc5,0xf1,0x4a,
4756
0x6f,0xa5,0xbf,0x72,0x8e,0x32,0xd0,0xcd,0x14,0x43,0x94,0x8b,0x94,0x4b,0x94,0x2b,
4757
0x38,0x67,0x33,0xb7,0xc2,0x66,0x8a,0x1d,0x38,0x5f,0xab,0xcf,0xb9,0x5a,0x98,0x29,
4758
0x0e,0x56,0xba,0xba,0x99,0xe2,0x28,0x37,0x53,0x98,0x5f,0x11,0x66,0x8a,0xd3,0xdc,
4759
0x4c,0x11,0x5c,0x8b,0xe1,0xca,0x48,0x66,0x8a,0x1b,0xdd,0x4c,0x11,0xce,0xe7,0xc6,
4760
0x2a,0x8f,0x32,0x53,0x94,0x2b,0x4f,0x28,0x93,0x98,0x29,0x5e,0xe2,0xec,0x2e,0xe5,
4761
0xce,0xed,0x0e,0x65,0xa6,0x38,0xce,0x9d,0xd7,0x4d,0xe5,0x8c,0x6e,0xb6,0x3b,0x8b,
4762
0x4b,0x31,0x53,0xc4,0x3d,0x08,0x3b,0x6b,0x1b,0xce,0x4c,0x61,0x4e,0xc3,0x6c,0xce,
4763
0xd3,0x2a,0x63,0x33,0x45,0x17,0xe7,0x22,0x9c,0xf2,0x13,0x33,0x45,0x59,0xcc,0x07,
4764
0x38,0xa5,0x9a,0x99,0x62,0x36,0x67,0x5b,0x49,0xce,0xb2,0xba,0x30,0x53,0x9c,0xe2,
4765
0x66,0x8a,0xd7,0xdd,0x4c,0xd1,0xce,0x9d,0x41,0x4d,0xe5,0xdc,0x69,0x87,0xd8,0x4c,
4766
0x31,0x94,0xf3,0xa5,0x6b,0xdc,0x3e,0x7c,0x98,0x29,0x4a,0xd9,0x7d,0x6f,0xc7,0xb9,
4767
0x52,0x2f,0xce,0x93,0xec,0xec,0xe8,0x6a,0x37,0x53,0x84,0xf3,0xa2,0x6d,0xd8,0x29,
4768
0x3f,0x8a,0xf3,0xa1,0x27,0xd9,0x1d,0x7f,0xc1,0x9d,0x13,0xd9,0x4c,0x61,0xe7,0x44,
4769
0x17,0x57,0xb3,0x17,0xbe,0x07,0xbb,0xe0,0x2d,0x38,0x27,0xda,0xde,0xcd,0x14,0x27,
4770
0xb9,0x99,0xe2,0x1c,0x77,0x5e,0x64,0x7b,0xdb,0xad,0xe8,0xb2,0xb1,0x99,0x62,0x30,
4771
0xbb,0xda,0xf7,0xb3,0xa3,0x6d,0xe7,0x44,0x9f,0x30,0x53,0x84,0x7d,0xec,0x96,0x9c,
4772
0x17,0xcd,0x67,0xdf,0x7a,0xa9,0x9b,0x29,0xc2,0xf9,0x50,0xa5,0x9b,0x29,0x6a,0xb3,
4773
0xd3,0x7c,0x2a,0xbb,0xca,0xe1,0xbc,0xc8,0xce,0x8a,0xc2,0x19,0x51,0x53,0xce,0x86,
4774
0x06,0x71,0x26,0x74,0x8f,0x3b,0x0b,0xb2,0x99,0x62,0x1f,0x66,0x8a,0xf3,0x99,0x29,
4775
0x9e,0x77,0xe7,0x3d,0x4d,0xd9,0x23,0x1d,0xce,0x4c,0x31,0x99,0x9d,0xd1,0x30,0x53,
4776
0x34,0x63,0x37,0xb4,0x4d,0x35,0x33,0xc5,0x44,0xce,0x72,0xec,0x1c,0x67,0x79,0x9e,
4777
0x99,0xa2,0x36,0x67,0x35,0x61,0xa6,0x58,0xe7,0x66,0x8a,0x70,0x4e,0xe3,0x77,0xf5,
4778
0xec,0x5c,0xe6,0x39,0x37,0x53,0xbc,0xc2,0x4c,0x31,0x5f,0x79,0x93,0x99,0xe2,0x3d,
4779
0x66,0x8a,0x45,0x6e,0xa6,0x08,0x67,0x38,0x9f,0x57,0x33,0x53,0x8c,0x54,0xae,0x65,
4780
0xa6,0xb8,0xde,0xcd,0x14,0x37,0xbb,0x99,0xe2,0x51,0x65,0x3c,0x33,0xc5,0xee,0x6e,
4781
0xa6,0xa8,0xcf,0x59,0xd0,0xa3,0xae,0xef,0xf8,0x45,0xce,0x83,0x6c,0x6f,0xaf,0x05,
4782
0x33,0x45,0x17,0xce,0x85,0x8e,0x62,0xa6,0x18,0xac,0x5c,0xe0,0xf6,0xf8,0xc2,0x4c,
4783
0x31,0x41,0x79,0x8a,0x99,0xe2,0x69,0x65,0x2a,0x33,0xc5,0x74,0x66,0x8a,0x99,0x79,
4784
0x66,0x0a,0x3b,0x57,0x1a,0xc2,0x5e,0xdf,0x53,0xee,0x2c,0x29,0xc5,0xee,0x5e,0x2b,
4785
0x66,0x8a,0x2b,0xd9,0xd3,0x9b,0xc5,0x4c,0xb1,0x2f,0x33,0x45,0xdb,0xd8,0x4c,0xf1,
4786
0x29,0xfb,0x75,0x1d,0x98,0x29,0x6c,0x4f,0xae,0x22,0x36,0x53,0x84,0xb3,0x9c,0x4e,
4787
0xec,0xba,0xd9,0x4c,0x31,0x89,0x99,0xa2,0x82,0x33,0x9d,0x27,0xd9,0x5d,0xab,0xe0,
4788
0x2c,0xa7,0x1d,0x33,0x45,0x99,0x9b,0x29,0x9e,0x8c,0xcd,0x14,0x7b,0x73,0xbe,0xd3,
4789
0x96,0xf3,0x9d,0x0e,0x6e,0xa6,0xb0,0x5d,0xb1,0x30,0x53,0x14,0xb3,0x13,0x66,0x67,
4790
0x35,0xc7,0x72,0x4e,0x73,0x9b,0x3b,0xa7,0x39,0x95,0x99,0xc2,0x76,0xba,0x3a,0x71,
4791
0x46,0x53,0xce,0x0e,0x57,0x38,0xa7,0x89,0xef,0x6c,0x75,0xe5,0x1c,0xc6,0xcf,0x14,
4792
0x5f,0xb0,0x7b,0xd5,0x2e,0x36,0x53,0x94,0x71,0xc6,0xd2,0x90,0x33,0x96,0x70,0xbe,
4793
0x62,0x67,0x2b,0x76,0x96,0x72,0x37,0x7b,0x47,0xb6,0x57,0xd4,0x80,0xf3,0x92,0xe1,
4794
0x9c,0x8f,0x84,0xb3,0x91,0x2e,0x9c,0x85,0xb4,0x71,0x67,0x1e,0x57,0xb9,0x9d,0x9a,
4795
0xea,0x76,0x68,0xc2,0x4c,0x61,0xe7,0x18,0xe1,0xfc,0x22,0x9c,0x5d,0xac,0x70,0x33,
4796
0x85,0x9d,0x55,0xd8,0x6e,0xcb,0x11,0xcc,0x14,0xb6,0x5f,0x51,0xb8,0xfe,0x21,0x05,
4797
0xf3,0x4d,0x25,0x95,0xc2,0x54,0x61,0x3a,0x9d,0x72,0x8f,0xe9,0xf0,0x2c,0xe9,0x94,
4798
0x9e,0x5c,0xe8,0x9f,0x5c,0xe8,0x9f,0x49,0x7f,0x28,0x59,0x18,0x3d,0x9f,0xfd,0x76,
4799
0x2a,0xf7,0x67,0x93,0xa9,0xdc,0xef,0xf2,0x37,0x16,0xfe,0xf3,0x1f,0x52,0x7a,0x3d,
4800
0x52,0xb9,0xc7,0x4d,0x7a,0x48,0x56,0xf7,0x57,0x14,0x6c,0xea,0xcb,0x4a,0xa7,0xd3,
4801
0x05,0xe9,0x54,0x41,0xf4,0x5e,0x4a,0x6d,0xf8,0x5e,0xcb,0x3d,0x99,0xf7,0x5c,0x41,
4802
0x61,0xf4,0x5e,0xc8,0xfd,0xc8,0x73,0xe4,0x7e,0x28,0x28,0xfc,0xf5,0x3c,0xe4,0xde,
4803
0x63,0xff,0x07,
4804
};
4805
}  // namespace ada::idna::table_blob
4806
#endif
4807
/* end file src/table_blob.inc */
4808
4809
#include <atomic>
4810
#include <bit>
4811
#include <cstdint>
4812
#include <cstddef>
4813
#include <new>
4814
4815
namespace ada::idna {
4816
4817
// table_blob.inc is packed little-endian (see scripts/pack_tables.py). After
4818
// inflate the multi-byte sections must be converted to host endianness so
4819
// big-endian platforms (s390x) can load uint16_t/uint32_t/uint64_t natively.
4820
// CRC is checked on the raw little-endian payload before any conversion.
4821
namespace detail {
4822
4823
template <typename T>
4824
0
inline void bswap_inplace(T* data, size_t count) noexcept {
4825
0
  if constexpr (std::endian::native == std::endian::little) {
4826
0
    (void)data;
4827
0
    (void)count;
4828
0
    return;
4829
0
  }
4830
0
  for (size_t i = 0; i < count; ++i) {
4831
0
    if constexpr (sizeof(T) == 2) {
4832
0
#if defined(__GNUC__) || defined(__clang__)
4833
0
      data[i] =
4834
0
          static_cast<T>(__builtin_bswap16(static_cast<uint16_t>(data[i])));
4835
0
#else
4836
0
      const auto v = static_cast<uint16_t>(data[i]);
4837
0
      data[i] = static_cast<T>(static_cast<uint16_t>((v >> 8) | (v << 8)));
4838
0
#endif
4839
0
    } else if constexpr (sizeof(T) == 4) {
4840
0
#if defined(__GNUC__) || defined(__clang__)
4841
0
      data[i] =
4842
0
          static_cast<T>(__builtin_bswap32(static_cast<uint32_t>(data[i])));
4843
0
#else
4844
0
      auto v = static_cast<uint32_t>(data[i]);
4845
0
      v = ((v & 0x000000FFu) << 24) | ((v & 0x0000FF00u) << 8) |
4846
0
          ((v & 0x00FF0000u) >> 8) | ((v & 0xFF000000u) >> 24);
4847
0
      data[i] = static_cast<T>(v);
4848
0
#endif
4849
0
    } else if constexpr (sizeof(T) == 8) {
4850
0
#if defined(__GNUC__) || defined(__clang__)
4851
0
      data[i] =
4852
0
          static_cast<T>(__builtin_bswap64(static_cast<uint64_t>(data[i])));
4853
0
#else
4854
0
      auto v = static_cast<uint64_t>(data[i]);
4855
0
      v = ((v & 0x00000000000000FFull) << 56) |
4856
0
          ((v & 0x000000000000FF00ull) << 40) |
4857
0
          ((v & 0x0000000000FF0000ull) << 24) |
4858
0
          ((v & 0x00000000FF000000ull) << 8) |
4859
0
          ((v & 0x000000FF00000000ull) >> 8) |
4860
0
          ((v & 0x0000FF0000000000ull) >> 24) |
4861
0
          ((v & 0x00FF000000000000ull) >> 40) |
4862
0
          ((v & 0xFF00000000000000ull) >> 56);
4863
0
      data[i] = static_cast<T>(v);
4864
0
#endif
4865
0
    } else {
4866
0
      static_assert(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
4867
0
    }
4868
0
  }
4869
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)
4870
4871
// Convert every multi-byte section of the inflated little-endian blob to host
4872
// order. Single-byte sections are left unchanged. Safe no-op on little-endian.
4873
1
inline void convert_table_blob_to_host_endian(uint8_t* buffer) noexcept {
4874
1
  if constexpr (std::endian::native == std::endian::little) {
4875
1
    (void)buffer;
4876
1
    return;
4877
1
  }
4878
0
  auto u16 = [&](size_t off, size_t count) {
4879
1
    bswap_inplace(reinterpret_cast<uint16_t*>(buffer + off), count);
4880
1
  };
4881
1
  auto u32 = [&](size_t off, size_t count) {
4882
1
    bswap_inplace(reinterpret_cast<uint32_t*>(buffer + off), count);
4883
1
  };
4884
1
  auto u64 = [&](size_t off, size_t count) {
4885
1
    bswap_inplace(reinterpret_cast<uint64_t*>(buffer + off), count);
4886
1
  };
4887
4888
1
  u16(table_blob::off_idna_stage1, table_blob::count_idna_stage1);
4889
1
  u16(table_blob::off_idna_stage2, table_blob::count_idna_stage2);
4890
1
  u64(table_blob::off_idna_bool_blocks, table_blob::count_idna_bool_blocks);
4891
1
  u16(table_blob::off_decomposition_block,
4892
1
      table_blob::count_decomposition_block);
4893
1
  u32(table_blob::off_decomposition_data, table_blob::count_decomposition_data);
4894
1
  u16(table_blob::off_composition_block, table_blob::count_composition_block);
4895
1
  u32(table_blob::off_composition_data, table_blob::count_composition_data);
4896
1
  u32(table_blob::off_id_continue_flat, table_blob::count_id_continue_flat);
4897
1
  u32(table_blob::off_id_start_flat, table_blob::count_id_start_flat);
4898
1
  u32(table_blob::off_dir_start, table_blob::count_dir_start);
4899
1
  u32(table_blob::off_dir_final, table_blob::count_dir_final);
4900
1
  u32(table_blob::off_combining_flat, table_blob::count_combining_flat);
4901
1
  u32(table_blob::off_joining_start, table_blob::count_joining_start);
4902
1
  u32(table_blob::off_joining_final, table_blob::count_joining_final);
4903
1
}
4904
4905
}  // namespace detail
4906
4907
// --- Blob layout invariants --------------------------------------------------
4908
static_assert(table_blob::count_decomposition_index == 4352);
4909
static_assert(table_blob::count_ccc_index == 4352);
4910
static_assert(table_blob::count_composition_index == 4352);
4911
static_assert(table_blob::count_decomposition_block ==
4912
              table_blob::decomposition_block_rows *
4913
                  table_blob::decomposition_block_cols);
4914
static_assert(table_blob::count_ccc_block ==
4915
              table_blob::ccc_block_rows * table_blob::ccc_block_cols);
4916
static_assert(table_blob::count_composition_block ==
4917
              table_blob::composition_block_rows *
4918
                  table_blob::composition_block_cols);
4919
static_assert(table_blob::count_dir_start == table_blob::dir_table_count &&
4920
              table_blob::count_dir_final == table_blob::dir_table_count &&
4921
              table_blob::count_dir_value == table_blob::dir_table_count);
4922
static_assert(
4923
    table_blob::count_joining_start == table_blob::joining_table_count &&
4924
    table_blob::count_joining_final == table_blob::joining_table_count &&
4925
    table_blob::count_joining_value == table_blob::joining_table_count);
4926
static_assert(table_blob::count_id_continue_flat ==
4927
              table_blob::id_continue_count * 2);
4928
static_assert(table_blob::count_id_start_flat ==
4929
              table_blob::id_start_count * 2);
4930
static_assert(table_blob::count_combining_flat ==
4931
              table_blob::combining_range_count * 2);
4932
static_assert(table_blob::off_idna_stage1 % alignof(uint16_t) == 0);
4933
static_assert(table_blob::off_idna_stage2 % alignof(uint16_t) == 0);
4934
static_assert(table_blob::off_idna_bool_blocks % alignof(uint64_t) == 0);
4935
static_assert(table_blob::off_decomposition_block % alignof(uint16_t) == 0);
4936
static_assert(table_blob::off_decomposition_data % alignof(char32_t) == 0);
4937
static_assert(table_blob::off_composition_block % alignof(uint16_t) == 0);
4938
static_assert(table_blob::off_composition_data % alignof(char32_t) == 0);
4939
static_assert(table_blob::off_id_continue_flat % alignof(uint32_t) == 0);
4940
static_assert(table_blob::off_id_start_flat % alignof(uint32_t) == 0);
4941
static_assert(table_blob::off_dir_start % alignof(uint32_t) == 0);
4942
static_assert(table_blob::off_dir_final % alignof(uint32_t) == 0);
4943
static_assert(table_blob::off_combining_flat % alignof(uint32_t) == 0);
4944
static_assert(table_blob::off_joining_start % alignof(uint32_t) == 0);
4945
static_assert(table_blob::off_joining_final % alignof(uint32_t) == 0);
4946
static_assert(table_blob::compressed_size == sizeof(table_blob::compressed));
4947
4948
// Every section must lie entirely inside the uncompressed buffer.
4949
#define ADA_IDNA_SECTION_IN_BOUNDS(off, count, width)                       \
4950
  static_assert((off) + (count) * (width) <= table_blob::uncompressed_size, \
4951
                #off " overflows uncompressed buffer")
4952
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_stage1,
4953
                           table_blob::count_idna_stage1, 2);
4954
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_stage2,
4955
                           table_blob::count_idna_stage2, 2);
4956
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_bool_blocks,
4957
                           table_blob::count_idna_bool_blocks, 8);
4958
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_idna_utf8_mappings,
4959
                           table_blob::count_idna_utf8_mappings, 1);
4960
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_index,
4961
                           table_blob::count_decomposition_index, 1);
4962
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_block,
4963
                           table_blob::count_decomposition_block, 2);
4964
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_decomposition_data,
4965
                           table_blob::count_decomposition_data, 4);
4966
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_ccc_index,
4967
                           table_blob::count_ccc_index, 1);
4968
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_ccc_block,
4969
                           table_blob::count_ccc_block, 1);
4970
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_index,
4971
                           table_blob::count_composition_index, 1);
4972
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_block,
4973
                           table_blob::count_composition_block, 2);
4974
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_composition_data,
4975
                           table_blob::count_composition_data, 4);
4976
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_id_continue_flat,
4977
                           table_blob::count_id_continue_flat, 4);
4978
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_id_start_flat,
4979
                           table_blob::count_id_start_flat, 4);
4980
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_start,
4981
                           table_blob::count_dir_start, 4);
4982
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_final,
4983
                           table_blob::count_dir_final, 4);
4984
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_dir_value,
4985
                           table_blob::count_dir_value, 1);
4986
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_combining_flat,
4987
                           table_blob::count_combining_flat, 4);
4988
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_joining_start,
4989
                           table_blob::count_joining_start, 4);
4990
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_joining_final,
4991
                           table_blob::count_joining_final, 4);
4992
ADA_IDNA_SECTION_IN_BOUNDS(table_blob::off_joining_value,
4993
                           table_blob::count_joining_value, 1);
4994
#undef ADA_IDNA_SECTION_IN_BOUNDS
4995
4996
// --- Mapping -----------------------------------------------------------------
4997
inline const uint16_t* idna_stage1 = nullptr;
4998
inline const uint16_t* idna_stage2 = nullptr;
4999
inline const uint64_t* idna_bool_blocks = nullptr;
5000
inline const uint8_t* idna_utf8_mappings = nullptr;
5001
5002
// --- Normalization (O(1) multi-stage) ----------------------------------------
5003
inline const uint8_t* decomposition_index = nullptr;
5004
inline const uint16_t* decomposition_block_flat = nullptr;
5005
inline const char32_t* decomposition_data = nullptr;
5006
inline const uint8_t* ccc_index = nullptr;
5007
inline const uint8_t* ccc_block_flat = nullptr;
5008
inline const uint8_t* composition_index = nullptr;
5009
inline const uint16_t* composition_block_flat = nullptr;
5010
inline const char32_t* composition_data = nullptr;
5011
5012
// --- Identifier --------------------------------------------------------------
5013
// Pointer-to-array alias. CF17 vs CF22 disagree on spacing inside (*)[2].
5014
// clang-format off
5015
using range_pair_ptr = const uint32_t(*)[2];
5016
// clang-format on
5017
inline range_pair_ptr id_continue = nullptr;
5018
inline range_pair_ptr id_start = nullptr;
5019
5020
// --- Validity (const SoA) ----------------------------------------------------
5021
inline const uint32_t* dir_start = nullptr;
5022
inline const uint32_t* dir_final = nullptr;
5023
inline const uint8_t* dir_value = nullptr;
5024
inline range_pair_ptr combining_ranges = nullptr;
5025
inline const uint32_t* joining_start = nullptr;
5026
inline const uint32_t* joining_final = nullptr;
5027
inline const uint8_t* joining_value = nullptr;
5028
5029
inline constexpr size_t id_continue_count = table_blob::id_continue_count;
5030
inline constexpr size_t id_start_count = table_blob::id_start_count;
5031
inline constexpr size_t dir_table_count = table_blob::dir_table_count;
5032
inline constexpr size_t joining_table_count = table_blob::joining_table_count;
5033
inline constexpr size_t combining_range_count =
5034
    table_blob::combining_range_count;
5035
inline constexpr size_t idna_utf8_mappings_size =
5036
    table_blob::count_idna_utf8_mappings;
5037
inline constexpr size_t decomposition_data_size =
5038
    table_blob::count_decomposition_data;
5039
inline constexpr size_t composition_data_size =
5040
    table_blob::count_composition_data;
5041
5042
inline constexpr size_t kDecompBlockCols =
5043
    table_blob::decomposition_block_cols;                            // 257
5044
inline constexpr size_t kCccBlockCols = table_blob::ccc_block_cols;  // 256
5045
inline constexpr size_t kCompBlockCols =
5046
    table_blob::composition_block_cols;  // 257
5047
inline constexpr size_t kDecompBlockRows = table_blob::decomposition_block_rows;
5048
inline constexpr size_t kCccBlockRows = table_blob::ccc_block_rows;
5049
inline constexpr size_t kCompBlockRows = table_blob::composition_block_rows;
5050
5051
// Init state: 0=uninit, 1=in progress, 2=ready, 3=failed.
5052
inline constexpr uint8_t kTablesUninit = 0;
5053
inline constexpr uint8_t kTablesInProgress = 1;
5054
inline constexpr uint8_t kTablesReady = 2;
5055
inline constexpr uint8_t kTablesFailed = 3;
5056
5057
inline std::atomic<uint8_t> tables_init_state{kTablesUninit};
5058
// Process-lifetime allocation published only by the winning init thread.
5059
// Never freed: shared read-only data for the process. Do not dlclose a DSO
5060
// that owns this buffer while other code may still call into ada::idna.
5061
inline uint8_t* tables_buffer = nullptr;
5062
5063
// Cap spin-wait so a stuck peer cannot hang the process forever.
5064
inline constexpr uint64_t kTablesSpinLimit = 1'000'000'000ull;
5065
5066
// ISO HDLC / zlib CRC-32 of the uncompressed table payload.
5067
[[nodiscard]] inline uint32_t crc32_ieee(const uint8_t* data,
5068
1
                                         size_t len) noexcept {
5069
1
  uint32_t c = 0xFFFFFFFFu;
5070
216k
  for (size_t i = 0; i < len; ++i) {
5071
216k
    c ^= data[i];
5072
1.94M
    for (int k = 0; k < 8; ++k) {
5073
1.72M
      const uint32_t mask = 0u - (c & 1u);
5074
1.72M
      c = (c >> 1) ^ (0xEDB88320u & mask);
5075
1.72M
    }
5076
216k
  }
5077
1
  return ~c;
5078
1
}
5079
5080
2.97k
[[nodiscard]] inline bool tables_are_ready() noexcept {
5081
2.97k
  return tables_init_state.load(std::memory_order_acquire) == kTablesReady;
5082
2.97k
}
5083
5084
// Returns true only when all table pointers are safe to use.
5085
6.48k
[[nodiscard]] inline bool ensure_tables() noexcept {
5086
6.48k
  uint8_t state = tables_init_state.load(std::memory_order_acquire);
5087
6.48k
  if (state == kTablesReady) {
5088
6.48k
    return true;
5089
6.48k
  }
5090
1
  if (state == kTablesFailed) {
5091
0
    return false;
5092
0
  }
5093
5094
1
  uint8_t expected = kTablesUninit;
5095
1
  if (tables_init_state.compare_exchange_strong(expected, kTablesInProgress,
5096
1
                                                std::memory_order_acq_rel,
5097
1
                                                std::memory_order_acquire)) {
5098
1
    uint8_t* buffer = new (std::nothrow) uint8_t[table_blob::uncompressed_size];
5099
1
    if (buffer == nullptr) {
5100
0
      tables_init_state.store(kTablesFailed, std::memory_order_release);
5101
0
      return false;
5102
0
    }
5103
5104
1
    const size_t n = deflate::inflate_raw(table_blob::compressed,
5105
1
                                          table_blob::compressed_size, buffer,
5106
1
                                          table_blob::uncompressed_size);
5107
1
    if (n != table_blob::uncompressed_size ||
5108
1
        crc32_ieee(buffer, n) != table_blob::uncompressed_crc32) {
5109
0
      delete[] buffer;
5110
0
      tables_init_state.store(kTablesFailed, std::memory_order_release);
5111
0
      return false;
5112
0
    }
5113
5114
    // LE payload verified; convert multi-byte fields for big-endian hosts.
5115
1
    detail::convert_table_blob_to_host_endian(buffer);
5116
5117
21
    auto at = [&](size_t off) noexcept -> const uint8_t* {
5118
21
      return buffer + off;
5119
21
    };
5120
5121
    // Publish all non-atomic pointers before READY. Waiters synchronize via
5122
    // acquire on tables_init_state and then observe these writes.
5123
1
    idna_stage1 =
5124
1
        reinterpret_cast<const uint16_t*>(at(table_blob::off_idna_stage1));
5125
1
    idna_stage2 =
5126
1
        reinterpret_cast<const uint16_t*>(at(table_blob::off_idna_stage2));
5127
1
    idna_bool_blocks =
5128
1
        reinterpret_cast<const uint64_t*>(at(table_blob::off_idna_bool_blocks));
5129
1
    idna_utf8_mappings = at(table_blob::off_idna_utf8_mappings);
5130
5131
1
    decomposition_index = at(table_blob::off_decomposition_index);
5132
1
    decomposition_block_flat = reinterpret_cast<const uint16_t*>(
5133
1
        at(table_blob::off_decomposition_block));
5134
1
    decomposition_data = reinterpret_cast<const char32_t*>(
5135
1
        at(table_blob::off_decomposition_data));
5136
1
    ccc_index = at(table_blob::off_ccc_index);
5137
1
    ccc_block_flat = at(table_blob::off_ccc_block);
5138
1
    composition_index = at(table_blob::off_composition_index);
5139
1
    composition_block_flat = reinterpret_cast<const uint16_t*>(
5140
1
        at(table_blob::off_composition_block));
5141
1
    composition_data =
5142
1
        reinterpret_cast<const char32_t*>(at(table_blob::off_composition_data));
5143
5144
1
    id_continue =
5145
1
        reinterpret_cast<range_pair_ptr>(at(table_blob::off_id_continue_flat));
5146
1
    id_start =
5147
1
        reinterpret_cast<range_pair_ptr>(at(table_blob::off_id_start_flat));
5148
5149
1
    dir_start =
5150
1
        reinterpret_cast<const uint32_t*>(at(table_blob::off_dir_start));
5151
1
    dir_final =
5152
1
        reinterpret_cast<const uint32_t*>(at(table_blob::off_dir_final));
5153
1
    dir_value = at(table_blob::off_dir_value);
5154
1
    combining_ranges =
5155
1
        reinterpret_cast<range_pair_ptr>(at(table_blob::off_combining_flat));
5156
1
    joining_start =
5157
1
        reinterpret_cast<const uint32_t*>(at(table_blob::off_joining_start));
5158
1
    joining_final =
5159
1
        reinterpret_cast<const uint32_t*>(at(table_blob::off_joining_final));
5160
1
    joining_value = at(table_blob::off_joining_value);
5161
5162
1
    tables_buffer = buffer;
5163
1
    tables_init_state.store(kTablesReady, std::memory_order_release);
5164
1
    return true;
5165
1
  }
5166
5167
  // Another thread owns init (or finished between our loads).
5168
0
  for (uint64_t spins = 0; spins < kTablesSpinLimit; ++spins) {
5169
0
    state = tables_init_state.load(std::memory_order_acquire);
5170
0
    if (state == kTablesReady) {
5171
0
      return true;
5172
0
    }
5173
0
    if (state == kTablesFailed) {
5174
0
      return false;
5175
0
    }
5176
0
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \
5177
0
    defined(_M_IX86)
5178
0
#if defined(__GNUC__) || defined(__clang__)
5179
0
    __builtin_ia32_pause();
5180
0
#endif
5181
#elif defined(__aarch64__) || defined(_M_ARM64)
5182
#if defined(__GNUC__) || defined(__clang__)
5183
    asm volatile("yield" ::: "memory");
5184
#endif
5185
#endif
5186
0
  }
5187
  // Timed out waiting for a peer - treat as failure rather than hang.
5188
0
  return false;
5189
0
}
5190
5191
// O(1) multi-stage accessors. Block indices from the tables are uint8_t and
5192
// theoretically can be out of range if the blob is corrupt; clamp to a valid
5193
// empty/default row (index 0) instead of reading OOB.
5194
85.2k
inline const uint16_t* decomposition_block_row(uint8_t bi) noexcept {
5195
85.2k
  if (bi >= kDecompBlockRows) {
5196
0
    bi = 0;
5197
0
  }
5198
85.2k
  return decomposition_block_flat + static_cast<size_t>(bi) * kDecompBlockCols;
5199
85.2k
}
5200
5201
121k
inline const uint8_t* ccc_block_row(uint8_t bi) noexcept {
5202
121k
  if (bi >= kCccBlockRows) {
5203
0
    bi = 0;
5204
0
  }
5205
121k
  return ccc_block_flat + static_cast<size_t>(bi) * kCccBlockCols;
5206
121k
}
5207
5208
40.0k
inline const uint16_t* composition_block_row(uint8_t bi) noexcept {
5209
40.0k
  if (bi >= kCompBlockRows) {
5210
0
    bi = 0;
5211
0
  }
5212
40.0k
  return composition_block_flat + static_cast<size_t>(bi) * kCompBlockCols;
5213
40.0k
}
5214
5215
}  // namespace ada::idna
5216
/* end file src/table_store.hpp */
5217
/* begin file src/mapping_tables.cpp */
5218
// IDNA 18.0.0
5219
// Two-level compressed mapping table (constants only).
5220
// Array payloads are stored in the DEFLATE blob (see table_store.hpp /
5221
// scripts/pack_tables.py).
5222
// Regenerate with: python3 scripts/idna_table.py --write
5223
// Logical table size: 51037 bytes (49.8 KB)
5224
//   stage1:        8162 bytes  (4081 uint16_t entries)
5225
//   stage2:       23424 bytes  (183 mixed blocks x 64)
5226
//   bool_blocks:   1800 bytes  (225 uint64_t words)
5227
//   utf8 maps:    17651 bytes
5228
5229
// clang-format off
5230
#ifndef ADA_IDNA_MAPPING_TABLE_H
5231
#define ADA_IDNA_MAPPING_TABLE_H
5232
#include <cstdint>
5233
5234
namespace ada::idna {
5235
5236
// Block size for two-level table (2^6 = 64 code points per block).
5237
constexpr uint32_t IDNA_BLOCK_BITS = 6u;
5238
constexpr uint32_t IDNA_BLOCK_SIZE = 64u;
5239
constexpr uint32_t IDNA_BLOCK_MASK = 63u;
5240
5241
// Sentinel values stored in stage2 / returned by lookup.
5242
constexpr uint16_t IDNA_VALID      = 0xFFFF;  // code point is valid as-is
5243
constexpr uint16_t IDNA_DISALLOWED = 0xFFFE;  // code point is disallowed
5244
constexpr uint16_t IDNA_IGNORED    = 0x0000;    // ignored (index into empty UTF-8 entry)
5245
5246
// Bit 15 of a stage1 entry: set = boolean block, clear = mixed block.
5247
constexpr uint16_t IDNA_BOOL_FLAG  = 0x8000;
5248
5249
// Two-level table covers code points [0, IDNA_LOW_RANGE_END).
5250
// Derived from the highest non-disallowed code point below the high-ignored range,
5251
// rounded up to the next 64-code-point block boundary.
5252
constexpr uint32_t IDNA_LOW_RANGE_END    = 0x0003FC40;
5253
5254
// Variation selectors supplement: U+E0100..U+E01EF are all ignored.
5255
// These are handled with a simple range check; everything else above
5256
// IDNA_LOW_RANGE_END is disallowed.
5257
constexpr uint32_t IDNA_HIGH_IGNORED_START = 0x000E0100;
5258
constexpr uint32_t IDNA_HIGH_IGNORED_END   = 0x000E01F0;  // exclusive
5259
5260
// Large arrays (idna_stage1/stage2/bool_blocks/utf8_mappings) live in table_blob.
5261
5262
}  // namespace ada::idna
5263
#endif  // ADA_IDNA_MAPPING_TABLE_H
5264
/* end file src/mapping_tables.cpp */
5265
5266
namespace ada::idna {
5267
5268
// --- O(1) two-level table lookup ---------------------------------------------
5269
//
5270
// Returns one of:
5271
//   IDNA_VALID      - keep code point in output unchanged
5272
//   IDNA_DISALLOWED - code point is not allowed (map() returns error)
5273
//   IDNA_IGNORED    - code point is ignored (index 0 = empty UTF-8 entry)
5274
//   other           - byte offset into idna_utf8_mappings[] (null-terminated)
5275
//
5276
// Assumes ensure_tables() has already been called by the public entry point.
5277
48.4k
static uint16_t idna_lookup(uint32_t cp) noexcept {
5278
48.4k
  if (cp < IDNA_LOW_RANGE_END) {
5279
48.0k
    uint16_t ref = idna_stage1[cp >> IDNA_BLOCK_BITS];
5280
48.0k
    if (ref & IDNA_BOOL_FLAG) {
5281
21.1k
      uint32_t bit_idx =
5282
21.1k
          static_cast<uint32_t>(ref & ~IDNA_BOOL_FLAG) * IDNA_BLOCK_SIZE +
5283
21.1k
          (cp & IDNA_BLOCK_MASK);
5284
21.1k
      bool is_valid = (idna_bool_blocks[bit_idx >> 6] >> (bit_idx & 63u)) & 1u;
5285
21.1k
      return is_valid ? IDNA_VALID : IDNA_DISALLOWED;
5286
21.1k
    }
5287
26.9k
    return idna_stage2[ref + (cp & IDNA_BLOCK_MASK)];
5288
48.0k
  }
5289
5290
379
  if (cp >= IDNA_HIGH_IGNORED_START && cp < IDNA_HIGH_IGNORED_END) {
5291
204
    return IDNA_IGNORED;
5292
204
  }
5293
5294
175
  return IDNA_DISALLOWED;
5295
379
}
5296
5297
// Advances *ptr past one well-formed UTF-8 code point from the mapping table.
5298
26.6k
static char32_t utf8_next(const uint8_t*& ptr) noexcept {
5299
26.6k
  uint8_t b0 = *ptr++;
5300
26.6k
  if (b0 < 0x80u) return static_cast<char32_t>(b0);
5301
17.3k
  if (b0 < 0xE0u) {
5302
13.3k
    uint32_t cp = (b0 & 0x1Fu) << 6;
5303
13.3k
    cp |= (*ptr++ & 0x3Fu);
5304
13.3k
    return static_cast<char32_t>(cp);
5305
13.3k
  }
5306
3.99k
  if (b0 < 0xF0u) {
5307
3.63k
    uint32_t cp = (b0 & 0x0Fu) << 12;
5308
3.63k
    cp |= ((*ptr++ & 0x3Fu) << 6);
5309
3.63k
    cp |= (*ptr++ & 0x3Fu);
5310
3.63k
    return static_cast<char32_t>(cp);
5311
3.63k
  }
5312
361
  uint32_t cp = (b0 & 0x07u) << 18;
5313
361
  cp |= ((*ptr++ & 0x3Fu) << 12);
5314
361
  cp |= ((*ptr++ & 0x3Fu) << 6);
5315
361
  cp |= (*ptr++ & 0x3Fu);
5316
361
  return static_cast<char32_t>(cp);
5317
3.99k
}
5318
5319
// Count UTF-8 code points in a null-terminated mapping string (trusted table).
5320
6.72k
static size_t utf8_count_codepoints(const uint8_t* ptr) noexcept {
5321
6.72k
  size_t n = 0;
5322
33.3k
  while (*ptr != 0) {
5323
26.6k
    ++n;
5324
26.6k
    if (*ptr < 0x80u) {
5325
9.24k
      ++ptr;
5326
17.3k
    } else if (*ptr < 0xE0u) {
5327
13.4k
      ptr += 2;
5328
13.4k
    } else if (*ptr < 0xF0u) {
5329
3.63k
      ptr += 3;
5330
3.63k
    } else {
5331
362
      ptr += 4;
5332
362
    }
5333
26.6k
  }
5334
6.72k
  return n;
5335
6.72k
}
5336
5337
// --- ASCII fast path ---------------------------------------------------------
5338
704
void ascii_map(char* input, size_t length) {
5339
2.11k
  auto broadcast = [](uint8_t v) -> uint64_t {
5340
2.11k
    return 0x101010101010101ull * v;
5341
2.11k
  };
5342
704
  uint64_t broadcast_80 = broadcast(0x80);
5343
704
  uint64_t broadcast_Ap = broadcast(128 - 'A');
5344
704
  uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
5345
704
  size_t i = 0;
5346
5347
832
  for (; i + 7 < length; i += 8) {
5348
128
    uint64_t word{};
5349
128
    std::memcpy(&word, input + i, sizeof(word));
5350
128
    word ^=
5351
128
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
5352
128
    std::memcpy(input + i, &word, sizeof(word));
5353
128
  }
5354
704
  if (i < length) {
5355
104
    uint64_t word{};
5356
104
    std::memcpy(&word, input + i, length - i);
5357
104
    word ^=
5358
104
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
5359
104
    std::memcpy(input + i, &word, length - i);
5360
104
  }
5361
704
}
5362
5363
// Two-pass map: first validate + exact size, then write once (no growth
5364
// realloc).
5365
3.26k
bool map(std::u32string_view input, std::u32string& out) {
5366
  //  [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap).
5367
3.26k
  out.clear();
5368
3.26k
  if (!ensure_tables()) {
5369
0
    return false;
5370
0
  }
5371
5372
  // Pass 1: validate and compute exact output length.
5373
3.26k
  size_t out_size = 0;
5374
24.4k
  for (char32_t x : input) {
5375
24.4k
    uint16_t status = idna_lookup(static_cast<uint32_t>(x));
5376
24.4k
    if (status == IDNA_DISALLOWED) {
5377
240
      return false;
5378
240
    }
5379
24.1k
    if (status == IDNA_VALID) {
5380
17.4k
      ++out_size;
5381
17.4k
      continue;
5382
17.4k
    }
5383
6.72k
    if (static_cast<size_t>(status) >= idna_utf8_mappings_size) {
5384
0
      return false;
5385
0
    }
5386
6.72k
    out_size += utf8_count_codepoints(idna_utf8_mappings + status);
5387
6.72k
  }
5388
5389
  // Pass 2: write into a single allocation.
5390
3.02k
  out.resize(out_size);
5391
3.02k
  size_t w = 0;
5392
24.0k
  for (char32_t x : input) {
5393
24.0k
    uint16_t status = idna_lookup(static_cast<uint32_t>(x));
5394
24.0k
    if (status == IDNA_VALID) {
5395
17.3k
      out[w++] = x;
5396
17.3k
      continue;
5397
17.3k
    }
5398
    // IGNORED or mapped (status already validated in pass 1).
5399
6.72k
    const uint8_t* ptr = idna_utf8_mappings + status;
5400
33.3k
    while (*ptr != 0) {
5401
26.6k
      out[w++] = utf8_next(ptr);
5402
26.6k
    }
5403
6.72k
  }
5404
3.02k
  return true;
5405
3.26k
}
5406
5407
0
std::u32string map(std::u32string_view input) {
5408
0
  std::u32string answer;
5409
0
  if (!map(input, answer)) {
5410
0
    return {};
5411
0
  }
5412
0
  return answer;
5413
0
}
5414
5415
}  // namespace ada::idna
5416
/* end file src/mapping.cpp */
5417
/* begin file src/normalization.cpp */
5418
/* begin file include/ada/idna/normalization.h */
5419
#ifndef ADA_IDNA_NORMALIZATION_H
5420
#define ADA_IDNA_NORMALIZATION_H
5421
5422
#include <string>
5423
#include <string_view>
5424
5425
namespace ada::idna {
5426
5427
// Returns true if `input` is already in Unicode Normalization Form C.
5428
// Requires that internal tables have been loaded (call ensure via normalize
5429
// or map first, or this returns false if tables are unavailable).
5430
[[nodiscard]] bool is_already_nfc(std::u32string_view input) noexcept;
5431
5432
// Normalize the characters according to IDNA (Unicode Normalization Form C).
5433
// Returns false if the internal Unicode tables could not be loaded; in that
5434
// case `input` is left unchanged. Skips work when the string is already NFC.
5435
[[nodiscard]] bool normalize(std::u32string& input);
5436
5437
}  // namespace ada::idna
5438
#endif
5439
/* end file include/ada/idna/normalization.h */
5440
/* begin file src/normalization_tables.cpp */
5441
// Normalization table helpers.
5442
// Array payloads live in the DEFLATE blob (table_store.hpp).
5443
// Regenerate with: python3 scripts/unicode_data_table.py --write
5444
// clang-format off
5445
#ifndef ADA_IDNA_NORMALIZATION_TABLES_H
5446
#define ADA_IDNA_NORMALIZATION_TABLES_H
5447
5448
namespace ada::idna {
5449
5450
// Accessors and multi-stage tables are provided by table_store.hpp after
5451
// ensure_tables(). Lookup code matches the classic O(1) uni-algo layout.
5452
5453
}  // namespace ada::idna
5454
#endif  // ADA_IDNA_NORMALIZATION_TABLES_H
5455
/* end file src/normalization_tables.cpp */
5456
5457
#include <cstdint>
5458
5459
namespace ada::idna {
5460
5461
// See
5462
// https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467
5463
constexpr char32_t hangul_sbase = 0xAC00;
5464
constexpr char32_t hangul_tbase = 0x11A7;
5465
constexpr char32_t hangul_vbase = 0x1161;
5466
constexpr char32_t hangul_lbase = 0x1100;
5467
constexpr char32_t hangul_lcount = 19;
5468
constexpr char32_t hangul_vcount = 21;
5469
constexpr char32_t hangul_tcount = 28;
5470
constexpr char32_t hangul_ncount = hangul_vcount * hangul_tcount;
5471
constexpr char32_t hangul_scount =
5472
    hangul_lcount * hangul_vcount * hangul_tcount;
5473
5474
// Canonical decomposition length (0 if none / compatibility-only / Hangul
5475
// syllable). Length 1 means a singleton mapping (character is not NFC form).
5476
// Length >= 2 means a primary composite that is already the NFC form of its
5477
// decomposition (e.g. U+00E9 LATIN SMALL LETTER E WITH ACUTE).
5478
33.6k
static size_t canonical_decomp_length(char32_t current_character) noexcept {
5479
33.6k
  if (current_character >= hangul_sbase &&
5480
2.81k
      current_character < hangul_sbase + hangul_scount) {
5481
    // Hangul precomposed syllables are NFC.
5482
1.33k
    return 0;
5483
1.33k
  }
5484
32.3k
  if (current_character >= 0x110000) {
5485
0
    return 0;
5486
0
  }
5487
32.3k
  const uint8_t di = decomposition_index[current_character >> 8];
5488
32.3k
  const uint16_t* const decomposition =
5489
32.3k
      decomposition_block_row(di) + (current_character % 256);
5490
32.3k
  size_t decomposition_length =
5491
32.3k
      (decomposition[1] >> 2) - (decomposition[0] >> 2);
5492
32.3k
  if ((decomposition_length > 0) && (decomposition[0] & 1)) {
5493
0
    decomposition_length = 0;  // compatibility-only: ignored for NFC
5494
0
  }
5495
32.3k
  return decomposition_length;
5496
32.3k
}
5497
5498
std::pair<bool, size_t> compute_decomposition_length(
5499
749
    const std::u32string_view input) noexcept {
5500
749
  bool decomposition_needed{false};
5501
749
  size_t additional_elements{0};
5502
10.8k
  for (char32_t current_character : input) {
5503
10.8k
    size_t decomposition_length{0};
5504
5505
10.8k
    if (current_character >= hangul_sbase &&
5506
1.12k
        current_character < hangul_sbase + hangul_scount) {
5507
      // Full NFD-style Hangul decomp for the decompose() step.
5508
565
      decomposition_length = 2;
5509
565
      if ((current_character - hangul_sbase) % hangul_tcount) {
5510
285
        decomposition_length = 3;
5511
285
      }
5512
10.2k
    } else if (current_character < 0x110000) {
5513
10.2k
      const uint8_t di = decomposition_index[current_character >> 8];
5514
10.2k
      const uint16_t* const decomposition =
5515
10.2k
          decomposition_block_row(di) + (current_character % 256);
5516
10.2k
      decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2);
5517
10.2k
      if ((decomposition_length > 0) && (decomposition[0] & 1)) {
5518
0
        decomposition_length = 0;
5519
0
      }
5520
10.2k
    }
5521
10.8k
    if (decomposition_length != 0) {
5522
1.67k
      decomposition_needed = true;
5523
1.67k
      additional_elements += decomposition_length - 1;
5524
1.67k
    }
5525
10.8k
  }
5526
749
  return {decomposition_needed, additional_elements};
5527
749
}
5528
5529
430
void decompose(std::u32string& input, size_t additional_elements) {
5530
430
  input.resize(input.size() + additional_elements);
5531
430
  for (size_t descending_idx = input.size(),
5532
430
              input_count = descending_idx - additional_elements;
5533
6.39k
       input_count--;) {
5534
5.96k
    if (input[input_count] >= hangul_sbase &&
5535
1.03k
        input[input_count] < hangul_sbase + hangul_scount) {
5536
      // Hangul decomposition.
5537
565
      char32_t s_index = input[input_count] - hangul_sbase;
5538
565
      if (s_index % hangul_tcount != 0) {
5539
285
        input[--descending_idx] = hangul_tbase + s_index % hangul_tcount;
5540
285
      }
5541
565
      input[--descending_idx] =
5542
565
          hangul_vbase + (s_index % hangul_ncount) / hangul_tcount;
5543
565
      input[--descending_idx] = hangul_lbase + s_index / hangul_ncount;
5544
5.39k
    } else if (input[input_count] < 0x110000) {
5545
5.39k
      const uint16_t* decomposition =
5546
5.39k
          decomposition_block_row(
5547
5.39k
              decomposition_index[input[input_count] >> 8]) +
5548
5.39k
          (input[input_count] % 256);
5549
5.39k
      uint16_t decomposition_length =
5550
5.39k
          (decomposition[1] >> 2) - (decomposition[0] >> 2);
5551
5.39k
      if (decomposition_length > 0 && (decomposition[0] & 1)) {
5552
0
        decomposition_length = 0;
5553
0
      }
5554
5.39k
      if (decomposition_length > 0) {
5555
1.10k
        const size_t base = static_cast<size_t>(decomposition[0] >> 2);
5556
1.10k
        if (base + decomposition_length > decomposition_data_size) {
5557
0
          input[--descending_idx] = input[input_count];
5558
1.10k
        } else {
5559
3.88k
          while (decomposition_length-- > 0) {
5560
2.77k
            input[--descending_idx] =
5561
2.77k
                decomposition_data[base + decomposition_length];
5562
2.77k
          }
5563
1.10k
        }
5564
4.29k
      } else {
5565
4.29k
        input[--descending_idx] = input[input_count];
5566
4.29k
      }
5567
5.39k
    } else {
5568
0
      input[--descending_idx] = input[input_count];
5569
0
    }
5570
5.96k
  }
5571
430
}
5572
5573
121k
uint8_t get_ccc(char32_t c) noexcept {
5574
121k
  if (c >= 0x110000) {
5575
0
    return 0;
5576
0
  }
5577
121k
  return ccc_block_row(ccc_index[c >> 8])[c % 256];
5578
121k
}
5579
5580
749
void sort_marks(std::u32string& input) {
5581
13.3k
  for (size_t idx = 1; idx < input.size(); idx++) {
5582
12.6k
    uint8_t ccc = get_ccc(input[idx]);
5583
12.6k
    if (ccc == 0) {
5584
9.57k
      continue;
5585
9.57k
    }
5586
3.04k
    auto current_character = input[idx];
5587
3.04k
    size_t back_idx = idx;
5588
4.38k
    while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) {
5589
1.33k
      input[back_idx] = input[back_idx - 1];
5590
1.33k
      back_idx--;
5591
1.33k
    }
5592
3.04k
    input[back_idx] = current_character;
5593
3.04k
  }
5594
749
}
5595
5596
749
void decompose_nfc(std::u32string& input) {
5597
  /**
5598
   * Decompose the domain_name string to Unicode Normalization Form C.
5599
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose
5600
   */
5601
749
  auto [decomposition_needed, additional_elements] =
5602
749
      compute_decomposition_length(input);
5603
749
  if (decomposition_needed) {
5604
430
    decompose(input, additional_elements);
5605
430
  }
5606
749
  sort_marks(input);
5607
749
}
5608
5609
// Returns true if the composition row of a starter has a pair with `second`.
5610
static bool has_composition(const uint16_t* composition,
5611
7.07k
                            char32_t second) noexcept {
5612
7.07k
  int left = composition[0];
5613
7.07k
  int right = composition[1];
5614
7.07k
  if (left < 0 || right <= left ||
5615
5.77k
      static_cast<size_t>(right) > composition_data_size) {
5616
1.30k
    return false;
5617
1.30k
  }
5618
13.8k
  while (left + 2 < right) {
5619
8.04k
    int middle = left + (((right - left) >> 1) & ~1);
5620
8.04k
    if (composition_data[static_cast<size_t>(middle)] <= second) {
5621
2.44k
      left = middle;
5622
2.44k
    }
5623
8.04k
    if (composition_data[static_cast<size_t>(middle)] >= second) {
5624
6.10k
      right = middle;
5625
6.10k
    }
5626
8.04k
  }
5627
5.77k
  return static_cast<size_t>(left + 1) < composition_data_size &&
5628
5.77k
         composition_data[static_cast<size_t>(left)] == second;
5629
7.07k
}
5630
5631
// Returns true if a composition step would change the string.
5632
2.22k
static bool would_compose(std::u32string_view input) noexcept {
5633
24.3k
  for (size_t input_count = 0; input_count < input.size();) {
5634
22.8k
    const char32_t current = input[input_count];
5635
22.8k
    if (current >= hangul_lbase && current < hangul_lbase + hangul_lcount) {
5636
413
      if (input_count + 1 < input.size() &&
5637
386
          input[input_count + 1] >= hangul_vbase &&
5638
197
          input[input_count + 1] < hangul_vbase + hangul_vcount) {
5639
62
        return true;
5640
62
      }
5641
351
      ++input_count;
5642
351
      continue;
5643
413
    }
5644
22.4k
    if (current >= hangul_sbase && current < hangul_sbase + hangul_scount) {
5645
981
      if ((current - hangul_sbase) % hangul_tcount == 0 &&
5646
467
          input_count + 1 < input.size() &&
5647
449
          input[input_count + 1] > hangul_tbase &&
5648
304
          input[input_count + 1] < hangul_tbase + hangul_tcount) {
5649
40
        return true;
5650
40
      }
5651
941
      ++input_count;
5652
941
      continue;
5653
981
    }
5654
21.4k
    if (current < 0x110000) {
5655
21.4k
      const uint16_t* composition =
5656
21.4k
          composition_block_row(composition_index[current >> 8]) +
5657
21.4k
          (current % 256);
5658
21.4k
      int32_t previous_ccc = -1;
5659
21.4k
      size_t j = input_count;
5660
22.9k
      for (; j + 1 < input.size(); ++j) {
5661
21.5k
        uint8_t ccc = get_ccc(input[j + 1]);
5662
21.5k
        if (composition[1] != composition[0] && previous_ccc < ccc &&
5663
5.17k
            has_composition(composition, input[j + 1])) {
5664
642
          return true;
5665
642
        }
5666
20.9k
        if (ccc == 0) {
5667
19.4k
          break;
5668
19.4k
        }
5669
1.48k
        previous_ccc = ccc;
5670
1.48k
      }
5671
20.8k
      input_count = j + 1;
5672
20.8k
      continue;
5673
21.4k
    }
5674
0
    ++input_count;
5675
0
  }
5676
1.48k
  return false;
5677
2.22k
}
5678
5679
// Trailing canonical combining class of a character: the combining class of the
5680
// last code point of its canonical decomposition, or the character's own class
5681
// when it has none. A precomposed starter such as U+00E1 (a + U+0301, class
5682
// 230) has class 0 but a nonzero trailing class, so a following mark of lower
5683
// class reorders past the hidden mark during normalization.
5684
33.6k
static uint8_t trailing_ccc(char32_t c) noexcept {
5685
33.6k
  const size_t length = canonical_decomp_length(c);
5686
33.6k
  if (length == 0) {
5687
31.4k
    return get_ccc(c);
5688
31.4k
  }
5689
2.17k
  const uint16_t* const decomposition =
5690
2.17k
      decomposition_block_row(decomposition_index[c >> 8]) + (c % 256);
5691
2.17k
  const size_t base = decomposition[0] >> 2;
5692
2.17k
  return get_ccc(decomposition_data[base + length - 1]);
5693
33.6k
}
5694
5695
void compose(std::u32string& input);
5696
5697
// A character that has a canonical decomposition is in NFC form only if that
5698
// decomposition composes back to exactly it. Singletons never do (e.g. U+212B
5699
// ANGSTROM SIGN). Composition exclusions do not either: their decomposition
5700
// composes to a different primary composite (e.g. U+1F71 -> U+03B1 U+0301 ->
5701
// U+03AC) or does not compose at all (e.g. U+0958 DEVANAGARI LETTER QA ->
5702
// U+0915 U+093C), and non-starter decompositions such as U+0344 -> U+0308
5703
// U+0301 stay decomposed. All are NFC_Quick_Check=No and must be normalized.
5704
// Since Unicode 16 the first code point of a decomposition can also compose
5705
// with the preceding character: U+16121 is U+1611E U+1611E, so U+1611E U+16121
5706
// normalizes to U+16121 U+1611E.
5707
36.4k
static bool decomposition_is_not_nfc(char32_t previous, char32_t c) noexcept {
5708
36.4k
  if (c >= hangul_sbase && c < hangul_sbase + hangul_scount) {
5709
1.35k
    return false;
5710
1.35k
  }
5711
35.1k
  if (c >= 0x110000) {
5712
0
    return false;
5713
0
  }
5714
35.1k
  const uint16_t* const decomposition =
5715
35.1k
      decomposition_block_row(decomposition_index[c >> 8]) + (c % 256);
5716
35.1k
  const size_t length = (decomposition[1] >> 2) - (decomposition[0] >> 2);
5717
35.1k
  if (length == 0 || (decomposition[0] & 1)) {
5718
32.6k
    return false;  // no canonical decomposition (or compatibility-only)
5719
32.6k
  }
5720
2.46k
  if (length == 1) {
5721
0
    return true;  // singleton
5722
0
  }
5723
2.46k
  const size_t base = decomposition[0] >> 2;
5724
2.46k
  if (base + length > decomposition_data_size) {
5725
0
    return false;
5726
0
  }
5727
  // Recompose the canonical decomposition; if it does not collapse back to c,
5728
  // then c is an exclusion / non-starter decomposition and is not NFC.
5729
2.46k
  std::u32string decomposed(decomposition_data + base,
5730
2.46k
                            decomposition_data + base + length);
5731
2.46k
  compose(decomposed);
5732
2.46k
  if (!(decomposed.size() == 1 && decomposed[0] == c)) {
5733
0
    return true;
5734
0
  }
5735
2.46k
  return previous < 0x110000 &&
5736
1.90k
         has_composition(
5737
1.90k
             composition_block_row(composition_index[previous >> 8]) +
5738
1.90k
                 (previous % 256),
5739
1.90k
             decomposition_data[base]);
5740
2.46k
}
5741
5742
2.97k
bool is_already_nfc(std::u32string_view input) noexcept {
5743
2.97k
  if (input.empty()) {
5744
0
    return true;
5745
0
  }
5746
2.97k
  if (!tables_are_ready() && !ensure_tables()) {
5747
0
    return false;
5748
0
  }
5749
  // 1) A character whose canonical decomposition does not compose back to it is
5750
  //    not NFC: singletons (e.g. U+212B), composition exclusions (e.g. U+0958)
5751
  //    and non-starter decompositions (e.g. U+0344), or one whose
5752
  //    decomposition starts with a code point that composes with the previous
5753
  //    character (e.g. U+1611E U+16121).
5754
2.97k
  char32_t previous = 0x110000;  // none
5755
36.4k
  for (char32_t c : input) {
5756
36.4k
    if (decomposition_is_not_nfc(previous, c)) {
5757
8
      return false;
5758
8
    }
5759
36.4k
    previous = c;
5760
36.4k
  }
5761
  // 2) Combining marks already in canonical order. prev_ccc carries the
5762
  //    trailing class of the previous character's canonical decomposition so a
5763
  //    composite starter followed by a lower-class mark is caught.
5764
2.97k
  uint8_t prev_ccc = 0;
5765
34.3k
  for (char32_t c : input) {
5766
34.3k
    uint8_t ccc = get_ccc(c);
5767
34.3k
    if (ccc != 0 && prev_ccc > ccc) {
5768
746
      return false;
5769
746
    }
5770
33.6k
    prev_ccc = trailing_ccc(c);
5771
33.6k
  }
5772
  // 3) No pairwise composition would apply (including Hangul L+V / LV+T).
5773
2.22k
  return !would_compose(input);
5774
2.97k
}
5775
5776
3.21k
void compose(std::u32string& input) {
5777
  /**
5778
   * Compose the domain_name string to Unicode Normalization Form C.
5779
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose
5780
   */
5781
3.21k
  size_t input_count{0};
5782
3.21k
  size_t composition_count{0};
5783
14.9k
  for (; input_count < input.size(); input_count++, composition_count++) {
5784
11.7k
    input[composition_count] = input[input_count];
5785
11.7k
    if (input[input_count] >= hangul_lbase &&
5786
2.35k
        input[input_count] < hangul_lbase + hangul_lcount) {
5787
758
      if (input_count + 1 < input.size() &&
5788
752
          input[input_count + 1] >= hangul_vbase &&
5789
665
          input[input_count + 1] < hangul_vbase + hangul_vcount) {
5790
596
        input[composition_count] =
5791
596
            hangul_sbase +
5792
596
            ((input[input_count] - hangul_lbase) * hangul_vcount +
5793
596
             input[input_count + 1] - hangul_vbase) *
5794
596
                hangul_tcount;
5795
596
        input_count++;
5796
596
        if (input_count + 1 < input.size() &&
5797
580
            input[input_count + 1] > hangul_tbase &&
5798
354
            input[input_count + 1] < hangul_tbase + hangul_tcount) {
5799
305
          input[composition_count] += input[++input_count] - hangul_tbase;
5800
305
        }
5801
596
      }
5802
10.9k
    } else if (input[input_count] >= hangul_sbase &&
5803
802
               input[input_count] < hangul_sbase + hangul_scount) {
5804
0
      if ((input[input_count] - hangul_sbase) % hangul_tcount == 0 &&
5805
0
          input_count + 1 < input.size() &&
5806
0
          input[input_count + 1] > hangul_tbase &&
5807
0
          input[input_count + 1] < hangul_tbase + hangul_tcount) {
5808
0
        input[composition_count] += input[++input_count] - hangul_tbase;
5809
0
      }
5810
10.9k
    } else if (input[input_count] < 0x110000) {
5811
10.9k
      const uint16_t* composition =
5812
10.9k
          composition_block_row(composition_index[input[input_count] >> 8]) +
5813
10.9k
          (input[input_count] % 256);
5814
10.9k
      size_t initial_composition_count = composition_count;
5815
17.7k
      for (int32_t previous_ccc = -1; input_count + 1 < input.size();
5816
14.6k
           input_count++) {
5817
14.6k
        uint8_t ccc = get_ccc(input[input_count + 1]);
5818
5819
14.6k
        if (composition[1] != composition[0] && previous_ccc < ccc) {
5820
8.00k
          int left = composition[0];
5821
8.00k
          int right = composition[1];
5822
8.00k
          if (left < 0 || right < left ||
5823
8.00k
              static_cast<size_t>(right) > composition_data_size) {
5824
0
            break;
5825
0
          }
5826
20.2k
          while (left + 2 < right) {
5827
12.2k
            int middle = left + (((right - left) >> 1) & ~1);
5828
12.2k
            if (composition_data[static_cast<size_t>(middle)] <=
5829
12.2k
                input[input_count + 1]) {
5830
7.14k
              left = middle;
5831
7.14k
            }
5832
12.2k
            if (composition_data[static_cast<size_t>(middle)] >=
5833
12.2k
                input[input_count + 1]) {
5834
8.78k
              right = middle;
5835
8.78k
            }
5836
12.2k
          }
5837
8.00k
          if (static_cast<size_t>(left + 1) < composition_data_size &&
5838
8.00k
              composition_data[static_cast<size_t>(left)] ==
5839
8.00k
                  input[input_count + 1]) {
5840
5.63k
            char32_t composed = composition_data[static_cast<size_t>(left + 1)];
5841
5.63k
            input[initial_composition_count] = composed;
5842
5.63k
            composition =
5843
5.63k
                composition_block_row(composition_index[composed >> 8]) +
5844
5.63k
                (composed % 256);
5845
5.63k
            continue;
5846
5.63k
          }
5847
8.00k
        }
5848
5849
8.99k
        if (ccc == 0) {
5850
7.79k
          break;
5851
7.79k
        }
5852
1.19k
        previous_ccc = ccc;
5853
1.19k
        input[++composition_count] = input[input_count + 1];
5854
1.19k
      }
5855
10.9k
    }
5856
11.7k
  }
5857
5858
3.21k
  if (composition_count < input_count) {
5859
3.13k
    input.resize(composition_count);
5860
3.13k
  }
5861
3.21k
}
5862
5863
749
bool normalize(std::u32string& input) {
5864
  /**
5865
   * Normalize the characters according to IDNA (Unicode Normalization Form C).
5866
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize
5867
   */
5868
749
  if (!ensure_tables() || decomposition_index == nullptr ||
5869
749
      composition_index == nullptr) {
5870
0
    return false;
5871
0
  }
5872
749
  if (is_already_nfc(input)) {
5873
0
    return true;
5874
0
  }
5875
749
  decompose_nfc(input);
5876
749
  compose(input);
5877
749
  return true;
5878
749
}
5879
5880
}  // namespace ada::idna
5881
/* end file src/normalization.cpp */
5882
/* begin file src/punycode.cpp */
5883
/* begin file include/ada/idna/punycode.h */
5884
#ifndef ADA_IDNA_PUNYCODE_H
5885
#define ADA_IDNA_PUNYCODE_H
5886
5887
#include <string>
5888
#include <string_view>
5889
5890
namespace ada::idna {
5891
5892
bool punycode_to_utf32(std::string_view input, std::u32string& out);
5893
bool verify_punycode(std::string_view input);
5894
bool utf32_to_punycode(std::u32string_view input, std::string& out);
5895
5896
}  // namespace ada::idna
5897
5898
#endif  // ADA_IDNA_PUNYCODE_H
5899
/* end file include/ada/idna/punycode.h */
5900
5901
#include <cstdint>
5902
5903
namespace ada::idna {
5904
5905
constexpr int32_t base = 36;
5906
constexpr int32_t tmin = 1;
5907
constexpr int32_t tmax = 26;
5908
constexpr int32_t skew = 38;
5909
constexpr int32_t damp = 700;
5910
constexpr int32_t initial_bias = 72;
5911
constexpr uint32_t initial_n = 128;
5912
5913
8.30k
static constexpr int32_t char_to_digit_value(char value) {
5914
8.30k
  if (value >= 'a' && value <= 'z') return value - 'a';
5915
1.82k
  if (value >= '0' && value <= '9') return value - '0' + 26;
5916
20
  return -1;
5917
1.82k
}
5918
5919
13.1k
static constexpr char digit_to_char(int32_t digit) {
5920
13.1k
  return digit < 26 ? char(digit + 97) : char(digit + 22);
5921
13.1k
}
5922
5923
10.5k
static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) {
5924
10.5k
  if (firsttime) {
5925
2.34k
    d = d / damp;
5926
8.20k
  } else {
5927
8.20k
    d = d / 2;
5928
8.20k
  }
5929
10.5k
  d += d / n;
5930
10.5k
  int32_t k = 0;
5931
13.0k
  while (d > ((base - tmin) * tmax) / 2) {
5932
2.51k
    d /= base - tmin;
5933
2.51k
    k += base;
5934
2.51k
  }
5935
10.5k
  return k + (((base - tmin + 1) * d) / (d + skew));
5936
10.5k
}
5937
5938
968
bool punycode_to_utf32(std::string_view input, std::u32string &out) {
5939
968
  int32_t written_out{0};
5940
968
  out.reserve(out.size() + input.size());
5941
968
  uint32_t n = initial_n;
5942
968
  int32_t i = 0;
5943
968
  int32_t bias = initial_bias;
5944
  // grab ascii content
5945
  // RFC 3492 section 6.2: copy the code points before the last delimiter,
5946
  // then consume the delimiter only "if more than zero code points were
5947
  // consumed". With a leading delimiter, b == 0, decoding starts at the
5948
  // delimiter itself, which is not a digit, and fails. This matches the
5949
  // reference implementation in appendix C (`in = b > 0 ? b + 1 : 0`).
5950
968
  size_t end_of_ascii = input.find_last_of('-');
5951
968
  if (end_of_ascii != std::string_view::npos && end_of_ascii > 0) {
5952
1.02k
    for (uint8_t c : input.substr(0, end_of_ascii)) {
5953
1.02k
      if (c >= 0x80) {
5954
0
        return false;
5955
0
      }
5956
1.02k
      out.push_back(c);
5957
1.02k
      written_out++;
5958
1.02k
    }
5959
192
    input.remove_prefix(end_of_ascii + 1);
5960
192
  }
5961
5.97k
  while (!input.empty()) {
5962
5.12k
    int32_t oldi = i;
5963
5.12k
    int32_t w = 1;
5964
8.36k
    for (int32_t k = base;; k += base) {
5965
8.36k
      if (input.empty()) {
5966
58
        return false;
5967
58
      }
5968
8.30k
      uint8_t code_point = input.front();
5969
8.30k
      input.remove_prefix(1);
5970
8.30k
      int32_t digit = char_to_digit_value(code_point);
5971
8.30k
      if (digit < 0) {
5972
20
        return false;
5973
20
      }
5974
8.28k
      if (digit > (0x7fffffff - i) / w) {
5975
7
        return false;
5976
7
      }
5977
8.27k
      i = i + digit * w;
5978
8.27k
      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
5979
8.27k
      if (digit < t) {
5980
5.03k
        break;
5981
5.03k
      }
5982
3.24k
      if (w > 0x7fffffff / (base - t)) {
5983
0
        return false;
5984
0
      }
5985
3.24k
      w = w * (base - t);
5986
3.24k
    }
5987
5.03k
    bias = adapt(i - oldi, written_out + 1, oldi == 0);
5988
5.03k
    if (i / (written_out + 1) > int32_t(0x7fffffff - n)) {
5989
30
      return false;
5990
30
    }
5991
5.00k
    n = n + i / (written_out + 1);
5992
5.00k
    i = i % (written_out + 1);
5993
5.00k
    if (n < 0x80) {
5994
0
      return false;
5995
0
    }
5996
5.00k
    out.insert(out.begin() + i, n);
5997
5.00k
    written_out++;
5998
5.00k
    ++i;
5999
5.00k
  }
6000
  // See https://github.com/whatwg/url/issues/803
6001
  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
6002
853
  if (out.size() >= 4 && out[0] == U'x' && out[1] == U'n' && out[2] == U'-' &&
6003
44
      out[3] == U'-') {
6004
1
    return false;
6005
1
  }
6006
852
  return true;
6007
853
}
6008
6009
0
bool verify_punycode(std::string_view input) {
6010
  // Track only the first 4 decoded code points to check for the "xn--" prefix.
6011
  // This avoids heap allocation while still detecting double-encoded ACE
6012
  // labels.
6013
0
  uint32_t first4[4]{};
6014
0
  size_t written_out{0};
6015
0
  uint32_t n = initial_n;
6016
0
  int32_t i = 0;
6017
0
  int32_t bias = initial_bias;
6018
  // grab ascii content
6019
0
  size_t end_of_ascii = input.find_last_of('-');
6020
0
  if (end_of_ascii != std::string_view::npos) {
6021
0
    for (uint8_t c : input.substr(0, end_of_ascii)) {
6022
0
      if (c >= 0x80) {
6023
0
        return false;
6024
0
      }
6025
0
      if (written_out < 4) {
6026
0
        first4[written_out] = c;
6027
0
      }
6028
0
      written_out++;
6029
0
    }
6030
0
    input.remove_prefix(end_of_ascii + 1);
6031
0
  }
6032
0
  while (!input.empty()) {
6033
0
    int32_t oldi = i;
6034
0
    int32_t w = 1;
6035
0
    for (int32_t k = base;; k += base) {
6036
0
      if (input.empty()) {
6037
0
        return false;
6038
0
      }
6039
0
      uint8_t code_point = input.front();
6040
0
      input.remove_prefix(1);
6041
0
      int32_t digit = char_to_digit_value(code_point);
6042
0
      if (digit < 0) {
6043
0
        return false;
6044
0
      }
6045
0
      if (digit > (0x7fffffff - i) / w) {
6046
0
        return false;
6047
0
      }
6048
0
      i = i + digit * w;
6049
0
      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
6050
0
      if (digit < t) {
6051
0
        break;
6052
0
      }
6053
0
      if (w > 0x7fffffff / (base - t)) {
6054
0
        return false;
6055
0
      }
6056
0
      w = w * (base - t);
6057
0
    }
6058
0
    bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0);
6059
0
    if (i / (written_out + 1) > 0x7fffffff - n) {
6060
0
      return false;
6061
0
    }
6062
0
    n = n + i / int32_t(written_out + 1);
6063
0
    i = i % int32_t(written_out + 1);
6064
0
    if (n < 0x80) {
6065
0
      return false;
6066
0
    }
6067
    // Simulate insert at position i, maintaining only the first 4 slots.
6068
0
    size_t insert_pos = size_t(i);
6069
0
    if (insert_pos < 4) {
6070
0
      for (size_t j = 3; j > insert_pos; j--) {
6071
0
        first4[j] = first4[j - 1];
6072
0
      }
6073
0
      first4[insert_pos] = n;
6074
0
    }
6075
0
    written_out++;
6076
0
    ++i;
6077
0
  }
6078
  // See https://github.com/whatwg/url/issues/803
6079
  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
6080
0
  if (written_out >= 4 && first4[0] == U'x' && first4[1] == U'n' &&
6081
0
      first4[2] == U'-' && first4[3] == U'-') {
6082
0
    return false;
6083
0
  }
6084
0
  return true;
6085
0
}
6086
6087
1.49k
bool utf32_to_punycode(std::u32string_view input, std::string &out) {
6088
1.49k
  out.reserve(input.size() + out.size());
6089
1.49k
  uint32_t n = initial_n;
6090
1.49k
  int32_t d = 0;
6091
1.49k
  int32_t bias = initial_bias;
6092
1.49k
  size_t h = 0;
6093
  // first push the ascii content
6094
7.29k
  for (uint32_t c : input) {
6095
7.29k
    if (c < 0x80) {
6096
1.78k
      ++h;
6097
1.78k
      out.push_back(char(c));
6098
1.78k
    }
6099
7.29k
    if (c > 0x10ffff || (c >= 0xd800 && c < 0xe000)) {
6100
0
      return false;
6101
0
    }
6102
7.29k
  }
6103
1.49k
  size_t b = h;
6104
1.49k
  if (b > 0) {
6105
528
    out.push_back('-');
6106
528
  }
6107
5.21k
  while (h < input.size()) {
6108
3.72k
    uint32_t m = 0x10FFFF;
6109
31.4k
    for (auto code_point : input) {
6110
31.4k
      if (code_point >= n && code_point < m) m = code_point;
6111
31.4k
    }
6112
6113
3.72k
    if ((m - n) > (0x7fffffff - d) / (h + 1)) {
6114
0
      return false;
6115
0
    }
6116
3.72k
    d = d + int32_t((m - n) * (h + 1));
6117
3.72k
    n = m;
6118
31.4k
    for (auto c : input) {
6119
31.4k
      if (c < n) {
6120
14.8k
        if (d == 0x7fffffff) {
6121
0
          return false;
6122
0
        }
6123
14.8k
        ++d;
6124
14.8k
      }
6125
31.4k
      if (c == n) {
6126
5.50k
        int32_t q = d;
6127
13.1k
        for (int32_t k = base;; k += base) {
6128
13.1k
          int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
6129
6130
13.1k
          if (q < t) {
6131
5.50k
            break;
6132
5.50k
          }
6133
7.62k
          out.push_back(digit_to_char(t + ((q - t) % (base - t))));
6134
7.62k
          q = (q - t) / (base - t);
6135
7.62k
        }
6136
5.50k
        out.push_back(digit_to_char(q));
6137
5.50k
        bias = adapt(d, int32_t(h + 1), h == b);
6138
5.50k
        d = 0;
6139
5.50k
        ++h;
6140
5.50k
      }
6141
31.4k
    }
6142
3.72k
    ++d;
6143
3.72k
    ++n;
6144
3.72k
  }
6145
1.49k
  return true;
6146
1.49k
}
6147
6148
}  // namespace ada::idna
6149
/* end file src/punycode.cpp */
6150
/* begin file src/validity.cpp */
6151
6152
#include <algorithm>
6153
#include <span>
6154
#include <string_view>
6155
6156
namespace ada::idna {
6157
6158
// Values stored in dir_value; keep in sync with BIDI_CLASSES in
6159
// scripts/unicode_data_table.py.
6160
enum direction : uint8_t {
6161
  NONE,
6162
  BN,
6163
  CS,
6164
  ES,
6165
  ON,
6166
  EN,
6167
  L,
6168
  R,
6169
  NSM,
6170
  AL,
6171
  AN,
6172
  ET,
6173
  WS,
6174
  RLO,
6175
  LRO,
6176
  PDF,
6177
  RLE,
6178
  RLI,
6179
  FSI,
6180
  PDI,
6181
  LRI,
6182
  B,
6183
  S,
6184
  LRE
6185
};
6186
6187
// Values stored in joining_value; keep in sync with JOINING_TYPES in
6188
// scripts/unicode_data_table.py. Code points without a range are U.
6189
enum class joining_type : uint8_t { U, C, D, L, R, T };
6190
6191
// Bidi direction and Joining_Type ranges live in the compressed blob as const
6192
// SoA arrays (dir_* and joining_*). See table_store.hpp layout asserts.
6193
// Regenerate with: python3 scripts/unicode_data_table.py --write
6194
6195
// Defined in normalization.cpp.
6196
uint8_t get_ccc(char32_t c) noexcept;
6197
6198
// CheckJoiners and CheckBidi are true for URL specification.
6199
6200
// Returns the index of the range [start[i], last[i]] that contains code_point,
6201
// or count if there is none. `last` must be sorted.
6202
inline static size_t find_range(const uint32_t* start, const uint32_t* last,
6203
27.3k
                                size_t count, uint32_t code_point) noexcept {
6204
27.3k
  size_t lo = 0, hi = count;
6205
317k
  while (lo < hi) {
6206
289k
    size_t mid = lo + (hi - lo) / 2;
6207
289k
    if (last[mid] < code_point) {
6208
77.2k
      lo = mid + 1;
6209
212k
    } else {
6210
212k
      hi = mid;
6211
212k
    }
6212
289k
  }
6213
27.3k
  return lo < count && code_point >= start[lo] ? lo : count;
6214
27.3k
}
6215
6216
// Assumes ensure_tables() has already been called by is_label_valid().
6217
26.4k
inline static direction find_direction(uint32_t code_point) noexcept {
6218
26.4k
  size_t i = find_range(dir_start, dir_final, dir_table_count, code_point);
6219
26.4k
  return i == dir_table_count ? direction::NONE
6220
26.4k
                              : static_cast<direction>(dir_value[i]);
6221
26.4k
}
6222
6223
// Assumes ensure_tables() has already been called by is_label_valid().
6224
844
inline static joining_type find_joining_type(uint32_t code_point) noexcept {
6225
844
  size_t i =
6226
844
      find_range(joining_start, joining_final, joining_table_count, code_point);
6227
844
  return i == joining_table_count ? joining_type::U
6228
844
                                  : static_cast<joining_type>(joining_value[i]);
6229
844
}
6230
6231
// The ContextJ rules for U+200C and U+200D from RFC 5892 Appendix A.
6232
2.36k
inline static bool is_contextj_valid(std::u32string_view label) noexcept {
6233
2.36k
  constexpr uint8_t virama_ccc = 9;
6234
23.2k
  for (size_t i = 0; i < label.size(); i++) {
6235
21.0k
    if (label[i] != 0x200C && label[i] != 0x200D) {
6236
20.7k
      continue;
6237
20.7k
    }
6238
    // If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True;
6239
290
    if (i > 0 && get_ccc(label[i - 1]) == virama_ccc) {
6240
39
      continue;
6241
39
    }
6242
251
    if (label[i] == 0x200D) {
6243
10
      return false;
6244
10
    }
6245
    // If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C
6246
    //    (Joining_Type:T)*(Joining_Type:{R,D})) Then True;
6247
241
    joining_type before = joining_type::U;
6248
470
    for (size_t j = i; j > 0;) {
6249
468
      before = find_joining_type(label[--j]);
6250
468
      if (before != joining_type::T) {
6251
239
        break;
6252
239
      }
6253
468
    }
6254
241
    if (before != joining_type::L && before != joining_type::D) {
6255
66
      return false;
6256
66
    }
6257
175
    joining_type after = joining_type::U;
6258
414
    for (size_t j = i + 1; j < label.size(); j++) {
6259
376
      after = find_joining_type(label[j]);
6260
376
      if (after != joining_type::T) {
6261
137
        break;
6262
137
      }
6263
376
    }
6264
175
    if (after != joining_type::R && after != joining_type::D) {
6265
84
      return false;
6266
84
    }
6267
175
  }
6268
2.20k
  return true;
6269
2.36k
}
6270
6271
inline static size_t find_last_not_of_nsm(
6272
2.20k
    const std::u32string_view label) noexcept {
6273
3.14k
  for (int i = static_cast<int>(label.size() - 1); i >= 0; i--)
6274
3.14k
    if (find_direction(label[i]) != direction::NSM) return i;
6275
6276
0
  return std::u32string_view::npos;
6277
2.20k
}
6278
6279
// An RTL label is a label that contains at least one character of type R, AL,
6280
// or AN. https://www.rfc-editor.org/rfc/rfc5893#section-2
6281
2.20k
inline static bool is_rtl_label(const std::u32string_view label) noexcept {
6282
2.20k
  const size_t mask =
6283
2.20k
      (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN);
6284
6285
2.20k
  size_t directions = 0;
6286
21.4k
  for (size_t i = 0; i < label.size(); i++) {
6287
19.2k
    directions |= 1u << find_direction(label[i]);
6288
19.2k
  }
6289
2.20k
  return (directions & mask) != 0;
6290
2.20k
}
6291
6292
2.46k
bool is_label_valid(const std::u32string_view label) {
6293
2.46k
  if (label.empty()) {
6294
0
    return true;
6295
0
  }
6296
2.46k
  if (!ensure_tables() || combining_ranges == nullptr || dir_start == nullptr ||
6297
2.46k
      dir_final == nullptr || dir_value == nullptr ||
6298
2.46k
      joining_start == nullptr || joining_final == nullptr ||
6299
2.46k
      joining_value == nullptr) {
6300
0
    return false;
6301
0
  }
6302
6303
  ///////////////
6304
  // We have a normalization step which ensures that we are in NFC.
6305
  // If we receive punycode, we normalize and check that the normalized
6306
  // version matches the original.
6307
  // --------------------------------------
6308
  // The label must be in Unicode Normalization Form NFC.
6309
6310
  // Current URL standard indicatest that CheckHyphens is set to false.
6311
  // ---------------------------------------
6312
  // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
6313
  // in both the third and fourth positions. If CheckHyphens, the label must
6314
  // neither begin nor end with a U+002D HYPHEN-MINUS character.
6315
6316
  // This is not necessary because we segment the
6317
  // labels by '.'.
6318
  // ---------------------------------------
6319
  // The label must not contain a U+002E ( . ) FULL STOP.
6320
  // if (label.find('.') != std::string_view::npos) return false;
6321
6322
  // The label must not begin with a combining mark.
6323
  // Range membership via lower_bound on range end.
6324
2.46k
  const std::span<const uint32_t[2]> comb_span{combining_ranges,
6325
2.46k
                                               combining_range_count};
6326
2.46k
  const auto comb_it = std::ranges::lower_bound(
6327
20.8k
      comb_span, label.front(), {}, [](const auto& range) { return range[1]; });
6328
2.46k
  if (comb_it != comb_span.end() && label.front() >= (*comb_it)[0]) {
6329
103
    return false;
6330
103
  }
6331
  // We verify this next step as part of the mapping:
6332
  // ---------------------------------------------
6333
  // Each code point in the label must only have certain status values
6334
  // according to Section 5, IDNA Mapping Table:
6335
  // - For Transitional Processing, each value must be valid.
6336
  // - For Nontransitional Processing, each value must be either valid or
6337
  // deviation.
6338
6339
  // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix
6340
  // A, in The Unicode Code Points and Internationalized Domain Names for
6341
  // Applications (IDNA) [IDNA2008].
6342
2.36k
  if (!is_contextj_valid(label)) {
6343
160
    return false;
6344
160
  }
6345
6346
  // If CheckBidi, and if the domain name is a  Bidi domain name, then the label
6347
  // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893,
6348
  // Section 2.
6349
6350
  // The following rule, consisting of six conditions, applies to labels
6351
  // in Bidi domain names.  The requirements that this rule satisfies are
6352
  // described in Section 3.  All of the conditions must be satisfied for
6353
  // the rule to be satisfied.
6354
  //
6355
  //  1.  The first character must be a character with Bidi property L, R,
6356
  //     or AL.  If it has the R or AL property, it is an RTL label; if it
6357
  //     has the L property, it is an LTR label.
6358
  //
6359
  //  2.  In an RTL label, only characters with the Bidi properties R, AL,
6360
  //      AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.
6361
  //
6362
  //   3.  In an RTL label, the end of the label must be a character with
6363
  //       Bidi property R, AL, EN, or AN, followed by zero or more
6364
  //       characters with Bidi property NSM.
6365
  //
6366
  //   4.  In an RTL label, if an EN is present, no AN may be present, and
6367
  //       vice versa.
6368
  //
6369
  //  5.  In an LTR label, only characters with the Bidi properties L, EN,
6370
  //       ES, CS, ET, ON, BN, or NSM are allowed.
6371
  //
6372
  //   6.  In an LTR label, the end of the label must be a character with
6373
  //       Bidi property L or EN, followed by zero or more characters with
6374
  //       Bidi property NSM.
6375
6376
2.20k
  size_t last_non_nsm_char = find_last_not_of_nsm(label);
6377
2.20k
  if (last_non_nsm_char == std::u32string_view::npos) {
6378
0
    return false;
6379
0
  }
6380
6381
  // A "Bidi domain name" is a domain name that contains at least one RTL label.
6382
  // The following rule, consisting of six conditions, applies to labels in Bidi
6383
  // domain names.
6384
2.20k
  if (is_rtl_label(label)) {
6385
    // The first character must be a character with Bidi property L, R,
6386
    // or AL. If it has the R or AL property, it is an RTL label; if it
6387
    // has the L property, it is an LTR label.
6388
6389
596
    if (find_direction(label[0]) == direction::L) {
6390
      // Eval as LTR
6391
6392
      // In an LTR label, only characters with the Bidi properties L, EN,
6393
      // ES, CS, ET, ON, BN, or NSM are allowed.
6394
1.11k
      for (size_t i = 0; i <= last_non_nsm_char; i++) {
6395
1.11k
        const direction d = find_direction(label[i]);
6396
1.11k
        if (!(d == direction::L || d == direction::EN || d == direction::ES ||
6397
489
              d == direction::CS || d == direction::ET || d == direction::ON ||
6398
277
              d == direction::BN || d == direction::NSM)) {
6399
128
          return false;
6400
128
        }
6401
1.11k
      }
6402
6403
0
      const direction last_dir = find_direction(label[last_non_nsm_char]);
6404
0
      if (!(last_dir == direction::L || last_dir == direction::EN)) {
6405
0
        return false;
6406
0
      }
6407
6408
0
      return true;
6409
6410
468
    } else {
6411
      // Eval as RTL
6412
6413
      // The first character must be R or AL; a leading AN (or any other
6414
      // direction) does not start a valid RTL label.
6415
468
      const direction first_dir = find_direction(label[0]);
6416
468
      if (first_dir != direction::R && first_dir != direction::AL) {
6417
27
        return false;
6418
27
      }
6419
6420
441
      bool has_an = false;
6421
441
      bool has_en = false;
6422
2.26k
      for (size_t i = 0; i <= last_non_nsm_char; i++) {
6423
1.95k
        const direction d = find_direction(label[i]);
6424
6425
        // In an RTL label, if an EN is present, no AN may be present, and vice
6426
        // versa.
6427
1.95k
        if ((d == direction::EN && ((has_en = true) && has_an)) ||
6428
1.95k
            (d == direction::AN && ((has_an = true) && has_en))) {
6429
2
          return false;
6430
2
        }
6431
6432
1.95k
        if (!(d == direction::R || d == direction::AL || d == direction::AN ||
6433
698
              d == direction::EN || d == direction::ES || d == direction::CS ||
6434
464
              d == direction::ET || d == direction::ON || d == direction::BN ||
6435
196
              d == direction::NSM)) {
6436
77
          return false;
6437
77
        }
6438
6439
1.87k
        if (i == last_non_nsm_char &&
6440
362
            !(d == direction::R || d == direction::AL || d == direction::AN ||
6441
88
              d == direction::EN)) {
6442
47
          return false;
6443
47
        }
6444
1.87k
      }
6445
6446
315
      return true;
6447
441
    }
6448
596
  }
6449
6450
1.61k
  return true;
6451
2.20k
}
6452
6453
}  // namespace ada::idna
6454
/* end file src/validity.cpp */
6455
/* begin file src/to_ascii.cpp */
6456
/* begin file include/ada/idna/to_ascii.h */
6457
#ifndef ADA_IDNA_TO_ASCII_H
6458
#define ADA_IDNA_TO_ASCII_H
6459
6460
#include <string>
6461
#include <string_view>
6462
6463
/* begin file include/ada/idna/limits.h */
6464
#ifndef ADA_IDNA_LIMITS_H
6465
#define ADA_IDNA_LIMITS_H
6466
6467
#include <cstddef>
6468
6469
namespace ada::idna {
6470
6471
// Maximum accepted UTF-8 domain length for non-ASCII to_ascii input and for
6472
// to_unicode input.
6473
// Bounds heap growth under untrusted input (DoS resistance). DNS wire limits
6474
// are smaller; this allows long Unicode labels used in URL tests/fixtures.
6475
inline constexpr size_t max_domain_input_bytes = 16384;
6476
6477
}  // namespace ada::idna
6478
6479
#endif  // ADA_IDNA_LIMITS_H
6480
/* end file include/ada/idna/limits.h */
6481
6482
namespace ada::idna {
6483
6484
// Converts a domain (e.g., www.google.com) possibly containing international
6485
// characters to an ascii domain (with punycode). It will not do percent
6486
// decoding: percent decoding should be done prior to calling this function. We
6487
// do not remove tabs and spaces, they should have been removed prior to calling
6488
// this function. We also do not trim control characters. We also assume that
6489
// the input is not empty. We return "" on error. Non-ASCII inputs longer than
6490
// max_domain_input_bytes are rejected; ASCII inputs of any length are accepted
6491
// (they are only lowercased).
6492
//
6493
// This function may accept or even produce invalid domains (WHATWG carve-outs).
6494
std::string to_ascii(std::string_view ut8_string);
6495
6496
// Same as to_ascii, but writes into `out` and returns false on error without
6497
// relying on empty-string ambiguity.
6498
[[nodiscard]] bool to_ascii(std::string_view ut8_string, std::string& out);
6499
6500
// Returns true if the string contains a forbidden code point according to the
6501
// WHATGL URL specification:
6502
// https://url.spec.whatwg.org/#forbidden-domain-code-point
6503
bool contains_forbidden_domain_code_point(std::string_view ascii_string);
6504
6505
bool constexpr is_ascii(std::u32string_view view);
6506
bool constexpr is_ascii(std::string_view view);
6507
6508
}  // namespace ada::idna
6509
6510
#endif  // ADA_IDNA_TO_ASCII_H
6511
/* end file include/ada/idna/to_ascii.h */
6512
6513
#include <algorithm>
6514
#include <cstdint>
6515
#include <cstring>
6516
#include <ranges>
6517
6518
/* begin file include/ada/idna/validity.h */
6519
#ifndef ADA_IDNA_VALIDITY_H
6520
#define ADA_IDNA_VALIDITY_H
6521
6522
#include <string>
6523
#include <string_view>
6524
6525
namespace ada::idna {
6526
6527
/**
6528
 * @see https://www.unicode.org/reports/tr46/#Validity_Criteria
6529
 */
6530
bool is_label_valid(std::u32string_view label);
6531
6532
}  // namespace ada::idna
6533
6534
#endif  // ADA_IDNA_VALIDITY_H
6535
/* end file include/ada/idna/validity.h */
6536
6537
#ifdef ADA_USE_SIMDUTF
6538
#include "simdutf.h"
6539
#endif
6540
6541
namespace ada::idna {
6542
6543
5.99k
bool constexpr is_ascii(std::u32string_view view) {
6544
23.4k
  for (uint32_t c : view) {
6545
23.4k
    if (c >= 0x80) {
6546
5.04k
      return false;
6547
5.04k
    }
6548
23.4k
  }
6549
954
  return true;
6550
5.99k
}
6551
6552
3.33k
bool constexpr is_ascii(std::string_view view) {
6553
11.6k
  for (uint8_t c : view) {
6554
11.6k
    if (c >= 0x80) {
6555
2.63k
      return false;
6556
2.63k
    }
6557
11.6k
  }
6558
704
  return true;
6559
3.33k
}
6560
6561
constexpr static uint8_t is_forbidden_domain_code_point_table[] = {
6562
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6563
    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
6564
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
6565
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
6566
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6567
    0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6568
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6569
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6570
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6571
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6572
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
6573
6574
static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
6575
6576
0
inline bool is_forbidden_domain_code_point(const char c) noexcept {
6577
0
  return is_forbidden_domain_code_point_table[uint8_t(c)];
6578
0
}
6579
6580
0
bool contains_forbidden_domain_code_point(std::string_view view) {
6581
0
  return std::ranges::any_of(view, is_forbidden_domain_code_point);
6582
0
}
6583
6584
// Per the WHATWG URL "domain to ASCII" algorithm, when beStrict is false and
6585
// the input domain is an ASCII string, the result is the input lowercased,
6586
// regardless of the outcome of Unicode ToASCII.
6587
//
6588
// See https://url.spec.whatwg.org/#concept-domain-to-ascii
6589
704
static void from_ascii_to_ascii(std::string_view ut8_string, std::string& out) {
6590
704
  out.assign(ut8_string);
6591
704
  ascii_map(out.data(), out.size());
6592
704
}
6593
6594
// Append ASCII code units from a UTF-32 label (all values < 0x80).
6595
1.12k
static void append_ascii_label(std::string& out, std::u32string_view label) {
6596
1.12k
  const size_t old = out.size();
6597
1.12k
  out.resize(old + label.size());
6598
1.12k
  char* dest = out.data() + old;
6599
14.0k
  for (char32_t c : label) {
6600
14.0k
    *dest++ = static_cast<char>(c);
6601
14.0k
  }
6602
1.12k
}
6603
6604
// True if label begins with "xn--" (already lowercased by mapping).
6605
3.17k
static bool is_ace_prefix(std::u32string_view label) noexcept {
6606
3.17k
  return label.size() >= 4 && label[0] == U'x' && label[1] == U'n' &&
6607
1.05k
         label[2] == U'-' && label[3] == U'-';
6608
3.17k
}
6609
6610
3.33k
[[nodiscard]] bool to_ascii(std::string_view ut8_string, std::string& out) {
6611
3.33k
  out.clear();
6612
  // The ASCII path is a single same-size copy, so it needs no length bound.
6613
  // Checking first would reject the (longer) ASCII output of a non-ASCII input
6614
  // that was accepted, breaking to_ascii(to_ascii(x)) == to_ascii(x).
6615
3.33k
  if (is_ascii(ut8_string)) {
6616
704
    from_ascii_to_ascii(ut8_string, out);
6617
704
    return true;
6618
704
  }
6619
2.63k
  if (ut8_string.size() > max_domain_input_bytes) {
6620
0
    return false;
6621
0
  }
6622
6623
#ifdef ADA_USE_SIMDUTF
6624
  size_t utf32_length =
6625
      simdutf::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
6626
  if (utf32_length == 0 && !ut8_string.empty()) {
6627
    return false;
6628
  }
6629
  std::u32string working(utf32_length, U'\0');
6630
  size_t actual_utf32_length = simdutf::convert_utf8_to_utf32(
6631
      ut8_string.data(), ut8_string.size(), working.data());
6632
#else
6633
2.63k
  size_t utf32_length =
6634
2.63k
      ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
6635
2.63k
  if (utf32_length == 0 && !ut8_string.empty()) {
6636
17
    return false;
6637
17
  }
6638
2.61k
  std::u32string working(utf32_length, U'\0');
6639
2.61k
  size_t actual_utf32_length = ada::idna::utf8_to_utf32(
6640
2.61k
      ut8_string.data(), ut8_string.size(), working.data());
6641
2.61k
#endif
6642
2.61k
  if (actual_utf32_length == 0 || actual_utf32_length != utf32_length) {
6643
128
    return false;
6644
128
  }
6645
2.48k
  working.resize(actual_utf32_length);
6646
6647
  // Map into a second buffer with exact sizing (no growth reallocs).
6648
2.48k
  std::u32string mapped;
6649
2.48k
  if (!ada::idna::map(working, mapped)) {
6650
45
    return false;
6651
45
  }
6652
  // Drop UTF-32 input; reuse `working` as scratch for ACE validation below.
6653
2.44k
  working.clear();
6654
6655
  // Skip NFC when already normalized (ASCII is a fast subset of this check).
6656
2.44k
  if (!is_ascii(mapped) && !is_already_nfc(mapped)) {
6657
518
    if (!normalize(mapped)) {
6658
0
      return false;
6659
0
    }
6660
518
  }
6661
6662
  // Estimate ASCII output size (punycode may expand non-ASCII labels).
6663
2.44k
  out.reserve(mapped.size() + 8);
6664
6665
  // Walk labels with a single pointer scan (no repeated string::find).
6666
2.44k
  const char32_t* p = mapped.data();
6667
2.44k
  const char32_t* const end = p + mapped.size();
6668
2.44k
  std::u32string post_map;
6669
6670
4.66k
  while (p < end) {
6671
3.31k
    const char32_t* label_begin = p;
6672
36.8k
    while (p < end && *p != U'.') {
6673
33.5k
      ++p;
6674
33.5k
    }
6675
3.31k
    const size_t label_size = static_cast<size_t>(p - label_begin);
6676
3.31k
    std::u32string_view label_view(label_begin, label_size);
6677
3.31k
    const bool is_last_label = (p == end);
6678
3.31k
    if (p < end) {
6679
915
      ++p;  // skip dot
6680
915
    }
6681
6682
3.31k
    if (label_size == 0) {
6683
      // empty label
6684
3.17k
    } else if (is_ace_prefix(label_view)) {
6685
13.5k
      for (char32_t c : label_view) {
6686
13.5k
        if (c >= 0x80) {
6687
12
          out.clear();
6688
12
          return false;
6689
12
        }
6690
13.5k
      }
6691
968
      append_ascii_label(out, label_view);
6692
968
      std::string_view puny_segment_ascii(
6693
968
          out.data() + (out.size() - label_size) + 4, label_size - 4);
6694
968
      working.clear();
6695
968
      if (!ada::idna::punycode_to_utf32(puny_segment_ascii, working)) {
6696
116
        out.clear();
6697
116
        return false;
6698
116
      }
6699
852
      if (is_ascii(working)) {
6700
74
        out.clear();
6701
74
        return false;
6702
74
      }
6703
778
      if (!ada::idna::map(working, post_map) || working != post_map) {
6704
264
        out.clear();
6705
264
        return false;
6706
264
      }
6707
      // Mapping must be stable; NFC must not change the mapped form either.
6708
514
      if (!is_ascii(post_map) && !is_already_nfc(post_map)) {
6709
231
        if (!normalize(post_map) || post_map != working) {
6710
80
          out.clear();
6711
80
          return false;
6712
80
        }
6713
231
      }
6714
434
      if (post_map.empty() || !is_label_valid(post_map)) {
6715
6
        out.clear();
6716
6
        return false;
6717
6
      }
6718
2.19k
    } else if (is_ascii(label_view)) {
6719
156
      append_ascii_label(out, label_view);
6720
2.03k
    } else {
6721
2.03k
      if (!is_label_valid(label_view)) {
6722
538
        out.clear();
6723
538
        return false;
6724
538
      }
6725
1.49k
      out.append("xn--");
6726
1.49k
      if (!ada::idna::utf32_to_punycode(label_view, out)) {
6727
0
        out.clear();
6728
0
        return false;
6729
0
      }
6730
1.49k
    }
6731
2.22k
    if (!is_last_label) {
6732
904
      out.push_back('.');
6733
904
    }
6734
2.22k
  }
6735
1.35k
  return true;
6736
2.44k
}
6737
6738
3.33k
std::string to_ascii(std::string_view ut8_string) {
6739
3.33k
  std::string out;
6740
3.33k
  if (!to_ascii(ut8_string, out)) {
6741
1.28k
    return {};
6742
1.28k
  }
6743
2.05k
  return out;
6744
3.33k
}
6745
}  // namespace ada::idna
6746
/* end file src/to_ascii.cpp */
6747
/* begin file src/to_unicode.cpp */
6748
/* begin file include/ada/idna/to_unicode.h */
6749
#ifndef ADA_IDNA_TO_UNICODE_H
6750
#define ADA_IDNA_TO_UNICODE_H
6751
6752
#include <string>
6753
#include <string_view>
6754
6755
6756
namespace ada::idna {
6757
6758
// UTS #46 ToUnicode. Never fails per the standard: on step failure the original
6759
// label is kept. Inputs longer than max_domain_input_bytes are returned
6760
// unchanged as a safety measure under untrusted input.
6761
std::string to_unicode(std::string_view input);
6762
6763
// Writes into `out`. Returns false only if the input exceeds
6764
// max_domain_input_bytes (out is left empty). Otherwise always returns true
6765
// (ToUnicode does not fail).
6766
[[nodiscard]] bool to_unicode(std::string_view input, std::string& out);
6767
6768
}  // namespace ada::idna
6769
6770
#endif  // ADA_IDNA_TO_UNICODE_H
6771
/* end file include/ada/idna/to_unicode.h */
6772
6773
#include <algorithm>
6774
#include <string>
6775
6776
/* begin file include/idna.h */
6777
#ifndef ADA_IDNA_H
6778
#define ADA_IDNA_H
6779
6780
/* begin file include/ada/idna/identifier.h */
6781
#ifndef ADA_IDNA_IDENTIFIER_H
6782
#define ADA_IDNA_IDENTIFIER_H
6783
6784
#include <string>
6785
#include <string_view>
6786
6787
namespace ada::idna {
6788
6789
// Verify if it is valid name code point given a Unicode code point and a
6790
// boolean first: If first is true return the result of checking if code point
6791
// is contained in the IdentifierStart set of code points. Otherwise return the
6792
// result of checking if code point is contained in the IdentifierPart set of
6793
// code points. Returns false if the input is empty or the code point is not
6794
// valid. There is minimal Unicode error handling: the input should be valid
6795
// UTF-8. https://urlpattern.spec.whatwg.org/#is-a-valid-name-code-point
6796
bool valid_name_code_point(char32_t code_point, bool first);
6797
6798
}  // namespace ada::idna
6799
6800
#endif
6801
/* end file include/ada/idna/identifier.h */
6802
6803
#endif
6804
/* end file include/idna.h */
6805
6806
#ifdef ADA_USE_SIMDUTF
6807
#include "simdutf.h"
6808
#endif
6809
6810
namespace ada::idna {
6811
6812
0
[[nodiscard]] bool to_unicode(std::string_view input, std::string& output) {
6813
0
  output.clear();
6814
0
  if (input.size() > max_domain_input_bytes) {
6815
0
    return false;
6816
0
  }
6817
0
  output.reserve(input.size());
6818
6819
0
  size_t label_start = 0;
6820
0
  std::u32string tmp_buffer;
6821
0
  std::u32string post_map;
6822
0
  while (label_start < input.size()) {
6823
0
    size_t loc_dot = input.find('.', label_start);
6824
0
    bool is_last_label = (loc_dot == std::string_view::npos);
6825
0
    size_t label_size =
6826
0
        is_last_label ? input.size() - label_start : loc_dot - label_start;
6827
0
    auto label_view = std::string_view(input.data() + label_start, label_size);
6828
6829
0
    if (label_view.starts_with("xn--") && ada::idna::is_ascii(label_view)) {
6830
0
      label_view.remove_prefix(4);
6831
0
      tmp_buffer.clear();
6832
0
      if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) {
6833
        // Per UTS #46, the decoded label must be re-validated. Reject decodings
6834
        // that are pure ASCII (xn-- encoding of an ASCII-only label), or whose
6835
        // mapping/normalization is not stable, or that fail label validity.
6836
0
        bool accept_decoded = true;
6837
0
        if (ada::idna::is_ascii(tmp_buffer)) {
6838
0
          accept_decoded = false;
6839
0
        } else {
6840
0
          post_map.clear();
6841
0
          if (!ada::idna::map(tmp_buffer, post_map) || post_map != tmp_buffer) {
6842
0
            accept_decoded = false;
6843
0
          } else if (!ada::idna::normalize(post_map) ||
6844
0
                     post_map != tmp_buffer || post_map.empty() ||
6845
0
                     !ada::idna::is_label_valid(post_map)) {
6846
0
            accept_decoded = false;
6847
0
          }
6848
0
        }
6849
6850
0
        if (accept_decoded) {
6851
#ifdef ADA_USE_SIMDUTF
6852
          auto utf8_size = simdutf::utf8_length_from_utf32(tmp_buffer.data(),
6853
                                                           tmp_buffer.size());
6854
          size_t old_size = output.size();
6855
          output.resize(old_size + utf8_size);
6856
          size_t written = simdutf::convert_utf32_to_utf8(
6857
              tmp_buffer.data(), tmp_buffer.size(), output.data() + old_size);
6858
          if (written != utf8_size) {
6859
            output.resize(old_size);
6860
            output.append(
6861
                std::string_view(input.data() + label_start, label_size));
6862
          }
6863
#else
6864
0
          auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(),
6865
0
                                                             tmp_buffer.size());
6866
0
          size_t old_size = output.size();
6867
0
          output.resize(old_size + utf8_size);
6868
0
          size_t written = ada::idna::utf32_to_utf8(
6869
0
              tmp_buffer.data(), tmp_buffer.size(), output.data() + old_size);
6870
0
          if (written != utf8_size) {
6871
0
            output.resize(old_size);
6872
0
            output.append(
6873
0
                std::string_view(input.data() + label_start, label_size));
6874
0
          }
6875
0
#endif
6876
0
        } else {
6877
          // ToUnicode never fails. If any step fails, return the original
6878
          // input sequence for the label.
6879
0
          output.append(
6880
0
              std::string_view(input.data() + label_start, label_size));
6881
0
        }
6882
0
      } else {
6883
0
        output.append(std::string_view(input.data() + label_start, label_size));
6884
0
      }
6885
0
    } else {
6886
0
      output.append(label_view);
6887
0
    }
6888
6889
0
    if (!is_last_label) {
6890
0
      output.push_back('.');
6891
0
    }
6892
6893
0
    label_start += label_size + 1;
6894
0
  }
6895
6896
0
  return true;
6897
0
}
6898
6899
0
std::string to_unicode(std::string_view input) {
6900
0
  std::string output;
6901
0
  if (!to_unicode(input, output)) {
6902
    // Over-limit input: return original (ToUnicode never fails in the sense of
6903
    // producing no answer for valid-length inputs).
6904
0
    return std::string(input);
6905
0
  }
6906
0
  return output;
6907
0
}
6908
}  // namespace ada::idna
6909
/* end file src/to_unicode.cpp */
6910
/* begin file src/identifier.cpp */
6911
6912
#include <algorithm>
6913
#include <array>
6914
#include <span>
6915
#include <string>
6916
6917
/* begin file src/id_tables.cpp */
6918
// IDNA  18.0.0
6919
// Identifier range tables are stored in the compressed blob (table_store.hpp).
6920
// Regenerate with: python3 scripts/derived_table.py --write
6921
//   id_continue: 1437 ranges
6922
//   id_start:    789 ranges
6923
6924
// clang-format off
6925
#ifndef ADA_IDNA_IDENTIFIER_TABLES_H
6926
#define ADA_IDNA_IDENTIFIER_TABLES_H
6927
#include <cstdint>
6928
6929
namespace ada::idna {
6930
6931
// id_continue / id_start pointers and counts are provided by table_store.hpp.
6932
6933
}  // namespace ada::idna
6934
#endif  // ADA_IDNA_IDENTIFIER_TABLES_H
6935
/* end file src/id_tables.cpp */
6936
6937
namespace ada::idna {
6938
0
constexpr bool is_ascii_letter(char32_t c) noexcept {
6939
0
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
6940
0
}
6941
6942
0
constexpr bool is_ascii_letter_or_digit(char32_t c) noexcept {
6943
0
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
6944
0
         (c >= '0' && c <= '9');
6945
0
}
6946
6947
0
bool valid_name_code_point(char32_t code_point, bool first) {
6948
  // https://tc39.es/ecma262/#prod-IdentifierStart
6949
6950
  // Fast paths (no table needed)
6951
0
  if (first && (code_point == U'$' || code_point == U'_' ||
6952
0
                is_ascii_letter(code_point))) {
6953
0
    return true;
6954
0
  }
6955
0
  if (!first && (code_point == U'$' || is_ascii_letter_or_digit(code_point))) {
6956
0
    return true;
6957
0
  }
6958
6959
  // Minimal error handling for invalid code point
6960
0
  if (code_point > 0x10FFFF) {
6961
0
    return false;
6962
0
  }
6963
0
  if (code_point >= 0xD800 && code_point <= 0xDFFF) {
6964
0
    return false;
6965
0
  }
6966
6967
0
  if (!ensure_tables() || id_start == nullptr || id_continue == nullptr) {
6968
0
    return false;
6969
0
  }
6970
6971
  // Slow path: binary search through the appropriate Unicode range table.
6972
  // Each entry is a [low, high] inclusive range.
6973
0
  const std::span<const uint32_t[2]> ranges =
6974
0
      first ? std::span<const uint32_t[2]>{ada::idna::id_start,
6975
0
                                           ada::idna::id_start_count}
6976
0
            : std::span<const uint32_t[2]>{ada::idna::id_continue,
6977
0
                                           ada::idna::id_continue_count};
6978
6979
0
  const auto iter = std::ranges::lower_bound(
6980
0
      ranges, code_point, {},
6981
0
      [](const auto& range) { return range[1]; });  // project to range-high
6982
6983
0
  return iter != ranges.end() && code_point >= (*iter)[0];
6984
0
}
6985
}  // namespace ada::idna
6986
/* end file src/identifier.cpp */
6987
/* end file src/idna.cpp */
6988
/* end file src/ada_idna.cpp */
6989
ADA_POP_DISABLE_WARNINGS
6990
6991
#include <algorithm>
6992
#include <array>
6993
#include <cstdint>
6994
#include <cstring>
6995
#include <iterator>
6996
#include <optional>
6997
#include <string>
6998
#include <string_view>
6999
#include <utility>
7000
#if ADA_SSSE3
7001
#include <tmmintrin.h>
7002
#elif ADA_NEON
7003
#include <arm_neon.h>
7004
#elif ADA_SSE2
7005
#include <emmintrin.h>
7006
#elif ADA_LSX
7007
#include <lsxintrin.h>
7008
#elif ADA_RVV
7009
#include <riscv_vector.h>
7010
#endif
7011
7012
#include <ranges>
7013
7014
namespace ada::unicode {
7015
7016
2.07k
constexpr bool is_tabs_or_newline(char c) noexcept {
7017
2.07k
  return c == '\r' || c == '\n' || c == '\t';
7018
2.07k
}
7019
7020
10.0k
constexpr uint64_t broadcast(uint8_t v) noexcept {
7021
10.0k
  return 0x101010101010101ull * v;
7022
10.0k
}
7023
7024
3.33k
constexpr bool to_lower_ascii(char* input, size_t length) noexcept {
7025
3.33k
  uint64_t broadcast_80 = broadcast(0x80);
7026
3.33k
  uint64_t broadcast_Ap = broadcast(128 - 'A');
7027
3.33k
  uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
7028
3.33k
  uint64_t non_ascii = 0;
7029
3.33k
  size_t i = 0;
7030
7031
4.44k
  for (; i + 7 < length; i += 8) {
7032
1.11k
    uint64_t word{};
7033
1.11k
    memcpy(&word, input + i, sizeof(word));
7034
1.11k
    non_ascii |= (word & broadcast_80);
7035
1.11k
    word ^=
7036
1.11k
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
7037
1.11k
    memcpy(input + i, &word, sizeof(word));
7038
1.11k
  }
7039
3.33k
  if (i < length) {
7040
454
    uint64_t word{};
7041
454
    memcpy(&word, input + i, length - i);
7042
454
    non_ascii |= (word & broadcast_80);
7043
454
    word ^=
7044
454
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
7045
454
    memcpy(input + i, &word, length - i);
7046
454
  }
7047
3.33k
  return non_ascii == 0;
7048
3.33k
}
7049
#if ADA_SSSE3
7050
ada_really_inline bool has_tabs_or_newline(
7051
    std::string_view user_input) noexcept {
7052
  // first check for short strings in which case we do it naively.
7053
  if (user_input.size() < 16) {  // slow path
7054
    return std::ranges::any_of(user_input, is_tabs_or_newline);
7055
  }
7056
  // fast path for long strings (expected to be common)
7057
  // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON)
7058
  size_t i = 0;
7059
  // Lookup table where positions 9, 10, 13 contain their own values
7060
  // Everything else is set to 1 so it won't match
7061
  const __m128i rnt =
7062
      _mm_setr_epi8(1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, 13, 0, 0);
7063
  __m128i running = _mm_setzero_si128();
7064
  for (; i + 15 < user_input.size(); i += 16) {
7065
    __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
7066
    // Shuffle the lookup table using input bytes as indices
7067
    __m128i shuffled = _mm_shuffle_epi8(rnt, word);
7068
    // Compare: if shuffled value matches input, we found \t, \n, or \r
7069
    __m128i matches = _mm_cmpeq_epi8(shuffled, word);
7070
    running = _mm_or_si128(running, matches);
7071
  }
7072
  if (i < user_input.size()) {
7073
    __m128i word = _mm_loadu_si128(
7074
        (const __m128i*)(user_input.data() + user_input.length() - 16));
7075
    __m128i shuffled = _mm_shuffle_epi8(rnt, word);
7076
    __m128i matches = _mm_cmpeq_epi8(shuffled, word);
7077
    running = _mm_or_si128(running, matches);
7078
  }
7079
  return _mm_movemask_epi8(running) != 0;
7080
}
7081
#elif ADA_NEON
7082
ada_really_inline bool has_tabs_or_newline(
7083
    std::string_view user_input) noexcept {
7084
  // first check for short strings in which case we do it naively.
7085
  if (user_input.size() < 16) {  // slow path
7086
    return std::ranges::any_of(user_input, is_tabs_or_newline);
7087
  }
7088
  // fast path for long strings (expected to be common)
7089
  size_t i = 0;
7090
  /**
7091
   * The fastest way to check for `\t` (==9), '\n'(== 10) and `\r` (==13) relies
7092
   * on table lookup instruction. We notice that these are all unique numbers
7093
   * between 0..15. Let's prepare a special register, where we put '\t' in the
7094
   * 9th position, '\n' - 10th and '\r' - 13th. Then we shuffle this register by
7095
   * input register. If the input had `\t` in position X then this shuffled
7096
   * register will also have '\t' in that position. Comparing input with this
7097
   * shuffled register will mark us all interesting characters in the input.
7098
   *
7099
   * credit for algorithmic idea: @aqrit, credit for description:
7100
   * @DenisYaroshevskiy
7101
   */
7102
  static uint8_t rnt_array[16] = {1, 0, 0,  0, 0, 0,  0, 0,
7103
                                  0, 9, 10, 0, 0, 13, 0, 0};
7104
  const uint8x16_t rnt = vld1q_u8(rnt_array);
7105
  // m['0xd', '0xa', '0x9']
7106
  uint8x16_t running{0};
7107
  for (; i + 15 < user_input.size(); i += 16) {
7108
    uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);
7109
7110
    running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
7111
  }
7112
  if (i < user_input.size()) {
7113
    uint8x16_t word =
7114
        vld1q_u8((const uint8_t*)user_input.data() + user_input.length() - 16);
7115
    running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
7116
  }
7117
  // `running` accumulates comparison results, so every lane is 0x00 or 0xFF:
7118
  // narrowing to four bits per lane and testing against zero is cheaper than a
7119
  // horizontal maximum. The double compare is faster (no GPR transfer) but
7120
  // incorrect if flush-to-zero is enabled; ADA_NEON_SAFE_ZERO_CHECK uses an
7121
  // integer compare instead.
7122
  uint8x8_t narrowed = vshrn_n_u16(vreinterpretq_u16_u8(running), 4);
7123
#if ADA_NEON_SAFE_ZERO_CHECK
7124
  return vget_lane_u64(vreinterpret_u64_u8(narrowed), 0) != 0;
7125
#else
7126
  return vdupd_lane_f64(vreinterpret_f64_u8(narrowed), 0) != 0.0;
7127
#endif
7128
}
7129
#elif ADA_SSE2
7130
ada_really_inline bool has_tabs_or_newline(
7131
6.66k
    std::string_view user_input) noexcept {
7132
  // first check for short strings in which case we do it naively.
7133
6.66k
  if (user_input.size() < 16) {  // slow path
7134
6.25k
    return std::ranges::any_of(user_input, is_tabs_or_newline);
7135
6.25k
  }
7136
  // fast path for long strings (expected to be common)
7137
414
  size_t i = 0;
7138
414
  const __m128i mask1 = _mm_set1_epi8('\r');
7139
414
  const __m128i mask2 = _mm_set1_epi8('\n');
7140
414
  const __m128i mask3 = _mm_set1_epi8('\t');
7141
  // If we supported SSSE3, we could use the algorithm that we use for NEON.
7142
414
  __m128i running{0};
7143
1.44k
  for (; i + 15 < user_input.size(); i += 16) {
7144
1.02k
    __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
7145
1.02k
    running = _mm_or_si128(
7146
1.02k
        _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
7147
1.02k
                                           _mm_cmpeq_epi8(word, mask2))),
7148
1.02k
        _mm_cmpeq_epi8(word, mask3));
7149
1.02k
  }
7150
414
  if (i < user_input.size()) {
7151
230
    __m128i word = _mm_loadu_si128(
7152
230
        (const __m128i*)(user_input.data() + user_input.length() - 16));
7153
230
    running = _mm_or_si128(
7154
230
        _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
7155
230
                                           _mm_cmpeq_epi8(word, mask2))),
7156
230
        _mm_cmpeq_epi8(word, mask3));
7157
230
  }
7158
414
  return _mm_movemask_epi8(running) != 0;
7159
6.66k
}
7160
#elif ADA_LSX
7161
ada_really_inline bool has_tabs_or_newline(
7162
    std::string_view user_input) noexcept {
7163
  // first check for short strings in which case we do it naively.
7164
  if (user_input.size() < 16) {  // slow path
7165
    return std::ranges::any_of(user_input, is_tabs_or_newline);
7166
  }
7167
  // fast path for long strings (expected to be common)
7168
  size_t i = 0;
7169
  const __m128i mask1 = __lsx_vrepli_b('\r');
7170
  const __m128i mask2 = __lsx_vrepli_b('\n');
7171
  const __m128i mask3 = __lsx_vrepli_b('\t');
7172
  // If we supported SSSE3, we could use the algorithm that we use for NEON.
7173
  __m128i running{0};
7174
  for (; i + 15 < user_input.size(); i += 16) {
7175
    __m128i word = __lsx_vld((const __m128i*)(user_input.data() + i), 0);
7176
    running = __lsx_vor_v(
7177
        __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1),
7178
                                         __lsx_vseq_b(word, mask2))),
7179
        __lsx_vseq_b(word, mask3));
7180
  }
7181
  if (i < user_input.size()) {
7182
    __m128i word = __lsx_vld(
7183
        (const __m128i*)(user_input.data() + user_input.length() - 16), 0);
7184
    running = __lsx_vor_v(
7185
        __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1),
7186
                                         __lsx_vseq_b(word, mask2))),
7187
        __lsx_vseq_b(word, mask3));
7188
  }
7189
  if (__lsx_bz_v(running)) return false;
7190
  return true;
7191
}
7192
#elif ADA_RVV
7193
ada_really_inline bool has_tabs_or_newline(
7194
    std::string_view user_input) noexcept {
7195
  uint8_t* src = (uint8_t*)user_input.data();
7196
  for (size_t vl, n = user_input.size(); n > 0; n -= vl, src += vl) {
7197
    vl = __riscv_vsetvl_e8m1(n);
7198
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
7199
    vbool8_t m1 = __riscv_vmseq(v, '\r', vl);
7200
    vbool8_t m2 = __riscv_vmseq(v, '\n', vl);
7201
    vbool8_t m3 = __riscv_vmseq(v, '\t', vl);
7202
    vbool8_t m = __riscv_vmor(__riscv_vmor(m1, m2, vl), m3, vl);
7203
    long idx = __riscv_vfirst(m, vl);
7204
    if (idx >= 0) return true;
7205
  }
7206
  return false;
7207
}
7208
#else
7209
ada_really_inline bool has_tabs_or_newline(
7210
    std::string_view user_input) noexcept {
7211
  auto has_zero_byte = [](uint64_t v) {
7212
    return ((v - 0x0101010101010101) & ~(v) & 0x8080808080808080);
7213
  };
7214
  size_t i = 0;
7215
  uint64_t mask1 = broadcast('\r');
7216
  uint64_t mask2 = broadcast('\n');
7217
  uint64_t mask3 = broadcast('\t');
7218
  uint64_t running{0};
7219
  for (; i + 7 < user_input.size(); i += 8) {
7220
    uint64_t word{};
7221
    memcpy(&word, user_input.data() + i, sizeof(word));
7222
    uint64_t xor1 = word ^ mask1;
7223
    uint64_t xor2 = word ^ mask2;
7224
    uint64_t xor3 = word ^ mask3;
7225
    running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
7226
  }
7227
  if (i < user_input.size()) {
7228
    uint64_t word{};
7229
    memcpy(&word, user_input.data() + i, user_input.size() - i);
7230
    uint64_t xor1 = word ^ mask1;
7231
    uint64_t xor2 = word ^ mask2;
7232
    uint64_t xor3 = word ^ mask3;
7233
    running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
7234
  }
7235
  return running;
7236
}
7237
#endif
7238
7239
// A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR,
7240
// U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>),
7241
// U+003F (?), U+0040 (@), U+005B ([), U+005C (\), U+005D (]), U+005E (^), or
7242
// U+007C (|).
7243
constexpr static std::array<uint8_t, 256> is_forbidden_host_code_point_table =
7244
    []() consteval {
7245
      std::array<uint8_t, 256> result{};
7246
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
7247
                        '>', '?', '@', '[', '\\', ']', '^', '|'}) {
7248
        result[c] = true;
7249
      }
7250
      return result;
7251
    }();
7252
7253
ada_really_inline constexpr bool is_forbidden_host_code_point(
7254
10.1k
    const char c) noexcept {
7255
10.1k
  return is_forbidden_host_code_point_table[uint8_t(c)];
7256
10.1k
}
7257
7258
constexpr static std::array<uint8_t, 256> is_forbidden_domain_code_point_table =
7259
    []() consteval {
7260
      std::array<uint8_t, 256> result{};
7261
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
7262
                        '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
7263
        result[c] = true;
7264
      }
7265
      for (uint8_t c = 0; c <= 32; c++) {
7266
        result[c] = true;
7267
      }
7268
      for (size_t c = 127; c < 256; c++) {
7269
        result[c] = true;
7270
      }
7271
      return result;
7272
    }();
7273
7274
static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
7275
7276
ada_really_inline constexpr bool is_forbidden_domain_code_point(
7277
10.1k
    const char c) noexcept {
7278
10.1k
  return is_forbidden_domain_code_point_table[uint8_t(c)];
7279
10.1k
}
7280
7281
ada_really_inline constexpr bool contains_forbidden_domain_code_point(
7282
4.78k
    const char* input, size_t length) noexcept {
7283
4.78k
  size_t i = 0;
7284
4.78k
  uint8_t accumulator{};
7285
13.4k
  for (; i + 4 <= length; i += 4) {
7286
8.66k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
7287
8.66k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])];
7288
8.66k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])];
7289
8.66k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])];
7290
8.66k
  }
7291
7.72k
  for (; i < length; i++) {
7292
2.93k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
7293
2.93k
  }
7294
4.78k
  return accumulator;
7295
4.78k
}
7296
7297
constexpr static std::array<uint8_t, 256>
7298
    is_forbidden_domain_code_point_table_or_upper = []() consteval {
7299
      std::array<uint8_t, 256> result{};
7300
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
7301
                        '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
7302
        result[c] = 1;
7303
      }
7304
      for (uint8_t c = 'A'; c <= 'Z'; c++) {
7305
        result[c] = 2;
7306
      }
7307
      for (uint8_t c = 0; c <= 32; c++) {
7308
        result[c] = 1;
7309
      }
7310
      for (size_t c = 127; c < 256; c++) {
7311
        result[c] = 1;
7312
      }
7313
      return result;
7314
    }();
7315
7316
ada_really_inline constexpr uint8_t
7317
contains_forbidden_domain_code_point_or_upper(const char* input,
7318
3.33k
                                              size_t length) noexcept {
7319
3.33k
  size_t i = 0;
7320
3.33k
  uint8_t accumulator{};
7321
5.66k
  for (; i + 4 <= length; i += 4) {
7322
2.33k
    accumulator |=
7323
2.33k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
7324
2.33k
    accumulator |=
7325
2.33k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])];
7326
2.33k
    accumulator |=
7327
2.33k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])];
7328
2.33k
    accumulator |=
7329
2.33k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])];
7330
2.33k
  }
7331
4.13k
  for (; i < length; i++) {
7332
804
    accumulator |=
7333
804
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
7334
804
  }
7335
3.33k
  return accumulator;
7336
3.33k
}
7337
7338
// std::isalnum(c) || c == '+' || c == '-' || c == '.') is true for
7339
constexpr static std::array<bool, 256> is_alnum_plus_table = []() consteval {
7340
  std::array<bool, 256> result{};
7341
  for (size_t c = 0; c < 256; c++) {
7342
    result[c] = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
7343
                (c >= 'A' && c <= 'Z') || c == '+' || c == '-' || c == '.';
7344
  }
7345
  return result;
7346
}();
7347
7348
10.1k
ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept {
7349
10.1k
  return is_alnum_plus_table[uint8_t(c)];
7350
  // A table is almost surely much faster than the
7351
  // following under most compilers: return
7352
  // return (std::isalnum(c) || c == '+' || c == '-' || c == '.');
7353
10.1k
}
7354
7355
11.4k
ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept {
7356
11.4k
  return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
7357
9.78k
         (c >= 'a' && c <= 'f');
7358
11.4k
}
7359
7360
10.1k
ada_really_inline constexpr bool is_ascii_digit(const char c) noexcept {
7361
  // An ASCII digit is a code point in the range U+0030 (0) to U+0039 (9),
7362
  // inclusive.
7363
10.1k
  return (c >= '0' && c <= '9');
7364
10.1k
}
7365
7366
10.1k
ada_really_inline constexpr bool is_ascii(const char32_t c) noexcept {
7367
  // If code point is between U+0000 and U+007F inclusive, then return true.
7368
10.1k
  return c <= 0x7F;
7369
10.1k
}
7370
7371
12.8k
ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept {
7372
12.8k
  return (unsigned char)c <= ' ';
7373
12.8k
}
7374
7375
ada_really_inline constexpr bool is_ascii_tab_or_newline(
7376
13.1k
    const char c) noexcept {
7377
13.1k
  return c == '\t' || c == '\n' || c == '\r';
7378
13.1k
}
7379
7380
constexpr std::string_view table_is_double_dot_path_segment[] = {
7381
    "..", "%2e.", ".%2e", "%2e%2e"};
7382
7383
ada_really_inline constexpr bool is_double_dot_path_segment(
7384
3.33k
    std::string_view input) noexcept {
7385
  // This will catch most cases:
7386
  // The length must be 2,4 or 6.
7387
  // We divide by two and require
7388
  // that the result be between 1 and 3 inclusively.
7389
3.33k
  uint64_t half_length = uint64_t(input.size()) / 2;
7390
3.33k
  if (half_length - 1 > 2) {
7391
3.09k
    return false;
7392
3.09k
  }
7393
  // We have a string of length 2, 4 or 6.
7394
  // We now check the first character:
7395
240
  if ((input[0] != '.') && (input[0] != '%')) {
7396
164
    return false;
7397
164
  }
7398
  // We are unlikely the get beyond this point.
7399
76
  int hash_value = (input.size() + (unsigned)(input[0])) & 3;
7400
76
  const std::string_view target = table_is_double_dot_path_segment[hash_value];
7401
76
  if (target.size() != input.size()) {
7402
43
    return false;
7403
43
  }
7404
  // We almost never get here.
7405
  // Optimizing the rest is relatively unimportant.
7406
33
  auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) {
7407
33
    uint16_t A, B;
7408
33
    memcpy(&A, a.data(), sizeof(A));
7409
33
    memcpy(&B, b.data(), sizeof(B));
7410
33
    return A == B;
7411
33
  };
7412
33
  if (!prefix_equal_unsafe(input, target)) {
7413
14
    return false;
7414
14
  }
7415
33
  for (size_t i = 2; i < input.size(); i++) {
7416
31
    char c = input[i];
7417
31
    if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) {
7418
17
      return false;
7419
17
    }
7420
31
  }
7421
2
  return true;
7422
  // The above code might be a bit better than the code below. Compilers
7423
  // are not stupid and may use the fact that these strings have length 2,4 and
7424
  // 6 and other tricks.
7425
  // return input == ".." ||
7426
  //  input == ".%2e" || input == ".%2E" ||
7427
  //  input == "%2e." || input == "%2E." ||
7428
  //  input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input ==
7429
  //  "%2e%2E";
7430
19
}
7431
7432
ada_really_inline constexpr bool is_single_dot_path_segment(
7433
3.33k
    std::string_view input) noexcept {
7434
3.33k
  return input == "." || input == "%2e" || input == "%2E";
7435
3.33k
}
7436
7437
10.1k
ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept {
7438
10.1k
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
7439
10.1k
}
7440
7441
constexpr static char hex_to_binary_table[] = {
7442
    0,  1,  2,  3,  4, 5, 6, 7, 8, 9, 0, 0,  0,  0,  0,  0,  0, 10, 11,
7443
    12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, 0,  0,
7444
    0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
7445
1.89k
unsigned constexpr convert_hex_to_binary(const char c) noexcept {
7446
1.89k
  return hex_to_binary_table[c - '0'];
7447
1.89k
}
7448
7449
3.33k
std::string percent_decode(const std::string_view input, size_t first_percent) {
7450
  // next line is for safety only, we expect users to avoid calling
7451
  // percent_decode when first_percent is outside the range.
7452
3.33k
  if (first_percent == std::string_view::npos) {
7453
0
    return std::string(input);
7454
0
  }
7455
7456
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7457
3.33k
  const char* const src = input.data();
7458
3.33k
  const char* const end = src + input.size();
7459
7460
  // Decoding never grows the string, so a single pre-sized buffer written via
7461
  // bulk memcpy of the plain runs (then shrunk to the final length) avoids the
7462
  // byte-at-a-time appends of the naive version.
7463
3.33k
  std::string out(input.size(), '\0');
7464
3.33k
  char* d = out.data();
7465
3.33k
  char* const d0 = d;
7466
7467
3.33k
  std::memcpy(d, src, first_percent);
7468
3.33k
  d += first_percent;
7469
7470
3.33k
  const char* p = src + first_percent;
7471
4.56k
  while (p < end) {
7472
1.22k
    if (*p == '%') {
7473
      // Decode runs of valid %XX tightly (common for nested/encoded URLs).
7474
979
      while (p + 2 < end && *p == '%') {
7475
797
        if (!is_ascii_hex_digit(p[1]) || !is_ascii_hex_digit(p[2])) {
7476
599
          break;
7477
599
        }
7478
198
        *d++ = static_cast<char>(convert_hex_to_binary(p[1]) * 16 +
7479
198
                                 convert_hex_to_binary(p[2]));
7480
198
        p += 3;
7481
198
      }
7482
781
      if (p < end && *p == '%') {
7483
        // Not a valid escape (too few chars left or bad hex): copy '%'
7484
        // literally and keep scanning after it.
7485
674
        *d++ = *p++;
7486
674
      }
7487
781
    } else {
7488
445
      const char* q = static_cast<const char*>(
7489
445
          std::memchr(p, '%', static_cast<size_t>(end - p)));
7490
445
      const char* run_end = q ? q : end;
7491
445
      const size_t n = static_cast<size_t>(run_end - p);
7492
445
      std::memcpy(d, p, n);
7493
445
      d += n;
7494
445
      p = run_end;
7495
445
    }
7496
1.22k
  }
7497
7498
3.33k
  out.resize(static_cast<size_t>(d - d0));
7499
3.33k
  return out;
7500
3.33k
}
7501
7502
// 0..15 for hex digits, 0xFF otherwise - validate and decode with two loads.
7503
constexpr static std::array<uint8_t, 256> unhex_table = []() consteval {
7504
  std::array<uint8_t, 256> t{};
7505
  for (size_t i = 0; i < 256; ++i) {
7506
    t[i] = 0xFF;
7507
  }
7508
  for (uint8_t i = 0; i < 10; ++i) {
7509
    t[static_cast<size_t>('0') + i] = i;
7510
  }
7511
  for (uint8_t i = 0; i < 6; ++i) {
7512
    t[static_cast<size_t>('A') + i] = static_cast<uint8_t>(10 + i);
7513
    t[static_cast<size_t>('a') + i] = static_cast<uint8_t>(10 + i);
7514
  }
7515
  return t;
7516
}();
7517
7518
0
std::string form_urlencoded_decode(const std::string_view input) {
7519
0
  const size_t len = input.size();
7520
0
  if (len == 0) [[unlikely]] {
7521
0
    return {};
7522
0
  }
7523
7524
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7525
0
  const char* const src = input.data();
7526
0
  const char* const end = src + len;
7527
0
  const char* p = src;
7528
7529
  // Advance over the untransformed prefix.
7530
0
  while (p < end && *p != '+' && *p != '%') {
7531
0
    ++p;
7532
0
  }
7533
0
  if (p == end) {
7534
0
    return std::string(input);
7535
0
  }
7536
7537
  // Output is always at most as long as the input: write into a single
7538
  // pre-sized buffer, then shrink to the final length.
7539
0
  std::string out(len, '\0');
7540
0
  char* d = out.data();
7541
0
  char* const d0 = d;
7542
7543
0
  const size_t prefix = static_cast<size_t>(p - src);
7544
0
  std::memcpy(d, src, prefix);
7545
0
  d += prefix;
7546
7547
0
  while (p < end) {
7548
0
    const char c = *p;
7549
0
    if (c == '+') {
7550
0
      *d++ = ' ';
7551
0
      ++p;
7552
0
    } else if (c == '%') {
7553
      // Decode runs of valid %XX tightly (common for nested URL query values).
7554
0
      while (p + 2 < end && *p == '%') {
7555
0
        const uint8_t hi = unhex_table[static_cast<uint8_t>(p[1])];
7556
0
        const uint8_t lo = unhex_table[static_cast<uint8_t>(p[2])];
7557
0
        if ((hi | lo) >= 16) {
7558
0
          break;
7559
0
        }
7560
0
        *d++ = static_cast<char>((hi << 4) | lo);
7561
0
        p += 3;
7562
0
      }
7563
0
      if (p < end && *p == '%') {
7564
        // Invalid escape: copy '%' literally and continue.
7565
0
        *d++ = *p++;
7566
0
      }
7567
0
    } else {
7568
      // Copy a plain run until the next '+' or '%'.
7569
0
      const char* start = p;
7570
0
      ++p;
7571
0
      while (p < end && *p != '+' && *p != '%') {
7572
0
        ++p;
7573
0
      }
7574
0
      const size_t n = static_cast<size_t>(p - start);
7575
0
      std::memcpy(d, start, n);
7576
0
      d += n;
7577
0
    }
7578
0
  }
7579
7580
0
  out.resize(static_cast<size_t>(d - d0));
7581
0
  return out;
7582
0
}
7583
7584
void percent_encode_suffix(const char* p, const char* end,
7585
                           const uint8_t character_set[], std::string& out);
7586
7587
std::string percent_encode(const std::string_view input,
7588
0
                           const uint8_t character_set[]) {
7589
0
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
7590
0
    return character_sets::bit_at(character_set, c);
7591
0
  });
7592
  // Optimization: Don't iterate if percent encode is not required
7593
0
  if (pointer == input.end()) {
7594
0
    return std::string(input);
7595
0
  }
7596
7597
0
  std::string result;
7598
0
  result.reserve(input.length());  // in the worst case, percent encoding might
7599
                                   // produce 3 characters.
7600
0
  result.append(input.substr(0, std::distance(input.begin(), pointer)));
7601
0
  if (static_cast<size_t>(input.end() - pointer) >= 48) {
7602
0
    percent_encode_suffix(&*pointer, input.data() + input.size(), character_set,
7603
0
                          result);
7604
0
  } else {
7605
0
    for (; pointer != input.end(); pointer++) {
7606
0
      if (character_sets::bit_at(character_set, *pointer)) {
7607
0
        result.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
7608
0
      } else {
7609
0
        result += *pointer;
7610
0
      }
7611
0
    }
7612
0
  }
7613
0
  return result;
7614
0
}
7615
7616
template <bool append>
7617
bool percent_encode(const std::string_view input, const uint8_t character_set[],
7618
0
                    std::string& out) {
7619
0
  ada_log("percent_encode ", input, " to output string while ",
7620
0
          append ? "appending" : "overwriting");
7621
0
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
7622
0
    return character_sets::bit_at(character_set, c);
7623
0
  });
Unexecuted instantiation: 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
Unexecuted instantiation: 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
7624
0
  ada_log("percent_encode done checking, moved to ",
7625
0
          std::distance(input.begin(), pointer));
7626
7627
  // Optimization: Don't iterate if percent encode is not required
7628
0
  if (pointer == input.end()) {
7629
0
    ada_log("percent_encode encoding not needed.");
7630
0
    return false;
7631
0
  }
7632
0
  if constexpr (!append) {
7633
0
    out.clear();
7634
0
  }
7635
0
  ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
7636
0
          " bytes");
7637
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7638
0
  out.append(input.data(), std::distance(input.begin(), pointer));
7639
0
  ada_log("percent_encode processing ", std::distance(pointer, input.end()),
7640
0
          " bytes");
7641
0
  for (; pointer != input.end(); pointer++) {
7642
0
    if (character_sets::bit_at(character_set, *pointer)) {
7643
0
      out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
7644
0
    } else {
7645
0
      out += *pointer;
7646
0
    }
7647
0
  }
7648
0
  return true;
7649
0
}
Unexecuted instantiation: 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> >&)
Unexecuted instantiation: 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> >&)
7650
7651
template bool percent_encode<true>(std::string_view input,
7652
                                   const uint8_t character_set[],
7653
                                   std::string& out);
7654
template bool percent_encode<false>(std::string_view input,
7655
                                    const uint8_t character_set[],
7656
                                    std::string& out);
7657
7658
bool to_ascii(std::optional<std::string>& out, const std::string_view plain,
7659
3.33k
              size_t first_percent) {
7660
3.33k
  std::string percent_decoded_buffer;
7661
3.33k
  std::string_view input = plain;
7662
3.33k
  if (first_percent != std::string_view::npos) {
7663
3.33k
    percent_decoded_buffer = unicode::percent_decode(plain, first_percent);
7664
3.33k
    input = percent_decoded_buffer;
7665
3.33k
  }
7666
  // input is a non-empty UTF-8 string, must be percent decoded
7667
3.33k
  std::string idna_ascii = ada::idna::to_ascii(input);
7668
3.33k
  if (idna_ascii.empty() || contains_forbidden_domain_code_point(
7669
2.14k
                                idna_ascii.data(), idna_ascii.size())) {
7670
2.14k
    return false;
7671
2.14k
  }
7672
1.18k
  out = std::move(idna_ascii);
7673
1.18k
  return true;
7674
3.33k
}
7675
7676
std::string percent_encode(const std::string_view input,
7677
0
                           const uint8_t character_set[], size_t index) {
7678
0
  std::string out;
7679
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
7680
0
  out.append(input.data(), index);
7681
0
  auto pointer = input.begin() + index;
7682
0
  if (static_cast<size_t>(input.end() - pointer) >= 48) {
7683
0
    percent_encode_suffix(&*pointer, input.data() + input.size(), character_set,
7684
0
                          out);
7685
0
  } else {
7686
0
    for (; pointer != input.end(); pointer++) {
7687
0
      if (character_sets::bit_at(character_set, *pointer)) {
7688
0
        out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
7689
0
      } else {
7690
0
        out += *pointer;
7691
0
      }
7692
0
    }
7693
0
  }
7694
0
  return out;
7695
0
}
7696
7697
}  // namespace ada::unicode
7698
/* end file src/unicode.cpp */
7699
#if !defined(ADA_PERCENT_ENCODE_SIMD_SEPARATE_TU)
7700
/* begin file src/unicode_percent_encode.cpp */
7701
#include <cstdint>
7702
7703
7704
7705
#include <cstring>
7706
#include <string>
7707
#if ADA_SSSE3
7708
#include <tmmintrin.h>
7709
#define ADA_UNICODE_SSSE3 1
7710
#elif ADA_NEON
7711
#include <arm_neon.h>
7712
#elif ADA_RVV
7713
#include <riscv_vector.h>
7714
#endif
7715
7716
// gcc/clang honor target("ssse3") on an SSE2 translation unit. clang-cl and
7717
// MSVC do not: they still compile the function as SSE2, then reject
7718
// always_inline _mm_shuffle_epi8. Same approach as parser.cpp.
7719
#if !ADA_UNICODE_SSSE3 && (defined(__x86_64__) || defined(__amd64__)) && \
7720
    defined(__GNUC__) && !defined(_MSC_VER)
7721
#include <tmmintrin.h>
7722
#define ADA_UNICODE_SSSE3 1
7723
#define ADA_UNICODE_NEED_SSSE3_TARGET 1
7724
#endif
7725
#ifndef ADA_UNICODE_SSSE3
7726
#define ADA_UNICODE_SSSE3 0
7727
#endif
7728
#ifdef ADA_UNICODE_NEED_SSSE3_TARGET
7729
// noinline: these functions must not be inlined into a caller that also
7730
// contains the CPU check. A target("ssse3") function can use SSSE3 in its
7731
// prologue, before any check inside it would run.
7732
#define ADA_UNICODE_SIMD __attribute__((target("ssse3"), noinline))
7733
#else
7734
#define ADA_UNICODE_SIMD ada_really_inline
7735
#endif
7736
7737
#ifdef ADA_REGULAR_VISUAL_STUDIO
7738
#include <intrin.h>
7739
#endif
7740
7741
namespace ada::unicode {
7742
namespace {
7743
7744
#if ADA_UNICODE_SSSE3 || ADA_NEON
7745
0
ada_really_inline int trailing_zeroes32(uint32_t input_num) noexcept {
7746
#ifdef ADA_REGULAR_VISUAL_STUDIO
7747
  unsigned long ret;
7748
  _BitScanForward(&ret, input_num);
7749
  return static_cast<int>(ret);
7750
#else
7751
0
  return __builtin_ctz(input_num);
7752
0
#endif
7753
0
}
7754
7755
// Append one window whose set bits mark bytes that need encoding.
7756
ada_really_inline void encode_mask_window(const char* p, uint32_t mask,
7757
0
                                          size_t width, std::string& out) {
7758
0
  uint64_t bits = mask;
7759
0
  size_t off = 0;
7760
0
  while (bits != 0) {
7761
0
    const int zero_run = trailing_zeroes32(static_cast<uint32_t>(bits));
7762
0
    if (zero_run != 0) {
7763
0
      out.append(p + off, static_cast<size_t>(zero_run));
7764
0
    }
7765
0
    off += static_cast<size_t>(zero_run);
7766
0
    out.append(character_sets::hex + uint8_t(p[off]) * 4, 3);
7767
0
    ++off;
7768
0
    bits >>= static_cast<unsigned>(zero_run + 1);
7769
0
  }
7770
0
  if (off < width) {
7771
0
    out.append(p + off, width - off);
7772
0
  }
7773
0
}
7774
#endif  // ADA_UNICODE_SSSE3 || ADA_NEON
7775
7776
ada_really_inline void percent_encode_to_scalar(const char* p, const char* end,
7777
                                                const uint8_t character_set[],
7778
0
                                                std::string& out) {
7779
0
  for (; p != end; ++p) {
7780
0
    if (character_sets::bit_at(character_set, *p)) {
7781
0
      out.append(character_sets::hex + uint8_t(*p) * 4, 3);
7782
0
    } else {
7783
0
      out += *p;
7784
0
    }
7785
0
  }
7786
0
}
7787
7788
#if ADA_UNICODE_SSSE3
7789
// Classify 16 input bytes against the 32-byte character_set bitmap:
7790
// bit_at(cs, b) == cs[b >> 3] & (1 << (b & 7)). pshufb looks up the two
7791
// 16-byte halves of that bitmap; no per-call nibble table is built.
7792
struct ssse3_percent_tables {
7793
  __m128i cs_lo;
7794
  __m128i cs_hi;
7795
  __m128i pow2;
7796
  __m128i mask_0f;
7797
  __m128i mask_07;
7798
  __m128i zero;
7799
};
7800
7801
ADA_UNICODE_SIMD ssse3_percent_tables
7802
0
load_ssse3_percent_tables(const uint8_t character_set[]) noexcept {
7803
0
  ssse3_percent_tables t{};
7804
0
  t.cs_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(character_set));
7805
0
  t.cs_hi =
7806
0
      _mm_loadu_si128(reinterpret_cast<const __m128i*>(character_set + 16));
7807
  // 1 << (0..7), duplicated so pshufb(index & 7) works for every lane.
7808
0
  t.pow2 =
7809
0
      _mm_setr_epi8(1, 2, 4, 8, 16, 32, 64, -128, 1, 2, 4, 8, 16, 32, 64, -128);
7810
0
  t.mask_0f = _mm_set1_epi8(0x0F);
7811
0
  t.mask_07 = _mm_set1_epi8(0x07);
7812
0
  t.zero = _mm_setzero_si128();
7813
0
  return t;
7814
0
}
7815
7816
ADA_UNICODE_SIMD int ssse3_percent_mask(
7817
0
    __m128i word, const ssse3_percent_tables& tables) noexcept {
7818
0
  const __m128i idx = _mm_and_si128(_mm_srli_epi16(word, 3), tables.mask_0f);
7819
0
  const __m128i lo = _mm_shuffle_epi8(tables.cs_lo, idx);
7820
0
  const __m128i hi = _mm_shuffle_epi8(tables.cs_hi, idx);
7821
  // Bytes 0x80-0xFF are signed-negative; select the high half of the bitmap.
7822
0
  const __m128i high_byte = _mm_cmpgt_epi8(tables.zero, word);
7823
0
  const __m128i cs_byte = _mm_or_si128(_mm_and_si128(hi, high_byte),
7824
0
                                       _mm_andnot_si128(high_byte, lo));
7825
0
  const __m128i bits =
7826
0
      _mm_shuffle_epi8(tables.pow2, _mm_and_si128(word, tables.mask_07));
7827
0
  const __m128i hits = _mm_and_si128(cs_byte, bits);
7828
0
  return _mm_movemask_epi8(_mm_cmpeq_epi8(hits, tables.zero)) ^ 0xFFFF;
7829
0
}
7830
7831
ADA_UNICODE_SIMD void percent_encode_to_ssse3(
7832
    const char* p, const char* end, const uint8_t character_set[],
7833
0
    const ssse3_percent_tables& tables, std::string& out) {
7834
  // Pair 16-byte windows so a fully clean 32-byte run is one append.
7835
0
  while (p + 32 <= end) {
7836
0
    const __m128i word0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p));
7837
0
    const __m128i word1 =
7838
0
        _mm_loadu_si128(reinterpret_cast<const __m128i*>(p + 16));
7839
0
    const int mask0 = ssse3_percent_mask(word0, tables);
7840
0
    const int mask1 = ssse3_percent_mask(word1, tables);
7841
0
    if ((mask0 | mask1) == 0) {
7842
0
      out.append(p, 32);
7843
0
    } else {
7844
0
      if (mask0 == 0) {
7845
0
        out.append(p, 16);
7846
0
      } else {
7847
0
        encode_mask_window(p, static_cast<uint32_t>(mask0), 16, out);
7848
0
      }
7849
0
      if (mask1 == 0) {
7850
0
        out.append(p + 16, 16);
7851
0
      } else {
7852
0
        encode_mask_window(p + 16, static_cast<uint32_t>(mask1), 16, out);
7853
0
      }
7854
0
    }
7855
0
    p += 32;
7856
0
  }
7857
0
  if (p + 16 <= end) {
7858
0
    const __m128i word = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p));
7859
0
    const int mask = ssse3_percent_mask(word, tables);
7860
0
    if (mask == 0) {
7861
0
      out.append(p, 16);
7862
0
    } else {
7863
0
      encode_mask_window(p, static_cast<uint32_t>(mask), 16, out);
7864
0
    }
7865
0
    p += 16;
7866
0
  }
7867
0
  percent_encode_to_scalar(p, end, character_set, out);
7868
0
}
7869
#endif  // ADA_UNICODE_SSSE3
7870
7871
#if ADA_NEON
7872
ada_really_inline uint8x16x2_t
7873
load_neon_percent_table(const uint8_t character_set[]) noexcept {
7874
  uint8x16x2_t table{};
7875
  table.val[0] = vld1q_u8(character_set);
7876
  table.val[1] = vld1q_u8(character_set + 16);
7877
  return table;
7878
}
7879
7880
ada_really_inline uint8x16_t neon_percent_hits(uint8x16_t word,
7881
                                               uint8x16x2_t table) noexcept {
7882
  const uint8x16_t cs_bytes = vqtbl2q_u8(table, vshrq_n_u8(word, 3));
7883
  const uint8x16_t bit_mask = vshlq_u8(
7884
      vdupq_n_u8(1), vreinterpretq_s8_u8(vandq_u8(word, vdupq_n_u8(7))));
7885
  return vandq_u8(cs_bytes, bit_mask);
7886
}
7887
7888
ada_really_inline uint32_t neon_percent_mask(uint8x16_t hits) noexcept {
7889
  const uint8x16_t cmp = vcgtq_u8(hits, vdupq_n_u8(0));
7890
  const uint8x16_t bit = {1, 2, 4, 8, 16, 32, 64, 128,
7891
                          1, 2, 4, 8, 16, 32, 64, 128};
7892
  const uint8x16_t masked = vandq_u8(cmp, bit);
7893
  return static_cast<uint32_t>(vaddv_u8(vget_low_u8(masked))) |
7894
         (static_cast<uint32_t>(vaddv_u8(vget_high_u8(masked))) << 8);
7895
}
7896
7897
ada_really_inline void percent_encode_to_neon(const char* p, const char* end,
7898
                                              const uint8_t character_set[],
7899
                                              uint8x16x2_t table,
7900
                                              std::string& out) {
7901
  while (p + 32 <= end) {
7902
    const uint8x16_t hits0 =
7903
        neon_percent_hits(vld1q_u8(reinterpret_cast<const uint8_t*>(p)), table);
7904
    const uint8x16_t hits1 = neon_percent_hits(
7905
        vld1q_u8(reinterpret_cast<const uint8_t*>(p + 16)), table);
7906
    const bool clean0 = vmaxvq_u32(vreinterpretq_u32_u8(hits0)) == 0;
7907
    const bool clean1 = vmaxvq_u32(vreinterpretq_u32_u8(hits1)) == 0;
7908
    if (clean0 && clean1) {
7909
      out.append(p, 32);
7910
    } else {
7911
      if (clean0) {
7912
        out.append(p, 16);
7913
      } else {
7914
        encode_mask_window(p, neon_percent_mask(hits0), 16, out);
7915
      }
7916
      if (clean1) {
7917
        out.append(p + 16, 16);
7918
      } else {
7919
        encode_mask_window(p + 16, neon_percent_mask(hits1), 16, out);
7920
      }
7921
    }
7922
    p += 32;
7923
  }
7924
  if (p + 16 <= end) {
7925
    const uint8x16_t hits =
7926
        neon_percent_hits(vld1q_u8(reinterpret_cast<const uint8_t*>(p)), table);
7927
    if (vmaxvq_u32(vreinterpretq_u32_u8(hits)) == 0) {
7928
      out.append(p, 16);
7929
    } else {
7930
      encode_mask_window(p, neon_percent_mask(hits), 16, out);
7931
    }
7932
    p += 16;
7933
  }
7934
  percent_encode_to_scalar(p, end, character_set, out);
7935
}
7936
#endif  // ADA_NEON
7937
7938
#if ADA_RVV
7939
ada_really_inline void percent_encode_to_rvv(const char* p, const char* end,
7940
                                             const uint8_t character_set[],
7941
                                             std::string& out) {
7942
  while (p < end) {
7943
    const size_t remaining = static_cast<size_t>(end - p);
7944
    const size_t vl = __riscv_vsetvl_e8m1(remaining);
7945
    const vuint8m1_t word =
7946
        __riscv_vle8_v_u8m1(reinterpret_cast<const uint8_t*>(p), vl);
7947
    const vuint8m1_t cs_bytes =
7948
        __riscv_vluxei8(character_set, __riscv_vsrl(word, 3, vl), vl);
7949
    const vuint8m1_t bit_mask = __riscv_vsll(__riscv_vmv_v_x_u8m1(1, vl),
7950
                                             __riscv_vand(word, 7, vl), vl);
7951
    const long idx = __riscv_vfirst(
7952
        __riscv_vmsne(__riscv_vand(cs_bytes, bit_mask, vl), 0, vl), vl);
7953
    if (idx < 0) {
7954
      out.append(p, vl);
7955
      p += vl;
7956
      continue;
7957
    }
7958
    if (idx > 0) {
7959
      out.append(p, static_cast<size_t>(idx));
7960
      p += idx;
7961
    }
7962
    out.append(character_sets::hex + uint8_t(*p) * 4, 3);
7963
    ++p;
7964
  }
7965
}
7966
#endif  // ADA_RVV
7967
7968
#if ADA_UNICODE_SSSE3 || ADA_NEON || ADA_RVV
7969
// Setter and existing percent_encode benches are 2-44 bytes. Table setup
7970
// plus mask walking costs more instructions than bit_at on those inputs
7971
// (especially dense USERINFO). SIMD pays off on the remaining suffix.
7972
static constexpr size_t kPercentEncodeSimdMin = 48;
7973
7974
void percent_encode_to_wide(const char* p, const char* end,
7975
0
                            const uint8_t character_set[], std::string& out) {
7976
  // Worst case every byte becomes %XX. Avoids realloc while walking windows.
7977
0
  out.reserve(out.size() + static_cast<size_t>(end - p) * 3);
7978
0
#if ADA_UNICODE_SSSE3
7979
0
  const ssse3_percent_tables tables = load_ssse3_percent_tables(character_set);
7980
0
  percent_encode_to_ssse3(p, end, character_set, tables, out);
7981
#elif ADA_NEON
7982
  percent_encode_to_neon(p, end, character_set,
7983
                         load_neon_percent_table(character_set), out);
7984
#elif ADA_RVV
7985
  percent_encode_to_rvv(p, end, character_set, out);
7986
#endif
7987
0
}
7988
#endif
7989
7990
}  // namespace
7991
7992
void percent_encode_suffix(const char* p, const char* end,
7993
0
                           const uint8_t character_set[], std::string& out) {
7994
0
#if ADA_UNICODE_SSSE3 || ADA_NEON || ADA_RVV
7995
0
#ifdef ADA_UNICODE_NEED_SSSE3_TARGET
7996
0
  static const bool ssse3_supported = __builtin_cpu_supports("ssse3") != 0;
7997
0
  const bool use_wide = ssse3_supported;
7998
#else
7999
  const bool use_wide = true;
8000
#endif
8001
0
  if (use_wide && static_cast<size_t>(end - p) >= kPercentEncodeSimdMin) {
8002
0
    percent_encode_to_wide(p, end, character_set, out);
8003
0
    return;
8004
0
  }
8005
0
#endif
8006
0
  percent_encode_to_scalar(p, end, character_set, out);
8007
0
}
8008
8009
}  // namespace ada::unicode
8010
/* end file src/unicode_percent_encode.cpp */
8011
#endif
8012
/* begin file src/serializers.cpp */
8013
8014
#include <array>
8015
#include <cstdint>
8016
#include <cstring>
8017
#include <string>
8018
8019
namespace ada::serializers {
8020
namespace {
8021
8022
// Digit pair LUT for fast decimal write: index 0..99 -> two chars.
8023
0
constexpr std::array<char, 200> make_digit_pairs() noexcept {
8024
0
  std::array<char, 200> t{};
8025
0
  for (size_t i = 0; i < 100; ++i) {
8026
0
    t[i * 2] = static_cast<char>('0' + i / 10);
8027
0
    t[i * 2 + 1] = static_cast<char>('0' + i % 10);
8028
0
  }
8029
0
  return t;
8030
0
}
8031
8032
constexpr auto digit_pairs = make_digit_pairs();
8033
8034
0
ada_really_inline char* write_u8(char* p, uint8_t v) noexcept {
8035
0
  if (v < 10) {
8036
0
    *p++ = static_cast<char>('0' + v);
8037
0
  } else if (v < 100) {
8038
0
    std::memcpy(p, &digit_pairs[static_cast<size_t>(v) * 2], 2);
8039
0
    p += 2;
8040
0
  } else {
8041
0
    *p++ = static_cast<char>('0' + v / 100);
8042
0
    std::memcpy(p, &digit_pairs[static_cast<size_t>(v % 100) * 2], 2);
8043
0
    p += 2;
8044
0
  }
8045
0
  return p;
8046
0
}
8047
8048
0
ada_really_inline char* write_hex_u16(char* p, uint16_t v) noexcept {
8049
0
  static constexpr char kHex[] = "0123456789abcdef";
8050
0
  if (v >= 0x1000) {
8051
0
    *p++ = kHex[(v >> 12) & 0xf];
8052
0
    *p++ = kHex[(v >> 8) & 0xf];
8053
0
    *p++ = kHex[(v >> 4) & 0xf];
8054
0
    *p++ = kHex[v & 0xf];
8055
0
  } else if (v >= 0x100) {
8056
0
    *p++ = kHex[(v >> 8) & 0xf];
8057
0
    *p++ = kHex[(v >> 4) & 0xf];
8058
0
    *p++ = kHex[v & 0xf];
8059
0
  } else if (v >= 0x10) {
8060
0
    *p++ = kHex[(v >> 4) & 0xf];
8061
0
    *p++ = kHex[v & 0xf];
8062
0
  } else {
8063
0
    *p++ = kHex[v & 0xf];
8064
0
  }
8065
0
  return p;
8066
0
}
8067
8068
}  // namespace
8069
8070
void find_longest_sequence_of_ipv6_pieces(
8071
    const std::array<uint16_t, 8>& address, size_t& compress,
8072
0
    size_t& compress_length) noexcept {
8073
0
  compress = 0;
8074
0
  compress_length = 0;
8075
0
  size_t i = 0;
8076
0
  while (i < 8) {
8077
0
    if (address[i] != 0) {
8078
0
      ++i;
8079
0
      continue;
8080
0
    }
8081
0
    size_t next = i + 1;
8082
0
    while (next < 8 && address[next] == 0) {
8083
0
      ++next;
8084
0
    }
8085
0
    const size_t count = next - i;
8086
0
    if (count > compress_length) {
8087
0
      compress_length = count;
8088
0
      compress = i;
8089
0
    }
8090
0
    i = next;
8091
0
  }
8092
0
}
8093
8094
0
std::string ipv6(const std::array<uint16_t, 8>& address) {
8095
0
  size_t compress = 0;
8096
0
  size_t compress_length = 0;
8097
0
  find_longest_sequence_of_ipv6_pieces(address, compress, compress_length);
8098
8099
  // Skip compression when the longest zero run is a single piece.
8100
0
  if (compress_length <= 1) {
8101
0
    compress = compress_length = 8;
8102
0
  }
8103
8104
  // Max: '[' + 8*4 hex + 7 ':' + ']' = 41
8105
0
  std::string output(4 * 8 + 7 + 2, '\0');
8106
0
  char* point = output.data();
8107
0
  *point++ = '[';
8108
0
  size_t piece_index = 0;
8109
0
  while (true) {
8110
0
    if (piece_index == compress) {
8111
0
      *point++ = ':';
8112
      // If we skip a value initially, we need to write '::'.
8113
0
      if (piece_index == 0) {
8114
0
        *point++ = ':';
8115
0
      }
8116
0
      piece_index += compress_length;
8117
0
      if (piece_index == 8) {
8118
0
        break;
8119
0
      }
8120
0
    }
8121
0
    point = write_hex_u16(point, address[piece_index]);
8122
0
    ++piece_index;
8123
0
    if (piece_index == 8) {
8124
0
      break;
8125
0
    }
8126
0
    *point++ = ':';
8127
0
  }
8128
0
  *point++ = ']';
8129
0
  output.resize(static_cast<size_t>(point - output.data()));
8130
0
  return output;
8131
0
}
8132
8133
0
std::string ipv4(const uint64_t address) {
8134
0
  std::string output(15, '\0');
8135
0
  char* point = output.data();
8136
0
  point = write_u8(point, static_cast<uint8_t>(address >> 24));
8137
0
  *point++ = '.';
8138
0
  point = write_u8(point, static_cast<uint8_t>(address >> 16));
8139
0
  *point++ = '.';
8140
0
  point = write_u8(point, static_cast<uint8_t>(address >> 8));
8141
0
  *point++ = '.';
8142
0
  point = write_u8(point, static_cast<uint8_t>(address));
8143
0
  output.resize(static_cast<size_t>(point - output.data()));
8144
0
  return output;
8145
0
}
8146
8147
}  // namespace ada::serializers
8148
/* end file src/serializers.cpp */
8149
/* begin file src/implementation.cpp */
8150
8151
#include <array>
8152
#include <atomic>
8153
#include <cstdint>
8154
#include <cstring>
8155
#include <limits>
8156
#include <optional>
8157
#include <string>
8158
#include <string_view>
8159
8160
8161
namespace ada {
8162
8163
static std::atomic<uint32_t> max_input_length_{
8164
    std::numeric_limits<uint32_t>::max()};
8165
8166
0
void set_max_input_length(uint32_t length) {
8167
0
  max_input_length_.store(length, std::memory_order_relaxed);
8168
0
}
8169
8170
0
uint32_t get_max_input_length() {
8171
0
  return max_input_length_.load(std::memory_order_relaxed);
8172
0
}
8173
8174
namespace {
8175
8176
constexpr std::array<uint8_t, 256> clean_http_host_byte = []() consteval {
8177
  std::array<uint8_t, 256> result{};
8178
  for (size_t i = 0; i < result.size(); ++i) {
8179
    const auto c = static_cast<uint8_t>(i);
8180
    result[i] =
8181
        static_cast<uint8_t>((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
8182
                             c == '-' || c == '.' || c == '_' || c == '~');
8183
  }
8184
  return result;
8185
}();
8186
8187
// SWAR: eight ASCII host bytes in [a-z0-9-._~] without 8 table lookups.
8188
// High bits must be clear first so the range subtracts cannot borrow
8189
// across bytes.
8190
// High-bit-cleared ASCII only. Subtracts cannot borrow across bytes because
8191
// each (hi|0x80) byte is >= 0x80 and each data byte is <= 0x7F. Do not use
8192
// has-zero (x-ones)&~x: a match followed by match^1 (e.g. "./" or "_^")
8193
// produces a false positive via borrow.
8194
ada_really_inline uint64_t swar_in_range(uint64_t w, uint8_t lo,
8195
0
                                         uint8_t hi) noexcept {
8196
0
  constexpr uint64_t k_ones = 0x0101010101010101ull;
8197
0
  constexpr uint64_t k_high = 0x8080808080808080ull;
8198
0
  const uint64_t ge_lo = (w | k_high) - (k_ones * lo);
8199
0
  const uint64_t le_hi = ((k_ones * hi) | k_high) - w;
8200
0
  return ge_lo & le_hi & k_high;
8201
0
}
8202
8203
ada_really_inline bool eight_clean_http_host_bytes(
8204
0
    const uint8_t* input) noexcept {
8205
0
  uint64_t w = 0;
8206
0
  std::memcpy(&w, input, 8);
8207
0
  constexpr uint64_t k_high = 0x8080808080808080ull;
8208
0
  if ((w & k_high) != 0) {
8209
0
    return false;
8210
0
  }
8211
0
  const uint64_t ok = swar_in_range(w, 'a', 'z') | swar_in_range(w, '0', '9') |
8212
0
                      swar_in_range(w, '-', '-') | swar_in_range(w, '.', '.') |
8213
0
                      swar_in_range(w, '_', '_') | swar_in_range(w, '~', '~');
8214
0
  return ok == k_high;
8215
0
}
8216
8217
// Minimal front end for the overwhelmingly common already-canonical HTTP(S)
8218
// case. It deliberately handles fewer inputs than
8219
// try_can_parse_absolute_fast: anything requiring normalization or detailed
8220
// host parsing falls through to that broader validator.
8221
#if defined(_MSC_VER) || \
8222
    (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
8223
constexpr bool k_can_parse_little_endian = true;
8224
#else
8225
constexpr bool k_can_parse_little_endian = false;
8226
#endif
8227
8228
0
std::optional<bool> try_can_parse_clean_http(std::string_view input) noexcept {
8229
0
  const auto* bytes = reinterpret_cast<const uint8_t*>(input.data());
8230
0
  const size_t length = input.size();
8231
0
  if (length < 7) {
8232
0
    return std::nullopt;
8233
0
  }
8234
8235
0
  size_t authority_start;
8236
0
  if constexpr (k_can_parse_little_endian) {
8237
0
    if (length >= 8) {
8238
0
      uint64_t first8 = 0;
8239
0
      std::memcpy(&first8, bytes, 8);
8240
0
      if (first8 == 0x2f2f3a7370747468ull) {  // "https://"
8241
0
        authority_start = 8;
8242
0
      } else if ((first8 & 0x00ffffffffffffffull) ==
8243
0
                 0x002f2f3a70747468ull) {  // "http://"
8244
0
        authority_start = 7;
8245
0
      } else {
8246
0
        return std::nullopt;
8247
0
      }
8248
0
    } else if (bytes[0] == 'h' && bytes[1] == 't' && bytes[2] == 't' &&
8249
0
               bytes[3] == 'p' && bytes[4] == ':' && bytes[5] == '/' &&
8250
0
               bytes[6] == '/') {
8251
0
      authority_start = 7;
8252
0
    } else {
8253
0
      return std::nullopt;
8254
0
    }
8255
  } else {
8256
    uint32_t first4{};
8257
    std::memcpy(&first4, bytes, 4);
8258
    if (first4 != 0x68747470u) {  // "http"
8259
      return std::nullopt;
8260
    }
8261
    if (length >= 8 && bytes[4] == 's' && bytes[5] == ':' && bytes[6] == '/' &&
8262
        bytes[7] == '/') {
8263
      authority_start = 8;
8264
    } else if (bytes[4] == ':' && bytes[5] == '/' && bytes[6] == '/') {
8265
      authority_start = 7;
8266
    } else {
8267
      return std::nullopt;
8268
    }
8269
  }
8270
8271
0
  if (authority_start >= length) {
8272
0
    return false;
8273
0
  }
8274
8275
0
  size_t cursor = authority_start;
8276
0
  while (cursor + 8 <= length && eight_clean_http_host_bytes(bytes + cursor)) {
8277
0
    cursor += 8;
8278
0
  }
8279
0
  while (cursor < length) {
8280
0
    const uint8_t c = bytes[cursor];
8281
0
    if (c == '/' || c == '?' || c == '#') {
8282
0
      break;
8283
0
    }
8284
0
    if (!clean_http_host_byte[c]) {
8285
0
      return std::nullopt;
8286
0
    }
8287
0
    ++cursor;
8288
0
  }
8289
8290
0
  const size_t host_length = cursor - authority_start;
8291
0
  if (host_length == 0) {
8292
    // Extra special-scheme slashes are normalization, not an empty host.
8293
0
    if (bytes[authority_start] == '/' || bytes[authority_start] == '\\') {
8294
0
      return std::nullopt;
8295
0
    }
8296
0
    return false;
8297
0
  }
8298
0
  if (host_length > 253 || bytes[cursor - 1] == '.') {
8299
0
    return std::nullopt;
8300
0
  }
8301
8302
0
  const std::string_view host(input.data() + authority_start, host_length);
8303
0
  if (checkers::last_label_may_be_a_number(host)) {
8304
0
    return std::nullopt;
8305
0
  }
8306
0
  if (host.find('x') != std::string_view::npos &&
8307
0
      host.find("xn-") != std::string_view::npos) {
8308
0
    return std::nullopt;
8309
0
  }
8310
8311
  // Once a special URL has a valid host, path/query/fragment bytes cannot make
8312
  // it structurally invalid: the full parser percent-encodes them as needed.
8313
0
  return true;
8314
0
}
8315
8316
// @private
8317
// Fast-path validator for can_parse.
8318
//
8319
// Validates absolute special (non-file) URLs without constructing any
8320
// url_aggregator object and without running the state machine.
8321
// Performs a single forward scan over the input bytes.
8322
//
8323
// Returns:
8324
//   true      -- URL is structurally valid
8325
//   false     -- URL is definitely invalid
8326
//   nullopt   -- edge case; fall through to the full parser
8327
//               (credentials, IDNA, IPv4/6, tabs/newlines, relative URLs, ...)
8328
std::optional<bool> try_can_parse_absolute_fast(
8329
0
    std::string_view input) noexcept {
8330
0
  const uint8_t* b = reinterpret_cast<const uint8_t*>(input.data());
8331
0
  size_t len = input.size();
8332
8333
  // -- Inline C0 whitespace trim (no allocation) --------------------------
8334
  // Note: \t (0x09), \n (0x0a), \r (0x0d) are all <= 0x20, so any
8335
  // leading/trailing tabs or newlines are correctly stripped here, matching
8336
  // the WHATWG spec's "remove leading/trailing C0 control and space" step.
8337
0
  while (len > 0 && b[0] <= 0x20) {
8338
0
    b++;
8339
0
    len--;
8340
0
  }
8341
0
  while (len > 0 && b[len - 1] <= 0x20) {
8342
0
    len--;
8343
0
  }
8344
0
  if (len == 0) return false;
8345
8346
  // -- Scheme detection -----------------------------------------------------
8347
  // Fast path for HTTP and HTTPS (covers ~90%+ of real-world URLs).
8348
  // Avoids the general scheme loop, buffer copy, and perfect hash lookup.
8349
  // We know HTTP and HTTPS are special non-file schemes, so no further
8350
  // scheme_type checks are needed on the fast path -- only `pos` matters.
8351
0
  size_t pos;
8352
8353
0
  if (len >= 7 && (b[0] | 0x20) == 'h' && (b[1] | 0x20) == 't' &&
8354
0
      (b[2] | 0x20) == 't' && (b[3] | 0x20) == 'p') {
8355
0
    if (b[4] == ':' && b[5] == '/' && b[6] == '/') {
8356
0
      pos = 7;
8357
0
      goto skip_extra_slashes;
8358
0
    }
8359
0
    if (len >= 8 && (b[4] | 0x20) == 's' && b[5] == ':' && b[6] == '/' &&
8360
0
        b[7] == '/') {
8361
0
      pos = 8;
8362
0
      goto skip_extra_slashes;
8363
0
    }
8364
    // Fall through: could be "httpe://", tabs in scheme, etc.
8365
0
  }
8366
8367
0
  {
8368
    // General scheme detection for ws, wss, ftp, and edge cases.
8369
0
    if (!checkers::is_alpha(static_cast<char>(b[0]))) return false;
8370
8371
    // Scan for ':' within the first 7 bytes. All special schemes are <= 5
8372
    // chars ("https"), so any URL whose first ':' is beyond byte 6 is either
8373
    // non-special or relative -- both require the full parser.
8374
0
    size_t colon_pos = 0;
8375
0
    for (size_t i = 1;; ++i) {
8376
0
      if (i >= 7 || i >= len) return std::nullopt;
8377
0
      const char c = static_cast<char>(b[i]);
8378
0
      if (c == ':') {
8379
0
        colon_pos = i;
8380
0
        break;
8381
0
      }
8382
      // Tabs/newlines in the scheme require the full parser to strip them.
8383
0
      if (c == '\t' || c == '\n' || c == '\r') return std::nullopt;
8384
0
      if (!unicode::is_alnum_plus(c)) return false;
8385
0
    }
8386
8387
    // Lowercase scheme bytes inline and classify via the existing perfect
8388
    // hash.
8389
0
    char scheme_buf[6];
8390
0
    scheme_buf[0] = static_cast<char>(b[0] | 0x20);
8391
0
    for (size_t i = 1; i < colon_pos; ++i)
8392
0
      scheme_buf[i] = static_cast<char>(b[i] | 0x20);
8393
8394
0
    const ada::scheme::type scheme_type =
8395
0
        ada::scheme::get_scheme_type({scheme_buf, colon_pos});
8396
8397
    // Only handle special, non-file schemes.
8398
0
    if (scheme_type == ada::scheme::NOT_SPECIAL) return std::nullopt;
8399
0
    if (scheme_type == ada::scheme::FILE) return std::nullopt;
8400
8401
    // Per WHATWG, special URLs don't require "//": "http:example.com" is valid
8402
    // (SPECIAL_AUTHORITY_IGNORE_SLASHES just skips leading slashes and
8403
    // proceeds to AUTHORITY).  Defer to the inline fallback for any input
8404
    // without "://".
8405
0
    pos = colon_pos + 1;
8406
0
    if (pos + 2 > len || b[pos] != '/' || b[pos + 1] != '/') {
8407
0
      return std::nullopt;
8408
0
    }
8409
0
    pos += 2;
8410
0
  }
8411
8412
0
skip_extra_slashes:
8413
  // SPECIAL_AUTHORITY_IGNORE_SLASHES: the full parser skips any additional
8414
  // leading '/' or '\' after the initial "//".  Mirror that here so we don't
8415
  // mis-identify the host as empty when there are extra slashes.
8416
0
  while (pos < len && (b[pos] == '/' || b[pos] == '\\')) {
8417
0
    ++pos;
8418
0
  }
8419
8420
  // Early IPv6 bail-out: if the authority starts with '[', it's an IPv6
8421
  // literal which requires the full parser.  Checking here avoids scanning
8422
  // the entire bracketed address only to bail out afterward.
8423
0
  if (pos < len && b[pos] == '[') return std::nullopt;
8424
8425
  // -- Merged authority + host scan ------------------------------------------
8426
  // A single forward pass over the authority bytes that simultaneously:
8427
  //   - finds the authority end and port colon
8428
  //   - validates host characters (forbidden domain code points)
8429
  //   - tracks IPv4 indicators (all-decimal-dots, last non-dot char)
8430
  //   - detects xn-- prefixes (IDNA punycode)
8431
  //   - detects tabs/newlines (which require the full parser to strip)
8432
  // This replaces 4 separate scans over the host bytes.
8433
0
  const size_t auth_start = pos;
8434
0
  size_t auth_end = pos;
8435
0
  size_t port_colon = SIZE_MAX;
8436
0
  bool all_dec_dots = true;
8437
8438
0
  for (; auth_end < len; ++auth_end) {
8439
0
    const uint8_t c = b[auth_end];
8440
8441
    // Non-ASCII -> needs IDNA processing -> full parser.
8442
0
    if (c >= 0x80) return std::nullopt;
8443
8444
    // Authority delimiters.
8445
0
    if (c == '/' || c == '?' || c == '#' || c == '\\') break;
8446
8447
    // Port separator.
8448
0
    if (c == ':') {
8449
0
      if (port_colon == SIZE_MAX) port_colon = auth_end;
8450
0
      continue;
8451
0
    }
8452
8453
    // Credentials or percent-encoding -> full parser.
8454
0
    if (c == '@' || c == '%') return std::nullopt;
8455
8456
    // Tabs/newlines anywhere in the authority require the full parser to
8457
    // strip them before validation.  Without this, a tab in the port (e.g.
8458
    // "http://host:8\t0/") would be mis-rejected by port validation.
8459
0
    if (c == '\t' || c == '\n' || c == '\r') return std::nullopt;
8460
8461
    // Skip remaining host-specific checks for port bytes.  Port digits are
8462
    // validated separately below, and no forbidden-domain-code-point check
8463
    // is needed on port characters.
8464
0
    if (port_colon != SIZE_MAX) continue;
8465
8466
    // -- Host byte validation (inlined) ------------------------------------
8467
    // Forbidden domain code points that are not already caught above:
8468
    //   C0 controls and space (0x00-0x20), DEL (0x7F), <, >, [, ], ^, |.
8469
    // At this stage, the input may still be userinfo or be normalized later
8470
    // (e.g., percent-encoded), so we do not reject here and defer to the
8471
    // parser. Characters already caught: >= 0x80 (non-ASCII), '/' '?' '#' '\\'
8472
    // (delimiters), ':' (port), '@' '%' (bail), '\t' '\n' '\r' (bail).
8473
0
    if (c <= 0x20 || c == 0x7F || c == '<' || c == '>' || c == '[' ||
8474
0
        c == ']' || c == '^' || c == '|') {
8475
0
      return std::nullopt;
8476
0
    }
8477
8478
    // Track whether host is all decimal digits and dots (potential IPv4).
8479
0
    if (c != '.' && (c < '0' || c > '9')) all_dec_dots = false;
8480
8481
    // Detect xn-- prefix inline (IDNA punycode -> needs full parser).
8482
    // Checking at every position mirrors the original behavior: any
8483
    // occurrence of "xn--" in the host (not just at label boundaries)
8484
    // triggers a bail-out to the full IDNA validator.
8485
0
    if ((c | 0x20) == 'x' && auth_end + 4 <= len &&
8486
0
        (b[auth_end + 1] | 0x20) == 'n' && b[auth_end + 2] == '-' &&
8487
0
        b[auth_end + 3] == '-') {
8488
0
      return std::nullopt;
8489
0
    }
8490
0
  }
8491
8492
0
  const size_t host_end = (port_colon != SIZE_MAX) ? port_colon : auth_end;
8493
8494
  // Empty host is invalid for special URLs.
8495
0
  if (auth_start == host_end) return false;
8496
8497
  // -- IPv4 handling ---------------------------------------------------------
8498
0
  const char* host_ptr = reinterpret_cast<const char*>(b + auth_start);
8499
0
  const size_t host_len = host_end - auth_start;
8500
8501
0
  if (all_dec_dots) {
8502
    // Host is all decimal digits and dots -> try the fast IPv4 parser.
8503
0
    if (checkers::try_parse_ipv4_fast({host_ptr, host_len}) !=
8504
0
        checkers::ipv4_fast_fail) {
8505
      // Valid decimal IPv4 host.  Do NOT return true yet: the port still
8506
      // needs to be validated below before we can declare the URL valid.
8507
0
      goto validate_port;
8508
0
    }
8509
    // Fast IPv4 parsing failed (e.g. host is ".", "..", "1.2.3.500").
8510
    // Such hosts may still be valid domain names; defer to the full parser.
8511
0
    return std::nullopt;
8512
0
  }
8513
8514
0
  if (checkers::last_label_may_be_a_number({host_ptr, host_len})) {
8515
0
    return std::nullopt;
8516
0
  }
8517
8518
  // -- Port validation -------------------------------------------------------
8519
0
validate_port:
8520
0
  if (port_colon != SIZE_MAX) {
8521
0
    const uint8_t* pp = b + port_colon + 1;
8522
0
    size_t pl = auth_end - port_colon - 1;
8523
0
    if (pl > 0) {
8524
      // Strip leading zeros: "0000001" == 1, "0000000000000" == 0, both valid.
8525
      // Only the significant digits count toward the 5-digit maximum.
8526
0
      while (pl > 0 && *pp == '0') {
8527
0
        ++pp;
8528
0
        --pl;
8529
0
      }
8530
0
      if (pl > 5) return false;  // significant digits > 99999
8531
0
      uint32_t pv = 0;
8532
0
      for (size_t i = 0; i < pl; ++i) {
8533
0
        if (pp[i] < '0' || pp[i] > '9') return false;
8534
0
        pv = pv * 10 + (pp[i] - '0');
8535
0
      }
8536
0
      if (pv > 65535) return false;
8537
0
    }
8538
0
  }
8539
8540
  // Path, query, and fragment are structurally always valid for can_parse --
8541
  // the parser would encode whatever is there.
8542
0
  return true;
8543
0
}
8544
8545
}  // namespace
8546
8547
template <class result_type>
8548
ada_warn_unused tl::expected<result_type, errors> parse(
8549
0
    std::string_view input, const result_type* base_url) {
8550
0
  result_type u = ada::parser::parse_url_impl<result_type>(input, base_url);
8551
0
  if (!u.is_valid) {
8552
0
    return tl::unexpected(errors::type_error);
8553
0
  }
8554
0
  return u;
8555
0
}
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*)
Unexecuted instantiation: 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*)
8556
8557
template ada::result<url> parse<url>(std::string_view input,
8558
                                     const url* base_url = nullptr);
8559
template ada::result<url_aggregator> parse<url_aggregator>(
8560
    std::string_view input, const url_aggregator* base_url = nullptr);
8561
8562
0
std::string href_from_file(std::string_view input) {
8563
  // Match ada::parse / setters: refuse inputs that already exceed the limit.
8564
  // Path percent-encoding can still expand the result, so we also check the
8565
  // final href below.
8566
0
  const uint32_t max_length = ada::get_max_input_length();
8567
0
  if (input.size() > max_length) {
8568
0
    return {};
8569
0
  }
8570
8571
  // This is going to be much faster than constructing a URL.
8572
0
  std::string tmp_buffer;
8573
0
  std::string_view internal_input;
8574
0
  if (unicode::has_tabs_or_newline(input)) {
8575
0
    tmp_buffer = input;
8576
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
8577
0
    internal_input = tmp_buffer;
8578
0
  } else {
8579
0
    internal_input = input;
8580
0
  }
8581
0
  std::string path;
8582
0
  if (internal_input.empty()) {
8583
0
    path = "/";
8584
0
  } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
8585
0
    helpers::parse_prepared_path(internal_input.substr(1),
8586
0
                                 ada::scheme::type::FILE, path);
8587
0
  } else {
8588
0
    helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path);
8589
0
  }
8590
0
  std::string result = "file://" + path;
8591
0
  if (result.size() > max_length) {
8592
0
    return {};
8593
0
  }
8594
0
  return result;
8595
0
}
8596
8597
0
bool can_parse(std::string_view input, const std::string_view* base_input) {
8598
  // Must match parse().has_value(), including post-normalization max length.
8599
  // Percent-encoding expands a byte by at most 3x, but IDNA expands more: a
8600
  // 3-byte UTF-8 label such as U+337F becomes the 17-byte "xn--6oqv20b1zgzxr",
8601
  // so a dotted host sustains 4.5x. When the input (plus base, if any) fits in
8602
  // max_length/5, the normalized href cannot exceed max_length, so
8603
  // validation-only parsing (store_values=false) is safe.
8604
8605
  // Hot path first: absolute special URLs, no base. Avoid loading max_length
8606
  // until we need it (common absolute-fast true/false cases).
8607
0
  if (base_input == nullptr) {
8608
0
    auto r = try_can_parse_clean_http(input);
8609
0
    if (!r.has_value()) {
8610
0
      r = try_can_parse_absolute_fast(input);
8611
0
    }
8612
0
    if (r.has_value()) {
8613
0
      if (!*r) {
8614
0
        return false;
8615
0
      }
8616
      // size <= max/5 => normalized href cannot exceed max (4.5x expansion).
8617
      // Check this first: default max is ~4GB so almost all URLs return true.
8618
0
      const uint32_t max_length = ada::get_max_input_length();
8619
0
      if (input.size() <= static_cast<size_t>(max_length) / 5) {
8620
0
        return true;
8621
0
      }
8622
0
      if (input.size() > max_length) {
8623
0
        return false;
8624
0
      }
8625
0
      return ada::parser::parse_url_impl<ada::url_aggregator, true>(input,
8626
0
                                                                    nullptr)
8627
0
          .is_valid;
8628
0
    }
8629
0
  }
8630
8631
0
  const uint32_t max_length = ada::get_max_input_length();
8632
0
  if (input.size() > max_length) {
8633
0
    return false;
8634
0
  }
8635
0
  if (base_input != nullptr && base_input->size() > max_length) {
8636
0
    return false;
8637
0
  }
8638
8639
  // Relative resolution combines base + input; bound the sum so 4.5x expansion
8640
  // of either side cannot push the final href past max_length.
8641
0
  const size_t combined =
8642
0
      input.size() + (base_input == nullptr ? 0 : base_input->size());
8643
0
  const bool size_safe = combined <= static_cast<size_t>(max_length) / 5;
8644
8645
0
  if (size_safe) {
8646
    // Validation-only: no buffer build, host still fully checked.
8647
0
    ada::url_aggregator base_agg;
8648
0
    ada::url_aggregator* base_ptr = nullptr;
8649
0
    if (base_input != nullptr) {
8650
0
      base_agg = ada::parser::parse_url_impl<ada::url_aggregator, false>(
8651
0
          *base_input, nullptr);
8652
0
      if (!base_agg.is_valid) {
8653
0
        return false;
8654
0
      }
8655
0
      base_ptr = &base_agg;
8656
0
    }
8657
0
    return ada::parser::parse_url_impl<ada::url_aggregator, false>(input,
8658
0
                                                                   base_ptr)
8659
0
        .is_valid;
8660
0
  }
8661
8662
  // Near the limit: full parse so post-normalization length matches parse().
8663
0
  if (base_input == nullptr) {
8664
0
    return ada::parser::parse_url_impl<ada::url_aggregator, true>(input,
8665
0
                                                                  nullptr)
8666
0
        .is_valid;
8667
0
  }
8668
0
  ada::url_aggregator base_agg =
8669
0
      ada::parser::parse_url_impl<ada::url_aggregator, true>(*base_input,
8670
0
                                                             nullptr);
8671
0
  if (!base_agg.is_valid) {
8672
0
    return false;
8673
0
  }
8674
0
  return ada::parser::parse_url_impl<ada::url_aggregator, true>(input,
8675
0
                                                                &base_agg)
8676
0
      .is_valid;
8677
0
}
8678
8679
0
ada_warn_unused std::string_view to_string(ada::encoding_type type) {
8680
0
  switch (type) {
8681
0
    case ada::encoding_type::UTF8:
8682
0
      return "UTF-8";
8683
0
    case ada::encoding_type::UTF_16LE:
8684
0
      return "UTF-16LE";
8685
0
    case ada::encoding_type::UTF_16BE:
8686
0
      return "UTF-16BE";
8687
0
    default:
8688
0
      unreachable();
8689
0
  }
8690
0
}
8691
8692
}  // namespace ada
8693
/* end file src/implementation.cpp */
8694
/* begin file src/helpers.cpp */
8695
#include <array>
8696
#include <cstdint>
8697
#include <cstring>
8698
#include <optional>
8699
#include <sstream>
8700
#include <string>
8701
#include <string_view>
8702
#include <utility>
8703
8704
8705
#if ADA_SSSE3
8706
#include <tmmintrin.h>
8707
#endif
8708
8709
namespace ada::helpers {
8710
8711
template <typename out_iter>
8712
0
void encode_json(std::string_view view, out_iter out) {
8713
  // trivial implementation. could be faster.
8714
0
  const char* hexvalues =
8715
0
      "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
8716
0
  for (uint8_t c : view) {
8717
0
    if (c == '\\') {
8718
0
      *out++ = '\\';
8719
0
      *out++ = '\\';
8720
0
    } else if (c == '"') {
8721
0
      *out++ = '\\';
8722
0
      *out++ = '"';
8723
0
    } else if (c <= 0x1f) {
8724
0
      *out++ = '\\';
8725
0
      *out++ = 'u';
8726
0
      *out++ = '0';
8727
0
      *out++ = '0';
8728
0
      *out++ = hexvalues[2 * c];
8729
0
      *out++ = hexvalues[2 * c + 1];
8730
0
    } else {
8731
0
      *out++ = c;
8732
0
    }
8733
0
  }
8734
0
}
8735
8736
0
ada_unused std::string get_state(ada::state s) {
8737
0
  switch (s) {
8738
0
    case ada::state::AUTHORITY:
8739
0
      return "Authority";
8740
0
    case ada::state::SCHEME_START:
8741
0
      return "Scheme Start";
8742
0
    case ada::state::SCHEME:
8743
0
      return "Scheme";
8744
0
    case ada::state::HOST:
8745
0
      return "Host";
8746
0
    case ada::state::NO_SCHEME:
8747
0
      return "No Scheme";
8748
0
    case ada::state::FRAGMENT:
8749
0
      return "Fragment";
8750
0
    case ada::state::RELATIVE_SCHEME:
8751
0
      return "Relative Scheme";
8752
0
    case ada::state::RELATIVE_SLASH:
8753
0
      return "Relative Slash";
8754
0
    case ada::state::FILE:
8755
0
      return "File";
8756
0
    case ada::state::FILE_HOST:
8757
0
      return "File Host";
8758
0
    case ada::state::FILE_SLASH:
8759
0
      return "File Slash";
8760
0
    case ada::state::PATH_OR_AUTHORITY:
8761
0
      return "Path or Authority";
8762
0
    case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES:
8763
0
      return "Special Authority Ignore Slashes";
8764
0
    case ada::state::SPECIAL_AUTHORITY_SLASHES:
8765
0
      return "Special Authority Slashes";
8766
0
    case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY:
8767
0
      return "Special Relative or Authority";
8768
0
    case ada::state::QUERY:
8769
0
      return "Query";
8770
0
    case ada::state::PATH:
8771
0
      return "Path";
8772
0
    case ada::state::PATH_START:
8773
0
      return "Path Start";
8774
0
    case ada::state::OPAQUE_PATH:
8775
0
      return "Opaque Path";
8776
0
    case ada::state::PORT:
8777
0
      return "Port";
8778
0
    default:
8779
0
      return "unknown state";
8780
0
  }
8781
0
}
8782
8783
ada_really_inline std::optional<std::string_view> prune_hash(
8784
3.33k
    std::string_view& input) noexcept {
8785
  // compiles down to 20--30 instructions including a class to memchr (C
8786
  // function). this function should be quite fast.
8787
3.33k
  size_t location_of_first = input.find('#');
8788
3.33k
  if (location_of_first == std::string_view::npos) {
8789
3.30k
    return std::nullopt;
8790
3.30k
  }
8791
32
  std::string_view hash = input;
8792
32
  hash.remove_prefix(location_of_first + 1);
8793
32
  input.remove_suffix(input.size() - location_of_first);
8794
32
  return hash;
8795
3.33k
}
8796
8797
0
ada_really_inline bool shorten_path(std::string& path, ada::scheme::type type) {
8798
  // Let path be url's path.
8799
  // If url's scheme is "file", path's size is 1, and path[0] is a normalized
8800
  // Windows drive letter, then return.
8801
0
  if (type == ada::scheme::type::FILE &&
8802
0
      path.find('/', 1) == std::string_view::npos && !path.empty()) {
8803
0
    if (checkers::is_normalized_windows_drive_letter(
8804
0
            helpers::substring(path, 1))) {
8805
0
      return false;
8806
0
    }
8807
0
  }
8808
8809
  // Remove path's last item, if any.
8810
0
  size_t last_delimiter = path.rfind('/');
8811
0
  if (last_delimiter != std::string::npos) {
8812
0
    path.erase(last_delimiter);
8813
0
    return true;
8814
0
  }
8815
8816
0
  return false;
8817
0
}
8818
8819
ada_really_inline bool shorten_path(std::string_view& path,
8820
0
                                    ada::scheme::type type) {
8821
  // Let path be url's path.
8822
  // If url's scheme is "file", path's size is 1, and path[0] is a normalized
8823
  // Windows drive letter, then return.
8824
0
  if (type == ada::scheme::type::FILE &&
8825
0
      path.find('/', 1) == std::string_view::npos && !path.empty()) {
8826
0
    if (checkers::is_normalized_windows_drive_letter(
8827
0
            helpers::substring(path, 1))) {
8828
0
      return false;
8829
0
    }
8830
0
  }
8831
8832
  // Remove path's last item, if any.
8833
0
  if (!path.empty()) {
8834
0
    size_t slash_loc = path.rfind('/');
8835
0
    if (slash_loc != std::string_view::npos) {
8836
0
      path.remove_suffix(path.size() - slash_loc);
8837
0
      return true;
8838
0
    }
8839
0
  }
8840
8841
0
  return false;
8842
0
}
8843
8844
3.33k
ada_really_inline void remove_ascii_tab_or_newline(std::string& input) {
8845
  // Fast path: inputs with no tab/newline (the common case) avoid the
8846
  // per-character erase_if scan. has_tabs_or_newline uses SIMD for inputs
8847
  // >= 16 bytes, making this check much cheaper than erase_if's scalar
8848
  // predicate walk when there is nothing to remove.
8849
3.33k
  if (!ada::unicode::has_tabs_or_newline(input)) {
8850
3.19k
    return;
8851
3.19k
  }
8852
142
  std::erase_if(input, ada::unicode::is_ascii_tab_or_newline);
8853
142
}
8854
8855
ada_really_inline constexpr std::string_view substring(std::string_view input,
8856
0
                                                       size_t pos) {
8857
0
  ADA_ASSERT_TRUE(pos <= input.size());
8858
  // The following is safer but unneeded if we have the above line:
8859
  // return pos > input.size() ? std::string_view() : input.substr(pos);
8860
0
  return input.substr(pos);
8861
0
}
8862
8863
0
ada_really_inline void resize(std::string_view& input, size_t pos) noexcept {
8864
0
  ADA_ASSERT_TRUE(pos <= input.size());
8865
0
  input.remove_suffix(input.size() - pos);
8866
0
}
8867
8868
// computes the number of trailing zeroes
8869
// this is a private inline function only defined in this source file.
8870
860
ada_really_inline int trailing_zeroes(uint32_t input_num) noexcept {
8871
#ifdef ADA_REGULAR_VISUAL_STUDIO
8872
  unsigned long ret;
8873
  // Search the mask data from least significant bit (LSB)
8874
  // to the most significant bit (MSB) for a set bit (1).
8875
  _BitScanForward(&ret, input_num);
8876
  return (int)ret;
8877
#else   // ADA_REGULAR_VISUAL_STUDIO
8878
860
  return __builtin_ctzl(input_num);
8879
860
#endif  // ADA_REGULAR_VISUAL_STUDIO
8880
860
}
8881
8882
#if ADA_NEON
8883
// computes the number of trailing zeroes of a 64-bit word
8884
// this is a private inline function only defined in this source file.
8885
ada_really_inline int trailing_zeroes64(uint64_t input_num) noexcept {
8886
#ifdef ADA_REGULAR_VISUAL_STUDIO
8887
  unsigned long ret;
8888
  _BitScanForward64(&ret, input_num);
8889
  return (int)ret;
8890
#else   // ADA_REGULAR_VISUAL_STUDIO
8891
  return __builtin_ctzll(input_num);
8892
#endif  // ADA_REGULAR_VISUAL_STUDIO
8893
}
8894
8895
// Given a NEON register whose lanes are all either 0x00 or 0xFF (i.e., the
8896
// result of a comparison), produce a 64-bit value with four bits set per
8897
// matching input byte, and zero bits elsewhere. Narrowing by four bits per
8898
// 16-bit lane is cheaper than materializing a 16-bit bitmask, and it keeps
8899
// the value in a vector register so that the "any match?" test can be done
8900
// with a floating-point compare against zero, avoiding a transfer to a
8901
// general-purpose register on the common no-match path.
8902
//
8903
// The floating-point compare treats the nibble mask as an IEEE 754 double.
8904
// Negative zero cannot occur (each byte is 0x00, 0x0F, 0xF0 or 0xFF), but a
8905
// mask with only low bits set is a denormal: if flush-to-zero is enabled,
8906
// those compare equal to 0.0. Do not use this on arbitrary vectors.
8907
// Define ADA_NEON_SAFE_ZERO_CHECK to 1 to use an integer compare instead.
8908
ada_really_inline uint8x8_t to_nibble_mask(uint8x16_t comparison) noexcept {
8909
  return vshrn_n_u16(vreinterpretq_u16_u8(comparison), 4);
8910
}
8911
8912
ada_really_inline bool any_set(uint8x8_t nibble_mask) noexcept {
8913
#if ADA_NEON_SAFE_ZERO_CHECK
8914
  return vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0) != 0;
8915
#else
8916
  return vdupd_lane_f64(vreinterpret_f64_u8(nibble_mask), 0) != 0.0;
8917
#endif
8918
}
8919
8920
// index of the first matching byte; only meaningful when any_set is true.
8921
ada_really_inline size_t first_set(uint8x8_t nibble_mask) noexcept {
8922
  return size_t(trailing_zeroes64(
8923
             vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0))) >>
8924
         2;
8925
}
8926
#endif  // ADA_NEON
8927
8928
// starting at index location, this finds the next location of a character
8929
// :, /, \\, ? or [. If none is found, view.size() is returned.
8930
// For use within get_host_delimiter_location.
8931
#if ADA_SSSE3
8932
ada_really_inline size_t find_next_host_delimiter_special(
8933
    std::string_view view, size_t location) noexcept {
8934
  // first check for short strings in which case we do it naively.
8935
  if (view.size() - location < 16) {  // slow path
8936
    for (size_t i = location; i < view.size(); i++) {
8937
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
8938
          view[i] == '?' || view[i] == '[') {
8939
        return i;
8940
      }
8941
    }
8942
    return size_t(view.size());
8943
  }
8944
  // fast path for long strings (expected to be common)
8945
  // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON)
8946
  size_t i = location;
8947
  const __m128i low_mask =
8948
      _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8949
                    0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
8950
  const __m128i high_mask =
8951
      _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
8952
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
8953
  const __m128i fmask = _mm_set1_epi8(0xf);
8954
  const __m128i zero = _mm_setzero_si128();
8955
  for (; i + 15 < view.size(); i += 16) {
8956
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
8957
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
8958
    __m128i highpart = _mm_shuffle_epi8(
8959
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
8960
    __m128i classify = _mm_and_si128(lowpart, highpart);
8961
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
8962
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
8963
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
8964
    // avoid false positives.
8965
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
8966
    if (mask != 0) {
8967
      return i + trailing_zeroes(static_cast<uint32_t>(mask));
8968
    }
8969
  }
8970
  if (i < view.size()) {
8971
    __m128i word =
8972
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
8973
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
8974
    __m128i highpart = _mm_shuffle_epi8(
8975
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
8976
    __m128i classify = _mm_and_si128(lowpart, highpart);
8977
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
8978
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
8979
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
8980
    // avoid false positives.
8981
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
8982
    if (mask != 0) {
8983
      return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask));
8984
    }
8985
  }
8986
  return size_t(view.size());
8987
}
8988
#elif ADA_NEON
8989
// The ada_make_uint8x16_t macro is necessary because Visual Studio does not
8990
// support direct initialization of uint8x16_t. See
8991
// https://developercommunity.visualstudio.com/t/error-C2078:-too-many-initializers-whe/402911?q=backend+neon
8992
#ifndef ada_make_uint8x16_t
8993
#define ada_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \
8994
                            x13, x14, x15, x16)                                \
8995
  ([=]() {                                                                     \
8996
    static uint8_t array[16] = {x1, x2,  x3,  x4,  x5,  x6,  x7,  x8,          \
8997
                                x9, x10, x11, x12, x13, x14, x15, x16};        \
8998
    return vld1q_u8(array);                                                    \
8999
  }())
9000
#endif
9001
9002
ada_really_inline size_t find_next_host_delimiter_special(
9003
    std::string_view view, size_t location) noexcept {
9004
  // first check for short strings in which case we do it naively.
9005
  if (view.size() - location < 16) {  // slow path
9006
    for (size_t i = location; i < view.size(); i++) {
9007
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
9008
          view[i] == '?' || view[i] == '[') {
9009
        return i;
9010
      }
9011
    }
9012
    return size_t(view.size());
9013
  }
9014
  // fast path for long strings (expected to be common)
9015
  size_t i = location;
9016
  uint8x16_t low_mask =
9017
      ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9018
                          0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
9019
  uint8x16_t high_mask =
9020
      ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
9021
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
9022
  uint8x16_t fmask = vmovq_n_u8(0xf);
9023
  for (; i + 15 < view.size(); i += 16) {
9024
    uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
9025
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
9026
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
9027
    // vtstq_u8 gives us 0xFF where (lowpart & highpart) is non-zero and 0x00
9028
    // elsewhere: unlike the plain AND, that is a proper comparison mask, which
9029
    // is what to_nibble_mask requires.
9030
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
9031
    if (any_set(matches)) {
9032
      return i + first_set(matches);
9033
    }
9034
  }
9035
9036
  if (i < view.size()) {
9037
    uint8x16_t word =
9038
        vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
9039
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
9040
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
9041
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
9042
    if (any_set(matches)) {
9043
      return view.length() - 16 + first_set(matches);
9044
    }
9045
  }
9046
  return size_t(view.size());
9047
}
9048
#elif ADA_SSE2
9049
ada_really_inline size_t find_next_host_delimiter_special(
9050
3.81k
    std::string_view view, size_t location) noexcept {
9051
  // first check for short strings in which case we do it naively.
9052
3.81k
  if (view.size() - location < 16) {  // slow path
9053
4.56k
    for (size_t i = location; i < view.size(); i++) {
9054
1.45k
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
9055
1.42k
          view[i] == '?' || view[i] == '[') {
9056
213
        return i;
9057
213
      }
9058
1.45k
    }
9059
3.10k
    return size_t(view.size());
9060
3.31k
  }
9061
  // fast path for long strings (expected to be common)
9062
502
  size_t i = location;
9063
502
  const __m128i mask1 = _mm_set1_epi8(':');
9064
502
  const __m128i mask2 = _mm_set1_epi8('/');
9065
502
  const __m128i mask3 = _mm_set1_epi8('\\');
9066
502
  const __m128i mask4 = _mm_set1_epi8('?');
9067
502
  const __m128i mask5 = _mm_set1_epi8('[');
9068
9069
774
  for (; i + 15 < view.size(); i += 16) {
9070
669
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
9071
669
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
9072
669
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
9073
669
    __m128i m3 = _mm_cmpeq_epi8(word, mask3);
9074
669
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
9075
669
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
9076
669
    __m128i m = _mm_or_si128(
9077
669
        _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
9078
669
    int mask = _mm_movemask_epi8(m);
9079
669
    if (mask != 0) {
9080
397
      return i + trailing_zeroes(mask);
9081
397
    }
9082
669
  }
9083
105
  if (i < view.size()) {
9084
64
    __m128i word =
9085
64
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
9086
64
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
9087
64
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
9088
64
    __m128i m3 = _mm_cmpeq_epi8(word, mask3);
9089
64
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
9090
64
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
9091
64
    __m128i m = _mm_or_si128(
9092
64
        _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
9093
64
    int mask = _mm_movemask_epi8(m);
9094
64
    if (mask != 0) {
9095
36
      return view.length() - 16 + trailing_zeroes(mask);
9096
36
    }
9097
64
  }
9098
69
  return size_t(view.length());
9099
105
}
9100
#elif ADA_LSX
9101
ada_really_inline size_t find_next_host_delimiter_special(
9102
    std::string_view view, size_t location) noexcept {
9103
  // first check for short strings in which case we do it naively.
9104
  if (view.size() - location < 16) {  // slow path
9105
    for (size_t i = location; i < view.size(); i++) {
9106
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
9107
          view[i] == '?' || view[i] == '[') {
9108
        return i;
9109
      }
9110
    }
9111
    return size_t(view.size());
9112
  }
9113
  // fast path for long strings (expected to be common)
9114
  size_t i = location;
9115
  const __m128i mask1 = __lsx_vrepli_b(':');
9116
  const __m128i mask2 = __lsx_vrepli_b('/');
9117
  const __m128i mask3 = __lsx_vrepli_b('\\');
9118
  const __m128i mask4 = __lsx_vrepli_b('?');
9119
  const __m128i mask5 = __lsx_vrepli_b('[');
9120
9121
  for (; i + 15 < view.size(); i += 16) {
9122
    __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0);
9123
    __m128i m1 = __lsx_vseq_b(word, mask1);
9124
    __m128i m2 = __lsx_vseq_b(word, mask2);
9125
    __m128i m3 = __lsx_vseq_b(word, mask3);
9126
    __m128i m4 = __lsx_vseq_b(word, mask4);
9127
    __m128i m5 = __lsx_vseq_b(word, mask5);
9128
    __m128i m =
9129
        __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5);
9130
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
9131
    if (mask != 0) {
9132
      return i + trailing_zeroes(mask);
9133
    }
9134
  }
9135
  if (i < view.size()) {
9136
    __m128i word =
9137
        __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0);
9138
    __m128i m1 = __lsx_vseq_b(word, mask1);
9139
    __m128i m2 = __lsx_vseq_b(word, mask2);
9140
    __m128i m3 = __lsx_vseq_b(word, mask3);
9141
    __m128i m4 = __lsx_vseq_b(word, mask4);
9142
    __m128i m5 = __lsx_vseq_b(word, mask5);
9143
    __m128i m =
9144
        __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5);
9145
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
9146
    if (mask != 0) {
9147
      return view.length() - 16 + trailing_zeroes(mask);
9148
    }
9149
  }
9150
  return size_t(view.length());
9151
}
9152
#elif ADA_RVV
9153
ada_really_inline size_t find_next_host_delimiter_special(
9154
    std::string_view view, size_t location) noexcept {
9155
  // The LUT approach was a bit slower on the SpacemiT X60, but I could see it
9156
  // being faster on future hardware.
9157
#if 0
9158
  // LUT generated using: s=":/\\?["; list(zip([((ord(c)>>2)&0xF)for c in s],s))
9159
  static const uint8_t tbl[16] = {
9160
    0xF, 0, 0, 0, 0, 0, '[', '\\', 0, 0, 0, '/', 0, 0, ':', '?'
9161
  };
9162
  vuint8m1_t vtbl = __riscv_vle8_v_u8m1(tbl, 16);
9163
#endif
9164
  uint8_t* src = (uint8_t*)view.data() + location;
9165
  for (size_t vl, n = view.size() - location; n > 0;
9166
       n -= vl, src += vl, location += vl) {
9167
    vl = __riscv_vsetvl_e8m1(n);
9168
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
9169
#if 0
9170
    vuint8m1_t vidx = __riscv_vand(__riscv_vsrl(v, 2, vl), 0xF, vl);
9171
    vuint8m1_t vlut = __riscv_vrgather(vtbl, vidx, vl);
9172
    vbool8_t m = __riscv_vmseq(v, vlut, vl);
9173
#else
9174
    vbool8_t m1 = __riscv_vmseq(v, ':', vl);
9175
    vbool8_t m2 = __riscv_vmseq(v, '/', vl);
9176
    vbool8_t m3 = __riscv_vmseq(v, '?', vl);
9177
    vbool8_t m4 = __riscv_vmseq(v, '[', vl);
9178
    vbool8_t m5 = __riscv_vmseq(v, '\\', vl);
9179
    vbool8_t m = __riscv_vmor(
9180
        __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl),
9181
        m5, vl);
9182
#endif
9183
    long idx = __riscv_vfirst(m, vl);
9184
    if (idx >= 0) return location + idx;
9185
  }
9186
  return size_t(view.size());
9187
}
9188
#else
9189
// : / [ \\ ?
9190
static constexpr std::array<uint8_t, 256> special_host_delimiters =
9191
    []() consteval {
9192
      std::array<uint8_t, 256> result{};
9193
      for (int i : {':', '/', '[', '\\', '?'}) {
9194
        result[i] = 1;
9195
      }
9196
      return result;
9197
    }();
9198
// credit: @the-moisrex recommended a table-based approach
9199
ada_really_inline size_t find_next_host_delimiter_special(
9200
    std::string_view view, size_t location) noexcept {
9201
  auto const str = view.substr(location);
9202
  for (auto pos = str.begin(); pos != str.end(); ++pos) {
9203
    if (special_host_delimiters[(uint8_t)*pos]) {
9204
      return pos - str.begin() + location;
9205
    }
9206
  }
9207
  return size_t(view.size());
9208
}
9209
#endif
9210
9211
// starting at index location, this finds the next location of a character
9212
// :, /, ? or [. If none is found, view.size() is returned.
9213
// For use within get_host_delimiter_location.
9214
#if ADA_SSSE3
9215
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9216
                                                  size_t location) noexcept {
9217
  // first check for short strings in which case we do it naively.
9218
  if (view.size() - location < 16) {  // slow path
9219
    for (size_t i = location; i < view.size(); i++) {
9220
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
9221
          view[i] == '[') {
9222
        return i;
9223
      }
9224
    }
9225
    return size_t(view.size());
9226
  }
9227
  // fast path for long strings (expected to be common)
9228
  size_t i = location;
9229
  // Lookup tables for bit classification:
9230
  // ':' (0x3A): low[0xA]=0x01, high[0x3]=0x01 -> match
9231
  // '/' (0x2F): low[0xF]=0x02, high[0x2]=0x02 -> match
9232
  // '?' (0x3F): low[0xF]=0x01, high[0x3]=0x01 -> match
9233
  // '[' (0x5B): low[0xB]=0x04, high[0x5]=0x04 -> match
9234
  const __m128i low_mask =
9235
      _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9236
                    0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
9237
  const __m128i high_mask =
9238
      _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
9239
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
9240
  const __m128i fmask = _mm_set1_epi8(0xf);
9241
  const __m128i zero = _mm_setzero_si128();
9242
9243
  for (; i + 15 < view.size(); i += 16) {
9244
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
9245
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
9246
    __m128i highpart = _mm_shuffle_epi8(
9247
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
9248
    __m128i classify = _mm_and_si128(lowpart, highpart);
9249
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
9250
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
9251
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
9252
    // avoid false positives.
9253
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
9254
    if (mask != 0) {
9255
      return i + trailing_zeroes(static_cast<uint32_t>(mask));
9256
    }
9257
  }
9258
9259
  if (i < view.size()) {
9260
    __m128i word =
9261
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
9262
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
9263
    __m128i highpart = _mm_shuffle_epi8(
9264
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
9265
    __m128i classify = _mm_and_si128(lowpart, highpart);
9266
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
9267
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
9268
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
9269
    // avoid false positives.
9270
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
9271
    if (mask != 0) {
9272
      return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask));
9273
    }
9274
  }
9275
  return size_t(view.size());
9276
}
9277
#elif ADA_NEON
9278
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9279
                                                  size_t location) noexcept {
9280
  // first check for short strings in which case we do it naively.
9281
  if (view.size() - location < 16) {  // slow path
9282
    for (size_t i = location; i < view.size(); i++) {
9283
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
9284
          view[i] == '[') {
9285
        return i;
9286
      }
9287
    }
9288
    return size_t(view.size());
9289
  }
9290
  // fast path for long strings (expected to be common)
9291
  size_t i = location;
9292
  uint8x16_t low_mask =
9293
      ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9294
                          0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
9295
  uint8x16_t high_mask =
9296
      ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
9297
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
9298
  uint8x16_t fmask = vmovq_n_u8(0xf);
9299
  for (; i + 15 < view.size(); i += 16) {
9300
    uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
9301
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
9302
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
9303
    // vtstq_u8 gives us 0xFF where (lowpart & highpart) is non-zero and 0x00
9304
    // elsewhere: unlike the plain AND, that is a proper comparison mask, which
9305
    // is what to_nibble_mask requires.
9306
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
9307
    if (any_set(matches)) {
9308
      return i + first_set(matches);
9309
    }
9310
  }
9311
9312
  if (i < view.size()) {
9313
    uint8x16_t word =
9314
        vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
9315
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
9316
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
9317
    uint8x8_t matches = to_nibble_mask(vtstq_u8(lowpart, highpart));
9318
    if (any_set(matches)) {
9319
      return view.length() - 16 + first_set(matches);
9320
    }
9321
  }
9322
  return size_t(view.size());
9323
}
9324
#elif ADA_SSE2
9325
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9326
3.81k
                                                  size_t location) noexcept {
9327
  // first check for short strings in which case we do it naively.
9328
3.81k
  if (view.size() - location < 16) {  // slow path
9329
4.58k
    for (size_t i = location; i < view.size(); i++) {
9330
1.47k
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
9331
1.44k
          view[i] == '[') {
9332
202
        return i;
9333
202
      }
9334
1.47k
    }
9335
3.11k
    return size_t(view.size());
9336
3.31k
  }
9337
  // fast path for long strings (expected to be common)
9338
502
  size_t i = location;
9339
502
  const __m128i mask1 = _mm_set1_epi8(':');
9340
502
  const __m128i mask2 = _mm_set1_epi8('/');
9341
502
  const __m128i mask4 = _mm_set1_epi8('?');
9342
502
  const __m128i mask5 = _mm_set1_epi8('[');
9343
9344
788
  for (; i + 15 < view.size(); i += 16) {
9345
679
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
9346
679
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
9347
679
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
9348
679
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
9349
679
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
9350
679
    __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
9351
679
    int mask = _mm_movemask_epi8(m);
9352
679
    if (mask != 0) {
9353
393
      return i + trailing_zeroes(mask);
9354
393
    }
9355
679
  }
9356
109
  if (i < view.size()) {
9357
64
    __m128i word =
9358
64
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
9359
64
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
9360
64
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
9361
64
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
9362
64
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
9363
64
    __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
9364
64
    int mask = _mm_movemask_epi8(m);
9365
64
    if (mask != 0) {
9366
34
      return view.length() - 16 + trailing_zeroes(mask);
9367
34
    }
9368
64
  }
9369
75
  return size_t(view.length());
9370
109
}
9371
#elif ADA_LSX
9372
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9373
                                                  size_t location) noexcept {
9374
  // first check for short strings in which case we do it naively.
9375
  if (view.size() - location < 16) {  // slow path
9376
    for (size_t i = location; i < view.size(); i++) {
9377
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
9378
          view[i] == '[') {
9379
        return i;
9380
      }
9381
    }
9382
    return size_t(view.size());
9383
  }
9384
  // fast path for long strings (expected to be common)
9385
  size_t i = location;
9386
  const __m128i mask1 = __lsx_vrepli_b(':');
9387
  const __m128i mask2 = __lsx_vrepli_b('/');
9388
  const __m128i mask4 = __lsx_vrepli_b('?');
9389
  const __m128i mask5 = __lsx_vrepli_b('[');
9390
9391
  for (; i + 15 < view.size(); i += 16) {
9392
    __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0);
9393
    __m128i m1 = __lsx_vseq_b(word, mask1);
9394
    __m128i m2 = __lsx_vseq_b(word, mask2);
9395
    __m128i m4 = __lsx_vseq_b(word, mask4);
9396
    __m128i m5 = __lsx_vseq_b(word, mask5);
9397
    __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5));
9398
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
9399
    if (mask != 0) {
9400
      return i + trailing_zeroes(mask);
9401
    }
9402
  }
9403
  if (i < view.size()) {
9404
    __m128i word =
9405
        __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0);
9406
    __m128i m1 = __lsx_vseq_b(word, mask1);
9407
    __m128i m2 = __lsx_vseq_b(word, mask2);
9408
    __m128i m4 = __lsx_vseq_b(word, mask4);
9409
    __m128i m5 = __lsx_vseq_b(word, mask5);
9410
    __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5));
9411
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
9412
    if (mask != 0) {
9413
      return view.length() - 16 + trailing_zeroes(mask);
9414
    }
9415
  }
9416
  return size_t(view.length());
9417
}
9418
#elif ADA_RVV
9419
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9420
                                                  size_t location) noexcept {
9421
  uint8_t* src = (uint8_t*)view.data() + location;
9422
  for (size_t vl, n = view.size() - location; n > 0;
9423
       n -= vl, src += vl, location += vl) {
9424
    vl = __riscv_vsetvl_e8m1(n);
9425
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
9426
    vbool8_t m1 = __riscv_vmseq(v, ':', vl);
9427
    vbool8_t m2 = __riscv_vmseq(v, '/', vl);
9428
    vbool8_t m3 = __riscv_vmseq(v, '?', vl);
9429
    vbool8_t m4 = __riscv_vmseq(v, '[', vl);
9430
    vbool8_t m =
9431
        __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl);
9432
    long idx = __riscv_vfirst(m, vl);
9433
    if (idx >= 0) return location + idx;
9434
  }
9435
  return size_t(view.size());
9436
}
9437
#else
9438
// : / [ ?
9439
static constexpr std::array<uint8_t, 256> host_delimiters = []() consteval {
9440
  std::array<uint8_t, 256> result{};
9441
  for (int i : {':', '/', '?', '['}) {
9442
    result[i] = 1;
9443
  }
9444
  return result;
9445
}();
9446
// credit: @the-moisrex recommended a table-based approach
9447
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
9448
                                                  size_t location) noexcept {
9449
  auto const str = view.substr(location);
9450
  for (auto pos = str.begin(); pos != str.end(); ++pos) {
9451
    if (host_delimiters[(uint8_t)*pos]) {
9452
      return pos - str.begin() + location;
9453
    }
9454
  }
9455
  return size_t(view.size());
9456
}
9457
#endif
9458
9459
ada_really_inline std::pair<size_t, bool> get_host_delimiter_location(
9460
6.66k
    const bool is_special, std::string_view& view) noexcept {
9461
  /**
9462
   * The spec at https://url.spec.whatwg.org/#hostname-state expects us to
9463
   * compute a variable called insideBrackets but this variable is only used
9464
   * once, to check whether a ':' character was found outside brackets. Exact
9465
   * text: "Otherwise, if c is U+003A (:) and insideBrackets is false, then:".
9466
   * It is conceptually simpler and arguably more efficient to just return a
9467
   * Boolean indicating whether ':' was found outside brackets.
9468
   */
9469
6.66k
  const size_t view_size = view.size();
9470
6.66k
  size_t location = 0;
9471
6.66k
  bool found_colon = false;
9472
  /**
9473
   * Performance analysis:
9474
   *
9475
   * We are basically seeking the end of the hostname which can be indicated
9476
   * by the end of the view, or by one of the characters ':', '/', '?', '\\'
9477
   * (where '\\' is only applicable for special URLs). However, these must
9478
   * appear outside a bracket range. E.g., if you have [something?]fd: then the
9479
   * '?' does not count.
9480
   *
9481
   * So we can skip ahead to the next delimiter, as long as we include '[' in
9482
   * the set of delimiters, and that we handle it first.
9483
   *
9484
   * So the trick is to have a fast function that locates the next delimiter.
9485
   * Unless we find '[', then it only needs to be called once! Ideally, such a
9486
   * function would be provided by the C++ standard library, but it seems that
9487
   * find_first_of is not very fast, so we are forced to roll our own.
9488
   *
9489
   * We do not break into two loops for speed, but for clarity.
9490
   */
9491
6.66k
  if (is_special) {
9492
    // We move to the next delimiter.
9493
3.33k
    location = find_next_host_delimiter_special(view, location);
9494
    // Unless we find '[' then we are going only going to have to call
9495
    // find_next_host_delimiter_special once.
9496
3.81k
    for (; location < view_size;
9497
3.33k
         location = find_next_host_delimiter_special(view, location)) {
9498
646
      if (view[location] == '[') {
9499
532
        location = view.find(']', location);
9500
532
        if (location == std::string_view::npos) {
9501
          // performance: view.find might get translated to a memchr, which
9502
          // has no notion of std::string_view::npos, so the code does not
9503
          // reflect the assembly.
9504
48
          location = view_size;
9505
48
          break;
9506
48
        }
9507
532
      } else {
9508
114
        found_colon = view[location] == ':';
9509
114
        break;
9510
114
      }
9511
646
    }
9512
3.33k
  } else {
9513
    // We move to the next delimiter.
9514
3.33k
    location = find_next_host_delimiter(view, location);
9515
    // Unless we find '[' then we are going only going to have to call
9516
    // find_next_host_delimiter_special once.
9517
3.81k
    for (; location < view_size;
9518
3.33k
         location = find_next_host_delimiter(view, location)) {
9519
629
      if (view[location] == '[') {
9520
532
        location = view.find(']', location);
9521
532
        if (location == std::string_view::npos) {
9522
          // performance: view.find might get translated to a memchr, which
9523
          // has no notion of std::string_view::npos, so the code does not
9524
          // reflect the assembly.
9525
48
          location = view_size;
9526
48
          break;
9527
48
        }
9528
532
      } else {
9529
97
        found_colon = view[location] == ':';
9530
97
        break;
9531
97
      }
9532
629
    }
9533
3.33k
  }
9534
  // performance: remove_suffix may translate into a single instruction.
9535
6.66k
  view.remove_suffix(view_size - location);
9536
6.66k
  return {location, found_colon};
9537
6.66k
}
9538
9539
3.33k
void trim_c0_whitespace(std::string_view& input) noexcept {
9540
4.64k
  while (!input.empty() &&
9541
1.80k
         ada::unicode::is_c0_control_or_space(input.front())) {
9542
1.30k
    input.remove_prefix(1);
9543
1.30k
  }
9544
3.71k
  while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) {
9545
377
    input.remove_suffix(1);
9546
377
  }
9547
3.33k
}
9548
9549
ada_really_inline void parse_prepared_path(std::string_view input,
9550
                                           ada::scheme::type type,
9551
0
                                           std::string& path) {
9552
0
  ada_log("parse_prepared_path ", input);
9553
0
  uint8_t accumulator = checkers::path_signature(input);
9554
  // Let us first detect a trivial case.
9555
  // If it is special, we check that we have no dot, no %,  no \ and no
9556
  // character needing percent encoding. Otherwise, we check that we have no %,
9557
  // no dot, and no character needing percent encoding.
9558
0
  constexpr uint8_t need_encoding = 1;
9559
0
  constexpr uint8_t backslash_char = 2;
9560
0
  constexpr uint8_t dot_char = 4;
9561
0
  constexpr uint8_t percent_char = 8;
9562
0
  bool special = type != ada::scheme::NOT_SPECIAL;
9563
0
  bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
9564
0
                                      checkers::is_windows_drive_letter(input));
9565
0
  bool trivial_path =
9566
0
      (special ? (accumulator == 0)
9567
0
               : ((accumulator & (need_encoding | dot_char | percent_char)) ==
9568
0
                  0)) &&
9569
0
      (!may_need_slow_file_handling);
9570
0
  if (accumulator == dot_char && !may_need_slow_file_handling) {
9571
    // '4' means that we have at least one dot, but nothing that requires
9572
    // percent encoding or decoding. The only part that is not trivial is
9573
    // that we may have single dots and double dots path segments.
9574
    // If we have such segments, then we either have a path that begins
9575
    // with '.' (easy to check), or we have the sequence './'.
9576
    // Note: input cannot be empty, it must at least contain one character ('.')
9577
    // Note: we know that '\' is not present.
9578
0
    if (input[0] != '.') {
9579
0
      size_t slashdot = 0;
9580
0
      bool dot_is_file = true;
9581
0
      for (;;) {
9582
0
        slashdot = input.find("/.", slashdot);
9583
0
        if (slashdot == std::string_view::npos) {  // common case
9584
0
          break;
9585
0
        } else {  // uncommon
9586
          // only three cases matter: /./, /.. or a final /
9587
0
          slashdot += 2;
9588
0
          dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' ||
9589
0
                           input[slashdot] == '/');
9590
0
        }
9591
0
      }
9592
0
      trivial_path = dot_is_file;
9593
0
    }
9594
0
  }
9595
0
  if (trivial_path) {
9596
0
    ada_log("parse_path trivial");
9597
0
    path += '/';
9598
0
    path += input;
9599
0
    return;
9600
0
  }
9601
  // We are going to need to look a bit at the path, but let us see if we can
9602
  // ignore percent encoding *and* backslashes *and* percent characters.
9603
  // Except for the trivial case, this is likely to capture 99% of paths out
9604
  // there.
9605
0
  bool fast_path =
9606
0
      (special &&
9607
0
       (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
9608
0
      (type != ada::scheme::type::FILE);
9609
0
  if (fast_path) {
9610
0
    ada_log("parse_prepared_path fast");
9611
    // Here we don't need to worry about \ or percent encoding.
9612
    // We also do not have a file protocol. We might have dots, however,
9613
    // but dots must as appear as '.', and they cannot be encoded because
9614
    // the symbol '%' is not present.
9615
0
    size_t previous_location = 0;  // We start at 0.
9616
0
    do {
9617
0
      size_t new_location = input.find('/', previous_location);
9618
      // std::string_view path_view = input;
9619
      //  We process the last segment separately:
9620
0
      if (new_location == std::string_view::npos) {
9621
0
        std::string_view path_view = input.substr(previous_location);
9622
0
        if (path_view == "..") {  // The path ends with ..
9623
          // e.g., if you receive ".." with an empty path, you go to "/".
9624
0
          if (path.empty()) {
9625
0
            path = '/';
9626
0
            return;
9627
0
          }
9628
          // Fast case where we have nothing to do:
9629
0
          if (path.back() == '/') {
9630
0
            return;
9631
0
          }
9632
          // If you have the path "/joe/myfriend",
9633
          // then you delete 'myfriend'.
9634
0
          path.resize(path.rfind('/') + 1);
9635
0
          return;
9636
0
        }
9637
0
        path += '/';
9638
0
        if (path_view != ".") {
9639
0
          path.append(path_view);
9640
0
        }
9641
0
        return;
9642
0
      } else {
9643
        // This is a non-final segment.
9644
0
        std::string_view path_view =
9645
0
            input.substr(previous_location, new_location - previous_location);
9646
0
        previous_location = new_location + 1;
9647
0
        if (path_view == "..") {
9648
0
          size_t last_delimiter = path.rfind('/');
9649
0
          if (last_delimiter != std::string::npos) {
9650
0
            path.erase(last_delimiter);
9651
0
          }
9652
0
        } else if (path_view != ".") {
9653
0
          path += '/';
9654
0
          path.append(path_view);
9655
0
        }
9656
0
      }
9657
0
    } while (true);
9658
0
  } else {
9659
0
    ada_log("parse_path slow");
9660
    // we have reached the general case
9661
0
    bool needs_percent_encoding = (accumulator & 1);
9662
0
    std::string path_buffer_tmp;
9663
0
    do {
9664
0
      size_t location = (special && (accumulator & 2))
9665
0
                            ? input.find_first_of("/\\")
9666
0
                            : input.find('/');
9667
0
      std::string_view path_view = input;
9668
0
      if (location != std::string_view::npos) {
9669
0
        path_view.remove_suffix(path_view.size() - location);
9670
0
        input.remove_prefix(location + 1);
9671
0
      }
9672
      // path_buffer is either path_view or it might point at a percent encoded
9673
      // temporary file.
9674
0
      std::string_view path_buffer =
9675
0
          (needs_percent_encoding &&
9676
0
           ada::unicode::percent_encode<false>(
9677
0
               path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
9678
0
              ? path_buffer_tmp
9679
0
              : path_view;
9680
0
      if (unicode::is_double_dot_path_segment(path_buffer)) {
9681
0
        helpers::shorten_path(path, type);
9682
0
        if (location == std::string_view::npos) {
9683
0
          path += '/';
9684
0
        }
9685
0
      } else if (unicode::is_single_dot_path_segment(path_buffer) &&
9686
0
                 (location == std::string_view::npos)) {
9687
0
        path += '/';
9688
0
      }
9689
      // Otherwise, if path_buffer is not a single-dot path segment, then:
9690
0
      else if (!unicode::is_single_dot_path_segment(path_buffer)) {
9691
        // If url's scheme is "file", url's path is empty, and path_buffer is a
9692
        // Windows drive letter, then replace the second code point in
9693
        // path_buffer with U+003A (:).
9694
0
        if (type == ada::scheme::type::FILE && path.empty() &&
9695
0
            checkers::is_windows_drive_letter(path_buffer)) {
9696
0
          path += '/';
9697
0
          path += path_buffer[0];
9698
0
          path += ':';
9699
0
          path_buffer.remove_prefix(2);
9700
0
          path.append(path_buffer);
9701
0
        } else {
9702
          // Append path_buffer to url's path.
9703
0
          path += '/';
9704
0
          path.append(path_buffer);
9705
0
        }
9706
0
      }
9707
0
      if (location == std::string_view::npos) {
9708
0
        return;
9709
0
      }
9710
0
    } while (true);
9711
0
  }
9712
0
}
9713
9714
0
bool overlaps(std::string_view input1, const std::string& input2) noexcept {
9715
0
  ada_log("helpers::overlaps check if string_view '", input1, "' [",
9716
0
          input1.size(), " bytes] is part of string '", input2, "' [",
9717
0
          input2.size(), " bytes]");
9718
0
  return !input1.empty() && !input2.empty() && input1.data() >= input2.data() &&
9719
0
         input1.data() < input2.data() + input2.size();
9720
0
}
9721
9722
template <class url_type>
9723
0
ada_really_inline void strip_trailing_spaces_from_opaque_path(url_type& url) {
9724
0
  ada_log("helpers::strip_trailing_spaces_from_opaque_path");
9725
0
  if (!url.has_opaque_path) return;
9726
0
  if (url.has_hash()) return;
9727
0
  if (url.has_search()) return;
9728
9729
0
  auto path = std::string(url.get_pathname());
9730
0
  while (!path.empty() && path.back() == ' ') {
9731
0
    path.resize(path.size() - 1);
9732
0
  }
9733
0
  url.update_base_pathname(path);
9734
0
}
Unexecuted instantiation: void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url>(ada::url&)
Unexecuted instantiation: void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url_aggregator>(ada::url_aggregator&)
9735
9736
// @ / \\ ?
9737
static constexpr std::array<uint8_t, 256> authority_delimiter_special =
9738
    []() consteval {
9739
      std::array<uint8_t, 256> result{};
9740
      for (uint8_t i : {'@', '/', '\\', '?'}) {
9741
        result[i] = 1;
9742
      }
9743
      return result;
9744
    }();
9745
// credit: @the-moisrex recommended a table-based approach
9746
ada_really_inline size_t
9747
3.33k
find_authority_delimiter_special(std::string_view view) noexcept {
9748
  // performance note: we might be able to gain further performance
9749
  // with SIMD intrinsics.
9750
11.8k
  for (auto pos = view.begin(); pos != view.end(); ++pos) {
9751
8.58k
    if (authority_delimiter_special[(uint8_t)*pos]) {
9752
107
      return pos - view.begin();
9753
107
    }
9754
8.58k
  }
9755
3.22k
  return size_t(view.size());
9756
3.33k
}
9757
9758
// @ / ?
9759
static constexpr std::array<uint8_t, 256> authority_delimiter = []() consteval {
9760
  std::array<uint8_t, 256> result{};
9761
  for (uint8_t i : {'@', '/', '?'}) {
9762
    result[i] = 1;
9763
  }
9764
  return result;
9765
}();
9766
// credit: @the-moisrex recommended a table-based approach
9767
ada_really_inline size_t
9768
3.33k
find_authority_delimiter(std::string_view view) noexcept {
9769
  // performance note: we might be able to gain further performance
9770
  // with SIMD instrinsics.
9771
12.0k
  for (auto pos = view.begin(); pos != view.end(); ++pos) {
9772
8.84k
    if (authority_delimiter[(uint8_t)*pos]) {
9773
89
      return pos - view.begin();
9774
89
    }
9775
8.84k
  }
9776
3.24k
  return size_t(view.size());
9777
3.33k
}
9778
9779
}  // namespace ada::helpers
9780
9781
namespace ada {
9782
0
ada_warn_unused std::string to_string(ada::state state) {
9783
0
  return ada::helpers::get_state(state);
9784
0
}
9785
#undef ada_make_uint8x16_t
9786
}  // namespace ada
9787
/* end file src/helpers.cpp */
9788
/* begin file src/url.cpp */
9789
/* begin file include/ada/url_ip-inl.h */
9790
/**
9791
 * @file url_ip-inl.h
9792
 * @brief Shared IPv4/IPv6 parsing helpers used by url and url_aggregator.
9793
 *
9794
 * Not part of the public API. Defined inline so the single-TU amalgamation
9795
 * (ada.cpp) can include them from multiple translation-unit sources once.
9796
 */
9797
#ifndef ADA_URL_IP_INL_H
9798
#define ADA_URL_IP_INL_H
9799
9800
9801
#include <array>
9802
#include <cstddef>
9803
#include <cstdint>
9804
9805
// The IPv6 kernel needs vpermi2b/vpermb (VBMI) and vpcompressb/vpexpandb
9806
// (VBMI2) on top of ADA_AVX512's BW+VL.
9807
#if defined(ADA_AVX512) && defined(__AVX512VBMI__) && defined(__AVX512VBMI2__)
9808
#define ADA_AVX512_IPV6 1
9809
#endif
9810
9811
#if defined(ADA_AVX512)
9812
#include <immintrin.h>
9813
#endif
9814
9815
namespace ada::detail {
9816
9817
// 256-entry: 0xff = not hex, else nibble value.
9818
0
inline constexpr std::array<uint8_t, 256> make_hex_nibble_table() noexcept {
9819
0
  std::array<uint8_t, 256> t{};
9820
0
  for (size_t i = 0; i < 256; ++i) {
9821
0
    t[i] = 0xff;
9822
0
  }
9823
0
  for (size_t d = 0; d < 10; ++d) {
9824
0
    t[size_t{'0'} + d] = static_cast<uint8_t>(d);
9825
0
  }
9826
0
  for (size_t d = 0; d < 6; ++d) {
9827
0
    t[size_t{'a'} + d] = static_cast<uint8_t>(10 + d);
9828
0
    t[size_t{'A'} + d] = static_cast<uint8_t>(10 + d);
9829
0
  }
9830
0
  return t;
9831
0
}
9832
9833
inline constexpr auto hex_nibble = make_hex_nibble_table();
9834
9835
inline bool parse_ipv4_number(const char*& p, const char* end, uint64_t& value,
9836
0
                              bool& is_pure_decimal) noexcept {
9837
0
  is_pure_decimal = false;
9838
0
  if (p >= end) [[unlikely]] {
9839
0
    return false;
9840
0
  }
9841
0
  if (end - p >= 2 && p[0] == '0' && ((p[1] | 0x20) == 'x')) {
9842
0
    p += 2;
9843
0
    if (p == end || *p == '.') {
9844
0
      value = 0;
9845
0
      return true;
9846
0
    }
9847
0
    uint64_t v = 0;
9848
0
    int digits = 0;
9849
0
    while (p < end && *p != '.') {
9850
0
      const uint8_t nib = hex_nibble[static_cast<unsigned char>(*p)];
9851
0
      if (nib == 0xff) [[unlikely]] {
9852
0
        return false;
9853
0
      }
9854
0
      if (v > (0xFFFFFFFFULL >> 4)) [[unlikely]] {
9855
0
        return false;
9856
0
      }
9857
0
      v = (v << 4) | nib;
9858
0
      ++p;
9859
0
      ++digits;
9860
0
    }
9861
0
    if (digits == 0) [[unlikely]] {
9862
0
      return false;
9863
0
    }
9864
0
    value = v;
9865
0
    return true;
9866
0
  }
9867
0
  if (end - p >= 2 && p[0] == '0' && p[1] >= '0' && p[1] <= '9') {
9868
0
    ++p;
9869
0
    uint64_t v = 0;
9870
0
    while (p < end && *p != '.') {
9871
0
      const char c = *p;
9872
0
      if (c < '0' || c > '7') [[unlikely]] {
9873
0
        return false;
9874
0
      }
9875
0
      if (v > (0xFFFFFFFFULL >> 3)) [[unlikely]] {
9876
0
        return false;
9877
0
      }
9878
0
      v = (v << 3) | static_cast<uint64_t>(c - '0');
9879
0
      ++p;
9880
0
    }
9881
0
    value = v;
9882
0
    return true;
9883
0
  }
9884
0
  if (*p < '0' || *p > '9') [[unlikely]] {
9885
0
    return false;
9886
0
  }
9887
0
  is_pure_decimal = true;
9888
0
  uint64_t v = static_cast<uint64_t>(*p - '0');
9889
0
  ++p;
9890
0
  while (p < end && *p != '.') {
9891
0
    const char c = *p;
9892
0
    if (c < '0' || c > '9') [[unlikely]] {
9893
0
      return false;
9894
0
    }
9895
0
    if (v > 429496729ULL) [[unlikely]] {
9896
0
      return false;
9897
0
    }
9898
0
    v = v * 10u + static_cast<uint64_t>(c - '0');
9899
0
    if (v > 0xFFFFFFFFULL) [[unlikely]] {
9900
0
      return false;
9901
0
    }
9902
0
    ++p;
9903
0
  }
9904
0
  value = v;
9905
0
  return true;
9906
0
}
9907
9908
// Parse up to 4 hex digits. Returns digit count (0 if none).
9909
inline int parse_hex_piece(const char*& pointer, const char* end,
9910
0
                           uint16_t& value) noexcept {
9911
0
  if (pointer == end) {
9912
0
    return 0;
9913
0
  }
9914
0
  const uint8_t n0 = hex_nibble[static_cast<unsigned char>(*pointer)];
9915
0
  if (n0 == 0xff) {
9916
0
    return 0;
9917
0
  }
9918
0
  uint32_t v = n0;
9919
0
  ++pointer;
9920
0
  int length = 1;
9921
0
  if (pointer != end) {
9922
0
    const uint8_t n1 = hex_nibble[static_cast<unsigned char>(*pointer)];
9923
0
    if (n1 != 0xff) {
9924
0
      v = (v << 4) | n1;
9925
0
      ++pointer;
9926
0
      ++length;
9927
0
      if (pointer != end) {
9928
0
        const uint8_t n2 = hex_nibble[static_cast<unsigned char>(*pointer)];
9929
0
        if (n2 != 0xff) {
9930
0
          v = (v << 4) | n2;
9931
0
          ++pointer;
9932
0
          ++length;
9933
0
          if (pointer != end) {
9934
0
            const uint8_t n3 = hex_nibble[static_cast<unsigned char>(*pointer)];
9935
0
            if (n3 != 0xff) {
9936
0
              v = (v << 4) | n3;
9937
0
              ++pointer;
9938
0
              ++length;
9939
0
            }
9940
0
          }
9941
0
        }
9942
0
      }
9943
0
    }
9944
0
  }
9945
0
  value = static_cast<uint16_t>(v);
9946
0
  return length;
9947
0
}
9948
9949
#if defined(ADA_AVX512_IPV6)
9950
// Gather each group's up-to-four nibbles and fold them into eight hextets.
9951
// `prev` is the byte before each group, so an index that runs off the front of
9952
// a short group clamps onto a colon, which translates to zero: no write mask.
9953
ada_really_inline void ipv6_gather(__m128i ends, __m128i prev, __m512i nib,
9954
                                   std::array<uint16_t, 8>& address) noexcept {
9955
  const __m256i grp =
9956
      _mm256_setr_epi8(0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
9957
                       4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7);
9958
  const __m256i off = _mm256_setr_epi8(
9959
      -4, -3, -2, -1, -4, -3, -2, -1, -4, -3, -2, -1, -4, -3, -2, -1, -4, -3,
9960
      -2, -1, -4, -3, -2, -1, -4, -3, -2, -1, -4, -3, -2, -1);
9961
  const __m256i idx = _mm256_max_epi8(
9962
      _mm256_add_epi8(
9963
          _mm256_permutexvar_epi8(grp, _mm256_castsi128_si256(ends)), off),
9964
      _mm256_permutexvar_epi8(grp, _mm256_castsi128_si256(prev)));
9965
  const __m256i gathered = _mm512_castsi512_si256(
9966
      _mm512_permutexvar_epi8(_mm512_castsi256_si512(idx), nib));
9967
  // (a,b) -> 16a+b are the sixteen address bytes; 256*hi+lo pairs them.
9968
  const __m256i hextets = _mm256_madd_epi16(
9969
      _mm256_maddubs_epi16(gathered, _mm256_set1_epi16(0x0110)),
9970
      _mm256_set1_epi32(0x00010100));
9971
  _mm_storeu_si128(reinterpret_cast<__m128i*>(address.data()),
9972
                   _mm256_cvtepi32_epi16(hextets));
9973
}
9974
9975
// Parse an IPv6 host with one masked 512-bit load. Derived from
9976
// vtlmks/ipv6-avx512 (Peter Fors, MIT).
9977
//
9978
// Returns false when the input is outside this kernel's grammar and the caller
9979
// must run the scalar parser. Otherwise `valid` receives the verdict, and
9980
// `address` the eight hextets when valid.
9981
ada_really_inline bool try_parse_ipv6_avx512(const char* data, size_t len,
9982
                                             std::array<uint16_t, 8>& address,
9983
                                             bool& valid) noexcept {
9984
  if (len < 2 || len > 45) [[unlikely]] {
9985
    return false;
9986
  }
9987
  // ':' rather than 0x80 for the colon, so a clamped index reads a zero nibble.
9988
  alignas(64) static constexpr uint8_t hex_lo[64] = {
9989
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9990
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9991
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9992
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9993
      0x80, 0x80, 0x80, 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
9994
      0x07, 0x08, 0x09, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80};
9995
  alignas(64) static constexpr uint8_t hex_hi[64] = {
9996
      0x80, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x80, 0x80, 0x80, 0x80,
9997
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9998
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
9999
      0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x80,
10000
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
10001
      0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
10002
  alignas(64) static constexpr uint8_t iota[64] = {
10003
      0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
10004
      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
10005
      32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
10006
      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63};
10007
10008
  const __mmask64 active =
10009
      static_cast<__mmask64>(_bzhi_u64(~0ULL, static_cast<uint32_t>(len)));
10010
  const __m512i colon = _mm512_set1_epi8(':');
10011
  // Merging ':' into the tail makes the terminator at `len` a real colon, so
10012
  // the compress mask below never has to be rebuilt in a general register.
10013
  const __m512i v = _mm512_mask_loadu_epi8(colon, active, data);
10014
  const __mmask64 mcolon = _mm512_cmpeq_epi8_mask(v, colon);
10015
10016
  // An embedded dotted quad is the one valid form this kernel does not cover.
10017
  // Because that is the only gap, every other input it does not accept is
10018
  // invalid, which is what makes `valid = false` below safe.
10019
  if (_mm512_cmpeq_epi8_mask(v, _mm512_set1_epi8('.'))) [[unlikely]] {
10020
    return false;
10021
  }
10022
10023
  const __m512i nib = _mm512_permutex2var_epi8(_mm512_load_si512(hex_lo), v,
10024
                                               _mm512_load_si512(hex_hi));
10025
  const __m128i comp = _mm512_castsi512_si128(
10026
      _mm512_maskz_compress_epi8(mcolon, _mm512_load_si512(iota)));
10027
  const __m128i lane0 =
10028
      _mm_setr_epi8(-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
10029
  const __m128i prev = _mm_or_si128(_mm_bslli_si128(comp, 1), lane0);
10030
  const __m128i width = _mm_sub_epi8(comp, prev);  // one too large
10031
10032
  const uint64_t mc = static_cast<uint64_t>(mcolon);
10033
  const uint64_t act = static_cast<uint64_t>(active);
10034
  const uint64_t dc = mc & (mc >> 1) & (act >> 1);  // a "::" inside [0, len)
10035
10036
  if (!dc) {
10037
    ipv6_gather(comp, prev, nib, address);
10038
    // nib | (v & 0x80): one scan for non-hex bytes and for bytes whose high
10039
    // bit made vpermi2b alias a legal one.
10040
    const __m512i fused = _mm512_ternarylogic_epi32(
10041
        nib, v, _mm512_set1_epi8(static_cast<char>(0x80)), 0xf8);
10042
    // Lanes 8..15 bound against 255, which an unsigned byte cannot exceed.
10043
    const __m128i wmax =
10044
        _mm_setr_epi8(3, 3, 3, 3, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1);
10045
    __mmask64 err = _kandn_mask64(mcolon, _mm512_movepi8_mask(fused));
10046
    err = _kor_mask64(
10047
        err, static_cast<__mmask64>(static_cast<uint16_t>(_mm_cmpgt_epu8_mask(
10048
                 _mm_sub_epi8(width, _mm_set1_epi8(2)), wmax))));
10049
    valid = (_mm_popcnt_u64(mc & act) == 7) && !err;
10050
    return true;
10051
  }
10052
10053
  // Drop the zero-width gap field(s), then expand the surviving head and tail
10054
  // fields into eight slots with all-zero groups inserted at the gap.
10055
  const uint32_t head = static_cast<uint32_t>(_mm_popcnt_u64(mc & (dc - 1))) +
10056
                        static_cast<uint32_t>(dc > 1);
10057
  const __mmask16 keep = _mm_cmpgt_epi8_mask(width, _mm_set1_epi8(1));
10058
  const uint32_t kept = static_cast<uint32_t>(_mm_popcnt_u32(keep));
10059
  const __mmask16 slots = static_cast<__mmask16>(
10060
      ~(_bzhi_u32(0xFFFFFFFFu, 8 - kept) << head) & 0xFFu);
10061
  // Inserted groups take prev = -1, so their indices clamp to byte 63, a tail
10062
  // colon, and read zero.
10063
  ipv6_gather(_mm_maskz_expand_epi8(slots, _mm_maskz_compress_epi8(keep, comp)),
10064
              _mm_mask_expand_epi8(_mm_set1_epi8(-1), slots,
10065
                                   _mm_maskz_compress_epi8(keep, prev)),
10066
              nib, address);
10067
10068
  uint64_t err = _mm512_movepi8_mask(v);    // high-bit bytes
10069
  err |= _mm512_movepi8_mask(nib) & ~mc;    // non-hex
10070
  err |= _blsr_u64(dc);                     // a second "::"
10071
  err |= static_cast<uint64_t>(kept >= 8);  // "::" elides nothing
10072
  err |= _mm_cmpgt_epu8_mask(width, _mm_set1_epi8(5)) & keep;  // group > 4
10073
  err |= (mc & 1ULL) & ~dc;                                // leading lone ':'
10074
  err |= ((mc >> (len - 1)) & 1ULL) & ~(dc >> (len - 2));  // trailing lone ':'
10075
  valid = !err;
10076
  return true;
10077
}
10078
#endif  // ADA_AVX512_IPV6
10079
10080
}  // namespace ada::detail
10081
10082
#endif  // ADA_URL_IP_INL_H
10083
/* end file include/ada/url_ip-inl.h */
10084
10085
#include <algorithm>
10086
#include <array>
10087
#include <cstddef>
10088
#include <cstdint>
10089
#include <iterator>
10090
#include <numeric>
10091
#include <optional>
10092
#include <ranges>
10093
#include <string>
10094
#include <string_view>
10095
#include <utility>
10096
10097
namespace ada {
10098
10099
0
bool url::parse_opaque_host(std::string_view input) {
10100
0
  ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
10101
0
  if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) {
10102
0
    return is_valid = false;
10103
0
  }
10104
10105
  // Return the result of running UTF-8 percent-encode on input using the C0
10106
  // control percent-encode set.
10107
0
  host = ada::unicode::percent_encode(
10108
0
      input, ada::character_sets::C0_CONTROL_PERCENT_ENCODE);
10109
0
  return true;
10110
0
}
10111
10112
0
bool url::parse_ipv4(std::string_view input) {
10113
0
  ada_log("parse_ipv4 ", input, " [", input.size(), " bytes]");
10114
0
  if (input.empty()) {
10115
0
    return is_valid = false;
10116
0
  }
10117
0
  std::string_view original_input = input;
10118
0
  if (original_input.back() == '.') {
10119
0
    original_input.remove_suffix(1);
10120
0
  }
10121
0
  if (input.back() == '.') {
10122
0
    input.remove_suffix(1);
10123
0
    if (input.empty()) {
10124
0
      return is_valid = false;
10125
0
    }
10126
0
  }
10127
10128
0
  const uint64_t fast = checkers::try_parse_ipv4_fast(input);
10129
0
  if (fast < checkers::ipv4_fast_fail) [[likely]] {
10130
0
    host = original_input;
10131
0
    host_type = IPV4;
10132
0
    return true;
10133
0
  }
10134
10135
0
  const char* p = input.data();
10136
0
  const char* end = p + input.size();
10137
0
  uint64_t ipv4 = 0;
10138
0
  int digit_count = 0;
10139
0
  int pure_decimal_count = 0;
10140
10141
0
  for (; digit_count < 4 && p < end; ++digit_count) {
10142
0
    uint64_t segment = 0;
10143
0
    bool pure = false;
10144
0
    if (!detail::parse_ipv4_number(p, end, segment, pure)) {
10145
0
      return is_valid = false;
10146
0
    }
10147
0
    if (pure) {
10148
0
      ++pure_decimal_count;
10149
0
    }
10150
0
    if (p >= end) {
10151
0
      const unsigned shift = static_cast<unsigned>(32 - digit_count * 8);
10152
0
      if (segment >= (uint64_t{1} << shift)) {
10153
0
        return is_valid = false;
10154
0
      }
10155
0
      ipv4 = (ipv4 << shift) | segment;
10156
0
      host = (pure_decimal_count == 4) ? std::string(original_input)
10157
0
                                       : ada::serializers::ipv4(ipv4);
10158
0
      host_type = IPV4;
10159
0
      return true;
10160
0
    }
10161
0
    if (segment > 255 || *p != '.') {
10162
0
      return is_valid = false;
10163
0
    }
10164
0
    ipv4 = (ipv4 << 8) | segment;
10165
0
    ++p;
10166
0
  }
10167
0
  if (digit_count != 4 || p != end) {
10168
0
    return is_valid = false;
10169
0
  }
10170
0
  host = (pure_decimal_count == 4) ? std::string(original_input)
10171
0
                                   : ada::serializers::ipv4(ipv4);
10172
0
  host_type = IPV4;
10173
0
  return true;
10174
0
}
10175
10176
0
bool url::parse_ipv6(std::string_view input) {
10177
0
  ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
10178
0
  if (input.empty() || input.size() > 45) [[unlikely]] {
10179
0
    return is_valid = false;
10180
0
  }
10181
0
  std::array<uint16_t, 8> address{};
10182
#if defined(ADA_AVX512_IPV6)
10183
  if (bool simd_valid; detail::try_parse_ipv6_avx512(input.data(), input.size(),
10184
                                                     address, simd_valid)) {
10185
    if (!simd_valid) [[unlikely]] {
10186
      return is_valid = false;
10187
    }
10188
    host = ada::serializers::ipv6(address);
10189
    host_type = IPV6;
10190
    return true;
10191
  }
10192
  address = {};
10193
#endif
10194
0
  const char* pointer = input.data();
10195
0
  const char* const end = pointer + input.size();
10196
0
  int piece_index = 0;
10197
0
  int compress = -1;
10198
10199
0
  if (*pointer == ':') {
10200
0
    if (input.size() == 1 || pointer[1] != ':') [[unlikely]] {
10201
0
      return is_valid = false;
10202
0
    }
10203
0
    pointer += 2;
10204
0
    compress = ++piece_index;
10205
0
  }
10206
10207
0
  while (pointer != end) {
10208
0
    if (piece_index == 8) [[unlikely]] {
10209
0
      return is_valid = false;
10210
0
    }
10211
0
    if (*pointer == ':') {
10212
0
      if (compress != -1) [[unlikely]] {
10213
0
        return is_valid = false;
10214
0
      }
10215
0
      ++pointer;
10216
0
      compress = ++piece_index;
10217
0
      continue;
10218
0
    }
10219
10220
0
    uint16_t value = 0;
10221
0
    const int length = detail::parse_hex_piece(pointer, end, value);
10222
10223
0
    if (pointer != end && *pointer == '.') {
10224
0
      if (length == 0) [[unlikely]] {
10225
0
        return is_valid = false;
10226
0
      }
10227
0
      pointer -= length;
10228
0
      if (piece_index > 6) [[unlikely]] {
10229
0
        return is_valid = false;
10230
0
      }
10231
10232
0
      int numbers_seen = 0;
10233
0
      while (pointer != end) {
10234
0
        int ipv4_piece = -1;
10235
0
        if (numbers_seen > 0) {
10236
0
          if (*pointer == '.' && numbers_seen < 4) {
10237
0
            ++pointer;
10238
0
          } else {
10239
0
            return is_valid = false;
10240
0
          }
10241
0
        }
10242
0
        if (pointer == end || *pointer < '0' || *pointer > '9') [[unlikely]] {
10243
0
          return is_valid = false;
10244
0
        }
10245
0
        ipv4_piece = *pointer - '0';
10246
0
        ++pointer;
10247
0
        if (pointer != end && *pointer >= '0' && *pointer <= '9') {
10248
0
          if (ipv4_piece == 0) [[unlikely]] {
10249
0
            return is_valid = false;
10250
0
          }
10251
0
          ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
10252
0
          ++pointer;
10253
0
          if (pointer != end && *pointer >= '0' && *pointer <= '9') {
10254
0
            ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
10255
0
            ++pointer;
10256
0
            if (ipv4_piece > 255) [[unlikely]] {
10257
0
              return is_valid = false;
10258
0
            }
10259
0
          }
10260
0
        }
10261
0
        address[static_cast<size_t>(piece_index)] = static_cast<uint16_t>(
10262
0
            address[static_cast<size_t>(piece_index)] * 0x100 +
10263
0
            static_cast<uint16_t>(ipv4_piece));
10264
0
        ++numbers_seen;
10265
0
        if (numbers_seen == 2 || numbers_seen == 4) {
10266
0
          ++piece_index;
10267
0
        }
10268
0
      }
10269
0
      if (numbers_seen != 4) [[unlikely]] {
10270
0
        return is_valid = false;
10271
0
      }
10272
0
      break;
10273
0
    }
10274
10275
0
    if (length == 0) [[unlikely]] {
10276
0
      return is_valid = false;
10277
0
    }
10278
10279
0
    if (pointer != end && *pointer == ':') {
10280
0
      ++pointer;
10281
0
      if (pointer == end) [[unlikely]] {
10282
0
        return is_valid = false;
10283
0
      }
10284
0
    } else if (pointer != end) [[unlikely]] {
10285
0
      return is_valid = false;
10286
0
    }
10287
10288
0
    address[static_cast<size_t>(piece_index)] = value;
10289
0
    ++piece_index;
10290
0
  }
10291
10292
0
  if (compress != -1) {
10293
0
    const int right = piece_index - compress;
10294
0
    if (right > 0) {
10295
0
      const size_t dest = static_cast<size_t>(8 - right);
10296
0
      const size_t src = static_cast<size_t>(compress);
10297
0
      if (dest != src) {
10298
0
        for (size_t i = static_cast<size_t>(right); i-- > 0;) {
10299
0
          address[dest + i] = address[src + i];
10300
0
          address[src + i] = 0;
10301
0
        }
10302
0
      }
10303
0
    }
10304
0
  } else if (piece_index != 8) [[unlikely]] {
10305
0
    return is_valid = false;
10306
0
  }
10307
10308
0
  host = ada::serializers::ipv6(address);
10309
0
  ada_log("parse_ipv6 ", *host);
10310
0
  host_type = IPV6;
10311
0
  return true;
10312
0
}
10313
10314
template <bool has_state_override>
10315
0
ada_really_inline bool url::parse_scheme(const std::string_view input) {
10316
0
  auto parsed_type = ada::scheme::get_scheme_type(input);
10317
0
  bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
10318
  /**
10319
   * In the common case, we will immediately recognize a special scheme (e.g.,
10320
   *http, https), in which case, we can go really fast.
10321
   **/
10322
0
  if (is_input_special) {  // fast path!!!
10323
0
    if constexpr (has_state_override) {
10324
      // If url's scheme is not a special scheme and buffer is a special scheme,
10325
      // then return.
10326
0
      if (is_special() != is_input_special) {
10327
0
        return false;
10328
0
      }
10329
10330
      // If url includes credentials or has a non-null port, and buffer is
10331
      // "file", then return.
10332
0
      if ((has_credentials() || port.has_value()) &&
10333
0
          parsed_type == ada::scheme::type::FILE) {
10334
0
        return false;
10335
0
      }
10336
10337
      // If url's scheme is "file" and its host is an empty host, then return.
10338
      // An empty host is the empty string.
10339
0
      if (type == ada::scheme::type::FILE && host.has_value() &&
10340
0
          host->empty()) {
10341
0
        return false;
10342
0
      }
10343
0
    }
10344
10345
0
    type = parsed_type;
10346
10347
0
    if constexpr (has_state_override) {
10348
      // This is uncommon.
10349
0
      uint16_t urls_scheme_port = get_special_port();
10350
10351
0
      if (urls_scheme_port) {
10352
        // If url's port is url's scheme's default port, then set url's port to
10353
        // null.
10354
0
        if (port.has_value() && *port == urls_scheme_port) {
10355
0
          port = std::nullopt;
10356
0
        }
10357
0
      }
10358
0
    }
10359
0
  } else {  // slow path
10360
0
    std::string _buffer(input);
10361
    // Next function is only valid if the input is ASCII and returns false
10362
    // otherwise, but it seems that we always have ascii content so we do not
10363
    // need to check the return value.
10364
    // bool is_ascii =
10365
0
    unicode::to_lower_ascii(_buffer.data(), _buffer.size());
10366
10367
0
    if constexpr (has_state_override) {
10368
      // The state-override validation errors below ("return" in the WHATWG URL
10369
      // parser) leave the URL unchanged. The setter contract is
10370
      // "true on success, false if the scheme is invalid" -- the fast path
10371
      // above already returns false here, so the slow path must agree.
10372
10373
      // If url's scheme is a special scheme and buffer is not a special scheme,
10374
      // then return. If url's scheme is not a special scheme and buffer is a
10375
      // special scheme, then return.
10376
0
      if (is_special() != ada::scheme::is_special(_buffer)) {
10377
0
        return false;
10378
0
      }
10379
10380
      // If url includes credentials or has a non-null port, and buffer is
10381
      // "file", then return.
10382
0
      if ((has_credentials() || port.has_value()) && _buffer == "file") {
10383
0
        return false;
10384
0
      }
10385
10386
      // If url's scheme is "file" and its host is an empty host, then return.
10387
      // An empty host is the empty string.
10388
0
      if (type == ada::scheme::type::FILE && host.has_value() &&
10389
0
          host->empty()) {
10390
0
        return false;
10391
0
      }
10392
0
    }
10393
10394
0
    set_scheme(std::move(_buffer));
10395
10396
0
    if constexpr (has_state_override) {
10397
      // This is uncommon.
10398
0
      uint16_t urls_scheme_port = get_special_port();
10399
10400
0
      if (urls_scheme_port) {
10401
        // If url's port is url's scheme's default port, then set url's port to
10402
        // null.
10403
0
        if (port.has_value() && *port == urls_scheme_port) {
10404
0
          port = std::nullopt;
10405
0
        }
10406
0
      }
10407
0
    }
10408
0
  }
10409
10410
0
  return true;
10411
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> >)
10412
10413
0
ada_really_inline bool url::parse_host(std::string_view input) {
10414
0
  ada_log("parse_host ", input, " [", input.size(), " bytes]");
10415
0
  if (input.empty()) {
10416
0
    return is_valid = false;
10417
0
  }  // technically unnecessary.
10418
  // If input starts with U+005B ([), then:
10419
0
  if (input[0] == '[') {
10420
    // If input does not end with U+005D (]), validation error, return failure.
10421
0
    if (input.back() != ']') {
10422
0
      return is_valid = false;
10423
0
    }
10424
0
    ada_log("parse_host ipv6");
10425
10426
    // Return the result of IPv6 parsing input with its leading U+005B ([) and
10427
    // trailing U+005D (]) removed.
10428
0
    input.remove_prefix(1);
10429
0
    input.remove_suffix(1);
10430
0
    return parse_ipv6(input);
10431
0
  }
10432
10433
  // If isNotSpecial is true, then return the result of opaque-host parsing
10434
  // input.
10435
0
  if (!is_special()) {
10436
0
    return parse_opaque_host(input);
10437
0
  }
10438
10439
  // Fast path: try to parse as pure decimal IPv4 first.
10440
0
  const uint64_t fast_result = checkers::try_parse_ipv4_fast(input);
10441
0
  if (fast_result < checkers::ipv4_fast_fail) {
10442
0
    if (!input.empty() && input.back() == '.') {
10443
0
      host = input.substr(0, input.size() - 1);
10444
0
    } else {
10445
0
      host = input;
10446
0
    }
10447
0
    host_type = IPV4;
10448
0
    is_valid = true;
10449
0
    ada_log("parse_host fast path decimal ipv4");
10450
0
    return true;
10451
0
  }
10452
  // Let domain be the result of running UTF-8 decode without BOM on the
10453
  // percent-decoding of input. Let asciiDomain be the result of running domain
10454
  // to ASCII with domain and false. The most common case is an ASCII input, in
10455
  // which case we do not need to call the expensive 'to_ascii' if a few
10456
  // conditions are met: no '%' and no 'xn-' subsequence.
10457
0
  const uint8_t forbidden_or_upper =
10458
0
      unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
10459
0
                                                             input.size());
10460
0
  static constexpr std::string_view xn_dash{"xn-", 3};
10461
0
  if ((forbidden_or_upper & 1) == 0) {
10462
0
    host = std::string(input);
10463
0
    if ((forbidden_or_upper & 2) != 0) {
10464
0
      unicode::to_lower_ascii(host->data(), host->size());
10465
0
    }
10466
0
    if (host->find('-') == std::string_view::npos ||
10467
0
        host->find(xn_dash) == std::string_view::npos) {
10468
0
      if (checkers::is_ipv4(*host)) {
10469
0
        ada_log("parse_host fast path ipv4");
10470
0
        return parse_ipv4(*host);
10471
0
      }
10472
0
      ada_log("parse_host fast path ", *host);
10473
0
      is_valid = true;
10474
0
      return true;
10475
0
    }
10476
0
  } else if (const size_t first_percent = input.find('%');
10477
0
             first_percent != std::string_view::npos) {
10478
0
    std::string decoded = unicode::percent_decode(input, first_percent);
10479
0
    const uint8_t decoded_flags =
10480
0
        unicode::contains_forbidden_domain_code_point_or_upper(decoded.data(),
10481
0
                                                               decoded.size());
10482
0
    if ((decoded_flags & 1) == 0) {
10483
0
      if ((decoded_flags & 2) != 0) {
10484
0
        unicode::to_lower_ascii(decoded.data(), decoded.size());
10485
0
      }
10486
0
      if (decoded.find('-') == std::string_view::npos ||
10487
0
          decoded.find(xn_dash) == std::string_view::npos) {
10488
0
        host = std::move(decoded);
10489
0
        if (checkers::is_ipv4(*host)) {
10490
0
          return parse_ipv4(*host);
10491
0
        }
10492
0
        is_valid = true;
10493
0
        return true;
10494
0
      }
10495
0
    }
10496
0
  }
10497
0
  ada_log("parse_host calling to_ascii");
10498
0
  is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
10499
0
  if (!is_valid || !host.has_value()) {
10500
0
    ada_log("parse_host to_ascii returns false");
10501
0
    return is_valid = false;
10502
0
  }
10503
0
  ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
10504
0
          " bytes]");
10505
10506
0
  if (std::any_of(host->begin(), host->end(),
10507
0
                  ada::unicode::is_forbidden_domain_code_point)) {
10508
0
    host = std::nullopt;
10509
0
    return is_valid = false;
10510
0
  }
10511
10512
  // If asciiDomain ends in a number, then return the result of IPv4 parsing
10513
  // asciiDomain.
10514
0
  if (checkers::is_ipv4(*host)) {
10515
0
    ada_log("parse_host got ipv4 ", *host);
10516
0
    return parse_ipv4(*host);
10517
0
  }
10518
10519
0
  return true;
10520
0
}
10521
10522
0
ada_really_inline void url::parse_path(std::string_view input) {
10523
0
  ada_log("parse_path ", input);
10524
0
  std::string tmp_buffer;
10525
0
  std::string_view internal_input;
10526
0
  if (unicode::has_tabs_or_newline(input)) {
10527
0
    tmp_buffer = input;
10528
    // Optimization opportunity: Instead of copying and then pruning, we could
10529
    // just directly build the string from user_input.
10530
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
10531
0
    internal_input = tmp_buffer;
10532
0
  } else {
10533
0
    internal_input = input;
10534
0
  }
10535
10536
  // If url is special, then:
10537
0
  if (is_special()) {
10538
0
    if (internal_input.empty()) {
10539
0
      path = "/";
10540
0
    } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
10541
0
      helpers::parse_prepared_path(internal_input.substr(1), type, path);
10542
0
    } else {
10543
0
      helpers::parse_prepared_path(internal_input, type, path);
10544
0
    }
10545
0
  } else if (!internal_input.empty()) {
10546
0
    if (internal_input[0] == '/') {
10547
0
      helpers::parse_prepared_path(internal_input.substr(1), type, path);
10548
0
    } else {
10549
0
      helpers::parse_prepared_path(internal_input, type, path);
10550
0
    }
10551
0
  } else {
10552
0
    if (!host.has_value()) {
10553
0
      path = "/";
10554
0
    }
10555
0
  }
10556
0
}
10557
10558
0
[[nodiscard]] std::string url::to_string() const {
10559
0
  if (!is_valid) {
10560
0
    return "null";
10561
0
  }
10562
0
  std::string answer;
10563
0
  auto back = std::back_insert_iterator(answer);
10564
0
  answer.append("{\n");
10565
0
  answer.append("\t\"protocol\":\"");
10566
0
  helpers::encode_json(get_protocol(), back);
10567
0
  answer.append("\",\n");
10568
0
  if (has_credentials()) {
10569
0
    answer.append("\t\"username\":\"");
10570
0
    helpers::encode_json(username, back);
10571
0
    answer.append("\",\n");
10572
0
    answer.append("\t\"password\":\"");
10573
0
    helpers::encode_json(password, back);
10574
0
    answer.append("\",\n");
10575
0
  }
10576
0
  if (host.has_value()) {
10577
0
    answer.append("\t\"host\":\"");
10578
0
    helpers::encode_json(host.value(), back);
10579
0
    answer.append("\",\n");
10580
0
  }
10581
0
  if (port.has_value()) {
10582
0
    answer.append("\t\"port\":\"");
10583
0
    answer.append(std::to_string(port.value()));
10584
0
    answer.append("\",\n");
10585
0
  }
10586
0
  answer.append("\t\"path\":\"");
10587
0
  helpers::encode_json(path, back);
10588
0
  answer.append("\",\n");
10589
0
  answer.append("\t\"opaque path\":");
10590
0
  answer.append((has_opaque_path ? "true" : "false"));
10591
0
  if (has_search()) {
10592
0
    answer.append(",\n");
10593
0
    answer.append("\t\"query\":\"");
10594
    // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
10595
0
    helpers::encode_json(query.value(), back);
10596
0
    answer.append("\"");
10597
0
  }
10598
0
  if (hash.has_value()) {
10599
0
    answer.append(",\n");
10600
0
    answer.append("\t\"hash\":\"");
10601
0
    helpers::encode_json(hash.value(), back);
10602
0
    answer.append("\"");
10603
0
  }
10604
0
  answer.append("\n}");
10605
0
  return answer;
10606
0
}
10607
10608
0
[[nodiscard]] bool url::has_valid_domain() const noexcept {
10609
0
  if (!host.has_value()) {
10610
0
    return false;
10611
0
  }
10612
0
  return checkers::verify_dns_length(*host);
10613
0
}
10614
10615
0
[[nodiscard]] std::string url::get_origin() const {
10616
0
  if (is_special()) {
10617
    // Return a new opaque origin.
10618
0
    if (type == scheme::FILE) {
10619
0
      return "null";
10620
0
    }
10621
0
    return ada::helpers::concat(get_protocol(), "//", get_host());
10622
0
  }
10623
10624
0
  if (non_special_scheme == "blob") {
10625
0
    if (!path.empty()) {
10626
0
      auto result = ada::parse<ada::url>(path);
10627
0
      if (result &&
10628
0
          (result->type == scheme::HTTP || result->type == scheme::HTTPS)) {
10629
        // If pathURL's scheme is not "http" and not "https", then return a
10630
        // new opaque origin.
10631
0
        return ada::helpers::concat(result->get_protocol(), "//",
10632
0
                                    result->get_host());
10633
0
      }
10634
0
    }
10635
0
  }
10636
10637
  // Return a new opaque origin.
10638
0
  return "null";
10639
0
}
10640
10641
0
[[nodiscard]] std::string url::get_protocol() const {
10642
0
  if (is_special()) {
10643
0
    return helpers::concat(ada::scheme::details::is_special_list[type], ":");
10644
0
  }
10645
  // We only move the 'scheme' if it is non-special.
10646
0
  return helpers::concat(non_special_scheme, ":");
10647
0
}
10648
10649
0
[[nodiscard]] std::string url::get_host() const {
10650
  // If url's host is null, then return the empty string.
10651
  // If url's port is null, return url's host, serialized.
10652
  // Return url's host, serialized, followed by U+003A (:) and url's port,
10653
  // serialized.
10654
0
  if (!host.has_value()) {
10655
0
    return "";
10656
0
  }
10657
0
  if (port.has_value()) {
10658
0
    return host.value() + ":" + get_port();
10659
0
  }
10660
0
  return host.value();
10661
0
}
10662
10663
0
[[nodiscard]] std::string url::get_hostname() const {
10664
0
  return host.value_or("");
10665
0
}
10666
10667
0
[[nodiscard]] std::string url::get_search() const {
10668
  // If this's URL's query is either null or the empty string, then return the
10669
  // empty string. Return U+003F (?), followed by this's URL's query.
10670
0
  return (!query.has_value() || (query->empty())) ? "" : "?" + query.value();
10671
0
}
10672
10673
0
[[nodiscard]] const std::string& url::get_username() const noexcept {
10674
0
  return username;
10675
0
}
10676
10677
0
[[nodiscard]] const std::string& url::get_password() const noexcept {
10678
0
  return password;
10679
0
}
10680
10681
0
[[nodiscard]] std::string url::get_port() const {
10682
0
  return port.has_value() ? std::to_string(port.value()) : "";
10683
0
}
10684
10685
0
[[nodiscard]] std::string url::get_hash() const {
10686
  // If this's URL's fragment is either null or the empty string, then return
10687
  // the empty string. Return U+0023 (#), followed by this's URL's fragment.
10688
0
  return (!hash.has_value() || (hash->empty())) ? "" : "#" + hash.value();
10689
0
}
10690
10691
0
bool url::needs_rollback_snapshot(size_t input_len) const noexcept {
10692
0
  return get_href_size() + input_len + 16 > ada::get_max_input_length();
10693
0
}
10694
10695
template <bool override_hostname>
10696
0
bool url::set_host_or_hostname(const std::string_view input) {
10697
0
  if (has_opaque_path) {
10698
0
    return false;
10699
0
  }
10700
10701
0
  url saved_url(*this);
10702
10703
0
  size_t host_end_pos = input.find('#');
10704
0
  std::string _host(input.data(), host_end_pos != std::string_view::npos
10705
0
                                      ? host_end_pos
10706
0
                                      : input.size());
10707
0
  helpers::remove_ascii_tab_or_newline(_host);
10708
0
  std::string_view new_host(_host);
10709
10710
0
  auto check_url_size = [&]() -> bool {
10711
0
    if (get_href_size() > ada::get_max_input_length()) {
10712
0
      *this = std::move(saved_url);
10713
0
      return false;
10714
0
    }
10715
0
    return true;
10716
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
10717
10718
  // If url's scheme is "file", then set state to file host state, instead of
10719
  // host state.
10720
0
  if (type != ada::scheme::type::FILE) {
10721
0
    std::string_view host_view(_host.data(), _host.length());
10722
0
    auto [location, found_colon] =
10723
0
        helpers::get_host_delimiter_location(is_special(), host_view);
10724
10725
    // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
10726
    // Note: the 'found_colon' value is true if and only if a colon was
10727
    // encountered while not inside brackets.
10728
0
    if (found_colon) {
10729
      // If buffer is the empty string, host-missing validation error, return
10730
      // failure.
10731
0
      std::string_view buffer = host_view.substr(0, location);
10732
0
      if (buffer.empty()) {
10733
0
        return false;
10734
0
      }
10735
10736
      // If state override is given and state override is hostname state, then
10737
      // return failure.
10738
0
      if constexpr (override_hostname) {
10739
0
        return false;
10740
0
      }
10741
10742
      // Let host be the result of host parsing buffer with url is not special.
10743
0
      bool succeeded = parse_host(buffer);
10744
0
      if (!succeeded) {
10745
0
        *this = std::move(saved_url);
10746
0
        return false;
10747
0
      }
10748
10749
      // Set url's host to host, buffer to the empty string, and state to port
10750
      // state.
10751
0
      std::string_view port_buffer = new_host.substr(location + 1);
10752
0
      if (!port_buffer.empty()) {
10753
0
        set_port(port_buffer);
10754
0
      }
10755
0
      return check_url_size();
10756
0
    }
10757
    // Otherwise, if one of the following is true:
10758
    // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
10759
    // - url is special and c is U+005C (\)
10760
0
    else {
10761
      // If url is special and host_view is the empty string, host-missing
10762
      // validation error, return failure.
10763
0
      if (host_view.empty() && is_special()) {
10764
0
        return false;
10765
0
      }
10766
10767
      // Otherwise, if state override is given, host_view is the empty string,
10768
      // and either url includes credentials or url's port is non-null, then
10769
      // return failure.
10770
0
      if (host_view.empty() && (has_credentials() || port.has_value())) {
10771
0
        return false;
10772
0
      }
10773
10774
      // Let host be the result of host parsing host_view with url is not
10775
      // special.
10776
0
      if (host_view.empty() && !is_special()) {
10777
0
        host = "";
10778
0
        return check_url_size();
10779
0
      }
10780
10781
0
      bool succeeded = parse_host(host_view);
10782
0
      if (!succeeded) {
10783
0
        *this = std::move(saved_url);
10784
0
        return false;
10785
0
      }
10786
0
      return check_url_size();
10787
0
    }
10788
0
  }
10789
10790
0
  size_t location = new_host.find_first_of("/\\?");
10791
0
  if (location != std::string_view::npos) {
10792
0
    new_host.remove_suffix(new_host.length() - location);
10793
0
  }
10794
10795
0
  if (new_host.empty()) {
10796
    // Set url's host to the empty string.
10797
0
    host = "";
10798
0
  } else {
10799
    // Let host be the result of host parsing buffer with url is not special.
10800
0
    if (!parse_host(new_host)) {
10801
0
      *this = std::move(saved_url);
10802
0
      return false;
10803
0
    }
10804
10805
    // If host is "localhost", then set host to the empty string.
10806
0
    if (host == "localhost") {
10807
0
      host = "";
10808
0
    }
10809
0
  }
10810
0
  return check_url_size();
10811
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> >)
10812
10813
0
bool url::set_host(const std::string_view input) {
10814
0
  return set_host_or_hostname<false>(input);
10815
0
}
10816
10817
0
bool url::set_hostname(const std::string_view input) {
10818
0
  return set_host_or_hostname<true>(input);
10819
0
}
10820
10821
0
bool url::set_username(const std::string_view input) {
10822
0
  if (cannot_have_credentials_or_port()) {
10823
0
    return false;
10824
0
  }
10825
0
  auto previous_username = std::move(username);
10826
0
  username = ada::unicode::percent_encode(
10827
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
10828
0
  if (get_href_size() > ada::get_max_input_length()) {
10829
0
    username = std::move(previous_username);
10830
0
    return false;
10831
0
  }
10832
0
  return true;
10833
0
}
10834
10835
0
bool url::set_password(const std::string_view input) {
10836
0
  if (cannot_have_credentials_or_port()) {
10837
0
    return false;
10838
0
  }
10839
0
  auto previous_password = std::move(password);
10840
0
  password = ada::unicode::percent_encode(
10841
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
10842
0
  if (get_href_size() > ada::get_max_input_length()) {
10843
0
    password = std::move(previous_password);
10844
0
    return false;
10845
0
  }
10846
0
  return true;
10847
0
}
10848
10849
0
bool url::set_port(const std::string_view input) {
10850
0
  if (cannot_have_credentials_or_port()) {
10851
0
    return false;
10852
0
  }
10853
10854
0
  if (input.empty()) {
10855
0
    port = std::nullopt;
10856
0
    return true;
10857
0
  }
10858
10859
0
  std::string trimmed(input);
10860
0
  helpers::remove_ascii_tab_or_newline(trimmed);
10861
10862
0
  if (trimmed.empty()) {
10863
0
    return true;
10864
0
  }
10865
10866
  // Input should not start with a non-digit character.
10867
0
  if (!ada::unicode::is_ascii_digit(trimmed.front())) {
10868
0
    return false;
10869
0
  }
10870
10871
  // Find the first non-digit character to determine the length of digits
10872
0
  auto first_non_digit =
10873
0
      std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit);
10874
0
  std::string_view digits_to_parse =
10875
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
10876
10877
  // Revert changes if parse_port fails.
10878
0
  std::optional<uint16_t> previous_port = port;
10879
0
  parse_port(digits_to_parse);
10880
0
  if (is_valid) {
10881
0
    if (get_href_size() > ada::get_max_input_length()) {
10882
0
      port = std::move(previous_port);
10883
0
      return false;
10884
0
    }
10885
0
    return true;
10886
0
  }
10887
0
  port = std::move(previous_port);
10888
0
  is_valid = true;
10889
0
  return false;
10890
0
}
10891
10892
0
void url::set_hash(const std::string_view input) {
10893
0
  if (input.empty()) {
10894
0
    hash = std::nullopt;
10895
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
10896
0
    return;
10897
0
  }
10898
10899
0
  std::string new_value;
10900
0
  new_value = input[0] == '#' ? input.substr(1) : input;
10901
0
  helpers::remove_ascii_tab_or_newline(new_value);
10902
0
  auto previous_hash = std::move(hash);
10903
0
  hash = unicode::percent_encode(new_value,
10904
0
                                 ada::character_sets::FRAGMENT_PERCENT_ENCODE);
10905
0
  if (get_href_size() > ada::get_max_input_length()) {
10906
0
    hash = std::move(previous_hash);
10907
0
  }
10908
0
}
10909
10910
0
void url::set_search(const std::string_view input) {
10911
0
  if (input.empty()) {
10912
0
    query = std::nullopt;
10913
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
10914
0
    return;
10915
0
  }
10916
10917
0
  std::string new_value;
10918
0
  new_value = input[0] == '?' ? input.substr(1) : input;
10919
0
  helpers::remove_ascii_tab_or_newline(new_value);
10920
10921
0
  auto query_percent_encode_set =
10922
0
      is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
10923
0
                   : ada::character_sets::QUERY_PERCENT_ENCODE;
10924
10925
0
  auto previous_query = std::move(query);
10926
0
  query = ada::unicode::percent_encode(new_value, query_percent_encode_set);
10927
0
  if (get_href_size() > ada::get_max_input_length()) {
10928
0
    query = std::move(previous_query);
10929
0
  }
10930
0
}
10931
10932
0
bool url::set_pathname(const std::string_view input) {
10933
0
  if (has_opaque_path) {
10934
0
    return false;
10935
0
  }
10936
0
  auto previous_path = std::move(path);
10937
0
  path.clear();
10938
0
  parse_path(input);
10939
0
  if (get_href_size() > ada::get_max_input_length()) {
10940
0
    path = std::move(previous_path);
10941
0
    return false;
10942
0
  }
10943
0
  return true;
10944
0
}
10945
10946
0
bool url::set_protocol(const std::string_view input) {
10947
0
  std::string view(input);
10948
0
  helpers::remove_ascii_tab_or_newline(view);
10949
0
  if (view.empty()) {
10950
0
    return true;
10951
0
  }
10952
10953
  // Schemes should start with alpha values.
10954
0
  if (!checkers::is_alpha(view[0])) {
10955
0
    return false;
10956
0
  }
10957
10958
0
  view.append(":");
10959
10960
0
  std::string::iterator pointer =
10961
0
      std::ranges::find_if_not(view, unicode::is_alnum_plus);
10962
10963
0
  if (pointer != view.end() && *pointer == ':') {
10964
0
    std::optional<url> saved_url;
10965
0
    if (needs_rollback_snapshot(view.size())) {
10966
0
      saved_url = *this;
10967
0
    }
10968
0
    bool result = parse_scheme<true>(
10969
0
        std::string_view(view.data(), pointer - view.begin()));
10970
0
    if (result && saved_url && get_href_size() > ada::get_max_input_length()) {
10971
0
      *this = std::move(*saved_url);
10972
0
      return false;
10973
0
    }
10974
0
    return result;
10975
0
  }
10976
0
  return false;
10977
0
}
10978
10979
0
bool url::set_href(const std::string_view input) {
10980
0
  ada::result<ada::url> out = ada::parse<ada::url>(input);
10981
10982
0
  if (out) {
10983
    // The parser enforces get_max_input_length() on both the input and the
10984
    // normalized result. This is a defense-in-depth check.
10985
0
    if (out->get_href_size() > ada::get_max_input_length()) {
10986
0
      return false;
10987
0
    }
10988
0
    *this = std::move(*out);
10989
0
  }
10990
10991
0
  return out.has_value();
10992
0
}
10993
10994
}  // namespace ada
10995
/* end file src/url.cpp */
10996
/* begin file src/parser.cpp */
10997
10998
#include <array>
10999
#include <bit>
11000
#include <charconv>
11001
#include <cstdint>
11002
#include <cstring>
11003
#include <limits>
11004
#include <optional>
11005
#include <ranges>
11006
#include <string>
11007
#include <string_view>
11008
#include <utility>
11009
11010
11011
#if ADA_NEON
11012
#include <arm_neon.h>
11013
#elif defined(__SSSE3__)
11014
#include <tmmintrin.h>
11015
#define ADA_PARSER_SSSE3 1
11016
#elif (defined(__x86_64__) || defined(__amd64__)) && defined(__GNUC__) && \
11017
    !defined(_MSC_VER)
11018
// gcc/clang honor target("ssse3"). clang-cl and MSVC do not: they still
11019
// compile the function as SSE2, then reject always_inline _mm_shuffle_epi8.
11020
#include <tmmintrin.h>
11021
#define ADA_PARSER_SSSE3 1
11022
#define ADA_PARSER_NEED_SSSE3_TARGET 1
11023
#elif ADA_SSE2
11024
#include <emmintrin.h>
11025
#endif
11026
#ifndef ADA_PARSER_SSSE3
11027
#define ADA_PARSER_SSSE3 0
11028
#endif
11029
11030
#ifdef ADA_PARSER_NEED_SSSE3_TARGET
11031
// Scan loops stay on the default ISA (SSE2 for generic x86-64). pshufb lives
11032
// in a noinline SSSE3 function so the CPU check is not inside a function the
11033
// compiler is free to compile entirely with SSSE3 instructions.
11034
#define ADA_PARSER_SIMD ada_really_inline
11035
#define ADA_PARSER_SSSE3_FN __attribute__((target("ssse3"), noinline))
11036
#else
11037
#define ADA_PARSER_SIMD ada_really_inline
11038
#define ADA_PARSER_SSSE3_FN ada_really_inline
11039
#endif
11040
11041
#ifdef ADA_REGULAR_VISUAL_STUDIO
11042
#include <intrin.h>
11043
#endif
11044
11045
namespace ada::parser {
11046
11047
// Classification tables and 16-byte run scanners for the absolute-URL fast
11048
// path. Inspired by oven-sh/WebKit#452 and #454: scan 16 bytes at a time
11049
// (nibble-table pshufb/tbl when SSSE3 or NEON is available), and when the
11050
// path/query/fragment is not already canonical, keep the parsed host and
11051
// finish with the existing path helpers instead of re-parsing from scratch.
11052
namespace {
11053
11054
// 0 = host byte, 1 = host delimiter (/ ? # :), 2 = reject
11055
constexpr std::array<uint8_t, 256> k_host_class = []() consteval {
11056
  std::array<uint8_t, 256> t{};
11057
  for (size_t i = 0; i < 256; ++i) {
11058
    t[i] = 2;
11059
  }
11060
  for (size_t i = 0x21; i <= 0x7E; ++i) {
11061
    t[i] = 0;
11062
  }
11063
  for (uint8_t c :
11064
       {'#', '/', ':', '<', '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
11065
    t[c] = 2;
11066
  }
11067
  t[static_cast<uint8_t>('/')] = 1;
11068
  t[static_cast<uint8_t>('?')] = 1;
11069
  t[static_cast<uint8_t>('#')] = 1;
11070
  t[static_cast<uint8_t>(':')] = 1;
11071
  return t;
11072
}();
11073
11074
// Path: 0 = copy, 1 = ?/#, 2 = needs work. Apostrophe is copyable in a path.
11075
constexpr std::array<uint8_t, 256> k_path = []() consteval {
11076
  std::array<uint8_t, 256> t{};
11077
  for (size_t i = 0; i < 256; ++i) {
11078
    t[i] = 2;
11079
  }
11080
  for (uint8_t c = 0x21; c <= 0x7E; ++c) {
11081
    t[c] = 0;
11082
  }
11083
  for (uint8_t c : {static_cast<uint8_t>('"'), static_cast<uint8_t>('<'),
11084
                    static_cast<uint8_t>('>'), static_cast<uint8_t>('`'),
11085
                    static_cast<uint8_t>('{'), static_cast<uint8_t>('}'),
11086
                    static_cast<uint8_t>('^'), static_cast<uint8_t>('\\'),
11087
                    static_cast<uint8_t>('%')}) {
11088
    t[c] = 2;
11089
  }
11090
  t[static_cast<uint8_t>('?')] = 1;
11091
  t[static_cast<uint8_t>('#')] = 1;
11092
  return t;
11093
}();
11094
11095
// Special-query: 0 = copy, 1 = #, 2 = needs work. Apostrophe must be encoded.
11096
constexpr std::array<uint8_t, 256> k_query = []() consteval {
11097
  std::array<uint8_t, 256> t{};
11098
  for (size_t i = 0; i < 256; ++i) {
11099
    t[i] = 2;
11100
  }
11101
  for (uint8_t c = 0x21; c <= 0x7E; ++c) {
11102
    t[c] = 0;
11103
  }
11104
  for (uint8_t c : {static_cast<uint8_t>('"'), static_cast<uint8_t>('<'),
11105
                    static_cast<uint8_t>('>'), static_cast<uint8_t>('\'')}) {
11106
    t[c] = 2;
11107
  }
11108
  t[static_cast<uint8_t>('#')] = 1;
11109
  return t;
11110
}();
11111
11112
// Fragment: 0 = copy, 2 = needs work. '?' '#' '%' are copyable.
11113
constexpr std::array<uint8_t, 256> k_hash = []() consteval {
11114
  std::array<uint8_t, 256> t{};
11115
  for (size_t i = 0; i < 256; ++i) {
11116
    t[i] = 2;
11117
  }
11118
  for (uint8_t c = 0x21; c <= 0x7E; ++c) {
11119
    t[c] = 0;
11120
  }
11121
  for (uint8_t c : {static_cast<uint8_t>('"'), static_cast<uint8_t>('<'),
11122
                    static_cast<uint8_t>('>'), static_cast<uint8_t>('`')}) {
11123
    t[c] = 2;
11124
  }
11125
  return t;
11126
}();
11127
11128
// Nibble tables for pshufb / tbl classification (oven-sh/WebKit#454).
11129
// A byte is a stop when low[b & 0xF] & high[b >> 4] != 0. High nibbles whose
11130
// sixteen bytes share a stop pattern share a bit, so any set with at most
11131
// eight distinct patterns fits. Tables are built from the scalar class
11132
// arrays, so the vector and scalar paths cannot disagree.
11133
struct nibble_tables {
11134
  alignas(16) uint8_t low[16]{};
11135
  alignas(16) uint8_t high[16]{};
11136
  bool fits{true};
11137
};
11138
11139
consteval nibble_tables make_stop_nibble_tables(
11140
    const std::array<uint8_t, 256>& cls) {
11141
  nibble_tables t{};
11142
  uint16_t patterns[16]{};
11143
  for (int hi = 0; hi < 16; ++hi) {
11144
    for (int lo = 0; lo < 16; ++lo) {
11145
      if (cls[static_cast<size_t>((hi << 4) | lo)] != 0) {
11146
        patterns[hi] = static_cast<uint16_t>(patterns[hi] | (1u << lo));
11147
      }
11148
    }
11149
  }
11150
  int bits_used = 0;
11151
  for (int hi = 0; hi < 16; ++hi) {
11152
    if (patterns[hi] == 0 || t.high[hi] != 0) {
11153
      continue;
11154
    }
11155
    if (bits_used == 8) {
11156
      t.fits = false;
11157
      return t;
11158
    }
11159
    const uint8_t bit = static_cast<uint8_t>(1u << bits_used++);
11160
    for (int other = hi; other < 16; ++other) {
11161
      if (patterns[other] == patterns[hi]) {
11162
        t.high[other] = static_cast<uint8_t>(t.high[other] | bit);
11163
      }
11164
    }
11165
    for (int lo = 0; lo < 16; ++lo) {
11166
      if ((patterns[hi] & (1u << lo)) != 0) {
11167
        t.low[lo] = static_cast<uint8_t>(t.low[lo] | bit);
11168
      }
11169
    }
11170
  }
11171
  return t;
11172
}
11173
11174
constexpr nibble_tables k_host_nibbles = make_stop_nibble_tables(k_host_class);
11175
constexpr nibble_tables k_path_nibbles = make_stop_nibble_tables(k_path);
11176
constexpr nibble_tables k_query_nibbles = make_stop_nibble_tables(k_query);
11177
constexpr nibble_tables k_hash_nibbles = make_stop_nibble_tables(k_hash);
11178
static_assert(k_host_nibbles.fits);
11179
static_assert(k_path_nibbles.fits);
11180
static_assert(k_query_nibbles.fits);
11181
static_assert(k_hash_nibbles.fits);
11182
11183
// WHATWG serializes a port as its decimal value with no leading zeros.
11184
0
ada_really_inline uint32_t port_decimal_digit_count(uint32_t port) noexcept {
11185
0
  uint32_t digits = 1;
11186
0
  while (port >= 10) {
11187
0
    port /= 10;
11188
0
    ++digits;
11189
0
  }
11190
0
  return digits;
11191
0
}
11192
11193
ada_really_inline void append_canonical_port(std::string& buffer,
11194
0
                                             uint32_t port) {
11195
0
  buffer += ':';
11196
0
  char port_buf[5];
11197
0
  auto [ptr, ec] = std::to_chars(port_buf, port_buf + 5, port);
11198
0
  (void)ec;
11199
0
  buffer.append(port_buf, static_cast<size_t>(ptr - port_buf));
11200
0
}
11201
11202
0
ada_really_inline int trailing_zeroes32(uint32_t input_num) noexcept {
11203
#ifdef ADA_REGULAR_VISUAL_STUDIO
11204
  unsigned long ret;
11205
  _BitScanForward(&ret, input_num);
11206
  return static_cast<int>(ret);
11207
#else
11208
0
  return __builtin_ctz(input_num);
11209
0
#endif
11210
0
}
11211
11212
0
ada_really_inline int trailing_zeroes64(uint64_t input_num) noexcept {
11213
0
#ifdef ADA_REGULAR_VISUAL_STUDIO
11214
0
  unsigned long ret;
11215
0
  _BitScanForward64(&ret, input_num);
11216
0
  return static_cast<int>(ret);
11217
0
#else
11218
0
  return __builtin_ctzll(input_num);
11219
0
#endif
11220
0
}
11221
11222
#if ADA_PARSER_SSSE3
11223
0
ADA_PARSER_SIMD __m128i nibble_load(const uint8_t* t) noexcept {
11224
0
  return _mm_load_si128(reinterpret_cast<const __m128i*>(t));
11225
0
}
11226
11227
// Non-zero lanes are stops. Tables are passed in so the scan loops can hoist
11228
// the loads out of the 16-byte iteration.
11229
ADA_PARSER_SSSE3_FN int ssse3_nibble_mask(__m128i w, __m128i lo_tbl,
11230
0
                                          __m128i hi_tbl) noexcept {
11231
0
  const __m128i nibble = _mm_set1_epi8(0x0F);
11232
0
  const __m128i lo = _mm_and_si128(w, nibble);
11233
0
  const __m128i hi = _mm_and_si128(_mm_srli_epi16(w, 4), nibble);
11234
0
  const __m128i hit =
11235
0
      _mm_and_si128(_mm_shuffle_epi8(lo_tbl, lo), _mm_shuffle_epi8(hi_tbl, hi));
11236
0
  return _mm_movemask_epi8(_mm_cmpeq_epi8(hit, _mm_setzero_si128())) ^ 0xFFFF;
11237
0
}
11238
#endif  // ADA_PARSER_SSSE3
11239
11240
#if ADA_SSE2
11241
#if !ADA_PARSER_SSSE3
11242
// Signed < 0x21 matches 0x00-0x20 and 0x80-0xFF; 0x7F is checked separately.
11243
ada_really_inline __m128i sse2_ctrl_or_nonascii(__m128i w) noexcept {
11244
  return _mm_or_si128(_mm_cmplt_epi8(w, _mm_set1_epi8(0x21)),
11245
                      _mm_cmpeq_epi8(w, _mm_set1_epi8(0x7F)));
11246
}
11247
11248
ada_really_inline int sse2_host_stop(__m128i w) noexcept {
11249
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
11250
  const __m128i is_upper = _mm_and_si128(
11251
      _mm_cmpgt_epi8(w, _mm_set1_epi8(static_cast<char>('A' - 1))),
11252
      _mm_cmplt_epi8(w, _mm_set1_epi8(static_cast<char>('Z' + 1))));
11253
  const __m128i at = _mm_sub_epi8(w, _mm_set1_epi8('@'));
11254
  const __m128i at_through_caret =
11255
      _mm_cmpeq_epi8(_mm_min_epu8(at, _mm_set1_epi8('^' - '@')), at);
11256
  const __m128i at_not_upper = _mm_andnot_si128(is_upper, at_through_caret);
11257
  const __m128i spec = _mm_or_si128(
11258
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('#')),
11259
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('%'))),
11260
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('/')),
11261
                                _mm_cmpeq_epi8(w, _mm_set1_epi8(':')))),
11262
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('<')),
11263
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('>'))),
11264
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('?')),
11265
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('|')))));
11266
  return _mm_movemask_epi8(
11267
      _mm_or_si128(_mm_or_si128(ctrl, at_not_upper), spec));
11268
}
11269
11270
ada_really_inline int sse2_path_stop(__m128i w) noexcept {
11271
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
11272
  const __m128i spec = _mm_or_si128(
11273
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('"')),
11274
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('#'))),
11275
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('%')),
11276
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('<')))),
11277
      _mm_or_si128(
11278
          _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('>')),
11279
                                    _mm_cmpeq_epi8(w, _mm_set1_epi8('?'))),
11280
                       _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('\\')),
11281
                                    _mm_cmpeq_epi8(w, _mm_set1_epi8('^')))),
11282
          _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('`')),
11283
                                    _mm_cmpeq_epi8(w, _mm_set1_epi8('{'))),
11284
                       _mm_cmpeq_epi8(w, _mm_set1_epi8('}')))));
11285
  return _mm_movemask_epi8(_mm_or_si128(ctrl, spec));
11286
}
11287
11288
ada_really_inline int sse2_query_stop(__m128i w) noexcept {
11289
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
11290
  const __m128i spec = _mm_or_si128(
11291
      _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('"')),
11292
                   _mm_cmpeq_epi8(w, _mm_set1_epi8('#'))),
11293
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('<')),
11294
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('>'))),
11295
                   _mm_cmpeq_epi8(w, _mm_set1_epi8('\''))));
11296
  return _mm_movemask_epi8(_mm_or_si128(ctrl, spec));
11297
}
11298
11299
ada_really_inline int sse2_hash_stop(__m128i w) noexcept {
11300
  const __m128i ctrl = sse2_ctrl_or_nonascii(w);
11301
  const __m128i spec =
11302
      _mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('"')),
11303
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('<'))),
11304
                   _mm_or_si128(_mm_cmpeq_epi8(w, _mm_set1_epi8('>')),
11305
                                _mm_cmpeq_epi8(w, _mm_set1_epi8('`'))));
11306
  return _mm_movemask_epi8(_mm_or_si128(ctrl, spec));
11307
}
11308
#endif  // !ADA_PARSER_SSSE3
11309
11310
0
ada_really_inline int sse2_uppercase(__m128i w) noexcept {
11311
0
  return _mm_movemask_epi8(_mm_and_si128(
11312
0
      _mm_cmpgt_epi8(w, _mm_set1_epi8(static_cast<char>('A' - 1))),
11313
0
      _mm_cmplt_epi8(w, _mm_set1_epi8(static_cast<char>('Z' + 1)))));
11314
0
}
11315
#endif  // ADA_SSE2
11316
11317
#if ADA_NEON
11318
ada_really_inline uint64_t neon_nibble_bits(uint8x16_t matches) noexcept {
11319
  const uint8x8_t nib = vshrn_n_u16(vreinterpretq_u16_u8(matches), 4);
11320
  return vget_lane_u64(vreinterpret_u64_u8(nib), 0);
11321
}
11322
11323
ada_really_inline uint64_t neon_table_stop(uint8x16_t w, uint8x16_t lo_tbl,
11324
                                           uint8x16_t hi_tbl) noexcept {
11325
  const uint8x16_t hit =
11326
      vandq_u8(vqtbl1q_u8(lo_tbl, vandq_u8(w, vdupq_n_u8(0x0F))),
11327
               vqtbl1q_u8(hi_tbl, vshrq_n_u8(w, 4)));
11328
  return neon_nibble_bits(vtstq_u8(hit, hit));
11329
}
11330
11331
ada_really_inline uint64_t neon_uppercase(uint8x16_t w) noexcept {
11332
  return neon_nibble_bits(
11333
      vandq_u8(vcgeq_u8(w, vdupq_n_u8('A')), vcleq_u8(w, vdupq_n_u8('Z'))));
11334
}
11335
#endif  // ADA_NEON
11336
11337
// True when '@' appears in the authority before '/', '?', or '#'.
11338
// One 16-byte window covers typical userinfo (SetHref's "user:pass@").
11339
// Longer userinfo still misses inside the never_inline fast path. No
11340
// '@' is a single load + compare so the parse hot path stays cheap.
11341
ada_really_inline bool authority_has_at(const uint8_t* p, size_t host_start,
11342
0
                                        size_t n) noexcept {
11343
0
  const size_t rem = n - host_start;
11344
0
  if (rem == 0) {
11345
0
    return false;
11346
0
  }
11347
#if ADA_NEON
11348
  if (rem >= 16) {
11349
    const uint8x16_t w = vld1q_u8(p + host_start);
11350
    const uint64_t at = neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('@')));
11351
    if (at == 0) {
11352
      return false;
11353
    }
11354
    const uint64_t delim = neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('/'))) |
11355
                           neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('?'))) |
11356
                           neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('#')));
11357
    return delim == 0 || std::countr_zero(at) < std::countr_zero(delim);
11358
  }
11359
#elif ADA_SSE2
11360
0
  if (rem >= 16) {
11361
0
    const __m128i w =
11362
0
        _mm_loadu_si128(reinterpret_cast<const __m128i*>(p + host_start));
11363
0
    const uint16_t at = static_cast<uint16_t>(
11364
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('@'))));
11365
0
    if (at == 0) {
11366
0
      return false;
11367
0
    }
11368
0
    const uint16_t delim = static_cast<uint16_t>(
11369
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('/'))) |
11370
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('?'))) |
11371
0
        _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('#'))));
11372
0
    return delim == 0 || std::countr_zero(at) < std::countr_zero(delim);
11373
0
  }
11374
0
#endif
11375
0
  const size_t lim = host_start + rem;
11376
0
  for (size_t i = host_start; i < lim; ++i) {
11377
0
    const uint8_t c = p[i];
11378
0
    if (c == '@') {
11379
0
      return true;
11380
0
    }
11381
0
    if (c == '/' || c == '?' || c == '#') {
11382
0
      return false;
11383
0
    }
11384
0
  }
11385
0
  return false;
11386
0
}
11387
11388
#if ADA_PARSER_SSSE3
11389
// True when this process can execute the SSSE3 scanners. When the binary was
11390
// built for SSSE3, the check is a constant. Otherwise it is cached from the
11391
// CPU and the scanners fall back to the scalar loops below.
11392
0
ada_really_inline bool parser_use_ssse3() noexcept {
11393
0
#ifdef ADA_PARSER_NEED_SSSE3_TARGET
11394
0
  static const bool supported = __builtin_cpu_supports("ssse3") != 0;
11395
0
  return supported;
11396
#else
11397
  return true;
11398
#endif
11399
0
}
11400
#endif
11401
11402
// Returns false if a forbidden host code point is found. On success, *end is
11403
// the first / ? # or len. has_upper / has_x only count host bytes, not the
11404
// path/query bytes that may sit in the same SIMD window after the delimiter.
11405
ADA_PARSER_SIMD bool scan_plain_host(const uint8_t* b, size_t start, size_t len,
11406
                                     size_t& end, bool& has_upper,
11407
0
                                     bool& has_x) noexcept {
11408
0
  has_upper = false;
11409
0
  has_x = false;
11410
0
  size_t i = start;
11411
0
#if ADA_PARSER_SSSE3
11412
0
  if (parser_use_ssse3() && (len - start >= 16)) {
11413
0
    const __m128i lo_tbl = nibble_load(k_host_nibbles.low);
11414
0
    const __m128i hi_tbl = nibble_load(k_host_nibbles.high);
11415
0
    const __m128i x_splat = _mm_set1_epi8('x');
11416
0
    auto visit = [&](size_t at) noexcept -> bool {
11417
0
      const __m128i w =
11418
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + at));
11419
0
      const int up = sse2_uppercase(w);
11420
0
      const int xs = _mm_movemask_epi8(_mm_cmpeq_epi8(w, x_splat));
11421
0
      const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);
11422
0
      if (mask == 0) {
11423
0
        if (up != 0) {
11424
0
          has_upper = true;
11425
0
        }
11426
0
        if (xs != 0) {
11427
0
          has_x = true;
11428
0
        }
11429
0
        return false;
11430
0
      }
11431
0
      const int hit = trailing_zeroes32(static_cast<uint32_t>(mask));
11432
0
      const int valid = (1 << hit) - 1;
11433
0
      if ((up & valid) != 0) {
11434
0
        has_upper = true;
11435
0
      }
11436
0
      if ((xs & valid) != 0) {
11437
0
        has_x = true;
11438
0
      }
11439
0
      end = at + static_cast<size_t>(hit);
11440
0
      return true;
11441
0
    };
11442
0
    for (; i + 32 <= len; i += 32) {
11443
0
      if (visit(i) || visit(i + 16)) {
11444
0
        return k_host_class[b[end]] == 1;
11445
0
      }
11446
0
    }
11447
0
    for (; i + 16 <= len; i += 16) {
11448
0
      if (visit(i)) {
11449
0
        return k_host_class[b[end]] == 1;
11450
0
      }
11451
0
    }
11452
    // Overlapping tail only after a full 16-byte step so the window cannot
11453
    // start before `start` (a prior '/' would otherwise look like a host stop).
11454
0
    if (i > start && i < len) {
11455
0
      if (visit(len - 16) && end >= i) {
11456
0
        return k_host_class[b[end]] == 1;
11457
0
      }
11458
0
      end = len;
11459
0
      return true;
11460
0
    }
11461
0
  }
11462
#elif ADA_SSE2
11463
  const __m128i x_splat = _mm_set1_epi8('x');
11464
  for (; i + 32 <= len; i += 32) {
11465
    for (size_t off = 0; off < 32; off += 16) {
11466
      const __m128i w =
11467
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i + off));
11468
      const int up = sse2_uppercase(w);
11469
      const int xs = _mm_movemask_epi8(_mm_cmpeq_epi8(w, x_splat));
11470
      const int mask = sse2_host_stop(w);
11471
      if (mask != 0) {
11472
        const int hit = trailing_zeroes32(static_cast<uint32_t>(mask));
11473
        const int valid = (1 << hit) - 1;
11474
        if ((up & valid) != 0) {
11475
          has_upper = true;
11476
        }
11477
        if ((xs & valid) != 0) {
11478
          has_x = true;
11479
        }
11480
        end = i + off + static_cast<size_t>(hit);
11481
        return k_host_class[b[end]] == 1;
11482
      }
11483
      if (up != 0) {
11484
        has_upper = true;
11485
      }
11486
      if (xs != 0) {
11487
        has_x = true;
11488
      }
11489
    }
11490
  }
11491
  for (; i + 16 <= len; i += 16) {
11492
    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11493
    const int up = sse2_uppercase(w);
11494
    const int xs = _mm_movemask_epi8(_mm_cmpeq_epi8(w, x_splat));
11495
    const int mask = sse2_host_stop(w);
11496
    if (mask != 0) {
11497
      const int hit = trailing_zeroes32(static_cast<uint32_t>(mask));
11498
      const int valid = (1 << hit) - 1;
11499
      if ((up & valid) != 0) {
11500
        has_upper = true;
11501
      }
11502
      if ((xs & valid) != 0) {
11503
        has_x = true;
11504
      }
11505
      end = i + static_cast<size_t>(hit);
11506
      return k_host_class[b[end]] == 1;
11507
    }
11508
    if (up != 0) {
11509
      has_upper = true;
11510
    }
11511
    if (xs != 0) {
11512
      has_x = true;
11513
    }
11514
  }
11515
#elif ADA_NEON
11516
  if (len - start >= 16) {
11517
    const uint8x16_t lo_tbl = vld1q_u8(k_host_nibbles.low);
11518
    const uint8x16_t hi_tbl = vld1q_u8(k_host_nibbles.high);
11519
    const uint8x16_t x_splat = vdupq_n_u8('x');
11520
    auto visit = [&](size_t at) noexcept -> bool {
11521
      const uint8x16_t w = vld1q_u8(b + at);
11522
      const uint64_t up = neon_uppercase(w);
11523
      const uint64_t xs = neon_nibble_bits(vceqq_u8(w, x_splat));
11524
      const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);
11525
      if (bits == 0) {
11526
        if (up != 0) {
11527
          has_upper = true;
11528
        }
11529
        if (xs != 0) {
11530
          has_x = true;
11531
        }
11532
        return false;
11533
      }
11534
      const size_t hit = static_cast<size_t>(trailing_zeroes64(bits)) >> 2;
11535
      const uint64_t valid = (hit == 0) ? 0 : (uint64_t{1} << (hit * 4)) - 1;
11536
      if ((up & valid) != 0) {
11537
        has_upper = true;
11538
      }
11539
      if ((xs & valid) != 0) {
11540
        has_x = true;
11541
      }
11542
      end = at + hit;
11543
      return true;
11544
    };
11545
    for (; i + 32 <= len; i += 32) {
11546
      if (visit(i) || visit(i + 16)) {
11547
        return k_host_class[b[end]] == 1;
11548
      }
11549
    }
11550
    for (; i + 16 <= len; i += 16) {
11551
      if (visit(i)) {
11552
        return k_host_class[b[end]] == 1;
11553
      }
11554
    }
11555
    if (i > start && i < len) {
11556
      if (visit(len - 16) && end >= i) {
11557
        return k_host_class[b[end]] == 1;
11558
      }
11559
      end = len;
11560
      return true;
11561
    }
11562
  }
11563
#endif
11564
0
  for (; i < len; ++i) {
11565
0
    const uint8_t c = b[i];
11566
0
    const uint8_t cls = k_host_class[c];
11567
0
    if (cls == 1) {
11568
0
      end = i;
11569
0
      return true;
11570
0
    }
11571
0
    if (cls == 2) {
11572
0
      return false;
11573
0
    }
11574
0
    if (c >= 'A' && c <= 'Z') {
11575
0
      has_upper = true;
11576
0
    } else if (c == 'x') {
11577
0
      has_x = true;
11578
0
    }
11579
0
  }
11580
0
  end = len;
11581
0
  return true;
11582
0
}
11583
11584
ada_really_inline void note_possible_dot_segment(
11585
    const uint8_t* b, size_t pos, size_t run_start,
11586
0
    bool& maybe_dot_segment) noexcept {
11587
0
  if (pos == run_start || b[pos - 1] == '/') {
11588
0
    maybe_dot_segment = true;
11589
0
  }
11590
0
}
11591
11592
#if ADA_PARSER_SSSE3 || ADA_SSE2
11593
// valid_mask selects bytes in this 16-byte window that belong to the path
11594
// (bits after a stop are cleared). A '.' starts a possible dot-segment when
11595
// it is the first path byte or immediately follows '/'.
11596
ada_really_inline void note_dots_in_window(const uint8_t* b, size_t i,
11597
                                           size_t run_start, __m128i w,
11598
                                           int valid_mask,
11599
0
                                           bool& maybe_dot_segment) noexcept {
11600
0
  if (maybe_dot_segment || valid_mask == 0) {
11601
0
    return;
11602
0
  }
11603
0
  const int dots =
11604
0
      _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('.'))) & valid_mask;
11605
0
  if (dots == 0) {
11606
0
    return;
11607
0
  }
11608
0
  const int slashes =
11609
0
      _mm_movemask_epi8(_mm_cmpeq_epi8(w, _mm_set1_epi8('/'))) & valid_mask;
11610
0
  if (((dots & 1) != 0 && (i == run_start || b[i - 1] == '/')) ||
11611
0
      (dots & (slashes << 1)) != 0) {
11612
0
    maybe_dot_segment = true;
11613
0
  }
11614
0
}
11615
#endif
11616
11617
#if ADA_NEON
11618
// Each NEON match nibble occupies 4 bits, so a '.' immediately after '/' is
11619
// (slashes << 4) rather than (slashes << 1).
11620
ada_really_inline void note_dots_in_window_neon(
11621
    const uint8_t* b, size_t i, size_t run_start, uint8x16_t w,
11622
    uint64_t valid_bits, bool& maybe_dot_segment) noexcept {
11623
  if (maybe_dot_segment || valid_bits == 0) {
11624
    return;
11625
  }
11626
  const uint64_t dots =
11627
      neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('.'))) & valid_bits;
11628
  if (dots == 0) {
11629
    return;
11630
  }
11631
  const uint64_t slashes =
11632
      neon_nibble_bits(vceqq_u8(w, vdupq_n_u8('/'))) & valid_bits;
11633
  if (((dots & 0xF) != 0 && (i == run_start || b[i - 1] == '/')) ||
11634
      (dots & (slashes << 4)) != 0) {
11635
    maybe_dot_segment = true;
11636
  }
11637
}
11638
#endif
11639
11640
// Advance i to the first path-class 1 or 2 character (or len).
11641
ADA_PARSER_SIMD void scan_path_run(const uint8_t* b, size_t& i, size_t len,
11642
0
                                   bool& maybe_dot_segment) noexcept {
11643
0
  const size_t run_start = i;
11644
0
#if ADA_PARSER_SSSE3
11645
0
  if (parser_use_ssse3() && (i + 16 <= len)) {
11646
0
    const __m128i lo_tbl = nibble_load(k_path_nibbles.low);
11647
0
    const __m128i hi_tbl = nibble_load(k_path_nibbles.high);
11648
0
    for (; i + 32 <= len; i += 32) {
11649
0
      const __m128i w0 =
11650
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11651
0
      const int m0 = ssse3_nibble_mask(w0, lo_tbl, hi_tbl);
11652
0
      if (m0 != 0) {
11653
0
        const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(m0));
11654
0
        note_dots_in_window(b, i, run_start, w0, (1 << hit_bit) - 1,
11655
0
                            maybe_dot_segment);
11656
0
        i += static_cast<size_t>(hit_bit);
11657
0
        return;
11658
0
      }
11659
0
      note_dots_in_window(b, i, run_start, w0, 0xFFFF, maybe_dot_segment);
11660
0
      const __m128i w1 =
11661
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i + 16));
11662
0
      const int m1 = ssse3_nibble_mask(w1, lo_tbl, hi_tbl);
11663
0
      if (m1 != 0) {
11664
0
        const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(m1));
11665
0
        note_dots_in_window(b, i + 16, run_start, w1, (1 << hit_bit) - 1,
11666
0
                            maybe_dot_segment);
11667
0
        i += 16 + static_cast<size_t>(hit_bit);
11668
0
        return;
11669
0
      }
11670
0
      note_dots_in_window(b, i + 16, run_start, w1, 0xFFFF, maybe_dot_segment);
11671
0
    }
11672
0
    for (; i + 16 <= len; i += 16) {
11673
0
      const __m128i w =
11674
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11675
0
      const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);
11676
0
      if (mask != 0) {
11677
0
        const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(mask));
11678
0
        note_dots_in_window(b, i, run_start, w, (1 << hit_bit) - 1,
11679
0
                            maybe_dot_segment);
11680
0
        i += static_cast<size_t>(hit_bit);
11681
0
        return;
11682
0
      }
11683
0
      note_dots_in_window(b, i, run_start, w, 0xFFFF, maybe_dot_segment);
11684
0
    }
11685
0
    if (i > run_start && i < len) {
11686
0
      const __m128i w =
11687
0
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + len - 16));
11688
0
      const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);
11689
0
      if (mask != 0) {
11690
0
        const size_t hit =
11691
0
            len - 16 +
11692
0
            static_cast<size_t>(trailing_zeroes32(static_cast<uint32_t>(mask)));
11693
0
        if (hit >= i) {
11694
0
          for (size_t j = i; j < hit; ++j) {
11695
0
            if (b[j] == '.') {
11696
0
              note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11697
0
            }
11698
0
          }
11699
0
          i = hit;
11700
0
          return;
11701
0
        }
11702
0
      }
11703
0
      for (size_t j = i; j < len; ++j) {
11704
0
        if (b[j] == '.') {
11705
0
          note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11706
0
        }
11707
0
      }
11708
0
      i = len;
11709
0
      return;
11710
0
    }
11711
0
  }
11712
#elif ADA_SSE2
11713
  for (; i + 16 <= len; i += 16) {
11714
    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));
11715
    const int mask = sse2_path_stop(w);
11716
    if (mask != 0) {
11717
      const int hit_bit = trailing_zeroes32(static_cast<uint32_t>(mask));
11718
      note_dots_in_window(b, i, run_start, w, (1 << hit_bit) - 1,
11719
                          maybe_dot_segment);
11720
      i += static_cast<size_t>(hit_bit);
11721
      return;
11722
    }
11723
    note_dots_in_window(b, i, run_start, w, 0xFFFF, maybe_dot_segment);
11724
  }
11725
#elif ADA_NEON
11726
  if (i + 16 <= len) {
11727
    const uint8x16_t lo_tbl = vld1q_u8(k_path_nibbles.low);
11728
    const uint8x16_t hi_tbl = vld1q_u8(k_path_nibbles.high);
11729
    for (; i + 32 <= len; i += 32) {
11730
      const uint8x16_t w0 = vld1q_u8(b + i);
11731
      const uint64_t bits0 = neon_table_stop(w0, lo_tbl, hi_tbl);
11732
      if (bits0 != 0) {
11733
        const size_t hit_off =
11734
            static_cast<size_t>(trailing_zeroes64(bits0)) >> 2;
11735
        const uint64_t valid =
11736
            (hit_off == 0) ? 0 : (uint64_t{1} << (hit_off * 4)) - 1;
11737
        note_dots_in_window_neon(b, i, run_start, w0, valid, maybe_dot_segment);
11738
        i += hit_off;
11739
        return;
11740
      }
11741
      note_dots_in_window_neon(b, i, run_start, w0, ~uint64_t{0},
11742
                               maybe_dot_segment);
11743
      const uint8x16_t w1 = vld1q_u8(b + i + 16);
11744
      const uint64_t bits1 = neon_table_stop(w1, lo_tbl, hi_tbl);
11745
      if (bits1 != 0) {
11746
        const size_t hit_off =
11747
            static_cast<size_t>(trailing_zeroes64(bits1)) >> 2;
11748
        const uint64_t valid =
11749
            (hit_off == 0) ? 0 : (uint64_t{1} << (hit_off * 4)) - 1;
11750
        note_dots_in_window_neon(b, i + 16, run_start, w1, valid,
11751
                                 maybe_dot_segment);
11752
        i += 16 + hit_off;
11753
        return;
11754
      }
11755
      note_dots_in_window_neon(b, i + 16, run_start, w1, ~uint64_t{0},
11756
                               maybe_dot_segment);
11757
    }
11758
    for (; i + 16 <= len; i += 16) {
11759
      const uint8x16_t w = vld1q_u8(b + i);
11760
      const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);
11761
      if (bits != 0) {
11762
        const size_t hit_off =
11763
            static_cast<size_t>(trailing_zeroes64(bits)) >> 2;
11764
        const uint64_t valid =
11765
            (hit_off == 0) ? 0 : (uint64_t{1} << (hit_off * 4)) - 1;
11766
        note_dots_in_window_neon(b, i, run_start, w, valid, maybe_dot_segment);
11767
        i += hit_off;
11768
        return;
11769
      }
11770
      note_dots_in_window_neon(b, i, run_start, w, ~uint64_t{0},
11771
                               maybe_dot_segment);
11772
    }
11773
    if (i > run_start && i < len) {
11774
      const uint8x16_t w = vld1q_u8(b + len - 16);
11775
      const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);
11776
      if (bits != 0) {
11777
        const size_t hit =
11778
            len - 16 + (static_cast<size_t>(trailing_zeroes64(bits)) >> 2);
11779
        if (hit >= i) {
11780
          for (size_t j = i; j < hit; ++j) {
11781
            if (b[j] == '.') {
11782
              note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11783
            }
11784
          }
11785
          i = hit;
11786
          return;
11787
        }
11788
      }
11789
      for (size_t j = i; j < len; ++j) {
11790
        if (b[j] == '.') {
11791
          note_possible_dot_segment(b, j, run_start, maybe_dot_segment);
11792
        }
11793
      }
11794
      i = len;
11795
      return;
11796
    }
11797
  }
11798
#endif
11799
0
  for (; i < len; ++i) {
11800
0
    const uint8_t c = b[i];
11801
0
    const uint8_t cls = k_path[c];
11802
0
    if (cls != 0) {
11803
0
      return;
11804
0
    }
11805
0
    if (c == '.') {
11806
0
      note_possible_dot_segment(b, i, run_start, maybe_dot_segment);
11807
0
    }
11808
0
  }
11809
0
}
11810
11811
// Advance i to the first class-table stop (or len). Query and hash share
11812
// this loop; path keeps its own copy because it also tracks '.' segments.
11813
#if ADA_PARSER_SSSE3
11814
#define ADA_SCAN_STOP_RUN(nibbles, cls, unused_sse2_stop)                    \
11815
0
  do {                                                                       \
11816
0
    const size_t scan_start = i;                                             \
11817
0
    if (parser_use_ssse3() && (i + 16 <= len)) {                             \
11818
0
      const __m128i lo_tbl = nibble_load((nibbles).low);                     \
11819
0
      const __m128i hi_tbl = nibble_load((nibbles).high);                    \
11820
0
      for (; i + 32 <= len; i += 32) {                                       \
11821
0
        const __m128i w0 =                                                   \
11822
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));        \
11823
0
        const int m0 = ssse3_nibble_mask(w0, lo_tbl, hi_tbl);                \
11824
0
        if (m0 != 0) {                                                       \
11825
0
          i += static_cast<size_t>(                                          \
11826
0
              trailing_zeroes32(static_cast<uint32_t>(m0)));                 \
11827
0
          return;                                                            \
11828
0
        }                                                                    \
11829
0
        const __m128i w1 =                                                   \
11830
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i + 16));   \
11831
0
        const int m1 = ssse3_nibble_mask(w1, lo_tbl, hi_tbl);                \
11832
0
        if (m1 != 0) {                                                       \
11833
0
          i += 16 + static_cast<size_t>(                                     \
11834
0
                        trailing_zeroes32(static_cast<uint32_t>(m1)));       \
11835
0
          return;                                                            \
11836
0
        }                                                                    \
11837
0
      }                                                                      \
11838
0
      for (; i + 16 <= len; i += 16) {                                       \
11839
0
        const __m128i w =                                                    \
11840
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i));        \
11841
0
        const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);               \
11842
0
        if (mask != 0) {                                                     \
11843
0
          i += static_cast<size_t>(                                          \
11844
0
              trailing_zeroes32(static_cast<uint32_t>(mask)));               \
11845
0
          return;                                                            \
11846
0
        }                                                                    \
11847
0
      }                                                                      \
11848
0
      if (i > scan_start && i < len) {                                       \
11849
0
        const __m128i w =                                                    \
11850
0
            _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + len - 16)); \
11851
0
        const int mask = ssse3_nibble_mask(w, lo_tbl, hi_tbl);               \
11852
0
        if (mask != 0) {                                                     \
11853
0
          const size_t hit = len - 16 +                                      \
11854
0
                             static_cast<size_t>(trailing_zeroes32(          \
11855
0
                                 static_cast<uint32_t>(mask)));              \
11856
0
          if (hit >= i) {                                                    \
11857
0
            i = hit;                                                         \
11858
0
            return;                                                          \
11859
0
          }                                                                  \
11860
0
        }                                                                    \
11861
0
        i = len;                                                             \
11862
0
        return;                                                              \
11863
0
      }                                                                      \
11864
0
    }                                                                        \
11865
0
    for (; i < len; ++i) {                                                   \
11866
0
      if ((cls)[b[i]] != 0) {                                                \
11867
0
        return;                                                              \
11868
0
      }                                                                      \
11869
0
    }                                                                        \
11870
0
  } while (0)
11871
#elif ADA_NEON
11872
#define ADA_SCAN_STOP_RUN(nibbles, cls, unused_sse2_stop)                     \
11873
  do {                                                                        \
11874
    const size_t scan_start = i;                                              \
11875
    if (i + 16 <= len) {                                                      \
11876
      const uint8x16_t lo_tbl = vld1q_u8((nibbles).low);                      \
11877
      const uint8x16_t hi_tbl = vld1q_u8((nibbles).high);                     \
11878
      for (; i + 32 <= len; i += 32) {                                        \
11879
        const uint64_t bits0 =                                                \
11880
            neon_table_stop(vld1q_u8(b + i), lo_tbl, hi_tbl);                 \
11881
        if (bits0 != 0) {                                                     \
11882
          i += static_cast<size_t>(trailing_zeroes64(bits0)) >> 2;            \
11883
          return;                                                             \
11884
        }                                                                     \
11885
        const uint64_t bits1 =                                                \
11886
            neon_table_stop(vld1q_u8(b + i + 16), lo_tbl, hi_tbl);            \
11887
        if (bits1 != 0) {                                                     \
11888
          i += 16 + (static_cast<size_t>(trailing_zeroes64(bits1)) >> 2);     \
11889
          return;                                                             \
11890
        }                                                                     \
11891
      }                                                                       \
11892
      for (; i + 16 <= len; i += 16) {                                        \
11893
        const uint8x16_t w = vld1q_u8(b + i);                                 \
11894
        const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);             \
11895
        if (bits != 0) {                                                      \
11896
          i += static_cast<size_t>(trailing_zeroes64(bits)) >> 2;             \
11897
          return;                                                             \
11898
        }                                                                     \
11899
      }                                                                       \
11900
      if (i > scan_start && i < len) {                                        \
11901
        const uint8x16_t w = vld1q_u8(b + len - 16);                          \
11902
        const uint64_t bits = neon_table_stop(w, lo_tbl, hi_tbl);             \
11903
        if (bits != 0) {                                                      \
11904
          const size_t hit =                                                  \
11905
              len - 16 + (static_cast<size_t>(trailing_zeroes64(bits)) >> 2); \
11906
          if (hit >= i) {                                                     \
11907
            i = hit;                                                          \
11908
            return;                                                           \
11909
          }                                                                   \
11910
        }                                                                     \
11911
        i = len;                                                              \
11912
        return;                                                               \
11913
      }                                                                       \
11914
    }                                                                         \
11915
    for (; i < len; ++i) {                                                    \
11916
      if ((cls)[b[i]] != 0) {                                                 \
11917
        return;                                                               \
11918
      }                                                                       \
11919
    }                                                                         \
11920
  } while (0)
11921
#elif ADA_SSE2
11922
#define ADA_SCAN_STOP_RUN(nibbles, cls, sse2_stop)                  \
11923
  do {                                                              \
11924
    for (; i + 16 <= len; i += 16) {                                \
11925
      const __m128i w =                                             \
11926
          _mm_loadu_si128(reinterpret_cast<const __m128i*>(b + i)); \
11927
      const int mask = sse2_stop(w);                                \
11928
      if (mask != 0) {                                              \
11929
        i += static_cast<size_t>(                                   \
11930
            trailing_zeroes32(static_cast<uint32_t>(mask)));        \
11931
        return;                                                     \
11932
      }                                                             \
11933
    }                                                               \
11934
    for (; i < len; ++i) {                                          \
11935
      if ((cls)[b[i]] != 0) {                                       \
11936
        return;                                                     \
11937
      }                                                             \
11938
    }                                                               \
11939
  } while (0)
11940
#else
11941
#define ADA_SCAN_STOP_RUN(nibbles, cls, unused_sse2_stop) \
11942
  do {                                                    \
11943
    for (; i < len; ++i) {                                \
11944
      if ((cls)[b[i]] != 0) {                             \
11945
        return;                                           \
11946
      }                                                   \
11947
    }                                                     \
11948
  } while (0)
11949
#endif
11950
11951
ADA_PARSER_SIMD void scan_query_run(const uint8_t* b, size_t& i,
11952
0
                                    size_t len) noexcept {
11953
0
  ADA_SCAN_STOP_RUN(k_query_nibbles, k_query, sse2_query_stop);
11954
0
}
11955
11956
ADA_PARSER_SIMD void scan_hash_run(const uint8_t* b, size_t& i,
11957
0
                                   size_t len) noexcept {
11958
0
  ADA_SCAN_STOP_RUN(k_hash_nibbles, k_hash, sse2_hash_stop);
11959
0
}
11960
11961
#undef ADA_SCAN_STOP_RUN
11962
11963
0
bool path_has_dot_segment(std::string_view path) noexcept {
11964
0
  if (path.empty()) {
11965
0
    return false;
11966
0
  }
11967
  // "." / ".." at the start, with or without a leading '/'.
11968
0
  const size_t i = (path[0] == '/') ? 1 : 0;
11969
0
  if (i < path.size() && path[i] == '.') {
11970
0
    const size_t after = i + 1;
11971
0
    if (after == path.size() || path[after] == '/' ||
11972
0
        (after < path.size() && path[after] == '.' &&
11973
0
         (after + 1 == path.size() || path[after + 1] == '/'))) {
11974
0
      return true;
11975
0
    }
11976
0
  }
11977
0
  static constexpr std::string_view slash_dot{"/.", 2};
11978
0
  size_t p = i;
11979
0
  while ((p = path.find(slash_dot, p)) != std::string_view::npos) {
11980
0
    const size_t after = p + 2;
11981
0
    if (after == path.size() || path[after] == '/' ||
11982
0
        (after < path.size() && path[after] == '.' &&
11983
0
         (after + 1 == path.size() || path[after + 1] == '/'))) {
11984
0
      return true;
11985
0
    }
11986
0
    p = after;
11987
0
  }
11988
0
  return false;
11989
0
}
11990
11991
}  // namespace
11992
11993
template <class result_type>
11994
ada_never_inline bool finish_simple_absolute_with_port(
11995
    std::string_view input, result_type& out, ada::scheme::type scheme_type,
11996
    uint32_t protocol_end, size_t host_start, size_t host_end, size_t host_len,
11997
0
    bool has_upper) {
11998
0
  constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>;
11999
0
  constexpr bool is_aggregator =
12000
0
      std::is_same_v<result_type, ada::url_aggregator>;
12001
0
  static_assert(is_ada_url || is_aggregator);
12002
12003
0
  const size_t len = input.size();
12004
0
  const auto* b = reinterpret_cast<const uint8_t*>(input.data());
12005
0
  size_t p = host_end + 1;
12006
0
  uint32_t port_value = 0;
12007
0
  bool any_digit = false;
12008
0
  while (p < len && b[p] >= '0' && b[p] <= '9') {
12009
0
    any_digit = true;
12010
0
    port_value = port_value * 10 + static_cast<uint32_t>(b[p] - '0');
12011
0
    if (port_value > 65535) [[unlikely]] {
12012
0
      return false;
12013
0
    }
12014
0
    ++p;
12015
0
  }
12016
0
  if (p < len && b[p] != '/' && b[p] != '?' && b[p] != '#') [[unlikely]] {
12017
0
    return false;
12018
0
  }
12019
0
  uint32_t parsed_port = url_components::omitted;
12020
0
  const uint16_t default_port = ada::scheme::get_special_port(scheme_type);
12021
0
  if (any_digit && port_value != default_port) {
12022
0
    parsed_port = port_value;
12023
0
  }
12024
0
  const size_t authority_end = p;
12025
12026
0
  size_t i = authority_end;
12027
0
  size_t path_start = host_end;
12028
0
  size_t path_end = host_end;
12029
0
  size_t query_start = std::string_view::npos;
12030
0
  size_t hash_start = std::string_view::npos;
12031
0
  bool has_path = false;
12032
0
  bool maybe_dot_segment = false;
12033
0
  bool rest_simple = true;
12034
12035
0
  if (i < len && b[i] == '/') {
12036
0
    has_path = true;
12037
0
    path_start = i;
12038
0
    ++i;
12039
0
    scan_path_run(b, i, len, maybe_dot_segment);
12040
0
    if (i < len) {
12041
0
      const uint8_t cls = k_path[b[i]];
12042
0
      if (cls == 1) {
12043
0
        path_end = i;
12044
0
        if (b[i] == '?') {
12045
0
          query_start = i;
12046
0
          ++i;
12047
0
          goto scan_query;
12048
0
        }
12049
0
        hash_start = i;
12050
0
        ++i;
12051
0
        goto scan_hash;
12052
0
      }
12053
0
      rest_simple = false;
12054
0
      for (; i < len; ++i) {
12055
0
        if (b[i] == '?') {
12056
0
          path_end = i;
12057
0
          query_start = i;
12058
0
          ++i;
12059
0
          goto scan_query_boundary;
12060
0
        }
12061
0
        if (b[i] == '#') {
12062
0
          path_end = i;
12063
0
          hash_start = i;
12064
0
          ++i;
12065
0
          goto after_rest;
12066
0
        }
12067
0
      }
12068
0
      path_end = i;
12069
0
      goto after_rest;
12070
0
    }
12071
0
    path_end = i;
12072
0
  } else if (i < len && b[i] == '?') {
12073
0
    query_start = i;
12074
0
    ++i;
12075
0
    goto scan_query;
12076
0
  } else if (i < len && b[i] == '#') {
12077
0
    hash_start = i;
12078
0
    ++i;
12079
0
    goto scan_hash;
12080
0
  }
12081
0
  goto after_rest;
12082
12083
0
scan_query:
12084
0
  scan_query_run(b, i, len);
12085
0
  if (i < len) {
12086
0
    if (b[i] == '#') {
12087
0
      hash_start = i;
12088
0
      ++i;
12089
0
      goto scan_hash;
12090
0
    }
12091
0
    rest_simple = false;
12092
0
    goto scan_query_boundary;
12093
0
  }
12094
0
  goto after_rest;
12095
12096
0
scan_query_boundary:
12097
0
  for (; i < len; ++i) {
12098
0
    if (b[i] == '#') {
12099
0
      hash_start = i;
12100
0
      ++i;
12101
0
      goto after_rest;
12102
0
    }
12103
0
  }
12104
0
  goto after_rest;
12105
12106
0
scan_hash:
12107
0
  scan_hash_run(b, i, len);
12108
0
  if (i < len) {
12109
0
    rest_simple = false;
12110
0
  }
12111
12112
0
after_rest:
12113
0
  if (rest_simple && maybe_dot_segment) {
12114
0
    const std::string_view path_body(input.data() + path_start,
12115
0
                                     path_end - path_start);
12116
0
    if (path_has_dot_segment(path_body)) {
12117
0
      rest_simple = false;
12118
0
    }
12119
0
  }
12120
12121
  // The slow path removes ASCII tab/newline anywhere in the input and trims a
12122
  // trailing C0 control or space; this fast path does neither. A query or
12123
  // fragment reaching the helpers below would keep those bytes percent-encoded
12124
  // ("?a\nb" -> "?a%0Ab", "#f " -> "#f%20") instead of stripped, so hand such
12125
  // inputs back to the slow path.
12126
0
  if (!rest_simple && (unicode::is_c0_control_or_space(input.back()) ||
12127
0
                       unicode::has_tabs_or_newline(input))) {
12128
0
    return false;
12129
0
  }
12130
12131
0
  out.type = scheme_type;
12132
0
  out.is_valid = true;
12133
0
  out.has_opaque_path = false;
12134
0
  out.host_type = DEFAULT;
12135
12136
0
  const uint32_t port_bytes = (parsed_port != url_components::omitted)
12137
0
                                  ? (1 + port_decimal_digit_count(parsed_port))
12138
0
                                  : 0;
12139
12140
0
  if (!rest_simple) {
12141
0
    const std::string_view path_view =
12142
0
        has_path
12143
0
            ? std::string_view(input.data() + path_start, path_end - path_start)
12144
0
            : std::string_view{};
12145
0
    auto apply_query_and_hash = [&]() {
12146
0
      if (query_start != std::string_view::npos) {
12147
0
        const size_t q_end =
12148
0
            (hash_start != std::string_view::npos) ? hash_start : len;
12149
0
        out.update_base_search(std::string_view(input.data() + query_start + 1,
12150
0
                                                q_end - query_start - 1),
12151
0
                               character_sets::SPECIAL_QUERY_PERCENT_ENCODE);
12152
0
      }
12153
0
      if (hash_start != std::string_view::npos) {
12154
0
        out.update_unencoded_base_hash(std::string_view(
12155
0
            input.data() + hash_start + 1, len - hash_start - 1));
12156
0
      }
12157
0
    };
Unexecuted instantiation: ada::parser::finish_simple_absolute_with_port<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::finish_simple_absolute_with_port<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)::{lambda()#1}::operator()() const
12158
0
    if constexpr (is_aggregator) {
12159
0
      out.buffer.assign(input.substr(0, host_end));
12160
0
      if (parsed_port != url_components::omitted) {
12161
0
        append_canonical_port(out.buffer, parsed_port);
12162
0
      }
12163
0
      if (has_upper) {
12164
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12165
0
      }
12166
0
      out.components.protocol_end = protocol_end;
12167
0
      out.components.username_end = protocol_end + 2;
12168
0
      out.components.host_start = protocol_end + 2;
12169
0
      out.components.host_end = static_cast<uint32_t>(host_end);
12170
0
      out.components.port = parsed_port;
12171
0
      out.components.pathname_start = static_cast<uint32_t>(out.buffer.size());
12172
0
      out.components.search_start = url_components::omitted;
12173
0
      out.components.hash_start = url_components::omitted;
12174
0
      out.parse_path(path_view);
12175
0
      apply_query_and_hash();
12176
0
    } else {
12177
0
      std::string host_str(input.substr(host_start, host_len));
12178
0
      if (has_upper) {
12179
0
        unicode::to_lower_ascii(host_str.data(), host_str.size());
12180
0
      }
12181
0
      out.host = std::move(host_str);
12182
0
      if (parsed_port != url_components::omitted) {
12183
0
        out.port = static_cast<uint16_t>(parsed_port);
12184
0
      }
12185
0
      out.parse_path(path_view);
12186
0
      apply_query_and_hash();
12187
0
    }
12188
0
    return true;
12189
0
  }
12190
12191
0
  const bool insert_slash = !has_path;
12192
0
  if constexpr (is_aggregator) {
12193
0
    const size_t out_len =
12194
0
        host_end + port_bytes + (insert_slash ? 1 : 0) + (len - authority_end);
12195
0
    const bool omit_port_bytes = parsed_port == url_components::omitted;
12196
0
    if (out_len == len && !insert_slash && !omit_port_bytes) {
12197
0
      out.buffer.assign(input);
12198
0
    } else {
12199
0
      out.buffer.clear();
12200
0
      out.buffer.reserve(out_len);
12201
0
      out.buffer.append(input.substr(0, host_end));
12202
0
      if (parsed_port != url_components::omitted) {
12203
0
        append_canonical_port(out.buffer, parsed_port);
12204
0
      }
12205
0
      if (insert_slash) {
12206
0
        out.buffer.push_back('/');
12207
0
      }
12208
0
      if (authority_end < len) {
12209
0
        out.buffer.append(input.substr(authority_end));
12210
0
      }
12211
0
    }
12212
0
    if (has_upper) {
12213
0
      unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12214
0
    }
12215
0
    const uint32_t pathname_start =
12216
0
        static_cast<uint32_t>(host_end) + port_bytes;
12217
0
    const int32_t tail_delta = static_cast<int32_t>(pathname_start) +
12218
0
                               (insert_slash ? 1 : 0) -
12219
0
                               static_cast<int32_t>(authority_end);
12220
0
    out.components.protocol_end = protocol_end;
12221
0
    out.components.username_end = protocol_end + 2;
12222
0
    out.components.host_start = protocol_end + 2;
12223
0
    out.components.host_end = static_cast<uint32_t>(host_end);
12224
0
    out.components.port = parsed_port;
12225
0
    out.components.pathname_start = pathname_start;
12226
0
    out.components.search_start =
12227
0
        (query_start != std::string_view::npos)
12228
0
            ? static_cast<uint32_t>(static_cast<int32_t>(query_start) +
12229
0
                                    tail_delta)
12230
0
            : url_components::omitted;
12231
0
    out.components.hash_start =
12232
0
        (hash_start != std::string_view::npos)
12233
0
            ? static_cast<uint32_t>(static_cast<int32_t>(hash_start) +
12234
0
                                    tail_delta)
12235
0
            : url_components::omitted;
12236
0
  } else {
12237
0
    std::string host_str(input.substr(host_start, host_len));
12238
0
    if (has_upper) {
12239
0
      unicode::to_lower_ascii(host_str.data(), host_str.size());
12240
0
    }
12241
0
    out.host = std::move(host_str);
12242
0
    if (parsed_port != url_components::omitted) {
12243
0
      out.port = static_cast<uint16_t>(parsed_port);
12244
0
    }
12245
0
    if (insert_slash) {
12246
0
      out.path = "/";
12247
0
    } else {
12248
0
      out.path.assign(input.data() + path_start, path_end - path_start);
12249
0
    }
12250
0
    if (query_start != std::string_view::npos) {
12251
0
      const size_t q_end =
12252
0
          (hash_start != std::string_view::npos) ? hash_start : len;
12253
0
      out.query.emplace(input.data() + query_start + 1,
12254
0
                        q_end - query_start - 1);
12255
0
    }
12256
0
    if (hash_start != std::string_view::npos) {
12257
0
      out.hash.emplace(input.data() + hash_start + 1, len - hash_start - 1);
12258
0
    }
12259
0
  }
12260
0
  return true;
12261
0
}
Unexecuted instantiation: bool ada::parser::finish_simple_absolute_with_port<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)
Unexecuted instantiation: bool ada::parser::finish_simple_absolute_with_port<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&, ada::scheme::type, unsigned int, unsigned long, unsigned long, unsigned long, bool)
12262
12263
// Fast path for already-canonical special-scheme URLs of the shape
12264
// scheme://host[/path][?query][#fragment]. When the host is a plain domain
12265
// but the rest needs encoding or dot-segment normalization, the host is
12266
// kept and the path/query/hash helpers finish the URL.
12267
template <class result_type>
12268
ada_never_inline bool try_parse_simple_absolute(std::string_view input,
12269
0
                                                result_type& out) {
12270
0
  constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>;
12271
0
  constexpr bool is_aggregator =
12272
0
      std::is_same_v<result_type, ada::url_aggregator>;
12273
0
  static_assert(is_ada_url || is_aggregator);
12274
12275
0
  const size_t len = input.size();
12276
  // Shortest accepted form is "ws://x" (6).
12277
0
  if (len < 6) [[unlikely]] {
12278
0
    return false;
12279
0
  }
12280
0
  const auto* b = reinterpret_cast<const uint8_t*>(input.data());
12281
12282
0
  size_t pos = 0;
12283
0
  ada::scheme::type scheme_type = ada::scheme::type::NOT_SPECIAL;
12284
0
  uint32_t protocol_end = 0;
12285
0
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
12286
0
    defined(_M_X64) || defined(_M_IX86) || defined(_M_AMD64)
12287
  // One 8-byte load + integer compare is a single cmp/jcc on x86-64.
12288
  // Masked compares cover the shorter special schemes without extra loads.
12289
0
  if (len >= 8) {
12290
0
    uint64_t first8 = 0;
12291
0
    std::memcpy(&first8, b, 8);
12292
0
    if (first8 == 0x2f2f3a7370747468ull) {  // "https://"
12293
0
      pos = 8;
12294
0
      scheme_type = ada::scheme::type::HTTPS;
12295
0
      protocol_end = 6;
12296
0
    } else if ((first8 & 0x00ffffffffffffffull) ==
12297
0
               0x002f2f3a70747468ull) {  // "http://"
12298
0
      pos = 7;
12299
0
      scheme_type = ada::scheme::type::HTTP;
12300
0
      protocol_end = 5;
12301
0
    } else if ((first8 & 0x0000ffffffffffffull) ==
12302
0
               0x00002f2f3a737377ull) {  // "wss://"
12303
0
      pos = 6;
12304
0
      scheme_type = ada::scheme::type::WSS;
12305
0
      protocol_end = 4;
12306
0
    } else if ((first8 & 0x0000ffffffffffffull) ==
12307
0
               0x00002f2f3a707466ull) {  // "ftp://"
12308
0
      pos = 6;
12309
0
      scheme_type = ada::scheme::type::FTP;
12310
0
      protocol_end = 4;
12311
0
    } else if ((first8 & 0x000000ffffffffffull) ==
12312
0
               0x0000002f2f3a7377ull) {  // "ws://"
12313
0
      pos = 5;
12314
0
      scheme_type = ada::scheme::type::WS;
12315
0
      protocol_end = 3;
12316
0
    } else {
12317
0
      return false;
12318
0
    }
12319
0
  } else if (b[0] == 'w' && b[1] == 's') {
12320
0
    if (b[2] == ':' && b[3] == '/' && b[4] == '/') {
12321
0
      pos = 5;
12322
0
      scheme_type = ada::scheme::type::WS;
12323
0
      protocol_end = 3;
12324
0
    } else if (b[2] == 's' && b[3] == ':' && b[4] == '/' && b[5] == '/') {
12325
0
      pos = 6;
12326
0
      scheme_type = ada::scheme::type::WSS;
12327
0
      protocol_end = 4;
12328
0
    } else {
12329
0
      return false;
12330
0
    }
12331
0
  } else if (b[0] == 'f' && b[1] == 't' && b[2] == 'p' && b[3] == ':' &&
12332
0
             b[4] == '/' && b[5] == '/') {
12333
0
    pos = 6;
12334
0
    scheme_type = ada::scheme::type::FTP;
12335
0
    protocol_end = 4;
12336
0
  } else if (len >= 7 && b[0] == 'h' && b[1] == 't' && b[2] == 't' &&
12337
0
             b[3] == 'p' && b[4] == ':' && b[5] == '/' && b[6] == '/') {
12338
0
    pos = 7;
12339
0
    scheme_type = ada::scheme::type::HTTP;
12340
0
    protocol_end = 5;
12341
0
  } else {
12342
0
    return false;
12343
0
  }
12344
#else
12345
  // Big-endian / uncommon arches: byte-wise special-scheme match.
12346
  if (len >= 8 && b[0] == 'h' && b[1] == 't' && b[2] == 't' && b[3] == 'p' &&
12347
      b[4] == 's' && b[5] == ':' && b[6] == '/' && b[7] == '/') {
12348
    pos = 8;
12349
    scheme_type = ada::scheme::type::HTTPS;
12350
    protocol_end = 6;
12351
  } else if (len >= 7 && b[0] == 'h' && b[1] == 't' && b[2] == 't' &&
12352
             b[3] == 'p' && b[4] == ':' && b[5] == '/' && b[6] == '/') {
12353
    pos = 7;
12354
    scheme_type = ada::scheme::type::HTTP;
12355
    protocol_end = 5;
12356
  } else if (b[0] == 'w' && b[1] == 's') {
12357
    if (b[2] == ':' && b[3] == '/' && b[4] == '/') {
12358
      pos = 5;
12359
      scheme_type = ada::scheme::type::WS;
12360
      protocol_end = 3;
12361
    } else if (len >= 6 && b[2] == 's' && b[3] == ':' && b[4] == '/' &&
12362
               b[5] == '/') {
12363
      pos = 6;
12364
      scheme_type = ada::scheme::type::WSS;
12365
      protocol_end = 4;
12366
    } else {
12367
      return false;
12368
    }
12369
  } else if (b[0] == 'f' && b[1] == 't' && b[2] == 'p' && b[3] == ':' &&
12370
             b[4] == '/' && b[5] == '/') {
12371
    pos = 6;
12372
    scheme_type = ada::scheme::type::FTP;
12373
    protocol_end = 4;
12374
  } else {
12375
    return false;
12376
  }
12377
#endif
12378
0
  if (pos < len && (b[pos] == '/' || b[pos] == '\\')) [[unlikely]] {
12379
0
    return false;
12380
0
  }
12381
12382
  // Digit-led hosts are IPv4/numeric; '[' is IPv6. Skip before scanning.
12383
0
  if (pos < len && ((b[pos] >= '0' && b[pos] <= '9') || b[pos] == '[')) {
12384
0
    return false;
12385
0
  }
12386
12387
0
  const size_t host_start = pos;
12388
0
  bool has_upper = false;
12389
0
  bool has_x = false;
12390
0
  size_t host_end = pos;
12391
0
  if (!scan_plain_host(b, pos, len, host_end, has_upper, has_x)) {
12392
0
    return false;
12393
0
  }
12394
0
  if (host_start == host_end) [[unlikely]] {
12395
0
    return false;
12396
0
  }
12397
0
  const size_t host_len = host_end - host_start;
12398
0
  if (host_len > 253) [[unlikely]] {
12399
0
    return false;
12400
0
  }
12401
0
  {
12402
0
    std::string_view hv(input.data() + host_start, host_len);
12403
0
    char host_buf[256];
12404
0
    if (has_upper) [[unlikely]] {
12405
0
      std::memcpy(host_buf, input.data() + host_start, host_len);
12406
0
      unicode::to_lower_ascii(host_buf, host_len);
12407
0
      hv = std::string_view(host_buf, host_len);
12408
0
    }
12409
0
    if (ada::checkers::last_label_may_be_a_number(hv)) [[unlikely]] {
12410
0
      return false;
12411
0
    }
12412
    // Punycode is "xn--...". The host scan already notes a lowercase 'x';
12413
    // uppercase 'X' is covered by has_upper after the in-place lower.
12414
0
    static constexpr std::string_view xn{"xn-", 3};
12415
0
    if ((has_x || has_upper) && hv.find(xn) != std::string_view::npos)
12416
0
        [[unlikely]] {
12417
0
      return false;
12418
0
    }
12419
0
  }
12420
12421
0
  if (host_end < len && b[host_end] == ':') [[unlikely]] {
12422
0
    return finish_simple_absolute_with_port(input, out, scheme_type,
12423
0
                                            protocol_end, host_start, host_end,
12424
0
                                            host_len, has_upper);
12425
0
  }
12426
12427
0
  size_t i = host_end;
12428
0
  size_t path_start = host_end;
12429
0
  size_t path_end = host_end;
12430
0
  size_t query_start = std::string_view::npos;
12431
0
  size_t hash_start = std::string_view::npos;
12432
0
  bool has_path = false;
12433
0
  bool maybe_dot_segment = false;
12434
0
  bool rest_simple = true;
12435
12436
0
  if (i < len && b[i] == '/') {
12437
0
    has_path = true;
12438
0
    path_start = i;
12439
0
    ++i;
12440
0
    scan_path_run(b, i, len, maybe_dot_segment);
12441
0
    if (i < len) {
12442
0
      const uint8_t cls = k_path[b[i]];
12443
0
      if (cls == 1) {
12444
0
        path_end = i;
12445
0
        if (b[i] == '?') {
12446
0
          query_start = i;
12447
0
          ++i;
12448
0
          goto scan_query;
12449
0
        }
12450
0
        hash_start = i;
12451
0
        ++i;
12452
0
        goto scan_hash;
12453
0
      }
12454
0
      rest_simple = false;
12455
0
      for (; i < len; ++i) {
12456
0
        if (b[i] == '?') {
12457
0
          path_end = i;
12458
0
          query_start = i;
12459
0
          ++i;
12460
0
          goto scan_query_boundary;
12461
0
        }
12462
0
        if (b[i] == '#') {
12463
0
          path_end = i;
12464
0
          hash_start = i;
12465
0
          ++i;
12466
0
          goto after_rest;
12467
0
        }
12468
0
      }
12469
0
      path_end = i;
12470
0
      goto after_rest;
12471
0
    }
12472
0
    path_end = i;
12473
0
  } else if (i < len && b[i] == '?') {
12474
0
    query_start = i;
12475
0
    ++i;
12476
0
    goto scan_query;
12477
0
  } else if (i < len && b[i] == '#') {
12478
0
    hash_start = i;
12479
0
    ++i;
12480
0
    goto scan_hash;
12481
0
  }
12482
0
  goto after_rest;
12483
12484
0
scan_query:
12485
0
  scan_query_run(b, i, len);
12486
0
  if (i < len) {
12487
0
    if (b[i] == '#') {
12488
0
      hash_start = i;
12489
0
      ++i;
12490
0
      goto scan_hash;
12491
0
    }
12492
0
    rest_simple = false;
12493
0
    goto scan_query_boundary;
12494
0
  }
12495
0
  goto after_rest;
12496
12497
0
scan_query_boundary:
12498
0
  for (; i < len; ++i) {
12499
0
    if (b[i] == '#') {
12500
0
      hash_start = i;
12501
0
      ++i;
12502
0
      goto after_rest;
12503
0
    }
12504
0
  }
12505
0
  goto after_rest;
12506
12507
0
scan_hash:
12508
0
  scan_hash_run(b, i, len);
12509
0
  if (i < len) {
12510
0
    rest_simple = false;
12511
0
  }
12512
12513
0
after_rest:
12514
0
  if (rest_simple && maybe_dot_segment) {
12515
0
    const std::string_view path_body(input.data() + path_start,
12516
0
                                     path_end - path_start);
12517
0
    if (path_has_dot_segment(path_body)) {
12518
0
      rest_simple = false;
12519
0
    }
12520
0
  }
12521
12522
  // The slow path removes ASCII tab/newline anywhere in the input and trims a
12523
  // trailing C0 control or space; this fast path does neither. A query or
12524
  // fragment reaching the helpers below would keep those bytes percent-encoded
12525
  // ("?a\nb" -> "?a%0Ab", "#f " -> "#f%20") instead of stripped, so hand such
12526
  // inputs back to the slow path.
12527
0
  if (!rest_simple && (unicode::is_c0_control_or_space(input.back()) ||
12528
0
                       unicode::has_tabs_or_newline(input))) {
12529
0
    return false;
12530
0
  }
12531
12532
0
  out.type = scheme_type;
12533
0
  out.is_valid = true;
12534
0
  out.has_opaque_path = false;
12535
0
  out.host_type = DEFAULT;
12536
12537
0
  if (!rest_simple) {
12538
    // Host is a plain domain. Finish path/query/hash with
12539
    // the regular helpers
12540
    // so percent-encoding and dot segments do not re-parse the authority.
12541
0
    const std::string_view path_view =
12542
0
        has_path
12543
0
            ? std::string_view(input.data() + path_start, path_end - path_start)
12544
0
            : std::string_view{};
12545
0
    auto apply_query_and_hash = [&]() {
12546
0
      if (query_start != std::string_view::npos) {
12547
0
        const size_t q_end =
12548
0
            (hash_start != std::string_view::npos) ? hash_start : len;
12549
0
        out.update_base_search(std::string_view(input.data() + query_start + 1,
12550
0
                                                q_end - query_start - 1),
12551
0
                               character_sets::SPECIAL_QUERY_PERCENT_ENCODE);
12552
0
      }
12553
0
      if (hash_start != std::string_view::npos) {
12554
0
        out.update_unencoded_base_hash(std::string_view(
12555
0
            input.data() + hash_start + 1, len - hash_start - 1));
12556
0
      }
12557
0
    };
Unexecuted instantiation: ada::parser::try_parse_simple_absolute<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::try_parse_simple_absolute<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&)::{lambda()#1}::operator()() const
12558
0
    if constexpr (is_aggregator) {
12559
0
      out.buffer.assign(input.substr(0, host_end));
12560
0
      if (has_upper) {
12561
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12562
0
      }
12563
0
      out.components.protocol_end = protocol_end;
12564
0
      out.components.username_end = protocol_end + 2;
12565
0
      out.components.host_start = protocol_end + 2;
12566
0
      out.components.host_end = static_cast<uint32_t>(host_end);
12567
0
      out.components.port = url_components::omitted;
12568
0
      out.components.pathname_start = static_cast<uint32_t>(host_end);
12569
0
      out.components.search_start = url_components::omitted;
12570
0
      out.components.hash_start = url_components::omitted;
12571
0
      out.parse_path(path_view);
12572
0
      apply_query_and_hash();
12573
0
    } else {
12574
0
      std::string host_str(input.substr(host_start, host_len));
12575
0
      if (has_upper) {
12576
0
        unicode::to_lower_ascii(host_str.data(), host_str.size());
12577
0
      }
12578
0
      out.host = std::move(host_str);
12579
0
      out.parse_path(path_view);
12580
0
      apply_query_and_hash();
12581
0
    }
12582
0
    return true;
12583
0
  }
12584
12585
0
  const bool need_slash = !has_path;
12586
0
  if constexpr (is_aggregator) {
12587
0
    if (!need_slash) {
12588
      // assign copies once. resize()+memcpy would value-init then overwrite.
12589
0
      out.buffer.assign(input);
12590
0
      if (has_upper) {
12591
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12592
0
      }
12593
0
      out.components.protocol_end = protocol_end;
12594
0
      out.components.username_end = protocol_end + 2;
12595
0
      out.components.host_start = protocol_end + 2;
12596
0
      out.components.host_end = static_cast<uint32_t>(host_end);
12597
0
      out.components.port = url_components::omitted;
12598
0
      out.components.pathname_start = static_cast<uint32_t>(path_start);
12599
0
      out.components.search_start = (query_start != std::string_view::npos)
12600
0
                                        ? static_cast<uint32_t>(query_start)
12601
0
                                        : url_components::omitted;
12602
0
      out.components.hash_start = (hash_start != std::string_view::npos)
12603
0
                                      ? static_cast<uint32_t>(hash_start)
12604
0
                                      : url_components::omitted;
12605
0
    } else {
12606
0
      out.buffer.clear();
12607
0
      out.buffer.reserve(len + 1);
12608
0
      out.buffer.append(input.substr(0, host_end));
12609
0
      out.buffer.push_back('/');
12610
0
      if (host_end < len) {
12611
0
        out.buffer.append(input.substr(host_end));
12612
0
      }
12613
0
      if (has_upper) {
12614
0
        unicode::to_lower_ascii(out.buffer.data() + host_start, host_len);
12615
0
      }
12616
0
      out.components.protocol_end = protocol_end;
12617
0
      out.components.username_end = protocol_end + 2;
12618
0
      out.components.host_start = protocol_end + 2;
12619
0
      out.components.host_end = static_cast<uint32_t>(host_end);
12620
0
      out.components.port = url_components::omitted;
12621
0
      out.components.pathname_start = static_cast<uint32_t>(host_end);
12622
0
      out.components.search_start = (query_start != std::string_view::npos)
12623
0
                                        ? static_cast<uint32_t>(query_start + 1)
12624
0
                                        : url_components::omitted;
12625
0
      out.components.hash_start = (hash_start != std::string_view::npos)
12626
0
                                      ? static_cast<uint32_t>(hash_start + 1)
12627
0
                                      : url_components::omitted;
12628
0
    }
12629
0
  } else {
12630
0
    std::string host_str(input.substr(host_start, host_len));
12631
0
    if (has_upper) {
12632
0
      unicode::to_lower_ascii(host_str.data(), host_str.size());
12633
0
    }
12634
0
    out.host = std::move(host_str);
12635
0
    if (need_slash) {
12636
0
      out.path = "/";
12637
0
    } else {
12638
0
      out.path.assign(input.data() + path_start, path_end - path_start);
12639
0
    }
12640
0
    if (query_start != std::string_view::npos) {
12641
0
      const size_t q_end =
12642
0
          (hash_start != std::string_view::npos) ? hash_start : len;
12643
0
      out.query.emplace(input.data() + query_start + 1,
12644
0
                        q_end - query_start - 1);
12645
0
    }
12646
0
    if (hash_start != std::string_view::npos) {
12647
0
      out.hash.emplace(input.data() + hash_start + 1, len - hash_start - 1);
12648
0
    }
12649
0
  }
12650
0
  return true;
12651
0
}
Unexecuted instantiation: bool ada::parser::try_parse_simple_absolute<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url&)
Unexecuted instantiation: bool ada::parser::try_parse_simple_absolute<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator&)
12652
12653
// Fast path for `/path`, path-relative (`foo`, `c/d?q`), `?query`, and
12654
// `#fragment` against a special-scheme base. Scheme-relative (`//`) and
12655
// scheme-like first segments (`foo:bar`) stay on the state machine.
12656
template <class result_type>
12657
ada_never_inline bool try_parse_simple_relative(std::string_view input,
12658
                                                const result_type& base,
12659
0
                                                result_type& out) {
12660
0
  constexpr bool is_ada_url = std::is_same_v<result_type, ada::url>;
12661
0
  constexpr bool is_aggregator =
12662
0
      std::is_same_v<result_type, ada::url_aggregator>;
12663
0
  static_assert(is_ada_url || is_aggregator);
12664
12665
0
  if (!base.is_special() || base.type == ada::scheme::type::FILE ||
12666
0
      base.has_opaque_path || input.empty()) {
12667
0
    return false;
12668
0
  }
12669
0
  const auto* b = reinterpret_cast<const uint8_t*>(input.data());
12670
0
  const size_t len = input.size();
12671
0
  const uint8_t first = b[0];
12672
0
  const bool path_relative = first != '/' && first != '?' && first != '#';
12673
0
  if (first == '/' && len > 1 && (b[1] == '/' || b[1] == '\\')) {
12674
0
    return false;
12675
0
  }
12676
  // A ':' before the first / ? # is a scheme, not a path segment.
12677
0
  if (path_relative) {
12678
0
    const size_t delim = input.find_first_of("/?#:");
12679
0
    if (delim != std::string_view::npos && input[delim] == ':') {
12680
0
      return false;
12681
0
    }
12682
0
  }
12683
12684
0
  size_t i = 0;
12685
0
  size_t path_start = 0;
12686
0
  size_t path_end = 0;
12687
0
  size_t query_start = std::string_view::npos;
12688
0
  size_t hash_start = std::string_view::npos;
12689
0
  bool has_path = false;
12690
0
  bool maybe_dot_segment = false;
12691
12692
0
  if (first == '/' || path_relative) {
12693
0
    has_path = true;
12694
0
    path_start = 0;
12695
0
    if (first == '/') {
12696
0
      i = 1;
12697
0
    }
12698
0
    scan_path_run(b, i, len, maybe_dot_segment);
12699
0
    if (i < len) {
12700
0
      const uint8_t cls = k_path[b[i]];
12701
0
      if (cls == 2) {
12702
0
        return false;
12703
0
      }
12704
0
    }
12705
0
    path_end = i;
12706
0
    if (i < len && b[i] == '?') {
12707
0
      query_start = i;
12708
0
      ++i;
12709
0
      scan_query_run(b, i, len);
12710
0
      if (i < len) {
12711
0
        if (b[i] != '#') {
12712
0
          return false;
12713
0
        }
12714
0
        hash_start = i;
12715
0
        ++i;
12716
0
        scan_hash_run(b, i, len);
12717
0
        if (i < len) {
12718
0
          return false;
12719
0
        }
12720
0
      }
12721
0
    } else if (i < len && b[i] == '#') {
12722
0
      hash_start = i;
12723
0
      ++i;
12724
0
      scan_hash_run(b, i, len);
12725
0
      if (i < len) {
12726
0
        return false;
12727
0
      }
12728
0
    } else if (i < len) {
12729
0
      return false;
12730
0
    }
12731
0
  } else if (first == '?') {
12732
0
    query_start = 0;
12733
0
    i = 1;
12734
0
    scan_query_run(b, i, len);
12735
0
    if (i < len) {
12736
0
      if (b[i] != '#') {
12737
0
        return false;
12738
0
      }
12739
0
      hash_start = i;
12740
0
      ++i;
12741
0
      scan_hash_run(b, i, len);
12742
0
      if (i < len) {
12743
0
        return false;
12744
0
      }
12745
0
    }
12746
0
  } else {
12747
0
    hash_start = 0;
12748
0
    i = 1;
12749
0
    scan_hash_run(b, i, len);
12750
0
    if (i < len) {
12751
0
      return false;
12752
0
    }
12753
0
  }
12754
12755
0
  if (has_path && maybe_dot_segment) {
12756
0
    const std::string_view path_body(input.data() + path_start,
12757
0
                                     path_end - path_start);
12758
0
    if (path_has_dot_segment(path_body)) {
12759
0
      return false;
12760
0
    }
12761
0
  }
12762
12763
0
  out = base;
12764
0
  out.is_valid = true;
12765
0
  out.has_opaque_path = false;
12766
12767
0
  const size_t q_end =
12768
0
      (hash_start != std::string_view::npos) ? hash_start : len;
12769
0
  const bool has_query = query_start != std::string_view::npos;
12770
0
  const bool has_hash = hash_start != std::string_view::npos;
12771
0
  const std::string_view query =
12772
0
      has_query ? std::string_view(input.data() + query_start + 1,
12773
0
                                   q_end - query_start - 1)
12774
0
                : std::string_view{};
12775
0
  const std::string_view hash =
12776
0
      has_hash ? std::string_view(input.data() + hash_start + 1,
12777
0
                                  len - hash_start - 1)
12778
0
               : std::string_view{};
12779
12780
0
  if constexpr (is_aggregator) {
12781
0
    if (first == '/' || first == '?' || path_relative) {
12782
0
      out.clear_hash();
12783
0
      out.clear_search();
12784
0
    }
12785
0
    if (first == '/') {
12786
0
      out.update_base_pathname(input.substr(path_start, path_end - path_start));
12787
0
    } else if (path_relative) {
12788
0
      const std::string_view base_path = out.get_pathname();
12789
0
      const size_t slash = base_path.rfind('/');
12790
0
      const std::string_view prefix = (slash == std::string_view::npos)
12791
0
                                          ? std::string_view("/")
12792
0
                                          : base_path.substr(0, slash + 1);
12793
0
      const std::string_view rel(input.data() + path_start,
12794
0
                                 path_end - path_start);
12795
0
      std::string new_path;
12796
0
      new_path.reserve(prefix.size() + rel.size());
12797
0
      new_path.assign(prefix);
12798
0
      new_path.append(rel);
12799
0
      out.update_base_pathname(new_path);
12800
0
    }
12801
0
    if (has_query) {
12802
      // Do not use update_base_search: it strips a leading '?' and would
12803
      // collapse '??a=b' into '?a=b'.
12804
0
      out.components.search_start = static_cast<uint32_t>(out.buffer.size());
12805
0
      out.buffer += '?';
12806
0
      out.buffer.append(query);
12807
0
    }
12808
0
    if (has_hash) {
12809
0
      out.update_unencoded_base_hash(hash);
12810
0
    }
12811
0
  } else {
12812
0
    if (first == '/' || first == '?' || path_relative) {
12813
0
      out.hash.reset();
12814
0
    }
12815
0
    if (first == '/') {
12816
0
      out.query.reset();
12817
0
      out.path.assign(input.substr(path_start, path_end - path_start));
12818
0
    } else if (path_relative) {
12819
0
      out.query.reset();
12820
0
      const size_t slash = out.path.rfind('/');
12821
0
      if (slash == std::string::npos) {
12822
0
        out.path = '/';
12823
0
      } else {
12824
0
        out.path.resize(slash + 1);
12825
0
      }
12826
0
      out.path.append(input.substr(path_start, path_end - path_start));
12827
0
    }
12828
0
    if (has_query) {
12829
0
      out.query.emplace(query);
12830
0
    }
12831
0
    if (has_hash) {
12832
0
      out.hash.emplace(hash);
12833
0
    }
12834
0
  }
12835
0
  return true;
12836
0
}
Unexecuted instantiation: bool ada::parser::try_parse_simple_relative<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const&, ada::url&)
Unexecuted instantiation: bool ada::parser::try_parse_simple_relative<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const&, ada::url_aggregator&)
12837
12838
template <class result_type, bool store_values>
12839
result_type parse_url_impl(std::string_view user_input,
12840
0
                           const result_type* base_url) {
12841
  // We can specialize the implementation per type.
12842
  // Important: result_type_is_ada_url is evaluated at *compile time*. This
12843
  // means that doing if constexpr(result_type_is_ada_url) { something } else {
12844
  // something else } is free (at runtime). This means that ada::url_aggregator
12845
  // and ada::url **do not have to support the exact same API**.
12846
0
  constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>;
12847
0
  constexpr bool result_type_is_ada_url_aggregator =
12848
0
      std::is_same_v<url_aggregator, result_type>;
12849
0
  static_assert(result_type_is_ada_url ||
12850
0
                result_type_is_ada_url_aggregator);  // We don't support
12851
                                                     // anything else for now.
12852
12853
0
  ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
12854
0
          " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
12855
0
          ")");
12856
12857
0
  result_type url{};
12858
12859
0
  const uint32_t max_input_length = ada::get_max_input_length();
12860
12861
  // Normalization (percent-encoding, IDNA) can push the serialized URL past
12862
  // max_input_length even when the input fit under it. The check at the end of
12863
  // the state machine covers URLs that run to completion, but several states
12864
  // return early after appending a query or fragment, so run the same check on
12865
  // those exits too. Without this, a query- or fragment-terminated URL such as
12866
  // file://x/?<...> or https://user@x/?<...> is accepted while the equivalent
12867
  // https://x/?<...> that takes the absolute fast path is rejected.
12868
0
  const auto enforce_max_input_length = [&]() {
12869
0
    if constexpr (store_values) {
12870
0
      if (url.is_valid) {
12871
0
        if constexpr (result_type_is_ada_url_aggregator) {
12872
0
          if (url.buffer.size() > max_input_length) [[unlikely]] {
12873
0
            url.is_valid = false;
12874
0
          }
12875
0
        } else {
12876
0
          if (url.get_href_size() > max_input_length) [[unlikely]] {
12877
0
            url.is_valid = false;
12878
0
          }
12879
0
        }
12880
0
      }
12881
0
    }
12882
0
  };
Unexecuted instantiation: ada::parser::parse_url_impl<ada::url, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::parse_url_impl<ada::url_aggregator, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::parser::parse_url_impl<ada::url_aggregator, false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)::{lambda()#1}::operator()() const
12883
12884
  // We refuse to parse URL strings that exceed the maximum input length.
12885
  // By default, this is 4GB but can be configured via
12886
  // ada::set_max_input_length().
12887
0
  if (user_input.size() > max_input_length) [[unlikely]] {
12888
0
    url.is_valid = false;
12889
0
  }
12890
  // Going forward, user_input.size() is in [0,
12891
  // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
12892
  // base, or the optional_url was invalid, we must return.
12893
0
  if (base_url != nullptr) {
12894
0
    url.is_valid &= base_url->is_valid;
12895
0
  }
12896
0
  if (!url.is_valid) {
12897
0
    return url;
12898
0
  }
12899
12900
  // Simple absolute / relative fast paths (before tabs/newline scan).
12901
0
  if constexpr (store_values) {
12902
0
    bool hit_fast_path = false;
12903
0
    if (base_url == nullptr) {
12904
      // IPv4/IPv6 and userinfo miss the fast path. Skip the never_inline
12905
      // call so those URLs (including SetHref) do not pay for a miss.
12906
0
      const auto* p = reinterpret_cast<const uint8_t*>(user_input.data());
12907
0
      const size_t n = user_input.size();
12908
0
      size_t host_start = 0;
12909
0
      if (n >= 8 && p[4] == ':' && p[5] == '/' && p[6] == '/') {
12910
0
        host_start = 7;
12911
0
      } else if (n >= 9 && p[5] == ':' && p[6] == '/' && p[7] == '/') {
12912
0
        host_start = 8;
12913
0
      }
12914
0
      const uint8_t host_first = host_start != 0 ? p[host_start] : 0;
12915
0
      const bool skip_ip =
12916
0
          host_first == '[' || (host_first >= '0' && host_first <= '9');
12917
0
      const bool skip_userinfo =
12918
0
          host_start != 0 && authority_has_at(p, host_start, n);
12919
0
      hit_fast_path = !skip_ip && !skip_userinfo &&
12920
0
                      try_parse_simple_absolute(user_input, url);
12921
0
    } else {
12922
0
      hit_fast_path = try_parse_simple_relative(user_input, *base_url, url);
12923
0
    }
12924
0
    if (hit_fast_path) {
12925
0
      if constexpr (result_type_is_ada_url_aggregator) {
12926
0
        if (url.buffer.size() > max_input_length) [[unlikely]] {
12927
0
          url.is_valid = false;
12928
0
        }
12929
0
      } else {
12930
        // For a small absolute input, even worst-case normalization cannot
12931
        // exceed the limit: percent encoding expands at most 3x and IDNA at
12932
        // most 4.5x. Avoid traversing every stored component on the common
12933
        // default-limit path.
12934
0
        if ((base_url != nullptr ||
12935
0
             user_input.size() > static_cast<size_t>(max_input_length) / 5) &&
12936
0
            url.get_href_size() > max_input_length) [[unlikely]] {
12937
0
          url.is_valid = false;
12938
0
        }
12939
0
      }
12940
0
      return url;
12941
0
    }
12942
0
  }
12943
12944
0
  state state = state::SCHEME_START;
12945
12946
0
  std::string tmp_buffer;
12947
0
  std::string_view url_data;
12948
0
  if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] {
12949
0
    tmp_buffer = user_input;
12950
    // Optimization opportunity: Instead of copying and then pruning, we could
12951
    // just directly build the string from user_input.
12952
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
12953
0
    url_data = tmp_buffer;
12954
0
  } else [[likely]] {
12955
0
    url_data = user_input;
12956
0
  }
12957
12958
  // Leading and trailing control characters are uncommon and easy to deal with
12959
  // (no performance concern).
12960
0
  helpers::trim_c0_whitespace(url_data);
12961
12962
0
  if constexpr (result_type_is_ada_url_aggregator && store_values) {
12963
    // Most of the time, we just need user_input.size().
12964
    // In some instances, we may need a bit more.
12965
    ///////////////////////////
12966
    // This is *very* important. This line should *not* be removed
12967
    // hastily. There are principled reasons why reserve is important
12968
    // for performance. If you have a benchmark with small inputs,
12969
    // it may not matter, but in other instances, it could.
12970
    ////
12971
    // This rounds up to the next power of two.
12972
    // We know that user_input.size() is in [0,
12973
    // std::numeric_limits<uint32_t>::max).
12974
0
    uint32_t reserve_capacity =
12975
0
        (0xFFFFFFFF >>
12976
0
         helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
12977
0
        1;
12978
0
    url.reserve(reserve_capacity);
12979
0
  }
12980
12981
  // Optimization opportunity. Most websites do not have fragment.
12982
0
  std::optional<std::string_view> fragment = helpers::prune_hash(url_data);
12983
  // We add it last so that an implementation like ada::url_aggregator
12984
  // can append it last to its internal buffer, thus improving performance.
12985
12986
  // Here url_data no longer has its fragment.
12987
  // We are going to access the data from url_data (it is immutable).
12988
  // At any given time, we are pointing at byte 'input_position' in url_data.
12989
  // The input_position variable should range from 0 to input_size.
12990
  // It is illegal to access url_data at input_size.
12991
0
  size_t input_position = 0;
12992
0
  const size_t input_size = url_data.size();
12993
  // Keep running the following state machine by switching on state.
12994
  // If after a run pointer points to the EOF code point, go to the next step.
12995
  // Otherwise, increase pointer by 1 and continue with the state machine.
12996
  // We never decrement input_position.
12997
0
  while (input_position <= input_size) {
12998
0
    ada_log("In parsing at ", input_position, " out of ", input_size,
12999
0
            " in state ", ada::to_string(state));
13000
0
    switch (state) {
13001
0
      case state::SCHEME_START: {
13002
0
        ada_log("SCHEME_START ", helpers::substring(url_data, input_position));
13003
        // If c is an ASCII alpha, append c, lowercased, to buffer, and set
13004
        // state to scheme state.
13005
0
        if ((input_position != input_size) &&
13006
0
            checkers::is_alpha(url_data[input_position])) {
13007
0
          state = state::SCHEME;
13008
0
          input_position++;
13009
0
        } else {
13010
          // Otherwise, if state override is not given, set state to no scheme
13011
          // state and decrease pointer by 1.
13012
0
          state = state::NO_SCHEME;
13013
0
        }
13014
0
        break;
13015
0
      }
13016
0
      case state::SCHEME: {
13017
0
        ada_log("SCHEME ", helpers::substring(url_data, input_position));
13018
        // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),
13019
        // append c, lowercased, to buffer.
13020
0
        while ((input_position != input_size) &&
13021
0
               (unicode::is_alnum_plus(url_data[input_position]))) {
13022
0
          input_position++;
13023
0
        }
13024
        // Otherwise, if c is U+003A (:), then:
13025
0
        if ((input_position != input_size) &&
13026
0
            (url_data[input_position] == ':')) {
13027
0
          ada_log("SCHEME the scheme should be ",
13028
0
                  url_data.substr(0, input_position));
13029
0
          if constexpr (result_type_is_ada_url) {
13030
0
            if (!url.parse_scheme(url_data.substr(0, input_position))) {
13031
0
              return url;
13032
0
            }
13033
0
          } else {
13034
            // we pass the colon along instead of painfully adding it back.
13035
0
            if (!url.parse_scheme_with_colon(
13036
0
                    url_data.substr(0, input_position + 1))) {
13037
0
              return url;
13038
0
            }
13039
0
          }
13040
0
          ada_log("SCHEME the scheme is ", url.get_protocol());
13041
13042
          // If url's scheme is "file", then:
13043
          // NOLINTNEXTLINE(bugprone-branch-clone)
13044
0
          if (url.type == scheme::type::FILE) {
13045
            // Set state to file state.
13046
0
            state = state::FILE;
13047
0
          }
13048
          // Otherwise, if url is special, base is non-null, and base's scheme
13049
          // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url
13050
          // != nullptr is false.
13051
0
          else if (url.is_special() && base_url != nullptr &&
13052
0
                   base_url->type == url.type) {
13053
            // Set state to special relative or authority state.
13054
0
            state = state::SPECIAL_RELATIVE_OR_AUTHORITY;
13055
0
          }
13056
          // Otherwise, if url is special, set state to special authority
13057
          // slashes state.
13058
0
          else if (url.is_special()) {
13059
0
            state = state::SPECIAL_AUTHORITY_SLASHES;
13060
0
          }
13061
          // Otherwise, if remaining starts with an U+002F (/), set state to
13062
          // path or authority state and increase pointer by 1.
13063
0
          else if (input_position + 1 < input_size &&
13064
0
                   url_data[input_position + 1] == '/') {
13065
0
            state = state::PATH_OR_AUTHORITY;
13066
0
            input_position++;
13067
0
          }
13068
          // Otherwise, set url's path to the empty string and set state to
13069
          // opaque path state.
13070
0
          else {
13071
0
            state = state::OPAQUE_PATH;
13072
0
          }
13073
0
        }
13074
        // Otherwise, if state override is not given, set buffer to the empty
13075
        // string, state to no scheme state, and start over (from the first code
13076
        // point in input).
13077
0
        else {
13078
0
          state = state::NO_SCHEME;
13079
0
          input_position = 0;
13080
0
          break;
13081
0
        }
13082
0
        input_position++;
13083
0
        break;
13084
0
      }
13085
0
      case state::NO_SCHEME: {
13086
0
        ada_log("NO_SCHEME ", helpers::substring(url_data, input_position));
13087
        // The fragment was pruned from url_data before the state machine ran,
13088
        // so 'c is U+0023 (#)' holds exactly when a fragment was found and
13089
        // nothing else remains in front of it.
13090
0
        const bool c_is_hash =
13091
0
            fragment.has_value() && input_position == input_size;
13092
        // If base is null, or base has an opaque path and c is not U+0023 (#),
13093
        // validation error, return failure.
13094
0
        if (base_url == nullptr || (base_url->has_opaque_path && !c_is_hash)) {
13095
0
          ada_log("NO_SCHEME validation error");
13096
0
          url.is_valid = false;
13097
0
          return url;
13098
0
        }
13099
        // Otherwise, if base has an opaque path and c is U+0023 (#),
13100
        // set url's scheme to base's scheme, url's path to base's path, url's
13101
        // query to base's query, and set state to fragment state.
13102
0
        else if (base_url->has_opaque_path && c_is_hash) {
13103
0
          ada_log("NO_SCHEME opaque base with fragment");
13104
0
          url.copy_scheme(*base_url);
13105
0
          url.has_opaque_path = base_url->has_opaque_path;
13106
13107
0
          if constexpr (result_type_is_ada_url) {
13108
0
            url.path = base_url->path;
13109
0
            url.query = base_url->query;
13110
0
          } else {
13111
0
            url.update_base_pathname(base_url->get_pathname());
13112
0
            if (base_url->has_search()) {
13113
              // get_search() returns "" for an empty query string (URL ends
13114
              // with '?'). update_base_search("") would incorrectly clear the
13115
              // query, so pass "?" to preserve the empty query distinction.
13116
0
              auto s = base_url->get_search();
13117
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
13118
0
            }
13119
0
          }
13120
0
          url.update_unencoded_base_hash(*fragment);
13121
0
          enforce_max_input_length();
13122
0
          return url;
13123
0
        }
13124
        // Otherwise, if base's scheme is not "file", set state to relative
13125
        // state and decrease pointer by 1.
13126
        // NOLINTNEXTLINE(bugprone-branch-clone)
13127
0
        else if (base_url->type != scheme::type::FILE) {
13128
0
          ada_log("NO_SCHEME non-file relative path");
13129
0
          state = state::RELATIVE_SCHEME;
13130
0
        }
13131
        // Otherwise, set state to file state and decrease pointer by 1.
13132
0
        else {
13133
0
          ada_log("NO_SCHEME file base type");
13134
0
          state = state::FILE;
13135
0
        }
13136
0
        break;
13137
0
      }
13138
0
      case state::AUTHORITY: {
13139
0
        ada_log("AUTHORITY ", helpers::substring(url_data, input_position));
13140
        // most URLs have no @. Having no @ tells us that we don't have to worry
13141
        // about AUTHORITY. Of course, we could have @ and still not have to
13142
        // worry about AUTHORITY.
13143
        // TODO: Instead of just collecting a bool, collect the location of the
13144
        // '@' and do something useful with it.
13145
        // TODO: We could do various processing early on, using a single pass
13146
        // over the string to collect information about it, e.g., telling us
13147
        // whether there is a @ and if so, where (or how many).
13148
13149
        // Check if url data contains an @.
13150
0
        if (url_data.find('@', input_position) == std::string_view::npos) {
13151
0
          state = state::HOST;
13152
0
          break;
13153
0
        }
13154
0
        bool at_sign_seen{false};
13155
0
        bool password_token_seen{false};
13156
        /**
13157
         * We expect something of the sort...
13158
         * https://user:pass@example.com:1234/foo/bar?baz#quux
13159
         * --------^
13160
         */
13161
0
        do {
13162
0
          std::string_view view = url_data.substr(input_position);
13163
          // The delimiters are @, /, ? \\.
13164
0
          size_t location =
13165
0
              url.is_special() ? helpers::find_authority_delimiter_special(view)
13166
0
                               : helpers::find_authority_delimiter(view);
13167
0
          std::string_view authority_view = view.substr(0, location);
13168
0
          size_t end_of_authority = input_position + authority_view.size();
13169
          // If c is U+0040 (@), then:
13170
0
          if ((end_of_authority != input_size) &&
13171
0
              (url_data[end_of_authority] == '@')) {
13172
            // If atSignSeen is true, then prepend "%40" to buffer.
13173
0
            if (at_sign_seen) {
13174
0
              if (password_token_seen) {
13175
0
                if constexpr (result_type_is_ada_url) {
13176
0
                  url.password += "%40";
13177
0
                } else {
13178
0
                  url.append_base_password("%40");
13179
0
                }
13180
0
              } else {
13181
0
                if constexpr (result_type_is_ada_url) {
13182
0
                  url.username += "%40";
13183
0
                } else {
13184
0
                  url.append_base_username("%40");
13185
0
                }
13186
0
              }
13187
0
            }
13188
13189
0
            at_sign_seen = true;
13190
13191
0
            if (!password_token_seen) {
13192
0
              size_t password_token_location = authority_view.find(':');
13193
0
              password_token_seen =
13194
0
                  password_token_location != std::string_view::npos;
13195
13196
0
              if constexpr (store_values) {
13197
0
                if (!password_token_seen) {
13198
0
                  if constexpr (result_type_is_ada_url) {
13199
0
                    url.username += unicode::percent_encode(
13200
0
                        authority_view,
13201
0
                        character_sets::USERINFO_PERCENT_ENCODE);
13202
0
                  } else {
13203
0
                    url.append_base_username(unicode::percent_encode(
13204
0
                        authority_view,
13205
0
                        character_sets::USERINFO_PERCENT_ENCODE));
13206
0
                  }
13207
0
                } else {
13208
0
                  if constexpr (result_type_is_ada_url) {
13209
0
                    url.username += unicode::percent_encode(
13210
0
                        authority_view.substr(0, password_token_location),
13211
0
                        character_sets::USERINFO_PERCENT_ENCODE);
13212
0
                    url.password += unicode::percent_encode(
13213
0
                        authority_view.substr(password_token_location + 1),
13214
0
                        character_sets::USERINFO_PERCENT_ENCODE);
13215
0
                  } else {
13216
0
                    url.append_base_username(unicode::percent_encode(
13217
0
                        authority_view.substr(0, password_token_location),
13218
0
                        character_sets::USERINFO_PERCENT_ENCODE));
13219
0
                    url.append_base_password(unicode::percent_encode(
13220
0
                        authority_view.substr(password_token_location + 1),
13221
0
                        character_sets::USERINFO_PERCENT_ENCODE));
13222
0
                  }
13223
0
                }
13224
0
              }
13225
0
            } else if constexpr (store_values) {
13226
0
              if constexpr (result_type_is_ada_url) {
13227
0
                url.password += unicode::percent_encode(
13228
0
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE);
13229
0
              } else {
13230
0
                url.append_base_password(unicode::percent_encode(
13231
0
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE));
13232
0
              }
13233
0
            }
13234
0
          }
13235
          // Otherwise, if one of the following is true:
13236
          // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
13237
          // - url is special and c is U+005C (\)
13238
0
          else if (end_of_authority == input_size ||
13239
0
                   url_data[end_of_authority] == '/' ||
13240
0
                   url_data[end_of_authority] == '?' ||
13241
0
                   (url.is_special() && url_data[end_of_authority] == '\\')) {
13242
            // If atSignSeen is true and authority_view is the empty string,
13243
            // validation error, return failure.
13244
0
            if (at_sign_seen && authority_view.empty()) {
13245
0
              url.is_valid = false;
13246
0
              return url;
13247
0
            }
13248
0
            state = state::HOST;
13249
0
            break;
13250
0
          }
13251
0
          if (end_of_authority == input_size) {
13252
0
            if constexpr (store_values) {
13253
0
              if (fragment.has_value()) {
13254
0
                url.update_unencoded_base_hash(*fragment);
13255
0
              }
13256
0
            }
13257
0
            enforce_max_input_length();
13258
0
            return url;
13259
0
          }
13260
0
          input_position = end_of_authority + 1;
13261
0
        } while (true);
13262
13263
0
        break;
13264
0
      }
13265
0
      case state::SPECIAL_RELATIVE_OR_AUTHORITY: {
13266
0
        ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ",
13267
0
                helpers::substring(url_data, input_position));
13268
13269
        // If c is U+002F (/) and remaining starts with U+002F (/),
13270
        // then set state to special authority ignore slashes state and increase
13271
        // pointer by 1.
13272
0
        if (url_data.substr(input_position, 2) == "//") {
13273
0
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
13274
0
          input_position += 2;
13275
0
        } else {
13276
          // Otherwise, validation error, set state to relative state and
13277
          // decrease pointer by 1.
13278
0
          state = state::RELATIVE_SCHEME;
13279
0
        }
13280
13281
0
        break;
13282
0
      }
13283
0
      case state::PATH_OR_AUTHORITY: {
13284
0
        ada_log("PATH_OR_AUTHORITY ",
13285
0
                helpers::substring(url_data, input_position));
13286
13287
        // If c is U+002F (/), then set state to authority state.
13288
0
        if ((input_position != input_size) &&
13289
0
            (url_data[input_position] == '/')) {
13290
0
          state = state::AUTHORITY;
13291
0
          input_position++;
13292
0
        } else {
13293
          // Otherwise, set state to path state, and decrease pointer by 1.
13294
0
          state = state::PATH;
13295
0
        }
13296
13297
0
        break;
13298
0
      }
13299
0
      case state::RELATIVE_SCHEME: {
13300
0
        ada_log("RELATIVE_SCHEME ",
13301
0
                helpers::substring(url_data, input_position));
13302
13303
        // Set url's scheme to base's scheme.
13304
0
        url.copy_scheme(*base_url);
13305
13306
        // If c is U+002F (/), then set state to relative slash state.
13307
0
        if ((input_position != input_size) &&
13308
            // NOLINTNEXTLINE(bugprone-branch-clone)
13309
0
            (url_data[input_position] == '/')) {
13310
0
          ada_log(
13311
0
              "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
13312
0
              "slash state");
13313
0
          state = state::RELATIVE_SLASH;
13314
0
        } else if (url.is_special() && (input_position != input_size) &&
13315
0
                   (url_data[input_position] == '\\')) {
13316
          // Otherwise, if url is special and c is U+005C (\), validation error,
13317
          // set state to relative slash state.
13318
0
          ada_log(
13319
0
              "RELATIVE_SCHEME  if url is special and c is U+005C, validation "
13320
0
              "error, set state to relative slash state");
13321
0
          state = state::RELATIVE_SLASH;
13322
0
        } else {
13323
0
          ada_log("RELATIVE_SCHEME otherwise");
13324
          // Set url's username to base's username, url's password to base's
13325
          // password, url's host to base's host, url's port to base's port,
13326
          // url's path to a clone of base's path, and url's query to base's
13327
          // query.
13328
0
          if constexpr (result_type_is_ada_url) {
13329
0
            url.username = base_url->username;
13330
0
            url.password = base_url->password;
13331
0
            url.host = base_url->host;
13332
0
            url.port = base_url->port;
13333
            // cloning the base path includes cloning the has_opaque_path flag
13334
0
            url.has_opaque_path = base_url->has_opaque_path;
13335
0
            url.path = base_url->path;
13336
0
            url.query = base_url->query;
13337
0
          } else {
13338
0
            url.update_base_authority(base_url->get_href(),
13339
0
                                      base_url->get_components());
13340
0
            url.update_host_to_base_host(base_url->get_hostname());
13341
0
            url.update_base_port(base_url->retrieve_base_port());
13342
            // cloning the base path includes cloning the has_opaque_path flag
13343
0
            url.has_opaque_path = base_url->has_opaque_path;
13344
0
            url.update_base_pathname(base_url->get_pathname());
13345
0
            if (base_url->has_search()) {
13346
              // get_search() returns "" for an empty query string (URL ends
13347
              // with '?'). update_base_search("") would incorrectly clear the
13348
              // query, so pass "?" to preserve the empty query distinction.
13349
0
              auto s = base_url->get_search();
13350
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
13351
0
            }
13352
0
          }
13353
13354
0
          url.has_opaque_path = base_url->has_opaque_path;
13355
13356
          // If c is U+003F (?), then set url's query to the empty string, and
13357
          // state to query state.
13358
0
          if ((input_position != input_size) &&
13359
0
              (url_data[input_position] == '?')) {
13360
0
            state = state::QUERY;
13361
0
          }
13362
          // Otherwise, if c is not the EOF code point:
13363
0
          else if (input_position != input_size) {
13364
            // Set url's query to null.
13365
0
            url.clear_search();
13366
0
            if constexpr (result_type_is_ada_url) {
13367
              // Shorten url's path.
13368
0
              helpers::shorten_path(url.path, url.type);
13369
0
            } else {
13370
0
              std::string_view path = url.get_pathname();
13371
0
              if (helpers::shorten_path(path, url.type)) {
13372
0
                url.update_base_pathname(std::move(std::string(path)));
13373
0
              }
13374
0
            }
13375
            // Set state to path state and decrease pointer by 1.
13376
0
            state = state::PATH;
13377
0
            break;
13378
0
          }
13379
0
        }
13380
0
        input_position++;
13381
0
        break;
13382
0
      }
13383
0
      case state::RELATIVE_SLASH: {
13384
0
        ada_log("RELATIVE_SLASH ",
13385
0
                helpers::substring(url_data, input_position));
13386
13387
        // If url is special and c is U+002F (/) or U+005C (\), then:
13388
        // NOLINTNEXTLINE(bugprone-branch-clone)
13389
0
        if (url.is_special() && (input_position != input_size) &&
13390
0
            (url_data[input_position] == '/' ||
13391
0
             url_data[input_position] == '\\')) {
13392
          // Set state to special authority ignore slashes state.
13393
0
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
13394
0
        }
13395
        // Otherwise, if c is U+002F (/), then set state to authority state.
13396
0
        else if ((input_position != input_size) &&
13397
0
                 (url_data[input_position] == '/')) {
13398
0
          state = state::AUTHORITY;
13399
0
        }
13400
        // Otherwise, set
13401
        // - url's username to base's username,
13402
        // - url's password to base's password,
13403
        // - url's host to base's host,
13404
        // - url's port to base's port,
13405
        // - state to path state, and then, decrease pointer by 1.
13406
0
        else {
13407
0
          if constexpr (result_type_is_ada_url) {
13408
0
            url.username = base_url->username;
13409
0
            url.password = base_url->password;
13410
0
            url.host = base_url->host;
13411
0
            url.port = base_url->port;
13412
0
          } else {
13413
0
            url.update_base_authority(base_url->get_href(),
13414
0
                                      base_url->get_components());
13415
0
            url.update_host_to_base_host(base_url->get_hostname());
13416
0
            url.update_base_port(base_url->retrieve_base_port());
13417
0
          }
13418
0
          state = state::PATH;
13419
0
          break;
13420
0
        }
13421
13422
0
        input_position++;
13423
0
        break;
13424
0
      }
13425
0
      case state::SPECIAL_AUTHORITY_SLASHES: {
13426
0
        ada_log("SPECIAL_AUTHORITY_SLASHES ",
13427
0
                helpers::substring(url_data, input_position));
13428
13429
        // If c is U+002F (/) and remaining starts with U+002F (/),
13430
        // then set state to special authority ignore slashes state and increase
13431
        // pointer by 1.
13432
0
        if (url_data.substr(input_position, 2) == "//") {
13433
0
          input_position += 2;
13434
0
        }
13435
13436
0
        [[fallthrough]];
13437
0
      }
13438
0
      case state::SPECIAL_AUTHORITY_IGNORE_SLASHES: {
13439
0
        ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ",
13440
0
                helpers::substring(url_data, input_position));
13441
13442
        // If c is neither U+002F (/) nor U+005C (\), then set state to
13443
        // authority state and decrease pointer by 1.
13444
0
        while ((input_position != input_size) &&
13445
0
               ((url_data[input_position] == '/') ||
13446
0
                (url_data[input_position] == '\\'))) {
13447
0
          input_position++;
13448
0
        }
13449
0
        state = state::AUTHORITY;
13450
13451
0
        break;
13452
0
      }
13453
0
      case state::QUERY: {
13454
0
        ada_log("QUERY ", helpers::substring(url_data, input_position));
13455
0
        if constexpr (store_values) {
13456
          // Let queryPercentEncodeSet be the special-query percent-encode set
13457
          // if url is special; otherwise the query percent-encode set.
13458
0
          const uint8_t* query_percent_encode_set =
13459
0
              url.is_special() ? character_sets::SPECIAL_QUERY_PERCENT_ENCODE
13460
0
                               : character_sets::QUERY_PERCENT_ENCODE;
13461
13462
          // Percent-encode after encoding, with encoding, buffer, and
13463
          // queryPercentEncodeSet, and append the result to url's query.
13464
0
          url.update_base_search(url_data.substr(input_position),
13465
0
                                 query_percent_encode_set);
13466
0
          ada_log("QUERY update_base_search completed ");
13467
0
          if (fragment.has_value()) {
13468
0
            url.update_unencoded_base_hash(*fragment);
13469
0
          }
13470
0
        }
13471
0
        enforce_max_input_length();
13472
0
        return url;
13473
0
      }
13474
0
      case state::HOST: {
13475
0
        ada_log("HOST ", helpers::substring(url_data, input_position));
13476
13477
0
        std::string_view host_view = url_data.substr(input_position);
13478
0
        auto [location, found_colon] =
13479
0
            helpers::get_host_delimiter_location(url.is_special(), host_view);
13480
0
        input_position = (location != std::string_view::npos)
13481
0
                             ? input_position + location
13482
0
                             : input_size;
13483
        // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
13484
        // Note: the 'found_colon' value is true if and only if a colon was
13485
        // encountered while not inside brackets.
13486
0
        if (found_colon) {
13487
          // If buffer is the empty string, validation error, return failure.
13488
          // Let host be the result of host parsing buffer with url is not
13489
          // special.
13490
0
          ada_log("HOST parsing ", host_view);
13491
0
          if (!url.parse_host(host_view)) {
13492
0
            return url;
13493
0
          }
13494
0
          ada_log("HOST parsing results in ", url.get_hostname());
13495
          // Set url's host to host, buffer to the empty string, and state to
13496
          // port state.
13497
0
          state = state::PORT;
13498
0
          input_position++;
13499
0
        }
13500
        // Otherwise, if one of the following is true:
13501
        // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
13502
        // - url is special and c is U+005C (\)
13503
        // The get_host_delimiter_location function either brings us to
13504
        // the colon outside of the bracket, or to one of those characters.
13505
0
        else {
13506
          // If url is special and host_view is the empty string, validation
13507
          // error, return failure.
13508
0
          if (host_view.empty() && url.is_special()) {
13509
0
            url.is_valid = false;
13510
0
            return url;
13511
0
          }
13512
0
          ada_log("HOST parsing ", host_view, " href=", url.get_href());
13513
          // Let host be the result of host parsing host_view with url is not
13514
          // special.
13515
0
          if (host_view.empty()) {
13516
0
            url.update_base_hostname("");
13517
0
          } else if (!url.parse_host(host_view)) {
13518
0
            return url;
13519
0
          }
13520
0
          ada_log("HOST parsing results in ", url.get_hostname(),
13521
0
                  " href=", url.get_href());
13522
13523
          // Set url's host to host, and state to path start state.
13524
0
          state = state::PATH_START;
13525
0
        }
13526
13527
0
        break;
13528
0
      }
13529
0
      case state::OPAQUE_PATH: {
13530
0
        ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position));
13531
        // Opaque path, query, and fragment are structurally always valid:
13532
        // the parser would just percent-encode whatever is there. When we
13533
        // are not storing values (can_parse), we can return immediately.
13534
        // We must set has_opaque_path = true before returning so that when
13535
        // this URL is used as an internal base inside can_parse, NO_SCHEME
13536
        // correctly rejects relative inputs against an opaque-path base
13537
        // (e.g. can_parse("", &"W:") must return false).
13538
0
        if constexpr (!store_values) {
13539
0
          url.has_opaque_path = true;
13540
0
          return url;
13541
0
        }
13542
0
        std::string_view view = url_data.substr(input_position);
13543
        // If c is U+003F (?), then set url's query to the empty string and
13544
        // state to query state.
13545
0
        size_t location = view.find('?');
13546
0
        if (location != std::string_view::npos) {
13547
0
          view.remove_suffix(view.size() - location);
13548
0
          state = state::QUERY;
13549
0
          input_position += location + 1;
13550
0
        } else {
13551
0
          input_position = input_size + 1;
13552
0
        }
13553
0
        url.has_opaque_path = true;
13554
13555
        // This is a really unlikely scenario in real world. We should not seek
13556
        // to optimize it.
13557
0
        if (view.ends_with(' ')) {
13558
0
          std::string modified_view =
13559
0
              std::string(view.substr(0, view.size() - 1)) + "%20";
13560
0
          url.update_base_pathname(unicode::percent_encode(
13561
0
              modified_view, character_sets::C0_CONTROL_PERCENT_ENCODE));
13562
0
        } else {
13563
0
          url.update_base_pathname(unicode::percent_encode(
13564
0
              view, character_sets::C0_CONTROL_PERCENT_ENCODE));
13565
0
        }
13566
0
        break;
13567
0
      }
13568
0
      case state::PORT: {
13569
0
        ada_log("PORT ", helpers::substring(url_data, input_position));
13570
0
        std::string_view port_view = url_data.substr(input_position);
13571
0
        input_position += url.parse_port(port_view, true);
13572
0
        if (!url.is_valid) {
13573
0
          return url;
13574
0
        }
13575
0
        state = state::PATH_START;
13576
0
        [[fallthrough]];
13577
0
      }
13578
0
      case state::PATH_START: {
13579
0
        ada_log("PATH_START ", helpers::substring(url_data, input_position));
13580
        // Path, query, and fragment are structurally always valid: the
13581
        // parser would just percent-encode whatever is there. When we are
13582
        // not storing values (can_parse), we can return immediately since
13583
        // no subsequent state can invalidate the URL.
13584
0
        if constexpr (!store_values) {
13585
0
          return url;
13586
0
        }
13587
13588
        // If url is special, then:
13589
0
        if (url.is_special()) {
13590
          // Set state to path state.
13591
0
          state = state::PATH;
13592
13593
          // Optimization: Avoiding going into PATH state improves the
13594
          // performance of urls ending with /.
13595
0
          if (input_position == input_size) {
13596
0
            if constexpr (store_values) {
13597
0
              url.update_base_pathname("/");
13598
0
              if (fragment.has_value()) {
13599
0
                url.update_unencoded_base_hash(*fragment);
13600
0
              }
13601
0
            }
13602
0
            enforce_max_input_length();
13603
0
            return url;
13604
0
          }
13605
          // If c is neither U+002F (/) nor U+005C (\), then decrease pointer
13606
          // by 1. We know that (input_position == input_size) is impossible
13607
          // here, because of the previous if-check.
13608
0
          if ((url_data[input_position] != '/') &&
13609
0
              (url_data[input_position] != '\\')) {
13610
0
            break;
13611
0
          }
13612
0
        }
13613
        // Otherwise, if state override is not given and c is U+003F (?),
13614
        // set url's query to the empty string and state to query state.
13615
0
        else if ((input_position != input_size) &&
13616
0
                 (url_data[input_position] == '?')) {
13617
0
          state = state::QUERY;
13618
0
        }
13619
        // Otherwise, if c is not the EOF code point:
13620
0
        else if (input_position != input_size) {
13621
          // Set state to path state.
13622
0
          state = state::PATH;
13623
13624
          // If c is not U+002F (/), then decrease pointer by 1.
13625
0
          if (url_data[input_position] != '/') {
13626
0
            break;
13627
0
          }
13628
0
        }
13629
13630
0
        input_position++;
13631
0
        break;
13632
0
      }
13633
0
      case state::PATH: {
13634
0
        ada_log("PATH ", helpers::substring(url_data, input_position));
13635
        // Path, query, and fragment are structurally always valid: the
13636
        // parser would just percent-encode whatever is there. When we are
13637
        // not storing values (can_parse), we can return immediately since
13638
        // no subsequent state can invalidate the URL.
13639
0
        if constexpr (!store_values) {
13640
0
          return url;
13641
0
        }
13642
0
        std::string_view view = url_data.substr(input_position);
13643
13644
        // Most time, we do not need percent encoding.
13645
        // Furthermore, we can immediately locate the '?'.
13646
0
        size_t locofquestionmark = view.find('?');
13647
0
        if (locofquestionmark != std::string_view::npos) {
13648
0
          state = state::QUERY;
13649
0
          view.remove_suffix(view.size() - locofquestionmark);
13650
0
          input_position += locofquestionmark + 1;
13651
0
        } else {
13652
0
          input_position = input_size + 1;
13653
0
        }
13654
0
        if constexpr (store_values) {
13655
0
          if constexpr (result_type_is_ada_url) {
13656
0
            helpers::parse_prepared_path(view, url.type, url.path);
13657
0
          } else {
13658
0
            url.consume_prepared_path(view);
13659
0
            ADA_ASSERT_TRUE(url.validate());
13660
0
          }
13661
0
        }
13662
0
        break;
13663
0
      }
13664
0
      case state::FILE_SLASH: {
13665
0
        ada_log("FILE_SLASH ", helpers::substring(url_data, input_position));
13666
13667
        // If c is U+002F (/) or U+005C (\), then:
13668
0
        if ((input_position != input_size) &&
13669
0
            (url_data[input_position] == '/' ||
13670
0
             url_data[input_position] == '\\')) {
13671
0
          ada_log("FILE_SLASH c is U+002F or U+005C");
13672
          // Set state to file host state.
13673
0
          state = state::FILE_HOST;
13674
0
          input_position++;
13675
0
        } else {
13676
0
          ada_log("FILE_SLASH otherwise");
13677
          // If base is non-null and base's scheme is "file", then:
13678
          // Note: it is unsafe to do base_url->scheme unless you know that
13679
          // base_url_has_value() is true.
13680
0
          if (base_url != nullptr && base_url->type == scheme::type::FILE) {
13681
            // Set url's host to base's host.
13682
0
            if constexpr (result_type_is_ada_url) {
13683
0
              url.host = base_url->host;
13684
0
            } else {
13685
0
              url.update_host_to_base_host(base_url->get_host());
13686
0
            }
13687
            // If the code point substring from pointer to the end of input does
13688
            // not start with a Windows drive letter and base's path[0] is a
13689
            // normalized Windows drive letter, then append base's path[0] to
13690
            // url's path.
13691
0
            if (!base_url->get_pathname().empty()) {
13692
0
              if (!checkers::is_windows_drive_letter(
13693
0
                      url_data.substr(input_position))) {
13694
0
                std::string_view first_base_url_path =
13695
0
                    base_url->get_pathname().substr(1);
13696
0
                size_t loc = first_base_url_path.find('/');
13697
0
                if (loc != std::string_view::npos) {
13698
0
                  helpers::resize(first_base_url_path, loc);
13699
0
                }
13700
0
                if (checkers::is_normalized_windows_drive_letter(
13701
0
                        first_base_url_path)) {
13702
0
                  if constexpr (result_type_is_ada_url) {
13703
0
                    url.path += '/';
13704
0
                    url.path += first_base_url_path;
13705
0
                  } else {
13706
0
                    url.append_base_pathname(
13707
0
                        helpers::concat("/", first_base_url_path));
13708
0
                  }
13709
0
                }
13710
0
              }
13711
0
            }
13712
0
          }
13713
13714
          // Set state to path state, and decrease pointer by 1.
13715
0
          state = state::PATH;
13716
0
        }
13717
13718
0
        break;
13719
0
      }
13720
0
      case state::FILE_HOST: {
13721
0
        ada_log("FILE_HOST ", helpers::substring(url_data, input_position));
13722
0
        std::string_view view = url_data.substr(input_position);
13723
13724
0
        size_t location = view.find_first_of("/\\?");
13725
0
        std::string_view file_host_buffer = view.substr(
13726
0
            0, (location != std::string_view::npos) ? location : view.size());
13727
13728
0
        if (checkers::is_windows_drive_letter(file_host_buffer)) {
13729
0
          state = state::PATH;
13730
0
        } else if (file_host_buffer.empty()) {
13731
          // Set url's host to the empty string.
13732
0
          if constexpr (result_type_is_ada_url) {
13733
0
            url.host = "";
13734
0
          } else {
13735
0
            url.update_base_hostname("");
13736
0
          }
13737
          // Set state to path start state.
13738
0
          state = state::PATH_START;
13739
0
        } else {
13740
0
          size_t consumed_bytes = file_host_buffer.size();
13741
0
          input_position += consumed_bytes;
13742
          // Let host be the result of host parsing buffer with url is not
13743
          // special.
13744
0
          if (!url.parse_host(file_host_buffer)) {
13745
0
            return url;
13746
0
          }
13747
13748
0
          if constexpr (result_type_is_ada_url) {
13749
            // If host is "localhost", then set host to the empty string.
13750
0
            if (url.host.has_value() && url.host.value() == "localhost") {
13751
0
              url.host = "";
13752
0
            }
13753
0
          } else {
13754
0
            if (url.get_hostname() == "localhost") {
13755
0
              url.update_base_hostname("");
13756
0
            }
13757
0
          }
13758
13759
          // Set buffer to the empty string and state to path start state.
13760
0
          state = state::PATH_START;
13761
0
        }
13762
13763
0
        break;
13764
0
      }
13765
0
      case state::FILE: {
13766
0
        ada_log("FILE ", helpers::substring(url_data, input_position));
13767
0
        std::string_view file_view = url_data.substr(input_position);
13768
13769
0
        url.set_protocol_as_file();
13770
0
        if constexpr (result_type_is_ada_url) {
13771
          // Set url's host to the empty string.
13772
0
          url.host = "";
13773
0
        } else {
13774
0
          url.update_base_hostname("");
13775
0
        }
13776
        // If c is U+002F (/) or U+005C (\), then:
13777
0
        if (input_position != input_size &&
13778
0
            (url_data[input_position] == '/' ||
13779
0
             url_data[input_position] == '\\')) {
13780
0
          ada_log("FILE c is U+002F or U+005C");
13781
          // Set state to file slash state.
13782
0
          state = state::FILE_SLASH;
13783
0
        }
13784
        // Otherwise, if base is non-null and base's scheme is "file":
13785
0
        else if (base_url != nullptr && base_url->type == scheme::type::FILE) {
13786
          // Set url's host to base's host, url's path to a clone of base's
13787
          // path, and url's query to base's query.
13788
0
          ada_log("FILE base non-null");
13789
0
          if constexpr (result_type_is_ada_url) {
13790
0
            url.host = base_url->host;
13791
0
            url.path = base_url->path;
13792
0
            url.query = base_url->query;
13793
0
          } else {
13794
0
            url.update_host_to_base_host(base_url->get_hostname());
13795
0
            url.update_base_pathname(base_url->get_pathname());
13796
0
            if (base_url->has_search()) {
13797
              // get_search() returns "" for an empty query string (URL ends
13798
              // with '?'). update_base_search("") would incorrectly clear the
13799
              // query, so pass "?" to preserve the empty query distinction.
13800
0
              auto s = base_url->get_search();
13801
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
13802
0
            }
13803
0
          }
13804
0
          url.has_opaque_path = base_url->has_opaque_path;
13805
13806
          // If c is U+003F (?), then set url's query to the empty string and
13807
          // state to query state.
13808
0
          if (input_position != input_size && url_data[input_position] == '?') {
13809
0
            state = state::QUERY;
13810
0
          }
13811
          // Otherwise, if c is not the EOF code point:
13812
0
          else if (input_position != input_size) {
13813
            // Set url's query to null.
13814
0
            url.clear_search();
13815
            // If the code point substring from pointer to the end of input does
13816
            // not start with a Windows drive letter, then shorten url's path.
13817
0
            if (!checkers::is_windows_drive_letter(file_view)) {
13818
0
              if constexpr (result_type_is_ada_url) {
13819
0
                helpers::shorten_path(url.path, url.type);
13820
0
              } else {
13821
0
                std::string_view path = url.get_pathname();
13822
0
                if (helpers::shorten_path(path, url.type)) {
13823
0
                  url.update_base_pathname(std::move(std::string(path)));
13824
0
                }
13825
0
              }
13826
0
            }
13827
            // Otherwise:
13828
0
            else {
13829
              // Set url's path to an empty list.
13830
0
              url.clear_pathname();
13831
0
              url.has_opaque_path = true;
13832
0
            }
13833
13834
            // Set state to path state and decrease pointer by 1.
13835
0
            state = state::PATH;
13836
0
            break;
13837
0
          }
13838
0
        }
13839
        // Otherwise, set state to path state, and decrease pointer by 1.
13840
0
        else {
13841
0
          ada_log("FILE go to path");
13842
0
          state = state::PATH;
13843
0
          break;
13844
0
        }
13845
13846
0
        input_position++;
13847
0
        break;
13848
0
      }
13849
0
      default:
13850
0
        unreachable();
13851
0
    }
13852
0
  }
13853
0
  if constexpr (store_values) {
13854
0
    if (fragment.has_value()) {
13855
0
      url.update_unencoded_base_hash(*fragment);
13856
0
    }
13857
0
  }
13858
0
  enforce_max_input_length();
13859
0
  return url;
13860
0
}
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*)
Unexecuted instantiation: 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*)
Unexecuted instantiation: 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*)
13861
13862
template bool try_parse_simple_absolute<url>(std::string_view, url&);
13863
template bool try_parse_simple_absolute<url_aggregator>(std::string_view,
13864
                                                        url_aggregator&);
13865
template bool finish_simple_absolute_with_port<url>(std::string_view, url&,
13866
                                                    ada::scheme::type, uint32_t,
13867
                                                    size_t, size_t, size_t,
13868
                                                    bool);
13869
template bool finish_simple_absolute_with_port<url_aggregator>(
13870
    std::string_view, url_aggregator&, ada::scheme::type, uint32_t, size_t,
13871
    size_t, size_t, bool);
13872
template bool try_parse_simple_relative<url>(std::string_view, const url&,
13873
                                             url&);
13874
template bool try_parse_simple_relative<url_aggregator>(std::string_view,
13875
                                                        const url_aggregator&,
13876
                                                        url_aggregator&);
13877
13878
template url parse_url_impl<url, true>(std::string_view user_input,
13879
                                       const url* base_url = nullptr);
13880
template url_aggregator parse_url_impl<url_aggregator, true>(
13881
    std::string_view user_input, const url_aggregator* base_url = nullptr);
13882
template url_aggregator parse_url_impl<url_aggregator, false>(
13883
    std::string_view user_input, const url_aggregator* base_url = nullptr);
13884
13885
template <class result_type>
13886
result_type parse_url(std::string_view user_input,
13887
0
                      const result_type* base_url) {
13888
0
  return parse_url_impl<result_type, true>(user_input, base_url);
13889
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*)
13890
13891
template url parse_url<url>(std::string_view user_input,
13892
                            const url* base_url = nullptr);
13893
template url_aggregator parse_url<url_aggregator>(
13894
    std::string_view user_input, const url_aggregator* base_url = nullptr);
13895
}  // namespace ada::parser
13896
/* end file src/parser.cpp */
13897
/* begin file src/url_components.cpp */
13898
13899
#include <iterator>
13900
#include <string>
13901
13902
namespace ada {
13903
13904
0
[[nodiscard]] std::string url_components::to_string() const {
13905
0
  std::string answer;
13906
0
  auto back = std::back_insert_iterator(answer);
13907
0
  answer.append("{\n");
13908
13909
0
  answer.append("\t\"protocol_end\":\"");
13910
0
  helpers::encode_json(std::to_string(protocol_end), back);
13911
0
  answer.append("\",\n");
13912
13913
0
  answer.append("\t\"username_end\":\"");
13914
0
  helpers::encode_json(std::to_string(username_end), back);
13915
0
  answer.append("\",\n");
13916
13917
0
  answer.append("\t\"host_start\":\"");
13918
0
  helpers::encode_json(std::to_string(host_start), back);
13919
0
  answer.append("\",\n");
13920
13921
0
  answer.append("\t\"host_end\":\"");
13922
0
  helpers::encode_json(std::to_string(host_end), back);
13923
0
  answer.append("\",\n");
13924
13925
0
  answer.append("\t\"port\":\"");
13926
0
  helpers::encode_json(std::to_string(port), back);
13927
0
  answer.append("\",\n");
13928
13929
0
  answer.append("\t\"pathname_start\":\"");
13930
0
  helpers::encode_json(std::to_string(pathname_start), back);
13931
0
  answer.append("\",\n");
13932
13933
0
  answer.append("\t\"search_start\":\"");
13934
0
  helpers::encode_json(std::to_string(search_start), back);
13935
0
  answer.append("\",\n");
13936
13937
0
  answer.append("\t\"hash_start\":\"");
13938
0
  helpers::encode_json(std::to_string(hash_start), back);
13939
0
  answer.append("\",\n");
13940
13941
0
  answer.append("\n}");
13942
0
  return answer;
13943
0
}
13944
13945
}  // namespace ada
13946
/* end file src/url_components.cpp */
13947
/* begin file src/url_aggregator.cpp */
13948
13949
#include <algorithm>
13950
#include <array>
13951
#include <cstdint>
13952
#include <cstring>
13953
#include <iterator>
13954
#include <optional>
13955
#include <ranges>
13956
#include <string>
13957
#include <string_view>
13958
#include <utility>
13959
13960
namespace {
13961
13962
ada_really_inline void apply_shifted_non_scheme_offsets(
13963
0
    ada::url_components& components, uint32_t new_difference) {
13964
0
  components.username_end += new_difference;
13965
0
  components.host_start += new_difference;
13966
0
  components.host_end += new_difference;
13967
0
  components.pathname_start += new_difference;
13968
0
  if (components.search_start != ada::url_components::omitted) {
13969
0
    components.search_start += new_difference;
13970
0
  }
13971
0
  if (components.hash_start != ada::url_components::omitted) {
13972
0
    components.hash_start += new_difference;
13973
0
  }
13974
0
}
13975
13976
}  // namespace
13977
13978
namespace ada {
13979
template <bool has_state_override>
13980
[[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon(
13981
0
    const std::string_view input_with_colon) {
13982
0
  ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon);
13983
0
  ADA_ASSERT_TRUE(validate());
13984
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));
13985
0
  std::string_view input{input_with_colon};
13986
0
  input.remove_suffix(1);
13987
0
  auto parsed_type = ada::scheme::get_scheme_type(input);
13988
0
  const bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
13989
  /**
13990
   * In the common case, we will immediately recognize a special scheme (e.g.,
13991
   *http, https), in which case, we can go really fast.
13992
   **/
13993
0
  if (is_input_special) {  // fast path!!!
13994
0
    if constexpr (has_state_override) {
13995
      // If url's scheme is not a special scheme and buffer is a special scheme,
13996
      // then return.
13997
0
      if (is_special() != is_input_special) {
13998
0
        return false;
13999
0
      }
14000
14001
      // If url includes credentials or has a non-null port, and buffer is
14002
      // "file", then return.
14003
0
      if ((has_credentials() || components.port != url_components::omitted) &&
14004
0
          parsed_type == ada::scheme::type::FILE) {
14005
0
        return false;
14006
0
      }
14007
14008
      // If url's scheme is "file" and its host is an empty host, then return.
14009
      // An empty host is the empty string.
14010
0
      if (type == ada::scheme::type::FILE &&
14011
0
          components.host_start == components.host_end) {
14012
0
        return false;
14013
0
      }
14014
0
    }
14015
14016
0
    type = parsed_type;
14017
0
    set_scheme_from_view_with_colon(input_with_colon);
14018
14019
0
    if constexpr (has_state_override) {
14020
      // This is uncommon.
14021
0
      uint16_t urls_scheme_port = get_special_port();
14022
14023
0
      if (urls_scheme_port) {
14024
        // If url's port is url's scheme's default port, then set url's port to
14025
        // null.
14026
0
        if (components.port == urls_scheme_port) {
14027
0
          clear_port();
14028
0
        }
14029
0
      }
14030
0
    }
14031
0
  } else {  // slow path
14032
0
    std::string _buffer(input);
14033
    // Next function is only valid if the input is ASCII and returns false
14034
    // otherwise, but it seems that we always have ascii content so we do not
14035
    // need to check the return value.
14036
0
    unicode::to_lower_ascii(_buffer.data(), _buffer.size());
14037
14038
0
    if constexpr (has_state_override) {
14039
      // The state-override validation errors below ("return" in the WHATWG URL
14040
      // parser) leave the URL unchanged. The setter contract is
14041
      // "true on success, false if the scheme is invalid" -- the fast path
14042
      // above already returns false here, so the slow path must agree.
14043
14044
      // If url's scheme is a special scheme and buffer is not a special scheme,
14045
      // then return. If url's scheme is not a special scheme and buffer is a
14046
      // special scheme, then return.
14047
0
      if (is_special() != ada::scheme::is_special(_buffer)) {
14048
0
        return false;
14049
0
      }
14050
14051
      // If url includes credentials or has a non-null port, and buffer is
14052
      // "file", then return.
14053
0
      if ((has_credentials() || components.port != url_components::omitted) &&
14054
0
          _buffer == "file") {
14055
0
        return false;
14056
0
      }
14057
14058
      // If url's scheme is "file" and its host is an empty host, then return.
14059
      // An empty host is the empty string.
14060
0
      if (type == ada::scheme::type::FILE &&
14061
0
          components.host_start == components.host_end) {
14062
0
        return false;
14063
0
      }
14064
0
    }
14065
14066
0
    set_scheme(_buffer);
14067
14068
0
    if constexpr (has_state_override) {
14069
      // This is uncommon.
14070
0
      uint16_t urls_scheme_port = get_special_port();
14071
14072
0
      if (urls_scheme_port) {
14073
        // If url's port is url's scheme's default port, then set url's port to
14074
        // null.
14075
0
        if (components.port == urls_scheme_port) {
14076
0
          clear_port();
14077
0
        }
14078
0
      }
14079
0
    }
14080
0
  }
14081
0
  ADA_ASSERT_TRUE(validate());
14082
0
  return true;
14083
0
}
Unexecuted instantiation: bool ada::url_aggregator::parse_scheme_with_colon<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: bool ada::url_aggregator::parse_scheme_with_colon<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
14084
14085
0
inline void url_aggregator::copy_scheme(const url_aggregator& u) {
14086
0
  ada_log("url_aggregator::copy_scheme ", u.buffer);
14087
0
  ADA_ASSERT_TRUE(validate());
14088
  // next line could overflow but unsigned arithmetic has well-defined
14089
  // overflows.
14090
0
  uint32_t new_difference = u.components.protocol_end - components.protocol_end;
14091
14092
0
  type = u.type;
14093
0
  buffer.erase(0, components.protocol_end);
14094
0
  buffer.insert(0, u.get_protocol());
14095
0
  components.protocol_end = u.components.protocol_end;
14096
14097
  // No need to update the components
14098
0
  if (new_difference == 0) {
14099
0
    return;
14100
0
  }
14101
14102
0
  apply_shifted_non_scheme_offsets(components, new_difference);
14103
0
  ADA_ASSERT_TRUE(validate());
14104
0
}
14105
14106
inline void url_aggregator::set_scheme_from_view_with_colon(
14107
0
    std::string_view new_scheme_with_colon) {
14108
0
  ada_log("url_aggregator::set_scheme_from_view_with_colon ",
14109
0
          new_scheme_with_colon);
14110
0
  ADA_ASSERT_TRUE(validate());
14111
0
  ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() &&
14112
0
                  new_scheme_with_colon.back() == ':');
14113
  // next line could overflow but unsigned arithmetic has well-defined
14114
  // overflows.
14115
0
  uint32_t new_difference =
14116
0
      uint32_t(new_scheme_with_colon.size()) - components.protocol_end;
14117
14118
0
  if (buffer.empty()) {
14119
0
    buffer.append(new_scheme_with_colon);
14120
0
  } else {
14121
0
    buffer.erase(0, components.protocol_end);
14122
0
    buffer.insert(0, new_scheme_with_colon);
14123
0
  }
14124
0
  components.protocol_end += new_difference;
14125
14126
0
  apply_shifted_non_scheme_offsets(components, new_difference);
14127
0
  ADA_ASSERT_TRUE(validate());
14128
0
}
14129
14130
0
inline void url_aggregator::set_scheme(std::string_view new_scheme) {
14131
0
  ada_log("url_aggregator::set_scheme ", new_scheme);
14132
0
  ADA_ASSERT_TRUE(validate());
14133
0
  ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':');
14134
  // next line could overflow but unsigned arithmetic has well-defined
14135
  // overflows.
14136
0
  uint32_t new_difference =
14137
0
      uint32_t(new_scheme.size()) - components.protocol_end + 1;
14138
14139
0
  type = ada::scheme::get_scheme_type(new_scheme);
14140
0
  if (buffer.empty()) {
14141
0
    buffer.append(helpers::concat(new_scheme, ":"));
14142
0
  } else {
14143
0
    buffer.erase(0, components.protocol_end);
14144
0
    buffer.insert(0, helpers::concat(new_scheme, ":"));
14145
0
  }
14146
0
  components.protocol_end = uint32_t(new_scheme.size() + 1);
14147
14148
0
  apply_shifted_non_scheme_offsets(components, new_difference);
14149
0
  ADA_ASSERT_TRUE(validate());
14150
0
}
14151
14152
0
bool url_aggregator::needs_rollback_snapshot(size_t input_len) const noexcept {
14153
  // 3x should cover worst-case percent-encoding of every input byte; the
14154
  // constant covers the handful of delimiter bytes a setter may add ("/.", "?",
14155
  // "#" and so on)
14156
0
  return buffer.size() + input_len * 3 + 16 > ada::get_max_input_length();
14157
0
}
14158
14159
0
bool url_aggregator::set_protocol(const std::string_view input) {
14160
0
  ada_log("url_aggregator::set_protocol ", input);
14161
0
  ADA_ASSERT_TRUE(validate());
14162
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14163
0
  std::string view(input);
14164
0
  helpers::remove_ascii_tab_or_newline(view);
14165
0
  if (view.empty()) {
14166
0
    return true;
14167
0
  }
14168
14169
  // Schemes should start with alpha values.
14170
0
  if (!checkers::is_alpha(view[0])) {
14171
0
    return false;
14172
0
  }
14173
14174
0
  view.append(":");
14175
14176
0
  std::string::iterator pointer =
14177
0
      std::ranges::find_if_not(view, unicode::is_alnum_plus);
14178
14179
0
  if (pointer != view.end() && *pointer == ':') {
14180
0
    std::optional<url_aggregator> saved_url;
14181
0
    if (needs_rollback_snapshot(view.size())) {
14182
0
      saved_url = *this;
14183
0
    }
14184
0
    bool result = parse_scheme_with_colon<true>(
14185
0
        view.substr(0, pointer - view.begin() + 1));
14186
0
    if (result && saved_url && buffer.size() > ada::get_max_input_length()) {
14187
0
      *this = std::move(*saved_url);
14188
0
      return false;
14189
0
    }
14190
0
    return result;
14191
0
  }
14192
0
  return false;
14193
0
}
14194
14195
0
bool url_aggregator::set_username(const std::string_view input) {
14196
0
  ada_log("url_aggregator::set_username '", input, "' ");
14197
0
  ADA_ASSERT_TRUE(validate());
14198
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14199
0
  if (cannot_have_credentials_or_port()) {
14200
0
    return false;
14201
0
  }
14202
0
  std::optional<url_aggregator> saved_url;
14203
0
  if (needs_rollback_snapshot(input.size())) {
14204
0
    saved_url = *this;
14205
0
  }
14206
0
  size_t idx = ada::unicode::percent_encode_index(
14207
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
14208
0
  if (idx == input.size()) {
14209
0
    update_base_username(input);
14210
0
  } else {
14211
    // We only create a temporary string if we have to!
14212
0
    update_base_username(ada::unicode::percent_encode(
14213
0
        input, character_sets::USERINFO_PERCENT_ENCODE, idx));
14214
0
  }
14215
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14216
0
    *this = std::move(*saved_url);
14217
0
    return false;
14218
0
  }
14219
0
  ADA_ASSERT_TRUE(validate());
14220
0
  return true;
14221
0
}
14222
14223
0
bool url_aggregator::set_password(const std::string_view input) {
14224
0
  ada_log("url_aggregator::set_password '", input, "'");
14225
0
  ADA_ASSERT_TRUE(validate());
14226
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14227
0
  if (cannot_have_credentials_or_port()) {
14228
0
    return false;
14229
0
  }
14230
0
  std::optional<url_aggregator> saved_url;
14231
0
  if (needs_rollback_snapshot(input.size())) {
14232
0
    saved_url = *this;
14233
0
  }
14234
0
  size_t idx = ada::unicode::percent_encode_index(
14235
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
14236
0
  if (idx == input.size()) {
14237
0
    update_base_password(input);
14238
0
  } else {
14239
    // We only create a temporary string if we have to!
14240
0
    update_base_password(ada::unicode::percent_encode(
14241
0
        input, character_sets::USERINFO_PERCENT_ENCODE, idx));
14242
0
  }
14243
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14244
0
    *this = std::move(*saved_url);
14245
0
    return false;
14246
0
  }
14247
0
  ADA_ASSERT_TRUE(validate());
14248
0
  return true;
14249
0
}
14250
14251
0
bool url_aggregator::set_port(const std::string_view input) {
14252
0
  ada_log("url_aggregator::set_port ", input);
14253
0
  ADA_ASSERT_TRUE(validate());
14254
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14255
0
  if (cannot_have_credentials_or_port()) {
14256
0
    return false;
14257
0
  }
14258
14259
0
  if (input.empty()) {
14260
0
    clear_port();
14261
0
    return true;
14262
0
  }
14263
14264
0
  std::string trimmed(input);
14265
0
  helpers::remove_ascii_tab_or_newline(trimmed);
14266
14267
0
  if (trimmed.empty()) {
14268
0
    return true;
14269
0
  }
14270
14271
  // Input should not start with a non-digit character.
14272
0
  if (!ada::unicode::is_ascii_digit(trimmed.front())) {
14273
0
    return false;
14274
0
  }
14275
14276
  // Find the first non-digit character to determine the length of digits
14277
0
  auto first_non_digit =
14278
0
      std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit);
14279
0
  std::string_view digits_to_parse =
14280
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
14281
14282
  // parse_port only touches the buffer once the digits are already known to
14283
  // be in range, so an invalid port never mutates anything and needs no
14284
  // rollback; a valid one can only grow the buffer by a few bytes.
14285
0
  std::optional<url_aggregator> saved_url;
14286
0
  if (needs_rollback_snapshot(digits_to_parse.size())) {
14287
0
    saved_url = *this;
14288
0
  }
14289
0
  parse_port(digits_to_parse);
14290
0
  if (!is_valid) {
14291
0
    is_valid = true;
14292
0
    ADA_ASSERT_TRUE(validate());
14293
0
    return false;
14294
0
  }
14295
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14296
0
    *this = std::move(*saved_url);
14297
0
    return false;
14298
0
  }
14299
0
  return true;
14300
0
}
14301
14302
0
bool url_aggregator::set_pathname(const std::string_view input) {
14303
0
  ada_log("url_aggregator::set_pathname ", input);
14304
0
  ADA_ASSERT_TRUE(validate());
14305
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14306
0
  if (has_opaque_path) {
14307
0
    return false;
14308
0
  }
14309
0
  std::optional<url_aggregator> saved_url;
14310
0
  if (needs_rollback_snapshot(input.size())) {
14311
0
    saved_url = *this;
14312
0
  }
14313
0
  clear_pathname();
14314
0
  parse_path(input);
14315
0
  if (get_pathname().starts_with("//") && !has_authority() && !has_dash_dot()) {
14316
0
    buffer.insert(components.pathname_start, "/.");
14317
0
    components.pathname_start += 2;
14318
0
    if (components.search_start != url_components::omitted) {
14319
0
      components.search_start += 2;
14320
0
    }
14321
0
    if (components.hash_start != url_components::omitted) {
14322
0
      components.hash_start += 2;
14323
0
    }
14324
0
  }
14325
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14326
0
    *this = std::move(*saved_url);
14327
0
    return false;
14328
0
  }
14329
0
  ADA_ASSERT_TRUE(validate());
14330
0
  return true;
14331
0
}
14332
14333
0
ada_really_inline void url_aggregator::parse_path(std::string_view input) {
14334
0
  ada_log("url_aggregator::parse_path ", input);
14335
0
  ADA_ASSERT_TRUE(validate());
14336
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14337
0
  std::string tmp_buffer;
14338
0
  std::string_view internal_input;
14339
0
  if (unicode::has_tabs_or_newline(input)) {
14340
0
    tmp_buffer = input;
14341
    // Optimization opportunity: Instead of copying and then pruning, we could
14342
    // just directly build the string from user_input.
14343
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
14344
0
    internal_input = tmp_buffer;
14345
0
  } else {
14346
0
    internal_input = input;
14347
0
  }
14348
14349
  // If url is special, then:
14350
0
  if (is_special()) {
14351
0
    if (internal_input.empty()) {
14352
0
      update_base_pathname("/");
14353
0
    } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
14354
0
      consume_prepared_path(internal_input.substr(1));
14355
0
    } else {
14356
0
      consume_prepared_path(internal_input);
14357
0
    }
14358
0
  } else if (!internal_input.empty()) {
14359
0
    if (internal_input[0] == '/') {
14360
0
      consume_prepared_path(internal_input.substr(1));
14361
0
    } else {
14362
0
      consume_prepared_path(internal_input);
14363
0
    }
14364
0
  } else {
14365
    // Non-special URLs with an empty host can have their paths erased
14366
    // Path-only URLs cannot have their paths erased
14367
0
    if (components.host_start == components.host_end && !has_authority()) {
14368
0
      update_base_pathname("/");
14369
0
    }
14370
0
  }
14371
0
  ADA_ASSERT_TRUE(validate());
14372
0
}
14373
14374
0
void url_aggregator::set_search(const std::string_view input) {
14375
0
  ada_log("url_aggregator::set_search ", input);
14376
0
  ADA_ASSERT_TRUE(validate());
14377
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14378
0
  if (input.empty()) {
14379
0
    clear_search();
14380
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
14381
0
    return;
14382
0
  }
14383
14384
0
  std::string_view stripped = input[0] == '?' ? input.substr(1) : input;
14385
  // Fast path: no tabs/newlines (the common case) avoids the std::string
14386
  // allocation entirely by passing the view straight to update_base_search.
14387
0
  std::string cleaned;
14388
0
  std::string_view effective = stripped;
14389
0
  if (unicode::has_tabs_or_newline(stripped)) {
14390
0
    cleaned = stripped;
14391
0
    helpers::remove_ascii_tab_or_newline(cleaned);
14392
0
    effective = cleaned;
14393
0
  }
14394
14395
0
  auto query_percent_encode_set =
14396
0
      is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
14397
0
                   : ada::character_sets::QUERY_PERCENT_ENCODE;
14398
14399
0
  std::optional<url_aggregator> saved_url;
14400
0
  if (needs_rollback_snapshot(effective.size())) {
14401
0
    saved_url = *this;
14402
0
  }
14403
0
  update_base_search(effective, query_percent_encode_set);
14404
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14405
0
    *this = std::move(*saved_url);
14406
0
    return;
14407
0
  }
14408
0
  ADA_ASSERT_TRUE(validate());
14409
0
}
14410
14411
0
void url_aggregator::set_hash(const std::string_view input) {
14412
0
  ada_log("url_aggregator::set_hash ", input);
14413
0
  ADA_ASSERT_TRUE(validate());
14414
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14415
0
  if (input.empty()) {
14416
0
    if (components.hash_start != url_components::omitted) {
14417
0
      buffer.resize(components.hash_start);
14418
0
      components.hash_start = url_components::omitted;
14419
0
    }
14420
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
14421
0
    return;
14422
0
  }
14423
14424
0
  std::string_view stripped = input[0] == '#' ? input.substr(1) : input;
14425
  // Fast path: no tabs/newlines (the common case) avoids the std::string
14426
  // allocation entirely by passing the view straight through.
14427
0
  std::string cleaned;
14428
0
  std::string_view effective = stripped;
14429
0
  if (unicode::has_tabs_or_newline(stripped)) {
14430
0
    cleaned = stripped;
14431
0
    helpers::remove_ascii_tab_or_newline(cleaned);
14432
0
    effective = cleaned;
14433
0
  }
14434
0
  std::optional<url_aggregator> saved_url;
14435
0
  if (needs_rollback_snapshot(effective.size())) {
14436
0
    saved_url = *this;
14437
0
  }
14438
0
  update_unencoded_base_hash(effective);
14439
0
  if (saved_url && buffer.size() > ada::get_max_input_length()) {
14440
0
    *this = std::move(*saved_url);
14441
0
    return;
14442
0
  }
14443
0
  ADA_ASSERT_TRUE(validate());
14444
0
}
14445
14446
0
bool url_aggregator::set_href(const std::string_view input) {
14447
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14448
0
  ada_log("url_aggregator::set_href ", input, " [", input.size(), " bytes]");
14449
0
  ada::result<url_aggregator> out = ada::parse<url_aggregator>(input);
14450
0
  ada_log("url_aggregator::set_href, success :", out.has_value());
14451
14452
0
  if (out) {
14453
    // The parser enforces get_max_input_length() on both the input and the
14454
    // normalized result. This is a defense-in-depth check.
14455
0
    if (out->buffer.size() > ada::get_max_input_length()) {
14456
0
      return false;
14457
0
    }
14458
0
    ada_log("url_aggregator::set_href, parsed ", out->to_string());
14459
    // TODO: Figure out why the following line puts test to never finish.
14460
0
    *this = std::move(*out);
14461
0
  }
14462
14463
0
  return out.has_value();
14464
0
}
14465
14466
0
ada_really_inline bool url_aggregator::parse_host(std::string_view input) {
14467
0
  ada_log("url_aggregator:parse_host \"", input, "\" [", input.size(),
14468
0
          " bytes]");
14469
0
  ADA_ASSERT_TRUE(validate());
14470
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14471
0
  if (input.empty()) {
14472
0
    return is_valid = false;
14473
0
  }  // technically unnecessary.
14474
  // If input starts with U+005B ([), then:
14475
0
  if (input[0] == '[') {
14476
    // If input does not end with U+005D (]), validation error, return failure.
14477
0
    if (input.back() != ']') {
14478
0
      return is_valid = false;
14479
0
    }
14480
0
    ada_log("parse_host ipv6");
14481
14482
    // Return the result of IPv6 parsing input with its leading U+005B ([) and
14483
    // trailing U+005D (]) removed.
14484
0
    input.remove_prefix(1);
14485
0
    input.remove_suffix(1);
14486
0
    return parse_ipv6(input);
14487
0
  }
14488
14489
  // If isNotSpecial is true, then return the result of opaque-host parsing
14490
  // input.
14491
0
  if (!is_special()) {
14492
0
    return parse_opaque_host(input);
14493
0
  }
14494
  // Let domain be the result of running UTF-8 decode without BOM on the
14495
  // percent-decoding of input. Let asciiDomain be the result of running domain
14496
  // to ASCII with domain and false. The most common case is an ASCII input, in
14497
  // which case we do not need to call the expensive 'to_ascii' if a few
14498
  // conditions are met: no '%' and no 'xn-' subsequence.
14499
14500
  // Often, the input does not contain any forbidden code points, and no upper
14501
  // case ASCII letter, then we can just copy it to the buffer. We want to
14502
  // optimize for such a common case.
14503
14504
  // Fast path: try to parse as pure decimal IPv4 first.
14505
0
  const uint64_t fast_result = checkers::try_parse_ipv4_fast(input);
14506
0
  if (fast_result < checkers::ipv4_fast_fail) {
14507
0
    if (!input.empty() && input.back() == '.') {
14508
0
      update_base_hostname(input.substr(0, input.size() - 1));
14509
0
    } else {
14510
0
      update_base_hostname(input);
14511
0
    }
14512
0
    host_type = IPV4;
14513
0
    is_valid = true;
14514
0
    ada_log("parse_host fast path decimal ipv4");
14515
0
    ADA_ASSERT_TRUE(validate());
14516
0
    return true;
14517
0
  }
14518
0
  uint8_t is_forbidden_or_upper =
14519
0
      unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
14520
0
                                                             input.size());
14521
0
  static constexpr std::string_view xn_dash{"xn-", 3};
14522
0
  if ((is_forbidden_or_upper & 1) == 0) {
14523
0
    if ((is_forbidden_or_upper & 2) != 0) {
14524
0
      std::string lowered(input);
14525
0
      unicode::to_lower_ascii(lowered.data(), lowered.size());
14526
0
      if (lowered.find('-') == std::string_view::npos ||
14527
0
          lowered.find(xn_dash) == std::string_view::npos) {
14528
        // Check IPv4 before mutating so failures leave the buffer untouched.
14529
        // This also avoids a double buffer rewrite for hex/octal IPv4.
14530
0
        if (checkers::is_ipv4(lowered)) {
14531
0
          ada_log("parse_host fast path ipv4");
14532
0
          return parse_ipv4(lowered, false);
14533
0
        }
14534
0
        update_base_hostname(lowered);
14535
0
        ada_log("parse_host fast path ", get_hostname());
14536
0
        is_valid = true;
14537
0
        return true;
14538
0
      }
14539
0
    } else if (input.find('-') == std::string_view::npos ||
14540
0
               input.find(xn_dash) == std::string_view::npos) {
14541
      // Check IPv4 before mutating so failures leave the buffer untouched.
14542
0
      if (checkers::is_ipv4(input)) {
14543
0
        ada_log("parse_host fast path ipv4");
14544
0
        return parse_ipv4(input, false);
14545
0
      }
14546
0
      update_base_hostname(input);
14547
0
      ada_log("parse_host fast path ", get_hostname());
14548
0
      is_valid = true;
14549
0
      return true;
14550
0
    }
14551
0
  } else if (const size_t first_percent = input.find('%');
14552
0
             first_percent != std::string_view::npos) {
14553
0
    std::string decoded = unicode::percent_decode(input, first_percent);
14554
0
    const uint8_t decoded_flags =
14555
0
        unicode::contains_forbidden_domain_code_point_or_upper(decoded.data(),
14556
0
                                                               decoded.size());
14557
0
    if ((decoded_flags & 1) == 0) {
14558
0
      if ((decoded_flags & 2) != 0) {
14559
0
        unicode::to_lower_ascii(decoded.data(), decoded.size());
14560
0
      }
14561
0
      if (decoded.find('-') == std::string_view::npos ||
14562
0
          decoded.find(xn_dash) == std::string_view::npos) {
14563
        // Check IPv4 before mutating so failures leave the buffer untouched.
14564
0
        if (checkers::is_ipv4(decoded)) {
14565
0
          return parse_ipv4(decoded, false);
14566
0
        }
14567
0
        update_base_hostname(decoded);
14568
0
        is_valid = true;
14569
0
        return true;
14570
0
      }
14571
0
    }
14572
0
  }
14573
  // We have encountered at least one forbidden code point or the input contains
14574
  // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full
14575
  // conversion.
14576
14577
0
  ada_log("parse_host calling to_ascii");
14578
0
  std::optional<std::string> host = std::string(get_hostname());
14579
0
  is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
14580
0
  if (!is_valid) {
14581
0
    ada_log("parse_host to_ascii returns false");
14582
0
    return is_valid = false;
14583
0
  }
14584
0
  ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
14585
0
          " bytes]");
14586
14587
0
  if (std::ranges::any_of(host.value(),
14588
0
                          ada::unicode::is_forbidden_domain_code_point)) {
14589
0
    return is_valid = false;
14590
0
  }
14591
14592
  // If asciiDomain ends in a number, then return the result of IPv4 parsing
14593
  // asciiDomain.
14594
0
  if (checkers::is_ipv4(host.value())) {
14595
0
    ada_log("parse_host got ipv4 ", *host);
14596
0
    return parse_ipv4(host.value(), false);
14597
0
  }
14598
14599
0
  update_base_hostname(host.value());
14600
0
  ADA_ASSERT_TRUE(validate());
14601
0
  return true;
14602
0
}
14603
14604
template <bool override_hostname>
14605
0
bool url_aggregator::set_host_or_hostname(const std::string_view input) {
14606
0
  ada_log("url_aggregator::set_host_or_hostname ", input);
14607
0
  ADA_ASSERT_TRUE(validate());
14608
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14609
0
  if (has_opaque_path) {
14610
0
    return false;
14611
0
  }
14612
14613
  // parse_host no longer mutates the buffer on failure (IPv4 is checked
14614
  // before update_base_hostname), so the only rollback needed is for the
14615
  // length limit. Snapshot only when the bound can be reached, like the
14616
  // other setters do via needs_rollback_snapshot.
14617
0
  const bool was_valid = is_valid;
14618
0
  std::optional<url_aggregator> saved_url;
14619
0
  if (needs_rollback_snapshot(input.size())) {
14620
0
    saved_url = *this;
14621
0
  }
14622
14623
0
  auto restore_on_failure = [&]() {
14624
0
    if (saved_url) {
14625
0
      *this = std::move(*saved_url);
14626
0
    } else {
14627
      // Buffer is untouched on parse failure; just restore the is_valid flag
14628
      // that parse_host may have cleared.
14629
0
      is_valid = was_valid;
14630
0
    }
14631
0
  };
Unexecuted instantiation: ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const
Unexecuted instantiation: ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const
14632
14633
0
  size_t host_end_pos = input.find('#');
14634
0
  std::string_view host_input(
14635
0
      input.data(),
14636
0
      host_end_pos != std::string_view::npos ? host_end_pos : input.size());
14637
  // Fast path: no tabs/newlines (the common case) avoids the std::string
14638
  // allocation by viewing the input prefix directly.
14639
0
  std::string _host_buf;
14640
0
  std::string_view new_host;
14641
0
  if (unicode::has_tabs_or_newline(host_input)) {
14642
0
    _host_buf = host_input;
14643
0
    helpers::remove_ascii_tab_or_newline(_host_buf);
14644
0
    new_host = _host_buf;
14645
0
  } else {
14646
0
    new_host = host_input;
14647
0
  }
14648
14649
0
  auto check_url_size = [&]() -> bool {
14650
0
    if (saved_url && buffer.size() > ada::get_max_input_length()) {
14651
0
      *this = std::move(*saved_url);
14652
0
      return false;
14653
0
    }
14654
0
    return true;
14655
0
  };
Unexecuted instantiation: ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#2}::operator()() const
Unexecuted instantiation: ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#2}::operator()() const
14656
14657
  // If url's scheme is "file", then set state to file host state, instead of
14658
  // host state.
14659
0
  if (type != ada::scheme::type::FILE) {
14660
0
    std::string_view host_view = new_host;
14661
0
    auto [location, found_colon] =
14662
0
        helpers::get_host_delimiter_location(is_special(), host_view);
14663
14664
    // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
14665
    // Note: the 'found_colon' value is true if and only if a colon was
14666
    // encountered while not inside brackets.
14667
0
    if (found_colon) {
14668
      // If buffer is the empty string, host-missing validation error, return
14669
      // failure.
14670
0
      std::string_view host_buffer = host_view.substr(0, location);
14671
0
      if (host_buffer.empty()) {
14672
0
        return false;
14673
0
      }
14674
14675
      // If state override is given and state override is hostname state, then
14676
      // return failure.
14677
0
      if constexpr (override_hostname) {
14678
0
        return false;
14679
0
      }
14680
14681
      // Let host be the result of host parsing buffer with url is not special.
14682
0
      bool succeeded = parse_host(host_buffer);
14683
0
      if (!succeeded) {
14684
0
        restore_on_failure();
14685
0
        return false;
14686
0
      } else if (has_dash_dot()) {
14687
        // The url now has a non-null host, so the "/." that guarded a
14688
        // leading "//" path is no longer needed. Drop it before the port is
14689
        // inserted at host_end, otherwise it stays wedged in the path.
14690
0
        delete_dash_dot();
14691
0
      }
14692
14693
      // Set url's host to host, buffer to the empty string, and state to port
14694
      // state.
14695
0
      std::string_view port_buffer = new_host.substr(location + 1);
14696
0
      if (!port_buffer.empty()) {
14697
0
        set_port(port_buffer);
14698
0
      }
14699
0
      return check_url_size();
14700
0
    }
14701
    // Otherwise, if one of the following is true:
14702
    // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
14703
    // - url is special and c is U+005C (\)
14704
0
    else {
14705
      // If url is special and host_view is the empty string, host-missing
14706
      // validation error, return failure.
14707
0
      if (host_view.empty() && is_special()) {
14708
0
        return false;
14709
0
      }
14710
14711
      // Otherwise, if state override is given, host_view is the empty string,
14712
      // and either url includes credentials or url's port is non-null, then
14713
      // return failure.
14714
0
      if (host_view.empty() && (has_credentials() || has_port())) {
14715
0
        return false;
14716
0
      }
14717
14718
      // Let host be the result of host parsing host_view with url is not
14719
      // special.
14720
0
      if (host_view.empty() && !is_special()) {
14721
0
        if (has_hostname()) {
14722
0
          clear_hostname();  // easy!
14723
0
        } else if (has_dash_dot()) {
14724
0
          add_authority_slashes_if_needed();
14725
0
          delete_dash_dot();
14726
0
        } else {
14727
          // The url has no authority yet (e.g. "foo:/bar"); setting an empty
14728
          // host must still give it an (empty) authority, matching ada::url.
14729
0
          add_authority_slashes_if_needed();
14730
0
        }
14731
0
        return check_url_size();
14732
0
      }
14733
14734
0
      bool succeeded = parse_host(host_view);
14735
0
      if (!succeeded) {
14736
0
        restore_on_failure();
14737
0
        return false;
14738
0
      } else if (has_dash_dot()) {
14739
        // Should remove dash_dot from pathname
14740
0
        delete_dash_dot();
14741
0
      }
14742
0
      return check_url_size();
14743
0
    }
14744
0
  }
14745
14746
0
  size_t location = new_host.find_first_of("/\\?");
14747
0
  if (location != std::string_view::npos) {
14748
0
    new_host.remove_suffix(new_host.length() - location);
14749
0
  }
14750
14751
0
  if (new_host.empty()) {
14752
    // Set url's host to the empty string.
14753
0
    clear_hostname();
14754
0
  } else {
14755
    // Let host be the result of host parsing buffer with url is not special.
14756
0
    if (!parse_host(new_host)) {
14757
0
      restore_on_failure();
14758
0
      return false;
14759
0
    }
14760
14761
    // If host is "localhost", then set host to the empty string.
14762
0
    if (helpers::substring(buffer, components.host_start,
14763
0
                           components.host_end) == "localhost") {
14764
0
      clear_hostname();
14765
0
    }
14766
0
  }
14767
0
  ADA_ASSERT_TRUE(validate());
14768
0
  return check_url_size();
14769
0
}
Unexecuted instantiation: bool ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: bool ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
14770
14771
0
bool url_aggregator::set_host(const std::string_view input) {
14772
0
  ada_log("url_aggregator::set_host '", input, "'");
14773
0
  ADA_ASSERT_TRUE(validate());
14774
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14775
0
  return set_host_or_hostname<false>(input);
14776
0
}
14777
14778
0
bool url_aggregator::set_hostname(const std::string_view input) {
14779
0
  ada_log("url_aggregator::set_hostname '", input, "'");
14780
0
  ADA_ASSERT_TRUE(validate());
14781
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14782
0
  return set_host_or_hostname<true>(input);
14783
0
}
14784
14785
0
[[nodiscard]] std::string url_aggregator::get_origin() const {
14786
0
  ada_log("url_aggregator::get_origin");
14787
0
  if (is_special()) {
14788
    // Return a new opaque origin.
14789
0
    if (type == scheme::FILE) {
14790
0
      return "null";
14791
0
    }
14792
14793
0
    return helpers::concat(get_protocol(), "//", get_host());
14794
0
  }
14795
14796
0
  if (get_protocol() == "blob:") {
14797
0
    std::string_view path = get_pathname();
14798
0
    if (!path.empty()) {
14799
0
      auto out = ada::parse<ada::url_aggregator>(path);
14800
0
      if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) {
14801
        // If pathURL's scheme is not "http" and not "https", then return a
14802
        // new opaque origin.
14803
0
        return helpers::concat(out->get_protocol(), "//", out->get_host());
14804
0
      }
14805
0
    }
14806
0
  }
14807
14808
  // Return a new opaque origin.
14809
0
  return "null";
14810
0
}
14811
14812
[[nodiscard]] std::string_view url_aggregator::get_username() const
14813
0
    ada_lifetime_bound {
14814
0
  ada_log("url_aggregator::get_username");
14815
0
  if (has_non_empty_username()) {
14816
0
    return helpers::substring(buffer, components.protocol_end + 2,
14817
0
                              components.username_end);
14818
0
  }
14819
0
  return "";
14820
0
}
14821
14822
[[nodiscard]] std::string_view url_aggregator::get_password() const
14823
0
    ada_lifetime_bound {
14824
0
  ada_log("url_aggregator::get_password");
14825
0
  if (has_non_empty_password()) {
14826
0
    return helpers::substring(buffer, components.username_end + 1,
14827
0
                              components.host_start);
14828
0
  }
14829
0
  return "";
14830
0
}
14831
14832
[[nodiscard]] std::string_view url_aggregator::get_port() const
14833
0
    ada_lifetime_bound {
14834
0
  ada_log("url_aggregator::get_port");
14835
0
  if (components.port == url_components::omitted) {
14836
0
    return "";
14837
0
  }
14838
0
  return helpers::substring(buffer, components.host_end + 1,
14839
0
                            components.pathname_start);
14840
0
}
14841
14842
[[nodiscard]] std::string_view url_aggregator::get_hash() const
14843
0
    ada_lifetime_bound {
14844
0
  ada_log("url_aggregator::get_hash");
14845
  // If this's URL's fragment is either null or the empty string, then return
14846
  // the empty string. Return U+0023 (#), followed by this's URL's fragment.
14847
0
  if (components.hash_start == url_components::omitted) {
14848
0
    return "";
14849
0
  }
14850
0
  if (buffer.size() - components.hash_start <= 1) {
14851
0
    return "";
14852
0
  }
14853
0
  return helpers::substring(buffer, components.hash_start);
14854
0
}
14855
14856
[[nodiscard]] std::string_view url_aggregator::get_host() const
14857
0
    ada_lifetime_bound {
14858
0
  ada_log("url_aggregator::get_host");
14859
  // Technically, we should check if there is a hostname, but
14860
  // the code below works even if there isn't.
14861
  // if(!has_hostname()) { return ""; }
14862
0
  size_t start = components.host_start;
14863
0
  if (components.host_end > components.host_start &&
14864
0
      buffer[components.host_start] == '@') {
14865
0
    start++;
14866
0
  }
14867
  // if we have an empty host, then the space between components.host_end and
14868
  // components.pathname_start may be occupied by /.
14869
0
  if (start == components.host_end) {
14870
0
    return {};
14871
0
  }
14872
0
  return helpers::substring(buffer, start, components.pathname_start);
14873
0
}
14874
14875
[[nodiscard]] std::string_view url_aggregator::get_hostname() const
14876
0
    ada_lifetime_bound {
14877
0
  ada_log("url_aggregator::get_hostname");
14878
  // Technically, we should check if there is a hostname, but
14879
  // the code below works even if there isn't.
14880
  // if(!has_hostname()) { return ""; }
14881
0
  size_t start = components.host_start;
14882
  // So host_start is not where the host begins.
14883
0
  if (components.host_end > components.host_start &&
14884
0
      buffer[components.host_start] == '@') {
14885
0
    start++;
14886
0
  }
14887
0
  return helpers::substring(buffer, start, components.host_end);
14888
0
}
14889
14890
[[nodiscard]] std::string_view url_aggregator::get_search() const
14891
0
    ada_lifetime_bound {
14892
0
  ada_log("url_aggregator::get_search");
14893
  // If this's URL's query is either null or the empty string, then return the
14894
  // empty string. Return U+003F (?), followed by this's URL's query.
14895
0
  if (components.search_start == url_components::omitted) {
14896
0
    return "";
14897
0
  }
14898
0
  auto ending_index = uint32_t(buffer.size());
14899
0
  if (components.hash_start != url_components::omitted) {
14900
0
    ending_index = components.hash_start;
14901
0
  }
14902
0
  if (ending_index - components.search_start <= 1) {
14903
0
    return "";
14904
0
  }
14905
0
  return helpers::substring(buffer, components.search_start, ending_index);
14906
0
}
14907
14908
[[nodiscard]] std::string_view url_aggregator::get_protocol() const
14909
0
    ada_lifetime_bound {
14910
0
  ada_log("url_aggregator::get_protocol");
14911
0
  return helpers::substring(buffer, 0, components.protocol_end);
14912
0
}
14913
14914
0
[[nodiscard]] std::string ada::url_aggregator::to_string() const {
14915
0
  ada_log("url_aggregator::to_string buffer:", buffer, " [", buffer.size(),
14916
0
          " bytes]");
14917
0
  if (!is_valid) {
14918
0
    return "null";
14919
0
  }
14920
14921
0
  std::string answer;
14922
0
  auto back = std::back_insert_iterator(answer);
14923
0
  answer.append("{\n");
14924
14925
0
  answer.append("\t\"buffer\":\"");
14926
0
  helpers::encode_json(buffer, back);
14927
0
  answer.append("\",\n");
14928
14929
0
  answer.append("\t\"protocol\":\"");
14930
0
  helpers::encode_json(get_protocol(), back);
14931
0
  answer.append("\",\n");
14932
14933
0
  if (has_credentials()) {
14934
0
    answer.append("\t\"username\":\"");
14935
0
    helpers::encode_json(get_username(), back);
14936
0
    answer.append("\",\n");
14937
0
    answer.append("\t\"password\":\"");
14938
0
    helpers::encode_json(get_password(), back);
14939
0
    answer.append("\",\n");
14940
0
  }
14941
14942
0
  answer.append("\t\"host\":\"");
14943
0
  helpers::encode_json(get_host(), back);
14944
0
  answer.append("\",\n");
14945
14946
0
  answer.append("\t\"path\":\"");
14947
0
  helpers::encode_json(get_pathname(), back);
14948
0
  answer.append("\",\n");
14949
0
  answer.append("\t\"opaque path\":");
14950
0
  answer.append((has_opaque_path ? "true" : "false"));
14951
0
  answer.append(",\n");
14952
14953
0
  if (components.search_start != url_components::omitted) {
14954
0
    answer.append("\t\"query\":\"");
14955
0
    helpers::encode_json(get_search(), back);
14956
0
    answer.append("\",\n");
14957
0
  }
14958
0
  if (components.hash_start != url_components::omitted) {
14959
0
    answer.append("\t\"fragment\":\"");
14960
0
    helpers::encode_json(get_hash(), back);
14961
0
    answer.append("\",\n");
14962
0
  }
14963
14964
0
  auto convert_offset_to_string = [](uint32_t offset) -> std::string {
14965
0
    if (offset == url_components::omitted) {
14966
0
      return "null";
14967
0
    } else {
14968
0
      return std::to_string(offset);
14969
0
    }
14970
0
  };
14971
14972
0
  answer.append("\t\"protocol_end\":");
14973
0
  answer.append(convert_offset_to_string(components.protocol_end));
14974
0
  answer.append(",\n");
14975
14976
0
  answer.append("\t\"username_end\":");
14977
0
  answer.append(convert_offset_to_string(components.username_end));
14978
0
  answer.append(",\n");
14979
14980
0
  answer.append("\t\"host_start\":");
14981
0
  answer.append(convert_offset_to_string(components.host_start));
14982
0
  answer.append(",\n");
14983
14984
0
  answer.append("\t\"host_end\":");
14985
0
  answer.append(convert_offset_to_string(components.host_end));
14986
0
  answer.append(",\n");
14987
14988
0
  answer.append("\t\"port\":");
14989
0
  answer.append(convert_offset_to_string(components.port));
14990
0
  answer.append(",\n");
14991
14992
0
  answer.append("\t\"pathname_start\":");
14993
0
  answer.append(convert_offset_to_string(components.pathname_start));
14994
0
  answer.append(",\n");
14995
14996
0
  answer.append("\t\"search_start\":");
14997
0
  answer.append(convert_offset_to_string(components.search_start));
14998
0
  answer.append(",\n");
14999
15000
0
  answer.append("\t\"hash_start\":");
15001
0
  answer.append(convert_offset_to_string(components.hash_start));
15002
0
  answer.append("\n}");
15003
15004
0
  return answer;
15005
0
}
15006
15007
0
[[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept {
15008
0
  if (components.host_start == components.host_end) {
15009
0
    return false;
15010
0
  }
15011
  // Avoid allocation: construct a string_view directly into the buffer.
15012
0
  size_t start = components.host_start;
15013
0
  if (components.host_end > components.host_start &&
15014
0
      buffer[components.host_start] == '@') {
15015
0
    start++;
15016
0
  }
15017
0
  return checkers::verify_dns_length(
15018
0
      std::string_view(buffer.data() + start, components.host_end - start));
15019
0
}
15020
15021
0
bool url_aggregator::parse_ipv4(std::string_view input, bool in_place) {
15022
0
  ada_log("parse_ipv4 ", input, " [", input.size(),
15023
0
          " bytes], overlaps with buffer: ",
15024
0
          helpers::overlaps(input, buffer) ? "yes" : "no");
15025
0
  ADA_ASSERT_TRUE(validate());
15026
0
  if (input.empty()) {
15027
0
    return is_valid = false;
15028
0
  }
15029
0
  const bool trailing_dot = (input.back() == '.');
15030
0
  if (trailing_dot) {
15031
0
    input.remove_suffix(1);
15032
0
    if (input.empty()) {
15033
0
      return is_valid = false;
15034
0
    }
15035
0
  }
15036
15037
0
  const uint64_t fast = checkers::try_parse_ipv4_fast(input);
15038
0
  if (fast < checkers::ipv4_fast_fail) [[likely]] {
15039
    // Pure decimal: keep the buffer when it already holds the address.
15040
    // Otherwise write the (trailing-dot-stripped) input.
15041
0
    if (!(in_place && !trailing_dot)) {
15042
0
      if (helpers::overlaps(input, buffer)) {
15043
0
        update_base_hostname(std::string(input));
15044
0
      } else {
15045
0
        update_base_hostname(input);
15046
0
      }
15047
0
    }
15048
0
    host_type = IPV4;
15049
0
    ADA_ASSERT_TRUE(validate());
15050
0
    return true;
15051
0
  }
15052
15053
0
  const char* p = input.data();
15054
0
  const char* end = p + input.size();
15055
0
  uint64_t ipv4 = 0;
15056
0
  int digit_count = 0;
15057
0
  int pure_decimal_count = 0;
15058
15059
0
  for (; digit_count < 4 && p < end; ++digit_count) {
15060
0
    uint64_t segment = 0;
15061
0
    bool pure = false;
15062
0
    if (!detail::parse_ipv4_number(p, end, segment, pure)) {
15063
0
      return is_valid = false;
15064
0
    }
15065
0
    if (pure) {
15066
0
      ++pure_decimal_count;
15067
0
    }
15068
0
    if (p >= end) {
15069
0
      const unsigned shift = static_cast<unsigned>(32 - digit_count * 8);
15070
0
      if (segment >= (uint64_t{1} << shift)) {
15071
0
        return is_valid = false;
15072
0
      }
15073
0
      ipv4 = (ipv4 << shift) | segment;
15074
0
      goto ipv4_done;
15075
0
    }
15076
0
    if (segment > 255 || *p != '.') {
15077
0
      return is_valid = false;
15078
0
    }
15079
0
    ipv4 = (ipv4 << 8) | segment;
15080
0
    ++p;
15081
0
  }
15082
0
  if (digit_count != 4 || p != end) {
15083
0
    return is_valid = false;
15084
0
  }
15085
0
ipv4_done:
15086
0
  ada_log("url_aggregator::parse_ipv4 completed ", get_href(),
15087
0
          " host: ", get_host());
15088
0
  if (in_place && pure_decimal_count == 4 && !trailing_dot) {
15089
0
    ada_log(
15090
0
        "url_aggregator::parse_ipv4 completed and was already correct in the "
15091
0
        "buffer");
15092
0
  } else {
15093
0
    update_base_hostname(ada::serializers::ipv4(ipv4));
15094
0
  }
15095
0
  host_type = IPV4;
15096
0
  ADA_ASSERT_TRUE(validate());
15097
0
  return true;
15098
0
}
15099
15100
0
bool url_aggregator::parse_ipv6(std::string_view input) {
15101
0
  ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
15102
0
  ADA_ASSERT_TRUE(validate());
15103
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15104
0
  if (input.empty() || input.size() > 45) [[unlikely]] {
15105
0
    return is_valid = false;
15106
0
  }
15107
0
  std::array<uint16_t, 8> address{};
15108
#if defined(ADA_AVX512_IPV6)
15109
  if (bool simd_valid; detail::try_parse_ipv6_avx512(input.data(), input.size(),
15110
                                                     address, simd_valid)) {
15111
    if (!simd_valid) [[unlikely]] {
15112
      return is_valid = false;
15113
    }
15114
    const std::string serialized = ada::serializers::ipv6(address);
15115
    if (get_hostname() != serialized) {
15116
      update_base_hostname(serialized);
15117
    }
15118
    host_type = IPV6;
15119
    return true;
15120
  }
15121
  address = {};
15122
#endif
15123
0
  const char* pointer = input.data();
15124
0
  const char* const end = pointer + input.size();
15125
0
  int piece_index = 0;
15126
0
  int compress = -1;
15127
15128
0
  if (*pointer == ':') {
15129
0
    if (input.size() == 1 || pointer[1] != ':') [[unlikely]] {
15130
0
      return is_valid = false;
15131
0
    }
15132
0
    pointer += 2;
15133
0
    compress = ++piece_index;
15134
0
  }
15135
15136
0
  while (pointer != end) {
15137
0
    if (piece_index == 8) [[unlikely]] {
15138
0
      return is_valid = false;
15139
0
    }
15140
0
    if (*pointer == ':') {
15141
0
      if (compress != -1) [[unlikely]] {
15142
0
        return is_valid = false;
15143
0
      }
15144
0
      ++pointer;
15145
0
      compress = ++piece_index;
15146
0
      continue;
15147
0
    }
15148
15149
0
    uint16_t value = 0;
15150
0
    const int length = detail::parse_hex_piece(pointer, end, value);
15151
15152
0
    if (pointer != end && *pointer == '.') {
15153
0
      if (length == 0) [[unlikely]] {
15154
0
        return is_valid = false;
15155
0
      }
15156
0
      pointer -= length;
15157
0
      if (piece_index > 6) [[unlikely]] {
15158
0
        return is_valid = false;
15159
0
      }
15160
15161
0
      int numbers_seen = 0;
15162
0
      while (pointer != end) {
15163
0
        int ipv4_piece = -1;
15164
0
        if (numbers_seen > 0) {
15165
0
          if (*pointer == '.' && numbers_seen < 4) {
15166
0
            ++pointer;
15167
0
          } else {
15168
0
            return is_valid = false;
15169
0
          }
15170
0
        }
15171
0
        if (pointer == end || *pointer < '0' || *pointer > '9') [[unlikely]] {
15172
0
          return is_valid = false;
15173
0
        }
15174
0
        ipv4_piece = *pointer - '0';
15175
0
        ++pointer;
15176
0
        if (pointer != end && *pointer >= '0' && *pointer <= '9') {
15177
0
          if (ipv4_piece == 0) [[unlikely]] {
15178
0
            return is_valid = false;
15179
0
          }
15180
0
          ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
15181
0
          ++pointer;
15182
0
          if (pointer != end && *pointer >= '0' && *pointer <= '9') {
15183
0
            ipv4_piece = ipv4_piece * 10 + (*pointer - '0');
15184
0
            ++pointer;
15185
0
            if (ipv4_piece > 255) [[unlikely]] {
15186
0
              return is_valid = false;
15187
0
            }
15188
0
          }
15189
0
        }
15190
0
        address[static_cast<size_t>(piece_index)] = static_cast<uint16_t>(
15191
0
            address[static_cast<size_t>(piece_index)] * 0x100 +
15192
0
            static_cast<uint16_t>(ipv4_piece));
15193
0
        ++numbers_seen;
15194
0
        if (numbers_seen == 2 || numbers_seen == 4) {
15195
0
          ++piece_index;
15196
0
        }
15197
0
      }
15198
0
      if (numbers_seen != 4) [[unlikely]] {
15199
0
        return is_valid = false;
15200
0
      }
15201
0
      break;
15202
0
    }
15203
15204
0
    if (length == 0) [[unlikely]] {
15205
0
      return is_valid = false;
15206
0
    }
15207
15208
0
    if (pointer != end && *pointer == ':') {
15209
0
      ++pointer;
15210
0
      if (pointer == end) [[unlikely]] {
15211
0
        return is_valid = false;
15212
0
      }
15213
0
    } else if (pointer != end) [[unlikely]] {
15214
0
      return is_valid = false;
15215
0
    }
15216
15217
0
    address[static_cast<size_t>(piece_index)] = value;
15218
0
    ++piece_index;
15219
0
  }
15220
15221
0
  if (compress != -1) {
15222
0
    const int right = piece_index - compress;
15223
0
    if (right > 0) {
15224
0
      const size_t dest = static_cast<size_t>(8 - right);
15225
0
      const size_t src = static_cast<size_t>(compress);
15226
0
      if (dest != src) {
15227
0
        for (size_t i = static_cast<size_t>(right); i-- > 0;) {
15228
0
          address[dest + i] = address[src + i];
15229
0
          address[src + i] = 0;
15230
0
        }
15231
0
      }
15232
0
    }
15233
0
  } else if (piece_index != 8) [[unlikely]] {
15234
0
    return is_valid = false;
15235
0
  }
15236
15237
  // Serialize once; skip rewrite when hostname is already canonical.
15238
0
  const std::string serialized = ada::serializers::ipv6(address);
15239
0
  const std::string_view current = get_hostname();
15240
0
  if (current.size() == serialized.size() &&
15241
0
      std::memcmp(current.data(), serialized.data(), serialized.size()) == 0) {
15242
0
    ada_log("parse_ipv6 in-place canonical match");
15243
0
  } else {
15244
0
    update_base_hostname(serialized);
15245
0
  }
15246
0
  ada_log("parse_ipv6 ", get_hostname());
15247
0
  ADA_ASSERT_TRUE(validate());
15248
0
  host_type = IPV6;
15249
0
  return true;
15250
0
}
15251
15252
0
bool url_aggregator::parse_opaque_host(std::string_view input) {
15253
0
  ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
15254
0
  ADA_ASSERT_TRUE(validate());
15255
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15256
0
  if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) {
15257
0
    return is_valid = false;
15258
0
  }
15259
15260
  // Return the result of running UTF-8 percent-encode on input using the C0
15261
  // control percent-encode set.
15262
0
  size_t idx = ada::unicode::percent_encode_index(
15263
0
      input, character_sets::C0_CONTROL_PERCENT_ENCODE);
15264
0
  if (idx == input.size()) {
15265
0
    update_base_hostname(input);
15266
0
  } else {
15267
    // We only create a temporary string if we need to.
15268
0
    update_base_hostname(ada::unicode::percent_encode(
15269
0
        input, character_sets::C0_CONTROL_PERCENT_ENCODE, idx));
15270
0
  }
15271
0
  ADA_ASSERT_TRUE(validate());
15272
0
  return true;
15273
0
}
15274
15275
0
[[nodiscard]] std::string url_aggregator::to_diagram() const {
15276
0
  if (!is_valid) {
15277
0
    return "invalid";
15278
0
  }
15279
0
  std::string answer;
15280
0
  answer.append(buffer);
15281
0
  answer.append(" [");
15282
0
  answer.append(std::to_string(buffer.size()));
15283
0
  answer.append(" bytes]");
15284
0
  answer.append("\n");
15285
  // first line
15286
0
  std::string line1;
15287
0
  line1.resize(buffer.size(), ' ');
15288
0
  if (components.hash_start != url_components::omitted) {
15289
0
    line1[components.hash_start] = '|';
15290
0
  }
15291
0
  if (components.search_start != url_components::omitted) {
15292
0
    line1[components.search_start] = '|';
15293
0
  }
15294
0
  if (components.pathname_start != buffer.size()) {
15295
0
    line1[components.pathname_start] = '|';
15296
0
  }
15297
0
  if (components.host_end != buffer.size()) {
15298
0
    line1[components.host_end] = '|';
15299
0
  }
15300
0
  if (components.host_start != buffer.size()) {
15301
0
    line1[components.host_start] = '|';
15302
0
  }
15303
0
  if (components.username_end != buffer.size()) {
15304
0
    line1[components.username_end] = '|';
15305
0
  }
15306
0
  if (components.protocol_end != buffer.size()) {
15307
0
    line1[components.protocol_end] = '|';
15308
0
  }
15309
0
  answer.append(line1);
15310
0
  answer.append("\n");
15311
15312
0
  std::string line2 = line1;
15313
0
  if (components.hash_start != url_components::omitted) {
15314
0
    line2[components.hash_start] = '`';
15315
0
    line1[components.hash_start] = ' ';
15316
15317
0
    for (size_t i = components.hash_start + 1; i < line2.size(); i++) {
15318
0
      line2[i] = '-';
15319
0
    }
15320
0
    line2.append(" hash_start");
15321
0
    answer.append(line2);
15322
0
    answer.append("\n");
15323
0
  }
15324
15325
0
  std::string line3 = line1;
15326
0
  if (components.search_start != url_components::omitted) {
15327
0
    line3[components.search_start] = '`';
15328
0
    line1[components.search_start] = ' ';
15329
15330
0
    for (size_t i = components.search_start + 1; i < line3.size(); i++) {
15331
0
      line3[i] = '-';
15332
0
    }
15333
0
    line3.append(" search_start ");
15334
0
    line3.append(std::to_string(components.search_start));
15335
0
    answer.append(line3);
15336
0
    answer.append("\n");
15337
0
  }
15338
15339
0
  std::string line4 = line1;
15340
0
  if (components.pathname_start != buffer.size()) {
15341
0
    line4[components.pathname_start] = '`';
15342
0
    line1[components.pathname_start] = ' ';
15343
0
    for (size_t i = components.pathname_start + 1; i < line4.size(); i++) {
15344
0
      line4[i] = '-';
15345
0
    }
15346
0
    line4.append(" pathname_start ");
15347
0
    line4.append(std::to_string(components.pathname_start));
15348
0
    answer.append(line4);
15349
0
    answer.append("\n");
15350
0
  }
15351
15352
0
  std::string line5 = line1;
15353
0
  if (components.host_end != buffer.size()) {
15354
0
    line5[components.host_end] = '`';
15355
0
    line1[components.host_end] = ' ';
15356
15357
0
    for (size_t i = components.host_end + 1; i < line5.size(); i++) {
15358
0
      line5[i] = '-';
15359
0
    }
15360
0
    line5.append(" host_end ");
15361
0
    line5.append(std::to_string(components.host_end));
15362
0
    answer.append(line5);
15363
0
    answer.append("\n");
15364
0
  }
15365
15366
0
  std::string line6 = line1;
15367
0
  if (components.host_start != buffer.size()) {
15368
0
    line6[components.host_start] = '`';
15369
0
    line1[components.host_start] = ' ';
15370
15371
0
    for (size_t i = components.host_start + 1; i < line6.size(); i++) {
15372
0
      line6[i] = '-';
15373
0
    }
15374
0
    line6.append(" host_start ");
15375
0
    line6.append(std::to_string(components.host_start));
15376
0
    answer.append(line6);
15377
0
    answer.append("\n");
15378
0
  }
15379
15380
0
  std::string line7 = line1;
15381
0
  if (components.username_end != buffer.size()) {
15382
0
    line7[components.username_end] = '`';
15383
0
    line1[components.username_end] = ' ';
15384
15385
0
    for (size_t i = components.username_end + 1; i < line7.size(); i++) {
15386
0
      line7[i] = '-';
15387
0
    }
15388
0
    line7.append(" username_end ");
15389
0
    line7.append(std::to_string(components.username_end));
15390
0
    answer.append(line7);
15391
0
    answer.append("\n");
15392
0
  }
15393
15394
0
  std::string line8 = line1;
15395
0
  if (components.protocol_end != buffer.size()) {
15396
0
    line8[components.protocol_end] = '`';
15397
0
    line1[components.protocol_end] = ' ';
15398
15399
0
    for (size_t i = components.protocol_end + 1; i < line8.size(); i++) {
15400
0
      line8[i] = '-';
15401
0
    }
15402
0
    line8.append(" protocol_end ");
15403
0
    line8.append(std::to_string(components.protocol_end));
15404
0
    answer.append(line8);
15405
0
    answer.append("\n");
15406
0
  }
15407
15408
0
  if (components.hash_start == url_components::omitted) {
15409
0
    answer.append("note: hash omitted\n");
15410
0
  }
15411
0
  if (components.search_start == url_components::omitted) {
15412
0
    answer.append("note: search omitted\n");
15413
0
  }
15414
0
  if (components.protocol_end > buffer.size()) {
15415
0
    answer.append("warning: protocol_end overflows\n");
15416
0
  }
15417
0
  if (components.username_end > buffer.size()) {
15418
0
    answer.append("warning: username_end overflows\n");
15419
0
  }
15420
0
  if (components.host_start > buffer.size()) {
15421
0
    answer.append("warning: host_start overflows\n");
15422
0
  }
15423
0
  if (components.host_end > buffer.size()) {
15424
0
    answer.append("warning: host_end overflows\n");
15425
0
  }
15426
0
  if (components.pathname_start > buffer.size()) {
15427
0
    answer.append("warning: pathname_start overflows\n");
15428
0
  }
15429
0
  return answer;
15430
0
}
15431
15432
0
void url_aggregator::delete_dash_dot() {
15433
0
  ada_log("url_aggregator::delete_dash_dot");
15434
0
  ADA_ASSERT_TRUE(validate());
15435
0
  ADA_ASSERT_TRUE(has_dash_dot());
15436
0
  buffer.erase(components.host_end, 2);
15437
0
  components.pathname_start -= 2;
15438
0
  if (components.search_start != url_components::omitted) {
15439
0
    components.search_start -= 2;
15440
0
  }
15441
0
  if (components.hash_start != url_components::omitted) {
15442
0
    components.hash_start -= 2;
15443
0
  }
15444
0
  ADA_ASSERT_TRUE(validate());
15445
0
  ADA_ASSERT_TRUE(!has_dash_dot());
15446
0
}
15447
15448
0
inline void url_aggregator::consume_prepared_path(std::string_view input) {
15449
0
  ada_log("url_aggregator::consume_prepared_path ", input);
15450
  /***
15451
   * This is largely duplicated code from helpers::parse_prepared_path, which is
15452
   * unfortunate. This particular function is nearly identical, except that it
15453
   * is a method on url_aggregator. The idea is that the trivial path (which is
15454
   * very common) merely appends to the buffer. This is the same trivial path as
15455
   * with helpers::parse_prepared_path, except that we have the additional check
15456
   * for is_at_path(). Otherwise, we grab a copy of the current path and we
15457
   * modify it, and then insert it back into the buffer.
15458
   */
15459
0
  uint8_t accumulator = checkers::path_signature(input);
15460
  // Let us first detect a trivial case.
15461
  // If it is special, we check that we have no dot, no %,  no \ and no
15462
  // character needing percent encoding. Otherwise, we check that we have no %,
15463
  // no dot, and no character needing percent encoding.
15464
0
  constexpr uint8_t need_encoding = 1;
15465
0
  constexpr uint8_t backslash_char = 2;
15466
0
  constexpr uint8_t dot_char = 4;
15467
0
  constexpr uint8_t percent_char = 8;
15468
0
  bool special = type != ada::scheme::NOT_SPECIAL;
15469
0
  bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
15470
0
                                      checkers::is_windows_drive_letter(input));
15471
0
  bool trivial_path =
15472
0
      (special ? (accumulator == 0)
15473
0
               : ((accumulator & (need_encoding | dot_char | percent_char)) ==
15474
0
                  0)) &&
15475
0
      (!may_need_slow_file_handling);
15476
0
  if (accumulator == dot_char && !may_need_slow_file_handling) {
15477
    // '4' means that we have at least one dot, but nothing that requires
15478
    // percent encoding or decoding. The only part that is not trivial is
15479
    // that we may have single dots and double dots path segments.
15480
    // If we have such segments, then we either have a path that begins
15481
    // with '.' (easy to check), or we have the sequence './'.
15482
    // Note: input cannot be empty, it must at least contain one character ('.')
15483
    // Note: we know that '\' is not present.
15484
0
    if (input[0] != '.') {
15485
0
      size_t slashdot = 0;
15486
0
      bool dot_is_file = true;
15487
0
      for (;;) {
15488
0
        slashdot = input.find("/.", slashdot);
15489
0
        if (slashdot == std::string_view::npos) {  // common case
15490
0
          break;
15491
0
        } else {  // uncommon
15492
          // only three cases matter: /./, /.. or a final /
15493
0
          slashdot += 2;
15494
0
          dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' ||
15495
0
                           input[slashdot] == '/');
15496
0
        }
15497
0
      }
15498
0
      trivial_path = dot_is_file;
15499
0
    }
15500
0
  }
15501
0
  if (trivial_path && is_at_path()) {
15502
0
    ada_log("parse_path trivial");
15503
0
    buffer += '/';
15504
0
    buffer += input;
15505
0
    return;
15506
0
  }
15507
0
  std::string path = std::string(get_pathname());
15508
  // We are going to need to look a bit at the path, but let us see if we can
15509
  // ignore percent encoding *and* backslashes *and* percent characters.
15510
  // Except for the trivial case, this is likely to capture 99% of paths out
15511
  // there.
15512
0
  bool fast_path =
15513
0
      (special &&
15514
0
       (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
15515
0
      (type != ada::scheme::type::FILE);
15516
0
  if (fast_path) {
15517
0
    ada_log("parse_prepared_path fast");
15518
    // Here we don't need to worry about \ or percent encoding.
15519
    // We also do not have a file protocol. We might have dots, however,
15520
    // but dots must as appear as '.', and they cannot be encoded because
15521
    // the symbol '%' is not present.
15522
0
    size_t previous_location = 0;  // We start at 0.
15523
0
    do {
15524
0
      size_t new_location = input.find('/', previous_location);
15525
      // std::string_view path_view = input;
15526
      //  We process the last segment separately:
15527
0
      if (new_location == std::string_view::npos) {
15528
0
        std::string_view path_view = input.substr(previous_location);
15529
0
        if (path_view == "..") {  // The path ends with ..
15530
          // e.g., if you receive ".." with an empty path, you go to "/".
15531
0
          if (path.empty()) {
15532
0
            path = '/';
15533
0
            update_base_pathname(path);
15534
0
            return;
15535
0
          }
15536
          // Fast case where we have nothing to do:
15537
0
          if (path.back() == '/') {
15538
0
            update_base_pathname(path);
15539
0
            return;
15540
0
          }
15541
          // If you have the path "/joe/myfriend",
15542
          // then you delete 'myfriend'.
15543
0
          path.resize(path.rfind('/') + 1);
15544
0
          update_base_pathname(path);
15545
0
          return;
15546
0
        }
15547
0
        path += '/';
15548
0
        if (path_view != ".") {
15549
0
          path.append(path_view);
15550
0
        }
15551
0
        update_base_pathname(path);
15552
0
        return;
15553
0
      } else {
15554
        // This is a non-final segment.
15555
0
        std::string_view path_view =
15556
0
            input.substr(previous_location, new_location - previous_location);
15557
0
        previous_location = new_location + 1;
15558
0
        if (path_view == "..") {
15559
0
          size_t last_delimiter = path.rfind('/');
15560
0
          if (last_delimiter != std::string::npos) {
15561
0
            path.erase(last_delimiter);
15562
0
          }
15563
0
        } else if (path_view != ".") {
15564
0
          path += '/';
15565
0
          path.append(path_view);
15566
0
        }
15567
0
      }
15568
0
    } while (true);
15569
0
  } else {
15570
0
    ada_log("parse_path slow");
15571
    // we have reached the general case
15572
0
    bool needs_percent_encoding = (accumulator & 1);
15573
0
    std::string path_buffer_tmp;
15574
0
    do {
15575
0
      size_t location = (special && (accumulator & 2))
15576
0
                            ? input.find_first_of("/\\")
15577
0
                            : input.find('/');
15578
0
      std::string_view path_view = input;
15579
0
      if (location != std::string_view::npos) {
15580
0
        path_view.remove_suffix(path_view.size() - location);
15581
0
        input.remove_prefix(location + 1);
15582
0
      }
15583
      // path_buffer is either path_view or it might point at a percent encoded
15584
      // temporary string.
15585
0
      std::string_view path_buffer =
15586
0
          (needs_percent_encoding &&
15587
0
           ada::unicode::percent_encode<false>(
15588
0
               path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
15589
0
              ? path_buffer_tmp
15590
0
              : path_view;
15591
0
      if (unicode::is_double_dot_path_segment(path_buffer)) {
15592
0
        helpers::shorten_path(path, type);
15593
0
        if (location == std::string_view::npos) {
15594
0
          path += '/';
15595
0
        }
15596
0
      } else if (unicode::is_single_dot_path_segment(path_buffer) &&
15597
0
                 (location == std::string_view::npos)) {
15598
0
        path += '/';
15599
0
      }
15600
      // Otherwise, if path_buffer is not a single-dot path segment, then:
15601
0
      else if (!unicode::is_single_dot_path_segment(path_buffer)) {
15602
        // If url's scheme is "file", url's path is empty, and path_buffer is a
15603
        // Windows drive letter, then replace the second code point in
15604
        // path_buffer with U+003A (:).
15605
0
        if (type == ada::scheme::type::FILE && path.empty() &&
15606
0
            checkers::is_windows_drive_letter(path_buffer)) {
15607
0
          path += '/';
15608
0
          path += path_buffer[0];
15609
0
          path += ':';
15610
0
          path_buffer.remove_prefix(2);
15611
0
          path.append(path_buffer);
15612
0
        } else {
15613
          // Append path_buffer to url's path.
15614
0
          path += '/';
15615
0
          path.append(path_buffer);
15616
0
        }
15617
0
      }
15618
0
      if (location == std::string_view::npos) {
15619
0
        update_base_pathname(path);
15620
0
        return;
15621
0
      }
15622
0
    } while (true);
15623
0
  }
15624
0
}
15625
}  // namespace ada
15626
/* end file src/url_aggregator.cpp */
15627
15628
#if ADA_INCLUDE_URL_PATTERN
15629
/* begin file src/url_pattern.cpp */
15630
#if ADA_INCLUDE_URL_PATTERN
15631
15632
15633
#include <algorithm>
15634
#include <optional>
15635
#include <string>
15636
#include <string_view>
15637
#include <utility>
15638
15639
namespace ada {
15640
15641
tl::expected<url_pattern_init, errors> url_pattern_init::process(
15642
    const url_pattern_init& init, url_pattern_init::process_type type,
15643
    std::optional<std::string_view> protocol,
15644
    std::optional<std::string_view> username,
15645
    std::optional<std::string_view> password,
15646
    std::optional<std::string_view> hostname,
15647
    std::optional<std::string_view> port,
15648
    std::optional<std::string_view> pathname,
15649
    std::optional<std::string_view> search,
15650
0
    std::optional<std::string_view> hash) {
15651
  // Let result be the result of creating a new URLPatternInit.
15652
0
  auto result = url_pattern_init{};
15653
15654
  // If protocol is not null, set result["protocol"] to protocol.
15655
0
  if (protocol.has_value()) result.protocol = *protocol;
15656
15657
  // If username is not null, set result["username"] to username.
15658
0
  if (username.has_value()) result.username = *username;
15659
15660
  // If password is not null, set result["password"] to password.
15661
0
  if (password.has_value()) result.password = *password;
15662
15663
  // If hostname is not null, set result["hostname"] to hostname.
15664
0
  if (hostname.has_value()) result.hostname = *hostname;
15665
15666
  // If port is not null, set result["port"] to port.
15667
0
  if (port.has_value()) result.port = *port;
15668
15669
  // If pathname is not null, set result["pathname"] to pathname.
15670
0
  if (pathname.has_value()) result.pathname = *pathname;
15671
15672
  // If search is not null, set result["search"] to search.
15673
0
  if (search.has_value()) result.search = *search;
15674
15675
  // If hash is not null, set result["hash"] to hash.
15676
0
  if (hash.has_value()) result.hash = *hash;
15677
15678
  // Let baseURL be null.
15679
0
  std::optional<url_aggregator> base_url{};
15680
15681
  // If init["baseURL"] exists:
15682
0
  if (init.base_url.has_value()) {
15683
    // Set baseURL to the result of parsing init["baseURL"].
15684
0
    auto parsing_result = ada::parse<url_aggregator>(*init.base_url);
15685
    // If baseURL is failure, then throw a TypeError.
15686
0
    if (!parsing_result) {
15687
0
      return tl::unexpected(errors::type_error);
15688
0
    }
15689
0
    base_url = std::move(*parsing_result);
15690
15691
    // If init["protocol"] does not exist, then set result["protocol"] to the
15692
    // result of processing a base URL string given baseURL's scheme and type.
15693
0
    if (!init.protocol.has_value()) {
15694
0
      ADA_ASSERT_TRUE(base_url.has_value());
15695
0
      std::string_view base_url_protocol = base_url->get_protocol();
15696
0
      if (base_url_protocol.ends_with(":")) base_url_protocol.remove_suffix(1);
15697
0
      result.protocol =
15698
0
          url_pattern_helpers::process_base_url_string(base_url_protocol, type);
15699
0
    }
15700
15701
    // If type is not "pattern" and init contains none of "protocol",
15702
    // "hostname", "port" and "username", then set result["username"] to the
15703
    // result of processing a base URL string given baseURL's username and type.
15704
0
    if (type != process_type::pattern && !init.protocol && !init.hostname &&
15705
0
        !init.port && !init.username) {
15706
0
      result.username = url_pattern_helpers::process_base_url_string(
15707
0
          base_url->get_username(), type);
15708
0
    }
15709
15710
    // TODO: Optimization opportunity: Merge this with the previous check.
15711
    // If type is not "pattern" and init contains none of "protocol",
15712
    // "hostname", "port", "username" and "password", then set
15713
    // result["password"] to the result of processing a base URL string given
15714
    // baseURL's password and type.
15715
0
    if (type != process_type::pattern && !init.protocol && !init.hostname &&
15716
0
        !init.port && !init.username && !init.password) {
15717
0
      result.password = url_pattern_helpers::process_base_url_string(
15718
0
          base_url->get_password(), type);
15719
0
    }
15720
15721
    // If init contains neither "protocol" nor "hostname", then:
15722
0
    if (!init.protocol && !init.hostname) {
15723
      // Let baseHost be baseURL's host.
15724
      // If baseHost is null, then set baseHost to the empty string.
15725
0
      auto base_host = base_url->get_hostname();
15726
      // Set result["hostname"] to the result of processing a base URL string
15727
      // given baseHost and type.
15728
0
      result.hostname =
15729
0
          url_pattern_helpers::process_base_url_string(base_host, type);
15730
0
    }
15731
15732
    // If init contains none of "protocol", "hostname", and "port", then:
15733
0
    if (!init.protocol && !init.hostname && !init.port) {
15734
      // If baseURL's port is null, then set result["port"] to the empty string.
15735
      // Otherwise, set result["port"] to baseURL's port, serialized.
15736
0
      result.port = base_url->get_port();
15737
0
    }
15738
15739
    // If init contains none of "protocol", "hostname", "port", and "pathname",
15740
    // then set result["pathname"] to the result of processing a base URL string
15741
    // given the result of URL path serializing baseURL and type.
15742
0
    if (!init.protocol && !init.hostname && !init.port && !init.pathname) {
15743
0
      result.pathname = url_pattern_helpers::process_base_url_string(
15744
0
          base_url->get_pathname(), type);
15745
0
    }
15746
15747
    // If init contains none of "protocol", "hostname", "port", "pathname", and
15748
    // "search", then:
15749
0
    if (!init.protocol && !init.hostname && !init.port && !init.pathname &&
15750
0
        !init.search) {
15751
      // Let baseQuery be baseURL's query. get_search() carries the leading "?"
15752
      // delimiter, but the spec inherits the query itself, so drop it.
15753
0
      std::string_view base_query = base_url->get_search();
15754
0
      if (base_query.starts_with("?")) base_query.remove_prefix(1);
15755
      // Set result["search"] to the result of processing a base URL string
15756
      // given baseQuery and type.
15757
0
      result.search =
15758
0
          url_pattern_helpers::process_base_url_string(base_query, type);
15759
0
    }
15760
15761
    // If init contains none of "protocol", "hostname", "port", "pathname",
15762
    // "search", and "hash", then:
15763
0
    if (!init.protocol && !init.hostname && !init.port && !init.pathname &&
15764
0
        !init.search && !init.hash) {
15765
      // Let baseFragment be baseURL's fragment. get_hash() carries the leading
15766
      // "#" delimiter, but the spec inherits the fragment itself, so drop it.
15767
0
      std::string_view base_fragment = base_url->get_hash();
15768
0
      if (base_fragment.starts_with("#")) base_fragment.remove_prefix(1);
15769
      // Set result["hash"] to the result of processing a base URL string given
15770
      // baseFragment and type.
15771
0
      result.hash =
15772
0
          url_pattern_helpers::process_base_url_string(base_fragment, type);
15773
0
    }
15774
0
  }
15775
15776
  // If init["protocol"] exists, then set result["protocol"] to the result of
15777
  // process protocol for init given init["protocol"] and type.
15778
0
  if (init.protocol) {
15779
0
    auto process_result = process_protocol(*init.protocol, type);
15780
0
    if (!process_result) {
15781
0
      return tl::unexpected(process_result.error());
15782
0
    }
15783
0
    result.protocol = std::move(*process_result);
15784
0
  }
15785
15786
  // If init["username"] exists, then set result["username"] to the result of
15787
  // process username for init given init["username"] and type.
15788
0
  if (init.username.has_value()) {
15789
0
    auto process_result = process_username(*init.username, type);
15790
0
    if (!process_result) {
15791
0
      return tl::unexpected(process_result.error());
15792
0
    }
15793
0
    result.username = std::move(*process_result);
15794
0
  }
15795
15796
  // If init["password"] exists, then set result["password"] to the result of
15797
  // process password for init given init["password"] and type.
15798
0
  if (init.password.has_value()) {
15799
0
    auto process_result = process_password(*init.password, type);
15800
0
    if (!process_result) {
15801
0
      return tl::unexpected(process_result.error());
15802
0
    }
15803
0
    result.password = std::move(*process_result);
15804
0
  }
15805
15806
  // If init["hostname"] exists, then set result["hostname"] to the result of
15807
  // process hostname for init given init["hostname"] and type.
15808
0
  if (init.hostname.has_value()) {
15809
0
    auto process_result = process_hostname(*init.hostname, type);
15810
0
    if (!process_result) {
15811
0
      return tl::unexpected(process_result.error());
15812
0
    }
15813
0
    result.hostname = std::move(*process_result);
15814
0
  }
15815
15816
  // If init["port"] exists, then set result["port"] to the result of process
15817
  // port for init given init["port"], result["protocol"], and type.
15818
0
  if (init.port) {
15819
0
    auto process_result =
15820
0
        process_port(*init.port, result.protocol.value_or("fake"), type);
15821
0
    if (!process_result) {
15822
0
      return tl::unexpected(process_result.error());
15823
0
    }
15824
0
    result.port = std::move(*process_result);
15825
0
  }
15826
15827
  // If init["pathname"] exists:
15828
0
  if (init.pathname.has_value()) {
15829
    // Set result["pathname"] to init["pathname"].
15830
0
    result.pathname = init.pathname;
15831
15832
    // If the following are all true:
15833
    // - baseURL is not null;
15834
    // - baseURL has an opaque path; and
15835
    // - the result of running is an absolute pathname given result["pathname"]
15836
    // and type is false,
15837
0
    if (base_url && !base_url->has_opaque_path &&
15838
0
        !url_pattern_helpers::is_absolute_pathname(*result.pathname, type)) {
15839
      // Let baseURLPath be the result of running process a base URL string
15840
      // given the result of URL path serializing baseURL and type.
15841
      // TODO: Optimization opportunity: Avoid returning a string if no slash
15842
      // exist.
15843
0
      std::string base_url_path = url_pattern_helpers::process_base_url_string(
15844
0
          base_url->get_pathname(), type);
15845
15846
      // Let slash index be the index of the last U+002F (/) code point found in
15847
      // baseURLPath, interpreted as a sequence of code points, or null if there
15848
      // are no instances of the code point.
15849
0
      auto slash_index = base_url_path.find_last_of('/');
15850
15851
      // If slash index is not null:
15852
0
      if (slash_index != std::string::npos) {
15853
        // Let new pathname be the code point substring from 0 to slash index +
15854
        // 1 within baseURLPath.
15855
0
        base_url_path.resize(slash_index + 1);
15856
        // Append result["pathname"] to the end of new pathname.
15857
0
        ADA_ASSERT_TRUE(result.pathname.has_value());
15858
0
        base_url_path.append(std::move(*result.pathname));
15859
        // Set result["pathname"] to new pathname.
15860
0
        result.pathname = std::move(base_url_path);
15861
0
      }
15862
0
    }
15863
15864
    // Set result["pathname"] to the result of process pathname for init given
15865
    // result["pathname"], result["protocol"], and type.
15866
0
    auto pathname_processing_result =
15867
0
        process_pathname(*result.pathname, result.protocol.value_or(""), type);
15868
0
    if (!pathname_processing_result) {
15869
0
      return tl::unexpected(pathname_processing_result.error());
15870
0
    }
15871
0
    result.pathname = std::move(*pathname_processing_result);
15872
0
  }
15873
15874
  // If init["search"] exists then set result["search"] to the result of process
15875
  // search for init given init["search"] and type.
15876
0
  if (init.search) {
15877
0
    auto process_result = process_search(*init.search, type);
15878
0
    if (!process_result) {
15879
0
      return tl::unexpected(process_result.error());
15880
0
    }
15881
0
    result.search = std::move(*process_result);
15882
0
  }
15883
15884
  // If init["hash"] exists then set result["hash"] to the result of process
15885
  // hash for init given init["hash"] and type.
15886
0
  if (init.hash) {
15887
0
    auto process_result = process_hash(*init.hash, type);
15888
0
    if (!process_result) {
15889
0
      return tl::unexpected(process_result.error());
15890
0
    }
15891
0
    result.hash = std::move(*process_result);
15892
0
  }
15893
  // Return result.
15894
0
  return result;
15895
0
}
15896
15897
tl::expected<std::string, errors> url_pattern_init::process_protocol(
15898
0
    std::string_view value, process_type type) {
15899
0
  ada_log("process_protocol=", value, " [", type, "]");
15900
  // Let strippedValue be the given value with a single trailing U+003A (:)
15901
  // removed, if any.
15902
0
  if (value.ends_with(":")) {
15903
0
    value.remove_suffix(1);
15904
0
  }
15905
  // If type is "pattern" then return strippedValue.
15906
0
  if (type == process_type::pattern) {
15907
0
    return std::string(value);
15908
0
  }
15909
  // Return the result of running canonicalize a protocol given strippedValue.
15910
0
  return url_pattern_helpers::canonicalize_protocol(value);
15911
0
}
15912
15913
tl::expected<std::string, errors> url_pattern_init::process_username(
15914
0
    std::string_view value, process_type type) {
15915
  // If type is "pattern" then return value.
15916
0
  if (type == process_type::pattern) {
15917
0
    return std::string(value);
15918
0
  }
15919
  // Return the result of running canonicalize a username given value.
15920
0
  return url_pattern_helpers::canonicalize_username(value);
15921
0
}
15922
15923
tl::expected<std::string, errors> url_pattern_init::process_password(
15924
0
    std::string_view value, process_type type) {
15925
  // If type is "pattern" then return value.
15926
0
  if (type == process_type::pattern) {
15927
0
    return std::string(value);
15928
0
  }
15929
  // Return the result of running canonicalize a password given value.
15930
0
  return url_pattern_helpers::canonicalize_password(value);
15931
0
}
15932
15933
tl::expected<std::string, errors> url_pattern_init::process_hostname(
15934
0
    std::string_view value, process_type type) {
15935
0
  ada_log("process_hostname value=", value, " type=", type);
15936
  // If type is "pattern" then return value.
15937
0
  if (type == process_type::pattern) {
15938
0
    return std::string(value);
15939
0
  }
15940
  // Return the result of running canonicalize a hostname given value.
15941
0
  return url_pattern_helpers::canonicalize_hostname(value);
15942
0
}
15943
15944
tl::expected<std::string, errors> url_pattern_init::process_port(
15945
0
    std::string_view port, std::string_view protocol, process_type type) {
15946
  // If type is "pattern" then return portValue.
15947
0
  if (type == process_type::pattern) {
15948
0
    return std::string(port);
15949
0
  }
15950
  // Return the result of running canonicalize a port given portValue and
15951
  // protocolValue.
15952
0
  return url_pattern_helpers::canonicalize_port_with_protocol(port, protocol);
15953
0
}
15954
15955
tl::expected<std::string, errors> url_pattern_init::process_pathname(
15956
0
    std::string_view value, std::string_view protocol, process_type type) {
15957
  // If type is "pattern" then return pathnameValue.
15958
0
  if (type == process_type::pattern) {
15959
0
    return std::string(value);
15960
0
  }
15961
15962
  // If protocolValue is a special scheme or the empty string, then return the
15963
  // result of running canonicalize a pathname given pathnameValue.
15964
0
  if (protocol.empty() || scheme::is_special(protocol)) {
15965
0
    return url_pattern_helpers::canonicalize_pathname(value);
15966
0
  }
15967
15968
  // Return the result of running canonicalize an opaque pathname given
15969
  // pathnameValue.
15970
0
  return url_pattern_helpers::canonicalize_opaque_pathname(value);
15971
0
}
15972
15973
tl::expected<std::string, errors> url_pattern_init::process_search(
15974
0
    std::string_view value, process_type type) {
15975
  // Let strippedValue be the given value with a single leading U+003F (?)
15976
  // removed, if any.
15977
0
  if (value.starts_with("?")) {
15978
0
    value.remove_prefix(1);
15979
0
  }
15980
  // We cannot assert that the value is no longer starting with a single
15981
  // question mark because technically it can start. The question is whether or
15982
  // not we should remove the first question mark. Ref:
15983
  // https://github.com/ada-url/ada/pull/992 The spec is not clear on this.
15984
15985
  // If type is "pattern" then return strippedValue.
15986
0
  if (type == process_type::pattern) {
15987
0
    return std::string(value);
15988
0
  }
15989
  // Return the result of running canonicalize a search given strippedValue.
15990
0
  return url_pattern_helpers::canonicalize_search(value);
15991
0
}
15992
15993
tl::expected<std::string, errors> url_pattern_init::process_hash(
15994
0
    std::string_view value, process_type type) {
15995
  // Let strippedValue be the given value with a single leading U+0023 (#)
15996
  // removed, if any.
15997
0
  if (value.starts_with("#")) {
15998
0
    value.remove_prefix(1);
15999
0
  }
16000
0
  ADA_ASSERT_TRUE(!value.starts_with("#"));
16001
  // If type is "pattern" then return strippedValue.
16002
0
  if (type == process_type::pattern) {
16003
0
    return std::string(value);
16004
0
  }
16005
  // Return the result of running canonicalize a hash given strippedValue.
16006
0
  return url_pattern_helpers::canonicalize_hash(value);
16007
0
}
16008
16009
}  // namespace ada
16010
16011
#endif  // ADA_INCLUDE_URL_PATTERN
16012
/* end file src/url_pattern.cpp */
16013
/* begin file src/url_pattern_helpers.cpp */
16014
#if ADA_INCLUDE_URL_PATTERN
16015
16016
#include <algorithm>
16017
#include <array>
16018
#include <charconv>
16019
#include <cstddef>
16020
#include <cstdint>
16021
#include <optional>
16022
#include <ranges>
16023
#include <string>
16024
#include <string_view>
16025
#include <system_error>
16026
#include <tuple>
16027
#include <utility>
16028
#include <vector>
16029
16030
16031
namespace ada::url_pattern_helpers {
16032
16033
std::tuple<std::string, std::vector<std::string>>
16034
generate_regular_expression_and_name_list(
16035
    const std::vector<url_pattern_part>& part_list,
16036
0
    url_pattern_compile_component_options options) {
16037
  // Let result be "^"
16038
0
  std::string result = "^";
16039
  // Reserve capacity to reduce reallocations
16040
0
  result.reserve(part_list.size() * 16);
16041
16042
  // Let name list be a new list
16043
0
  std::vector<std::string> name_list{};
16044
0
  name_list.reserve(part_list.size());
16045
16046
  // Pre-generate segment wildcard regexp if needed (avoids repeated generation)
16047
0
  std::string segment_wildcard_regexp;
16048
16049
  // For each part of part list:
16050
0
  for (const url_pattern_part& part : part_list) {
16051
    // If part's type is "fixed-text":
16052
0
    if (part.type == url_pattern_part_type::FIXED_TEXT) {
16053
      // If part's modifier is "none"
16054
0
      if (part.modifier == url_pattern_part_modifier::none) {
16055
0
        result.append(escape_regexp_string(part.value));
16056
0
      } else {
16057
        // (?:<fixed text>)<modifier>
16058
0
        result.append("(?:");
16059
0
        result.append(escape_regexp_string(part.value));
16060
0
        result.push_back(')');
16061
0
        result.append(convert_modifier_to_string(part.modifier));
16062
0
      }
16063
0
      continue;
16064
0
    }
16065
16066
    // Assert: part's name is not the empty string
16067
0
    ADA_ASSERT_TRUE(!part.name.empty());
16068
0
    name_list.push_back(part.name);
16069
16070
    // Use string_view to avoid copies where possible
16071
0
    std::string_view regexp_value = part.value;
16072
16073
0
    if (part.type == url_pattern_part_type::SEGMENT_WILDCARD) {
16074
      // Lazy generate segment wildcard regexp
16075
0
      if (segment_wildcard_regexp.empty()) {
16076
0
        segment_wildcard_regexp = generate_segment_wildcard_regexp(options);
16077
0
      }
16078
0
      regexp_value = segment_wildcard_regexp;
16079
0
    } else if (part.type == url_pattern_part_type::FULL_WILDCARD) {
16080
0
      regexp_value = ".*";
16081
0
    }
16082
16083
    // If part's prefix is the empty string and part's suffix is the empty
16084
    // string
16085
0
    if (part.prefix.empty() && part.suffix.empty()) {
16086
      // If part's modifier is "none" or "optional"
16087
0
      if (part.modifier == url_pattern_part_modifier::none ||
16088
0
          part.modifier == url_pattern_part_modifier::optional) {
16089
        // (<regexp value>)<modifier>
16090
0
        result.push_back('(');
16091
0
        result.append(regexp_value);
16092
0
        result.push_back(')');
16093
0
        result.append(convert_modifier_to_string(part.modifier));
16094
0
      } else {
16095
        // ((?:<regexp value>)<modifier>)
16096
0
        result.append("((?:");
16097
0
        result.append(regexp_value);
16098
0
        result.push_back(')');
16099
0
        result.append(convert_modifier_to_string(part.modifier));
16100
0
        result.push_back(')');
16101
0
      }
16102
0
      continue;
16103
0
    }
16104
16105
    // If part's modifier is "none" or "optional"
16106
0
    if (part.modifier == url_pattern_part_modifier::none ||
16107
0
        part.modifier == url_pattern_part_modifier::optional) {
16108
      // (?:<prefix>(<regexp value>)<suffix>)<modifier>
16109
0
      result.append("(?:");
16110
0
      result.append(escape_regexp_string(part.prefix));
16111
0
      result.push_back('(');
16112
0
      result.append(regexp_value);
16113
0
      result.push_back(')');
16114
0
      result.append(escape_regexp_string(part.suffix));
16115
0
      result.push_back(')');
16116
0
      result.append(convert_modifier_to_string(part.modifier));
16117
0
      continue;
16118
0
    }
16119
16120
    // Assert: part's modifier is "zero-or-more" or "one-or-more"
16121
0
    ADA_ASSERT_TRUE(part.modifier == url_pattern_part_modifier::zero_or_more ||
16122
0
                    part.modifier == url_pattern_part_modifier::one_or_more);
16123
16124
    // Assert: part's prefix is not the empty string or part's suffix is not the
16125
    // empty string
16126
0
    ADA_ASSERT_TRUE(!part.prefix.empty() || !part.suffix.empty());
16127
16128
    // (?:<prefix>((?:<regexp value>)(?:<suffix><prefix>(?:<regexp
16129
    // value>))*)<suffix>)?
16130
    // Append "(?:" to the end of result.
16131
0
    result.append("(?:");
16132
    // Append the result of running escape a regexp string given part's prefix
16133
    // to the end of result.
16134
0
    result.append(escape_regexp_string(part.prefix));
16135
    // Append "((?:" to the end of result.
16136
0
    result.append("((?:");
16137
    // Append regexp value to the end of result.
16138
0
    result.append(regexp_value);
16139
    // Append ")(?:" to the end of result.
16140
0
    result.append(")(?:");
16141
    // Append the result of running escape a regexp string given part's suffix
16142
    // to the end of result.
16143
0
    result.append(escape_regexp_string(part.suffix));
16144
    // Append the result of running escape a regexp string given part's prefix
16145
    // to the end of result.
16146
0
    result.append(escape_regexp_string(part.prefix));
16147
    // Append "(?:" to the end of result.
16148
0
    result.append("(?:");
16149
    // Append regexp value to the end of result.
16150
0
    result.append(regexp_value);
16151
    // Append "))*)" to the end of result.
16152
0
    result.append("))*)");
16153
    // Append the result of running escape a regexp string given part's suffix
16154
    // to the end of result.
16155
0
    result.append(escape_regexp_string(part.suffix));
16156
    // Append ")" to the end of result.
16157
0
    result.append(")");
16158
16159
    // If part's modifier is "zero-or-more" then append "?" to the end of result
16160
0
    if (part.modifier == url_pattern_part_modifier::zero_or_more) {
16161
0
      result += "?";
16162
0
    }
16163
0
  }
16164
16165
  // Append "$" to the end of result
16166
0
  result += "$";
16167
16168
  // Return (result, name list)
16169
0
  return {std::move(result), std::move(name_list)};
16170
0
}
16171
16172
0
bool is_ipv6_address(std::string_view input) noexcept {
16173
  // If input's code point length is less than 2, then return false.
16174
0
  if (input.size() < 2) return false;
16175
16176
  // Let input code points be input interpreted as a list of code points.
16177
  // If input code points[0] is U+005B ([), then return true.
16178
0
  if (input.front() == '[') return true;
16179
  // If input code points[0] is U+007B ({) and input code points[1] is U+005B
16180
  // ([), then return true.
16181
0
  if (input.starts_with("{[")) return true;
16182
  // If input code points[0] is U+005C (\) and input code points[1] is U+005B
16183
  // ([), then return true.
16184
0
  return input.starts_with("\\[");
16185
0
}
16186
16187
std::string_view convert_modifier_to_string(
16188
0
    url_pattern_part_modifier modifier) {
16189
0
  switch (modifier) {
16190
      // If modifier is "zero-or-more", then return "*".
16191
0
    case url_pattern_part_modifier::zero_or_more:
16192
0
      return "*";
16193
    // If modifier is "optional", then return "?".
16194
0
    case url_pattern_part_modifier::optional:
16195
0
      return "?";
16196
    // If modifier is "one-or-more", then return "+".
16197
0
    case url_pattern_part_modifier::one_or_more:
16198
0
      return "+";
16199
    // Return the empty string.
16200
0
    default:
16201
0
      return "";
16202
0
  }
16203
0
}
16204
16205
std::string generate_segment_wildcard_regexp(
16206
0
    url_pattern_compile_component_options options) {
16207
  // Let result be "[^".
16208
0
  std::string result = "[^";
16209
  // Append the result of running escape a regexp string given options's
16210
  // delimiter code point to the end of result.
16211
0
  result.append(escape_regexp_string(options.get_delimiter()));
16212
  // Append "]+?" to the end of result.
16213
0
  result.append("]+?");
16214
  // Return result.
16215
0
  ada_log("generate_segment_wildcard_regexp result: ", result);
16216
0
  return result;
16217
0
}
16218
16219
namespace {
16220
// Unified lookup table for URL pattern character classification
16221
// Bit flags for different character types
16222
constexpr uint8_t CHAR_SCHEME = 1;  // valid in scheme (a-z, A-Z, 0-9, +, -, .)
16223
constexpr uint8_t CHAR_UPPER = 2;   // uppercase letter (needs lowercasing)
16224
constexpr uint8_t CHAR_SIMPLE_HOSTNAME = 4;  // simple hostname (a-z, 0-9, -, .)
16225
constexpr uint8_t CHAR_SIMPLE_PATHNAME =
16226
    8;  // simple pathname (a-z, A-Z, 0-9, /, -, _, ~)
16227
16228
constexpr std::array<uint8_t, 256> char_class_table = []() consteval {
16229
  std::array<uint8_t, 256> table{};
16230
  for (int c = 'a'; c <= 'z'; c++)
16231
    table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
16232
  for (int c = 'A'; c <= 'Z'; c++)
16233
    table[c] = CHAR_SCHEME | CHAR_UPPER | CHAR_SIMPLE_PATHNAME;
16234
  for (int c = '0'; c <= '9'; c++)
16235
    table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
16236
  table['+'] = CHAR_SCHEME;
16237
  table['-'] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
16238
  table['.'] =
16239
      CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME;  // not pathname (needs normalization)
16240
  table['/'] = CHAR_SIMPLE_PATHNAME;
16241
  table['_'] = CHAR_SIMPLE_PATHNAME;
16242
  table['~'] = CHAR_SIMPLE_PATHNAME;
16243
  return table;
16244
}();
16245
}  // namespace
16246
16247
tl::expected<std::string, errors> canonicalize_protocol(
16248
0
    std::string_view input) {
16249
0
  ada_log("canonicalize_protocol called with input=", input);
16250
0
  if (input.empty()) [[unlikely]] {
16251
0
    return "";
16252
0
  }
16253
16254
0
  if (input.ends_with(":")) {
16255
0
    input.remove_suffix(1);
16256
0
  }
16257
16258
  // Fast path: special schemes are already canonical
16259
0
  if (scheme::is_special(input)) {
16260
0
    return std::string(input);
16261
0
  }
16262
16263
  // Fast path: validate scheme chars and check for uppercase
16264
  // First char must be alpha (not +, -, ., or digit)
16265
0
  uint8_t first_flags = char_class_table[static_cast<uint8_t>(input[0])];
16266
0
  if (!(first_flags & CHAR_SCHEME) || input[0] == '+' || input[0] == '-' ||
16267
0
      input[0] == '.' || unicode::is_ascii_digit(input[0])) {
16268
0
    return tl::unexpected(errors::type_error);
16269
0
  }
16270
16271
0
  uint8_t needs_lowercase = first_flags & CHAR_UPPER;
16272
0
  for (size_t i = 1; i < input.size(); i++) {
16273
0
    uint8_t flags = char_class_table[static_cast<uint8_t>(input[i])];
16274
0
    if (!(flags & CHAR_SCHEME)) {
16275
0
      return tl::unexpected(errors::type_error);
16276
0
    }
16277
0
    needs_lowercase |= flags & CHAR_UPPER;
16278
0
  }
16279
16280
0
  if (needs_lowercase == 0) {
16281
0
    return std::string(input);
16282
0
  }
16283
16284
0
  std::string result(input);
16285
0
  unicode::to_lower_ascii(result.data(), result.size());
16286
0
  return result;
16287
0
}
16288
16289
tl::expected<std::string, errors> canonicalize_username(
16290
0
    std::string_view input) {
16291
  // If value is the empty string, return value.
16292
0
  if (input.empty()) [[unlikely]] {
16293
0
    return "";
16294
0
  }
16295
  // Percent-encode the input using the userinfo percent-encode set.
16296
0
  size_t idx = ada::unicode::percent_encode_index(
16297
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
16298
0
  if (idx == input.size()) {
16299
    // No encoding needed, return input as-is
16300
0
    return std::string(input);
16301
0
  }
16302
  // Percent-encode from the first character that needs encoding
16303
0
  return ada::unicode::percent_encode(
16304
0
      input, character_sets::USERINFO_PERCENT_ENCODE, idx);
16305
0
}
16306
16307
tl::expected<std::string, errors> canonicalize_password(
16308
0
    std::string_view input) {
16309
  // If value is the empty string, return value.
16310
0
  if (input.empty()) [[unlikely]] {
16311
0
    return "";
16312
0
  }
16313
  // Percent-encode the input using the userinfo percent-encode set.
16314
0
  size_t idx = ada::unicode::percent_encode_index(
16315
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
16316
0
  if (idx == input.size()) {
16317
    // No encoding needed, return input as-is
16318
0
    return std::string(input);
16319
0
  }
16320
  // Percent-encode from the first character that needs encoding
16321
0
  return ada::unicode::percent_encode(
16322
0
      input, character_sets::USERINFO_PERCENT_ENCODE, idx);
16323
0
}
16324
16325
tl::expected<std::string, errors> canonicalize_hostname(
16326
0
    std::string_view input) {
16327
0
  ada_log("canonicalize_hostname input=", input);
16328
0
  if (input.empty()) [[unlikely]] {
16329
0
    return "";
16330
0
  }
16331
16332
  // Fast path: simple hostnames (lowercase ASCII, digits, -, .) need no IDNA.
16333
  // The simple character set also covers IPv4-shaped hosts, which the slow
16334
  // path rewrites ("0" -> "0.0.0.0", "0x7f.1" -> "127.0.0.1"). Exclude those
16335
  // so the fast path can't return a non-canonical hostname.
16336
  //
16337
  // Pure-ASCII "xn--" labels are intentionally left on the fast path: with
16338
  // beStrict=false, domain-to-ASCII returns the lowercased ASCII input even
16339
  // when Unicode ToASCII would fail (e.g. invalid ACE "xn--a"). See
16340
  // https://url.spec.whatwg.org/#concept-domain-to-ascii
16341
0
  bool needs_processing = false;
16342
0
  for (char c : input) {
16343
0
    needs_processing |=
16344
0
        !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_HOSTNAME);
16345
0
  }
16346
0
  if (!needs_processing && !checkers::is_ipv4(input)) {
16347
0
    return std::string(input);
16348
0
  }
16349
16350
  // Let dummyURL be a new URL record.
16351
  // Let parseResult be the result of running the basic URL parser given value
16352
  // with dummyURL as url and hostname state as state override.
16353
16354
  // IMPORTANT: The protocol needs to be a special protocol, otherwise the
16355
  // hostname will not be converted using IDNA.
16356
0
  auto url = ada::parse<url_aggregator>("https://dummy.test", nullptr);
16357
0
  ADA_ASSERT_TRUE(url);
16358
  // if (!isValidHostnameInput(hostname)) return kj::none;
16359
0
  if (!url->set_hostname(input)) {
16360
    // If parseResult is failure, then throw a TypeError.
16361
0
    return tl::unexpected(errors::type_error);
16362
0
  }
16363
  // Return dummyURL's host, serialized, or empty string if it is null.
16364
0
  return std::string(url->get_hostname());
16365
0
}
16366
16367
tl::expected<std::string, errors> canonicalize_ipv6_hostname(
16368
0
    std::string_view input) {
16369
0
  ada_log("canonicalize_ipv6_hostname input=", input);
16370
  // TODO: Optimization opportunity: Use lookup table to speed up checking
16371
0
  if (std::ranges::any_of(input, [](char c) {
16372
0
        return c != '[' && c != ']' && c != ':' &&
16373
0
               !unicode::is_ascii_hex_digit(c);
16374
0
      })) {
16375
0
    return tl::unexpected(errors::type_error);
16376
0
  }
16377
  // Append the result of running ASCII lowercase given code point to the end of
16378
  // result.
16379
0
  auto hostname = std::string(input);
16380
0
  unicode::to_lower_ascii(hostname.data(), hostname.size());
16381
0
  return hostname;
16382
0
}
16383
16384
tl::expected<std::string, errors> canonicalize_port(
16385
0
    std::string_view port_value) {
16386
  // If portValue is the empty string, return portValue.
16387
0
  if (port_value.empty()) [[unlikely]] {
16388
0
    return "";
16389
0
  }
16390
16391
  // Remove ASCII tab or newline characters
16392
0
  std::string trimmed(port_value);
16393
0
  helpers::remove_ascii_tab_or_newline(trimmed);
16394
16395
0
  if (trimmed.empty()) {
16396
0
    return "";
16397
0
  }
16398
16399
  // Input should start with a digit character
16400
0
  if (!unicode::is_ascii_digit(trimmed.front())) {
16401
0
    return tl::unexpected(errors::type_error);
16402
0
  }
16403
16404
  // Find the first non-digit character
16405
0
  auto first_non_digit =
16406
0
      std::ranges::find_if_not(trimmed, unicode::is_ascii_digit);
16407
0
  std::string_view digits_to_parse =
16408
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
16409
16410
  // Here we have a range of ASCII digit characters identified by
16411
  // digits_to_parse. It is non-empty. The port state of the URL parser reads
16412
  // it as an integer, so leading zeros are part of the number: "0080" is 80
16413
  // and "065535" is 65535, not a six-digit overflow. Only the significant
16414
  // digits count toward the 5-digit maximum, matching the fast path in
16415
  // implementation.cpp.
16416
0
  size_t first_significant = digits_to_parse.find_first_not_of('0');
16417
0
  if (first_significant == std::string_view::npos) {
16418
    // The value is all zeros, i.e. port 0.
16419
0
    return "0";
16420
0
  }
16421
0
  digits_to_parse.remove_prefix(first_significant);
16422
  // We want to determine whether it is a valid port number (0-65535).
16423
  // Clearly, if the length is greater than 5, it is invalid.
16424
  // If the length is 5, we need to compare lexicographically to "65535".
16425
  // Otherwise it is valid.
16426
0
  if (digits_to_parse.size() == 5) {
16427
0
    if (digits_to_parse > "65535") {
16428
0
      return tl::unexpected(errors::type_error);
16429
0
    }
16430
0
  } else if (digits_to_parse.size() > 5) {
16431
0
    return tl::unexpected(errors::type_error);
16432
0
  }
16433
  // It is valid! Most times, we do not need to parse it into an integer.
16434
0
  return std::string(digits_to_parse);
16435
0
}
16436
16437
tl::expected<std::string, errors> canonicalize_port_with_protocol(
16438
0
    std::string_view port_value, std::string_view protocol) {
16439
  // If portValue is the empty string, return portValue.
16440
0
  if (port_value.empty()) [[unlikely]] {
16441
0
    return "";
16442
0
  }
16443
16444
  // Handle empty or trailing colon in protocol
16445
0
  if (protocol.empty()) {
16446
0
    protocol = "fake";
16447
0
  } else if (protocol.ends_with(":")) {
16448
0
    protocol.remove_suffix(1);
16449
0
  }
16450
16451
  // Remove ASCII tab or newline characters
16452
0
  std::string trimmed(port_value);
16453
0
  helpers::remove_ascii_tab_or_newline(trimmed);
16454
16455
0
  if (trimmed.empty()) {
16456
0
    return "";
16457
0
  }
16458
16459
  // Input should start with a digit character
16460
0
  if (!unicode::is_ascii_digit(trimmed.front())) {
16461
0
    return tl::unexpected(errors::type_error);
16462
0
  }
16463
16464
  // Find the first non-digit character
16465
0
  auto first_non_digit =
16466
0
      std::ranges::find_if_not(trimmed, unicode::is_ascii_digit);
16467
0
  std::string_view digits_to_parse =
16468
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
16469
16470
  // Parse the port number
16471
0
  uint16_t parsed_port{};
16472
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
16473
0
  auto result = std::from_chars(digits_to_parse.data(),
16474
0
                                digits_to_parse.data() + digits_to_parse.size(),
16475
0
                                parsed_port);
16476
16477
0
  if (result.ec == std::errc::result_out_of_range) {
16478
0
    return tl::unexpected(errors::type_error);
16479
0
  }
16480
16481
0
  if (result.ec == std::errc()) {
16482
    // Check if this is the default port for the scheme
16483
0
    uint16_t default_port = scheme::get_special_port(protocol);
16484
16485
    // If it's the default port for a special scheme, return empty string
16486
0
    if (default_port != 0 && default_port == parsed_port) {
16487
0
      return "";
16488
0
    }
16489
16490
    // Successfully parsed, return as string
16491
0
    return std::to_string(parsed_port);
16492
0
  }
16493
16494
0
  return tl::unexpected(errors::type_error);
16495
0
}
16496
16497
tl::expected<std::string, errors> canonicalize_pathname(
16498
0
    std::string_view input) {
16499
0
  if (input.empty()) [[unlikely]] {
16500
0
    return "";
16501
0
  }
16502
16503
  // Fast path: simple pathnames (no . which needs normalization) can be
16504
  // returned as-is
16505
0
  bool needs_processing = false;
16506
0
  for (char c : input) {
16507
0
    needs_processing |=
16508
0
        !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_PATHNAME);
16509
0
  }
16510
0
  if (!needs_processing) {
16511
0
    return std::string(input);
16512
0
  }
16513
16514
  // Let leading slash be true if the first code point in value is U+002F (/)
16515
  // and otherwise false.
16516
0
  const bool leading_slash = input.starts_with("/");
16517
  // Let modified value be "/-" if leading slash is false and otherwise the
16518
  // empty string.
16519
0
  const auto modified_value =
16520
0
      (leading_slash ? std::string() : std::string("/-")) + std::string(input);
16521
  // The spec runs the basic URL parser with the path in state override, where
16522
  // '?' and '#' are ordinary path code points (percent-encoded) and leading or
16523
  // trailing C0 control or space is kept. Building a full URL string and
16524
  // parsing it (no state override) instead let '?' and '#' start the
16525
  // query/fragment, so the pathname was silently truncated at the first literal
16526
  // '?' or '#'. set_pathname runs the parser in path state override, matching
16527
  // how canonicalize_hostname uses set_hostname.
16528
  // The spec's "create a dummy URL" is "https://dummy.invalid/": a special
16529
  // URL, so the path parser turns "\\" into "/" as it does in a special URL.
16530
  // A non-special dummy kept a literal backslash, so a pattern such as
16531
  // "/a\\b" never matched "https://h/a/b".
16532
0
  auto url = ada::parse<url_aggregator>("https://dummy.invalid/", nullptr);
16533
0
  ADA_ASSERT_TRUE(url);
16534
0
  if (!url->set_pathname(modified_value)) {
16535
    // If parseResult is failure, then throw a TypeError.
16536
0
    return tl::unexpected(errors::type_error);
16537
0
  }
16538
0
  const auto pathname = url->get_pathname();
16539
  // If leading slash is false, then set result to the code point substring
16540
  // from 2 to the end of the string within result.
16541
0
  if (!leading_slash) {
16542
    // pathname should start with "/-" but path traversal (e.g. "../../")
16543
    // can reduce it to just "/" which is shorter than 2 characters.
16544
0
    if (pathname.size() < 2) {
16545
0
      return tl::unexpected(errors::type_error);
16546
0
    }
16547
0
    return std::string(pathname.substr(2));
16548
0
  }
16549
0
  return std::string(pathname);
16550
0
}
16551
16552
tl::expected<std::string, errors> canonicalize_opaque_pathname(
16553
0
    std::string_view input) {
16554
  // If value is the empty string, return value.
16555
0
  if (input.empty()) [[unlikely]] {
16556
0
    return "";
16557
0
  }
16558
  // Let dummyURL be a new URL record.
16559
  // Set dummyURL's path to the empty string.
16560
  // Let parseResult be the result of running URL parsing given value with
16561
  // dummyURL as url and opaque path state as state override.
16562
0
  if (auto url =
16563
0
          ada::parse<url_aggregator>("fake:" + std::string(input), nullptr)) {
16564
    // Return the result of URL path serializing dummyURL.
16565
0
    return std::string(url->get_pathname());
16566
0
  }
16567
  // If parseResult is failure, then throw a TypeError.
16568
0
  return tl::unexpected(errors::type_error);
16569
0
}
16570
16571
0
tl::expected<std::string, errors> canonicalize_search(std::string_view input) {
16572
  // If value is the empty string, return value.
16573
0
  if (input.empty()) [[unlikely]] {
16574
0
    return "";
16575
0
  }
16576
  // A leading '?' is a valid query code point here: it is the caller (process a
16577
  // search) that removes a single delimiter, not this step, which mirrors the
16578
  // basic URL parser's query state.
16579
0
  std::string new_value(input);
16580
  // Remove ASCII tab or newline characters
16581
0
  helpers::remove_ascii_tab_or_newline(new_value);
16582
16583
0
  if (new_value.empty()) {
16584
0
    return "";
16585
0
  }
16586
16587
  // Percent-encode using QUERY_PERCENT_ENCODE (for non-special URLs)
16588
  // Note: "fake://dummy.test" is not a special URL, so we use
16589
  // QUERY_PERCENT_ENCODE
16590
0
  size_t idx = ada::unicode::percent_encode_index(
16591
0
      new_value, character_sets::QUERY_PERCENT_ENCODE);
16592
0
  if (idx == new_value.size()) {
16593
    // No encoding needed
16594
0
    return new_value;
16595
0
  }
16596
  // Percent-encode from the first character that needs encoding
16597
0
  return ada::unicode::percent_encode(
16598
0
      new_value, character_sets::QUERY_PERCENT_ENCODE, idx);
16599
0
}
16600
16601
0
tl::expected<std::string, errors> canonicalize_hash(std::string_view input) {
16602
  // If value is the empty string, return value.
16603
0
  if (input.empty()) [[unlikely]] {
16604
0
    return "";
16605
0
  }
16606
  // A leading '#' is a valid fragment code point here: it is the caller
16607
  // (process a hash) that removes a single delimiter, not this step, which
16608
  // mirrors the basic URL parser's fragment state.
16609
0
  std::string new_value(input);
16610
  // Remove ASCII tab or newline characters
16611
0
  helpers::remove_ascii_tab_or_newline(new_value);
16612
16613
0
  if (new_value.empty()) {
16614
0
    return "";
16615
0
  }
16616
16617
  // Percent-encode using FRAGMENT_PERCENT_ENCODE
16618
0
  size_t idx = ada::unicode::percent_encode_index(
16619
0
      new_value, character_sets::FRAGMENT_PERCENT_ENCODE);
16620
0
  if (idx == new_value.size()) {
16621
    // No encoding needed
16622
0
    return new_value;
16623
0
  }
16624
  // Percent-encode from the first character that needs encoding
16625
0
  return ada::unicode::percent_encode(
16626
0
      new_value, character_sets::FRAGMENT_PERCENT_ENCODE, idx);
16627
0
}
16628
16629
tl::expected<std::vector<token>, errors> tokenize(std::string_view input,
16630
0
                                                  token_policy policy) {
16631
0
  ada_log("tokenize input: ", input);
16632
  // Let tokenizer be a new tokenizer.
16633
  // Set tokenizer's input to input.
16634
  // Set tokenizer's policy to policy.
16635
0
  auto tokenizer = Tokenizer(input, policy);
16636
  // While tokenizer's index is less than tokenizer's input's code point length:
16637
0
  while (tokenizer.index < tokenizer.input.size()) {
16638
    // Run seek and get the next code point given tokenizer and tokenizer's
16639
    // index.
16640
0
    tokenizer.seek_and_get_next_code_point(tokenizer.index);
16641
16642
    // Malformed UTF-8 must not stall tokenization: report an invalid-char
16643
    // token (lenient) or fail fast (strict), while always making progress.
16644
0
    if (tokenizer.had_invalid_code_point()) {
16645
0
      if (auto error = tokenizer.process_tokenizing_error(tokenizer.next_index,
16646
0
                                                          tokenizer.index)) {
16647
0
        return tl::unexpected(*error);
16648
0
      }
16649
0
      continue;
16650
0
    }
16651
16652
    // If tokenizer's code point is U+002A (*):
16653
0
    if (tokenizer.code_point == '*') {
16654
      // Run add a token with default position and length given tokenizer and
16655
      // "asterisk".
16656
0
      tokenizer.add_token_with_defaults(token_type::ASTERISK);
16657
0
      ada_log("add ASTERISK token");
16658
      // Continue.
16659
0
      continue;
16660
0
    }
16661
16662
    // If tokenizer's code point is U+002B (+) or U+003F (?):
16663
0
    if (tokenizer.code_point == '+' || tokenizer.code_point == '?') {
16664
      // Run add a token with default position and length given tokenizer and
16665
      // "other-modifier".
16666
0
      tokenizer.add_token_with_defaults(token_type::OTHER_MODIFIER);
16667
      // Continue.
16668
0
      continue;
16669
0
    }
16670
16671
    // If tokenizer's code point is U+005C (\):
16672
0
    if (tokenizer.code_point == '\\') {
16673
      // If tokenizer's index is equal to tokenizer's input's code point length
16674
      // - 1:
16675
0
      if (tokenizer.index == tokenizer.input.size() - 1) {
16676
        // Run process a tokenizing error given tokenizer, tokenizer's next
16677
        // index, and tokenizer's index.
16678
0
        if (auto error = tokenizer.process_tokenizing_error(
16679
0
                tokenizer.next_index, tokenizer.index)) {
16680
0
          ada_log("process_tokenizing_error failed");
16681
0
          return tl::unexpected(*error);
16682
0
        }
16683
0
        continue;
16684
0
      }
16685
16686
      // Let escaped index be tokenizer's next index.
16687
0
      auto escaped_index = tokenizer.next_index;
16688
      // Run get the next code point given tokenizer.
16689
0
      tokenizer.get_next_code_point();
16690
0
      if (tokenizer.had_invalid_code_point()) {
16691
0
        if (auto error = tokenizer.process_tokenizing_error(
16692
0
                tokenizer.next_index, escaped_index)) {
16693
0
          return tl::unexpected(*error);
16694
0
        }
16695
0
        continue;
16696
0
      }
16697
      // Run add a token with default length given tokenizer, "escaped-char",
16698
      // tokenizer's next index, and escaped index.
16699
0
      tokenizer.add_token_with_default_length(
16700
0
          token_type::ESCAPED_CHAR, tokenizer.next_index, escaped_index);
16701
0
      ada_log("add ESCAPED_CHAR token on next_index ", tokenizer.next_index,
16702
0
              " with escaped index ", escaped_index);
16703
      // Continue.
16704
0
      continue;
16705
0
    }
16706
16707
    // If tokenizer's code point is U+007B ({):
16708
0
    if (tokenizer.code_point == '{') {
16709
      // Run add a token with default position and length given tokenizer and
16710
      // "open".
16711
0
      tokenizer.add_token_with_defaults(token_type::OPEN);
16712
0
      ada_log("add OPEN token");
16713
0
      continue;
16714
0
    }
16715
16716
    // If tokenizer's code point is U+007D (}):
16717
0
    if (tokenizer.code_point == '}') {
16718
      // Run add a token with default position and length given tokenizer and
16719
      // "close".
16720
0
      tokenizer.add_token_with_defaults(token_type::CLOSE);
16721
0
      ada_log("add CLOSE token");
16722
0
      continue;
16723
0
    }
16724
16725
    // If tokenizer's code point is U+003A (:):
16726
0
    if (tokenizer.code_point == ':') {
16727
      // Let name position be tokenizer's next index.
16728
0
      auto name_position = tokenizer.next_index;
16729
      // Let name start be name position.
16730
0
      auto name_start = name_position;
16731
0
      bool invalid_name = false;
16732
      // While name position is less than tokenizer's input's code point length:
16733
0
      while (name_position < tokenizer.input.size()) {
16734
        // Run seek and get the next code point given tokenizer and name
16735
        // position.
16736
0
        tokenizer.seek_and_get_next_code_point(name_position);
16737
0
        if (tokenizer.had_invalid_code_point()) {
16738
0
          if (auto error = tokenizer.process_tokenizing_error(
16739
0
                  tokenizer.next_index, name_position)) {
16740
0
            return tl::unexpected(*error);
16741
0
          }
16742
0
          invalid_name = true;
16743
0
          break;
16744
0
        }
16745
        // Let first code point be true if name position equals name start and
16746
        // false otherwise.
16747
0
        bool first_code_point = name_position == name_start;
16748
        // Let valid code point be the result of running is a valid name code
16749
        // point given tokenizer's code point and first code point.
16750
0
        auto valid_code_point =
16751
0
            idna::valid_name_code_point(tokenizer.code_point, first_code_point);
16752
0
        ada_log("tokenizer.code_point=", uint32_t(tokenizer.code_point),
16753
0
                " first_code_point=", first_code_point,
16754
0
                " valid_code_point=", valid_code_point);
16755
        // If valid code point is false break.
16756
0
        if (!valid_code_point) break;
16757
        // Set name position to tokenizer's next index.
16758
0
        name_position = tokenizer.next_index;
16759
0
      }
16760
16761
0
      if (invalid_name) {
16762
0
        continue;
16763
0
      }
16764
16765
      // If name position is less than or equal to name start:
16766
0
      if (name_position <= name_start) {
16767
        // Run process a tokenizing error given tokenizer, name start, and
16768
        // tokenizer's index.
16769
0
        if (auto error = tokenizer.process_tokenizing_error(name_start,
16770
0
                                                            tokenizer.index)) {
16771
0
          ada_log("process_tokenizing_error failed");
16772
0
          return tl::unexpected(*error);
16773
0
        }
16774
        // Continue
16775
0
        continue;
16776
0
      }
16777
16778
      // Run add a token with default length given tokenizer, "name", name
16779
      // position, and name start.
16780
0
      tokenizer.add_token_with_default_length(token_type::NAME, name_position,
16781
0
                                              name_start);
16782
0
      continue;
16783
0
    }
16784
16785
    // If tokenizer's code point is U+0028 (():
16786
0
    if (tokenizer.code_point == '(') {
16787
      // Let depth be 1.
16788
0
      size_t depth = 1;
16789
      // Let regexp position be tokenizer's next index.
16790
0
      auto regexp_position = tokenizer.next_index;
16791
      // Let regexp start be regexp position.
16792
0
      auto regexp_start = regexp_position;
16793
      // Let error be false.
16794
0
      bool error = false;
16795
16796
      // While regexp position is less than tokenizer's input's code point
16797
      // length:
16798
0
      while (regexp_position < tokenizer.input.size()) {
16799
        // Run seek and get the next code point given tokenizer and regexp
16800
        // position.
16801
0
        tokenizer.seek_and_get_next_code_point(regexp_position);
16802
0
        if (tokenizer.had_invalid_code_point()) {
16803
0
          if (auto process_error = tokenizer.process_tokenizing_error(
16804
0
                  tokenizer.next_index, regexp_position)) {
16805
0
            return tl::unexpected(*process_error);
16806
0
          }
16807
0
          error = true;
16808
0
          break;
16809
0
        }
16810
16811
        // TODO: Optimization opportunity: The next 2 if statements can be
16812
        // merged. If the result of running is ASCII given tokenizer's code
16813
        // point is false:
16814
0
        if (!unicode::is_ascii(tokenizer.code_point)) {
16815
          // Run process a tokenizing error given tokenizer, regexp start, and
16816
          // tokenizer's index.
16817
0
          if (auto process_error = tokenizer.process_tokenizing_error(
16818
0
                  regexp_start, tokenizer.index)) {
16819
0
            return tl::unexpected(*process_error);
16820
0
          }
16821
          // Set error to true.
16822
0
          error = true;
16823
0
          break;
16824
0
        }
16825
16826
        // If regexp position equals regexp start and tokenizer's code point is
16827
        // U+003F (?):
16828
0
        if (regexp_position == regexp_start && tokenizer.code_point == '?') {
16829
          // Run process a tokenizing error given tokenizer, regexp start, and
16830
          // tokenizer's index.
16831
0
          if (auto process_error = tokenizer.process_tokenizing_error(
16832
0
                  regexp_start, tokenizer.index)) {
16833
0
            return tl::unexpected(*process_error);
16834
0
          }
16835
          // Set error to true;
16836
0
          error = true;
16837
0
          break;
16838
0
        }
16839
16840
        // If tokenizer's code point is U+005C (\):
16841
0
        if (tokenizer.code_point == '\\') {
16842
          // If regexp position equals tokenizer's input's code point length - 1
16843
0
          if (regexp_position == tokenizer.input.size() - 1) {
16844
            // Run process a tokenizing error given tokenizer, regexp start, and
16845
            // tokenizer's index.
16846
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16847
0
                    regexp_start, tokenizer.index)) {
16848
0
              return tl::unexpected(*process_error);
16849
0
            }
16850
            // Set error to true.
16851
0
            error = true;
16852
0
            break;
16853
0
          }
16854
          // Run get the next code point given tokenizer.
16855
0
          auto escaped_index = tokenizer.next_index;
16856
0
          tokenizer.get_next_code_point();
16857
0
          if (tokenizer.had_invalid_code_point()) {
16858
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16859
0
                    tokenizer.next_index, escaped_index)) {
16860
0
              return tl::unexpected(*process_error);
16861
0
            }
16862
0
            error = true;
16863
0
            break;
16864
0
          }
16865
          // If the result of running is ASCII given tokenizer's code point is
16866
          // false:
16867
0
          if (!unicode::is_ascii(tokenizer.code_point)) {
16868
            // Run process a tokenizing error given tokenizer, regexp start, and
16869
            // tokenizer's index.
16870
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16871
0
                    regexp_start, tokenizer.index);
16872
0
                process_error.has_value()) {
16873
0
              return tl::unexpected(*process_error);
16874
0
            }
16875
            // Set error to true.
16876
0
            error = true;
16877
0
            break;
16878
0
          }
16879
          // Set regexp position to tokenizer's next index.
16880
0
          regexp_position = tokenizer.next_index;
16881
0
          continue;
16882
0
        }
16883
16884
        // If tokenizer's code point is U+0029 ()):
16885
0
        if (tokenizer.code_point == ')') {
16886
          // Decrement depth by 1.
16887
0
          depth--;
16888
          // If depth is 0:
16889
0
          if (depth == 0) {
16890
            // Set regexp position to tokenizer's next index.
16891
0
            regexp_position = tokenizer.next_index;
16892
            // Break.
16893
0
            break;
16894
0
          }
16895
0
        } else if (tokenizer.code_point == '(') {
16896
          // Otherwise if tokenizer's code point is U+0028 (():
16897
          // Increment depth by 1.
16898
0
          depth++;
16899
          // If regexp position equals tokenizer's input's code point length -
16900
          // 1:
16901
0
          if (regexp_position == tokenizer.input.size() - 1) {
16902
            // Run process a tokenizing error given tokenizer, regexp start, and
16903
            // tokenizer's index.
16904
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16905
0
                    regexp_start, tokenizer.index)) {
16906
0
              return tl::unexpected(*process_error);
16907
0
            }
16908
            // Set error to true.
16909
0
            error = true;
16910
0
            break;
16911
0
          }
16912
          // Let temporary position be tokenizer's next index.
16913
0
          auto temporary_position = tokenizer.next_index;
16914
          // Run get the next code point given tokenizer.
16915
0
          tokenizer.get_next_code_point();
16916
0
          if (tokenizer.had_invalid_code_point()) {
16917
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16918
0
                    tokenizer.next_index, temporary_position)) {
16919
0
              return tl::unexpected(*process_error);
16920
0
            }
16921
0
            error = true;
16922
0
            break;
16923
0
          }
16924
          // If tokenizer's code point is not U+003F (?):
16925
0
          if (tokenizer.code_point != '?') {
16926
            // Run process a tokenizing error given tokenizer, regexp start, and
16927
            // tokenizer's index.
16928
0
            if (auto process_error = tokenizer.process_tokenizing_error(
16929
0
                    regexp_start, tokenizer.index)) {
16930
0
              return tl::unexpected(*process_error);
16931
0
            }
16932
            // Set error to true.
16933
0
            error = true;
16934
0
            break;
16935
0
          }
16936
          // Set tokenizer's next index to temporary position.
16937
0
          tokenizer.next_index = temporary_position;
16938
0
        }
16939
        // Set regexp position to tokenizer's next index.
16940
0
        regexp_position = tokenizer.next_index;
16941
0
      }
16942
16943
      // If error is true continue.
16944
0
      if (error) continue;
16945
      // If depth is not zero:
16946
0
      if (depth != 0) {
16947
        // Run process a tokenizing error given tokenizer, regexp start, and
16948
        // tokenizer's index.
16949
0
        if (auto process_error = tokenizer.process_tokenizing_error(
16950
0
                regexp_start, tokenizer.index)) {
16951
0
          return tl::unexpected(*process_error);
16952
0
        }
16953
0
        continue;
16954
0
      }
16955
      // Let regexp length be regexp position - regexp start - 1.
16956
0
      auto regexp_length = regexp_position - regexp_start - 1;
16957
      // If regexp length is zero:
16958
0
      if (regexp_length == 0) {
16959
        // Run process a tokenizing error given tokenizer, regexp start, and
16960
        // tokenizer's index.
16961
0
        if (auto process_error = tokenizer.process_tokenizing_error(
16962
0
                regexp_start, tokenizer.index)) {
16963
0
          ada_log("process_tokenizing_error failed");
16964
0
          return tl::unexpected(*process_error);
16965
0
        }
16966
0
        continue;
16967
0
      }
16968
      // Run add a token given tokenizer, "regexp", regexp position, regexp
16969
      // start, and regexp length.
16970
0
      tokenizer.add_token(token_type::REGEXP, regexp_position, regexp_start,
16971
0
                          regexp_length);
16972
0
      continue;
16973
0
    }
16974
    // Run add a token with default position and length given tokenizer and
16975
    // "char".
16976
0
    tokenizer.add_token_with_defaults(token_type::CHAR);
16977
0
  }
16978
  // Run add a token with default length given tokenizer, "end", tokenizer's
16979
  // index, and tokenizer's index.
16980
0
  tokenizer.add_token_with_default_length(token_type::END, tokenizer.index,
16981
0
                                          tokenizer.index);
16982
16983
0
  ada_log("tokenizer.token_list size is: ", tokenizer.token_list.size());
16984
  // Return tokenizer's token list.
16985
0
  return tokenizer.token_list;
16986
0
}
16987
16988
namespace {
16989
constexpr std::array<uint8_t, 256> escape_pattern_table = []() consteval {
16990
  std::array<uint8_t, 256> out{};
16991
  for (auto& c : {'+', '*', '?', ':', '{', '}', '(', ')', '\\'}) {
16992
    out[c] = 1;
16993
  }
16994
  return out;
16995
}();
16996
16997
0
constexpr bool should_escape_pattern_char(char c) {
16998
0
  return escape_pattern_table[static_cast<uint8_t>(c)];
16999
0
}
17000
}  // namespace
17001
17002
0
std::string escape_pattern_string(std::string_view input) {
17003
0
  ada_log("escape_pattern_string called with input=", input);
17004
0
  if (input.empty()) [[unlikely]] {
17005
0
    return "";
17006
0
  }
17007
  // Assert: input is an ASCII string.
17008
0
  ADA_ASSERT_TRUE(ada::idna::is_ascii(input));
17009
  // Let result be the empty string.
17010
0
  std::string result{};
17011
  // Reserve extra space for potential escapes
17012
0
  result.reserve(input.size() * 2);
17013
17014
  // While index is less than input's length:
17015
0
  for (const char c : input) {
17016
0
    if (should_escape_pattern_char(c)) {
17017
      // Append U+005C (\) to the end of result.
17018
0
      result.push_back('\\');
17019
0
    }
17020
    // Append c to the end of result.
17021
0
    result.push_back(c);
17022
0
  }
17023
  // Return result.
17024
0
  return result;
17025
0
}
17026
17027
namespace {
17028
constexpr std::array<uint8_t, 256> escape_regexp_table = []() consteval {
17029
  std::array<uint8_t, 256> out{};
17030
  for (auto& c : {'.', '+', '*', '?', '^', '$', '{', '}', '(', ')', '[', ']',
17031
                  '|', '/', '\\'}) {
17032
    out[c] = 1;
17033
  }
17034
  return out;
17035
}();
17036
17037
0
constexpr bool should_escape_regexp_char(char c) {
17038
0
  return escape_regexp_table[(uint8_t)c];
17039
0
}
17040
}  // namespace
17041
17042
0
std::string escape_regexp_string(std::string_view input) {
17043
  // Assert: input is an ASCII string.
17044
0
  ADA_ASSERT_TRUE(idna::is_ascii(input));
17045
  // Let result be the empty string.
17046
0
  std::string result{};
17047
  // Reserve extra space for potential escapes (worst case: all chars escaped)
17048
0
  result.reserve(input.size() * 2);
17049
0
  for (const char c : input) {
17050
0
    if (should_escape_regexp_char(c)) {
17051
      // Avoid temporary string allocation - directly append characters
17052
0
      result.push_back('\\');
17053
0
      result.push_back(c);
17054
0
    } else {
17055
0
      result.push_back(c);
17056
0
    }
17057
0
  }
17058
0
  return result;
17059
0
}
17060
17061
std::string process_base_url_string(std::string_view input,
17062
0
                                    url_pattern_init::process_type type) {
17063
  // If type is not "pattern" return input.
17064
0
  if (type != url_pattern_init::process_type::pattern) {
17065
0
    return std::string(input);
17066
0
  }
17067
  // Return the result of escaping a pattern string given input.
17068
0
  return escape_pattern_string(input);
17069
0
}
17070
17071
constexpr bool is_absolute_pathname(
17072
0
    std::string_view input, url_pattern_init::process_type type) noexcept {
17073
  // If input is the empty string, then return false.
17074
0
  if (input.empty()) [[unlikely]] {
17075
0
    return false;
17076
0
  }
17077
  // If input[0] is U+002F (/), then return true.
17078
0
  if (input.starts_with("/")) return true;
17079
  // If type is "url", then return false.
17080
0
  if (type == url_pattern_init::process_type::url) return false;
17081
  // If input's code point length is less than 2, then return false.
17082
0
  if (input.size() < 2) return false;
17083
  // If input[0] is U+005C (\) and input[1] is U+002F (/), then return true.
17084
  // If input[0] is U+007B ({) and input[1] is U+002F (/), then return true.
17085
  // Return false.
17086
0
  return input[1] == '/' && (input[0] == '\\' || input[0] == '{');
17087
0
}
17088
17089
std::string generate_pattern_string(
17090
    std::vector<url_pattern_part>& part_list,
17091
0
    url_pattern_compile_component_options& options) {
17092
  // Let result be the empty string.
17093
0
  std::string result{};
17094
  // Let index list be the result of getting the indices for part list.
17095
  // For each index of index list:
17096
0
  for (size_t index = 0; index < part_list.size(); index++) {
17097
    // Let part be part list[index].
17098
    // Use reference to avoid copy
17099
0
    const auto& part = part_list[index];
17100
    // Let previous part be part list[index - 1] if index is greater than 0,
17101
    // otherwise let it be null.
17102
    // Use pointer to avoid copy
17103
0
    const url_pattern_part* previous_part =
17104
0
        index == 0 ? nullptr : &part_list[index - 1];
17105
    // Let next part be part list[index + 1] if index is less than index list's
17106
    // size - 1, otherwise let it be null.
17107
0
    const url_pattern_part* next_part =
17108
0
        index < part_list.size() - 1 ? &part_list[index + 1] : nullptr;
17109
    // If part's type is "fixed-text" then:
17110
0
    if (part.type == url_pattern_part_type::FIXED_TEXT) {
17111
      // If part's modifier is "none" then:
17112
0
      if (part.modifier == url_pattern_part_modifier::none) {
17113
        // Append the result of running escape a pattern string given part's
17114
        // value to the end of result.
17115
0
        result.append(escape_pattern_string(part.value));
17116
0
        continue;
17117
0
      }
17118
      // Append "{" to the end of result.
17119
0
      result += "{";
17120
      // Append the result of running escape a pattern string given part's value
17121
      // to the end of result.
17122
0
      result.append(escape_pattern_string(part.value));
17123
      // Append "}" to the end of result.
17124
0
      result += "}";
17125
      // Append the result of running convert a modifier to a string given
17126
      // part's modifier to the end of result.
17127
0
      result.append(convert_modifier_to_string(part.modifier));
17128
0
      continue;
17129
0
    }
17130
    // Let custom name be true if part's name[0] is not an ASCII digit;
17131
    // otherwise false.
17132
0
    bool custom_name = !unicode::is_ascii_digit(part.name[0]);
17133
    // Let needs grouping be true if at least one of the following are true,
17134
    // otherwise let it be false:
17135
    // - part's suffix is not the empty string.
17136
    // - part's prefix is not the empty string and is not options's prefix code
17137
    // point.
17138
0
    bool needs_grouping =
17139
0
        !part.suffix.empty() ||
17140
0
        (!part.prefix.empty() && (options.get_prefix().empty() ||
17141
0
                                  part.prefix[0] != options.get_prefix()[0]));
17142
17143
    // If all of the following are true:
17144
    // - needs grouping is false; and
17145
    // - custom name is true; and
17146
    // - part's type is "segment-wildcard"; and
17147
    // - part's modifier is "none"; and
17148
    // - next part is not null; and
17149
    // - next part's prefix is the empty string; and
17150
    // - next part's suffix is the empty string
17151
0
    if (!needs_grouping && custom_name &&
17152
0
        part.type == url_pattern_part_type::SEGMENT_WILDCARD &&
17153
0
        part.modifier == url_pattern_part_modifier::none && next_part &&
17154
0
        next_part->prefix.empty() && next_part->suffix.empty()) {
17155
      // If next part's type is "fixed-text":
17156
0
      if (next_part->type == url_pattern_part_type::FIXED_TEXT) {
17157
        // Set needs grouping to true if the result of running is a valid name
17158
        // code point given next part's value's first code point and the boolean
17159
        // false is true.
17160
0
        if (idna::valid_name_code_point(next_part->value[0], false)) {
17161
0
          needs_grouping = true;
17162
0
        }
17163
0
      } else {
17164
        // Set needs grouping to true if next part's name[0] is an ASCII digit.
17165
0
        needs_grouping = !next_part->name.empty() &&
17166
0
                         unicode::is_ascii_digit(next_part->name[0]);
17167
0
      }
17168
0
    }
17169
17170
    // If all of the following are true:
17171
    // - needs grouping is false; and
17172
    // - part's prefix is the empty string; and
17173
    // - previous part is not null; and
17174
    // - previous part's type is "fixed-text"; and
17175
    // - previous part's value's last code point is options's prefix code point.
17176
    // then set needs grouping to true.
17177
0
    if (!needs_grouping && part.prefix.empty() && previous_part &&
17178
0
        previous_part->type == url_pattern_part_type::FIXED_TEXT &&
17179
0
        !previous_part->value.empty() && !options.get_prefix().empty() &&
17180
0
        previous_part->value.back() == options.get_prefix()[0]) {
17181
0
      needs_grouping = true;
17182
0
    }
17183
17184
    // Assert: part's name is not the empty string or null.
17185
0
    ADA_ASSERT_TRUE(!part.name.empty());
17186
17187
    // If needs grouping is true, then append "{" to the end of result.
17188
0
    if (needs_grouping) {
17189
0
      result.append("{");
17190
0
    }
17191
17192
    // Append the result of running escape a pattern string given part's prefix
17193
    // to the end of result.
17194
0
    result.append(escape_pattern_string(part.prefix));
17195
17196
    // If custom name is true:
17197
0
    if (custom_name) {
17198
      // Append ":" to the end of result.
17199
0
      result.append(":");
17200
      // Append part's name to the end of result.
17201
0
      result.append(part.name);
17202
0
    }
17203
17204
    // If part's type is "regexp" then:
17205
0
    if (part.type == url_pattern_part_type::REGEXP) {
17206
      // Append "(" to the end of result.
17207
0
      result.append("(");
17208
      // Append part's value to the end of result.
17209
0
      result.append(part.value);
17210
      // Append ")" to the end of result.
17211
0
      result.append(")");
17212
0
    } else if (part.type == url_pattern_part_type::SEGMENT_WILDCARD &&
17213
0
               !custom_name) {
17214
      // Otherwise if part's type is "segment-wildcard" and custom name is
17215
      // false: Append "(" to the end of result.
17216
0
      result.append("(");
17217
      // Append the result of running generate a segment wildcard regexp given
17218
      // options to the end of result.
17219
0
      result.append(generate_segment_wildcard_regexp(options));
17220
      // Append ")" to the end of result.
17221
0
      result.append(")");
17222
0
    } else if (part.type == url_pattern_part_type::FULL_WILDCARD) {
17223
      // Otherwise if part's type is "full-wildcard":
17224
      // If custom name is false and one of the following is true:
17225
      // - previous part is null; or
17226
      // - previous part's type is "fixed-text"; or
17227
      // - previous part's modifier is not "none"; or
17228
      // - needs grouping is true; or
17229
      // - part's prefix is not the empty string
17230
      // - then append "*" to the end of result.
17231
0
      if (!custom_name &&
17232
0
          (!previous_part ||
17233
0
           previous_part->type == url_pattern_part_type::FIXED_TEXT ||
17234
0
           previous_part->modifier != url_pattern_part_modifier::none ||
17235
0
           needs_grouping || !part.prefix.empty())) {
17236
0
        result.append("*");
17237
0
      } else {
17238
        // Append "(" to the end of result.
17239
        // Append full wildcard regexp value to the end of result.
17240
        // Append ")" to the end of result.
17241
0
        result.append("(.*)");
17242
0
      }
17243
0
    }
17244
17245
    // If all of the following are true:
17246
    // - part's type is "segment-wildcard"; and
17247
    // - custom name is true; and
17248
    // - part's suffix is not the empty string; and
17249
    // - The result of running is a valid name code point given part's suffix's
17250
    // first code point and the boolean false is true then append U+005C (\) to
17251
    // the end of result.
17252
0
    if (part.type == url_pattern_part_type::SEGMENT_WILDCARD && custom_name &&
17253
0
        !part.suffix.empty() &&
17254
0
        idna::valid_name_code_point(part.suffix[0], false)) {
17255
0
      result.append("\\");
17256
0
    }
17257
17258
    // Append the result of running escape a pattern string given part's suffix
17259
    // to the end of result.
17260
0
    result.append(escape_pattern_string(part.suffix));
17261
    // If needs grouping is true, then append "}" to the end of result.
17262
0
    if (needs_grouping) result.append("}");
17263
    // Append the result of running convert a modifier to a string given part's
17264
    // modifier to the end of result.
17265
0
    result.append(convert_modifier_to_string(part.modifier));
17266
0
  }
17267
  // Return result.
17268
0
  return result;
17269
0
}
17270
}  // namespace ada::url_pattern_helpers
17271
17272
#endif  // ADA_INCLUDE_URL_PATTERN
17273
/* end file src/url_pattern_helpers.cpp */
17274
/* begin file src/url_pattern_regex.cpp */
17275
#if ADA_INCLUDE_URL_PATTERN
17276
17277
17278
#ifdef ADA_USE_UNSAFE_STD_REGEX_PROVIDER
17279
#include <cstddef>
17280
#include <optional>
17281
#include <regex>
17282
#include <string>
17283
#include <string_view>
17284
#include <vector>
17285
#endif  // ADA_USE_UNSAFE_STD_REGEX_PROVIDER
17286
17287
namespace ada::url_pattern_regex {
17288
17289
#ifdef ADA_USE_UNSAFE_STD_REGEX_PROVIDER
17290
std::optional<std::regex> std_regex_provider::create_instance(
17291
    std::string_view pattern, bool ignore_case) {
17292
  // Let flags be an empty string.
17293
  // If options's ignore case is true then set flags to "vi".
17294
  // Otherwise set flags to "v"
17295
  auto flags = ignore_case
17296
                   ? std::regex::icase | std::regex_constants::ECMAScript
17297
                   : std::regex_constants::ECMAScript;
17298
  try {
17299
    return std::regex(pattern.data(), pattern.size(), flags);
17300
  } catch (const std::regex_error& e) {
17301
    (void)e;
17302
    ada_log("std_regex_provider::create_instance failed:", e.what());
17303
    return std::nullopt;
17304
  }
17305
}
17306
17307
std::optional<std::vector<std::optional<std::string>>>
17308
std_regex_provider::regex_search(std::string_view input,
17309
                                 const std::regex& pattern) {
17310
  // Use iterator-based regex_search to avoid string allocation
17311
  std::match_results<std::string_view::const_iterator> match_result;
17312
  try {
17313
    if (!std::regex_search(input.begin(), input.end(), match_result, pattern,
17314
                           std::regex_constants::match_any)) {
17315
      return std::nullopt;
17316
    }
17317
  } catch (const std::regex_error& e) {
17318
    (void)e;
17319
    ada_log("std_regex_provider::regex_search failed:", e.what());
17320
    return std::nullopt;
17321
  }
17322
  std::vector<std::optional<std::string>> matches;
17323
  // An empty input can still match with capture groups (e.g. "(x*)" or an
17324
  // optional ":a?" against ""), so the group values must be extracted here
17325
  // just like for a non-empty input. A successful regex_search always leaves
17326
  // the full match at index 0, so match_result is never empty at this point.
17327
  if (match_result.empty()) {
17328
    return matches;
17329
  }
17330
  matches.reserve(match_result.size());
17331
  for (size_t i = 1; i < match_result.size(); ++i) {
17332
    if (auto entry = match_result[i]; entry.matched) {
17333
      matches.emplace_back(entry.str());
17334
    } else {
17335
      // A capture group that did not participate in the match is undefined,
17336
      // not absent. Emitting nullopt keeps the result aligned by position with
17337
      // the component's group name list; dropping it shifts every later group
17338
      // onto the wrong name.
17339
      matches.emplace_back(std::nullopt);
17340
    }
17341
  }
17342
  return matches;
17343
}
17344
17345
bool std_regex_provider::regex_match(std::string_view input,
17346
                                     const std::regex& pattern) {
17347
  try {
17348
    return std::regex_match(input.begin(), input.end(), pattern);
17349
  } catch (const std::regex_error& e) {
17350
    (void)e;
17351
    ada_log("std_regex_provider::regex_match failed:", e.what());
17352
    return false;
17353
  }
17354
}
17355
17356
#endif  // ADA_USE_UNSAFE_STD_REGEX_PROVIDER
17357
17358
}  // namespace ada::url_pattern_regex
17359
17360
#endif  // ADA_INCLUDE_URL_PATTERN
17361
/* end file src/url_pattern_regex.cpp */
17362
#if !defined(ADA_URL_PATTERN_LIST_SEPARATE_TU)
17363
/* begin file src/url_pattern_list.cpp */
17364
/**
17365
 * @file url_pattern_list.cpp
17366
 * @brief Route-set compiler backing ada::url_pattern_list.
17367
 *
17368
 * The provider-independent build side: classification of URLPattern part
17369
 * lists into pattern segments, the compiler (segment trie, per-node dispatch,
17370
 * auxiliary-route pruning), the arena packing, and the sequential reference
17371
 * matcher used beyond the fast-path limits. The matcher itself is inline in
17372
 * url_pattern_list-inl.h.
17373
 *
17374
 * Every dispatch decision is made at build time so that the per-request
17375
 * residual is a segment scan and a trie walk with bounded backtracking.
17376
 * Offline searches (witness plans, perfect multipliers) that fail demote the
17377
 * affected node to a linear scan: slower, never incorrect.
17378
 */
17379
/* begin file src/url_pattern_list_compiler.h */
17380
/**
17381
 * @file url_pattern_list_compiler.h
17382
 * @brief The url_pattern_list route-set compiler: pattern classification and
17383
 * the build-time table construction behind ada::parse_url_pattern_list.
17384
 *
17385
 * This header is NOT part of the public API and is not included from ada.h:
17386
 * only src/url_pattern_list.cpp (and, through the amalgamated ada.cpp, the
17387
 * url_pattern_list fuzzer) include it. The matcher-visible table layout it
17388
 * produces is declared in include/ada/url_pattern_list.h.
17389
 */
17390
#ifndef ADA_URL_PATTERN_LIST_COMPILER_H
17391
#define ADA_URL_PATTERN_LIST_COMPILER_H
17392
17393
17394
#include <cstddef>
17395
#include <cstdint>
17396
#include <string>
17397
#include <vector>
17398
17399
#if ADA_INCLUDE_URL_PATTERN
17400
namespace ada::url_pattern_list_compiler {
17401
17402
/**
17403
 * Maximum number of entries a perfect-hash dispatch table may index (slot
17404
 * ordinals are 8-bit, with 0xFF reserved for "empty"). Nodes with a larger
17405
 * static fanout are demoted to a linear scan: slower, never incorrect.
17406
 */
17407
inline constexpr uint32_t max_dispatch_table_entries = 254;
17408
17409
/**
17410
 * Static fanout up to which a node compares its children directly, in
17411
 * turn; wider nodes dispatch through a projection table. Measured on a
17412
 * synthetic node hit uniformly: direct compares beat the projection by
17413
 * about 1 ns for keys of varied length up to about 12 children, while for
17414
 * keys of one length (which the length gate cannot reject) the projection
17415
 * wins by 4-5 ns at every fanout and by more on misses, because the direct
17416
 * loop's exit is unpredictable. Eight keeps the first case and bounds the
17417
 * second.
17418
 */
17419
inline constexpr uint32_t max_direct_children = 8;
17420
17421
/**
17422
 * The kind of one compiled pattern segment. The numeric values define match
17423
 * priority: at the first differing segment, a literal beats a ":param" and a
17424
 * ":param" beats a "*" (find-my-way / Express-compatible specificity order).
17425
 */
17426
enum class segment_kind : uint8_t {
17427
  literal = 0,
17428
  param = 1,
17429
  wildcard = 2,
17430
};
17431
17432
/**
17433
 * One '/'-separated segment of a compiled pattern: a literal text (already
17434
 * canonicalized by the URLPattern pattern parser), a ":param" (text = group
17435
 * name), or a trailing "*" wildcard.
17436
 */
17437
struct route_segment {
17438
  segment_kind kind = segment_kind::literal;
17439
  std::string text{};
17440
};
17441
17442
/**
17443
 * Everything the compiler knows about one route. `kind_sequence` packs the
17444
 * per-segment kinds two bits per segment, most significant first, so that
17445
 * comparing (kind_sequence, kind_length, route index) as a tuple is exactly
17446
 * the documented specificity order. For regexp-mode routes, `segments`
17447
 * holds only the anchored literal prefix (the leading segments that are
17448
 * whole fixed text, closed by a '/'), which the auxiliary-route pruning
17449
 * uses to rule out routes that can never match the same input.
17450
 */
17451
struct route_info {
17452
  std::vector<route_segment> segments{};
17453
  // Capture group names, in capture order (params left to right, then the
17454
  // wildcard group). Regexp-mode routes: filled from the compiled component.
17455
  std::vector<std::string> group_names{};
17456
  uint64_t kind_sequence = 0;
17457
  uint8_t kind_length = 0;
17458
  url_pattern_list_detail::route_mode mode =
17459
      url_pattern_list_detail::route_mode::sequential;
17460
  bool has_wildcard = false;
17461
  bool all_literal = false;
17462
};
17463
17464
/**
17465
 * Classifies a URLPattern part list into '/'-separated pattern segments.
17466
 * Returns true when the pattern is expressible in the static/":param"/"*"
17467
 * subset (every segment wholly a literal, a param, or a final wildcard);
17468
 * `segments` and `group_names` are only valid on success.
17469
 */
17470
bool classify_parts(const std::vector<url_pattern_part>& parts,
17471
                    std::vector<route_segment>& segments,
17472
                    std::vector<std::string>& group_names);
17473
17474
/**
17475
 * Computes kind sequence and flags from route.segments and decides the
17476
 * route's mode: trie when every fast-path build limit is met, sequential
17477
 * otherwise (the empty pattern, more than max_trie_pattern_segments
17478
 * segments, or more than max_captures_per_route capture groups).
17479
 */
17480
void finalize_route(route_info& route) noexcept;
17481
17482
/**
17483
 * Best-effort kind sequence for a route that needs regexp matching, so it can
17484
 * participate in the specificity order: custom "(...)" groups count as params,
17485
 * full wildcards and modified ("?", "+", "*") groups terminate the sequence as
17486
 * a wildcard tail. This mapping is an approximation and is called out as an
17487
 * open question in the class documentation. Also records the route's
17488
 * anchored literal prefix in route.segments and sets mode = regexp.
17489
 */
17490
void approximate_kind_sequence(const std::vector<url_pattern_part>& parts,
17491
                               route_info& route);
17492
17493
/**
17494
 * True when route `a` (at insertion index `a_index`) outranks route `b`.
17495
 */
17496
constexpr bool route_outranks(const route_info& a, size_t a_index,
17497
0
                              const route_info& b, size_t b_index) noexcept {
17498
0
  return url_pattern_list_detail::outranks(a.kind_sequence, a.kind_length,
17499
0
                                           a_index, b.kind_sequence,
17500
0
                                           b.kind_length, b_index);
17501
0
}
17502
17503
/**
17504
 * Compiles the route set: builds the trie and its dispatch plans over the
17505
 * trie-mode routes, the segment table, the auxiliary-route table with its
17506
 * per-route challenger ranges, and packs everything into one arena. Never
17507
 * fails: any node whose offline search fails is demoted to a slower but
17508
 * correct plan.
17509
 * Literal texts are used as given (the caller has already case-folded them
17510
 * when ignore_case is set).
17511
 */
17512
url_pattern_list_detail::compiled_routes compile_route_set(
17513
    std::vector<route_info>& routes);
17514
17515
}  // namespace ada::url_pattern_list_compiler
17516
#endif  // ADA_INCLUDE_URL_PATTERN
17517
#endif  // ADA_URL_PATTERN_LIST_COMPILER_H
17518
/* end file src/url_pattern_list_compiler.h */
17519
17520
#include <algorithm>
17521
#include <array>
17522
#include <bit>
17523
#include <cstdint>
17524
#include <cstring>
17525
#include <limits>
17526
#include <span>
17527
#include <string_view>
17528
#include <utility>
17529
#include <vector>
17530
17531
#if ADA_INCLUDE_URL_PATTERN
17532
17533
namespace ada::url_pattern_list_compiler {
17534
17535
namespace {
17536
17537
using url_pattern_list_detail::compiled_routes;
17538
using url_pattern_list_detail::edge_record;
17539
using url_pattern_list_detail::hash_record;
17540
using url_pattern_list_detail::node_record;
17541
using url_pattern_list_detail::route_mode;
17542
using url_pattern_list_detail::route_record;
17543
using url_pattern_list_detail::segment_record;
17544
using url_pattern_list_limits::max_captures_per_route;
17545
using url_pattern_list_limits::max_trie_pattern_segments;
17546
17547
// The tables under construction, one vector per section; packed into the
17548
// single arena of compiled_routes at the end of the build.
17549
struct builder_tables {
17550
  std::vector<node_record> nodes{};
17551
  std::vector<hash_record> hashes{};
17552
  std::vector<edge_record> edges{};
17553
  std::vector<uint8_t> slots{};
17554
  std::vector<char> blob{};
17555
  std::vector<route_record> routes{};
17556
  std::vector<segment_record> segments{};
17557
  std::vector<uint32_t> aux{};
17558
  std::vector<uint16_t> root_index{};
17559
  uint32_t n_aux_all = 0;
17560
};
17561
17562
// Witness plan for single-string tables: nibbles 0..2 hold witness ids
17563
// (distinct ids first, remaining slots duplicating id 0 so the runtime
17564
// gather is fixed-shape and branch-free); bits 12..14 are metadata.
17565
constexpr uint16_t pack_witness_plan(const uint8_t* ids, uint32_t n_ids,
17566
0
                                     bool use_len) noexcept {
17567
0
  uint16_t w = 0;
17568
0
  for (uint32_t j = 0; j < 3; j++) {
17569
0
    w = static_cast<uint16_t>(
17570
0
        w | static_cast<uint16_t>((j < n_ids ? ids[j] : ids[0]) & 15u)
17571
0
                << (4 * j));
17572
0
  }
17573
0
  w = static_cast<uint16_t>(w | static_cast<uint16_t>(n_ids << 12));
17574
0
  if (use_len) {
17575
0
    w = static_cast<uint16_t>(w | static_cast<uint16_t>(1) << 14);
17576
0
  }
17577
0
  return w;
17578
0
}
17579
17580
// Bytes [from, min(from + 8, len)) of a key, packed little-endian and
17581
// zero-padded; the build-time twin of the matcher's window load.
17582
constexpr uint64_t pack_window_le(const char* p, uint32_t len,
17583
0
                                  uint32_t from) noexcept {
17584
0
  uint64_t x = 0;
17585
0
  for (uint32_t j = 0; j < 8 && from + j < len; j++) {
17586
0
    x |= static_cast<uint64_t>(static_cast<uint8_t>(p[from + j])) << (8 * j);
17587
0
  }
17588
0
  return x;
17589
0
}
17590
17591
// Deterministic RNG for the multiplier search (splitmix64).
17592
struct splitmix64 {
17593
  uint64_t state;
17594
0
  constexpr explicit splitmix64(uint64_t seed) noexcept : state(seed) {}
17595
0
  constexpr uint64_t next() noexcept {
17596
0
    uint64_t z = (state += 0x9E3779B97F4A7C15ull);
17597
0
    z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ull;
17598
0
    z = (z ^ (z >> 27)) * 0x94D049BB133111EBull;
17599
0
    return z ^ (z >> 31);
17600
0
  }
17601
};
17602
17603
struct transient_node {  // build-time trie (views into route segment storage)
17604
  std::vector<std::pair<std::string_view, int32_t>> kids{};
17605
  int32_t param = -1;
17606
  int32_t wild_route = -1;
17607
  int32_t terminal = -1;
17608
};
17609
17610
0
constexpr unsigned ceil_log2(size_t n) noexcept {
17611
0
  unsigned b = 0;
17612
0
  while ((size_t{1} << b) < n) {
17613
0
    b++;
17614
0
  }
17615
0
  return b;
17616
0
}
17617
17618
// Starting table size for n keys: load factor <= ~1/4, loosened as n grows
17619
// so the multiplier search still lands inside the budget.
17620
0
constexpr unsigned initial_slot_bits(size_t n) noexcept {
17621
0
  unsigned headroom = 1;
17622
0
  if (n > 64) {
17623
0
    headroom = 3;
17624
0
  } else if (n > 8) {
17625
0
    headroom = 2;
17626
0
  }
17627
0
  return ceil_log2(n) + headroom;
17628
0
}
17629
17630
bool find_multiplier(const std::vector<uint64_t>& proj, unsigned b0,
17631
0
                     uint64_t& multiplier_out, uint8_t& bits_out) {
17632
0
  const size_t n = proj.size();
17633
0
  for (unsigned b = b0; b <= 12; b++) {
17634
0
    std::vector<uint32_t> stamp(size_t{1} << b, 0);
17635
0
    splitmix64 rng(0x14C0FFEEull + b);
17636
0
    for (uint32_t t = 1; t <= 4000; t++) {
17637
0
      const uint64_t m = rng.next() | 1;
17638
0
      bool ok = true;
17639
0
      for (size_t i = 0; i < n; i++) {
17640
0
        const uint64_t s = (proj[i] * m) >> (64 - b);
17641
0
        if (stamp[s] == t) {
17642
0
          ok = false;
17643
0
          break;
17644
0
        }
17645
0
        stamp[s] = t;
17646
0
      }
17647
0
      if (ok) {
17648
0
        multiplier_out = m;
17649
0
        bits_out = static_cast<uint8_t>(b);
17650
0
        return true;
17651
0
      }
17652
0
    }
17653
0
  }
17654
0
  return false;
17655
0
}
17656
17657
// Emits a perfect-hash slot table for `proj` at the end of `slots`. Returns
17658
// false if the search failed, in which case nothing was appended and the
17659
// caller demotes that table to a linear scan.
17660
bool emit_slot_table(const std::vector<uint64_t>& proj,
17661
                     std::vector<uint8_t>& slots, uint64_t& multiplier_out,
17662
0
                     uint8_t& bits_out, uint32_t& base_out) {
17663
0
  if (!find_multiplier(proj, initial_slot_bits(proj.size()), multiplier_out,
17664
0
                       bits_out)) {
17665
0
    return false;
17666
0
  }
17667
0
  base_out = static_cast<uint32_t>(slots.size());
17668
0
  slots.resize(slots.size() + (size_t{1} << bits_out), 0xFF);
17669
0
  for (size_t i = 0; i < proj.size(); i++) {
17670
0
    slots[base_out +
17671
0
          url_pattern_list_detail::slot_of(proj[i], multiplier_out, bits_out)] =
17672
0
        static_cast<uint8_t>(i);
17673
0
  }
17674
0
  return true;
17675
0
}
17676
17677
// Advances `c` to the next k-combination of {0..n-1} in lexicographic
17678
// order; false once the last one has been visited.
17679
template <size_t N>
17680
constexpr bool next_combination(std::array<uint32_t, N>& c, uint32_t k,
17681
0
                                uint32_t n) noexcept {
17682
0
  int32_t j = static_cast<int32_t>(k) - 1;
17683
0
  while (j >= 0 &&
17684
0
         c[static_cast<uint32_t>(j)] == n - k + static_cast<uint32_t>(j)) {
17685
0
    j--;
17686
0
  }
17687
0
  if (j < 0) {
17688
0
    return false;
17689
0
  }
17690
0
  c[static_cast<uint32_t>(j)]++;
17691
0
  for (uint32_t t = static_cast<uint32_t>(j) + 1; t < k; t++) {
17692
0
    c[t] = c[t - 1] + 1;
17693
0
  }
17694
0
  return true;
17695
0
}
17696
17697
// Witness-subset search over the given id alphabet, cost-ordered: fewest
17698
// distinct witness ids first (the length is always packed -- it is free).
17699
// The first injective subset wins.
17700
bool find_witness_plan(
17701
    const std::vector<std::pair<std::string_view, int32_t>>& kids,
17702
    const uint8_t* alphabet, uint32_t n_alpha, uint32_t max_reads,
17703
0
    uint16_t& plan_out) {
17704
0
  const size_t n = kids.size();
17705
0
  auto injective = [&](uint16_t wp) {  // sort + adjacent compare
17706
0
    std::vector<uint64_t> proj(n);
17707
0
    for (size_t i = 0; i < n; i++) {
17708
0
      proj[i] = url_pattern_list_detail::project(
17709
0
          kids[i].first.data(), static_cast<uint32_t>(kids[i].first.size()),
17710
0
          wp);
17711
0
    }
17712
0
    std::sort(proj.begin(), proj.end());
17713
0
    for (size_t i = 1; i < n; i++) {
17714
0
      if (proj[i] == proj[i - 1]) {
17715
0
        return false;
17716
0
      }
17717
0
    }
17718
0
    return true;
17719
0
  };
17720
0
  for (uint32_t k = 1; k <= max_reads && k <= n_alpha; k++) {
17721
0
    std::array<uint32_t, 3> c{0, 1, 2};
17722
0
    do {
17723
0
      uint8_t ids[3] = {0, 0, 0};
17724
0
      for (uint32_t j = 0; j < k; j++) {
17725
0
        ids[j] = alphabet[c[j]];
17726
0
      }
17727
0
      const uint16_t wp = pack_witness_plan(ids, k, true);
17728
0
      if (injective(wp)) {
17729
0
        plan_out = wp;
17730
0
        return true;
17731
0
      }
17732
0
    } while (next_combination(c, k, n_alpha));
17733
0
  }
17734
0
  return false;
17735
0
}
17736
17737
// ---- build stages ----------------------------------------------------------
17738
17739
// Segment trie over the trie-mode routes. Priority is resolved here, at
17740
// build, into each node's fixed decision order (static children -> param ->
17741
// wildcard); a DFS in that order returns the match with the
17742
// lexicographically minimal kind sequence. Duplicate patterns collapse onto
17743
// one slot: an occupied slot is never overwritten, so the smallest route
17744
// index survives.
17745
0
std::vector<transient_node> build_trie(const std::vector<route_info>& routes) {
17746
0
  std::vector<transient_node> t(1);
17747
0
  for (size_t i = 0; i < routes.size(); i++) {
17748
0
    const route_info& rt = routes[i];
17749
0
    if (rt.mode != route_mode::trie) {
17750
0
      continue;
17751
0
    }
17752
0
    int32_t cur = 0;
17753
0
    for (const route_segment& ps : rt.segments) {
17754
0
      if (ps.kind == segment_kind::literal) {
17755
0
        int32_t nxt = -1;
17756
0
        for (auto& kv : t[static_cast<size_t>(cur)].kids) {
17757
0
          if (kv.first == ps.text) {
17758
0
            nxt = kv.second;
17759
0
            break;
17760
0
          }
17761
0
        }
17762
0
        if (nxt < 0) {
17763
0
          nxt = static_cast<int32_t>(t.size());
17764
0
          t[static_cast<size_t>(cur)].kids.emplace_back(ps.text, nxt);
17765
0
          t.emplace_back();
17766
0
        }
17767
0
        cur = nxt;
17768
0
      } else if (ps.kind == segment_kind::param) {
17769
0
        if (t[static_cast<size_t>(cur)].param < 0) {
17770
0
          t[static_cast<size_t>(cur)].param = static_cast<int32_t>(t.size());
17771
0
          t.emplace_back();
17772
0
        }
17773
0
        cur = t[static_cast<size_t>(cur)].param;
17774
0
      } else {  // wildcard (classification guarantees final)
17775
0
        if (t[static_cast<size_t>(cur)].wild_route < 0) {
17776
0
          t[static_cast<size_t>(cur)].wild_route = static_cast<int32_t>(i);
17777
0
        }
17778
0
        cur = -1;
17779
0
        break;
17780
0
      }
17781
0
    }
17782
0
    if (cur >= 0 && t[static_cast<size_t>(cur)].terminal < 0) {
17783
0
      t[static_cast<size_t>(cur)].terminal = static_cast<int32_t>(i);
17784
0
    }
17785
0
  }
17786
  // The root's children are sorted by first byte so that the first-byte
17787
  // index can address each run of same-byte children as one contiguous
17788
  // block of edges.
17789
0
  std::stable_sort(
17790
0
      t[0].kids.begin(), t[0].kids.end(), [](const auto& a, const auto& b) {
17791
0
        const int ka = a.first.empty() ? -1 : static_cast<uint8_t>(a.first[0]);
17792
0
        const int kb = b.first.empty() ? -1 : static_cast<uint8_t>(b.first[0]);
17793
0
        return ka < kb;
17794
0
      });
17795
0
  return t;
17796
0
}
17797
17798
// Per-route records: priority data, capture positions (so extracting params
17799
// at match time is a fixed walk over param_positions), regexp ordinals.
17800
void compile_route_records(builder_tables& r,
17801
0
                           const std::vector<route_info>& routes) {
17802
0
  r.routes.resize(routes.size());
17803
0
  int32_t n_regexp = 0;
17804
0
  for (size_t i = 0; i < routes.size(); i++) {
17805
0
    const route_info& rt = routes[i];
17806
0
    route_record& rm = r.routes[i];
17807
0
    rm.kind_sequence = rt.kind_sequence;
17808
0
    rm.kind_length = rt.kind_length;
17809
0
    rm.mode = rt.mode;
17810
0
    rm.wild = rt.has_wildcard ? 1 : 0;
17811
0
    if (rt.mode == route_mode::regexp) {
17812
0
      rm.regexp_component = n_regexp++;
17813
0
      continue;
17814
0
    }
17815
0
    if (rt.mode != route_mode::trie) {
17816
0
      continue;  // capture positions are only read for trie-answered routes
17817
0
    }
17818
0
    for (size_t s = 0; s < rt.segments.size(); s++) {
17819
0
      if (rt.segments[s].kind == segment_kind::param) {
17820
        // Classification guarantees n_params <= max_captures_per_route for
17821
        // trie-mode routes.
17822
0
        rm.param_positions[rm.n_params++] = static_cast<uint8_t>(s);
17823
0
      }
17824
0
    }
17825
0
  }
17826
0
}
17827
17828
// BFS layout: assign final node ids breadth-first so each node's static
17829
// children occupy a contiguous block of edges[]. Returns the transient-node
17830
// id per final id.
17831
std::vector<int32_t> layout_nodes(builder_tables& r,
17832
0
                                  const std::vector<transient_node>& t) {
17833
0
  std::vector<int32_t> order;  // transient id per final id
17834
0
  order.push_back(0);
17835
0
  r.nodes.resize(1);
17836
0
  for (size_t head = 0; head < order.size(); head++) {
17837
0
    const transient_node& tn = t[static_cast<size_t>(order[head])];
17838
0
    node_record nd{};
17839
0
    nd.wild_route = tn.wild_route;
17840
0
    nd.terminal_route = tn.terminal;
17841
0
    nd.first_child = static_cast<int32_t>(r.edges.size());
17842
0
    nd.n_static = static_cast<uint16_t>(tn.kids.size());
17843
0
    const size_t id_base = order.size();  // children take the next BFS ids
17844
0
    for (size_t ci = 0; ci < tn.kids.size(); ci++) {
17845
0
      const std::string_view k = tn.kids[ci].first;
17846
0
      edge_record e{};
17847
0
      e.key_length = static_cast<uint16_t>(k.size());
17848
0
      e.key_offset = static_cast<uint32_t>(r.blob.size());
17849
0
      r.blob.insert(r.blob.end(), k.begin(), k.end());
17850
0
      e.prefix = pack_window_le(k.data(), static_cast<uint32_t>(k.size()), 0);
17851
0
      e.suffix = pack_window_le(
17852
0
          k.data(), static_cast<uint32_t>(k.size()),
17853
0
          k.size() >= 8 ? static_cast<uint32_t>(k.size()) - 8 : 0);
17854
0
      e.node = static_cast<int32_t>(id_base + ci);
17855
0
      r.edges.push_back(e);
17856
0
    }
17857
0
    for (size_t ci = 0; ci < tn.kids.size(); ci++) {
17858
0
      order.push_back(tn.kids[ci].second);
17859
0
    }
17860
0
    if (tn.param >= 0) {
17861
0
      nd.param_child = static_cast<int32_t>(order.size());
17862
0
      order.push_back(tn.param);
17863
0
    }
17864
0
    nd.has_alternative = (nd.param_child >= 0 || nd.wild_route >= 0) ? 1 : 0;
17865
0
    r.nodes.resize(order.size());
17866
0
    r.nodes[head] = nd;
17867
0
  }
17868
0
  return order;
17869
0
}
17870
17871
// Root first-byte index: a 256-entry table from the first byte of the
17872
// input's first segment to the first root child starting with it (the
17873
// children are sorted by first byte). Built for a root with at least three
17874
// children; a run of same-byte children longer than max_direct_children, or
17875
// an empty key, falls back to the regular ladder. Returns true when the
17876
// index was emitted.
17877
0
bool build_root_index(builder_tables& r, const transient_node& root) {
17878
0
  const size_t nk = root.kids.size();
17879
0
  if (nk < 3) {
17880
0
    return false;
17881
0
  }
17882
0
  std::array<uint16_t, 256> index{};
17883
0
  index.fill(0xFFFF);
17884
0
  std::array<uint32_t, 256> run{};
17885
0
  for (size_t ci = 0; ci < nk; ci++) {
17886
0
    if (root.kids[ci].first.empty()) {
17887
0
      return false;  // an empty key has no first byte: regular ladder
17888
0
    }
17889
0
    const uint8_t b = static_cast<uint8_t>(root.kids[ci].first[0]);
17890
0
    if (index[b] == 0xFFFF) {
17891
0
      index[b] = static_cast<uint16_t>(ci);
17892
0
    }
17893
0
    if (++run[b] > max_direct_children) {
17894
0
      return false;
17895
0
    }
17896
0
  }
17897
0
  r.root_index.assign(index.begin(), index.end());
17898
0
  return true;
17899
0
}
17900
17901
// Per-node dispatch ladder, chosen by static child count: 0 none, up to
17902
// max_direct_children direct compares, then projection over a restricted
17903
// alphabet (escalating to the full alphabet); linear demotion when a search
17904
// fails or when the fanout exceeds max_dispatch_table_entries. The root
17905
// gets the first-byte index when its fanout allows. Never incorrect, only
17906
// slower.
17907
void compile_dispatch(builder_tables& r, const std::vector<transient_node>& t,
17908
0
                      const std::vector<int32_t>& order) {
17909
0
  for (size_t ni = 0; ni < r.nodes.size(); ni++) {
17910
0
    node_record& nd = r.nodes[ni];
17911
0
    const transient_node& tn = t[static_cast<size_t>(order[ni])];
17912
0
    const size_t nk = tn.kids.size();
17913
0
    if (nk == 0) {
17914
0
      nd.dispatch = 0;
17915
0
      continue;
17916
0
    }
17917
0
    if (ni == 0 && build_root_index(r, tn)) {
17918
0
      nd.dispatch = 4;
17919
0
      continue;
17920
0
    }
17921
0
    if (nk <= max_direct_children) {
17922
0
      nd.dispatch = 1;
17923
0
      continue;
17924
0
    }
17925
0
    if (nk > max_dispatch_table_entries) {
17926
0
      nd.dispatch = 3;  // slot ordinals are 8-bit; linear scan stays correct
17927
0
      continue;
17928
0
    }
17929
0
    uint16_t wp = 0;
17930
0
    bool found = false;
17931
0
    if (nk <= 16) {
17932
0
      constexpr uint8_t alpha_small[2] = {0, 8};  // s[0], s[len - 1]
17933
0
      found = find_witness_plan(tn.kids, alpha_small, 2, 2, wp);
17934
0
    }
17935
0
    if (!found) {  // full alphabet (also the escalation path for <= 16)
17936
0
      uint8_t alpha_full[16] = {0, 1, 2,  3,  4,  5,  6,  7,
17937
0
                                8, 9, 10, 11, 12, 13, 14, 15};
17938
0
      found = find_witness_plan(tn.kids, alpha_full, 16, 3, wp);
17939
0
    }
17940
0
    hash_record h{};
17941
0
    if (found) {
17942
0
      std::vector<uint64_t> proj(nk);
17943
0
      for (size_t i = 0; i < nk; i++) {
17944
0
        proj[i] = url_pattern_list_detail::project(
17945
0
            tn.kids[i].first.data(),
17946
0
            static_cast<uint32_t>(tn.kids[i].first.size()), wp);
17947
0
      }
17948
0
      found = emit_slot_table(proj, r.slots, h.multiplier, h.slot_bits,
17949
0
                              h.slot_base);
17950
0
    }
17951
0
    if (!found) {
17952
0
      nd.dispatch = 3;  // demoted: correct, slower
17953
0
      continue;
17954
0
    }
17955
0
    nd.dispatch = 2;
17956
0
    h.witness_plan = wp;
17957
0
    nd.hash_index = static_cast<uint32_t>(r.hashes.size());
17958
0
    r.hashes.push_back(h);
17959
0
  }
17960
0
}
17961
17962
// Pure-leaf edge encoding, last: a child that is a pure leaf (terminal
17963
// route only) is encoded as -2 - route directly in the edge, so the walk
17964
// finishes or dead-ends there without loading the leaf node. -1 keeps
17965
// meaning "absent" for param_child.
17966
0
void encode_leaf_shortcuts(builder_tables& r) {
17967
0
  auto pure_leaf = [&](int32_t ni) {
17968
0
    const node_record& nd = r.nodes[static_cast<size_t>(ni)];
17969
0
    return nd.n_static == 0 && nd.param_child < 0 && nd.wild_route < 0 &&
17970
0
           nd.terminal_route >= 0;
17971
0
  };
17972
0
  for (auto& e : r.edges) {
17973
0
    if (pure_leaf(e.node)) {
17974
0
      e.node = -2 - r.nodes[static_cast<size_t>(e.node)].terminal_route;
17975
0
    }
17976
0
  }
17977
0
  for (auto& nd : r.nodes) {
17978
0
    if (nd.param_child >= 0 && pure_leaf(nd.param_child)) {
17979
0
      nd.param_child =
17980
0
          -2 - r.nodes[static_cast<size_t>(nd.param_child)].terminal_route;
17981
0
    }
17982
0
  }
17983
0
}
17984
17985
// Segment table: every non-regexp route's segments (kind plus literal text
17986
// in the blob), so the sequential fallback beyond the fast-path limits can
17987
// match any route without the compiler's types; for regexp routes, the
17988
// anchored literal prefix the matcher checks before running the provider.
17989
void build_segment_table(builder_tables& r,
17990
0
                         const std::vector<route_info>& routes) {
17991
0
  for (size_t i = 0; i < routes.size(); i++) {
17992
0
    const route_info& rt = routes[i];
17993
0
    route_record& rm = r.routes[i];
17994
0
    rm.segment_first = static_cast<uint32_t>(r.segments.size());
17995
0
    rm.segment_count = static_cast<uint32_t>(rt.segments.size());
17996
0
    for (const route_segment& s : rt.segments) {
17997
0
      segment_record sr{};
17998
0
      sr.kind = static_cast<uint8_t>(s.kind);
17999
0
      if (s.kind == segment_kind::literal) {
18000
0
        sr.text_offset = static_cast<uint32_t>(r.blob.size());
18001
0
        sr.text_length = static_cast<uint32_t>(s.text.size());
18002
0
        r.blob.insert(r.blob.end(), s.text.begin(), s.text.end());
18003
0
      }
18004
0
      r.segments.push_back(sr);
18005
0
    }
18006
0
  }
18007
0
}
18008
18009
// Could some pathname match both a fast-path route `w` (full segment
18010
// information) and route `c`? Conservative: true unless a literal conflict
18011
// or a segment-count conflict proves otherwise. For a regexp-mode `c`,
18012
// segments are what approximate_kind_sequence could certify (see there);
18013
// has_wildcard means the input needs at least segments.size() segments
18014
// rather than exactly that many.
18015
0
bool co_matchable(const route_info& w, const route_info& c) noexcept {
18016
0
  const bool c_regexp = c.mode == route_mode::regexp;
18017
0
  const size_t wn = w.segments.size();
18018
0
  const size_t cn = c.segments.size();
18019
0
  constexpr size_t unbounded = ~size_t{0};
18020
  // Segment counts each route accepts: [min, max].
18021
0
  const size_t w_max = w.has_wildcard ? unbounded : wn;
18022
0
  const size_t c_max = c.has_wildcard ? unbounded : cn;
18023
0
  if ((wn > cn ? wn : cn) > (w_max < c_max ? w_max : c_max)) {
18024
0
    return false;
18025
0
  }
18026
  // Positions both routes constrain (a safe wildcard segment constrains
18027
  // nothing; a regexp route's segments are all constraining).
18028
0
  const size_t w_fixed = w.has_wildcard ? wn - 1 : wn;
18029
0
  const size_t c_fixed = (!c_regexp && c.has_wildcard) ? cn - 1 : cn;
18030
0
  const size_t upto = w_fixed < c_fixed ? w_fixed : c_fixed;
18031
0
  for (size_t j = 0; j < upto; j++) {
18032
0
    const route_segment& ws = w.segments[j];
18033
0
    const route_segment& cs = c.segments[j];
18034
0
    if (ws.kind == segment_kind::literal && cs.kind == segment_kind::literal) {
18035
0
      if (ws.text != cs.text) {
18036
0
        return false;
18037
0
      }
18038
0
    } else if (ws.kind == segment_kind::literal &&
18039
0
               cs.kind == segment_kind::param) {
18040
0
      if (ws.text.empty()) {
18041
0
        return false;  // params never bind an empty segment
18042
0
      }
18043
0
    } else if (ws.kind == segment_kind::param &&
18044
0
               cs.kind == segment_kind::literal) {
18045
0
      if (cs.text.empty()) {
18046
0
        return false;
18047
0
      }
18048
0
    }
18049
0
  }
18050
0
  return true;
18051
0
}
18052
18053
// Auxiliary routes: those the trie cannot answer for (regexp mode and
18054
// sequential mode), in insertion order, followed by one challenger range per
18055
// trie route: the auxiliary routes that outrank it AND could match the same
18056
// input. After a fast-path hit only the winner's challengers are tested
18057
// (usually none).
18058
0
void build_aux_table(builder_tables& r, const std::vector<route_info>& routes) {
18059
0
  std::vector<uint32_t> aux_all;
18060
0
  for (size_t i = 0; i < routes.size(); i++) {
18061
0
    if (routes[i].mode != route_mode::trie) {
18062
0
      aux_all.push_back(static_cast<uint32_t>(i));
18063
0
    }
18064
0
  }
18065
0
  r.aux = aux_all;
18066
0
  r.n_aux_all = static_cast<uint32_t>(aux_all.size());
18067
0
  for (size_t w = 0; w < routes.size(); w++) {
18068
0
    const route_info& winner = routes[w];
18069
0
    if (winner.mode != route_mode::trie) {
18070
0
      continue;  // never a fast-path winner
18071
0
    }
18072
0
    route_record& rm = r.routes[w];
18073
0
    rm.challenger_first = static_cast<uint32_t>(r.aux.size());
18074
0
    for (const uint32_t c : aux_all) {
18075
0
      if (route_outranks(routes[c], c, winner, w) &&
18076
0
          co_matchable(winner, routes[c])) {
18077
0
        r.aux.push_back(c);
18078
0
      }
18079
0
    }
18080
0
    rm.challenger_count =
18081
0
        static_cast<uint32_t>(r.aux.size()) - rm.challenger_first;
18082
0
  }
18083
0
}
18084
18085
// Packs every table into one arena, each section 8-byte aligned, and
18086
// records the section offsets. The blob gets 8 bytes of zero padding so
18087
// short key windows can always be loaded whole.
18088
0
compiled_routes pack_arena(builder_tables& r) {
18089
0
  compiled_routes out{};
18090
0
  r.blob.insert(r.blob.end(), 8, '\0');
18091
0
  size_t total = 0;
18092
0
  const auto reserve = [&](size_t bytes) {
18093
0
    const size_t offset = total;
18094
0
    total += (bytes + 7) & ~size_t{7};
18095
0
    return static_cast<uint32_t>(offset);
18096
0
  };
18097
0
  const auto bytes_of = [](const auto& v) { return v.size() * sizeof(v[0]); };
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<ada::url_pattern_list_detail::node_record, std::__1::allocator<ada::url_pattern_list_detail::node_record> > >(std::__1::vector<ada::url_pattern_list_detail::node_record, std::__1::allocator<ada::url_pattern_list_detail::node_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<ada::url_pattern_list_detail::hash_record, std::__1::allocator<ada::url_pattern_list_detail::hash_record> > >(std::__1::vector<ada::url_pattern_list_detail::hash_record, std::__1::allocator<ada::url_pattern_list_detail::hash_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<ada::url_pattern_list_detail::edge_record, std::__1::allocator<ada::url_pattern_list_detail::edge_record> > >(std::__1::vector<ada::url_pattern_list_detail::edge_record, std::__1::allocator<ada::url_pattern_list_detail::edge_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<char, std::__1::allocator<char> > >(std::__1::vector<char, std::__1::allocator<char> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<ada::url_pattern_list_detail::route_record, std::__1::allocator<ada::url_pattern_list_detail::route_record> > >(std::__1::vector<ada::url_pattern_list_detail::route_record, std::__1::allocator<ada::url_pattern_list_detail::route_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<ada::url_pattern_list_detail::segment_record, std::__1::allocator<ada::url_pattern_list_detail::segment_record> > >(std::__1::vector<ada::url_pattern_list_detail::segment_record, std::__1::allocator<ada::url_pattern_list_detail::segment_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > >(std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_0::operator()<std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > >(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) const
18098
0
  out.nodes_offset = reserve(bytes_of(r.nodes));
18099
0
  out.hashes_offset = reserve(bytes_of(r.hashes));
18100
0
  out.edges_offset = reserve(bytes_of(r.edges));
18101
0
  out.slots_offset = reserve(bytes_of(r.slots));
18102
0
  out.blob_offset = reserve(bytes_of(r.blob));
18103
0
  out.routes_offset = reserve(bytes_of(r.routes));
18104
0
  out.segments_offset = reserve(bytes_of(r.segments));
18105
0
  out.aux_offset = reserve(bytes_of(r.aux));
18106
0
  out.root_index_offset = reserve(bytes_of(r.root_index));
18107
0
  out.arena.assign(total, 0);
18108
0
  const auto place = [&](uint32_t offset, const auto& v) {
18109
0
    if (!v.empty()) {
18110
0
      std::memcpy(out.arena.data() + offset, v.data(), v.size() * sizeof(v[0]));
18111
0
    }
18112
0
  };
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<ada::url_pattern_list_detail::node_record, std::__1::allocator<ada::url_pattern_list_detail::node_record> > >(unsigned int, std::__1::vector<ada::url_pattern_list_detail::node_record, std::__1::allocator<ada::url_pattern_list_detail::node_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<ada::url_pattern_list_detail::hash_record, std::__1::allocator<ada::url_pattern_list_detail::hash_record> > >(unsigned int, std::__1::vector<ada::url_pattern_list_detail::hash_record, std::__1::allocator<ada::url_pattern_list_detail::hash_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<ada::url_pattern_list_detail::edge_record, std::__1::allocator<ada::url_pattern_list_detail::edge_record> > >(unsigned int, std::__1::vector<ada::url_pattern_list_detail::edge_record, std::__1::allocator<ada::url_pattern_list_detail::edge_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >(unsigned int, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<char, std::__1::allocator<char> > >(unsigned int, std::__1::vector<char, std::__1::allocator<char> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<ada::url_pattern_list_detail::route_record, std::__1::allocator<ada::url_pattern_list_detail::route_record> > >(unsigned int, std::__1::vector<ada::url_pattern_list_detail::route_record, std::__1::allocator<ada::url_pattern_list_detail::route_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<ada::url_pattern_list_detail::segment_record, std::__1::allocator<ada::url_pattern_list_detail::segment_record> > >(unsigned int, std::__1::vector<ada::url_pattern_list_detail::segment_record, std::__1::allocator<ada::url_pattern_list_detail::segment_record> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > >(unsigned int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&) const
Unexecuted instantiation: unicode.cc:auto ada::url_pattern_list_compiler::(anonymous namespace)::pack_arena(ada::url_pattern_list_compiler::(anonymous namespace)::builder_tables&)::$_1::operator()<std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > >(unsigned int, std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&) const
18113
0
  place(out.nodes_offset, r.nodes);
18114
0
  place(out.hashes_offset, r.hashes);
18115
0
  place(out.edges_offset, r.edges);
18116
0
  place(out.slots_offset, r.slots);
18117
0
  place(out.blob_offset, r.blob);
18118
0
  place(out.routes_offset, r.routes);
18119
0
  place(out.segments_offset, r.segments);
18120
0
  place(out.aux_offset, r.aux);
18121
0
  place(out.root_index_offset, r.root_index);
18122
0
  out.n_routes = static_cast<uint32_t>(r.routes.size());
18123
0
  out.n_aux_all = r.n_aux_all;
18124
0
  return out;
18125
0
}
18126
18127
// Fills route.kind_sequence / kind_length from route.segments.
18128
0
void compute_kind_sequence(route_info& route) noexcept {
18129
0
  uint64_t seq = 0;
18130
0
  const size_t n = route.segments.size();
18131
0
  for (size_t j = 0; j < n && j < 32; j++) {
18132
0
    seq |= static_cast<uint64_t>(route.segments[j].kind) << (62 - 2 * j);
18133
0
  }
18134
0
  route.kind_sequence = seq;
18135
0
  route.kind_length = static_cast<uint8_t>(n < 255 ? n : 255);
18136
0
}
18137
18138
}  // namespace
18139
18140
// ---- compiler entry points -------------------------------------------------
18141
18142
bool classify_parts(const std::vector<url_pattern_part>& parts,
18143
                    std::vector<route_segment>& segments,
18144
0
                    std::vector<std::string>& group_names) {
18145
0
  segments.clear();
18146
0
  group_names.clear();
18147
0
  bool started = false;        // leading '/' consumed
18148
0
  bool group_open = false;     // the open segment slot is a group
18149
0
  bool wildcard_seen = false;  // a "*" segment was consumed (must stay last)
18150
0
  std::string literal;
18151
0
  const auto close_segment = [&]() {
18152
0
    if (!group_open) {
18153
0
      segments.push_back(route_segment{segment_kind::literal, literal});
18154
0
    }
18155
0
    literal.clear();
18156
0
    group_open = false;
18157
0
  };
18158
0
  const auto process_text = [&](std::string_view text) {
18159
0
    for (const char c : text) {
18160
0
      if (wildcard_seen) {
18161
0
        return false;  // nothing may follow a "*" segment
18162
0
      }
18163
0
      if (c == '/') {
18164
0
        if (!started) {
18165
0
          started = true;
18166
0
        } else {
18167
0
          close_segment();
18168
0
        }
18169
0
      } else {
18170
0
        if (!started || group_open) {
18171
0
          return false;  // text before '/', or suffix text after a group
18172
0
        }
18173
0
        literal += c;
18174
0
      }
18175
0
    }
18176
0
    return true;
18177
0
  };
18178
0
  for (const url_pattern_part& part : parts) {
18179
0
    if (part.type == url_pattern_part_type::FIXED_TEXT &&
18180
0
        part.modifier == url_pattern_part_modifier::none) {
18181
0
      if (!process_text(part.prefix) || !process_text(part.value) ||
18182
0
          !process_text(part.suffix)) {
18183
0
        return false;
18184
0
      }
18185
0
    } else if ((part.type == url_pattern_part_type::SEGMENT_WILDCARD ||
18186
0
                part.type == url_pattern_part_type::FULL_WILDCARD) &&
18187
0
               part.modifier == url_pattern_part_modifier::none &&
18188
0
               part.suffix.empty()) {
18189
0
      if (wildcard_seen) {
18190
0
        return false;
18191
0
      }
18192
0
      if (part.prefix == "/") {
18193
0
        if (!started) {
18194
0
          started = true;
18195
0
        } else {
18196
0
          close_segment();
18197
0
        }
18198
0
      } else if (part.prefix.empty()) {
18199
        // The group must occupy a whole, freshly opened segment slot.
18200
0
        if (!started || group_open || !literal.empty()) {
18201
0
          return false;
18202
0
        }
18203
0
      } else {
18204
0
        return false;  // group not aligned on a '/' boundary
18205
0
      }
18206
0
      const bool is_wildcard =
18207
0
          part.type == url_pattern_part_type::FULL_WILDCARD;
18208
0
      segments.push_back(route_segment{
18209
0
          is_wildcard ? segment_kind::wildcard : segment_kind::param,
18210
0
          part.name});
18211
0
      group_names.push_back(part.name);
18212
0
      group_open = true;
18213
0
      wildcard_seen = is_wildcard;
18214
0
    } else {
18215
0
      return false;  // regexp group or a "?" / "+" / "*" modifier
18216
0
    }
18217
0
  }
18218
0
  if (!started) {
18219
    // Only the empty pattern (zero parts) is representable without a leading
18220
    // '/': it matches exactly the empty pathname.
18221
0
    return parts.empty();
18222
0
  }
18223
0
  close_segment();
18224
0
  return true;
18225
0
}
18226
18227
0
void finalize_route(route_info& route) noexcept {
18228
0
  compute_kind_sequence(route);
18229
0
  route.all_literal = true;
18230
0
  route.has_wildcard = false;
18231
0
  size_t n_params = 0;
18232
  // A trie edge keeps its literal segment length in edge_record::key_length, a
18233
  // uint16_t. A literal longer than that wraps around, so the trie would match
18234
  // a shorter, truncated length (e.g. a 65536-byte segment becomes length 0 and
18235
  // matches an empty segment). Keep such a route out of the trie and let the
18236
  // sequential matcher, which compares the whole segment, answer it.
18237
0
  bool literal_fits_edge = true;
18238
0
  for (const route_segment& s : route.segments) {
18239
0
    if (s.kind != segment_kind::literal) {
18240
0
      route.all_literal = false;
18241
0
      if (s.kind == segment_kind::param) {
18242
0
        n_params++;
18243
0
      } else {
18244
0
        route.has_wildcard = true;
18245
0
      }
18246
0
    } else if (s.text.size() > std::numeric_limits<uint16_t>::max()) {
18247
0
      literal_fits_edge = false;
18248
0
    }
18249
0
  }
18250
0
  const size_t n_captures = n_params + (route.has_wildcard ? 1 : 0);
18251
0
  const bool trie_safe = !route.segments.empty() &&
18252
0
                         route.segments.size() <= max_trie_pattern_segments &&
18253
0
                         n_captures <= max_captures_per_route &&
18254
0
                         literal_fits_edge;
18255
0
  route.mode = trie_safe ? route_mode::trie : route_mode::sequential;
18256
0
}
18257
18258
void approximate_kind_sequence(const std::vector<url_pattern_part>& parts,
18259
0
                               route_info& route) {
18260
0
  std::vector<uint8_t> kinds;
18261
  // The route's segment shape, as far as it is known: literal segments carry
18262
  // their text, opaque ones (a ":name" group, alone or mixed with text) are
18263
  // params. Exact while every group is a ":name" segment wildcard, which
18264
  // cannot match '/': then the segment count and every literal position are
18265
  // certain. A custom "(...)" group, a "*" or a modifier can span segments,
18266
  // so from there on nothing is known and only the anchored literal prefix
18267
  // before it is kept.
18268
0
  std::vector<route_segment> shape;
18269
0
  std::string literal;
18270
0
  bool started = false;
18271
0
  bool open = false;
18272
0
  bool leading_slash = false;  // the pattern is anchored at a '/'
18273
0
  bool exact = true;           // no part can span a segment boundary
18274
0
  bool tail_known = true;      // segments after the last closed one are known
18275
0
  uint8_t current = 0;
18276
  // Closes the open segment; `complete` is true only when a '/' of fixed
18277
  // text closed it, i.e. the segment is exactly what was accumulated.
18278
0
  const auto close = [&](bool complete) {
18279
0
    if (open) {
18280
0
      kinds.push_back(current);
18281
0
      if (complete || exact) {
18282
0
        shape.push_back(current == 0
18283
0
                            ? route_segment{segment_kind::literal, literal}
18284
0
                            : route_segment{segment_kind::param, {}});
18285
0
      } else {
18286
0
        tail_known = false;
18287
0
      }
18288
0
      open = false;
18289
0
      current = 0;
18290
0
    }
18291
0
    literal.clear();
18292
0
  };
18293
0
  const auto process_text = [&](std::string_view text) {
18294
0
    for (const char c : text) {
18295
0
      if (c == '/') {
18296
0
        if (started) {
18297
0
          close(true);
18298
0
        } else {
18299
0
          leading_slash = true;
18300
0
        }
18301
0
        started = true;
18302
0
        open = true;
18303
0
        current = 0;
18304
0
      } else {
18305
0
        if (!started) {
18306
0
          started = true;
18307
0
        }
18308
0
        if (!open) {
18309
0
          open = true;
18310
0
          current = 0;
18311
0
        }
18312
0
        literal += c;
18313
0
      }
18314
0
    }
18315
0
  };
18316
0
  const auto add_group = [&](uint8_t kind) {
18317
0
    if (!open) {
18318
0
      started = true;
18319
0
      open = true;
18320
0
      current = 0;
18321
0
    }
18322
0
    current = current < kind ? kind : current;
18323
0
  };
18324
0
  for (const url_pattern_part& part : parts) {
18325
0
    if (part.type == url_pattern_part_type::FULL_WILDCARD ||
18326
0
        part.modifier != url_pattern_part_modifier::none) {
18327
      // A greedy or modified group can span segments: treat the rest of the
18328
      // route as a wildcard tail and stop. A "/" prefix closes the previous
18329
      // segment only when this part must occur. An optional ("?") or
18330
      // zero-or-more ("*") part, prefix included, may be absent, so the text
18331
      // after it stays in the same segment ("/reports{/:id}?.json" matches
18332
      // "/reports.json"). Treating that "/" as a definite boundary certified
18333
      // a segment the input does not have, and the shape check rejected the
18334
      // match before the provider ran.
18335
0
      exact = false;
18336
0
      const bool must_occur =
18337
0
          part.modifier != url_pattern_part_modifier::optional &&
18338
0
          part.modifier != url_pattern_part_modifier::zero_or_more;
18339
0
      close(must_occur && part.prefix == "/");
18340
0
      tail_known = false;
18341
0
      kinds.push_back(2);
18342
0
      break;
18343
0
    }
18344
0
    if (part.type == url_pattern_part_type::FIXED_TEXT) {
18345
0
      process_text(part.value);
18346
0
    } else {  // SEGMENT_WILDCARD or REGEXP, modifier none
18347
0
      if (part.type == url_pattern_part_type::REGEXP) {
18348
0
        exact = false;  // a custom group may match '/'
18349
0
      }
18350
0
      process_text(part.prefix);
18351
0
      add_group(1);
18352
0
      process_text(part.suffix);
18353
0
    }
18354
0
  }
18355
0
  close(exact);
18356
0
  uint64_t seq = 0;
18357
0
  for (size_t j = 0; j < kinds.size() && j < 32; j++) {
18358
0
    seq |= static_cast<uint64_t>(kinds[j]) << (62 - 2 * j);
18359
0
  }
18360
0
  route.kind_sequence = seq;
18361
0
  route.kind_length =
18362
0
      static_cast<uint8_t>(kinds.size() < 255 ? kinds.size() : 255);
18363
0
  route.mode = route_mode::regexp;
18364
0
  route.all_literal = false;
18365
0
  route.segments.clear();
18366
0
  if (!leading_slash) {
18367
    // Not anchored at '/': nothing about the segments is known.
18368
0
    route.has_wildcard = true;
18369
0
    return;
18370
0
  }
18371
  // has_wildcard here means "the tail is unconstrained": the input needs at
18372
  // least segments.size() segments; otherwise exactly that many.
18373
0
  route.has_wildcard = !(exact && tail_known);
18374
0
  if (route.has_wildcard) {
18375
    // Keep only the anchored literal prefix.
18376
0
    size_t n_prefix = 0;
18377
0
    while (n_prefix < shape.size() &&
18378
0
           shape[n_prefix].kind == segment_kind::literal) {
18379
0
      n_prefix++;
18380
0
    }
18381
0
    shape.resize(n_prefix);
18382
0
  }
18383
0
  route.segments = std::move(shape);
18384
0
}
18385
18386
0
compiled_routes compile_route_set(std::vector<route_info>& routes) {
18387
0
  builder_tables r{};
18388
0
  const std::vector<transient_node> t = build_trie(routes);
18389
0
  compile_route_records(r, routes);
18390
0
  const std::vector<int32_t> order = layout_nodes(r, t);
18391
0
  compile_dispatch(r, t, order);
18392
0
  encode_leaf_shortcuts(r);  // last: must not confuse the stages above
18393
0
  build_segment_table(r, routes);
18394
0
  build_aux_table(r, routes);
18395
0
  compiled_routes out = pack_arena(r);
18396
0
  out.group_names.resize(routes.size());
18397
0
  for (size_t i = 0; i < routes.size(); i++) {
18398
0
    if (routes[i].mode != route_mode::regexp) {
18399
0
      out.group_names[i] = routes[i].group_names;
18400
0
    }
18401
0
  }
18402
0
  return out;
18403
0
}
18404
18405
}  // namespace ada::url_pattern_list_compiler
18406
18407
namespace ada::url_pattern_list_detail {
18408
18409
tl::expected<compiled_routes, errors> compile_pathname_patterns(
18410
0
    std::span<const std::string> patterns, bool ignore_case) {
18411
0
  namespace compiler = url_pattern_list_compiler;
18412
0
  std::vector<compiler::route_info> routes;
18413
0
  routes.reserve(patterns.size());
18414
0
  for (const std::string& pattern : patterns) {
18415
    // The pattern side goes through ada's own URLPattern machinery: the
18416
    // pattern parser tokenizes and canonicalizes exactly as a URLPattern
18417
    // pathname component would.
18418
0
    auto options = url_pattern_compile_component_options::PATHNAME;
18419
0
    auto part_list = url_pattern_helpers::parse_pattern_string(
18420
0
        pattern, options, url_pattern_helpers::canonicalize_pathname);
18421
0
    if (!part_list) {
18422
0
      return tl::unexpected(part_list.error());
18423
0
    }
18424
0
    compiler::route_info route{};
18425
0
    if (compiler::classify_parts(*part_list, route.segments,
18426
0
                                 route.group_names)) {
18427
0
      compiler::finalize_route(route);
18428
0
    } else {
18429
      // The pattern needs URLPattern regexp semantics: the caller compiles
18430
      // it as a pathname component through the provider; it participates
18431
      // in the priority order via its approximated kind sequence.
18432
0
      compiler::approximate_kind_sequence(*part_list, route);
18433
0
    }
18434
0
    if (ignore_case) {
18435
      // The compiled literals are ASCII-folded; the matcher folds the input
18436
      // the same way.
18437
0
      for (compiler::route_segment& s : route.segments) {
18438
0
        if (s.kind == compiler::segment_kind::literal) {
18439
0
          ascii_fold(s.text.data(), static_cast<uint32_t>(s.text.size()),
18440
0
                     s.text.data());
18441
0
        }
18442
0
      }
18443
0
    }
18444
0
    routes.push_back(std::move(route));
18445
0
  }
18446
0
  compiled_routes compiled = compiler::compile_route_set(routes);
18447
0
  compiled.ignore_case = ignore_case ? 1 : 0;
18448
0
  return compiled;
18449
0
}
18450
18451
namespace {
18452
18453
// Literal-segment compare against the blob, folding the input on request
18454
// (the blob text is already folded).
18455
bool literal_equals(std::string_view s, const char* text, uint32_t length,
18456
0
                    bool fold_input) noexcept {
18457
0
  if (s.size() != length) {
18458
0
    return false;
18459
0
  }
18460
0
  if (!fold_input) {
18461
0
    return s.size() == 0 || std::memcmp(s.data(), text, s.size()) == 0;
18462
0
  }
18463
0
  for (size_t i = 0; i < s.size(); i++) {
18464
0
    const uint8_t c = static_cast<uint8_t>(s[i]);
18465
0
    const char folded =
18466
0
        static_cast<char>(c | ((c >= 'A' && c <= 'Z') ? 0x20u : 0u));
18467
0
    if (folded != text[i]) {
18468
0
      return false;
18469
0
    }
18470
0
  }
18471
0
  return true;
18472
0
}
18473
18474
}  // namespace
18475
18476
// Kept out of line on purpose: inlined into the walk, this loop cost the
18477
// static and ":param" paths, which never run it, about 5 ns through register
18478
// allocation; as a call it costs only wildcard hits. It lives in this
18479
// translation unit rather than the header because MSVC's ada_never_inline
18480
// expands to __declspec(noinline) with no inline linkage, so a definition in
18481
// the header is emitted in every translation unit and the link fails.
18482
//
18483
// On AArch64 whole 16-byte blocks go through NEON (a running byte minimum);
18484
// the rest is SWAR, 8 bytes per step: "some byte is below 0x20" ("hasless"
18485
// of Bit Twiddling Hacks) is exact as a yes/no answer, because a borrow can
18486
// only leave a lane that itself qualifies. Only a tail holding a control
18487
// byte gets the exact byte check.
18488
0
bool wildcard_tail_ok(const char* p, uint32_t n) noexcept {
18489
0
  constexpr uint64_t spaces = 0x2020202020202020ull;
18490
0
  constexpr uint64_t highs = 0x8080808080808080ull;
18491
0
  const auto below_space = [](uint64_t x) noexcept {
18492
0
    return (x - spaces) & ~x & highs;
18493
0
  };
18494
0
  uint64_t control = 0;
18495
0
  uint32_t i = 0;
18496
#if ADA_NEON
18497
  if (n >= 16) {
18498
    uint8x16_t lowest = vdupq_n_u8(0xFF);
18499
    for (; i + 16 <= n; i += 16) {
18500
      lowest =
18501
          vminq_u8(lowest, vld1q_u8(reinterpret_cast<const uint8_t*>(p + i)));
18502
    }
18503
    control = vminvq_u8(lowest) < 0x20 ? 1 : 0;
18504
  }
18505
#endif
18506
0
  for (; i + 8 <= n; i += 8) {
18507
0
    control |= below_space(load8_le(p + i));
18508
0
  }
18509
0
  if (i < n) {  // 1..7 bytes, padded with spaces
18510
0
    control |= below_space(gather_le(p + i, n - i) |
18511
0
                           (spaces & ~low_bytes_mask(n - i)));
18512
0
  }
18513
0
  if (control == 0) {
18514
0
    return true;
18515
0
  }
18516
0
  for (uint32_t j = 0; j < n; j++) {
18517
0
    if (p[j] == '\n' || p[j] == '\r') {
18518
0
      return false;
18519
0
    }
18520
0
  }
18521
0
  return true;
18522
0
}
18523
18524
bool match_regexp_shape(const compiled_routes& r, uint32_t route,
18525
0
                        std::string_view pathname, bool fold_input) noexcept {
18526
0
  const route_record& rt = r.section<route_record>(r.routes_offset)[route];
18527
0
  const segment_record* segs =
18528
0
      r.section<segment_record>(r.segments_offset) + rt.segment_first;
18529
0
  const char* blob = r.section<char>(r.blob_offset);
18530
0
  if (rt.segment_count == 0 && rt.wild != 0) {
18531
0
    return true;  // nothing is known about the route's shape
18532
0
  }
18533
0
  if (pathname.empty() || pathname[0] != '/') {
18534
0
    return false;  // a known shape always starts with '/'
18535
0
  }
18536
0
  size_t seg_start = 1;
18537
0
  for (uint32_t si = 0; si < rt.segment_count; si++) {
18538
0
    if (seg_start > pathname.size()) {
18539
0
      return false;  // fewer segments than the shape
18540
0
    }
18541
0
    const size_t slash = pathname.find('/', seg_start);
18542
0
    const size_t seg_end =
18543
0
        slash == std::string_view::npos ? pathname.size() : slash;
18544
0
    const std::string_view s(pathname.data() + seg_start, seg_end - seg_start);
18545
0
    if (segs[si].kind == 0) {  // literal
18546
0
      if (!literal_equals(s, blob + segs[si].text_offset, segs[si].text_length,
18547
0
                          fold_input)) {
18548
0
        return false;
18549
0
      }
18550
0
    } else if (s.empty()) {
18551
0
      return false;  // a ":name" group, mixed or not, never binds ""
18552
0
    }
18553
0
    seg_start = seg_end + 1;
18554
0
  }
18555
  // An exact shape admits no further segments.
18556
0
  return rt.wild != 0 || seg_start == pathname.size() + 1;
18557
0
}
18558
18559
bool match_route_sequential(const compiled_routes& r, uint32_t route,
18560
                            std::string_view pathname, bool fold_input,
18561
0
                            engine_result& result) noexcept {
18562
0
  using url_pattern_list_limits::max_captures_per_route;
18563
0
  result.capture_count = 0;
18564
0
  result.captures_truncated = false;
18565
0
  const route_record& rt = r.section<route_record>(r.routes_offset)[route];
18566
0
  const segment_record* segs =
18567
0
      r.section<segment_record>(r.segments_offset) + rt.segment_first;
18568
0
  const char* blob = r.section<char>(r.blob_offset);
18569
0
  const size_t n_pattern = rt.segment_count;
18570
0
  if (n_pattern == 0) {
18571
0
    return pathname.empty();  // the empty pattern matches only ""
18572
0
  }
18573
0
  if (pathname.empty() || pathname[0] != '/') {
18574
0
    return false;
18575
0
  }
18576
0
  const bool wild = rt.wild != 0;  // wildcard is always the last segment
18577
0
  const size_t n_fixed = wild ? n_pattern - 1 : n_pattern;
18578
0
  uint32_t total_captures = 0;
18579
0
  const auto add_capture = [&](size_t offset, size_t length) {
18580
0
    if (total_captures < max_captures_per_route) {
18581
0
      result.captures[total_captures] = {static_cast<uint32_t>(offset),
18582
0
                                         static_cast<uint32_t>(length)};
18583
0
    } else {
18584
0
      result.captures_truncated = true;
18585
0
    }
18586
0
    total_captures++;
18587
0
  };
18588
0
  size_t seg_start = 1;
18589
0
  for (size_t si = 0; si < n_fixed; si++) {
18590
0
    if (seg_start > pathname.size()) {
18591
0
      return false;  // the input has fewer segments than the pattern
18592
0
    }
18593
0
    const size_t slash = pathname.find('/', seg_start);
18594
0
    const size_t seg_end =
18595
0
        slash == std::string_view::npos ? pathname.size() : slash;
18596
    // seg_start <= pathname.size() was checked above, so this is in range
18597
    // (spelled without substr to keep the function provably non-throwing).
18598
0
    const std::string_view s(pathname.data() + seg_start, seg_end - seg_start);
18599
0
    if (segs[si].kind == 0) {  // literal
18600
0
      if (!literal_equals(s, blob + segs[si].text_offset, segs[si].text_length,
18601
0
                          fold_input)) {
18602
0
        return false;
18603
0
      }
18604
0
    } else {  // param: binds one non-empty segment
18605
0
      if (s.empty()) {
18606
0
        return false;
18607
0
      }
18608
0
      add_capture(seg_start, s.size());
18609
0
    }
18610
0
    seg_start = seg_end + 1;
18611
0
  }
18612
0
  if (wild) {
18613
0
    if (seg_start > pathname.size()) {
18614
0
      return false;  // the wildcard still needs its (possibly empty) segment
18615
0
    }
18616
    // "(.*)" does not match a line terminator (see wildcard_tail_ok).
18617
0
    if (pathname.find_first_of("\n\r", seg_start) != std::string_view::npos) {
18618
0
      return false;
18619
0
    }
18620
0
    add_capture(seg_start, pathname.size() - seg_start);
18621
0
  } else if (seg_start != pathname.size() + 1) {
18622
0
    return false;  // the input has more segments than the pattern
18623
0
  }
18624
0
  result.capture_count = total_captures < max_captures_per_route
18625
0
                             ? total_captures
18626
0
                             : max_captures_per_route;
18627
0
  return true;
18628
0
}
18629
18630
}  // namespace ada::url_pattern_list_detail
18631
#endif  // ADA_INCLUDE_URL_PATTERN
18632
/* end file src/url_pattern_list.cpp */
18633
#endif
18634
#endif  // ADA_INCLUDE_URL_PATTERN
18635
18636
/* begin file src/ada_c.cpp */
18637
// NOLINTBEGIN(bugprone-exception-escape,
18638
// bugprone-suspicious-stringview-data-usage)
18639
18640
0
ada::result<ada::url_aggregator>& get_instance(void* result) noexcept {
18641
0
  return *(ada::result<ada::url_aggregator>*)result;
18642
0
}
18643
18644
extern "C" {
18645
typedef void* ada_url;
18646
typedef void* ada_url_search_params;
18647
typedef void* ada_strings;
18648
typedef void* ada_url_search_params_keys_iter;
18649
typedef void* ada_url_search_params_values_iter;
18650
typedef void* ada_url_search_params_entries_iter;
18651
18652
struct ada_string {
18653
  const char* data;
18654
  size_t length;
18655
};
18656
18657
struct ada_owned_string {
18658
  const char* data;
18659
  size_t length;
18660
};
18661
18662
struct ada_string_pair {
18663
  ada_string key;
18664
  ada_string value;
18665
};
18666
18667
0
ada_string ada_string_create(const char* data, size_t length) {
18668
0
  ada_string out{};
18669
0
  out.data = data;
18670
0
  out.length = length;
18671
0
  return out;
18672
0
}
18673
18674
struct ada_url_components {
18675
  /*
18676
   * By using 32-bit integers, we implicitly assume that the URL string
18677
   * cannot exceed 4 GB.
18678
   *
18679
   * https://user:pass@example.com:1234/foo/bar?baz#quux
18680
   *       |     |    |          | ^^^^|       |   |
18681
   *       |     |    |          | |   |       |   `----- hash_start
18682
   *       |     |    |          | |   |       `--------- search_start
18683
   *       |     |    |          | |   `----------------- pathname_start
18684
   *       |     |    |          | `--------------------- port
18685
   *       |     |    |          `----------------------- host_end
18686
   *       |     |    `---------------------------------- host_start
18687
   *       |     `--------------------------------------- username_end
18688
   *       `--------------------------------------------- protocol_end
18689
   */
18690
  uint32_t protocol_end;
18691
  /**
18692
   * Username end is not `omitted` by default (-1) to make username and password
18693
   * getters less costly to implement.
18694
   */
18695
  uint32_t username_end;
18696
  uint32_t host_start;
18697
  uint32_t host_end;
18698
  uint32_t port;
18699
  uint32_t pathname_start;
18700
  uint32_t search_start;
18701
  uint32_t hash_start;
18702
};
18703
18704
0
ada_url ada_parse(const char* input, size_t length) noexcept {
18705
0
  return new ada::result<ada::url_aggregator>(
18706
0
      ada::parse<ada::url_aggregator>(std::string_view(input, length)));
18707
0
}
18708
18709
ada_url ada_parse_with_base(const char* input, size_t input_length,
18710
0
                            const char* base, size_t base_length) noexcept {
18711
0
  auto base_out =
18712
0
      ada::parse<ada::url_aggregator>(std::string_view(base, base_length));
18713
18714
0
  if (!base_out) {
18715
0
    return new ada::result<ada::url_aggregator>(base_out);
18716
0
  }
18717
18718
0
  return new ada::result<ada::url_aggregator>(ada::parse<ada::url_aggregator>(
18719
0
      std::string_view(input, input_length), &base_out.value()));
18720
0
}
18721
18722
0
bool ada_can_parse(const char* input, size_t length) noexcept {
18723
0
  return ada::can_parse(std::string_view(input, length));
18724
0
}
18725
18726
bool ada_can_parse_with_base(const char* input, size_t input_length,
18727
0
                             const char* base, size_t base_length) noexcept {
18728
0
  std::string_view base_view(base, base_length);
18729
0
  return ada::can_parse(std::string_view(input, input_length), &base_view);
18730
0
}
18731
18732
0
void ada_free(ada_url result) noexcept {
18733
0
  auto* r = (ada::result<ada::url_aggregator>*)result;
18734
0
  delete r;
18735
0
}
18736
18737
0
ada_url ada_copy(ada_url input) noexcept {
18738
0
  ada::result<ada::url_aggregator>& r = get_instance(input);
18739
0
  return new ada::result<ada::url_aggregator>(r);
18740
0
}
18741
18742
0
bool ada_is_valid(ada_url result) noexcept {
18743
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18744
0
  return r.has_value();
18745
0
}
18746
18747
// caller must free the result with ada_free_owned_string
18748
0
ada_owned_string ada_get_origin(ada_url result) noexcept {
18749
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18750
0
  ada_owned_string owned{};
18751
0
  if (!r) {
18752
0
    owned.data = nullptr;
18753
0
    owned.length = 0;
18754
0
    return owned;
18755
0
  }
18756
0
  std::string out = r->get_origin();
18757
0
  owned.length = out.size();
18758
0
  owned.data = new char[owned.length];
18759
0
  memcpy((void*)owned.data, out.data(), owned.length);
18760
0
  return owned;
18761
0
}
18762
18763
0
void ada_free_owned_string(ada_owned_string owned) noexcept {
18764
0
  delete[] owned.data;
18765
0
}
18766
18767
0
ada_string ada_get_href(ada_url result) noexcept {
18768
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18769
0
  if (!r) {
18770
0
    return ada_string_create(nullptr, 0);
18771
0
  }
18772
0
  std::string_view out = r->get_href();
18773
0
  return ada_string_create(out.data(), out.length());
18774
0
}
18775
18776
0
ada_string ada_get_username(ada_url result) noexcept {
18777
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18778
0
  if (!r) {
18779
0
    return ada_string_create(nullptr, 0);
18780
0
  }
18781
0
  std::string_view out = r->get_username();
18782
0
  return ada_string_create(out.data(), out.length());
18783
0
}
18784
18785
0
ada_string ada_get_password(ada_url result) noexcept {
18786
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18787
0
  if (!r) {
18788
0
    return ada_string_create(nullptr, 0);
18789
0
  }
18790
0
  std::string_view out = r->get_password();
18791
0
  return ada_string_create(out.data(), out.length());
18792
0
}
18793
18794
0
ada_string ada_get_port(ada_url result) noexcept {
18795
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18796
0
  if (!r) {
18797
0
    return ada_string_create(nullptr, 0);
18798
0
  }
18799
0
  std::string_view out = r->get_port();
18800
0
  return ada_string_create(out.data(), out.length());
18801
0
}
18802
18803
0
ada_string ada_get_hash(ada_url result) noexcept {
18804
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18805
0
  if (!r) {
18806
0
    return ada_string_create(nullptr, 0);
18807
0
  }
18808
0
  std::string_view out = r->get_hash();
18809
0
  return ada_string_create(out.data(), out.length());
18810
0
}
18811
18812
0
ada_string ada_get_host(ada_url result) noexcept {
18813
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18814
0
  if (!r) {
18815
0
    return ada_string_create(nullptr, 0);
18816
0
  }
18817
0
  std::string_view out = r->get_host();
18818
0
  return ada_string_create(out.data(), out.length());
18819
0
}
18820
18821
0
ada_string ada_get_hostname(ada_url result) noexcept {
18822
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18823
0
  if (!r) {
18824
0
    return ada_string_create(nullptr, 0);
18825
0
  }
18826
0
  std::string_view out = r->get_hostname();
18827
0
  return ada_string_create(out.data(), out.length());
18828
0
}
18829
18830
0
ada_string ada_get_pathname(ada_url result) noexcept {
18831
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18832
0
  if (!r) {
18833
0
    return ada_string_create(nullptr, 0);
18834
0
  }
18835
0
  std::string_view out = r->get_pathname();
18836
0
  return ada_string_create(out.data(), out.length());
18837
0
}
18838
18839
0
ada_string ada_get_search(ada_url result) noexcept {
18840
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18841
0
  if (!r) {
18842
0
    return ada_string_create(nullptr, 0);
18843
0
  }
18844
0
  std::string_view out = r->get_search();
18845
0
  return ada_string_create(out.data(), out.length());
18846
0
}
18847
18848
0
ada_string ada_get_protocol(ada_url result) noexcept {
18849
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18850
0
  if (!r) {
18851
0
    return ada_string_create(nullptr, 0);
18852
0
  }
18853
0
  std::string_view out = r->get_protocol();
18854
0
  return ada_string_create(out.data(), out.length());
18855
0
}
18856
18857
0
uint8_t ada_get_host_type(ada_url result) noexcept {
18858
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18859
0
  if (!r) {
18860
0
    return 0;
18861
0
  }
18862
0
  return r->host_type;
18863
0
}
18864
18865
0
uint8_t ada_get_scheme_type(ada_url result) noexcept {
18866
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18867
0
  if (!r) {
18868
0
    return 0;
18869
0
  }
18870
0
  return r->type;
18871
0
}
18872
18873
0
bool ada_set_href(ada_url result, const char* input, size_t length) noexcept {
18874
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18875
0
  if (!r) {
18876
0
    return false;
18877
0
  }
18878
0
  return r->set_href(std::string_view(input, length));
18879
0
}
18880
18881
0
bool ada_set_host(ada_url result, const char* input, size_t length) noexcept {
18882
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18883
0
  if (!r) {
18884
0
    return false;
18885
0
  }
18886
0
  return r->set_host(std::string_view(input, length));
18887
0
}
18888
18889
bool ada_set_hostname(ada_url result, const char* input,
18890
0
                      size_t length) noexcept {
18891
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18892
0
  if (!r) {
18893
0
    return false;
18894
0
  }
18895
0
  return r->set_hostname(std::string_view(input, length));
18896
0
}
18897
18898
bool ada_set_protocol(ada_url result, const char* input,
18899
0
                      size_t length) noexcept {
18900
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18901
0
  if (!r) {
18902
0
    return false;
18903
0
  }
18904
0
  return r->set_protocol(std::string_view(input, length));
18905
0
}
18906
18907
bool ada_set_username(ada_url result, const char* input,
18908
0
                      size_t length) noexcept {
18909
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18910
0
  if (!r) {
18911
0
    return false;
18912
0
  }
18913
0
  return r->set_username(std::string_view(input, length));
18914
0
}
18915
18916
bool ada_set_password(ada_url result, const char* input,
18917
0
                      size_t length) noexcept {
18918
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18919
0
  if (!r) {
18920
0
    return false;
18921
0
  }
18922
0
  return r->set_password(std::string_view(input, length));
18923
0
}
18924
18925
0
bool ada_set_port(ada_url result, const char* input, size_t length) noexcept {
18926
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18927
0
  if (!r) {
18928
0
    return false;
18929
0
  }
18930
0
  return r->set_port(std::string_view(input, length));
18931
0
}
18932
18933
bool ada_set_pathname(ada_url result, const char* input,
18934
0
                      size_t length) noexcept {
18935
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18936
0
  if (!r) {
18937
0
    return false;
18938
0
  }
18939
0
  return r->set_pathname(std::string_view(input, length));
18940
0
}
18941
18942
/**
18943
 * Update the search/query of the URL.
18944
 *
18945
 * If a URL has `?` as the search value, passing empty string to this function
18946
 * does not remove the attribute. If you need to remove it, please use
18947
 * `ada_clear_search` method.
18948
 */
18949
0
void ada_set_search(ada_url result, const char* input, size_t length) noexcept {
18950
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18951
0
  if (r) {
18952
0
    r->set_search(std::string_view(input, length));
18953
0
  }
18954
0
}
18955
18956
/**
18957
 * Update the hash/fragment of the URL.
18958
 *
18959
 * If a URL has `#` as the hash value, passing empty string to this function
18960
 * does not remove the attribute. If you need to remove it, please use
18961
 * `ada_clear_hash` method.
18962
 */
18963
0
void ada_set_hash(ada_url result, const char* input, size_t length) noexcept {
18964
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18965
0
  if (r) {
18966
0
    r->set_hash(std::string_view(input, length));
18967
0
  }
18968
0
}
18969
18970
0
void ada_clear_port(ada_url result) noexcept {
18971
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18972
0
  if (r) {
18973
0
    r->clear_port();
18974
0
  }
18975
0
}
18976
18977
/**
18978
 * Removes the hash of the URL.
18979
 *
18980
 * Despite `ada_set_hash` method, this function allows the complete
18981
 * removal of the hash attribute, even if it has a value of `#`.
18982
 */
18983
0
void ada_clear_hash(ada_url result) noexcept {
18984
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18985
0
  if (r) {
18986
0
    r->clear_hash();
18987
0
  }
18988
0
}
18989
18990
/**
18991
 * Removes the search of the URL.
18992
 *
18993
 * Despite `ada_set_search` method, this function allows the complete
18994
 * removal of the search attribute, even if it has a value of `?`.
18995
 */
18996
0
void ada_clear_search(ada_url result) noexcept {
18997
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18998
0
  if (r) {
18999
0
    r->clear_search();
19000
0
  }
19001
0
}
19002
19003
0
bool ada_has_credentials(ada_url result) noexcept {
19004
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19005
0
  if (!r) {
19006
0
    return false;
19007
0
  }
19008
0
  return r->has_credentials();
19009
0
}
19010
19011
0
bool ada_has_empty_hostname(ada_url result) noexcept {
19012
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19013
0
  if (!r) {
19014
0
    return false;
19015
0
  }
19016
0
  return r->has_empty_hostname();
19017
0
}
19018
19019
0
bool ada_has_hostname(ada_url result) noexcept {
19020
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19021
0
  if (!r) {
19022
0
    return false;
19023
0
  }
19024
0
  return r->has_hostname();
19025
0
}
19026
19027
0
bool ada_has_non_empty_username(ada_url result) noexcept {
19028
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19029
0
  if (!r) {
19030
0
    return false;
19031
0
  }
19032
0
  return r->has_non_empty_username();
19033
0
}
19034
19035
0
bool ada_has_non_empty_password(ada_url result) noexcept {
19036
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19037
0
  if (!r) {
19038
0
    return false;
19039
0
  }
19040
0
  return r->has_non_empty_password();
19041
0
}
19042
19043
0
bool ada_has_port(ada_url result) noexcept {
19044
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19045
0
  if (!r) {
19046
0
    return false;
19047
0
  }
19048
0
  return r->has_port();
19049
0
}
19050
19051
0
bool ada_has_password(ada_url result) noexcept {
19052
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19053
0
  if (!r) {
19054
0
    return false;
19055
0
  }
19056
0
  return r->has_password();
19057
0
}
19058
19059
0
bool ada_has_hash(ada_url result) noexcept {
19060
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19061
0
  if (!r) {
19062
0
    return false;
19063
0
  }
19064
0
  return r->has_hash();
19065
0
}
19066
19067
0
bool ada_has_search(ada_url result) noexcept {
19068
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19069
0
  if (!r) {
19070
0
    return false;
19071
0
  }
19072
0
  return r->has_search();
19073
0
}
19074
19075
// returns a pointer to the internal url_aggregator::url_components
19076
0
const ada_url_components* ada_get_components(ada_url result) noexcept {
19077
0
  static_assert(sizeof(ada_url_components) == sizeof(ada::url_components));
19078
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
19079
0
  if (!r) {
19080
0
    return nullptr;
19081
0
  }
19082
0
  return reinterpret_cast<const ada_url_components*>(&r->get_components());
19083
0
}
19084
19085
0
ada_owned_string ada_idna_to_unicode(const char* input, size_t length) {
19086
0
  std::string out = ada::idna::to_unicode(std::string_view(input, length));
19087
0
  ada_owned_string owned{};
19088
0
  owned.length = out.length();
19089
0
  owned.data = new char[owned.length];
19090
0
  memcpy((void*)owned.data, out.data(), owned.length);
19091
0
  return owned;
19092
0
}
19093
19094
0
ada_owned_string ada_idna_to_ascii(const char* input, size_t length) {
19095
0
  std::string out = ada::idna::to_ascii(std::string_view(input, length));
19096
0
  ada_owned_string owned{};
19097
0
  owned.length = out.size();
19098
0
  owned.data = new char[owned.length];
19099
0
  memcpy((void*)owned.data, out.data(), owned.length);
19100
0
  return owned;
19101
0
}
19102
19103
ada_url_search_params ada_parse_search_params(const char* input,
19104
0
                                              size_t length) {
19105
0
  return new ada::result<ada::url_search_params>(
19106
0
      ada::url_search_params(std::string_view(input, length)));
19107
0
}
19108
19109
0
void ada_free_search_params(ada_url_search_params result) {
19110
0
  auto* r = (ada::result<ada::url_search_params>*)result;
19111
0
  delete r;
19112
0
}
19113
19114
0
ada_owned_string ada_search_params_to_string(ada_url_search_params result) {
19115
0
  ada::result<ada::url_search_params>& r =
19116
0
      *(ada::result<ada::url_search_params>*)result;
19117
0
  if (!r) return ada_owned_string{nullptr, 0};
19118
0
  std::string out = r->to_string();
19119
0
  ada_owned_string owned{};
19120
0
  owned.length = out.size();
19121
0
  owned.data = new char[owned.length];
19122
0
  memcpy((void*)owned.data, out.data(), owned.length);
19123
0
  return owned;
19124
0
}
19125
19126
0
size_t ada_search_params_size(ada_url_search_params result) {
19127
0
  ada::result<ada::url_search_params>& r =
19128
0
      *(ada::result<ada::url_search_params>*)result;
19129
0
  if (!r) {
19130
0
    return 0;
19131
0
  }
19132
0
  return r->size();
19133
0
}
19134
19135
0
void ada_search_params_sort(ada_url_search_params result) {
19136
0
  ada::result<ada::url_search_params>& r =
19137
0
      *(ada::result<ada::url_search_params>*)result;
19138
0
  if (r) {
19139
0
    r->sort();
19140
0
  }
19141
0
}
19142
19143
void ada_search_params_reset(ada_url_search_params result, const char* input,
19144
0
                             size_t length) {
19145
0
  ada::result<ada::url_search_params>& r =
19146
0
      *(ada::result<ada::url_search_params>*)result;
19147
0
  if (r) {
19148
0
    r->reset(std::string_view(input, length));
19149
0
  }
19150
0
}
19151
19152
void ada_search_params_append(ada_url_search_params result, const char* key,
19153
                              size_t key_length, const char* value,
19154
0
                              size_t value_length) {
19155
0
  ada::result<ada::url_search_params>& r =
19156
0
      *(ada::result<ada::url_search_params>*)result;
19157
0
  if (r) {
19158
0
    r->append(std::string_view(key, key_length),
19159
0
              std::string_view(value, value_length));
19160
0
  }
19161
0
}
19162
19163
void ada_search_params_set(ada_url_search_params result, const char* key,
19164
                           size_t key_length, const char* value,
19165
0
                           size_t value_length) {
19166
0
  ada::result<ada::url_search_params>& r =
19167
0
      *(ada::result<ada::url_search_params>*)result;
19168
0
  if (r) {
19169
0
    r->set(std::string_view(key, key_length),
19170
0
           std::string_view(value, value_length));
19171
0
  }
19172
0
}
19173
19174
void ada_search_params_remove(ada_url_search_params result, const char* key,
19175
0
                              size_t key_length) {
19176
0
  ada::result<ada::url_search_params>& r =
19177
0
      *(ada::result<ada::url_search_params>*)result;
19178
0
  if (r) {
19179
0
    r->remove(std::string_view(key, key_length));
19180
0
  }
19181
0
}
19182
19183
void ada_search_params_remove_value(ada_url_search_params result,
19184
                                    const char* key, size_t key_length,
19185
0
                                    const char* value, size_t value_length) {
19186
0
  ada::result<ada::url_search_params>& r =
19187
0
      *(ada::result<ada::url_search_params>*)result;
19188
0
  if (r) {
19189
0
    r->remove(std::string_view(key, key_length),
19190
0
              std::string_view(value, value_length));
19191
0
  }
19192
0
}
19193
19194
bool ada_search_params_has(ada_url_search_params result, const char* key,
19195
0
                           size_t key_length) {
19196
0
  ada::result<ada::url_search_params>& r =
19197
0
      *(ada::result<ada::url_search_params>*)result;
19198
0
  if (!r) {
19199
0
    return false;
19200
0
  }
19201
0
  return r->has(std::string_view(key, key_length));
19202
0
}
19203
19204
bool ada_search_params_has_value(ada_url_search_params result, const char* key,
19205
                                 size_t key_length, const char* value,
19206
0
                                 size_t value_length) {
19207
0
  ada::result<ada::url_search_params>& r =
19208
0
      *(ada::result<ada::url_search_params>*)result;
19209
0
  if (!r) {
19210
0
    return false;
19211
0
  }
19212
0
  return r->has(std::string_view(key, key_length),
19213
0
                std::string_view(value, value_length));
19214
0
}
19215
19216
ada_string ada_search_params_get(ada_url_search_params result, const char* key,
19217
0
                                 size_t key_length) {
19218
0
  ada::result<ada::url_search_params>& r =
19219
0
      *(ada::result<ada::url_search_params>*)result;
19220
0
  if (!r) {
19221
0
    return ada_string_create(nullptr, 0);
19222
0
  }
19223
0
  auto found = r->get(std::string_view(key, key_length));
19224
0
  if (!found.has_value()) {
19225
0
    return ada_string_create(nullptr, 0);
19226
0
  }
19227
0
  return ada_string_create(found->data(), found->length());
19228
0
}
19229
19230
ada_strings ada_search_params_get_all(ada_url_search_params result,
19231
0
                                      const char* key, size_t key_length) {
19232
0
  ada::result<ada::url_search_params>& r =
19233
0
      *(ada::result<ada::url_search_params>*)result;
19234
0
  if (!r) {
19235
0
    return new ada::result<std::vector<std::string>>(
19236
0
        std::vector<std::string>());
19237
0
  }
19238
0
  return new ada::result<std::vector<std::string>>(
19239
0
      r->get_all(std::string_view(key, key_length)));
19240
0
}
19241
19242
ada_url_search_params_keys_iter ada_search_params_get_keys(
19243
0
    ada_url_search_params result) {
19244
0
  ada::result<ada::url_search_params>& r =
19245
0
      *(ada::result<ada::url_search_params>*)result;
19246
0
  if (!r) {
19247
0
    return new ada::result<ada::url_search_params_keys_iter>(
19248
0
        ada::url_search_params_keys_iter());
19249
0
  }
19250
0
  return new ada::result<ada::url_search_params_keys_iter>(r->get_keys());
19251
0
}
19252
19253
ada_url_search_params_values_iter ada_search_params_get_values(
19254
0
    ada_url_search_params result) {
19255
0
  ada::result<ada::url_search_params>& r =
19256
0
      *(ada::result<ada::url_search_params>*)result;
19257
0
  if (!r) {
19258
0
    return new ada::result<ada::url_search_params_values_iter>(
19259
0
        ada::url_search_params_values_iter());
19260
0
  }
19261
0
  return new ada::result<ada::url_search_params_values_iter>(r->get_values());
19262
0
}
19263
19264
ada_url_search_params_entries_iter ada_search_params_get_entries(
19265
0
    ada_url_search_params result) {
19266
0
  ada::result<ada::url_search_params>& r =
19267
0
      *(ada::result<ada::url_search_params>*)result;
19268
0
  if (!r) {
19269
0
    return new ada::result<ada::url_search_params_entries_iter>(
19270
0
        ada::url_search_params_entries_iter());
19271
0
  }
19272
0
  return new ada::result<ada::url_search_params_entries_iter>(r->get_entries());
19273
0
}
19274
19275
0
void ada_free_strings(ada_strings result) {
19276
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
19277
0
  delete r;
19278
0
}
19279
19280
0
size_t ada_strings_size(ada_strings result) {
19281
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
19282
0
  if (!r) {
19283
0
    return 0;
19284
0
  }
19285
0
  return (*r)->size();
19286
0
}
19287
19288
0
ada_string ada_strings_get(ada_strings result, size_t index) {
19289
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
19290
0
  if (!r || index >= (*r)->size()) {
19291
0
    return ada_string_create(nullptr, 0);
19292
0
  }
19293
0
  std::string_view view = (*r)->at(index);
19294
0
  return ada_string_create(view.data(), view.length());
19295
0
}
19296
19297
0
void ada_free_search_params_keys_iter(ada_url_search_params_keys_iter result) {
19298
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
19299
0
  delete r;
19300
0
}
19301
19302
ada_string ada_search_params_keys_iter_next(
19303
0
    ada_url_search_params_keys_iter result) {
19304
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
19305
0
  if (!r) {
19306
0
    return ada_string_create(nullptr, 0);
19307
0
  }
19308
0
  auto next = (*r)->next();
19309
0
  if (!next.has_value()) {
19310
0
    return ada_string_create(nullptr, 0);
19311
0
  }
19312
0
  return ada_string_create(next->data(), next->length());
19313
0
}
19314
19315
bool ada_search_params_keys_iter_has_next(
19316
0
    ada_url_search_params_keys_iter result) {
19317
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
19318
0
  if (!r) {
19319
0
    return false;
19320
0
  }
19321
0
  return (*r)->has_next();
19322
0
}
19323
19324
void ada_free_search_params_values_iter(
19325
0
    ada_url_search_params_values_iter result) {
19326
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
19327
0
  delete r;
19328
0
}
19329
19330
ada_string ada_search_params_values_iter_next(
19331
0
    ada_url_search_params_values_iter result) {
19332
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
19333
0
  if (!r) {
19334
0
    return ada_string_create(nullptr, 0);
19335
0
  }
19336
0
  auto next = (*r)->next();
19337
0
  if (!next.has_value()) {
19338
0
    return ada_string_create(nullptr, 0);
19339
0
  }
19340
0
  return ada_string_create(next->data(), next->length());
19341
0
}
19342
19343
bool ada_search_params_values_iter_has_next(
19344
0
    ada_url_search_params_values_iter result) {
19345
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
19346
0
  if (!r) {
19347
0
    return false;
19348
0
  }
19349
0
  return (*r)->has_next();
19350
0
}
19351
19352
void ada_free_search_params_entries_iter(
19353
0
    ada_url_search_params_entries_iter result) {
19354
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
19355
0
  delete r;
19356
0
}
19357
19358
ada_string_pair ada_search_params_entries_iter_next(
19359
0
    ada_url_search_params_entries_iter result) {
19360
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
19361
0
  if (!r) return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
19362
0
  auto next = (*r)->next();
19363
0
  if (!next.has_value()) {
19364
0
    return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
19365
0
  }
19366
0
  return ada_string_pair{
19367
0
      ada_string_create(next->first.data(), next->first.length()),
19368
0
      ada_string_create(next->second.data(), next->second.length())};
19369
0
}
19370
19371
bool ada_search_params_entries_iter_has_next(
19372
0
    ada_url_search_params_entries_iter result) {
19373
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
19374
0
  if (!r) {
19375
0
    return false;
19376
0
  }
19377
0
  return (*r)->has_next();
19378
0
}
19379
19380
0
void ada_set_max_input_length(uint32_t length) noexcept {
19381
0
  ada::set_max_input_length(length);
19382
0
}
19383
19384
0
uint32_t ada_get_max_input_length() noexcept {
19385
0
  return ada::get_max_input_length();
19386
0
}
19387
19388
typedef struct {
19389
  int major;
19390
  int minor;
19391
  int revision;
19392
} ada_version_components;
19393
19394
0
const char* ada_get_version() { return ADA_VERSION; }
19395
19396
0
ada_version_components ada_get_version_components() {
19397
0
  return ada_version_components{
19398
0
      .major = ada::ADA_VERSION_MAJOR,
19399
0
      .minor = ada::ADA_VERSION_MINOR,
19400
0
      .revision = ada::ADA_VERSION_REVISION,
19401
0
  };
19402
0
}
19403
19404
}  // extern "C"
19405
// NOLINTEND(bugprone-exception-escape,
19406
// bugprone-suspicious-stringview-data-usage)
19407
/* end file src/ada_c.cpp */
19408
/* end file src/ada.cpp */