Coverage Report

Created: 2026-06-10 06:28

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-06-03 08:26:49 -0400. Do not edit! */
2
/* begin file src/ada.cpp */
3
#include "ada.h"
4
/* begin file src/checkers.cpp */
5
6
#include <algorithm>
7
#include <array>
8
#include <string_view>
9
10
namespace ada::checkers {
11
12
458k
ada_really_inline constexpr bool is_ipv4(std::string_view view) noexcept {
13
  // The string is not empty and does not contain upper case ASCII characters.
14
  //
15
  // Optimization. To be considered as a possible ipv4, the string must end
16
  // with 'x' or a lowercase hex character.
17
  // Most of the time, this will be false so this simple check will save a lot
18
  // of effort.
19
  // If the address ends with a dot, we need to prune it (special case).
20
458k
  if (view.ends_with('.')) {
21
18.8k
    view.remove_suffix(1);
22
18.8k
    if (view.empty()) {
23
11.8k
      return false;
24
11.8k
    }
25
18.8k
  }
26
446k
  char last_char = view.back();
27
446k
  bool possible_ipv4 = (last_char >= '0' && last_char <= '9') ||
28
401k
                       (last_char >= 'a' && last_char <= 'f') ||
29
371k
                       last_char == 'x';
30
446k
  if (!possible_ipv4) {
31
368k
    return false;
32
368k
  }
33
  // From the last character, find the last dot.
34
78.2k
  size_t last_dot = view.rfind('.');
35
78.2k
  if (last_dot != std::string_view::npos) {
36
    // We have at least one dot.
37
12.8k
    view.remove_prefix(last_dot + 1);
38
12.8k
  }
39
  /** Optimization opportunity: we have basically identified the last number of
40
     the ipv4 if we return true here. We might as well parse it and have at
41
     least one number parsed when we get to parse_ipv4. */
42
78.2k
  if (std::ranges::all_of(view, ada::checkers::is_digit)) {
43
36.1k
    return true;
44
36.1k
  }
45
  // It could be hex (0x), but not if there is a single character.
46
42.1k
  if (view.size() == 1) {
47
10.9k
    return false;
48
10.9k
  }
49
  // It must start with 0x.
50
31.2k
  if (!view.starts_with("0x")) {
51
20.2k
    return false;
52
20.2k
  }
53
  // We must allow "0x".
54
10.9k
  if (view.size() == 2) {
55
477
    return true;
56
477
  }
57
  // We have 0x followed by some characters, we need to check that they are
58
  // hexadecimals.
59
10.5k
  view.remove_prefix(2);
60
10.5k
  return std::ranges::all_of(view, ada::unicode::is_lowercase_hex);
61
10.9k
}
62
63
// for use with path_signature, we include all characters that need percent
64
// encoding.
65
static constexpr std::array<uint8_t, 256> path_signature_table =
66
    []() consteval {
67
      std::array<uint8_t, 256> result{};
68
      for (size_t i = 0; i < 256; i++) {
69
        if (i <= 0x20 || i == 0x22 || i == 0x23 || i == 0x3c || i == 0x3e ||
70
            i == 0x3f || i == 0x5e || i == 0x60 || i == 0x7b || i == 0x7d ||
71
            i > 0x7e) {
72
          result[i] = 1;
73
        } else if (i == 0x25) {
74
          result[i] = 8;
75
        } else if (i == 0x2e) {
76
          result[i] = 4;
77
        } else if (i == 0x5c) {
78
          result[i] = 2;
79
        } else {
80
          result[i] = 0;
81
        }
82
      }
83
      return result;
84
    }();
85
86
ada_really_inline constexpr uint8_t path_signature(
87
385k
    std::string_view input) noexcept {
88
  // The path percent-encode set is the query percent-encode set and U+003F (?),
89
  // U+0060 (`), U+007B ({), and U+007D (}). The query percent-encode set is the
90
  // C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#),
91
  // U+003C (<), and U+003E (>). The C0 control percent-encode set are the C0
92
  // controls and all code points greater than U+007E (~).
93
385k
  size_t i = 0;
94
385k
  uint8_t accumulator{};
95
710k
  for (; i + 7 < input.size(); i += 8) {
96
324k
    accumulator |= uint8_t(path_signature_table[uint8_t(input[i])] |
97
324k
                           path_signature_table[uint8_t(input[i + 1])] |
98
324k
                           path_signature_table[uint8_t(input[i + 2])] |
99
324k
                           path_signature_table[uint8_t(input[i + 3])] |
100
324k
                           path_signature_table[uint8_t(input[i + 4])] |
101
324k
                           path_signature_table[uint8_t(input[i + 5])] |
102
324k
                           path_signature_table[uint8_t(input[i + 6])] |
103
324k
                           path_signature_table[uint8_t(input[i + 7])]);
104
324k
  }
105
1.07M
  for (; i < input.size(); i++) {
106
685k
    accumulator |= uint8_t(path_signature_table[uint8_t(input[i])]);
107
685k
  }
108
385k
  return accumulator;
109
385k
}
110
111
ada_really_inline constexpr bool verify_dns_length(
112
0
    std::string_view input) noexcept {
113
0
  if (input.empty()) return false;
114
0
  if (input.back() == '.') {
115
0
    if (input.size() > 254) return false;
116
0
  } else if (input.size() > 253)
117
0
    return false;
118
119
0
  size_t start = 0;
120
0
  while (start < input.size()) {
121
0
    auto dot_location = input.find('.', start);
122
    // If not found, it's likely the end of the domain
123
0
    if (dot_location == std::string_view::npos) dot_location = input.size();
124
125
0
    auto label_size = dot_location - start;
126
0
    if (label_size > 63 || label_size == 0) return false;
127
128
0
    start = dot_location + 1;
129
0
  }
130
131
0
  return true;
132
0
}
133
134
}  // namespace ada::checkers
135
/* end file src/checkers.cpp */
136
/* begin file src/unicode.cpp */
137
138
139
ADA_PUSH_DISABLE_ALL_WARNINGS
140
/* begin file src/ada_idna.cpp */
141
/* auto-generated on 2026-05-25 17:39:11 -0400. Do not edit! */
142
/* begin file src/idna.cpp */
143
/* begin file src/unicode_transcoding.cpp */
144
145
#include <algorithm>
146
#include <cstdint>
147
#include <cstring>
148
149
namespace ada::idna {
150
151
37.1k
size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) {
152
37.1k
  const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);
153
37.1k
  size_t pos = 0;
154
37.1k
  const char32_t* start{utf32_output};
155
253k
  while (pos < len) {
156
    // try to convert the next block of 16 ASCII bytes
157
221k
    if (pos + 16 <= len) {  // if it is safe to read 16 more
158
                            // bytes, check that they are ascii
159
21.4k
      uint64_t v1;
160
21.4k
      std::memcpy(&v1, data + pos, sizeof(uint64_t));
161
21.4k
      uint64_t v2;
162
21.4k
      std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
163
21.4k
      uint64_t v{v1 | v2};
164
21.4k
      if ((v & 0x8080808080808080) == 0) {
165
3.28k
        size_t final_pos = pos + 16;
166
55.8k
        while (pos < final_pos) {
167
52.5k
          *utf32_output++ = char32_t(buf[pos]);
168
52.5k
          pos++;
169
52.5k
        }
170
3.28k
        continue;
171
3.28k
      }
172
21.4k
    }
173
218k
    uint8_t leading_byte = data[pos];  // leading byte
174
218k
    if (leading_byte < 0b10000000) {
175
      // converting one ASCII byte !!!
176
174k
      *utf32_output++ = char32_t(leading_byte);
177
174k
      pos++;
178
174k
    } else if ((leading_byte & 0b11100000) == 0b11000000) {
179
      // We have a two-byte UTF-8
180
29.1k
      if (pos + 1 >= len) {
181
207
        return 0;
182
207
      }  // minimal bound checking
183
28.9k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
184
754
        return 0;
185
754
      }
186
      // range check
187
28.1k
      uint32_t code_point =
188
28.1k
          (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
189
28.1k
      if (code_point < 0x80 || 0x7ff < code_point) {
190
96
        return 0;
191
96
      }
192
28.0k
      *utf32_output++ = char32_t(code_point);
193
28.0k
      pos += 2;
194
28.0k
    } else if ((leading_byte & 0b11110000) == 0b11100000) {
195
      // We have a three-byte UTF-8
196
8.95k
      if (pos + 2 >= len) {
197
205
        return 0;
198
205
      }  // minimal bound checking
199
200
8.74k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
201
530
        return 0;
202
530
      }
203
8.21k
      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
204
202
        return 0;
205
202
      }
206
      // range check
207
8.01k
      uint32_t code_point = (leading_byte & 0b00001111) << 12 |
208
8.01k
                            (data[pos + 1] & 0b00111111) << 6 |
209
8.01k
                            (data[pos + 2] & 0b00111111);
210
8.01k
      if (code_point < 0x800 || 0xffff < code_point ||
211
7.65k
          (0xd7ff < code_point && code_point < 0xe000)) {
212
454
        return 0;
213
454
      }
214
7.56k
      *utf32_output++ = char32_t(code_point);
215
7.56k
      pos += 3;
216
7.56k
    } else if ((leading_byte & 0b11111000) == 0b11110000) {  // 0b11110000
217
      // we have a 4-byte UTF-8 word.
218
3.94k
      if (pos + 3 >= len) {
219
150
        return 0;
220
150
      }  // minimal bound checking
221
3.79k
      if ((data[pos + 1] & 0b11000000) != 0b10000000) {
222
425
        return 0;
223
425
      }
224
3.36k
      if ((data[pos + 2] & 0b11000000) != 0b10000000) {
225
198
        return 0;
226
198
      }
227
3.16k
      if ((data[pos + 3] & 0b11000000) != 0b10000000) {
228
199
        return 0;
229
199
      }
230
231
      // range check
232
2.96k
      uint32_t code_point = (leading_byte & 0b00000111) << 18 |
233
2.96k
                            (data[pos + 1] & 0b00111111) << 12 |
234
2.96k
                            (data[pos + 2] & 0b00111111) << 6 |
235
2.96k
                            (data[pos + 3] & 0b00111111);
236
2.96k
      if (code_point <= 0xffff || 0x10ffff < code_point) {
237
609
        return 0;
238
609
      }
239
2.35k
      *utf32_output++ = char32_t(code_point);
240
2.35k
      pos += 4;
241
2.35k
    } else {
242
1.83k
      return 0;
243
1.83k
    }
244
218k
  }
245
31.2k
  return utf32_output - start;
246
37.1k
}
247
248
0
size_t utf8_length_from_utf32(const char32_t* buf, size_t len) {
249
  // We are not BOM aware.
250
0
  const uint32_t* p = reinterpret_cast<const uint32_t*>(buf);
251
0
  size_t counter{0};
252
0
  for (size_t i = 0; i != len; ++i) {
253
0
    ++counter;                                      // ASCII
254
0
    counter += static_cast<size_t>(p[i] > 0x7F);    // two-byte
255
0
    counter += static_cast<size_t>(p[i] > 0x7FF);   // three-byte
256
0
    counter += static_cast<size_t>(p[i] > 0xFFFF);  // four-bytes
257
0
  }
258
0
  return counter;
259
0
}
260
261
37.1k
size_t utf32_length_from_utf8(const char* buf, size_t len) {
262
37.1k
  const int8_t* p = reinterpret_cast<const int8_t*>(buf);
263
342k
  return std::count_if(p, std::next(p, len), [](int8_t c) {
264
    // -65 is 0b10111111, anything larger in two-complement's
265
    // should start a new code point.
266
342k
    return c > -65;
267
342k
  });
268
37.1k
}
269
270
0
size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) {
271
0
  const uint32_t* data = reinterpret_cast<const uint32_t*>(buf);
272
0
  size_t pos = 0;
273
0
  const char* start{utf8_output};
274
0
  while (pos < len) {
275
    // try to convert the next block of 2 ASCII characters
276
0
    if (pos + 2 <= len) {  // if it is safe to read 8 more
277
                           // bytes, check that they are ascii
278
0
      uint64_t v;
279
0
      std::memcpy(&v, data + pos, sizeof(uint64_t));
280
0
      if ((v & 0xFFFFFF80FFFFFF80) == 0) {
281
0
        *utf8_output++ = char(buf[pos]);
282
0
        *utf8_output++ = char(buf[pos + 1]);
283
0
        pos += 2;
284
0
        continue;
285
0
      }
286
0
    }
287
0
    uint32_t word = data[pos];
288
0
    if ((word & 0xFFFFFF80) == 0) {
289
      // will generate one UTF-8 bytes
290
0
      *utf8_output++ = char(word);
291
0
      pos++;
292
0
    } else if ((word & 0xFFFFF800) == 0) {
293
      // will generate two UTF-8 bytes
294
      // we have 0b110XXXXX 0b10XXXXXX
295
0
      *utf8_output++ = char((word >> 6) | 0b11000000);
296
0
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
297
0
      pos++;
298
0
    } else if ((word & 0xFFFF0000) == 0) {
299
      // will generate three UTF-8 bytes
300
      // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX
301
0
      if (word >= 0xD800 && word <= 0xDFFF) {
302
0
        return 0;
303
0
      }
304
0
      *utf8_output++ = char((word >> 12) | 0b11100000);
305
0
      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
306
0
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
307
0
      pos++;
308
0
    } else {
309
      // will generate four UTF-8 bytes
310
      // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX
311
      // 0b10XXXXXX
312
0
      if (word > 0x10FFFF) {
313
0
        return 0;
314
0
      }
315
0
      *utf8_output++ = char((word >> 18) | 0b11110000);
316
0
      *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000);
317
0
      *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
318
0
      *utf8_output++ = char((word & 0b111111) | 0b10000000);
319
0
      pos++;
320
0
    }
321
0
  }
322
0
  return utf8_output - start;
323
0
}
324
}  // namespace ada::idna
325
/* end file src/unicode_transcoding.cpp */
326
/* begin file src/mapping.cpp */
327
328
#include <array>
329
#include <cstring>
330
#include <cstdint>
331
#include <string>
332
333
/* begin file src/mapping_tables.cpp */
334
// IDNA 17.0.0
335
// Two-level compressed mapping table.
336
// All constants are derived from the table data; no hardcoded boundaries.
337
// Total binary size: 48659 bytes (47.5 KB)
338
//   stage1:        6564 bytes  (3282 uint16_t entries)
339
//   stage2:       22912 bytes  (179 mixed blocks x 64)
340
//   bool_blocks:   1800 bytes  (225 uint64_t words)
341
//   utf8 maps:    17383 bytes
342
343
// clang-format off
344
#ifndef ADA_IDNA_MAPPING_TABLE_H
345
#define ADA_IDNA_MAPPING_TABLE_H
346
#include <cstdint>
347
348
namespace ada::idna {
349
350
// Block size for two-level table (2^6 = 64 code points per block).
351
constexpr uint32_t IDNA_BLOCK_BITS = 6u;
352
constexpr uint32_t IDNA_BLOCK_SIZE = 64u;
353
constexpr uint32_t IDNA_BLOCK_MASK = 63u;
354
355
// Sentinel values stored in stage2 / returned by lookup.
356
constexpr uint16_t IDNA_VALID      = 0xFFFF;  // code point is valid as-is
357
constexpr uint16_t IDNA_DISALLOWED = 0xFFFE;  // code point is disallowed
358
constexpr uint16_t IDNA_IGNORED    = 0x0000;    // ignored (index into empty UTF-8 entry)
359
360
// Bit 15 of a stage1 entry: set = boolean block, clear = mixed block.
361
constexpr uint16_t IDNA_BOOL_FLAG  = 0x8000;
362
363
// Two-level table covers code points [0, IDNA_LOW_RANGE_END).
364
// Derived from the highest non-disallowed code point below the high-ignored range,
365
// rounded up to the next 64-code-point block boundary.
366
constexpr uint32_t IDNA_LOW_RANGE_END    = 0x00033480;
367
368
// Variation selectors supplement: U+E0100..U+E01EF are all ignored.
369
// These are handled with a simple range check; everything else above
370
// IDNA_LOW_RANGE_END is disallowed.
371
constexpr uint32_t IDNA_HIGH_IGNORED_START = 0x000E0100;
372
constexpr uint32_t IDNA_HIGH_IGNORED_END   = 0x000E01F0;  // exclusive
373
374
// idna_stage1[cp >> 6]: one entry per 64-code-point block.
375
// Bit 15 set  -> lower 15 bits = index into idna_bool_blocks[].
376
// Bit 15 clear -> value = base offset into idna_stage2[] for this block.
377
const uint16_t idna_stage1[3282] = {
378
  0x8000, 0x0000, 0x0040, 0x0080, 0x00C0, 0x0100, 0x0140, 0x0180, 0x01C0, 0x0200, 0x0240, 0x0280,
379
  0x8000, 0x02C0, 0x0300, 0x0340, 0x0380, 0x03C0, 0x0400, 0x0440, 0x0480, 0x04C0, 0x0500, 0x8001,
380
  0x8002, 0x0540, 0x8000, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B,
381
  0x8000, 0x0580, 0x800C, 0x05C0, 0x0600, 0x0640, 0x800D, 0x800E, 0x800F, 0x0680, 0x8010, 0x8011,
382
  0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x06C0, 0x801A, 0x0700, 0x0740,
383
  0x0780, 0x07C0, 0x0800, 0x801B, 0x8000, 0x8000, 0x0840, 0x0880, 0x8000, 0x08C0, 0x8000, 0x8000,
384
  0x8000, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x0900, 0x8000, 0x8000, 0x8000, 0x8000,
385
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8022, 0x8023, 0x8024, 0x8025, 0x0940, 0x8026,
386
  0x0980, 0x8023, 0x8027, 0x8028, 0x8029, 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030,
387
  0x8000, 0x8031, 0x8000, 0x8032, 0x8033, 0x8034, 0x09C0, 0x8035, 0x0A00, 0x0A40, 0x0A80, 0x8000,
388
  0x0AC0, 0x0B00, 0x0B40, 0x0B80, 0x0BC0, 0x0C00, 0x0C40, 0x0C80, 0x0CC0, 0x0D00, 0x0D40, 0x8036,
389
  0x0D80, 0x0DC0, 0x0E00, 0x8000, 0x0E40, 0x8000, 0x8000, 0x8000, 0x0E80, 0x8000, 0x8000, 0x8000,
390
  0x8037, 0x0EC0, 0x0F00, 0x0F40, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
391
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
392
  0x0F80, 0x0FC0, 0x8000, 0x1000, 0x8000, 0x8038, 0x8000, 0x8000, 0x1040, 0x1080, 0x10C0, 0x1100,
393
  0x8039, 0x1140, 0x803A, 0x803B, 0x8000, 0x803C, 0x1180, 0x11C0, 0x1200, 0x1240, 0x1280, 0x12C0,
394
  0x1300, 0x803D, 0x1340, 0x1380, 0x13C0, 0x1400, 0x1440, 0x803E, 0x1480, 0x14C0, 0x1500, 0x1540,
395
  0x1580, 0x15C0, 0x1600, 0x1640, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
396
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
397
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
398
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
399
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
400
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
401
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
402
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
403
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
404
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
405
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
406
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
407
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
408
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
409
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
410
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
411
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
412
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
413
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
414
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
415
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
416
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
417
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
418
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
419
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
420
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
421
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
422
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
423
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
424
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
425
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
426
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
427
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
428
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
429
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
430
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
431
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
432
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x803F, 0x8040,
433
  0x8000, 0x8000, 0x8000, 0x8000, 0x8041, 0x1680, 0x16C0, 0x8042, 0x1700, 0x1740, 0x1780, 0x17C0,
434
  0x8043, 0x8042, 0x8000, 0x8044, 0x8000, 0x8045, 0x8000, 0x8046, 0x8047, 0x8048, 0x8000, 0x8049,
435
  0x804A, 0x1800, 0x1840, 0x804B, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
436
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
437
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
438
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
439
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
440
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
441
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
442
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
443
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
444
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
445
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
446
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
447
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
448
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
449
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x804C, 0x804D,
450
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
451
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
452
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
453
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
454
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
455
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
456
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
457
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
458
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
459
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
460
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
461
  0x1880, 0x18C0, 0x1900, 0x1940, 0x1980, 0x19C0, 0x1A00, 0x1A40, 0x1A80, 0x1AC0, 0x1B00, 0x1B40,
462
  0x1B80, 0x1BC0, 0x1C00, 0x1C40, 0x1C80, 0x1CC0, 0x1D00, 0x1D40, 0x1D80, 0x1DC0, 0x1E00, 0x1E40,
463
  0x1E80, 0x1EC0, 0x1F00, 0x1F40, 0x804F, 0x8050, 0x8000, 0x8051, 0x8052, 0x8000, 0x8053, 0x8054,
464
  0x804E, 0x804E, 0x8055, 0x8056, 0x8057, 0x8058, 0x8059, 0x805A, 0x1F80, 0x8000, 0x1FC0, 0x2000,
465
  0x805B, 0x2040, 0x2080, 0x805C, 0x8000, 0x8000, 0x8000, 0x8000, 0x8047, 0x805D, 0x20C0, 0x804E,
466
  0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063, 0x8064, 0x8065, 0x8066, 0x8067, 0x8068, 0x8069,
467
  0x806A, 0x806B, 0x806C, 0x804E, 0x8000, 0x806D, 0x2100, 0x806E, 0x806F, 0x2140, 0x8070, 0x804E,
468
  0x804E, 0x8071, 0x8072, 0x8073, 0x805B, 0x8074, 0x8075, 0x8076, 0x8000, 0x8077, 0x8078, 0x8079,
469
  0x807A, 0x807B, 0x8000, 0x807C, 0x807D, 0x807E, 0x807F, 0x8080, 0x8081, 0x8082, 0x8083, 0x8084,
470
  0x8000, 0x8085, 0x8000, 0x8086, 0x804E, 0x804E, 0x8087, 0x803C, 0x8000, 0x8088, 0x8089, 0x808A,
471
  0x808B, 0x808C, 0x804E, 0x804E, 0x808D, 0x804E, 0x2180, 0x808E, 0x808F, 0x8090, 0x8091, 0x8092,
472
  0x8000, 0x8093, 0x8094, 0x8023, 0x8095, 0x8096, 0x804E, 0x8097, 0x8098, 0x8099, 0x809A, 0x804E,
473
  0x809B, 0x809C, 0x809D, 0x809E, 0x804E, 0x804E, 0x804E, 0x809F, 0x80A0, 0x80A1, 0x80A2, 0x80A3,
474
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
475
  0x8000, 0x8000, 0x8063, 0x804E, 0x8000, 0x80A4, 0x8000, 0x8000, 0x8000, 0x80A5, 0x804E, 0x804E,
476
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
477
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
478
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
479
  0x804E, 0x804E, 0x80A6, 0x80A7, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
480
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x80A8, 0x80A9, 0x8000, 0x8000,
481
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
482
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
483
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
484
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
485
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8051,
486
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x808C, 0x804E, 0x804E,
487
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
488
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
489
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
490
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
491
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
492
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
493
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
494
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
495
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x8089, 0x804E, 0x804E, 0x804E,
496
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
497
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
498
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8023, 0x80AA, 0x80AB, 0x80AC,
499
  0x8000, 0x80AD, 0x80AE, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x8089, 0x804E, 0x804E,
500
  0x804E, 0x21C0, 0x2200, 0x80AF, 0x8000, 0x80B0, 0x80B1, 0x80B2, 0x8000, 0x8000, 0x8000, 0x8000,
501
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
502
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
503
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
504
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
505
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
506
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
507
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
508
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
509
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
510
  0x8000, 0x8000, 0x8000, 0x80B3, 0x80B4, 0x804E, 0x8000, 0x80A7, 0x804E, 0x804E, 0x804E, 0x804E,
511
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
512
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
513
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
514
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
515
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
516
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
517
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
518
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
519
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
520
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
521
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x80B5,
522
  0x8000, 0x8000, 0x8000, 0x8000, 0x80B6, 0x80B7, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x808D,
523
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
524
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
525
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
526
  0x8000, 0x80B8, 0x2240, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
527
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
528
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
529
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
530
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
531
  0x804E, 0x804E, 0x804E, 0x804E, 0x8000, 0x8000, 0x8000, 0x2280, 0x8000, 0x8000, 0x8000, 0x8000,
532
  0x8000, 0x8000, 0x80B9, 0x80BA, 0x80BB, 0x8040, 0x8000, 0x80A5, 0x8000, 0x8000, 0x8000, 0x8028,
533
  0x80BC, 0x22C0, 0x2300, 0x2340, 0x8000, 0x80BD, 0x804E, 0x80BE, 0x8000, 0x80BF, 0x804E, 0x804E,
534
  0x2380, 0x23C0, 0x2400, 0x2440, 0x2480, 0x24C0, 0x2500, 0x2540, 0x2580, 0x25C0, 0x2600, 0x2640,
535
  0x2680, 0x26C0, 0x2700, 0x2740, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
536
  0x8000, 0x8000, 0x80C0, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
537
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x80C1, 0x804E, 0x804E, 0x804E,
538
  0x2780, 0x27C0, 0x80C2, 0x804E, 0x80C3, 0x80C4, 0x804E, 0x804E, 0x804E, 0x804E, 0x80C5, 0x80C6,
539
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x80C7, 0x804E, 0x804E, 0x804E, 0x80C8,
540
  0x804E, 0x804E, 0x804E, 0x80C9, 0x804E, 0x804E, 0x804E, 0x80CA, 0x8000, 0x8000, 0x8000, 0x80CB,
541
  0x2800, 0x80CC, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
542
  0x804E, 0x80CD, 0x80CE, 0x804E, 0x80CF, 0x804E, 0x804E, 0x804E, 0x2840, 0x2880, 0x28C0, 0x80D0,
543
  0x804E, 0x804E, 0x804E, 0x804E, 0x802B, 0x8000, 0x80D1, 0x80D2, 0x2900, 0x2940, 0x2980, 0x80D3,
544
  0x29C0, 0x2A00, 0x804E, 0x804E, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
545
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x80D4, 0x8000, 0x8000, 0x8000, 0x80D5,
546
  0x80D6, 0x80D7, 0x80D8, 0x80D9, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x80DA, 0x80DB, 0x80DC,
547
  0x8000, 0x8000, 0x80DD, 0x2A40, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
548
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x8000, 0x8000, 0x8000, 0x8000,
549
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
550
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
551
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
552
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
553
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
554
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
555
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
556
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
557
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
558
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
559
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
560
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
561
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
562
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
563
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
564
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
565
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
566
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
567
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
568
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
569
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
570
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
571
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
572
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
573
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
574
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
575
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
576
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
577
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
578
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
579
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
580
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
581
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
582
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
583
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
584
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
585
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
586
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
587
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
588
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
589
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
590
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
591
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
592
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
593
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
594
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
595
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
596
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
597
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
598
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
599
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
600
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
601
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
602
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
603
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
604
  0x8000, 0x8000, 0x8000, 0x8068, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
605
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
606
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
607
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
608
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
609
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
610
  0x80DE, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
611
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
612
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
613
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
614
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
615
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
616
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
617
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x80BB, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
618
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
619
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
620
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
621
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
622
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
623
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
624
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
625
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
626
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
627
  0x8000, 0x8000, 0x8000, 0x80DF, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
628
  0x8000, 0x803C, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
629
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
630
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
631
  0x804E, 0x804E, 0x804E, 0x804E, 0x2A80, 0x2AC0, 0x2B00, 0x2B40, 0x2B80, 0x2BC0, 0x2C00, 0x2C40,
632
  0x2C80, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
633
  0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E, 0x804E,
634
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
635
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
636
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
637
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
638
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
639
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
640
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x80E0, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
641
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
642
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
643
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
644
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
645
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
646
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
647
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
648
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
649
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
650
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
651
  0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8089
652
};
653
654
// idna_stage2[]: mixed blocks. Each entry is IDNA_VALID, IDNA_DISALLOWED,
655
// IDNA_IGNORED, or a byte offset into idna_utf8_mappings[].
656
const uint16_t idna_stage2[11456] = {
657
  0xFFFF, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015,
658
  0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D,
659
  0x002F, 0x0031, 0x0033, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
660
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
661
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
662
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
663
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
664
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
665
  0x0035, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0037, 0xFFFF, 0x0001, 0xFFFF,
666
  0xFFFF, 0x0000, 0xFFFF, 0x003B, 0xFFFF, 0xFFFF, 0x003F, 0x0041, 0x0043, 0x0047, 0xFFFF, 0xFFFF,
667
  0x004A, 0x004E, 0x001D, 0xFFFF, 0x0050, 0x0056, 0x005C, 0xFFFF, 0x0062, 0x0065, 0x0068, 0x006B,
668
  0x006E, 0x0071, 0x0074, 0x0077, 0x007A, 0x007D, 0x0080, 0x0083, 0x0086, 0x0089, 0x008C, 0x008F,
669
  0x0092, 0x0095, 0x0098, 0x009B, 0x009E, 0x00A1, 0x00A4, 0xFFFF, 0x00A7, 0x00AA, 0x00AD, 0x00B0,
670
  0x00B3, 0x00B6, 0x00B9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
671
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
672
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
673
  0x00BC, 0xFFFF, 0x00BF, 0xFFFF, 0x00C2, 0xFFFF, 0x00C5, 0xFFFF, 0x00C8, 0xFFFF, 0x00CB, 0xFFFF,
674
  0x00CE, 0xFFFF, 0x00D1, 0xFFFF, 0x00D4, 0xFFFF, 0x00D7, 0xFFFF, 0x00DA, 0xFFFF, 0x00DD, 0xFFFF,
675
  0x00E0, 0xFFFF, 0x00E3, 0xFFFF, 0x00E6, 0xFFFF, 0x00E9, 0xFFFF, 0x00EC, 0xFFFF, 0x00EF, 0xFFFF,
676
  0x00F2, 0xFFFF, 0x00F5, 0xFFFF, 0x00F8, 0xFFFF, 0x00FB, 0xFFFF, 0x00FE, 0xFFFF, 0x0101, 0xFFFF,
677
  0x0104, 0xFFFF, 0x0108, 0x0108, 0x010B, 0xFFFF, 0x010E, 0xFFFF, 0xFFFF, 0x0111, 0xFFFF, 0x0114,
678
  0xFFFF, 0x0117, 0xFFFF, 0x011A, 0x011A, 0x011E, 0xFFFF, 0x0121, 0xFFFF, 0x0124, 0xFFFF, 0x0127,
679
  0xFFFF, 0x012A, 0x012E, 0xFFFF, 0x0131, 0xFFFF, 0x0134, 0xFFFF, 0x0137, 0xFFFF, 0x013A, 0xFFFF,
680
  0x013D, 0xFFFF, 0x0140, 0xFFFF, 0x0143, 0xFFFF, 0x0146, 0xFFFF, 0x0149, 0xFFFF, 0x014C, 0xFFFF,
681
  0x014F, 0xFFFF, 0x0152, 0xFFFF, 0x0155, 0xFFFF, 0x0158, 0xFFFF, 0x015B, 0xFFFF, 0x015E, 0xFFFF,
682
  0x0161, 0xFFFF, 0x0164, 0xFFFF, 0x0167, 0xFFFF, 0x016A, 0xFFFF, 0x016D, 0xFFFF, 0x0170, 0xFFFF,
683
  0x0173, 0x0176, 0xFFFF, 0x0179, 0xFFFF, 0x017C, 0xFFFF, 0x0025, 0xFFFF, 0x017F, 0x0182, 0xFFFF,
684
  0x0185, 0xFFFF, 0x0188, 0x018B, 0xFFFF, 0x018E, 0x0191, 0x0194, 0xFFFF, 0xFFFF, 0x0197, 0x019A,
685
  0x019D, 0x01A0, 0xFFFF, 0x01A3, 0x01A6, 0xFFFF, 0x01A9, 0x01AC, 0x01AF, 0xFFFF, 0xFFFF, 0xFFFF,
686
  0x01B2, 0x01B5, 0xFFFF, 0x01B8, 0x01BB, 0xFFFF, 0x01BE, 0xFFFF, 0x01C1, 0xFFFF, 0x01C4, 0x01C7,
687
  0xFFFF, 0x01CA, 0xFFFF, 0xFFFF, 0x01CD, 0xFFFF, 0x01D0, 0x01D3, 0xFFFF, 0x01D6, 0x01D9, 0x01DC,
688
  0xFFFF, 0x01DF, 0xFFFF, 0x01E2, 0x01E5, 0xFFFF, 0xFFFF, 0xFFFF, 0x01E8, 0xFFFF, 0xFFFF, 0xFFFF,
689
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x01EB, 0x01EB, 0x01EB, 0x01EF, 0x01EF, 0x01EF, 0x01F2, 0x01F2,
690
  0x01F2, 0x01F5, 0xFFFF, 0x01F8, 0xFFFF, 0x01FB, 0xFFFF, 0x01FE, 0xFFFF, 0x0201, 0xFFFF, 0x0204,
691
  0xFFFF, 0x0207, 0xFFFF, 0x020A, 0xFFFF, 0xFFFF, 0x020D, 0xFFFF, 0x0210, 0xFFFF, 0x0213, 0xFFFF,
692
  0x0216, 0xFFFF, 0x0219, 0xFFFF, 0x021C, 0xFFFF, 0x021F, 0xFFFF, 0x0222, 0xFFFF, 0x0225, 0xFFFF,
693
  0xFFFF, 0x0228, 0x0228, 0x0228, 0x022B, 0xFFFF, 0x022E, 0x0231, 0x0234, 0xFFFF, 0x0237, 0xFFFF,
694
  0x023A, 0xFFFF, 0x023D, 0xFFFF, 0x0240, 0xFFFF, 0x0243, 0xFFFF, 0x0246, 0xFFFF, 0x0249, 0xFFFF,
695
  0x024C, 0xFFFF, 0x024F, 0xFFFF, 0x0252, 0xFFFF, 0x0255, 0xFFFF, 0x0258, 0xFFFF, 0x025B, 0xFFFF,
696
  0x025E, 0xFFFF, 0x0261, 0xFFFF, 0x0264, 0xFFFF, 0x0267, 0xFFFF, 0x026A, 0xFFFF, 0x026D, 0xFFFF,
697
  0x0270, 0xFFFF, 0x0273, 0xFFFF, 0x0276, 0xFFFF, 0x0279, 0xFFFF, 0x027C, 0xFFFF, 0x027F, 0xFFFF,
698
  0x0282, 0xFFFF, 0x0285, 0xFFFF, 0x0288, 0xFFFF, 0x028B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
699
  0xFFFF, 0xFFFF, 0x028E, 0x0292, 0xFFFF, 0x0295, 0x0298, 0xFFFF, 0xFFFF, 0x029C, 0xFFFF, 0x029F,
700
  0x02A2, 0x02A5, 0x02A8, 0xFFFF, 0x02AB, 0xFFFF, 0x02AE, 0xFFFF, 0x02B1, 0xFFFF, 0x02B4, 0xFFFF,
701
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
702
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
703
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
704
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
705
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
706
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
707
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
708
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
709
  0x000F, 0x02B7, 0x0013, 0x0023, 0x02BA, 0x02BD, 0x02C0, 0x002D, 0x0031, 0xFFFF, 0xFFFF, 0xFFFF,
710
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
711
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
712
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x02C3, 0x02C7, 0x02CB, 0x02CF, 0x02D3, 0x02D7, 0xFFFF, 0xFFFF,
713
  0x01A6, 0x0017, 0x0025, 0x002F, 0x02DB, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
714
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
715
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x02DE, 0x02E1, 0xFFFF, 0x02E4,
716
  0x02E7, 0x02EC, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
717
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
718
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
719
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x02EF, 0xFFFF, 0x02F2, 0xFFFF,
720
  0x02F5, 0xFFFF, 0x02F8, 0xFFFF, 0xFFFE, 0xFFFE, 0x02FB, 0xFFFF, 0xFFFF, 0xFFFF, 0x02FF, 0x0301,
721
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0043, 0x0304, 0x030A, 0x030D, 0x0310, 0x0313, 0x0316, 0xFFFE,
722
  0x0319, 0xFFFE, 0x031C, 0x031F, 0xFFFF, 0x0322, 0x0325, 0x0328, 0x032B, 0x032E, 0x0331, 0x0334,
723
  0x0337, 0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0xFFFE, 0x034F,
724
  0x0352, 0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x0364, 0x0367, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
725
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
726
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
727
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x036A, 0x0325, 0x0337, 0x0355, 0x031C,
728
  0x0367, 0x0358, 0x0349, 0xFFFF, 0x036D, 0xFFFF, 0x0370, 0xFFFF, 0x0373, 0xFFFF, 0x0376, 0xFFFF,
729
  0x0379, 0xFFFF, 0x037C, 0xFFFF, 0x037F, 0xFFFF, 0x0382, 0xFFFF, 0x0385, 0xFFFF, 0x0388, 0xFFFF,
730
  0x038B, 0xFFFF, 0x038E, 0xFFFF, 0x033A, 0x034C, 0x034F, 0xFFFF, 0x0337, 0x032E, 0xFFFF, 0x0391,
731
  0xFFFF, 0x034F, 0x0394, 0xFFFF, 0xFFFF, 0x0397, 0x039A, 0x039D, 0x03A0, 0x03A3, 0x03A6, 0x03A9,
732
  0x03AC, 0x03AF, 0x03B2, 0x03B5, 0x03B8, 0x03BB, 0x03BE, 0x03C1, 0x03C4, 0x03C7, 0x03CA, 0x03CD,
733
  0x03D0, 0x03D3, 0x03D6, 0x03D9, 0x03DC, 0x03DF, 0x03E2, 0x03E5, 0x03E8, 0x03EB, 0x03EE, 0x03F1,
734
  0x03F4, 0x03F7, 0x03FA, 0x03FD, 0x0400, 0x0403, 0x0406, 0x0409, 0x040C, 0x040F, 0x0412, 0x0415,
735
  0x0418, 0x041B, 0x041E, 0x0421, 0x0424, 0x0427, 0x042A, 0x042D, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
736
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
737
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
738
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
739
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0430, 0xFFFF, 0x0433, 0xFFFF,
740
  0x0436, 0xFFFF, 0x0439, 0xFFFF, 0x043C, 0xFFFF, 0x043F, 0xFFFF, 0x0442, 0xFFFF, 0x0445, 0xFFFF,
741
  0x0448, 0xFFFF, 0x044B, 0xFFFF, 0x044E, 0xFFFF, 0x0451, 0xFFFF, 0x0454, 0xFFFF, 0x0457, 0xFFFF,
742
  0x045A, 0xFFFF, 0x045D, 0xFFFF, 0x0460, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
743
  0xFFFF, 0xFFFF, 0x0463, 0xFFFF, 0x0466, 0xFFFF, 0x0469, 0xFFFF, 0x046C, 0xFFFF, 0x046F, 0xFFFF,
744
  0x0472, 0xFFFF, 0x0475, 0xFFFF, 0x0478, 0xFFFF, 0x047B, 0xFFFF, 0x047E, 0xFFFF, 0x0481, 0xFFFF,
745
  0x0484, 0xFFFF, 0x0487, 0xFFFF, 0x048A, 0xFFFF, 0x048D, 0xFFFF, 0x0490, 0xFFFF, 0x0493, 0xFFFF,
746
  0x0496, 0xFFFF, 0x0499, 0xFFFF, 0x049C, 0xFFFF, 0x049F, 0xFFFF, 0x04A2, 0xFFFF, 0x04A5, 0xFFFF,
747
  0x04A8, 0xFFFF, 0x04AB, 0xFFFF, 0x04AE, 0xFFFF, 0x04B1, 0xFFFF, 0x04B4, 0x04B7, 0xFFFF, 0x04BA,
748
  0xFFFF, 0x04BD, 0xFFFF, 0x04C0, 0xFFFF, 0x04C3, 0xFFFF, 0x04C6, 0xFFFF, 0x04C9, 0xFFFF, 0xFFFF,
749
  0x04CC, 0xFFFF, 0x04CF, 0xFFFF, 0x04D2, 0xFFFF, 0x04D5, 0xFFFF, 0x04D8, 0xFFFF, 0x04DB, 0xFFFF,
750
  0x04DE, 0xFFFF, 0x04E1, 0xFFFF, 0x04E4, 0xFFFF, 0x04E7, 0xFFFF, 0x04EA, 0xFFFF, 0x04ED, 0xFFFF,
751
  0x04F0, 0xFFFF, 0x04F3, 0xFFFF, 0x04F6, 0xFFFF, 0x04F9, 0xFFFF, 0x04FC, 0xFFFF, 0x04FF, 0xFFFF,
752
  0x0502, 0xFFFF, 0x0505, 0xFFFF, 0x0508, 0xFFFF, 0x050B, 0xFFFF, 0x050E, 0xFFFF, 0x0511, 0xFFFF,
753
  0x0514, 0xFFFF, 0x0517, 0xFFFF, 0x051A, 0xFFFF, 0x051D, 0xFFFF, 0x0520, 0xFFFF, 0x0523, 0xFFFF,
754
  0x0526, 0xFFFF, 0x0529, 0xFFFF, 0x052C, 0xFFFF, 0x052F, 0xFFFF, 0x0532, 0xFFFF, 0x0535, 0xFFFF,
755
  0x0538, 0xFFFF, 0x053B, 0xFFFF, 0x053E, 0xFFFF, 0x0541, 0xFFFF, 0x0544, 0xFFFF, 0x0547, 0xFFFF,
756
  0x054A, 0xFFFF, 0x054D, 0xFFFF, 0x0550, 0xFFFF, 0x0553, 0xFFFF, 0x0556, 0xFFFF, 0x0559, 0xFFFF,
757
  0xFFFE, 0x055C, 0x055F, 0x0562, 0x0565, 0x0568, 0x056B, 0x056E, 0x0571, 0x0574, 0x0577, 0x057A,
758
  0x057D, 0x0580, 0x0583, 0x0586, 0x0589, 0x058C, 0x058F, 0x0592, 0x0595, 0x0598, 0x059B, 0x059E,
759
  0x05A1, 0x05A4, 0x05A7, 0x05AA, 0x05AD, 0x05B0, 0x05B3, 0x05B6, 0x05B9, 0x05BC, 0x05BF, 0x05C2,
760
  0x05C5, 0x05C8, 0x05CB, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
761
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
762
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
763
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
764
  0xFFFF, 0xFFFF, 0xFFFF, 0x05CE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
765
  0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
766
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
767
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
768
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
769
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
770
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
771
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
772
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
773
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x05D3, 0x05D8, 0x05DD, 0x05E2, 0xFFFF, 0xFFFF, 0xFFFF,
774
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
775
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
776
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x05E7, 0x05EE, 0x05F5, 0x05FC, 0x0603, 0x060A, 0x0611, 0x0618,
777
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
778
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
779
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
780
  0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE,
781
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
782
  0x061F, 0x0626, 0xFFFE, 0x062D, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF,
783
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
784
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE,
785
  0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE,
786
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
787
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
788
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
789
  0xFFFF, 0xFFFE, 0xFFFF, 0x0634, 0xFFFE, 0xFFFF, 0x063B, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE,
790
  0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF,
791
  0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFE, 0xFFFE,
792
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0642, 0x0649, 0x0650, 0xFFFF, 0xFFFE, 0x0657, 0xFFFE,
793
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
794
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE,
795
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
796
  0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE,
797
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
798
  0x065E, 0x0665, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF,
799
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
800
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
801
  0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
802
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
803
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
804
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
805
  0xFFFF, 0xFFFF, 0xFFFF, 0x066C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE,
806
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF,
807
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
808
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
809
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
810
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0673, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
811
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
812
  0xFFFF, 0xFFFE, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE,
813
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE,
814
  0x067A, 0x0681, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
815
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
816
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
817
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
818
  0x0688, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
819
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
820
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
821
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
822
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x068C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
823
  0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0693, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x069A, 0xFFFF,
824
  0xFFFF, 0xFFFF, 0xFFFF, 0x06A1, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x06A8, 0xFFFF, 0xFFFF, 0xFFFF,
825
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x06AF, 0xFFFF, 0xFFFF,
826
  0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0x06B6, 0xFFFF, 0x06BD, 0x06C4, 0x06CB,
827
  0x06D5, 0x06DC, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x06E6, 0xFFFF, 0xFFFF,
828
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
829
  0xFFFF, 0xFFFF, 0xFFFF, 0x06ED, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
830
  0xFFFF, 0x06F4, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x06FB, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0702,
831
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0709, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
832
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0710, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF,
833
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
834
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
835
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0717, 0x071B, 0x071F, 0x0723,
836
  0x0727, 0x072B, 0x072F, 0x0733, 0x0737, 0x073B, 0x073F, 0x0743, 0x0747, 0x074B, 0x074F, 0x0753,
837
  0x0757, 0x075B, 0x075F, 0x0763, 0x0767, 0x076B, 0x076F, 0x0773, 0x0777, 0x077B, 0x077F, 0x0783,
838
  0x0787, 0x078B, 0x078F, 0x0793, 0x0797, 0x079B, 0x079F, 0x07A3, 0x07A7, 0x07AB, 0xFFFE, 0x07AF,
839
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x07B3, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
840
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
841
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
842
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
843
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x07B7, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
844
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
845
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
846
  0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
847
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
848
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
849
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
850
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
851
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
852
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
853
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0x07BB, 0x07BF, 0x07C3, 0x07C7,
854
  0x07CB, 0x07CF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
855
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
856
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
857
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
858
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF,
859
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
860
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
861
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE,
862
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
863
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
864
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
865
  0x03D6, 0x03DC, 0x03FA, 0x0403, 0x0406, 0x0406, 0x041E, 0x0433, 0x07D3, 0x07D7, 0xFFFF, 0xFFFE,
866
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x07DB, 0x07DF, 0x07E3, 0x07E7, 0x07EB, 0x07EF, 0x07F3, 0x07F7,
867
  0x07FB, 0x07FF, 0x0803, 0x0807, 0x07B7, 0x080B, 0x080F, 0x0813, 0x0817, 0x081B, 0x081F, 0x0823,
868
  0x0827, 0x082B, 0x082F, 0x0833, 0x0837, 0x083B, 0x083F, 0x0843, 0x0847, 0x084B, 0x084F, 0x0853,
869
  0x0857, 0x085B, 0x085F, 0x0863, 0x0867, 0x086B, 0x086F, 0x0873, 0x0877, 0x087B, 0x087F, 0xFFFE,
870
  0xFFFE, 0x0883, 0x0887, 0x088B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
871
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
872
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
873
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
874
  0x0001, 0x0074, 0x0003, 0xFFFF, 0x0007, 0x0009, 0x0197, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015,
875
  0x0017, 0x0019, 0x001B, 0xFFFF, 0x001D, 0x0273, 0x001F, 0x0023, 0x0027, 0x0029, 0x002D, 0x0001,
876
  0x088F, 0x0892, 0x0895, 0x0003, 0x0007, 0x0009, 0x019A, 0x019D, 0x0899, 0x000D, 0xFFFF, 0x0015,
877
  0x0019, 0x012E, 0x001D, 0x0188, 0x089C, 0x08A0, 0x001F, 0x0027, 0x0029, 0x08A4, 0x01B2, 0x002B,
878
  0x08A8, 0x0325, 0x0328, 0x032B, 0x0358, 0x035B, 0x0011, 0x0023, 0x0029, 0x002B, 0x0325, 0x0328,
879
  0x034C, 0x0358, 0x035B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
880
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x03F7, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
881
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
882
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
883
  0xFFFF, 0xFFFF, 0xFFFF, 0x08AC, 0x0005, 0x08AF, 0x0092, 0x0899, 0x000B, 0x08B2, 0x08B5, 0x08B8,
884
  0x01AC, 0x01A9, 0x08BB, 0x08BE, 0x08C2, 0x08C5, 0x08C8, 0x08CC, 0x08CF, 0x08D2, 0x01B5, 0x08D5,
885
  0x08D8, 0x01B8, 0x08DB, 0x08DE, 0x01CA, 0x08E1, 0x02A2, 0x01D6, 0x08E4, 0x01D9, 0x02A5, 0x0033,
886
  0x08E8, 0x08EB, 0x01E2, 0x0337, 0x08EE, 0xFFFF, 0x08F2, 0xFFFF, 0x08F6, 0xFFFF, 0x08FA, 0xFFFF,
887
  0x08FE, 0xFFFF, 0x0902, 0xFFFF, 0x0906, 0xFFFF, 0x090A, 0xFFFF, 0x090E, 0xFFFF, 0x0912, 0xFFFF,
888
  0x0916, 0xFFFF, 0x091A, 0xFFFF, 0x091E, 0xFFFF, 0x0922, 0xFFFF, 0x0926, 0xFFFF, 0x092A, 0xFFFF,
889
  0x092E, 0xFFFF, 0x0932, 0xFFFF, 0x0936, 0xFFFF, 0x093A, 0xFFFF, 0x093E, 0xFFFF, 0x0942, 0xFFFF,
890
  0x0946, 0xFFFF, 0x094A, 0xFFFF, 0x094E, 0xFFFF, 0x0952, 0xFFFF, 0x0956, 0xFFFF, 0x095A, 0xFFFF,
891
  0x095E, 0xFFFF, 0x0962, 0xFFFF, 0x0966, 0xFFFF, 0x096A, 0xFFFF, 0x096E, 0xFFFF, 0x0972, 0xFFFF,
892
  0x0976, 0xFFFF, 0x097A, 0xFFFF, 0x097E, 0xFFFF, 0x0982, 0xFFFF, 0x0986, 0xFFFF, 0x098A, 0xFFFF,
893
  0x098E, 0xFFFF, 0x0992, 0xFFFF, 0x0996, 0xFFFF, 0x099A, 0xFFFF, 0x099E, 0xFFFF, 0x09A2, 0xFFFF,
894
  0x09A6, 0xFFFF, 0x09AA, 0xFFFF, 0x09AE, 0xFFFF, 0x09B2, 0xFFFF, 0x09B6, 0xFFFF, 0x09BA, 0xFFFF,
895
  0x09BE, 0xFFFF, 0x09C2, 0xFFFF, 0x09C6, 0xFFFF, 0x09CA, 0xFFFF, 0x09CE, 0xFFFF, 0x09D2, 0xFFFF,
896
  0x09D6, 0xFFFF, 0x09DA, 0xFFFF, 0x09DE, 0xFFFF, 0x09E2, 0xFFFF, 0x09E6, 0xFFFF, 0x09EA, 0xFFFF,
897
  0x09EE, 0xFFFF, 0x09F2, 0xFFFF, 0x09F6, 0xFFFF, 0x09FA, 0xFFFF, 0x09FE, 0xFFFF, 0x0A02, 0xFFFF,
898
  0x0A06, 0xFFFF, 0x0A0A, 0xFFFF, 0x0A0E, 0xFFFF, 0x0A12, 0xFFFF, 0x0A16, 0xFFFF, 0xFFFF, 0xFFFF,
899
  0xFFFF, 0xFFFF, 0x0A1A, 0x09AE, 0xFFFF, 0xFFFF, 0x0A1E, 0xFFFF, 0x0A21, 0xFFFF, 0x0A25, 0xFFFF,
900
  0x0A29, 0xFFFF, 0x0A2D, 0xFFFF, 0x0A31, 0xFFFF, 0x0A35, 0xFFFF, 0x0A39, 0xFFFF, 0x0A3D, 0xFFFF,
901
  0x0A41, 0xFFFF, 0x0A45, 0xFFFF, 0x0A49, 0xFFFF, 0x0A4D, 0xFFFF, 0x0A51, 0xFFFF, 0x0A55, 0xFFFF,
902
  0x0A59, 0xFFFF, 0x0A5D, 0xFFFF, 0x0A61, 0xFFFF, 0x0A65, 0xFFFF, 0x0A69, 0xFFFF, 0x0A6D, 0xFFFF,
903
  0x0A71, 0xFFFF, 0x0A75, 0xFFFF, 0x0A79, 0xFFFF, 0x0A7D, 0xFFFF, 0x0A81, 0xFFFF, 0x0A85, 0xFFFF,
904
  0x0A89, 0xFFFF, 0x0A8D, 0xFFFF, 0x0A91, 0xFFFF, 0x0A95, 0xFFFF, 0x0A99, 0xFFFF, 0x0A9D, 0xFFFF,
905
  0x0AA1, 0xFFFF, 0x0AA5, 0xFFFF, 0x0AA9, 0xFFFF, 0x0AAD, 0xFFFF, 0x0AB1, 0xFFFF, 0x0AB5, 0xFFFF,
906
  0x0AB9, 0xFFFF, 0x0ABD, 0xFFFF, 0x0AC1, 0xFFFF, 0x0AC5, 0xFFFF, 0x0AC9, 0xFFFF, 0x0ACD, 0xFFFF,
907
  0x0AD1, 0xFFFF, 0x0AD5, 0xFFFF, 0x0AD9, 0xFFFF, 0x0ADD, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
908
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0AE1, 0x0AE5, 0x0AE9, 0x0AED, 0x0AF1, 0x0AF5, 0x0AF9, 0x0AFD,
909
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0x0B01, 0x0B05, 0x0B09, 0x0B0D,
910
  0x0B11, 0x0B15, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
911
  0x0B19, 0x0B1D, 0x0B21, 0x0B25, 0x0B29, 0x0B2D, 0x0B31, 0x0B35, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
912
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0B39, 0x0B3D, 0x0B41, 0x0B45, 0x0B49, 0x0B4D, 0x0B51, 0x0B55,
913
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0x0B59, 0x0B5D, 0x0B61, 0x0B65,
914
  0x0B69, 0x0B6D, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
915
  0xFFFE, 0x0B71, 0xFFFE, 0x0B75, 0xFFFE, 0x0B79, 0xFFFE, 0x0B7D, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
916
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0B81, 0x0B85, 0x0B89, 0x0B8D, 0x0B91, 0x0B95, 0x0B99, 0x0B9D,
917
  0xFFFF, 0x030A, 0xFFFF, 0x0310, 0xFFFF, 0x0313, 0xFFFF, 0x0316, 0xFFFF, 0x0319, 0xFFFF, 0x031C,
918
  0xFFFF, 0x031F, 0xFFFE, 0xFFFE, 0x0BA1, 0x0BA7, 0x0BAD, 0x0BB3, 0x0BB9, 0x0BBF, 0x0BC5, 0x0BCB,
919
  0x0BA1, 0x0BA7, 0x0BAD, 0x0BB3, 0x0BB9, 0x0BBF, 0x0BC5, 0x0BCB, 0x0BD1, 0x0BD7, 0x0BDD, 0x0BE3,
920
  0x0BE9, 0x0BEF, 0x0BF5, 0x0BFB, 0x0BD1, 0x0BD7, 0x0BDD, 0x0BE3, 0x0BE9, 0x0BEF, 0x0BF5, 0x0BFB,
921
  0x0C01, 0x0C07, 0x0C0D, 0x0C13, 0x0C19, 0x0C1F, 0x0C25, 0x0C2B, 0x0C01, 0x0C07, 0x0C0D, 0x0C13,
922
  0x0C19, 0x0C1F, 0x0C25, 0x0C2B, 0xFFFF, 0xFFFF, 0x0C31, 0x0C37, 0x0C3C, 0xFFFE, 0xFFFF, 0x0C41,
923
  0x0C47, 0x0C4B, 0x0C4F, 0x030A, 0x0C37, 0x0C53, 0x02EC, 0x0C53, 0x0C57, 0x0C5B, 0x0C61, 0x0C67,
924
  0x0C6C, 0xFFFE, 0xFFFF, 0x0C71, 0x0C77, 0x0310, 0x0C7B, 0x0313, 0x0C67, 0x0C7F, 0x0C85, 0x0C8B,
925
  0xFFFF, 0xFFFF, 0xFFFF, 0x0C91, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0x0C94, 0x0C98, 0x0C9C, 0x0316,
926
  0xFFFE, 0x0CA0, 0x0CA6, 0x0CAC, 0xFFFF, 0xFFFF, 0xFFFF, 0x0CB2, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
927
  0x0CB5, 0x0CB9, 0x0CBD, 0x031C, 0x0CC1, 0x0CC5, 0x0304, 0x0CCB, 0xFFFE, 0xFFFE, 0x0CCD, 0x0CD3,
928
  0x0CD8, 0xFFFE, 0xFFFF, 0x0CDD, 0x0CE3, 0x0319, 0x0CE7, 0x031F, 0x0CD3, 0x0043, 0x0CEB, 0xFFFE,
929
  0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0035, 0x0000,
930
  0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0x0CEF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0CF3,
931
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
932
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0035,
933
  0xFFFF, 0xFFFF, 0xFFFF, 0x0CF7, 0x0CFE, 0xFFFF, 0x0D08, 0x0D0F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
934
  0x0D19, 0xFFFF, 0x0D1C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0D20,
935
  0x0D23, 0x0D26, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
936
  0xFFFF, 0xFFFF, 0xFFFF, 0x0D29, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0035,
937
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0000, 0x0000,
938
  0x0000, 0x0000, 0x0000, 0x0000, 0x0D36, 0x0011, 0xFFFE, 0xFFFE, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E,
939
  0x0D40, 0x0D42, 0x0D44, 0x0D46, 0x0D4A, 0x0D4C, 0x0D4E, 0x001B, 0x0D36, 0x004E, 0x003F, 0x0041,
940
  0x0D38, 0x0D3A, 0x0D3C, 0x0D3E, 0x0D40, 0x0D42, 0x0D44, 0x0D46, 0x0D4A, 0x0D4C, 0x0D4E, 0xFFFE,
941
  0x0001, 0x0009, 0x001D, 0x002F, 0x019A, 0x000F, 0x0015, 0x0017, 0x0019, 0x001B, 0x001F, 0x0025,
942
  0x0027, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
943
  0x0D50, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
944
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
945
  0x0D53, 0x0D57, 0x0005, 0x0D5B, 0xFFFF, 0x0D5F, 0x0D63, 0x019D, 0xFFFF, 0x0D67, 0x000D, 0x000F,
946
  0x000F, 0x000F, 0x000F, 0x00F5, 0x0011, 0x0011, 0x0017, 0x0017, 0xFFFF, 0x001B, 0x0D6B, 0xFFFF,
947
  0xFFFF, 0x001F, 0x0021, 0x0023, 0x0023, 0x0023, 0xFFFF, 0xFFFF, 0x0D6E, 0x0D71, 0x0D75, 0xFFFF,
948
  0x0033, 0xFFFF, 0x0361, 0xFFFF, 0x0033, 0xFFFF, 0x0015, 0x0071, 0x0003, 0x0005, 0xFFFF, 0x0009,
949
  0x0009, 0x000B, 0x0D78, 0x0019, 0x001D, 0x0D7C, 0x0D7F, 0x0D82, 0x0D85, 0x0011, 0xFFFF, 0x0D88,
950
  0x0349, 0x0328, 0x0328, 0x0349, 0x0D8C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0007, 0x0007, 0x0009,
951
  0x0011, 0x0013, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0D90, 0x0D96, 0x0D9C, 0x0DA3,
952
  0x0DA9, 0x0DAF, 0x0DB5, 0x0DBB, 0x0DC1, 0x0DC7, 0x0DCD, 0x0DD3, 0x0DD9, 0x0DDF, 0x0DE5, 0x0DEB,
953
  0x0011, 0x0DF0, 0x0DF3, 0x0DF7, 0x002B, 0x0DFA, 0x0DFD, 0x0E01, 0x0E06, 0x002F, 0x0E09, 0x0E0C,
954
  0x0017, 0x0005, 0x0007, 0x0019, 0x0011, 0x0DF0, 0x0DF3, 0x0DF7, 0x002B, 0x0DFA, 0x0DFD, 0x0E01,
955
  0x0E06, 0x002F, 0x0E09, 0x0E0C, 0x0017, 0x0005, 0x0007, 0x0019, 0xFFFF, 0xFFFF, 0xFFFF, 0x0E10,
956
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0E14, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
957
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
958
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
959
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
960
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
961
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
962
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
963
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
964
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0E1A, 0x0E21, 0xFFFF, 0x0E2B,
965
  0x0E32, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
966
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
967
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
968
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
969
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0E3C, 0x0E40, 0xFFFF,
970
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
971
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
972
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
973
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
974
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E, 0x0D40,
975
  0x0D42, 0x0E44, 0x0E47, 0x0E4A, 0x0E4D, 0x0E50, 0x0E53, 0x0E56, 0x0E59, 0x0E5C, 0x0E5F, 0x0E62,
976
  0x0E65, 0x0E69, 0x0E6D, 0x0E71, 0x0E75, 0x0E79, 0x0E7D, 0x0E81, 0x0E85, 0x0E89, 0x0E8E, 0x0E93,
977
  0x0E98, 0x0E9D, 0x0EA2, 0x0EA7, 0x0EAC, 0x0EB1, 0x0EB6, 0x0EBB, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
978
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
979
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0EC0, 0x0EC4, 0x0EC8, 0x0ECC, 0x0ED0, 0x0ED4, 0x0ED8, 0x0EDC,
980
  0x0EE0, 0x0EE4, 0x0EE8, 0x0EEC, 0x0EF0, 0x0EF4, 0x0EF8, 0x0EFC, 0x0F00, 0x0F04, 0x0F08, 0x0F0C,
981
  0x0F10, 0x0F14, 0x0F18, 0x0F1C, 0x0F20, 0x0F24, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B,
982
  0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023,
983
  0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007,
984
  0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F,
985
  0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0D36, 0xFFFF,
986
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
987
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
988
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0F28, 0xFFFF, 0xFFFF, 0xFFFF,
989
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
990
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
991
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
992
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
993
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
994
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
995
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
996
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
997
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0F35, 0x0F39, 0x0F3C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
998
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
999
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1000
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0F40, 0xFFFF, 0xFFFF, 0xFFFF,
1001
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1002
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1003
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0F46, 0x0F4A, 0x0F4E, 0x0F52,
1004
  0x0F56, 0x0F5A, 0x0F5E, 0x0F62, 0x0F66, 0x0F6A, 0x0F6E, 0x0F72, 0x0F76, 0x0F7A, 0x0F7E, 0x0F82,
1005
  0x0F86, 0x0F8A, 0x0F8E, 0x0F92, 0x0F96, 0x0F9A, 0x0F9E, 0x0FA2, 0x0FA6, 0x0FAA, 0x0FAE, 0x0FB2,
1006
  0x0FB6, 0x0FBA, 0x0FBE, 0x0FC2, 0x0FC6, 0x0FCA, 0x0FCE, 0x0FD2, 0x0FD6, 0x0FDA, 0x0FDE, 0x0FE2,
1007
  0x0FE6, 0x0FEA, 0x0FEE, 0x0FF2, 0x0FF6, 0x0FFA, 0x0FFE, 0x1002, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1008
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1009
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1010
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1011
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x1006, 0xFFFF, 0x100A, 0x100D,
1012
  0x1011, 0xFFFF, 0xFFFF, 0x1014, 0xFFFF, 0x1018, 0xFFFF, 0x101C, 0xFFFF, 0x0892, 0x08CF, 0x088F,
1013
  0x08AC, 0xFFFF, 0x1020, 0xFFFF, 0xFFFF, 0x1024, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1014
  0x0013, 0x002B, 0x1028, 0x102B, 0x102E, 0xFFFF, 0x1032, 0xFFFF, 0x1036, 0xFFFF, 0x103A, 0xFFFF,
1015
  0x103E, 0xFFFF, 0x1042, 0xFFFF, 0x1046, 0xFFFF, 0x104A, 0xFFFF, 0x104E, 0xFFFF, 0x1052, 0xFFFF,
1016
  0x1056, 0xFFFF, 0x105A, 0xFFFF, 0x105E, 0xFFFF, 0x1062, 0xFFFF, 0x1066, 0xFFFF, 0x106A, 0xFFFF,
1017
  0x106E, 0xFFFF, 0x1072, 0xFFFF, 0x1076, 0xFFFF, 0x107A, 0xFFFF, 0x107E, 0xFFFF, 0x1082, 0xFFFF,
1018
  0x1086, 0xFFFF, 0x108A, 0xFFFF, 0x108E, 0xFFFF, 0x1092, 0xFFFF, 0x1096, 0xFFFF, 0x109A, 0xFFFF,
1019
  0x109E, 0xFFFF, 0x10A2, 0xFFFF, 0x10A6, 0xFFFF, 0x10AA, 0xFFFF, 0x10AE, 0xFFFF, 0x10B2, 0xFFFF,
1020
  0x10B6, 0xFFFF, 0x10BA, 0xFFFF, 0x10BE, 0xFFFF, 0x10C2, 0xFFFF, 0x10C6, 0xFFFF, 0x10CA, 0xFFFF,
1021
  0x10CE, 0xFFFF, 0x10D2, 0xFFFF, 0x10D6, 0xFFFF, 0x10DA, 0xFFFF, 0x10DE, 0xFFFF, 0x10E2, 0xFFFF,
1022
  0x10E6, 0xFFFF, 0x10EA, 0xFFFF, 0x10EE, 0xFFFF, 0x10F2, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1023
  0xFFFF, 0xFFFF, 0xFFFF, 0x10F6, 0xFFFF, 0x10FA, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x10FE, 0xFFFF,
1024
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1025
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1026
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1027
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1028
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x1102,
1029
  0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1030
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1031
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1032
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x1106,
1033
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1034
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1035
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1036
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1037
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1038
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1039
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x110A,
1040
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1041
  0x110E, 0x1112, 0x1116, 0x111A, 0x111E, 0x1122, 0x1126, 0x112A, 0x112E, 0x1132, 0x1136, 0x113A,
1042
  0x113E, 0x1142, 0x1146, 0x114A, 0x114E, 0x1152, 0x1156, 0x115A, 0x115E, 0x1162, 0x1166, 0x116A,
1043
  0x116E, 0x1172, 0x1176, 0x117A, 0x117E, 0x1182, 0x1186, 0x118A, 0x118E, 0x1192, 0x1196, 0x119A,
1044
  0x119E, 0x11A2, 0x11A6, 0x11AA, 0x11AE, 0x11B2, 0x11B6, 0x11BA, 0x11BE, 0x11C2, 0x11C6, 0x11CA,
1045
  0x11CE, 0x11D2, 0x11D6, 0x11DA, 0x11DE, 0x11E2, 0x11E6, 0x11EA, 0x11EE, 0x11F2, 0x11F6, 0x11FA,
1046
  0x11FE, 0x1202, 0x1206, 0x120A, 0x120E, 0x1212, 0x1216, 0x121A, 0x121E, 0x1222, 0x1226, 0x122A,
1047
  0x122E, 0x1232, 0x1236, 0x123A, 0x123E, 0x1242, 0x1246, 0x124A, 0x124E, 0x1252, 0x1256, 0x125A,
1048
  0x125E, 0x1262, 0x1266, 0x126A, 0x126E, 0x1272, 0x1276, 0x127A, 0x127E, 0x1282, 0x1286, 0x128A,
1049
  0x128E, 0x1292, 0x1296, 0x129A, 0x129E, 0x12A2, 0x12A6, 0x12AA, 0x12AE, 0x12B2, 0x12B6, 0x12BA,
1050
  0x12BE, 0x12C2, 0x12C6, 0x12CA, 0x12CE, 0x12D2, 0x12D6, 0x12DA, 0x12DE, 0x12E2, 0x12E6, 0x12EA,
1051
  0x12EE, 0x12F2, 0x12F6, 0x12FA, 0x12FE, 0x1302, 0x1306, 0x130A, 0x130E, 0x1312, 0x1316, 0x131A,
1052
  0x131E, 0x1322, 0x1326, 0x132A, 0x132E, 0x1332, 0x1336, 0x133A, 0x133E, 0x1342, 0x1346, 0x134A,
1053
  0x134E, 0x1352, 0x1356, 0x135A, 0x135E, 0x1362, 0x1366, 0x136A, 0x136E, 0x1372, 0x1376, 0x137A,
1054
  0x137E, 0x1382, 0x1386, 0x138A, 0x138E, 0x1392, 0x1396, 0x139A, 0x139E, 0x13A2, 0x13A6, 0x13AA,
1055
  0x13AE, 0x13B2, 0x13B6, 0x13BA, 0x13BE, 0x13C2, 0x13C6, 0x13CA, 0x13CE, 0x13D2, 0x13D6, 0x13DA,
1056
  0x13DE, 0x13E2, 0x13E6, 0x13EA, 0x13EE, 0x13F2, 0x13F6, 0x13FA, 0x13FE, 0x1402, 0x1406, 0x140A,
1057
  0x140E, 0x1412, 0x1416, 0x141A, 0x141E, 0x1422, 0x1426, 0x142A, 0x142E, 0x1432, 0x1436, 0x143A,
1058
  0x143E, 0x1442, 0x1446, 0x144A, 0x144E, 0x1452, 0x1456, 0x145A, 0x145E, 0x1462, 0xFFFE, 0xFFFE,
1059
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1060
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1061
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1062
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0035, 0xFFFF, 0x1466, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1063
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1064
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1065
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1066
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x1468, 0xFFFF,
1067
  0x116A, 0x146C, 0x1470, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1068
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1069
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0x1474,
1070
  0x1479, 0xFFFF, 0xFFFF, 0x147E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1071
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1072
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1073
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1074
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1075
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1076
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1077
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1078
  0xFFFF, 0xFFFF, 0xFFFF, 0x1485, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
1079
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1080
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1081
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1082
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0x148C, 0x1490, 0x1494, 0x1498, 0x149C, 0x14A0, 0x14A4,
1083
  0x14A8, 0x14AC, 0x14B0, 0x14B4, 0x14B8, 0x14BC, 0x14C0, 0x14C4, 0x14C8, 0x14CC, 0x14D0, 0x14D4,
1084
  0x14D8, 0x14DC, 0x14E0, 0x14E4, 0x14E8, 0x14EC, 0x14F0, 0x14F4, 0x14F8, 0x14FC, 0x1500, 0x1504,
1085
  0x1508, 0x150C, 0x1510, 0x1514, 0x1518, 0x151C, 0x1520, 0x1524, 0x1528, 0x152C, 0x1530, 0x1534,
1086
  0x1538, 0x153C, 0x1540, 0x1544, 0x1548, 0x154C, 0x1550, 0x1554, 0x0000, 0x1558, 0x155C, 0x1560,
1087
  0x1564, 0x1568, 0x156C, 0x1570, 0x1574, 0x1578, 0x157C, 0x1580, 0x1584, 0x1588, 0x158C, 0x1590,
1088
  0x1594, 0x1598, 0x159C, 0x15A0, 0x15A4, 0x15A8, 0x15AC, 0x15B0, 0x15B4, 0x15B8, 0x15BC, 0x15C0,
1089
  0x15C4, 0x15C8, 0x15CC, 0x15D0, 0x15D4, 0x15D8, 0x15DC, 0x15E0, 0x15E4, 0x15E8, 0x15EC, 0x15F0,
1090
  0x15F4, 0x15F8, 0x15FC, 0xFFFE, 0xFFFF, 0xFFFF, 0x110E, 0x1126, 0x1600, 0x1604, 0x1608, 0x160C,
1091
  0x1610, 0x1614, 0x111E, 0x1618, 0x161C, 0x1620, 0x1624, 0x112E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1092
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1093
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1094
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x1628, 0x162E, 0x1634, 0x163A, 0x1640, 0x1646, 0x164C, 0x1652,
1095
  0x1658, 0x165E, 0x1664, 0x166A, 0x1670, 0x1676, 0x167C, 0x1682, 0x1688, 0x168E, 0x1694, 0x169A,
1096
  0x16A0, 0x16A6, 0x16AC, 0x16B2, 0x16B8, 0x16BE, 0x16C4, 0x16CA, 0x16D0, 0x16D6, 0x16DF, 0xFFFE,
1097
  0x16E8, 0x16EE, 0x16F4, 0x16FA, 0x1700, 0x1706, 0x170C, 0x1712, 0x1718, 0x171E, 0x1724, 0x172A,
1098
  0x1730, 0x1736, 0x173C, 0x1742, 0x1748, 0x174E, 0x1754, 0x175A, 0x1760, 0x1766, 0x176C, 0x1772,
1099
  0x1778, 0x177E, 0x1784, 0x178A, 0x1790, 0x1796, 0x179C, 0x17A2, 0x17A8, 0x17AE, 0x17B4, 0x17BA,
1100
  0x17C0, 0x17C4, 0x1216, 0x17C8, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1101
  0x17CC, 0x17D0, 0x17D3, 0x17D6, 0x17D9, 0x17DC, 0x17DF, 0x17E2, 0x17E5, 0x17E8, 0x17EB, 0x17EE,
1102
  0x17F1, 0x17F4, 0x17F7, 0x17FA, 0x148C, 0x1498, 0x14A4, 0x14AC, 0x14CC, 0x14D0, 0x14DC, 0x14E4,
1103
  0x14E8, 0x14F0, 0x14F4, 0x14F8, 0x14FC, 0x1500, 0x17FD, 0x1801, 0x1805, 0x1809, 0x180D, 0x1811,
1104
  0x1815, 0x1819, 0x181D, 0x1821, 0x1825, 0x1829, 0x182D, 0x1831, 0x1835, 0x183C, 0x1843, 0xFFFF,
1105
  0x110E, 0x1126, 0x1600, 0x1604, 0x1847, 0x184B, 0x184F, 0x113A, 0x1853, 0x116A, 0x1232, 0x1262,
1106
  0x125E, 0x1236, 0x13A6, 0x118A, 0x122A, 0x1857, 0x185B, 0x185F, 0x1863, 0x1867, 0x186B, 0x186F,
1107
  0x1873, 0x1877, 0x187B, 0x11A2, 0x187F, 0x1883, 0x1887, 0x188B, 0x188F, 0x1893, 0x1897, 0x189B,
1108
  0x1608, 0x160C, 0x1610, 0x189F, 0x18A3, 0x18A7, 0x18AB, 0x18AF, 0x18B3, 0x18B7, 0x18BB, 0x18BF,
1109
  0x18C3, 0x18C7, 0x18CA, 0x18CD, 0x18D0, 0x18D3, 0x18D6, 0x18D9, 0x18DC, 0x18DF, 0x18E2, 0x18E5,
1110
  0x18E8, 0x18EB, 0x18EE, 0x18F1, 0x18F4, 0x18F9, 0x18FE, 0x1903, 0x1908, 0x190D, 0x1912, 0x1917,
1111
  0x191C, 0x1921, 0x1927, 0x192D, 0x1933, 0x1936, 0x193A, 0x193D, 0x1941, 0x1945, 0x1949, 0x194D,
1112
  0x1951, 0x1955, 0x1959, 0x195D, 0x1961, 0x1965, 0x1969, 0x196D, 0x1971, 0x1975, 0x1979, 0x197D,
1113
  0x1981, 0x1985, 0x1989, 0x198D, 0x1991, 0x1995, 0x1999, 0x199D, 0x19A1, 0x19A5, 0x19A9, 0x19AD,
1114
  0x19B1, 0x19B5, 0x19B9, 0x19BD, 0x19C1, 0x19C5, 0x19C9, 0x19CD, 0x19D1, 0x19D5, 0x19D9, 0x19DD,
1115
  0x19E1, 0x19E5, 0x19E9, 0x19ED, 0x19F1, 0x19F5, 0x19F9, 0x19FD, 0x1A04, 0x1A11, 0x1A1E, 0x1A2B,
1116
  0x1A35, 0x1A42, 0x1A4C, 0x1A56, 0x1A66, 0x1A73, 0x1A7D, 0x1A87, 0x1A91, 0x1A9E, 0x1AAB, 0x1AB5,
1117
  0x1ABF, 0x1AC6, 0x1AD0, 0x1ADD, 0x1AEA, 0x1AF1, 0x1B01, 0x1B14, 0x1B24, 0x1B2E, 0x1B3E, 0x1B4E,
1118
  0x1B5B, 0x1B65, 0x1B6F, 0x1B79, 0x1B86, 0x1B96, 0x1BA3, 0x1BAD, 0x1BB7, 0x1BC1, 0x1BC8, 0x1BCF,
1119
  0x1BD6, 0x1BDD, 0x1BE7, 0x1BF1, 0x1C01, 0x1C0B, 0x1C18, 0x1C28, 0x1C32, 0x1C39, 0x1C40, 0x1C50,
1120
  0x1C5D, 0x1C6D, 0x1C77, 0x1C87, 0x1C8E, 0x1C98, 0x1CA2, 0x1CAC, 0x1CB6, 0x1CC0, 0x1CCD, 0x1CD7,
1121
  0x1CDE, 0x1CE8, 0x1CF2, 0x1CFC, 0x1D09, 0x1D13, 0x1D1D, 0x1D27, 0x1D37, 0x1D44, 0x1D4B, 0x1D5B,
1122
  0x1D62, 0x1D6F, 0x1D7C, 0x1D86, 0x1D90, 0x1D9A, 0x1DA7, 0x1DAE, 0x1DB8, 0x1DC5, 0x1DCC, 0x1DDC,
1123
  0x1DE6, 0x1DEB, 0x1DF0, 0x1DF5, 0x1DFA, 0x1DFF, 0x1E04, 0x1E09, 0x1E0E, 0x1E13, 0x1E18, 0x1E1E,
1124
  0x1E24, 0x1E2A, 0x1E30, 0x1E36, 0x1E3C, 0x1E42, 0x1E48, 0x1E4E, 0x1E54, 0x1E5A, 0x1E60, 0x1E66,
1125
  0x1E6C, 0x1E72, 0x1E76, 0x1E79, 0x1E7C, 0x1E80, 0x1E83, 0x1E86, 0x1E89, 0x1E8D, 0x1E91, 0x1E94,
1126
  0x1E9B, 0x1EA2, 0x1EA9, 0x1EB0, 0x1EBD, 0x1EC0, 0x1EC3, 0x1EC7, 0x1ECA, 0x1ECD, 0x1ED0, 0x1ED3,
1127
  0x1ED6, 0x1EDA, 0x1EDF, 0x1EE2, 0x1EE5, 0x1EE9, 0x1EED, 0x1EF0, 0x1EF3, 0x1EF6, 0x1EFA, 0x1EFE,
1128
  0x1F02, 0x1F06, 0x1F0A, 0x1F0D, 0x1F10, 0x1F13, 0x1F16, 0x1F19, 0x1F1D, 0x1F20, 0x1F23, 0x1F26,
1129
  0x1F2A, 0x1F2E, 0x1F31, 0x1F35, 0x1F39, 0x1F3D, 0x1F40, 0x1F44, 0x1F4A, 0x1EBD, 0x1F51, 0x1F55,
1130
  0x1F59, 0x1F5D, 0x1F61, 0x1F69, 0x1F72, 0x1F75, 0x1F78, 0x1F7C, 0x1F7F, 0x1F82, 0x1F85, 0x1F89,
1131
  0x1F8C, 0x1F89, 0x1F8F, 0x1F92, 0x1F95, 0x1F99, 0x1F9C, 0x1F99, 0x1F9F, 0x1FA3, 0xFFFE, 0x1FA7,
1132
  0x1FAA, 0x1FAD, 0x1FB0, 0xFFFE, 0x1FB7, 0x1FBA, 0x1FBD, 0x1FC0, 0x1FC3, 0x1FC6, 0x1F23, 0x1FC9,
1133
  0x1FCC, 0x1FCF, 0x1FD2, 0x1FD6, 0x1ED0, 0x1FD9, 0x1FDD, 0x1FE1, 0xFFFE, 0x1FE4, 0x1FE8, 0x1FEB,
1134
  0x1FEE, 0x1FF1, 0x1FF4, 0x1FFA, 0x2000, 0x2005, 0x200A, 0x200F, 0x2014, 0x2019, 0x201E, 0x2023,
1135
  0x2028, 0x202D, 0x2033, 0x2039, 0x203F, 0x2045, 0x204B, 0x2051, 0x2057, 0x205D, 0x2063, 0x2069,
1136
  0x206F, 0x2075, 0x207B, 0x2081, 0x2087, 0x208D, 0x2093, 0x2099, 0x209F, 0x20A5, 0x20AB, 0x20B1,
1137
  0x20B5, 0xFFFF, 0x20B9, 0xFFFF, 0x20BD, 0xFFFF, 0x20C1, 0xFFFF, 0x20C5, 0xFFFF, 0x07D3, 0xFFFF,
1138
  0x20C9, 0xFFFF, 0x20CD, 0xFFFF, 0x20D1, 0xFFFF, 0x20D5, 0xFFFF, 0x20D9, 0xFFFF, 0x20DD, 0xFFFF,
1139
  0x20E1, 0xFFFF, 0x20E5, 0xFFFF, 0x20E9, 0xFFFF, 0x20ED, 0xFFFF, 0x20F1, 0xFFFF, 0x20F5, 0xFFFF,
1140
  0x20F9, 0xFFFF, 0x20FD, 0xFFFF, 0x2101, 0xFFFF, 0x2105, 0xFFFF, 0x2109, 0xFFFF, 0xFFFF, 0xFFFF,
1141
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1142
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x210D, 0xFFFF, 0x2111, 0xFFFF, 0x2115, 0xFFFF, 0x2119, 0xFFFF,
1143
  0x211D, 0xFFFF, 0x2121, 0xFFFF, 0x2125, 0xFFFF, 0x2129, 0xFFFF, 0x212D, 0xFFFF, 0x2131, 0xFFFF,
1144
  0x2135, 0xFFFF, 0x2139, 0xFFFF, 0x213D, 0xFFFF, 0x2141, 0xFFFF, 0x041E, 0x0424, 0xFFFF, 0xFFFF,
1145
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1146
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1147
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1148
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1149
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1150
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x2145, 0xFFFF, 0x2149, 0xFFFF, 0x214D, 0xFFFF,
1151
  0x2151, 0xFFFF, 0x2155, 0xFFFF, 0x2159, 0xFFFF, 0x215D, 0xFFFF, 0xFFFF, 0xFFFF, 0x2161, 0xFFFF,
1152
  0x2165, 0xFFFF, 0x2169, 0xFFFF, 0x216D, 0xFFFF, 0x2171, 0xFFFF, 0x2175, 0xFFFF, 0x2179, 0xFFFF,
1153
  0x217D, 0xFFFF, 0x2181, 0xFFFF, 0x2185, 0xFFFF, 0x2189, 0xFFFF, 0x218D, 0xFFFF, 0x2191, 0xFFFF,
1154
  0x2195, 0xFFFF, 0x2199, 0xFFFF, 0x219D, 0xFFFF, 0x21A1, 0xFFFF, 0x21A5, 0xFFFF, 0x21A9, 0xFFFF,
1155
  0x21AD, 0xFFFF, 0x21B1, 0xFFFF, 0x21B5, 0xFFFF, 0x21B9, 0xFFFF, 0x21BD, 0xFFFF, 0x21C1, 0xFFFF,
1156
  0x21C5, 0xFFFF, 0x21C9, 0xFFFF, 0x21CD, 0xFFFF, 0x21D1, 0xFFFF, 0x21D5, 0xFFFF, 0x21D9, 0xFFFF,
1157
  0x21D9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x21DD, 0xFFFF, 0x21E1,
1158
  0xFFFF, 0x21E5, 0x21E9, 0xFFFF, 0x21ED, 0xFFFF, 0x21F1, 0xFFFF, 0x21F5, 0xFFFF, 0x21F9, 0xFFFF,
1159
  0xFFFF, 0xFFFF, 0xFFFF, 0x21FD, 0xFFFF, 0x08B8, 0xFFFF, 0xFFFF, 0x2201, 0xFFFF, 0x2205, 0xFFFF,
1160
  0xFFFF, 0xFFFF, 0x2209, 0xFFFF, 0x220D, 0xFFFF, 0x2211, 0xFFFF, 0x2215, 0xFFFF, 0x2219, 0xFFFF,
1161
  0x221D, 0xFFFF, 0x2221, 0xFFFF, 0x2225, 0xFFFF, 0x2229, 0xFFFF, 0x222D, 0xFFFF, 0x02B7, 0x0899,
1162
  0x08B5, 0x2231, 0x08BB, 0xFFFF, 0x2234, 0x2237, 0x08C2, 0x223A, 0x223E, 0xFFFF, 0x2242, 0xFFFF,
1163
  0x2246, 0xFFFF, 0x224A, 0xFFFF, 0x224E, 0xFFFF, 0x2252, 0xFFFF, 0x2256, 0xFFFF, 0x225A, 0xFFFF,
1164
  0x225E, 0x08DE, 0x2262, 0x2266, 0xFFFF, 0x226A, 0xFFFF, 0x226E, 0x2271, 0xFFFF, 0x2275, 0xFFFF,
1165
  0x2279, 0xFFFF, 0x227D, 0xFFFF, 0x2281, 0xFFFF, 0x2285, 0xFFFF, 0x2289, 0xFFFF, 0x228D, 0xFFFF,
1166
  0x2291, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1167
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0025, 0x0005, 0x000B,
1168
  0x0021, 0x2294, 0xFFFF, 0xFFFF, 0x00F5, 0x013A, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1169
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1170
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1171
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x214D, 0x2298, 0x100A, 0x229C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1172
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x22A0, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1173
  0x22A3, 0x22A7, 0x22AB, 0x22AF, 0x22B3, 0x22B7, 0x22BB, 0x22BF, 0x22C3, 0x22C7, 0x22CB, 0x22CF,
1174
  0x22D3, 0x22D7, 0x22DB, 0x22DF, 0x22E3, 0x22E7, 0x22EB, 0x22EF, 0x22F3, 0x22F7, 0x22FB, 0x22FF,
1175
  0x2303, 0x2307, 0x230B, 0x230F, 0x2313, 0x2317, 0x231B, 0x231F, 0x2323, 0x2327, 0x232B, 0x232F,
1176
  0x2333, 0x2337, 0x233B, 0x233F, 0x2343, 0x2347, 0x234B, 0x234F, 0x2353, 0x2357, 0x235B, 0x235F,
1177
  0x2363, 0x2367, 0x236B, 0x236F, 0x2373, 0x2377, 0x237B, 0x237F, 0x2383, 0x2387, 0x238B, 0x238F,
1178
  0x2393, 0x2397, 0x239B, 0x239F, 0x23A3, 0x23A7, 0x23AB, 0x23AF, 0x23B3, 0x23B7, 0x23BB, 0x23BF,
1179
  0x23C3, 0x23C7, 0x23CB, 0x23CF, 0x23D3, 0x23D7, 0x23DB, 0x23DF, 0x23E3, 0x23E7, 0x1386, 0x23EB,
1180
  0x23EF, 0x23F3, 0x23F7, 0x145E, 0x145E, 0x23FB, 0x13A6, 0x23FF, 0x2403, 0x2407, 0x240B, 0x240F,
1181
  0x2413, 0x2417, 0x241B, 0x241F, 0x2423, 0x2427, 0x242B, 0x242F, 0x2433, 0x2437, 0x243B, 0x243F,
1182
  0x2443, 0x2447, 0x244B, 0x244F, 0x2453, 0x2457, 0x245B, 0x245F, 0x2463, 0x2467, 0x246B, 0x246F,
1183
  0x2473, 0x2477, 0x247B, 0x247F, 0x2483, 0x2487, 0x248B, 0x248F, 0x2493, 0x2497, 0x249B, 0x249F,
1184
  0x12FE, 0x24A3, 0x24A7, 0x24AB, 0x24AF, 0x24B3, 0x24B7, 0x24BB, 0x24BF, 0x24C3, 0x24C7, 0x24CB,
1185
  0x1422, 0x24CF, 0x24D3, 0x24D7, 0x24DB, 0x24DF, 0x24E3, 0x24E7, 0x24EB, 0x24EF, 0x24F3, 0x24F7,
1186
  0x24FB, 0x24FF, 0x2503, 0x2507, 0x250B, 0x250F, 0x2513, 0x2517, 0x251B, 0x251F, 0x2523, 0x2527,
1187
  0x252B, 0x252F, 0x2533, 0x2537, 0x2423, 0x253B, 0x253F, 0x2543, 0x2547, 0x254B, 0x254F, 0x2553,
1188
  0x2557, 0x255B, 0x255F, 0x2563, 0x2567, 0x256B, 0x256F, 0x2573, 0x2577, 0x257B, 0x257F, 0x2583,
1189
  0x2587, 0x138E, 0x258B, 0x258F, 0x2593, 0x2597, 0x259B, 0x259F, 0x25A3, 0x25A7, 0x25AB, 0x25AF,
1190
  0x25B3, 0x25B7, 0x25BB, 0x25BF, 0x25C3, 0x11A2, 0x25C7, 0x25CB, 0x25CF, 0x25D3, 0x25D7, 0x25DB,
1191
  0x25DF, 0x25E3, 0x1156, 0x25E7, 0x25EB, 0x25EF, 0x25F3, 0x25F7, 0x25FB, 0x25FF, 0x2603, 0x2607,
1192
  0x260B, 0x260F, 0x2613, 0x2617, 0x261B, 0x261F, 0x2623, 0x2627, 0x262B, 0x262F, 0x2633, 0x2637,
1193
  0x263B, 0x2583, 0x263F, 0x2643, 0x2647, 0x264B, 0x264F, 0x2653, 0x2657, 0x265B, 0x2543, 0x265F,
1194
  0x2663, 0x2667, 0x266B, 0x266F, 0x2673, 0x2677, 0x267B, 0x267F, 0x2683, 0x2687, 0x268B, 0x268F,
1195
  0x2693, 0x2697, 0x269B, 0x269F, 0x26A3, 0x26A7, 0x26AB, 0x2423, 0x26AF, 0x26B3, 0x26B7, 0x26BB,
1196
  0x145A, 0x26BF, 0x26C3, 0x26C7, 0x26CB, 0x26CF, 0x26D3, 0x26D7, 0x26DB, 0x26DF, 0x26E3, 0x26E7,
1197
  0x26EB, 0x184B, 0x26EF, 0x26F3, 0x26F7, 0x26FB, 0x26FF, 0x2703, 0x2707, 0x270B, 0x270F, 0x254B,
1198
  0x2713, 0x2717, 0x271B, 0x271F, 0x2723, 0x2727, 0x272B, 0x272F, 0x2733, 0x2737, 0x273B, 0x273F,
1199
  0x2743, 0x13A2, 0x2747, 0x274B, 0x274F, 0x2753, 0x2757, 0x275B, 0x275F, 0x2763, 0x2767, 0x276B,
1200
  0x276F, 0x2773, 0x2777, 0x12DE, 0x277B, 0x277F, 0x2783, 0x2787, 0x278B, 0x278F, 0x2793, 0x2797,
1201
  0x279B, 0x279F, 0x27A3, 0x27A7, 0x27AB, 0x27AF, 0x27B3, 0x27B7, 0x134A, 0x27BB, 0x1356, 0x27BF,
1202
  0x27C3, 0x27C7, 0xFFFF, 0xFFFF, 0x27CB, 0xFFFF, 0x27CF, 0xFFFF, 0xFFFF, 0x27D3, 0x27D7, 0x27DB,
1203
  0x27DF, 0x27E3, 0x27E7, 0x27EB, 0x27EF, 0x27F3, 0x12FA, 0xFFFF, 0x27F7, 0xFFFF, 0x27FB, 0xFFFF,
1204
  0xFFFF, 0x27FF, 0x2803, 0xFFFF, 0xFFFF, 0xFFFF, 0x2807, 0x280B, 0x280F, 0x2813, 0x2817, 0x281B,
1205
  0x281F, 0x2823, 0x2827, 0x282B, 0x282F, 0x2833, 0x2837, 0x283B, 0x283F, 0x2843, 0x2847, 0x284B,
1206
  0x11BE, 0x284F, 0x2853, 0x2857, 0x285B, 0x285F, 0x2863, 0x2867, 0x286B, 0x286F, 0x2873, 0x2877,
1207
  0x287B, 0x287F, 0x2883, 0x2887, 0x185F, 0x288B, 0x288F, 0x2893, 0x2897, 0x186F, 0x289B, 0x289F,
1208
  0x28A3, 0x28A7, 0x28AB, 0x2613, 0x28AF, 0x28B3, 0x28B7, 0x28BB, 0x28BF, 0x28C3, 0x28C3, 0x28C7,
1209
  0x28CB, 0x28CF, 0x28D3, 0x28D7, 0x28DB, 0x28DF, 0x28E3, 0x27FF, 0x28E7, 0x28EB, 0x28EF, 0x28F3,
1210
  0x28F7, 0x28FC, 0xFFFE, 0xFFFE, 0x2900, 0x2904, 0x2908, 0x290C, 0x2910, 0x2914, 0x2918, 0x291C,
1211
  0x2837, 0x2920, 0x2924, 0x2928, 0x27CB, 0x292C, 0x2930, 0x2934, 0x2938, 0x293C, 0x2940, 0x2944,
1212
  0x2948, 0x294C, 0x2950, 0x2954, 0x2958, 0x2857, 0x295C, 0x285B, 0x2960, 0x2964, 0x2968, 0x296C,
1213
  0x2970, 0x27CF, 0x2477, 0x2974, 0x2978, 0x1242, 0x2587, 0x26D3, 0x297C, 0x2980, 0x2877, 0x2984,
1214
  0x287B, 0x2988, 0x298C, 0x2990, 0x27D7, 0x2994, 0x2998, 0x299C, 0x29A0, 0x29A4, 0x27DB, 0x29A8,
1215
  0x29AC, 0x29B0, 0x29B4, 0x29B8, 0x29BC, 0x28AB, 0x29C0, 0x29C4, 0x2613, 0x29C8, 0x28BB, 0x29CC,
1216
  0x29D0, 0x29D4, 0x29D8, 0x29DC, 0x28CF, 0x29E0, 0x27FB, 0x29E4, 0x28D3, 0x253B, 0x29E8, 0x28D7,
1217
  0x29EC, 0x28DF, 0x29F0, 0x29F4, 0x29F8, 0x29FC, 0x2A00, 0x28E7, 0x27EF, 0x2A04, 0x28EB, 0x2A08,
1218
  0x28EF, 0x2A0C, 0x145E, 0x2A10, 0x2A15, 0x2A1A, 0x2A1F, 0x2A23, 0x2A27, 0x2A2B, 0x2A30, 0x2A35,
1219
  0x2A3A, 0x2A3E, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1220
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1221
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1222
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x2A42, 0x2A45, 0x2A48, 0x2A4B, 0x2A4F, 0x2A53, 0x2A53, 0xFFFE,
1223
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x2A56,
1224
  0x2A5B, 0x2A60, 0x2A65, 0x2A6A, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x2A6F, 0xFFFF, 0x2A74,
1225
  0x2A79, 0x0D7C, 0x0D85, 0x2A7C, 0x2A7F, 0x2A82, 0x2A85, 0x2A88, 0x2A8B, 0x0D44, 0x2A8E, 0x2A93,
1226
  0x2A98, 0x2A9F, 0x2AA6, 0x2AAB, 0x2AB0, 0x2AB5, 0x2ABA, 0x2ABF, 0x2AC4, 0x2AC9, 0x2ACE, 0xFFFE,
1227
  0x2AD3, 0x2AD8, 0x2ADD, 0x2AE2, 0x2AE7, 0xFFFE, 0x2AEC, 0xFFFE, 0x2AF1, 0x2AF6, 0xFFFE, 0x2AFB,
1228
  0x2B00, 0xFFFE, 0x2B05, 0x2B0A, 0x2B0F, 0x2B14, 0x2B19, 0x2B1E, 0x2B23, 0x2B28, 0x2B2D, 0x2B32,
1229
  0x2B37, 0x2B37, 0x2B3A, 0x2B3A, 0x2B3A, 0x2B3A, 0x2B3D, 0x2B3D, 0x2B3D, 0x2B3D, 0x2B40, 0x2B40,
1230
  0x2B40, 0x2B40, 0x2B43, 0x2B43, 0x2B43, 0x2B43, 0x2B46, 0x2B46, 0x2B46, 0x2B46, 0x2B49, 0x2B49,
1231
  0x2B49, 0x2B49, 0x2B4C, 0x2B4C, 0x2B4C, 0x2B4C, 0x2B4F, 0x2B4F, 0x2B4F, 0x2B4F, 0x2B52, 0x2B52,
1232
  0x2B52, 0x2B52, 0x2B55, 0x2B55, 0x2B55, 0x2B55, 0x2B58, 0x2B58, 0x2B58, 0x2B58, 0x2B5B, 0x2B5B,
1233
  0x2B5B, 0x2B5B, 0x2B5E, 0x2B5E, 0x2B61, 0x2B61, 0x2B64, 0x2B64, 0x2B67, 0x2B67, 0x2B6A, 0x2B6A,
1234
  0x2B6D, 0x2B6D, 0x2B70, 0x2B70, 0x2B70, 0x2B70, 0x2B73, 0x2B73, 0x2B73, 0x2B73, 0x2B76, 0x2B76,
1235
  0x2B76, 0x2B76, 0x2B79, 0x2B79, 0x2B79, 0x2B79, 0x2B7C, 0x2B7C, 0x2B7F, 0x2B7F, 0x2B7F, 0x2B7F,
1236
  0x2B82, 0x2B82, 0x2B85, 0x2B85, 0x2B85, 0x2B85, 0x2B88, 0x2B88, 0x2B88, 0x2B88, 0x2B8B, 0x2B8B,
1237
  0x2B8E, 0x2B8E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1238
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1239
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x2B91,
1240
  0x2B91, 0x2B91, 0x2B91, 0x2B94, 0x2B94, 0x2B97, 0x2B97, 0x2B9A, 0x2B9A, 0x05DD, 0x2B9D, 0x2B9D,
1241
  0x2BA0, 0x2BA0, 0x2BA3, 0x2BA3, 0x2BA6, 0x2BA6, 0x2BA6, 0x2BA6, 0x2BA9, 0x2BA9, 0x2BAC, 0x2BAC,
1242
  0x2BB1, 0x2BB1, 0x2BB6, 0x2BB6, 0x2BBB, 0x2BBB, 0x2BC0, 0x2BC0, 0x2BC5, 0x2BC5, 0x2BCA, 0x2BCA,
1243
  0x2BCA, 0x2BCF, 0x2BCF, 0x2BCF, 0x2BD4, 0x2BD4, 0x2BD4, 0x2BD4, 0x2BD7, 0x2BDC, 0x2BE1, 0x2BCF,
1244
  0x2BE6, 0x2BEB, 0x2BF0, 0x2BF5, 0x2BFA, 0x2BFF, 0x2C04, 0x2C09, 0x2C0E, 0x2C13, 0x2C18, 0x2C1D,
1245
  0x2C22, 0x2C27, 0x2C2C, 0x2C31, 0x2C36, 0x2C3B, 0x2C40, 0x2C45, 0x2C4A, 0x2C4F, 0x2C54, 0x2C59,
1246
  0x2C5E, 0x2C63, 0x2C68, 0x2C6D, 0x2C72, 0x2C77, 0x2C7C, 0x2C81, 0x2C86, 0x2C8B, 0x2C90, 0x2C95,
1247
  0x2C9A, 0x2C9F, 0x2CA4, 0x2CA9, 0x2CAE, 0x2CB3, 0x2CB8, 0x2CBD, 0x2CC2, 0x2CC7, 0x2CCC, 0x2CD1,
1248
  0x2CD6, 0x2CDB, 0x2CE0, 0x2CE5, 0x2CEA, 0x2CEF, 0x2CF4, 0x2CF9, 0x2CFE, 0x2D03, 0x2D08, 0x2D0D,
1249
  0x2D12, 0x2D17, 0x2D1C, 0x2D21, 0x2D26, 0x2D2B, 0x2D30, 0x2D35, 0x2D3A, 0x2D3F, 0x2D44, 0x2D49,
1250
  0x2D4E, 0x2D53, 0x2D58, 0x2D5D, 0x2D62, 0x2D67, 0x2D6C, 0x2D71, 0x2D76, 0x2D7B, 0x2D80, 0x2D85,
1251
  0x2D8A, 0x2D8F, 0x2D94, 0x2D99, 0x2D9E, 0x2DA3, 0x2DA8, 0x2DAE, 0x2DB4, 0x2DBA, 0x2DC0, 0x2DC6,
1252
  0x2DCC, 0x2DD1, 0x2BE1, 0x2DD6, 0x2BCF, 0x2BE6, 0x2DDB, 0x2DE0, 0x2BFA, 0x2DE5, 0x2BFF, 0x2C04,
1253
  0x2DEA, 0x2DEF, 0x2C18, 0x2DF4, 0x2C1D, 0x2C22, 0x2DF9, 0x2DFE, 0x2C2C, 0x2E03, 0x2C31, 0x2C36,
1254
  0x2CC7, 0x2CCC, 0x2CDB, 0x2CE0, 0x2CE5, 0x2CF9, 0x2CFE, 0x2D03, 0x2D08, 0x2D1C, 0x2D21, 0x2D26,
1255
  0x2E08, 0x2D3A, 0x2E0D, 0x2E12, 0x2D58, 0x2E17, 0x2D5D, 0x2D62, 0x2DA3, 0x2E1C, 0x2E21, 0x2D8A,
1256
  0x2E26, 0x2D8F, 0x2D94, 0x2BD7, 0x2BDC, 0x2E2B, 0x2BE1, 0x2E30, 0x2BEB, 0x2BF0, 0x2BF5, 0x2BFA,
1257
  0x2E35, 0x2C09, 0x2C0E, 0x2C13, 0x2C18, 0x2E3A, 0x2C2C, 0x2C3B, 0x2C40, 0x2C45, 0x2C4A, 0x2C4F,
1258
  0x2C59, 0x2C5E, 0x2C63, 0x2C68, 0x2C6D, 0x2C72, 0x2E3F, 0x2C77, 0x2C7C, 0x2C81, 0x2C86, 0x2C8B,
1259
  0x2C90, 0x2C9A, 0x2C9F, 0x2CA4, 0x2CA9, 0x2CAE, 0x2CB3, 0x2CB8, 0x2CBD, 0x2CC2, 0x2CD1, 0x2CD6,
1260
  0x2CEA, 0x2CEF, 0x2CF4, 0x2CF9, 0x2CFE, 0x2D0D, 0x2D12, 0x2D17, 0x2D1C, 0x2E44, 0x2D2B, 0x2D30,
1261
  0x2D35, 0x2D3A, 0x2D49, 0x2D4E, 0x2D53, 0x2D58, 0x2E49, 0x2D67, 0x2D6C, 0x2E4E, 0x2D7B, 0x2D80,
1262
  0x2D85, 0x2D8A, 0x2E53, 0x2BE1, 0x2E30, 0x2BFA, 0x2E35, 0x2C18, 0x2E3A, 0x2C2C, 0x2E58, 0x2C6D,
1263
  0x2E5D, 0x2E62, 0x2E67, 0x2CF9, 0x2CFE, 0x2D1C, 0x2D58, 0x2E49, 0x2D8A, 0x2E53, 0x2E6C, 0x2E73,
1264
  0x2E7A, 0x2E81, 0x2E86, 0x2E8B, 0x2E90, 0x2E95, 0x2E9A, 0x2E9F, 0x2EA4, 0x2EA9, 0x2EAE, 0x2EB3,
1265
  0x2EB8, 0x2EBD, 0x2EC2, 0x2EC7, 0x2ECC, 0x2ED1, 0x2ED6, 0x2EDB, 0x2EE0, 0x2EE5, 0x2EEA, 0x2EEF,
1266
  0x2E62, 0x2EF4, 0x2EF9, 0x2EFE, 0x2F03, 0x2E81, 0x2E86, 0x2E8B, 0x2E90, 0x2E95, 0x2E9A, 0x2E9F,
1267
  0x2EA4, 0x2EA9, 0x2EAE, 0x2EB3, 0x2EB8, 0x2EBD, 0x2EC2, 0x2EC7, 0x2ECC, 0x2ED1, 0x2ED6, 0x2EDB,
1268
  0x2EE0, 0x2EE5, 0x2EEA, 0x2EEF, 0x2E62, 0x2EF4, 0x2EF9, 0x2EFE, 0x2F03, 0x2EE5, 0x2EEA, 0x2EEF,
1269
  0x2E62, 0x2E5D, 0x2E67, 0x2C95, 0x2C5E, 0x2C63, 0x2C68, 0x2EE5, 0x2EEA, 0x2EEF, 0x2C95, 0x2C9A,
1270
  0x2F08, 0x2F08, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1271
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x2F0D, 0x2F14, 0x2F14, 0x2F1B,
1272
  0x2F22, 0x2F29, 0x2F30, 0x2F37, 0x2F3E, 0x2F3E, 0x2F45, 0x2F4C, 0x2F53, 0x2F5A, 0x2F61, 0x2F68,
1273
  0x2F68, 0x2F6F, 0x2F76, 0x2F76, 0x2F7D, 0x2F7D, 0x2F84, 0x2F8B, 0x2F8B, 0x2F92, 0x2F99, 0x2F99,
1274
  0x2FA0, 0x2FA0, 0x2FA7, 0x2FAE, 0x2FAE, 0x2FB5, 0x2FB5, 0x2FBC, 0x2FC3, 0x2FCA, 0x2FD1, 0x2FD1,
1275
  0x2FD8, 0x2FDF, 0x2FE6, 0x2FED, 0x2FF4, 0x2FF4, 0x2FFB, 0x3002, 0x3009, 0x3010, 0x3017, 0x301E,
1276
  0x301E, 0x3025, 0x3025, 0x302C, 0x302C, 0x3033, 0x303A, 0x3041, 0x3048, 0x304F, 0x3056, 0x305D,
1277
  0xFFFF, 0xFFFF, 0x3064, 0x306B, 0x3072, 0x3079, 0x3080, 0x3087, 0x3087, 0x308E, 0x3095, 0x309C,
1278
  0x30A3, 0x30A3, 0x30AA, 0x30B1, 0x30B8, 0x30BF, 0x30C6, 0x30CD, 0x30D4, 0x30DB, 0x30E2, 0x30E9,
1279
  0x30F0, 0x30F7, 0x30FE, 0x3105, 0x310C, 0x3113, 0x311A, 0x3121, 0x3128, 0x312F, 0x3136, 0x313D,
1280
  0x2FFB, 0x3009, 0x3144, 0x314B, 0x3152, 0x3159, 0x3160, 0x3167, 0x3160, 0x3152, 0x316E, 0x3175,
1281
  0x317C, 0x3183, 0x318A, 0x3167, 0x2FCA, 0x2F84, 0x3191, 0x3198, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1282
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1283
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1284
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1285
  0x319F, 0x31A6, 0x31AD, 0x31B6, 0x31BF, 0x31C8, 0x31D1, 0x31DA, 0x31E3, 0x31EC, 0x31F3, 0x3215,
1286
  0x3225, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1287
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x322E, 0x3230, 0xFFFE, 0x3234,
1288
  0x02FF, 0x3236, 0x3238, 0x323A, 0x323E, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1289
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1290
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0x3242, 0x3246, 0x324A, 0x324A, 0x0D4C, 0x0D4E, 0x324C,
1291
  0x324E, 0x3250, 0x3254, 0x3258, 0x325C, 0x3260, 0x3264, 0x0E3C, 0x0E40, 0x3268, 0x326C, 0x3270,
1292
  0x3274, 0xFFFF, 0xFFFF, 0x3278, 0x327A, 0x0D1C, 0x0D1C, 0x0D1C, 0x0D1C, 0x324A, 0x324A, 0x324A,
1293
  0x322E, 0x3230, 0xFFFE, 0xFFFE, 0x02FF, 0x3234, 0x3238, 0x3236, 0x3242, 0x0D4C, 0x0D4E, 0x324C,
1294
  0x324E, 0x3250, 0x3254, 0x327C, 0x327E, 0x3280, 0x0D44, 0x3282, 0x3284, 0x3286, 0x0D4A, 0xFFFE,
1295
  0x3288, 0x328A, 0x328C, 0x328E, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x3290, 0x3294, 0x3299, 0xFFFF,
1296
  0x329D, 0xFFFE, 0x32A1, 0x32A5, 0x32AA, 0x32AE, 0x32B3, 0x32B7, 0x32BC, 0x32C0, 0x32C5, 0x32C9,
1297
  0x32CE, 0x32D1, 0x32D1, 0x32D4, 0x32D4, 0x32D7, 0x32D7, 0x32DA, 0x32DA, 0x32DD, 0x32DD, 0x32DD,
1298
  0x32DD, 0x32E0, 0x32E0, 0x32E3, 0x32E3, 0x32E3, 0x32E3, 0x32E6, 0x32E6, 0x32E9, 0x32E9, 0x32E9,
1299
  0x32E9, 0x32EC, 0x32EC, 0x32EC, 0x32EC, 0x32EF, 0x32EF, 0x32EF, 0x32EF, 0x32F2, 0x32F2, 0x32F2,
1300
  0x32F2, 0x32F5, 0x32F5, 0x32F5, 0x32F5, 0x32F8, 0x32F8, 0x32FB, 0x32FB, 0x32FE, 0x32FE, 0x3301,
1301
  0x3301, 0x3304, 0x3304, 0x3304, 0x3304, 0x3307, 0x3307, 0x3307, 0x3307, 0x330A, 0x330A, 0x330A,
1302
  0x330A, 0x330D, 0x330D, 0x330D, 0x330D, 0x3310, 0x3310, 0x3310, 0x3310, 0x3313, 0x3313, 0x3313,
1303
  0x3313, 0x3316, 0x3316, 0x3316, 0x3316, 0x3319, 0x3319, 0x3319, 0x3319, 0x331C, 0x331C, 0x331C,
1304
  0x331C, 0x331F, 0x331F, 0x331F, 0x331F, 0x3322, 0x3322, 0x3322, 0x3322, 0x3325, 0x3325, 0x3325,
1305
  0x3325, 0x3328, 0x3328, 0x3328, 0x3328, 0x332B, 0x332B, 0x332B, 0x332B, 0x332E, 0x332E, 0x332E,
1306
  0x332E, 0x3331, 0x3331, 0x2BA9, 0x2BA9, 0x3334, 0x3334, 0x3334, 0x3334, 0x3337, 0x3337, 0x333C,
1307
  0x333C, 0x3341, 0x3341, 0x3346, 0x3346, 0xFFFE, 0xFFFE, 0x0000, 0xFFFE, 0x3236, 0x334B, 0x327C,
1308
  0x328A, 0x328C, 0x327E, 0x334D, 0x0D4C, 0x0D4E, 0x3280, 0x0D44, 0x322E, 0x3282, 0x1466, 0x334F,
1309
  0x0D36, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E, 0x0D40, 0x0D42, 0x3234, 0x02FF,
1310
  0x3284, 0x0D4A, 0x3286, 0x3238, 0x328E, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D,
1311
  0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025,
1312
  0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x3278, 0x3288, 0x327A, 0x3351, 0x324A,
1313
  0x0CCB, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015,
1314
  0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D,
1315
  0x002F, 0x0031, 0x0033, 0x324C, 0x3353, 0x324E, 0x3355, 0x3357, 0x335B, 0x1466, 0x3268, 0x326C,
1316
  0x3230, 0x335F, 0x19F9, 0x3363, 0x3367, 0x336B, 0x336F, 0x3373, 0x3377, 0x337B, 0x337F, 0x3383,
1317
  0x3387, 0x1941, 0x1945, 0x1949, 0x194D, 0x1951, 0x1955, 0x1959, 0x195D, 0x1961, 0x1965, 0x1969,
1318
  0x196D, 0x1971, 0x1975, 0x1979, 0x197D, 0x1981, 0x1985, 0x1989, 0x198D, 0x1991, 0x1995, 0x1999,
1319
  0x199D, 0x19A1, 0x19A5, 0x19A9, 0x19AD, 0x19B1, 0x19B5, 0x19B9, 0x19BD, 0x19C1, 0x19C5, 0x19C9,
1320
  0x19CD, 0x19D1, 0x19D5, 0x19D9, 0x19DD, 0x19E1, 0x19E5, 0x19E9, 0x19ED, 0x338B, 0x338F, 0x3393,
1321
  0x0000, 0x148C, 0x1490, 0x1494, 0x1498, 0x149C, 0x14A0, 0x14A4, 0x14A8, 0x14AC, 0x14B0, 0x14B4,
1322
  0x14B8, 0x14BC, 0x14C0, 0x14C4, 0x14C8, 0x14CC, 0x14D0, 0x14D4, 0x14D8, 0x14DC, 0x14E0, 0x14E4,
1323
  0x14E8, 0x14EC, 0x14F0, 0x14F4, 0x14F8, 0x14FC, 0x1500, 0xFFFE, 0xFFFE, 0xFFFE, 0x1504, 0x1508,
1324
  0x150C, 0x1510, 0x1514, 0x1518, 0xFFFE, 0xFFFE, 0x151C, 0x1520, 0x1524, 0x1528, 0x152C, 0x1530,
1325
  0xFFFE, 0xFFFE, 0x1534, 0x1538, 0x153C, 0x1540, 0x1544, 0x1548, 0xFFFE, 0xFFFE, 0x154C, 0x1550,
1326
  0x1554, 0xFFFE, 0xFFFE, 0xFFFE, 0x3397, 0x339A, 0x339D, 0x003B, 0x33A0, 0x33A3, 0x33A6, 0xFFFE,
1327
  0x33AA, 0x33AE, 0x33B2, 0x33B6, 0x33BA, 0x33BE, 0x33C2, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1328
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1329
  0x33C6, 0x33CB, 0x33D0, 0x33D5, 0x33DA, 0x33DF, 0x33E4, 0x33E9, 0x33EE, 0x33F3, 0x33F8, 0x33FD,
1330
  0x3402, 0x3407, 0x340C, 0x3411, 0x3416, 0x341B, 0x3420, 0x3425, 0x342A, 0x342F, 0x3434, 0x3439,
1331
  0x343E, 0x3443, 0x3448, 0x344D, 0x3452, 0x3457, 0x345C, 0x3461, 0x3466, 0x346B, 0x3470, 0x3475,
1332
  0x347A, 0x347F, 0x3484, 0x3489, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1333
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1334
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1335
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1336
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE,
1337
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE,
1338
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x348E, 0x3493, 0x3498, 0x349D, 0x34A2, 0x34A7, 0x34AC, 0x34B1,
1339
  0x34B6, 0x34BB, 0x34C0, 0x34C5, 0x34CA, 0x34CF, 0x34D4, 0x34D9, 0x34DE, 0x34E3, 0x34E8, 0x34ED,
1340
  0x34F2, 0x34F7, 0x34FC, 0x3501, 0x3506, 0x350B, 0x3510, 0x3515, 0x351A, 0x351F, 0x3524, 0x3529,
1341
  0x352E, 0x3533, 0x3538, 0x353D, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1342
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1343
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1344
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1345
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1346
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1347
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1348
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF,
1349
  0x3542, 0x3547, 0x354C, 0x3551, 0x3556, 0x355B, 0x3560, 0x3565, 0x356A, 0x356F, 0x3574, 0xFFFE,
1350
  0x3579, 0x357E, 0x3583, 0x3588, 0x358D, 0x3592, 0x3597, 0x359C, 0x35A1, 0x35A6, 0x35AB, 0x35B0,
1351
  0x35B5, 0x35BA, 0x35BF, 0xFFFE, 0x35C4, 0x35C9, 0x35CE, 0x35D3, 0x35D8, 0x35DD, 0x35E2, 0xFFFE,
1352
  0x35E7, 0x35EC, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1353
  0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1354
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1355
  0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0x35F1, 0x35F4, 0x0074,
1356
  0x35F7, 0x017F, 0xFFFE, 0x35FA, 0x35FD, 0x3601, 0x3604, 0x018E, 0x0191, 0x3607, 0x360B, 0x360E,
1357
  0x3611, 0x226E, 0x3614, 0x01A3, 0x3617, 0x00F5, 0x361A, 0x361D, 0x3620, 0x3623, 0x3626, 0x2231,
1358
  0x3629, 0x362E, 0x3632, 0x3635, 0x363A, 0x363D, 0x00A7, 0x3642, 0x3645, 0x0021, 0x3648, 0x364B,
1359
  0x1011, 0x3650, 0x01C4, 0x3653, 0x3656, 0x3659, 0x365D, 0x01D0, 0x3660, 0xFFFE, 0x3664, 0x3667,
1360
  0x366A, 0x366D, 0x3670, 0x3673, 0x3676, 0x3679, 0x367E, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1361
  0x3683, 0x3688, 0x368D, 0x3692, 0x3697, 0x369C, 0x36A1, 0x36A6, 0x36AB, 0x36B0, 0x36B5, 0x36BA,
1362
  0x36BF, 0x36C4, 0x36C9, 0x36CE, 0x36D3, 0x36D8, 0x36DD, 0x36E2, 0x36E7, 0x36EC, 0x36F1, 0x36F6,
1363
  0x36FB, 0x3700, 0x3705, 0x370A, 0x370F, 0x3714, 0x3719, 0x371E, 0x3723, 0x3728, 0x372D, 0x3732,
1364
  0x3737, 0x373C, 0x3741, 0x3746, 0x374B, 0x3750, 0x3755, 0x375A, 0x375F, 0x3764, 0x3769, 0x376E,
1365
  0x3773, 0x3778, 0x377D, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1366
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1367
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x3782, 0x3787, 0x378C, 0x3791,
1368
  0x3796, 0x379B, 0x37A0, 0x37A5, 0x37AA, 0x37AF, 0x37B4, 0x37B9, 0x37BE, 0x37C3, 0x37C8, 0x37CD,
1369
  0x37D2, 0x37D7, 0x37DC, 0x37E1, 0x37E6, 0x37EB, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
1370
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1371
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1372
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1373
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1374
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x37F0, 0x37F5, 0x37FA, 0x37FF, 0x3804, 0x3809, 0x380E, 0x3813,
1375
  0x3818, 0x381D, 0x3822, 0x3827, 0x382C, 0x3831, 0x3836, 0x383B, 0x3840, 0x3845, 0x384A, 0x384F,
1376
  0x3854, 0x3859, 0x385E, 0x3863, 0x3868, 0x386D, 0x3872, 0x3877, 0x387C, 0x3881, 0x3886, 0x388B,
1377
  0x3890, 0x3895, 0x389A, 0x389F, 0x38A4, 0x38A9, 0x38AE, 0x38B3, 0x38B8, 0x38BD, 0x38C2, 0x38C7,
1378
  0x38CC, 0x38D1, 0x38D6, 0x38DB, 0x38E0, 0x38E5, 0x38EA, 0x38EF, 0x38F4, 0x38F9, 0x38FE, 0x3903,
1379
  0x3908, 0x390D, 0x3912, 0x3917, 0x391C, 0x3921, 0x3926, 0x392B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1380
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1381
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1382
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1383
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1384
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1385
  0x3930, 0x3935, 0x393A, 0x393F, 0x3944, 0x3949, 0x394E, 0x3953, 0x3958, 0x395D, 0x3962, 0x3967,
1386
  0x396C, 0x3971, 0x3976, 0x397B, 0x3980, 0x3985, 0x398A, 0x398F, 0x3994, 0x3999, 0x399E, 0x39A3,
1387
  0x39A8, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1388
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1389
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE,
1390
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1391
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1392
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1393
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1394
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0001, 0x0003,
1395
  0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B,
1396
  0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033,
1397
  0x0D36, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E, 0x0D40, 0x0D42, 0xFFFF, 0xFFFF,
1398
  0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1399
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1400
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x39AD, 0x39B6,
1401
  0x39BF, 0x39CC, 0x39D9, 0x39E6, 0x39F3, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1402
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1403
  0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1404
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1405
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1406
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1407
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1408
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x3A00, 0x3A09, 0x3A12, 0x3A1F, 0x3A2C,
1409
  0x3A39, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1410
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1411
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1412
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1413
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1414
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F,
1415
  0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027,
1416
  0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B,
1417
  0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023,
1418
  0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007,
1419
  0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F,
1420
  0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003,
1421
  0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0xFFFE, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B,
1422
  0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033,
1423
  0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017,
1424
  0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F,
1425
  0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013,
1426
  0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B,
1427
  0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0xFFFE, 0x0005, 0x0007, 0xFFFE, 0xFFFE, 0x000D, 0xFFFE,
1428
  0xFFFE, 0x0013, 0x0015, 0xFFFE, 0xFFFE, 0x001B, 0x001D, 0x001F, 0x0021, 0xFFFE, 0x0025, 0x0027,
1429
  0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0xFFFE, 0x000B,
1430
  0xFFFE, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0xFFFE, 0x001F, 0x0021, 0x0023,
1431
  0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007,
1432
  0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F,
1433
  0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003,
1434
  0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B,
1435
  0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033,
1436
  0x0001, 0x0003, 0xFFFE, 0x0007, 0x0009, 0x000B, 0x000D, 0xFFFE, 0xFFFE, 0x0013, 0x0015, 0x0017,
1437
  0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0xFFFE, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F,
1438
  0x0031, 0xFFFE, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013,
1439
  0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B,
1440
  0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0xFFFE, 0x0007, 0x0009, 0x000B, 0x000D, 0xFFFE,
1441
  0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0xFFFE, 0x001D, 0xFFFE, 0xFFFE, 0xFFFE, 0x0025, 0x0027,
1442
  0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0xFFFE, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B,
1443
  0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023,
1444
  0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007,
1445
  0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F,
1446
  0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003,
1447
  0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B,
1448
  0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033,
1449
  0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017,
1450
  0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F,
1451
  0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013,
1452
  0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B,
1453
  0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F,
1454
  0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027,
1455
  0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B,
1456
  0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023,
1457
  0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007,
1458
  0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F,
1459
  0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003,
1460
  0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B,
1461
  0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033,
1462
  0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017,
1463
  0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F,
1464
  0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013,
1465
  0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B,
1466
  0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B, 0x000D, 0x000F,
1467
  0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023, 0x0025, 0x0027,
1468
  0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0001, 0x0003, 0x0005, 0x0007, 0x0009, 0x000B,
1469
  0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F, 0x0021, 0x0023,
1470
  0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x3A46, 0x3A49, 0xFFFE, 0xFFFE,
1471
  0x0322, 0x0325, 0x0328, 0x032B, 0x032E, 0x0331, 0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047,
1472
  0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0x0337, 0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E,
1473
  0x0361, 0x3A4C, 0x0322, 0x0325, 0x0328, 0x032B, 0x032E, 0x0331, 0x0334, 0x0337, 0x02EC, 0x033A,
1474
  0x033D, 0x0047, 0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0x034F, 0x034F, 0x0352, 0x0355, 0x0358,
1475
  0x035B, 0x035E, 0x0361, 0x3A50, 0x032E, 0x0337, 0x033A, 0x0358, 0x034C, 0x0349, 0x0322, 0x0325,
1476
  0x0328, 0x032B, 0x032E, 0x0331, 0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343,
1477
  0x0346, 0x0349, 0x034C, 0x0337, 0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x3A4C,
1478
  0x0322, 0x0325, 0x0328, 0x032B, 0x032E, 0x0331, 0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047,
1479
  0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0x034F, 0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E,
1480
  0x0361, 0x3A50, 0x032E, 0x0337, 0x033A, 0x0358, 0x034C, 0x0349, 0x0322, 0x0325, 0x0328, 0x032B,
1481
  0x032E, 0x0331, 0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343, 0x0346, 0x0349,
1482
  0x034C, 0x0337, 0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x3A4C, 0x0322, 0x0325,
1483
  0x0328, 0x032B, 0x032E, 0x0331, 0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343,
1484
  0x0346, 0x0349, 0x034C, 0x034F, 0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x3A50,
1485
  0x032E, 0x0337, 0x033A, 0x0358, 0x034C, 0x0349, 0x0322, 0x0325, 0x0328, 0x032B, 0x032E, 0x0331,
1486
  0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0x0337,
1487
  0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x3A4C, 0x0322, 0x0325, 0x0328, 0x032B,
1488
  0x032E, 0x0331, 0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343, 0x0346, 0x0349,
1489
  0x034C, 0x034F, 0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x3A50, 0x032E, 0x0337,
1490
  0x033A, 0x0358, 0x034C, 0x0349, 0x0322, 0x0325, 0x0328, 0x032B, 0x032E, 0x0331, 0x0334, 0x0337,
1491
  0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0x0337, 0x034F, 0x0352,
1492
  0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x3A4C, 0x0322, 0x0325, 0x0328, 0x032B, 0x032E, 0x0331,
1493
  0x0334, 0x0337, 0x02EC, 0x033A, 0x033D, 0x0047, 0x0340, 0x0343, 0x0346, 0x0349, 0x034C, 0x034F,
1494
  0x034F, 0x0352, 0x0355, 0x0358, 0x035B, 0x035E, 0x0361, 0x3A50, 0x032E, 0x0337, 0x033A, 0x0358,
1495
  0x034C, 0x0349, 0x0373, 0x0373, 0xFFFE, 0xFFFE, 0x0D36, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A,
1496
  0x0D3C, 0x0D3E, 0x0D40, 0x0D42, 0x0D36, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E,
1497
  0x0D40, 0x0D42, 0x0D36, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E, 0x0D40, 0x0D42,
1498
  0x0D36, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E, 0x0D40, 0x0D42, 0x0D36, 0x004E,
1499
  0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E, 0x0D40, 0x0D42, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1500
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1501
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF,
1502
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF,
1503
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x03D0, 0x03D3, 0x03D6, 0x03D9,
1504
  0x03DC, 0x03DF, 0x03E2, 0x03E5, 0x03E8, 0x03EE, 0x03F1, 0x03F4, 0x03FA, 0x03FD, 0x0400, 0x0403,
1505
  0x0406, 0x0409, 0x040C, 0x040F, 0x0412, 0x0415, 0x0418, 0x0421, 0x0427, 0x042A, 0x211D, 0x04D8,
1506
  0x03B2, 0x03B8, 0x04F0, 0x0499, 0x04B4, 0x03D0, 0x03D3, 0x03D6, 0x03D9, 0x03DC, 0x03DF, 0x03E2,
1507
  0x03E5, 0x03E8, 0x03EE, 0x03F1, 0x03FA, 0x03FD, 0x0403, 0x0409, 0x040C, 0x040F, 0x0412, 0x0415,
1508
  0x0418, 0x041E, 0x0421, 0x046C, 0x03B2, 0x03AF, 0x03CD, 0x0493, 0x20D1, 0x049C, 0xFFFE, 0xFFFE,
1509
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1510
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x3A54, 0x3A59, 0x3A5E, 0x3A63, 0x3A68, 0x3A6D, 0x3A72, 0x3A77,
1511
  0x3A7C, 0x3A81, 0x3A86, 0x3A8B, 0x3A90, 0x3A95, 0x3A9A, 0x3A9F, 0x3AA4, 0x3AA9, 0x3AAE, 0x3AB3,
1512
  0x3AB8, 0x3ABD, 0x3AC2, 0x3AC7, 0x3ACC, 0x3AD1, 0x3AD6, 0x3ADB, 0x3AE0, 0x3AE5, 0x3AEA, 0x3AEF,
1513
  0x3AF4, 0x3AF9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1514
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1515
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x32E0, 0x32E3, 0x32EF, 0x32F8,
1516
  0xFFFE, 0x3331, 0x3301, 0x32F2, 0x3310, 0x3334, 0x3322, 0x3325, 0x3328, 0x332B, 0x3304, 0x3316,
1517
  0x331C, 0x330A, 0x331F, 0x32FE, 0x3307, 0x32E9, 0x32EC, 0x32F5, 0x32FB, 0x330D, 0x3313, 0x3319,
1518
  0x3AFE, 0x2B7C, 0x3B01, 0x3B04, 0xFFFE, 0x32E3, 0x32EF, 0xFFFE, 0x332E, 0xFFFE, 0xFFFE, 0x32F2,
1519
  0xFFFE, 0x3334, 0x3322, 0x3325, 0x3328, 0x332B, 0x3304, 0x3316, 0x331C, 0x330A, 0x331F, 0xFFFE,
1520
  0x3307, 0x32E9, 0x32EC, 0x32F5, 0xFFFE, 0x330D, 0xFFFE, 0x3319, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1521
  0xFFFE, 0xFFFE, 0x32EF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x32F2, 0xFFFE, 0x3334, 0xFFFE, 0x3325,
1522
  0xFFFE, 0x332B, 0x3304, 0x3316, 0xFFFE, 0x330A, 0x331F, 0xFFFE, 0x3307, 0xFFFE, 0xFFFE, 0x32F5,
1523
  0xFFFE, 0x330D, 0xFFFE, 0x3319, 0xFFFE, 0x2B7C, 0xFFFE, 0x3B04, 0xFFFE, 0x32E3, 0x32EF, 0xFFFE,
1524
  0x332E, 0xFFFE, 0xFFFE, 0x32F2, 0x3310, 0x3334, 0x3322, 0xFFFE, 0x3328, 0x332B, 0x3304, 0x3316,
1525
  0x331C, 0x330A, 0x331F, 0xFFFE, 0x3307, 0x32E9, 0x32EC, 0x32F5, 0xFFFE, 0x330D, 0x3313, 0x3319,
1526
  0x3AFE, 0xFFFE, 0x3B01, 0xFFFE, 0x32E0, 0x32E3, 0x32EF, 0x32F8, 0x332E, 0x3331, 0x3301, 0x32F2,
1527
  0x3310, 0x3334, 0xFFFE, 0x3325, 0x3328, 0x332B, 0x3304, 0x3316, 0x331C, 0x330A, 0x331F, 0x32FE,
1528
  0x3307, 0x32E9, 0x32EC, 0x32F5, 0x32FB, 0x330D, 0x3313, 0x3319, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1529
  0xFFFE, 0x32E3, 0x32EF, 0x32F8, 0xFFFE, 0x3331, 0x3301, 0x32F2, 0x3310, 0x3334, 0xFFFE, 0x3325,
1530
  0x3328, 0x332B, 0x3304, 0x3316, 0x331C, 0x330A, 0x331F, 0x32FE, 0x3307, 0x32E9, 0x32EC, 0x32F5,
1531
  0x32FB, 0x330D, 0x3313, 0x3319, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x3B07, 0x3B0A, 0x3B0D,
1532
  0x3B10, 0x3B13, 0x3B16, 0x3B19, 0x3B1C, 0x3B1F, 0x3B22, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1533
  0x0EC0, 0x0EC4, 0x0EC8, 0x0ECC, 0x0ED0, 0x0ED4, 0x0ED8, 0x0EDC, 0x0EE0, 0x0EE4, 0x0EE8, 0x0EEC,
1534
  0x0EF0, 0x0EF4, 0x0EF8, 0x0EFC, 0x0F00, 0x0F04, 0x0F08, 0x0F0C, 0x0F10, 0x0F14, 0x0F18, 0x0F1C,
1535
  0x0F20, 0x0F24, 0x3B25, 0x0005, 0x0023, 0x1FAD, 0x3B2D, 0xFFFF, 0x0001, 0x0003, 0x0005, 0x0007,
1536
  0x0009, 0x000B, 0x000D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001B, 0x001D, 0x001F,
1537
  0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x3B30, 0x1F89,
1538
  0x3B33, 0x3B36, 0x3B39, 0x3B3D, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1539
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1540
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x3B40, 0x3B43, 0x3B46, 0xFFFF, 0xFFFF, 0xFFFF,
1541
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1542
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1543
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x3B49, 0xFFFF, 0xFFFF, 0xFFFF,
1544
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1545
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1546
  0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1547
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x3B4C, 0x3B53, 0x1969, 0xFFFE,
1548
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1549
  0x120A, 0x3B5A, 0x3B5E, 0x3B62, 0x1126, 0x3B66, 0x3B6A, 0x1620, 0x3B6E, 0x3B72, 0x3B76, 0x26AB,
1550
  0x3B7A, 0x3B7E, 0x3B82, 0x3B86, 0x3B8A, 0x3B8E, 0x129A, 0x3B92, 0x3B96, 0x3B9A, 0x3B9E, 0x3BA2,
1551
  0x3BA6, 0x110E, 0x1600, 0x3BAA, 0x189F, 0x160C, 0x18A3, 0x3BAE, 0x137A, 0x3BB2, 0x3BB6, 0x3BBA,
1552
  0x3BBE, 0x3BC2, 0x185B, 0x1232, 0x3BC6, 0x3BCA, 0x3BCE, 0x3BD2, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1553
  0x3BD6, 0x3BE0, 0x3BEA, 0x3BF4, 0x3BFE, 0x3C08, 0x3C12, 0x3C1C, 0x3C26, 0xFFFE, 0xFFFE, 0xFFFE,
1554
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x3C30, 0x3C34, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1555
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1556
  0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1557
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1558
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1559
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1560
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1561
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1562
  0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0D36, 0x004E, 0x003F, 0x0041, 0x0D38, 0x0D3A, 0x0D3C, 0x0D3E,
1563
  0x0D40, 0x0D42, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0x3C38, 0x3C3C, 0x3C40, 0x3C44,
1564
  0x3C49, 0x281F, 0x3C4D, 0x3C51, 0x3C55, 0x3C59, 0x2823, 0x3C5D, 0x3C61, 0x3C65, 0x2827, 0x3C6A,
1565
  0x3C6E, 0x3C72, 0x3C76, 0x3C7B, 0x3C7F, 0x3B82, 0x3C83, 0x3C88, 0x3C8C, 0x3C90, 0x3C94, 0x2904,
1566
  0x3C98, 0x114E, 0x3C9D, 0x3CA1, 0x3CA5, 0x3CA9, 0x3BCA, 0x3CAD, 0x3CB1, 0x2918, 0x282B, 0x282F,
1567
  0x291C, 0x3CB5, 0x3CB9, 0x2553, 0x3CBD, 0x2833, 0x3CC1, 0x3CC5, 0x3CC9, 0x3CCD, 0x3CCD, 0x3CCD,
1568
  0x3CD1, 0x3CD6, 0x3CDA, 0x3CDE, 0x3CE2, 0x3CE7, 0x3CEB, 0x3CEF, 0x3CF3, 0x3CF7, 0x3CFB, 0x3CFF,
1569
  0x3D03, 0x3D07, 0x3D0B, 0x3D0F, 0x3D13, 0x3D17, 0x3D17, 0x2924, 0x3D1B, 0x3D1F, 0x3D23, 0x3D27,
1570
  0x283B, 0x3D2B, 0x3D2F, 0x3D33, 0x279B, 0x3D37, 0x3D3B, 0x3D3F, 0x3D43, 0x3D47, 0x3D4B, 0x3D4F,
1571
  0x3D53, 0x3D57, 0x3D5C, 0x3D60, 0x3D64, 0x3B66, 0x3D68, 0x3D6C, 0x3D70, 0x3D75, 0x3D7A, 0x3D7E,
1572
  0x3D82, 0x3D86, 0x3D8A, 0x3D8E, 0x3D92, 0x3D96, 0x3D9A, 0x3D9A, 0x3D9E, 0x3DA3, 0x3DA7, 0x2543,
1573
  0x3DAB, 0x3DAF, 0x3DB4, 0x3DB8, 0x3DBC, 0x11B6, 0x3DC0, 0x3DC4, 0x11BE, 0x3DC8, 0x3DCC, 0x3DD0,
1574
  0x3DD5, 0x3DD9, 0x3DDE, 0x3DE2, 0x3DE6, 0x3DEA, 0x3DEE, 0x3DF2, 0x3DF6, 0x3DFA, 0x3DFE, 0x3E02,
1575
  0x3E06, 0x3E0A, 0x3E0F, 0x3E13, 0x3E17, 0x3E1B, 0x2473, 0x3E1F, 0x11E6, 0x3E24, 0x3E24, 0x3E29,
1576
  0x3E2D, 0x3E2D, 0x3E31, 0x3E35, 0x3E3A, 0x3E3F, 0x3E43, 0x3E47, 0x3E4B, 0x3E4F, 0x3E53, 0x3E57,
1577
  0x3E5B, 0x3E5F, 0x3E63, 0x284F, 0x3E67, 0x3E6C, 0x3E70, 0x3E74, 0x2954, 0x3E74, 0x3E78, 0x2857,
1578
  0x3E7C, 0x3E80, 0x3E84, 0x3E88, 0x285B, 0x2407, 0x3E8C, 0x3E90, 0x3E94, 0x3E98, 0x3E9C, 0x3EA0,
1579
  0x3EA4, 0x3EA9, 0x3EAD, 0x3EB1, 0x3EB5, 0x3EB9, 0x3EBD, 0x3EC2, 0x3EC6, 0x3ECA, 0x3ECE, 0x3ED2,
1580
  0x3ED6, 0x3EDA, 0x3EDE, 0x3EE2, 0x285F, 0x3EE6, 0x3EEA, 0x3EEF, 0x3EF3, 0x3EF7, 0x3EFB, 0x2867,
1581
  0x3EFF, 0x3F03, 0x3F07, 0x3F0B, 0x3F0F, 0x3F13, 0x3F17, 0x3F1B, 0x2477, 0x2974, 0x3F1F, 0x3F23,
1582
  0x3F27, 0x3F2B, 0x3F30, 0x3F34, 0x3F38, 0x3F3C, 0x286B, 0x3F40, 0x3F45, 0x3F49, 0x3F4D, 0x2A1F,
1583
  0x3F51, 0x3F55, 0x3F59, 0x3F5D, 0x3F61, 0x3F66, 0x3F6A, 0x3F6E, 0x3F72, 0x3F77, 0x3F7B, 0x3F7F,
1584
  0x3F83, 0x2587, 0x3F87, 0x3F8B, 0x3F90, 0x3F95, 0x3F9A, 0x3F9E, 0x3FA3, 0x3FA7, 0x3FAB, 0x3FAF,
1585
  0x3FB3, 0x286F, 0x26D3, 0x3FB7, 0x3FBB, 0x3FBF, 0x3FC3, 0x3FC8, 0x3FCC, 0x3FD0, 0x3FD4, 0x2980,
1586
  0x3FD8, 0x3FDC, 0x3FE1, 0x3FE5, 0x3FE9, 0x3FEE, 0x3FF3, 0x3FF7, 0x2984, 0x3FFB, 0x3FFF, 0x4003,
1587
  0x4007, 0x400B, 0x400F, 0x4013, 0x4018, 0x401C, 0x4021, 0x4025, 0x402A, 0x298C, 0x402E, 0x4032,
1588
  0x4037, 0x403B, 0x403F, 0x4044, 0x4049, 0x404D, 0x4051, 0x4055, 0x4059, 0x4059, 0x405D, 0x4061,
1589
  0x2994, 0x4065, 0x4069, 0x406D, 0x4071, 0x4075, 0x407A, 0x407E, 0x254F, 0x4083, 0x4088, 0x408C,
1590
  0x4091, 0x4096, 0x409B, 0x409F, 0x29AC, 0x40A3, 0x40A8, 0x40AD, 0x40B2, 0x40B7, 0x40BB, 0x40BB,
1591
  0x29B0, 0x2A27, 0x40BF, 0x40C3, 0x40C7, 0x40CB, 0x40D0, 0x24BB, 0x29B8, 0x40D4, 0x40D8, 0x2897,
1592
  0x40DD, 0x40E2, 0x27EB, 0x40E7, 0x40EB, 0x28A3, 0x40EF, 0x40F3, 0x40F7, 0x40FC, 0x40FC, 0x4101,
1593
  0x4105, 0x4109, 0x410E, 0x4112, 0x4116, 0x411A, 0x411F, 0x4123, 0x4127, 0x412B, 0x412F, 0x4133,
1594
  0x4138, 0x413C, 0x4140, 0x4144, 0x4148, 0x414C, 0x4150, 0x4155, 0x415A, 0x415E, 0x4163, 0x4167,
1595
  0x416C, 0x4170, 0x28BB, 0x4174, 0x4179, 0x417E, 0x4182, 0x4187, 0x418B, 0x4190, 0x4194, 0x4198,
1596
  0x419C, 0x41A0, 0x41A4, 0x41A8, 0x41AD, 0x41B2, 0x41B7, 0x3E29, 0x41BC, 0x41C0, 0x41C4, 0x41C8,
1597
  0x41CC, 0x41D0, 0x41D4, 0x41D8, 0x41DC, 0x41E0, 0x41E4, 0x41E8, 0x2593, 0x41ED, 0x41F1, 0x41F5,
1598
  0x41F9, 0x41FD, 0x4201, 0x28C7, 0x4205, 0x4209, 0x420D, 0x4211, 0x4215, 0x421A, 0x421F, 0x4224,
1599
  0x4228, 0x422C, 0x4230, 0x4234, 0x4239, 0x423D, 0x4242, 0x4246, 0x424A, 0x424F, 0x4254, 0x4258,
1600
  0x24A7, 0x425C, 0x4260, 0x4264, 0x4268, 0x426C, 0x4270, 0x29D4, 0x4274, 0x4278, 0x427C, 0x4280,
1601
  0x4284, 0x4288, 0x428C, 0x4290, 0x134E, 0x4294, 0x4299, 0x429D, 0x42A1, 0x42A5, 0x42A9, 0x42AD,
1602
  0x42B2, 0x42B7, 0x42BB, 0x42BF, 0x29E8, 0x29EC, 0x136A, 0x42C3, 0x42C8, 0x42CC, 0x42D0, 0x42D4,
1603
  0x42D8, 0x42DD, 0x42E2, 0x42E6, 0x42EA, 0x42EE, 0x42F3, 0x29F0, 0x42F7, 0x42FC, 0x4301, 0x4305,
1604
  0x4309, 0x430D, 0x4312, 0x4316, 0x431A, 0x431E, 0x4322, 0x4326, 0x432A, 0x432E, 0x4333, 0x4337,
1605
  0x433B, 0x433F, 0x4344, 0x4348, 0x434C, 0x4350, 0x4354, 0x4359, 0x435E, 0x4362, 0x4366, 0x436A,
1606
  0x436F, 0x4373, 0x2A08, 0x2A08, 0x4378, 0x437C, 0x4381, 0x4385, 0x4389, 0x438D, 0x4391, 0x4395,
1607
  0x4399, 0x439D, 0x2A0C, 0x43A2, 0x43A6, 0x43AA, 0x43AE, 0x43B2, 0x43B6, 0x43BB, 0x43BF, 0x43C4,
1608
  0x43C9, 0x142A, 0x43CE, 0x143A, 0x43D2, 0x43D6, 0x43DA, 0x43DE, 0x144E, 0x43E2, 0xFFFE, 0xFFFE,
1609
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1610
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
1611
  0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE
1612
};
1613
1614
// idna_bool_blocks[]: one uint64_t per boolean block.
1615
// Bit k (0 = LSB) = 1 -> (block_start + k) is VALID; 0 -> DISALLOWED.
1616
const uint64_t idna_bool_blocks[225] = {
1617
  0xFFFFFFFFFFFFFFFFULL, 0x001F87FFFFFF00FFULL, 0xFFFFFFFFEFFFFFC0ULL, 0xFFFFFFFFDFFFFFFFULL,
1618
  0xFFFFFFFFFFFF3FFFULL, 0xFFFFFFFFFFFFE7FFULL, 0x0003FFFFFFFFFFFFULL, 0xE7FFFFFFFFFFFFFFULL,
1619
  0x7FFF3FFFFFFFFFFFULL, 0xFFFF07FF4FFFFFFFULL, 0xFFFFFFFFFF80FFFFULL, 0xFFFFFFFBFFFFFFFFULL,
1620
  0xF3C5FDFFFFF99FEFULL, 0xF3EDFDFFFFFBBFEEULL, 0xFE03FFCF00013BBFULL, 0xF3EDFDFFFFF99FEEULL,
1621
  0xC3FFC718D63DC7ECULL, 0x07FFFFC000813DC7ULL, 0xF3FFFDFFFFFDDFFFULL, 0xFF80FFCF37603DDFULL,
1622
  0xF3EFFDFFFFFDDFFFULL, 0x000EFFCF70603DDFULL, 0xFFFFFFFFFFFDDFFFULL, 0xFFFFFFCFFFF0FDDFULL,
1623
  0x2FFBFFFFFC7FFFEEULL, 0x001CFFC0FF5F847FULL, 0x000000000FFFFFFFULL, 0x0000000007FFDFFFULL,
1624
  0xFFFFFFFF3D7F3DFFULL, 0x7F3DFFFFFFFF3DFFULL, 0xFFFFFFFFFF7FFF3DULL, 0xFFFFFFFFFF3DFFFFULL,
1625
  0x1FFFFFFFE7FFFFFFULL, 0xFFFFFFFF03FFFFFFULL, 0xFFFFFFFF1FFFFFFEULL, 0x01FFFFFFFFFFFFFFULL,
1626
  0x007FFFFF803FFFFFULL, 0x000DDFFF000FFFFFULL, 0x03FF03FF3FFFFFFFULL, 0xFFFF07FFFFFFFFFFULL,
1627
  0x003FFFFFFFFFFFFFULL, 0x0FFF0FFF7FFFFFFFULL, 0x001F3FFFFFFFFFF1ULL, 0xFFFF0FFFFFFFFFFFULL,
1628
  0xFFFFFFFFC7FF03FFULL, 0xFFFFFFFFCFFFFFFFULL, 0x9FFFFFFF7FFFFFFFULL, 0xFFFF3FFF03FF03FFULL,
1629
  0x00000FFF3FFFFFFFULL, 0xFFFFFFFFFFFFDFFFULL, 0xF00FFFFFFFFFFFFFULL, 0xF8FFFFFFFFFFFFFFULL,
1630
  0xFFFFFFFFFFFFE3FFULL, 0x07FFFFFFFFFF00FFULL, 0x0001FFFFFFFF0003ULL, 0x000003FFFFFFFFFFULL,
1631
  0xFFCFFFFFFFFFFFFFULL, 0xFFFF20BFFFFFFFFFULL, 0x7F7F7F7F007FFFFFULL, 0xFFFFFFFF7F7F7F7FULL,
1632
  0x000000003FFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFF003FFFFFFFFFULL, 0xFFFFFFFFFFFF1FFFULL,
1633
  0xFFFFFFFFFFFF007FULL, 0x00000FFFFFFFFFFFULL, 0x00FFFFFFFFFFFFFFULL, 0x03FF1FFFFFFFFFFFULL,
1634
  0xFFFFFFFF03FFC03FULL, 0x1FFFFFFF800FFFFFULL, 0x7FFFFFFFC3FFBFFFULL, 0x007FFFFFFFFFFFFFULL,
1635
  0xFFFFFFFFF3FF3FFFULL, 0x007FFFFFF8000007ULL, 0xFFFF7F7F007E7E7EULL, 0x03FF3FFFFFFFFFFFULL,
1636
  0xFFFF000FFFFFFFFFULL, 0x0FFFFFFFFFFFF87FULL, 0x0000000000000000ULL, 0xB7FFFF7FFFFFEFFFULL,
1637
  0x000000003FFF3FFFULL, 0x07FFFFFFFFFFFFFFULL, 0xFF8FFFFFFFFFFF87ULL, 0x000000011FFF7FFFULL,
1638
  0x3FFFFFFFFFFF0000ULL, 0xFFFFFFFF1FFFFFFFULL, 0x0FFFFFFF0001FFFFULL, 0xFFFFE00FFFFFFFFFULL,
1639
  0x07FFFFFFFFFF07FFULL, 0xFFFFFFFFBFFFFFFFULL, 0x00000000003FFF0FULL, 0xFFFF00FFFFFFFFFFULL,
1640
  0x000FFFFFFFFFFFFFULL, 0x000000FF003FFFFFULL, 0x91BFFFFFFFFFFD3FULL, 0xFFFFFFFFFFBFFFFFULL,
1641
  0x0000FF807FFFFFFFULL, 0xF837FFFF00000000ULL, 0x83FFFFFF8FFFFFFFULL, 0x0000000003FFFFFFULL,
1642
  0xF0FFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFCFFFFULL, 0x873FFFFFFEEFF06FULL, 0xFFFFFFFF01FF01FFULL,
1643
  0x00000000FFFFFFFFULL, 0x007FF87FFFFFFFFFULL, 0xFE3FFFFFFFFFFFFFULL, 0xFF07FFFFFF3FFFFFULL,
1644
  0x0000FE001E03FFFFULL, 0x00000000000001FFULL, 0xFC07FFFFFFFFFFFFULL, 0x03FF00FFFFFFFFFFULL,
1645
  0x000000000000C03FULL, 0x7FFFFFFF00000000ULL, 0x00033BFFFFFFFFFFULL, 0xFC00000001FF00FCULL,
1646
  0xFFFF000003FFFFFFULL, 0xFFFF0000000003FFULL, 0x007FFFFF00000FFFULL, 0x803FFFFFFFFC3FFFULL,
1647
  0xDFFFFFFFFFFFFFFFULL, 0x03FF01FFFFFF0007ULL, 0xFFDFFFFFFFFFFFFFULL, 0x007FFFFFFFFF00FFULL,
1648
  0x001FFFFEFFFFFFFFULL, 0xFFFFFFFFFFFBFFFFULL, 0x0000000000000003ULL, 0xFFFF03FFBFFFBD7FULL,
1649
  0x03FF07FFFFFFFFFFULL, 0xFBEDFDFFFFF99FEFULL, 0x001F1FCFE081399FULL, 0xFFBFFFFFFFFF4BFFULL,
1650
  0x0000000601BFF7A5ULL, 0x00000003EFFFFFFFULL, 0x0000000003FF00FFULL, 0xFF3FFFFFFFFFFFFFULL,
1651
  0x00001FFF03FF001FULL, 0x03FFFFFFFFFFFFFFULL, 0x0000000FFFFF03FFULL, 0xFFFF0FFFE7FFFFFFULL,
1652
  0x000000000000007FULL, 0x0FFFFFFFFFFFFFFFULL, 0x8007FFFFFFFFFFFFULL, 0xF9BFFFFFFF6FF27FULL,
1653
  0x0000000003FF007FULL, 0xFFFFFCFF00000000ULL, 0x0000001FFCFFFFFFULL, 0xFFFFFFFFFFFF00FFULL,
1654
  0xFFFF0007FFFFFFFFULL, 0x00000000000003FFULL, 0x000000FF00000000ULL, 0x03FF0003FFFFFFFFULL,
1655
  0xFF7FFFFFFFFFFDFFULL, 0xFFFF1FFFFFFF003FULL, 0x007FFEFFFFFCFFFFULL, 0xB47FFFFFFFFFFB7FULL,
1656
  0xFFFFFDBF03FF00FFULL, 0xFFFF03FF01FB7FFFULL, 0x000003FF0FFFFFFFULL, 0x01FFFFFF00000000ULL,
1657
  0xC7FFFFFFFFFDFFFFULL, 0x0000000007FFFFFFULL, 0x0001000000000000ULL, 0x8003FFFFFFFFFFFFULL,
1658
  0x001F7FFFFFFFFFFFULL, 0x000000000000000FULL, 0xFFFFFFFFFFFF0000ULL, 0x0007FFFFFFFFFFFFULL,
1659
  0x0000FFFFFFFFFFFFULL, 0xFFFFFFFF003FFFFFULL, 0xFFFFC3FF7FFFFFFFULL, 0x7FFFFFFFFFFFFFFFULL,
1660
  0x003F3FFFFFFF03FFULL, 0xE0FFFFFBFBFF003FULL, 0x000000000000FFFFULL, 0x00000000000FFFFFULL,
1661
  0xFFFFFFFFFFFF87FFULL, 0x00000000FFFF80FFULL, 0x007F001F00000000ULL, 0x80000000003FFFFFULL,
1662
  0x000000007FFFFFFFULL, 0x6FEF000000000000ULL, 0x00040007FFFFFFFFULL, 0xFFFF00F000270000ULL,
1663
  0x1FFF07FFFFFFFFFFULL, 0xFC0FFFFFFFFFFFFFULL, 0x0001FFFF0001FFFFULL, 0xFFFF3FFFFFFFFFFFULL,
1664
  0xFFFFFE7FFFFFFFFFULL, 0x000000000000003FULL, 0x000FFFFF000FFFFFULL, 0x01FFFFFF007FFFFFULL,
1665
  0x0000FFFEF8000FFFULL, 0x000007E07FFFFFFFULL, 0x0000000000008000ULL, 0x3FFF1FFFFFFFFFFFULL,
1666
  0x000000000000C3FFULL, 0x00007FFFFFFF0000ULL, 0x83FFFFFFFFFFFFFFULL, 0x03FFFFFFFFFF0000ULL,
1667
  0x87FFFFFFFFFF0000ULL, 0xC03FFFFF7FFFFFFFULL, 0x7FFF6F7F00000000ULL, 0x00000000007FFF9FULL,
1668
  0x00000000C3FF0FFFULL, 0xFFFE000000000000ULL, 0x001FFFFFFFFFFFFFULL, 0x3FFFFFFFFFFFFFFEULL,
1669
  0x0003000000000000ULL, 0xFFFE7FFF000FFFFFULL, 0x003FFFFFFFFEFFFEULL, 0xFFFFFFC000000000ULL,
1670
  0x1FFF1FFFF1FFFFFFULL, 0x00010FFF03FFFFFFULL, 0xFFFFFFFFFFFF0FFFULL, 0xFFFFFFFF03FF00FFULL,
1671
  0x0FFF3FFFFFFF00FFULL, 0x0000000001FF0003ULL, 0x1FFF3FFF00FFFFFFULL, 0xFFFFFFFFFFFFC7FFULL,
1672
  0x01FF87FF9FFFE17FULL, 0xFFFFFFFFFFF7FFFFULL, 0xFFFFFFFF3FFFFFFFULL, 0xFFFF0001FFFFFFFFULL,
1673
  0xFFFFFFFFFFFF07FFULL
1674
};
1675
1676
// idna_utf8_mappings[]: null-terminated UTF-8 mapping strings.
1677
// Byte offset 0 is the empty string (for ignored code points).
1678
const uint8_t idna_utf8_mappings[17383] = {
1679
  0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68,
1680
  0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x70,
1681
  0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78,
1682
  0x00, 0x79, 0x00, 0x7A, 0x00, 0x20, 0x00, 0x20, 0xCC, 0x88, 0x00, 0x20, 0xCC, 0x84, 0x00, 0x32,
1683
  0x00, 0x33, 0x00, 0x20, 0xCC, 0x81, 0x00, 0xCE, 0xBC, 0x00, 0x20, 0xCC, 0xA7, 0x00, 0x31, 0x00,
1684
  0x31, 0xE2, 0x81, 0x84, 0x34, 0x00, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x00, 0x33, 0xE2, 0x81, 0x84,
1685
  0x34, 0x00, 0xC3, 0xA0, 0x00, 0xC3, 0xA1, 0x00, 0xC3, 0xA2, 0x00, 0xC3, 0xA3, 0x00, 0xC3, 0xA4,
1686
  0x00, 0xC3, 0xA5, 0x00, 0xC3, 0xA6, 0x00, 0xC3, 0xA7, 0x00, 0xC3, 0xA8, 0x00, 0xC3, 0xA9, 0x00,
1687
  0xC3, 0xAA, 0x00, 0xC3, 0xAB, 0x00, 0xC3, 0xAC, 0x00, 0xC3, 0xAD, 0x00, 0xC3, 0xAE, 0x00, 0xC3,
1688
  0xAF, 0x00, 0xC3, 0xB0, 0x00, 0xC3, 0xB1, 0x00, 0xC3, 0xB2, 0x00, 0xC3, 0xB3, 0x00, 0xC3, 0xB4,
1689
  0x00, 0xC3, 0xB5, 0x00, 0xC3, 0xB6, 0x00, 0xC3, 0xB8, 0x00, 0xC3, 0xB9, 0x00, 0xC3, 0xBA, 0x00,
1690
  0xC3, 0xBB, 0x00, 0xC3, 0xBC, 0x00, 0xC3, 0xBD, 0x00, 0xC3, 0xBE, 0x00, 0xC4, 0x81, 0x00, 0xC4,
1691
  0x83, 0x00, 0xC4, 0x85, 0x00, 0xC4, 0x87, 0x00, 0xC4, 0x89, 0x00, 0xC4, 0x8B, 0x00, 0xC4, 0x8D,
1692
  0x00, 0xC4, 0x8F, 0x00, 0xC4, 0x91, 0x00, 0xC4, 0x93, 0x00, 0xC4, 0x95, 0x00, 0xC4, 0x97, 0x00,
1693
  0xC4, 0x99, 0x00, 0xC4, 0x9B, 0x00, 0xC4, 0x9D, 0x00, 0xC4, 0x9F, 0x00, 0xC4, 0xA1, 0x00, 0xC4,
1694
  0xA3, 0x00, 0xC4, 0xA5, 0x00, 0xC4, 0xA7, 0x00, 0xC4, 0xA9, 0x00, 0xC4, 0xAB, 0x00, 0xC4, 0xAD,
1695
  0x00, 0xC4, 0xAF, 0x00, 0x69, 0xCC, 0x87, 0x00, 0x69, 0x6A, 0x00, 0xC4, 0xB5, 0x00, 0xC4, 0xB7,
1696
  0x00, 0xC4, 0xBA, 0x00, 0xC4, 0xBC, 0x00, 0xC4, 0xBE, 0x00, 0x6C, 0xC2, 0xB7, 0x00, 0xC5, 0x82,
1697
  0x00, 0xC5, 0x84, 0x00, 0xC5, 0x86, 0x00, 0xC5, 0x88, 0x00, 0xCA, 0xBC, 0x6E, 0x00, 0xC5, 0x8B,
1698
  0x00, 0xC5, 0x8D, 0x00, 0xC5, 0x8F, 0x00, 0xC5, 0x91, 0x00, 0xC5, 0x93, 0x00, 0xC5, 0x95, 0x00,
1699
  0xC5, 0x97, 0x00, 0xC5, 0x99, 0x00, 0xC5, 0x9B, 0x00, 0xC5, 0x9D, 0x00, 0xC5, 0x9F, 0x00, 0xC5,
1700
  0xA1, 0x00, 0xC5, 0xA3, 0x00, 0xC5, 0xA5, 0x00, 0xC5, 0xA7, 0x00, 0xC5, 0xA9, 0x00, 0xC5, 0xAB,
1701
  0x00, 0xC5, 0xAD, 0x00, 0xC5, 0xAF, 0x00, 0xC5, 0xB1, 0x00, 0xC5, 0xB3, 0x00, 0xC5, 0xB5, 0x00,
1702
  0xC5, 0xB7, 0x00, 0xC3, 0xBF, 0x00, 0xC5, 0xBA, 0x00, 0xC5, 0xBC, 0x00, 0xC5, 0xBE, 0x00, 0xC9,
1703
  0x93, 0x00, 0xC6, 0x83, 0x00, 0xC6, 0x85, 0x00, 0xC9, 0x94, 0x00, 0xC6, 0x88, 0x00, 0xC9, 0x96,
1704
  0x00, 0xC9, 0x97, 0x00, 0xC6, 0x8C, 0x00, 0xC7, 0x9D, 0x00, 0xC9, 0x99, 0x00, 0xC9, 0x9B, 0x00,
1705
  0xC6, 0x92, 0x00, 0xC9, 0xA0, 0x00, 0xC9, 0xA3, 0x00, 0xC9, 0xA9, 0x00, 0xC9, 0xA8, 0x00, 0xC6,
1706
  0x99, 0x00, 0xC9, 0xAF, 0x00, 0xC9, 0xB2, 0x00, 0xC9, 0xB5, 0x00, 0xC6, 0xA1, 0x00, 0xC6, 0xA3,
1707
  0x00, 0xC6, 0xA5, 0x00, 0xCA, 0x80, 0x00, 0xC6, 0xA8, 0x00, 0xCA, 0x83, 0x00, 0xC6, 0xAD, 0x00,
1708
  0xCA, 0x88, 0x00, 0xC6, 0xB0, 0x00, 0xCA, 0x8A, 0x00, 0xCA, 0x8B, 0x00, 0xC6, 0xB4, 0x00, 0xC6,
1709
  0xB6, 0x00, 0xCA, 0x92, 0x00, 0xC6, 0xB9, 0x00, 0xC6, 0xBD, 0x00, 0x64, 0xC5, 0xBE, 0x00, 0x6C,
1710
  0x6A, 0x00, 0x6E, 0x6A, 0x00, 0xC7, 0x8E, 0x00, 0xC7, 0x90, 0x00, 0xC7, 0x92, 0x00, 0xC7, 0x94,
1711
  0x00, 0xC7, 0x96, 0x00, 0xC7, 0x98, 0x00, 0xC7, 0x9A, 0x00, 0xC7, 0x9C, 0x00, 0xC7, 0x9F, 0x00,
1712
  0xC7, 0xA1, 0x00, 0xC7, 0xA3, 0x00, 0xC7, 0xA5, 0x00, 0xC7, 0xA7, 0x00, 0xC7, 0xA9, 0x00, 0xC7,
1713
  0xAB, 0x00, 0xC7, 0xAD, 0x00, 0xC7, 0xAF, 0x00, 0x64, 0x7A, 0x00, 0xC7, 0xB5, 0x00, 0xC6, 0x95,
1714
  0x00, 0xC6, 0xBF, 0x00, 0xC7, 0xB9, 0x00, 0xC7, 0xBB, 0x00, 0xC7, 0xBD, 0x00, 0xC7, 0xBF, 0x00,
1715
  0xC8, 0x81, 0x00, 0xC8, 0x83, 0x00, 0xC8, 0x85, 0x00, 0xC8, 0x87, 0x00, 0xC8, 0x89, 0x00, 0xC8,
1716
  0x8B, 0x00, 0xC8, 0x8D, 0x00, 0xC8, 0x8F, 0x00, 0xC8, 0x91, 0x00, 0xC8, 0x93, 0x00, 0xC8, 0x95,
1717
  0x00, 0xC8, 0x97, 0x00, 0xC8, 0x99, 0x00, 0xC8, 0x9B, 0x00, 0xC8, 0x9D, 0x00, 0xC8, 0x9F, 0x00,
1718
  0xC6, 0x9E, 0x00, 0xC8, 0xA3, 0x00, 0xC8, 0xA5, 0x00, 0xC8, 0xA7, 0x00, 0xC8, 0xA9, 0x00, 0xC8,
1719
  0xAB, 0x00, 0xC8, 0xAD, 0x00, 0xC8, 0xAF, 0x00, 0xC8, 0xB1, 0x00, 0xC8, 0xB3, 0x00, 0xE2, 0xB1,
1720
  0xA5, 0x00, 0xC8, 0xBC, 0x00, 0xC6, 0x9A, 0x00, 0xE2, 0xB1, 0xA6, 0x00, 0xC9, 0x82, 0x00, 0xC6,
1721
  0x80, 0x00, 0xCA, 0x89, 0x00, 0xCA, 0x8C, 0x00, 0xC9, 0x87, 0x00, 0xC9, 0x89, 0x00, 0xC9, 0x8B,
1722
  0x00, 0xC9, 0x8D, 0x00, 0xC9, 0x8F, 0x00, 0xC9, 0xA6, 0x00, 0xC9, 0xB9, 0x00, 0xC9, 0xBB, 0x00,
1723
  0xCA, 0x81, 0x00, 0x20, 0xCC, 0x86, 0x00, 0x20, 0xCC, 0x87, 0x00, 0x20, 0xCC, 0x8A, 0x00, 0x20,
1724
  0xCC, 0xA8, 0x00, 0x20, 0xCC, 0x83, 0x00, 0x20, 0xCC, 0x8B, 0x00, 0xCA, 0x95, 0x00, 0xCC, 0x80,
1725
  0x00, 0xCC, 0x81, 0x00, 0xCC, 0x93, 0x00, 0xCC, 0x88, 0xCC, 0x81, 0x00, 0xCE, 0xB9, 0x00, 0xCD,
1726
  0xB1, 0x00, 0xCD, 0xB3, 0x00, 0xCA, 0xB9, 0x00, 0xCD, 0xB7, 0x00, 0x20, 0xCE, 0xB9, 0x00, 0x3B,
1727
  0x00, 0xCF, 0xB3, 0x00, 0x20, 0xCC, 0x88, 0xCC, 0x81, 0x00, 0xCE, 0xAC, 0x00, 0xC2, 0xB7, 0x00,
1728
  0xCE, 0xAD, 0x00, 0xCE, 0xAE, 0x00, 0xCE, 0xAF, 0x00, 0xCF, 0x8C, 0x00, 0xCF, 0x8D, 0x00, 0xCF,
1729
  0x8E, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB2, 0x00, 0xCE, 0xB3, 0x00, 0xCE, 0xB4, 0x00, 0xCE, 0xB5,
1730
  0x00, 0xCE, 0xB6, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB8, 0x00, 0xCE, 0xBA, 0x00, 0xCE, 0xBB, 0x00,
1731
  0xCE, 0xBD, 0x00, 0xCE, 0xBE, 0x00, 0xCE, 0xBF, 0x00, 0xCF, 0x80, 0x00, 0xCF, 0x81, 0x00, 0xCF,
1732
  0x83, 0x00, 0xCF, 0x84, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x86, 0x00, 0xCF, 0x87, 0x00, 0xCF, 0x88,
1733
  0x00, 0xCF, 0x89, 0x00, 0xCF, 0x8A, 0x00, 0xCF, 0x8B, 0x00, 0xCF, 0x97, 0x00, 0xCF, 0x99, 0x00,
1734
  0xCF, 0x9B, 0x00, 0xCF, 0x9D, 0x00, 0xCF, 0x9F, 0x00, 0xCF, 0xA1, 0x00, 0xCF, 0xA3, 0x00, 0xCF,
1735
  0xA5, 0x00, 0xCF, 0xA7, 0x00, 0xCF, 0xA9, 0x00, 0xCF, 0xAB, 0x00, 0xCF, 0xAD, 0x00, 0xCF, 0xAF,
1736
  0x00, 0xCF, 0xB8, 0x00, 0xCF, 0xBB, 0x00, 0xCD, 0xBB, 0x00, 0xCD, 0xBC, 0x00, 0xCD, 0xBD, 0x00,
1737
  0xD1, 0x90, 0x00, 0xD1, 0x91, 0x00, 0xD1, 0x92, 0x00, 0xD1, 0x93, 0x00, 0xD1, 0x94, 0x00, 0xD1,
1738
  0x95, 0x00, 0xD1, 0x96, 0x00, 0xD1, 0x97, 0x00, 0xD1, 0x98, 0x00, 0xD1, 0x99, 0x00, 0xD1, 0x9A,
1739
  0x00, 0xD1, 0x9B, 0x00, 0xD1, 0x9C, 0x00, 0xD1, 0x9D, 0x00, 0xD1, 0x9E, 0x00, 0xD1, 0x9F, 0x00,
1740
  0xD0, 0xB0, 0x00, 0xD0, 0xB1, 0x00, 0xD0, 0xB2, 0x00, 0xD0, 0xB3, 0x00, 0xD0, 0xB4, 0x00, 0xD0,
1741
  0xB5, 0x00, 0xD0, 0xB6, 0x00, 0xD0, 0xB7, 0x00, 0xD0, 0xB8, 0x00, 0xD0, 0xB9, 0x00, 0xD0, 0xBA,
1742
  0x00, 0xD0, 0xBB, 0x00, 0xD0, 0xBC, 0x00, 0xD0, 0xBD, 0x00, 0xD0, 0xBE, 0x00, 0xD0, 0xBF, 0x00,
1743
  0xD1, 0x80, 0x00, 0xD1, 0x81, 0x00, 0xD1, 0x82, 0x00, 0xD1, 0x83, 0x00, 0xD1, 0x84, 0x00, 0xD1,
1744
  0x85, 0x00, 0xD1, 0x86, 0x00, 0xD1, 0x87, 0x00, 0xD1, 0x88, 0x00, 0xD1, 0x89, 0x00, 0xD1, 0x8A,
1745
  0x00, 0xD1, 0x8B, 0x00, 0xD1, 0x8C, 0x00, 0xD1, 0x8D, 0x00, 0xD1, 0x8E, 0x00, 0xD1, 0x8F, 0x00,
1746
  0xD1, 0xA1, 0x00, 0xD1, 0xA3, 0x00, 0xD1, 0xA5, 0x00, 0xD1, 0xA7, 0x00, 0xD1, 0xA9, 0x00, 0xD1,
1747
  0xAB, 0x00, 0xD1, 0xAD, 0x00, 0xD1, 0xAF, 0x00, 0xD1, 0xB1, 0x00, 0xD1, 0xB3, 0x00, 0xD1, 0xB5,
1748
  0x00, 0xD1, 0xB7, 0x00, 0xD1, 0xB9, 0x00, 0xD1, 0xBB, 0x00, 0xD1, 0xBD, 0x00, 0xD1, 0xBF, 0x00,
1749
  0xD2, 0x81, 0x00, 0xD2, 0x8B, 0x00, 0xD2, 0x8D, 0x00, 0xD2, 0x8F, 0x00, 0xD2, 0x91, 0x00, 0xD2,
1750
  0x93, 0x00, 0xD2, 0x95, 0x00, 0xD2, 0x97, 0x00, 0xD2, 0x99, 0x00, 0xD2, 0x9B, 0x00, 0xD2, 0x9D,
1751
  0x00, 0xD2, 0x9F, 0x00, 0xD2, 0xA1, 0x00, 0xD2, 0xA3, 0x00, 0xD2, 0xA5, 0x00, 0xD2, 0xA7, 0x00,
1752
  0xD2, 0xA9, 0x00, 0xD2, 0xAB, 0x00, 0xD2, 0xAD, 0x00, 0xD2, 0xAF, 0x00, 0xD2, 0xB1, 0x00, 0xD2,
1753
  0xB3, 0x00, 0xD2, 0xB5, 0x00, 0xD2, 0xB7, 0x00, 0xD2, 0xB9, 0x00, 0xD2, 0xBB, 0x00, 0xD2, 0xBD,
1754
  0x00, 0xD2, 0xBF, 0x00, 0xD3, 0x8F, 0x00, 0xD3, 0x82, 0x00, 0xD3, 0x84, 0x00, 0xD3, 0x86, 0x00,
1755
  0xD3, 0x88, 0x00, 0xD3, 0x8A, 0x00, 0xD3, 0x8C, 0x00, 0xD3, 0x8E, 0x00, 0xD3, 0x91, 0x00, 0xD3,
1756
  0x93, 0x00, 0xD3, 0x95, 0x00, 0xD3, 0x97, 0x00, 0xD3, 0x99, 0x00, 0xD3, 0x9B, 0x00, 0xD3, 0x9D,
1757
  0x00, 0xD3, 0x9F, 0x00, 0xD3, 0xA1, 0x00, 0xD3, 0xA3, 0x00, 0xD3, 0xA5, 0x00, 0xD3, 0xA7, 0x00,
1758
  0xD3, 0xA9, 0x00, 0xD3, 0xAB, 0x00, 0xD3, 0xAD, 0x00, 0xD3, 0xAF, 0x00, 0xD3, 0xB1, 0x00, 0xD3,
1759
  0xB3, 0x00, 0xD3, 0xB5, 0x00, 0xD3, 0xB7, 0x00, 0xD3, 0xB9, 0x00, 0xD3, 0xBB, 0x00, 0xD3, 0xBD,
1760
  0x00, 0xD3, 0xBF, 0x00, 0xD4, 0x81, 0x00, 0xD4, 0x83, 0x00, 0xD4, 0x85, 0x00, 0xD4, 0x87, 0x00,
1761
  0xD4, 0x89, 0x00, 0xD4, 0x8B, 0x00, 0xD4, 0x8D, 0x00, 0xD4, 0x8F, 0x00, 0xD4, 0x91, 0x00, 0xD4,
1762
  0x93, 0x00, 0xD4, 0x95, 0x00, 0xD4, 0x97, 0x00, 0xD4, 0x99, 0x00, 0xD4, 0x9B, 0x00, 0xD4, 0x9D,
1763
  0x00, 0xD4, 0x9F, 0x00, 0xD4, 0xA1, 0x00, 0xD4, 0xA3, 0x00, 0xD4, 0xA5, 0x00, 0xD4, 0xA7, 0x00,
1764
  0xD4, 0xA9, 0x00, 0xD4, 0xAB, 0x00, 0xD4, 0xAD, 0x00, 0xD4, 0xAF, 0x00, 0xD5, 0xA1, 0x00, 0xD5,
1765
  0xA2, 0x00, 0xD5, 0xA3, 0x00, 0xD5, 0xA4, 0x00, 0xD5, 0xA5, 0x00, 0xD5, 0xA6, 0x00, 0xD5, 0xA7,
1766
  0x00, 0xD5, 0xA8, 0x00, 0xD5, 0xA9, 0x00, 0xD5, 0xAA, 0x00, 0xD5, 0xAB, 0x00, 0xD5, 0xAC, 0x00,
1767
  0xD5, 0xAD, 0x00, 0xD5, 0xAE, 0x00, 0xD5, 0xAF, 0x00, 0xD5, 0xB0, 0x00, 0xD5, 0xB1, 0x00, 0xD5,
1768
  0xB2, 0x00, 0xD5, 0xB3, 0x00, 0xD5, 0xB4, 0x00, 0xD5, 0xB5, 0x00, 0xD5, 0xB6, 0x00, 0xD5, 0xB7,
1769
  0x00, 0xD5, 0xB8, 0x00, 0xD5, 0xB9, 0x00, 0xD5, 0xBA, 0x00, 0xD5, 0xBB, 0x00, 0xD5, 0xBC, 0x00,
1770
  0xD5, 0xBD, 0x00, 0xD5, 0xBE, 0x00, 0xD5, 0xBF, 0x00, 0xD6, 0x80, 0x00, 0xD6, 0x81, 0x00, 0xD6,
1771
  0x82, 0x00, 0xD6, 0x83, 0x00, 0xD6, 0x84, 0x00, 0xD6, 0x85, 0x00, 0xD6, 0x86, 0x00, 0xD5, 0xA5,
1772
  0xD6, 0x82, 0x00, 0xD8, 0xA7, 0xD9, 0xB4, 0x00, 0xD9, 0x88, 0xD9, 0xB4, 0x00, 0xDB, 0x87, 0xD9,
1773
  0xB4, 0x00, 0xD9, 0x8A, 0xD9, 0xB4, 0x00, 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBC, 0x00, 0xE0, 0xA4,
1774
  0x96, 0xE0, 0xA4, 0xBC, 0x00, 0xE0, 0xA4, 0x97, 0xE0, 0xA4, 0xBC, 0x00, 0xE0, 0xA4, 0x9C, 0xE0,
1775
  0xA4, 0xBC, 0x00, 0xE0, 0xA4, 0xA1, 0xE0, 0xA4, 0xBC, 0x00, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, 0xBC,
1776
  0x00, 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC, 0x00, 0xE0, 0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0x00, 0xE0,
1777
  0xA6, 0xA1, 0xE0, 0xA6, 0xBC, 0x00, 0xE0, 0xA6, 0xA2, 0xE0, 0xA6, 0xBC, 0x00, 0xE0, 0xA6, 0xAF,
1778
  0xE0, 0xA6, 0xBC, 0x00, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, 0xBC, 0x00, 0xE0, 0xA8, 0xB8, 0xE0, 0xA8,
1779
  0xBC, 0x00, 0xE0, 0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0x00, 0xE0, 0xA8, 0x97, 0xE0, 0xA8, 0xBC, 0x00,
1780
  0xE0, 0xA8, 0x9C, 0xE0, 0xA8, 0xBC, 0x00, 0xE0, 0xA8, 0xAB, 0xE0, 0xA8, 0xBC, 0x00, 0xE0, 0xAC,
1781
  0xA1, 0xE0, 0xAC, 0xBC, 0x00, 0xE0, 0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0x00, 0xE0, 0xB9, 0x8D, 0xE0,
1782
  0xB8, 0xB2, 0x00, 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, 0x00, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99,
1783
  0x00, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0xA1, 0x00, 0xE0, 0xBC, 0x8B, 0x00, 0xE0, 0xBD, 0x82, 0xE0,
1784
  0xBE, 0xB7, 0x00, 0xE0, 0xBD, 0x8C, 0xE0, 0xBE, 0xB7, 0x00, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, 0xB7,
1785
  0x00, 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, 0x00, 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x00, 0xE0,
1786
  0xBD, 0x80, 0xE0, 0xBE, 0xB5, 0x00, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2, 0x00, 0xE0, 0xBD, 0xB1,
1787
  0xE0, 0xBD, 0xB4, 0x00, 0xE0, 0xBE, 0xB2, 0xE0, 0xBE, 0x80, 0x00, 0xE0, 0xBE, 0xB2, 0xE0, 0xBD,
1788
  0xB1, 0xE0, 0xBE, 0x80, 0x00, 0xE0, 0xBE, 0xB3, 0xE0, 0xBE, 0x80, 0x00, 0xE0, 0xBE, 0xB3, 0xE0,
1789
  0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x00, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x00, 0xE0, 0xBE, 0x92,
1790
  0xE0, 0xBE, 0xB7, 0x00, 0xE0, 0xBE, 0x9C, 0xE0, 0xBE, 0xB7, 0x00, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE,
1791
  0xB7, 0x00, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7, 0x00, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0x00,
1792
  0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0x00, 0xE2, 0xB4, 0x80, 0x00, 0xE2, 0xB4, 0x81, 0x00, 0xE2,
1793
  0xB4, 0x82, 0x00, 0xE2, 0xB4, 0x83, 0x00, 0xE2, 0xB4, 0x84, 0x00, 0xE2, 0xB4, 0x85, 0x00, 0xE2,
1794
  0xB4, 0x86, 0x00, 0xE2, 0xB4, 0x87, 0x00, 0xE2, 0xB4, 0x88, 0x00, 0xE2, 0xB4, 0x89, 0x00, 0xE2,
1795
  0xB4, 0x8A, 0x00, 0xE2, 0xB4, 0x8B, 0x00, 0xE2, 0xB4, 0x8C, 0x00, 0xE2, 0xB4, 0x8D, 0x00, 0xE2,
1796
  0xB4, 0x8E, 0x00, 0xE2, 0xB4, 0x8F, 0x00, 0xE2, 0xB4, 0x90, 0x00, 0xE2, 0xB4, 0x91, 0x00, 0xE2,
1797
  0xB4, 0x92, 0x00, 0xE2, 0xB4, 0x93, 0x00, 0xE2, 0xB4, 0x94, 0x00, 0xE2, 0xB4, 0x95, 0x00, 0xE2,
1798
  0xB4, 0x96, 0x00, 0xE2, 0xB4, 0x97, 0x00, 0xE2, 0xB4, 0x98, 0x00, 0xE2, 0xB4, 0x99, 0x00, 0xE2,
1799
  0xB4, 0x9A, 0x00, 0xE2, 0xB4, 0x9B, 0x00, 0xE2, 0xB4, 0x9C, 0x00, 0xE2, 0xB4, 0x9D, 0x00, 0xE2,
1800
  0xB4, 0x9E, 0x00, 0xE2, 0xB4, 0x9F, 0x00, 0xE2, 0xB4, 0xA0, 0x00, 0xE2, 0xB4, 0xA1, 0x00, 0xE2,
1801
  0xB4, 0xA2, 0x00, 0xE2, 0xB4, 0xA3, 0x00, 0xE2, 0xB4, 0xA4, 0x00, 0xE2, 0xB4, 0xA5, 0x00, 0xE2,
1802
  0xB4, 0xA7, 0x00, 0xE2, 0xB4, 0xAD, 0x00, 0xE1, 0x83, 0x9C, 0x00, 0xE1, 0x8F, 0xB0, 0x00, 0xE1,
1803
  0x8F, 0xB1, 0x00, 0xE1, 0x8F, 0xB2, 0x00, 0xE1, 0x8F, 0xB3, 0x00, 0xE1, 0x8F, 0xB4, 0x00, 0xE1,
1804
  0x8F, 0xB5, 0x00, 0xEA, 0x99, 0x8B, 0x00, 0xE1, 0xB2, 0x8A, 0x00, 0xE1, 0x83, 0x90, 0x00, 0xE1,
1805
  0x83, 0x91, 0x00, 0xE1, 0x83, 0x92, 0x00, 0xE1, 0x83, 0x93, 0x00, 0xE1, 0x83, 0x94, 0x00, 0xE1,
1806
  0x83, 0x95, 0x00, 0xE1, 0x83, 0x96, 0x00, 0xE1, 0x83, 0x97, 0x00, 0xE1, 0x83, 0x98, 0x00, 0xE1,
1807
  0x83, 0x99, 0x00, 0xE1, 0x83, 0x9A, 0x00, 0xE1, 0x83, 0x9B, 0x00, 0xE1, 0x83, 0x9D, 0x00, 0xE1,
1808
  0x83, 0x9E, 0x00, 0xE1, 0x83, 0x9F, 0x00, 0xE1, 0x83, 0xA0, 0x00, 0xE1, 0x83, 0xA1, 0x00, 0xE1,
1809
  0x83, 0xA2, 0x00, 0xE1, 0x83, 0xA3, 0x00, 0xE1, 0x83, 0xA4, 0x00, 0xE1, 0x83, 0xA5, 0x00, 0xE1,
1810
  0x83, 0xA6, 0x00, 0xE1, 0x83, 0xA7, 0x00, 0xE1, 0x83, 0xA8, 0x00, 0xE1, 0x83, 0xA9, 0x00, 0xE1,
1811
  0x83, 0xAA, 0x00, 0xE1, 0x83, 0xAB, 0x00, 0xE1, 0x83, 0xAC, 0x00, 0xE1, 0x83, 0xAD, 0x00, 0xE1,
1812
  0x83, 0xAE, 0x00, 0xE1, 0x83, 0xAF, 0x00, 0xE1, 0x83, 0xB0, 0x00, 0xE1, 0x83, 0xB1, 0x00, 0xE1,
1813
  0x83, 0xB2, 0x00, 0xE1, 0x83, 0xB3, 0x00, 0xE1, 0x83, 0xB4, 0x00, 0xE1, 0x83, 0xB5, 0x00, 0xE1,
1814
  0x83, 0xB6, 0x00, 0xE1, 0x83, 0xB7, 0x00, 0xE1, 0x83, 0xB8, 0x00, 0xE1, 0x83, 0xB9, 0x00, 0xE1,
1815
  0x83, 0xBA, 0x00, 0xE1, 0x83, 0xBD, 0x00, 0xE1, 0x83, 0xBE, 0x00, 0xE1, 0x83, 0xBF, 0x00, 0xC9,
1816
  0x90, 0x00, 0xC9, 0x91, 0x00, 0xE1, 0xB4, 0x82, 0x00, 0xC9, 0x9C, 0x00, 0xE1, 0xB4, 0x96, 0x00,
1817
  0xE1, 0xB4, 0x97, 0x00, 0xE1, 0xB4, 0x9D, 0x00, 0xE1, 0xB4, 0xA5, 0x00, 0xC9, 0x92, 0x00, 0xC9,
1818
  0x95, 0x00, 0xC9, 0x9F, 0x00, 0xC9, 0xA1, 0x00, 0xC9, 0xA5, 0x00, 0xC9, 0xAA, 0x00, 0xE1, 0xB5,
1819
  0xBB, 0x00, 0xCA, 0x9D, 0x00, 0xC9, 0xAD, 0x00, 0xE1, 0xB6, 0x85, 0x00, 0xCA, 0x9F, 0x00, 0xC9,
1820
  0xB1, 0x00, 0xC9, 0xB0, 0x00, 0xC9, 0xB3, 0x00, 0xC9, 0xB4, 0x00, 0xC9, 0xB8, 0x00, 0xCA, 0x82,
1821
  0x00, 0xC6, 0xAB, 0x00, 0xE1, 0xB4, 0x9C, 0x00, 0xCA, 0x90, 0x00, 0xCA, 0x91, 0x00, 0xE1, 0xB8,
1822
  0x81, 0x00, 0xE1, 0xB8, 0x83, 0x00, 0xE1, 0xB8, 0x85, 0x00, 0xE1, 0xB8, 0x87, 0x00, 0xE1, 0xB8,
1823
  0x89, 0x00, 0xE1, 0xB8, 0x8B, 0x00, 0xE1, 0xB8, 0x8D, 0x00, 0xE1, 0xB8, 0x8F, 0x00, 0xE1, 0xB8,
1824
  0x91, 0x00, 0xE1, 0xB8, 0x93, 0x00, 0xE1, 0xB8, 0x95, 0x00, 0xE1, 0xB8, 0x97, 0x00, 0xE1, 0xB8,
1825
  0x99, 0x00, 0xE1, 0xB8, 0x9B, 0x00, 0xE1, 0xB8, 0x9D, 0x00, 0xE1, 0xB8, 0x9F, 0x00, 0xE1, 0xB8,
1826
  0xA1, 0x00, 0xE1, 0xB8, 0xA3, 0x00, 0xE1, 0xB8, 0xA5, 0x00, 0xE1, 0xB8, 0xA7, 0x00, 0xE1, 0xB8,
1827
  0xA9, 0x00, 0xE1, 0xB8, 0xAB, 0x00, 0xE1, 0xB8, 0xAD, 0x00, 0xE1, 0xB8, 0xAF, 0x00, 0xE1, 0xB8,
1828
  0xB1, 0x00, 0xE1, 0xB8, 0xB3, 0x00, 0xE1, 0xB8, 0xB5, 0x00, 0xE1, 0xB8, 0xB7, 0x00, 0xE1, 0xB8,
1829
  0xB9, 0x00, 0xE1, 0xB8, 0xBB, 0x00, 0xE1, 0xB8, 0xBD, 0x00, 0xE1, 0xB8, 0xBF, 0x00, 0xE1, 0xB9,
1830
  0x81, 0x00, 0xE1, 0xB9, 0x83, 0x00, 0xE1, 0xB9, 0x85, 0x00, 0xE1, 0xB9, 0x87, 0x00, 0xE1, 0xB9,
1831
  0x89, 0x00, 0xE1, 0xB9, 0x8B, 0x00, 0xE1, 0xB9, 0x8D, 0x00, 0xE1, 0xB9, 0x8F, 0x00, 0xE1, 0xB9,
1832
  0x91, 0x00, 0xE1, 0xB9, 0x93, 0x00, 0xE1, 0xB9, 0x95, 0x00, 0xE1, 0xB9, 0x97, 0x00, 0xE1, 0xB9,
1833
  0x99, 0x00, 0xE1, 0xB9, 0x9B, 0x00, 0xE1, 0xB9, 0x9D, 0x00, 0xE1, 0xB9, 0x9F, 0x00, 0xE1, 0xB9,
1834
  0xA1, 0x00, 0xE1, 0xB9, 0xA3, 0x00, 0xE1, 0xB9, 0xA5, 0x00, 0xE1, 0xB9, 0xA7, 0x00, 0xE1, 0xB9,
1835
  0xA9, 0x00, 0xE1, 0xB9, 0xAB, 0x00, 0xE1, 0xB9, 0xAD, 0x00, 0xE1, 0xB9, 0xAF, 0x00, 0xE1, 0xB9,
1836
  0xB1, 0x00, 0xE1, 0xB9, 0xB3, 0x00, 0xE1, 0xB9, 0xB5, 0x00, 0xE1, 0xB9, 0xB7, 0x00, 0xE1, 0xB9,
1837
  0xB9, 0x00, 0xE1, 0xB9, 0xBB, 0x00, 0xE1, 0xB9, 0xBD, 0x00, 0xE1, 0xB9, 0xBF, 0x00, 0xE1, 0xBA,
1838
  0x81, 0x00, 0xE1, 0xBA, 0x83, 0x00, 0xE1, 0xBA, 0x85, 0x00, 0xE1, 0xBA, 0x87, 0x00, 0xE1, 0xBA,
1839
  0x89, 0x00, 0xE1, 0xBA, 0x8B, 0x00, 0xE1, 0xBA, 0x8D, 0x00, 0xE1, 0xBA, 0x8F, 0x00, 0xE1, 0xBA,
1840
  0x91, 0x00, 0xE1, 0xBA, 0x93, 0x00, 0xE1, 0xBA, 0x95, 0x00, 0x61, 0xCA, 0xBE, 0x00, 0xC3, 0x9F,
1841
  0x00, 0xE1, 0xBA, 0xA1, 0x00, 0xE1, 0xBA, 0xA3, 0x00, 0xE1, 0xBA, 0xA5, 0x00, 0xE1, 0xBA, 0xA7,
1842
  0x00, 0xE1, 0xBA, 0xA9, 0x00, 0xE1, 0xBA, 0xAB, 0x00, 0xE1, 0xBA, 0xAD, 0x00, 0xE1, 0xBA, 0xAF,
1843
  0x00, 0xE1, 0xBA, 0xB1, 0x00, 0xE1, 0xBA, 0xB3, 0x00, 0xE1, 0xBA, 0xB5, 0x00, 0xE1, 0xBA, 0xB7,
1844
  0x00, 0xE1, 0xBA, 0xB9, 0x00, 0xE1, 0xBA, 0xBB, 0x00, 0xE1, 0xBA, 0xBD, 0x00, 0xE1, 0xBA, 0xBF,
1845
  0x00, 0xE1, 0xBB, 0x81, 0x00, 0xE1, 0xBB, 0x83, 0x00, 0xE1, 0xBB, 0x85, 0x00, 0xE1, 0xBB, 0x87,
1846
  0x00, 0xE1, 0xBB, 0x89, 0x00, 0xE1, 0xBB, 0x8B, 0x00, 0xE1, 0xBB, 0x8D, 0x00, 0xE1, 0xBB, 0x8F,
1847
  0x00, 0xE1, 0xBB, 0x91, 0x00, 0xE1, 0xBB, 0x93, 0x00, 0xE1, 0xBB, 0x95, 0x00, 0xE1, 0xBB, 0x97,
1848
  0x00, 0xE1, 0xBB, 0x99, 0x00, 0xE1, 0xBB, 0x9B, 0x00, 0xE1, 0xBB, 0x9D, 0x00, 0xE1, 0xBB, 0x9F,
1849
  0x00, 0xE1, 0xBB, 0xA1, 0x00, 0xE1, 0xBB, 0xA3, 0x00, 0xE1, 0xBB, 0xA5, 0x00, 0xE1, 0xBB, 0xA7,
1850
  0x00, 0xE1, 0xBB, 0xA9, 0x00, 0xE1, 0xBB, 0xAB, 0x00, 0xE1, 0xBB, 0xAD, 0x00, 0xE1, 0xBB, 0xAF,
1851
  0x00, 0xE1, 0xBB, 0xB1, 0x00, 0xE1, 0xBB, 0xB3, 0x00, 0xE1, 0xBB, 0xB5, 0x00, 0xE1, 0xBB, 0xB7,
1852
  0x00, 0xE1, 0xBB, 0xB9, 0x00, 0xE1, 0xBB, 0xBB, 0x00, 0xE1, 0xBB, 0xBD, 0x00, 0xE1, 0xBB, 0xBF,
1853
  0x00, 0xE1, 0xBC, 0x80, 0x00, 0xE1, 0xBC, 0x81, 0x00, 0xE1, 0xBC, 0x82, 0x00, 0xE1, 0xBC, 0x83,
1854
  0x00, 0xE1, 0xBC, 0x84, 0x00, 0xE1, 0xBC, 0x85, 0x00, 0xE1, 0xBC, 0x86, 0x00, 0xE1, 0xBC, 0x87,
1855
  0x00, 0xE1, 0xBC, 0x90, 0x00, 0xE1, 0xBC, 0x91, 0x00, 0xE1, 0xBC, 0x92, 0x00, 0xE1, 0xBC, 0x93,
1856
  0x00, 0xE1, 0xBC, 0x94, 0x00, 0xE1, 0xBC, 0x95, 0x00, 0xE1, 0xBC, 0xA0, 0x00, 0xE1, 0xBC, 0xA1,
1857
  0x00, 0xE1, 0xBC, 0xA2, 0x00, 0xE1, 0xBC, 0xA3, 0x00, 0xE1, 0xBC, 0xA4, 0x00, 0xE1, 0xBC, 0xA5,
1858
  0x00, 0xE1, 0xBC, 0xA6, 0x00, 0xE1, 0xBC, 0xA7, 0x00, 0xE1, 0xBC, 0xB0, 0x00, 0xE1, 0xBC, 0xB1,
1859
  0x00, 0xE1, 0xBC, 0xB2, 0x00, 0xE1, 0xBC, 0xB3, 0x00, 0xE1, 0xBC, 0xB4, 0x00, 0xE1, 0xBC, 0xB5,
1860
  0x00, 0xE1, 0xBC, 0xB6, 0x00, 0xE1, 0xBC, 0xB7, 0x00, 0xE1, 0xBD, 0x80, 0x00, 0xE1, 0xBD, 0x81,
1861
  0x00, 0xE1, 0xBD, 0x82, 0x00, 0xE1, 0xBD, 0x83, 0x00, 0xE1, 0xBD, 0x84, 0x00, 0xE1, 0xBD, 0x85,
1862
  0x00, 0xE1, 0xBD, 0x91, 0x00, 0xE1, 0xBD, 0x93, 0x00, 0xE1, 0xBD, 0x95, 0x00, 0xE1, 0xBD, 0x97,
1863
  0x00, 0xE1, 0xBD, 0xA0, 0x00, 0xE1, 0xBD, 0xA1, 0x00, 0xE1, 0xBD, 0xA2, 0x00, 0xE1, 0xBD, 0xA3,
1864
  0x00, 0xE1, 0xBD, 0xA4, 0x00, 0xE1, 0xBD, 0xA5, 0x00, 0xE1, 0xBD, 0xA6, 0x00, 0xE1, 0xBD, 0xA7,
1865
  0x00, 0xE1, 0xBC, 0x80, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0x81, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0x82,
1866
  0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0x83, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0x84, 0xCE, 0xB9, 0x00, 0xE1,
1867
  0xBC, 0x85, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0x86, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0x87, 0xCE, 0xB9,
1868
  0x00, 0xE1, 0xBC, 0xA0, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0xA1, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0xA2,
1869
  0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0xA3, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0xA4, 0xCE, 0xB9, 0x00, 0xE1,
1870
  0xBC, 0xA5, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0xA6, 0xCE, 0xB9, 0x00, 0xE1, 0xBC, 0xA7, 0xCE, 0xB9,
1871
  0x00, 0xE1, 0xBD, 0xA0, 0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xA1, 0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xA2,
1872
  0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xA3, 0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xA4, 0xCE, 0xB9, 0x00, 0xE1,
1873
  0xBD, 0xA5, 0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xA6, 0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xA7, 0xCE, 0xB9,
1874
  0x00, 0xE1, 0xBD, 0xB0, 0xCE, 0xB9, 0x00, 0xCE, 0xB1, 0xCE, 0xB9, 0x00, 0xCE, 0xAC, 0xCE, 0xB9,
1875
  0x00, 0xE1, 0xBE, 0xB6, 0xCE, 0xB9, 0x00, 0xE1, 0xBE, 0xB0, 0x00, 0xE1, 0xBE, 0xB1, 0x00, 0xE1,
1876
  0xBD, 0xB0, 0x00, 0x20, 0xCC, 0x93, 0x00, 0x20, 0xCD, 0x82, 0x00, 0x20, 0xCC, 0x88, 0xCD, 0x82,
1877
  0x00, 0xE1, 0xBD, 0xB4, 0xCE, 0xB9, 0x00, 0xCE, 0xB7, 0xCE, 0xB9, 0x00, 0xCE, 0xAE, 0xCE, 0xB9,
1878
  0x00, 0xE1, 0xBF, 0x86, 0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xB2, 0x00, 0xE1, 0xBD, 0xB4, 0x00, 0x20,
1879
  0xCC, 0x93, 0xCC, 0x80, 0x00, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0x00, 0x20, 0xCC, 0x93, 0xCD, 0x82,
1880
  0x00, 0xCE, 0x90, 0x00, 0xE1, 0xBF, 0x90, 0x00, 0xE1, 0xBF, 0x91, 0x00, 0xE1, 0xBD, 0xB6, 0x00,
1881
  0x20, 0xCC, 0x94, 0xCC, 0x80, 0x00, 0x20, 0xCC, 0x94, 0xCC, 0x81, 0x00, 0x20, 0xCC, 0x94, 0xCD,
1882
  0x82, 0x00, 0xCE, 0xB0, 0x00, 0xE1, 0xBF, 0xA0, 0x00, 0xE1, 0xBF, 0xA1, 0x00, 0xE1, 0xBD, 0xBA,
1883
  0x00, 0xE1, 0xBF, 0xA5, 0x00, 0x20, 0xCC, 0x88, 0xCC, 0x80, 0x00, 0x60, 0x00, 0xE1, 0xBD, 0xBC,
1884
  0xCE, 0xB9, 0x00, 0xCF, 0x89, 0xCE, 0xB9, 0x00, 0xCF, 0x8E, 0xCE, 0xB9, 0x00, 0xE1, 0xBF, 0xB6,
1885
  0xCE, 0xB9, 0x00, 0xE1, 0xBD, 0xB8, 0x00, 0xE1, 0xBD, 0xBC, 0x00, 0x20, 0xCC, 0x94, 0x00, 0xE2,
1886
  0x80, 0x90, 0x00, 0x20, 0xCC, 0xB3, 0x00, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x00, 0xE2, 0x80,
1887
  0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x00, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x00, 0xE2,
1888
  0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x00, 0x21, 0x21, 0x00, 0x20, 0xCC, 0x85, 0x00,
1889
  0x3F, 0x3F, 0x00, 0x3F, 0x21, 0x00, 0x21, 0x3F, 0x00, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2,
1890
  0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x00, 0x30, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00,
1891
  0x38, 0x00, 0x39, 0x00, 0x2B, 0x00, 0xE2, 0x88, 0x92, 0x00, 0x3D, 0x00, 0x28, 0x00, 0x29, 0x00,
1892
  0x72, 0x73, 0x00, 0x61, 0x2F, 0x63, 0x00, 0x61, 0x2F, 0x73, 0x00, 0xC2, 0xB0, 0x63, 0x00, 0x63,
1893
  0x2F, 0x6F, 0x00, 0x63, 0x2F, 0x75, 0x00, 0xC2, 0xB0, 0x66, 0x00, 0x6E, 0x6F, 0x00, 0x73, 0x6D,
1894
  0x00, 0x74, 0x65, 0x6C, 0x00, 0x74, 0x6D, 0x00, 0xE2, 0x85, 0x8E, 0x00, 0xD7, 0x90, 0x00, 0xD7,
1895
  0x91, 0x00, 0xD7, 0x92, 0x00, 0xD7, 0x93, 0x00, 0x66, 0x61, 0x78, 0x00, 0xE2, 0x88, 0x91, 0x00,
1896
  0x31, 0xE2, 0x81, 0x84, 0x37, 0x00, 0x31, 0xE2, 0x81, 0x84, 0x39, 0x00, 0x31, 0xE2, 0x81, 0x84,
1897
  0x31, 0x30, 0x00, 0x31, 0xE2, 0x81, 0x84, 0x33, 0x00, 0x32, 0xE2, 0x81, 0x84, 0x33, 0x00, 0x31,
1898
  0xE2, 0x81, 0x84, 0x35, 0x00, 0x32, 0xE2, 0x81, 0x84, 0x35, 0x00, 0x33, 0xE2, 0x81, 0x84, 0x35,
1899
  0x00, 0x34, 0xE2, 0x81, 0x84, 0x35, 0x00, 0x31, 0xE2, 0x81, 0x84, 0x36, 0x00, 0x35, 0xE2, 0x81,
1900
  0x84, 0x36, 0x00, 0x31, 0xE2, 0x81, 0x84, 0x38, 0x00, 0x33, 0xE2, 0x81, 0x84, 0x38, 0x00, 0x35,
1901
  0xE2, 0x81, 0x84, 0x38, 0x00, 0x37, 0xE2, 0x81, 0x84, 0x38, 0x00, 0x31, 0xE2, 0x81, 0x84, 0x00,
1902
  0x69, 0x69, 0x00, 0x69, 0x69, 0x69, 0x00, 0x69, 0x76, 0x00, 0x76, 0x69, 0x00, 0x76, 0x69, 0x69,
1903
  0x00, 0x76, 0x69, 0x69, 0x69, 0x00, 0x69, 0x78, 0x00, 0x78, 0x69, 0x00, 0x78, 0x69, 0x69, 0x00,
1904
  0xE2, 0x86, 0x84, 0x00, 0x30, 0xE2, 0x81, 0x84, 0x33, 0x00, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB,
1905
  0x00, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x00, 0xE2, 0x88, 0xAE, 0xE2, 0x88,
1906
  0xAE, 0x00, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0x00, 0xE3, 0x80, 0x88, 0x00,
1907
  0xE3, 0x80, 0x89, 0x00, 0x31, 0x30, 0x00, 0x31, 0x31, 0x00, 0x31, 0x32, 0x00, 0x31, 0x33, 0x00,
1908
  0x31, 0x34, 0x00, 0x31, 0x35, 0x00, 0x31, 0x36, 0x00, 0x31, 0x37, 0x00, 0x31, 0x38, 0x00, 0x31,
1909
  0x39, 0x00, 0x32, 0x30, 0x00, 0x28, 0x31, 0x29, 0x00, 0x28, 0x32, 0x29, 0x00, 0x28, 0x33, 0x29,
1910
  0x00, 0x28, 0x34, 0x29, 0x00, 0x28, 0x35, 0x29, 0x00, 0x28, 0x36, 0x29, 0x00, 0x28, 0x37, 0x29,
1911
  0x00, 0x28, 0x38, 0x29, 0x00, 0x28, 0x39, 0x29, 0x00, 0x28, 0x31, 0x30, 0x29, 0x00, 0x28, 0x31,
1912
  0x31, 0x29, 0x00, 0x28, 0x31, 0x32, 0x29, 0x00, 0x28, 0x31, 0x33, 0x29, 0x00, 0x28, 0x31, 0x34,
1913
  0x29, 0x00, 0x28, 0x31, 0x35, 0x29, 0x00, 0x28, 0x31, 0x36, 0x29, 0x00, 0x28, 0x31, 0x37, 0x29,
1914
  0x00, 0x28, 0x31, 0x38, 0x29, 0x00, 0x28, 0x31, 0x39, 0x29, 0x00, 0x28, 0x32, 0x30, 0x29, 0x00,
1915
  0x28, 0x61, 0x29, 0x00, 0x28, 0x62, 0x29, 0x00, 0x28, 0x63, 0x29, 0x00, 0x28, 0x64, 0x29, 0x00,
1916
  0x28, 0x65, 0x29, 0x00, 0x28, 0x66, 0x29, 0x00, 0x28, 0x67, 0x29, 0x00, 0x28, 0x68, 0x29, 0x00,
1917
  0x28, 0x69, 0x29, 0x00, 0x28, 0x6A, 0x29, 0x00, 0x28, 0x6B, 0x29, 0x00, 0x28, 0x6C, 0x29, 0x00,
1918
  0x28, 0x6D, 0x29, 0x00, 0x28, 0x6E, 0x29, 0x00, 0x28, 0x6F, 0x29, 0x00, 0x28, 0x70, 0x29, 0x00,
1919
  0x28, 0x71, 0x29, 0x00, 0x28, 0x72, 0x29, 0x00, 0x28, 0x73, 0x29, 0x00, 0x28, 0x74, 0x29, 0x00,
1920
  0x28, 0x75, 0x29, 0x00, 0x28, 0x76, 0x29, 0x00, 0x28, 0x77, 0x29, 0x00, 0x28, 0x78, 0x29, 0x00,
1921
  0x28, 0x79, 0x29, 0x00, 0x28, 0x7A, 0x29, 0x00, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88,
1922
  0xAB, 0xE2, 0x88, 0xAB, 0x00, 0x3A, 0x3A, 0x3D, 0x00, 0x3D, 0x3D, 0x00, 0x3D, 0x3D, 0x3D, 0x00,
1923
  0xE2, 0xAB, 0x9D, 0xCC, 0xB8, 0x00, 0xE2, 0xB0, 0xB0, 0x00, 0xE2, 0xB0, 0xB1, 0x00, 0xE2, 0xB0,
1924
  0xB2, 0x00, 0xE2, 0xB0, 0xB3, 0x00, 0xE2, 0xB0, 0xB4, 0x00, 0xE2, 0xB0, 0xB5, 0x00, 0xE2, 0xB0,
1925
  0xB6, 0x00, 0xE2, 0xB0, 0xB7, 0x00, 0xE2, 0xB0, 0xB8, 0x00, 0xE2, 0xB0, 0xB9, 0x00, 0xE2, 0xB0,
1926
  0xBA, 0x00, 0xE2, 0xB0, 0xBB, 0x00, 0xE2, 0xB0, 0xBC, 0x00, 0xE2, 0xB0, 0xBD, 0x00, 0xE2, 0xB0,
1927
  0xBE, 0x00, 0xE2, 0xB0, 0xBF, 0x00, 0xE2, 0xB1, 0x80, 0x00, 0xE2, 0xB1, 0x81, 0x00, 0xE2, 0xB1,
1928
  0x82, 0x00, 0xE2, 0xB1, 0x83, 0x00, 0xE2, 0xB1, 0x84, 0x00, 0xE2, 0xB1, 0x85, 0x00, 0xE2, 0xB1,
1929
  0x86, 0x00, 0xE2, 0xB1, 0x87, 0x00, 0xE2, 0xB1, 0x88, 0x00, 0xE2, 0xB1, 0x89, 0x00, 0xE2, 0xB1,
1930
  0x8A, 0x00, 0xE2, 0xB1, 0x8B, 0x00, 0xE2, 0xB1, 0x8C, 0x00, 0xE2, 0xB1, 0x8D, 0x00, 0xE2, 0xB1,
1931
  0x8E, 0x00, 0xE2, 0xB1, 0x8F, 0x00, 0xE2, 0xB1, 0x90, 0x00, 0xE2, 0xB1, 0x91, 0x00, 0xE2, 0xB1,
1932
  0x92, 0x00, 0xE2, 0xB1, 0x93, 0x00, 0xE2, 0xB1, 0x94, 0x00, 0xE2, 0xB1, 0x95, 0x00, 0xE2, 0xB1,
1933
  0x96, 0x00, 0xE2, 0xB1, 0x97, 0x00, 0xE2, 0xB1, 0x98, 0x00, 0xE2, 0xB1, 0x99, 0x00, 0xE2, 0xB1,
1934
  0x9A, 0x00, 0xE2, 0xB1, 0x9B, 0x00, 0xE2, 0xB1, 0x9C, 0x00, 0xE2, 0xB1, 0x9D, 0x00, 0xE2, 0xB1,
1935
  0x9E, 0x00, 0xE2, 0xB1, 0x9F, 0x00, 0xE2, 0xB1, 0xA1, 0x00, 0xC9, 0xAB, 0x00, 0xE1, 0xB5, 0xBD,
1936
  0x00, 0xC9, 0xBD, 0x00, 0xE2, 0xB1, 0xA8, 0x00, 0xE2, 0xB1, 0xAA, 0x00, 0xE2, 0xB1, 0xAC, 0x00,
1937
  0xE2, 0xB1, 0xB3, 0x00, 0xE2, 0xB1, 0xB6, 0x00, 0xC8, 0xBF, 0x00, 0xC9, 0x80, 0x00, 0xE2, 0xB2,
1938
  0x81, 0x00, 0xE2, 0xB2, 0x83, 0x00, 0xE2, 0xB2, 0x85, 0x00, 0xE2, 0xB2, 0x87, 0x00, 0xE2, 0xB2,
1939
  0x89, 0x00, 0xE2, 0xB2, 0x8B, 0x00, 0xE2, 0xB2, 0x8D, 0x00, 0xE2, 0xB2, 0x8F, 0x00, 0xE2, 0xB2,
1940
  0x91, 0x00, 0xE2, 0xB2, 0x93, 0x00, 0xE2, 0xB2, 0x95, 0x00, 0xE2, 0xB2, 0x97, 0x00, 0xE2, 0xB2,
1941
  0x99, 0x00, 0xE2, 0xB2, 0x9B, 0x00, 0xE2, 0xB2, 0x9D, 0x00, 0xE2, 0xB2, 0x9F, 0x00, 0xE2, 0xB2,
1942
  0xA1, 0x00, 0xE2, 0xB2, 0xA3, 0x00, 0xE2, 0xB2, 0xA5, 0x00, 0xE2, 0xB2, 0xA7, 0x00, 0xE2, 0xB2,
1943
  0xA9, 0x00, 0xE2, 0xB2, 0xAB, 0x00, 0xE2, 0xB2, 0xAD, 0x00, 0xE2, 0xB2, 0xAF, 0x00, 0xE2, 0xB2,
1944
  0xB1, 0x00, 0xE2, 0xB2, 0xB3, 0x00, 0xE2, 0xB2, 0xB5, 0x00, 0xE2, 0xB2, 0xB7, 0x00, 0xE2, 0xB2,
1945
  0xB9, 0x00, 0xE2, 0xB2, 0xBB, 0x00, 0xE2, 0xB2, 0xBD, 0x00, 0xE2, 0xB2, 0xBF, 0x00, 0xE2, 0xB3,
1946
  0x81, 0x00, 0xE2, 0xB3, 0x83, 0x00, 0xE2, 0xB3, 0x85, 0x00, 0xE2, 0xB3, 0x87, 0x00, 0xE2, 0xB3,
1947
  0x89, 0x00, 0xE2, 0xB3, 0x8B, 0x00, 0xE2, 0xB3, 0x8D, 0x00, 0xE2, 0xB3, 0x8F, 0x00, 0xE2, 0xB3,
1948
  0x91, 0x00, 0xE2, 0xB3, 0x93, 0x00, 0xE2, 0xB3, 0x95, 0x00, 0xE2, 0xB3, 0x97, 0x00, 0xE2, 0xB3,
1949
  0x99, 0x00, 0xE2, 0xB3, 0x9B, 0x00, 0xE2, 0xB3, 0x9D, 0x00, 0xE2, 0xB3, 0x9F, 0x00, 0xE2, 0xB3,
1950
  0xA1, 0x00, 0xE2, 0xB3, 0xA3, 0x00, 0xE2, 0xB3, 0xAC, 0x00, 0xE2, 0xB3, 0xAE, 0x00, 0xE2, 0xB3,
1951
  0xB3, 0x00, 0xE2, 0xB5, 0xA1, 0x00, 0xE6, 0xAF, 0x8D, 0x00, 0xE9, 0xBE, 0x9F, 0x00, 0xE4, 0xB8,
1952
  0x80, 0x00, 0xE4, 0xB8, 0xA8, 0x00, 0xE4, 0xB8, 0xB6, 0x00, 0xE4, 0xB8, 0xBF, 0x00, 0xE4, 0xB9,
1953
  0x99, 0x00, 0xE4, 0xBA, 0x85, 0x00, 0xE4, 0xBA, 0x8C, 0x00, 0xE4, 0xBA, 0xA0, 0x00, 0xE4, 0xBA,
1954
  0xBA, 0x00, 0xE5, 0x84, 0xBF, 0x00, 0xE5, 0x85, 0xA5, 0x00, 0xE5, 0x85, 0xAB, 0x00, 0xE5, 0x86,
1955
  0x82, 0x00, 0xE5, 0x86, 0x96, 0x00, 0xE5, 0x86, 0xAB, 0x00, 0xE5, 0x87, 0xA0, 0x00, 0xE5, 0x87,
1956
  0xB5, 0x00, 0xE5, 0x88, 0x80, 0x00, 0xE5, 0x8A, 0x9B, 0x00, 0xE5, 0x8B, 0xB9, 0x00, 0xE5, 0x8C,
1957
  0x95, 0x00, 0xE5, 0x8C, 0x9A, 0x00, 0xE5, 0x8C, 0xB8, 0x00, 0xE5, 0x8D, 0x81, 0x00, 0xE5, 0x8D,
1958
  0x9C, 0x00, 0xE5, 0x8D, 0xA9, 0x00, 0xE5, 0x8E, 0x82, 0x00, 0xE5, 0x8E, 0xB6, 0x00, 0xE5, 0x8F,
1959
  0x88, 0x00, 0xE5, 0x8F, 0xA3, 0x00, 0xE5, 0x9B, 0x97, 0x00, 0xE5, 0x9C, 0x9F, 0x00, 0xE5, 0xA3,
1960
  0xAB, 0x00, 0xE5, 0xA4, 0x82, 0x00, 0xE5, 0xA4, 0x8A, 0x00, 0xE5, 0xA4, 0x95, 0x00, 0xE5, 0xA4,
1961
  0xA7, 0x00, 0xE5, 0xA5, 0xB3, 0x00, 0xE5, 0xAD, 0x90, 0x00, 0xE5, 0xAE, 0x80, 0x00, 0xE5, 0xAF,
1962
  0xB8, 0x00, 0xE5, 0xB0, 0x8F, 0x00, 0xE5, 0xB0, 0xA2, 0x00, 0xE5, 0xB0, 0xB8, 0x00, 0xE5, 0xB1,
1963
  0xAE, 0x00, 0xE5, 0xB1, 0xB1, 0x00, 0xE5, 0xB7, 0x9B, 0x00, 0xE5, 0xB7, 0xA5, 0x00, 0xE5, 0xB7,
1964
  0xB1, 0x00, 0xE5, 0xB7, 0xBE, 0x00, 0xE5, 0xB9, 0xB2, 0x00, 0xE5, 0xB9, 0xBA, 0x00, 0xE5, 0xB9,
1965
  0xBF, 0x00, 0xE5, 0xBB, 0xB4, 0x00, 0xE5, 0xBB, 0xBE, 0x00, 0xE5, 0xBC, 0x8B, 0x00, 0xE5, 0xBC,
1966
  0x93, 0x00, 0xE5, 0xBD, 0x90, 0x00, 0xE5, 0xBD, 0xA1, 0x00, 0xE5, 0xBD, 0xB3, 0x00, 0xE5, 0xBF,
1967
  0x83, 0x00, 0xE6, 0x88, 0x88, 0x00, 0xE6, 0x88, 0xB6, 0x00, 0xE6, 0x89, 0x8B, 0x00, 0xE6, 0x94,
1968
  0xAF, 0x00, 0xE6, 0x94, 0xB4, 0x00, 0xE6, 0x96, 0x87, 0x00, 0xE6, 0x96, 0x97, 0x00, 0xE6, 0x96,
1969
  0xA4, 0x00, 0xE6, 0x96, 0xB9, 0x00, 0xE6, 0x97, 0xA0, 0x00, 0xE6, 0x97, 0xA5, 0x00, 0xE6, 0x9B,
1970
  0xB0, 0x00, 0xE6, 0x9C, 0x88, 0x00, 0xE6, 0x9C, 0xA8, 0x00, 0xE6, 0xAC, 0xA0, 0x00, 0xE6, 0xAD,
1971
  0xA2, 0x00, 0xE6, 0xAD, 0xB9, 0x00, 0xE6, 0xAE, 0xB3, 0x00, 0xE6, 0xAF, 0x8B, 0x00, 0xE6, 0xAF,
1972
  0x94, 0x00, 0xE6, 0xAF, 0x9B, 0x00, 0xE6, 0xB0, 0x8F, 0x00, 0xE6, 0xB0, 0x94, 0x00, 0xE6, 0xB0,
1973
  0xB4, 0x00, 0xE7, 0x81, 0xAB, 0x00, 0xE7, 0x88, 0xAA, 0x00, 0xE7, 0x88, 0xB6, 0x00, 0xE7, 0x88,
1974
  0xBB, 0x00, 0xE7, 0x88, 0xBF, 0x00, 0xE7, 0x89, 0x87, 0x00, 0xE7, 0x89, 0x99, 0x00, 0xE7, 0x89,
1975
  0x9B, 0x00, 0xE7, 0x8A, 0xAC, 0x00, 0xE7, 0x8E, 0x84, 0x00, 0xE7, 0x8E, 0x89, 0x00, 0xE7, 0x93,
1976
  0x9C, 0x00, 0xE7, 0x93, 0xA6, 0x00, 0xE7, 0x94, 0x98, 0x00, 0xE7, 0x94, 0x9F, 0x00, 0xE7, 0x94,
1977
  0xA8, 0x00, 0xE7, 0x94, 0xB0, 0x00, 0xE7, 0x96, 0x8B, 0x00, 0xE7, 0x96, 0x92, 0x00, 0xE7, 0x99,
1978
  0xB6, 0x00, 0xE7, 0x99, 0xBD, 0x00, 0xE7, 0x9A, 0xAE, 0x00, 0xE7, 0x9A, 0xBF, 0x00, 0xE7, 0x9B,
1979
  0xAE, 0x00, 0xE7, 0x9F, 0x9B, 0x00, 0xE7, 0x9F, 0xA2, 0x00, 0xE7, 0x9F, 0xB3, 0x00, 0xE7, 0xA4,
1980
  0xBA, 0x00, 0xE7, 0xA6, 0xB8, 0x00, 0xE7, 0xA6, 0xBE, 0x00, 0xE7, 0xA9, 0xB4, 0x00, 0xE7, 0xAB,
1981
  0x8B, 0x00, 0xE7, 0xAB, 0xB9, 0x00, 0xE7, 0xB1, 0xB3, 0x00, 0xE7, 0xB3, 0xB8, 0x00, 0xE7, 0xBC,
1982
  0xB6, 0x00, 0xE7, 0xBD, 0x91, 0x00, 0xE7, 0xBE, 0x8A, 0x00, 0xE7, 0xBE, 0xBD, 0x00, 0xE8, 0x80,
1983
  0x81, 0x00, 0xE8, 0x80, 0x8C, 0x00, 0xE8, 0x80, 0x92, 0x00, 0xE8, 0x80, 0xB3, 0x00, 0xE8, 0x81,
1984
  0xBF, 0x00, 0xE8, 0x82, 0x89, 0x00, 0xE8, 0x87, 0xA3, 0x00, 0xE8, 0x87, 0xAA, 0x00, 0xE8, 0x87,
1985
  0xB3, 0x00, 0xE8, 0x87, 0xBC, 0x00, 0xE8, 0x88, 0x8C, 0x00, 0xE8, 0x88, 0x9B, 0x00, 0xE8, 0x88,
1986
  0x9F, 0x00, 0xE8, 0x89, 0xAE, 0x00, 0xE8, 0x89, 0xB2, 0x00, 0xE8, 0x89, 0xB8, 0x00, 0xE8, 0x99,
1987
  0x8D, 0x00, 0xE8, 0x99, 0xAB, 0x00, 0xE8, 0xA1, 0x80, 0x00, 0xE8, 0xA1, 0x8C, 0x00, 0xE8, 0xA1,
1988
  0xA3, 0x00, 0xE8, 0xA5, 0xBE, 0x00, 0xE8, 0xA6, 0x8B, 0x00, 0xE8, 0xA7, 0x92, 0x00, 0xE8, 0xA8,
1989
  0x80, 0x00, 0xE8, 0xB0, 0xB7, 0x00, 0xE8, 0xB1, 0x86, 0x00, 0xE8, 0xB1, 0x95, 0x00, 0xE8, 0xB1,
1990
  0xB8, 0x00, 0xE8, 0xB2, 0x9D, 0x00, 0xE8, 0xB5, 0xA4, 0x00, 0xE8, 0xB5, 0xB0, 0x00, 0xE8, 0xB6,
1991
  0xB3, 0x00, 0xE8, 0xBA, 0xAB, 0x00, 0xE8, 0xBB, 0x8A, 0x00, 0xE8, 0xBE, 0x9B, 0x00, 0xE8, 0xBE,
1992
  0xB0, 0x00, 0xE8, 0xBE, 0xB5, 0x00, 0xE9, 0x82, 0x91, 0x00, 0xE9, 0x85, 0x89, 0x00, 0xE9, 0x87,
1993
  0x86, 0x00, 0xE9, 0x87, 0x8C, 0x00, 0xE9, 0x87, 0x91, 0x00, 0xE9, 0x95, 0xB7, 0x00, 0xE9, 0x96,
1994
  0x80, 0x00, 0xE9, 0x98, 0x9C, 0x00, 0xE9, 0x9A, 0xB6, 0x00, 0xE9, 0x9A, 0xB9, 0x00, 0xE9, 0x9B,
1995
  0xA8, 0x00, 0xE9, 0x9D, 0x91, 0x00, 0xE9, 0x9D, 0x9E, 0x00, 0xE9, 0x9D, 0xA2, 0x00, 0xE9, 0x9D,
1996
  0xA9, 0x00, 0xE9, 0x9F, 0x8B, 0x00, 0xE9, 0x9F, 0xAD, 0x00, 0xE9, 0x9F, 0xB3, 0x00, 0xE9, 0xA0,
1997
  0x81, 0x00, 0xE9, 0xA2, 0xA8, 0x00, 0xE9, 0xA3, 0x9B, 0x00, 0xE9, 0xA3, 0x9F, 0x00, 0xE9, 0xA6,
1998
  0x96, 0x00, 0xE9, 0xA6, 0x99, 0x00, 0xE9, 0xA6, 0xAC, 0x00, 0xE9, 0xAA, 0xA8, 0x00, 0xE9, 0xAB,
1999
  0x98, 0x00, 0xE9, 0xAB, 0x9F, 0x00, 0xE9, 0xAC, 0xA5, 0x00, 0xE9, 0xAC, 0xAF, 0x00, 0xE9, 0xAC,
2000
  0xB2, 0x00, 0xE9, 0xAC, 0xBC, 0x00, 0xE9, 0xAD, 0x9A, 0x00, 0xE9, 0xB3, 0xA5, 0x00, 0xE9, 0xB9,
2001
  0xB5, 0x00, 0xE9, 0xB9, 0xBF, 0x00, 0xE9, 0xBA, 0xA5, 0x00, 0xE9, 0xBA, 0xBB, 0x00, 0xE9, 0xBB,
2002
  0x83, 0x00, 0xE9, 0xBB, 0x8D, 0x00, 0xE9, 0xBB, 0x91, 0x00, 0xE9, 0xBB, 0xB9, 0x00, 0xE9, 0xBB,
2003
  0xBD, 0x00, 0xE9, 0xBC, 0x8E, 0x00, 0xE9, 0xBC, 0x93, 0x00, 0xE9, 0xBC, 0xA0, 0x00, 0xE9, 0xBC,
2004
  0xBB, 0x00, 0xE9, 0xBD, 0x8A, 0x00, 0xE9, 0xBD, 0x92, 0x00, 0xE9, 0xBE, 0x8D, 0x00, 0xE9, 0xBE,
2005
  0x9C, 0x00, 0xE9, 0xBE, 0xA0, 0x00, 0x2E, 0x00, 0xE3, 0x80, 0x92, 0x00, 0xE5, 0x8D, 0x84, 0x00,
2006
  0xE5, 0x8D, 0x85, 0x00, 0x20, 0xE3, 0x82, 0x99, 0x00, 0x20, 0xE3, 0x82, 0x9A, 0x00, 0xE3, 0x82,
2007
  0x88, 0xE3, 0x82, 0x8A, 0x00, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, 0x00, 0xE1, 0x84, 0x80, 0x00,
2008
  0xE1, 0x84, 0x81, 0x00, 0xE1, 0x86, 0xAA, 0x00, 0xE1, 0x84, 0x82, 0x00, 0xE1, 0x86, 0xAC, 0x00,
2009
  0xE1, 0x86, 0xAD, 0x00, 0xE1, 0x84, 0x83, 0x00, 0xE1, 0x84, 0x84, 0x00, 0xE1, 0x84, 0x85, 0x00,
2010
  0xE1, 0x86, 0xB0, 0x00, 0xE1, 0x86, 0xB1, 0x00, 0xE1, 0x86, 0xB2, 0x00, 0xE1, 0x86, 0xB3, 0x00,
2011
  0xE1, 0x86, 0xB4, 0x00, 0xE1, 0x86, 0xB5, 0x00, 0xE1, 0x84, 0x9A, 0x00, 0xE1, 0x84, 0x86, 0x00,
2012
  0xE1, 0x84, 0x87, 0x00, 0xE1, 0x84, 0x88, 0x00, 0xE1, 0x84, 0xA1, 0x00, 0xE1, 0x84, 0x89, 0x00,
2013
  0xE1, 0x84, 0x8A, 0x00, 0xE1, 0x84, 0x8B, 0x00, 0xE1, 0x84, 0x8C, 0x00, 0xE1, 0x84, 0x8D, 0x00,
2014
  0xE1, 0x84, 0x8E, 0x00, 0xE1, 0x84, 0x8F, 0x00, 0xE1, 0x84, 0x90, 0x00, 0xE1, 0x84, 0x91, 0x00,
2015
  0xE1, 0x84, 0x92, 0x00, 0xE1, 0x85, 0xA1, 0x00, 0xE1, 0x85, 0xA2, 0x00, 0xE1, 0x85, 0xA3, 0x00,
2016
  0xE1, 0x85, 0xA4, 0x00, 0xE1, 0x85, 0xA5, 0x00, 0xE1, 0x85, 0xA6, 0x00, 0xE1, 0x85, 0xA7, 0x00,
2017
  0xE1, 0x85, 0xA8, 0x00, 0xE1, 0x85, 0xA9, 0x00, 0xE1, 0x85, 0xAA, 0x00, 0xE1, 0x85, 0xAB, 0x00,
2018
  0xE1, 0x85, 0xAC, 0x00, 0xE1, 0x85, 0xAD, 0x00, 0xE1, 0x85, 0xAE, 0x00, 0xE1, 0x85, 0xAF, 0x00,
2019
  0xE1, 0x85, 0xB0, 0x00, 0xE1, 0x85, 0xB1, 0x00, 0xE1, 0x85, 0xB2, 0x00, 0xE1, 0x85, 0xB3, 0x00,
2020
  0xE1, 0x85, 0xB4, 0x00, 0xE1, 0x85, 0xB5, 0x00, 0xE1, 0x84, 0x94, 0x00, 0xE1, 0x84, 0x95, 0x00,
2021
  0xE1, 0x87, 0x87, 0x00, 0xE1, 0x87, 0x88, 0x00, 0xE1, 0x87, 0x8C, 0x00, 0xE1, 0x87, 0x8E, 0x00,
2022
  0xE1, 0x87, 0x93, 0x00, 0xE1, 0x87, 0x97, 0x00, 0xE1, 0x87, 0x99, 0x00, 0xE1, 0x84, 0x9C, 0x00,
2023
  0xE1, 0x87, 0x9D, 0x00, 0xE1, 0x87, 0x9F, 0x00, 0xE1, 0x84, 0x9D, 0x00, 0xE1, 0x84, 0x9E, 0x00,
2024
  0xE1, 0x84, 0xA0, 0x00, 0xE1, 0x84, 0xA2, 0x00, 0xE1, 0x84, 0xA3, 0x00, 0xE1, 0x84, 0xA7, 0x00,
2025
  0xE1, 0x84, 0xA9, 0x00, 0xE1, 0x84, 0xAB, 0x00, 0xE1, 0x84, 0xAC, 0x00, 0xE1, 0x84, 0xAD, 0x00,
2026
  0xE1, 0x84, 0xAE, 0x00, 0xE1, 0x84, 0xAF, 0x00, 0xE1, 0x84, 0xB2, 0x00, 0xE1, 0x84, 0xB6, 0x00,
2027
  0xE1, 0x85, 0x80, 0x00, 0xE1, 0x85, 0x87, 0x00, 0xE1, 0x85, 0x8C, 0x00, 0xE1, 0x87, 0xB1, 0x00,
2028
  0xE1, 0x87, 0xB2, 0x00, 0xE1, 0x85, 0x97, 0x00, 0xE1, 0x85, 0x98, 0x00, 0xE1, 0x85, 0x99, 0x00,
2029
  0xE1, 0x86, 0x84, 0x00, 0xE1, 0x86, 0x85, 0x00, 0xE1, 0x86, 0x88, 0x00, 0xE1, 0x86, 0x91, 0x00,
2030
  0xE1, 0x86, 0x92, 0x00, 0xE1, 0x86, 0x94, 0x00, 0xE1, 0x86, 0x9E, 0x00, 0xE1, 0x86, 0xA1, 0x00,
2031
  0xE4, 0xB8, 0x89, 0x00, 0xE5, 0x9B, 0x9B, 0x00, 0xE4, 0xB8, 0x8A, 0x00, 0xE4, 0xB8, 0xAD, 0x00,
2032
  0xE4, 0xB8, 0x8B, 0x00, 0xE7, 0x94, 0xB2, 0x00, 0xE4, 0xB8, 0x99, 0x00, 0xE4, 0xB8, 0x81, 0x00,
2033
  0xE5, 0xA4, 0xA9, 0x00, 0xE5, 0x9C, 0xB0, 0x00, 0x28, 0xE1, 0x84, 0x80, 0x29, 0x00, 0x28, 0xE1,
2034
  0x84, 0x82, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x83, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x85, 0x29, 0x00,
2035
  0x28, 0xE1, 0x84, 0x86, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x87, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x89,
2036
  0x29, 0x00, 0x28, 0xE1, 0x84, 0x8B, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x8C, 0x29, 0x00, 0x28, 0xE1,
2037
  0x84, 0x8E, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x8F, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x90, 0x29, 0x00,
2038
  0x28, 0xE1, 0x84, 0x91, 0x29, 0x00, 0x28, 0xE1, 0x84, 0x92, 0x29, 0x00, 0x28, 0xEA, 0xB0, 0x80,
2039
  0x29, 0x00, 0x28, 0xEB, 0x82, 0x98, 0x29, 0x00, 0x28, 0xEB, 0x8B, 0xA4, 0x29, 0x00, 0x28, 0xEB,
2040
  0x9D, 0xBC, 0x29, 0x00, 0x28, 0xEB, 0xA7, 0x88, 0x29, 0x00, 0x28, 0xEB, 0xB0, 0x94, 0x29, 0x00,
2041
  0x28, 0xEC, 0x82, 0xAC, 0x29, 0x00, 0x28, 0xEC, 0x95, 0x84, 0x29, 0x00, 0x28, 0xEC, 0x9E, 0x90,
2042
  0x29, 0x00, 0x28, 0xEC, 0xB0, 0xA8, 0x29, 0x00, 0x28, 0xEC, 0xB9, 0xB4, 0x29, 0x00, 0x28, 0xED,
2043
  0x83, 0x80, 0x29, 0x00, 0x28, 0xED, 0x8C, 0x8C, 0x29, 0x00, 0x28, 0xED, 0x95, 0x98, 0x29, 0x00,
2044
  0x28, 0xEC, 0xA3, 0xBC, 0x29, 0x00, 0x28, 0xEC, 0x98, 0xA4, 0xEC, 0xA0, 0x84, 0x29, 0x00, 0x28,
2045
  0xEC, 0x98, 0xA4, 0xED, 0x9B, 0x84, 0x29, 0x00, 0x28, 0xE4, 0xB8, 0x80, 0x29, 0x00, 0x28, 0xE4,
2046
  0xBA, 0x8C, 0x29, 0x00, 0x28, 0xE4, 0xB8, 0x89, 0x29, 0x00, 0x28, 0xE5, 0x9B, 0x9B, 0x29, 0x00,
2047
  0x28, 0xE4, 0xBA, 0x94, 0x29, 0x00, 0x28, 0xE5, 0x85, 0xAD, 0x29, 0x00, 0x28, 0xE4, 0xB8, 0x83,
2048
  0x29, 0x00, 0x28, 0xE5, 0x85, 0xAB, 0x29, 0x00, 0x28, 0xE4, 0xB9, 0x9D, 0x29, 0x00, 0x28, 0xE5,
2049
  0x8D, 0x81, 0x29, 0x00, 0x28, 0xE6, 0x9C, 0x88, 0x29, 0x00, 0x28, 0xE7, 0x81, 0xAB, 0x29, 0x00,
2050
  0x28, 0xE6, 0xB0, 0xB4, 0x29, 0x00, 0x28, 0xE6, 0x9C, 0xA8, 0x29, 0x00, 0x28, 0xE9, 0x87, 0x91,
2051
  0x29, 0x00, 0x28, 0xE5, 0x9C, 0x9F, 0x29, 0x00, 0x28, 0xE6, 0x97, 0xA5, 0x29, 0x00, 0x28, 0xE6,
2052
  0xA0, 0xAA, 0x29, 0x00, 0x28, 0xE6, 0x9C, 0x89, 0x29, 0x00, 0x28, 0xE7, 0xA4, 0xBE, 0x29, 0x00,
2053
  0x28, 0xE5, 0x90, 0x8D, 0x29, 0x00, 0x28, 0xE7, 0x89, 0xB9, 0x29, 0x00, 0x28, 0xE8, 0xB2, 0xA1,
2054
  0x29, 0x00, 0x28, 0xE7, 0xA5, 0x9D, 0x29, 0x00, 0x28, 0xE5, 0x8A, 0xB4, 0x29, 0x00, 0x28, 0xE4,
2055
  0xBB, 0xA3, 0x29, 0x00, 0x28, 0xE5, 0x91, 0xBC, 0x29, 0x00, 0x28, 0xE5, 0xAD, 0xA6, 0x29, 0x00,
2056
  0x28, 0xE7, 0x9B, 0xA3, 0x29, 0x00, 0x28, 0xE4, 0xBC, 0x81, 0x29, 0x00, 0x28, 0xE8, 0xB3, 0x87,
2057
  0x29, 0x00, 0x28, 0xE5, 0x8D, 0x94, 0x29, 0x00, 0x28, 0xE7, 0xA5, 0xAD, 0x29, 0x00, 0x28, 0xE4,
2058
  0xBC, 0x91, 0x29, 0x00, 0x28, 0xE8, 0x87, 0xAA, 0x29, 0x00, 0x28, 0xE8, 0x87, 0xB3, 0x29, 0x00,
2059
  0xE5, 0x95, 0x8F, 0x00, 0xE5, 0xB9, 0xBC, 0x00, 0xE7, 0xAE, 0x8F, 0x00, 0x70, 0x74, 0x65, 0x00,
2060
  0x32, 0x31, 0x00, 0x32, 0x32, 0x00, 0x32, 0x33, 0x00, 0x32, 0x34, 0x00, 0x32, 0x35, 0x00, 0x32,
2061
  0x36, 0x00, 0x32, 0x37, 0x00, 0x32, 0x38, 0x00, 0x32, 0x39, 0x00, 0x33, 0x30, 0x00, 0x33, 0x31,
2062
  0x00, 0x33, 0x32, 0x00, 0x33, 0x33, 0x00, 0x33, 0x34, 0x00, 0x33, 0x35, 0x00, 0xEA, 0xB0, 0x80,
2063
  0x00, 0xEB, 0x82, 0x98, 0x00, 0xEB, 0x8B, 0xA4, 0x00, 0xEB, 0x9D, 0xBC, 0x00, 0xEB, 0xA7, 0x88,
2064
  0x00, 0xEB, 0xB0, 0x94, 0x00, 0xEC, 0x82, 0xAC, 0x00, 0xEC, 0x95, 0x84, 0x00, 0xEC, 0x9E, 0x90,
2065
  0x00, 0xEC, 0xB0, 0xA8, 0x00, 0xEC, 0xB9, 0xB4, 0x00, 0xED, 0x83, 0x80, 0x00, 0xED, 0x8C, 0x8C,
2066
  0x00, 0xED, 0x95, 0x98, 0x00, 0xEC, 0xB0, 0xB8, 0xEA, 0xB3, 0xA0, 0x00, 0xEC, 0xA3, 0xBC, 0xEC,
2067
  0x9D, 0x98, 0x00, 0xEC, 0x9A, 0xB0, 0x00, 0xE4, 0xBA, 0x94, 0x00, 0xE5, 0x85, 0xAD, 0x00, 0xE4,
2068
  0xB8, 0x83, 0x00, 0xE4, 0xB9, 0x9D, 0x00, 0xE6, 0xA0, 0xAA, 0x00, 0xE6, 0x9C, 0x89, 0x00, 0xE7,
2069
  0xA4, 0xBE, 0x00, 0xE5, 0x90, 0x8D, 0x00, 0xE7, 0x89, 0xB9, 0x00, 0xE8, 0xB2, 0xA1, 0x00, 0xE7,
2070
  0xA5, 0x9D, 0x00, 0xE5, 0x8A, 0xB4, 0x00, 0xE7, 0xA7, 0x98, 0x00, 0xE7, 0x94, 0xB7, 0x00, 0xE9,
2071
  0x81, 0xA9, 0x00, 0xE5, 0x84, 0xAA, 0x00, 0xE5, 0x8D, 0xB0, 0x00, 0xE6, 0xB3, 0xA8, 0x00, 0xE9,
2072
  0xA0, 0x85, 0x00, 0xE4, 0xBC, 0x91, 0x00, 0xE5, 0x86, 0x99, 0x00, 0xE6, 0xAD, 0xA3, 0x00, 0xE5,
2073
  0xB7, 0xA6, 0x00, 0xE5, 0x8F, 0xB3, 0x00, 0xE5, 0x8C, 0xBB, 0x00, 0xE5, 0xAE, 0x97, 0x00, 0xE5,
2074
  0xAD, 0xA6, 0x00, 0xE7, 0x9B, 0xA3, 0x00, 0xE4, 0xBC, 0x81, 0x00, 0xE8, 0xB3, 0x87, 0x00, 0xE5,
2075
  0x8D, 0x94, 0x00, 0xE5, 0xA4, 0x9C, 0x00, 0x33, 0x36, 0x00, 0x33, 0x37, 0x00, 0x33, 0x38, 0x00,
2076
  0x33, 0x39, 0x00, 0x34, 0x30, 0x00, 0x34, 0x31, 0x00, 0x34, 0x32, 0x00, 0x34, 0x33, 0x00, 0x34,
2077
  0x34, 0x00, 0x34, 0x35, 0x00, 0x34, 0x36, 0x00, 0x34, 0x37, 0x00, 0x34, 0x38, 0x00, 0x34, 0x39,
2078
  0x00, 0x35, 0x30, 0x00, 0x31, 0xE6, 0x9C, 0x88, 0x00, 0x32, 0xE6, 0x9C, 0x88, 0x00, 0x33, 0xE6,
2079
  0x9C, 0x88, 0x00, 0x34, 0xE6, 0x9C, 0x88, 0x00, 0x35, 0xE6, 0x9C, 0x88, 0x00, 0x36, 0xE6, 0x9C,
2080
  0x88, 0x00, 0x37, 0xE6, 0x9C, 0x88, 0x00, 0x38, 0xE6, 0x9C, 0x88, 0x00, 0x39, 0xE6, 0x9C, 0x88,
2081
  0x00, 0x31, 0x30, 0xE6, 0x9C, 0x88, 0x00, 0x31, 0x31, 0xE6, 0x9C, 0x88, 0x00, 0x31, 0x32, 0xE6,
2082
  0x9C, 0x88, 0x00, 0x68, 0x67, 0x00, 0x65, 0x72, 0x67, 0x00, 0x65, 0x76, 0x00, 0x6C, 0x74, 0x64,
2083
  0x00, 0xE3, 0x82, 0xA2, 0x00, 0xE3, 0x82, 0xA4, 0x00, 0xE3, 0x82, 0xA6, 0x00, 0xE3, 0x82, 0xA8,
2084
  0x00, 0xE3, 0x82, 0xAA, 0x00, 0xE3, 0x82, 0xAB, 0x00, 0xE3, 0x82, 0xAD, 0x00, 0xE3, 0x82, 0xAF,
2085
  0x00, 0xE3, 0x82, 0xB1, 0x00, 0xE3, 0x82, 0xB3, 0x00, 0xE3, 0x82, 0xB5, 0x00, 0xE3, 0x82, 0xB7,
2086
  0x00, 0xE3, 0x82, 0xB9, 0x00, 0xE3, 0x82, 0xBB, 0x00, 0xE3, 0x82, 0xBD, 0x00, 0xE3, 0x82, 0xBF,
2087
  0x00, 0xE3, 0x83, 0x81, 0x00, 0xE3, 0x83, 0x84, 0x00, 0xE3, 0x83, 0x86, 0x00, 0xE3, 0x83, 0x88,
2088
  0x00, 0xE3, 0x83, 0x8A, 0x00, 0xE3, 0x83, 0x8B, 0x00, 0xE3, 0x83, 0x8C, 0x00, 0xE3, 0x83, 0x8D,
2089
  0x00, 0xE3, 0x83, 0x8E, 0x00, 0xE3, 0x83, 0x8F, 0x00, 0xE3, 0x83, 0x92, 0x00, 0xE3, 0x83, 0x95,
2090
  0x00, 0xE3, 0x83, 0x98, 0x00, 0xE3, 0x83, 0x9B, 0x00, 0xE3, 0x83, 0x9E, 0x00, 0xE3, 0x83, 0x9F,
2091
  0x00, 0xE3, 0x83, 0xA0, 0x00, 0xE3, 0x83, 0xA1, 0x00, 0xE3, 0x83, 0xA2, 0x00, 0xE3, 0x83, 0xA4,
2092
  0x00, 0xE3, 0x83, 0xA6, 0x00, 0xE3, 0x83, 0xA8, 0x00, 0xE3, 0x83, 0xA9, 0x00, 0xE3, 0x83, 0xAA,
2093
  0x00, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0xAC, 0x00, 0xE3, 0x83, 0xAD, 0x00, 0xE3, 0x83, 0xAF,
2094
  0x00, 0xE3, 0x83, 0xB0, 0x00, 0xE3, 0x83, 0xB1, 0x00, 0xE3, 0x83, 0xB2, 0x00, 0xE4, 0xBB, 0xA4,
2095
  0xE5, 0x92, 0x8C, 0x00, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0x91, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
2096
  0x00, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA1, 0x00, 0xE3, 0x82,
2097
  0xA2, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9A, 0xE3, 0x82, 0xA2, 0x00, 0xE3, 0x82, 0xA2, 0xE3, 0x83,
2098
  0xBC, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
2099
  0xB0, 0x00, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x00, 0xE3, 0x82, 0xA6, 0xE3,
2100
  0x82, 0xA9, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0xAF, 0xE3,
2101
  0x83, 0xBC, 0xE3, 0x83, 0x89, 0x00, 0xE3, 0x82, 0xA8, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3,
2102
  0x83, 0xBC, 0x00, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x00, 0xE3, 0x82, 0xAA,
2103
  0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x00, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAA,
2104
  0x00, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x00, 0xE3, 0x82,
2105
  0xAB, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x00, 0xE3, 0x82, 0xAC, 0xE3, 0x83,
2106
  0xAD, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x82, 0xAC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9E, 0x00, 0xE3,
2107
  0x82, 0xAE, 0xE3, 0x82, 0xAC, 0x00, 0xE3, 0x82, 0xAE, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xBC, 0x00,
2108
  0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x00, 0xE3, 0x82, 0xAE,
2109
  0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x80, 0xE3, 0x83, 0xBC, 0x00, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
2110
  0x00, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xB0, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0,
2111
  0x00, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
2112
  0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83,
2113
  0xE3, 0x83, 0x88, 0x00, 0xE3, 0x82, 0xB0, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x00, 0xE3, 0x82,
2114
  0xB0, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x82,
2115
  0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBC, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAD, 0x00, 0xE3, 0x82,
2116
  0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x8D, 0x00, 0xE3, 0x82, 0xB1, 0xE3, 0x83,
2117
  0xBC, 0xE3, 0x82, 0xB9, 0x00, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x8A, 0x00, 0xE3,
2118
  0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x9D, 0x00, 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0xA4, 0xE3,
2119
  0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3,
2120
  0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x00, 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3,
2121
  0x82, 0xB0, 0x00, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x00, 0xE3, 0x82, 0xBB,
2122
  0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0x00, 0xE3, 0x83, 0x80, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9,
2123
  0x00, 0xE3, 0x83, 0x87, 0xE3, 0x82, 0xB7, 0x00, 0xE3, 0x83, 0x89, 0xE3, 0x83, 0xAB, 0x00, 0xE3,
2124
  0x83, 0x88, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8E, 0x00, 0xE3, 0x83, 0x8E,
2125
  0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x00, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x84,
2126
  0x00, 0xE3, 0x83, 0x91, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88,
2127
  0x00, 0xE3, 0x83, 0x91, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0x00, 0xE3, 0x83, 0x90, 0xE3, 0x83,
2128
  0xBC, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0x94, 0xE3, 0x82, 0xA2, 0xE3, 0x82,
2129
  0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0x94, 0xE3, 0x82, 0xAF, 0xE3, 0x83,
2130
  0xAB, 0x00, 0xE3, 0x83, 0x94, 0xE3, 0x82, 0xB3, 0x00, 0xE3, 0x83, 0x93, 0xE3, 0x83, 0xAB, 0x00,
2131
  0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x89, 0x00,
2132
  0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0x00, 0xE3, 0x83, 0x96,
2133
  0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0x95,
2134
  0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xBF,
2135
  0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0x9A, 0xE3, 0x82, 0xBD, 0x00, 0xE3, 0x83,
2136
  0x9A, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x92, 0x00, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB, 0xE3, 0x83,
2137
  0x84, 0x00, 0xE3, 0x83, 0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x00, 0xE3, 0x83, 0x9A, 0xE3,
2138
  0x83, 0xBC, 0xE3, 0x82, 0xB8, 0x00, 0xE3, 0x83, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBF, 0x00,
2139
  0xE3, 0x83, 0x9D, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0x00, 0xE3, 0x83, 0x9C,
2140
  0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x88, 0x00, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83,
2141
  0x9D, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x89, 0x00, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
2142
  0xAB, 0x00, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83, 0x9E, 0xE3,
2143
  0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0x00, 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3,
2144
  0x83, 0xAB, 0x00, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x8F, 0x00, 0xE3, 0x83, 0x9E,
2145
  0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAF, 0x00, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7,
2146
  0xE3, 0x83, 0xA7, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83, 0x9F, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD,
2147
  0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0x00, 0xE3, 0x83, 0x9F, 0xE3, 0x83,
2148
  0xAA, 0xE3, 0x83, 0x90, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0xA1, 0xE3, 0x82,
2149
  0xAC, 0x00, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x00, 0xE3,
2150
  0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0xA4, 0xE3,
2151
  0x83, 0xBC, 0xE3, 0x83, 0x89, 0x00, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x00,
2152
  0xE3, 0x83, 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x83,
2153
  0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xA9, 0x00, 0xE3, 0x83,
2154
  0xAB, 0xE3, 0x83, 0x94, 0xE3, 0x83, 0xBC, 0x00, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
2155
  0x96, 0xE3, 0x83, 0xAB, 0x00, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xA0, 0x00, 0xE3, 0x83, 0xAC, 0xE3,
2156
  0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xB2, 0xE3, 0x83, 0xB3, 0x00, 0xE3, 0x83, 0xAF, 0xE3,
2157
  0x83, 0x83, 0xE3, 0x83, 0x88, 0x00, 0x30, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0xE7, 0x82, 0xB9, 0x00,
2158
  0x32, 0xE7, 0x82, 0xB9, 0x00, 0x33, 0xE7, 0x82, 0xB9, 0x00, 0x34, 0xE7, 0x82, 0xB9, 0x00, 0x35,
2159
  0xE7, 0x82, 0xB9, 0x00, 0x36, 0xE7, 0x82, 0xB9, 0x00, 0x37, 0xE7, 0x82, 0xB9, 0x00, 0x38, 0xE7,
2160
  0x82, 0xB9, 0x00, 0x39, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0x30, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0x31,
2161
  0xE7, 0x82, 0xB9, 0x00, 0x31, 0x32, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0x33, 0xE7, 0x82, 0xB9, 0x00,
2162
  0x31, 0x34, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0x35, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0x36, 0xE7, 0x82,
2163
  0xB9, 0x00, 0x31, 0x37, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0x38, 0xE7, 0x82, 0xB9, 0x00, 0x31, 0x39,
2164
  0xE7, 0x82, 0xB9, 0x00, 0x32, 0x30, 0xE7, 0x82, 0xB9, 0x00, 0x32, 0x31, 0xE7, 0x82, 0xB9, 0x00,
2165
  0x32, 0x32, 0xE7, 0x82, 0xB9, 0x00, 0x32, 0x33, 0xE7, 0x82, 0xB9, 0x00, 0x32, 0x34, 0xE7, 0x82,
2166
  0xB9, 0x00, 0x68, 0x70, 0x61, 0x00, 0x64, 0x61, 0x00, 0x61, 0x75, 0x00, 0x62, 0x61, 0x72, 0x00,
2167
  0x6F, 0x76, 0x00, 0x70, 0x63, 0x00, 0x64, 0x6D, 0x00, 0x64, 0x6D, 0x32, 0x00, 0x64, 0x6D, 0x33,
2168
  0x00, 0x69, 0x75, 0x00, 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, 0x00, 0xE6, 0x98, 0xAD, 0xE5, 0x92,
2169
  0x8C, 0x00, 0xE5, 0xA4, 0xA7, 0xE6, 0xAD, 0xA3, 0x00, 0xE6, 0x98, 0x8E, 0xE6, 0xB2, 0xBB, 0x00,
2170
  0xE6, 0xA0, 0xAA, 0xE5, 0xBC, 0x8F, 0xE4, 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x00, 0x70, 0x61, 0x00,
2171
  0x6E, 0x61, 0x00, 0xCE, 0xBC, 0x61, 0x00, 0x6D, 0x61, 0x00, 0x6B, 0x61, 0x00, 0x6B, 0x62, 0x00,
2172
  0x6D, 0x62, 0x00, 0x67, 0x62, 0x00, 0x63, 0x61, 0x6C, 0x00, 0x6B, 0x63, 0x61, 0x6C, 0x00, 0x70,
2173
  0x66, 0x00, 0x6E, 0x66, 0x00, 0xCE, 0xBC, 0x66, 0x00, 0xCE, 0xBC, 0x67, 0x00, 0x6D, 0x67, 0x00,
2174
  0x6B, 0x67, 0x00, 0x68, 0x7A, 0x00, 0x6B, 0x68, 0x7A, 0x00, 0x6D, 0x68, 0x7A, 0x00, 0x67, 0x68,
2175
  0x7A, 0x00, 0x74, 0x68, 0x7A, 0x00, 0xCE, 0xBC, 0x6C, 0x00, 0x6D, 0x6C, 0x00, 0x64, 0x6C, 0x00,
2176
  0x6B, 0x6C, 0x00, 0x66, 0x6D, 0x00, 0x6E, 0x6D, 0x00, 0xCE, 0xBC, 0x6D, 0x00, 0x6D, 0x6D, 0x00,
2177
  0x63, 0x6D, 0x00, 0x6B, 0x6D, 0x00, 0x6D, 0x6D, 0x32, 0x00, 0x63, 0x6D, 0x32, 0x00, 0x6D, 0x32,
2178
  0x00, 0x6B, 0x6D, 0x32, 0x00, 0x6D, 0x6D, 0x33, 0x00, 0x63, 0x6D, 0x33, 0x00, 0x6D, 0x33, 0x00,
2179
  0x6B, 0x6D, 0x33, 0x00, 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x00, 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x32,
2180
  0x00, 0x6B, 0x70, 0x61, 0x00, 0x6D, 0x70, 0x61, 0x00, 0x67, 0x70, 0x61, 0x00, 0x72, 0x61, 0x64,
2181
  0x00, 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x00, 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73,
2182
  0x32, 0x00, 0x70, 0x73, 0x00, 0x6E, 0x73, 0x00, 0xCE, 0xBC, 0x73, 0x00, 0x6D, 0x73, 0x00, 0x70,
2183
  0x76, 0x00, 0x6E, 0x76, 0x00, 0xCE, 0xBC, 0x76, 0x00, 0x6D, 0x76, 0x00, 0x6B, 0x76, 0x00, 0x70,
2184
  0x77, 0x00, 0x6E, 0x77, 0x00, 0xCE, 0xBC, 0x77, 0x00, 0x6D, 0x77, 0x00, 0x6B, 0x77, 0x00, 0x6B,
2185
  0xCF, 0x89, 0x00, 0x6D, 0xCF, 0x89, 0x00, 0x62, 0x71, 0x00, 0x63, 0x63, 0x00, 0x63, 0x64, 0x00,
2186
  0x63, 0xE2, 0x88, 0x95, 0x6B, 0x67, 0x00, 0x64, 0x62, 0x00, 0x67, 0x79, 0x00, 0x68, 0x61, 0x00,
2187
  0x68, 0x70, 0x00, 0x69, 0x6E, 0x00, 0x6B, 0x6B, 0x00, 0x6B, 0x74, 0x00, 0x6C, 0x6D, 0x00, 0x6C,
2188
  0x6E, 0x00, 0x6C, 0x6F, 0x67, 0x00, 0x6C, 0x78, 0x00, 0x6D, 0x69, 0x6C, 0x00, 0x6D, 0x6F, 0x6C,
2189
  0x00, 0x70, 0x68, 0x00, 0x70, 0x70, 0x6D, 0x00, 0x70, 0x72, 0x00, 0x73, 0x72, 0x00, 0x73, 0x76,
2190
  0x00, 0x77, 0x62, 0x00, 0x76, 0xE2, 0x88, 0x95, 0x6D, 0x00, 0x61, 0xE2, 0x88, 0x95, 0x6D, 0x00,
2191
  0x31, 0xE6, 0x97, 0xA5, 0x00, 0x32, 0xE6, 0x97, 0xA5, 0x00, 0x33, 0xE6, 0x97, 0xA5, 0x00, 0x34,
2192
  0xE6, 0x97, 0xA5, 0x00, 0x35, 0xE6, 0x97, 0xA5, 0x00, 0x36, 0xE6, 0x97, 0xA5, 0x00, 0x37, 0xE6,
2193
  0x97, 0xA5, 0x00, 0x38, 0xE6, 0x97, 0xA5, 0x00, 0x39, 0xE6, 0x97, 0xA5, 0x00, 0x31, 0x30, 0xE6,
2194
  0x97, 0xA5, 0x00, 0x31, 0x31, 0xE6, 0x97, 0xA5, 0x00, 0x31, 0x32, 0xE6, 0x97, 0xA5, 0x00, 0x31,
2195
  0x33, 0xE6, 0x97, 0xA5, 0x00, 0x31, 0x34, 0xE6, 0x97, 0xA5, 0x00, 0x31, 0x35, 0xE6, 0x97, 0xA5,
2196
  0x00, 0x31, 0x36, 0xE6, 0x97, 0xA5, 0x00, 0x31, 0x37, 0xE6, 0x97, 0xA5, 0x00, 0x31, 0x38, 0xE6,
2197
  0x97, 0xA5, 0x00, 0x31, 0x39, 0xE6, 0x97, 0xA5, 0x00, 0x32, 0x30, 0xE6, 0x97, 0xA5, 0x00, 0x32,
2198
  0x31, 0xE6, 0x97, 0xA5, 0x00, 0x32, 0x32, 0xE6, 0x97, 0xA5, 0x00, 0x32, 0x33, 0xE6, 0x97, 0xA5,
2199
  0x00, 0x32, 0x34, 0xE6, 0x97, 0xA5, 0x00, 0x32, 0x35, 0xE6, 0x97, 0xA5, 0x00, 0x32, 0x36, 0xE6,
2200
  0x97, 0xA5, 0x00, 0x32, 0x37, 0xE6, 0x97, 0xA5, 0x00, 0x32, 0x38, 0xE6, 0x97, 0xA5, 0x00, 0x32,
2201
  0x39, 0xE6, 0x97, 0xA5, 0x00, 0x33, 0x30, 0xE6, 0x97, 0xA5, 0x00, 0x33, 0x31, 0xE6, 0x97, 0xA5,
2202
  0x00, 0x67, 0x61, 0x6C, 0x00, 0xEA, 0x99, 0x81, 0x00, 0xEA, 0x99, 0x83, 0x00, 0xEA, 0x99, 0x85,
2203
  0x00, 0xEA, 0x99, 0x87, 0x00, 0xEA, 0x99, 0x89, 0x00, 0xEA, 0x99, 0x8D, 0x00, 0xEA, 0x99, 0x8F,
2204
  0x00, 0xEA, 0x99, 0x91, 0x00, 0xEA, 0x99, 0x93, 0x00, 0xEA, 0x99, 0x95, 0x00, 0xEA, 0x99, 0x97,
2205
  0x00, 0xEA, 0x99, 0x99, 0x00, 0xEA, 0x99, 0x9B, 0x00, 0xEA, 0x99, 0x9D, 0x00, 0xEA, 0x99, 0x9F,
2206
  0x00, 0xEA, 0x99, 0xA1, 0x00, 0xEA, 0x99, 0xA3, 0x00, 0xEA, 0x99, 0xA5, 0x00, 0xEA, 0x99, 0xA7,
2207
  0x00, 0xEA, 0x99, 0xA9, 0x00, 0xEA, 0x99, 0xAB, 0x00, 0xEA, 0x99, 0xAD, 0x00, 0xEA, 0x9A, 0x81,
2208
  0x00, 0xEA, 0x9A, 0x83, 0x00, 0xEA, 0x9A, 0x85, 0x00, 0xEA, 0x9A, 0x87, 0x00, 0xEA, 0x9A, 0x89,
2209
  0x00, 0xEA, 0x9A, 0x8B, 0x00, 0xEA, 0x9A, 0x8D, 0x00, 0xEA, 0x9A, 0x8F, 0x00, 0xEA, 0x9A, 0x91,
2210
  0x00, 0xEA, 0x9A, 0x93, 0x00, 0xEA, 0x9A, 0x95, 0x00, 0xEA, 0x9A, 0x97, 0x00, 0xEA, 0x9A, 0x99,
2211
  0x00, 0xEA, 0x9A, 0x9B, 0x00, 0xEA, 0x9C, 0xA3, 0x00, 0xEA, 0x9C, 0xA5, 0x00, 0xEA, 0x9C, 0xA7,
2212
  0x00, 0xEA, 0x9C, 0xA9, 0x00, 0xEA, 0x9C, 0xAB, 0x00, 0xEA, 0x9C, 0xAD, 0x00, 0xEA, 0x9C, 0xAF,
2213
  0x00, 0xEA, 0x9C, 0xB3, 0x00, 0xEA, 0x9C, 0xB5, 0x00, 0xEA, 0x9C, 0xB7, 0x00, 0xEA, 0x9C, 0xB9,
2214
  0x00, 0xEA, 0x9C, 0xBB, 0x00, 0xEA, 0x9C, 0xBD, 0x00, 0xEA, 0x9C, 0xBF, 0x00, 0xEA, 0x9D, 0x81,
2215
  0x00, 0xEA, 0x9D, 0x83, 0x00, 0xEA, 0x9D, 0x85, 0x00, 0xEA, 0x9D, 0x87, 0x00, 0xEA, 0x9D, 0x89,
2216
  0x00, 0xEA, 0x9D, 0x8B, 0x00, 0xEA, 0x9D, 0x8D, 0x00, 0xEA, 0x9D, 0x8F, 0x00, 0xEA, 0x9D, 0x91,
2217
  0x00, 0xEA, 0x9D, 0x93, 0x00, 0xEA, 0x9D, 0x95, 0x00, 0xEA, 0x9D, 0x97, 0x00, 0xEA, 0x9D, 0x99,
2218
  0x00, 0xEA, 0x9D, 0x9B, 0x00, 0xEA, 0x9D, 0x9D, 0x00, 0xEA, 0x9D, 0x9F, 0x00, 0xEA, 0x9D, 0xA1,
2219
  0x00, 0xEA, 0x9D, 0xA3, 0x00, 0xEA, 0x9D, 0xA5, 0x00, 0xEA, 0x9D, 0xA7, 0x00, 0xEA, 0x9D, 0xA9,
2220
  0x00, 0xEA, 0x9D, 0xAB, 0x00, 0xEA, 0x9D, 0xAD, 0x00, 0xEA, 0x9D, 0xAF, 0x00, 0xEA, 0x9D, 0xBA,
2221
  0x00, 0xEA, 0x9D, 0xBC, 0x00, 0xE1, 0xB5, 0xB9, 0x00, 0xEA, 0x9D, 0xBF, 0x00, 0xEA, 0x9E, 0x81,
2222
  0x00, 0xEA, 0x9E, 0x83, 0x00, 0xEA, 0x9E, 0x85, 0x00, 0xEA, 0x9E, 0x87, 0x00, 0xEA, 0x9E, 0x8C,
2223
  0x00, 0xEA, 0x9E, 0x91, 0x00, 0xEA, 0x9E, 0x93, 0x00, 0xEA, 0x9E, 0x97, 0x00, 0xEA, 0x9E, 0x99,
2224
  0x00, 0xEA, 0x9E, 0x9B, 0x00, 0xEA, 0x9E, 0x9D, 0x00, 0xEA, 0x9E, 0x9F, 0x00, 0xEA, 0x9E, 0xA1,
2225
  0x00, 0xEA, 0x9E, 0xA3, 0x00, 0xEA, 0x9E, 0xA5, 0x00, 0xEA, 0x9E, 0xA7, 0x00, 0xEA, 0x9E, 0xA9,
2226
  0x00, 0xC9, 0xAC, 0x00, 0xCA, 0x9E, 0x00, 0xCA, 0x87, 0x00, 0xEA, 0xAD, 0x93, 0x00, 0xEA, 0x9E,
2227
  0xB5, 0x00, 0xEA, 0x9E, 0xB7, 0x00, 0xEA, 0x9E, 0xB9, 0x00, 0xEA, 0x9E, 0xBB, 0x00, 0xEA, 0x9E,
2228
  0xBD, 0x00, 0xEA, 0x9E, 0xBF, 0x00, 0xEA, 0x9F, 0x81, 0x00, 0xEA, 0x9F, 0x83, 0x00, 0xEA, 0x9E,
2229
  0x94, 0x00, 0xE1, 0xB6, 0x8E, 0x00, 0xEA, 0x9F, 0x88, 0x00, 0xEA, 0x9F, 0x8A, 0x00, 0xC9, 0xA4,
2230
  0x00, 0xEA, 0x9F, 0x8D, 0x00, 0xEA, 0x9F, 0x8F, 0x00, 0xEA, 0x9F, 0x91, 0x00, 0xEA, 0x9F, 0x93,
2231
  0x00, 0xEA, 0x9F, 0x95, 0x00, 0xEA, 0x9F, 0x97, 0x00, 0xEA, 0x9F, 0x99, 0x00, 0xEA, 0x9F, 0x9B,
2232
  0x00, 0xC6, 0x9B, 0x00, 0xEA, 0x9F, 0xB6, 0x00, 0xEA, 0xAC, 0xB7, 0x00, 0xEA, 0xAD, 0x92, 0x00,
2233
  0xCA, 0x8D, 0x00, 0xE1, 0x8E, 0xA0, 0x00, 0xE1, 0x8E, 0xA1, 0x00, 0xE1, 0x8E, 0xA2, 0x00, 0xE1,
2234
  0x8E, 0xA3, 0x00, 0xE1, 0x8E, 0xA4, 0x00, 0xE1, 0x8E, 0xA5, 0x00, 0xE1, 0x8E, 0xA6, 0x00, 0xE1,
2235
  0x8E, 0xA7, 0x00, 0xE1, 0x8E, 0xA8, 0x00, 0xE1, 0x8E, 0xA9, 0x00, 0xE1, 0x8E, 0xAA, 0x00, 0xE1,
2236
  0x8E, 0xAB, 0x00, 0xE1, 0x8E, 0xAC, 0x00, 0xE1, 0x8E, 0xAD, 0x00, 0xE1, 0x8E, 0xAE, 0x00, 0xE1,
2237
  0x8E, 0xAF, 0x00, 0xE1, 0x8E, 0xB0, 0x00, 0xE1, 0x8E, 0xB1, 0x00, 0xE1, 0x8E, 0xB2, 0x00, 0xE1,
2238
  0x8E, 0xB3, 0x00, 0xE1, 0x8E, 0xB4, 0x00, 0xE1, 0x8E, 0xB5, 0x00, 0xE1, 0x8E, 0xB6, 0x00, 0xE1,
2239
  0x8E, 0xB7, 0x00, 0xE1, 0x8E, 0xB8, 0x00, 0xE1, 0x8E, 0xB9, 0x00, 0xE1, 0x8E, 0xBA, 0x00, 0xE1,
2240
  0x8E, 0xBB, 0x00, 0xE1, 0x8E, 0xBC, 0x00, 0xE1, 0x8E, 0xBD, 0x00, 0xE1, 0x8E, 0xBE, 0x00, 0xE1,
2241
  0x8E, 0xBF, 0x00, 0xE1, 0x8F, 0x80, 0x00, 0xE1, 0x8F, 0x81, 0x00, 0xE1, 0x8F, 0x82, 0x00, 0xE1,
2242
  0x8F, 0x83, 0x00, 0xE1, 0x8F, 0x84, 0x00, 0xE1, 0x8F, 0x85, 0x00, 0xE1, 0x8F, 0x86, 0x00, 0xE1,
2243
  0x8F, 0x87, 0x00, 0xE1, 0x8F, 0x88, 0x00, 0xE1, 0x8F, 0x89, 0x00, 0xE1, 0x8F, 0x8A, 0x00, 0xE1,
2244
  0x8F, 0x8B, 0x00, 0xE1, 0x8F, 0x8C, 0x00, 0xE1, 0x8F, 0x8D, 0x00, 0xE1, 0x8F, 0x8E, 0x00, 0xE1,
2245
  0x8F, 0x8F, 0x00, 0xE1, 0x8F, 0x90, 0x00, 0xE1, 0x8F, 0x91, 0x00, 0xE1, 0x8F, 0x92, 0x00, 0xE1,
2246
  0x8F, 0x93, 0x00, 0xE1, 0x8F, 0x94, 0x00, 0xE1, 0x8F, 0x95, 0x00, 0xE1, 0x8F, 0x96, 0x00, 0xE1,
2247
  0x8F, 0x97, 0x00, 0xE1, 0x8F, 0x98, 0x00, 0xE1, 0x8F, 0x99, 0x00, 0xE1, 0x8F, 0x9A, 0x00, 0xE1,
2248
  0x8F, 0x9B, 0x00, 0xE1, 0x8F, 0x9C, 0x00, 0xE1, 0x8F, 0x9D, 0x00, 0xE1, 0x8F, 0x9E, 0x00, 0xE1,
2249
  0x8F, 0x9F, 0x00, 0xE1, 0x8F, 0xA0, 0x00, 0xE1, 0x8F, 0xA1, 0x00, 0xE1, 0x8F, 0xA2, 0x00, 0xE1,
2250
  0x8F, 0xA3, 0x00, 0xE1, 0x8F, 0xA4, 0x00, 0xE1, 0x8F, 0xA5, 0x00, 0xE1, 0x8F, 0xA6, 0x00, 0xE1,
2251
  0x8F, 0xA7, 0x00, 0xE1, 0x8F, 0xA8, 0x00, 0xE1, 0x8F, 0xA9, 0x00, 0xE1, 0x8F, 0xAA, 0x00, 0xE1,
2252
  0x8F, 0xAB, 0x00, 0xE1, 0x8F, 0xAC, 0x00, 0xE1, 0x8F, 0xAD, 0x00, 0xE1, 0x8F, 0xAE, 0x00, 0xE1,
2253
  0x8F, 0xAF, 0x00, 0xE8, 0xB1, 0x88, 0x00, 0xE6, 0x9B, 0xB4, 0x00, 0xE8, 0xB3, 0x88, 0x00, 0xE6,
2254
  0xBB, 0x91, 0x00, 0xE4, 0xB8, 0xB2, 0x00, 0xE5, 0x8F, 0xA5, 0x00, 0xE5, 0xA5, 0x91, 0x00, 0xE5,
2255
  0x96, 0x87, 0x00, 0xE5, 0xA5, 0x88, 0x00, 0xE6, 0x87, 0xB6, 0x00, 0xE7, 0x99, 0xA9, 0x00, 0xE7,
2256
  0xBE, 0x85, 0x00, 0xE8, 0x98, 0xBF, 0x00, 0xE8, 0x9E, 0xBA, 0x00, 0xE8, 0xA3, 0xB8, 0x00, 0xE9,
2257
  0x82, 0x8F, 0x00, 0xE6, 0xA8, 0x82, 0x00, 0xE6, 0xB4, 0x9B, 0x00, 0xE7, 0x83, 0x99, 0x00, 0xE7,
2258
  0x8F, 0x9E, 0x00, 0xE8, 0x90, 0xBD, 0x00, 0xE9, 0x85, 0xAA, 0x00, 0xE9, 0xA7, 0xB1, 0x00, 0xE4,
2259
  0xBA, 0x82, 0x00, 0xE5, 0x8D, 0xB5, 0x00, 0xE6, 0xAC, 0x84, 0x00, 0xE7, 0x88, 0x9B, 0x00, 0xE8,
2260
  0x98, 0xAD, 0x00, 0xE9, 0xB8, 0x9E, 0x00, 0xE5, 0xB5, 0x90, 0x00, 0xE6, 0xBF, 0xAB, 0x00, 0xE8,
2261
  0x97, 0x8D, 0x00, 0xE8, 0xA5, 0xA4, 0x00, 0xE6, 0x8B, 0x89, 0x00, 0xE8, 0x87, 0x98, 0x00, 0xE8,
2262
  0xA0, 0x9F, 0x00, 0xE5, 0xBB, 0x8A, 0x00, 0xE6, 0x9C, 0x97, 0x00, 0xE6, 0xB5, 0xAA, 0x00, 0xE7,
2263
  0x8B, 0xBC, 0x00, 0xE9, 0x83, 0x8E, 0x00, 0xE4, 0xBE, 0x86, 0x00, 0xE5, 0x86, 0xB7, 0x00, 0xE5,
2264
  0x8B, 0x9E, 0x00, 0xE6, 0x93, 0x84, 0x00, 0xE6, 0xAB, 0x93, 0x00, 0xE7, 0x88, 0x90, 0x00, 0xE7,
2265
  0x9B, 0xA7, 0x00, 0xE8, 0x98, 0x86, 0x00, 0xE8, 0x99, 0x9C, 0x00, 0xE8, 0xB7, 0xAF, 0x00, 0xE9,
2266
  0x9C, 0xB2, 0x00, 0xE9, 0xAD, 0xAF, 0x00, 0xE9, 0xB7, 0xBA, 0x00, 0xE7, 0xA2, 0x8C, 0x00, 0xE7,
2267
  0xA5, 0xBF, 0x00, 0xE7, 0xB6, 0xA0, 0x00, 0xE8, 0x8F, 0x89, 0x00, 0xE9, 0x8C, 0x84, 0x00, 0xE8,
2268
  0xAB, 0x96, 0x00, 0xE5, 0xA3, 0x9F, 0x00, 0xE5, 0xBC, 0x84, 0x00, 0xE7, 0xB1, 0xA0, 0x00, 0xE8,
2269
  0x81, 0xBE, 0x00, 0xE7, 0x89, 0xA2, 0x00, 0xE7, 0xA3, 0x8A, 0x00, 0xE8, 0xB3, 0x82, 0x00, 0xE9,
2270
  0x9B, 0xB7, 0x00, 0xE5, 0xA3, 0x98, 0x00, 0xE5, 0xB1, 0xA2, 0x00, 0xE6, 0xA8, 0x93, 0x00, 0xE6,
2271
  0xB7, 0x9A, 0x00, 0xE6, 0xBC, 0x8F, 0x00, 0xE7, 0xB4, 0xAF, 0x00, 0xE7, 0xB8, 0xB7, 0x00, 0xE9,
2272
  0x99, 0x8B, 0x00, 0xE5, 0x8B, 0x92, 0x00, 0xE8, 0x82, 0x8B, 0x00, 0xE5, 0x87, 0x9C, 0x00, 0xE5,
2273
  0x87, 0x8C, 0x00, 0xE7, 0xA8, 0x9C, 0x00, 0xE7, 0xB6, 0xBE, 0x00, 0xE8, 0x8F, 0xB1, 0x00, 0xE9,
2274
  0x99, 0xB5, 0x00, 0xE8, 0xAE, 0x80, 0x00, 0xE6, 0x8B, 0x8F, 0x00, 0xE8, 0xAB, 0xBE, 0x00, 0xE4,
2275
  0xB8, 0xB9, 0x00, 0xE5, 0xAF, 0xA7, 0x00, 0xE6, 0x80, 0x92, 0x00, 0xE7, 0x8E, 0x87, 0x00, 0xE7,
2276
  0x95, 0xB0, 0x00, 0xE5, 0x8C, 0x97, 0x00, 0xE7, 0xA3, 0xBB, 0x00, 0xE4, 0xBE, 0xBF, 0x00, 0xE5,
2277
  0xBE, 0xA9, 0x00, 0xE4, 0xB8, 0x8D, 0x00, 0xE6, 0xB3, 0x8C, 0x00, 0xE6, 0x95, 0xB8, 0x00, 0xE7,
2278
  0xB4, 0xA2, 0x00, 0xE5, 0x8F, 0x83, 0x00, 0xE5, 0xA1, 0x9E, 0x00, 0xE7, 0x9C, 0x81, 0x00, 0xE8,
2279
  0x91, 0x89, 0x00, 0xE8, 0xAA, 0xAA, 0x00, 0xE6, 0xAE, 0xBA, 0x00, 0xE6, 0xB2, 0x88, 0x00, 0xE6,
2280
  0x8B, 0xBE, 0x00, 0xE8, 0x8B, 0xA5, 0x00, 0xE6, 0x8E, 0xA0, 0x00, 0xE7, 0x95, 0xA5, 0x00, 0xE4,
2281
  0xBA, 0xAE, 0x00, 0xE5, 0x85, 0xA9, 0x00, 0xE5, 0x87, 0x89, 0x00, 0xE6, 0xA2, 0x81, 0x00, 0xE7,
2282
  0xB3, 0xA7, 0x00, 0xE8, 0x89, 0xAF, 0x00, 0xE8, 0xAB, 0x92, 0x00, 0xE9, 0x87, 0x8F, 0x00, 0xE5,
2283
  0x8B, 0xB5, 0x00, 0xE5, 0x91, 0x82, 0x00, 0xE5, 0xBB, 0xAC, 0x00, 0xE6, 0x97, 0x85, 0x00, 0xE6,
2284
  0xBF, 0xBE, 0x00, 0xE7, 0xA4, 0xAA, 0x00, 0xE9, 0x96, 0xAD, 0x00, 0xE9, 0xA9, 0xAA, 0x00, 0xE9,
2285
  0xBA, 0x97, 0x00, 0xE9, 0xBB, 0x8E, 0x00, 0xE6, 0x9B, 0x86, 0x00, 0xE6, 0xAD, 0xB7, 0x00, 0xE8,
2286
  0xBD, 0xA2, 0x00, 0xE5, 0xB9, 0xB4, 0x00, 0xE6, 0x86, 0x90, 0x00, 0xE6, 0x88, 0x80, 0x00, 0xE6,
2287
  0x92, 0x9A, 0x00, 0xE6, 0xBC, 0xA3, 0x00, 0xE7, 0x85, 0x89, 0x00, 0xE7, 0x92, 0x89, 0x00, 0xE7,
2288
  0xA7, 0x8A, 0x00, 0xE7, 0xB7, 0xB4, 0x00, 0xE8, 0x81, 0xAF, 0x00, 0xE8, 0xBC, 0xA6, 0x00, 0xE8,
2289
  0x93, 0xAE, 0x00, 0xE9, 0x80, 0xA3, 0x00, 0xE9, 0x8D, 0x8A, 0x00, 0xE5, 0x88, 0x97, 0x00, 0xE5,
2290
  0x8A, 0xA3, 0x00, 0xE5, 0x92, 0xBD, 0x00, 0xE7, 0x83, 0x88, 0x00, 0xE8, 0xA3, 0x82, 0x00, 0xE5,
2291
  0xBB, 0x89, 0x00, 0xE5, 0xBF, 0xB5, 0x00, 0xE6, 0x8D, 0xBB, 0x00, 0xE6, 0xAE, 0xAE, 0x00, 0xE7,
2292
  0xB0, 0xBE, 0x00, 0xE7, 0x8D, 0xB5, 0x00, 0xE4, 0xBB, 0xA4, 0x00, 0xE5, 0x9B, 0xB9, 0x00, 0xE5,
2293
  0xB6, 0xBA, 0x00, 0xE6, 0x80, 0x9C, 0x00, 0xE7, 0x8E, 0xB2, 0x00, 0xE7, 0x91, 0xA9, 0x00, 0xE7,
2294
  0xBE, 0x9A, 0x00, 0xE8, 0x81, 0x86, 0x00, 0xE9, 0x88, 0xB4, 0x00, 0xE9, 0x9B, 0xB6, 0x00, 0xE9,
2295
  0x9D, 0x88, 0x00, 0xE9, 0xA0, 0x98, 0x00, 0xE4, 0xBE, 0x8B, 0x00, 0xE7, 0xA6, 0xAE, 0x00, 0xE9,
2296
  0x86, 0xB4, 0x00, 0xE9, 0x9A, 0xB8, 0x00, 0xE6, 0x83, 0xA1, 0x00, 0xE4, 0xBA, 0x86, 0x00, 0xE5,
2297
  0x83, 0x9A, 0x00, 0xE5, 0xAF, 0xAE, 0x00, 0xE5, 0xB0, 0xBF, 0x00, 0xE6, 0x96, 0x99, 0x00, 0xE7,
2298
  0x87, 0x8E, 0x00, 0xE7, 0x99, 0x82, 0x00, 0xE8, 0x93, 0xBC, 0x00, 0xE9, 0x81, 0xBC, 0x00, 0xE6,
2299
  0x9A, 0x88, 0x00, 0xE9, 0x98, 0xAE, 0x00, 0xE5, 0x8A, 0x89, 0x00, 0xE6, 0x9D, 0xBB, 0x00, 0xE6,
2300
  0x9F, 0xB3, 0x00, 0xE6, 0xB5, 0x81, 0x00, 0xE6, 0xBA, 0x9C, 0x00, 0xE7, 0x90, 0x89, 0x00, 0xE7,
2301
  0x95, 0x99, 0x00, 0xE7, 0xA1, 0xAB, 0x00, 0xE7, 0xB4, 0x90, 0x00, 0xE9, 0xA1, 0x9E, 0x00, 0xE6,
2302
  0x88, 0xAE, 0x00, 0xE9, 0x99, 0xB8, 0x00, 0xE5, 0x80, 0xAB, 0x00, 0xE5, 0xB4, 0x99, 0x00, 0xE6,
2303
  0xB7, 0xAA, 0x00, 0xE8, 0xBC, 0xAA, 0x00, 0xE5, 0xBE, 0x8B, 0x00, 0xE6, 0x85, 0x84, 0x00, 0xE6,
2304
  0xA0, 0x97, 0x00, 0xE9, 0x9A, 0x86, 0x00, 0xE5, 0x88, 0xA9, 0x00, 0xE5, 0x90, 0x8F, 0x00, 0xE5,
2305
  0xB1, 0xA5, 0x00, 0xE6, 0x98, 0x93, 0x00, 0xE6, 0x9D, 0x8E, 0x00, 0xE6, 0xA2, 0xA8, 0x00, 0xE6,
2306
  0xB3, 0xA5, 0x00, 0xE7, 0x90, 0x86, 0x00, 0xE7, 0x97, 0xA2, 0x00, 0xE7, 0xBD, 0xB9, 0x00, 0xE8,
2307
  0xA3, 0x8F, 0x00, 0xE8, 0xA3, 0xA1, 0x00, 0xE9, 0x9B, 0xA2, 0x00, 0xE5, 0x8C, 0xBF, 0x00, 0xE6,
2308
  0xBA, 0xBA, 0x00, 0xE5, 0x90, 0x9D, 0x00, 0xE7, 0x87, 0x90, 0x00, 0xE7, 0x92, 0x98, 0x00, 0xE8,
2309
  0x97, 0xBA, 0x00, 0xE9, 0x9A, 0xA3, 0x00, 0xE9, 0xB1, 0x97, 0x00, 0xE9, 0xBA, 0x9F, 0x00, 0xE6,
2310
  0x9E, 0x97, 0x00, 0xE6, 0xB7, 0x8B, 0x00, 0xE8, 0x87, 0xA8, 0x00, 0xE7, 0xAC, 0xA0, 0x00, 0xE7,
2311
  0xB2, 0x92, 0x00, 0xE7, 0x8B, 0x80, 0x00, 0xE7, 0x82, 0x99, 0x00, 0xE8, 0xAD, 0x98, 0x00, 0xE4,
2312
  0xBB, 0x80, 0x00, 0xE8, 0x8C, 0xB6, 0x00, 0xE5, 0x88, 0xBA, 0x00, 0xE5, 0x88, 0x87, 0x00, 0xE5,
2313
  0xBA, 0xA6, 0x00, 0xE6, 0x8B, 0x93, 0x00, 0xE7, 0xB3, 0x96, 0x00, 0xE5, 0xAE, 0x85, 0x00, 0xE6,
2314
  0xB4, 0x9E, 0x00, 0xE6, 0x9A, 0xB4, 0x00, 0xE8, 0xBC, 0xBB, 0x00, 0xE9, 0x99, 0x8D, 0x00, 0xE5,
2315
  0xBB, 0x93, 0x00, 0xE5, 0x85, 0x80, 0x00, 0xE5, 0x97, 0x80, 0x00, 0xE5, 0xA1, 0x9A, 0x00, 0xE6,
2316
  0x99, 0xB4, 0x00, 0xE5, 0x87, 0x9E, 0x00, 0xE7, 0x8C, 0xAA, 0x00, 0xE7, 0x9B, 0x8A, 0x00, 0xE7,
2317
  0xA4, 0xBC, 0x00, 0xE7, 0xA5, 0x9E, 0x00, 0xE7, 0xA5, 0xA5, 0x00, 0xE7, 0xA6, 0x8F, 0x00, 0xE9,
2318
  0x9D, 0x96, 0x00, 0xE7, 0xB2, 0xBE, 0x00, 0xE8, 0x98, 0x92, 0x00, 0xE8, 0xAB, 0xB8, 0x00, 0xE9,
2319
  0x80, 0xB8, 0x00, 0xE9, 0x83, 0xBD, 0x00, 0xE9, 0xA3, 0xAF, 0x00, 0xE9, 0xA3, 0xBC, 0x00, 0xE9,
2320
  0xA4, 0xA8, 0x00, 0xE9, 0xB6, 0xB4, 0x00, 0xE9, 0x83, 0x9E, 0x00, 0xE9, 0x9A, 0xB7, 0x00, 0xE4,
2321
  0xBE, 0xAE, 0x00, 0xE5, 0x83, 0xA7, 0x00, 0xE5, 0x85, 0x8D, 0x00, 0xE5, 0x8B, 0x89, 0x00, 0xE5,
2322
  0x8B, 0xA4, 0x00, 0xE5, 0x8D, 0x91, 0x00, 0xE5, 0x96, 0x9D, 0x00, 0xE5, 0x98, 0x86, 0x00, 0xE5,
2323
  0x99, 0xA8, 0x00, 0xE5, 0xA1, 0x80, 0x00, 0xE5, 0xA2, 0xA8, 0x00, 0xE5, 0xB1, 0xA4, 0x00, 0xE6,
2324
  0x82, 0x94, 0x00, 0xE6, 0x85, 0xA8, 0x00, 0xE6, 0x86, 0x8E, 0x00, 0xE6, 0x87, 0xB2, 0x00, 0xE6,
2325
  0x95, 0x8F, 0x00, 0xE6, 0x97, 0xA2, 0x00, 0xE6, 0x9A, 0x91, 0x00, 0xE6, 0xA2, 0x85, 0x00, 0xE6,
2326
  0xB5, 0xB7, 0x00, 0xE6, 0xB8, 0x9A, 0x00, 0xE6, 0xBC, 0xA2, 0x00, 0xE7, 0x85, 0xAE, 0x00, 0xE7,
2327
  0x88, 0xAB, 0x00, 0xE7, 0x90, 0xA2, 0x00, 0xE7, 0xA2, 0x91, 0x00, 0xE7, 0xA5, 0x89, 0x00, 0xE7,
2328
  0xA5, 0x88, 0x00, 0xE7, 0xA5, 0x90, 0x00, 0xE7, 0xA5, 0x96, 0x00, 0xE7, 0xA6, 0x8D, 0x00, 0xE7,
2329
  0xA6, 0x8E, 0x00, 0xE7, 0xA9, 0x80, 0x00, 0xE7, 0xAA, 0x81, 0x00, 0xE7, 0xAF, 0x80, 0x00, 0xE7,
2330
  0xB8, 0x89, 0x00, 0xE7, 0xB9, 0x81, 0x00, 0xE7, 0xBD, 0xB2, 0x00, 0xE8, 0x80, 0x85, 0x00, 0xE8,
2331
  0x87, 0xAD, 0x00, 0xE8, 0x89, 0xB9, 0x00, 0xE8, 0x91, 0x97, 0x00, 0xE8, 0xA4, 0x90, 0x00, 0xE8,
2332
  0xA6, 0x96, 0x00, 0xE8, 0xAC, 0x81, 0x00, 0xE8, 0xAC, 0xB9, 0x00, 0xE8, 0xB3, 0x93, 0x00, 0xE8,
2333
  0xB4, 0x88, 0x00, 0xE8, 0xBE, 0xB6, 0x00, 0xE9, 0x9B, 0xA3, 0x00, 0xE9, 0x9F, 0xBF, 0x00, 0xE9,
2334
  0xA0, 0xBB, 0x00, 0xE6, 0x81, 0xB5, 0x00, 0xF0, 0xA4, 0x8B, 0xAE, 0x00, 0xE8, 0x88, 0x98, 0x00,
2335
  0xE4, 0xB8, 0xA6, 0x00, 0xE5, 0x86, 0xB5, 0x00, 0xE5, 0x85, 0xA8, 0x00, 0xE4, 0xBE, 0x80, 0x00,
2336
  0xE5, 0x85, 0x85, 0x00, 0xE5, 0x86, 0x80, 0x00, 0xE5, 0x8B, 0x87, 0x00, 0xE5, 0x8B, 0xBA, 0x00,
2337
  0xE5, 0x95, 0x95, 0x00, 0xE5, 0x96, 0x99, 0x00, 0xE5, 0x97, 0xA2, 0x00, 0xE5, 0xA2, 0xB3, 0x00,
2338
  0xE5, 0xA5, 0x84, 0x00, 0xE5, 0xA5, 0x94, 0x00, 0xE5, 0xA9, 0xA2, 0x00, 0xE5, 0xAC, 0xA8, 0x00,
2339
  0xE5, 0xBB, 0x92, 0x00, 0xE5, 0xBB, 0x99, 0x00, 0xE5, 0xBD, 0xA9, 0x00, 0xE5, 0xBE, 0xAD, 0x00,
2340
  0xE6, 0x83, 0x98, 0x00, 0xE6, 0x85, 0x8E, 0x00, 0xE6, 0x84, 0x88, 0x00, 0xE6, 0x85, 0xA0, 0x00,
2341
  0xE6, 0x88, 0xB4, 0x00, 0xE6, 0x8F, 0x84, 0x00, 0xE6, 0x90, 0x9C, 0x00, 0xE6, 0x91, 0x92, 0x00,
2342
  0xE6, 0x95, 0x96, 0x00, 0xE6, 0x9C, 0x9B, 0x00, 0xE6, 0x9D, 0x96, 0x00, 0xE6, 0xBB, 0x9B, 0x00,
2343
  0xE6, 0xBB, 0x8B, 0x00, 0xE7, 0x80, 0x9E, 0x00, 0xE7, 0x9E, 0xA7, 0x00, 0xE7, 0x88, 0xB5, 0x00,
2344
  0xE7, 0x8A, 0xAF, 0x00, 0xE7, 0x91, 0xB1, 0x00, 0xE7, 0x94, 0x86, 0x00, 0xE7, 0x94, 0xBB, 0x00,
2345
  0xE7, 0x98, 0x9D, 0x00, 0xE7, 0x98, 0x9F, 0x00, 0xE7, 0x9B, 0x9B, 0x00, 0xE7, 0x9B, 0xB4, 0x00,
2346
  0xE7, 0x9D, 0x8A, 0x00, 0xE7, 0x9D, 0x80, 0x00, 0xE7, 0xA3, 0x8C, 0x00, 0xE7, 0xAA, 0xB1, 0x00,
2347
  0xE7, 0xB1, 0xBB, 0x00, 0xE7, 0xB5, 0x9B, 0x00, 0xE7, 0xBC, 0xBE, 0x00, 0xE8, 0x8D, 0x92, 0x00,
2348
  0xE8, 0x8F, 0xAF, 0x00, 0xE8, 0x9D, 0xB9, 0x00, 0xE8, 0xA5, 0x81, 0x00, 0xE8, 0xA6, 0x86, 0x00,
2349
  0xE8, 0xAA, 0xBF, 0x00, 0xE8, 0xAB, 0x8B, 0x00, 0xE8, 0xAB, 0xAD, 0x00, 0xE8, 0xAE, 0x8A, 0x00,
2350
  0xE8, 0xBC, 0xB8, 0x00, 0xE9, 0x81, 0xB2, 0x00, 0xE9, 0x86, 0x99, 0x00, 0xE9, 0x89, 0xB6, 0x00,
2351
  0xE9, 0x99, 0xBC, 0x00, 0xE9, 0x9F, 0x9B, 0x00, 0xE9, 0xA0, 0x8B, 0x00, 0xE9, 0xAC, 0x92, 0x00,
2352
  0xF0, 0xA2, 0xA1, 0x8A, 0x00, 0xF0, 0xA2, 0xA1, 0x84, 0x00, 0xF0, 0xA3, 0x8F, 0x95, 0x00, 0xE3,
2353
  0xAE, 0x9D, 0x00, 0xE4, 0x80, 0x98, 0x00, 0xE4, 0x80, 0xB9, 0x00, 0xF0, 0xA5, 0x89, 0x89, 0x00,
2354
  0xF0, 0xA5, 0xB3, 0x90, 0x00, 0xF0, 0xA7, 0xBB, 0x93, 0x00, 0xE9, 0xBD, 0x83, 0x00, 0xE9, 0xBE,
2355
  0x8E, 0x00, 0x66, 0x66, 0x00, 0x66, 0x69, 0x00, 0x66, 0x6C, 0x00, 0x66, 0x66, 0x69, 0x00, 0x66,
2356
  0x66, 0x6C, 0x00, 0x73, 0x74, 0x00, 0xD5, 0xB4, 0xD5, 0xB6, 0x00, 0xD5, 0xB4, 0xD5, 0xA5, 0x00,
2357
  0xD5, 0xB4, 0xD5, 0xAB, 0x00, 0xD5, 0xBE, 0xD5, 0xB6, 0x00, 0xD5, 0xB4, 0xD5, 0xAD, 0x00, 0xD7,
2358
  0x99, 0xD6, 0xB4, 0x00, 0xD7, 0xB2, 0xD6, 0xB7, 0x00, 0xD7, 0xA2, 0x00, 0xD7, 0x94, 0x00, 0xD7,
2359
  0x9B, 0x00, 0xD7, 0x9C, 0x00, 0xD7, 0x9D, 0x00, 0xD7, 0xA8, 0x00, 0xD7, 0xAA, 0x00, 0xD7, 0xA9,
2360
  0xD7, 0x81, 0x00, 0xD7, 0xA9, 0xD7, 0x82, 0x00, 0xD7, 0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0x00, 0xD7,
2361
  0xA9, 0xD6, 0xBC, 0xD7, 0x82, 0x00, 0xD7, 0x90, 0xD6, 0xB7, 0x00, 0xD7, 0x90, 0xD6, 0xB8, 0x00,
2362
  0xD7, 0x90, 0xD6, 0xBC, 0x00, 0xD7, 0x91, 0xD6, 0xBC, 0x00, 0xD7, 0x92, 0xD6, 0xBC, 0x00, 0xD7,
2363
  0x93, 0xD6, 0xBC, 0x00, 0xD7, 0x94, 0xD6, 0xBC, 0x00, 0xD7, 0x95, 0xD6, 0xBC, 0x00, 0xD7, 0x96,
2364
  0xD6, 0xBC, 0x00, 0xD7, 0x98, 0xD6, 0xBC, 0x00, 0xD7, 0x99, 0xD6, 0xBC, 0x00, 0xD7, 0x9A, 0xD6,
2365
  0xBC, 0x00, 0xD7, 0x9B, 0xD6, 0xBC, 0x00, 0xD7, 0x9C, 0xD6, 0xBC, 0x00, 0xD7, 0x9E, 0xD6, 0xBC,
2366
  0x00, 0xD7, 0xA0, 0xD6, 0xBC, 0x00, 0xD7, 0xA1, 0xD6, 0xBC, 0x00, 0xD7, 0xA3, 0xD6, 0xBC, 0x00,
2367
  0xD7, 0xA4, 0xD6, 0xBC, 0x00, 0xD7, 0xA6, 0xD6, 0xBC, 0x00, 0xD7, 0xA7, 0xD6, 0xBC, 0x00, 0xD7,
2368
  0xA8, 0xD6, 0xBC, 0x00, 0xD7, 0xA9, 0xD6, 0xBC, 0x00, 0xD7, 0xAA, 0xD6, 0xBC, 0x00, 0xD7, 0x95,
2369
  0xD6, 0xB9, 0x00, 0xD7, 0x91, 0xD6, 0xBF, 0x00, 0xD7, 0x9B, 0xD6, 0xBF, 0x00, 0xD7, 0xA4, 0xD6,
2370
  0xBF, 0x00, 0xD7, 0x90, 0xD7, 0x9C, 0x00, 0xD9, 0xB1, 0x00, 0xD9, 0xBB, 0x00, 0xD9, 0xBE, 0x00,
2371
  0xDA, 0x80, 0x00, 0xD9, 0xBA, 0x00, 0xD9, 0xBF, 0x00, 0xD9, 0xB9, 0x00, 0xDA, 0xA4, 0x00, 0xDA,
2372
  0xA6, 0x00, 0xDA, 0x84, 0x00, 0xDA, 0x83, 0x00, 0xDA, 0x86, 0x00, 0xDA, 0x87, 0x00, 0xDA, 0x8D,
2373
  0x00, 0xDA, 0x8C, 0x00, 0xDA, 0x8E, 0x00, 0xDA, 0x88, 0x00, 0xDA, 0x98, 0x00, 0xDA, 0x91, 0x00,
2374
  0xDA, 0xA9, 0x00, 0xDA, 0xAF, 0x00, 0xDA, 0xB3, 0x00, 0xDA, 0xB1, 0x00, 0xDA, 0xBA, 0x00, 0xDA,
2375
  0xBB, 0x00, 0xDB, 0x80, 0x00, 0xDB, 0x81, 0x00, 0xDA, 0xBE, 0x00, 0xDB, 0x92, 0x00, 0xDB, 0x93,
2376
  0x00, 0xDA, 0xAD, 0x00, 0xDB, 0x87, 0x00, 0xDB, 0x86, 0x00, 0xDB, 0x88, 0x00, 0xDB, 0x8B, 0x00,
2377
  0xDB, 0x85, 0x00, 0xDB, 0x89, 0x00, 0xDB, 0x90, 0x00, 0xD9, 0x89, 0x00, 0xD8, 0xA6, 0xD8, 0xA7,
2378
  0x00, 0xD8, 0xA6, 0xDB, 0x95, 0x00, 0xD8, 0xA6, 0xD9, 0x88, 0x00, 0xD8, 0xA6, 0xDB, 0x87, 0x00,
2379
  0xD8, 0xA6, 0xDB, 0x86, 0x00, 0xD8, 0xA6, 0xDB, 0x88, 0x00, 0xD8, 0xA6, 0xDB, 0x90, 0x00, 0xD8,
2380
  0xA6, 0xD9, 0x89, 0x00, 0xDB, 0x8C, 0x00, 0xD8, 0xA6, 0xD8, 0xAC, 0x00, 0xD8, 0xA6, 0xD8, 0xAD,
2381
  0x00, 0xD8, 0xA6, 0xD9, 0x85, 0x00, 0xD8, 0xA6, 0xD9, 0x8A, 0x00, 0xD8, 0xA8, 0xD8, 0xAC, 0x00,
2382
  0xD8, 0xA8, 0xD8, 0xAD, 0x00, 0xD8, 0xA8, 0xD8, 0xAE, 0x00, 0xD8, 0xA8, 0xD9, 0x85, 0x00, 0xD8,
2383
  0xA8, 0xD9, 0x89, 0x00, 0xD8, 0xA8, 0xD9, 0x8A, 0x00, 0xD8, 0xAA, 0xD8, 0xAC, 0x00, 0xD8, 0xAA,
2384
  0xD8, 0xAD, 0x00, 0xD8, 0xAA, 0xD8, 0xAE, 0x00, 0xD8, 0xAA, 0xD9, 0x85, 0x00, 0xD8, 0xAA, 0xD9,
2385
  0x89, 0x00, 0xD8, 0xAA, 0xD9, 0x8A, 0x00, 0xD8, 0xAB, 0xD8, 0xAC, 0x00, 0xD8, 0xAB, 0xD9, 0x85,
2386
  0x00, 0xD8, 0xAB, 0xD9, 0x89, 0x00, 0xD8, 0xAB, 0xD9, 0x8A, 0x00, 0xD8, 0xAC, 0xD8, 0xAD, 0x00,
2387
  0xD8, 0xAC, 0xD9, 0x85, 0x00, 0xD8, 0xAD, 0xD8, 0xAC, 0x00, 0xD8, 0xAD, 0xD9, 0x85, 0x00, 0xD8,
2388
  0xAE, 0xD8, 0xAC, 0x00, 0xD8, 0xAE, 0xD8, 0xAD, 0x00, 0xD8, 0xAE, 0xD9, 0x85, 0x00, 0xD8, 0xB3,
2389
  0xD8, 0xAC, 0x00, 0xD8, 0xB3, 0xD8, 0xAD, 0x00, 0xD8, 0xB3, 0xD8, 0xAE, 0x00, 0xD8, 0xB3, 0xD9,
2390
  0x85, 0x00, 0xD8, 0xB5, 0xD8, 0xAD, 0x00, 0xD8, 0xB5, 0xD9, 0x85, 0x00, 0xD8, 0xB6, 0xD8, 0xAC,
2391
  0x00, 0xD8, 0xB6, 0xD8, 0xAD, 0x00, 0xD8, 0xB6, 0xD8, 0xAE, 0x00, 0xD8, 0xB6, 0xD9, 0x85, 0x00,
2392
  0xD8, 0xB7, 0xD8, 0xAD, 0x00, 0xD8, 0xB7, 0xD9, 0x85, 0x00, 0xD8, 0xB8, 0xD9, 0x85, 0x00, 0xD8,
2393
  0xB9, 0xD8, 0xAC, 0x00, 0xD8, 0xB9, 0xD9, 0x85, 0x00, 0xD8, 0xBA, 0xD8, 0xAC, 0x00, 0xD8, 0xBA,
2394
  0xD9, 0x85, 0x00, 0xD9, 0x81, 0xD8, 0xAC, 0x00, 0xD9, 0x81, 0xD8, 0xAD, 0x00, 0xD9, 0x81, 0xD8,
2395
  0xAE, 0x00, 0xD9, 0x81, 0xD9, 0x85, 0x00, 0xD9, 0x81, 0xD9, 0x89, 0x00, 0xD9, 0x81, 0xD9, 0x8A,
2396
  0x00, 0xD9, 0x82, 0xD8, 0xAD, 0x00, 0xD9, 0x82, 0xD9, 0x85, 0x00, 0xD9, 0x82, 0xD9, 0x89, 0x00,
2397
  0xD9, 0x82, 0xD9, 0x8A, 0x00, 0xD9, 0x83, 0xD8, 0xA7, 0x00, 0xD9, 0x83, 0xD8, 0xAC, 0x00, 0xD9,
2398
  0x83, 0xD8, 0xAD, 0x00, 0xD9, 0x83, 0xD8, 0xAE, 0x00, 0xD9, 0x83, 0xD9, 0x84, 0x00, 0xD9, 0x83,
2399
  0xD9, 0x85, 0x00, 0xD9, 0x83, 0xD9, 0x89, 0x00, 0xD9, 0x83, 0xD9, 0x8A, 0x00, 0xD9, 0x84, 0xD8,
2400
  0xAC, 0x00, 0xD9, 0x84, 0xD8, 0xAD, 0x00, 0xD9, 0x84, 0xD8, 0xAE, 0x00, 0xD9, 0x84, 0xD9, 0x85,
2401
  0x00, 0xD9, 0x84, 0xD9, 0x89, 0x00, 0xD9, 0x84, 0xD9, 0x8A, 0x00, 0xD9, 0x85, 0xD8, 0xAC, 0x00,
2402
  0xD9, 0x85, 0xD8, 0xAD, 0x00, 0xD9, 0x85, 0xD8, 0xAE, 0x00, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD9,
2403
  0x85, 0xD9, 0x89, 0x00, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD9, 0x86, 0xD8, 0xAC, 0x00, 0xD9, 0x86,
2404
  0xD8, 0xAD, 0x00, 0xD9, 0x86, 0xD8, 0xAE, 0x00, 0xD9, 0x86, 0xD9, 0x85, 0x00, 0xD9, 0x86, 0xD9,
2405
  0x89, 0x00, 0xD9, 0x86, 0xD9, 0x8A, 0x00, 0xD9, 0x87, 0xD8, 0xAC, 0x00, 0xD9, 0x87, 0xD9, 0x85,
2406
  0x00, 0xD9, 0x87, 0xD9, 0x89, 0x00, 0xD9, 0x87, 0xD9, 0x8A, 0x00, 0xD9, 0x8A, 0xD8, 0xAC, 0x00,
2407
  0xD9, 0x8A, 0xD8, 0xAD, 0x00, 0xD9, 0x8A, 0xD8, 0xAE, 0x00, 0xD9, 0x8A, 0xD9, 0x85, 0x00, 0xD9,
2408
  0x8A, 0xD9, 0x89, 0x00, 0xD9, 0x8A, 0xD9, 0x8A, 0x00, 0xD8, 0xB0, 0xD9, 0xB0, 0x00, 0xD8, 0xB1,
2409
  0xD9, 0xB0, 0x00, 0xD9, 0x89, 0xD9, 0xB0, 0x00, 0x20, 0xD9, 0x8C, 0xD9, 0x91, 0x00, 0x20, 0xD9,
2410
  0x8D, 0xD9, 0x91, 0x00, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x00, 0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x00,
2411
  0x20, 0xD9, 0x90, 0xD9, 0x91, 0x00, 0x20, 0xD9, 0x91, 0xD9, 0xB0, 0x00, 0xD8, 0xA6, 0xD8, 0xB1,
2412
  0x00, 0xD8, 0xA6, 0xD8, 0xB2, 0x00, 0xD8, 0xA6, 0xD9, 0x86, 0x00, 0xD8, 0xA8, 0xD8, 0xB1, 0x00,
2413
  0xD8, 0xA8, 0xD8, 0xB2, 0x00, 0xD8, 0xA8, 0xD9, 0x86, 0x00, 0xD8, 0xAA, 0xD8, 0xB1, 0x00, 0xD8,
2414
  0xAA, 0xD8, 0xB2, 0x00, 0xD8, 0xAA, 0xD9, 0x86, 0x00, 0xD8, 0xAB, 0xD8, 0xB1, 0x00, 0xD8, 0xAB,
2415
  0xD8, 0xB2, 0x00, 0xD8, 0xAB, 0xD9, 0x86, 0x00, 0xD9, 0x85, 0xD8, 0xA7, 0x00, 0xD9, 0x86, 0xD8,
2416
  0xB1, 0x00, 0xD9, 0x86, 0xD8, 0xB2, 0x00, 0xD9, 0x86, 0xD9, 0x86, 0x00, 0xD9, 0x8A, 0xD8, 0xB1,
2417
  0x00, 0xD9, 0x8A, 0xD8, 0xB2, 0x00, 0xD9, 0x8A, 0xD9, 0x86, 0x00, 0xD8, 0xA6, 0xD8, 0xAE, 0x00,
2418
  0xD8, 0xA6, 0xD9, 0x87, 0x00, 0xD8, 0xA8, 0xD9, 0x87, 0x00, 0xD8, 0xAA, 0xD9, 0x87, 0x00, 0xD8,
2419
  0xB5, 0xD8, 0xAE, 0x00, 0xD9, 0x84, 0xD9, 0x87, 0x00, 0xD9, 0x86, 0xD9, 0x87, 0x00, 0xD9, 0x87,
2420
  0xD9, 0xB0, 0x00, 0xD9, 0x8A, 0xD9, 0x87, 0x00, 0xD8, 0xAB, 0xD9, 0x87, 0x00, 0xD8, 0xB3, 0xD9,
2421
  0x87, 0x00, 0xD8, 0xB4, 0xD9, 0x85, 0x00, 0xD8, 0xB4, 0xD9, 0x87, 0x00, 0xD9, 0x80, 0xD9, 0x8E,
2422
  0xD9, 0x91, 0x00, 0xD9, 0x80, 0xD9, 0x8F, 0xD9, 0x91, 0x00, 0xD9, 0x80, 0xD9, 0x90, 0xD9, 0x91,
2423
  0x00, 0xD8, 0xB7, 0xD9, 0x89, 0x00, 0xD8, 0xB7, 0xD9, 0x8A, 0x00, 0xD8, 0xB9, 0xD9, 0x89, 0x00,
2424
  0xD8, 0xB9, 0xD9, 0x8A, 0x00, 0xD8, 0xBA, 0xD9, 0x89, 0x00, 0xD8, 0xBA, 0xD9, 0x8A, 0x00, 0xD8,
2425
  0xB3, 0xD9, 0x89, 0x00, 0xD8, 0xB3, 0xD9, 0x8A, 0x00, 0xD8, 0xB4, 0xD9, 0x89, 0x00, 0xD8, 0xB4,
2426
  0xD9, 0x8A, 0x00, 0xD8, 0xAD, 0xD9, 0x89, 0x00, 0xD8, 0xAD, 0xD9, 0x8A, 0x00, 0xD8, 0xAC, 0xD9,
2427
  0x89, 0x00, 0xD8, 0xAC, 0xD9, 0x8A, 0x00, 0xD8, 0xAE, 0xD9, 0x89, 0x00, 0xD8, 0xAE, 0xD9, 0x8A,
2428
  0x00, 0xD8, 0xB5, 0xD9, 0x89, 0x00, 0xD8, 0xB5, 0xD9, 0x8A, 0x00, 0xD8, 0xB6, 0xD9, 0x89, 0x00,
2429
  0xD8, 0xB6, 0xD9, 0x8A, 0x00, 0xD8, 0xB4, 0xD8, 0xAC, 0x00, 0xD8, 0xB4, 0xD8, 0xAD, 0x00, 0xD8,
2430
  0xB4, 0xD8, 0xAE, 0x00, 0xD8, 0xB4, 0xD8, 0xB1, 0x00, 0xD8, 0xB3, 0xD8, 0xB1, 0x00, 0xD8, 0xB5,
2431
  0xD8, 0xB1, 0x00, 0xD8, 0xB6, 0xD8, 0xB1, 0x00, 0xD8, 0xA7, 0xD9, 0x8B, 0x00, 0xD8, 0xAA, 0xD8,
2432
  0xAC, 0xD9, 0x85, 0x00, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0x00, 0xD8, 0xAA, 0xD8, 0xAD, 0xD9,
2433
  0x85, 0x00, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x85, 0x00, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, 0x00,
2434
  0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0x00, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAE, 0x00, 0xD8, 0xAC,
2435
  0xD9, 0x85, 0xD8, 0xAD, 0x00, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD8, 0xAD, 0xD9, 0x85,
2436
  0xD9, 0x89, 0x00, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xAC, 0x00, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8, 0xAD,
2437
  0x00, 0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89, 0x00, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAD, 0x00, 0xD8,
2438
  0xB3, 0xD9, 0x85, 0xD8, 0xAC, 0x00, 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD8, 0xB5, 0xD8,
2439
  0xAD, 0xD8, 0xAD, 0x00, 0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9,
2440
  0x85, 0x00, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9, 0x8A, 0x00, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0x00,
2441
  0xD8, 0xB4, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0x00, 0xD8, 0xB6,
2442
  0xD8, 0xAE, 0xD9, 0x85, 0x00, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0x00, 0xD8, 0xB7, 0xD9, 0x85,
2443
  0xD9, 0x85, 0x00, 0xD8, 0xB7, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85,
2444
  0x00, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x89, 0x00, 0xD8,
2445
  0xBA, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD8, 0xBA, 0xD9,
2446
  0x85, 0xD9, 0x89, 0x00, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x85, 0x00, 0xD9, 0x82, 0xD9, 0x85, 0xD8,
2447
  0xAD, 0x00, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x85, 0x00,
2448
  0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x8A, 0x00, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0x00, 0xD9, 0x84,
2449
  0xD8, 0xAC, 0xD8, 0xAC, 0x00, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0x00, 0xD9, 0x84, 0xD9, 0x85,
2450
  0xD8, 0xAD, 0x00, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0x00, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85,
2451
  0x00, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x8A, 0x00, 0xD9, 0x85, 0xD8, 0xAC, 0xD8, 0xAD, 0x00, 0xD9,
2452
  0x85, 0xD8, 0xAC, 0xD9, 0x85, 0x00, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0x00, 0xD9, 0x85, 0xD8,
2453
  0xAE, 0xD9, 0x85, 0x00, 0xD9, 0x85, 0xD8, 0xAC, 0xD8, 0xAE, 0x00, 0xD9, 0x87, 0xD9, 0x85, 0xD8,
2454
  0xAC, 0x00, 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x85, 0x00,
2455
  0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x89, 0x00, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0x00, 0xD9, 0x86,
2456
  0xD8, 0xAC, 0xD9, 0x89, 0x00, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD9, 0x86, 0xD9, 0x85,
2457
  0xD9, 0x89, 0x00, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD8, 0xA8, 0xD8, 0xAE, 0xD9, 0x8A,
2458
  0x00, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x8A, 0x00, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0x00, 0xD8,
2459
  0xAA, 0xD8, 0xAE, 0xD9, 0x8A, 0x00, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x89, 0x00, 0xD8, 0xAA, 0xD9,
2460
  0x85, 0xD9, 0x8A, 0x00, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0x00, 0xD8, 0xAC, 0xD9, 0x85, 0xD9,
2461
  0x8A, 0x00, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x89, 0x00, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, 0x00,
2462
  0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0x00, 0xD8, 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, 0x00, 0xD8, 0xB4,
2463
  0xD8, 0xAD, 0xD9, 0x8A, 0x00, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, 0x00, 0xD9, 0x84, 0xD8, 0xAC,
2464
  0xD9, 0x8A, 0x00, 0xD9, 0x84, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD9, 0x8A, 0xD8, 0xAD, 0xD9, 0x8A,
2465
  0x00, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, 0x00, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD9,
2466
  0x85, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD9, 0x86, 0xD8,
2467
  0xAD, 0xD9, 0x8A, 0x00, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD9, 0x83, 0xD9, 0x85, 0xD9,
2468
  0x8A, 0x00, 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0x00, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x8A, 0x00,
2469
  0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x85, 0x00, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, 0x00, 0xD8, 0xAC,
2470
  0xD8, 0xAD, 0xD9, 0x8A, 0x00, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A, 0x00, 0xD9, 0x85, 0xD8, 0xAC,
2471
  0xD9, 0x8A, 0x00, 0xD9, 0x81, 0xD9, 0x85, 0xD9, 0x8A, 0x00, 0xD8, 0xA8, 0xD8, 0xAD, 0xD9, 0x8A,
2472
  0x00, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x8A, 0x00, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x8A, 0x00, 0xD8,
2473
  0xB5, 0xD9, 0x84, 0xDB, 0x92, 0x00, 0xD9, 0x82, 0xD9, 0x84, 0xDB, 0x92, 0x00, 0xD8, 0xA7, 0xD9,
2474
  0x84, 0xD9, 0x84, 0xD9, 0x87, 0x00, 0xD8, 0xA7, 0xD9, 0x83, 0xD8, 0xA8, 0xD8, 0xB1, 0x00, 0xD9,
2475
  0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAF, 0x00, 0xD8, 0xB5, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x85,
2476
  0x00, 0xD8, 0xB1, 0xD8, 0xB3, 0xD9, 0x88, 0xD9, 0x84, 0x00, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A,
2477
  0xD9, 0x87, 0x00, 0xD9, 0x88, 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x00, 0xD8, 0xB5, 0xD9, 0x84,
2478
  0xD9, 0x89, 0x00, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89, 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84,
2479
  0xD9, 0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3,
2480
  0xD9, 0x84, 0xD9, 0x85, 0x00, 0xD8, 0xAC, 0xD9, 0x84, 0x20, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7,
2481
  0xD9, 0x84, 0xD9, 0x87, 0x00, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, 0xD9, 0x84, 0x00, 0x2C, 0x00,
2482
  0xE3, 0x80, 0x81, 0x00, 0x3A, 0x00, 0x21, 0x00, 0x3F, 0x00, 0xE3, 0x80, 0x96, 0x00, 0xE3, 0x80,
2483
  0x97, 0x00, 0xE2, 0x80, 0x94, 0x00, 0xE2, 0x80, 0x93, 0x00, 0x5F, 0x00, 0x7B, 0x00, 0x7D, 0x00,
2484
  0xE3, 0x80, 0x94, 0x00, 0xE3, 0x80, 0x95, 0x00, 0xE3, 0x80, 0x90, 0x00, 0xE3, 0x80, 0x91, 0x00,
2485
  0xE3, 0x80, 0x8A, 0x00, 0xE3, 0x80, 0x8B, 0x00, 0xE3, 0x80, 0x8C, 0x00, 0xE3, 0x80, 0x8D, 0x00,
2486
  0xE3, 0x80, 0x8E, 0x00, 0xE3, 0x80, 0x8F, 0x00, 0x5B, 0x00, 0x5D, 0x00, 0x23, 0x00, 0x26, 0x00,
2487
  0x2A, 0x00, 0x2D, 0x00, 0x3C, 0x00, 0x3E, 0x00, 0x5C, 0x00, 0x24, 0x00, 0x25, 0x00, 0x40, 0x00,
2488
  0x20, 0xD9, 0x8B, 0x00, 0xD9, 0x80, 0xD9, 0x8B, 0x00, 0x20, 0xD9, 0x8C, 0x00, 0x20, 0xD9, 0x8D,
2489
  0x00, 0x20, 0xD9, 0x8E, 0x00, 0xD9, 0x80, 0xD9, 0x8E, 0x00, 0x20, 0xD9, 0x8F, 0x00, 0xD9, 0x80,
2490
  0xD9, 0x8F, 0x00, 0x20, 0xD9, 0x90, 0x00, 0xD9, 0x80, 0xD9, 0x90, 0x00, 0x20, 0xD9, 0x91, 0x00,
2491
  0xD9, 0x80, 0xD9, 0x91, 0x00, 0x20, 0xD9, 0x92, 0x00, 0xD9, 0x80, 0xD9, 0x92, 0x00, 0xD8, 0xA1,
2492
  0x00, 0xD8, 0xA2, 0x00, 0xD8, 0xA3, 0x00, 0xD8, 0xA4, 0x00, 0xD8, 0xA5, 0x00, 0xD8, 0xA6, 0x00,
2493
  0xD8, 0xA7, 0x00, 0xD8, 0xA8, 0x00, 0xD8, 0xA9, 0x00, 0xD8, 0xAA, 0x00, 0xD8, 0xAB, 0x00, 0xD8,
2494
  0xAC, 0x00, 0xD8, 0xAD, 0x00, 0xD8, 0xAE, 0x00, 0xD8, 0xAF, 0x00, 0xD8, 0xB0, 0x00, 0xD8, 0xB1,
2495
  0x00, 0xD8, 0xB2, 0x00, 0xD8, 0xB3, 0x00, 0xD8, 0xB4, 0x00, 0xD8, 0xB5, 0x00, 0xD8, 0xB6, 0x00,
2496
  0xD8, 0xB7, 0x00, 0xD8, 0xB8, 0x00, 0xD8, 0xB9, 0x00, 0xD8, 0xBA, 0x00, 0xD9, 0x81, 0x00, 0xD9,
2497
  0x82, 0x00, 0xD9, 0x83, 0x00, 0xD9, 0x84, 0x00, 0xD9, 0x85, 0x00, 0xD9, 0x86, 0x00, 0xD9, 0x87,
2498
  0x00, 0xD9, 0x88, 0x00, 0xD9, 0x8A, 0x00, 0xD9, 0x84, 0xD8, 0xA2, 0x00, 0xD9, 0x84, 0xD8, 0xA3,
2499
  0x00, 0xD9, 0x84, 0xD8, 0xA5, 0x00, 0xD9, 0x84, 0xD8, 0xA7, 0x00, 0x22, 0x00, 0x27, 0x00, 0x2F,
2500
  0x00, 0x5E, 0x00, 0x7C, 0x00, 0x7E, 0x00, 0xE2, 0xA6, 0x85, 0x00, 0xE2, 0xA6, 0x86, 0x00, 0xE3,
2501
  0x83, 0xBB, 0x00, 0xE3, 0x82, 0xA1, 0x00, 0xE3, 0x82, 0xA3, 0x00, 0xE3, 0x82, 0xA5, 0x00, 0xE3,
2502
  0x82, 0xA7, 0x00, 0xE3, 0x82, 0xA9, 0x00, 0xE3, 0x83, 0xA3, 0x00, 0xE3, 0x83, 0xA5, 0x00, 0xE3,
2503
  0x83, 0xA7, 0x00, 0xE3, 0x83, 0x83, 0x00, 0xE3, 0x83, 0xBC, 0x00, 0xE3, 0x83, 0xB3, 0x00, 0xE3,
2504
  0x82, 0x99, 0x00, 0xE3, 0x82, 0x9A, 0x00, 0xC2, 0xA2, 0x00, 0xC2, 0xA3, 0x00, 0xC2, 0xAC, 0x00,
2505
  0xC2, 0xA6, 0x00, 0xC2, 0xA5, 0x00, 0xE2, 0x82, 0xA9, 0x00, 0xE2, 0x94, 0x82, 0x00, 0xE2, 0x86,
2506
  0x90, 0x00, 0xE2, 0x86, 0x91, 0x00, 0xE2, 0x86, 0x92, 0x00, 0xE2, 0x86, 0x93, 0x00, 0xE2, 0x96,
2507
  0xA0, 0x00, 0xE2, 0x97, 0x8B, 0x00, 0xF0, 0x90, 0x90, 0xA8, 0x00, 0xF0, 0x90, 0x90, 0xA9, 0x00,
2508
  0xF0, 0x90, 0x90, 0xAA, 0x00, 0xF0, 0x90, 0x90, 0xAB, 0x00, 0xF0, 0x90, 0x90, 0xAC, 0x00, 0xF0,
2509
  0x90, 0x90, 0xAD, 0x00, 0xF0, 0x90, 0x90, 0xAE, 0x00, 0xF0, 0x90, 0x90, 0xAF, 0x00, 0xF0, 0x90,
2510
  0x90, 0xB0, 0x00, 0xF0, 0x90, 0x90, 0xB1, 0x00, 0xF0, 0x90, 0x90, 0xB2, 0x00, 0xF0, 0x90, 0x90,
2511
  0xB3, 0x00, 0xF0, 0x90, 0x90, 0xB4, 0x00, 0xF0, 0x90, 0x90, 0xB5, 0x00, 0xF0, 0x90, 0x90, 0xB6,
2512
  0x00, 0xF0, 0x90, 0x90, 0xB7, 0x00, 0xF0, 0x90, 0x90, 0xB8, 0x00, 0xF0, 0x90, 0x90, 0xB9, 0x00,
2513
  0xF0, 0x90, 0x90, 0xBA, 0x00, 0xF0, 0x90, 0x90, 0xBB, 0x00, 0xF0, 0x90, 0x90, 0xBC, 0x00, 0xF0,
2514
  0x90, 0x90, 0xBD, 0x00, 0xF0, 0x90, 0x90, 0xBE, 0x00, 0xF0, 0x90, 0x90, 0xBF, 0x00, 0xF0, 0x90,
2515
  0x91, 0x80, 0x00, 0xF0, 0x90, 0x91, 0x81, 0x00, 0xF0, 0x90, 0x91, 0x82, 0x00, 0xF0, 0x90, 0x91,
2516
  0x83, 0x00, 0xF0, 0x90, 0x91, 0x84, 0x00, 0xF0, 0x90, 0x91, 0x85, 0x00, 0xF0, 0x90, 0x91, 0x86,
2517
  0x00, 0xF0, 0x90, 0x91, 0x87, 0x00, 0xF0, 0x90, 0x91, 0x88, 0x00, 0xF0, 0x90, 0x91, 0x89, 0x00,
2518
  0xF0, 0x90, 0x91, 0x8A, 0x00, 0xF0, 0x90, 0x91, 0x8B, 0x00, 0xF0, 0x90, 0x91, 0x8C, 0x00, 0xF0,
2519
  0x90, 0x91, 0x8D, 0x00, 0xF0, 0x90, 0x91, 0x8E, 0x00, 0xF0, 0x90, 0x91, 0x8F, 0x00, 0xF0, 0x90,
2520
  0x93, 0x98, 0x00, 0xF0, 0x90, 0x93, 0x99, 0x00, 0xF0, 0x90, 0x93, 0x9A, 0x00, 0xF0, 0x90, 0x93,
2521
  0x9B, 0x00, 0xF0, 0x90, 0x93, 0x9C, 0x00, 0xF0, 0x90, 0x93, 0x9D, 0x00, 0xF0, 0x90, 0x93, 0x9E,
2522
  0x00, 0xF0, 0x90, 0x93, 0x9F, 0x00, 0xF0, 0x90, 0x93, 0xA0, 0x00, 0xF0, 0x90, 0x93, 0xA1, 0x00,
2523
  0xF0, 0x90, 0x93, 0xA2, 0x00, 0xF0, 0x90, 0x93, 0xA3, 0x00, 0xF0, 0x90, 0x93, 0xA4, 0x00, 0xF0,
2524
  0x90, 0x93, 0xA5, 0x00, 0xF0, 0x90, 0x93, 0xA6, 0x00, 0xF0, 0x90, 0x93, 0xA7, 0x00, 0xF0, 0x90,
2525
  0x93, 0xA8, 0x00, 0xF0, 0x90, 0x93, 0xA9, 0x00, 0xF0, 0x90, 0x93, 0xAA, 0x00, 0xF0, 0x90, 0x93,
2526
  0xAB, 0x00, 0xF0, 0x90, 0x93, 0xAC, 0x00, 0xF0, 0x90, 0x93, 0xAD, 0x00, 0xF0, 0x90, 0x93, 0xAE,
2527
  0x00, 0xF0, 0x90, 0x93, 0xAF, 0x00, 0xF0, 0x90, 0x93, 0xB0, 0x00, 0xF0, 0x90, 0x93, 0xB1, 0x00,
2528
  0xF0, 0x90, 0x93, 0xB2, 0x00, 0xF0, 0x90, 0x93, 0xB3, 0x00, 0xF0, 0x90, 0x93, 0xB4, 0x00, 0xF0,
2529
  0x90, 0x93, 0xB5, 0x00, 0xF0, 0x90, 0x93, 0xB6, 0x00, 0xF0, 0x90, 0x93, 0xB7, 0x00, 0xF0, 0x90,
2530
  0x93, 0xB8, 0x00, 0xF0, 0x90, 0x93, 0xB9, 0x00, 0xF0, 0x90, 0x93, 0xBA, 0x00, 0xF0, 0x90, 0x93,
2531
  0xBB, 0x00, 0xF0, 0x90, 0x96, 0x97, 0x00, 0xF0, 0x90, 0x96, 0x98, 0x00, 0xF0, 0x90, 0x96, 0x99,
2532
  0x00, 0xF0, 0x90, 0x96, 0x9A, 0x00, 0xF0, 0x90, 0x96, 0x9B, 0x00, 0xF0, 0x90, 0x96, 0x9C, 0x00,
2533
  0xF0, 0x90, 0x96, 0x9D, 0x00, 0xF0, 0x90, 0x96, 0x9E, 0x00, 0xF0, 0x90, 0x96, 0x9F, 0x00, 0xF0,
2534
  0x90, 0x96, 0xA0, 0x00, 0xF0, 0x90, 0x96, 0xA1, 0x00, 0xF0, 0x90, 0x96, 0xA3, 0x00, 0xF0, 0x90,
2535
  0x96, 0xA4, 0x00, 0xF0, 0x90, 0x96, 0xA5, 0x00, 0xF0, 0x90, 0x96, 0xA6, 0x00, 0xF0, 0x90, 0x96,
2536
  0xA7, 0x00, 0xF0, 0x90, 0x96, 0xA8, 0x00, 0xF0, 0x90, 0x96, 0xA9, 0x00, 0xF0, 0x90, 0x96, 0xAA,
2537
  0x00, 0xF0, 0x90, 0x96, 0xAB, 0x00, 0xF0, 0x90, 0x96, 0xAC, 0x00, 0xF0, 0x90, 0x96, 0xAD, 0x00,
2538
  0xF0, 0x90, 0x96, 0xAE, 0x00, 0xF0, 0x90, 0x96, 0xAF, 0x00, 0xF0, 0x90, 0x96, 0xB0, 0x00, 0xF0,
2539
  0x90, 0x96, 0xB1, 0x00, 0xF0, 0x90, 0x96, 0xB3, 0x00, 0xF0, 0x90, 0x96, 0xB4, 0x00, 0xF0, 0x90,
2540
  0x96, 0xB5, 0x00, 0xF0, 0x90, 0x96, 0xB6, 0x00, 0xF0, 0x90, 0x96, 0xB7, 0x00, 0xF0, 0x90, 0x96,
2541
  0xB8, 0x00, 0xF0, 0x90, 0x96, 0xB9, 0x00, 0xF0, 0x90, 0x96, 0xBB, 0x00, 0xF0, 0x90, 0x96, 0xBC,
2542
  0x00, 0xCB, 0x90, 0x00, 0xCB, 0x91, 0x00, 0xCA, 0x99, 0x00, 0xCA, 0xA3, 0x00, 0xEA, 0xAD, 0xA6,
2543
  0x00, 0xCA, 0xA5, 0x00, 0xCA, 0xA4, 0x00, 0xE1, 0xB6, 0x91, 0x00, 0xC9, 0x98, 0x00, 0xC9, 0x9E,
2544
  0x00, 0xCA, 0xA9, 0x00, 0xC9, 0xA2, 0x00, 0xCA, 0x9B, 0x00, 0xCA, 0x9C, 0x00, 0xC9, 0xA7, 0x00,
2545
  0xCA, 0x84, 0x00, 0xCA, 0xAA, 0x00, 0xCA, 0xAB, 0x00, 0xF0, 0x9D, 0xBC, 0x84, 0x00, 0xEA, 0x9E,
2546
  0x8E, 0x00, 0xC9, 0xAE, 0x00, 0xF0, 0x9D, 0xBC, 0x85, 0x00, 0xCA, 0x8E, 0x00, 0xF0, 0x9D, 0xBC,
2547
  0x86, 0x00, 0xC9, 0xB6, 0x00, 0xC9, 0xB7, 0x00, 0xC9, 0xBA, 0x00, 0xF0, 0x9D, 0xBC, 0x88, 0x00,
2548
  0xC9, 0xBE, 0x00, 0xCA, 0xA8, 0x00, 0xCA, 0xA6, 0x00, 0xEA, 0xAD, 0xA7, 0x00, 0xCA, 0xA7, 0x00,
2549
  0xE2, 0xB1, 0xB1, 0x00, 0xCA, 0x8F, 0x00, 0xCA, 0xA1, 0x00, 0xCA, 0xA2, 0x00, 0xCA, 0x98, 0x00,
2550
  0xC7, 0x80, 0x00, 0xC7, 0x81, 0x00, 0xC7, 0x82, 0x00, 0xF0, 0x9D, 0xBC, 0x8A, 0x00, 0xF0, 0x9D,
2551
  0xBC, 0x9E, 0x00, 0xF0, 0x90, 0xB3, 0x80, 0x00, 0xF0, 0x90, 0xB3, 0x81, 0x00, 0xF0, 0x90, 0xB3,
2552
  0x82, 0x00, 0xF0, 0x90, 0xB3, 0x83, 0x00, 0xF0, 0x90, 0xB3, 0x84, 0x00, 0xF0, 0x90, 0xB3, 0x85,
2553
  0x00, 0xF0, 0x90, 0xB3, 0x86, 0x00, 0xF0, 0x90, 0xB3, 0x87, 0x00, 0xF0, 0x90, 0xB3, 0x88, 0x00,
2554
  0xF0, 0x90, 0xB3, 0x89, 0x00, 0xF0, 0x90, 0xB3, 0x8A, 0x00, 0xF0, 0x90, 0xB3, 0x8B, 0x00, 0xF0,
2555
  0x90, 0xB3, 0x8C, 0x00, 0xF0, 0x90, 0xB3, 0x8D, 0x00, 0xF0, 0x90, 0xB3, 0x8E, 0x00, 0xF0, 0x90,
2556
  0xB3, 0x8F, 0x00, 0xF0, 0x90, 0xB3, 0x90, 0x00, 0xF0, 0x90, 0xB3, 0x91, 0x00, 0xF0, 0x90, 0xB3,
2557
  0x92, 0x00, 0xF0, 0x90, 0xB3, 0x93, 0x00, 0xF0, 0x90, 0xB3, 0x94, 0x00, 0xF0, 0x90, 0xB3, 0x95,
2558
  0x00, 0xF0, 0x90, 0xB3, 0x96, 0x00, 0xF0, 0x90, 0xB3, 0x97, 0x00, 0xF0, 0x90, 0xB3, 0x98, 0x00,
2559
  0xF0, 0x90, 0xB3, 0x99, 0x00, 0xF0, 0x90, 0xB3, 0x9A, 0x00, 0xF0, 0x90, 0xB3, 0x9B, 0x00, 0xF0,
2560
  0x90, 0xB3, 0x9C, 0x00, 0xF0, 0x90, 0xB3, 0x9D, 0x00, 0xF0, 0x90, 0xB3, 0x9E, 0x00, 0xF0, 0x90,
2561
  0xB3, 0x9F, 0x00, 0xF0, 0x90, 0xB3, 0xA0, 0x00, 0xF0, 0x90, 0xB3, 0xA1, 0x00, 0xF0, 0x90, 0xB3,
2562
  0xA2, 0x00, 0xF0, 0x90, 0xB3, 0xA3, 0x00, 0xF0, 0x90, 0xB3, 0xA4, 0x00, 0xF0, 0x90, 0xB3, 0xA5,
2563
  0x00, 0xF0, 0x90, 0xB3, 0xA6, 0x00, 0xF0, 0x90, 0xB3, 0xA7, 0x00, 0xF0, 0x90, 0xB3, 0xA8, 0x00,
2564
  0xF0, 0x90, 0xB3, 0xA9, 0x00, 0xF0, 0x90, 0xB3, 0xAA, 0x00, 0xF0, 0x90, 0xB3, 0xAB, 0x00, 0xF0,
2565
  0x90, 0xB3, 0xAC, 0x00, 0xF0, 0x90, 0xB3, 0xAD, 0x00, 0xF0, 0x90, 0xB3, 0xAE, 0x00, 0xF0, 0x90,
2566
  0xB3, 0xAF, 0x00, 0xF0, 0x90, 0xB3, 0xB0, 0x00, 0xF0, 0x90, 0xB3, 0xB1, 0x00, 0xF0, 0x90, 0xB3,
2567
  0xB2, 0x00, 0xF0, 0x90, 0xB5, 0xB0, 0x00, 0xF0, 0x90, 0xB5, 0xB1, 0x00, 0xF0, 0x90, 0xB5, 0xB2,
2568
  0x00, 0xF0, 0x90, 0xB5, 0xB3, 0x00, 0xF0, 0x90, 0xB5, 0xB4, 0x00, 0xF0, 0x90, 0xB5, 0xB5, 0x00,
2569
  0xF0, 0x90, 0xB5, 0xB6, 0x00, 0xF0, 0x90, 0xB5, 0xB7, 0x00, 0xF0, 0x90, 0xB5, 0xB8, 0x00, 0xF0,
2570
  0x90, 0xB5, 0xB9, 0x00, 0xF0, 0x90, 0xB5, 0xBA, 0x00, 0xF0, 0x90, 0xB5, 0xBB, 0x00, 0xF0, 0x90,
2571
  0xB5, 0xBC, 0x00, 0xF0, 0x90, 0xB5, 0xBD, 0x00, 0xF0, 0x90, 0xB5, 0xBE, 0x00, 0xF0, 0x90, 0xB5,
2572
  0xBF, 0x00, 0xF0, 0x90, 0xB6, 0x80, 0x00, 0xF0, 0x90, 0xB6, 0x81, 0x00, 0xF0, 0x90, 0xB6, 0x82,
2573
  0x00, 0xF0, 0x90, 0xB6, 0x83, 0x00, 0xF0, 0x90, 0xB6, 0x84, 0x00, 0xF0, 0x90, 0xB6, 0x85, 0x00,
2574
  0xF0, 0x91, 0xA3, 0x80, 0x00, 0xF0, 0x91, 0xA3, 0x81, 0x00, 0xF0, 0x91, 0xA3, 0x82, 0x00, 0xF0,
2575
  0x91, 0xA3, 0x83, 0x00, 0xF0, 0x91, 0xA3, 0x84, 0x00, 0xF0, 0x91, 0xA3, 0x85, 0x00, 0xF0, 0x91,
2576
  0xA3, 0x86, 0x00, 0xF0, 0x91, 0xA3, 0x87, 0x00, 0xF0, 0x91, 0xA3, 0x88, 0x00, 0xF0, 0x91, 0xA3,
2577
  0x89, 0x00, 0xF0, 0x91, 0xA3, 0x8A, 0x00, 0xF0, 0x91, 0xA3, 0x8B, 0x00, 0xF0, 0x91, 0xA3, 0x8C,
2578
  0x00, 0xF0, 0x91, 0xA3, 0x8D, 0x00, 0xF0, 0x91, 0xA3, 0x8E, 0x00, 0xF0, 0x91, 0xA3, 0x8F, 0x00,
2579
  0xF0, 0x91, 0xA3, 0x90, 0x00, 0xF0, 0x91, 0xA3, 0x91, 0x00, 0xF0, 0x91, 0xA3, 0x92, 0x00, 0xF0,
2580
  0x91, 0xA3, 0x93, 0x00, 0xF0, 0x91, 0xA3, 0x94, 0x00, 0xF0, 0x91, 0xA3, 0x95, 0x00, 0xF0, 0x91,
2581
  0xA3, 0x96, 0x00, 0xF0, 0x91, 0xA3, 0x97, 0x00, 0xF0, 0x91, 0xA3, 0x98, 0x00, 0xF0, 0x91, 0xA3,
2582
  0x99, 0x00, 0xF0, 0x91, 0xA3, 0x9A, 0x00, 0xF0, 0x91, 0xA3, 0x9B, 0x00, 0xF0, 0x91, 0xA3, 0x9C,
2583
  0x00, 0xF0, 0x91, 0xA3, 0x9D, 0x00, 0xF0, 0x91, 0xA3, 0x9E, 0x00, 0xF0, 0x91, 0xA3, 0x9F, 0x00,
2584
  0xF0, 0x96, 0xB9, 0xA0, 0x00, 0xF0, 0x96, 0xB9, 0xA1, 0x00, 0xF0, 0x96, 0xB9, 0xA2, 0x00, 0xF0,
2585
  0x96, 0xB9, 0xA3, 0x00, 0xF0, 0x96, 0xB9, 0xA4, 0x00, 0xF0, 0x96, 0xB9, 0xA5, 0x00, 0xF0, 0x96,
2586
  0xB9, 0xA6, 0x00, 0xF0, 0x96, 0xB9, 0xA7, 0x00, 0xF0, 0x96, 0xB9, 0xA8, 0x00, 0xF0, 0x96, 0xB9,
2587
  0xA9, 0x00, 0xF0, 0x96, 0xB9, 0xAA, 0x00, 0xF0, 0x96, 0xB9, 0xAB, 0x00, 0xF0, 0x96, 0xB9, 0xAC,
2588
  0x00, 0xF0, 0x96, 0xB9, 0xAD, 0x00, 0xF0, 0x96, 0xB9, 0xAE, 0x00, 0xF0, 0x96, 0xB9, 0xAF, 0x00,
2589
  0xF0, 0x96, 0xB9, 0xB0, 0x00, 0xF0, 0x96, 0xB9, 0xB1, 0x00, 0xF0, 0x96, 0xB9, 0xB2, 0x00, 0xF0,
2590
  0x96, 0xB9, 0xB3, 0x00, 0xF0, 0x96, 0xB9, 0xB4, 0x00, 0xF0, 0x96, 0xB9, 0xB5, 0x00, 0xF0, 0x96,
2591
  0xB9, 0xB6, 0x00, 0xF0, 0x96, 0xB9, 0xB7, 0x00, 0xF0, 0x96, 0xB9, 0xB8, 0x00, 0xF0, 0x96, 0xB9,
2592
  0xB9, 0x00, 0xF0, 0x96, 0xB9, 0xBA, 0x00, 0xF0, 0x96, 0xB9, 0xBB, 0x00, 0xF0, 0x96, 0xB9, 0xBC,
2593
  0x00, 0xF0, 0x96, 0xB9, 0xBD, 0x00, 0xF0, 0x96, 0xB9, 0xBE, 0x00, 0xF0, 0x96, 0xB9, 0xBF, 0x00,
2594
  0xF0, 0x96, 0xBA, 0xBB, 0x00, 0xF0, 0x96, 0xBA, 0xBC, 0x00, 0xF0, 0x96, 0xBA, 0xBD, 0x00, 0xF0,
2595
  0x96, 0xBA, 0xBE, 0x00, 0xF0, 0x96, 0xBA, 0xBF, 0x00, 0xF0, 0x96, 0xBB, 0x80, 0x00, 0xF0, 0x96,
2596
  0xBB, 0x81, 0x00, 0xF0, 0x96, 0xBB, 0x82, 0x00, 0xF0, 0x96, 0xBB, 0x83, 0x00, 0xF0, 0x96, 0xBB,
2597
  0x84, 0x00, 0xF0, 0x96, 0xBB, 0x85, 0x00, 0xF0, 0x96, 0xBB, 0x86, 0x00, 0xF0, 0x96, 0xBB, 0x87,
2598
  0x00, 0xF0, 0x96, 0xBB, 0x88, 0x00, 0xF0, 0x96, 0xBB, 0x89, 0x00, 0xF0, 0x96, 0xBB, 0x8A, 0x00,
2599
  0xF0, 0x96, 0xBB, 0x8B, 0x00, 0xF0, 0x96, 0xBB, 0x8C, 0x00, 0xF0, 0x96, 0xBB, 0x8D, 0x00, 0xF0,
2600
  0x96, 0xBB, 0x8E, 0x00, 0xF0, 0x96, 0xBB, 0x8F, 0x00, 0xF0, 0x96, 0xBB, 0x90, 0x00, 0xF0, 0x96,
2601
  0xBB, 0x91, 0x00, 0xF0, 0x96, 0xBB, 0x92, 0x00, 0xF0, 0x96, 0xBB, 0x93, 0x00, 0xF0, 0x9D, 0x85,
2602
  0x97, 0xF0, 0x9D, 0x85, 0xA5, 0x00, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0x00, 0xF0,
2603
  0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0x00, 0xF0, 0x9D, 0x85, 0x98,
2604
  0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x00, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85,
2605
  0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0x00, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
2606
  0x85, 0xB1, 0x00, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0x00,
2607
  0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0x00, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85,
2608
  0xA5, 0x00, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0x00, 0xF0,
2609
  0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0x00, 0xF0, 0x9D, 0x86, 0xB9,
2610
  0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x00, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85,
2611
  0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x00, 0xC4, 0xB1, 0x00, 0xC8, 0xB7, 0x00, 0xE2, 0x88, 0x87, 0x00,
2612
  0xE2, 0x88, 0x82, 0x00, 0xF0, 0x9E, 0xA4, 0xA2, 0x00, 0xF0, 0x9E, 0xA4, 0xA3, 0x00, 0xF0, 0x9E,
2613
  0xA4, 0xA4, 0x00, 0xF0, 0x9E, 0xA4, 0xA5, 0x00, 0xF0, 0x9E, 0xA4, 0xA6, 0x00, 0xF0, 0x9E, 0xA4,
2614
  0xA7, 0x00, 0xF0, 0x9E, 0xA4, 0xA8, 0x00, 0xF0, 0x9E, 0xA4, 0xA9, 0x00, 0xF0, 0x9E, 0xA4, 0xAA,
2615
  0x00, 0xF0, 0x9E, 0xA4, 0xAB, 0x00, 0xF0, 0x9E, 0xA4, 0xAC, 0x00, 0xF0, 0x9E, 0xA4, 0xAD, 0x00,
2616
  0xF0, 0x9E, 0xA4, 0xAE, 0x00, 0xF0, 0x9E, 0xA4, 0xAF, 0x00, 0xF0, 0x9E, 0xA4, 0xB0, 0x00, 0xF0,
2617
  0x9E, 0xA4, 0xB1, 0x00, 0xF0, 0x9E, 0xA4, 0xB2, 0x00, 0xF0, 0x9E, 0xA4, 0xB3, 0x00, 0xF0, 0x9E,
2618
  0xA4, 0xB4, 0x00, 0xF0, 0x9E, 0xA4, 0xB5, 0x00, 0xF0, 0x9E, 0xA4, 0xB6, 0x00, 0xF0, 0x9E, 0xA4,
2619
  0xB7, 0x00, 0xF0, 0x9E, 0xA4, 0xB8, 0x00, 0xF0, 0x9E, 0xA4, 0xB9, 0x00, 0xF0, 0x9E, 0xA4, 0xBA,
2620
  0x00, 0xF0, 0x9E, 0xA4, 0xBB, 0x00, 0xF0, 0x9E, 0xA4, 0xBC, 0x00, 0xF0, 0x9E, 0xA4, 0xBD, 0x00,
2621
  0xF0, 0x9E, 0xA4, 0xBE, 0x00, 0xF0, 0x9E, 0xA4, 0xBF, 0x00, 0xF0, 0x9E, 0xA5, 0x80, 0x00, 0xF0,
2622
  0x9E, 0xA5, 0x81, 0x00, 0xF0, 0x9E, 0xA5, 0x82, 0x00, 0xF0, 0x9E, 0xA5, 0x83, 0x00, 0xD9, 0xAE,
2623
  0x00, 0xDA, 0xA1, 0x00, 0xD9, 0xAF, 0x00, 0x30, 0x2C, 0x00, 0x31, 0x2C, 0x00, 0x32, 0x2C, 0x00,
2624
  0x33, 0x2C, 0x00, 0x34, 0x2C, 0x00, 0x35, 0x2C, 0x00, 0x36, 0x2C, 0x00, 0x37, 0x2C, 0x00, 0x38,
2625
  0x2C, 0x00, 0x39, 0x2C, 0x00, 0xE3, 0x80, 0x94, 0x73, 0xE3, 0x80, 0x95, 0x00, 0x77, 0x7A, 0x00,
2626
  0x68, 0x76, 0x00, 0x73, 0x64, 0x00, 0x73, 0x73, 0x00, 0x70, 0x70, 0x76, 0x00, 0x77, 0x63, 0x00,
2627
  0x6D, 0x63, 0x00, 0x6D, 0x64, 0x00, 0x6D, 0x72, 0x00, 0x64, 0x6A, 0x00, 0xE3, 0x81, 0xBB, 0xE3,
2628
  0x81, 0x8B, 0x00, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB3, 0x00, 0xE5, 0xAD, 0x97, 0x00, 0xE5, 0x8F,
2629
  0x8C, 0x00, 0xE3, 0x83, 0x87, 0x00, 0xE5, 0xA4, 0x9A, 0x00, 0xE8, 0xA7, 0xA3, 0x00, 0xE4, 0xBA,
2630
  0xA4, 0x00, 0xE6, 0x98, 0xA0, 0x00, 0xE7, 0x84, 0xA1, 0x00, 0xE5, 0x89, 0x8D, 0x00, 0xE5, 0xBE,
2631
  0x8C, 0x00, 0xE5, 0x86, 0x8D, 0x00, 0xE6, 0x96, 0xB0, 0x00, 0xE5, 0x88, 0x9D, 0x00, 0xE7, 0xB5,
2632
  0x82, 0x00, 0xE8, 0xB2, 0xA9, 0x00, 0xE5, 0xA3, 0xB0, 0x00, 0xE5, 0x90, 0xB9, 0x00, 0xE6, 0xBC,
2633
  0x94, 0x00, 0xE6, 0x8A, 0x95, 0x00, 0xE6, 0x8D, 0x95, 0x00, 0xE9, 0x81, 0x8A, 0x00, 0xE6, 0x8C,
2634
  0x87, 0x00, 0xE6, 0x89, 0x93, 0x00, 0xE7, 0xA6, 0x81, 0x00, 0xE7, 0xA9, 0xBA, 0x00, 0xE5, 0x90,
2635
  0x88, 0x00, 0xE6, 0xBA, 0x80, 0x00, 0xE7, 0x94, 0xB3, 0x00, 0xE5, 0x89, 0xB2, 0x00, 0xE5, 0x96,
2636
  0xB6, 0x00, 0xE9, 0x85, 0x8D, 0x00, 0xE3, 0x80, 0x94, 0xE6, 0x9C, 0xAC, 0xE3, 0x80, 0x95, 0x00,
2637
  0xE3, 0x80, 0x94, 0xE4, 0xB8, 0x89, 0xE3, 0x80, 0x95, 0x00, 0xE3, 0x80, 0x94, 0xE4, 0xBA, 0x8C,
2638
  0xE3, 0x80, 0x95, 0x00, 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89, 0xE3, 0x80, 0x95, 0x00, 0xE3, 0x80,
2639
  0x94, 0xE7, 0x82, 0xB9, 0xE3, 0x80, 0x95, 0x00, 0xE3, 0x80, 0x94, 0xE6, 0x89, 0x93, 0xE3, 0x80,
2640
  0x95, 0x00, 0xE3, 0x80, 0x94, 0xE7, 0x9B, 0x97, 0xE3, 0x80, 0x95, 0x00, 0xE3, 0x80, 0x94, 0xE5,
2641
  0x8B, 0x9D, 0xE3, 0x80, 0x95, 0x00, 0xE3, 0x80, 0x94, 0xE6, 0x95, 0x97, 0xE3, 0x80, 0x95, 0x00,
2642
  0xE5, 0xBE, 0x97, 0x00, 0xE5, 0x8F, 0xAF, 0x00, 0xE4, 0xB8, 0xBD, 0x00, 0xE4, 0xB8, 0xB8, 0x00,
2643
  0xE4, 0xB9, 0x81, 0x00, 0xF0, 0xA0, 0x84, 0xA2, 0x00, 0xE4, 0xBD, 0xA0, 0x00, 0xE4, 0xBE, 0xBB,
2644
  0x00, 0xE5, 0x80, 0x82, 0x00, 0xE5, 0x81, 0xBA, 0x00, 0xE5, 0x82, 0x99, 0x00, 0xE5, 0x83, 0x8F,
2645
  0x00, 0xE3, 0x92, 0x9E, 0x00, 0xF0, 0xA0, 0x98, 0xBA, 0x00, 0xE5, 0x85, 0x94, 0x00, 0xE5, 0x85,
2646
  0xA4, 0x00, 0xE5, 0x85, 0xB7, 0x00, 0xF0, 0xA0, 0x94, 0x9C, 0x00, 0xE3, 0x92, 0xB9, 0x00, 0xE5,
2647
  0x85, 0xA7, 0x00, 0xF0, 0xA0, 0x95, 0x8B, 0x00, 0xE5, 0x86, 0x97, 0x00, 0xE5, 0x86, 0xA4, 0x00,
2648
  0xE4, 0xBB, 0x8C, 0x00, 0xE5, 0x86, 0xAC, 0x00, 0xF0, 0xA9, 0x87, 0x9F, 0x00, 0xE5, 0x88, 0x83,
2649
  0x00, 0xE3, 0x93, 0x9F, 0x00, 0xE5, 0x88, 0xBB, 0x00, 0xE5, 0x89, 0x86, 0x00, 0xE5, 0x89, 0xB7,
2650
  0x00, 0xE3, 0x94, 0x95, 0x00, 0xE5, 0x8C, 0x85, 0x00, 0xE5, 0x8C, 0x86, 0x00, 0xE5, 0x8D, 0x89,
2651
  0x00, 0xE5, 0x8D, 0x9A, 0x00, 0xE5, 0x8D, 0xB3, 0x00, 0xE5, 0x8D, 0xBD, 0x00, 0xE5, 0x8D, 0xBF,
2652
  0x00, 0xF0, 0xA0, 0xA8, 0xAC, 0x00, 0xE7, 0x81, 0xB0, 0x00, 0xE5, 0x8F, 0x8A, 0x00, 0xE5, 0x8F,
2653
  0x9F, 0x00, 0xF0, 0xA0, 0xAD, 0xA3, 0x00, 0xE5, 0x8F, 0xAB, 0x00, 0xE5, 0x8F, 0xB1, 0x00, 0xE5,
2654
  0x90, 0x86, 0x00, 0xE5, 0x92, 0x9E, 0x00, 0xE5, 0x90, 0xB8, 0x00, 0xE5, 0x91, 0x88, 0x00, 0xE5,
2655
  0x91, 0xA8, 0x00, 0xE5, 0x92, 0xA2, 0x00, 0xE5, 0x93, 0xB6, 0x00, 0xE5, 0x94, 0x90, 0x00, 0xE5,
2656
  0x95, 0x93, 0x00, 0xE5, 0x95, 0xA3, 0x00, 0xE5, 0x96, 0x84, 0x00, 0xE5, 0x96, 0xAB, 0x00, 0xE5,
2657
  0x96, 0xB3, 0x00, 0xE5, 0x97, 0x82, 0x00, 0xE5, 0x9C, 0x96, 0x00, 0xE5, 0x9C, 0x97, 0x00, 0xE5,
2658
  0x99, 0x91, 0x00, 0xE5, 0x99, 0xB4, 0x00, 0xE5, 0xA3, 0xAE, 0x00, 0xE5, 0x9F, 0x8E, 0x00, 0xE5,
2659
  0x9F, 0xB4, 0x00, 0xE5, 0xA0, 0x8D, 0x00, 0xE5, 0x9E, 0x8B, 0x00, 0xE5, 0xA0, 0xB2, 0x00, 0xE5,
2660
  0xA0, 0xB1, 0x00, 0xE5, 0xA2, 0xAC, 0x00, 0xF0, 0xA1, 0x93, 0xA4, 0x00, 0xE5, 0xA3, 0xB2, 0x00,
2661
  0xE5, 0xA3, 0xB7, 0x00, 0xE5, 0xA4, 0x86, 0x00, 0xE5, 0xA4, 0xA2, 0x00, 0xE5, 0xA5, 0xA2, 0x00,
2662
  0xF0, 0xA1, 0x9A, 0xA8, 0x00, 0xF0, 0xA1, 0x9B, 0xAA, 0x00, 0xE5, 0xA7, 0xAC, 0x00, 0xE5, 0xA8,
2663
  0x9B, 0x00, 0xE5, 0xA8, 0xA7, 0x00, 0xE5, 0xA7, 0x98, 0x00, 0xE5, 0xA9, 0xA6, 0x00, 0xE3, 0x9B,
2664
  0xAE, 0x00, 0xE3, 0x9B, 0xBC, 0x00, 0xE5, 0xAC, 0x88, 0x00, 0xE5, 0xAC, 0xBE, 0x00, 0xF0, 0xA1,
2665
  0xA7, 0x88, 0x00, 0xE5, 0xAF, 0x83, 0x00, 0xE5, 0xAF, 0x98, 0x00, 0xE5, 0xAF, 0xB3, 0x00, 0xF0,
2666
  0xA1, 0xAC, 0x98, 0x00, 0xE5, 0xAF, 0xBF, 0x00, 0xE5, 0xB0, 0x86, 0x00, 0xE5, 0xBD, 0x93, 0x00,
2667
  0xE3, 0x9E, 0x81, 0x00, 0xE5, 0xB1, 0xA0, 0x00, 0xE5, 0xB3, 0x80, 0x00, 0xE5, 0xB2, 0x8D, 0x00,
2668
  0xF0, 0xA1, 0xB7, 0xA4, 0x00, 0xE5, 0xB5, 0x83, 0x00, 0xF0, 0xA1, 0xB7, 0xA6, 0x00, 0xE5, 0xB5,
2669
  0xAE, 0x00, 0xE5, 0xB5, 0xAB, 0x00, 0xE5, 0xB5, 0xBC, 0x00, 0xE5, 0xB7, 0xA1, 0x00, 0xE5, 0xB7,
2670
  0xA2, 0x00, 0xE3, 0xA0, 0xAF, 0x00, 0xE5, 0xB7, 0xBD, 0x00, 0xE5, 0xB8, 0xA8, 0x00, 0xE5, 0xB8,
2671
  0xBD, 0x00, 0xE5, 0xB9, 0xA9, 0x00, 0xE3, 0xA1, 0xA2, 0x00, 0xF0, 0xA2, 0x86, 0x83, 0x00, 0xE3,
2672
  0xA1, 0xBC, 0x00, 0xE5, 0xBA, 0xB0, 0x00, 0xE5, 0xBA, 0xB3, 0x00, 0xE5, 0xBA, 0xB6, 0x00, 0xF0,
2673
  0xAA, 0x8E, 0x92, 0x00, 0xF0, 0xA2, 0x8C, 0xB1, 0x00, 0xE8, 0x88, 0x81, 0x00, 0xE5, 0xBC, 0xA2,
2674
  0x00, 0xE3, 0xA3, 0x87, 0x00, 0xF0, 0xA3, 0x8A, 0xB8, 0x00, 0xF0, 0xA6, 0x87, 0x9A, 0x00, 0xE5,
2675
  0xBD, 0xA2, 0x00, 0xE5, 0xBD, 0xAB, 0x00, 0xE3, 0xA3, 0xA3, 0x00, 0xE5, 0xBE, 0x9A, 0x00, 0xE5,
2676
  0xBF, 0x8D, 0x00, 0xE5, 0xBF, 0x97, 0x00, 0xE5, 0xBF, 0xB9, 0x00, 0xE6, 0x82, 0x81, 0x00, 0xE3,
2677
  0xA4, 0xBA, 0x00, 0xE3, 0xA4, 0x9C, 0x00, 0xF0, 0xA2, 0x9B, 0x94, 0x00, 0xE6, 0x83, 0x87, 0x00,
2678
  0xE6, 0x85, 0x88, 0x00, 0xE6, 0x85, 0x8C, 0x00, 0xE6, 0x85, 0xBA, 0x00, 0xE6, 0x86, 0xB2, 0x00,
2679
  0xE6, 0x86, 0xA4, 0x00, 0xE6, 0x86, 0xAF, 0x00, 0xE6, 0x87, 0x9E, 0x00, 0xE6, 0x88, 0x90, 0x00,
2680
  0xE6, 0x88, 0x9B, 0x00, 0xE6, 0x89, 0x9D, 0x00, 0xE6, 0x8A, 0xB1, 0x00, 0xE6, 0x8B, 0x94, 0x00,
2681
  0xE6, 0x8D, 0x90, 0x00, 0xF0, 0xA2, 0xAC, 0x8C, 0x00, 0xE6, 0x8C, 0xBD, 0x00, 0xE6, 0x8B, 0xBC,
2682
  0x00, 0xE6, 0x8D, 0xA8, 0x00, 0xE6, 0x8E, 0x83, 0x00, 0xE6, 0x8F, 0xA4, 0x00, 0xF0, 0xA2, 0xAF,
2683
  0xB1, 0x00, 0xE6, 0x90, 0xA2, 0x00, 0xE6, 0x8F, 0x85, 0x00, 0xE6, 0x8E, 0xA9, 0x00, 0xE3, 0xA8,
2684
  0xAE, 0x00, 0xE6, 0x91, 0xA9, 0x00, 0xE6, 0x91, 0xBE, 0x00, 0xE6, 0x92, 0x9D, 0x00, 0xE6, 0x91,
2685
  0xB7, 0x00, 0xE3, 0xA9, 0xAC, 0x00, 0xE6, 0x95, 0xAC, 0x00, 0xF0, 0xA3, 0x80, 0x8A, 0x00, 0xE6,
2686
  0x97, 0xA3, 0x00, 0xE6, 0x9B, 0xB8, 0x00, 0xE6, 0x99, 0x89, 0x00, 0xE3, 0xAC, 0x99, 0x00, 0xE3,
2687
  0xAC, 0x88, 0x00, 0xE3, 0xAB, 0xA4, 0x00, 0xE5, 0x86, 0x92, 0x00, 0xE5, 0x86, 0x95, 0x00, 0xE6,
2688
  0x9C, 0x80, 0x00, 0xE6, 0x9A, 0x9C, 0x00, 0xE8, 0x82, 0xAD, 0x00, 0xE4, 0x8F, 0x99, 0x00, 0xE6,
2689
  0x9C, 0xA1, 0x00, 0xE6, 0x9D, 0x9E, 0x00, 0xE6, 0x9D, 0x93, 0x00, 0xF0, 0xA3, 0x8F, 0x83, 0x00,
2690
  0xE3, 0xAD, 0x89, 0x00, 0xE6, 0x9F, 0xBA, 0x00, 0xE6, 0x9E, 0x85, 0x00, 0xE6, 0xA1, 0x92, 0x00,
2691
  0xF0, 0xA3, 0x91, 0xAD, 0x00, 0xE6, 0xA2, 0x8E, 0x00, 0xE6, 0xA0, 0x9F, 0x00, 0xE6, 0xA4, 0x94,
2692
  0x00, 0xE6, 0xA5, 0x82, 0x00, 0xE6, 0xA6, 0xA3, 0x00, 0xE6, 0xA7, 0xAA, 0x00, 0xE6, 0xAA, 0xA8,
2693
  0x00, 0xF0, 0xA3, 0x9A, 0xA3, 0x00, 0xE6, 0xAB, 0x9B, 0x00, 0xE3, 0xB0, 0x98, 0x00, 0xE6, 0xAC,
2694
  0xA1, 0x00, 0xF0, 0xA3, 0xA2, 0xA7, 0x00, 0xE6, 0xAD, 0x94, 0x00, 0xE3, 0xB1, 0x8E, 0x00, 0xE6,
2695
  0xAD, 0xB2, 0x00, 0xE6, 0xAE, 0x9F, 0x00, 0xE6, 0xAE, 0xBB, 0x00, 0xF0, 0xA3, 0xAA, 0x8D, 0x00,
2696
  0xF0, 0xA1, 0xB4, 0x8B, 0x00, 0xF0, 0xA3, 0xAB, 0xBA, 0x00, 0xE6, 0xB1, 0x8E, 0x00, 0xF0, 0xA3,
2697
  0xB2, 0xBC, 0x00, 0xE6, 0xB2, 0xBF, 0x00, 0xE6, 0xB3, 0x8D, 0x00, 0xE6, 0xB1, 0xA7, 0x00, 0xE6,
2698
  0xB4, 0x96, 0x00, 0xE6, 0xB4, 0xBE, 0x00, 0xE6, 0xB5, 0xA9, 0x00, 0xE6, 0xB5, 0xB8, 0x00, 0xE6,
2699
  0xB6, 0x85, 0x00, 0xF0, 0xA3, 0xB4, 0x9E, 0x00, 0xE6, 0xB4, 0xB4, 0x00, 0xE6, 0xB8, 0xAF, 0x00,
2700
  0xE6, 0xB9, 0xAE, 0x00, 0xE3, 0xB4, 0xB3, 0x00, 0xE6, 0xBB, 0x87, 0x00, 0xF0, 0xA3, 0xBB, 0x91,
2701
  0x00, 0xE6, 0xB7, 0xB9, 0x00, 0xE6, 0xBD, 0xAE, 0x00, 0xF0, 0xA3, 0xBD, 0x9E, 0x00, 0xF0, 0xA3,
2702
  0xBE, 0x8E, 0x00, 0xE6, 0xBF, 0x86, 0x00, 0xE7, 0x80, 0xB9, 0x00, 0xE7, 0x80, 0x9B, 0x00, 0xE3,
2703
  0xB6, 0x96, 0x00, 0xE7, 0x81, 0x8A, 0x00, 0xE7, 0x81, 0xBD, 0x00, 0xE7, 0x81, 0xB7, 0x00, 0xE7,
2704
  0x82, 0xAD, 0x00, 0xF0, 0xA0, 0x94, 0xA5, 0x00, 0xE7, 0x85, 0x85, 0x00, 0xF0, 0xA4, 0x89, 0xA3,
2705
  0x00, 0xE7, 0x86, 0x9C, 0x00, 0xF0, 0xA4, 0x8E, 0xAB, 0x00, 0xE7, 0x88, 0xA8, 0x00, 0xE7, 0x89,
2706
  0x90, 0x00, 0xF0, 0xA4, 0x98, 0x88, 0x00, 0xE7, 0x8A, 0x80, 0x00, 0xE7, 0x8A, 0x95, 0x00, 0xF0,
2707
  0xA4, 0x9C, 0xB5, 0x00, 0xF0, 0xA4, 0xA0, 0x94, 0x00, 0xE7, 0x8D, 0xBA, 0x00, 0xE7, 0x8E, 0x8B,
2708
  0x00, 0xE3, 0xBA, 0xAC, 0x00, 0xE7, 0x8E, 0xA5, 0x00, 0xE3, 0xBA, 0xB8, 0x00, 0xE7, 0x91, 0x87,
2709
  0x00, 0xE7, 0x91, 0x9C, 0x00, 0xE7, 0x92, 0x85, 0x00, 0xE7, 0x93, 0x8A, 0x00, 0xE3, 0xBC, 0x9B,
2710
  0x00, 0xE7, 0x94, 0xA4, 0x00, 0xF0, 0xA4, 0xB0, 0xB6, 0x00, 0xE7, 0x94, 0xBE, 0x00, 0xF0, 0xA4,
2711
  0xB2, 0x92, 0x00, 0xF0, 0xA2, 0x86, 0x9F, 0x00, 0xE7, 0x98, 0x90, 0x00, 0xF0, 0xA4, 0xBE, 0xA1,
2712
  0x00, 0xF0, 0xA4, 0xBE, 0xB8, 0x00, 0xF0, 0xA5, 0x81, 0x84, 0x00, 0xE3, 0xBF, 0xBC, 0x00, 0xE4,
2713
  0x80, 0x88, 0x00, 0xF0, 0xA5, 0x83, 0xB3, 0x00, 0xF0, 0xA5, 0x83, 0xB2, 0x00, 0xF0, 0xA5, 0x84,
2714
  0x99, 0x00, 0xF0, 0xA5, 0x84, 0xB3, 0x00, 0xE7, 0x9C, 0x9E, 0x00, 0xE7, 0x9C, 0x9F, 0x00, 0xE7,
2715
  0x9E, 0x8B, 0x00, 0xE4, 0x81, 0x86, 0x00, 0xE4, 0x82, 0x96, 0x00, 0xF0, 0xA5, 0x90, 0x9D, 0x00,
2716
  0xE7, 0xA1, 0x8E, 0x00, 0xE4, 0x83, 0xA3, 0x00, 0xF0, 0xA5, 0x98, 0xA6, 0x00, 0xF0, 0xA5, 0x9A,
2717
  0x9A, 0x00, 0xF0, 0xA5, 0x9B, 0x85, 0x00, 0xE7, 0xA7, 0xAB, 0x00, 0xE4, 0x84, 0xAF, 0x00, 0xE7,
2718
  0xA9, 0x8A, 0x00, 0xE7, 0xA9, 0x8F, 0x00, 0xF0, 0xA5, 0xA5, 0xBC, 0x00, 0xF0, 0xA5, 0xAA, 0xA7,
2719
  0x00, 0xE7, 0xAB, 0xAE, 0x00, 0xE4, 0x88, 0x82, 0x00, 0xF0, 0xA5, 0xAE, 0xAB, 0x00, 0xE7, 0xAF,
2720
  0x86, 0x00, 0xE7, 0xAF, 0x89, 0x00, 0xE4, 0x88, 0xA7, 0x00, 0xF0, 0xA5, 0xB2, 0x80, 0x00, 0xE7,
2721
  0xB3, 0x92, 0x00, 0xE4, 0x8A, 0xA0, 0x00, 0xE7, 0xB3, 0xA8, 0x00, 0xE7, 0xB3, 0xA3, 0x00, 0xE7,
2722
  0xB4, 0x80, 0x00, 0xF0, 0xA5, 0xBE, 0x86, 0x00, 0xE7, 0xB5, 0xA3, 0x00, 0xE4, 0x8C, 0x81, 0x00,
2723
  0xE7, 0xB7, 0x87, 0x00, 0xE7, 0xB8, 0x82, 0x00, 0xE7, 0xB9, 0x85, 0x00, 0xE4, 0x8C, 0xB4, 0x00,
2724
  0xF0, 0xA6, 0x88, 0xA8, 0x00, 0xF0, 0xA6, 0x89, 0x87, 0x00, 0xE4, 0x8D, 0x99, 0x00, 0xF0, 0xA6,
2725
  0x8B, 0x99, 0x00, 0xE7, 0xBD, 0xBA, 0x00, 0xF0, 0xA6, 0x8C, 0xBE, 0x00, 0xE7, 0xBE, 0x95, 0x00,
2726
  0xE7, 0xBF, 0xBA, 0x00, 0xF0, 0xA6, 0x93, 0x9A, 0x00, 0xF0, 0xA6, 0x94, 0xA3, 0x00, 0xE8, 0x81,
2727
  0xA0, 0x00, 0xF0, 0xA6, 0x96, 0xA8, 0x00, 0xE8, 0x81, 0xB0, 0x00, 0xF0, 0xA3, 0x8D, 0x9F, 0x00,
2728
  0xE4, 0x8F, 0x95, 0x00, 0xE8, 0x82, 0xB2, 0x00, 0xE8, 0x84, 0x83, 0x00, 0xE4, 0x90, 0x8B, 0x00,
2729
  0xE8, 0x84, 0xBE, 0x00, 0xE5, 0xAA, 0xB5, 0x00, 0xF0, 0xA6, 0x9E, 0xA7, 0x00, 0xF0, 0xA6, 0x9E,
2730
  0xB5, 0x00, 0xF0, 0xA3, 0x8E, 0x93, 0x00, 0xF0, 0xA3, 0x8E, 0x9C, 0x00, 0xE8, 0x88, 0x84, 0x00,
2731
  0xE8, 0xBE, 0x9E, 0x00, 0xE4, 0x91, 0xAB, 0x00, 0xE8, 0x8A, 0x91, 0x00, 0xE8, 0x8A, 0x8B, 0x00,
2732
  0xE8, 0x8A, 0x9D, 0x00, 0xE5, 0x8A, 0xB3, 0x00, 0xE8, 0x8A, 0xB1, 0x00, 0xE8, 0x8A, 0xB3, 0x00,
2733
  0xE8, 0x8A, 0xBD, 0x00, 0xE8, 0x8B, 0xA6, 0x00, 0xF0, 0xA6, 0xAC, 0xBC, 0x00, 0xE8, 0x8C, 0x9D,
2734
  0x00, 0xE8, 0x8D, 0xA3, 0x00, 0xE8, 0x8E, 0xAD, 0x00, 0xE8, 0x8C, 0xA3, 0x00, 0xE8, 0x8E, 0xBD,
2735
  0x00, 0xE8, 0x8F, 0xA7, 0x00, 0xE8, 0x8D, 0x93, 0x00, 0xE8, 0x8F, 0x8A, 0x00, 0xE8, 0x8F, 0x8C,
2736
  0x00, 0xE8, 0x8F, 0x9C, 0x00, 0xF0, 0xA6, 0xB0, 0xB6, 0x00, 0xF0, 0xA6, 0xB5, 0xAB, 0x00, 0xF0,
2737
  0xA6, 0xB3, 0x95, 0x00, 0xE4, 0x94, 0xAB, 0x00, 0xE8, 0x93, 0xB1, 0x00, 0xE8, 0x93, 0xB3, 0x00,
2738
  0xE8, 0x94, 0x96, 0x00, 0xF0, 0xA7, 0x8F, 0x8A, 0x00, 0xE8, 0x95, 0xA4, 0x00, 0xF0, 0xA6, 0xBC,
2739
  0xAC, 0x00, 0xE4, 0x95, 0x9D, 0x00, 0xE4, 0x95, 0xA1, 0x00, 0xF0, 0xA6, 0xBE, 0xB1, 0x00, 0xF0,
2740
  0xA7, 0x83, 0x92, 0x00, 0xE4, 0x95, 0xAB, 0x00, 0xE8, 0x99, 0x90, 0x00, 0xE8, 0x99, 0xA7, 0x00,
2741
  0xE8, 0x99, 0xA9, 0x00, 0xE8, 0x9A, 0xA9, 0x00, 0xE8, 0x9A, 0x88, 0x00, 0xE8, 0x9C, 0x8E, 0x00,
2742
  0xE8, 0x9B, 0xA2, 0x00, 0xE8, 0x9C, 0xA8, 0x00, 0xE8, 0x9D, 0xAB, 0x00, 0xE8, 0x9E, 0x86, 0x00,
2743
  0xE4, 0x97, 0x97, 0x00, 0xE8, 0x9F, 0xA1, 0x00, 0xE8, 0xA0, 0x81, 0x00, 0xE4, 0x97, 0xB9, 0x00,
2744
  0xE8, 0xA1, 0xA0, 0x00, 0xF0, 0xA7, 0x99, 0xA7, 0x00, 0xE8, 0xA3, 0x97, 0x00, 0xE8, 0xA3, 0x9E,
2745
  0x00, 0xE4, 0x98, 0xB5, 0x00, 0xE8, 0xA3, 0xBA, 0x00, 0xE3, 0x92, 0xBB, 0x00, 0xF0, 0xA7, 0xA2,
2746
  0xAE, 0x00, 0xF0, 0xA7, 0xA5, 0xA6, 0x00, 0xE4, 0x9A, 0xBE, 0x00, 0xE4, 0x9B, 0x87, 0x00, 0xE8,
2747
  0xAA, 0xA0, 0x00, 0xF0, 0xA7, 0xB2, 0xA8, 0x00, 0xE8, 0xB2, 0xAB, 0x00, 0xE8, 0xB3, 0x81, 0x00,
2748
  0xE8, 0xB4, 0x9B, 0x00, 0xE8, 0xB5, 0xB7, 0x00, 0xF0, 0xA7, 0xBC, 0xAF, 0x00, 0xF0, 0xA0, 0xA0,
2749
  0x84, 0x00, 0xE8, 0xB7, 0x8B, 0x00, 0xE8, 0xB6, 0xBC, 0x00, 0xE8, 0xB7, 0xB0, 0x00, 0xF0, 0xA0,
2750
  0xA3, 0x9E, 0x00, 0xE8, 0xBB, 0x94, 0x00, 0xF0, 0xA8, 0x97, 0x92, 0x00, 0xF0, 0xA8, 0x97, 0xAD,
2751
  0x00, 0xE9, 0x82, 0x94, 0x00, 0xE9, 0x83, 0xB1, 0x00, 0xE9, 0x84, 0x91, 0x00, 0xF0, 0xA8, 0x9C,
2752
  0xAE, 0x00, 0xE9, 0x84, 0x9B, 0x00, 0xE9, 0x88, 0xB8, 0x00, 0xE9, 0x8B, 0x97, 0x00, 0xE9, 0x8B,
2753
  0x98, 0x00, 0xE9, 0x89, 0xBC, 0x00, 0xE9, 0x8F, 0xB9, 0x00, 0xE9, 0x90, 0x95, 0x00, 0xF0, 0xA8,
2754
  0xAF, 0xBA, 0x00, 0xE9, 0x96, 0x8B, 0x00, 0xE4, 0xA6, 0x95, 0x00, 0xE9, 0x96, 0xB7, 0x00, 0xF0,
2755
  0xA8, 0xB5, 0xB7, 0x00, 0xE4, 0xA7, 0xA6, 0x00, 0xE9, 0x9B, 0x83, 0x00, 0xE5, 0xB6, 0xB2, 0x00,
2756
  0xE9, 0x9C, 0xA3, 0x00, 0xF0, 0xA9, 0x85, 0x85, 0x00, 0xF0, 0xA9, 0x88, 0x9A, 0x00, 0xE4, 0xA9,
2757
  0xAE, 0x00, 0xE4, 0xA9, 0xB6, 0x00, 0xE9, 0x9F, 0xA0, 0x00, 0xF0, 0xA9, 0x90, 0x8A, 0x00, 0xE4,
2758
  0xAA, 0xB2, 0x00, 0xF0, 0xA9, 0x92, 0x96, 0x00, 0xE9, 0xA0, 0xA9, 0x00, 0xF0, 0xA9, 0x96, 0xB6,
2759
  0x00, 0xE9, 0xA3, 0xA2, 0x00, 0xE4, 0xAC, 0xB3, 0x00, 0xE9, 0xA4, 0xA9, 0x00, 0xE9, 0xA6, 0xA7,
2760
  0x00, 0xE9, 0xA7, 0x82, 0x00, 0xE9, 0xA7, 0xBE, 0x00, 0xE4, 0xAF, 0x8E, 0x00, 0xF0, 0xA9, 0xAC,
2761
  0xB0, 0x00, 0xE9, 0xB1, 0x80, 0x00, 0xE9, 0xB3, 0xBD, 0x00, 0xE4, 0xB3, 0x8E, 0x00, 0xE4, 0xB3,
2762
  0xAD, 0x00, 0xE9, 0xB5, 0xA7, 0x00, 0xF0, 0xAA, 0x83, 0x8E, 0x00, 0xE4, 0xB3, 0xB8, 0x00, 0xF0,
2763
  0xAA, 0x84, 0x85, 0x00, 0xF0, 0xAA, 0x88, 0x8E, 0x00, 0xF0, 0xAA, 0x8A, 0x91, 0x00, 0xE4, 0xB5,
2764
  0x96, 0x00, 0xE9, 0xBB, 0xBE, 0x00, 0xE9, 0xBC, 0x85, 0x00, 0xE9, 0xBC, 0x8F, 0x00, 0xE9, 0xBC,
2765
  0x96, 0x00, 0xF0, 0xAA, 0x98, 0x80, 0x00
2766
};
2767
2768
} // namespace ada::idna
2769
#endif // ADA_IDNA_MAPPING_TABLE_H
2770
/* end file src/mapping_tables.cpp */
2771
2772
namespace ada::idna {
2773
2774
// --- O(1) two-level table lookup ---------------------------------------------
2775
//
2776
// Returns one of:
2777
//   IDNA_VALID      - keep code point in output unchanged
2778
//   IDNA_DISALLOWED - code point is not allowed (map() returns error)
2779
//   IDNA_IGNORED    - code point is ignored (index 0 = empty UTF-8 entry)
2780
//   other           - byte offset into idna_utf8_mappings[] (null-terminated)
2781
//
2782
// The two-level table covers [0, IDNA_LOW_RANGE_END).  All constants
2783
// (LOW_RANGE_END, HIGH_IGNORED_*) are generated from the IDNA table itself;
2784
// no Unicode version-specific values are hardcoded here.
2785
//
2786
435k
static uint16_t idna_lookup(uint32_t cp) noexcept {
2787
  // -- Two-level table covers the full active code-point range ---------------
2788
435k
  if (cp < IDNA_LOW_RANGE_END) {
2789
425k
    uint16_t ref = idna_stage1[cp >> IDNA_BLOCK_BITS];
2790
425k
    if (ref & IDNA_BOOL_FLAG) {
2791
      // Boolean block: one bit per code point, 1 = VALID, 0 = DISALLOWED.
2792
221k
      uint32_t bit_idx =
2793
221k
          static_cast<uint32_t>(ref & ~IDNA_BOOL_FLAG) * IDNA_BLOCK_SIZE +
2794
221k
          (cp & IDNA_BLOCK_MASK);
2795
221k
      bool is_valid = (idna_bool_blocks[bit_idx >> 6] >> (bit_idx & 63u)) & 1u;
2796
221k
      return is_valid ? IDNA_VALID : IDNA_DISALLOWED;
2797
221k
    }
2798
203k
    return idna_stage2[ref + (cp & IDNA_BLOCK_MASK)];
2799
425k
  }
2800
2801
  // -- Variation selectors supplement (U+E0100-U+E01EF): all ignored ---------
2802
  // Everything else above IDNA_LOW_RANGE_END is disallowed.
2803
10.2k
  if (cp >= IDNA_HIGH_IGNORED_START && cp < IDNA_HIGH_IGNORED_END) {
2804
2.87k
    return IDNA_IGNORED;
2805
2.87k
  }
2806
2807
7.37k
  return IDNA_DISALLOWED;
2808
10.2k
}
2809
2810
// --- Decode one UTF-8 code point ---------------------------------------------
2811
// Advances *ptr past the bytes consumed.  The mapping table is trusted to be
2812
// well-formed UTF-8, so no validity checking is performed.
2813
94.9k
static char32_t utf8_next(const uint8_t*& ptr) noexcept {
2814
94.9k
  uint8_t b0 = *ptr++;
2815
94.9k
  if (b0 < 0x80u) return static_cast<char32_t>(b0);
2816
65.3k
  if (b0 < 0xE0u) {
2817
39.4k
    uint32_t cp = (b0 & 0x1Fu) << 6;
2818
39.4k
    cp |= (*ptr++ & 0x3Fu);
2819
39.4k
    return static_cast<char32_t>(cp);
2820
39.4k
  }
2821
25.8k
  if (b0 < 0xF0u) {
2822
24.5k
    uint32_t cp = (b0 & 0x0Fu) << 12;
2823
24.5k
    cp |= ((*ptr++ & 0x3Fu) << 6);
2824
24.5k
    cp |= (*ptr++ & 0x3Fu);
2825
24.5k
    return static_cast<char32_t>(cp);
2826
24.5k
  }
2827
  // 4-byte sequence
2828
1.32k
  uint32_t cp = (b0 & 0x07u) << 18;
2829
1.32k
  cp |= ((*ptr++ & 0x3Fu) << 12);
2830
1.32k
  cp |= ((*ptr++ & 0x3Fu) << 6);
2831
1.32k
  cp |= (*ptr++ & 0x3Fu);
2832
1.32k
  return static_cast<char32_t>(cp);
2833
25.8k
}
2834
2835
// --- ASCII fast path
2836
// ----------------------------------------------------------
2837
113k
void ascii_map(char* input, size_t length) {
2838
340k
  auto broadcast = [](uint8_t v) -> uint64_t {
2839
340k
    return 0x101010101010101ull * v;
2840
340k
  };
2841
113k
  uint64_t broadcast_80 = broadcast(0x80);
2842
113k
  uint64_t broadcast_Ap = broadcast(128 - 'A');
2843
113k
  uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
2844
113k
  size_t i = 0;
2845
2846
189k
  for (; i + 7 < length; i += 8) {
2847
76.4k
    uint64_t word{};
2848
76.4k
    std::memcpy(&word, input + i, sizeof(word));
2849
76.4k
    word ^=
2850
76.4k
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
2851
76.4k
    std::memcpy(input + i, &word, sizeof(word));
2852
76.4k
  }
2853
113k
  if (i < length) {
2854
101k
    uint64_t word{};
2855
101k
    std::memcpy(&word, input + i, length - i);
2856
101k
    word ^=
2857
101k
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
2858
101k
    std::memcpy(input + i, &word, length - i);
2859
101k
  }
2860
113k
}
2861
2862
// --- IDNA map
2863
// ----------------------------------------------------------------- Maps each
2864
// code point according to IDNA processing. Returns an empty string on error
2865
// (disallowed code point encountered).
2866
81.0k
bool map(std::u32string_view input, std::u32string& out) {
2867
  //  [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap).
2868
  //  For each code point in the domain_name string, look up the status
2869
  //  value in Section 5, [IDNA Mapping
2870
  //  Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table),
2871
  //  and take the following actions:
2872
  //    * disallowed: Leave the code point unchanged in the string, and
2873
  //    record that there was an error.
2874
  //    * ignored: Remove the code point from the string.
2875
  //    * mapped: Replace the code point in the string by the value for
2876
  //    the mapping in Section 5, [IDNA Mapping
2877
  //    Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table).
2878
  //    * valid: Leave the code point unchanged in the string.
2879
81.0k
  out.clear();
2880
81.0k
  out.reserve(input.size());
2881
435k
  for (char32_t x : input) {
2882
435k
    uint16_t status = idna_lookup(static_cast<uint32_t>(x));
2883
435k
    if (status == IDNA_DISALLOWED) {
2884
9.31k
      return false;
2885
9.31k
    }
2886
426k
    if (status == IDNA_VALID) {
2887
371k
      out.push_back(x);
2888
371k
      continue;
2889
371k
    }
2890
    // IDNA_IGNORED (status==0) falls through: idna_utf8_mappings[0] == 0x00
2891
    // (null terminator), so the decode loop below produces nothing.
2892
2893
    // Mapped (or ignored): decode null-terminated UTF-8 from the mapping table.
2894
54.3k
    const uint8_t* ptr = idna_utf8_mappings + status;
2895
149k
    while (*ptr != 0) {
2896
94.9k
      out.push_back(utf8_next(ptr));
2897
94.9k
    }
2898
54.3k
  }
2899
71.7k
  return true;
2900
81.0k
}
2901
2902
0
std::u32string map(std::u32string_view input) {
2903
0
  std::u32string answer;
2904
0
  if (!map(input, answer)) {
2905
0
    return {};
2906
0
  }
2907
0
  return answer;
2908
0
}
2909
2910
}  // namespace ada::idna
2911
/* end file src/mapping.cpp */
2912
/* begin file src/normalization.cpp */
2913
/* begin file src/normalization_tables.cpp */
2914
// IDNA  17.0.0
2915
2916
// clang-format off
2917
#ifndef ADA_IDNA_NORMALIZATION_TABLES_H
2918
#define ADA_IDNA_NORMALIZATION_TABLES_H
2919
#include <cstdint>
2920
2921
/**
2922
 * Unicode Standard Annex #15
2923
 *
2924
 * UNICODE NORMALIZATION FORMS
2925
 * https://www.unicode.org/reports/tr15/
2926
 *
2927
 * See https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/data/data_norm.h for reference.
2928
 */
2929
2930
namespace ada::idna {
2931
2932
const uint8_t decomposition_index[4352] = {
2933
    0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  9,  10, 11, 12, 13, 14, 15, 7,  7,
2934
    7,  7,  7,  7,  7,  7,  7,  7,  16, 7,  17, 18, 19, 20, 21, 22, 23, 24, 7,
2935
    7,  7,  7,  7,  25, 7,  26, 27, 28, 29, 30, 31, 32, 33, 7,  7,  7,  7,  7,
2936
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2937
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2938
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2939
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2940
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2941
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  34, 35, 7,  7,  7,
2942
    36, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2943
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2944
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2945
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2946
    7,  7,  37, 38, 39, 40, 41, 42, 43, 7,  7,  7,  7,  7,  7,  7,  44, 7,  7,
2947
    7,  7,  7,  7,  7,  7,  45, 46, 7,  47, 48, 49, 7,  7,  7,  50, 7,  7,  7,
2948
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2949
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2950
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2951
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2952
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2953
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2954
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2955
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2956
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2957
    7,  7,  7,  7,  7,  7,  7,  7,  7,  51, 7,  52, 53, 54, 55, 56, 7,  7,  7,
2958
    7,  7,  7,  7,  7,  57, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  58,
2959
    59, 7,  60, 61, 62, 7,  7,  7,  7,  7,  7,  7,  7,  63, 7,  7,  7,  7,  7,
2960
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2961
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2962
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2963
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2964
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2965
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2966
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2967
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2968
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2969
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2970
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2971
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2972
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2973
    64, 65, 66, 7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2974
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2975
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2976
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2977
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2978
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2979
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2980
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2981
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2982
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2983
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2984
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2985
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2986
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2987
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2988
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2989
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2990
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2991
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2992
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2993
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2994
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2995
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2996
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2997
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2998
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
2999
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3000
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3001
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3002
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3003
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3004
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3005
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3006
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3007
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3008
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3009
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3010
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3011
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3012
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3013
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3014
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3015
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3016
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3017
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3018
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3019
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3020
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3021
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3022
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3023
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3024
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3025
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3026
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3027
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3028
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3029
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3030
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3031
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3032
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3033
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3034
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3035
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3036
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3037
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3038
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3039
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3040
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3041
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3042
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3043
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3044
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3045
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3046
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3047
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3048
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3049
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3050
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3051
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3052
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3053
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3054
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3055
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3056
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3057
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3058
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3059
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3060
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3061
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3062
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3063
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3064
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3065
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3066
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3067
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3068
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3069
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3070
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3071
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3072
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3073
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3074
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3075
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3076
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3077
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3078
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3079
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3080
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3081
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3082
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3083
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3084
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3085
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3086
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3087
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3088
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3089
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3090
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3091
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3092
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3093
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3094
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3095
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3096
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3097
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3098
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3099
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3100
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3101
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3102
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3103
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3104
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3105
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3106
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3107
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3108
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3109
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3110
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3111
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3112
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3113
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3114
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3115
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3116
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3117
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3118
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3119
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3120
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3121
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3122
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3123
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3124
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3125
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3126
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3127
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3128
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3129
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3130
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3131
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3132
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3133
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3134
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3135
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3136
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3137
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3138
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3139
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3140
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3141
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3142
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3143
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3144
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3145
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3146
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3147
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3148
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3149
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3150
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3151
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3152
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3153
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3154
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3155
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3156
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3157
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3158
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3159
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3160
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3161
    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
3162
    7};
3163
3164
const uint16_t decomposition_block[67][257] = {
3165
    {4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3166
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3167
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3168
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3169
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3170
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3171
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3172
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3173
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3174
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
3175
     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   5,   8,   8,   8,   8,
3176
     8,   8,   8,   9,   16,  17,  20,  20,  20,  20,  21,  28,  28,  29,  33,
3177
     37,  45,  48,  48,  49,  57,  61,  64,  65,  77,  89,  100, 100, 108, 116,
3178
     124, 132, 140, 148, 148, 156, 164, 172, 180, 188, 196, 204, 212, 220, 220,
3179
     228, 236, 244, 252, 260, 268, 268, 268, 276, 284, 292, 300, 308, 308, 308,
3180
     316, 324, 332, 340, 348, 356, 356, 364, 372, 380, 388, 396, 404, 412, 420,
3181
     428, 428, 436, 444, 452, 460, 468, 476, 476, 476, 484, 492, 500, 508, 516,
3182
     516, 524},
3183
    {524,  532,  540,  548,  556,  564,  572,  580,  588,  596,  604,  612,
3184
     620,  628,  636,  644,  652,  652,  652,  660,  668,  676,  684,  692,
3185
     700,  708,  716,  724,  732,  740,  748,  756,  764,  772,  780,  788,
3186
     796,  804,  812,  812,  812,  820,  828,  836,  844,  852,  860,  868,
3187
     876,  884,  885,  893,  900,  908,  916,  924,  932,  932,  940,  948,
3188
     956,  964,  972,  981,  989,  996,  996,  996,  1004, 1012, 1020, 1028,
3189
     1036, 1045, 1052, 1052, 1052, 1060, 1068, 1076, 1084, 1092, 1100, 1100,
3190
     1100, 1108, 1116, 1124, 1132, 1140, 1148, 1156, 1164, 1172, 1180, 1188,
3191
     1196, 1204, 1212, 1220, 1228, 1236, 1244, 1244, 1244, 1252, 1260, 1268,
3192
     1276, 1284, 1292, 1300, 1308, 1316, 1324, 1332, 1340, 1348, 1356, 1364,
3193
     1372, 1380, 1388, 1396, 1404, 1412, 1420, 1429, 1432, 1432, 1432, 1432,
3194
     1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
3195
     1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
3196
     1432, 1432, 1432, 1432, 1432, 1440, 1448, 1448, 1448, 1448, 1448, 1448,
3197
     1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1456, 1464, 1464, 1464,
3198
     1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464,
3199
     1464, 1464, 1464, 1464, 1465, 1477, 1489, 1501, 1509, 1517, 1525, 1533,
3200
     1541, 1548, 1556, 1564, 1572, 1580, 1588, 1596, 1604, 1612, 1624, 1636,
3201
     1648, 1660, 1672, 1684, 1696, 1708, 1708, 1720, 1732, 1744, 1756, 1764,
3202
     1772, 1772, 1772, 1780, 1788, 1796, 1804, 1812, 1820, 1832, 1844, 1852,
3203
     1860, 1869, 1877, 1885, 1892, 1900, 1908, 1908, 1908, 1916, 1924, 1936,
3204
     1948, 1956, 1964, 1972, 1980},
3205
    {1980, 1988, 1996, 2004, 2012, 2020, 2028, 2036, 2044, 2052, 2060, 2068,
3206
     2076, 2084, 2092, 2100, 2108, 2116, 2124, 2132, 2140, 2148, 2156, 2164,
3207
     2172, 2180, 2188, 2196, 2204, 2204, 2204, 2212, 2220, 2220, 2220, 2220,
3208
     2220, 2220, 2220, 2228, 2236, 2244, 2252, 2264, 2276, 2288, 2300, 2308,
3209
     2316, 2328, 2340, 2348, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3210
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3211
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3212
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3213
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3214
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3215
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3216
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3217
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3218
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3219
     2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2357, 2361, 2365, 2369,
3220
     2373, 2377, 2381, 2385, 2389, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3221
     2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3222
     2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3223
     2393, 2401, 2409, 2417, 2425, 2433, 2440, 2440, 2441, 2445, 2449, 2453,
3224
     2457, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3225
     2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3226
     2460, 2460, 2460, 2460, 2460},
3227
    {2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3228
     2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3229
     2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3230
     2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3231
     2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3232
     2460, 2460, 2460, 2460, 2460, 2464, 2468, 2468, 2472, 2480, 2480, 2480,
3233
     2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,
3234
     2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,
3235
     2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,
3236
     2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2484, 2484, 2484,
3237
     2484, 2484, 2485, 2492, 2492, 2492, 2492, 2496, 2496, 2496, 2496, 2496,
3238
     2497, 2506, 2512, 2520, 2524, 2532, 2540, 2548, 2548, 2556, 2556, 2564,
3239
     2572, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,
3240
     2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,
3241
     2584, 2584, 2584, 2592, 2600, 2608, 2616, 2624, 2632, 2644, 2644, 2644,
3242
     2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644,
3243
     2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2652,
3244
     2660, 2668, 2676, 2684, 2685, 2689, 2693, 2698, 2706, 2713, 2717, 2720,
3245
     2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,
3246
     2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,
3247
     2721, 2725, 2729, 2732, 2733, 2737, 2740, 2740, 2740, 2741, 2744, 2744,
3248
     2744, 2744, 2744, 2744, 2744},
3249
    {2744, 2752, 2760, 2760, 2768, 2768, 2768, 2768, 2776, 2776, 2776, 2776,
3250
     2776, 2784, 2792, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800,
3251
     2800, 2800, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,
3252
     2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,
3253
     2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2816, 2816,
3254
     2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816,
3255
     2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2824, 2832, 2832,
3256
     2840, 2840, 2840, 2840, 2848, 2848, 2848, 2848, 2848, 2856, 2864, 2872,
3257
     2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872,
3258
     2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2880,
3259
     2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3260
     2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3261
     2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3262
     2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3263
     2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3264
     2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3265
     2888, 2888, 2896, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904,
3266
     2904, 2904, 2904, 2904, 2904, 2912, 2920, 2928, 2936, 2936, 2936, 2944,
3267
     2952, 2952, 2952, 2960, 2968, 2976, 2984, 2992, 3000, 3000, 3000, 3008,
3268
     3016, 3024, 3032, 3040, 3048, 3048, 3048, 3056, 3064, 3072, 3080, 3088,
3269
     3096, 3104, 3112, 3120, 3128, 3136, 3144, 3144, 3144, 3152, 3160, 3160,
3270
     3160, 3160, 3160, 3160, 3160},
3271
    {3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3272
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3273
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3274
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3275
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3276
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3277
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3278
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3279
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3280
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3281
     3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3282
     3160, 3160, 3160, 3161, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3283
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3284
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3285
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3286
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3287
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3288
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3289
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3290
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3291
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3292
     3168, 3168, 3168, 3168, 3168},
3293
    {3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3294
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3295
     3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3176,
3296
     3184, 3192, 3200, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3297
     3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3298
     3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3299
     3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3300
     3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3301
     3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3302
     3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3209, 3217, 3225,
3303
     3233, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3304
     3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3305
     3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3306
     3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3307
     3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3308
     3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3309
     3240, 3248, 3248, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256,
3310
     3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3264, 3264, 3264, 3264,
3311
     3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3312
     3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3313
     3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3314
     3264, 3264, 3264, 3264, 3264},
3315
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3316
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3317
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3318
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3319
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3320
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3321
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3322
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3323
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3324
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3325
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3326
    {3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3327
     3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3328
     3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3329
     3264, 3264, 3264, 3264, 3264, 3264, 3272, 3272, 3272, 3272, 3272, 3272,
3330
     3272, 3272, 3280, 3280, 3280, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3331
     3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3332
     3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3333
     3288, 3288, 3288, 3288, 3288, 3296, 3304, 3312, 3320, 3328, 3336, 3344,
3334
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3335
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3336
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3337
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3338
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3339
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3340
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3341
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3342
     3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3343
     3360, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368,
3344
     3368, 3368, 3368, 3368, 3368, 3376, 3384, 3384, 3392, 3392, 3392, 3392,
3345
     3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3346
     3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3347
     3392, 3392, 3392, 3392, 3392},
3348
    {3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3349
     3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3350
     3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3351
     3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3352
     3392, 3392, 3392, 3392, 3400, 3400, 3400, 3408, 3408, 3408, 3408, 3408,
3353
     3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,
3354
     3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,
3355
     3408, 3408, 3408, 3408, 3408, 3408, 3416, 3424, 3432, 3432, 3432, 3440,
3356
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3357
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3358
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3359
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3360
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3361
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3362
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3363
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3364
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3365
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3366
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3367
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3368
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3369
     3440, 3440, 3440, 3440, 3440},
3370
    {3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3371
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3372
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3373
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3374
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3375
     3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3376
     3440, 3448, 3448, 3448, 3456, 3464, 3464, 3464, 3464, 3464, 3464, 3464,
3377
     3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3472, 3480, 3480,
3378
     3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3379
     3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3380
     3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3381
     3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3382
     3480, 3480, 3480, 3480, 3480, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3383
     3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3384
     3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3385
     3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3386
     3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3496,
3387
     3504, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3388
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3389
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3390
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3391
     3512, 3512, 3512, 3512, 3512},
3392
    {3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3393
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3394
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3395
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3396
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3397
     3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3398
     3512, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3399
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3400
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3401
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3402
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3403
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3404
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3405
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3406
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3407
     3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3408
     3520, 3528, 3528, 3528, 3528, 3528, 3528, 3528, 3536, 3544, 3544, 3552,
3409
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3410
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3411
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3412
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3413
     3564, 3564, 3564, 3564, 3564},
3414
    {3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3415
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3416
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3417
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3418
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3419
     3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3420
     3564, 3564, 3564, 3572, 3580, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3421
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3422
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3423
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3424
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3425
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3426
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3427
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3428
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3429
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3430
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3431
     3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3432
     3588, 3588, 3588, 3596, 3596, 3604, 3616, 3624, 3624, 3624, 3624, 3624,
3433
     3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3434
     3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3435
     3624, 3624, 3624, 3624, 3624},
3436
    {3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3437
     3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3438
     3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3439
     3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3440
     3624, 3624, 3624, 3625, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3441
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3442
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3443
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3444
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3445
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3446
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3447
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3448
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3449
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3450
     3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3633,
3451
     3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3452
     3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3453
     3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3454
     3640, 3640, 3640, 3640, 3641, 3649, 3656, 3656, 3656, 3656, 3656, 3656,
3455
     3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3456
     3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3457
     3656, 3656, 3656, 3656, 3656},
3458
    {3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3459
     3657, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3460
     3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3461
     3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3462
     3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3463
     3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3668, 3668, 3668, 3668,
3464
     3668, 3668, 3668, 3668, 3668, 3668, 3676, 3676, 3676, 3676, 3676, 3684,
3465
     3684, 3684, 3684, 3684, 3692, 3692, 3692, 3692, 3692, 3700, 3700, 3700,
3466
     3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3708, 3708,
3467
     3708, 3708, 3708, 3708, 3708, 3708, 3708, 3708, 3716, 3716, 3724, 3733,
3468
     3744, 3753, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3772, 3772,
3469
     3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772,
3470
     3772, 3772, 3772, 3772, 3780, 3780, 3780, 3780, 3780, 3780, 3780, 3780,
3471
     3780, 3780, 3788, 3788, 3788, 3788, 3788, 3796, 3796, 3796, 3796, 3796,
3472
     3804, 3804, 3804, 3804, 3804, 3812, 3812, 3812, 3812, 3812, 3812, 3812,
3473
     3812, 3812, 3812, 3812, 3812, 3812, 3820, 3820, 3820, 3820, 3820, 3820,
3474
     3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3475
     3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3476
     3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3477
     3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3478
     3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3479
     3820, 3820, 3820, 3820, 3820},
3480
    {3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3481
     3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3482
     3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3483
     3820, 3820, 3820, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3484
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3485
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3486
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3487
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3488
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3489
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3490
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3491
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3492
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3493
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3494
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3495
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3496
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3497
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3498
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3499
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3500
     3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3501
     3829, 3832, 3832, 3832, 3832},
3502
    {3832, 3832, 3832, 3832, 3832, 3832, 3832, 3840, 3840, 3848, 3848, 3856,
3503
     3856, 3864, 3864, 3872, 3872, 3872, 3872, 3880, 3880, 3880, 3880, 3880,
3504
     3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3505
     3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3506
     3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3507
     3888, 3888, 3896, 3896, 3896, 3904, 3912, 3912, 3920, 3920, 3920, 3920,
3508
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3509
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3510
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3511
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3512
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3513
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3514
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3515
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3516
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3517
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3518
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3519
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3520
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3521
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3522
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3523
     3920, 3920, 3920, 3920, 3920},
3524
    {3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3525
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3526
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3527
     3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3921, 3925, 3929, 3932,
3528
     3933, 3937, 3941, 3945, 3949, 3953, 3957, 3961, 3965, 3969, 3973, 3976,
3529
     3977, 3981, 3985, 3989, 3993, 3997, 4001, 4005, 4009, 4013, 4017, 4021,
3530
     4025, 4029, 4033, 4037, 4041, 4045, 4048, 4049, 4053, 4057, 4061, 4065,
3531
     4069, 4073, 4077, 4081, 4085, 4089, 4093, 4097, 4101, 4105, 4109, 4113,
3532
     4117, 4121, 4125, 4129, 4133, 4137, 4141, 4145, 4149, 4153, 4157, 4160,
3533
     4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160,
3534
     4161, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,
3535
     4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,
3536
     4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4165,
3537
     4169, 4173, 4177, 4181, 4185, 4189, 4193, 4197, 4201, 4205, 4209, 4213,
3538
     4217, 4221, 4225, 4229, 4233, 4237, 4241, 4245, 4249, 4253, 4257, 4261,
3539
     4265, 4269, 4273, 4277, 4281, 4285, 4289, 4293, 4297, 4301, 4305, 4309,
3540
     4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3541
     4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3542
     4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3543
     4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3544
     4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3545
     4312, 4312, 4312, 4312, 4312},
3546
    {4312, 4320, 4328, 4336, 4344, 4352, 4360, 4368, 4376, 4388, 4400, 4408,
3547
     4416, 4424, 4432, 4440, 4448, 4456, 4464, 4472, 4480, 4492, 4504, 4516,
3548
     4528, 4536, 4544, 4552, 4560, 4572, 4584, 4592, 4600, 4608, 4616, 4624,
3549
     4632, 4640, 4648, 4656, 4664, 4672, 4680, 4688, 4696, 4704, 4712, 4724,
3550
     4736, 4744, 4752, 4760, 4768, 4776, 4784, 4792, 4800, 4812, 4824, 4832,
3551
     4840, 4848, 4856, 4864, 4872, 4880, 4888, 4896, 4904, 4912, 4920, 4928,
3552
     4936, 4944, 4952, 4960, 4968, 4980, 4992, 5004, 5016, 5028, 5040, 5052,
3553
     5064, 5072, 5080, 5088, 5096, 5104, 5112, 5120, 5128, 5140, 5152, 5160,
3554
     5168, 5176, 5184, 5192, 5200, 5212, 5224, 5236, 5248, 5260, 5272, 5280,
3555
     5288, 5296, 5304, 5312, 5320, 5328, 5336, 5344, 5352, 5360, 5368, 5376,
3556
     5384, 5396, 5408, 5420, 5432, 5440, 5448, 5456, 5464, 5472, 5480, 5488,
3557
     5496, 5504, 5512, 5520, 5528, 5536, 5544, 5552, 5560, 5568, 5576, 5584,
3558
     5592, 5600, 5608, 5616, 5624, 5632, 5640, 5648, 5656, 5664, 5673, 5682,
3559
     5688, 5688, 5688, 5688, 5688, 5696, 5704, 5712, 5720, 5732, 5744, 5756,
3560
     5768, 5780, 5792, 5804, 5816, 5828, 5840, 5852, 5864, 5876, 5888, 5900,
3561
     5912, 5924, 5936, 5948, 5960, 5968, 5976, 5984, 5992, 6000, 6008, 6020,
3562
     6032, 6044, 6056, 6068, 6080, 6092, 6104, 6116, 6128, 6136, 6144, 6152,
3563
     6160, 6168, 6176, 6184, 6192, 6204, 6216, 6228, 6240, 6252, 6264, 6276,
3564
     6288, 6300, 6312, 6324, 6336, 6348, 6360, 6372, 6384, 6396, 6408, 6420,
3565
     6432, 6440, 6448, 6456, 6464, 6476, 6488, 6500, 6512, 6524, 6536, 6548,
3566
     6560, 6572, 6584, 6592, 6600, 6608, 6616, 6624, 6632, 6640, 6648, 6648,
3567
     6648, 6648, 6648, 6648, 6648},
3568
    {6648, 6656, 6664, 6676, 6688, 6700, 6712, 6724, 6736, 6744, 6752, 6764,
3569
     6776, 6788, 6800, 6812, 6824, 6832, 6840, 6852, 6864, 6876, 6888, 6888,
3570
     6888, 6896, 6904, 6916, 6928, 6940, 6952, 6952, 6952, 6960, 6968, 6980,
3571
     6992, 7004, 7016, 7028, 7040, 7048, 7056, 7068, 7080, 7092, 7104, 7116,
3572
     7128, 7136, 7144, 7156, 7168, 7180, 7192, 7204, 7216, 7224, 7232, 7244,
3573
     7256, 7268, 7280, 7292, 7304, 7312, 7320, 7332, 7344, 7356, 7368, 7368,
3574
     7368, 7376, 7384, 7396, 7408, 7420, 7432, 7432, 7432, 7440, 7448, 7460,
3575
     7472, 7484, 7496, 7508, 7520, 7520, 7528, 7528, 7540, 7540, 7552, 7552,
3576
     7564, 7572, 7580, 7592, 7604, 7616, 7628, 7640, 7652, 7660, 7668, 7680,
3577
     7692, 7704, 7716, 7728, 7740, 7748, 7756, 7764, 7772, 7780, 7788, 7796,
3578
     7804, 7812, 7820, 7828, 7836, 7844, 7852, 7852, 7852, 7864, 7876, 7892,
3579
     7908, 7924, 7940, 7956, 7972, 7984, 7996, 8012, 8028, 8044, 8060, 8076,
3580
     8092, 8104, 8116, 8132, 8148, 8164, 8180, 8196, 8212, 8224, 8236, 8252,
3581
     8268, 8284, 8300, 8316, 8332, 8344, 8356, 8372, 8388, 8404, 8420, 8436,
3582
     8452, 8464, 8476, 8492, 8508, 8524, 8540, 8556, 8572, 8580, 8588, 8600,
3583
     8608, 8620, 8620, 8628, 8640, 8648, 8656, 8664, 8672, 8681, 8688, 8693,
3584
     8701, 8710, 8716, 8728, 8736, 8748, 8748, 8756, 8768, 8776, 8784, 8792,
3585
     8800, 8810, 8818, 8826, 8832, 8840, 8848, 8860, 8872, 8872, 8872, 8880,
3586
     8892, 8900, 8908, 8916, 8924, 8926, 8934, 8942, 8948, 8956, 8964, 8976,
3587
     8988, 8996, 9004, 9012, 9024, 9032, 9040, 9048, 9056, 9066, 9074, 9080,
3588
     9084, 9084, 9084, 9096, 9104, 9116, 9116, 9124, 9136, 9144, 9152, 9160,
3589
     9168, 9178, 9181, 9188, 9190},
3590
    {9190, 9194, 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9232,
3591
     9232, 9232, 9232, 9232, 9232, 9233, 9236, 9236, 9236, 9236, 9236, 9237,
3592
     9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244,
3593
     9245, 9249, 9257, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9269,
3594
     9272, 9272, 9272, 9273, 9281, 9292, 9293, 9301, 9312, 9312, 9312, 9312,
3595
     9313, 9320, 9321, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9329,
3596
     9337, 9345, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352,
3597
     9352, 9352, 9352, 9353, 9368, 9368, 9368, 9368, 9368, 9368, 9368, 9369,
3598
     9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372,
3599
     9372, 9372, 9372, 9372, 9373, 9377, 9380, 9380, 9381, 9385, 9389, 9393,
3600
     9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, 9433, 9437, 9441,
3601
     9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, 9481, 9485, 9488,
3602
     9489, 9493, 9497, 9501, 9505, 9509, 9513, 9517, 9521, 9525, 9529, 9533,
3603
     9537, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540,
3604
     9541, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3605
     9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3606
     9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3607
     9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3608
     9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3609
     9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3610
     9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3611
     9548, 9548, 9548, 9548, 9549},
3612
    {9549,  9561,  9573,  9577,  9584,  9585,  9597,  9609,  9612,  9613,
3613
     9621,  9625,  9629,  9633,  9637,  9641,  9645,  9649,  9653,  9657,
3614
     9660,  9661,  9665,  9672,  9672,  9673,  9677,  9681,  9685,  9689,
3615
     9692,  9692,  9693,  9701,  9713,  9720,  9721,  9724,  9724,  9728,
3616
     9729,  9732,  9732,  9736,  9745,  9749,  9752,  9753,  9757,  9761,
3617
     9764,  9765,  9769,  9773,  9777,  9781,  9785,  9789,  9792,  9793,
3618
     9805,  9809,  9813,  9817,  9821,  9824,  9824,  9824,  9824,  9825,
3619
     9829,  9833,  9837,  9841,  9844,  9844,  9844,  9844,  9844,  9844,
3620
     9845,  9857,  9869,  9885,  9897,  9909,  9921,  9933,  9945,  9957,
3621
     9969,  9981,  9993,  10005, 10017, 10029, 10037, 10041, 10049, 10061,
3622
     10069, 10073, 10081, 10093, 10109, 10117, 10121, 10129, 10141, 10145,
3623
     10149, 10153, 10157, 10161, 10169, 10181, 10189, 10193, 10201, 10213,
3624
     10229, 10237, 10241, 10249, 10261, 10265, 10269, 10273, 10276, 10276,
3625
     10276, 10276, 10276, 10276, 10276, 10276, 10276, 10277, 10288, 10288,
3626
     10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288,
3627
     10288, 10288, 10288, 10288, 10288, 10296, 10304, 10304, 10304, 10304,
3628
     10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304,
3629
     10304, 10304, 10304, 10304, 10304, 10312, 10312, 10312, 10312, 10312,
3630
     10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,
3631
     10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,
3632
     10312, 10312, 10312, 10312, 10312, 10312, 10320, 10328, 10336, 10336,
3633
     10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3634
     10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3635
     10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3636
     10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3637
     10336, 10336, 10336, 10336, 10336, 10336, 10336},
3638
    {10336, 10336, 10336, 10336, 10336, 10344, 10344, 10344, 10344, 10344,
3639
     10352, 10352, 10352, 10360, 10360, 10360, 10360, 10360, 10360, 10360,
3640
     10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360,
3641
     10360, 10360, 10360, 10360, 10360, 10360, 10360, 10368, 10368, 10376,
3642
     10376, 10376, 10376, 10376, 10377, 10385, 10396, 10397, 10405, 10416,
3643
     10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416,
3644
     10416, 10416, 10416, 10416, 10416, 10416, 10424, 10424, 10424, 10432,
3645
     10432, 10432, 10440, 10440, 10448, 10448, 10448, 10448, 10448, 10448,
3646
     10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448,
3647
     10448, 10448, 10448, 10448, 10448, 10448, 10448, 10456, 10456, 10464,
3648
     10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464,
3649
     10472, 10480, 10488, 10496, 10504, 10504, 10504, 10512, 10520, 10520,
3650
     10520, 10528, 10536, 10536, 10536, 10536, 10536, 10536, 10536, 10544,
3651
     10552, 10552, 10552, 10560, 10568, 10568, 10568, 10576, 10584, 10584,
3652
     10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3653
     10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3654
     10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3655
     10584, 10584, 10584, 10592, 10600, 10608, 10616, 10616, 10616, 10616,
3656
     10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3657
     10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3658
     10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3659
     10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3660
     10616, 10616, 10616, 10616, 10616, 10624, 10632, 10640, 10648, 10648,
3661
     10648, 10648, 10648, 10648, 10648, 10656, 10664, 10672, 10680, 10680,
3662
     10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3663
     10680, 10680, 10680, 10680, 10680, 10680, 10680},
3664
    {10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3665
     10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3666
     10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3667
     10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3668
     10680, 10680, 10684, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3669
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3670
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3671
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3672
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3673
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3674
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3675
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3676
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3677
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3678
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3679
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3680
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3681
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3682
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3683
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3684
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3685
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3686
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3687
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3688
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3689
     10688, 10688, 10688, 10688, 10688, 10688, 10688},
3690
    {10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3691
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3692
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3693
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3694
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3695
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3696
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3697
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3698
     10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3699
     10688, 10688, 10688, 10688, 10688, 10688, 10689, 10693, 10697, 10701,
3700
     10705, 10709, 10713, 10717, 10721, 10725, 10733, 10741, 10749, 10757,
3701
     10765, 10773, 10781, 10789, 10797, 10805, 10813, 10825, 10837, 10849,
3702
     10861, 10873, 10885, 10897, 10909, 10921, 10937, 10953, 10969, 10985,
3703
     11001, 11017, 11033, 11049, 11065, 11081, 11097, 11105, 11113, 11121,
3704
     11129, 11137, 11145, 11153, 11161, 11169, 11181, 11193, 11205, 11217,
3705
     11229, 11241, 11253, 11265, 11277, 11289, 11301, 11313, 11325, 11337,
3706
     11349, 11361, 11373, 11385, 11397, 11409, 11421, 11433, 11445, 11457,
3707
     11469, 11481, 11493, 11505, 11517, 11529, 11541, 11553, 11565, 11577,
3708
     11589, 11601, 11613, 11617, 11621, 11625, 11629, 11633, 11637, 11641,
3709
     11645, 11649, 11653, 11657, 11661, 11665, 11669, 11673, 11677, 11681,
3710
     11685, 11689, 11693, 11697, 11701, 11705, 11709, 11713, 11717, 11721,
3711
     11725, 11729, 11733, 11737, 11741, 11745, 11749, 11753, 11757, 11761,
3712
     11765, 11769, 11773, 11777, 11781, 11785, 11789, 11793, 11797, 11801,
3713
     11805, 11809, 11813, 11817, 11821, 11824, 11824, 11824, 11824, 11824,
3714
     11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824,
3715
     11824, 11824, 11824, 11824, 11824, 11824, 11824},
3716
    {11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824,
3717
     11824, 11824, 11825, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3718
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3719
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3720
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3721
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3722
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3723
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3724
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3725
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3726
     11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3727
     11840, 11840, 11840, 11840, 11840, 11840, 11841, 11853, 11861, 11872,
3728
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3729
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3730
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3731
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3732
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3733
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3734
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3735
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3736
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3737
     11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3738
     11872, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3739
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3740
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3741
     11880, 11880, 11880, 11880, 11880, 11880, 11880},
3742
    {11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3743
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3744
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3745
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3746
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3747
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3748
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3749
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3750
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3751
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3752
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3753
     11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3754
     11880, 11880, 11880, 11880, 11881, 11885, 11888, 11888, 11888, 11888,
3755
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3756
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3757
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3758
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3759
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3760
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3761
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3762
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3763
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3764
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3765
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3766
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3767
     11888, 11888, 11888, 11888, 11888, 11888, 11888},
3768
    {11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3769
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3770
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3771
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3772
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3773
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3774
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3775
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3776
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3777
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3778
     11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3779
     11888, 11889, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3780
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3781
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3782
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3783
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3784
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3785
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3786
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3787
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3788
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3789
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3790
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3791
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3792
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3793
     11892, 11892, 11892, 11892, 11892, 11892, 11892},
3794
    {11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3795
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3796
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3797
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3798
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3799
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3800
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3801
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3802
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3803
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3804
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3805
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3806
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3807
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3808
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3809
     11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11893,
3810
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3811
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3812
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3813
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3814
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3815
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3816
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3817
     11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3818
     11896, 11896, 11896, 11897, 11900, 11900, 11900, 11900, 11900, 11900,
3819
     11900, 11900, 11900, 11900, 11900, 11900, 11901},
3820
    {11901, 11905, 11909, 11913, 11917, 11921, 11925, 11929, 11933, 11937,
3821
     11941, 11945, 11949, 11953, 11957, 11961, 11965, 11969, 11973, 11977,
3822
     11981, 11985, 11989, 11993, 11997, 12001, 12005, 12009, 12013, 12017,
3823
     12021, 12025, 12029, 12033, 12037, 12041, 12045, 12049, 12053, 12057,
3824
     12061, 12065, 12069, 12073, 12077, 12081, 12085, 12089, 12093, 12097,
3825
     12101, 12105, 12109, 12113, 12117, 12121, 12125, 12129, 12133, 12137,
3826
     12141, 12145, 12149, 12153, 12157, 12161, 12165, 12169, 12173, 12177,
3827
     12181, 12185, 12189, 12193, 12197, 12201, 12205, 12209, 12213, 12217,
3828
     12221, 12225, 12229, 12233, 12237, 12241, 12245, 12249, 12253, 12257,
3829
     12261, 12265, 12269, 12273, 12277, 12281, 12285, 12289, 12293, 12297,
3830
     12301, 12305, 12309, 12313, 12317, 12321, 12325, 12329, 12333, 12337,
3831
     12341, 12345, 12349, 12353, 12357, 12361, 12365, 12369, 12373, 12377,
3832
     12381, 12385, 12389, 12393, 12397, 12401, 12405, 12409, 12413, 12417,
3833
     12421, 12425, 12429, 12433, 12437, 12441, 12445, 12449, 12453, 12457,
3834
     12461, 12465, 12469, 12473, 12477, 12481, 12485, 12489, 12493, 12497,
3835
     12501, 12505, 12509, 12513, 12517, 12521, 12525, 12529, 12533, 12537,
3836
     12541, 12545, 12549, 12553, 12557, 12561, 12565, 12569, 12573, 12577,
3837
     12581, 12585, 12589, 12593, 12597, 12601, 12605, 12609, 12613, 12617,
3838
     12621, 12625, 12629, 12633, 12637, 12641, 12645, 12649, 12653, 12657,
3839
     12661, 12665, 12669, 12673, 12677, 12681, 12685, 12689, 12693, 12697,
3840
     12701, 12705, 12709, 12713, 12717, 12721, 12725, 12729, 12733, 12737,
3841
     12741, 12745, 12749, 12753, 12756, 12756, 12756, 12756, 12756, 12756,
3842
     12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3843
     12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3844
     12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3845
     12756, 12756, 12756, 12756, 12756, 12756, 12757},
3846
    {12757, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3847
     12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3848
     12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3849
     12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3850
     12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3851
     12760, 12760, 12760, 12760, 12761, 12764, 12765, 12769, 12773, 12776,
3852
     12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776,
3853
     12776, 12776, 12776, 12776, 12776, 12776, 12776, 12784, 12784, 12792,
3854
     12792, 12800, 12800, 12808, 12808, 12816, 12816, 12824, 12824, 12832,
3855
     12832, 12840, 12840, 12848, 12848, 12856, 12856, 12864, 12864, 12872,
3856
     12872, 12872, 12880, 12880, 12888, 12888, 12896, 12896, 12896, 12896,
3857
     12896, 12896, 12896, 12904, 12912, 12912, 12920, 12928, 12928, 12936,
3858
     12944, 12944, 12952, 12960, 12960, 12968, 12976, 12976, 12976, 12976,
3859
     12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976,
3860
     12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12984,
3861
     12984, 12984, 12984, 12984, 12984, 12985, 12993, 13000, 13000, 13009,
3862
     13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016,
3863
     13016, 13016, 13016, 13024, 13024, 13032, 13032, 13040, 13040, 13048,
3864
     13048, 13056, 13056, 13064, 13064, 13072, 13072, 13080, 13080, 13088,
3865
     13088, 13096, 13096, 13104, 13104, 13112, 13112, 13112, 13120, 13120,
3866
     13128, 13128, 13136, 13136, 13136, 13136, 13136, 13136, 13136, 13144,
3867
     13152, 13152, 13160, 13168, 13168, 13176, 13184, 13184, 13192, 13200,
3868
     13200, 13208, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,
3869
     13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,
3870
     13216, 13216, 13216, 13216, 13216, 13224, 13224, 13224, 13232, 13240,
3871
     13248, 13256, 13256, 13256, 13256, 13265, 13272},
3872
    {13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3873
     13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3874
     13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3875
     13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3876
     13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13273,
3877
     13277, 13281, 13285, 13289, 13293, 13297, 13301, 13305, 13309, 13313,
3878
     13317, 13321, 13325, 13329, 13333, 13337, 13341, 13345, 13349, 13353,
3879
     13357, 13361, 13365, 13369, 13373, 13377, 13381, 13385, 13389, 13393,
3880
     13397, 13401, 13405, 13409, 13413, 13417, 13421, 13425, 13429, 13433,
3881
     13437, 13441, 13445, 13449, 13453, 13457, 13461, 13465, 13469, 13473,
3882
     13477, 13481, 13485, 13489, 13493, 13497, 13501, 13505, 13509, 13513,
3883
     13517, 13521, 13525, 13529, 13533, 13537, 13541, 13545, 13549, 13553,
3884
     13557, 13561, 13565, 13569, 13573, 13577, 13581, 13585, 13589, 13593,
3885
     13597, 13601, 13605, 13609, 13613, 13617, 13621, 13625, 13629, 13633,
3886
     13637, 13641, 13645, 13648, 13648, 13648, 13649, 13653, 13657, 13661,
3887
     13665, 13669, 13673, 13677, 13681, 13685, 13689, 13693, 13697, 13701,
3888
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3889
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3890
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3891
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3892
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3893
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3894
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3895
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3896
     13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3897
     13704, 13704, 13704, 13704, 13704, 13704, 13705},
3898
    {13705, 13717, 13729, 13741, 13753, 13765, 13777, 13789, 13801, 13813,
3899
     13825, 13837, 13849, 13861, 13873, 13889, 13905, 13921, 13937, 13953,
3900
     13969, 13985, 14001, 14017, 14033, 14049, 14065, 14081, 14097, 14113,
3901
     14141, 14164, 14165, 14177, 14189, 14201, 14213, 14225, 14237, 14249,
3902
     14261, 14273, 14285, 14297, 14309, 14321, 14333, 14345, 14357, 14369,
3903
     14381, 14393, 14405, 14417, 14429, 14441, 14453, 14465, 14477, 14489,
3904
     14501, 14513, 14525, 14537, 14549, 14561, 14573, 14585, 14597, 14601,
3905
     14605, 14609, 14612, 14612, 14612, 14612, 14612, 14612, 14612, 14612,
3906
     14613, 14625, 14633, 14641, 14649, 14657, 14665, 14673, 14681, 14689,
3907
     14697, 14705, 14713, 14721, 14729, 14737, 14745, 14749, 14753, 14757,
3908
     14761, 14765, 14769, 14773, 14777, 14781, 14785, 14789, 14793, 14797,
3909
     14801, 14809, 14817, 14825, 14833, 14841, 14849, 14857, 14865, 14873,
3910
     14881, 14889, 14897, 14905, 14913, 14933, 14949, 14956, 14957, 14961,
3911
     14965, 14969, 14973, 14977, 14981, 14985, 14989, 14993, 14997, 15001,
3912
     15005, 15009, 15013, 15017, 15021, 15025, 15029, 15033, 15037, 15041,
3913
     15045, 15049, 15053, 15057, 15061, 15065, 15069, 15073, 15077, 15081,
3914
     15085, 15089, 15093, 15097, 15101, 15105, 15109, 15113, 15117, 15121,
3915
     15125, 15129, 15133, 15137, 15141, 15145, 15149, 15153, 15161, 15169,
3916
     15177, 15185, 15193, 15201, 15209, 15217, 15225, 15233, 15241, 15249,
3917
     15257, 15265, 15273, 15281, 15289, 15297, 15305, 15313, 15321, 15329,
3918
     15337, 15345, 15357, 15369, 15381, 15389, 15401, 15409, 15421, 15425,
3919
     15429, 15433, 15437, 15441, 15445, 15449, 15453, 15457, 15461, 15465,
3920
     15469, 15473, 15477, 15481, 15485, 15489, 15493, 15497, 15501, 15505,
3921
     15509, 15513, 15517, 15521, 15525, 15529, 15533, 15537, 15541, 15545,
3922
     15549, 15553, 15557, 15561, 15565, 15569, 15573, 15577, 15581, 15585,
3923
     15589, 15593, 15597, 15601, 15605, 15609, 15617},
3924
    {15617, 15637, 15653, 15673, 15685, 15705, 15717, 15729, 15753, 15769,
3925
     15781, 15793, 15805, 15821, 15837, 15853, 15869, 15885, 15901, 15917,
3926
     15941, 15949, 15973, 15997, 16017, 16033, 16057, 16081, 16097, 16109,
3927
     16121, 16137, 16153, 16173, 16193, 16205, 16217, 16233, 16245, 16257,
3928
     16265, 16273, 16285, 16297, 16321, 16337, 16357, 16381, 16397, 16409,
3929
     16421, 16445, 16461, 16485, 16497, 16517, 16529, 16545, 16557, 16573,
3930
     16593, 16609, 16629, 16645, 16653, 16673, 16685, 16697, 16713, 16725,
3931
     16737, 16749, 16769, 16785, 16793, 16817, 16829, 16849, 16865, 16881,
3932
     16893, 16905, 16921, 16929, 16945, 16965, 16973, 16997, 17009, 17017,
3933
     17025, 17033, 17041, 17049, 17057, 17065, 17073, 17081, 17089, 17101,
3934
     17113, 17125, 17137, 17149, 17161, 17173, 17185, 17197, 17209, 17221,
3935
     17233, 17245, 17257, 17269, 17281, 17289, 17297, 17309, 17317, 17325,
3936
     17333, 17345, 17357, 17365, 17373, 17381, 17389, 17397, 17413, 17421,
3937
     17429, 17437, 17445, 17453, 17461, 17469, 17477, 17489, 17505, 17513,
3938
     17521, 17529, 17537, 17545, 17553, 17561, 17573, 17585, 17597, 17609,
3939
     17617, 17625, 17633, 17641, 17649, 17657, 17665, 17673, 17681, 17689,
3940
     17701, 17713, 17721, 17733, 17745, 17757, 17765, 17777, 17789, 17805,
3941
     17813, 17825, 17837, 17849, 17861, 17881, 17905, 17913, 17921, 17929,
3942
     17937, 17945, 17953, 17961, 17969, 17977, 17985, 17993, 18001, 18009,
3943
     18017, 18025, 18033, 18041, 18049, 18065, 18073, 18081, 18089, 18105,
3944
     18117, 18125, 18133, 18141, 18149, 18157, 18165, 18173, 18181, 18189,
3945
     18197, 18209, 18217, 18225, 18237, 18249, 18257, 18273, 18285, 18293,
3946
     18301, 18309, 18317, 18329, 18341, 18349, 18357, 18365, 18373, 18381,
3947
     18389, 18397, 18405, 18413, 18425, 18437, 18449, 18461, 18473, 18485,
3948
     18497, 18509, 18521, 18533, 18545, 18557, 18569, 18581, 18593, 18605,
3949
     18617, 18629, 18641, 18653, 18665, 18677, 18688},
3950
    {18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3951
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3952
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3953
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3954
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3955
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3956
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3957
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3958
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3959
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3960
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3961
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3962
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3963
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3964
     18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3965
     18688, 18688, 18688, 18688, 18688, 18688, 18689, 18693, 18696, 18696,
3966
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3967
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3968
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3969
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3970
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3971
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3972
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3973
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3974
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3975
     18696, 18696, 18696, 18696, 18696, 18696, 18696},
3976
    {18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3977
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3978
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3979
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3980
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3981
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3982
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3983
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3984
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3985
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3986
     18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3987
     18696, 18696, 18697, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3988
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3989
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3990
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3991
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3992
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3993
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3994
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3995
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3996
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3997
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3998
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3999
     18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
4000
     18700, 18700, 18701, 18705, 18709, 18712, 18712, 18712, 18713, 18717,
4001
     18720, 18720, 18720, 18720, 18720, 18720, 18720},
4002
    {18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4003
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4004
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4005
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4006
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4007
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4008
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4009
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4010
     18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
4011
     18720, 18720, 18721, 18725, 18729, 18733, 18736, 18736, 18736, 18736,
4012
     18736, 18736, 18736, 18736, 18736, 18737, 18740, 18740, 18740, 18740,
4013
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4014
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4015
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4016
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4017
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4018
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4019
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4020
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4021
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4022
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4023
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4024
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4025
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4026
     18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
4027
     18740, 18740, 18740, 18740, 18740, 18740, 18740},
4028
    {18740, 18744, 18748, 18752, 18756, 18760, 18764, 18768, 18772, 18776,
4029
     18780, 18784, 18788, 18792, 18796, 18800, 18804, 18808, 18812, 18816,
4030
     18820, 18824, 18828, 18832, 18836, 18840, 18844, 18848, 18852, 18856,
4031
     18860, 18864, 18868, 18872, 18876, 18880, 18884, 18888, 18892, 18896,
4032
     18900, 18904, 18908, 18912, 18916, 18920, 18924, 18928, 18932, 18936,
4033
     18940, 18944, 18948, 18952, 18956, 18960, 18964, 18968, 18972, 18976,
4034
     18980, 18984, 18988, 18992, 18996, 19000, 19004, 19008, 19012, 19016,
4035
     19020, 19024, 19028, 19032, 19036, 19040, 19044, 19048, 19052, 19056,
4036
     19060, 19064, 19068, 19072, 19076, 19080, 19084, 19088, 19092, 19096,
4037
     19100, 19104, 19108, 19112, 19116, 19120, 19124, 19128, 19132, 19136,
4038
     19140, 19144, 19148, 19152, 19156, 19160, 19164, 19168, 19172, 19176,
4039
     19180, 19184, 19188, 19192, 19196, 19200, 19204, 19208, 19212, 19216,
4040
     19220, 19224, 19228, 19232, 19236, 19240, 19244, 19248, 19252, 19256,
4041
     19260, 19264, 19268, 19272, 19276, 19280, 19284, 19288, 19292, 19296,
4042
     19300, 19304, 19308, 19312, 19316, 19320, 19324, 19328, 19332, 19336,
4043
     19340, 19344, 19348, 19352, 19356, 19360, 19364, 19368, 19372, 19376,
4044
     19380, 19384, 19388, 19392, 19396, 19400, 19404, 19408, 19412, 19416,
4045
     19420, 19424, 19428, 19432, 19436, 19440, 19444, 19448, 19452, 19456,
4046
     19460, 19464, 19468, 19472, 19476, 19480, 19484, 19488, 19492, 19496,
4047
     19500, 19504, 19508, 19512, 19516, 19520, 19524, 19528, 19532, 19536,
4048
     19540, 19544, 19548, 19552, 19556, 19560, 19564, 19568, 19572, 19576,
4049
     19580, 19584, 19588, 19592, 19596, 19600, 19604, 19608, 19612, 19616,
4050
     19620, 19624, 19628, 19632, 19636, 19640, 19644, 19648, 19652, 19656,
4051
     19660, 19664, 19668, 19672, 19676, 19680, 19684, 19688, 19692, 19696,
4052
     19700, 19704, 19708, 19712, 19716, 19720, 19724, 19728, 19732, 19736,
4053
     19740, 19744, 19748, 19752, 19756, 19760, 19764},
4054
    {19764, 19768, 19772, 19776, 19780, 19784, 19788, 19792, 19796, 19800,
4055
     19804, 19808, 19812, 19816, 19820, 19820, 19820, 19824, 19824, 19828,
4056
     19828, 19828, 19832, 19836, 19840, 19844, 19848, 19852, 19856, 19860,
4057
     19864, 19868, 19868, 19872, 19872, 19876, 19876, 19876, 19880, 19884,
4058
     19884, 19884, 19884, 19888, 19892, 19896, 19900, 19904, 19908, 19912,
4059
     19916, 19920, 19924, 19928, 19932, 19936, 19940, 19944, 19948, 19952,
4060
     19956, 19960, 19964, 19968, 19972, 19976, 19980, 19984, 19988, 19992,
4061
     19996, 20000, 20004, 20008, 20012, 20016, 20020, 20024, 20028, 20032,
4062
     20036, 20040, 20044, 20048, 20052, 20056, 20060, 20064, 20068, 20072,
4063
     20076, 20080, 20084, 20088, 20092, 20096, 20100, 20104, 20108, 20112,
4064
     20116, 20120, 20124, 20128, 20132, 20136, 20140, 20144, 20148, 20152,
4065
     20156, 20156, 20156, 20160, 20164, 20168, 20172, 20176, 20180, 20184,
4066
     20188, 20192, 20196, 20200, 20204, 20208, 20212, 20216, 20220, 20224,
4067
     20228, 20232, 20236, 20240, 20244, 20248, 20252, 20256, 20260, 20264,
4068
     20268, 20272, 20276, 20280, 20284, 20288, 20292, 20296, 20300, 20304,
4069
     20308, 20312, 20316, 20320, 20324, 20328, 20332, 20336, 20340, 20344,
4070
     20348, 20352, 20356, 20360, 20364, 20368, 20372, 20376, 20380, 20384,
4071
     20388, 20392, 20396, 20400, 20404, 20408, 20412, 20416, 20420, 20424,
4072
     20428, 20432, 20436, 20440, 20444, 20448, 20452, 20456, 20460, 20464,
4073
     20468, 20472, 20476, 20480, 20484, 20488, 20492, 20496, 20500, 20504,
4074
     20508, 20512, 20516, 20520, 20524, 20528, 20532, 20536, 20540, 20544,
4075
     20548, 20552, 20556, 20560, 20564, 20568, 20572, 20576, 20580, 20580,
4076
     20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4077
     20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4078
     20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4079
     20580, 20580, 20580, 20580, 20580, 20580, 20581},
4080
    {20581, 20589, 20597, 20605, 20617, 20629, 20637, 20644, 20644, 20644,
4081
     20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20645,
4082
     20653, 20661, 20669, 20677, 20684, 20684, 20684, 20684, 20684, 20684,
4083
     20692, 20692, 20701, 20705, 20709, 20713, 20717, 20721, 20725, 20729,
4084
     20733, 20737, 20740, 20748, 20756, 20768, 20780, 20788, 20796, 20804,
4085
     20812, 20820, 20828, 20836, 20844, 20852, 20852, 20860, 20868, 20876,
4086
     20884, 20892, 20892, 20900, 20900, 20908, 20916, 20916, 20924, 20932,
4087
     20932, 20940, 20948, 20956, 20964, 20972, 20980, 20988, 20996, 21005,
4088
     21013, 21017, 21021, 21025, 21029, 21033, 21037, 21041, 21045, 21049,
4089
     21053, 21057, 21061, 21065, 21069, 21073, 21077, 21081, 21085, 21089,
4090
     21093, 21097, 21101, 21105, 21109, 21113, 21117, 21121, 21125, 21129,
4091
     21133, 21137, 21141, 21145, 21149, 21153, 21157, 21161, 21165, 21169,
4092
     21173, 21177, 21181, 21185, 21189, 21193, 21197, 21201, 21205, 21209,
4093
     21213, 21217, 21221, 21225, 21229, 21233, 21237, 21241, 21245, 21249,
4094
     21253, 21257, 21261, 21265, 21269, 21273, 21277, 21281, 21285, 21289,
4095
     21293, 21297, 21301, 21305, 21309, 21313, 21317, 21321, 21325, 21329,
4096
     21333, 21337, 21341, 21345, 21349, 21357, 21365, 21369, 21373, 21377,
4097
     21381, 21385, 21389, 21393, 21397, 21401, 21405, 21413, 21420, 21420,
4098
     21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4099
     21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4100
     21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4101
     21420, 21421, 21425, 21429, 21433, 21437, 21441, 21445, 21449, 21453,
4102
     21457, 21461, 21469, 21473, 21477, 21481, 21485, 21489, 21493, 21497,
4103
     21501, 21505, 21509, 21513, 21517, 21529, 21541, 21553, 21565, 21577,
4104
     21589, 21601, 21613, 21625, 21637, 21649, 21661, 21673, 21685, 21697,
4105
     21709, 21721, 21733, 21737, 21741, 21745, 21749},
4106
    {21749, 21761, 21773, 21785, 21797, 21809, 21817, 21825, 21833, 21841,
4107
     21849, 21857, 21865, 21873, 21881, 21889, 21897, 21905, 21913, 21921,
4108
     21929, 21937, 21945, 21953, 21961, 21969, 21977, 21985, 21993, 22001,
4109
     22009, 22017, 22025, 22033, 22041, 22049, 22057, 22065, 22073, 22081,
4110
     22089, 22097, 22105, 22113, 22121, 22129, 22137, 22145, 22153, 22161,
4111
     22169, 22177, 22185, 22193, 22201, 22209, 22217, 22225, 22233, 22241,
4112
     22249, 22257, 22265, 22273, 22281, 22289, 22297, 22305, 22313, 22321,
4113
     22329, 22337, 22345, 22353, 22361, 22369, 22377, 22385, 22393, 22401,
4114
     22409, 22417, 22425, 22433, 22441, 22449, 22457, 22465, 22473, 22481,
4115
     22489, 22497, 22505, 22513, 22521, 22533, 22545, 22557, 22569, 22581,
4116
     22593, 22605, 22617, 22629, 22641, 22653, 22665, 22673, 22681, 22689,
4117
     22697, 22705, 22713, 22721, 22729, 22737, 22745, 22753, 22761, 22769,
4118
     22777, 22785, 22793, 22801, 22809, 22817, 22825, 22833, 22841, 22849,
4119
     22857, 22865, 22873, 22881, 22889, 22897, 22905, 22913, 22921, 22929,
4120
     22937, 22945, 22953, 22961, 22969, 22977, 22985, 22993, 23001, 23009,
4121
     23017, 23025, 23037, 23049, 23061, 23073, 23085, 23093, 23101, 23109,
4122
     23117, 23125, 23133, 23141, 23149, 23157, 23165, 23173, 23181, 23189,
4123
     23197, 23205, 23213, 23221, 23229, 23237, 23245, 23253, 23261, 23269,
4124
     23277, 23285, 23293, 23301, 23309, 23317, 23325, 23333, 23341, 23349,
4125
     23357, 23365, 23373, 23381, 23389, 23397, 23405, 23413, 23421, 23429,
4126
     23437, 23445, 23453, 23461, 23469, 23477, 23485, 23493, 23501, 23509,
4127
     23517, 23525, 23533, 23541, 23549, 23557, 23565, 23573, 23581, 23589,
4128
     23597, 23605, 23613, 23621, 23633, 23645, 23653, 23661, 23669, 23677,
4129
     23685, 23693, 23701, 23709, 23717, 23725, 23733, 23741, 23749, 23757,
4130
     23765, 23773, 23781, 23793, 23805, 23817, 23825, 23833, 23841, 23849,
4131
     23857, 23865, 23873, 23881, 23889, 23897, 23905},
4132
    {23905, 23913, 23921, 23929, 23937, 23945, 23953, 23961, 23969, 23977,
4133
     23985, 23993, 24001, 24009, 24017, 24025, 24033, 24041, 24049, 24057,
4134
     24065, 24073, 24081, 24089, 24097, 24105, 24113, 24121, 24129, 24137,
4135
     24145, 24153, 24161, 24169, 24177, 24185, 24193, 24201, 24209, 24217,
4136
     24225, 24233, 24241, 24249, 24257, 24265, 24273, 24281, 24289, 24297,
4137
     24305, 24313, 24321, 24329, 24337, 24345, 24353, 24361, 24369, 24377,
4138
     24385, 24393, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,
4139
     24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,
4140
     24401, 24413, 24425, 24437, 24449, 24461, 24473, 24485, 24497, 24509,
4141
     24521, 24533, 24545, 24557, 24569, 24581, 24593, 24605, 24617, 24629,
4142
     24641, 24653, 24665, 24677, 24689, 24701, 24713, 24725, 24737, 24749,
4143
     24761, 24773, 24785, 24797, 24809, 24821, 24833, 24845, 24857, 24869,
4144
     24881, 24893, 24905, 24917, 24929, 24941, 24953, 24965, 24977, 24989,
4145
     25001, 25013, 25025, 25037, 25049, 25061, 25073, 25085, 25097, 25109,
4146
     25121, 25133, 25145, 25157, 25168, 25168, 25169, 25181, 25193, 25205,
4147
     25217, 25229, 25241, 25253, 25265, 25277, 25289, 25301, 25313, 25325,
4148
     25337, 25349, 25361, 25373, 25385, 25397, 25409, 25421, 25433, 25445,
4149
     25457, 25469, 25481, 25493, 25505, 25517, 25529, 25541, 25553, 25565,
4150
     25577, 25589, 25601, 25613, 25625, 25637, 25649, 25661, 25673, 25685,
4151
     25697, 25709, 25721, 25733, 25745, 25757, 25769, 25781, 25793, 25805,
4152
     25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4153
     25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4154
     25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4155
     25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4156
     25817, 25829, 25841, 25857, 25873, 25889, 25905, 25921, 25937, 25953,
4157
     25965, 26037, 26069, 26084, 26084, 26084, 26084},
4158
    {26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084,
4159
     26084, 26084, 26084, 26084, 26084, 26084, 26085, 26089, 26093, 26097,
4160
     26101, 26105, 26109, 26113, 26117, 26121, 26132, 26132, 26132, 26132,
4161
     26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132,
4162
     26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26133, 26141,
4163
     26145, 26149, 26153, 26157, 26161, 26165, 26169, 26173, 26177, 26181,
4164
     26185, 26189, 26193, 26197, 26201, 26205, 26209, 26213, 26217, 26220,
4165
     26220, 26221, 26225, 26229, 26237, 26245, 26253, 26261, 26265, 26269,
4166
     26273, 26277, 26281, 26284, 26285, 26289, 26293, 26297, 26301, 26305,
4167
     26309, 26313, 26317, 26321, 26325, 26329, 26333, 26337, 26341, 26345,
4168
     26349, 26353, 26357, 26360, 26361, 26365, 26369, 26373, 26376, 26376,
4169
     26376, 26376, 26377, 26385, 26393, 26400, 26401, 26408, 26409, 26417,
4170
     26425, 26433, 26441, 26449, 26457, 26465, 26473, 26481, 26489, 26493,
4171
     26501, 26509, 26517, 26525, 26533, 26541, 26549, 26557, 26565, 26573,
4172
     26581, 26589, 26593, 26597, 26601, 26605, 26609, 26613, 26617, 26621,
4173
     26625, 26629, 26633, 26637, 26641, 26645, 26649, 26653, 26657, 26661,
4174
     26665, 26669, 26673, 26677, 26681, 26685, 26689, 26693, 26697, 26701,
4175
     26705, 26709, 26713, 26717, 26721, 26725, 26729, 26733, 26737, 26741,
4176
     26745, 26749, 26753, 26757, 26761, 26765, 26769, 26773, 26777, 26781,
4177
     26785, 26789, 26793, 26797, 26801, 26805, 26809, 26813, 26817, 26821,
4178
     26825, 26829, 26833, 26837, 26841, 26845, 26849, 26853, 26857, 26861,
4179
     26865, 26869, 26873, 26877, 26881, 26885, 26889, 26893, 26897, 26901,
4180
     26905, 26909, 26913, 26917, 26921, 26925, 26929, 26933, 26937, 26941,
4181
     26945, 26949, 26953, 26957, 26961, 26965, 26969, 26973, 26977, 26981,
4182
     26985, 26989, 26993, 26997, 27001, 27005, 27017, 27029, 27041, 27053,
4183
     27065, 27077, 27085, 27092, 27092, 27092, 27092},
4184
    {27092, 27093, 27097, 27101, 27105, 27109, 27113, 27117, 27121, 27125,
4185
     27129, 27133, 27137, 27141, 27145, 27149, 27153, 27157, 27161, 27165,
4186
     27169, 27173, 27177, 27181, 27185, 27189, 27193, 27197, 27201, 27205,
4187
     27209, 27213, 27217, 27221, 27225, 27229, 27233, 27237, 27241, 27245,
4188
     27249, 27253, 27257, 27261, 27265, 27269, 27273, 27277, 27281, 27285,
4189
     27289, 27293, 27297, 27301, 27305, 27309, 27313, 27317, 27321, 27325,
4190
     27329, 27333, 27337, 27341, 27345, 27349, 27353, 27357, 27361, 27365,
4191
     27369, 27373, 27377, 27381, 27385, 27389, 27393, 27397, 27401, 27405,
4192
     27409, 27413, 27417, 27421, 27425, 27429, 27433, 27437, 27441, 27445,
4193
     27449, 27453, 27457, 27461, 27465, 27469, 27473, 27477, 27481, 27485,
4194
     27489, 27493, 27497, 27501, 27505, 27509, 27513, 27517, 27521, 27525,
4195
     27529, 27533, 27537, 27541, 27545, 27549, 27553, 27557, 27561, 27565,
4196
     27569, 27573, 27577, 27581, 27585, 27589, 27593, 27597, 27601, 27605,
4197
     27609, 27613, 27617, 27621, 27625, 27629, 27633, 27637, 27641, 27645,
4198
     27649, 27653, 27657, 27661, 27665, 27669, 27673, 27677, 27681, 27685,
4199
     27689, 27693, 27697, 27701, 27705, 27709, 27713, 27717, 27721, 27725,
4200
     27729, 27733, 27737, 27741, 27745, 27749, 27753, 27757, 27761, 27765,
4201
     27769, 27773, 27777, 27781, 27785, 27789, 27793, 27797, 27801, 27805,
4202
     27809, 27813, 27817, 27821, 27825, 27829, 27833, 27837, 27841, 27845,
4203
     27849, 27852, 27852, 27852, 27853, 27857, 27861, 27865, 27869, 27873,
4204
     27876, 27876, 27877, 27881, 27885, 27889, 27893, 27897, 27900, 27900,
4205
     27901, 27905, 27909, 27913, 27917, 27921, 27924, 27924, 27925, 27929,
4206
     27933, 27936, 27936, 27936, 27937, 27941, 27945, 27949, 27957, 27961,
4207
     27965, 27968, 27969, 27973, 27977, 27981, 27985, 27989, 27993, 27996,
4208
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4209
     27996, 27996, 27996, 27996, 27996, 27996, 27996},
4210
    {27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4211
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4212
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4213
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4214
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4215
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4216
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4217
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4218
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4219
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4220
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4221
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4222
     27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27997,
4223
     28001, 28005, 28009, 28013, 28016, 28017, 28021, 28025, 28029, 28033,
4224
     28037, 28041, 28045, 28049, 28053, 28057, 28061, 28065, 28069, 28073,
4225
     28077, 28081, 28085, 28089, 28093, 28097, 28101, 28105, 28109, 28113,
4226
     28117, 28121, 28125, 28129, 28133, 28137, 28141, 28145, 28149, 28153,
4227
     28157, 28161, 28165, 28169, 28173, 28177, 28181, 28184, 28185, 28189,
4228
     28193, 28197, 28201, 28205, 28209, 28213, 28217, 28220, 28220, 28220,
4229
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4230
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4231
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4232
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4233
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4234
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4235
     28220, 28220, 28220, 28220, 28220, 28220, 28220},
4236
    {28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4237
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4238
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4239
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4240
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4241
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4242
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4243
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4244
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4245
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4246
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4247
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4248
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4249
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4250
     28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4251
     28220, 28220, 28220, 28220, 28220, 28228, 28228, 28236, 28236, 28236,
4252
     28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236,
4253
     28236, 28236, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4254
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4255
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4256
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4257
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4258
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4259
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4260
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4261
     28244, 28244, 28244, 28244, 28244, 28244, 28244},
4262
    {28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4263
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4264
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4265
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4266
     28244, 28244, 28244, 28244, 28244, 28244, 28244, 28252, 28260, 28260,
4267
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4268
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4269
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4270
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4271
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4272
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4273
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4274
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4275
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4276
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4277
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4278
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4279
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4280
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4281
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4282
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4283
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4284
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4285
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4286
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4287
     28260, 28260, 28260, 28260, 28260, 28260, 28260},
4288
    {28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4289
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4290
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4291
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4292
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4293
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4294
     28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4295
     28260, 28260, 28260, 28260, 28260, 28260, 28268, 28276, 28276, 28276,
4296
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4297
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4298
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4299
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4300
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4301
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4302
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4303
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4304
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4305
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4306
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4307
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4308
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4309
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4310
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4311
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4312
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4313
     28276, 28276, 28276, 28276, 28276, 28276, 28276},
4314
    {28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4315
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4316
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4317
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4318
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4319
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4320
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4321
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4322
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4323
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4324
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4325
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4326
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4327
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4328
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4329
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4330
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4331
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4332
     28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28284, 28292,
4333
     28292, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4334
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4335
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4336
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4337
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4338
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4339
     28300, 28300, 28300, 28300, 28300, 28300, 28300},
4340
    {28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4341
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4342
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4343
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4344
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4345
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4346
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4347
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4348
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4349
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4350
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4351
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4352
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4353
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4354
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4355
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4356
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4357
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4358
     28300, 28300, 28300, 28300, 28300, 28300, 28300, 28308, 28316, 28316,
4359
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4360
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4361
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4362
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4363
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4364
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4365
     28316, 28316, 28316, 28316, 28316, 28316, 28316},
4366
    {28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4367
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4368
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4369
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4370
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4371
     28316, 28316, 28316, 28316, 28316, 28316, 28316, 28324, 28324, 28324,
4372
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4373
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4374
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4375
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4376
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4377
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4378
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4379
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4380
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4381
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4382
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4383
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4384
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4385
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4386
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4387
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4388
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4389
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4390
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4391
     28324, 28324, 28324, 28324, 28324, 28324, 28324},
4392
    {28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4393
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4394
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4395
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4396
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4397
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4398
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4399
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4400
     28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4401
     28324, 28324, 28324, 28324, 28324, 28332, 28340, 28352, 28364, 28376,
4402
     28388, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4403
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4404
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4405
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4406
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4407
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4408
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4409
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4410
     28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28408, 28416,
4411
     28428, 28440, 28452, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4412
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4413
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4414
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4415
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4416
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4417
     28464, 28464, 28464, 28464, 28464, 28464, 28464},
4418
    {28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4419
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4420
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4421
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4422
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4423
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4424
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4425
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4426
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4427
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4428
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4429
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4430
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4431
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4432
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4433
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4434
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4435
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4436
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4437
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4438
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4439
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4440
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4441
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4442
     28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4443
     28464, 28464, 28464, 28464, 28464, 28464, 28465},
4444
    {28465, 28469, 28473, 28477, 28481, 28485, 28489, 28493, 28497, 28501,
4445
     28505, 28509, 28513, 28517, 28521, 28525, 28529, 28533, 28537, 28541,
4446
     28545, 28549, 28553, 28557, 28561, 28565, 28569, 28573, 28577, 28581,
4447
     28585, 28589, 28593, 28597, 28601, 28605, 28609, 28613, 28617, 28621,
4448
     28625, 28629, 28633, 28637, 28641, 28645, 28649, 28653, 28657, 28661,
4449
     28665, 28669, 28673, 28677, 28681, 28685, 28689, 28693, 28697, 28701,
4450
     28705, 28709, 28713, 28717, 28721, 28725, 28729, 28733, 28737, 28741,
4451
     28745, 28749, 28753, 28757, 28761, 28765, 28769, 28773, 28777, 28781,
4452
     28785, 28789, 28793, 28797, 28801, 28804, 28805, 28809, 28813, 28817,
4453
     28821, 28825, 28829, 28833, 28837, 28841, 28845, 28849, 28853, 28857,
4454
     28861, 28865, 28869, 28873, 28877, 28881, 28885, 28889, 28893, 28897,
4455
     28901, 28905, 28909, 28913, 28917, 28921, 28925, 28929, 28933, 28937,
4456
     28941, 28945, 28949, 28953, 28957, 28961, 28965, 28969, 28973, 28977,
4457
     28981, 28985, 28989, 28993, 28997, 29001, 29005, 29009, 29013, 29017,
4458
     29021, 29025, 29029, 29033, 29037, 29041, 29045, 29049, 29053, 29057,
4459
     29061, 29065, 29069, 29073, 29077, 29081, 29085, 29088, 29089, 29093,
4460
     29096, 29096, 29097, 29100, 29100, 29101, 29105, 29108, 29108, 29109,
4461
     29113, 29117, 29121, 29124, 29125, 29129, 29133, 29137, 29141, 29145,
4462
     29149, 29153, 29157, 29161, 29165, 29169, 29172, 29173, 29176, 29177,
4463
     29181, 29185, 29189, 29193, 29197, 29201, 29204, 29205, 29209, 29213,
4464
     29217, 29221, 29225, 29229, 29233, 29237, 29241, 29245, 29249, 29253,
4465
     29257, 29261, 29265, 29269, 29273, 29277, 29281, 29285, 29289, 29293,
4466
     29297, 29301, 29305, 29309, 29313, 29317, 29321, 29325, 29329, 29333,
4467
     29337, 29341, 29345, 29349, 29353, 29357, 29361, 29365, 29369, 29373,
4468
     29377, 29381, 29385, 29389, 29393, 29397, 29401, 29405, 29409, 29413,
4469
     29417, 29421, 29425, 29429, 29433, 29437, 29441},
4470
    {29441, 29445, 29449, 29453, 29457, 29461, 29464, 29465, 29469, 29473,
4471
     29477, 29480, 29480, 29481, 29485, 29489, 29493, 29497, 29501, 29505,
4472
     29509, 29512, 29513, 29517, 29521, 29525, 29529, 29533, 29537, 29540,
4473
     29541, 29545, 29549, 29553, 29557, 29561, 29565, 29569, 29573, 29577,
4474
     29581, 29585, 29589, 29593, 29597, 29601, 29605, 29609, 29613, 29617,
4475
     29621, 29625, 29629, 29633, 29637, 29641, 29645, 29649, 29652, 29653,
4476
     29657, 29661, 29665, 29668, 29669, 29673, 29677, 29681, 29685, 29688,
4477
     29689, 29692, 29692, 29692, 29693, 29697, 29701, 29705, 29709, 29713,
4478
     29717, 29720, 29721, 29725, 29729, 29733, 29737, 29741, 29745, 29749,
4479
     29753, 29757, 29761, 29765, 29769, 29773, 29777, 29781, 29785, 29789,
4480
     29793, 29797, 29801, 29805, 29809, 29813, 29817, 29821, 29825, 29829,
4481
     29833, 29837, 29841, 29845, 29849, 29853, 29857, 29861, 29865, 29869,
4482
     29873, 29877, 29881, 29885, 29889, 29893, 29897, 29901, 29905, 29909,
4483
     29913, 29917, 29921, 29925, 29929, 29933, 29937, 29941, 29945, 29949,
4484
     29953, 29957, 29961, 29965, 29969, 29973, 29977, 29981, 29985, 29989,
4485
     29993, 29997, 30001, 30005, 30009, 30013, 30017, 30021, 30025, 30029,
4486
     30033, 30037, 30041, 30045, 30049, 30053, 30057, 30061, 30065, 30069,
4487
     30073, 30077, 30081, 30085, 30089, 30093, 30097, 30101, 30105, 30109,
4488
     30113, 30117, 30121, 30125, 30129, 30133, 30137, 30141, 30145, 30149,
4489
     30153, 30157, 30161, 30165, 30169, 30173, 30177, 30181, 30185, 30189,
4490
     30193, 30197, 30201, 30205, 30209, 30213, 30217, 30221, 30225, 30229,
4491
     30233, 30237, 30241, 30245, 30249, 30253, 30257, 30261, 30265, 30269,
4492
     30273, 30277, 30281, 30285, 30289, 30293, 30297, 30301, 30305, 30309,
4493
     30313, 30317, 30321, 30325, 30329, 30333, 30337, 30341, 30345, 30349,
4494
     30353, 30357, 30361, 30365, 30369, 30373, 30377, 30381, 30385, 30389,
4495
     30393, 30397, 30401, 30405, 30409, 30413, 30417},
4496
    {30417, 30421, 30425, 30429, 30433, 30437, 30441, 30445, 30449, 30453,
4497
     30457, 30461, 30465, 30469, 30473, 30477, 30481, 30485, 30489, 30493,
4498
     30497, 30501, 30505, 30509, 30513, 30517, 30521, 30525, 30529, 30533,
4499
     30537, 30541, 30545, 30549, 30553, 30557, 30561, 30565, 30569, 30573,
4500
     30577, 30581, 30585, 30589, 30593, 30597, 30601, 30605, 30609, 30613,
4501
     30617, 30621, 30625, 30629, 30633, 30637, 30641, 30645, 30649, 30653,
4502
     30657, 30661, 30665, 30669, 30673, 30677, 30681, 30685, 30689, 30693,
4503
     30697, 30701, 30705, 30709, 30713, 30717, 30721, 30725, 30729, 30733,
4504
     30737, 30741, 30745, 30749, 30753, 30757, 30761, 30765, 30769, 30773,
4505
     30777, 30781, 30785, 30789, 30793, 30797, 30801, 30805, 30809, 30813,
4506
     30817, 30821, 30825, 30829, 30833, 30837, 30841, 30845, 30849, 30853,
4507
     30857, 30861, 30865, 30869, 30873, 30877, 30881, 30885, 30889, 30893,
4508
     30897, 30901, 30905, 30909, 30913, 30917, 30921, 30925, 30929, 30933,
4509
     30937, 30941, 30945, 30949, 30953, 30957, 30961, 30965, 30969, 30973,
4510
     30977, 30981, 30985, 30989, 30993, 30997, 31001, 31005, 31009, 31013,
4511
     31017, 31021, 31025, 31029, 31033, 31037, 31041, 31045, 31049, 31053,
4512
     31057, 31061, 31065, 31069, 31073, 31077, 31080, 31080, 31081, 31085,
4513
     31089, 31093, 31097, 31101, 31105, 31109, 31113, 31117, 31121, 31125,
4514
     31129, 31133, 31137, 31141, 31145, 31149, 31153, 31157, 31161, 31165,
4515
     31169, 31173, 31177, 31181, 31185, 31189, 31193, 31197, 31201, 31205,
4516
     31209, 31213, 31217, 31221, 31225, 31229, 31233, 31237, 31241, 31245,
4517
     31249, 31253, 31257, 31261, 31265, 31269, 31273, 31277, 31281, 31285,
4518
     31289, 31293, 31297, 31301, 31305, 31309, 31313, 31317, 31321, 31325,
4519
     31329, 31333, 31337, 31341, 31345, 31349, 31353, 31357, 31361, 31365,
4520
     31369, 31373, 31377, 31381, 31385, 31389, 31393, 31397, 31401, 31405,
4521
     31409, 31413, 31417, 31421, 31425, 31429, 31433},
4522
    {31433, 31437, 31441, 31445, 31449, 31453, 31457, 31461, 31465, 31469,
4523
     31473, 31477, 31481, 31485, 31489, 31493, 31497, 31501, 31505, 31509,
4524
     31513, 31517, 31521, 31525, 31529, 31533, 31537, 31541, 31545, 31549,
4525
     31553, 31557, 31561, 31565, 31569, 31573, 31577, 31581, 31585, 31589,
4526
     31593, 31597, 31601, 31605, 31609, 31613, 31617, 31621, 31625, 31629,
4527
     31633, 31637, 31641, 31645, 31649, 31653, 31657, 31661, 31665, 31669,
4528
     31673, 31677, 31681, 31685, 31689, 31693, 31697, 31701, 31705, 31709,
4529
     31713, 31717, 31721, 31725, 31729, 31733, 31737, 31741, 31745, 31749,
4530
     31753, 31757, 31761, 31765, 31769, 31773, 31777, 31781, 31785, 31789,
4531
     31793, 31797, 31801, 31805, 31809, 31813, 31817, 31821, 31825, 31829,
4532
     31833, 31837, 31841, 31845, 31849, 31853, 31857, 31861, 31865, 31869,
4533
     31873, 31877, 31881, 31885, 31889, 31893, 31897, 31901, 31905, 31909,
4534
     31913, 31917, 31921, 31925, 31929, 31933, 31937, 31941, 31945, 31949,
4535
     31953, 31957, 31961, 31965, 31969, 31973, 31977, 31981, 31985, 31989,
4536
     31993, 31997, 32001, 32005, 32009, 32013, 32017, 32021, 32025, 32029,
4537
     32033, 32037, 32041, 32045, 32049, 32053, 32057, 32061, 32065, 32069,
4538
     32073, 32077, 32081, 32085, 32089, 32093, 32097, 32101, 32105, 32109,
4539
     32113, 32117, 32121, 32125, 32129, 32133, 32137, 32141, 32145, 32149,
4540
     32153, 32157, 32161, 32165, 32169, 32173, 32177, 32181, 32185, 32189,
4541
     32193, 32197, 32201, 32205, 32209, 32213, 32217, 32221, 32225, 32229,
4542
     32233, 32237, 32241, 32245, 32248, 32248, 32249, 32253, 32257, 32261,
4543
     32265, 32269, 32273, 32277, 32281, 32285, 32289, 32293, 32297, 32301,
4544
     32305, 32309, 32313, 32317, 32321, 32325, 32329, 32333, 32337, 32341,
4545
     32345, 32349, 32353, 32357, 32361, 32365, 32369, 32373, 32377, 32381,
4546
     32385, 32389, 32393, 32397, 32401, 32405, 32409, 32413, 32417, 32421,
4547
     32425, 32429, 32433, 32437, 32441, 32445, 32448},
4548
    {32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4549
     32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4550
     32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4551
     32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4552
     32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32449, 32453,
4553
     32457, 32461, 32465, 32469, 32473, 32477, 32481, 32485, 32489, 32493,
4554
     32497, 32501, 32505, 32509, 32513, 32517, 32521, 32525, 32529, 32533,
4555
     32537, 32541, 32545, 32549, 32553, 32557, 32561, 32565, 32569, 32573,
4556
     32577, 32581, 32585, 32589, 32593, 32597, 32601, 32605, 32609, 32613,
4557
     32617, 32621, 32625, 32629, 32633, 32637, 32641, 32645, 32649, 32653,
4558
     32657, 32661, 32665, 32669, 32673, 32677, 32681, 32685, 32689, 32693,
4559
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4560
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4561
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4562
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4563
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4564
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4565
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4566
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4567
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4568
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4569
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4570
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4571
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4572
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4573
     32696, 32696, 32696, 32696, 32696, 32696, 32696},
4574
    {32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4575
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4576
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4577
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4578
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4579
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4580
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4581
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4582
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4583
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4584
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4585
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4586
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4587
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4588
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4589
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4590
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4591
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4592
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4593
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4594
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4595
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4596
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4597
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4598
     32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4599
     32696, 32696, 32696, 32696, 32696, 32696, 32697},
4600
    {32697, 32701, 32705, 32709, 32712, 32713, 32717, 32721, 32725, 32729,
4601
     32733, 32737, 32741, 32745, 32749, 32753, 32757, 32761, 32765, 32769,
4602
     32773, 32777, 32781, 32785, 32789, 32793, 32797, 32801, 32805, 32809,
4603
     32813, 32817, 32820, 32821, 32825, 32828, 32829, 32832, 32832, 32833,
4604
     32836, 32837, 32841, 32845, 32849, 32853, 32857, 32861, 32865, 32869,
4605
     32873, 32876, 32877, 32881, 32885, 32889, 32892, 32893, 32896, 32897,
4606
     32900, 32900, 32900, 32900, 32900, 32900, 32901, 32904, 32904, 32904,
4607
     32904, 32905, 32908, 32909, 32912, 32913, 32916, 32917, 32921, 32925,
4608
     32928, 32929, 32933, 32936, 32937, 32940, 32940, 32941, 32944, 32945,
4609
     32948, 32949, 32952, 32953, 32956, 32957, 32960, 32961, 32965, 32968,
4610
     32969, 32972, 32972, 32973, 32977, 32981, 32985, 32988, 32989, 32993,
4611
     32997, 33001, 33005, 33009, 33013, 33016, 33017, 33021, 33025, 33029,
4612
     33032, 33033, 33037, 33041, 33045, 33048, 33049, 33052, 33053, 33057,
4613
     33061, 33065, 33069, 33073, 33077, 33081, 33085, 33089, 33092, 33093,
4614
     33097, 33101, 33105, 33109, 33113, 33117, 33121, 33125, 33129, 33133,
4615
     33137, 33141, 33145, 33149, 33153, 33157, 33160, 33160, 33160, 33160,
4616
     33160, 33161, 33165, 33169, 33172, 33173, 33177, 33181, 33185, 33189,
4617
     33192, 33193, 33197, 33201, 33205, 33209, 33213, 33217, 33221, 33225,
4618
     33229, 33233, 33237, 33241, 33245, 33249, 33253, 33257, 33260, 33260,
4619
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4620
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4621
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4622
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4623
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4624
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4625
     33260, 33260, 33260, 33260, 33260, 33260, 33260},
4626
    {33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4627
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4628
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4629
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4630
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4631
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4632
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4633
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4634
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4635
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4636
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4637
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4638
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4639
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4640
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4641
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4642
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4643
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4644
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4645
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4646
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4647
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4648
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4649
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4650
     33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4651
     33260, 33260, 33260, 33260, 33260, 33260, 33261},
4652
    {33261, 33269, 33277, 33285, 33293, 33301, 33309, 33317, 33325, 33333,
4653
     33341, 33348, 33348, 33348, 33348, 33348, 33349, 33361, 33373, 33385,
4654
     33397, 33409, 33421, 33433, 33445, 33457, 33469, 33481, 33493, 33505,
4655
     33517, 33529, 33541, 33553, 33565, 33577, 33589, 33601, 33613, 33625,
4656
     33637, 33649, 33661, 33673, 33677, 33681, 33689, 33696, 33697, 33701,
4657
     33705, 33709, 33713, 33717, 33721, 33725, 33729, 33733, 33737, 33741,
4658
     33745, 33749, 33753, 33757, 33761, 33765, 33769, 33773, 33777, 33781,
4659
     33785, 33789, 33793, 33797, 33801, 33809, 33817, 33825, 33833, 33845,
4660
     33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,
4661
     33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,
4662
     33852, 33852, 33852, 33852, 33852, 33852, 33853, 33861, 33869, 33876,
4663
     33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4664
     33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4665
     33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4666
     33876, 33876, 33876, 33876, 33877, 33884, 33884, 33884, 33884, 33884,
4667
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4668
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4669
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4670
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4671
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4672
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4673
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4674
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4675
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4676
     33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4677
     33884, 33884, 33884, 33884, 33884, 33884, 33885},
4678
    {33885, 33893, 33901, 33904, 33904, 33904, 33904, 33904, 33904, 33904,
4679
     33904, 33904, 33904, 33904, 33904, 33904, 33905, 33909, 33913, 33917,
4680
     33925, 33929, 33933, 33937, 33941, 33945, 33949, 33953, 33957, 33961,
4681
     33965, 33969, 33973, 33977, 33981, 33985, 33989, 33993, 33997, 34001,
4682
     34005, 34009, 34013, 34017, 34021, 34025, 34029, 34033, 34037, 34041,
4683
     34045, 34049, 34053, 34057, 34061, 34065, 34069, 34073, 34077, 34081,
4684
     34084, 34084, 34084, 34084, 34085, 34097, 34109, 34121, 34133, 34145,
4685
     34157, 34169, 34181, 34192, 34192, 34192, 34192, 34192, 34192, 34192,
4686
     34193, 34197, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4687
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4688
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4689
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4690
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4691
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4692
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4693
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4694
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4695
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4696
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4697
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4698
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4699
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4700
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4701
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4702
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4703
     34200, 34200, 34200, 34200, 34200, 34200, 34200},
4704
    {34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4705
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4706
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4707
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4708
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4709
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4710
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4711
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4712
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4713
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4714
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4715
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4716
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4717
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4718
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4719
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4720
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4721
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4722
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4723
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4724
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4725
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4726
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4727
     34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4728
     34201, 34205, 34209, 34213, 34217, 34221, 34225, 34229, 34233, 34237,
4729
     34240, 34240, 34240, 34240, 34240, 34240, 34240},
4730
    {34240, 34244, 34248, 34252, 34256, 34260, 34264, 34268, 34272, 34276,
4731
     34280, 34284, 34288, 34292, 34296, 34300, 34304, 34308, 34312, 34316,
4732
     34320, 34324, 34328, 34332, 34336, 34340, 34344, 34348, 34352, 34356,
4733
     34360, 34364, 34368, 34372, 34376, 34380, 34384, 34388, 34392, 34396,
4734
     34400, 34404, 34408, 34412, 34416, 34420, 34424, 34428, 34432, 34436,
4735
     34440, 34444, 34448, 34452, 34456, 34460, 34464, 34468, 34472, 34476,
4736
     34480, 34484, 34488, 34492, 34496, 34500, 34504, 34508, 34512, 34516,
4737
     34520, 34524, 34528, 34532, 34536, 34540, 34544, 34548, 34552, 34556,
4738
     34560, 34564, 34568, 34572, 34576, 34580, 34584, 34588, 34592, 34596,
4739
     34600, 34604, 34608, 34612, 34616, 34620, 34624, 34628, 34632, 34636,
4740
     34640, 34644, 34648, 34652, 34656, 34660, 34664, 34668, 34672, 34676,
4741
     34680, 34684, 34688, 34692, 34696, 34700, 34704, 34708, 34712, 34716,
4742
     34720, 34724, 34728, 34732, 34736, 34740, 34744, 34748, 34752, 34756,
4743
     34760, 34764, 34768, 34772, 34776, 34780, 34784, 34788, 34792, 34796,
4744
     34800, 34804, 34808, 34812, 34816, 34820, 34824, 34828, 34832, 34836,
4745
     34840, 34844, 34848, 34852, 34856, 34860, 34864, 34868, 34872, 34876,
4746
     34880, 34884, 34888, 34892, 34896, 34900, 34904, 34908, 34912, 34916,
4747
     34920, 34924, 34928, 34932, 34936, 34940, 34944, 34948, 34952, 34956,
4748
     34960, 34964, 34968, 34972, 34976, 34980, 34984, 34988, 34992, 34996,
4749
     35000, 35004, 35008, 35012, 35016, 35020, 35024, 35028, 35032, 35036,
4750
     35040, 35044, 35048, 35052, 35056, 35060, 35064, 35068, 35072, 35076,
4751
     35080, 35084, 35088, 35092, 35096, 35100, 35104, 35108, 35112, 35116,
4752
     35120, 35124, 35128, 35132, 35136, 35140, 35144, 35148, 35152, 35156,
4753
     35160, 35164, 35168, 35172, 35176, 35180, 35184, 35188, 35192, 35196,
4754
     35200, 35204, 35208, 35212, 35216, 35220, 35224, 35228, 35232, 35236,
4755
     35240, 35244, 35248, 35252, 35256, 35260, 35264},
4756
    {35264, 35268, 35272, 35276, 35280, 35284, 35288, 35292, 35296, 35300,
4757
     35304, 35308, 35312, 35316, 35320, 35324, 35328, 35332, 35336, 35340,
4758
     35344, 35348, 35352, 35356, 35360, 35364, 35368, 35372, 35376, 35380,
4759
     35384, 35388, 35392, 35396, 35400, 35404, 35408, 35412, 35416, 35420,
4760
     35424, 35428, 35432, 35436, 35440, 35444, 35448, 35452, 35456, 35460,
4761
     35464, 35468, 35472, 35476, 35480, 35484, 35488, 35492, 35496, 35500,
4762
     35504, 35508, 35512, 35516, 35520, 35524, 35528, 35532, 35536, 35540,
4763
     35544, 35548, 35552, 35556, 35560, 35564, 35568, 35572, 35576, 35580,
4764
     35584, 35588, 35592, 35596, 35600, 35604, 35608, 35612, 35616, 35620,
4765
     35624, 35628, 35632, 35636, 35640, 35644, 35648, 35652, 35656, 35660,
4766
     35664, 35668, 35672, 35676, 35680, 35684, 35688, 35692, 35696, 35700,
4767
     35704, 35708, 35712, 35716, 35720, 35724, 35728, 35732, 35736, 35740,
4768
     35744, 35748, 35752, 35756, 35760, 35764, 35768, 35772, 35776, 35780,
4769
     35784, 35788, 35792, 35796, 35800, 35804, 35808, 35812, 35816, 35820,
4770
     35824, 35828, 35832, 35836, 35840, 35844, 35848, 35852, 35856, 35860,
4771
     35864, 35868, 35872, 35876, 35880, 35884, 35888, 35892, 35896, 35900,
4772
     35904, 35908, 35912, 35916, 35920, 35924, 35928, 35932, 35936, 35940,
4773
     35944, 35948, 35952, 35956, 35960, 35964, 35968, 35972, 35976, 35980,
4774
     35984, 35988, 35992, 35996, 36000, 36004, 36008, 36012, 36016, 36020,
4775
     36024, 36028, 36032, 36036, 36040, 36044, 36048, 36052, 36056, 36060,
4776
     36064, 36068, 36072, 36076, 36080, 36084, 36088, 36092, 36096, 36100,
4777
     36104, 36108, 36112, 36116, 36120, 36124, 36128, 36132, 36136, 36140,
4778
     36144, 36148, 36152, 36156, 36160, 36164, 36168, 36172, 36176, 36180,
4779
     36184, 36188, 36192, 36196, 36200, 36204, 36208, 36212, 36216, 36220,
4780
     36224, 36228, 36232, 36236, 36240, 36244, 36248, 36252, 36256, 36260,
4781
     36264, 36268, 36272, 36276, 36280, 36284, 36288},
4782
    {36288, 36292, 36296, 36300, 36304, 36308, 36312, 36316, 36320, 36324,
4783
     36328, 36332, 36336, 36340, 36344, 36348, 36352, 36356, 36360, 36364,
4784
     36368, 36372, 36376, 36380, 36384, 36388, 36392, 36396, 36400, 36404,
4785
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4786
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4787
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4788
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4789
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4790
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4791
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4792
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4793
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4794
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4795
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4796
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4797
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4798
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4799
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4800
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4801
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4802
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4803
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4804
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4805
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4806
     36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4807
     36408, 36408, 36408, 36408, 36408, 36408, 36408}};
4808
const char32_t decomposition_data[9102] = {
4809
    0,      32,     32,     776,    97,     32,     772,    50,     51,
4810
    32,     769,    956,    32,     807,    49,     111,    49,     8260,
4811
    52,     49,     8260,   50,     51,     8260,   52,     65,     768,
4812
    65,     769,    65,     770,    65,     771,    65,     776,    65,
4813
    778,    67,     807,    69,     768,    69,     769,    69,     770,
4814
    69,     776,    73,     768,    73,     769,    73,     770,    73,
4815
    776,    78,     771,    79,     768,    79,     769,    79,     770,
4816
    79,     771,    79,     776,    85,     768,    85,     769,    85,
4817
    770,    85,     776,    89,     769,    97,     768,    97,     769,
4818
    97,     770,    97,     771,    97,     776,    97,     778,    99,
4819
    807,    101,    768,    101,    769,    101,    770,    101,    776,
4820
    105,    768,    105,    769,    105,    770,    105,    776,    110,
4821
    771,    111,    768,    111,    769,    111,    770,    111,    771,
4822
    111,    776,    117,    768,    117,    769,    117,    770,    117,
4823
    776,    121,    769,    121,    776,    65,     772,    97,     772,
4824
    65,     774,    97,     774,    65,     808,    97,     808,    67,
4825
    769,    99,     769,    67,     770,    99,     770,    67,     775,
4826
    99,     775,    67,     780,    99,     780,    68,     780,    100,
4827
    780,    69,     772,    101,    772,    69,     774,    101,    774,
4828
    69,     775,    101,    775,    69,     808,    101,    808,    69,
4829
    780,    101,    780,    71,     770,    103,    770,    71,     774,
4830
    103,    774,    71,     775,    103,    775,    71,     807,    103,
4831
    807,    72,     770,    104,    770,    73,     771,    105,    771,
4832
    73,     772,    105,    772,    73,     774,    105,    774,    73,
4833
    808,    105,    808,    73,     775,    73,     74,     105,    106,
4834
    74,     770,    106,    770,    75,     807,    107,    807,    76,
4835
    769,    108,    769,    76,     807,    108,    807,    76,     780,
4836
    108,    780,    76,     183,    108,    183,    78,     769,    110,
4837
    769,    78,     807,    110,    807,    78,     780,    110,    780,
4838
    700,    110,    79,     772,    111,    772,    79,     774,    111,
4839
    774,    79,     779,    111,    779,    82,     769,    114,    769,
4840
    82,     807,    114,    807,    82,     780,    114,    780,    83,
4841
    769,    115,    769,    83,     770,    115,    770,    83,     807,
4842
    115,    807,    83,     780,    115,    780,    84,     807,    116,
4843
    807,    84,     780,    116,    780,    85,     771,    117,    771,
4844
    85,     772,    117,    772,    85,     774,    117,    774,    85,
4845
    778,    117,    778,    85,     779,    117,    779,    85,     808,
4846
    117,    808,    87,     770,    119,    770,    89,     770,    121,
4847
    770,    89,     776,    90,     769,    122,    769,    90,     775,
4848
    122,    775,    90,     780,    122,    780,    115,    79,     795,
4849
    111,    795,    85,     795,    117,    795,    68,     90,     780,
4850
    68,     122,    780,    100,    122,    780,    76,     74,     76,
4851
    106,    108,    106,    78,     74,     78,     106,    110,    106,
4852
    65,     780,    97,     780,    73,     780,    105,    780,    79,
4853
    780,    111,    780,    85,     780,    117,    780,    85,     776,
4854
    772,    117,    776,    772,    85,     776,    769,    117,    776,
4855
    769,    85,     776,    780,    117,    776,    780,    85,     776,
4856
    768,    117,    776,    768,    65,     776,    772,    97,     776,
4857
    772,    65,     775,    772,    97,     775,    772,    198,    772,
4858
    230,    772,    71,     780,    103,    780,    75,     780,    107,
4859
    780,    79,     808,    111,    808,    79,     808,    772,    111,
4860
    808,    772,    439,    780,    658,    780,    106,    780,    68,
4861
    90,     68,     122,    100,    122,    71,     769,    103,    769,
4862
    78,     768,    110,    768,    65,     778,    769,    97,     778,
4863
    769,    198,    769,    230,    769,    216,    769,    248,    769,
4864
    65,     783,    97,     783,    65,     785,    97,     785,    69,
4865
    783,    101,    783,    69,     785,    101,    785,    73,     783,
4866
    105,    783,    73,     785,    105,    785,    79,     783,    111,
4867
    783,    79,     785,    111,    785,    82,     783,    114,    783,
4868
    82,     785,    114,    785,    85,     783,    117,    783,    85,
4869
    785,    117,    785,    83,     806,    115,    806,    84,     806,
4870
    116,    806,    72,     780,    104,    780,    65,     775,    97,
4871
    775,    69,     807,    101,    807,    79,     776,    772,    111,
4872
    776,    772,    79,     771,    772,    111,    771,    772,    79,
4873
    775,    111,    775,    79,     775,    772,    111,    775,    772,
4874
    89,     772,    121,    772,    104,    614,    106,    114,    633,
4875
    635,    641,    119,    121,    32,     774,    32,     775,    32,
4876
    778,    32,     808,    32,     771,    32,     779,    611,    108,
4877
    115,    120,    661,    768,    769,    787,    776,    769,    697,
4878
    32,     837,    59,     32,     769,    168,    769,    913,    769,
4879
    183,    917,    769,    919,    769,    921,    769,    927,    769,
4880
    933,    769,    937,    769,    953,    776,    769,    921,    776,
4881
    933,    776,    945,    769,    949,    769,    951,    769,    953,
4882
    769,    965,    776,    769,    953,    776,    965,    776,    959,
4883
    769,    965,    769,    969,    769,    946,    952,    933,    978,
4884
    769,    978,    776,    966,    960,    954,    961,    962,    920,
4885
    949,    931,    1045,   768,    1045,   776,    1043,   769,    1030,
4886
    776,    1050,   769,    1048,   768,    1059,   774,    1048,   774,
4887
    1080,   774,    1077,   768,    1077,   776,    1075,   769,    1110,
4888
    776,    1082,   769,    1080,   768,    1091,   774,    1140,   783,
4889
    1141,   783,    1046,   774,    1078,   774,    1040,   774,    1072,
4890
    774,    1040,   776,    1072,   776,    1045,   774,    1077,   774,
4891
    1240,   776,    1241,   776,    1046,   776,    1078,   776,    1047,
4892
    776,    1079,   776,    1048,   772,    1080,   772,    1048,   776,
4893
    1080,   776,    1054,   776,    1086,   776,    1256,   776,    1257,
4894
    776,    1069,   776,    1101,   776,    1059,   772,    1091,   772,
4895
    1059,   776,    1091,   776,    1059,   779,    1091,   779,    1063,
4896
    776,    1095,   776,    1067,   776,    1099,   776,    1381,   1410,
4897
    1575,   1619,   1575,   1620,   1608,   1620,   1575,   1621,   1610,
4898
    1620,   1575,   1652,   1608,   1652,   1735,   1652,   1610,   1652,
4899
    1749,   1620,   1729,   1620,   1746,   1620,   2344,   2364,   2352,
4900
    2364,   2355,   2364,   2325,   2364,   2326,   2364,   2327,   2364,
4901
    2332,   2364,   2337,   2364,   2338,   2364,   2347,   2364,   2351,
4902
    2364,   2503,   2494,   2503,   2519,   2465,   2492,   2466,   2492,
4903
    2479,   2492,   2610,   2620,   2616,   2620,   2582,   2620,   2583,
4904
    2620,   2588,   2620,   2603,   2620,   2887,   2902,   2887,   2878,
4905
    2887,   2903,   2849,   2876,   2850,   2876,   2962,   3031,   3014,
4906
    3006,   3015,   3006,   3014,   3031,   3142,   3158,   3263,   3285,
4907
    3270,   3285,   3270,   3286,   3270,   3266,   3270,   3266,   3285,
4908
    3398,   3390,   3399,   3390,   3398,   3415,   3545,   3530,   3545,
4909
    3535,   3545,   3535,   3530,   3545,   3551,   3661,   3634,   3789,
4910
    3762,   3755,   3737,   3755,   3745,   3851,   3906,   4023,   3916,
4911
    4023,   3921,   4023,   3926,   4023,   3931,   4023,   3904,   4021,
4912
    3953,   3954,   3953,   3956,   4018,   3968,   4018,   3953,   3968,
4913
    4019,   3968,   4019,   3953,   3968,   3953,   3968,   3986,   4023,
4914
    3996,   4023,   4001,   4023,   4006,   4023,   4011,   4023,   3984,
4915
    4021,   4133,   4142,   4316,   6917,   6965,   6919,   6965,   6921,
4916
    6965,   6923,   6965,   6925,   6965,   6929,   6965,   6970,   6965,
4917
    6972,   6965,   6974,   6965,   6975,   6965,   6978,   6965,   65,
4918
    198,    66,     68,     69,     398,    71,     72,     73,     74,
4919
    75,     76,     77,     78,     79,     546,    80,     82,     84,
4920
    85,     87,     97,     592,    593,    7426,   98,     100,    101,
4921
    601,    603,    604,    103,    107,    109,    331,    111,    596,
4922
    7446,   7447,   112,    116,    117,    7453,   623,    118,    7461,
4923
    946,    947,    948,    966,    967,    105,    114,    117,    118,
4924
    946,    947,    961,    966,    967,    1085,   594,    99,     597,
4925
    240,    604,    102,    607,    609,    613,    616,    617,    618,
4926
    7547,   669,    621,    7557,   671,    625,    624,    626,    627,
4927
    628,    629,    632,    642,    643,    427,    649,    650,    7452,
4928
    651,    652,    122,    656,    657,    658,    952,    65,     805,
4929
    97,     805,    66,     775,    98,     775,    66,     803,    98,
4930
    803,    66,     817,    98,     817,    67,     807,    769,    99,
4931
    807,    769,    68,     775,    100,    775,    68,     803,    100,
4932
    803,    68,     817,    100,    817,    68,     807,    100,    807,
4933
    68,     813,    100,    813,    69,     772,    768,    101,    772,
4934
    768,    69,     772,    769,    101,    772,    769,    69,     813,
4935
    101,    813,    69,     816,    101,    816,    69,     807,    774,
4936
    101,    807,    774,    70,     775,    102,    775,    71,     772,
4937
    103,    772,    72,     775,    104,    775,    72,     803,    104,
4938
    803,    72,     776,    104,    776,    72,     807,    104,    807,
4939
    72,     814,    104,    814,    73,     816,    105,    816,    73,
4940
    776,    769,    105,    776,    769,    75,     769,    107,    769,
4941
    75,     803,    107,    803,    75,     817,    107,    817,    76,
4942
    803,    108,    803,    76,     803,    772,    108,    803,    772,
4943
    76,     817,    108,    817,    76,     813,    108,    813,    77,
4944
    769,    109,    769,    77,     775,    109,    775,    77,     803,
4945
    109,    803,    78,     775,    110,    775,    78,     803,    110,
4946
    803,    78,     817,    110,    817,    78,     813,    110,    813,
4947
    79,     771,    769,    111,    771,    769,    79,     771,    776,
4948
    111,    771,    776,    79,     772,    768,    111,    772,    768,
4949
    79,     772,    769,    111,    772,    769,    80,     769,    112,
4950
    769,    80,     775,    112,    775,    82,     775,    114,    775,
4951
    82,     803,    114,    803,    82,     803,    772,    114,    803,
4952
    772,    82,     817,    114,    817,    83,     775,    115,    775,
4953
    83,     803,    115,    803,    83,     769,    775,    115,    769,
4954
    775,    83,     780,    775,    115,    780,    775,    83,     803,
4955
    775,    115,    803,    775,    84,     775,    116,    775,    84,
4956
    803,    116,    803,    84,     817,    116,    817,    84,     813,
4957
    116,    813,    85,     804,    117,    804,    85,     816,    117,
4958
    816,    85,     813,    117,    813,    85,     771,    769,    117,
4959
    771,    769,    85,     772,    776,    117,    772,    776,    86,
4960
    771,    118,    771,    86,     803,    118,    803,    87,     768,
4961
    119,    768,    87,     769,    119,    769,    87,     776,    119,
4962
    776,    87,     775,    119,    775,    87,     803,    119,    803,
4963
    88,     775,    120,    775,    88,     776,    120,    776,    89,
4964
    775,    121,    775,    90,     770,    122,    770,    90,     803,
4965
    122,    803,    90,     817,    122,    817,    104,    817,    116,
4966
    776,    119,    778,    121,    778,    97,     702,    383,    775,
4967
    65,     803,    97,     803,    65,     777,    97,     777,    65,
4968
    770,    769,    97,     770,    769,    65,     770,    768,    97,
4969
    770,    768,    65,     770,    777,    97,     770,    777,    65,
4970
    770,    771,    97,     770,    771,    65,     803,    770,    97,
4971
    803,    770,    65,     774,    769,    97,     774,    769,    65,
4972
    774,    768,    97,     774,    768,    65,     774,    777,    97,
4973
    774,    777,    65,     774,    771,    97,     774,    771,    65,
4974
    803,    774,    97,     803,    774,    69,     803,    101,    803,
4975
    69,     777,    101,    777,    69,     771,    101,    771,    69,
4976
    770,    769,    101,    770,    769,    69,     770,    768,    101,
4977
    770,    768,    69,     770,    777,    101,    770,    777,    69,
4978
    770,    771,    101,    770,    771,    69,     803,    770,    101,
4979
    803,    770,    73,     777,    105,    777,    73,     803,    105,
4980
    803,    79,     803,    111,    803,    79,     777,    111,    777,
4981
    79,     770,    769,    111,    770,    769,    79,     770,    768,
4982
    111,    770,    768,    79,     770,    777,    111,    770,    777,
4983
    79,     770,    771,    111,    770,    771,    79,     803,    770,
4984
    111,    803,    770,    79,     795,    769,    111,    795,    769,
4985
    79,     795,    768,    111,    795,    768,    79,     795,    777,
4986
    111,    795,    777,    79,     795,    771,    111,    795,    771,
4987
    79,     795,    803,    111,    795,    803,    85,     803,    117,
4988
    803,    85,     777,    117,    777,    85,     795,    769,    117,
4989
    795,    769,    85,     795,    768,    117,    795,    768,    85,
4990
    795,    777,    117,    795,    777,    85,     795,    771,    117,
4991
    795,    771,    85,     795,    803,    117,    795,    803,    89,
4992
    768,    121,    768,    89,     803,    121,    803,    89,     777,
4993
    121,    777,    89,     771,    121,    771,    945,    787,    945,
4994
    788,    945,    787,    768,    945,    788,    768,    945,    787,
4995
    769,    945,    788,    769,    945,    787,    834,    945,    788,
4996
    834,    913,    787,    913,    788,    913,    787,    768,    913,
4997
    788,    768,    913,    787,    769,    913,    788,    769,    913,
4998
    787,    834,    913,    788,    834,    949,    787,    949,    788,
4999
    949,    787,    768,    949,    788,    768,    949,    787,    769,
5000
    949,    788,    769,    917,    787,    917,    788,    917,    787,
5001
    768,    917,    788,    768,    917,    787,    769,    917,    788,
5002
    769,    951,    787,    951,    788,    951,    787,    768,    951,
5003
    788,    768,    951,    787,    769,    951,    788,    769,    951,
5004
    787,    834,    951,    788,    834,    919,    787,    919,    788,
5005
    919,    787,    768,    919,    788,    768,    919,    787,    769,
5006
    919,    788,    769,    919,    787,    834,    919,    788,    834,
5007
    953,    787,    953,    788,    953,    787,    768,    953,    788,
5008
    768,    953,    787,    769,    953,    788,    769,    953,    787,
5009
    834,    953,    788,    834,    921,    787,    921,    788,    921,
5010
    787,    768,    921,    788,    768,    921,    787,    769,    921,
5011
    788,    769,    921,    787,    834,    921,    788,    834,    959,
5012
    787,    959,    788,    959,    787,    768,    959,    788,    768,
5013
    959,    787,    769,    959,    788,    769,    927,    787,    927,
5014
    788,    927,    787,    768,    927,    788,    768,    927,    787,
5015
    769,    927,    788,    769,    965,    787,    965,    788,    965,
5016
    787,    768,    965,    788,    768,    965,    787,    769,    965,
5017
    788,    769,    965,    787,    834,    965,    788,    834,    933,
5018
    788,    933,    788,    768,    933,    788,    769,    933,    788,
5019
    834,    969,    787,    969,    788,    969,    787,    768,    969,
5020
    788,    768,    969,    787,    769,    969,    788,    769,    969,
5021
    787,    834,    969,    788,    834,    937,    787,    937,    788,
5022
    937,    787,    768,    937,    788,    768,    937,    787,    769,
5023
    937,    788,    769,    937,    787,    834,    937,    788,    834,
5024
    945,    768,    945,    769,    949,    768,    949,    769,    951,
5025
    768,    951,    769,    953,    768,    953,    769,    959,    768,
5026
    959,    769,    965,    768,    965,    769,    969,    768,    969,
5027
    769,    945,    787,    837,    945,    788,    837,    945,    787,
5028
    768,    837,    945,    788,    768,    837,    945,    787,    769,
5029
    837,    945,    788,    769,    837,    945,    787,    834,    837,
5030
    945,    788,    834,    837,    913,    787,    837,    913,    788,
5031
    837,    913,    787,    768,    837,    913,    788,    768,    837,
5032
    913,    787,    769,    837,    913,    788,    769,    837,    913,
5033
    787,    834,    837,    913,    788,    834,    837,    951,    787,
5034
    837,    951,    788,    837,    951,    787,    768,    837,    951,
5035
    788,    768,    837,    951,    787,    769,    837,    951,    788,
5036
    769,    837,    951,    787,    834,    837,    951,    788,    834,
5037
    837,    919,    787,    837,    919,    788,    837,    919,    787,
5038
    768,    837,    919,    788,    768,    837,    919,    787,    769,
5039
    837,    919,    788,    769,    837,    919,    787,    834,    837,
5040
    919,    788,    834,    837,    969,    787,    837,    969,    788,
5041
    837,    969,    787,    768,    837,    969,    788,    768,    837,
5042
    969,    787,    769,    837,    969,    788,    769,    837,    969,
5043
    787,    834,    837,    969,    788,    834,    837,    937,    787,
5044
    837,    937,    788,    837,    937,    787,    768,    837,    937,
5045
    788,    768,    837,    937,    787,    769,    837,    937,    788,
5046
    769,    837,    937,    787,    834,    837,    937,    788,    834,
5047
    837,    945,    774,    945,    772,    945,    768,    837,    945,
5048
    837,    945,    769,    837,    945,    834,    945,    834,    837,
5049
    913,    774,    913,    772,    913,    768,    913,    769,    913,
5050
    837,    32,     787,    953,    32,     787,    32,     834,    168,
5051
    834,    951,    768,    837,    951,    837,    951,    769,    837,
5052
    951,    834,    951,    834,    837,    917,    768,    917,    769,
5053
    919,    768,    919,    769,    919,    837,    8127,   768,    8127,
5054
    769,    8127,   834,    953,    774,    953,    772,    953,    776,
5055
    768,    953,    776,    769,    953,    834,    953,    776,    834,
5056
    921,    774,    921,    772,    921,    768,    921,    769,    8190,
5057
    768,    8190,   769,    8190,   834,    965,    774,    965,    772,
5058
    965,    776,    768,    965,    776,    769,    961,    787,    961,
5059
    788,    965,    834,    965,    776,    834,    933,    774,    933,
5060
    772,    933,    768,    933,    769,    929,    788,    168,    768,
5061
    168,    769,    96,     969,    768,    837,    969,    837,    969,
5062
    769,    837,    969,    834,    969,    834,    837,    927,    768,
5063
    927,    769,    937,    768,    937,    769,    937,    837,    180,
5064
    32,     788,    8194,   8195,   32,     32,     32,     32,     32,
5065
    32,     32,     32,     32,     8208,   32,     819,    46,     46,
5066
    46,     46,     46,     46,     32,     8242,   8242,   8242,   8242,
5067
    8242,   8245,   8245,   8245,   8245,   8245,   33,     33,     32,
5068
    773,    63,     63,     63,     33,     33,     63,     8242,   8242,
5069
    8242,   8242,   32,     48,     105,    52,     53,     54,     55,
5070
    56,     57,     43,     8722,   61,     40,     41,     110,    48,
5071
    49,     50,     51,     52,     53,     54,     55,     56,     57,
5072
    43,     8722,   61,     40,     41,     97,     101,    111,    120,
5073
    601,    104,    107,    108,    109,    110,    112,    115,    116,
5074
    82,     115,    97,     47,     99,     97,     47,     115,    67,
5075
    176,    67,     99,     47,     111,    99,     47,     117,    400,
5076
    176,    70,     103,    72,     72,     72,     104,    295,    73,
5077
    73,     76,     108,    78,     78,     111,    80,     81,     82,
5078
    82,     82,     83,     77,     84,     69,     76,     84,     77,
5079
    90,     937,    90,     75,     65,     778,    66,     67,     101,
5080
    69,     70,     77,     111,    1488,   1489,   1490,   1491,   105,
5081
    70,     65,     88,     960,    947,    915,    928,    8721,   68,
5082
    100,    101,    105,    106,    49,     8260,   55,     49,     8260,
5083
    57,     49,     8260,   49,     48,     49,     8260,   51,     50,
5084
    8260,   51,     49,     8260,   53,     50,     8260,   53,     51,
5085
    8260,   53,     52,     8260,   53,     49,     8260,   54,     53,
5086
    8260,   54,     49,     8260,   56,     51,     8260,   56,     53,
5087
    8260,   56,     55,     8260,   56,     49,     8260,   73,     73,
5088
    73,     73,     73,     73,     73,     86,     86,     86,     73,
5089
    86,     73,     73,     86,     73,     73,     73,     73,     88,
5090
    88,     88,     73,     88,     73,     73,     76,     67,     68,
5091
    77,     105,    105,    105,    105,    105,    105,    105,    118,
5092
    118,    118,    105,    118,    105,    105,    118,    105,    105,
5093
    105,    105,    120,    120,    120,    105,    120,    105,    105,
5094
    108,    99,     100,    109,    48,     8260,   51,     8592,   824,
5095
    8594,   824,    8596,   824,    8656,   824,    8660,   824,    8658,
5096
    824,    8707,   824,    8712,   824,    8715,   824,    8739,   824,
5097
    8741,   824,    8747,   8747,   8747,   8747,   8747,   8750,   8750,
5098
    8750,   8750,   8750,   8764,   824,    8771,   824,    8773,   824,
5099
    8776,   824,    61,     824,    8801,   824,    8781,   824,    60,
5100
    824,    62,     824,    8804,   824,    8805,   824,    8818,   824,
5101
    8819,   824,    8822,   824,    8823,   824,    8826,   824,    8827,
5102
    824,    8834,   824,    8835,   824,    8838,   824,    8839,   824,
5103
    8866,   824,    8872,   824,    8873,   824,    8875,   824,    8828,
5104
    824,    8829,   824,    8849,   824,    8850,   824,    8882,   824,
5105
    8883,   824,    8884,   824,    8885,   824,    12296,  12297,  49,
5106
    50,     51,     52,     53,     54,     55,     56,     57,     49,
5107
    48,     49,     49,     49,     50,     49,     51,     49,     52,
5108
    49,     53,     49,     54,     49,     55,     49,     56,     49,
5109
    57,     50,     48,     40,     49,     41,     40,     50,     41,
5110
    40,     51,     41,     40,     52,     41,     40,     53,     41,
5111
    40,     54,     41,     40,     55,     41,     40,     56,     41,
5112
    40,     57,     41,     40,     49,     48,     41,     40,     49,
5113
    49,     41,     40,     49,     50,     41,     40,     49,     51,
5114
    41,     40,     49,     52,     41,     40,     49,     53,     41,
5115
    40,     49,     54,     41,     40,     49,     55,     41,     40,
5116
    49,     56,     41,     40,     49,     57,     41,     40,     50,
5117
    48,     41,     49,     46,     50,     46,     51,     46,     52,
5118
    46,     53,     46,     54,     46,     55,     46,     56,     46,
5119
    57,     46,     49,     48,     46,     49,     49,     46,     49,
5120
    50,     46,     49,     51,     46,     49,     52,     46,     49,
5121
    53,     46,     49,     54,     46,     49,     55,     46,     49,
5122
    56,     46,     49,     57,     46,     50,     48,     46,     40,
5123
    97,     41,     40,     98,     41,     40,     99,     41,     40,
5124
    100,    41,     40,     101,    41,     40,     102,    41,     40,
5125
    103,    41,     40,     104,    41,     40,     105,    41,     40,
5126
    106,    41,     40,     107,    41,     40,     108,    41,     40,
5127
    109,    41,     40,     110,    41,     40,     111,    41,     40,
5128
    112,    41,     40,     113,    41,     40,     114,    41,     40,
5129
    115,    41,     40,     116,    41,     40,     117,    41,     40,
5130
    118,    41,     40,     119,    41,     40,     120,    41,     40,
5131
    121,    41,     40,     122,    41,     65,     66,     67,     68,
5132
    69,     70,     71,     72,     73,     74,     75,     76,     77,
5133
    78,     79,     80,     81,     82,     83,     84,     85,     86,
5134
    87,     88,     89,     90,     97,     98,     99,     100,    101,
5135
    102,    103,    104,    105,    106,    107,    108,    109,    110,
5136
    111,    112,    113,    114,    115,    116,    117,    118,    119,
5137
    120,    121,    122,    48,     8747,   8747,   8747,   8747,   58,
5138
    58,     61,     61,     61,     61,     61,     61,     10973,  824,
5139
    106,    86,     11617,  27597,  40863,  19968,  20008,  20022,  20031,
5140
    20057,  20101,  20108,  20128,  20154,  20799,  20837,  20843,  20866,
5141
    20886,  20907,  20960,  20981,  20992,  21147,  21241,  21269,  21274,
5142
    21304,  21313,  21340,  21353,  21378,  21430,  21448,  21475,  22231,
5143
    22303,  22763,  22786,  22794,  22805,  22823,  22899,  23376,  23424,
5144
    23544,  23567,  23586,  23608,  23662,  23665,  24027,  24037,  24049,
5145
    24062,  24178,  24186,  24191,  24308,  24318,  24331,  24339,  24400,
5146
    24417,  24435,  24515,  25096,  25142,  25163,  25903,  25908,  25991,
5147
    26007,  26020,  26041,  26080,  26085,  26352,  26376,  26408,  27424,
5148
    27490,  27513,  27571,  27595,  27604,  27611,  27663,  27668,  27700,
5149
    28779,  29226,  29238,  29243,  29247,  29255,  29273,  29275,  29356,
5150
    29572,  29577,  29916,  29926,  29976,  29983,  29992,  30000,  30091,
5151
    30098,  30326,  30333,  30382,  30399,  30446,  30683,  30690,  30707,
5152
    31034,  31160,  31166,  31348,  31435,  31481,  31859,  31992,  32566,
5153
    32593,  32650,  32701,  32769,  32780,  32786,  32819,  32895,  32905,
5154
    33251,  33258,  33267,  33276,  33292,  33307,  33311,  33390,  33394,
5155
    33400,  34381,  34411,  34880,  34892,  34915,  35198,  35211,  35282,
5156
    35328,  35895,  35910,  35925,  35960,  35997,  36196,  36208,  36275,
5157
    36523,  36554,  36763,  36784,  36789,  37009,  37193,  37318,  37324,
5158
    37329,  38263,  38272,  38428,  38582,  38585,  38632,  38737,  38750,
5159
    38754,  38761,  38859,  38893,  38899,  38913,  39080,  39131,  39135,
5160
    39318,  39321,  39340,  39592,  39640,  39647,  39717,  39727,  39730,
5161
    39740,  39770,  40165,  40565,  40575,  40613,  40635,  40643,  40653,
5162
    40657,  40697,  40701,  40718,  40723,  40736,  40763,  40778,  40786,
5163
    40845,  40860,  40864,  32,     12306,  21313,  21316,  21317,  12363,
5164
    12441,  12365,  12441,  12367,  12441,  12369,  12441,  12371,  12441,
5165
    12373,  12441,  12375,  12441,  12377,  12441,  12379,  12441,  12381,
5166
    12441,  12383,  12441,  12385,  12441,  12388,  12441,  12390,  12441,
5167
    12392,  12441,  12399,  12441,  12399,  12442,  12402,  12441,  12402,
5168
    12442,  12405,  12441,  12405,  12442,  12408,  12441,  12408,  12442,
5169
    12411,  12441,  12411,  12442,  12358,  12441,  32,     12441,  32,
5170
    12442,  12445,  12441,  12424,  12426,  12459,  12441,  12461,  12441,
5171
    12463,  12441,  12465,  12441,  12467,  12441,  12469,  12441,  12471,
5172
    12441,  12473,  12441,  12475,  12441,  12477,  12441,  12479,  12441,
5173
    12481,  12441,  12484,  12441,  12486,  12441,  12488,  12441,  12495,
5174
    12441,  12495,  12442,  12498,  12441,  12498,  12442,  12501,  12441,
5175
    12501,  12442,  12504,  12441,  12504,  12442,  12507,  12441,  12507,
5176
    12442,  12454,  12441,  12527,  12441,  12528,  12441,  12529,  12441,
5177
    12530,  12441,  12541,  12441,  12467,  12488,  4352,   4353,   4522,
5178
    4354,   4524,   4525,   4355,   4356,   4357,   4528,   4529,   4530,
5179
    4531,   4532,   4533,   4378,   4358,   4359,   4360,   4385,   4361,
5180
    4362,   4363,   4364,   4365,   4366,   4367,   4368,   4369,   4370,
5181
    4449,   4450,   4451,   4452,   4453,   4454,   4455,   4456,   4457,
5182
    4458,   4459,   4460,   4461,   4462,   4463,   4464,   4465,   4466,
5183
    4467,   4468,   4469,   4448,   4372,   4373,   4551,   4552,   4556,
5184
    4558,   4563,   4567,   4569,   4380,   4573,   4575,   4381,   4382,
5185
    4384,   4386,   4387,   4391,   4393,   4395,   4396,   4397,   4398,
5186
    4399,   4402,   4406,   4416,   4423,   4428,   4593,   4594,   4439,
5187
    4440,   4441,   4484,   4485,   4488,   4497,   4498,   4500,   4510,
5188
    4513,   19968,  20108,  19977,  22235,  19978,  20013,  19979,  30002,
5189
    20057,  19993,  19969,  22825,  22320,  20154,  40,     4352,   41,
5190
    40,     4354,   41,     40,     4355,   41,     40,     4357,   41,
5191
    40,     4358,   41,     40,     4359,   41,     40,     4361,   41,
5192
    40,     4363,   41,     40,     4364,   41,     40,     4366,   41,
5193
    40,     4367,   41,     40,     4368,   41,     40,     4369,   41,
5194
    40,     4370,   41,     40,     4352,   4449,   41,     40,     4354,
5195
    4449,   41,     40,     4355,   4449,   41,     40,     4357,   4449,
5196
    41,     40,     4358,   4449,   41,     40,     4359,   4449,   41,
5197
    40,     4361,   4449,   41,     40,     4363,   4449,   41,     40,
5198
    4364,   4449,   41,     40,     4366,   4449,   41,     40,     4367,
5199
    4449,   41,     40,     4368,   4449,   41,     40,     4369,   4449,
5200
    41,     40,     4370,   4449,   41,     40,     4364,   4462,   41,
5201
    40,     4363,   4457,   4364,   4453,   4523,   41,     40,     4363,
5202
    4457,   4370,   4462,   41,     40,     19968,  41,     40,     20108,
5203
    41,     40,     19977,  41,     40,     22235,  41,     40,     20116,
5204
    41,     40,     20845,  41,     40,     19971,  41,     40,     20843,
5205
    41,     40,     20061,  41,     40,     21313,  41,     40,     26376,
5206
    41,     40,     28779,  41,     40,     27700,  41,     40,     26408,
5207
    41,     40,     37329,  41,     40,     22303,  41,     40,     26085,
5208
    41,     40,     26666,  41,     40,     26377,  41,     40,     31038,
5209
    41,     40,     21517,  41,     40,     29305,  41,     40,     36001,
5210
    41,     40,     31069,  41,     40,     21172,  41,     40,     20195,
5211
    41,     40,     21628,  41,     40,     23398,  41,     40,     30435,
5212
    41,     40,     20225,  41,     40,     36039,  41,     40,     21332,
5213
    41,     40,     31085,  41,     40,     20241,  41,     40,     33258,
5214
    41,     40,     33267,  41,     21839,  24188,  25991,  31631,  80,
5215
    84,     69,     50,     49,     50,     50,     50,     51,     50,
5216
    52,     50,     53,     50,     54,     50,     55,     50,     56,
5217
    50,     57,     51,     48,     51,     49,     51,     50,     51,
5218
    51,     51,     52,     51,     53,     4352,   4354,   4355,   4357,
5219
    4358,   4359,   4361,   4363,   4364,   4366,   4367,   4368,   4369,
5220
    4370,   4352,   4449,   4354,   4449,   4355,   4449,   4357,   4449,
5221
    4358,   4449,   4359,   4449,   4361,   4449,   4363,   4449,   4364,
5222
    4449,   4366,   4449,   4367,   4449,   4368,   4449,   4369,   4449,
5223
    4370,   4449,   4366,   4449,   4535,   4352,   4457,   4364,   4462,
5224
    4363,   4468,   4363,   4462,   19968,  20108,  19977,  22235,  20116,
5225
    20845,  19971,  20843,  20061,  21313,  26376,  28779,  27700,  26408,
5226
    37329,  22303,  26085,  26666,  26377,  31038,  21517,  29305,  36001,
5227
    31069,  21172,  31192,  30007,  22899,  36969,  20778,  21360,  27880,
5228
    38917,  20241,  20889,  27491,  19978,  20013,  19979,  24038,  21491,
5229
    21307,  23447,  23398,  30435,  20225,  36039,  21332,  22812,  51,
5230
    54,     51,     55,     51,     56,     51,     57,     52,     48,
5231
    52,     49,     52,     50,     52,     51,     52,     52,     52,
5232
    53,     52,     54,     52,     55,     52,     56,     52,     57,
5233
    53,     48,     49,     26376,  50,     26376,  51,     26376,  52,
5234
    26376,  53,     26376,  54,     26376,  55,     26376,  56,     26376,
5235
    57,     26376,  49,     48,     26376,  49,     49,     26376,  49,
5236
    50,     26376,  72,     103,    101,    114,    103,    101,    86,
5237
    76,     84,     68,     12450,  12452,  12454,  12456,  12458,  12459,
5238
    12461,  12463,  12465,  12467,  12469,  12471,  12473,  12475,  12477,
5239
    12479,  12481,  12484,  12486,  12488,  12490,  12491,  12492,  12493,
5240
    12494,  12495,  12498,  12501,  12504,  12507,  12510,  12511,  12512,
5241
    12513,  12514,  12516,  12518,  12520,  12521,  12522,  12523,  12524,
5242
    12525,  12527,  12528,  12529,  12530,  20196,  21644,  12450,  12495,
5243
    12442,  12540,  12488,  12450,  12523,  12501,  12449,  12450,  12531,
5244
    12504,  12442,  12450,  12450,  12540,  12523,  12452,  12491,  12531,
5245
    12463,  12441,  12452,  12531,  12481,  12454,  12457,  12531,  12456,
5246
    12473,  12463,  12540,  12488,  12441,  12456,  12540,  12459,  12540,
5247
    12458,  12531,  12473,  12458,  12540,  12512,  12459,  12452,  12522,
5248
    12459,  12521,  12483,  12488,  12459,  12525,  12522,  12540,  12459,
5249
    12441,  12525,  12531,  12459,  12441,  12531,  12510,  12461,  12441,
5250
    12459,  12441,  12461,  12441,  12491,  12540,  12461,  12517,  12522,
5251
    12540,  12461,  12441,  12523,  12479,  12441,  12540,  12461,  12525,
5252
    12461,  12525,  12463,  12441,  12521,  12512,  12461,  12525,  12513,
5253
    12540,  12488,  12523,  12461,  12525,  12527,  12483,  12488,  12463,
5254
    12441,  12521,  12512,  12463,  12441,  12521,  12512,  12488,  12531,
5255
    12463,  12523,  12475,  12441,  12452,  12525,  12463,  12525,  12540,
5256
    12493,  12465,  12540,  12473,  12467,  12523,  12490,  12467,  12540,
5257
    12507,  12442,  12469,  12452,  12463,  12523,  12469,  12531,  12481,
5258
    12540,  12512,  12471,  12522,  12531,  12463,  12441,  12475,  12531,
5259
    12481,  12475,  12531,  12488,  12479,  12441,  12540,  12473,  12486,
5260
    12441,  12471,  12488,  12441,  12523,  12488,  12531,  12490,  12494,
5261
    12494,  12483,  12488,  12495,  12452,  12484,  12495,  12442,  12540,
5262
    12475,  12531,  12488,  12495,  12442,  12540,  12484,  12495,  12441,
5263
    12540,  12524,  12523,  12498,  12442,  12450,  12473,  12488,  12523,
5264
    12498,  12442,  12463,  12523,  12498,  12442,  12467,  12498,  12441,
5265
    12523,  12501,  12449,  12521,  12483,  12488,  12441,  12501,  12451,
5266
    12540,  12488,  12501,  12441,  12483,  12471,  12455,  12523,  12501,
5267
    12521,  12531,  12504,  12463,  12479,  12540,  12523,  12504,  12442,
5268
    12477,  12504,  12442,  12491,  12498,  12504,  12523,  12484,  12504,
5269
    12442,  12531,  12473,  12504,  12442,  12540,  12471,  12441,  12504,
5270
    12441,  12540,  12479,  12507,  12442,  12452,  12531,  12488,  12507,
5271
    12441,  12523,  12488,  12507,  12531,  12507,  12442,  12531,  12488,
5272
    12441,  12507,  12540,  12523,  12507,  12540,  12531,  12510,  12452,
5273
    12463,  12525,  12510,  12452,  12523,  12510,  12483,  12495,  12510,
5274
    12523,  12463,  12510,  12531,  12471,  12519,  12531,  12511,  12463,
5275
    12525,  12531,  12511,  12522,  12511,  12522,  12495,  12441,  12540,
5276
    12523,  12513,  12459,  12441,  12513,  12459,  12441,  12488,  12531,
5277
    12513,  12540,  12488,  12523,  12516,  12540,  12488,  12441,  12516,
5278
    12540,  12523,  12518,  12450,  12531,  12522,  12483,  12488,  12523,
5279
    12522,  12521,  12523,  12498,  12442,  12540,  12523,  12540,  12501,
5280
    12441,  12523,  12524,  12512,  12524,  12531,  12488,  12465,  12441,
5281
    12531,  12527,  12483,  12488,  48,     28857,  49,     28857,  50,
5282
    28857,  51,     28857,  52,     28857,  53,     28857,  54,     28857,
5283
    55,     28857,  56,     28857,  57,     28857,  49,     48,     28857,
5284
    49,     49,     28857,  49,     50,     28857,  49,     51,     28857,
5285
    49,     52,     28857,  49,     53,     28857,  49,     54,     28857,
5286
    49,     55,     28857,  49,     56,     28857,  49,     57,     28857,
5287
    50,     48,     28857,  50,     49,     28857,  50,     50,     28857,
5288
    50,     51,     28857,  50,     52,     28857,  104,    80,     97,
5289
    100,    97,     65,     85,     98,     97,     114,    111,    86,
5290
    112,    99,     100,    109,    100,    109,    50,     100,    109,
5291
    51,     73,     85,     24179,  25104,  26157,  21644,  22823,  27491,
5292
    26126,  27835,  26666,  24335,  20250,  31038,  112,    65,     110,
5293
    65,     956,    65,     109,    65,     107,    65,     75,     66,
5294
    77,     66,     71,     66,     99,     97,     108,    107,    99,
5295
    97,     108,    112,    70,     110,    70,     956,    70,     956,
5296
    103,    109,    103,    107,    103,    72,     122,    107,    72,
5297
    122,    77,     72,     122,    71,     72,     122,    84,     72,
5298
    122,    956,    108,    109,    108,    100,    108,    107,    108,
5299
    102,    109,    110,    109,    956,    109,    109,    109,    99,
5300
    109,    107,    109,    109,    109,    50,     99,     109,    50,
5301
    109,    50,     107,    109,    50,     109,    109,    51,     99,
5302
    109,    51,     109,    51,     107,    109,    51,     109,    8725,
5303
    115,    109,    8725,   115,    50,     80,     97,     107,    80,
5304
    97,     77,     80,     97,     71,     80,     97,     114,    97,
5305
    100,    114,    97,     100,    8725,   115,    114,    97,     100,
5306
    8725,   115,    50,     112,    115,    110,    115,    956,    115,
5307
    109,    115,    112,    86,     110,    86,     956,    86,     109,
5308
    86,     107,    86,     77,     86,     112,    87,     110,    87,
5309
    956,    87,     109,    87,     107,    87,     77,     87,     107,
5310
    937,    77,     937,    97,     46,     109,    46,     66,     113,
5311
    99,     99,     99,     100,    67,     8725,   107,    103,    67,
5312
    111,    46,     100,    66,     71,     121,    104,    97,     72,
5313
    80,     105,    110,    75,     75,     75,     77,     107,    116,
5314
    108,    109,    108,    110,    108,    111,    103,    108,    120,
5315
    109,    98,     109,    105,    108,    109,    111,    108,    80,
5316
    72,     112,    46,     109,    46,     80,     80,     77,     80,
5317
    82,     115,    114,    83,     118,    87,     98,     86,     8725,
5318
    109,    65,     8725,   109,    49,     26085,  50,     26085,  51,
5319
    26085,  52,     26085,  53,     26085,  54,     26085,  55,     26085,
5320
    56,     26085,  57,     26085,  49,     48,     26085,  49,     49,
5321
    26085,  49,     50,     26085,  49,     51,     26085,  49,     52,
5322
    26085,  49,     53,     26085,  49,     54,     26085,  49,     55,
5323
    26085,  49,     56,     26085,  49,     57,     26085,  50,     48,
5324
    26085,  50,     49,     26085,  50,     50,     26085,  50,     51,
5325
    26085,  50,     52,     26085,  50,     53,     26085,  50,     54,
5326
    26085,  50,     55,     26085,  50,     56,     26085,  50,     57,
5327
    26085,  51,     48,     26085,  51,     49,     26085,  103,    97,
5328
    108,    1098,   1100,   42863,  67,     70,     81,     294,    339,
5329
    42791,  43831,  619,    43858,  653,    35912,  26356,  36554,  36040,
5330
    28369,  20018,  21477,  40860,  40860,  22865,  37329,  21895,  22856,
5331
    25078,  30313,  32645,  34367,  34746,  35064,  37007,  27138,  27931,
5332
    28889,  29662,  33853,  37226,  39409,  20098,  21365,  27396,  29211,
5333
    34349,  40478,  23888,  28651,  34253,  35172,  25289,  33240,  34847,
5334
    24266,  26391,  28010,  29436,  37070,  20358,  20919,  21214,  25796,
5335
    27347,  29200,  30439,  32769,  34310,  34396,  36335,  38706,  39791,
5336
    40442,  30860,  31103,  32160,  33737,  37636,  40575,  35542,  22751,
5337
    24324,  31840,  32894,  29282,  30922,  36034,  38647,  22744,  23650,
5338
    27155,  28122,  28431,  32047,  32311,  38475,  21202,  32907,  20956,
5339
    20940,  31260,  32190,  33777,  38517,  35712,  25295,  27138,  35582,
5340
    20025,  23527,  24594,  29575,  30064,  21271,  30971,  20415,  24489,
5341
    19981,  27852,  25976,  32034,  21443,  22622,  30465,  33865,  35498,
5342
    27578,  36784,  27784,  25342,  33509,  25504,  30053,  20142,  20841,
5343
    20937,  26753,  31975,  33391,  35538,  37327,  21237,  21570,  22899,
5344
    24300,  26053,  28670,  31018,  38317,  39530,  40599,  40654,  21147,
5345
    26310,  27511,  36706,  24180,  24976,  25088,  25754,  28451,  29001,
5346
    29833,  31178,  32244,  32879,  36646,  34030,  36899,  37706,  21015,
5347
    21155,  21693,  28872,  35010,  35498,  24265,  24565,  25467,  27566,
5348
    31806,  29557,  20196,  22265,  23527,  23994,  24604,  29618,  29801,
5349
    32666,  32838,  37428,  38646,  38728,  38936,  20363,  31150,  37300,
5350
    38584,  24801,  20102,  20698,  23534,  23615,  26009,  27138,  29134,
5351
    30274,  34044,  36988,  40845,  26248,  38446,  21129,  26491,  26611,
5352
    27969,  28316,  29705,  30041,  30827,  32016,  39006,  20845,  25134,
5353
    38520,  20523,  23833,  28138,  36650,  24459,  24900,  26647,  29575,
5354
    38534,  21033,  21519,  23653,  26131,  26446,  26792,  27877,  29702,
5355
    30178,  32633,  35023,  35041,  37324,  38626,  21311,  28346,  21533,
5356
    29136,  29848,  34298,  38563,  40023,  40607,  26519,  28107,  33256,
5357
    31435,  31520,  31890,  29376,  28825,  35672,  20160,  33590,  21050,
5358
    20999,  24230,  25299,  31958,  23429,  27934,  26292,  36667,  34892,
5359
    38477,  35211,  24275,  20800,  21952,  22618,  26228,  20958,  29482,
5360
    30410,  31036,  31070,  31077,  31119,  38742,  31934,  32701,  34322,
5361
    35576,  36920,  37117,  39151,  39164,  39208,  40372,  37086,  38583,
5362
    20398,  20711,  20813,  21193,  21220,  21329,  21917,  22022,  22120,
5363
    22592,  22696,  23652,  23662,  24724,  24936,  24974,  25074,  25935,
5364
    26082,  26257,  26757,  28023,  28186,  28450,  29038,  29227,  29730,
5365
    30865,  31038,  31049,  31048,  31056,  31062,  31069,  31117,  31118,
5366
    31296,  31361,  31680,  32244,  32265,  32321,  32626,  32773,  33261,
5367
    33401,  33401,  33879,  35088,  35222,  35585,  35641,  36051,  36104,
5368
    36790,  36920,  38627,  38911,  38971,  24693,  148206, 33304,  20006,
5369
    20917,  20840,  20352,  20805,  20864,  21191,  21242,  21917,  21845,
5370
    21913,  21986,  22618,  22707,  22852,  22868,  23138,  23336,  24274,
5371
    24281,  24425,  24493,  24792,  24910,  24840,  24974,  24928,  25074,
5372
    25140,  25540,  25628,  25682,  25942,  26228,  26391,  26395,  26454,
5373
    27513,  27578,  27969,  28379,  28363,  28450,  28702,  29038,  30631,
5374
    29237,  29359,  29482,  29809,  29958,  30011,  30237,  30239,  30410,
5375
    30427,  30452,  30538,  30528,  30924,  31409,  31680,  31867,  32091,
5376
    32244,  32574,  32773,  33618,  33775,  34681,  35137,  35206,  35222,
5377
    35519,  35576,  35531,  35585,  35582,  35565,  35641,  35722,  36104,
5378
    36664,  36978,  37273,  37494,  38524,  38627,  38742,  38875,  38911,
5379
    38923,  38971,  39698,  40860,  141386, 141380, 144341, 15261,  16408,
5380
    16441,  152137, 154832, 163539, 40771,  40846,  102,    102,    102,
5381
    105,    102,    108,    102,    102,    105,    102,    102,    108,
5382
    115,    116,    115,    116,    1396,   1398,   1396,   1381,   1396,
5383
    1387,   1406,   1398,   1396,   1389,   1497,   1460,   1522,   1463,
5384
    1506,   1488,   1491,   1492,   1499,   1500,   1501,   1512,   1514,
5385
    43,     1513,   1473,   1513,   1474,   1513,   1468,   1473,   1513,
5386
    1468,   1474,   1488,   1463,   1488,   1464,   1488,   1468,   1489,
5387
    1468,   1490,   1468,   1491,   1468,   1492,   1468,   1493,   1468,
5388
    1494,   1468,   1496,   1468,   1497,   1468,   1498,   1468,   1499,
5389
    1468,   1500,   1468,   1502,   1468,   1504,   1468,   1505,   1468,
5390
    1507,   1468,   1508,   1468,   1510,   1468,   1511,   1468,   1512,
5391
    1468,   1513,   1468,   1514,   1468,   1493,   1465,   1489,   1471,
5392
    1499,   1471,   1508,   1471,   1488,   1500,   1649,   1649,   1659,
5393
    1659,   1659,   1659,   1662,   1662,   1662,   1662,   1664,   1664,
5394
    1664,   1664,   1658,   1658,   1658,   1658,   1663,   1663,   1663,
5395
    1663,   1657,   1657,   1657,   1657,   1700,   1700,   1700,   1700,
5396
    1702,   1702,   1702,   1702,   1668,   1668,   1668,   1668,   1667,
5397
    1667,   1667,   1667,   1670,   1670,   1670,   1670,   1671,   1671,
5398
    1671,   1671,   1677,   1677,   1676,   1676,   1678,   1678,   1672,
5399
    1672,   1688,   1688,   1681,   1681,   1705,   1705,   1705,   1705,
5400
    1711,   1711,   1711,   1711,   1715,   1715,   1715,   1715,   1713,
5401
    1713,   1713,   1713,   1722,   1722,   1723,   1723,   1723,   1723,
5402
    1749,   1620,   1749,   1620,   1729,   1729,   1729,   1729,   1726,
5403
    1726,   1726,   1726,   1746,   1746,   1746,   1620,   1746,   1620,
5404
    1709,   1709,   1709,   1709,   1735,   1735,   1734,   1734,   1736,
5405
    1736,   1735,   1652,   1739,   1739,   1733,   1733,   1737,   1737,
5406
    1744,   1744,   1744,   1744,   1609,   1609,   1610,   1620,   1575,
5407
    1610,   1620,   1575,   1610,   1620,   1749,   1610,   1620,   1749,
5408
    1610,   1620,   1608,   1610,   1620,   1608,   1610,   1620,   1735,
5409
    1610,   1620,   1735,   1610,   1620,   1734,   1610,   1620,   1734,
5410
    1610,   1620,   1736,   1610,   1620,   1736,   1610,   1620,   1744,
5411
    1610,   1620,   1744,   1610,   1620,   1744,   1610,   1620,   1609,
5412
    1610,   1620,   1609,   1610,   1620,   1609,   1740,   1740,   1740,
5413
    1740,   1610,   1620,   1580,   1610,   1620,   1581,   1610,   1620,
5414
    1605,   1610,   1620,   1609,   1610,   1620,   1610,   1576,   1580,
5415
    1576,   1581,   1576,   1582,   1576,   1605,   1576,   1609,   1576,
5416
    1610,   1578,   1580,   1578,   1581,   1578,   1582,   1578,   1605,
5417
    1578,   1609,   1578,   1610,   1579,   1580,   1579,   1605,   1579,
5418
    1609,   1579,   1610,   1580,   1581,   1580,   1605,   1581,   1580,
5419
    1581,   1605,   1582,   1580,   1582,   1581,   1582,   1605,   1587,
5420
    1580,   1587,   1581,   1587,   1582,   1587,   1605,   1589,   1581,
5421
    1589,   1605,   1590,   1580,   1590,   1581,   1590,   1582,   1590,
5422
    1605,   1591,   1581,   1591,   1605,   1592,   1605,   1593,   1580,
5423
    1593,   1605,   1594,   1580,   1594,   1605,   1601,   1580,   1601,
5424
    1581,   1601,   1582,   1601,   1605,   1601,   1609,   1601,   1610,
5425
    1602,   1581,   1602,   1605,   1602,   1609,   1602,   1610,   1603,
5426
    1575,   1603,   1580,   1603,   1581,   1603,   1582,   1603,   1604,
5427
    1603,   1605,   1603,   1609,   1603,   1610,   1604,   1580,   1604,
5428
    1581,   1604,   1582,   1604,   1605,   1604,   1609,   1604,   1610,
5429
    1605,   1580,   1605,   1581,   1605,   1582,   1605,   1605,   1605,
5430
    1609,   1605,   1610,   1606,   1580,   1606,   1581,   1606,   1582,
5431
    1606,   1605,   1606,   1609,   1606,   1610,   1607,   1580,   1607,
5432
    1605,   1607,   1609,   1607,   1610,   1610,   1580,   1610,   1581,
5433
    1610,   1582,   1610,   1605,   1610,   1609,   1610,   1610,   1584,
5434
    1648,   1585,   1648,   1609,   1648,   32,     1612,   1617,   32,
5435
    1613,   1617,   32,     1614,   1617,   32,     1615,   1617,   32,
5436
    1616,   1617,   32,     1617,   1648,   1610,   1620,   1585,   1610,
5437
    1620,   1586,   1610,   1620,   1605,   1610,   1620,   1606,   1610,
5438
    1620,   1609,   1610,   1620,   1610,   1576,   1585,   1576,   1586,
5439
    1576,   1605,   1576,   1606,   1576,   1609,   1576,   1610,   1578,
5440
    1585,   1578,   1586,   1578,   1605,   1578,   1606,   1578,   1609,
5441
    1578,   1610,   1579,   1585,   1579,   1586,   1579,   1605,   1579,
5442
    1606,   1579,   1609,   1579,   1610,   1601,   1609,   1601,   1610,
5443
    1602,   1609,   1602,   1610,   1603,   1575,   1603,   1604,   1603,
5444
    1605,   1603,   1609,   1603,   1610,   1604,   1605,   1604,   1609,
5445
    1604,   1610,   1605,   1575,   1605,   1605,   1606,   1585,   1606,
5446
    1586,   1606,   1605,   1606,   1606,   1606,   1609,   1606,   1610,
5447
    1609,   1648,   1610,   1585,   1610,   1586,   1610,   1605,   1610,
5448
    1606,   1610,   1609,   1610,   1610,   1610,   1620,   1580,   1610,
5449
    1620,   1581,   1610,   1620,   1582,   1610,   1620,   1605,   1610,
5450
    1620,   1607,   1576,   1580,   1576,   1581,   1576,   1582,   1576,
5451
    1605,   1576,   1607,   1578,   1580,   1578,   1581,   1578,   1582,
5452
    1578,   1605,   1578,   1607,   1579,   1605,   1580,   1581,   1580,
5453
    1605,   1581,   1580,   1581,   1605,   1582,   1580,   1582,   1605,
5454
    1587,   1580,   1587,   1581,   1587,   1582,   1587,   1605,   1589,
5455
    1581,   1589,   1582,   1589,   1605,   1590,   1580,   1590,   1581,
5456
    1590,   1582,   1590,   1605,   1591,   1581,   1592,   1605,   1593,
5457
    1580,   1593,   1605,   1594,   1580,   1594,   1605,   1601,   1580,
5458
    1601,   1581,   1601,   1582,   1601,   1605,   1602,   1581,   1602,
5459
    1605,   1603,   1580,   1603,   1581,   1603,   1582,   1603,   1604,
5460
    1603,   1605,   1604,   1580,   1604,   1581,   1604,   1582,   1604,
5461
    1605,   1604,   1607,   1605,   1580,   1605,   1581,   1605,   1582,
5462
    1605,   1605,   1606,   1580,   1606,   1581,   1606,   1582,   1606,
5463
    1605,   1606,   1607,   1607,   1580,   1607,   1605,   1607,   1648,
5464
    1610,   1580,   1610,   1581,   1610,   1582,   1610,   1605,   1610,
5465
    1607,   1610,   1620,   1605,   1610,   1620,   1607,   1576,   1605,
5466
    1576,   1607,   1578,   1605,   1578,   1607,   1579,   1605,   1579,
5467
    1607,   1587,   1605,   1587,   1607,   1588,   1605,   1588,   1607,
5468
    1603,   1604,   1603,   1605,   1604,   1605,   1606,   1605,   1606,
5469
    1607,   1610,   1605,   1610,   1607,   1600,   1614,   1617,   1600,
5470
    1615,   1617,   1600,   1616,   1617,   1591,   1609,   1591,   1610,
5471
    1593,   1609,   1593,   1610,   1594,   1609,   1594,   1610,   1587,
5472
    1609,   1587,   1610,   1588,   1609,   1588,   1610,   1581,   1609,
5473
    1581,   1610,   1580,   1609,   1580,   1610,   1582,   1609,   1582,
5474
    1610,   1589,   1609,   1589,   1610,   1590,   1609,   1590,   1610,
5475
    1588,   1580,   1588,   1581,   1588,   1582,   1588,   1605,   1588,
5476
    1585,   1587,   1585,   1589,   1585,   1590,   1585,   1591,   1609,
5477
    1591,   1610,   1593,   1609,   1593,   1610,   1594,   1609,   1594,
5478
    1610,   1587,   1609,   1587,   1610,   1588,   1609,   1588,   1610,
5479
    1581,   1609,   1581,   1610,   1580,   1609,   1580,   1610,   1582,
5480
    1609,   1582,   1610,   1589,   1609,   1589,   1610,   1590,   1609,
5481
    1590,   1610,   1588,   1580,   1588,   1581,   1588,   1582,   1588,
5482
    1605,   1588,   1585,   1587,   1585,   1589,   1585,   1590,   1585,
5483
    1588,   1580,   1588,   1581,   1588,   1582,   1588,   1605,   1587,
5484
    1607,   1588,   1607,   1591,   1605,   1587,   1580,   1587,   1581,
5485
    1587,   1582,   1588,   1580,   1588,   1581,   1588,   1582,   1591,
5486
    1605,   1592,   1605,   1575,   1611,   1575,   1611,   1578,   1580,
5487
    1605,   1578,   1581,   1580,   1578,   1581,   1580,   1578,   1581,
5488
    1605,   1578,   1582,   1605,   1578,   1605,   1580,   1578,   1605,
5489
    1581,   1578,   1605,   1582,   1580,   1605,   1581,   1580,   1605,
5490
    1581,   1581,   1605,   1610,   1581,   1605,   1609,   1587,   1581,
5491
    1580,   1587,   1580,   1581,   1587,   1580,   1609,   1587,   1605,
5492
    1581,   1587,   1605,   1581,   1587,   1605,   1580,   1587,   1605,
5493
    1605,   1587,   1605,   1605,   1589,   1581,   1581,   1589,   1581,
5494
    1581,   1589,   1605,   1605,   1588,   1581,   1605,   1588,   1581,
5495
    1605,   1588,   1580,   1610,   1588,   1605,   1582,   1588,   1605,
5496
    1582,   1588,   1605,   1605,   1588,   1605,   1605,   1590,   1581,
5497
    1609,   1590,   1582,   1605,   1590,   1582,   1605,   1591,   1605,
5498
    1581,   1591,   1605,   1581,   1591,   1605,   1605,   1591,   1605,
5499
    1610,   1593,   1580,   1605,   1593,   1605,   1605,   1593,   1605,
5500
    1605,   1593,   1605,   1609,   1594,   1605,   1605,   1594,   1605,
5501
    1610,   1594,   1605,   1609,   1601,   1582,   1605,   1601,   1582,
5502
    1605,   1602,   1605,   1581,   1602,   1605,   1605,   1604,   1581,
5503
    1605,   1604,   1581,   1610,   1604,   1581,   1609,   1604,   1580,
5504
    1580,   1604,   1580,   1580,   1604,   1582,   1605,   1604,   1582,
5505
    1605,   1604,   1605,   1581,   1604,   1605,   1581,   1605,   1581,
5506
    1580,   1605,   1581,   1605,   1605,   1581,   1610,   1605,   1580,
5507
    1581,   1605,   1580,   1605,   1605,   1582,   1580,   1605,   1582,
5508
    1605,   1605,   1580,   1582,   1607,   1605,   1580,   1607,   1605,
5509
    1605,   1606,   1581,   1605,   1606,   1581,   1609,   1606,   1580,
5510
    1605,   1606,   1580,   1605,   1606,   1580,   1609,   1606,   1605,
5511
    1610,   1606,   1605,   1609,   1610,   1605,   1605,   1610,   1605,
5512
    1605,   1576,   1582,   1610,   1578,   1580,   1610,   1578,   1580,
5513
    1609,   1578,   1582,   1610,   1578,   1582,   1609,   1578,   1605,
5514
    1610,   1578,   1605,   1609,   1580,   1605,   1610,   1580,   1581,
5515
    1609,   1580,   1605,   1609,   1587,   1582,   1609,   1589,   1581,
5516
    1610,   1588,   1581,   1610,   1590,   1581,   1610,   1604,   1580,
5517
    1610,   1604,   1605,   1610,   1610,   1581,   1610,   1610,   1580,
5518
    1610,   1610,   1605,   1610,   1605,   1605,   1610,   1602,   1605,
5519
    1610,   1606,   1581,   1610,   1602,   1605,   1581,   1604,   1581,
5520
    1605,   1593,   1605,   1610,   1603,   1605,   1610,   1606,   1580,
5521
    1581,   1605,   1582,   1610,   1604,   1580,   1605,   1603,   1605,
5522
    1605,   1604,   1580,   1605,   1606,   1580,   1581,   1580,   1581,
5523
    1610,   1581,   1580,   1610,   1605,   1580,   1610,   1601,   1605,
5524
    1610,   1576,   1581,   1610,   1603,   1605,   1605,   1593,   1580,
5525
    1605,   1589,   1605,   1605,   1587,   1582,   1610,   1606,   1580,
5526
    1610,   1589,   1604,   1746,   1602,   1604,   1746,   1575,   1604,
5527
    1604,   1607,   1575,   1603,   1576,   1585,   1605,   1581,   1605,
5528
    1583,   1589,   1604,   1593,   1605,   1585,   1587,   1608,   1604,
5529
    1593,   1604,   1610,   1607,   1608,   1587,   1604,   1605,   1589,
5530
    1604,   1609,   1589,   1604,   1609,   32,     1575,   1604,   1604,
5531
    1607,   32,     1593,   1604,   1610,   1607,   32,     1608,   1587,
5532
    1604,   1605,   1580,   1604,   32,     1580,   1604,   1575,   1604,
5533
    1607,   1585,   1740,   1575,   1604,   44,     12289,  12290,  58,
5534
    59,     33,     63,     12310,  12311,  46,     46,     46,     46,
5535
    46,     8212,   8211,   95,     95,     40,     41,     123,    125,
5536
    12308,  12309,  12304,  12305,  12298,  12299,  12296,  12297,  12300,
5537
    12301,  12302,  12303,  91,     93,     32,     773,    32,     773,
5538
    32,     773,    32,     773,    95,     95,     95,     44,     12289,
5539
    46,     59,     58,     63,     33,     8212,   40,     41,     123,
5540
    125,    12308,  12309,  35,     38,     42,     43,     45,     60,
5541
    62,     61,     92,     36,     37,     64,     32,     1611,   1600,
5542
    1611,   32,     1612,   32,     1613,   32,     1614,   1600,   1614,
5543
    32,     1615,   1600,   1615,   32,     1616,   1600,   1616,   32,
5544
    1617,   1600,   1617,   32,     1618,   1600,   1618,   1569,   1575,
5545
    1619,   1575,   1619,   1575,   1620,   1575,   1620,   1608,   1620,
5546
    1608,   1620,   1575,   1621,   1575,   1621,   1610,   1620,   1610,
5547
    1620,   1610,   1620,   1610,   1620,   1575,   1575,   1576,   1576,
5548
    1576,   1576,   1577,   1577,   1578,   1578,   1578,   1578,   1579,
5549
    1579,   1579,   1579,   1580,   1580,   1580,   1580,   1581,   1581,
5550
    1581,   1581,   1582,   1582,   1582,   1582,   1583,   1583,   1584,
5551
    1584,   1585,   1585,   1586,   1586,   1587,   1587,   1587,   1587,
5552
    1588,   1588,   1588,   1588,   1589,   1589,   1589,   1589,   1590,
5553
    1590,   1590,   1590,   1591,   1591,   1591,   1591,   1592,   1592,
5554
    1592,   1592,   1593,   1593,   1593,   1593,   1594,   1594,   1594,
5555
    1594,   1601,   1601,   1601,   1601,   1602,   1602,   1602,   1602,
5556
    1603,   1603,   1603,   1603,   1604,   1604,   1604,   1604,   1605,
5557
    1605,   1605,   1605,   1606,   1606,   1606,   1606,   1607,   1607,
5558
    1607,   1607,   1608,   1608,   1609,   1609,   1610,   1610,   1610,
5559
    1610,   1604,   1575,   1619,   1604,   1575,   1619,   1604,   1575,
5560
    1620,   1604,   1575,   1620,   1604,   1575,   1621,   1604,   1575,
5561
    1621,   1604,   1575,   1604,   1575,   33,     34,     35,     36,
5562
    37,     38,     39,     40,     41,     42,     43,     44,     45,
5563
    46,     47,     48,     49,     50,     51,     52,     53,     54,
5564
    55,     56,     57,     58,     59,     60,     61,     62,     63,
5565
    64,     65,     66,     67,     68,     69,     70,     71,     72,
5566
    73,     74,     75,     76,     77,     78,     79,     80,     81,
5567
    82,     83,     84,     85,     86,     87,     88,     89,     90,
5568
    91,     92,     93,     94,     95,     96,     97,     98,     99,
5569
    100,    101,    102,    103,    104,    105,    106,    107,    108,
5570
    109,    110,    111,    112,    113,    114,    115,    116,    117,
5571
    118,    119,    120,    121,    122,    123,    124,    125,    126,
5572
    10629,  10630,  12290,  12300,  12301,  12289,  12539,  12530,  12449,
5573
    12451,  12453,  12455,  12457,  12515,  12517,  12519,  12483,  12540,
5574
    12450,  12452,  12454,  12456,  12458,  12459,  12461,  12463,  12465,
5575
    12467,  12469,  12471,  12473,  12475,  12477,  12479,  12481,  12484,
5576
    12486,  12488,  12490,  12491,  12492,  12493,  12494,  12495,  12498,
5577
    12501,  12504,  12507,  12510,  12511,  12512,  12513,  12514,  12516,
5578
    12518,  12520,  12521,  12522,  12523,  12524,  12525,  12527,  12531,
5579
    12441,  12442,  4448,   4352,   4353,   4522,   4354,   4524,   4525,
5580
    4355,   4356,   4357,   4528,   4529,   4530,   4531,   4532,   4533,
5581
    4378,   4358,   4359,   4360,   4385,   4361,   4362,   4363,   4364,
5582
    4365,   4366,   4367,   4368,   4369,   4370,   4449,   4450,   4451,
5583
    4452,   4453,   4454,   4455,   4456,   4457,   4458,   4459,   4460,
5584
    4461,   4462,   4463,   4464,   4465,   4466,   4467,   4468,   4469,
5585
    162,    163,    172,    32,     772,    166,    165,    8361,   9474,
5586
    8592,   8593,   8594,   8595,   9632,   9675,   720,    721,    230,
5587
    665,    595,    675,    43878,  677,    676,    598,    599,    7569,
5588
    600,    606,    681,    612,    610,    608,    667,    295,    668,
5589
    615,    644,    682,    683,    620,    122628, 42894,  622,    122629,
5590
    654,    122630, 248,    630,    631,    113,    634,    122632, 637,
5591
    638,    640,    680,    678,    43879,  679,    648,    11377,  655,
5592
    673,    674,    664,    448,    449,    450,    122634, 122654, 69785,
5593
    69818,  69787,  69818,  69797,  69818,  69937,  69927,  69938,  69927,
5594
    70471,  70462,  70471,  70487,  70841,  70842,  70841,  70832,  70841,
5595
    70845,  71096,  71087,  71097,  71087,  71989,  71984,  119127, 119141,
5596
    119128, 119141, 119128, 119141, 119150, 119128, 119141, 119151, 119128,
5597
    119141, 119152, 119128, 119141, 119153, 119128, 119141, 119154, 119225,
5598
    119141, 119226, 119141, 119225, 119141, 119150, 119226, 119141, 119150,
5599
    119225, 119141, 119151, 119226, 119141, 119151, 65,     66,     67,
5600
    68,     69,     70,     71,     72,     73,     74,     75,     76,
5601
    77,     78,     79,     80,     81,     82,     83,     84,     85,
5602
    86,     87,     88,     89,     90,     97,     98,     99,     100,
5603
    101,    102,    103,    104,    105,    106,    107,    108,    109,
5604
    110,    111,    112,    113,    114,    115,    116,    117,    118,
5605
    119,    120,    121,    122,    65,     66,     67,     68,     69,
5606
    70,     71,     72,     73,     74,     75,     76,     77,     78,
5607
    79,     80,     81,     82,     83,     84,     85,     86,     87,
5608
    88,     89,     90,     97,     98,     99,     100,    101,    102,
5609
    103,    105,    106,    107,    108,    109,    110,    111,    112,
5610
    113,    114,    115,    116,    117,    118,    119,    120,    121,
5611
    122,    65,     66,     67,     68,     69,     70,     71,     72,
5612
    73,     74,     75,     76,     77,     78,     79,     80,     81,
5613
    82,     83,     84,     85,     86,     87,     88,     89,     90,
5614
    97,     98,     99,     100,    101,    102,    103,    104,    105,
5615
    106,    107,    108,    109,    110,    111,    112,    113,    114,
5616
    115,    116,    117,    118,    119,    120,    121,    122,    65,
5617
    67,     68,     71,     74,     75,     78,     79,     80,     81,
5618
    83,     84,     85,     86,     87,     88,     89,     90,     97,
5619
    98,     99,     100,    102,    104,    105,    106,    107,    108,
5620
    109,    110,    112,    113,    114,    115,    116,    117,    118,
5621
    119,    120,    121,    122,    65,     66,     67,     68,     69,
5622
    70,     71,     72,     73,     74,     75,     76,     77,     78,
5623
    79,     80,     81,     82,     83,     84,     85,     86,     87,
5624
    88,     89,     90,     97,     98,     99,     100,    101,    102,
5625
    103,    104,    105,    106,    107,    108,    109,    110,    111,
5626
    112,    113,    114,    115,    116,    117,    118,    119,    120,
5627
    121,    122,    65,     66,     68,     69,     70,     71,     74,
5628
    75,     76,     77,     78,     79,     80,     81,     83,     84,
5629
    85,     86,     87,     88,     89,     97,     98,     99,     100,
5630
    101,    102,    103,    104,    105,    106,    107,    108,    109,
5631
    110,    111,    112,    113,    114,    115,    116,    117,    118,
5632
    119,    120,    121,    122,    65,     66,     68,     69,     70,
5633
    71,     73,     74,     75,     76,     77,     79,     83,     84,
5634
    85,     86,     87,     88,     89,     97,     98,     99,     100,
5635
    101,    102,    103,    104,    105,    106,    107,    108,    109,
5636
    110,    111,    112,    113,    114,    115,    116,    117,    118,
5637
    119,    120,    121,    122,    65,     66,     67,     68,     69,
5638
    70,     71,     72,     73,     74,     75,     76,     77,     78,
5639
    79,     80,     81,     82,     83,     84,     85,     86,     87,
5640
    88,     89,     90,     97,     98,     99,     100,    101,    102,
5641
    103,    104,    105,    106,    107,    108,    109,    110,    111,
5642
    112,    113,    114,    115,    116,    117,    118,    119,    120,
5643
    121,    122,    65,     66,     67,     68,     69,     70,     71,
5644
    72,     73,     74,     75,     76,     77,     78,     79,     80,
5645
    81,     82,     83,     84,     85,     86,     87,     88,     89,
5646
    90,     97,     98,     99,     100,    101,    102,    103,    104,
5647
    105,    106,    107,    108,    109,    110,    111,    112,    113,
5648
    114,    115,    116,    117,    118,    119,    120,    121,    122,
5649
    65,     66,     67,     68,     69,     70,     71,     72,     73,
5650
    74,     75,     76,     77,     78,     79,     80,     81,     82,
5651
    83,     84,     85,     86,     87,     88,     89,     90,     97,
5652
    98,     99,     100,    101,    102,    103,    104,    105,    106,
5653
    107,    108,    109,    110,    111,    112,    113,    114,    115,
5654
    116,    117,    118,    119,    120,    121,    122,    65,     66,
5655
    67,     68,     69,     70,     71,     72,     73,     74,     75,
5656
    76,     77,     78,     79,     80,     81,     82,     83,     84,
5657
    85,     86,     87,     88,     89,     90,     97,     98,     99,
5658
    100,    101,    102,    103,    104,    105,    106,    107,    108,
5659
    109,    110,    111,    112,    113,    114,    115,    116,    117,
5660
    118,    119,    120,    121,    122,    65,     66,     67,     68,
5661
    69,     70,     71,     72,     73,     74,     75,     76,     77,
5662
    78,     79,     80,     81,     82,     83,     84,     85,     86,
5663
    87,     88,     89,     90,     97,     98,     99,     100,    101,
5664
    102,    103,    104,    105,    106,    107,    108,    109,    110,
5665
    111,    112,    113,    114,    115,    116,    117,    118,    119,
5666
    120,    121,    122,    65,     66,     67,     68,     69,     70,
5667
    71,     72,     73,     74,     75,     76,     77,     78,     79,
5668
    80,     81,     82,     83,     84,     85,     86,     87,     88,
5669
    89,     90,     97,     98,     99,     100,    101,    102,    103,
5670
    104,    105,    106,    107,    108,    109,    110,    111,    112,
5671
    113,    114,    115,    116,    117,    118,    119,    120,    121,
5672
    122,    305,    567,    913,    914,    915,    916,    917,    918,
5673
    919,    920,    921,    922,    923,    924,    925,    926,    927,
5674
    928,    929,    920,    931,    932,    933,    934,    935,    936,
5675
    937,    8711,   945,    946,    947,    948,    949,    950,    951,
5676
    952,    953,    954,    955,    956,    957,    958,    959,    960,
5677
    961,    962,    963,    964,    965,    966,    967,    968,    969,
5678
    8706,   949,    952,    954,    966,    961,    960,    913,    914,
5679
    915,    916,    917,    918,    919,    920,    921,    922,    923,
5680
    924,    925,    926,    927,    928,    929,    920,    931,    932,
5681
    933,    934,    935,    936,    937,    8711,   945,    946,    947,
5682
    948,    949,    950,    951,    952,    953,    954,    955,    956,
5683
    957,    958,    959,    960,    961,    962,    963,    964,    965,
5684
    966,    967,    968,    969,    8706,   949,    952,    954,    966,
5685
    961,    960,    913,    914,    915,    916,    917,    918,    919,
5686
    920,    921,    922,    923,    924,    925,    926,    927,    928,
5687
    929,    920,    931,    932,    933,    934,    935,    936,    937,
5688
    8711,   945,    946,    947,    948,    949,    950,    951,    952,
5689
    953,    954,    955,    956,    957,    958,    959,    960,    961,
5690
    962,    963,    964,    965,    966,    967,    968,    969,    8706,
5691
    949,    952,    954,    966,    961,    960,    913,    914,    915,
5692
    916,    917,    918,    919,    920,    921,    922,    923,    924,
5693
    925,    926,    927,    928,    929,    920,    931,    932,    933,
5694
    934,    935,    936,    937,    8711,   945,    946,    947,    948,
5695
    949,    950,    951,    952,    953,    954,    955,    956,    957,
5696
    958,    959,    960,    961,    962,    963,    964,    965,    966,
5697
    967,    968,    969,    8706,   949,    952,    954,    966,    961,
5698
    960,    913,    914,    915,    916,    917,    918,    919,    920,
5699
    921,    922,    923,    924,    925,    926,    927,    928,    929,
5700
    920,    931,    932,    933,    934,    935,    936,    937,    8711,
5701
    945,    946,    947,    948,    949,    950,    951,    952,    953,
5702
    954,    955,    956,    957,    958,    959,    960,    961,    962,
5703
    963,    964,    965,    966,    967,    968,    969,    8706,   949,
5704
    952,    954,    966,    961,    960,    988,    989,    48,     49,
5705
    50,     51,     52,     53,     54,     55,     56,     57,     48,
5706
    49,     50,     51,     52,     53,     54,     55,     56,     57,
5707
    48,     49,     50,     51,     52,     53,     54,     55,     56,
5708
    57,     48,     49,     50,     51,     52,     53,     54,     55,
5709
    56,     57,     48,     49,     50,     51,     52,     53,     54,
5710
    55,     56,     57,     1072,   1073,   1074,   1075,   1076,   1077,
5711
    1078,   1079,   1080,   1082,   1083,   1084,   1086,   1087,   1088,
5712
    1089,   1090,   1091,   1092,   1093,   1094,   1095,   1096,   1099,
5713
    1101,   1102,   42633,  1241,   1110,   1112,   1257,   1199,   1231,
5714
    1072,   1073,   1074,   1075,   1076,   1077,   1078,   1079,   1080,
5715
    1082,   1083,   1086,   1087,   1089,   1091,   1092,   1093,   1094,
5716
    1095,   1096,   1098,   1099,   1169,   1110,   1109,   1119,   1195,
5717
    42577,  1201,   1575,   1576,   1580,   1583,   1608,   1586,   1581,
5718
    1591,   1610,   1603,   1604,   1605,   1606,   1587,   1593,   1601,
5719
    1589,   1602,   1585,   1588,   1578,   1579,   1582,   1584,   1590,
5720
    1592,   1594,   1646,   1722,   1697,   1647,   1576,   1580,   1607,
5721
    1581,   1610,   1603,   1604,   1605,   1606,   1587,   1593,   1601,
5722
    1589,   1602,   1588,   1578,   1579,   1582,   1590,   1594,   1580,
5723
    1581,   1610,   1604,   1606,   1587,   1593,   1589,   1602,   1588,
5724
    1582,   1590,   1594,   1722,   1647,   1576,   1580,   1607,   1581,
5725
    1591,   1610,   1603,   1605,   1606,   1587,   1593,   1601,   1589,
5726
    1602,   1588,   1578,   1579,   1582,   1590,   1592,   1594,   1646,
5727
    1697,   1575,   1576,   1580,   1583,   1607,   1608,   1586,   1581,
5728
    1591,   1610,   1604,   1605,   1606,   1587,   1593,   1601,   1589,
5729
    1602,   1585,   1588,   1578,   1579,   1582,   1584,   1590,   1592,
5730
    1594,   1576,   1580,   1583,   1608,   1586,   1581,   1591,   1610,
5731
    1604,   1605,   1606,   1587,   1593,   1601,   1589,   1602,   1585,
5732
    1588,   1578,   1579,   1582,   1584,   1590,   1592,   1594,   48,
5733
    46,     48,     44,     49,     44,     50,     44,     51,     44,
5734
    52,     44,     53,     44,     54,     44,     55,     44,     56,
5735
    44,     57,     44,     40,     65,     41,     40,     66,     41,
5736
    40,     67,     41,     40,     68,     41,     40,     69,     41,
5737
    40,     70,     41,     40,     71,     41,     40,     72,     41,
5738
    40,     73,     41,     40,     74,     41,     40,     75,     41,
5739
    40,     76,     41,     40,     77,     41,     40,     78,     41,
5740
    40,     79,     41,     40,     80,     41,     40,     81,     41,
5741
    40,     82,     41,     40,     83,     41,     40,     84,     41,
5742
    40,     85,     41,     40,     86,     41,     40,     87,     41,
5743
    40,     88,     41,     40,     89,     41,     40,     90,     41,
5744
    12308,  83,     12309,  67,     82,     67,     68,     87,     90,
5745
    65,     66,     67,     68,     69,     70,     71,     72,     73,
5746
    74,     75,     76,     77,     78,     79,     80,     81,     82,
5747
    83,     84,     85,     86,     87,     88,     89,     90,     72,
5748
    86,     77,     86,     83,     68,     83,     83,     80,     80,
5749
    86,     87,     67,     77,     67,     77,     68,     77,     82,
5750
    68,     74,     12411,  12363,  12467,  12467,  12469,  25163,  23383,
5751
    21452,  12486,  12441,  20108,  22810,  35299,  22825,  20132,  26144,
5752
    28961,  26009,  21069,  24460,  20877,  26032,  21021,  32066,  29983,
5753
    36009,  22768,  21561,  28436,  25237,  25429,  19968,  19977,  36938,
5754
    24038,  20013,  21491,  25351,  36208,  25171,  31105,  31354,  21512,
5755
    28288,  26377,  26376,  30003,  21106,  21942,  37197,  12308,  26412,
5756
    12309,  12308,  19977,  12309,  12308,  20108,  12309,  12308,  23433,
5757
    12309,  12308,  28857,  12309,  12308,  25171,  12309,  12308,  30423,
5758
    12309,  12308,  21213,  12309,  12308,  25943,  12309,  24471,  21487,
5759
    48,     49,     50,     51,     52,     53,     54,     55,     56,
5760
    57,     20029,  20024,  20033,  131362, 20320,  20398,  20411,  20482,
5761
    20602,  20633,  20711,  20687,  13470,  132666, 20813,  20820,  20836,
5762
    20855,  132380, 13497,  20839,  20877,  132427, 20887,  20900,  20172,
5763
    20908,  20917,  168415, 20981,  20995,  13535,  21051,  21062,  21106,
5764
    21111,  13589,  21191,  21193,  21220,  21242,  21253,  21254,  21271,
5765
    21321,  21329,  21338,  21363,  21373,  21375,  21375,  21375,  133676,
5766
    28784,  21450,  21471,  133987, 21483,  21489,  21510,  21662,  21560,
5767
    21576,  21608,  21666,  21750,  21776,  21843,  21859,  21892,  21892,
5768
    21913,  21931,  21939,  21954,  22294,  22022,  22295,  22097,  22132,
5769
    20999,  22766,  22478,  22516,  22541,  22411,  22578,  22577,  22700,
5770
    136420, 22770,  22775,  22790,  22810,  22818,  22882,  136872, 136938,
5771
    23020,  23067,  23079,  23000,  23142,  14062,  14076,  23304,  23358,
5772
    23358,  137672, 23491,  23512,  23527,  23539,  138008, 23551,  23558,
5773
    24403,  23586,  14209,  23648,  23662,  23744,  23693,  138724, 23875,
5774
    138726, 23918,  23915,  23932,  24033,  24034,  14383,  24061,  24104,
5775
    24125,  24169,  14434,  139651, 14460,  24240,  24243,  24246,  24266,
5776
    172946, 24318,  140081, 140081, 33281,  24354,  24354,  14535,  144056,
5777
    156122, 24418,  24427,  14563,  24474,  24525,  24535,  24569,  24705,
5778
    14650,  14620,  24724,  141012, 24775,  24904,  24908,  24910,  24908,
5779
    24954,  24974,  25010,  24996,  25007,  25054,  25074,  25078,  25104,
5780
    25115,  25181,  25265,  25300,  25424,  142092, 25405,  25340,  25448,
5781
    25475,  25572,  142321, 25634,  25541,  25513,  14894,  25705,  25726,
5782
    25757,  25719,  14956,  25935,  25964,  143370, 26083,  26360,  26185,
5783
    15129,  26257,  15112,  15076,  20882,  20885,  26368,  26268,  32941,
5784
    17369,  26391,  26395,  26401,  26462,  26451,  144323, 15177,  26618,
5785
    26501,  26706,  26757,  144493, 26766,  26655,  26900,  15261,  26946,
5786
    27043,  27114,  27304,  145059, 27355,  15384,  27425,  145575, 27476,
5787
    15438,  27506,  27551,  27578,  27579,  146061, 138507, 146170, 27726,
5788
    146620, 27839,  27853,  27751,  27926,  27966,  28023,  27969,  28009,
5789
    28024,  28037,  146718, 27956,  28207,  28270,  15667,  28363,  28359,
5790
    147153, 28153,  28526,  147294, 147342, 28614,  28729,  28702,  28699,
5791
    15766,  28746,  28797,  28791,  28845,  132389, 28997,  148067, 29084,
5792
    148395, 29224,  29237,  29264,  149000, 29312,  29333,  149301, 149524,
5793
    29562,  29579,  16044,  29605,  16056,  16056,  29767,  29788,  29809,
5794
    29829,  29898,  16155,  29988,  150582, 30014,  150674, 30064,  139679,
5795
    30224,  151457, 151480, 151620, 16380,  16392,  30452,  151795, 151794,
5796
    151833, 151859, 30494,  30495,  30495,  30538,  16441,  30603,  16454,
5797
    16534,  152605, 30798,  30860,  30924,  16611,  153126, 31062,  153242,
5798
    153285, 31119,  31211,  16687,  31296,  31306,  31311,  153980, 154279,
5799
    154279, 31470,  16898,  154539, 31686,  31689,  16935,  154752, 31954,
5800
    17056,  31976,  31971,  32000,  155526, 32099,  17153,  32199,  32258,
5801
    32325,  17204,  156200, 156231, 17241,  156377, 32634,  156478, 32661,
5802
    32762,  32773,  156890, 156963, 32864,  157096, 32880,  144223, 17365,
5803
    32946,  33027,  17419,  33086,  23221,  157607, 157621, 144275, 144284,
5804
    33281,  33284,  36766,  17515,  33425,  33419,  33437,  21171,  33457,
5805
    33459,  33469,  33510,  158524, 33509,  33565,  33635,  33709,  33571,
5806
    33725,  33767,  33879,  33619,  33738,  33740,  33756,  158774, 159083,
5807
    158933, 17707,  34033,  34035,  34070,  160714, 34148,  159532, 17757,
5808
    17761,  159665, 159954, 17771,  34384,  34396,  34407,  34409,  34473,
5809
    34440,  34574,  34530,  34681,  34600,  34667,  34694,  17879,  34785,
5810
    34817,  17913,  34912,  34915,  161383, 35031,  35038,  17973,  35066,
5811
    13499,  161966, 162150, 18110,  18119,  35488,  35565,  35722,  35925,
5812
    162984, 36011,  36033,  36123,  36215,  163631, 133124, 36299,  36284,
5813
    36336,  133342, 36564,  36664,  165330, 165357, 37012,  37105,  37137,
5814
    165678, 37147,  37432,  37591,  37592,  37500,  37881,  37909,  166906,
5815
    38283,  18837,  38327,  167287, 18918,  38595,  23986,  38691,  168261,
5816
    168474, 19054,  19062,  38880,  168970, 19122,  169110, 38923,  38923,
5817
    38953,  169398, 39138,  19251,  39209,  39335,  39362,  39422,  19406,
5818
    170800, 39698,  40000,  40189,  19662,  19693,  40295,  172238, 19704,
5819
    172293, 172558, 172689, 40635,  19798,  40697,  40702,  40709,  40719,
5820
    40726,  40763,  173568};
5821
5822
const uint8_t canonical_combining_class_index[4352] = {
5823
    0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 0,  0,
5824
    15, 0,  0,  0,  16, 17, 18, 19, 20, 21, 22, 0,  0,  23, 0,  0,  0,  0,  0,
5825
    0,  0,  0,  0,  0,  0,  24, 25, 0,  0,  26, 0,  0,  0,  0,  0,  0,  0,  0,
5826
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5827
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5828
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5829
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5830
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5831
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  27, 0,  28, 29, 30,
5832
    31, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5833
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5834
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5835
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5836
    0,  0,  0,  0,  32, 0,  0,  33, 0,  0,  34, 35, 36, 0,  0,  0,  0,  0,  0,
5837
    37, 0,  0,  38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0,  52,
5838
    53, 0,  54, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5839
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5840
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5841
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5842
    0,  55, 56, 0,  0,  0,  57, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5843
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5844
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5845
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5846
    0,  0,  0,  0,  0,  0,  0,  58, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5847
    0,  0,  0,  0,  0,  0,  0,  0,  0,  59, 60, 0,  0,  0,  0,  0,  0,  0,  0,
5848
    0,  0,  0,  0,  0,  61, 56, 62, 0,  63, 0,  0,  0,  64, 65, 0,  0,  0,  0,
5849
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5850
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5851
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5852
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5853
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5854
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5855
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5856
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5857
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5858
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5859
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5860
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5861
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5862
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5863
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5864
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5865
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5866
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5867
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5868
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5869
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5870
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5871
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5872
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5873
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5874
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5875
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5876
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5877
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5878
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5879
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5880
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5881
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5882
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5883
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5884
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5885
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5886
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5887
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5888
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5889
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5890
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5891
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5892
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5893
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5894
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5895
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5896
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5897
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5898
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5899
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5900
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5901
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5902
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5903
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5904
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5905
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5906
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5907
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5908
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5909
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5910
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5911
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5912
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5913
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5914
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5915
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5916
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5917
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5918
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5919
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5920
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5921
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5922
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5923
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5924
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5925
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5926
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5927
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5928
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5929
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5930
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5931
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5932
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5933
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5934
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5935
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5936
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5937
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5938
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5939
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5940
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5941
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5942
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5943
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5944
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5945
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5946
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5947
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5948
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5949
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5950
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5951
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5952
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5953
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5954
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5955
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5956
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5957
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5958
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5959
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5960
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5961
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5962
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5963
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5964
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5965
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5966
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5967
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5968
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5969
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5970
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5971
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5972
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5973
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5974
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5975
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5976
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5977
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5978
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5979
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5980
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5981
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5982
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5983
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5984
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5985
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5986
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5987
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5988
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5989
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5990
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5991
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5992
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5993
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5994
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5995
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5996
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5997
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5998
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
5999
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6000
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6001
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6002
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6003
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6004
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6005
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6006
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6007
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6008
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6009
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6010
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6011
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6012
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6013
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6014
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6015
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6016
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6017
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6018
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6019
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6020
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6021
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6022
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6023
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6024
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6025
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6026
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6027
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6028
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6029
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6030
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6031
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6032
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6033
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6034
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6035
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6036
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6037
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6038
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6039
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6040
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6041
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6042
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6043
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6044
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6045
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6046
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6047
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6048
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6049
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6050
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6051
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
6052
    0};
6053
const uint8_t canonical_combining_class_block[67][256] = {
6054
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6055
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6056
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6057
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6058
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6059
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6060
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6061
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6062
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6063
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6064
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6065
    {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6066
     230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220,
6067
     220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220,
6068
     220, 220, 220, 220, 220, 220, 220, 1,   1,   1,   1,   1,   220, 220, 220,
6069
     220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230,
6070
     230, 230, 220, 220, 0,   230, 230, 230, 220, 220, 220, 220, 230, 232, 220,
6071
     220, 230, 233, 234, 234, 233, 234, 234, 233, 230, 230, 230, 230, 230, 230,
6072
     230, 230, 230, 230, 230, 230, 230, 0,   0,   0,   0,   0,   0,   0,   0,
6073
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6074
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6075
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6076
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6077
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6078
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6079
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6080
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6081
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6082
     0},
6083
    {0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6084
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6085
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6086
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6087
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6088
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6089
     230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6090
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6091
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6092
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6093
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6094
     0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6095
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6096
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6097
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6098
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6099
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6100
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6101
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6102
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6103
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6104
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   220, 230, 230, 230, 230,
6105
     220, 230, 230, 230, 222, 220, 230, 230, 230, 230, 230, 230, 220, 220, 220,
6106
     220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230, 10,  11,  12,  13,
6107
     14,  15,  16,  17,  18,  19,  19,  20,  21,  22,  0,   23,  0,   24,  25,
6108
     0,   230, 220, 0,   18,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6109
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6110
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6111
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6112
     0},
6113
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6114
     0,   230, 230, 230, 230, 230, 230, 230, 230, 30,  31,  32,  0,   0,   0,
6115
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6116
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6117
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6118
     27,  28,  29,  30,  31,  32,  33,  34,  230, 230, 220, 220, 230, 230, 230,
6119
     230, 230, 220, 230, 230, 220, 0,   0,   0,   0,   0,   0,   0,   0,   0,
6120
     0,   0,   0,   0,   0,   0,   0,   35,  0,   0,   0,   0,   0,   0,   0,
6121
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6122
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6123
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6124
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6125
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6126
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6127
     0,   0,   0,   0,   230, 230, 230, 230, 230, 230, 230, 0,   0,   230, 230,
6128
     230, 230, 220, 230, 0,   0,   230, 230, 0,   220, 230, 230, 220, 0,   0,
6129
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6130
     0},
6131
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6132
     0,   0,   36,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6133
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6134
     0,   0,   0,   230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220,
6135
     220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230,
6136
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6137
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6138
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6139
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6140
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6141
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6142
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6143
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6144
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6145
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6146
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230, 230,
6147
     230, 230, 220, 230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   220, 0,
6148
     0},
6149
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6150
     0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230, 0,   230, 230, 230,
6151
     230, 230, 230, 230, 230, 230, 0,   230, 230, 230, 0,   230, 230, 230, 230,
6152
     230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6153
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6154
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   220,
6155
     220, 220, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6156
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6157
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6158
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6159
     0,   0,   230, 220, 220, 220, 230, 230, 230, 230, 0,   0,   0,   0,   0,
6160
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6161
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6162
     0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230, 230, 220, 220, 220,
6163
     220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6164
     230, 0,   220, 230, 230, 220, 230, 230, 220, 230, 230, 230, 220, 220, 220,
6165
     27,  28,  29,  230, 230, 230, 220, 230, 230, 220, 220, 230, 230, 230, 230,
6166
     230},
6167
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6168
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6169
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   7,   0,   0,   0, 0, 0,
6170
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,   0, 0, 230, 220, 230, 230, 0, 0, 0,
6171
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6172
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6173
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6174
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6175
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6176
     0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6177
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0,   0,   0,   0,   0, 0, 0,
6178
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0},
6179
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6180
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6181
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6182
     0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6183
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6184
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6185
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6186
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
6187
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6188
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6189
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6190
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6191
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6192
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6193
     0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6194
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6195
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6196
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6197
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6198
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6199
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6200
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6201
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6202
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6203
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6204
     0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6205
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6206
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6207
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6208
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 7, 0, 0, 0,
6209
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6210
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,
6211
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0},
6212
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6213
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6214
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6215
     0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6216
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6217
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6218
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6219
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6220
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6221
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6222
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6223
    {0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6224
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6225
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6226
     0,   0,   103, 103, 9,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6227
     107, 107, 107, 107, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6228
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6229
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6230
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6231
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6232
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6233
     0,   0,   0,   0,   118, 118, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6234
     0,   0,   122, 122, 122, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6235
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6236
     0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6237
     0,   0,   0,   0},
6238
    {0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6239
     0,   0, 0,   0,   0,   0,   0, 0, 0,   220, 220, 0,   0,   0, 0,
6240
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6241
     0,   0, 0,   0,   0,   0,   0, 0, 220, 0,   220, 0,   216, 0, 0,
6242
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6243
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6244
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6245
     0,   0, 0,   0,   0,   0,   0, 0, 129, 130, 0,   132, 0,   0, 0,
6246
     0,   0, 130, 130, 130, 130, 0, 0, 130, 0,   230, 230, 9,   0, 230,
6247
     230, 0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6248
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6249
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6250
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6251
     0,   0, 0,   220, 0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6252
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6253
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6254
     0,   0, 0,   0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0, 0,
6255
     0},
6256
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6257
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6258
     0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6259
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6260
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6261
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0,
6262
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6263
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6264
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6265
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,
6266
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6267
    {0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6268
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6269
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6270
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6271
     0, 0, 0, 0, 0, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6272
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6273
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6274
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6275
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6276
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6277
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6278
     0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0},
6279
    {0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0,
6280
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6281
     0, 0, 0, 0, 9, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6282
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6283
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6284
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6285
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6286
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6287
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
6288
     0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6289
     0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6290
    {0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6291
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6292
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6293
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6294
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6295
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6296
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6297
     0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6298
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6299
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6300
     0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6301
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6302
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6303
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0, 0, 0,
6304
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6305
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6306
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6307
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6308
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6309
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6310
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6311
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0, 0, 0, 0, 0,
6312
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6313
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6314
     0,   0,   0,   0,   0,   0,   0,   0,   230, 220, 0,   0,   0,   0,   0,
6315
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6316
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6317
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6318
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6319
     0,   0,   0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,
6320
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 230,
6321
     230, 230, 230, 230, 230, 0,   0,   220, 0,   0,   0,   0,   0,   0,   0,
6322
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6323
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6324
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 230, 230,
6325
     230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 0,   220, 220, 230, 230,
6326
     220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 230, 230, 0,   0,   0,
6327
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6328
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6329
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6330
     0},
6331
    {0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6332
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6333
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   7,   0,   0,   0,   0,
6334
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,   0,   0,   0,   0,   0,   0,
6335
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6336
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230, 230, 230,
6337
     230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6338
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6339
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   9,
6340
     9,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6341
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6342
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,
6343
     0,   0,   7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   9,   9,   0,   0,   0,
6344
     0,   0,   0, 0, 0, 0, 0, 0, 0},
6345
    {0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6346
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6347
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6348
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,   0,
6349
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6350
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6351
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6352
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6353
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6354
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6355
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6356
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6357
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6358
     0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230,
6359
     230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220, 230,
6360
     0,   1, 1, 1,   1,   1,   1,   1,   0,   0,   0,   0,   220, 0,   0,
6361
     0,   0, 0, 0,   230, 0,   0,   0,   230, 230, 0,   0,   0,   0,   0,
6362
     0},
6363
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6364
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6365
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6366
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6367
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6368
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6369
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6370
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6371
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6372
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6373
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6374
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6375
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230, 220,
6376
     230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220, 202, 230,
6377
     230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6378
     230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6379
     230, 230, 230, 230, 230, 230, 232, 228, 228, 220, 218, 230, 233, 220, 230,
6380
     220},
6381
    {0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6382
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6383
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6384
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6385
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6386
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6387
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6388
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6389
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6390
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6391
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6392
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6393
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,
6394
     230, 230, 1, 1, 230, 230, 230, 230, 1,   1,   1, 230, 230, 0,   0,   0,
6395
     0,   230, 0, 0, 0,   1,   1,   230, 220, 230, 1, 1,   220, 220, 220, 220,
6396
     230, 0,   0, 0, 0,   0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0},
6397
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6398
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6399
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6400
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6401
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6402
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6403
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6404
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6405
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6406
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,
6407
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230,
6408
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6409
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6410
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6411
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6412
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6413
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6414
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6415
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6416
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6417
     0,   0,   0,   0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,
6418
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6419
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6420
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6421
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6422
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6423
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230,
6424
     230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6425
     230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6426
     230},
6427
    {0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6428
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6429
     0, 0, 218, 228, 232, 222, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6430
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6431
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6432
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6433
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6434
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
6435
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6436
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6437
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6438
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6439
     0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0},
6440
    {0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6441
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6442
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6443
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6444
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6445
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6446
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230,
6447
     0,   0,   0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0,   0,
6448
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6449
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230, 230,
6450
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6451
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6452
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6453
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6454
     0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6455
     230, 230, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0},
6456
    {0,   0,   0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0,   0,   0,
6457
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6458
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   9,
6459
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6460
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6461
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6462
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6463
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6464
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6465
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6466
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6467
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6468
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6469
     0,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6470
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   230,
6471
     230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6472
     230, 230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6473
     0},
6474
    {0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6475
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220,
6476
     220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6477
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
6478
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6479
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6480
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6481
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6482
     0,   0,   0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
6483
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6484
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6485
     0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6486
    {0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6487
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6488
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6489
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6490
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6491
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6492
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6493
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6494
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6495
     0,   0,   0, 0,   0, 230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0,
6496
     230, 230, 0, 230, 0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6497
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 0,
6498
     0,   0,   0, 0,   0, 0,   0, 0,   0,   0,   0, 0, 0,   0,   0, 0, 0, 0, 9,
6499
     0,   0,   0, 0,   0, 0,   0, 0,   0},
6500
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6501
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6502
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6503
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6504
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6505
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6506
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6507
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6508
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6509
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
6510
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6511
    {0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6512
     0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6513
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6514
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6515
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6516
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6517
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6518
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6519
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6520
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6521
     0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0},
6522
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6523
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6524
     0,   0,   230, 230, 230, 230, 230, 230, 230, 220, 220, 220, 220, 220, 220,
6525
     220, 230, 230, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6526
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6527
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6528
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6529
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6530
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6531
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6532
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6533
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6534
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6535
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6536
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6537
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6538
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6539
     0},
6540
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6541
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6542
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6543
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6544
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6545
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6546
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6547
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6548
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6549
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6550
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0},
6551
    {0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6552
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6553
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6554
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6555
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6556
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6557
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6558
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6559
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6560
     0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6561
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0},
6562
    {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
6563
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
6564
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 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, 0, 0, 0,
6566
     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, 0, 0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6568
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
6569
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
6570
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
6571
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
6572
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0,
6573
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0},
6574
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 220, 0, 230, 0,   0, 0,   0,
6575
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6576
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   230, 1, 220, 0,
6577
     0, 0, 0, 9, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6578
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6579
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6580
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6581
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6582
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6583
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6584
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0,   0,   0, 0,   0,
6585
     0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0,   0, 0,   0,   0, 0,   0,
6586
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,   0, 0},
6587
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6588
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0,
6589
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6590
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6591
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6592
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6593
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6594
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6595
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6596
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6597
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0, 0, 0,
6598
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6599
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6600
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6601
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6602
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6603
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6604
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6605
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6606
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 230, 230, 0, 0, 0,
6607
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6608
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6609
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,  0, 0, 0, 0,   0,   0, 0, 0,
6610
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220},
6611
    {0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6612
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6613
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6614
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 220, 220,
6615
     230, 230, 230, 220, 230, 220, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6616
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6617
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6618
     0,   0,   0,   0,   230, 220, 230, 220, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6619
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6620
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6621
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6622
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6623
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6624
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0,   0,
6625
     0,   0,   0,   0},
6626
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6627
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6628
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
6629
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6630
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
6631
     0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6632
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6633
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0,
6634
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6635
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6636
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6637
    {230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6638
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6639
     0,   0,   0,   0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6640
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6641
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6642
     0,   0,   0,   0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6643
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6644
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6645
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
6646
     0,   0,   0,   0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6647
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6648
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6649
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6650
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6651
     0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6652
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6653
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6654
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6655
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6656
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6657
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6658
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 0, 0, 0,
6659
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6660
    {0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6661
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6662
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6663
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   7,   7,   0, 0, 0,
6664
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   9, 0, 0,
6665
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6666
     0,   0,   0,   0,   0,   0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0,
6667
     230, 230, 230, 230, 230, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6668
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6669
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6670
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6671
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6672
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6673
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6674
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0,
6675
     0,   0,   0,   0,   0,   0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0},
6676
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6677
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6678
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 7,   0,
6679
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0,
6680
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6681
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6682
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6683
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6684
     0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6685
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,
6686
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6687
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6688
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6689
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6690
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6691
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6692
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6693
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6694
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
6695
     7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6696
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6697
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6698
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6699
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6700
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
6701
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6702
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6703
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6704
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6705
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,
6706
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6707
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6708
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6709
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6710
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
6711
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6712
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6713
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6714
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6715
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6716
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6717
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6718
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6719
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6720
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6721
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6722
     0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6723
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6724
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6725
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6726
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6727
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6728
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6729
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6730
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6731
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6732
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6733
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 7, 0, 0, 0, 0,
6734
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6735
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6736
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6737
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6738
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6739
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6740
     0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6741
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6742
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6743
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6744
     0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
6745
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6746
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6747
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6748
     0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6749
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6750
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6751
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6752
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6753
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6754
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6755
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
6756
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6757
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6758
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6759
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6760
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6761
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6762
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6763
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6764
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6765
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6766
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0,
6767
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6768
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6769
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6770
     0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6771
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6772
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6773
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6774
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6775
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6776
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6777
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,
6778
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6779
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6780
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6781
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6782
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6783
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6784
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6785
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6786
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6787
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6788
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6789
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6790
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6791
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6792
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6793
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6794
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6795
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6796
     1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6797
    {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6798
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6799
     0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0,
6800
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6801
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6802
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6803
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6804
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6805
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6806
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6807
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6808
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6809
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0},
6810
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6811
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6812
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6813
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6814
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6815
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6816
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6817
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6818
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6819
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6820
     6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6821
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6822
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6823
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6824
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6825
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6826
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6827
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6828
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6829
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6830
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6831
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6832
    {0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6833
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6834
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6835
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6836
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6837
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6838
     0,   0,   0,   0, 0, 216, 216, 1,   1,   1,   0,   0,   0,   226, 216, 216,
6839
     216, 216, 216, 0, 0, 0,   0,   0,   0,   0,   0,   220, 220, 220, 220, 220,
6840
     220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0,   0,   0,   0,
6841
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6842
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   230, 230, 230, 230, 0,   0,
6843
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6844
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6845
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6846
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6847
     0,   0,   0,   0, 0, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0},
6848
    {0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6849
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6850
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6851
     230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6852
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6853
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6854
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6855
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6856
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6857
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6858
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6859
     0,   0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6860
    {230, 230, 230, 230, 230, 230, 230, 0,   230, 230, 230, 230, 230, 230, 230,
6861
     230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0,   0,   230, 230, 230,
6862
     230, 230, 230, 230, 0,   230, 230, 0,   230, 230, 230, 230, 230, 0,   0,
6863
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6864
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6865
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6866
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6867
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6868
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6869
     0,   0,   0,   0,   0,   0,   0,   0,   230, 0,   0,   0,   0,   0,   0,
6870
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6871
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6872
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6873
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6874
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6875
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6876
     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
6877
     0},
6878
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6879
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6880
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6881
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6882
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6883
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6884
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6885
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   230, 0,
6886
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6887
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,
6888
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0,   0,
6889
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6890
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6891
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6892
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6893
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6894
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6895
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6896
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6897
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6898
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6899
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0, 0,
6900
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 232, 220, 230, 0, 0,
6901
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6902
    {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6903
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6904
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6905
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6906
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6907
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6908
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6909
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6910
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6911
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6912
     0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 220, 0, 0, 0, 0, 0,
6913
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0,
6914
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0,   0},
6915
    {0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6916
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6917
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6918
     0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 7, 0, 0, 0, 0, 0,
6919
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6920
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6921
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6922
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6923
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6924
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6925
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6926
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
6927
     0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0,   0, 0}};
6928
6929
const uint8_t composition_index[4352] = {
6930
    0, 1, 2, 3, 4,  5,  6, 5, 5,  7,  5, 8,  9,  10, 5, 5, 11, 5,  5, 5, 5, 5,
6931
    5, 5, 5, 5, 5,  12, 5, 5, 13, 14, 5, 15, 16, 5,  5, 5, 5,  5,  5, 5, 5, 5,
6932
    5, 5, 5, 5, 17, 5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6933
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6934
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6935
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6936
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6937
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6938
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6939
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6940
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6941
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6942
    5, 5, 5, 5, 5,  5,  5, 5, 18, 19, 5, 20, 21, 22, 5, 5, 5,  23, 5, 5, 5, 5,
6943
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6944
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6945
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6946
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6947
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6948
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6949
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6950
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6951
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6952
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6953
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6954
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6955
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6956
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6957
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6958
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6959
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6960
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6961
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6962
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6963
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6964
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6965
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6966
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6967
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6968
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6969
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6970
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6971
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6972
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6973
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6974
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6975
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6976
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6977
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6978
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6979
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6980
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6981
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6982
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6983
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6984
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6985
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6986
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6987
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6988
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6989
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6990
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6991
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6992
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6993
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6994
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6995
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6996
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6997
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6998
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
6999
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7000
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7001
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7002
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7003
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7004
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7005
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7006
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7007
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7008
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7009
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7010
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7011
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7012
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7013
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7014
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7015
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7016
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7017
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7018
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7019
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7020
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7021
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7022
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7023
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7024
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7025
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7026
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7027
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7028
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7029
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7030
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7031
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7032
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7033
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7034
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7035
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7036
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7037
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7038
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7039
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7040
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7041
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7042
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7043
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7044
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7045
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7046
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7047
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7048
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7049
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7050
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7051
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7052
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7053
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7054
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7055
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7056
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7057
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7058
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7059
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7060
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7061
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7062
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7063
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7064
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7065
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7066
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7067
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7068
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7069
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7070
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7071
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7072
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7073
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7074
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7075
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7076
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7077
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7078
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7079
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7080
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7081
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7082
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7083
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7084
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7085
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7086
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7087
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7088
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7089
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7090
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7091
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7092
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7093
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7094
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7095
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7096
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7097
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7098
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7099
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7100
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7101
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7102
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7103
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7104
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7105
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7106
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7107
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7108
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7109
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7110
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7111
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7112
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7113
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7114
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7115
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7116
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7117
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7118
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7119
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7120
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7121
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7122
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7123
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7124
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7125
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7126
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5,  5, 5, 5, 5,
7127
    5, 5, 5, 5, 5,  5,  5, 5, 5,  5,  5, 5,  5,  5,  5, 5, 5,  5};
7128
const uint16_t composition_block[67][257] = {
7129
    {1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
7130
     1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
7131
     1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
7132
     1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
7133
     1,   3,   5,   7,   7,   7,   39,  45,  55,  67,  101, 103, 117, 131, 161,
7134
     163, 173, 185, 191, 209, 241, 245, 245, 261, 275, 289, 327, 331, 343, 347,
7135
     365, 377, 377, 377, 377, 377, 377, 377, 409, 415, 425, 437, 471, 473, 487,
7136
     503, 531, 535, 545, 557, 563, 581, 613, 617, 617, 633, 647, 663, 701, 705,
7137
     719, 723, 743, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7138
     755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7139
     755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7140
     755, 755, 755, 755, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
7141
     761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
7142
     769, 769, 771, 773, 777, 779, 779, 779, 787, 787, 787, 787, 787, 789, 789,
7143
     789, 789, 789, 797, 803, 805, 805, 807, 807, 807, 807, 815, 815, 815, 815,
7144
     815, 815, 823, 823, 825, 827, 831, 833, 833, 833, 841, 841, 841, 841, 841,
7145
     843, 843, 843, 843, 843, 851, 857, 859, 859, 861, 861, 861, 861, 869, 869,
7146
     869, 869},
7147
    {869, 869, 869, 877, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885,
7148
     885, 885, 885, 885, 889, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7149
     893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7150
     893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7151
     893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7152
     893, 893, 897, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901,
7153
     901, 903, 905, 905, 905, 905, 905, 907, 909, 909, 909, 909, 909, 909, 909,
7154
     911, 913, 915, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917,
7155
     917, 917, 917, 917, 917, 917, 917, 917, 919, 919, 919, 919, 919, 919, 919,
7156
     919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919,
7157
     919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 929, 939, 939, 939,
7158
     939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 949, 959, 959, 959,
7159
     959, 959, 959, 959, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7160
     961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7161
     961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7162
     961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 963, 965, 965, 965, 965,
7163
     965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7164
     965, 965},
7165
    {965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7166
     965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7167
     965, 965, 965, 965, 965, 965, 965, 965, 965, 967, 969, 971, 973, 973, 973,
7168
     973, 973, 975, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7169
     977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7170
     977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7171
     977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7172
     977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7173
     977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7174
     977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 979, 979, 979,
7175
     979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7176
     979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7177
     979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7178
     979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7179
     979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7180
     979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7181
     979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7182
     979, 979},
7183
    {979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7184
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7185
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7186
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7187
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7188
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7189
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7190
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7191
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7192
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7193
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7194
     979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,  979,
7195
     979,  979,  993,  993,  993,  993,  1001, 1001, 1011, 1011, 1025, 1025,
7196
     1025, 1025, 1025, 1025, 1033, 1033, 1035, 1035, 1035, 1035, 1047, 1047,
7197
     1047, 1047, 1057, 1057, 1057, 1059, 1059, 1061, 1061, 1061, 1077, 1077,
7198
     1077, 1077, 1085, 1085, 1097, 1097, 1113, 1113, 1113, 1113, 1113, 1113,
7199
     1121, 1121, 1125, 1125, 1125, 1125, 1141, 1141, 1141, 1141, 1153, 1159,
7200
     1165, 1165, 1165, 1167, 1167, 1167, 1167, 1171, 1171, 1171, 1171, 1171,
7201
     1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7202
     1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7203
     1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7204
     1171, 1171, 1171, 1171, 1171},
7205
    {1171, 1171, 1171, 1171, 1171, 1171, 1171, 1173, 1173, 1173, 1173, 1173,
7206
     1173, 1173, 1173, 1173, 1173, 1177, 1177, 1177, 1179, 1179, 1185, 1189,
7207
     1191, 1199, 1199, 1201, 1201, 1201, 1201, 1203, 1203, 1203, 1203, 1203,
7208
     1211, 1211, 1211, 1211, 1213, 1213, 1213, 1213, 1215, 1215, 1217, 1217,
7209
     1217, 1221, 1221, 1221, 1223, 1223, 1229, 1233, 1235, 1243, 1243, 1245,
7210
     1245, 1245, 1245, 1247, 1247, 1247, 1247, 1247, 1255, 1255, 1255, 1255,
7211
     1257, 1257, 1257, 1257, 1259, 1259, 1261, 1261, 1261, 1261, 1261, 1261,
7212
     1261, 1261, 1261, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,
7213
     1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,
7214
     1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1265, 1267, 1267,
7215
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7216
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7217
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7218
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7219
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7220
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7221
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7222
     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7223
     1267, 1269, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271,
7224
     1271, 1271, 1271, 1271, 1271, 1273, 1275, 1275, 1275, 1275, 1275, 1275,
7225
     1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7226
     1275, 1275, 1275, 1275, 1275},
7227
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7228
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7229
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7230
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7231
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7232
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7233
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7234
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7235
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7236
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7237
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
7238
    {1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7239
     1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7240
     1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7241
     1275, 1275, 1275, 1275, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7242
     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7243
     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7244
     1281, 1283, 1283, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7245
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7246
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7247
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7248
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7249
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7250
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7251
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7252
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7253
     1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7254
     1285, 1285, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
7255
     1287, 1287, 1287, 1287, 1287, 1287, 1287, 1289, 1289, 1289, 1291, 1291,
7256
     1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7257
     1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7258
     1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7259
     1291, 1291, 1291, 1291, 1291},
7260
    {1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7261
     1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7262
     1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7263
     1291, 1291, 1291, 1291, 1291, 1293, 1293, 1293, 1293, 1293, 1293, 1293,
7264
     1293, 1295, 1295, 1295, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7265
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7266
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7267
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7268
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7269
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7270
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7271
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7272
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7273
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7274
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7275
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7276
     1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1301, 1301, 1301, 1301,
7277
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7278
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7279
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7280
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7281
     1301, 1301, 1301, 1301, 1301},
7282
    {1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7283
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7284
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7285
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7286
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7287
     1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7288
     1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7289
     1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7290
     1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7291
     1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7292
     1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7293
     1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7294
     1307, 1307, 1307, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7295
     1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7296
     1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7297
     1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7298
     1309, 1309, 1309, 1309, 1309, 1309, 1309, 1313, 1315, 1315, 1315, 1315,
7299
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7300
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7301
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7302
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7303
     1315, 1315, 1315, 1315, 1315},
7304
    {1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7305
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7306
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7307
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7308
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7309
     1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1317,
7310
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7311
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7312
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7313
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7314
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7315
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7316
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7317
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7318
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7319
     1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7320
     1319, 1319, 1319, 1319, 1319, 1319, 1319, 1325, 1325, 1325, 1325, 1327,
7321
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7322
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7323
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7324
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7325
     1327, 1327, 1327, 1327, 1327},
7326
    {1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7327
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7328
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7329
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7330
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7331
     1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1331,
7332
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7333
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7334
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7335
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7336
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7337
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7338
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7339
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7340
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7341
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7342
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7343
     1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7344
     1333, 1333, 1339, 1339, 1339, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7345
     1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7346
     1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7347
     1341, 1341, 1341, 1341, 1341},
7348
    {1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7349
     1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7350
     1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7351
     1341, 1341, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7352
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7353
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7354
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7355
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7356
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7357
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7358
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7359
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7360
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7361
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7362
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7363
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7364
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7365
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7366
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7367
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7368
     1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7369
     1343, 1343, 1343, 1343, 1343},
7370
    {1343, 1343, 1343, 1343, 1343, 1343, 1345, 1345, 1347, 1347, 1349, 1349,
7371
     1351, 1351, 1353, 1353, 1353, 1353, 1355, 1355, 1355, 1355, 1355, 1355,
7372
     1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,
7373
     1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,
7374
     1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1357,
7375
     1357, 1359, 1359, 1361, 1363, 1363, 1363, 1365, 1365, 1365, 1365, 1365,
7376
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7377
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7378
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7379
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7380
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7381
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7382
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7383
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7384
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7385
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7386
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7387
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7388
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7389
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7390
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7391
     1365, 1365, 1365, 1365, 1365},
7392
    {1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7393
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7394
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7395
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7396
     1365, 1365, 1365, 1365, 1365, 1365, 1365, 1367, 1369, 1369, 1369, 1369,
7397
     1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,
7398
     1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,
7399
     1369, 1369, 1369, 1369, 1369, 1369, 1369, 1371, 1373, 1373, 1373, 1373,
7400
     1373, 1373, 1373, 1375, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7401
     1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7402
     1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7403
     1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7404
     1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7405
     1377, 1377, 1377, 1377, 1377, 1381, 1385, 1385, 1385, 1385, 1385, 1385,
7406
     1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
7407
     1385, 1385, 1385, 1385, 1385, 1387, 1389, 1389, 1389, 1389, 1389, 1389,
7408
     1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389,
7409
     1389, 1391, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7410
     1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7411
     1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7412
     1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7413
     1393, 1393, 1393, 1393, 1393},
7414
    {1393, 1401, 1409, 1411, 1413, 1415, 1417, 1419, 1421, 1429, 1437, 1439,
7415
     1441, 1443, 1445, 1447, 1449, 1453, 1457, 1457, 1457, 1457, 1457, 1457,
7416
     1457, 1461, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1473, 1481, 1483,
7417
     1485, 1487, 1489, 1491, 1493, 1501, 1509, 1511, 1513, 1515, 1517, 1519,
7418
     1521, 1527, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1539, 1545, 1545,
7419
     1545, 1545, 1545, 1545, 1545, 1549, 1553, 1553, 1553, 1553, 1553, 1553,
7420
     1553, 1557, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1567, 1573, 1573,
7421
     1573, 1573, 1573, 1573, 1573, 1573, 1579, 1579, 1579, 1579, 1579, 1579,
7422
     1579, 1587, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1615, 1623, 1625,
7423
     1627, 1629, 1631, 1633, 1635, 1637, 1637, 1637, 1637, 1639, 1639, 1639,
7424
     1639, 1639, 1639, 1639, 1639, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7425
     1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7426
     1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7427
     1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7428
     1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7429
     1641, 1641, 1641, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643,
7430
     1649, 1649, 1649, 1649, 1649, 1649, 1649, 1651, 1651, 1651, 1651, 1651,
7431
     1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,
7432
     1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,
7433
     1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,
7434
     1651, 1651, 1651, 1651, 1651, 1651, 1651, 1653, 1653, 1653, 1653, 1653,
7435
     1653, 1653, 1653, 1659, 1659},
7436
    {1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7437
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7438
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7439
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7440
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7441
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7442
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7443
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7444
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7445
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7446
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7447
     1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7448
     1659, 1661, 1661, 1663, 1663, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7449
     1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7450
     1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7451
     1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7452
     1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7453
     1665, 1665, 1665, 1665, 1665, 1667, 1667, 1669, 1669, 1671, 1671, 1671,
7454
     1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7455
     1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7456
     1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7457
     1671, 1671, 1671, 1671, 1671},
7458
    {1671, 1671, 1671, 1671, 1673, 1673, 1673, 1673, 1673, 1675, 1675, 1675,
7459
     1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
7460
     1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
7461
     1679, 1679, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
7462
     1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
7463
     1681, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1685, 1685, 1687, 1687,
7464
     1687, 1689, 1689, 1689, 1689, 1689, 1691, 1691, 1691, 1691, 1691, 1691,
7465
     1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691,
7466
     1691, 1691, 1693, 1693, 1693, 1695, 1697, 1697, 1697, 1697, 1697, 1697,
7467
     1697, 1697, 1697, 1697, 1697, 1697, 1697, 1699, 1701, 1701, 1701, 1703,
7468
     1705, 1705, 1705, 1707, 1709, 1711, 1713, 1713, 1713, 1713, 1713, 1715,
7469
     1717, 1717, 1717, 1719, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
7470
     1721, 1721, 1723, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725,
7471
     1725, 1725, 1725, 1725, 1725, 1725, 1725, 1727, 1727, 1727, 1727, 1727,
7472
     1727, 1729, 1731, 1731, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1735,
7473
     1737, 1739, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7474
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7475
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7476
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7477
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7478
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7479
     1741, 1741, 1741, 1741, 1741},
7480
    {1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7481
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7482
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7483
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7484
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7485
     1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1743,
7486
     1743, 1743, 1743, 1743, 1745, 1745, 1747, 1747, 1749, 1749, 1751, 1751,
7487
     1753, 1753, 1755, 1755, 1757, 1757, 1759, 1759, 1761, 1761, 1763, 1763,
7488
     1765, 1765, 1767, 1767, 1767, 1769, 1769, 1771, 1771, 1773, 1773, 1773,
7489
     1773, 1773, 1773, 1773, 1777, 1777, 1777, 1781, 1781, 1781, 1785, 1785,
7490
     1785, 1789, 1789, 1789, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7491
     1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7492
     1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7493
     1793, 1793, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1797,
7494
     1797, 1797, 1797, 1797, 1799, 1799, 1801, 1801, 1803, 1803, 1805, 1805,
7495
     1807, 1807, 1809, 1809, 1811, 1811, 1813, 1813, 1815, 1815, 1817, 1817,
7496
     1819, 1819, 1821, 1821, 1821, 1823, 1823, 1825, 1825, 1827, 1827, 1827,
7497
     1827, 1827, 1827, 1827, 1831, 1831, 1831, 1835, 1835, 1835, 1839, 1839,
7498
     1839, 1843, 1843, 1843, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
7499
     1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
7500
     1849, 1851, 1853, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,
7501
     1855, 1855, 1857, 1857, 1857},
7502
    {1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7503
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7504
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7505
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7506
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7507
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7508
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7509
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7510
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7511
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7512
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7513
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7514
     1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1859, 1859,
7515
     1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1863, 1863,
7516
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7517
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7518
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7519
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7520
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7521
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7522
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7523
     1863, 1863, 1863, 1863, 1863},
7524
    {1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7525
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7526
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7527
     1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7528
     1863, 1863, 1865, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7529
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7530
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7531
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7532
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7533
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7534
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7535
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7536
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7537
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7538
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7539
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7540
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7541
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7542
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7543
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7544
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7545
     1867, 1867, 1867, 1867, 1867},
7546
    {1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7547
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7548
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7549
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7550
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7551
     1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7552
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7553
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7554
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7555
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7556
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7557
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7558
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7559
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7560
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7561
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7562
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7563
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7564
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7565
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7566
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7567
     1871, 1871, 1871, 1871, 1871},
7568
    {1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7569
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7570
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7571
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7572
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7573
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7574
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7575
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7576
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7577
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7578
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7579
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7580
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7581
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7582
     1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7583
     1871, 1871, 1871, 1871, 1871, 1871, 1877, 1877, 1877, 1877, 1877, 1877,
7584
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7585
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7586
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7587
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7588
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7589
     1877, 1877, 1877, 1877, 1877},
7590
    {1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7591
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7592
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7593
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7594
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7595
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7596
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7597
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7598
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7599
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7600
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7601
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7602
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7603
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7604
     1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7605
     1877, 1877, 1877, 1877, 1877, 1879, 1881, 1881, 1881, 1881, 1881, 1881,
7606
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7607
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7608
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7609
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7610
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7611
     1881, 1881, 1881, 1881, 1881},
7612
    {1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7613
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7614
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7615
     1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7616
     1881, 1881, 1881, 1881, 1881, 1881, 1883, 1883, 1883, 1883, 1883, 1883,
7617
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7618
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7619
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7620
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7621
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7622
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7623
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7624
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7625
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7626
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7627
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7628
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7629
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7630
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7631
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7632
     1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7633
     1883, 1883, 1883, 1883, 1883}};
7634
const char32_t composition_data[1883] = {
7635
    0,     824,   8814,  824,   8800,  824,   8815,  768,   192,   769,   193,
7636
    770,   194,   771,   195,   772,   256,   774,   258,   775,   550,   776,
7637
    196,   777,   7842,  778,   197,   780,   461,   783,   512,   785,   514,
7638
    803,   7840,  805,   7680,  808,   260,   775,   7682,  803,   7684,  817,
7639
    7686,  769,   262,   770,   264,   775,   266,   780,   268,   807,   199,
7640
    775,   7690,  780,   270,   803,   7692,  807,   7696,  813,   7698,  817,
7641
    7694,  768,   200,   769,   201,   770,   202,   771,   7868,  772,   274,
7642
    774,   276,   775,   278,   776,   203,   777,   7866,  780,   282,   783,
7643
    516,   785,   518,   803,   7864,  807,   552,   808,   280,   813,   7704,
7644
    816,   7706,  775,   7710,  769,   500,   770,   284,   772,   7712,  774,
7645
    286,   775,   288,   780,   486,   807,   290,   770,   292,   775,   7714,
7646
    776,   7718,  780,   542,   803,   7716,  807,   7720,  814,   7722,  768,
7647
    204,   769,   205,   770,   206,   771,   296,   772,   298,   774,   300,
7648
    775,   304,   776,   207,   777,   7880,  780,   463,   783,   520,   785,
7649
    522,   803,   7882,  808,   302,   816,   7724,  770,   308,   769,   7728,
7650
    780,   488,   803,   7730,  807,   310,   817,   7732,  769,   313,   780,
7651
    317,   803,   7734,  807,   315,   813,   7740,  817,   7738,  769,   7742,
7652
    775,   7744,  803,   7746,  768,   504,   769,   323,   771,   209,   775,
7653
    7748,  780,   327,   803,   7750,  807,   325,   813,   7754,  817,   7752,
7654
    768,   210,   769,   211,   770,   212,   771,   213,   772,   332,   774,
7655
    334,   775,   558,   776,   214,   777,   7886,  779,   336,   780,   465,
7656
    783,   524,   785,   526,   795,   416,   803,   7884,  808,   490,   769,
7657
    7764,  775,   7766,  769,   340,   775,   7768,  780,   344,   783,   528,
7658
    785,   530,   803,   7770,  807,   342,   817,   7774,  769,   346,   770,
7659
    348,   775,   7776,  780,   352,   803,   7778,  806,   536,   807,   350,
7660
    775,   7786,  780,   356,   803,   7788,  806,   538,   807,   354,   813,
7661
    7792,  817,   7790,  768,   217,   769,   218,   770,   219,   771,   360,
7662
    772,   362,   774,   364,   776,   220,   777,   7910,  778,   366,   779,
7663
    368,   780,   467,   783,   532,   785,   534,   795,   431,   803,   7908,
7664
    804,   7794,  808,   370,   813,   7798,  816,   7796,  771,   7804,  803,
7665
    7806,  768,   7808,  769,   7810,  770,   372,   775,   7814,  776,   7812,
7666
    803,   7816,  775,   7818,  776,   7820,  768,   7922,  769,   221,   770,
7667
    374,   771,   7928,  772,   562,   775,   7822,  776,   376,   777,   7926,
7668
    803,   7924,  769,   377,   770,   7824,  775,   379,   780,   381,   803,
7669
    7826,  817,   7828,  768,   224,   769,   225,   770,   226,   771,   227,
7670
    772,   257,   774,   259,   775,   551,   776,   228,   777,   7843,  778,
7671
    229,   780,   462,   783,   513,   785,   515,   803,   7841,  805,   7681,
7672
    808,   261,   775,   7683,  803,   7685,  817,   7687,  769,   263,   770,
7673
    265,   775,   267,   780,   269,   807,   231,   775,   7691,  780,   271,
7674
    803,   7693,  807,   7697,  813,   7699,  817,   7695,  768,   232,   769,
7675
    233,   770,   234,   771,   7869,  772,   275,   774,   277,   775,   279,
7676
    776,   235,   777,   7867,  780,   283,   783,   517,   785,   519,   803,
7677
    7865,  807,   553,   808,   281,   813,   7705,  816,   7707,  775,   7711,
7678
    769,   501,   770,   285,   772,   7713,  774,   287,   775,   289,   780,
7679
    487,   807,   291,   770,   293,   775,   7715,  776,   7719,  780,   543,
7680
    803,   7717,  807,   7721,  814,   7723,  817,   7830,  768,   236,   769,
7681
    237,   770,   238,   771,   297,   772,   299,   774,   301,   776,   239,
7682
    777,   7881,  780,   464,   783,   521,   785,   523,   803,   7883,  808,
7683
    303,   816,   7725,  770,   309,   780,   496,   769,   7729,  780,   489,
7684
    803,   7731,  807,   311,   817,   7733,  769,   314,   780,   318,   803,
7685
    7735,  807,   316,   813,   7741,  817,   7739,  769,   7743,  775,   7745,
7686
    803,   7747,  768,   505,   769,   324,   771,   241,   775,   7749,  780,
7687
    328,   803,   7751,  807,   326,   813,   7755,  817,   7753,  768,   242,
7688
    769,   243,   770,   244,   771,   245,   772,   333,   774,   335,   775,
7689
    559,   776,   246,   777,   7887,  779,   337,   780,   466,   783,   525,
7690
    785,   527,   795,   417,   803,   7885,  808,   491,   769,   7765,  775,
7691
    7767,  769,   341,   775,   7769,  780,   345,   783,   529,   785,   531,
7692
    803,   7771,  807,   343,   817,   7775,  769,   347,   770,   349,   775,
7693
    7777,  780,   353,   803,   7779,  806,   537,   807,   351,   775,   7787,
7694
    776,   7831,  780,   357,   803,   7789,  806,   539,   807,   355,   813,
7695
    7793,  817,   7791,  768,   249,   769,   250,   770,   251,   771,   361,
7696
    772,   363,   774,   365,   776,   252,   777,   7911,  778,   367,   779,
7697
    369,   780,   468,   783,   533,   785,   535,   795,   432,   803,   7909,
7698
    804,   7795,  808,   371,   813,   7799,  816,   7797,  771,   7805,  803,
7699
    7807,  768,   7809,  769,   7811,  770,   373,   775,   7815,  776,   7813,
7700
    778,   7832,  803,   7817,  775,   7819,  776,   7821,  768,   7923,  769,
7701
    253,   770,   375,   771,   7929,  772,   563,   775,   7823,  776,   255,
7702
    777,   7927,  778,   7833,  803,   7925,  769,   378,   770,   7825,  775,
7703
    380,   780,   382,   803,   7827,  817,   7829,  768,   8173,  769,   901,
7704
    834,   8129,  768,   7846,  769,   7844,  771,   7850,  777,   7848,  772,
7705
    478,   769,   506,   769,   508,   772,   482,   769,   7688,  768,   7872,
7706
    769,   7870,  771,   7876,  777,   7874,  769,   7726,  768,   7890,  769,
7707
    7888,  771,   7894,  777,   7892,  769,   7756,  772,   556,   776,   7758,
7708
    772,   554,   769,   510,   768,   475,   769,   471,   772,   469,   780,
7709
    473,   768,   7847,  769,   7845,  771,   7851,  777,   7849,  772,   479,
7710
    769,   507,   769,   509,   772,   483,   769,   7689,  768,   7873,  769,
7711
    7871,  771,   7877,  777,   7875,  769,   7727,  768,   7891,  769,   7889,
7712
    771,   7895,  777,   7893,  769,   7757,  772,   557,   776,   7759,  772,
7713
    555,   769,   511,   768,   476,   769,   472,   772,   470,   780,   474,
7714
    768,   7856,  769,   7854,  771,   7860,  777,   7858,  768,   7857,  769,
7715
    7855,  771,   7861,  777,   7859,  768,   7700,  769,   7702,  768,   7701,
7716
    769,   7703,  768,   7760,  769,   7762,  768,   7761,  769,   7763,  775,
7717
    7780,  775,   7781,  775,   7782,  775,   7783,  769,   7800,  769,   7801,
7718
    776,   7802,  776,   7803,  775,   7835,  768,   7900,  769,   7898,  771,
7719
    7904,  777,   7902,  803,   7906,  768,   7901,  769,   7899,  771,   7905,
7720
    777,   7903,  803,   7907,  768,   7914,  769,   7912,  771,   7918,  777,
7721
    7916,  803,   7920,  768,   7915,  769,   7913,  771,   7919,  777,   7917,
7722
    803,   7921,  780,   494,   772,   492,   772,   493,   772,   480,   772,
7723
    481,   774,   7708,  774,   7709,  772,   560,   772,   561,   780,   495,
7724
    768,   8122,  769,   902,   772,   8121,  774,   8120,  787,   7944,  788,
7725
    7945,  837,   8124,  768,   8136,  769,   904,   787,   7960,  788,   7961,
7726
    768,   8138,  769,   905,   787,   7976,  788,   7977,  837,   8140,  768,
7727
    8154,  769,   906,   772,   8153,  774,   8152,  776,   938,   787,   7992,
7728
    788,   7993,  768,   8184,  769,   908,   787,   8008,  788,   8009,  788,
7729
    8172,  768,   8170,  769,   910,   772,   8169,  774,   8168,  776,   939,
7730
    788,   8025,  768,   8186,  769,   911,   787,   8040,  788,   8041,  837,
7731
    8188,  837,   8116,  837,   8132,  768,   8048,  769,   940,   772,   8113,
7732
    774,   8112,  787,   7936,  788,   7937,  834,   8118,  837,   8115,  768,
7733
    8050,  769,   941,   787,   7952,  788,   7953,  768,   8052,  769,   942,
7734
    787,   7968,  788,   7969,  834,   8134,  837,   8131,  768,   8054,  769,
7735
    943,   772,   8145,  774,   8144,  776,   970,   787,   7984,  788,   7985,
7736
    834,   8150,  768,   8056,  769,   972,   787,   8000,  788,   8001,  787,
7737
    8164,  788,   8165,  768,   8058,  769,   973,   772,   8161,  774,   8160,
7738
    776,   971,   787,   8016,  788,   8017,  834,   8166,  768,   8060,  769,
7739
    974,   787,   8032,  788,   8033,  834,   8182,  837,   8179,  768,   8146,
7740
    769,   912,   834,   8151,  768,   8162,  769,   944,   834,   8167,  837,
7741
    8180,  769,   979,   776,   980,   776,   1031,  774,   1232,  776,   1234,
7742
    769,   1027,  768,   1024,  774,   1238,  776,   1025,  774,   1217,  776,
7743
    1244,  776,   1246,  768,   1037,  772,   1250,  774,   1049,  776,   1252,
7744
    769,   1036,  776,   1254,  772,   1262,  774,   1038,  776,   1264,  779,
7745
    1266,  776,   1268,  776,   1272,  776,   1260,  774,   1233,  776,   1235,
7746
    769,   1107,  768,   1104,  774,   1239,  776,   1105,  774,   1218,  776,
7747
    1245,  776,   1247,  768,   1117,  772,   1251,  774,   1081,  776,   1253,
7748
    769,   1116,  776,   1255,  772,   1263,  774,   1118,  776,   1265,  779,
7749
    1267,  776,   1269,  776,   1273,  776,   1261,  776,   1111,  783,   1142,
7750
    783,   1143,  776,   1242,  776,   1243,  776,   1258,  776,   1259,  1619,
7751
    1570,  1620,  1571,  1621,  1573,  1620,  1572,  1620,  1574,  1620,  1730,
7752
    1620,  1747,  1620,  1728,  2364,  2345,  2364,  2353,  2364,  2356,  2494,
7753
    2507,  2519,  2508,  2878,  2891,  2902,  2888,  2903,  2892,  3031,  2964,
7754
    3006,  3018,  3031,  3020,  3006,  3019,  3158,  3144,  3285,  3264,  3266,
7755
    3274,  3285,  3271,  3286,  3272,  3285,  3275,  3390,  3402,  3415,  3404,
7756
    3390,  3403,  3530,  3546,  3535,  3548,  3551,  3550,  3530,  3549,  4142,
7757
    4134,  6965,  6918,  6965,  6920,  6965,  6922,  6965,  6924,  6965,  6926,
7758
    6965,  6930,  6965,  6971,  6965,  6973,  6965,  6976,  6965,  6977,  6965,
7759
    6979,  772,   7736,  772,   7737,  772,   7772,  772,   7773,  775,   7784,
7760
    775,   7785,  770,   7852,  774,   7862,  770,   7853,  774,   7863,  770,
7761
    7878,  770,   7879,  770,   7896,  770,   7897,  768,   7938,  769,   7940,
7762
    834,   7942,  837,   8064,  768,   7939,  769,   7941,  834,   7943,  837,
7763
    8065,  837,   8066,  837,   8067,  837,   8068,  837,   8069,  837,   8070,
7764
    837,   8071,  768,   7946,  769,   7948,  834,   7950,  837,   8072,  768,
7765
    7947,  769,   7949,  834,   7951,  837,   8073,  837,   8074,  837,   8075,
7766
    837,   8076,  837,   8077,  837,   8078,  837,   8079,  768,   7954,  769,
7767
    7956,  768,   7955,  769,   7957,  768,   7962,  769,   7964,  768,   7963,
7768
    769,   7965,  768,   7970,  769,   7972,  834,   7974,  837,   8080,  768,
7769
    7971,  769,   7973,  834,   7975,  837,   8081,  837,   8082,  837,   8083,
7770
    837,   8084,  837,   8085,  837,   8086,  837,   8087,  768,   7978,  769,
7771
    7980,  834,   7982,  837,   8088,  768,   7979,  769,   7981,  834,   7983,
7772
    837,   8089,  837,   8090,  837,   8091,  837,   8092,  837,   8093,  837,
7773
    8094,  837,   8095,  768,   7986,  769,   7988,  834,   7990,  768,   7987,
7774
    769,   7989,  834,   7991,  768,   7994,  769,   7996,  834,   7998,  768,
7775
    7995,  769,   7997,  834,   7999,  768,   8002,  769,   8004,  768,   8003,
7776
    769,   8005,  768,   8010,  769,   8012,  768,   8011,  769,   8013,  768,
7777
    8018,  769,   8020,  834,   8022,  768,   8019,  769,   8021,  834,   8023,
7778
    768,   8027,  769,   8029,  834,   8031,  768,   8034,  769,   8036,  834,
7779
    8038,  837,   8096,  768,   8035,  769,   8037,  834,   8039,  837,   8097,
7780
    837,   8098,  837,   8099,  837,   8100,  837,   8101,  837,   8102,  837,
7781
    8103,  768,   8042,  769,   8044,  834,   8046,  837,   8104,  768,   8043,
7782
    769,   8045,  834,   8047,  837,   8105,  837,   8106,  837,   8107,  837,
7783
    8108,  837,   8109,  837,   8110,  837,   8111,  837,   8114,  837,   8130,
7784
    837,   8178,  837,   8119,  768,   8141,  769,   8142,  834,   8143,  837,
7785
    8135,  837,   8183,  768,   8157,  769,   8158,  834,   8159,  824,   8602,
7786
    824,   8603,  824,   8622,  824,   8653,  824,   8655,  824,   8654,  824,
7787
    8708,  824,   8713,  824,   8716,  824,   8740,  824,   8742,  824,   8769,
7788
    824,   8772,  824,   8775,  824,   8777,  824,   8813,  824,   8802,  824,
7789
    8816,  824,   8817,  824,   8820,  824,   8821,  824,   8824,  824,   8825,
7790
    824,   8832,  824,   8833,  824,   8928,  824,   8929,  824,   8836,  824,
7791
    8837,  824,   8840,  824,   8841,  824,   8930,  824,   8931,  824,   8876,
7792
    824,   8877,  824,   8878,  824,   8879,  824,   8938,  824,   8939,  824,
7793
    8940,  824,   8941,  12441, 12436, 12441, 12364, 12441, 12366, 12441, 12368,
7794
    12441, 12370, 12441, 12372, 12441, 12374, 12441, 12376, 12441, 12378, 12441,
7795
    12380, 12441, 12382, 12441, 12384, 12441, 12386, 12441, 12389, 12441, 12391,
7796
    12441, 12393, 12441, 12400, 12442, 12401, 12441, 12403, 12442, 12404, 12441,
7797
    12406, 12442, 12407, 12441, 12409, 12442, 12410, 12441, 12412, 12442, 12413,
7798
    12441, 12446, 12441, 12532, 12441, 12460, 12441, 12462, 12441, 12464, 12441,
7799
    12466, 12441, 12468, 12441, 12470, 12441, 12472, 12441, 12474, 12441, 12476,
7800
    12441, 12478, 12441, 12480, 12441, 12482, 12441, 12485, 12441, 12487, 12441,
7801
    12489, 12441, 12496, 12442, 12497, 12441, 12499, 12442, 12500, 12441, 12502,
7802
    12442, 12503, 12441, 12505, 12442, 12506, 12441, 12508, 12442, 12509, 12441,
7803
    12535, 12441, 12536, 12441, 12537, 12441, 12538, 12441, 12542, 69818, 69786,
7804
    69818, 69788, 69818, 69803, 69927, 69934, 69927, 69935, 70462, 70475, 70487,
7805
    70476, 70832, 70844, 70842, 70843, 70845, 70846, 71087, 71098, 71087, 71099,
7806
    71984, 71992};
7807
7808
}  // namespace ada::idna
7809
#endif  // ADA_IDNA_NORMALIZATION_TABLES_H
7810
/* end file src/normalization_tables.cpp */
7811
7812
namespace ada::idna {
7813
7814
// See
7815
// https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467
7816
constexpr char32_t hangul_sbase = 0xAC00;
7817
constexpr char32_t hangul_tbase = 0x11A7;
7818
constexpr char32_t hangul_vbase = 0x1161;
7819
constexpr char32_t hangul_lbase = 0x1100;
7820
constexpr char32_t hangul_lcount = 19;
7821
constexpr char32_t hangul_vcount = 21;
7822
constexpr char32_t hangul_tcount = 28;
7823
constexpr char32_t hangul_ncount = hangul_vcount * hangul_tcount;
7824
constexpr char32_t hangul_scount =
7825
    hangul_lcount * hangul_vcount * hangul_tcount;
7826
7827
std::pair<bool, size_t> compute_decomposition_length(
7828
66.6k
    const std::u32string_view input) noexcept {
7829
66.6k
  bool decomposition_needed{false};
7830
66.6k
  size_t additional_elements{0};
7831
423k
  for (char32_t current_character : input) {
7832
423k
    size_t decomposition_length{0};
7833
7834
423k
    if (current_character >= hangul_sbase &&
7835
34.1k
        current_character < hangul_sbase + hangul_scount) {
7836
14.4k
      decomposition_length = 2;
7837
14.4k
      if ((current_character - hangul_sbase) % hangul_tcount) {
7838
11.9k
        decomposition_length = 3;
7839
11.9k
      }
7840
408k
    } else if (current_character < 0x110000) {
7841
408k
      const uint8_t di = decomposition_index[current_character >> 8];
7842
408k
      const uint16_t* const decomposition =
7843
408k
          decomposition_block[di] + (current_character % 256);
7844
408k
      decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2);
7845
408k
      if ((decomposition_length > 0) && (decomposition[0] & 1)) {
7846
0
        decomposition_length = 0;
7847
0
      }
7848
408k
    }
7849
423k
    if (decomposition_length != 0) {
7850
26.5k
      decomposition_needed = true;
7851
26.5k
      additional_elements += decomposition_length - 1;
7852
26.5k
    }
7853
423k
  }
7854
66.6k
  return {decomposition_needed, additional_elements};
7855
66.6k
}
7856
7857
12.5k
void decompose(std::u32string& input, size_t additional_elements) {
7858
12.5k
  input.resize(input.size() + additional_elements);
7859
12.5k
  for (size_t descending_idx = input.size(),
7860
12.5k
              input_count = descending_idx - additional_elements;
7861
70.2k
       input_count--;) {
7862
57.7k
    if (input[input_count] >= hangul_sbase &&
7863
17.3k
        input[input_count] < hangul_sbase + hangul_scount) {
7864
      // Hangul decomposition.
7865
14.4k
      char32_t s_index = input[input_count] - hangul_sbase;
7866
14.4k
      if (s_index % hangul_tcount != 0) {
7867
11.9k
        input[--descending_idx] = hangul_tbase + s_index % hangul_tcount;
7868
11.9k
      }
7869
14.4k
      input[--descending_idx] =
7870
14.4k
          hangul_vbase + (s_index % hangul_ncount) / hangul_tcount;
7871
14.4k
      input[--descending_idx] = hangul_lbase + s_index / hangul_ncount;
7872
43.2k
    } else if (input[input_count] < 0x110000) {
7873
      // Check decomposition_data.
7874
43.2k
      const uint16_t* decomposition =
7875
43.2k
          decomposition_block[decomposition_index[input[input_count] >> 8]] +
7876
43.2k
          (input[input_count] % 256);
7877
43.2k
      uint16_t decomposition_length =
7878
43.2k
          (decomposition[1] >> 2) - (decomposition[0] >> 2);
7879
43.2k
      if (decomposition_length > 0 && (decomposition[0] & 1)) {
7880
0
        decomposition_length = 0;
7881
0
      }
7882
43.2k
      if (decomposition_length > 0) {
7883
        // Non-recursive decomposition.
7884
40.3k
        while (decomposition_length-- > 0) {
7885
28.2k
          input[--descending_idx] = decomposition_data[(decomposition[0] >> 2) +
7886
28.2k
                                                       decomposition_length];
7887
28.2k
        }
7888
31.1k
      } else {
7889
        // No decomposition.
7890
31.1k
        input[--descending_idx] = input[input_count];
7891
31.1k
      }
7892
43.2k
    } else {
7893
      // Non-Unicode character.
7894
0
      input[--descending_idx] = input[input_count];
7895
0
    }
7896
57.7k
  }
7897
12.5k
}
7898
7899
798k
uint8_t get_ccc(char32_t c) noexcept {
7900
798k
  return c < 0x110000 ? canonical_combining_class_block
7901
798k
                            [canonical_combining_class_index[c >> 8]][c % 256]
7902
798k
                      : 0;
7903
798k
}
7904
7905
66.6k
void sort_marks(std::u32string& input) {
7906
465k
  for (size_t idx = 1; idx < input.size(); idx++) {
7907
399k
    uint8_t ccc = get_ccc(input[idx]);
7908
399k
    if (ccc == 0) {
7909
362k
      continue;
7910
362k
    }  // Skip non-combining characters.
7911
36.3k
    auto current_character = input[idx];
7912
36.3k
    size_t back_idx = idx;
7913
48.7k
    while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) {
7914
12.4k
      input[back_idx] = input[back_idx - 1];
7915
12.4k
      back_idx--;
7916
12.4k
    }
7917
36.3k
    input[back_idx] = current_character;
7918
36.3k
  }
7919
66.6k
}
7920
7921
66.6k
void decompose_nfc(std::u32string& input) {
7922
  /**
7923
   * Decompose the domain_name string to Unicode Normalization Form C.
7924
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose
7925
   */
7926
66.6k
  auto [decomposition_needed, additional_elements] =
7927
66.6k
      compute_decomposition_length(input);
7928
66.6k
  if (decomposition_needed) {
7929
12.5k
    decompose(input, additional_elements);
7930
12.5k
  }
7931
66.6k
  sort_marks(input);
7932
66.6k
}
7933
7934
66.6k
void compose(std::u32string& input) {
7935
  /**
7936
   * Compose the domain_name string to Unicode Normalization Form C.
7937
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose
7938
   */
7939
66.6k
  size_t input_count{0};
7940
66.6k
  size_t composition_count{0};
7941
469k
  for (; input_count < input.size(); input_count++, composition_count++) {
7942
402k
    input[composition_count] = input[input_count];
7943
402k
    if (input[input_count] >= hangul_lbase &&
7944
80.0k
        input[input_count] < hangul_lbase + hangul_lcount) {
7945
24.4k
      if (input_count + 1 < input.size() &&
7946
22.8k
          input[input_count + 1] >= hangul_vbase &&
7947
17.2k
          input[input_count + 1] < hangul_vbase + hangul_vcount) {
7948
14.8k
        input[composition_count] =
7949
14.8k
            hangul_sbase +
7950
14.8k
            ((input[input_count] - hangul_lbase) * hangul_vcount +
7951
14.8k
             input[input_count + 1] - hangul_vbase) *
7952
14.8k
                hangul_tcount;
7953
14.8k
        input_count++;
7954
14.8k
        if (input_count + 1 < input.size() &&
7955
14.6k
            input[input_count + 1] > hangul_tbase &&
7956
12.7k
            input[input_count + 1] < hangul_tbase + hangul_tcount) {
7957
11.9k
          input[composition_count] += input[++input_count] - hangul_tbase;
7958
11.9k
        }
7959
14.8k
      }
7960
378k
    } else if (input[input_count] >= hangul_sbase &&
7961
19.1k
               input[input_count] < hangul_sbase + hangul_scount) {
7962
0
      if ((input[input_count] - hangul_sbase) % hangul_tcount &&
7963
0
          input_count + 1 < input.size() &&
7964
0
          input[input_count + 1] > hangul_tbase &&
7965
0
          input[input_count + 1] < hangul_tbase + hangul_tcount) {
7966
0
        input[composition_count] += input[++input_count] - hangul_tbase;
7967
0
      }
7968
378k
    } else if (input[input_count] < 0x110000) {
7969
378k
      const uint16_t* composition =
7970
378k
          &composition_block[composition_index[input[input_count] >> 8]]
7971
378k
                            [input[input_count] % 256];
7972
378k
      size_t initial_composition_count = composition_count;
7973
414k
      for (int32_t previous_ccc = -1; input_count + 1 < input.size();
7974
378k
           input_count++) {
7975
353k
        uint8_t ccc = get_ccc(input[input_count + 1]);
7976
7977
353k
        if (composition[1] != composition[0] && previous_ccc < ccc) {
7978
          // Try finding a composition.
7979
106k
          int left = composition[0];
7980
106k
          int right = composition[1];
7981
317k
          while (left + 2 < right) {
7982
            // mean without overflow
7983
210k
            int middle = left + (((right - left) >> 1) & ~1);
7984
210k
            if (composition_data[middle] <= input[input_count + 1]) {
7985
50.5k
              left = middle;
7986
50.5k
            }
7987
210k
            if (composition_data[middle] >= input[input_count + 1]) {
7988
175k
              right = middle;
7989
175k
            }
7990
210k
          }
7991
106k
          if (composition_data[left] == input[input_count + 1]) {
7992
18.4k
            input[initial_composition_count] = composition_data[left + 1];
7993
18.4k
            composition =
7994
18.4k
                &composition_block
7995
18.4k
                    [composition_index[composition_data[left + 1] >> 8]]
7996
18.4k
                    [composition_data[left + 1] % 256];
7997
18.4k
            continue;
7998
18.4k
          }
7999
106k
        }
8000
8001
334k
        if (ccc == 0) {
8002
316k
          break;
8003
316k
        }  // Not a combining character.
8004
18.0k
        previous_ccc = ccc;
8005
18.0k
        input[++composition_count] = input[input_count + 1];
8006
18.0k
      }
8007
378k
    }
8008
402k
  }
8009
8010
66.6k
  if (composition_count < input_count) {
8011
15.0k
    input.resize(composition_count);
8012
15.0k
  }
8013
66.6k
}
8014
8015
66.6k
void normalize(std::u32string& input) {
8016
  /**
8017
   * Normalize the domain_name string to Unicode Normalization Form C.
8018
   * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize
8019
   */
8020
66.6k
  decompose_nfc(input);
8021
66.6k
  compose(input);
8022
66.6k
}
8023
8024
}  // namespace ada::idna
8025
/* end file src/normalization.cpp */
8026
/* begin file src/punycode.cpp */
8027
8028
#include <cstdint>
8029
8030
namespace ada::idna {
8031
8032
constexpr int32_t base = 36;
8033
constexpr int32_t tmin = 1;
8034
constexpr int32_t tmax = 26;
8035
constexpr int32_t skew = 38;
8036
constexpr int32_t damp = 700;
8037
constexpr int32_t initial_bias = 72;
8038
constexpr uint32_t initial_n = 128;
8039
8040
418k
static constexpr int32_t char_to_digit_value(char value) {
8041
418k
  if (value >= 'a' && value <= 'z') return value - 'a';
8042
137k
  if (value >= '0' && value <= '9') return value - '0' + 26;
8043
1.85k
  return -1;
8044
137k
}
8045
8046
114k
static constexpr char digit_to_char(int32_t digit) {
8047
114k
  return digit < 26 ? char(digit + 97) : char(digit + 22);
8048
114k
}
8049
8050
207k
static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) {
8051
207k
  if (firsttime) {
8052
78.8k
    d = d / damp;
8053
129k
  } else {
8054
129k
    d = d / 2;
8055
129k
  }
8056
207k
  d += d / n;
8057
207k
  int32_t k = 0;
8058
283k
  while (d > ((base - tmin) * tmax) / 2) {
8059
76.0k
    d /= base - tmin;
8060
76.0k
    k += base;
8061
76.0k
  }
8062
207k
  return k + (((base - tmin + 1) * d) / (d + skew));
8063
207k
}
8064
8065
59.6k
bool punycode_to_utf32(std::string_view input, std::u32string &out) {
8066
59.6k
  int32_t written_out{0};
8067
59.6k
  out.reserve(out.size() + input.size());
8068
59.6k
  uint32_t n = initial_n;
8069
59.6k
  int32_t i = 0;
8070
59.6k
  int32_t bias = initial_bias;
8071
  // grab ascii content
8072
59.6k
  size_t end_of_ascii = input.find_last_of('-');
8073
59.6k
  if (end_of_ascii != std::string_view::npos) {
8074
55.0k
    for (uint8_t c : input.substr(0, end_of_ascii)) {
8075
55.0k
      if (c >= 0x80) {
8076
0
        return false;
8077
0
      }
8078
55.0k
      out.push_back(c);
8079
55.0k
      written_out++;
8080
55.0k
    }
8081
13.2k
    input.remove_prefix(end_of_ascii + 1);
8082
13.2k
  }
8083
226k
  while (!input.empty()) {
8084
173k
    int32_t oldi = i;
8085
173k
    int32_t w = 1;
8086
421k
    for (int32_t k = base;; k += base) {
8087
421k
      if (input.empty()) {
8088
2.84k
        return false;
8089
2.84k
      }
8090
418k
      uint8_t code_point = input.front();
8091
418k
      input.remove_prefix(1);
8092
418k
      int32_t digit = char_to_digit_value(code_point);
8093
418k
      if (digit < 0) {
8094
1.85k
        return false;
8095
1.85k
      }
8096
416k
      if (digit > (0x7fffffff - i) / w) {
8097
249
        return false;
8098
249
      }
8099
416k
      i = i + digit * w;
8100
416k
      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8101
416k
      if (digit < t) {
8102
168k
        break;
8103
168k
      }
8104
247k
      if (w > 0x7fffffff / (base - t)) {
8105
0
        return false;
8106
0
      }
8107
247k
      w = w * (base - t);
8108
247k
    }
8109
168k
    bias = adapt(i - oldi, written_out + 1, oldi == 0);
8110
168k
    if (i / (written_out + 1) > int32_t(0x7fffffff - n)) {
8111
1.53k
      return false;
8112
1.53k
    }
8113
167k
    n = n + i / (written_out + 1);
8114
167k
    i = i % (written_out + 1);
8115
167k
    if (n < 0x80) {
8116
0
      return false;
8117
0
    }
8118
167k
    out.insert(out.begin() + i, n);
8119
167k
    written_out++;
8120
167k
    ++i;
8121
167k
  }
8122
  // See https://github.com/whatwg/url/issues/803
8123
  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
8124
53.1k
  if (out.size() >= 4 && out[0] == U'x' && out[1] == U'n' && out[2] == U'-' &&
8125
1.42k
      out[3] == U'-') {
8126
87
    return false;
8127
87
  }
8128
53.1k
  return true;
8129
53.1k
}
8130
8131
0
bool verify_punycode(std::string_view input) {
8132
  // Track only the first 4 decoded code points to check for the "xn--" prefix.
8133
  // This avoids heap allocation while still detecting double-encoded ACE
8134
  // labels.
8135
0
  uint32_t first4[4]{};
8136
0
  size_t written_out{0};
8137
0
  uint32_t n = initial_n;
8138
0
  int32_t i = 0;
8139
0
  int32_t bias = initial_bias;
8140
  // grab ascii content
8141
0
  size_t end_of_ascii = input.find_last_of('-');
8142
0
  if (end_of_ascii != std::string_view::npos) {
8143
0
    for (uint8_t c : input.substr(0, end_of_ascii)) {
8144
0
      if (c >= 0x80) {
8145
0
        return false;
8146
0
      }
8147
0
      if (written_out < 4) {
8148
0
        first4[written_out] = c;
8149
0
      }
8150
0
      written_out++;
8151
0
    }
8152
0
    input.remove_prefix(end_of_ascii + 1);
8153
0
  }
8154
0
  while (!input.empty()) {
8155
0
    int32_t oldi = i;
8156
0
    int32_t w = 1;
8157
0
    for (int32_t k = base;; k += base) {
8158
0
      if (input.empty()) {
8159
0
        return false;
8160
0
      }
8161
0
      uint8_t code_point = input.front();
8162
0
      input.remove_prefix(1);
8163
0
      int32_t digit = char_to_digit_value(code_point);
8164
0
      if (digit < 0) {
8165
0
        return false;
8166
0
      }
8167
0
      if (digit > (0x7fffffff - i) / w) {
8168
0
        return false;
8169
0
      }
8170
0
      i = i + digit * w;
8171
0
      int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8172
0
      if (digit < t) {
8173
0
        break;
8174
0
      }
8175
0
      if (w > 0x7fffffff / (base - t)) {
8176
0
        return false;
8177
0
      }
8178
0
      w = w * (base - t);
8179
0
    }
8180
0
    bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0);
8181
0
    if (i / (written_out + 1) > 0x7fffffff - n) {
8182
0
      return false;
8183
0
    }
8184
0
    n = n + i / int32_t(written_out + 1);
8185
0
    i = i % int32_t(written_out + 1);
8186
0
    if (n < 0x80) {
8187
0
      return false;
8188
0
    }
8189
    // Simulate insert at position i, maintaining only the first 4 slots.
8190
0
    size_t insert_pos = size_t(i);
8191
0
    if (insert_pos < 4) {
8192
0
      for (size_t j = 3; j > insert_pos; j--) {
8193
0
        first4[j] = first4[j - 1];
8194
0
      }
8195
0
      first4[insert_pos] = n;
8196
0
    }
8197
0
    written_out++;
8198
0
    ++i;
8199
0
  }
8200
  // See https://github.com/whatwg/url/issues/803
8201
  // Reject labels whose decoded form begins with "xn--" (double-encoded ACE).
8202
0
  if (written_out >= 4 && first4[0] == U'x' && first4[1] == U'n' &&
8203
0
      first4[2] == U'-' && first4[3] == U'-') {
8204
0
    return false;
8205
0
  }
8206
0
  return true;
8207
0
}
8208
8209
25.2k
bool utf32_to_punycode(std::u32string_view input, std::string &out) {
8210
25.2k
  out.reserve(input.size() + out.size());
8211
25.2k
  uint32_t n = initial_n;
8212
25.2k
  int32_t d = 0;
8213
25.2k
  int32_t bias = initial_bias;
8214
25.2k
  size_t h = 0;
8215
  // first push the ascii content
8216
95.0k
  for (uint32_t c : input) {
8217
95.0k
    if (c < 0x80) {
8218
55.7k
      ++h;
8219
55.7k
      out.push_back(char(c));
8220
55.7k
    }
8221
95.0k
    if (c > 0x10ffff || (c >= 0xd800 && c < 0xe000)) {
8222
0
      return false;
8223
0
    }
8224
95.0k
  }
8225
25.2k
  size_t b = h;
8226
25.2k
  if (b > 0) {
8227
12.3k
    out.push_back('-');
8228
12.3k
  }
8229
63.4k
  while (h < input.size()) {
8230
38.2k
    uint32_t m = 0x10FFFF;
8231
171k
    for (auto code_point : input) {
8232
171k
      if (code_point >= n && code_point < m) m = code_point;
8233
171k
    }
8234
8235
38.2k
    if ((m - n) > (0x7fffffff - d) / (h + 1)) {
8236
0
      return false;
8237
0
    }
8238
38.2k
    d = d + int32_t((m - n) * (h + 1));
8239
38.2k
    n = m;
8240
171k
    for (auto c : input) {
8241
171k
      if (c < n) {
8242
111k
        if (d == 0x7fffffff) {
8243
0
          return false;
8244
0
        }
8245
111k
        ++d;
8246
111k
      }
8247
171k
      if (c == n) {
8248
39.2k
        int32_t q = d;
8249
114k
        for (int32_t k = base;; k += base) {
8250
114k
          int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8251
8252
114k
          if (q < t) {
8253
39.2k
            break;
8254
39.2k
          }
8255
75.6k
          out.push_back(digit_to_char(t + ((q - t) % (base - t))));
8256
75.6k
          q = (q - t) / (base - t);
8257
75.6k
        }
8258
39.2k
        out.push_back(digit_to_char(q));
8259
39.2k
        bias = adapt(d, int32_t(h + 1), h == b);
8260
39.2k
        d = 0;
8261
39.2k
        ++h;
8262
39.2k
      }
8263
171k
    }
8264
38.2k
    ++d;
8265
38.2k
    ++n;
8266
38.2k
  }
8267
25.2k
  return true;
8268
25.2k
}
8269
8270
}  // namespace ada::idna
8271
/* end file src/punycode.cpp */
8272
/* begin file src/validity.cpp */
8273
#include <algorithm>
8274
#include <string_view>
8275
8276
namespace ada::idna {
8277
8278
enum direction : uint8_t {
8279
  NONE,
8280
  BN,
8281
  CS,
8282
  ES,
8283
  ON,
8284
  EN,
8285
  L,
8286
  R,
8287
  NSM,
8288
  AL,
8289
  AN,
8290
  ET,
8291
  WS,
8292
  RLO,
8293
  LRO,
8294
  PDF,
8295
  RLE,
8296
  RLI,
8297
  FSI,
8298
  PDI,
8299
  LRI,
8300
  B,
8301
  S,
8302
  LRE
8303
};
8304
8305
struct directions {
8306
  uint32_t start_code;
8307
  uint32_t final_code;
8308
  direction direct;
8309
};
8310
8311
static directions dir_table[] = {
8312
    {0x0, 0x8, direction::BN},          {0x9, 0x9, direction::S},
8313
    {0xa, 0xa, direction::B},           {0xb, 0xb, direction::S},
8314
    {0xc, 0xc, direction::WS},          {0xd, 0xd, direction::B},
8315
    {0xe, 0x1b, direction::BN},         {0x1c, 0x1e, direction::B},
8316
    {0x1f, 0x1f, direction::S},         {0x20, 0x20, direction::WS},
8317
    {0x21, 0x22, direction::ON},        {0x23, 0x25, direction::ET},
8318
    {0x26, 0x2a, direction::ON},        {0x2b, 0x2b, direction::ES},
8319
    {0x2c, 0x2c, direction::CS},        {0x2d, 0x2d, direction::ES},
8320
    {0x2e, 0x2f, direction::CS},        {0x30, 0x39, direction::EN},
8321
    {0x3a, 0x3a, direction::CS},        {0x3b, 0x40, direction::ON},
8322
    {0x41, 0x5a, direction::L},         {0x5b, 0x60, direction::ON},
8323
    {0x61, 0x7a, direction::L},         {0x7b, 0x7e, direction::ON},
8324
    {0x7f, 0x84, direction::BN},        {0x85, 0x85, direction::B},
8325
    {0x86, 0x9f, direction::BN},        {0xa0, 0xa0, direction::CS},
8326
    {0xa1, 0xa1, direction::ON},        {0xa2, 0xa5, direction::ET},
8327
    {0xa6, 0xa9, direction::ON},        {0xaa, 0xaa, direction::L},
8328
    {0xab, 0xac, direction::ON},        {0xad, 0xad, direction::BN},
8329
    {0xae, 0xaf, direction::ON},        {0xb0, 0xb1, direction::ET},
8330
    {0xb2, 0xb3, direction::EN},        {0xb4, 0xb4, direction::ON},
8331
    {0xb5, 0xb5, direction::L},         {0xb6, 0xb8, direction::ON},
8332
    {0xb9, 0xb9, direction::EN},        {0xba, 0xba, direction::L},
8333
    {0xbb, 0xbf, direction::ON},        {0xc0, 0xd6, direction::L},
8334
    {0xd7, 0xd7, direction::ON},        {0xd8, 0xf6, direction::L},
8335
    {0xf7, 0xf7, direction::ON},        {0xf8, 0x2b8, direction::L},
8336
    {0x2b9, 0x2ba, direction::ON},      {0x2bb, 0x2c1, direction::L},
8337
    {0x2c2, 0x2cf, direction::ON},      {0x2d0, 0x2d1, direction::L},
8338
    {0x2d2, 0x2df, direction::ON},      {0x2e0, 0x2e4, direction::L},
8339
    {0x2e5, 0x2ed, direction::ON},      {0x2ee, 0x2ee, direction::L},
8340
    {0x2ef, 0x2ff, direction::ON},      {0x300, 0x36f, direction::NSM},
8341
    {0x370, 0x373, direction::L},       {0x374, 0x375, direction::ON},
8342
    {0x376, 0x377, direction::L},       {0x37a, 0x37d, direction::L},
8343
    {0x37e, 0x37e, direction::ON},      {0x37f, 0x37f, direction::L},
8344
    {0x384, 0x385, direction::ON},      {0x386, 0x386, direction::L},
8345
    {0x387, 0x387, direction::ON},      {0x388, 0x38a, direction::L},
8346
    {0x38c, 0x38c, direction::L},       {0x38e, 0x3a1, direction::L},
8347
    {0x3a3, 0x3f5, direction::L},       {0x3f6, 0x3f6, direction::ON},
8348
    {0x3f7, 0x482, direction::L},       {0x483, 0x489, direction::NSM},
8349
    {0x48a, 0x52f, direction::L},       {0x531, 0x556, direction::L},
8350
    {0x559, 0x589, direction::L},       {0x58a, 0x58a, direction::ON},
8351
    {0x58d, 0x58e, direction::ON},      {0x58f, 0x58f, direction::ET},
8352
    {0x591, 0x5bd, direction::NSM},     {0x5be, 0x5be, direction::R},
8353
    {0x5bf, 0x5bf, direction::NSM},     {0x5c0, 0x5c0, direction::R},
8354
    {0x5c1, 0x5c2, direction::NSM},     {0x5c3, 0x5c3, direction::R},
8355
    {0x5c4, 0x5c5, direction::NSM},     {0x5c6, 0x5c6, direction::R},
8356
    {0x5c7, 0x5c7, direction::NSM},     {0x5d0, 0x5ea, direction::R},
8357
    {0x5ef, 0x5f4, direction::R},       {0x600, 0x605, direction::AN},
8358
    {0x606, 0x607, direction::ON},      {0x608, 0x608, direction::AL},
8359
    {0x609, 0x60a, direction::ET},      {0x60b, 0x60b, direction::AL},
8360
    {0x60c, 0x60c, direction::CS},      {0x60d, 0x60d, direction::AL},
8361
    {0x60e, 0x60f, direction::ON},      {0x610, 0x61a, direction::NSM},
8362
    {0x61b, 0x61c, direction::AL},      {0x61e, 0x64a, direction::AL},
8363
    {0x64b, 0x65f, direction::NSM},     {0x660, 0x669, direction::AN},
8364
    {0x66a, 0x66a, direction::ET},      {0x66b, 0x66c, direction::AN},
8365
    {0x66d, 0x66f, direction::AL},      {0x670, 0x670, direction::NSM},
8366
    {0x671, 0x6d5, direction::AL},      {0x6d6, 0x6dc, direction::NSM},
8367
    {0x6dd, 0x6dd, direction::AN},      {0x6de, 0x6de, direction::ON},
8368
    {0x6df, 0x6e4, direction::NSM},     {0x6e5, 0x6e6, direction::AL},
8369
    {0x6e7, 0x6e8, direction::NSM},     {0x6e9, 0x6e9, direction::ON},
8370
    {0x6ea, 0x6ed, direction::NSM},     {0x6ee, 0x6ef, direction::AL},
8371
    {0x6f0, 0x6f9, direction::EN},      {0x6fa, 0x70d, direction::AL},
8372
    {0x70f, 0x710, direction::AL},      {0x711, 0x711, direction::NSM},
8373
    {0x712, 0x72f, direction::AL},      {0x730, 0x74a, direction::NSM},
8374
    {0x74d, 0x7a5, direction::AL},      {0x7a6, 0x7b0, direction::NSM},
8375
    {0x7b1, 0x7b1, direction::AL},      {0x7c0, 0x7ea, direction::R},
8376
    {0x7eb, 0x7f3, direction::NSM},     {0x7f4, 0x7f5, direction::R},
8377
    {0x7f6, 0x7f9, direction::ON},      {0x7fa, 0x7fa, direction::R},
8378
    {0x7fd, 0x7fd, direction::NSM},     {0x7fe, 0x815, direction::R},
8379
    {0x816, 0x819, direction::NSM},     {0x81a, 0x81a, direction::R},
8380
    {0x81b, 0x823, direction::NSM},     {0x824, 0x824, direction::R},
8381
    {0x825, 0x827, direction::NSM},     {0x828, 0x828, direction::R},
8382
    {0x829, 0x82d, direction::NSM},     {0x830, 0x83e, direction::R},
8383
    {0x840, 0x858, direction::R},       {0x859, 0x85b, direction::NSM},
8384
    {0x85e, 0x85e, direction::R},       {0x860, 0x86a, direction::AL},
8385
    {0x8a0, 0x8b4, direction::AL},      {0x8b6, 0x8c7, direction::AL},
8386
    {0x8d3, 0x8e1, direction::NSM},     {0x8e2, 0x8e2, direction::AN},
8387
    {0x8e3, 0x902, direction::NSM},     {0x903, 0x939, direction::L},
8388
    {0x93a, 0x93a, direction::NSM},     {0x93b, 0x93b, direction::L},
8389
    {0x93c, 0x93c, direction::NSM},     {0x93d, 0x940, direction::L},
8390
    {0x941, 0x948, direction::NSM},     {0x949, 0x94c, direction::L},
8391
    {0x94d, 0x94d, direction::NSM},     {0x94e, 0x950, direction::L},
8392
    {0x951, 0x957, direction::NSM},     {0x958, 0x961, direction::L},
8393
    {0x962, 0x963, direction::NSM},     {0x964, 0x980, direction::L},
8394
    {0x981, 0x981, direction::NSM},     {0x982, 0x983, direction::L},
8395
    {0x985, 0x98c, direction::L},       {0x98f, 0x990, direction::L},
8396
    {0x993, 0x9a8, direction::L},       {0x9aa, 0x9b0, direction::L},
8397
    {0x9b2, 0x9b2, direction::L},       {0x9b6, 0x9b9, direction::L},
8398
    {0x9bc, 0x9bc, direction::NSM},     {0x9bd, 0x9c0, direction::L},
8399
    {0x9c1, 0x9c4, direction::NSM},     {0x9c7, 0x9c8, direction::L},
8400
    {0x9cb, 0x9cc, direction::L},       {0x9cd, 0x9cd, direction::NSM},
8401
    {0x9ce, 0x9ce, direction::L},       {0x9d7, 0x9d7, direction::L},
8402
    {0x9dc, 0x9dd, direction::L},       {0x9df, 0x9e1, direction::L},
8403
    {0x9e2, 0x9e3, direction::NSM},     {0x9e6, 0x9f1, direction::L},
8404
    {0x9f2, 0x9f3, direction::ET},      {0x9f4, 0x9fa, direction::L},
8405
    {0x9fb, 0x9fb, direction::ET},      {0x9fc, 0x9fd, direction::L},
8406
    {0x9fe, 0x9fe, direction::NSM},     {0xa01, 0xa02, direction::NSM},
8407
    {0xa03, 0xa03, direction::L},       {0xa05, 0xa0a, direction::L},
8408
    {0xa0f, 0xa10, direction::L},       {0xa13, 0xa28, direction::L},
8409
    {0xa2a, 0xa30, direction::L},       {0xa32, 0xa33, direction::L},
8410
    {0xa35, 0xa36, direction::L},       {0xa38, 0xa39, direction::L},
8411
    {0xa3c, 0xa3c, direction::NSM},     {0xa3e, 0xa40, direction::L},
8412
    {0xa41, 0xa42, direction::NSM},     {0xa47, 0xa48, direction::NSM},
8413
    {0xa4b, 0xa4d, direction::NSM},     {0xa51, 0xa51, direction::NSM},
8414
    {0xa59, 0xa5c, direction::L},       {0xa5e, 0xa5e, direction::L},
8415
    {0xa66, 0xa6f, direction::L},       {0xa70, 0xa71, direction::NSM},
8416
    {0xa72, 0xa74, direction::L},       {0xa75, 0xa75, direction::NSM},
8417
    {0xa76, 0xa76, direction::L},       {0xa81, 0xa82, direction::NSM},
8418
    {0xa83, 0xa83, direction::L},       {0xa85, 0xa8d, direction::L},
8419
    {0xa8f, 0xa91, direction::L},       {0xa93, 0xaa8, direction::L},
8420
    {0xaaa, 0xab0, direction::L},       {0xab2, 0xab3, direction::L},
8421
    {0xab5, 0xab9, direction::L},       {0xabc, 0xabc, direction::NSM},
8422
    {0xabd, 0xac0, direction::L},       {0xac1, 0xac5, direction::NSM},
8423
    {0xac7, 0xac8, direction::NSM},     {0xac9, 0xac9, direction::L},
8424
    {0xacb, 0xacc, direction::L},       {0xacd, 0xacd, direction::NSM},
8425
    {0xad0, 0xad0, direction::L},       {0xae0, 0xae1, direction::L},
8426
    {0xae2, 0xae3, direction::NSM},     {0xae6, 0xaf0, direction::L},
8427
    {0xaf1, 0xaf1, direction::ET},      {0xaf9, 0xaf9, direction::L},
8428
    {0xafa, 0xaff, direction::NSM},     {0xb01, 0xb01, direction::NSM},
8429
    {0xb02, 0xb03, direction::L},       {0xb05, 0xb0c, direction::L},
8430
    {0xb0f, 0xb10, direction::L},       {0xb13, 0xb28, direction::L},
8431
    {0xb2a, 0xb30, direction::L},       {0xb32, 0xb33, direction::L},
8432
    {0xb35, 0xb39, direction::L},       {0xb3c, 0xb3c, direction::NSM},
8433
    {0xb3d, 0xb3e, direction::L},       {0xb3f, 0xb3f, direction::NSM},
8434
    {0xb40, 0xb40, direction::L},       {0xb41, 0xb44, direction::NSM},
8435
    {0xb47, 0xb48, direction::L},       {0xb4b, 0xb4c, direction::L},
8436
    {0xb4d, 0xb4d, direction::NSM},     {0xb55, 0xb56, direction::NSM},
8437
    {0xb57, 0xb57, direction::L},       {0xb5c, 0xb5d, direction::L},
8438
    {0xb5f, 0xb61, direction::L},       {0xb62, 0xb63, direction::NSM},
8439
    {0xb66, 0xb77, direction::L},       {0xb82, 0xb82, direction::NSM},
8440
    {0xb83, 0xb83, direction::L},       {0xb85, 0xb8a, direction::L},
8441
    {0xb8e, 0xb90, direction::L},       {0xb92, 0xb95, direction::L},
8442
    {0xb99, 0xb9a, direction::L},       {0xb9c, 0xb9c, direction::L},
8443
    {0xb9e, 0xb9f, direction::L},       {0xba3, 0xba4, direction::L},
8444
    {0xba8, 0xbaa, direction::L},       {0xbae, 0xbb9, direction::L},
8445
    {0xbbe, 0xbbf, direction::L},       {0xbc0, 0xbc0, direction::NSM},
8446
    {0xbc1, 0xbc2, direction::L},       {0xbc6, 0xbc8, direction::L},
8447
    {0xbca, 0xbcc, direction::L},       {0xbcd, 0xbcd, direction::NSM},
8448
    {0xbd0, 0xbd0, direction::L},       {0xbd7, 0xbd7, direction::L},
8449
    {0xbe6, 0xbf2, direction::L},       {0xbf3, 0xbf8, direction::ON},
8450
    {0xbf9, 0xbf9, direction::ET},      {0xbfa, 0xbfa, direction::ON},
8451
    {0xc00, 0xc00, direction::NSM},     {0xc01, 0xc03, direction::L},
8452
    {0xc04, 0xc04, direction::NSM},     {0xc05, 0xc0c, direction::L},
8453
    {0xc0e, 0xc10, direction::L},       {0xc12, 0xc28, direction::L},
8454
    {0xc2a, 0xc39, direction::L},       {0xc3d, 0xc3d, direction::L},
8455
    {0xc3e, 0xc40, direction::NSM},     {0xc41, 0xc44, direction::L},
8456
    {0xc46, 0xc48, direction::NSM},     {0xc4a, 0xc4d, direction::NSM},
8457
    {0xc55, 0xc56, direction::NSM},     {0xc58, 0xc5a, direction::L},
8458
    {0xc60, 0xc61, direction::L},       {0xc62, 0xc63, direction::NSM},
8459
    {0xc66, 0xc6f, direction::L},       {0xc77, 0xc77, direction::L},
8460
    {0xc78, 0xc7e, direction::ON},      {0xc7f, 0xc80, direction::L},
8461
    {0xc81, 0xc81, direction::NSM},     {0xc82, 0xc8c, direction::L},
8462
    {0xc8e, 0xc90, direction::L},       {0xc92, 0xca8, direction::L},
8463
    {0xcaa, 0xcb3, direction::L},       {0xcb5, 0xcb9, direction::L},
8464
    {0xcbc, 0xcbc, direction::NSM},     {0xcbd, 0xcc4, direction::L},
8465
    {0xcc6, 0xcc8, direction::L},       {0xcca, 0xccb, direction::L},
8466
    {0xccc, 0xccd, direction::NSM},     {0xcd5, 0xcd6, direction::L},
8467
    {0xcde, 0xcde, direction::L},       {0xce0, 0xce1, direction::L},
8468
    {0xce2, 0xce3, direction::NSM},     {0xce6, 0xcef, direction::L},
8469
    {0xcf1, 0xcf2, direction::L},       {0xd00, 0xd01, direction::NSM},
8470
    {0xd02, 0xd0c, direction::L},       {0xd0e, 0xd10, direction::L},
8471
    {0xd12, 0xd3a, direction::L},       {0xd3b, 0xd3c, direction::NSM},
8472
    {0xd3d, 0xd40, direction::L},       {0xd41, 0xd44, direction::NSM},
8473
    {0xd46, 0xd48, direction::L},       {0xd4a, 0xd4c, direction::L},
8474
    {0xd4d, 0xd4d, direction::NSM},     {0xd4e, 0xd4f, direction::L},
8475
    {0xd54, 0xd61, direction::L},       {0xd62, 0xd63, direction::NSM},
8476
    {0xd66, 0xd7f, direction::L},       {0xd81, 0xd81, direction::NSM},
8477
    {0xd82, 0xd83, direction::L},       {0xd85, 0xd96, direction::L},
8478
    {0xd9a, 0xdb1, direction::L},       {0xdb3, 0xdbb, direction::L},
8479
    {0xdbd, 0xdbd, direction::L},       {0xdc0, 0xdc6, direction::L},
8480
    {0xdca, 0xdca, direction::NSM},     {0xdcf, 0xdd1, direction::L},
8481
    {0xdd2, 0xdd4, direction::NSM},     {0xdd6, 0xdd6, direction::NSM},
8482
    {0xdd8, 0xddf, direction::L},       {0xde6, 0xdef, direction::L},
8483
    {0xdf2, 0xdf4, direction::L},       {0xe01, 0xe30, direction::L},
8484
    {0xe31, 0xe31, direction::NSM},     {0xe32, 0xe33, direction::L},
8485
    {0xe34, 0xe3a, direction::NSM},     {0xe3f, 0xe3f, direction::ET},
8486
    {0xe40, 0xe46, direction::L},       {0xe47, 0xe4e, direction::NSM},
8487
    {0xe4f, 0xe5b, direction::L},       {0xe81, 0xe82, direction::L},
8488
    {0xe84, 0xe84, direction::L},       {0xe86, 0xe8a, direction::L},
8489
    {0xe8c, 0xea3, direction::L},       {0xea5, 0xea5, direction::L},
8490
    {0xea7, 0xeb0, direction::L},       {0xeb1, 0xeb1, direction::NSM},
8491
    {0xeb2, 0xeb3, direction::L},       {0xeb4, 0xebc, direction::NSM},
8492
    {0xebd, 0xebd, direction::L},       {0xec0, 0xec4, direction::L},
8493
    {0xec6, 0xec6, direction::L},       {0xec8, 0xecd, direction::NSM},
8494
    {0xed0, 0xed9, direction::L},       {0xedc, 0xedf, direction::L},
8495
    {0xf00, 0xf17, direction::L},       {0xf18, 0xf19, direction::NSM},
8496
    {0xf1a, 0xf34, direction::L},       {0xf35, 0xf35, direction::NSM},
8497
    {0xf36, 0xf36, direction::L},       {0xf37, 0xf37, direction::NSM},
8498
    {0xf38, 0xf38, direction::L},       {0xf39, 0xf39, direction::NSM},
8499
    {0xf3a, 0xf3d, direction::ON},      {0xf3e, 0xf47, direction::L},
8500
    {0xf49, 0xf6c, direction::L},       {0xf71, 0xf7e, direction::NSM},
8501
    {0xf7f, 0xf7f, direction::L},       {0xf80, 0xf84, direction::NSM},
8502
    {0xf85, 0xf85, direction::L},       {0xf86, 0xf87, direction::NSM},
8503
    {0xf88, 0xf8c, direction::L},       {0xf8d, 0xf97, direction::NSM},
8504
    {0xf99, 0xfbc, direction::NSM},     {0xfbe, 0xfc5, direction::L},
8505
    {0xfc6, 0xfc6, direction::NSM},     {0xfc7, 0xfcc, direction::L},
8506
    {0xfce, 0xfda, direction::L},       {0x1000, 0x102c, direction::L},
8507
    {0x102d, 0x1030, direction::NSM},   {0x1031, 0x1031, direction::L},
8508
    {0x1032, 0x1037, direction::NSM},   {0x1038, 0x1038, direction::L},
8509
    {0x1039, 0x103a, direction::NSM},   {0x103b, 0x103c, direction::L},
8510
    {0x103d, 0x103e, direction::NSM},   {0x103f, 0x1057, direction::L},
8511
    {0x1058, 0x1059, direction::NSM},   {0x105a, 0x105d, direction::L},
8512
    {0x105e, 0x1060, direction::NSM},   {0x1061, 0x1070, direction::L},
8513
    {0x1071, 0x1074, direction::NSM},   {0x1075, 0x1081, direction::L},
8514
    {0x1082, 0x1082, direction::NSM},   {0x1083, 0x1084, direction::L},
8515
    {0x1085, 0x1086, direction::NSM},   {0x1087, 0x108c, direction::L},
8516
    {0x108d, 0x108d, direction::NSM},   {0x108e, 0x109c, direction::L},
8517
    {0x109d, 0x109d, direction::NSM},   {0x109e, 0x10c5, direction::L},
8518
    {0x10c7, 0x10c7, direction::L},     {0x10cd, 0x10cd, direction::L},
8519
    {0x10d0, 0x1248, direction::L},     {0x124a, 0x124d, direction::L},
8520
    {0x1250, 0x1256, direction::L},     {0x1258, 0x1258, direction::L},
8521
    {0x125a, 0x125d, direction::L},     {0x1260, 0x1288, direction::L},
8522
    {0x128a, 0x128d, direction::L},     {0x1290, 0x12b0, direction::L},
8523
    {0x12b2, 0x12b5, direction::L},     {0x12b8, 0x12be, direction::L},
8524
    {0x12c0, 0x12c0, direction::L},     {0x12c2, 0x12c5, direction::L},
8525
    {0x12c8, 0x12d6, direction::L},     {0x12d8, 0x1310, direction::L},
8526
    {0x1312, 0x1315, direction::L},     {0x1318, 0x135a, direction::L},
8527
    {0x135d, 0x135f, direction::NSM},   {0x1360, 0x137c, direction::L},
8528
    {0x1380, 0x138f, direction::L},     {0x1390, 0x1399, direction::ON},
8529
    {0x13a0, 0x13f5, direction::L},     {0x13f8, 0x13fd, direction::L},
8530
    {0x1400, 0x1400, direction::ON},    {0x1401, 0x167f, direction::L},
8531
    {0x1680, 0x1680, direction::WS},    {0x1681, 0x169a, direction::L},
8532
    {0x169b, 0x169c, direction::ON},    {0x16a0, 0x16f8, direction::L},
8533
    {0x1700, 0x170c, direction::L},     {0x170e, 0x1711, direction::L},
8534
    {0x1712, 0x1714, direction::NSM},   {0x1720, 0x1731, direction::L},
8535
    {0x1732, 0x1734, direction::NSM},   {0x1735, 0x1736, direction::L},
8536
    {0x1740, 0x1751, direction::L},     {0x1752, 0x1753, direction::NSM},
8537
    {0x1760, 0x176c, direction::L},     {0x176e, 0x1770, direction::L},
8538
    {0x1772, 0x1773, direction::NSM},   {0x1780, 0x17b3, direction::L},
8539
    {0x17b4, 0x17b5, direction::NSM},   {0x17b6, 0x17b6, direction::L},
8540
    {0x17b7, 0x17bd, direction::NSM},   {0x17be, 0x17c5, direction::L},
8541
    {0x17c6, 0x17c6, direction::NSM},   {0x17c7, 0x17c8, direction::L},
8542
    {0x17c9, 0x17d3, direction::NSM},   {0x17d4, 0x17da, direction::L},
8543
    {0x17db, 0x17db, direction::ET},    {0x17dc, 0x17dc, direction::L},
8544
    {0x17dd, 0x17dd, direction::NSM},   {0x17e0, 0x17e9, direction::L},
8545
    {0x17f0, 0x17f9, direction::ON},    {0x1800, 0x180a, direction::ON},
8546
    {0x180b, 0x180d, direction::NSM},   {0x180e, 0x180e, direction::BN},
8547
    {0x1810, 0x1819, direction::L},     {0x1820, 0x1878, direction::L},
8548
    {0x1880, 0x1884, direction::L},     {0x1885, 0x1886, direction::NSM},
8549
    {0x1887, 0x18a8, direction::L},     {0x18a9, 0x18a9, direction::NSM},
8550
    {0x18aa, 0x18aa, direction::L},     {0x18b0, 0x18f5, direction::L},
8551
    {0x1900, 0x191e, direction::L},     {0x1920, 0x1922, direction::NSM},
8552
    {0x1923, 0x1926, direction::L},     {0x1927, 0x1928, direction::NSM},
8553
    {0x1929, 0x192b, direction::L},     {0x1930, 0x1931, direction::L},
8554
    {0x1932, 0x1932, direction::NSM},   {0x1933, 0x1938, direction::L},
8555
    {0x1939, 0x193b, direction::NSM},   {0x1940, 0x1940, direction::ON},
8556
    {0x1944, 0x1945, direction::ON},    {0x1946, 0x196d, direction::L},
8557
    {0x1970, 0x1974, direction::L},     {0x1980, 0x19ab, direction::L},
8558
    {0x19b0, 0x19c9, direction::L},     {0x19d0, 0x19da, direction::L},
8559
    {0x19de, 0x19ff, direction::ON},    {0x1a00, 0x1a16, direction::L},
8560
    {0x1a17, 0x1a18, direction::NSM},   {0x1a19, 0x1a1a, direction::L},
8561
    {0x1a1b, 0x1a1b, direction::NSM},   {0x1a1e, 0x1a55, direction::L},
8562
    {0x1a56, 0x1a56, direction::NSM},   {0x1a57, 0x1a57, direction::L},
8563
    {0x1a58, 0x1a5e, direction::NSM},   {0x1a60, 0x1a60, direction::NSM},
8564
    {0x1a61, 0x1a61, direction::L},     {0x1a62, 0x1a62, direction::NSM},
8565
    {0x1a63, 0x1a64, direction::L},     {0x1a65, 0x1a6c, direction::NSM},
8566
    {0x1a6d, 0x1a72, direction::L},     {0x1a73, 0x1a7c, direction::NSM},
8567
    {0x1a7f, 0x1a7f, direction::NSM},   {0x1a80, 0x1a89, direction::L},
8568
    {0x1a90, 0x1a99, direction::L},     {0x1aa0, 0x1aad, direction::L},
8569
    {0x1ab0, 0x1ac0, direction::NSM},   {0x1b00, 0x1b03, direction::NSM},
8570
    {0x1b04, 0x1b33, direction::L},     {0x1b34, 0x1b34, direction::NSM},
8571
    {0x1b35, 0x1b35, direction::L},     {0x1b36, 0x1b3a, direction::NSM},
8572
    {0x1b3b, 0x1b3b, direction::L},     {0x1b3c, 0x1b3c, direction::NSM},
8573
    {0x1b3d, 0x1b41, direction::L},     {0x1b42, 0x1b42, direction::NSM},
8574
    {0x1b43, 0x1b4b, direction::L},     {0x1b50, 0x1b6a, direction::L},
8575
    {0x1b6b, 0x1b73, direction::NSM},   {0x1b74, 0x1b7c, direction::L},
8576
    {0x1b80, 0x1b81, direction::NSM},   {0x1b82, 0x1ba1, direction::L},
8577
    {0x1ba2, 0x1ba5, direction::NSM},   {0x1ba6, 0x1ba7, direction::L},
8578
    {0x1ba8, 0x1ba9, direction::NSM},   {0x1baa, 0x1baa, direction::L},
8579
    {0x1bab, 0x1bad, direction::NSM},   {0x1bae, 0x1be5, direction::L},
8580
    {0x1be6, 0x1be6, direction::NSM},   {0x1be7, 0x1be7, direction::L},
8581
    {0x1be8, 0x1be9, direction::NSM},   {0x1bea, 0x1bec, direction::L},
8582
    {0x1bed, 0x1bed, direction::NSM},   {0x1bee, 0x1bee, direction::L},
8583
    {0x1bef, 0x1bf1, direction::NSM},   {0x1bf2, 0x1bf3, direction::L},
8584
    {0x1bfc, 0x1c2b, direction::L},     {0x1c2c, 0x1c33, direction::NSM},
8585
    {0x1c34, 0x1c35, direction::L},     {0x1c36, 0x1c37, direction::NSM},
8586
    {0x1c3b, 0x1c49, direction::L},     {0x1c4d, 0x1c88, direction::L},
8587
    {0x1c90, 0x1cba, direction::L},     {0x1cbd, 0x1cc7, direction::L},
8588
    {0x1cd0, 0x1cd2, direction::NSM},   {0x1cd3, 0x1cd3, direction::L},
8589
    {0x1cd4, 0x1ce0, direction::NSM},   {0x1ce1, 0x1ce1, direction::L},
8590
    {0x1ce2, 0x1ce8, direction::NSM},   {0x1ce9, 0x1cec, direction::L},
8591
    {0x1ced, 0x1ced, direction::NSM},   {0x1cee, 0x1cf3, direction::L},
8592
    {0x1cf4, 0x1cf4, direction::NSM},   {0x1cf5, 0x1cf7, direction::L},
8593
    {0x1cf8, 0x1cf9, direction::NSM},   {0x1cfa, 0x1cfa, direction::L},
8594
    {0x1d00, 0x1dbf, direction::L},     {0x1dc0, 0x1df9, direction::NSM},
8595
    {0x1dfb, 0x1dff, direction::NSM},   {0x1e00, 0x1f15, direction::L},
8596
    {0x1f18, 0x1f1d, direction::L},     {0x1f20, 0x1f45, direction::L},
8597
    {0x1f48, 0x1f4d, direction::L},     {0x1f50, 0x1f57, direction::L},
8598
    {0x1f59, 0x1f59, direction::L},     {0x1f5b, 0x1f5b, direction::L},
8599
    {0x1f5d, 0x1f5d, direction::L},     {0x1f5f, 0x1f7d, direction::L},
8600
    {0x1f80, 0x1fb4, direction::L},     {0x1fb6, 0x1fbc, direction::L},
8601
    {0x1fbd, 0x1fbd, direction::ON},    {0x1fbe, 0x1fbe, direction::L},
8602
    {0x1fbf, 0x1fc1, direction::ON},    {0x1fc2, 0x1fc4, direction::L},
8603
    {0x1fc6, 0x1fcc, direction::L},     {0x1fcd, 0x1fcf, direction::ON},
8604
    {0x1fd0, 0x1fd3, direction::L},     {0x1fd6, 0x1fdb, direction::L},
8605
    {0x1fdd, 0x1fdf, direction::ON},    {0x1fe0, 0x1fec, direction::L},
8606
    {0x1fed, 0x1fef, direction::ON},    {0x1ff2, 0x1ff4, direction::L},
8607
    {0x1ff6, 0x1ffc, direction::L},     {0x1ffd, 0x1ffe, direction::ON},
8608
    {0x2000, 0x200a, direction::WS},    {0x200b, 0x200d, direction::BN},
8609
    {0x200e, 0x200e, direction::L},     {0x200f, 0x200f, direction::R},
8610
    {0x2010, 0x2027, direction::ON},    {0x2028, 0x2028, direction::WS},
8611
    {0x2029, 0x2029, direction::B},     {0x202a, 0x202a, direction::LRE},
8612
    {0x202b, 0x202b, direction::RLE},   {0x202c, 0x202c, direction::PDF},
8613
    {0x202d, 0x202d, direction::LRO},   {0x202e, 0x202e, direction::RLO},
8614
    {0x202f, 0x202f, direction::CS},    {0x2030, 0x2034, direction::ET},
8615
    {0x2035, 0x2043, direction::ON},    {0x2044, 0x2044, direction::CS},
8616
    {0x2045, 0x205e, direction::ON},    {0x205f, 0x205f, direction::WS},
8617
    {0x2060, 0x2064, direction::BN},    {0x2066, 0x2066, direction::LRI},
8618
    {0x2067, 0x2067, direction::RLI},   {0x2068, 0x2068, direction::FSI},
8619
    {0x2069, 0x2069, direction::PDI},   {0x206a, 0x206f, direction::BN},
8620
    {0x2070, 0x2070, direction::EN},    {0x2071, 0x2071, direction::L},
8621
    {0x2074, 0x2079, direction::EN},    {0x207a, 0x207b, direction::ES},
8622
    {0x207c, 0x207e, direction::ON},    {0x207f, 0x207f, direction::L},
8623
    {0x2080, 0x2089, direction::EN},    {0x208a, 0x208b, direction::ES},
8624
    {0x208c, 0x208e, direction::ON},    {0x2090, 0x209c, direction::L},
8625
    {0x20a0, 0x20bf, direction::ET},    {0x20d0, 0x20f0, direction::NSM},
8626
    {0x2100, 0x2101, direction::ON},    {0x2102, 0x2102, direction::L},
8627
    {0x2103, 0x2106, direction::ON},    {0x2107, 0x2107, direction::L},
8628
    {0x2108, 0x2109, direction::ON},    {0x210a, 0x2113, direction::L},
8629
    {0x2114, 0x2114, direction::ON},    {0x2115, 0x2115, direction::L},
8630
    {0x2116, 0x2118, direction::ON},    {0x2119, 0x211d, direction::L},
8631
    {0x211e, 0x2123, direction::ON},    {0x2124, 0x2124, direction::L},
8632
    {0x2125, 0x2125, direction::ON},    {0x2126, 0x2126, direction::L},
8633
    {0x2127, 0x2127, direction::ON},    {0x2128, 0x2128, direction::L},
8634
    {0x2129, 0x2129, direction::ON},    {0x212a, 0x212d, direction::L},
8635
    {0x212e, 0x212e, direction::ET},    {0x212f, 0x2139, direction::L},
8636
    {0x213a, 0x213b, direction::ON},    {0x213c, 0x213f, direction::L},
8637
    {0x2140, 0x2144, direction::ON},    {0x2145, 0x2149, direction::L},
8638
    {0x214a, 0x214d, direction::ON},    {0x214e, 0x214f, direction::L},
8639
    {0x2150, 0x215f, direction::ON},    {0x2160, 0x2188, direction::L},
8640
    {0x2189, 0x218b, direction::ON},    {0x2190, 0x2211, direction::ON},
8641
    {0x2212, 0x2212, direction::ES},    {0x2213, 0x2213, direction::ET},
8642
    {0x2214, 0x2335, direction::ON},    {0x2336, 0x237a, direction::L},
8643
    {0x237b, 0x2394, direction::ON},    {0x2395, 0x2395, direction::L},
8644
    {0x2396, 0x2426, direction::ON},    {0x2440, 0x244a, direction::ON},
8645
    {0x2460, 0x2487, direction::ON},    {0x2488, 0x249b, direction::EN},
8646
    {0x249c, 0x24e9, direction::L},     {0x24ea, 0x26ab, direction::ON},
8647
    {0x26ac, 0x26ac, direction::L},     {0x26ad, 0x27ff, direction::ON},
8648
    {0x2800, 0x28ff, direction::L},     {0x2900, 0x2b73, direction::ON},
8649
    {0x2b76, 0x2b95, direction::ON},    {0x2b97, 0x2bff, direction::ON},
8650
    {0x2c00, 0x2c2e, direction::L},     {0x2c30, 0x2c5e, direction::L},
8651
    {0x2c60, 0x2ce4, direction::L},     {0x2ce5, 0x2cea, direction::ON},
8652
    {0x2ceb, 0x2cee, direction::L},     {0x2cef, 0x2cf1, direction::NSM},
8653
    {0x2cf2, 0x2cf3, direction::L},     {0x2cf9, 0x2cff, direction::ON},
8654
    {0x2d00, 0x2d25, direction::L},     {0x2d27, 0x2d27, direction::L},
8655
    {0x2d2d, 0x2d2d, direction::L},     {0x2d30, 0x2d67, direction::L},
8656
    {0x2d6f, 0x2d70, direction::L},     {0x2d7f, 0x2d7f, direction::NSM},
8657
    {0x2d80, 0x2d96, direction::L},     {0x2da0, 0x2da6, direction::L},
8658
    {0x2da8, 0x2dae, direction::L},     {0x2db0, 0x2db6, direction::L},
8659
    {0x2db8, 0x2dbe, direction::L},     {0x2dc0, 0x2dc6, direction::L},
8660
    {0x2dc8, 0x2dce, direction::L},     {0x2dd0, 0x2dd6, direction::L},
8661
    {0x2dd8, 0x2dde, direction::L},     {0x2de0, 0x2dff, direction::NSM},
8662
    {0x2e00, 0x2e52, direction::ON},    {0x2e80, 0x2e99, direction::ON},
8663
    {0x2e9b, 0x2ef3, direction::ON},    {0x2f00, 0x2fd5, direction::ON},
8664
    {0x2ff0, 0x2ffb, direction::ON},    {0x3000, 0x3000, direction::WS},
8665
    {0x3001, 0x3004, direction::ON},    {0x3005, 0x3007, direction::L},
8666
    {0x3008, 0x3020, direction::ON},    {0x3021, 0x3029, direction::L},
8667
    {0x302a, 0x302d, direction::NSM},   {0x302e, 0x302f, direction::L},
8668
    {0x3030, 0x3030, direction::ON},    {0x3031, 0x3035, direction::L},
8669
    {0x3036, 0x3037, direction::ON},    {0x3038, 0x303c, direction::L},
8670
    {0x303d, 0x303f, direction::ON},    {0x3041, 0x3096, direction::L},
8671
    {0x3099, 0x309a, direction::NSM},   {0x309b, 0x309c, direction::ON},
8672
    {0x309d, 0x309f, direction::L},     {0x30a0, 0x30a0, direction::ON},
8673
    {0x30a1, 0x30fa, direction::L},     {0x30fb, 0x30fb, direction::ON},
8674
    {0x30fc, 0x30ff, direction::L},     {0x3105, 0x312f, direction::L},
8675
    {0x3131, 0x318e, direction::L},     {0x3190, 0x31bf, direction::L},
8676
    {0x31c0, 0x31e3, direction::ON},    {0x31f0, 0x321c, direction::L},
8677
    {0x321d, 0x321e, direction::ON},    {0x3220, 0x324f, direction::L},
8678
    {0x3250, 0x325f, direction::ON},    {0x3260, 0x327b, direction::L},
8679
    {0x327c, 0x327e, direction::ON},    {0x327f, 0x32b0, direction::L},
8680
    {0x32b1, 0x32bf, direction::ON},    {0x32c0, 0x32cb, direction::L},
8681
    {0x32cc, 0x32cf, direction::ON},    {0x32d0, 0x3376, direction::L},
8682
    {0x3377, 0x337a, direction::ON},    {0x337b, 0x33dd, direction::L},
8683
    {0x33de, 0x33df, direction::ON},    {0x33e0, 0x33fe, direction::L},
8684
    {0x33ff, 0x33ff, direction::ON},    {0x3400, 0x4dbf, direction::L},
8685
    {0x4dc0, 0x4dff, direction::ON},    {0x4e00, 0x9ffc, direction::L},
8686
    {0xa000, 0xa48c, direction::L},     {0xa490, 0xa4c6, direction::ON},
8687
    {0xa4d0, 0xa60c, direction::L},     {0xa60d, 0xa60f, direction::ON},
8688
    {0xa610, 0xa62b, direction::L},     {0xa640, 0xa66e, direction::L},
8689
    {0xa66f, 0xa672, direction::NSM},   {0xa673, 0xa673, direction::ON},
8690
    {0xa674, 0xa67d, direction::NSM},   {0xa67e, 0xa67f, direction::ON},
8691
    {0xa680, 0xa69d, direction::L},     {0xa69e, 0xa69f, direction::NSM},
8692
    {0xa6a0, 0xa6ef, direction::L},     {0xa6f0, 0xa6f1, direction::NSM},
8693
    {0xa6f2, 0xa6f7, direction::L},     {0xa700, 0xa721, direction::ON},
8694
    {0xa722, 0xa787, direction::L},     {0xa788, 0xa788, direction::ON},
8695
    {0xa789, 0xa7bf, direction::L},     {0xa7c2, 0xa7ca, direction::L},
8696
    {0xa7f5, 0xa801, direction::L},     {0xa802, 0xa802, direction::NSM},
8697
    {0xa803, 0xa805, direction::L},     {0xa806, 0xa806, direction::NSM},
8698
    {0xa807, 0xa80a, direction::L},     {0xa80b, 0xa80b, direction::NSM},
8699
    {0xa80c, 0xa824, direction::L},     {0xa825, 0xa826, direction::NSM},
8700
    {0xa827, 0xa827, direction::L},     {0xa828, 0xa82b, direction::ON},
8701
    {0xa82c, 0xa82c, direction::NSM},   {0xa830, 0xa837, direction::L},
8702
    {0xa838, 0xa839, direction::ET},    {0xa840, 0xa873, direction::L},
8703
    {0xa874, 0xa877, direction::ON},    {0xa880, 0xa8c3, direction::L},
8704
    {0xa8c4, 0xa8c5, direction::NSM},   {0xa8ce, 0xa8d9, direction::L},
8705
    {0xa8e0, 0xa8f1, direction::NSM},   {0xa8f2, 0xa8fe, direction::L},
8706
    {0xa8ff, 0xa8ff, direction::NSM},   {0xa900, 0xa925, direction::L},
8707
    {0xa926, 0xa92d, direction::NSM},   {0xa92e, 0xa946, direction::L},
8708
    {0xa947, 0xa951, direction::NSM},   {0xa952, 0xa953, direction::L},
8709
    {0xa95f, 0xa97c, direction::L},     {0xa980, 0xa982, direction::NSM},
8710
    {0xa983, 0xa9b2, direction::L},     {0xa9b3, 0xa9b3, direction::NSM},
8711
    {0xa9b4, 0xa9b5, direction::L},     {0xa9b6, 0xa9b9, direction::NSM},
8712
    {0xa9ba, 0xa9bb, direction::L},     {0xa9bc, 0xa9bd, direction::NSM},
8713
    {0xa9be, 0xa9cd, direction::L},     {0xa9cf, 0xa9d9, direction::L},
8714
    {0xa9de, 0xa9e4, direction::L},     {0xa9e5, 0xa9e5, direction::NSM},
8715
    {0xa9e6, 0xa9fe, direction::L},     {0xaa00, 0xaa28, direction::L},
8716
    {0xaa29, 0xaa2e, direction::NSM},   {0xaa2f, 0xaa30, direction::L},
8717
    {0xaa31, 0xaa32, direction::NSM},   {0xaa33, 0xaa34, direction::L},
8718
    {0xaa35, 0xaa36, direction::NSM},   {0xaa40, 0xaa42, direction::L},
8719
    {0xaa43, 0xaa43, direction::NSM},   {0xaa44, 0xaa4b, direction::L},
8720
    {0xaa4c, 0xaa4c, direction::NSM},   {0xaa4d, 0xaa4d, direction::L},
8721
    {0xaa50, 0xaa59, direction::L},     {0xaa5c, 0xaa7b, direction::L},
8722
    {0xaa7c, 0xaa7c, direction::NSM},   {0xaa7d, 0xaaaf, direction::L},
8723
    {0xaab0, 0xaab0, direction::NSM},   {0xaab1, 0xaab1, direction::L},
8724
    {0xaab2, 0xaab4, direction::NSM},   {0xaab5, 0xaab6, direction::L},
8725
    {0xaab7, 0xaab8, direction::NSM},   {0xaab9, 0xaabd, direction::L},
8726
    {0xaabe, 0xaabf, direction::NSM},   {0xaac0, 0xaac0, direction::L},
8727
    {0xaac1, 0xaac1, direction::NSM},   {0xaac2, 0xaac2, direction::L},
8728
    {0xaadb, 0xaaeb, direction::L},     {0xaaec, 0xaaed, direction::NSM},
8729
    {0xaaee, 0xaaf5, direction::L},     {0xaaf6, 0xaaf6, direction::NSM},
8730
    {0xab01, 0xab06, direction::L},     {0xab09, 0xab0e, direction::L},
8731
    {0xab11, 0xab16, direction::L},     {0xab20, 0xab26, direction::L},
8732
    {0xab28, 0xab2e, direction::L},     {0xab30, 0xab69, direction::L},
8733
    {0xab6a, 0xab6b, direction::ON},    {0xab70, 0xabe4, direction::L},
8734
    {0xabe5, 0xabe5, direction::NSM},   {0xabe6, 0xabe7, direction::L},
8735
    {0xabe8, 0xabe8, direction::NSM},   {0xabe9, 0xabec, direction::L},
8736
    {0xabed, 0xabed, direction::NSM},   {0xabf0, 0xabf9, direction::L},
8737
    {0xac00, 0xd7a3, direction::L},     {0xd7b0, 0xd7c6, direction::L},
8738
    {0xd7cb, 0xd7fb, direction::L},     {0xd800, 0xfa6d, direction::L},
8739
    {0xfa70, 0xfad9, direction::L},     {0xfb00, 0xfb06, direction::L},
8740
    {0xfb13, 0xfb17, direction::L},     {0xfb1d, 0xfb1d, direction::R},
8741
    {0xfb1e, 0xfb1e, direction::NSM},   {0xfb1f, 0xfb28, direction::R},
8742
    {0xfb29, 0xfb29, direction::ES},    {0xfb2a, 0xfb36, direction::R},
8743
    {0xfb38, 0xfb3c, direction::R},     {0xfb3e, 0xfb3e, direction::R},
8744
    {0xfb40, 0xfb41, direction::R},     {0xfb43, 0xfb44, direction::R},
8745
    {0xfb46, 0xfb4f, direction::R},     {0xfb50, 0xfbc1, direction::AL},
8746
    {0xfbd3, 0xfd3d, direction::AL},    {0xfd3e, 0xfd3f, direction::ON},
8747
    {0xfd50, 0xfd8f, direction::AL},    {0xfd92, 0xfdc7, direction::AL},
8748
    {0xfdf0, 0xfdfc, direction::AL},    {0xfdfd, 0xfdfd, direction::ON},
8749
    {0xfe00, 0xfe0f, direction::NSM},   {0xfe10, 0xfe19, direction::ON},
8750
    {0xfe20, 0xfe2f, direction::NSM},   {0xfe30, 0xfe4f, direction::ON},
8751
    {0xfe50, 0xfe50, direction::CS},    {0xfe51, 0xfe51, direction::ON},
8752
    {0xfe52, 0xfe52, direction::CS},    {0xfe54, 0xfe54, direction::ON},
8753
    {0xfe55, 0xfe55, direction::CS},    {0xfe56, 0xfe5e, direction::ON},
8754
    {0xfe5f, 0xfe5f, direction::ET},    {0xfe60, 0xfe61, direction::ON},
8755
    {0xfe62, 0xfe63, direction::ES},    {0xfe64, 0xfe66, direction::ON},
8756
    {0xfe68, 0xfe68, direction::ON},    {0xfe69, 0xfe6a, direction::ET},
8757
    {0xfe6b, 0xfe6b, direction::ON},    {0xfe70, 0xfe74, direction::AL},
8758
    {0xfe76, 0xfefc, direction::AL},    {0xfeff, 0xfeff, direction::BN},
8759
    {0xff01, 0xff02, direction::ON},    {0xff03, 0xff05, direction::ET},
8760
    {0xff06, 0xff0a, direction::ON},    {0xff0b, 0xff0b, direction::ES},
8761
    {0xff0c, 0xff0c, direction::CS},    {0xff0d, 0xff0d, direction::ES},
8762
    {0xff0e, 0xff0f, direction::CS},    {0xff10, 0xff19, direction::EN},
8763
    {0xff1a, 0xff1a, direction::CS},    {0xff1b, 0xff20, direction::ON},
8764
    {0xff21, 0xff3a, direction::L},     {0xff3b, 0xff40, direction::ON},
8765
    {0xff41, 0xff5a, direction::L},     {0xff5b, 0xff65, direction::ON},
8766
    {0xff66, 0xffbe, direction::L},     {0xffc2, 0xffc7, direction::L},
8767
    {0xffca, 0xffcf, direction::L},     {0xffd2, 0xffd7, direction::L},
8768
    {0xffda, 0xffdc, direction::L},     {0xffe0, 0xffe1, direction::ET},
8769
    {0xffe2, 0xffe4, direction::ON},    {0xffe5, 0xffe6, direction::ET},
8770
    {0xffe8, 0xffee, direction::ON},    {0xfff9, 0xfffd, direction::ON},
8771
    {0x10000, 0x1000b, direction::L},   {0x1000d, 0x10026, direction::L},
8772
    {0x10028, 0x1003a, direction::L},   {0x1003c, 0x1003d, direction::L},
8773
    {0x1003f, 0x1004d, direction::L},   {0x10050, 0x1005d, direction::L},
8774
    {0x10080, 0x100fa, direction::L},   {0x10100, 0x10100, direction::L},
8775
    {0x10101, 0x10101, direction::ON},  {0x10102, 0x10102, direction::L},
8776
    {0x10107, 0x10133, direction::L},   {0x10137, 0x1013f, direction::L},
8777
    {0x10140, 0x1018c, direction::ON},  {0x1018d, 0x1018e, direction::L},
8778
    {0x10190, 0x1019c, direction::ON},  {0x101a0, 0x101a0, direction::ON},
8779
    {0x101d0, 0x101fc, direction::L},   {0x101fd, 0x101fd, direction::NSM},
8780
    {0x10280, 0x1029c, direction::L},   {0x102a0, 0x102d0, direction::L},
8781
    {0x102e0, 0x102e0, direction::NSM}, {0x102e1, 0x102fb, direction::EN},
8782
    {0x10300, 0x10323, direction::L},   {0x1032d, 0x1034a, direction::L},
8783
    {0x10350, 0x10375, direction::L},   {0x10376, 0x1037a, direction::NSM},
8784
    {0x10380, 0x1039d, direction::L},   {0x1039f, 0x103c3, direction::L},
8785
    {0x103c8, 0x103d5, direction::L},   {0x10400, 0x1049d, direction::L},
8786
    {0x104a0, 0x104a9, direction::L},   {0x104b0, 0x104d3, direction::L},
8787
    {0x104d8, 0x104fb, direction::L},   {0x10500, 0x10527, direction::L},
8788
    {0x10530, 0x10563, direction::L},   {0x1056f, 0x1056f, direction::L},
8789
    {0x10600, 0x10736, direction::L},   {0x10740, 0x10755, direction::L},
8790
    {0x10760, 0x10767, direction::L},   {0x10800, 0x10805, direction::R},
8791
    {0x10808, 0x10808, direction::R},   {0x1080a, 0x10835, direction::R},
8792
    {0x10837, 0x10838, direction::R},   {0x1083c, 0x1083c, direction::R},
8793
    {0x1083f, 0x10855, direction::R},   {0x10857, 0x1089e, direction::R},
8794
    {0x108a7, 0x108af, direction::R},   {0x108e0, 0x108f2, direction::R},
8795
    {0x108f4, 0x108f5, direction::R},   {0x108fb, 0x1091b, direction::R},
8796
    {0x1091f, 0x1091f, direction::ON},  {0x10920, 0x10939, direction::R},
8797
    {0x1093f, 0x1093f, direction::R},   {0x10980, 0x109b7, direction::R},
8798
    {0x109bc, 0x109cf, direction::R},   {0x109d2, 0x10a00, direction::R},
8799
    {0x10a01, 0x10a03, direction::NSM}, {0x10a05, 0x10a06, direction::NSM},
8800
    {0x10a0c, 0x10a0f, direction::NSM}, {0x10a10, 0x10a13, direction::R},
8801
    {0x10a15, 0x10a17, direction::R},   {0x10a19, 0x10a35, direction::R},
8802
    {0x10a38, 0x10a3a, direction::NSM}, {0x10a3f, 0x10a3f, direction::NSM},
8803
    {0x10a40, 0x10a48, direction::R},   {0x10a50, 0x10a58, direction::R},
8804
    {0x10a60, 0x10a9f, direction::R},   {0x10ac0, 0x10ae4, direction::R},
8805
    {0x10ae5, 0x10ae6, direction::NSM}, {0x10aeb, 0x10af6, direction::R},
8806
    {0x10b00, 0x10b35, direction::R},   {0x10b39, 0x10b3f, direction::ON},
8807
    {0x10b40, 0x10b55, direction::R},   {0x10b58, 0x10b72, direction::R},
8808
    {0x10b78, 0x10b91, direction::R},   {0x10b99, 0x10b9c, direction::R},
8809
    {0x10ba9, 0x10baf, direction::R},   {0x10c00, 0x10c48, direction::R},
8810
    {0x10c80, 0x10cb2, direction::R},   {0x10cc0, 0x10cf2, direction::R},
8811
    {0x10cfa, 0x10cff, direction::R},   {0x10d00, 0x10d23, direction::AL},
8812
    {0x10d24, 0x10d27, direction::NSM}, {0x10d30, 0x10d39, direction::AN},
8813
    {0x10e60, 0x10e7e, direction::AN},  {0x10e80, 0x10ea9, direction::R},
8814
    {0x10eab, 0x10eac, direction::NSM}, {0x10ead, 0x10ead, direction::R},
8815
    {0x10eb0, 0x10eb1, direction::R},   {0x10f00, 0x10f27, direction::R},
8816
    {0x10f30, 0x10f45, direction::AL},  {0x10f46, 0x10f50, direction::NSM},
8817
    {0x10f51, 0x10f59, direction::AL},  {0x10fb0, 0x10fcb, direction::R},
8818
    {0x10fe0, 0x10ff6, direction::R},   {0x11000, 0x11000, direction::L},
8819
    {0x11001, 0x11001, direction::NSM}, {0x11002, 0x11037, direction::L},
8820
    {0x11038, 0x11046, direction::NSM}, {0x11047, 0x1104d, direction::L},
8821
    {0x11052, 0x11065, direction::ON},  {0x11066, 0x1106f, direction::L},
8822
    {0x1107f, 0x11081, direction::NSM}, {0x11082, 0x110b2, direction::L},
8823
    {0x110b3, 0x110b6, direction::NSM}, {0x110b7, 0x110b8, direction::L},
8824
    {0x110b9, 0x110ba, direction::NSM}, {0x110bb, 0x110c1, direction::L},
8825
    {0x110cd, 0x110cd, direction::L},   {0x110d0, 0x110e8, direction::L},
8826
    {0x110f0, 0x110f9, direction::L},   {0x11100, 0x11102, direction::NSM},
8827
    {0x11103, 0x11126, direction::L},   {0x11127, 0x1112b, direction::NSM},
8828
    {0x1112c, 0x1112c, direction::L},   {0x1112d, 0x11134, direction::NSM},
8829
    {0x11136, 0x11147, direction::L},   {0x11150, 0x11172, direction::L},
8830
    {0x11173, 0x11173, direction::NSM}, {0x11174, 0x11176, direction::L},
8831
    {0x11180, 0x11181, direction::NSM}, {0x11182, 0x111b5, direction::L},
8832
    {0x111b6, 0x111be, direction::NSM}, {0x111bf, 0x111c8, direction::L},
8833
    {0x111c9, 0x111cc, direction::NSM}, {0x111cd, 0x111ce, direction::L},
8834
    {0x111cf, 0x111cf, direction::NSM}, {0x111d0, 0x111df, direction::L},
8835
    {0x111e1, 0x111f4, direction::L},   {0x11200, 0x11211, direction::L},
8836
    {0x11213, 0x1122e, direction::L},   {0x1122f, 0x11231, direction::NSM},
8837
    {0x11232, 0x11233, direction::L},   {0x11234, 0x11234, direction::NSM},
8838
    {0x11235, 0x11235, direction::L},   {0x11236, 0x11237, direction::NSM},
8839
    {0x11238, 0x1123d, direction::L},   {0x1123e, 0x1123e, direction::NSM},
8840
    {0x11280, 0x11286, direction::L},   {0x11288, 0x11288, direction::L},
8841
    {0x1128a, 0x1128d, direction::L},   {0x1128f, 0x1129d, direction::L},
8842
    {0x1129f, 0x112a9, direction::L},   {0x112b0, 0x112de, direction::L},
8843
    {0x112df, 0x112df, direction::NSM}, {0x112e0, 0x112e2, direction::L},
8844
    {0x112e3, 0x112ea, direction::NSM}, {0x112f0, 0x112f9, direction::L},
8845
    {0x11300, 0x11301, direction::NSM}, {0x11302, 0x11303, direction::L},
8846
    {0x11305, 0x1130c, direction::L},   {0x1130f, 0x11310, direction::L},
8847
    {0x11313, 0x11328, direction::L},   {0x1132a, 0x11330, direction::L},
8848
    {0x11332, 0x11333, direction::L},   {0x11335, 0x11339, direction::L},
8849
    {0x1133b, 0x1133c, direction::NSM}, {0x1133d, 0x1133f, direction::L},
8850
    {0x11340, 0x11340, direction::NSM}, {0x11341, 0x11344, direction::L},
8851
    {0x11347, 0x11348, direction::L},   {0x1134b, 0x1134d, direction::L},
8852
    {0x11350, 0x11350, direction::L},   {0x11357, 0x11357, direction::L},
8853
    {0x1135d, 0x11363, direction::L},   {0x11366, 0x1136c, direction::NSM},
8854
    {0x11370, 0x11374, direction::NSM}, {0x11400, 0x11437, direction::L},
8855
    {0x11438, 0x1143f, direction::NSM}, {0x11440, 0x11441, direction::L},
8856
    {0x11442, 0x11444, direction::NSM}, {0x11445, 0x11445, direction::L},
8857
    {0x11446, 0x11446, direction::NSM}, {0x11447, 0x1145b, direction::L},
8858
    {0x1145d, 0x1145d, direction::L},   {0x1145e, 0x1145e, direction::NSM},
8859
    {0x1145f, 0x11461, direction::L},   {0x11480, 0x114b2, direction::L},
8860
    {0x114b3, 0x114b8, direction::NSM}, {0x114b9, 0x114b9, direction::L},
8861
    {0x114ba, 0x114ba, direction::NSM}, {0x114bb, 0x114be, direction::L},
8862
    {0x114bf, 0x114c0, direction::NSM}, {0x114c1, 0x114c1, direction::L},
8863
    {0x114c2, 0x114c3, direction::NSM}, {0x114c4, 0x114c7, direction::L},
8864
    {0x114d0, 0x114d9, direction::L},   {0x11580, 0x115b1, direction::L},
8865
    {0x115b2, 0x115b5, direction::NSM}, {0x115b8, 0x115bb, direction::L},
8866
    {0x115bc, 0x115bd, direction::NSM}, {0x115be, 0x115be, direction::L},
8867
    {0x115bf, 0x115c0, direction::NSM}, {0x115c1, 0x115db, direction::L},
8868
    {0x115dc, 0x115dd, direction::NSM}, {0x11600, 0x11632, direction::L},
8869
    {0x11633, 0x1163a, direction::NSM}, {0x1163b, 0x1163c, direction::L},
8870
    {0x1163d, 0x1163d, direction::NSM}, {0x1163e, 0x1163e, direction::L},
8871
    {0x1163f, 0x11640, direction::NSM}, {0x11641, 0x11644, direction::L},
8872
    {0x11650, 0x11659, direction::L},   {0x11660, 0x1166c, direction::ON},
8873
    {0x11680, 0x116aa, direction::L},   {0x116ab, 0x116ab, direction::NSM},
8874
    {0x116ac, 0x116ac, direction::L},   {0x116ad, 0x116ad, direction::NSM},
8875
    {0x116ae, 0x116af, direction::L},   {0x116b0, 0x116b5, direction::NSM},
8876
    {0x116b6, 0x116b6, direction::L},   {0x116b7, 0x116b7, direction::NSM},
8877
    {0x116b8, 0x116b8, direction::L},   {0x116c0, 0x116c9, direction::L},
8878
    {0x11700, 0x1171a, direction::L},   {0x1171d, 0x1171f, direction::NSM},
8879
    {0x11720, 0x11721, direction::L},   {0x11722, 0x11725, direction::NSM},
8880
    {0x11726, 0x11726, direction::L},   {0x11727, 0x1172b, direction::NSM},
8881
    {0x11730, 0x1173f, direction::L},   {0x11800, 0x1182e, direction::L},
8882
    {0x1182f, 0x11837, direction::NSM}, {0x11838, 0x11838, direction::L},
8883
    {0x11839, 0x1183a, direction::NSM}, {0x1183b, 0x1183b, direction::L},
8884
    {0x118a0, 0x118f2, direction::L},   {0x118ff, 0x11906, direction::L},
8885
    {0x11909, 0x11909, direction::L},   {0x1190c, 0x11913, direction::L},
8886
    {0x11915, 0x11916, direction::L},   {0x11918, 0x11935, direction::L},
8887
    {0x11937, 0x11938, direction::L},   {0x1193b, 0x1193c, direction::NSM},
8888
    {0x1193d, 0x1193d, direction::L},   {0x1193e, 0x1193e, direction::NSM},
8889
    {0x1193f, 0x11942, direction::L},   {0x11943, 0x11943, direction::NSM},
8890
    {0x11944, 0x11946, direction::L},   {0x11950, 0x11959, direction::L},
8891
    {0x119a0, 0x119a7, direction::L},   {0x119aa, 0x119d3, direction::L},
8892
    {0x119d4, 0x119d7, direction::NSM}, {0x119da, 0x119db, direction::NSM},
8893
    {0x119dc, 0x119df, direction::L},   {0x119e0, 0x119e0, direction::NSM},
8894
    {0x119e1, 0x119e4, direction::L},   {0x11a00, 0x11a00, direction::L},
8895
    {0x11a01, 0x11a06, direction::NSM}, {0x11a07, 0x11a08, direction::L},
8896
    {0x11a09, 0x11a0a, direction::NSM}, {0x11a0b, 0x11a32, direction::L},
8897
    {0x11a33, 0x11a38, direction::NSM}, {0x11a39, 0x11a3a, direction::L},
8898
    {0x11a3b, 0x11a3e, direction::NSM}, {0x11a3f, 0x11a46, direction::L},
8899
    {0x11a47, 0x11a47, direction::NSM}, {0x11a50, 0x11a50, direction::L},
8900
    {0x11a51, 0x11a56, direction::NSM}, {0x11a57, 0x11a58, direction::L},
8901
    {0x11a59, 0x11a5b, direction::NSM}, {0x11a5c, 0x11a89, direction::L},
8902
    {0x11a8a, 0x11a96, direction::NSM}, {0x11a97, 0x11a97, direction::L},
8903
    {0x11a98, 0x11a99, direction::NSM}, {0x11a9a, 0x11aa2, direction::L},
8904
    {0x11ac0, 0x11af8, direction::L},   {0x11c00, 0x11c08, direction::L},
8905
    {0x11c0a, 0x11c2f, direction::L},   {0x11c30, 0x11c36, direction::NSM},
8906
    {0x11c38, 0x11c3d, direction::NSM}, {0x11c3e, 0x11c45, direction::L},
8907
    {0x11c50, 0x11c6c, direction::L},   {0x11c70, 0x11c8f, direction::L},
8908
    {0x11c92, 0x11ca7, direction::NSM}, {0x11ca9, 0x11ca9, direction::L},
8909
    {0x11caa, 0x11cb0, direction::NSM}, {0x11cb1, 0x11cb1, direction::L},
8910
    {0x11cb2, 0x11cb3, direction::NSM}, {0x11cb4, 0x11cb4, direction::L},
8911
    {0x11cb5, 0x11cb6, direction::NSM}, {0x11d00, 0x11d06, direction::L},
8912
    {0x11d08, 0x11d09, direction::L},   {0x11d0b, 0x11d30, direction::L},
8913
    {0x11d31, 0x11d36, direction::NSM}, {0x11d3a, 0x11d3a, direction::NSM},
8914
    {0x11d3c, 0x11d3d, direction::NSM}, {0x11d3f, 0x11d45, direction::NSM},
8915
    {0x11d46, 0x11d46, direction::L},   {0x11d47, 0x11d47, direction::NSM},
8916
    {0x11d50, 0x11d59, direction::L},   {0x11d60, 0x11d65, direction::L},
8917
    {0x11d67, 0x11d68, direction::L},   {0x11d6a, 0x11d8e, direction::L},
8918
    {0x11d90, 0x11d91, direction::NSM}, {0x11d93, 0x11d94, direction::L},
8919
    {0x11d95, 0x11d95, direction::NSM}, {0x11d96, 0x11d96, direction::L},
8920
    {0x11d97, 0x11d97, direction::NSM}, {0x11d98, 0x11d98, direction::L},
8921
    {0x11da0, 0x11da9, direction::L},   {0x11ee0, 0x11ef2, direction::L},
8922
    {0x11ef3, 0x11ef4, direction::NSM}, {0x11ef5, 0x11ef8, direction::L},
8923
    {0x11fb0, 0x11fb0, direction::L},   {0x11fc0, 0x11fd4, direction::L},
8924
    {0x11fd5, 0x11fdc, direction::ON},  {0x11fdd, 0x11fe0, direction::ET},
8925
    {0x11fe1, 0x11ff1, direction::ON},  {0x11fff, 0x12399, direction::L},
8926
    {0x12400, 0x1246e, direction::L},   {0x12470, 0x12474, direction::L},
8927
    {0x12480, 0x12543, direction::L},   {0x13000, 0x1342e, direction::L},
8928
    {0x13430, 0x13438, direction::L},   {0x14400, 0x14646, direction::L},
8929
    {0x16800, 0x16a38, direction::L},   {0x16a40, 0x16a5e, direction::L},
8930
    {0x16a60, 0x16a69, direction::L},   {0x16a6e, 0x16a6f, direction::L},
8931
    {0x16ad0, 0x16aed, direction::L},   {0x16af0, 0x16af4, direction::NSM},
8932
    {0x16af5, 0x16af5, direction::L},   {0x16b00, 0x16b2f, direction::L},
8933
    {0x16b30, 0x16b36, direction::NSM}, {0x16b37, 0x16b45, direction::L},
8934
    {0x16b50, 0x16b59, direction::L},   {0x16b5b, 0x16b61, direction::L},
8935
    {0x16b63, 0x16b77, direction::L},   {0x16b7d, 0x16b8f, direction::L},
8936
    {0x16e40, 0x16e9a, direction::L},   {0x16f00, 0x16f4a, direction::L},
8937
    {0x16f4f, 0x16f4f, direction::NSM}, {0x16f50, 0x16f87, direction::L},
8938
    {0x16f8f, 0x16f92, direction::NSM}, {0x16f93, 0x16f9f, direction::L},
8939
    {0x16fe0, 0x16fe1, direction::L},   {0x16fe2, 0x16fe2, direction::ON},
8940
    {0x16fe3, 0x16fe3, direction::L},   {0x16fe4, 0x16fe4, direction::NSM},
8941
    {0x16ff0, 0x16ff1, direction::L},   {0x17000, 0x187f7, direction::L},
8942
    {0x18800, 0x18cd5, direction::L},   {0x18d00, 0x18d08, direction::L},
8943
    {0x1b000, 0x1b11e, direction::L},   {0x1b150, 0x1b152, direction::L},
8944
    {0x1b164, 0x1b167, direction::L},   {0x1b170, 0x1b2fb, direction::L},
8945
    {0x1bc00, 0x1bc6a, direction::L},   {0x1bc70, 0x1bc7c, direction::L},
8946
    {0x1bc80, 0x1bc88, direction::L},   {0x1bc90, 0x1bc99, direction::L},
8947
    {0x1bc9c, 0x1bc9c, direction::L},   {0x1bc9d, 0x1bc9e, direction::NSM},
8948
    {0x1bc9f, 0x1bc9f, direction::L},   {0x1bca0, 0x1bca3, direction::BN},
8949
    {0x1d000, 0x1d0f5, direction::L},   {0x1d100, 0x1d126, direction::L},
8950
    {0x1d129, 0x1d166, direction::L},   {0x1d167, 0x1d169, direction::NSM},
8951
    {0x1d16a, 0x1d172, direction::L},   {0x1d173, 0x1d17a, direction::BN},
8952
    {0x1d17b, 0x1d182, direction::NSM}, {0x1d183, 0x1d184, direction::L},
8953
    {0x1d185, 0x1d18b, direction::NSM}, {0x1d18c, 0x1d1a9, direction::L},
8954
    {0x1d1aa, 0x1d1ad, direction::NSM}, {0x1d1ae, 0x1d1e8, direction::L},
8955
    {0x1d200, 0x1d241, direction::ON},  {0x1d242, 0x1d244, direction::NSM},
8956
    {0x1d245, 0x1d245, direction::ON},  {0x1d2e0, 0x1d2f3, direction::L},
8957
    {0x1d300, 0x1d356, direction::ON},  {0x1d360, 0x1d378, direction::L},
8958
    {0x1d400, 0x1d454, direction::L},   {0x1d456, 0x1d49c, direction::L},
8959
    {0x1d49e, 0x1d49f, direction::L},   {0x1d4a2, 0x1d4a2, direction::L},
8960
    {0x1d4a5, 0x1d4a6, direction::L},   {0x1d4a9, 0x1d4ac, direction::L},
8961
    {0x1d4ae, 0x1d4b9, direction::L},   {0x1d4bb, 0x1d4bb, direction::L},
8962
    {0x1d4bd, 0x1d4c3, direction::L},   {0x1d4c5, 0x1d505, direction::L},
8963
    {0x1d507, 0x1d50a, direction::L},   {0x1d50d, 0x1d514, direction::L},
8964
    {0x1d516, 0x1d51c, direction::L},   {0x1d51e, 0x1d539, direction::L},
8965
    {0x1d53b, 0x1d53e, direction::L},   {0x1d540, 0x1d544, direction::L},
8966
    {0x1d546, 0x1d546, direction::L},   {0x1d54a, 0x1d550, direction::L},
8967
    {0x1d552, 0x1d6a5, direction::L},   {0x1d6a8, 0x1d6da, direction::L},
8968
    {0x1d6db, 0x1d6db, direction::ON},  {0x1d6dc, 0x1d714, direction::L},
8969
    {0x1d715, 0x1d715, direction::ON},  {0x1d716, 0x1d74e, direction::L},
8970
    {0x1d74f, 0x1d74f, direction::ON},  {0x1d750, 0x1d788, direction::L},
8971
    {0x1d789, 0x1d789, direction::ON},  {0x1d78a, 0x1d7c2, direction::L},
8972
    {0x1d7c3, 0x1d7c3, direction::ON},  {0x1d7c4, 0x1d7cb, direction::L},
8973
    {0x1d7ce, 0x1d7ff, direction::EN},  {0x1d800, 0x1d9ff, direction::L},
8974
    {0x1da00, 0x1da36, direction::NSM}, {0x1da37, 0x1da3a, direction::L},
8975
    {0x1da3b, 0x1da6c, direction::NSM}, {0x1da6d, 0x1da74, direction::L},
8976
    {0x1da75, 0x1da75, direction::NSM}, {0x1da76, 0x1da83, direction::L},
8977
    {0x1da84, 0x1da84, direction::NSM}, {0x1da85, 0x1da8b, direction::L},
8978
    {0x1da9b, 0x1da9f, direction::NSM}, {0x1daa1, 0x1daaf, direction::NSM},
8979
    {0x1e000, 0x1e006, direction::NSM}, {0x1e008, 0x1e018, direction::NSM},
8980
    {0x1e01b, 0x1e021, direction::NSM}, {0x1e023, 0x1e024, direction::NSM},
8981
    {0x1e026, 0x1e02a, direction::NSM}, {0x1e100, 0x1e12c, direction::L},
8982
    {0x1e130, 0x1e136, direction::NSM}, {0x1e137, 0x1e13d, direction::L},
8983
    {0x1e140, 0x1e149, direction::L},   {0x1e14e, 0x1e14f, direction::L},
8984
    {0x1e2c0, 0x1e2eb, direction::L},   {0x1e2ec, 0x1e2ef, direction::NSM},
8985
    {0x1e2f0, 0x1e2f9, direction::L},   {0x1e2ff, 0x1e2ff, direction::ET},
8986
    {0x1e800, 0x1e8c4, direction::R},   {0x1e8c7, 0x1e8cf, direction::R},
8987
    {0x1e8d0, 0x1e8d6, direction::NSM}, {0x1e900, 0x1e943, direction::R},
8988
    {0x1e944, 0x1e94a, direction::NSM}, {0x1e94b, 0x1e94b, direction::R},
8989
    {0x1e950, 0x1e959, direction::R},   {0x1e95e, 0x1e95f, direction::R},
8990
    {0x1ec71, 0x1ecb4, direction::AL},  {0x1ed01, 0x1ed3d, direction::AL},
8991
    {0x1ee00, 0x1ee03, direction::AL},  {0x1ee05, 0x1ee1f, direction::AL},
8992
    {0x1ee21, 0x1ee22, direction::AL},  {0x1ee24, 0x1ee24, direction::AL},
8993
    {0x1ee27, 0x1ee27, direction::AL},  {0x1ee29, 0x1ee32, direction::AL},
8994
    {0x1ee34, 0x1ee37, direction::AL},  {0x1ee39, 0x1ee39, direction::AL},
8995
    {0x1ee3b, 0x1ee3b, direction::AL},  {0x1ee42, 0x1ee42, direction::AL},
8996
    {0x1ee47, 0x1ee47, direction::AL},  {0x1ee49, 0x1ee49, direction::AL},
8997
    {0x1ee4b, 0x1ee4b, direction::AL},  {0x1ee4d, 0x1ee4f, direction::AL},
8998
    {0x1ee51, 0x1ee52, direction::AL},  {0x1ee54, 0x1ee54, direction::AL},
8999
    {0x1ee57, 0x1ee57, direction::AL},  {0x1ee59, 0x1ee59, direction::AL},
9000
    {0x1ee5b, 0x1ee5b, direction::AL},  {0x1ee5d, 0x1ee5d, direction::AL},
9001
    {0x1ee5f, 0x1ee5f, direction::AL},  {0x1ee61, 0x1ee62, direction::AL},
9002
    {0x1ee64, 0x1ee64, direction::AL},  {0x1ee67, 0x1ee6a, direction::AL},
9003
    {0x1ee6c, 0x1ee72, direction::AL},  {0x1ee74, 0x1ee77, direction::AL},
9004
    {0x1ee79, 0x1ee7c, direction::AL},  {0x1ee7e, 0x1ee7e, direction::AL},
9005
    {0x1ee80, 0x1ee89, direction::AL},  {0x1ee8b, 0x1ee9b, direction::AL},
9006
    {0x1eea1, 0x1eea3, direction::AL},  {0x1eea5, 0x1eea9, direction::AL},
9007
    {0x1eeab, 0x1eebb, direction::AL},  {0x1eef0, 0x1eef1, direction::ON},
9008
    {0x1f000, 0x1f02b, direction::ON},  {0x1f030, 0x1f093, direction::ON},
9009
    {0x1f0a0, 0x1f0ae, direction::ON},  {0x1f0b1, 0x1f0bf, direction::ON},
9010
    {0x1f0c1, 0x1f0cf, direction::ON},  {0x1f0d1, 0x1f0f5, direction::ON},
9011
    {0x1f100, 0x1f10a, direction::EN},  {0x1f10b, 0x1f10f, direction::ON},
9012
    {0x1f110, 0x1f12e, direction::L},   {0x1f12f, 0x1f12f, direction::ON},
9013
    {0x1f130, 0x1f169, direction::L},   {0x1f16a, 0x1f16f, direction::ON},
9014
    {0x1f170, 0x1f1ac, direction::L},   {0x1f1ad, 0x1f1ad, direction::ON},
9015
    {0x1f1e6, 0x1f202, direction::L},   {0x1f210, 0x1f23b, direction::L},
9016
    {0x1f240, 0x1f248, direction::L},   {0x1f250, 0x1f251, direction::L},
9017
    {0x1f260, 0x1f265, direction::ON},  {0x1f300, 0x1f6d7, direction::ON},
9018
    {0x1f6e0, 0x1f6ec, direction::ON},  {0x1f6f0, 0x1f6fc, direction::ON},
9019
    {0x1f700, 0x1f773, direction::ON},  {0x1f780, 0x1f7d8, direction::ON},
9020
    {0x1f7e0, 0x1f7eb, direction::ON},  {0x1f800, 0x1f80b, direction::ON},
9021
    {0x1f810, 0x1f847, direction::ON},  {0x1f850, 0x1f859, direction::ON},
9022
    {0x1f860, 0x1f887, direction::ON},  {0x1f890, 0x1f8ad, direction::ON},
9023
    {0x1f8b0, 0x1f8b1, direction::ON},  {0x1f900, 0x1f978, direction::ON},
9024
    {0x1f97a, 0x1f9cb, direction::ON},  {0x1f9cd, 0x1fa53, direction::ON},
9025
    {0x1fa60, 0x1fa6d, direction::ON},  {0x1fa70, 0x1fa74, direction::ON},
9026
    {0x1fa78, 0x1fa7a, direction::ON},  {0x1fa80, 0x1fa86, direction::ON},
9027
    {0x1fa90, 0x1faa8, direction::ON},  {0x1fab0, 0x1fab6, direction::ON},
9028
    {0x1fac0, 0x1fac2, direction::ON},  {0x1fad0, 0x1fad6, direction::ON},
9029
    {0x1fb00, 0x1fb92, direction::ON},  {0x1fb94, 0x1fbca, direction::ON},
9030
    {0x1fbf0, 0x1fbf9, direction::EN},  {0x20000, 0x2a6dd, direction::L},
9031
    {0x2a700, 0x2b734, direction::L},   {0x2b740, 0x2b81d, direction::L},
9032
    {0x2b820, 0x2cea1, direction::L},   {0x2ceb0, 0x2ebe0, direction::L},
9033
    {0x2f800, 0x2fa1d, direction::L},   {0x30000, 0x3134a, direction::L},
9034
    {0xe0001, 0xe0001, direction::BN},  {0xe0020, 0xe007f, direction::BN},
9035
    {0xe0100, 0xe01ef, direction::NSM}, {0xf0000, 0xffffd, direction::L},
9036
    {0x100000, 0x10fffd, direction::L}};
9037
9038
// CheckJoiners and CheckBidi are true for URL specification.
9039
9040
382k
inline static direction find_direction(uint32_t code_point) noexcept {
9041
382k
  const auto it = std::ranges::lower_bound(
9042
382k
      dir_table, code_point, {},
9043
382k
      &directions::final_code);  // project to the upper bound of each range
9044
9045
  // Safety check - almost always false, but cheap.
9046
382k
  if (it == std::ranges::end(dir_table)) {
9047
0
    return direction::NONE;
9048
0
  }
9049
9050
  // Invariant: it->final_code >= code_point. Confirm it's also in range.
9051
382k
  return code_point >= it->start_code ? it->direct : direction::NONE;
9052
382k
}
9053
9054
inline static size_t find_last_not_of_nsm(
9055
56.9k
    const std::u32string_view label) noexcept {
9056
62.0k
  for (int i = static_cast<int>(label.size() - 1); i >= 0; i--)
9057
62.0k
    if (find_direction(label[i]) != direction::NSM) return i;
9058
9059
0
  return std::u32string_view::npos;
9060
56.9k
}
9061
9062
// An RTL label is a label that contains at least one character of type R, AL,
9063
// or AN. https://www.rfc-editor.org/rfc/rfc5893#section-2
9064
56.9k
inline static bool is_rtl_label(const std::u32string_view label) noexcept {
9065
56.9k
  const size_t mask =
9066
56.9k
      (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN);
9067
9068
56.9k
  size_t directions = 0;
9069
290k
  for (size_t i = 0; i < label.size(); i++) {
9070
233k
    directions |= 1u << find_direction(label[i]);
9071
233k
  }
9072
56.9k
  return (directions & mask) != 0;
9073
56.9k
}
9074
9075
65.1k
bool is_label_valid(const std::u32string_view label) {
9076
65.1k
  if (label.empty()) {
9077
0
    return true;
9078
0
  }
9079
9080
  ///////////////
9081
  // We have a normalization step which ensures that we are in NFC.
9082
  // If we receive punycode, we normalize and check that the normalized
9083
  // version matches the original.
9084
  // --------------------------------------
9085
  // The label must be in Unicode Normalization Form NFC.
9086
9087
  // Current URL standard indicatest that CheckHyphens is set to false.
9088
  // ---------------------------------------
9089
  // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
9090
  // in both the third and fourth positions. If CheckHyphens, the label must
9091
  // neither begin nor end with a U+002D HYPHEN-MINUS character.
9092
9093
  // This is not necessary because we segment the
9094
  // labels by '.'.
9095
  // ---------------------------------------
9096
  // The label must not contain a U+002E ( . ) FULL STOP.
9097
  // if (label.find('.') != std::string_view::npos) return false;
9098
9099
  // The label must not begin with a combining mark, that is:
9100
  // General_Category=Mark.
9101
65.1k
  constexpr static uint32_t combining[] = {
9102
65.1k
      0x300,   0x301,   0x302,   0x303,   0x304,   0x305,   0x306,   0x307,
9103
65.1k
      0x308,   0x309,   0x30a,   0x30b,   0x30c,   0x30d,   0x30e,   0x30f,
9104
65.1k
      0x310,   0x311,   0x312,   0x313,   0x314,   0x315,   0x316,   0x317,
9105
65.1k
      0x318,   0x319,   0x31a,   0x31b,   0x31c,   0x31d,   0x31e,   0x31f,
9106
65.1k
      0x320,   0x321,   0x322,   0x323,   0x324,   0x325,   0x326,   0x327,
9107
65.1k
      0x328,   0x329,   0x32a,   0x32b,   0x32c,   0x32d,   0x32e,   0x32f,
9108
65.1k
      0x330,   0x331,   0x332,   0x333,   0x334,   0x335,   0x336,   0x337,
9109
65.1k
      0x338,   0x339,   0x33a,   0x33b,   0x33c,   0x33d,   0x33e,   0x33f,
9110
65.1k
      0x340,   0x341,   0x342,   0x343,   0x344,   0x345,   0x346,   0x347,
9111
65.1k
      0x348,   0x349,   0x34a,   0x34b,   0x34c,   0x34d,   0x34e,   0x34f,
9112
65.1k
      0x350,   0x351,   0x352,   0x353,   0x354,   0x355,   0x356,   0x357,
9113
65.1k
      0x358,   0x359,   0x35a,   0x35b,   0x35c,   0x35d,   0x35e,   0x35f,
9114
65.1k
      0x360,   0x361,   0x362,   0x363,   0x364,   0x365,   0x366,   0x367,
9115
65.1k
      0x368,   0x369,   0x36a,   0x36b,   0x36c,   0x36d,   0x36e,   0x36f,
9116
65.1k
      0x483,   0x484,   0x485,   0x486,   0x487,   0x488,   0x489,   0x591,
9117
65.1k
      0x592,   0x593,   0x594,   0x595,   0x596,   0x597,   0x598,   0x599,
9118
65.1k
      0x59a,   0x59b,   0x59c,   0x59d,   0x59e,   0x59f,   0x5a0,   0x5a1,
9119
65.1k
      0x5a2,   0x5a3,   0x5a4,   0x5a5,   0x5a6,   0x5a7,   0x5a8,   0x5a9,
9120
65.1k
      0x5aa,   0x5ab,   0x5ac,   0x5ad,   0x5ae,   0x5af,   0x5b0,   0x5b1,
9121
65.1k
      0x5b2,   0x5b3,   0x5b4,   0x5b5,   0x5b6,   0x5b7,   0x5b8,   0x5b9,
9122
65.1k
      0x5ba,   0x5bb,   0x5bc,   0x5bd,   0x5bf,   0x5c1,   0x5c2,   0x5c4,
9123
65.1k
      0x5c5,   0x5c7,   0x610,   0x611,   0x612,   0x613,   0x614,   0x615,
9124
65.1k
      0x616,   0x617,   0x618,   0x619,   0x61a,   0x64b,   0x64c,   0x64d,
9125
65.1k
      0x64e,   0x64f,   0x650,   0x651,   0x652,   0x653,   0x654,   0x655,
9126
65.1k
      0x656,   0x657,   0x658,   0x659,   0x65a,   0x65b,   0x65c,   0x65d,
9127
65.1k
      0x65e,   0x65f,   0x670,   0x6d6,   0x6d7,   0x6d8,   0x6d9,   0x6da,
9128
65.1k
      0x6db,   0x6dc,   0x6df,   0x6e0,   0x6e1,   0x6e2,   0x6e3,   0x6e4,
9129
65.1k
      0x6e7,   0x6e8,   0x6ea,   0x6eb,   0x6ec,   0x6ed,   0x711,   0x730,
9130
65.1k
      0x731,   0x732,   0x733,   0x734,   0x735,   0x736,   0x737,   0x738,
9131
65.1k
      0x739,   0x73a,   0x73b,   0x73c,   0x73d,   0x73e,   0x73f,   0x740,
9132
65.1k
      0x741,   0x742,   0x743,   0x744,   0x745,   0x746,   0x747,   0x748,
9133
65.1k
      0x749,   0x74a,   0x7a6,   0x7a7,   0x7a8,   0x7a9,   0x7aa,   0x7ab,
9134
65.1k
      0x7ac,   0x7ad,   0x7ae,   0x7af,   0x7b0,   0x7eb,   0x7ec,   0x7ed,
9135
65.1k
      0x7ee,   0x7ef,   0x7f0,   0x7f1,   0x7f2,   0x7f3,   0x7fd,   0x816,
9136
65.1k
      0x817,   0x818,   0x819,   0x81b,   0x81c,   0x81d,   0x81e,   0x81f,
9137
65.1k
      0x820,   0x821,   0x822,   0x823,   0x825,   0x826,   0x827,   0x829,
9138
65.1k
      0x82a,   0x82b,   0x82c,   0x82d,   0x859,   0x85a,   0x85b,   0x8d3,
9139
65.1k
      0x8d4,   0x8d5,   0x8d6,   0x8d7,   0x8d8,   0x8d9,   0x8da,   0x8db,
9140
65.1k
      0x8dc,   0x8dd,   0x8de,   0x8df,   0x8e0,   0x8e1,   0x8e3,   0x8e4,
9141
65.1k
      0x8e5,   0x8e6,   0x8e7,   0x8e8,   0x8e9,   0x8ea,   0x8eb,   0x8ec,
9142
65.1k
      0x8ed,   0x8ee,   0x8ef,   0x8f0,   0x8f1,   0x8f2,   0x8f3,   0x8f4,
9143
65.1k
      0x8f5,   0x8f6,   0x8f7,   0x8f8,   0x8f9,   0x8fa,   0x8fb,   0x8fc,
9144
65.1k
      0x8fd,   0x8fe,   0x8ff,   0x900,   0x901,   0x902,   0x903,   0x93a,
9145
65.1k
      0x93b,   0x93c,   0x93e,   0x93f,   0x940,   0x941,   0x942,   0x943,
9146
65.1k
      0x944,   0x945,   0x946,   0x947,   0x948,   0x949,   0x94a,   0x94b,
9147
65.1k
      0x94c,   0x94d,   0x94e,   0x94f,   0x951,   0x952,   0x953,   0x954,
9148
65.1k
      0x955,   0x956,   0x957,   0x962,   0x963,   0x981,   0x982,   0x983,
9149
65.1k
      0x9bc,   0x9be,   0x9bf,   0x9c0,   0x9c1,   0x9c2,   0x9c3,   0x9c4,
9150
65.1k
      0x9c7,   0x9c8,   0x9cb,   0x9cc,   0x9cd,   0x9d7,   0x9e2,   0x9e3,
9151
65.1k
      0x9fe,   0xa01,   0xa02,   0xa03,   0xa3c,   0xa3e,   0xa3f,   0xa40,
9152
65.1k
      0xa41,   0xa42,   0xa47,   0xa48,   0xa4b,   0xa4c,   0xa4d,   0xa51,
9153
65.1k
      0xa70,   0xa71,   0xa75,   0xa81,   0xa82,   0xa83,   0xabc,   0xabe,
9154
65.1k
      0xabf,   0xac0,   0xac1,   0xac2,   0xac3,   0xac4,   0xac5,   0xac7,
9155
65.1k
      0xac8,   0xac9,   0xacb,   0xacc,   0xacd,   0xae2,   0xae3,   0xafa,
9156
65.1k
      0xafb,   0xafc,   0xafd,   0xafe,   0xaff,   0xb01,   0xb02,   0xb03,
9157
65.1k
      0xb3c,   0xb3e,   0xb3f,   0xb40,   0xb41,   0xb42,   0xb43,   0xb44,
9158
65.1k
      0xb47,   0xb48,   0xb4b,   0xb4c,   0xb4d,   0xb55,   0xb56,   0xb57,
9159
65.1k
      0xb62,   0xb63,   0xb82,   0xbbe,   0xbbf,   0xbc0,   0xbc1,   0xbc2,
9160
65.1k
      0xbc6,   0xbc7,   0xbc8,   0xbca,   0xbcb,   0xbcc,   0xbcd,   0xbd7,
9161
65.1k
      0xc00,   0xc01,   0xc02,   0xc03,   0xc04,   0xc3e,   0xc3f,   0xc40,
9162
65.1k
      0xc41,   0xc42,   0xc43,   0xc44,   0xc46,   0xc47,   0xc48,   0xc4a,
9163
65.1k
      0xc4b,   0xc4c,   0xc4d,   0xc55,   0xc56,   0xc62,   0xc63,   0xc81,
9164
65.1k
      0xc82,   0xc83,   0xcbc,   0xcbe,   0xcbf,   0xcc0,   0xcc1,   0xcc2,
9165
65.1k
      0xcc3,   0xcc4,   0xcc6,   0xcc7,   0xcc8,   0xcca,   0xccb,   0xccc,
9166
65.1k
      0xccd,   0xcd5,   0xcd6,   0xce2,   0xce3,   0xd00,   0xd01,   0xd02,
9167
65.1k
      0xd03,   0xd3b,   0xd3c,   0xd3e,   0xd3f,   0xd40,   0xd41,   0xd42,
9168
65.1k
      0xd43,   0xd44,   0xd46,   0xd47,   0xd48,   0xd4a,   0xd4b,   0xd4c,
9169
65.1k
      0xd4d,   0xd57,   0xd62,   0xd63,   0xd81,   0xd82,   0xd83,   0xdca,
9170
65.1k
      0xdcf,   0xdd0,   0xdd1,   0xdd2,   0xdd3,   0xdd4,   0xdd6,   0xdd8,
9171
65.1k
      0xdd9,   0xdda,   0xddb,   0xddc,   0xddd,   0xdde,   0xddf,   0xdf2,
9172
65.1k
      0xdf3,   0xe31,   0xe34,   0xe35,   0xe36,   0xe37,   0xe38,   0xe39,
9173
65.1k
      0xe3a,   0xe47,   0xe48,   0xe49,   0xe4a,   0xe4b,   0xe4c,   0xe4d,
9174
65.1k
      0xe4e,   0xeb1,   0xeb4,   0xeb5,   0xeb6,   0xeb7,   0xeb8,   0xeb9,
9175
65.1k
      0xeba,   0xebb,   0xebc,   0xec8,   0xec9,   0xeca,   0xecb,   0xecc,
9176
65.1k
      0xecd,   0xf18,   0xf19,   0xf35,   0xf37,   0xf39,   0xf3e,   0xf3f,
9177
65.1k
      0xf71,   0xf72,   0xf73,   0xf74,   0xf75,   0xf76,   0xf77,   0xf78,
9178
65.1k
      0xf79,   0xf7a,   0xf7b,   0xf7c,   0xf7d,   0xf7e,   0xf7f,   0xf80,
9179
65.1k
      0xf81,   0xf82,   0xf83,   0xf84,   0xf86,   0xf87,   0xf8d,   0xf8e,
9180
65.1k
      0xf8f,   0xf90,   0xf91,   0xf92,   0xf93,   0xf94,   0xf95,   0xf96,
9181
65.1k
      0xf97,   0xf99,   0xf9a,   0xf9b,   0xf9c,   0xf9d,   0xf9e,   0xf9f,
9182
65.1k
      0xfa0,   0xfa1,   0xfa2,   0xfa3,   0xfa4,   0xfa5,   0xfa6,   0xfa7,
9183
65.1k
      0xfa8,   0xfa9,   0xfaa,   0xfab,   0xfac,   0xfad,   0xfae,   0xfaf,
9184
65.1k
      0xfb0,   0xfb1,   0xfb2,   0xfb3,   0xfb4,   0xfb5,   0xfb6,   0xfb7,
9185
65.1k
      0xfb8,   0xfb9,   0xfba,   0xfbb,   0xfbc,   0xfc6,   0x102b,  0x102c,
9186
65.1k
      0x102d,  0x102e,  0x102f,  0x1030,  0x1031,  0x1032,  0x1033,  0x1034,
9187
65.1k
      0x1035,  0x1036,  0x1037,  0x1038,  0x1039,  0x103a,  0x103b,  0x103c,
9188
65.1k
      0x103d,  0x103e,  0x1056,  0x1057,  0x1058,  0x1059,  0x105e,  0x105f,
9189
65.1k
      0x1060,  0x1062,  0x1063,  0x1064,  0x1067,  0x1068,  0x1069,  0x106a,
9190
65.1k
      0x106b,  0x106c,  0x106d,  0x1071,  0x1072,  0x1073,  0x1074,  0x1082,
9191
65.1k
      0x1083,  0x1084,  0x1085,  0x1086,  0x1087,  0x1088,  0x1089,  0x108a,
9192
65.1k
      0x108b,  0x108c,  0x108d,  0x108f,  0x109a,  0x109b,  0x109c,  0x109d,
9193
65.1k
      0x135d,  0x135e,  0x135f,  0x1712,  0x1713,  0x1714,  0x1732,  0x1733,
9194
65.1k
      0x1734,  0x1752,  0x1753,  0x1772,  0x1773,  0x17b4,  0x17b5,  0x17b6,
9195
65.1k
      0x17b7,  0x17b8,  0x17b9,  0x17ba,  0x17bb,  0x17bc,  0x17bd,  0x17be,
9196
65.1k
      0x17bf,  0x17c0,  0x17c1,  0x17c2,  0x17c3,  0x17c4,  0x17c5,  0x17c6,
9197
65.1k
      0x17c7,  0x17c8,  0x17c9,  0x17ca,  0x17cb,  0x17cc,  0x17cd,  0x17ce,
9198
65.1k
      0x17cf,  0x17d0,  0x17d1,  0x17d2,  0x17d3,  0x17dd,  0x180b,  0x180c,
9199
65.1k
      0x180d,  0x1885,  0x1886,  0x18a9,  0x1920,  0x1921,  0x1922,  0x1923,
9200
65.1k
      0x1924,  0x1925,  0x1926,  0x1927,  0x1928,  0x1929,  0x192a,  0x192b,
9201
65.1k
      0x1930,  0x1931,  0x1932,  0x1933,  0x1934,  0x1935,  0x1936,  0x1937,
9202
65.1k
      0x1938,  0x1939,  0x193a,  0x193b,  0x1a17,  0x1a18,  0x1a19,  0x1a1a,
9203
65.1k
      0x1a1b,  0x1a55,  0x1a56,  0x1a57,  0x1a58,  0x1a59,  0x1a5a,  0x1a5b,
9204
65.1k
      0x1a5c,  0x1a5d,  0x1a5e,  0x1a60,  0x1a61,  0x1a62,  0x1a63,  0x1a64,
9205
65.1k
      0x1a65,  0x1a66,  0x1a67,  0x1a68,  0x1a69,  0x1a6a,  0x1a6b,  0x1a6c,
9206
65.1k
      0x1a6d,  0x1a6e,  0x1a6f,  0x1a70,  0x1a71,  0x1a72,  0x1a73,  0x1a74,
9207
65.1k
      0x1a75,  0x1a76,  0x1a77,  0x1a78,  0x1a79,  0x1a7a,  0x1a7b,  0x1a7c,
9208
65.1k
      0x1a7f,  0x1ab0,  0x1ab1,  0x1ab2,  0x1ab3,  0x1ab4,  0x1ab5,  0x1ab6,
9209
65.1k
      0x1ab7,  0x1ab8,  0x1ab9,  0x1aba,  0x1abb,  0x1abc,  0x1abd,  0x1abe,
9210
65.1k
      0x1abf,  0x1ac0,  0x1b00,  0x1b01,  0x1b02,  0x1b03,  0x1b04,  0x1b34,
9211
65.1k
      0x1b35,  0x1b36,  0x1b37,  0x1b38,  0x1b39,  0x1b3a,  0x1b3b,  0x1b3c,
9212
65.1k
      0x1b3d,  0x1b3e,  0x1b3f,  0x1b40,  0x1b41,  0x1b42,  0x1b43,  0x1b44,
9213
65.1k
      0x1b6b,  0x1b6c,  0x1b6d,  0x1b6e,  0x1b6f,  0x1b70,  0x1b71,  0x1b72,
9214
65.1k
      0x1b73,  0x1b80,  0x1b81,  0x1b82,  0x1ba1,  0x1ba2,  0x1ba3,  0x1ba4,
9215
65.1k
      0x1ba5,  0x1ba6,  0x1ba7,  0x1ba8,  0x1ba9,  0x1baa,  0x1bab,  0x1bac,
9216
65.1k
      0x1bad,  0x1be6,  0x1be7,  0x1be8,  0x1be9,  0x1bea,  0x1beb,  0x1bec,
9217
65.1k
      0x1bed,  0x1bee,  0x1bef,  0x1bf0,  0x1bf1,  0x1bf2,  0x1bf3,  0x1c24,
9218
65.1k
      0x1c25,  0x1c26,  0x1c27,  0x1c28,  0x1c29,  0x1c2a,  0x1c2b,  0x1c2c,
9219
65.1k
      0x1c2d,  0x1c2e,  0x1c2f,  0x1c30,  0x1c31,  0x1c32,  0x1c33,  0x1c34,
9220
65.1k
      0x1c35,  0x1c36,  0x1c37,  0x1cd0,  0x1cd1,  0x1cd2,  0x1cd4,  0x1cd5,
9221
65.1k
      0x1cd6,  0x1cd7,  0x1cd8,  0x1cd9,  0x1cda,  0x1cdb,  0x1cdc,  0x1cdd,
9222
65.1k
      0x1cde,  0x1cdf,  0x1ce0,  0x1ce1,  0x1ce2,  0x1ce3,  0x1ce4,  0x1ce5,
9223
65.1k
      0x1ce6,  0x1ce7,  0x1ce8,  0x1ced,  0x1cf4,  0x1cf7,  0x1cf8,  0x1cf9,
9224
65.1k
      0x1dc0,  0x1dc1,  0x1dc2,  0x1dc3,  0x1dc4,  0x1dc5,  0x1dc6,  0x1dc7,
9225
65.1k
      0x1dc8,  0x1dc9,  0x1dca,  0x1dcb,  0x1dcc,  0x1dcd,  0x1dce,  0x1dcf,
9226
65.1k
      0x1dd0,  0x1dd1,  0x1dd2,  0x1dd3,  0x1dd4,  0x1dd5,  0x1dd6,  0x1dd7,
9227
65.1k
      0x1dd8,  0x1dd9,  0x1dda,  0x1ddb,  0x1ddc,  0x1ddd,  0x1dde,  0x1ddf,
9228
65.1k
      0x1de0,  0x1de1,  0x1de2,  0x1de3,  0x1de4,  0x1de5,  0x1de6,  0x1de7,
9229
65.1k
      0x1de8,  0x1de9,  0x1dea,  0x1deb,  0x1dec,  0x1ded,  0x1dee,  0x1def,
9230
65.1k
      0x1df0,  0x1df1,  0x1df2,  0x1df3,  0x1df4,  0x1df5,  0x1df6,  0x1df7,
9231
65.1k
      0x1df8,  0x1df9,  0x1dfb,  0x1dfc,  0x1dfd,  0x1dfe,  0x1dff,  0x20d0,
9232
65.1k
      0x20d1,  0x20d2,  0x20d3,  0x20d4,  0x20d5,  0x20d6,  0x20d7,  0x20d8,
9233
65.1k
      0x20d9,  0x20da,  0x20db,  0x20dc,  0x20dd,  0x20de,  0x20df,  0x20e0,
9234
65.1k
      0x20e1,  0x20e2,  0x20e3,  0x20e4,  0x20e5,  0x20e6,  0x20e7,  0x20e8,
9235
65.1k
      0x20e9,  0x20ea,  0x20eb,  0x20ec,  0x20ed,  0x20ee,  0x20ef,  0x20f0,
9236
65.1k
      0x2cef,  0x2cf0,  0x2cf1,  0x2d7f,  0x2de0,  0x2de1,  0x2de2,  0x2de3,
9237
65.1k
      0x2de4,  0x2de5,  0x2de6,  0x2de7,  0x2de8,  0x2de9,  0x2dea,  0x2deb,
9238
65.1k
      0x2dec,  0x2ded,  0x2dee,  0x2def,  0x2df0,  0x2df1,  0x2df2,  0x2df3,
9239
65.1k
      0x2df4,  0x2df5,  0x2df6,  0x2df7,  0x2df8,  0x2df9,  0x2dfa,  0x2dfb,
9240
65.1k
      0x2dfc,  0x2dfd,  0x2dfe,  0x2dff,  0x302a,  0x302b,  0x302c,  0x302d,
9241
65.1k
      0x302e,  0x302f,  0x3099,  0x309a,  0xa66f,  0xa670,  0xa671,  0xa672,
9242
65.1k
      0xa674,  0xa675,  0xa676,  0xa677,  0xa678,  0xa679,  0xa67a,  0xa67b,
9243
65.1k
      0xa67c,  0xa67d,  0xa69e,  0xa69f,  0xa6f0,  0xa6f1,  0xa802,  0xa806,
9244
65.1k
      0xa80b,  0xa823,  0xa824,  0xa825,  0xa826,  0xa827,  0xa82c,  0xa880,
9245
65.1k
      0xa881,  0xa8b4,  0xa8b5,  0xa8b6,  0xa8b7,  0xa8b8,  0xa8b9,  0xa8ba,
9246
65.1k
      0xa8bb,  0xa8bc,  0xa8bd,  0xa8be,  0xa8bf,  0xa8c0,  0xa8c1,  0xa8c2,
9247
65.1k
      0xa8c3,  0xa8c4,  0xa8c5,  0xa8e0,  0xa8e1,  0xa8e2,  0xa8e3,  0xa8e4,
9248
65.1k
      0xa8e5,  0xa8e6,  0xa8e7,  0xa8e8,  0xa8e9,  0xa8ea,  0xa8eb,  0xa8ec,
9249
65.1k
      0xa8ed,  0xa8ee,  0xa8ef,  0xa8f0,  0xa8f1,  0xa8ff,  0xa926,  0xa927,
9250
65.1k
      0xa928,  0xa929,  0xa92a,  0xa92b,  0xa92c,  0xa92d,  0xa947,  0xa948,
9251
65.1k
      0xa949,  0xa94a,  0xa94b,  0xa94c,  0xa94d,  0xa94e,  0xa94f,  0xa950,
9252
65.1k
      0xa951,  0xa952,  0xa953,  0xa980,  0xa981,  0xa982,  0xa983,  0xa9b3,
9253
65.1k
      0xa9b4,  0xa9b5,  0xa9b6,  0xa9b7,  0xa9b8,  0xa9b9,  0xa9ba,  0xa9bb,
9254
65.1k
      0xa9bc,  0xa9bd,  0xa9be,  0xa9bf,  0xa9c0,  0xa9e5,  0xaa29,  0xaa2a,
9255
65.1k
      0xaa2b,  0xaa2c,  0xaa2d,  0xaa2e,  0xaa2f,  0xaa30,  0xaa31,  0xaa32,
9256
65.1k
      0xaa33,  0xaa34,  0xaa35,  0xaa36,  0xaa43,  0xaa4c,  0xaa4d,  0xaa7b,
9257
65.1k
      0xaa7c,  0xaa7d,  0xaab0,  0xaab2,  0xaab3,  0xaab4,  0xaab7,  0xaab8,
9258
65.1k
      0xaabe,  0xaabf,  0xaac1,  0xaaeb,  0xaaec,  0xaaed,  0xaaee,  0xaaef,
9259
65.1k
      0xaaf5,  0xaaf6,  0xabe3,  0xabe4,  0xabe5,  0xabe6,  0xabe7,  0xabe8,
9260
65.1k
      0xabe9,  0xabea,  0xabec,  0xabed,  0xfb1e,  0xfe00,  0xfe01,  0xfe02,
9261
65.1k
      0xfe03,  0xfe04,  0xfe05,  0xfe06,  0xfe07,  0xfe08,  0xfe09,  0xfe0a,
9262
65.1k
      0xfe0b,  0xfe0c,  0xfe0d,  0xfe0e,  0xfe0f,  0xfe20,  0xfe21,  0xfe22,
9263
65.1k
      0xfe23,  0xfe24,  0xfe25,  0xfe26,  0xfe27,  0xfe28,  0xfe29,  0xfe2a,
9264
65.1k
      0xfe2b,  0xfe2c,  0xfe2d,  0xfe2e,  0xfe2f,  0x101fd, 0x102e0, 0x10376,
9265
65.1k
      0x10377, 0x10378, 0x10379, 0x1037a, 0x10a01, 0x10a02, 0x10a03, 0x10a05,
9266
65.1k
      0x10a06, 0x10a0c, 0x10a0d, 0x10a0e, 0x10a0f, 0x10a38, 0x10a39, 0x10a3a,
9267
65.1k
      0x10a3f, 0x10ae5, 0x10ae6, 0x10d24, 0x10d25, 0x10d26, 0x10d27, 0x10eab,
9268
65.1k
      0x10eac, 0x10f46, 0x10f47, 0x10f48, 0x10f49, 0x10f4a, 0x10f4b, 0x10f4c,
9269
65.1k
      0x10f4d, 0x10f4e, 0x10f4f, 0x10f50, 0x11000, 0x11001, 0x11002, 0x11038,
9270
65.1k
      0x11039, 0x1103a, 0x1103b, 0x1103c, 0x1103d, 0x1103e, 0x1103f, 0x11040,
9271
65.1k
      0x11041, 0x11042, 0x11043, 0x11044, 0x11045, 0x11046, 0x1107f, 0x11080,
9272
65.1k
      0x11081, 0x11082, 0x110b0, 0x110b1, 0x110b2, 0x110b3, 0x110b4, 0x110b5,
9273
65.1k
      0x110b6, 0x110b7, 0x110b8, 0x110b9, 0x110ba, 0x11100, 0x11101, 0x11102,
9274
65.1k
      0x11127, 0x11128, 0x11129, 0x1112a, 0x1112b, 0x1112c, 0x1112d, 0x1112e,
9275
65.1k
      0x1112f, 0x11130, 0x11131, 0x11132, 0x11133, 0x11134, 0x11145, 0x11146,
9276
65.1k
      0x11173, 0x11180, 0x11181, 0x11182, 0x111b3, 0x111b4, 0x111b5, 0x111b6,
9277
65.1k
      0x111b7, 0x111b8, 0x111b9, 0x111ba, 0x111bb, 0x111bc, 0x111bd, 0x111be,
9278
65.1k
      0x111bf, 0x111c0, 0x111c9, 0x111ca, 0x111cb, 0x111cc, 0x111ce, 0x111cf,
9279
65.1k
      0x1122c, 0x1122d, 0x1122e, 0x1122f, 0x11230, 0x11231, 0x11232, 0x11233,
9280
65.1k
      0x11234, 0x11235, 0x11236, 0x11237, 0x1123e, 0x112df, 0x112e0, 0x112e1,
9281
65.1k
      0x112e2, 0x112e3, 0x112e4, 0x112e5, 0x112e6, 0x112e7, 0x112e8, 0x112e9,
9282
65.1k
      0x112ea, 0x11300, 0x11301, 0x11302, 0x11303, 0x1133b, 0x1133c, 0x1133e,
9283
65.1k
      0x1133f, 0x11340, 0x11341, 0x11342, 0x11343, 0x11344, 0x11347, 0x11348,
9284
65.1k
      0x1134b, 0x1134c, 0x1134d, 0x11357, 0x11362, 0x11363, 0x11366, 0x11367,
9285
65.1k
      0x11368, 0x11369, 0x1136a, 0x1136b, 0x1136c, 0x11370, 0x11371, 0x11372,
9286
65.1k
      0x11373, 0x11374, 0x11435, 0x11436, 0x11437, 0x11438, 0x11439, 0x1143a,
9287
65.1k
      0x1143b, 0x1143c, 0x1143d, 0x1143e, 0x1143f, 0x11440, 0x11441, 0x11442,
9288
65.1k
      0x11443, 0x11444, 0x11445, 0x11446, 0x1145e, 0x114b0, 0x114b1, 0x114b2,
9289
65.1k
      0x114b3, 0x114b4, 0x114b5, 0x114b6, 0x114b7, 0x114b8, 0x114b9, 0x114ba,
9290
65.1k
      0x114bb, 0x114bc, 0x114bd, 0x114be, 0x114bf, 0x114c0, 0x114c1, 0x114c2,
9291
65.1k
      0x114c3, 0x115af, 0x115b0, 0x115b1, 0x115b2, 0x115b3, 0x115b4, 0x115b5,
9292
65.1k
      0x115b8, 0x115b9, 0x115ba, 0x115bb, 0x115bc, 0x115bd, 0x115be, 0x115bf,
9293
65.1k
      0x115c0, 0x115dc, 0x115dd, 0x11630, 0x11631, 0x11632, 0x11633, 0x11634,
9294
65.1k
      0x11635, 0x11636, 0x11637, 0x11638, 0x11639, 0x1163a, 0x1163b, 0x1163c,
9295
65.1k
      0x1163d, 0x1163e, 0x1163f, 0x11640, 0x116ab, 0x116ac, 0x116ad, 0x116ae,
9296
65.1k
      0x116af, 0x116b0, 0x116b1, 0x116b2, 0x116b3, 0x116b4, 0x116b5, 0x116b6,
9297
65.1k
      0x116b7, 0x1171d, 0x1171e, 0x1171f, 0x11720, 0x11721, 0x11722, 0x11723,
9298
65.1k
      0x11724, 0x11725, 0x11726, 0x11727, 0x11728, 0x11729, 0x1172a, 0x1172b,
9299
65.1k
      0x1182c, 0x1182d, 0x1182e, 0x1182f, 0x11830, 0x11831, 0x11832, 0x11833,
9300
65.1k
      0x11834, 0x11835, 0x11836, 0x11837, 0x11838, 0x11839, 0x1183a, 0x11930,
9301
65.1k
      0x11931, 0x11932, 0x11933, 0x11934, 0x11935, 0x11937, 0x11938, 0x1193b,
9302
65.1k
      0x1193c, 0x1193d, 0x1193e, 0x11940, 0x11942, 0x11943, 0x119d1, 0x119d2,
9303
65.1k
      0x119d3, 0x119d4, 0x119d5, 0x119d6, 0x119d7, 0x119da, 0x119db, 0x119dc,
9304
65.1k
      0x119dd, 0x119de, 0x119df, 0x119e0, 0x119e4, 0x11a01, 0x11a02, 0x11a03,
9305
65.1k
      0x11a04, 0x11a05, 0x11a06, 0x11a07, 0x11a08, 0x11a09, 0x11a0a, 0x11a33,
9306
65.1k
      0x11a34, 0x11a35, 0x11a36, 0x11a37, 0x11a38, 0x11a39, 0x11a3b, 0x11a3c,
9307
65.1k
      0x11a3d, 0x11a3e, 0x11a47, 0x11a51, 0x11a52, 0x11a53, 0x11a54, 0x11a55,
9308
65.1k
      0x11a56, 0x11a57, 0x11a58, 0x11a59, 0x11a5a, 0x11a5b, 0x11a8a, 0x11a8b,
9309
65.1k
      0x11a8c, 0x11a8d, 0x11a8e, 0x11a8f, 0x11a90, 0x11a91, 0x11a92, 0x11a93,
9310
65.1k
      0x11a94, 0x11a95, 0x11a96, 0x11a97, 0x11a98, 0x11a99, 0x11c2f, 0x11c30,
9311
65.1k
      0x11c31, 0x11c32, 0x11c33, 0x11c34, 0x11c35, 0x11c36, 0x11c38, 0x11c39,
9312
65.1k
      0x11c3a, 0x11c3b, 0x11c3c, 0x11c3d, 0x11c3e, 0x11c3f, 0x11c92, 0x11c93,
9313
65.1k
      0x11c94, 0x11c95, 0x11c96, 0x11c97, 0x11c98, 0x11c99, 0x11c9a, 0x11c9b,
9314
65.1k
      0x11c9c, 0x11c9d, 0x11c9e, 0x11c9f, 0x11ca0, 0x11ca1, 0x11ca2, 0x11ca3,
9315
65.1k
      0x11ca4, 0x11ca5, 0x11ca6, 0x11ca7, 0x11ca9, 0x11caa, 0x11cab, 0x11cac,
9316
65.1k
      0x11cad, 0x11cae, 0x11caf, 0x11cb0, 0x11cb1, 0x11cb2, 0x11cb3, 0x11cb4,
9317
65.1k
      0x11cb5, 0x11cb6, 0x11d31, 0x11d32, 0x11d33, 0x11d34, 0x11d35, 0x11d36,
9318
65.1k
      0x11d3a, 0x11d3c, 0x11d3d, 0x11d3f, 0x11d40, 0x11d41, 0x11d42, 0x11d43,
9319
65.1k
      0x11d44, 0x11d45, 0x11d47, 0x11d8a, 0x11d8b, 0x11d8c, 0x11d8d, 0x11d8e,
9320
65.1k
      0x11d90, 0x11d91, 0x11d93, 0x11d94, 0x11d95, 0x11d96, 0x11d97, 0x11ef3,
9321
65.1k
      0x11ef4, 0x11ef5, 0x11ef6, 0x16af0, 0x16af1, 0x16af2, 0x16af3, 0x16af4,
9322
65.1k
      0x16b30, 0x16b31, 0x16b32, 0x16b33, 0x16b34, 0x16b35, 0x16b36, 0x16f4f,
9323
65.1k
      0x16f51, 0x16f52, 0x16f53, 0x16f54, 0x16f55, 0x16f56, 0x16f57, 0x16f58,
9324
65.1k
      0x16f59, 0x16f5a, 0x16f5b, 0x16f5c, 0x16f5d, 0x16f5e, 0x16f5f, 0x16f60,
9325
65.1k
      0x16f61, 0x16f62, 0x16f63, 0x16f64, 0x16f65, 0x16f66, 0x16f67, 0x16f68,
9326
65.1k
      0x16f69, 0x16f6a, 0x16f6b, 0x16f6c, 0x16f6d, 0x16f6e, 0x16f6f, 0x16f70,
9327
65.1k
      0x16f71, 0x16f72, 0x16f73, 0x16f74, 0x16f75, 0x16f76, 0x16f77, 0x16f78,
9328
65.1k
      0x16f79, 0x16f7a, 0x16f7b, 0x16f7c, 0x16f7d, 0x16f7e, 0x16f7f, 0x16f80,
9329
65.1k
      0x16f81, 0x16f82, 0x16f83, 0x16f84, 0x16f85, 0x16f86, 0x16f87, 0x16f8f,
9330
65.1k
      0x16f90, 0x16f91, 0x16f92, 0x16fe4, 0x16ff0, 0x16ff1, 0x1bc9d, 0x1bc9e,
9331
65.1k
      0x1d165, 0x1d166, 0x1d167, 0x1d168, 0x1d169, 0x1d16d, 0x1d16e, 0x1d16f,
9332
65.1k
      0x1d170, 0x1d171, 0x1d172, 0x1d17b, 0x1d17c, 0x1d17d, 0x1d17e, 0x1d17f,
9333
65.1k
      0x1d180, 0x1d181, 0x1d182, 0x1d185, 0x1d186, 0x1d187, 0x1d188, 0x1d189,
9334
65.1k
      0x1d18a, 0x1d18b, 0x1d1aa, 0x1d1ab, 0x1d1ac, 0x1d1ad, 0x1d242, 0x1d243,
9335
65.1k
      0x1d244, 0x1da00, 0x1da01, 0x1da02, 0x1da03, 0x1da04, 0x1da05, 0x1da06,
9336
65.1k
      0x1da07, 0x1da08, 0x1da09, 0x1da0a, 0x1da0b, 0x1da0c, 0x1da0d, 0x1da0e,
9337
65.1k
      0x1da0f, 0x1da10, 0x1da11, 0x1da12, 0x1da13, 0x1da14, 0x1da15, 0x1da16,
9338
65.1k
      0x1da17, 0x1da18, 0x1da19, 0x1da1a, 0x1da1b, 0x1da1c, 0x1da1d, 0x1da1e,
9339
65.1k
      0x1da1f, 0x1da20, 0x1da21, 0x1da22, 0x1da23, 0x1da24, 0x1da25, 0x1da26,
9340
65.1k
      0x1da27, 0x1da28, 0x1da29, 0x1da2a, 0x1da2b, 0x1da2c, 0x1da2d, 0x1da2e,
9341
65.1k
      0x1da2f, 0x1da30, 0x1da31, 0x1da32, 0x1da33, 0x1da34, 0x1da35, 0x1da36,
9342
65.1k
      0x1da3b, 0x1da3c, 0x1da3d, 0x1da3e, 0x1da3f, 0x1da40, 0x1da41, 0x1da42,
9343
65.1k
      0x1da43, 0x1da44, 0x1da45, 0x1da46, 0x1da47, 0x1da48, 0x1da49, 0x1da4a,
9344
65.1k
      0x1da4b, 0x1da4c, 0x1da4d, 0x1da4e, 0x1da4f, 0x1da50, 0x1da51, 0x1da52,
9345
65.1k
      0x1da53, 0x1da54, 0x1da55, 0x1da56, 0x1da57, 0x1da58, 0x1da59, 0x1da5a,
9346
65.1k
      0x1da5b, 0x1da5c, 0x1da5d, 0x1da5e, 0x1da5f, 0x1da60, 0x1da61, 0x1da62,
9347
65.1k
      0x1da63, 0x1da64, 0x1da65, 0x1da66, 0x1da67, 0x1da68, 0x1da69, 0x1da6a,
9348
65.1k
      0x1da6b, 0x1da6c, 0x1da75, 0x1da84, 0x1da9b, 0x1da9c, 0x1da9d, 0x1da9e,
9349
65.1k
      0x1da9f, 0x1daa1, 0x1daa2, 0x1daa3, 0x1daa4, 0x1daa5, 0x1daa6, 0x1daa7,
9350
65.1k
      0x1daa8, 0x1daa9, 0x1daaa, 0x1daab, 0x1daac, 0x1daad, 0x1daae, 0x1daaf,
9351
65.1k
      0x1e000, 0x1e001, 0x1e002, 0x1e003, 0x1e004, 0x1e005, 0x1e006, 0x1e008,
9352
65.1k
      0x1e009, 0x1e00a, 0x1e00b, 0x1e00c, 0x1e00d, 0x1e00e, 0x1e00f, 0x1e010,
9353
65.1k
      0x1e011, 0x1e012, 0x1e013, 0x1e014, 0x1e015, 0x1e016, 0x1e017, 0x1e018,
9354
65.1k
      0x1e01b, 0x1e01c, 0x1e01d, 0x1e01e, 0x1e01f, 0x1e020, 0x1e021, 0x1e023,
9355
65.1k
      0x1e024, 0x1e026, 0x1e027, 0x1e028, 0x1e029, 0x1e02a, 0x1e130, 0x1e131,
9356
65.1k
      0x1e132, 0x1e133, 0x1e134, 0x1e135, 0x1e136, 0x1e2ec, 0x1e2ed, 0x1e2ee,
9357
65.1k
      0x1e2ef, 0x1e8d0, 0x1e8d1, 0x1e8d2, 0x1e8d3, 0x1e8d4, 0x1e8d5, 0x1e8d6,
9358
65.1k
      0x1e944, 0x1e945, 0x1e946, 0x1e947, 0x1e948, 0x1e949, 0x1e94a, 0xe0100,
9359
65.1k
      0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106, 0xe0107, 0xe0108,
9360
65.1k
      0xe0109, 0xe010a, 0xe010b, 0xe010c, 0xe010d, 0xe010e, 0xe010f, 0xe0110,
9361
65.1k
      0xe0111, 0xe0112, 0xe0113, 0xe0114, 0xe0115, 0xe0116, 0xe0117, 0xe0118,
9362
65.1k
      0xe0119, 0xe011a, 0xe011b, 0xe011c, 0xe011d, 0xe011e, 0xe011f, 0xe0120,
9363
65.1k
      0xe0121, 0xe0122, 0xe0123, 0xe0124, 0xe0125, 0xe0126, 0xe0127, 0xe0128,
9364
65.1k
      0xe0129, 0xe012a, 0xe012b, 0xe012c, 0xe012d, 0xe012e, 0xe012f, 0xe0130,
9365
65.1k
      0xe0131, 0xe0132, 0xe0133, 0xe0134, 0xe0135, 0xe0136, 0xe0137, 0xe0138,
9366
65.1k
      0xe0139, 0xe013a, 0xe013b, 0xe013c, 0xe013d, 0xe013e, 0xe013f, 0xe0140,
9367
65.1k
      0xe0141, 0xe0142, 0xe0143, 0xe0144, 0xe0145, 0xe0146, 0xe0147, 0xe0148,
9368
65.1k
      0xe0149, 0xe014a, 0xe014b, 0xe014c, 0xe014d, 0xe014e, 0xe014f, 0xe0150,
9369
65.1k
      0xe0151, 0xe0152, 0xe0153, 0xe0154, 0xe0155, 0xe0156, 0xe0157, 0xe0158,
9370
65.1k
      0xe0159, 0xe015a, 0xe015b, 0xe015c, 0xe015d, 0xe015e, 0xe015f, 0xe0160,
9371
65.1k
      0xe0161, 0xe0162, 0xe0163, 0xe0164, 0xe0165, 0xe0166, 0xe0167, 0xe0168,
9372
65.1k
      0xe0169, 0xe016a, 0xe016b, 0xe016c, 0xe016d, 0xe016e, 0xe016f, 0xe0170,
9373
65.1k
      0xe0171, 0xe0172, 0xe0173, 0xe0174, 0xe0175, 0xe0176, 0xe0177, 0xe0178,
9374
65.1k
      0xe0179, 0xe017a, 0xe017b, 0xe017c, 0xe017d, 0xe017e, 0xe017f, 0xe0180,
9375
65.1k
      0xe0181, 0xe0182, 0xe0183, 0xe0184, 0xe0185, 0xe0186, 0xe0187, 0xe0188,
9376
65.1k
      0xe0189, 0xe018a, 0xe018b, 0xe018c, 0xe018d, 0xe018e, 0xe018f, 0xe0190,
9377
65.1k
      0xe0191, 0xe0192, 0xe0193, 0xe0194, 0xe0195, 0xe0196, 0xe0197, 0xe0198,
9378
65.1k
      0xe0199, 0xe019a, 0xe019b, 0xe019c, 0xe019d, 0xe019e, 0xe019f, 0xe01a0,
9379
65.1k
      0xe01a1, 0xe01a2, 0xe01a3, 0xe01a4, 0xe01a5, 0xe01a6, 0xe01a7, 0xe01a8,
9380
65.1k
      0xe01a9, 0xe01aa, 0xe01ab, 0xe01ac, 0xe01ad, 0xe01ae, 0xe01af, 0xe01b0,
9381
65.1k
      0xe01b1, 0xe01b2, 0xe01b3, 0xe01b4, 0xe01b5, 0xe01b6, 0xe01b7, 0xe01b8,
9382
65.1k
      0xe01b9, 0xe01ba, 0xe01bb, 0xe01bc, 0xe01bd, 0xe01be, 0xe01bf, 0xe01c0,
9383
65.1k
      0xe01c1, 0xe01c2, 0xe01c3, 0xe01c4, 0xe01c5, 0xe01c6, 0xe01c7, 0xe01c8,
9384
65.1k
      0xe01c9, 0xe01ca, 0xe01cb, 0xe01cc, 0xe01cd, 0xe01ce, 0xe01cf, 0xe01d0,
9385
65.1k
      0xe01d1, 0xe01d2, 0xe01d3, 0xe01d4, 0xe01d5, 0xe01d6, 0xe01d7, 0xe01d8,
9386
65.1k
      0xe01d9, 0xe01da, 0xe01db, 0xe01dc, 0xe01dd, 0xe01de, 0xe01df, 0xe01e0,
9387
65.1k
      0xe01e1, 0xe01e2, 0xe01e3, 0xe01e4, 0xe01e5, 0xe01e6, 0xe01e7, 0xe01e8,
9388
65.1k
      0xe01e9, 0xe01ea, 0xe01eb, 0xe01ec, 0xe01ed, 0xe01ee, 0xe01ef};
9389
65.1k
  if (std::ranges::binary_search(combining, label.front())) {
9390
1.00k
    return false;
9391
1.00k
  }
9392
  // We verify this next step as part of the mapping:
9393
  // ---------------------------------------------
9394
  // Each code point in the label must only have certain status values
9395
  // according to Section 5, IDNA Mapping Table:
9396
  // - For Transitional Processing, each value must be valid.
9397
  // - For Nontransitional Processing, each value must be either valid or
9398
  // deviation.
9399
9400
  // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix
9401
  // A, in The Unicode Code Points and Internationalized Domain Names for
9402
  // Applications (IDNA) [IDNA2008].
9403
64.1k
  constexpr static uint32_t virama[] = {
9404
64.1k
      0x094D,  0x09CD,  0x0A4D,  0x0ACD,  0x0B4D,  0x0BCD,  0x0C4D,  0x0CCD,
9405
64.1k
      0x0D3B,  0x0D3C,  0x0D4D,  0x0DCA,  0x0E3A,  0x0EBA,  0x0F84,  0x1039,
9406
64.1k
      0x103A,  0x1714,  0x1734,  0x17D2,  0x1A60,  0x1B44,  0x1BAA,  0x1BAB,
9407
64.1k
      0x1BF2,  0x1BF3,  0x2D7F,  0xA806,  0xA82C,  0xA8C4,  0xA953,  0xA9C0,
9408
64.1k
      0xAAF6,  0xABED,  0x10A3F, 0x11046, 0x1107F, 0x110B9, 0x11133, 0x11134,
9409
64.1k
      0x111C0, 0x11235, 0x112EA, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F,
9410
64.1k
      0x116B6, 0x1172B, 0x11839, 0x1193D, 0x1193E, 0x119E0, 0x11A34, 0x11A47,
9411
64.1k
      0x11A99, 0x11C3F, 0x11D44, 0x11D45, 0x11D97};
9412
64.1k
  constexpr static uint32_t R[] = {
9413
64.1k
      0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630, 0x631,
9414
64.1k
      0x632, 0x648, 0x671, 0x672, 0x673, 0x675, 0x676, 0x677, 0x688,
9415
64.1k
      0x689, 0x68a, 0x68b, 0x68c, 0x68d, 0x68e, 0x68f, 0x690, 0x691,
9416
64.1k
      0x692, 0x693, 0x694, 0x695, 0x696, 0x697, 0x698, 0x699, 0x6c0,
9417
64.1k
      0x6c3, 0x6c4, 0x6c5, 0x6c6, 0x6c7, 0x6c8, 0x6c9, 0x6ca, 0x6cb,
9418
64.1k
      0x6cd, 0x6cf, 0x6d2, 0x6d3, 0x6d5, 0x6ee, 0x6ef, 0x710, 0x715,
9419
64.1k
      0x716, 0x717, 0x718, 0x719, 0x71e, 0x728, 0x72a, 0x72c, 0x72f,
9420
64.1k
      0x74d, 0x759, 0x75a, 0x75b, 0x854, 0x8aa, 0x8ab, 0x8ac};
9421
64.1k
  constexpr static uint32_t L[] = {0xa872};
9422
64.1k
  constexpr static uint32_t D[] = {
9423
64.1k
      0x620,  0x626,  0x628,  0x62a,  0x62b,  0x62c,  0x62d,  0x62e,  0x633,
9424
64.1k
      0x634,  0x635,  0x636,  0x637,  0x638,  0x639,  0x63a,  0x63b,  0x63c,
9425
64.1k
      0x63d,  0x63e,  0x63f,  0x641,  0x642,  0x643,  0x644,  0x645,  0x646,
9426
64.1k
      0x647,  0x649,  0x64a,  0x66e,  0x66f,  0x678,  0x679,  0x67a,  0x67b,
9427
64.1k
      0x67c,  0x67d,  0x67e,  0x67f,  0x680,  0x681,  0x682,  0x683,  0x684,
9428
64.1k
      0x685,  0x686,  0x687,  0x69a,  0x69b,  0x69c,  0x69d,  0x69e,  0x69f,
9429
64.1k
      0x6a0,  0x6a1,  0x6a2,  0x6a3,  0x6a4,  0x6a5,  0x6a6,  0x6a7,  0x6a8,
9430
64.1k
      0x6a9,  0x6aa,  0x6ab,  0x6ac,  0x6ad,  0x6ae,  0x6af,  0x6b0,  0x6b1,
9431
64.1k
      0x6b2,  0x6b3,  0x6b4,  0x6b5,  0x6b6,  0x6b7,  0x6b8,  0x6b9,  0x6ba,
9432
64.1k
      0x6bb,  0x6bc,  0x6bd,  0x6be,  0x6bf,  0x6c1,  0x6c2,  0x6cc,  0x6ce,
9433
64.1k
      0x6d0,  0x6d1,  0x6fa,  0x6fb,  0x6fc,  0x6ff,  0x712,  0x713,  0x714,
9434
64.1k
      0x71a,  0x71b,  0x71c,  0x71d,  0x71f,  0x720,  0x721,  0x722,  0x723,
9435
64.1k
      0x724,  0x725,  0x726,  0x727,  0x729,  0x72b,  0x72d,  0x72e,  0x74e,
9436
64.1k
      0x74f,  0x750,  0x751,  0x752,  0x753,  0x754,  0x755,  0x756,  0x757,
9437
64.1k
      0x758,  0x75c,  0x75d,  0x75e,  0x75f,  0x760,  0x761,  0x762,  0x763,
9438
64.1k
      0x764,  0x765,  0x766,  0x850,  0x851,  0x852,  0x853,  0x855,  0x8a0,
9439
64.1k
      0x8a2,  0x8a3,  0x8a4,  0x8a5,  0x8a6,  0x8a7,  0x8a8,  0x8a9,  0x1807,
9440
64.1k
      0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828,
9441
64.1k
      0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 0x1830, 0x1831,
9442
64.1k
      0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 0x1838, 0x1839, 0x183a,
9443
64.1k
      0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 0x1840, 0x1841, 0x1842, 0x1843,
9444
64.1k
      0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x184a, 0x184b, 0x184c,
9445
64.1k
      0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855,
9446
64.1k
      0x1856, 0x1857, 0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e,
9447
64.1k
      0x185f, 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,
9448
64.1k
      0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 0x1870,
9449
64.1k
      0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 0x1887, 0x1888,
9450
64.1k
      0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 0x1890, 0x1891,
9451
64.1k
      0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 0x1898, 0x1899, 0x189a,
9452
64.1k
      0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 0x18a0, 0x18a1, 0x18a2, 0x18a3,
9453
64.1k
      0x18a4, 0x18a5, 0x18a6, 0x18a7, 0x18a8, 0x18aa, 0xa840, 0xa841, 0xa842,
9454
64.1k
      0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 0xa848, 0xa849, 0xa84a, 0xa84b,
9455
64.1k
      0xa84c, 0xa84d, 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa853, 0xa854,
9456
64.1k
      0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d,
9457
64.1k
      0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866,
9458
64.1k
      0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f,
9459
64.1k
      0xa870, 0xa871};
9460
9461
322k
  for (size_t i = 0; i < label.size(); i++) {
9462
265k
    uint32_t c = label[i];
9463
265k
    if (c == 0x200c) {
9464
5.60k
      if (i > 0) {
9465
5.51k
        if (std::ranges::binary_search(virama, label[i - 1])) {
9466
87
          return true;
9467
87
        }
9468
5.51k
      }
9469
5.51k
      if ((i == 0) || (i + 1 >= label.size())) {
9470
396
        return false;
9471
396
      }
9472
      // we go backward looking for L or D
9473
15.0k
      auto is_l_or_d = [](uint32_t code) {
9474
15.0k
        return std::ranges::binary_search(L, code) ||
9475
14.8k
               std::ranges::binary_search(D, code);
9476
15.0k
      };
9477
12.3k
      auto is_r_or_d = [](uint32_t code) {
9478
12.3k
        return std::ranges::binary_search(R, code) ||
9479
12.3k
               std::ranges::binary_search(D, code);
9480
12.3k
      };
9481
5.12k
      std::u32string_view before = label.substr(0, i);
9482
5.12k
      std::u32string_view after = label.substr(i + 1);
9483
5.12k
      return (std::find_if(before.begin(), before.end(), is_l_or_d) !=
9484
5.12k
              before.end()) &&
9485
2.28k
             (std::find_if(after.begin(), after.end(), is_r_or_d) !=
9486
2.28k
              after.end());
9487
259k
    } else if (c == 0x200d) {
9488
1.54k
      if (i > 0) {
9489
1.45k
        if (std::ranges::binary_search(virama, label[i - 1])) {
9490
142
          return true;
9491
142
        }
9492
1.45k
      }
9493
1.40k
      return false;
9494
1.54k
    }
9495
265k
  }
9496
9497
  // If CheckBidi, and if the domain name is a  Bidi domain name, then the label
9498
  // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893,
9499
  // Section 2.
9500
9501
  // The following rule, consisting of six conditions, applies to labels
9502
  // in Bidi domain names.  The requirements that this rule satisfies are
9503
  // described in Section 3.  All of the conditions must be satisfied for
9504
  // the rule to be satisfied.
9505
  //
9506
  //  1.  The first character must be a character with Bidi property L, R,
9507
  //     or AL.  If it has the R or AL property, it is an RTL label; if it
9508
  //     has the L property, it is an LTR label.
9509
  //
9510
  //  2.  In an RTL label, only characters with the Bidi properties R, AL,
9511
  //      AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.
9512
  //
9513
  //   3.  In an RTL label, the end of the label must be a character with
9514
  //       Bidi property R, AL, EN, or AN, followed by zero or more
9515
  //       characters with Bidi property NSM.
9516
  //
9517
  //   4.  In an RTL label, if an EN is present, no AN may be present, and
9518
  //       vice versa.
9519
  //
9520
  //  5.  In an LTR label, only characters with the Bidi properties L, EN,
9521
  //       ES, CS, ET, ON, BN, or NSM are allowed.
9522
  //
9523
  //   6.  In an LTR label, the end of the label must be a character with
9524
  //       Bidi property L or EN, followed by zero or more characters with
9525
  //       Bidi property NSM.
9526
9527
56.9k
  size_t last_non_nsm_char = find_last_not_of_nsm(label);
9528
56.9k
  if (last_non_nsm_char == std::u32string_view::npos) {
9529
0
    return false;
9530
0
  }
9531
9532
  // A "Bidi domain name" is a domain name that contains at least one RTL label.
9533
  // The following rule, consisting of six conditions, applies to labels in Bidi
9534
  // domain names.
9535
56.9k
  if (is_rtl_label(label)) {
9536
    // The first character must be a character with Bidi property L, R,
9537
    // or AL. If it has the R or AL property, it is an RTL label; if it
9538
    // has the L property, it is an LTR label.
9539
9540
16.5k
    if (find_direction(label[0]) == direction::L) {
9541
      // Eval as LTR
9542
9543
      // In an LTR label, only characters with the Bidi properties L, EN,
9544
      // ES, CS, ET, ON, BN, or NSM are allowed.
9545
22.7k
      for (size_t i = 0; i <= last_non_nsm_char; i++) {
9546
22.7k
        const direction d = find_direction(label[i]);
9547
22.7k
        if (!(d == direction::L || d == direction::EN || d == direction::ES ||
9548
12.1k
              d == direction::CS || d == direction::ET || d == direction::ON ||
9549
7.87k
              d == direction::BN || d == direction::NSM)) {
9550
4.92k
          return false;
9551
4.92k
        }
9552
22.7k
      }
9553
9554
0
      const direction last_dir = find_direction(label[last_non_nsm_char]);
9555
0
      if (!(last_dir == direction::L || last_dir == direction::EN)) {
9556
0
        return false;
9557
0
      }
9558
9559
0
      return true;
9560
9561
11.6k
    } else {
9562
      // Eval as RTL
9563
9564
      // The first character must be R or AL; a leading AN (or any other
9565
      // direction) does not start a valid RTL label.
9566
11.6k
      const direction first_dir = find_direction(label[0]);
9567
11.6k
      if (first_dir != direction::R && first_dir != direction::AL) {
9568
1.70k
        return false;
9569
1.70k
      }
9570
9571
9.94k
      bool has_an = false;
9572
9.94k
      bool has_en = false;
9573
42.6k
      for (size_t i = 0; i <= last_non_nsm_char; i++) {
9574
36.3k
        const direction d = find_direction(label[i]);
9575
9576
        // In an RTL label, if an EN is present, no AN may be present, and vice
9577
        // versa.
9578
36.3k
        if ((d == direction::EN && ((has_en = true) && has_an)) ||
9579
36.2k
            (d == direction::AN && ((has_an = true) && has_en))) {
9580
177
          return false;
9581
177
        }
9582
9583
36.1k
        if (!(d == direction::R || d == direction::AL || d == direction::AN ||
9584
16.2k
              d == direction::EN || d == direction::ES || d == direction::CS ||
9585
9.75k
              d == direction::ET || d == direction::ON || d == direction::BN ||
9586
3.68k
              d == direction::NSM)) {
9587
1.98k
          return false;
9588
1.98k
        }
9589
9590
34.1k
        if (i == last_non_nsm_char &&
9591
7.78k
            !(d == direction::R || d == direction::AL || d == direction::AN ||
9592
2.37k
              d == direction::EN)) {
9593
1.46k
          return false;
9594
1.46k
        }
9595
34.1k
      }
9596
9597
6.32k
      return true;
9598
9.94k
    }
9599
16.5k
  }
9600
9601
40.3k
  return true;
9602
56.9k
}
9603
9604
}  // namespace ada::idna
9605
/* end file src/validity.cpp */
9606
/* begin file src/to_ascii.cpp */
9607
9608
#include <algorithm>
9609
#include <cstdint>
9610
#include <ranges>
9611
9612
9613
#ifdef ADA_USE_SIMDUTF
9614
#include "simdutf.h"
9615
#endif
9616
9617
namespace ada::idna {
9618
9619
92.0k
bool constexpr is_ascii(std::u32string_view view) {
9620
160k
  for (uint32_t c : view) {
9621
160k
    if (c >= 0x80) {
9622
81.8k
      return false;
9623
81.8k
    }
9624
160k
  }
9625
10.1k
  return true;
9626
92.0k
}
9627
9628
135k
bool constexpr is_ascii(std::string_view view) {
9629
1.05M
  for (uint8_t c : view) {
9630
1.05M
    if (c >= 0x80) {
9631
37.1k
      return false;
9632
37.1k
    }
9633
1.05M
  }
9634
98.1k
  return true;
9635
135k
}
9636
9637
constexpr static uint8_t is_forbidden_domain_code_point_table[] = {
9638
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9639
    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
9640
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
9641
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
9642
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9643
    0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9644
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9645
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9646
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9647
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9648
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
9649
9650
static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
9651
9652
0
inline bool is_forbidden_domain_code_point(const char c) noexcept {
9653
0
  return is_forbidden_domain_code_point_table[uint8_t(c)];
9654
0
}
9655
9656
0
bool contains_forbidden_domain_code_point(std::string_view view) {
9657
0
  return std::ranges::any_of(view, is_forbidden_domain_code_point);
9658
0
}
9659
9660
// We return "" on error.
9661
98.1k
static std::string from_ascii_to_ascii(std::string_view ut8_string) {
9662
98.1k
  static const std::string error = "";
9663
98.1k
  std::string out;
9664
98.1k
  out.reserve(ut8_string.size());
9665
98.1k
  std::u32string tmp_buffer;
9666
98.1k
  std::u32string post_map;
9667
98.1k
  size_t label_start = 0;
9668
9669
187k
  while (label_start != ut8_string.size()) {
9670
121k
    size_t loc_dot = ut8_string.find('.', label_start);
9671
121k
    bool is_last_label = (loc_dot == std::string_view::npos);
9672
121k
    size_t label_size =
9673
121k
        is_last_label ? ut8_string.size() - label_start : loc_dot - label_start;
9674
121k
    size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
9675
121k
    std::string_view label_view(ut8_string.data() + label_start, label_size);
9676
121k
    label_start += label_size_with_dot;
9677
121k
    if (label_size == 0) {
9678
      // empty label? Nothing to do.
9679
113k
    } else {
9680
      // Append the label to out and lowercase it in-place, avoiding a separate
9681
      // copy of the entire input string.
9682
113k
      size_t label_out_start = out.size();
9683
113k
      out.append(label_view);
9684
113k
      ascii_map(out.data() + label_out_start, label_size);
9685
113k
      std::string_view mapped_label(out.data() + label_out_start, label_size);
9686
113k
      if (mapped_label.starts_with("xn--")) {
9687
        // The xn-- part is the expensive game.
9688
52.6k
        std::string_view puny_segment_ascii(out.data() + label_out_start + 4,
9689
52.6k
                                            label_size - 4);
9690
52.6k
        tmp_buffer.clear();
9691
52.6k
        bool is_ok =
9692
52.6k
            ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
9693
52.6k
        if (!is_ok) {
9694
6.11k
          return error;
9695
6.11k
        }
9696
        // If the input is just ASCII, it should not have been encoded
9697
        // as punycode.
9698
        // https://github.com/whatwg/url/issues/760
9699
46.5k
        if (is_ascii(tmp_buffer)) {
9700
2.34k
          return error;
9701
2.34k
        }
9702
44.1k
        if (!ada::idna::map(tmp_buffer, post_map)) {
9703
7.39k
          return error;
9704
7.39k
        }
9705
36.7k
        if (tmp_buffer != post_map) {
9706
3.73k
          return error;
9707
3.73k
        }
9708
33.0k
        normalize(post_map);
9709
33.0k
        if (post_map != tmp_buffer) {
9710
2.29k
          return error;
9711
2.29k
        }
9712
30.7k
        if (post_map.empty()) {
9713
0
          return error;
9714
0
        }
9715
30.7k
        if (!is_label_valid(post_map)) {
9716
9.69k
          return error;
9717
9.69k
        }
9718
30.7k
      }
9719
113k
    }
9720
89.5k
    if (!is_last_label) {
9721
24.5k
      out.push_back('.');
9722
24.5k
    }
9723
89.5k
  }
9724
66.5k
  return out;
9725
98.1k
}
9726
9727
// We return "" on error.
9728
135k
std::string to_ascii(std::string_view ut8_string) {
9729
135k
  if (is_ascii(ut8_string)) {
9730
98.1k
    return from_ascii_to_ascii(ut8_string);
9731
98.1k
  }
9732
37.1k
  static const std::string error = "";
9733
  // We convert to UTF-32
9734
9735
#ifdef ADA_USE_SIMDUTF
9736
  size_t utf32_length =
9737
      simdutf::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
9738
  std::u32string utf32(utf32_length, '\0');
9739
  size_t actual_utf32_length = simdutf::convert_utf8_to_utf32(
9740
      ut8_string.data(), ut8_string.size(), utf32.data());
9741
#else
9742
37.1k
  size_t utf32_length =
9743
37.1k
      ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
9744
37.1k
  std::u32string utf32(utf32_length, '\0');
9745
37.1k
  size_t actual_utf32_length = ada::idna::utf8_to_utf32(
9746
37.1k
      ut8_string.data(), ut8_string.size(), utf32.data());
9747
37.1k
#endif
9748
37.1k
  if (actual_utf32_length == 0) {
9749
5.86k
    return error;
9750
5.86k
  }
9751
  // mapping: use the two-argument overload to avoid an extra heap allocation
9752
  // that the single-argument overload (which returns by value) would incur.
9753
31.2k
  std::u32string tmp_buffer;
9754
31.2k
  std::u32string post_map;
9755
31.2k
  if (!ada::idna::map(utf32, tmp_buffer)) {
9756
691
    return error;
9757
691
  }
9758
30.5k
  utf32 = std::move(tmp_buffer);
9759
30.5k
  normalize(utf32);
9760
30.5k
  std::string out;
9761
30.5k
  out.reserve(ut8_string.size());
9762
30.5k
  size_t label_start = 0;
9763
9764
72.8k
  while (label_start != utf32.size()) {
9765
54.6k
    size_t loc_dot = utf32.find('.', label_start);
9766
54.6k
    bool is_last_label = (loc_dot == std::string_view::npos);
9767
54.6k
    size_t label_size =
9768
54.6k
        is_last_label ? utf32.size() - label_start : loc_dot - label_start;
9769
54.6k
    size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
9770
54.6k
    std::u32string_view label_view(utf32.data() + label_start, label_size);
9771
54.6k
    label_start += label_size_with_dot;
9772
54.6k
    if (label_size == 0) {
9773
      // empty label? Nothing to do.
9774
46.5k
    } else if (label_view.starts_with(U"xn--")) {
9775
      // we do not need to check, e.g., Xn-- because mapping goes to lower case
9776
      // Validate first, then bulk-copy with a single resize to avoid per-char
9777
      // capacity checks in operator+=.
9778
71.4k
      for (char32_t c : label_view) {
9779
71.4k
        if (c >= 0x80) {
9780
630
          return error;
9781
630
        }
9782
71.4k
      }
9783
7.03k
      size_t label_out_start = out.size();
9784
7.03k
      out.resize(label_out_start + label_size);
9785
7.03k
      char* dest = out.data() + label_out_start;
9786
67.6k
      for (char32_t c : label_view) {
9787
67.6k
        *dest++ = static_cast<char>(c);
9788
67.6k
      }
9789
7.03k
      std::string_view puny_segment_ascii(out.data() + label_out_start + 4,
9790
7.03k
                                          label_size - 4);
9791
7.03k
      tmp_buffer.clear();
9792
7.03k
      bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
9793
7.03k
      if (!is_ok) {
9794
456
        return error;
9795
456
      }
9796
      // If the input is just ASCII, it should not have been encoded
9797
      // as punycode.
9798
      // https://github.com/whatwg/url/issues/760
9799
6.57k
      if (is_ascii(tmp_buffer)) {
9800
929
        return error;
9801
929
      }
9802
5.64k
      if (!ada::idna::map(tmp_buffer, post_map)) {
9803
1.22k
        return error;
9804
1.22k
      }
9805
4.42k
      if (tmp_buffer != post_map) {
9806
1.31k
        return error;
9807
1.31k
      }
9808
3.10k
      normalize(post_map);
9809
3.10k
      if (post_map != tmp_buffer) {
9810
772
        return error;
9811
772
      }
9812
2.32k
      if (post_map.empty()) {
9813
0
        return error;
9814
0
      }
9815
2.32k
      if (!is_label_valid(post_map)) {
9816
229
        return error;
9817
229
      }
9818
38.9k
    } else {
9819
      // The fast path here is an ascii label.
9820
38.9k
      if (is_ascii(label_view)) {
9821
        // no validation needed; bulk-copy with single resize.
9822
6.88k
        size_t old_size = out.size();
9823
6.88k
        out.resize(old_size + label_size);
9824
6.88k
        char* dest = out.data() + old_size;
9825
16.7k
        for (char32_t c : label_view) {
9826
16.7k
          *dest++ = static_cast<char>(c);
9827
16.7k
        }
9828
32.0k
      } else {
9829
        // slow path.
9830
        // first check validity.
9831
32.0k
        if (!is_label_valid(label_view)) {
9832
6.78k
          return error;
9833
6.78k
        }
9834
        // It is valid! So now we must encode it as punycode...
9835
25.2k
        out.append("xn--");
9836
25.2k
        bool is_ok = ada::idna::utf32_to_punycode(label_view, out);
9837
25.2k
        if (!is_ok) {
9838
0
          return error;
9839
0
        }
9840
25.2k
      }
9841
38.9k
    }
9842
42.3k
    if (!is_last_label) {
9843
25.1k
      out.push_back('.');
9844
25.1k
    }
9845
42.3k
  }
9846
18.1k
  return out;
9847
30.5k
}
9848
}  // namespace ada::idna
9849
/* end file src/to_ascii.cpp */
9850
/* begin file src/to_unicode.cpp */
9851
9852
#include <algorithm>
9853
#include <string>
9854
9855
9856
#ifdef ADA_USE_SIMDUTF
9857
#include "simdutf.h"
9858
#endif
9859
9860
namespace ada::idna {
9861
0
std::string to_unicode(std::string_view input) {
9862
0
  std::string output;
9863
0
  output.reserve(input.size());
9864
9865
0
  size_t label_start = 0;
9866
0
  std::u32string tmp_buffer;
9867
0
  std::u32string post_map;
9868
0
  while (label_start < input.size()) {
9869
0
    size_t loc_dot = input.find('.', label_start);
9870
0
    bool is_last_label = (loc_dot == std::string_view::npos);
9871
0
    size_t label_size =
9872
0
        is_last_label ? input.size() - label_start : loc_dot - label_start;
9873
0
    auto label_view = std::string_view(input.data() + label_start, label_size);
9874
9875
0
    if (label_view.starts_with("xn--") && ada::idna::is_ascii(label_view)) {
9876
0
      label_view.remove_prefix(4);
9877
0
      tmp_buffer.clear();
9878
0
      if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) {
9879
        // Per UTS #46, the decoded label must be re-validated. Reject decodings
9880
        // that are pure ASCII (xn-- encoding of an ASCII-only label), or whose
9881
        // mapping/normalization is not stable, or that fail label validity.
9882
0
        bool accept_decoded = true;
9883
0
        if (ada::idna::is_ascii(tmp_buffer)) {
9884
0
          accept_decoded = false;
9885
0
        } else {
9886
0
          post_map.clear();
9887
0
          if (!ada::idna::map(tmp_buffer, post_map) || post_map != tmp_buffer) {
9888
0
            accept_decoded = false;
9889
0
          } else {
9890
0
            ada::idna::normalize(post_map);
9891
0
            if (post_map != tmp_buffer || post_map.empty() ||
9892
0
                !ada::idna::is_label_valid(post_map)) {
9893
0
              accept_decoded = false;
9894
0
            }
9895
0
          }
9896
0
        }
9897
9898
0
        if (accept_decoded) {
9899
#ifdef ADA_USE_SIMDUTF
9900
          auto utf8_size = simdutf::utf8_length_from_utf32(tmp_buffer.data(),
9901
                                                           tmp_buffer.size());
9902
          size_t old_size = output.size();
9903
          output.resize(old_size + utf8_size);
9904
          size_t written = simdutf::convert_utf32_to_utf8(
9905
              tmp_buffer.data(), tmp_buffer.size(), output.data() + old_size);
9906
          if (written != utf8_size) {
9907
            // This cannot happen because punycode_to_utf32 only produces valid
9908
            // Unicode code points, but if it does (it would indicate a bug in
9909
            // punycode_to_utf32 or simdutf), we can fall back to the original
9910
            // input. This is pendantic. We have no report of such an issue and
9911
            // no reason to expect it, but we want to be robust against any such
9912
            // bug.
9913
            output.resize(old_size);
9914
            output.append(
9915
                std::string_view(input.data() + label_start, label_size));
9916
          }
9917
#else
9918
0
          auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(),
9919
0
                                                             tmp_buffer.size());
9920
0
          size_t old_size = output.size();
9921
0
          output.resize(old_size + utf8_size);
9922
0
          ada::idna::utf32_to_utf8(tmp_buffer.data(), tmp_buffer.size(),
9923
0
                                   output.data() + old_size);
9924
0
#endif
9925
0
        } else {
9926
          // ToUnicode never fails. If any step fails, return the original
9927
          // input sequence for the label.
9928
0
          output.append(
9929
0
              std::string_view(input.data() + label_start, label_size));
9930
0
        }
9931
0
      } else {
9932
        // ToUnicode never fails.  If any step fails, then the original input
9933
        // sequence is returned immediately in that step.
9934
0
        output.append(std::string_view(input.data() + label_start, label_size));
9935
0
      }
9936
0
    } else {
9937
0
      output.append(label_view);
9938
0
    }
9939
9940
0
    if (!is_last_label) {
9941
0
      output.push_back('.');
9942
0
    }
9943
9944
0
    label_start += label_size + 1;
9945
0
  }
9946
9947
0
  return output;
9948
0
}
9949
}  // namespace ada::idna
9950
/* end file src/to_unicode.cpp */
9951
/* begin file src/identifier.cpp */
9952
9953
#include <algorithm>
9954
#include <array>
9955
#include <span>
9956
#include <string>
9957
9958
/* begin file src/id_tables.cpp */
9959
// IDNA  17.0.0
9960
9961
// clang-format off
9962
#ifndef ADA_IDNA_IDENTIFIER_TABLES_H
9963
#define ADA_IDNA_IDENTIFIER_TABLES_H
9964
#include <cstdint>
9965
9966
namespace ada::idna {
9967
9968
const uint32_t id_continue[1418][2] =
9969
{
9970
  {48, 57}, {65, 90}, {95, 95}, {97, 122},
9971
  {170, 170}, {181, 181}, {183, 183}, {186, 186},
9972
  {192, 214}, {216, 246}, {248, 442}, {443, 443},
9973
  {444, 447}, {448, 451}, {452, 659}, {660, 661},
9974
  {662, 687}, {688, 705}, {710, 721}, {736, 740},
9975
  {748, 748}, {750, 750}, {768, 879}, {880, 883},
9976
  {884, 884}, {886, 887}, {890, 890}, {891, 893},
9977
  {895, 895}, {902, 902}, {903, 903}, {904, 906},
9978
  {908, 908}, {910, 929}, {931, 1013}, {1015, 1153},
9979
  {1155, 1159}, {1162, 1327}, {1329, 1366}, {1369, 1369},
9980
  {1376, 1416}, {1425, 1469}, {1471, 1471}, {1473, 1474},
9981
  {1476, 1477}, {1479, 1479}, {1488, 1514}, {1519, 1522},
9982
  {1552, 1562}, {1568, 1599}, {1600, 1600}, {1601, 1610},
9983
  {1611, 1631}, {1632, 1641}, {1646, 1647}, {1648, 1648},
9984
  {1649, 1747}, {1749, 1749}, {1750, 1756}, {1759, 1764},
9985
  {1765, 1766}, {1767, 1768}, {1770, 1773}, {1774, 1775},
9986
  {1776, 1785}, {1786, 1788}, {1791, 1791}, {1808, 1808},
9987
  {1809, 1809}, {1810, 1839}, {1840, 1866}, {1869, 1957},
9988
  {1958, 1968}, {1969, 1969}, {1984, 1993}, {1994, 2026},
9989
  {2027, 2035}, {2036, 2037}, {2042, 2042}, {2045, 2045},
9990
  {2048, 2069}, {2070, 2073}, {2074, 2074}, {2075, 2083},
9991
  {2084, 2084}, {2085, 2087}, {2088, 2088}, {2089, 2093},
9992
  {2112, 2136}, {2137, 2139}, {2144, 2154}, {2160, 2183},
9993
  {2185, 2191}, {2199, 2207}, {2208, 2248}, {2249, 2249},
9994
  {2250, 2273}, {2275, 2306}, {2307, 2307}, {2308, 2361},
9995
  {2362, 2362}, {2363, 2363}, {2364, 2364}, {2365, 2365},
9996
  {2366, 2368}, {2369, 2376}, {2377, 2380}, {2381, 2381},
9997
  {2382, 2383}, {2384, 2384}, {2385, 2391}, {2392, 2401},
9998
  {2402, 2403}, {2406, 2415}, {2417, 2417}, {2418, 2432},
9999
  {2433, 2433}, {2434, 2435}, {2437, 2444}, {2447, 2448},
10000
  {2451, 2472}, {2474, 2480}, {2482, 2482}, {2486, 2489},
10001
  {2492, 2492}, {2493, 2493}, {2494, 2496}, {2497, 2500},
10002
  {2503, 2504}, {2507, 2508}, {2509, 2509}, {2510, 2510},
10003
  {2519, 2519}, {2524, 2525}, {2527, 2529}, {2530, 2531},
10004
  {2534, 2543}, {2544, 2545}, {2556, 2556}, {2558, 2558},
10005
  {2561, 2562}, {2563, 2563}, {2565, 2570}, {2575, 2576},
10006
  {2579, 2600}, {2602, 2608}, {2610, 2611}, {2613, 2614},
10007
  {2616, 2617}, {2620, 2620}, {2622, 2624}, {2625, 2626},
10008
  {2631, 2632}, {2635, 2637}, {2641, 2641}, {2649, 2652},
10009
  {2654, 2654}, {2662, 2671}, {2672, 2673}, {2674, 2676},
10010
  {2677, 2677}, {2689, 2690}, {2691, 2691}, {2693, 2701},
10011
  {2703, 2705}, {2707, 2728}, {2730, 2736}, {2738, 2739},
10012
  {2741, 2745}, {2748, 2748}, {2749, 2749}, {2750, 2752},
10013
  {2753, 2757}, {2759, 2760}, {2761, 2761}, {2763, 2764},
10014
  {2765, 2765}, {2768, 2768}, {2784, 2785}, {2786, 2787},
10015
  {2790, 2799}, {2809, 2809}, {2810, 2815}, {2817, 2817},
10016
  {2818, 2819}, {2821, 2828}, {2831, 2832}, {2835, 2856},
10017
  {2858, 2864}, {2866, 2867}, {2869, 2873}, {2876, 2876},
10018
  {2877, 2877}, {2878, 2878}, {2879, 2879}, {2880, 2880},
10019
  {2881, 2884}, {2887, 2888}, {2891, 2892}, {2893, 2893},
10020
  {2901, 2902}, {2903, 2903}, {2908, 2909}, {2911, 2913},
10021
  {2914, 2915}, {2918, 2927}, {2929, 2929}, {2946, 2946},
10022
  {2947, 2947}, {2949, 2954}, {2958, 2960}, {2962, 2965},
10023
  {2969, 2970}, {2972, 2972}, {2974, 2975}, {2979, 2980},
10024
  {2984, 2986}, {2990, 3001}, {3006, 3007}, {3008, 3008},
10025
  {3009, 3010}, {3014, 3016}, {3018, 3020}, {3021, 3021},
10026
  {3024, 3024}, {3031, 3031}, {3046, 3055}, {3072, 3072},
10027
  {3073, 3075}, {3076, 3076}, {3077, 3084}, {3086, 3088},
10028
  {3090, 3112}, {3114, 3129}, {3132, 3132}, {3133, 3133},
10029
  {3134, 3136}, {3137, 3140}, {3142, 3144}, {3146, 3149},
10030
  {3157, 3158}, {3160, 3162}, {3164, 3165}, {3168, 3169},
10031
  {3170, 3171}, {3174, 3183}, {3200, 3200}, {3201, 3201},
10032
  {3202, 3203}, {3205, 3212}, {3214, 3216}, {3218, 3240},
10033
  {3242, 3251}, {3253, 3257}, {3260, 3260}, {3261, 3261},
10034
  {3262, 3262}, {3263, 3263}, {3264, 3268}, {3270, 3270},
10035
  {3271, 3272}, {3274, 3275}, {3276, 3277}, {3285, 3286},
10036
  {3292, 3294}, {3296, 3297}, {3298, 3299}, {3302, 3311},
10037
  {3313, 3314}, {3315, 3315}, {3328, 3329}, {3330, 3331},
10038
  {3332, 3340}, {3342, 3344}, {3346, 3386}, {3387, 3388},
10039
  {3389, 3389}, {3390, 3392}, {3393, 3396}, {3398, 3400},
10040
  {3402, 3404}, {3405, 3405}, {3406, 3406}, {3412, 3414},
10041
  {3415, 3415}, {3423, 3425}, {3426, 3427}, {3430, 3439},
10042
  {3450, 3455}, {3457, 3457}, {3458, 3459}, {3461, 3478},
10043
  {3482, 3505}, {3507, 3515}, {3517, 3517}, {3520, 3526},
10044
  {3530, 3530}, {3535, 3537}, {3538, 3540}, {3542, 3542},
10045
  {3544, 3551}, {3558, 3567}, {3570, 3571}, {3585, 3632},
10046
  {3633, 3633}, {3634, 3635}, {3636, 3642}, {3648, 3653},
10047
  {3654, 3654}, {3655, 3662}, {3664, 3673}, {3713, 3714},
10048
  {3716, 3716}, {3718, 3722}, {3724, 3747}, {3749, 3749},
10049
  {3751, 3760}, {3761, 3761}, {3762, 3763}, {3764, 3772},
10050
  {3773, 3773}, {3776, 3780}, {3782, 3782}, {3784, 3790},
10051
  {3792, 3801}, {3804, 3807}, {3840, 3840}, {3864, 3865},
10052
  {3872, 3881}, {3893, 3893}, {3895, 3895}, {3897, 3897},
10053
  {3902, 3903}, {3904, 3911}, {3913, 3948}, {3953, 3966},
10054
  {3967, 3967}, {3968, 3972}, {3974, 3975}, {3976, 3980},
10055
  {3981, 3991}, {3993, 4028}, {4038, 4038}, {4096, 4138},
10056
  {4139, 4140}, {4141, 4144}, {4145, 4145}, {4146, 4151},
10057
  {4152, 4152}, {4153, 4154}, {4155, 4156}, {4157, 4158},
10058
  {4159, 4159}, {4160, 4169}, {4176, 4181}, {4182, 4183},
10059
  {4184, 4185}, {4186, 4189}, {4190, 4192}, {4193, 4193},
10060
  {4194, 4196}, {4197, 4198}, {4199, 4205}, {4206, 4208},
10061
  {4209, 4212}, {4213, 4225}, {4226, 4226}, {4227, 4228},
10062
  {4229, 4230}, {4231, 4236}, {4237, 4237}, {4238, 4238},
10063
  {4239, 4239}, {4240, 4249}, {4250, 4252}, {4253, 4253},
10064
  {4256, 4293}, {4295, 4295}, {4301, 4301}, {4304, 4346},
10065
  {4348, 4348}, {4349, 4351}, {4352, 4680}, {4682, 4685},
10066
  {4688, 4694}, {4696, 4696}, {4698, 4701}, {4704, 4744},
10067
  {4746, 4749}, {4752, 4784}, {4786, 4789}, {4792, 4798},
10068
  {4800, 4800}, {4802, 4805}, {4808, 4822}, {4824, 4880},
10069
  {4882, 4885}, {4888, 4954}, {4957, 4959}, {4969, 4977},
10070
  {4992, 5007}, {5024, 5109}, {5112, 5117}, {5121, 5740},
10071
  {5743, 5759}, {5761, 5786}, {5792, 5866}, {5870, 5872},
10072
  {5873, 5880}, {5888, 5905}, {5906, 5908}, {5909, 5909},
10073
  {5919, 5937}, {5938, 5939}, {5940, 5940}, {5952, 5969},
10074
  {5970, 5971}, {5984, 5996}, {5998, 6000}, {6002, 6003},
10075
  {6016, 6067}, {6068, 6069}, {6070, 6070}, {6071, 6077},
10076
  {6078, 6085}, {6086, 6086}, {6087, 6088}, {6089, 6099},
10077
  {6103, 6103}, {6108, 6108}, {6109, 6109}, {6112, 6121},
10078
  {6155, 6157}, {6159, 6159}, {6160, 6169}, {6176, 6210},
10079
  {6211, 6211}, {6212, 6264}, {6272, 6276}, {6277, 6278},
10080
  {6279, 6312}, {6313, 6313}, {6314, 6314}, {6320, 6389},
10081
  {6400, 6430}, {6432, 6434}, {6435, 6438}, {6439, 6440},
10082
  {6441, 6443}, {6448, 6449}, {6450, 6450}, {6451, 6456},
10083
  {6457, 6459}, {6470, 6479}, {6480, 6509}, {6512, 6516},
10084
  {6528, 6571}, {6576, 6601}, {6608, 6617}, {6618, 6618},
10085
  {6656, 6678}, {6679, 6680}, {6681, 6682}, {6683, 6683},
10086
  {6688, 6740}, {6741, 6741}, {6742, 6742}, {6743, 6743},
10087
  {6744, 6750}, {6752, 6752}, {6753, 6753}, {6754, 6754},
10088
  {6755, 6756}, {6757, 6764}, {6765, 6770}, {6771, 6780},
10089
  {6783, 6783}, {6784, 6793}, {6800, 6809}, {6823, 6823},
10090
  {6832, 6845}, {6847, 6877}, {6880, 6891}, {6912, 6915},
10091
  {6916, 6916}, {6917, 6963}, {6964, 6964}, {6965, 6965},
10092
  {6966, 6970}, {6971, 6971}, {6972, 6972}, {6973, 6977},
10093
  {6978, 6978}, {6979, 6980}, {6981, 6988}, {6992, 7001},
10094
  {7019, 7027}, {7040, 7041}, {7042, 7042}, {7043, 7072},
10095
  {7073, 7073}, {7074, 7077}, {7078, 7079}, {7080, 7081},
10096
  {7082, 7082}, {7083, 7085}, {7086, 7087}, {7088, 7097},
10097
  {7098, 7141}, {7142, 7142}, {7143, 7143}, {7144, 7145},
10098
  {7146, 7148}, {7149, 7149}, {7150, 7150}, {7151, 7153},
10099
  {7154, 7155}, {7168, 7203}, {7204, 7211}, {7212, 7219},
10100
  {7220, 7221}, {7222, 7223}, {7232, 7241}, {7245, 7247},
10101
  {7248, 7257}, {7258, 7287}, {7288, 7293}, {7296, 7306},
10102
  {7312, 7354}, {7357, 7359}, {7376, 7378}, {7380, 7392},
10103
  {7393, 7393}, {7394, 7400}, {7401, 7404}, {7405, 7405},
10104
  {7406, 7411}, {7412, 7412}, {7413, 7414}, {7415, 7415},
10105
  {7416, 7417}, {7418, 7418}, {7424, 7467}, {7468, 7530},
10106
  {7531, 7543}, {7544, 7544}, {7545, 7578}, {7579, 7615},
10107
  {7616, 7679}, {7680, 7957}, {7960, 7965}, {7968, 8005},
10108
  {8008, 8013}, {8016, 8023}, {8025, 8025}, {8027, 8027},
10109
  {8029, 8029}, {8031, 8061}, {8064, 8116}, {8118, 8124},
10110
  {8126, 8126}, {8130, 8132}, {8134, 8140}, {8144, 8147},
10111
  {8150, 8155}, {8160, 8172}, {8178, 8180}, {8182, 8188},
10112
  {8204, 8205}, {8255, 8256}, {8276, 8276}, {8305, 8305},
10113
  {8319, 8319}, {8336, 8348}, {8400, 8412}, {8417, 8417},
10114
  {8421, 8432}, {8450, 8450}, {8455, 8455}, {8458, 8467},
10115
  {8469, 8469}, {8472, 8472}, {8473, 8477}, {8484, 8484},
10116
  {8486, 8486}, {8488, 8488}, {8490, 8493}, {8494, 8494},
10117
  {8495, 8500}, {8501, 8504}, {8505, 8505}, {8508, 8511},
10118
  {8517, 8521}, {8526, 8526}, {8544, 8578}, {8579, 8580},
10119
  {8581, 8584}, {11264, 11387}, {11388, 11389}, {11390, 11492},
10120
  {11499, 11502}, {11503, 11505}, {11506, 11507}, {11520, 11557},
10121
  {11559, 11559}, {11565, 11565}, {11568, 11623}, {11631, 11631},
10122
  {11647, 11647}, {11648, 11670}, {11680, 11686}, {11688, 11694},
10123
  {11696, 11702}, {11704, 11710}, {11712, 11718}, {11720, 11726},
10124
  {11728, 11734}, {11736, 11742}, {11744, 11775}, {12293, 12293},
10125
  {12294, 12294}, {12295, 12295}, {12321, 12329}, {12330, 12333},
10126
  {12334, 12335}, {12337, 12341}, {12344, 12346}, {12347, 12347},
10127
  {12348, 12348}, {12353, 12438}, {12441, 12442}, {12443, 12444},
10128
  {12445, 12446}, {12447, 12447}, {12449, 12538}, {12539, 12539},
10129
  {12540, 12542}, {12543, 12543}, {12549, 12591}, {12593, 12686},
10130
  {12704, 12735}, {12784, 12799}, {13312, 19903}, {19968, 40980},
10131
  {40981, 40981}, {40982, 42124}, {42192, 42231}, {42232, 42237},
10132
  {42240, 42507}, {42508, 42508}, {42512, 42527}, {42528, 42537},
10133
  {42538, 42539}, {42560, 42605}, {42606, 42606}, {42607, 42607},
10134
  {42612, 42621}, {42623, 42623}, {42624, 42651}, {42652, 42653},
10135
  {42654, 42655}, {42656, 42725}, {42726, 42735}, {42736, 42737},
10136
  {42775, 42783}, {42786, 42863}, {42864, 42864}, {42865, 42887},
10137
  {42888, 42888}, {42891, 42894}, {42895, 42895}, {42896, 42972},
10138
  {42993, 42996}, {42997, 42998}, {42999, 42999}, {43000, 43001},
10139
  {43002, 43002}, {43003, 43009}, {43010, 43010}, {43011, 43013},
10140
  {43014, 43014}, {43015, 43018}, {43019, 43019}, {43020, 43042},
10141
  {43043, 43044}, {43045, 43046}, {43047, 43047}, {43052, 43052},
10142
  {43072, 43123}, {43136, 43137}, {43138, 43187}, {43188, 43203},
10143
  {43204, 43205}, {43216, 43225}, {43232, 43249}, {43250, 43255},
10144
  {43259, 43259}, {43261, 43262}, {43263, 43263}, {43264, 43273},
10145
  {43274, 43301}, {43302, 43309}, {43312, 43334}, {43335, 43345},
10146
  {43346, 43347}, {43360, 43388}, {43392, 43394}, {43395, 43395},
10147
  {43396, 43442}, {43443, 43443}, {43444, 43445}, {43446, 43449},
10148
  {43450, 43451}, {43452, 43453}, {43454, 43456}, {43471, 43471},
10149
  {43472, 43481}, {43488, 43492}, {43493, 43493}, {43494, 43494},
10150
  {43495, 43503}, {43504, 43513}, {43514, 43518}, {43520, 43560},
10151
  {43561, 43566}, {43567, 43568}, {43569, 43570}, {43571, 43572},
10152
  {43573, 43574}, {43584, 43586}, {43587, 43587}, {43588, 43595},
10153
  {43596, 43596}, {43597, 43597}, {43600, 43609}, {43616, 43631},
10154
  {43632, 43632}, {43633, 43638}, {43642, 43642}, {43643, 43643},
10155
  {43644, 43644}, {43645, 43645}, {43646, 43695}, {43696, 43696},
10156
  {43697, 43697}, {43698, 43700}, {43701, 43702}, {43703, 43704},
10157
  {43705, 43709}, {43710, 43711}, {43712, 43712}, {43713, 43713},
10158
  {43714, 43714}, {43739, 43740}, {43741, 43741}, {43744, 43754},
10159
  {43755, 43755}, {43756, 43757}, {43758, 43759}, {43762, 43762},
10160
  {43763, 43764}, {43765, 43765}, {43766, 43766}, {43777, 43782},
10161
  {43785, 43790}, {43793, 43798}, {43808, 43814}, {43816, 43822},
10162
  {43824, 43866}, {43868, 43871}, {43872, 43880}, {43881, 43881},
10163
  {43888, 43967}, {43968, 44002}, {44003, 44004}, {44005, 44005},
10164
  {44006, 44007}, {44008, 44008}, {44009, 44010}, {44012, 44012},
10165
  {44013, 44013}, {44016, 44025}, {44032, 55203}, {55216, 55238},
10166
  {55243, 55291}, {63744, 64109}, {64112, 64217}, {64256, 64262},
10167
  {64275, 64279}, {64285, 64285}, {64286, 64286}, {64287, 64296},
10168
  {64298, 64310}, {64312, 64316}, {64318, 64318}, {64320, 64321},
10169
  {64323, 64324}, {64326, 64433}, {64467, 64829}, {64848, 64911},
10170
  {64914, 64967}, {65008, 65019}, {65024, 65039}, {65056, 65071},
10171
  {65075, 65076}, {65101, 65103}, {65136, 65140}, {65142, 65276},
10172
  {65296, 65305}, {65313, 65338}, {65343, 65343}, {65345, 65370},
10173
  {65381, 65381}, {65382, 65391}, {65392, 65392}, {65393, 65437},
10174
  {65438, 65439}, {65440, 65470}, {65474, 65479}, {65482, 65487},
10175
  {65490, 65495}, {65498, 65500}, {65536, 65547}, {65549, 65574},
10176
  {65576, 65594}, {65596, 65597}, {65599, 65613}, {65616, 65629},
10177
  {65664, 65786}, {65856, 65908}, {66045, 66045}, {66176, 66204},
10178
  {66208, 66256}, {66272, 66272}, {66304, 66335}, {66349, 66368},
10179
  {66369, 66369}, {66370, 66377}, {66378, 66378}, {66384, 66421},
10180
  {66422, 66426}, {66432, 66461}, {66464, 66499}, {66504, 66511},
10181
  {66513, 66517}, {66560, 66639}, {66640, 66717}, {66720, 66729},
10182
  {66736, 66771}, {66776, 66811}, {66816, 66855}, {66864, 66915},
10183
  {66928, 66938}, {66940, 66954}, {66956, 66962}, {66964, 66965},
10184
  {66967, 66977}, {66979, 66993}, {66995, 67001}, {67003, 67004},
10185
  {67008, 67059}, {67072, 67382}, {67392, 67413}, {67424, 67431},
10186
  {67456, 67461}, {67463, 67504}, {67506, 67514}, {67584, 67589},
10187
  {67592, 67592}, {67594, 67637}, {67639, 67640}, {67644, 67644},
10188
  {67647, 67669}, {67680, 67702}, {67712, 67742}, {67808, 67826},
10189
  {67828, 67829}, {67840, 67861}, {67872, 67897}, {67904, 67929},
10190
  {67968, 68023}, {68030, 68031}, {68096, 68096}, {68097, 68099},
10191
  {68101, 68102}, {68108, 68111}, {68112, 68115}, {68117, 68119},
10192
  {68121, 68149}, {68152, 68154}, {68159, 68159}, {68192, 68220},
10193
  {68224, 68252}, {68288, 68295}, {68297, 68324}, {68325, 68326},
10194
  {68352, 68405}, {68416, 68437}, {68448, 68466}, {68480, 68497},
10195
  {68608, 68680}, {68736, 68786}, {68800, 68850}, {68864, 68899},
10196
  {68900, 68903}, {68912, 68921}, {68928, 68937}, {68938, 68941},
10197
  {68942, 68942}, {68943, 68943}, {68944, 68965}, {68969, 68973},
10198
  {68975, 68975}, {68976, 68997}, {69248, 69289}, {69291, 69292},
10199
  {69296, 69297}, {69314, 69316}, {69317, 69317}, {69318, 69319},
10200
  {69370, 69375}, {69376, 69404}, {69415, 69415}, {69424, 69445},
10201
  {69446, 69456}, {69488, 69505}, {69506, 69509}, {69552, 69572},
10202
  {69600, 69622}, {69632, 69632}, {69633, 69633}, {69634, 69634},
10203
  {69635, 69687}, {69688, 69702}, {69734, 69743}, {69744, 69744},
10204
  {69745, 69746}, {69747, 69748}, {69749, 69749}, {69759, 69761},
10205
  {69762, 69762}, {69763, 69807}, {69808, 69810}, {69811, 69814},
10206
  {69815, 69816}, {69817, 69818}, {69826, 69826}, {69840, 69864},
10207
  {69872, 69881}, {69888, 69890}, {69891, 69926}, {69927, 69931},
10208
  {69932, 69932}, {69933, 69940}, {69942, 69951}, {69956, 69956},
10209
  {69957, 69958}, {69959, 69959}, {69968, 70002}, {70003, 70003},
10210
  {70006, 70006}, {70016, 70017}, {70018, 70018}, {70019, 70066},
10211
  {70067, 70069}, {70070, 70078}, {70079, 70080}, {70081, 70084},
10212
  {70089, 70092}, {70094, 70094}, {70095, 70095}, {70096, 70105},
10213
  {70106, 70106}, {70108, 70108}, {70144, 70161}, {70163, 70187},
10214
  {70188, 70190}, {70191, 70193}, {70194, 70195}, {70196, 70196},
10215
  {70197, 70197}, {70198, 70199}, {70206, 70206}, {70207, 70208},
10216
  {70209, 70209}, {70272, 70278}, {70280, 70280}, {70282, 70285},
10217
  {70287, 70301}, {70303, 70312}, {70320, 70366}, {70367, 70367},
10218
  {70368, 70370}, {70371, 70378}, {70384, 70393}, {70400, 70401},
10219
  {70402, 70403}, {70405, 70412}, {70415, 70416}, {70419, 70440},
10220
  {70442, 70448}, {70450, 70451}, {70453, 70457}, {70459, 70460},
10221
  {70461, 70461}, {70462, 70463}, {70464, 70464}, {70465, 70468},
10222
  {70471, 70472}, {70475, 70477}, {70480, 70480}, {70487, 70487},
10223
  {70493, 70497}, {70498, 70499}, {70502, 70508}, {70512, 70516},
10224
  {70528, 70537}, {70539, 70539}, {70542, 70542}, {70544, 70581},
10225
  {70583, 70583}, {70584, 70586}, {70587, 70592}, {70594, 70594},
10226
  {70597, 70597}, {70599, 70602}, {70604, 70605}, {70606, 70606},
10227
  {70607, 70607}, {70608, 70608}, {70609, 70609}, {70610, 70610},
10228
  {70611, 70611}, {70625, 70626}, {70656, 70708}, {70709, 70711},
10229
  {70712, 70719}, {70720, 70721}, {70722, 70724}, {70725, 70725},
10230
  {70726, 70726}, {70727, 70730}, {70736, 70745}, {70750, 70750},
10231
  {70751, 70753}, {70784, 70831}, {70832, 70834}, {70835, 70840},
10232
  {70841, 70841}, {70842, 70842}, {70843, 70846}, {70847, 70848},
10233
  {70849, 70849}, {70850, 70851}, {70852, 70853}, {70855, 70855},
10234
  {70864, 70873}, {71040, 71086}, {71087, 71089}, {71090, 71093},
10235
  {71096, 71099}, {71100, 71101}, {71102, 71102}, {71103, 71104},
10236
  {71128, 71131}, {71132, 71133}, {71168, 71215}, {71216, 71218},
10237
  {71219, 71226}, {71227, 71228}, {71229, 71229}, {71230, 71230},
10238
  {71231, 71232}, {71236, 71236}, {71248, 71257}, {71296, 71338},
10239
  {71339, 71339}, {71340, 71340}, {71341, 71341}, {71342, 71343},
10240
  {71344, 71349}, {71350, 71350}, {71351, 71351}, {71352, 71352},
10241
  {71360, 71369}, {71376, 71395}, {71424, 71450}, {71453, 71453},
10242
  {71454, 71454}, {71455, 71455}, {71456, 71457}, {71458, 71461},
10243
  {71462, 71462}, {71463, 71467}, {71472, 71481}, {71488, 71494},
10244
  {71680, 71723}, {71724, 71726}, {71727, 71735}, {71736, 71736},
10245
  {71737, 71738}, {71840, 71903}, {71904, 71913}, {71935, 71942},
10246
  {71945, 71945}, {71948, 71955}, {71957, 71958}, {71960, 71983},
10247
  {71984, 71989}, {71991, 71992}, {71995, 71996}, {71997, 71997},
10248
  {71998, 71998}, {71999, 71999}, {72000, 72000}, {72001, 72001},
10249
  {72002, 72002}, {72003, 72003}, {72016, 72025}, {72096, 72103},
10250
  {72106, 72144}, {72145, 72147}, {72148, 72151}, {72154, 72155},
10251
  {72156, 72159}, {72160, 72160}, {72161, 72161}, {72163, 72163},
10252
  {72164, 72164}, {72192, 72192}, {72193, 72202}, {72203, 72242},
10253
  {72243, 72248}, {72249, 72249}, {72250, 72250}, {72251, 72254},
10254
  {72263, 72263}, {72272, 72272}, {72273, 72278}, {72279, 72280},
10255
  {72281, 72283}, {72284, 72329}, {72330, 72342}, {72343, 72343},
10256
  {72344, 72345}, {72349, 72349}, {72368, 72440}, {72544, 72544},
10257
  {72545, 72545}, {72546, 72548}, {72549, 72549}, {72550, 72550},
10258
  {72551, 72551}, {72640, 72672}, {72688, 72697}, {72704, 72712},
10259
  {72714, 72750}, {72751, 72751}, {72752, 72758}, {72760, 72765},
10260
  {72766, 72766}, {72767, 72767}, {72768, 72768}, {72784, 72793},
10261
  {72818, 72847}, {72850, 72871}, {72873, 72873}, {72874, 72880},
10262
  {72881, 72881}, {72882, 72883}, {72884, 72884}, {72885, 72886},
10263
  {72960, 72966}, {72968, 72969}, {72971, 73008}, {73009, 73014},
10264
  {73018, 73018}, {73020, 73021}, {73023, 73029}, {73030, 73030},
10265
  {73031, 73031}, {73040, 73049}, {73056, 73061}, {73063, 73064},
10266
  {73066, 73097}, {73098, 73102}, {73104, 73105}, {73107, 73108},
10267
  {73109, 73109}, {73110, 73110}, {73111, 73111}, {73112, 73112},
10268
  {73120, 73129}, {73136, 73176}, {73177, 73177}, {73178, 73179},
10269
  {73184, 73193}, {73440, 73458}, {73459, 73460}, {73461, 73462},
10270
  {73472, 73473}, {73474, 73474}, {73475, 73475}, {73476, 73488},
10271
  {73490, 73523}, {73524, 73525}, {73526, 73530}, {73534, 73535},
10272
  {73536, 73536}, {73537, 73537}, {73538, 73538}, {73552, 73561},
10273
  {73562, 73562}, {73648, 73648}, {73728, 74649}, {74752, 74862},
10274
  {74880, 75075}, {77712, 77808}, {77824, 78895}, {78912, 78912},
10275
  {78913, 78918}, {78919, 78933}, {78944, 82938}, {82944, 83526},
10276
  {90368, 90397}, {90398, 90409}, {90410, 90412}, {90413, 90415},
10277
  {90416, 90425}, {92160, 92728}, {92736, 92766}, {92768, 92777},
10278
  {92784, 92862}, {92864, 92873}, {92880, 92909}, {92912, 92916},
10279
  {92928, 92975}, {92976, 92982}, {92992, 92995}, {93008, 93017},
10280
  {93027, 93047}, {93053, 93071}, {93504, 93506}, {93507, 93546},
10281
  {93547, 93548}, {93552, 93561}, {93760, 93823}, {93856, 93880},
10282
  {93883, 93907}, {93952, 94026}, {94031, 94031}, {94032, 94032},
10283
  {94033, 94087}, {94095, 94098}, {94099, 94111}, {94176, 94177},
10284
  {94179, 94179}, {94180, 94180}, {94192, 94193}, {94194, 94195},
10285
  {94196, 94198}, {94208, 101589}, {101631, 101662}, {101760, 101874},
10286
  {110576, 110579}, {110581, 110587}, {110589, 110590}, {110592, 110882},
10287
  {110898, 110898}, {110928, 110930}, {110933, 110933}, {110948, 110951},
10288
  {110960, 111355}, {113664, 113770}, {113776, 113788}, {113792, 113800},
10289
  {113808, 113817}, {113821, 113822}, {118000, 118009}, {118528, 118573},
10290
  {118576, 118598}, {119141, 119142}, {119143, 119145}, {119149, 119154},
10291
  {119163, 119170}, {119173, 119179}, {119210, 119213}, {119362, 119364},
10292
  {119808, 119892}, {119894, 119964}, {119966, 119967}, {119970, 119970},
10293
  {119973, 119974}, {119977, 119980}, {119982, 119993}, {119995, 119995},
10294
  {119997, 120003}, {120005, 120069}, {120071, 120074}, {120077, 120084},
10295
  {120086, 120092}, {120094, 120121}, {120123, 120126}, {120128, 120132},
10296
  {120134, 120134}, {120138, 120144}, {120146, 120485}, {120488, 120512},
10297
  {120514, 120538}, {120540, 120570}, {120572, 120596}, {120598, 120628},
10298
  {120630, 120654}, {120656, 120686}, {120688, 120712}, {120714, 120744},
10299
  {120746, 120770}, {120772, 120779}, {120782, 120831}, {121344, 121398},
10300
  {121403, 121452}, {121461, 121461}, {121476, 121476}, {121499, 121503},
10301
  {121505, 121519}, {122624, 122633}, {122634, 122634}, {122635, 122654},
10302
  {122661, 122666}, {122880, 122886}, {122888, 122904}, {122907, 122913},
10303
  {122915, 122916}, {122918, 122922}, {122928, 122989}, {123023, 123023},
10304
  {123136, 123180}, {123184, 123190}, {123191, 123197}, {123200, 123209},
10305
  {123214, 123214}, {123536, 123565}, {123566, 123566}, {123584, 123627},
10306
  {123628, 123631}, {123632, 123641}, {124112, 124138}, {124139, 124139},
10307
  {124140, 124143}, {124144, 124153}, {124368, 124397}, {124398, 124399},
10308
  {124400, 124400}, {124401, 124410}, {124608, 124638}, {124640, 124642},
10309
  {124643, 124643}, {124644, 124645}, {124646, 124646}, {124647, 124653},
10310
  {124654, 124655}, {124656, 124660}, {124661, 124661}, {124670, 124670},
10311
  {124671, 124671}, {124896, 124902}, {124904, 124907}, {124909, 124910},
10312
  {124912, 124926}, {124928, 125124}, {125136, 125142}, {125184, 125251},
10313
  {125252, 125258}, {125259, 125259}, {125264, 125273}, {126464, 126467},
10314
  {126469, 126495}, {126497, 126498}, {126500, 126500}, {126503, 126503},
10315
  {126505, 126514}, {126516, 126519}, {126521, 126521}, {126523, 126523},
10316
  {126530, 126530}, {126535, 126535}, {126537, 126537}, {126539, 126539},
10317
  {126541, 126543}, {126545, 126546}, {126548, 126548}, {126551, 126551},
10318
  {126553, 126553}, {126555, 126555}, {126557, 126557}, {126559, 126559},
10319
  {126561, 126562}, {126564, 126564}, {126567, 126570}, {126572, 126578},
10320
  {126580, 126583}, {126585, 126588}, {126590, 126590}, {126592, 126601},
10321
  {126603, 126619}, {126625, 126627}, {126629, 126633}, {126635, 126651},
10322
  {130032, 130041}, {131072, 173791}, {173824, 178205}, {178208, 183981},
10323
  {183984, 191456}, {191472, 192093}, {194560, 195101}, {196608, 201546},
10324
  {201552, 210041}, {917760, 917999}
10325
};
10326
const uint32_t id_start[776][2] =
10327
{
10328
  {65, 90}, {97, 122}, {170, 170}, {181, 181},
10329
  {186, 186}, {192, 214}, {216, 246}, {248, 442},
10330
  {443, 443}, {444, 447}, {448, 451}, {452, 659},
10331
  {660, 661}, {662, 687}, {688, 705}, {710, 721},
10332
  {736, 740}, {748, 748}, {750, 750}, {880, 883},
10333
  {884, 884}, {886, 887}, {890, 890}, {891, 893},
10334
  {895, 895}, {902, 902}, {904, 906}, {908, 908},
10335
  {910, 929}, {931, 1013}, {1015, 1153}, {1162, 1327},
10336
  {1329, 1366}, {1369, 1369}, {1376, 1416}, {1488, 1514},
10337
  {1519, 1522}, {1568, 1599}, {1600, 1600}, {1601, 1610},
10338
  {1646, 1647}, {1649, 1747}, {1749, 1749}, {1765, 1766},
10339
  {1774, 1775}, {1786, 1788}, {1791, 1791}, {1808, 1808},
10340
  {1810, 1839}, {1869, 1957}, {1969, 1969}, {1994, 2026},
10341
  {2036, 2037}, {2042, 2042}, {2048, 2069}, {2074, 2074},
10342
  {2084, 2084}, {2088, 2088}, {2112, 2136}, {2144, 2154},
10343
  {2160, 2183}, {2185, 2191}, {2208, 2248}, {2249, 2249},
10344
  {2308, 2361}, {2365, 2365}, {2384, 2384}, {2392, 2401},
10345
  {2417, 2417}, {2418, 2432}, {2437, 2444}, {2447, 2448},
10346
  {2451, 2472}, {2474, 2480}, {2482, 2482}, {2486, 2489},
10347
  {2493, 2493}, {2510, 2510}, {2524, 2525}, {2527, 2529},
10348
  {2544, 2545}, {2556, 2556}, {2565, 2570}, {2575, 2576},
10349
  {2579, 2600}, {2602, 2608}, {2610, 2611}, {2613, 2614},
10350
  {2616, 2617}, {2649, 2652}, {2654, 2654}, {2674, 2676},
10351
  {2693, 2701}, {2703, 2705}, {2707, 2728}, {2730, 2736},
10352
  {2738, 2739}, {2741, 2745}, {2749, 2749}, {2768, 2768},
10353
  {2784, 2785}, {2809, 2809}, {2821, 2828}, {2831, 2832},
10354
  {2835, 2856}, {2858, 2864}, {2866, 2867}, {2869, 2873},
10355
  {2877, 2877}, {2908, 2909}, {2911, 2913}, {2929, 2929},
10356
  {2947, 2947}, {2949, 2954}, {2958, 2960}, {2962, 2965},
10357
  {2969, 2970}, {2972, 2972}, {2974, 2975}, {2979, 2980},
10358
  {2984, 2986}, {2990, 3001}, {3024, 3024}, {3077, 3084},
10359
  {3086, 3088}, {3090, 3112}, {3114, 3129}, {3133, 3133},
10360
  {3160, 3162}, {3164, 3165}, {3168, 3169}, {3200, 3200},
10361
  {3205, 3212}, {3214, 3216}, {3218, 3240}, {3242, 3251},
10362
  {3253, 3257}, {3261, 3261}, {3292, 3294}, {3296, 3297},
10363
  {3313, 3314}, {3332, 3340}, {3342, 3344}, {3346, 3386},
10364
  {3389, 3389}, {3406, 3406}, {3412, 3414}, {3423, 3425},
10365
  {3450, 3455}, {3461, 3478}, {3482, 3505}, {3507, 3515},
10366
  {3517, 3517}, {3520, 3526}, {3585, 3632}, {3634, 3635},
10367
  {3648, 3653}, {3654, 3654}, {3713, 3714}, {3716, 3716},
10368
  {3718, 3722}, {3724, 3747}, {3749, 3749}, {3751, 3760},
10369
  {3762, 3763}, {3773, 3773}, {3776, 3780}, {3782, 3782},
10370
  {3804, 3807}, {3840, 3840}, {3904, 3911}, {3913, 3948},
10371
  {3976, 3980}, {4096, 4138}, {4159, 4159}, {4176, 4181},
10372
  {4186, 4189}, {4193, 4193}, {4197, 4198}, {4206, 4208},
10373
  {4213, 4225}, {4238, 4238}, {4256, 4293}, {4295, 4295},
10374
  {4301, 4301}, {4304, 4346}, {4348, 4348}, {4349, 4351},
10375
  {4352, 4680}, {4682, 4685}, {4688, 4694}, {4696, 4696},
10376
  {4698, 4701}, {4704, 4744}, {4746, 4749}, {4752, 4784},
10377
  {4786, 4789}, {4792, 4798}, {4800, 4800}, {4802, 4805},
10378
  {4808, 4822}, {4824, 4880}, {4882, 4885}, {4888, 4954},
10379
  {4992, 5007}, {5024, 5109}, {5112, 5117}, {5121, 5740},
10380
  {5743, 5759}, {5761, 5786}, {5792, 5866}, {5870, 5872},
10381
  {5873, 5880}, {5888, 5905}, {5919, 5937}, {5952, 5969},
10382
  {5984, 5996}, {5998, 6000}, {6016, 6067}, {6103, 6103},
10383
  {6108, 6108}, {6176, 6210}, {6211, 6211}, {6212, 6264},
10384
  {6272, 6276}, {6277, 6278}, {6279, 6312}, {6314, 6314},
10385
  {6320, 6389}, {6400, 6430}, {6480, 6509}, {6512, 6516},
10386
  {6528, 6571}, {6576, 6601}, {6656, 6678}, {6688, 6740},
10387
  {6823, 6823}, {6917, 6963}, {6981, 6988}, {7043, 7072},
10388
  {7086, 7087}, {7098, 7141}, {7168, 7203}, {7245, 7247},
10389
  {7258, 7287}, {7288, 7293}, {7296, 7306}, {7312, 7354},
10390
  {7357, 7359}, {7401, 7404}, {7406, 7411}, {7413, 7414},
10391
  {7418, 7418}, {7424, 7467}, {7468, 7530}, {7531, 7543},
10392
  {7544, 7544}, {7545, 7578}, {7579, 7615}, {7680, 7957},
10393
  {7960, 7965}, {7968, 8005}, {8008, 8013}, {8016, 8023},
10394
  {8025, 8025}, {8027, 8027}, {8029, 8029}, {8031, 8061},
10395
  {8064, 8116}, {8118, 8124}, {8126, 8126}, {8130, 8132},
10396
  {8134, 8140}, {8144, 8147}, {8150, 8155}, {8160, 8172},
10397
  {8178, 8180}, {8182, 8188}, {8305, 8305}, {8319, 8319},
10398
  {8336, 8348}, {8450, 8450}, {8455, 8455}, {8458, 8467},
10399
  {8469, 8469}, {8472, 8472}, {8473, 8477}, {8484, 8484},
10400
  {8486, 8486}, {8488, 8488}, {8490, 8493}, {8494, 8494},
10401
  {8495, 8500}, {8501, 8504}, {8505, 8505}, {8508, 8511},
10402
  {8517, 8521}, {8526, 8526}, {8544, 8578}, {8579, 8580},
10403
  {8581, 8584}, {11264, 11387}, {11388, 11389}, {11390, 11492},
10404
  {11499, 11502}, {11506, 11507}, {11520, 11557}, {11559, 11559},
10405
  {11565, 11565}, {11568, 11623}, {11631, 11631}, {11648, 11670},
10406
  {11680, 11686}, {11688, 11694}, {11696, 11702}, {11704, 11710},
10407
  {11712, 11718}, {11720, 11726}, {11728, 11734}, {11736, 11742},
10408
  {12293, 12293}, {12294, 12294}, {12295, 12295}, {12321, 12329},
10409
  {12337, 12341}, {12344, 12346}, {12347, 12347}, {12348, 12348},
10410
  {12353, 12438}, {12443, 12444}, {12445, 12446}, {12447, 12447},
10411
  {12449, 12538}, {12540, 12542}, {12543, 12543}, {12549, 12591},
10412
  {12593, 12686}, {12704, 12735}, {12784, 12799}, {13312, 19903},
10413
  {19968, 40980}, {40981, 40981}, {40982, 42124}, {42192, 42231},
10414
  {42232, 42237}, {42240, 42507}, {42508, 42508}, {42512, 42527},
10415
  {42538, 42539}, {42560, 42605}, {42606, 42606}, {42623, 42623},
10416
  {42624, 42651}, {42652, 42653}, {42656, 42725}, {42726, 42735},
10417
  {42775, 42783}, {42786, 42863}, {42864, 42864}, {42865, 42887},
10418
  {42888, 42888}, {42891, 42894}, {42895, 42895}, {42896, 42972},
10419
  {42993, 42996}, {42997, 42998}, {42999, 42999}, {43000, 43001},
10420
  {43002, 43002}, {43003, 43009}, {43011, 43013}, {43015, 43018},
10421
  {43020, 43042}, {43072, 43123}, {43138, 43187}, {43250, 43255},
10422
  {43259, 43259}, {43261, 43262}, {43274, 43301}, {43312, 43334},
10423
  {43360, 43388}, {43396, 43442}, {43471, 43471}, {43488, 43492},
10424
  {43494, 43494}, {43495, 43503}, {43514, 43518}, {43520, 43560},
10425
  {43584, 43586}, {43588, 43595}, {43616, 43631}, {43632, 43632},
10426
  {43633, 43638}, {43642, 43642}, {43646, 43695}, {43697, 43697},
10427
  {43701, 43702}, {43705, 43709}, {43712, 43712}, {43714, 43714},
10428
  {43739, 43740}, {43741, 43741}, {43744, 43754}, {43762, 43762},
10429
  {43763, 43764}, {43777, 43782}, {43785, 43790}, {43793, 43798},
10430
  {43808, 43814}, {43816, 43822}, {43824, 43866}, {43868, 43871},
10431
  {43872, 43880}, {43881, 43881}, {43888, 43967}, {43968, 44002},
10432
  {44032, 55203}, {55216, 55238}, {55243, 55291}, {63744, 64109},
10433
  {64112, 64217}, {64256, 64262}, {64275, 64279}, {64285, 64285},
10434
  {64287, 64296}, {64298, 64310}, {64312, 64316}, {64318, 64318},
10435
  {64320, 64321}, {64323, 64324}, {64326, 64433}, {64467, 64829},
10436
  {64848, 64911}, {64914, 64967}, {65008, 65019}, {65136, 65140},
10437
  {65142, 65276}, {65313, 65338}, {65345, 65370}, {65382, 65391},
10438
  {65392, 65392}, {65393, 65437}, {65438, 65439}, {65440, 65470},
10439
  {65474, 65479}, {65482, 65487}, {65490, 65495}, {65498, 65500},
10440
  {65536, 65547}, {65549, 65574}, {65576, 65594}, {65596, 65597},
10441
  {65599, 65613}, {65616, 65629}, {65664, 65786}, {65856, 65908},
10442
  {66176, 66204}, {66208, 66256}, {66304, 66335}, {66349, 66368},
10443
  {66369, 66369}, {66370, 66377}, {66378, 66378}, {66384, 66421},
10444
  {66432, 66461}, {66464, 66499}, {66504, 66511}, {66513, 66517},
10445
  {66560, 66639}, {66640, 66717}, {66736, 66771}, {66776, 66811},
10446
  {66816, 66855}, {66864, 66915}, {66928, 66938}, {66940, 66954},
10447
  {66956, 66962}, {66964, 66965}, {66967, 66977}, {66979, 66993},
10448
  {66995, 67001}, {67003, 67004}, {67008, 67059}, {67072, 67382},
10449
  {67392, 67413}, {67424, 67431}, {67456, 67461}, {67463, 67504},
10450
  {67506, 67514}, {67584, 67589}, {67592, 67592}, {67594, 67637},
10451
  {67639, 67640}, {67644, 67644}, {67647, 67669}, {67680, 67702},
10452
  {67712, 67742}, {67808, 67826}, {67828, 67829}, {67840, 67861},
10453
  {67872, 67897}, {67904, 67929}, {67968, 68023}, {68030, 68031},
10454
  {68096, 68096}, {68112, 68115}, {68117, 68119}, {68121, 68149},
10455
  {68192, 68220}, {68224, 68252}, {68288, 68295}, {68297, 68324},
10456
  {68352, 68405}, {68416, 68437}, {68448, 68466}, {68480, 68497},
10457
  {68608, 68680}, {68736, 68786}, {68800, 68850}, {68864, 68899},
10458
  {68938, 68941}, {68942, 68942}, {68943, 68943}, {68944, 68965},
10459
  {68975, 68975}, {68976, 68997}, {69248, 69289}, {69296, 69297},
10460
  {69314, 69316}, {69317, 69317}, {69318, 69319}, {69376, 69404},
10461
  {69415, 69415}, {69424, 69445}, {69488, 69505}, {69552, 69572},
10462
  {69600, 69622}, {69635, 69687}, {69745, 69746}, {69749, 69749},
10463
  {69763, 69807}, {69840, 69864}, {69891, 69926}, {69956, 69956},
10464
  {69959, 69959}, {69968, 70002}, {70006, 70006}, {70019, 70066},
10465
  {70081, 70084}, {70106, 70106}, {70108, 70108}, {70144, 70161},
10466
  {70163, 70187}, {70207, 70208}, {70272, 70278}, {70280, 70280},
10467
  {70282, 70285}, {70287, 70301}, {70303, 70312}, {70320, 70366},
10468
  {70405, 70412}, {70415, 70416}, {70419, 70440}, {70442, 70448},
10469
  {70450, 70451}, {70453, 70457}, {70461, 70461}, {70480, 70480},
10470
  {70493, 70497}, {70528, 70537}, {70539, 70539}, {70542, 70542},
10471
  {70544, 70581}, {70583, 70583}, {70609, 70609}, {70611, 70611},
10472
  {70656, 70708}, {70727, 70730}, {70751, 70753}, {70784, 70831},
10473
  {70852, 70853}, {70855, 70855}, {71040, 71086}, {71128, 71131},
10474
  {71168, 71215}, {71236, 71236}, {71296, 71338}, {71352, 71352},
10475
  {71424, 71450}, {71488, 71494}, {71680, 71723}, {71840, 71903},
10476
  {71935, 71942}, {71945, 71945}, {71948, 71955}, {71957, 71958},
10477
  {71960, 71983}, {71999, 71999}, {72001, 72001}, {72096, 72103},
10478
  {72106, 72144}, {72161, 72161}, {72163, 72163}, {72192, 72192},
10479
  {72203, 72242}, {72250, 72250}, {72272, 72272}, {72284, 72329},
10480
  {72349, 72349}, {72368, 72440}, {72640, 72672}, {72704, 72712},
10481
  {72714, 72750}, {72768, 72768}, {72818, 72847}, {72960, 72966},
10482
  {72968, 72969}, {72971, 73008}, {73030, 73030}, {73056, 73061},
10483
  {73063, 73064}, {73066, 73097}, {73112, 73112}, {73136, 73176},
10484
  {73177, 73177}, {73178, 73179}, {73440, 73458}, {73474, 73474},
10485
  {73476, 73488}, {73490, 73523}, {73648, 73648}, {73728, 74649},
10486
  {74752, 74862}, {74880, 75075}, {77712, 77808}, {77824, 78895},
10487
  {78913, 78918}, {78944, 82938}, {82944, 83526}, {90368, 90397},
10488
  {92160, 92728}, {92736, 92766}, {92784, 92862}, {92880, 92909},
10489
  {92928, 92975}, {92992, 92995}, {93027, 93047}, {93053, 93071},
10490
  {93504, 93506}, {93507, 93546}, {93547, 93548}, {93760, 93823},
10491
  {93856, 93880}, {93883, 93907}, {93952, 94026}, {94032, 94032},
10492
  {94099, 94111}, {94176, 94177}, {94179, 94179}, {94194, 94195},
10493
  {94196, 94198}, {94208, 101589}, {101631, 101662}, {101760, 101874},
10494
  {110576, 110579}, {110581, 110587}, {110589, 110590}, {110592, 110882},
10495
  {110898, 110898}, {110928, 110930}, {110933, 110933}, {110948, 110951},
10496
  {110960, 111355}, {113664, 113770}, {113776, 113788}, {113792, 113800},
10497
  {113808, 113817}, {119808, 119892}, {119894, 119964}, {119966, 119967},
10498
  {119970, 119970}, {119973, 119974}, {119977, 119980}, {119982, 119993},
10499
  {119995, 119995}, {119997, 120003}, {120005, 120069}, {120071, 120074},
10500
  {120077, 120084}, {120086, 120092}, {120094, 120121}, {120123, 120126},
10501
  {120128, 120132}, {120134, 120134}, {120138, 120144}, {120146, 120485},
10502
  {120488, 120512}, {120514, 120538}, {120540, 120570}, {120572, 120596},
10503
  {120598, 120628}, {120630, 120654}, {120656, 120686}, {120688, 120712},
10504
  {120714, 120744}, {120746, 120770}, {120772, 120779}, {122624, 122633},
10505
  {122634, 122634}, {122635, 122654}, {122661, 122666}, {122928, 122989},
10506
  {123136, 123180}, {123191, 123197}, {123214, 123214}, {123536, 123565},
10507
  {123584, 123627}, {124112, 124138}, {124139, 124139}, {124368, 124397},
10508
  {124400, 124400}, {124608, 124638}, {124640, 124642}, {124644, 124645},
10509
  {124647, 124653}, {124656, 124660}, {124670, 124670}, {124671, 124671},
10510
  {124896, 124902}, {124904, 124907}, {124909, 124910}, {124912, 124926},
10511
  {124928, 125124}, {125184, 125251}, {125259, 125259}, {126464, 126467},
10512
  {126469, 126495}, {126497, 126498}, {126500, 126500}, {126503, 126503},
10513
  {126505, 126514}, {126516, 126519}, {126521, 126521}, {126523, 126523},
10514
  {126530, 126530}, {126535, 126535}, {126537, 126537}, {126539, 126539},
10515
  {126541, 126543}, {126545, 126546}, {126548, 126548}, {126551, 126551},
10516
  {126553, 126553}, {126555, 126555}, {126557, 126557}, {126559, 126559},
10517
  {126561, 126562}, {126564, 126564}, {126567, 126570}, {126572, 126578},
10518
  {126580, 126583}, {126585, 126588}, {126590, 126590}, {126592, 126601},
10519
  {126603, 126619}, {126625, 126627}, {126629, 126633}, {126635, 126651},
10520
  {131072, 173791}, {173824, 178205}, {178208, 183981}, {183984, 191456},
10521
  {191472, 192093}, {194560, 195101}, {196608, 201546}, {201552, 210041}
10522
};
10523
10524
10525
} // namespace ada::idna
10526
#endif // ADA_IDNA_IDENTIFIER_TABLES_H
10527
/* end file src/id_tables.cpp */
10528
10529
namespace ada::idna {
10530
43.4k
constexpr bool is_ascii_letter(char32_t c) noexcept {
10531
43.4k
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
10532
43.4k
}
10533
10534
7.81k
constexpr bool is_ascii_letter_or_digit(char32_t c) noexcept {
10535
7.81k
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
10536
5.67k
         (c >= '0' && c <= '9');
10537
7.81k
}
10538
10539
52.6k
bool valid_name_code_point(char32_t code_point, bool first) {
10540
  // https://tc39.es/ecma262/#prod-IdentifierStart
10541
10542
  // Fast paths
10543
52.6k
  if (first && (code_point == U'$' || code_point == U'_' ||
10544
43.4k
                is_ascii_letter(code_point))) {
10545
4.34k
    return true;
10546
4.34k
  }
10547
48.2k
  if (!first && (code_point == U'$' || is_ascii_letter_or_digit(code_point))) {
10548
3.34k
    return true;
10549
3.34k
  }
10550
10551
  // Minimal error handling for invalid code point
10552
44.9k
  if (code_point > 0x10FFFF) {
10553
0
    return false;
10554
0
  }
10555
44.9k
  if (code_point >= 0xD800 && code_point <= 0xDFFF) {
10556
0
    return false;
10557
0
  }
10558
10559
  // Slow path: binary search through the appropriate Unicode range table.
10560
  // Each entry is a [low, high] inclusive range.
10561
44.9k
  const std::span<const uint32_t[2]> ranges =
10562
44.9k
      first ? std::span<const uint32_t[2]>{ada::idna::id_start}
10563
44.9k
            : std::span<const uint32_t[2]>{ada::idna::id_continue};
10564
10565
44.9k
  const auto iter = std::ranges::lower_bound(
10566
44.9k
      ranges, code_point, {},
10567
452k
      [](const auto& range) { return range[1]; });  // project to range-high
10568
10569
44.9k
  return iter != ranges.end() && code_point >= (*iter)[0];
10570
44.9k
}
10571
}  // namespace ada::idna
10572
/* end file src/identifier.cpp */
10573
/* end file src/idna.cpp */
10574
/* end file src/ada_idna.cpp */
10575
ADA_POP_DISABLE_WARNINGS
10576
10577
#include <algorithm>
10578
#if ADA_SSSE3
10579
#include <tmmintrin.h>
10580
#elif ADA_NEON
10581
#include <arm_neon.h>
10582
#elif ADA_SSE2
10583
#include <emmintrin.h>
10584
#elif ADA_LSX
10585
#include <lsxintrin.h>
10586
#elif ADA_RVV
10587
#include <riscv_vector.h>
10588
#endif
10589
10590
#include <ranges>
10591
10592
namespace ada::unicode {
10593
10594
5.29M
constexpr bool is_tabs_or_newline(char c) noexcept {
10595
5.29M
  return c == '\r' || c == '\n' || c == '\t';
10596
5.29M
}
10597
10598
721k
constexpr uint64_t broadcast(uint8_t v) noexcept {
10599
721k
  return 0x101010101010101ull * v;
10600
721k
}
10601
10602
240k
constexpr bool to_lower_ascii(char* input, size_t length) noexcept {
10603
240k
  uint64_t broadcast_80 = broadcast(0x80);
10604
240k
  uint64_t broadcast_Ap = broadcast(128 - 'A');
10605
240k
  uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
10606
240k
  uint64_t non_ascii = 0;
10607
240k
  size_t i = 0;
10608
10609
240k
  for (; i + 7 < length; i += 8) {
10610
84
    uint64_t word{};
10611
84
    memcpy(&word, input + i, sizeof(word));
10612
84
    non_ascii |= (word & broadcast_80);
10613
84
    word ^=
10614
84
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
10615
84
    memcpy(input + i, &word, sizeof(word));
10616
84
  }
10617
240k
  if (i < length) {
10618
240k
    uint64_t word{};
10619
240k
    memcpy(&word, input + i, length - i);
10620
240k
    non_ascii |= (word & broadcast_80);
10621
240k
    word ^=
10622
240k
        (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
10623
240k
    memcpy(input + i, &word, length - i);
10624
240k
  }
10625
240k
  return non_ascii == 0;
10626
240k
}
10627
#if ADA_SSSE3
10628
ada_really_inline bool has_tabs_or_newline(
10629
    std::string_view user_input) noexcept {
10630
  // first check for short strings in which case we do it naively.
10631
  if (user_input.size() < 16) {  // slow path
10632
    return std::ranges::any_of(user_input, is_tabs_or_newline);
10633
  }
10634
  // fast path for long strings (expected to be common)
10635
  // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON)
10636
  size_t i = 0;
10637
  // Lookup table where positions 9, 10, 13 contain their own values
10638
  // Everything else is set to 1 so it won't match
10639
  const __m128i rnt =
10640
      _mm_setr_epi8(1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0, 13, 0, 0);
10641
  __m128i running = _mm_setzero_si128();
10642
  for (; i + 15 < user_input.size(); i += 16) {
10643
    __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
10644
    // Shuffle the lookup table using input bytes as indices
10645
    __m128i shuffled = _mm_shuffle_epi8(rnt, word);
10646
    // Compare: if shuffled value matches input, we found \t, \n, or \r
10647
    __m128i matches = _mm_cmpeq_epi8(shuffled, word);
10648
    running = _mm_or_si128(running, matches);
10649
  }
10650
  if (i < user_input.size()) {
10651
    __m128i word = _mm_loadu_si128(
10652
        (const __m128i*)(user_input.data() + user_input.length() - 16));
10653
    __m128i shuffled = _mm_shuffle_epi8(rnt, word);
10654
    __m128i matches = _mm_cmpeq_epi8(shuffled, word);
10655
    running = _mm_or_si128(running, matches);
10656
  }
10657
  return _mm_movemask_epi8(running) != 0;
10658
}
10659
#elif ADA_NEON
10660
ada_really_inline bool has_tabs_or_newline(
10661
    std::string_view user_input) noexcept {
10662
  // first check for short strings in which case we do it naively.
10663
  if (user_input.size() < 16) {  // slow path
10664
    return std::ranges::any_of(user_input, is_tabs_or_newline);
10665
  }
10666
  // fast path for long strings (expected to be common)
10667
  size_t i = 0;
10668
  /**
10669
   * The fastest way to check for `\t` (==9), '\n'(== 10) and `\r` (==13) relies
10670
   * on table lookup instruction. We notice that these are all unique numbers
10671
   * between 0..15. Let's prepare a special register, where we put '\t' in the
10672
   * 9th position, '\n' - 10th and '\r' - 13th. Then we shuffle this register by
10673
   * input register. If the input had `\t` in position X then this shuffled
10674
   * register will also have '\t' in that position. Comparing input with this
10675
   * shuffled register will mark us all interesting characters in the input.
10676
   *
10677
   * credit for algorithmic idea: @aqrit, credit for description:
10678
   * @DenisYaroshevskiy
10679
   */
10680
  static uint8_t rnt_array[16] = {1, 0, 0,  0, 0, 0,  0, 0,
10681
                                  0, 9, 10, 0, 0, 13, 0, 0};
10682
  const uint8x16_t rnt = vld1q_u8(rnt_array);
10683
  // m['0xd', '0xa', '0x9']
10684
  uint8x16_t running{0};
10685
  for (; i + 15 < user_input.size(); i += 16) {
10686
    uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);
10687
10688
    running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
10689
  }
10690
  if (i < user_input.size()) {
10691
    uint8x16_t word =
10692
        vld1q_u8((const uint8_t*)user_input.data() + user_input.length() - 16);
10693
    running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
10694
  }
10695
  return vmaxvq_u32(vreinterpretq_u32_u8(running)) != 0;
10696
}
10697
#elif ADA_SSE2
10698
ada_really_inline bool has_tabs_or_newline(
10699
1.20M
    std::string_view user_input) noexcept {
10700
  // first check for short strings in which case we do it naively.
10701
1.20M
  if (user_input.size() < 16) {  // slow path
10702
571k
    return std::ranges::any_of(user_input, is_tabs_or_newline);
10703
571k
  }
10704
  // fast path for long strings (expected to be common)
10705
637k
  size_t i = 0;
10706
637k
  const __m128i mask1 = _mm_set1_epi8('\r');
10707
637k
  const __m128i mask2 = _mm_set1_epi8('\n');
10708
637k
  const __m128i mask3 = _mm_set1_epi8('\t');
10709
  // If we supported SSSE3, we could use the algorithm that we use for NEON.
10710
637k
  __m128i running{0};
10711
1.36M
  for (; i + 15 < user_input.size(); i += 16) {
10712
728k
    __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
10713
728k
    running = _mm_or_si128(
10714
728k
        _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
10715
728k
                                           _mm_cmpeq_epi8(word, mask2))),
10716
728k
        _mm_cmpeq_epi8(word, mask3));
10717
728k
  }
10718
637k
  if (i < user_input.size()) {
10719
613k
    __m128i word = _mm_loadu_si128(
10720
613k
        (const __m128i*)(user_input.data() + user_input.length() - 16));
10721
613k
    running = _mm_or_si128(
10722
613k
        _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
10723
613k
                                           _mm_cmpeq_epi8(word, mask2))),
10724
613k
        _mm_cmpeq_epi8(word, mask3));
10725
613k
  }
10726
637k
  return _mm_movemask_epi8(running) != 0;
10727
1.20M
}
10728
#elif ADA_LSX
10729
ada_really_inline bool has_tabs_or_newline(
10730
    std::string_view user_input) noexcept {
10731
  // first check for short strings in which case we do it naively.
10732
  if (user_input.size() < 16) {  // slow path
10733
    return std::ranges::any_of(user_input, is_tabs_or_newline);
10734
  }
10735
  // fast path for long strings (expected to be common)
10736
  size_t i = 0;
10737
  const __m128i mask1 = __lsx_vrepli_b('\r');
10738
  const __m128i mask2 = __lsx_vrepli_b('\n');
10739
  const __m128i mask3 = __lsx_vrepli_b('\t');
10740
  // If we supported SSSE3, we could use the algorithm that we use for NEON.
10741
  __m128i running{0};
10742
  for (; i + 15 < user_input.size(); i += 16) {
10743
    __m128i word = __lsx_vld((const __m128i*)(user_input.data() + i), 0);
10744
    running = __lsx_vor_v(
10745
        __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1),
10746
                                         __lsx_vseq_b(word, mask2))),
10747
        __lsx_vseq_b(word, mask3));
10748
  }
10749
  if (i < user_input.size()) {
10750
    __m128i word = __lsx_vld(
10751
        (const __m128i*)(user_input.data() + user_input.length() - 16), 0);
10752
    running = __lsx_vor_v(
10753
        __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1),
10754
                                         __lsx_vseq_b(word, mask2))),
10755
        __lsx_vseq_b(word, mask3));
10756
  }
10757
  if (__lsx_bz_v(running)) return false;
10758
  return true;
10759
}
10760
#elif ADA_RVV
10761
ada_really_inline bool has_tabs_or_newline(
10762
    std::string_view user_input) noexcept {
10763
  uint8_t* src = (uint8_t*)user_input.data();
10764
  for (size_t vl, n = user_input.size(); n > 0; n -= vl, src += vl) {
10765
    vl = __riscv_vsetvl_e8m1(n);
10766
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
10767
    vbool8_t m1 = __riscv_vmseq(v, '\r', vl);
10768
    vbool8_t m2 = __riscv_vmseq(v, '\n', vl);
10769
    vbool8_t m3 = __riscv_vmseq(v, '\t', vl);
10770
    vbool8_t m = __riscv_vmor(__riscv_vmor(m1, m2, vl), m3, vl);
10771
    long idx = __riscv_vfirst(m, vl);
10772
    if (idx >= 0) return true;
10773
  }
10774
  return false;
10775
}
10776
#else
10777
ada_really_inline bool has_tabs_or_newline(
10778
    std::string_view user_input) noexcept {
10779
  auto has_zero_byte = [](uint64_t v) {
10780
    return ((v - 0x0101010101010101) & ~(v) & 0x8080808080808080);
10781
  };
10782
  size_t i = 0;
10783
  uint64_t mask1 = broadcast('\r');
10784
  uint64_t mask2 = broadcast('\n');
10785
  uint64_t mask3 = broadcast('\t');
10786
  uint64_t running{0};
10787
  for (; i + 7 < user_input.size(); i += 8) {
10788
    uint64_t word{};
10789
    memcpy(&word, user_input.data() + i, sizeof(word));
10790
    uint64_t xor1 = word ^ mask1;
10791
    uint64_t xor2 = word ^ mask2;
10792
    uint64_t xor3 = word ^ mask3;
10793
    running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
10794
  }
10795
  if (i < user_input.size()) {
10796
    uint64_t word{};
10797
    memcpy(&word, user_input.data() + i, user_input.size() - i);
10798
    uint64_t xor1 = word ^ mask1;
10799
    uint64_t xor2 = word ^ mask2;
10800
    uint64_t xor3 = word ^ mask3;
10801
    running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
10802
  }
10803
  return running;
10804
}
10805
#endif
10806
10807
// A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR,
10808
// U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>),
10809
// U+003F (?), U+0040 (@), U+005B ([), U+005C (\), U+005D (]), U+005E (^), or
10810
// U+007C (|).
10811
constexpr static std::array<uint8_t, 256> is_forbidden_host_code_point_table =
10812
    []() consteval {
10813
      std::array<uint8_t, 256> result{};
10814
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
10815
                        '>', '?', '@', '[', '\\', ']', '^', '|'}) {
10816
        result[c] = true;
10817
      }
10818
      return result;
10819
    }();
10820
10821
ada_really_inline constexpr bool is_forbidden_host_code_point(
10822
1.74M
    const char c) noexcept {
10823
1.74M
  return is_forbidden_host_code_point_table[uint8_t(c)];
10824
1.74M
}
10825
10826
constexpr static std::array<uint8_t, 256> is_forbidden_domain_code_point_table =
10827
    []() consteval {
10828
      std::array<uint8_t, 256> result{};
10829
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
10830
                        '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
10831
        result[c] = true;
10832
      }
10833
      for (uint8_t c = 0; c <= 32; c++) {
10834
        result[c] = true;
10835
      }
10836
      for (size_t c = 127; c < 256; c++) {
10837
        result[c] = true;
10838
      }
10839
      return result;
10840
    }();
10841
10842
static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
10843
10844
ada_really_inline constexpr bool is_forbidden_domain_code_point(
10845
481k
    const char c) noexcept {
10846
481k
  return is_forbidden_domain_code_point_table[uint8_t(c)];
10847
481k
}
10848
10849
ada_really_inline constexpr bool contains_forbidden_domain_code_point(
10850
84.6k
    const char* input, size_t length) noexcept {
10851
84.6k
  size_t i = 0;
10852
84.6k
  uint8_t accumulator{};
10853
256k
  for (; i + 4 <= length; i += 4) {
10854
171k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
10855
171k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])];
10856
171k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])];
10857
171k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])];
10858
171k
  }
10859
208k
  for (; i < length; i++) {
10860
123k
    accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
10861
123k
  }
10862
84.6k
  return accumulator;
10863
84.6k
}
10864
10865
constexpr static std::array<uint8_t, 256>
10866
    is_forbidden_domain_code_point_table_or_upper = []() consteval {
10867
      std::array<uint8_t, 256> result{};
10868
      for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
10869
                        '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
10870
        result[c] = 1;
10871
      }
10872
      for (uint8_t c = 'A'; c <= 'Z'; c++) {
10873
        result[c] = 2;
10874
      }
10875
      for (uint8_t c = 0; c <= 32; c++) {
10876
        result[c] = 1;
10877
      }
10878
      for (size_t c = 127; c < 256; c++) {
10879
        result[c] = 1;
10880
      }
10881
      return result;
10882
    }();
10883
10884
ada_really_inline constexpr uint8_t
10885
contains_forbidden_domain_code_point_or_upper(const char* input,
10886
534k
                                              size_t length) noexcept {
10887
534k
  size_t i = 0;
10888
534k
  uint8_t accumulator{};
10889
1.44M
  for (; i + 4 <= length; i += 4) {
10890
911k
    accumulator |=
10891
911k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
10892
911k
    accumulator |=
10893
911k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])];
10894
911k
    accumulator |=
10895
911k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])];
10896
911k
    accumulator |=
10897
911k
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])];
10898
911k
  }
10899
1.70M
  for (; i < length; i++) {
10900
1.17M
    accumulator |=
10901
1.17M
        is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
10902
1.17M
  }
10903
534k
  return accumulator;
10904
534k
}
10905
10906
// std::isalnum(c) || c == '+' || c == '-' || c == '.') is true for
10907
constexpr static std::array<bool, 256> is_alnum_plus_table = []() consteval {
10908
  std::array<bool, 256> result{};
10909
  for (size_t c = 0; c < 256; c++) {
10910
    result[c] = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
10911
                (c >= 'A' && c <= 'Z') || c == '+' || c == '-' || c == '.';
10912
  }
10913
  return result;
10914
}();
10915
10916
5.68M
ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept {
10917
5.68M
  return is_alnum_plus_table[uint8_t(c)];
10918
  // A table is almost surely much faster than the
10919
  // following under most compilers: return
10920
  // return (std::isalnum(c) || c == '+' || c == '-' || c == '.');
10921
5.68M
}
10922
10923
256k
ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept {
10924
256k
  return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
10925
105k
         (c >= 'a' && c <= 'f');
10926
256k
}
10927
10928
497k
ada_really_inline constexpr bool is_ascii_digit(const char c) noexcept {
10929
  // An ASCII digit is a code point in the range U+0030 (0) to U+0039 (9),
10930
  // inclusive.
10931
497k
  return (c >= '0' && c <= '9');
10932
497k
}
10933
10934
24.8k
ada_really_inline constexpr bool is_ascii(const char32_t c) noexcept {
10935
  // If code point is between U+0000 and U+007F inclusive, then return true.
10936
24.8k
  return c <= 0x7F;
10937
24.8k
}
10938
10939
2.42M
ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept {
10940
2.42M
  return (unsigned char)c <= ' ';
10941
2.42M
}
10942
10943
ada_really_inline constexpr bool is_ascii_tab_or_newline(
10944
200k
    const char c) noexcept {
10945
200k
  return c == '\t' || c == '\n' || c == '\r';
10946
200k
}
10947
10948
constexpr std::string_view table_is_double_dot_path_segment[] = {
10949
    "..", "%2e.", ".%2e", "%2e%2e"};
10950
10951
ada_really_inline constexpr bool is_double_dot_path_segment(
10952
199k
    std::string_view input) noexcept {
10953
  // This will catch most cases:
10954
  // The length must be 2,4 or 6.
10955
  // We divide by two and require
10956
  // that the result be between 1 and 3 inclusively.
10957
199k
  uint64_t half_length = uint64_t(input.size()) / 2;
10958
199k
  if (half_length - 1 > 2) {
10959
136k
    return false;
10960
136k
  }
10961
  // We have a string of length 2, 4 or 6.
10962
  // We now check the first character:
10963
63.1k
  if ((input[0] != '.') && (input[0] != '%')) {
10964
41.9k
    return false;
10965
41.9k
  }
10966
  // We are unlikely the get beyond this point.
10967
21.2k
  int hash_value = (input.size() + (unsigned)(input[0])) & 3;
10968
21.2k
  const std::string_view target = table_is_double_dot_path_segment[hash_value];
10969
21.2k
  if (target.size() != input.size()) {
10970
9.55k
    return false;
10971
9.55k
  }
10972
  // We almost never get here.
10973
  // Optimizing the rest is relatively unimportant.
10974
11.6k
  auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) {
10975
11.6k
    uint16_t A, B;
10976
11.6k
    memcpy(&A, a.data(), sizeof(A));
10977
11.6k
    memcpy(&B, b.data(), sizeof(B));
10978
11.6k
    return A == B;
10979
11.6k
  };
10980
11.6k
  if (!prefix_equal_unsafe(input, target)) {
10981
3.24k
    return false;
10982
3.24k
  }
10983
9.93k
  for (size_t i = 2; i < input.size(); i++) {
10984
2.50k
    char c = input[i];
10985
2.50k
    if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) {
10986
982
      return false;
10987
982
    }
10988
2.50k
  }
10989
7.43k
  return true;
10990
  // The above code might be a bit better than the code below. Compilers
10991
  // are not stupid and may use the fact that these strings have length 2,4 and
10992
  // 6 and other tricks.
10993
  // return input == ".." ||
10994
  //  input == ".%2e" || input == ".%2E" ||
10995
  //  input == "%2e." || input == "%2E." ||
10996
  //  input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input ==
10997
  //  "%2e%2E";
10998
8.41k
}
10999
11000
ada_really_inline constexpr bool is_single_dot_path_segment(
11001
383k
    std::string_view input) noexcept {
11002
383k
  return input == "." || input == "%2e" || input == "%2E";
11003
383k
}
11004
11005
64.2k
ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept {
11006
64.2k
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
11007
64.2k
}
11008
11009
constexpr static char hex_to_binary_table[] = {
11010
    0,  1,  2,  3,  4, 5, 6, 7, 8, 9, 0, 0,  0,  0,  0,  0,  0, 10, 11,
11011
    12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, 0,  0,
11012
    0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
11013
228k
unsigned constexpr convert_hex_to_binary(const char c) noexcept {
11014
228k
  return hex_to_binary_table[c - '0'];
11015
228k
}
11016
11017
44.4k
std::string percent_decode(const std::string_view input, size_t first_percent) {
11018
  // next line is for safety only, we expect users to avoid calling
11019
  // percent_decode when first_percent is outside the range.
11020
44.4k
  if (first_percent == std::string_view::npos) {
11021
0
    return std::string(input);
11022
0
  }
11023
44.4k
  std::string dest;
11024
44.4k
  dest.reserve(input.length());
11025
44.4k
  dest.append(input.substr(0, first_percent));
11026
44.4k
  const char* pointer = input.data() + first_percent;
11027
44.4k
  const char* end = input.data() + input.size();
11028
  // Optimization opportunity: if the following code gets
11029
  // called often, it can be optimized quite a bit.
11030
366k
  while (pointer < end) {
11031
322k
    const char ch = pointer[0];
11032
322k
    size_t remaining = end - pointer - 1;
11033
322k
    if (ch != '%' || remaining < 2 ||
11034
112k
        (  // ch == '%' && // It is unnecessary to check that ch == '%'.
11035
112k
            (!is_ascii_hex_digit(pointer[1]) ||
11036
220k
             !is_ascii_hex_digit(pointer[2])))) {
11037
220k
      dest += ch;
11038
220k
      pointer++;
11039
220k
    } else {
11040
101k
      unsigned a = convert_hex_to_binary(pointer[1]);
11041
101k
      unsigned b = convert_hex_to_binary(pointer[2]);
11042
101k
      char c = static_cast<char>(a * 16 + b);
11043
101k
      dest += c;
11044
101k
      pointer += 3;
11045
101k
    }
11046
322k
  }
11047
44.4k
  return dest;
11048
44.4k
}
11049
11050
std::string percent_encode(const std::string_view input,
11051
72.3k
                           const uint8_t character_set[]) {
11052
72.3k
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
11053
57.6k
    return character_sets::bit_at(character_set, c);
11054
57.6k
  });
11055
  // Optimization: Don't iterate if percent encode is not required
11056
72.3k
  if (pointer == input.end()) {
11057
54.0k
    return std::string(input);
11058
54.0k
  }
11059
11060
18.2k
  std::string result;
11061
18.2k
  result.reserve(input.length());  // in the worst case, percent encoding might
11062
                                   // produce 3 characters.
11063
18.2k
  result.append(input.substr(0, std::distance(input.begin(), pointer)));
11064
11065
111k
  for (; pointer != input.end(); pointer++) {
11066
93.4k
    if (character_sets::bit_at(character_set, *pointer)) {
11067
77.7k
      result.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
11068
77.7k
    } else {
11069
15.6k
      result += *pointer;
11070
15.6k
    }
11071
93.4k
  }
11072
11073
18.2k
  return result;
11074
72.3k
}
11075
11076
template <bool append>
11077
bool percent_encode(const std::string_view input, const uint8_t character_set[],
11078
141k
                    std::string& out) {
11079
141k
  ada_log("percent_encode ", input, " to output string while ",
11080
141k
          append ? "appending" : "overwriting");
11081
294k
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
11082
294k
    return character_sets::bit_at(character_set, c);
11083
294k
  });
ada::unicode::percent_encode<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)::{lambda(char)#1}::operator()(char) const
Line
Count
Source
11081
247k
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
11082
247k
    return character_sets::bit_at(character_set, c);
11083
247k
  });
ada::unicode::percent_encode<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)::{lambda(char)#1}::operator()(char) const
Line
Count
Source
11081
46.6k
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
11082
46.6k
    return character_sets::bit_at(character_set, c);
11083
46.6k
  });
11084
141k
  ada_log("percent_encode done checking, moved to ",
11085
141k
          std::distance(input.begin(), pointer));
11086
11087
  // Optimization: Don't iterate if percent encode is not required
11088
141k
  if (pointer == input.end()) {
11089
96.8k
    ada_log("percent_encode encoding not needed.");
11090
96.8k
    return false;
11091
96.8k
  }
11092
44.7k
  if constexpr (!append) {
11093
34.1k
    out.clear();
11094
34.1k
  }
11095
44.7k
  ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
11096
44.7k
          " bytes");
11097
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
11098
44.7k
  out.append(input.data(), std::distance(input.begin(), pointer));
11099
44.7k
  ada_log("percent_encode processing ", std::distance(pointer, input.end()),
11100
44.7k
          " bytes");
11101
416k
  for (; pointer != input.end(); pointer++) {
11102
371k
    if (character_sets::bit_at(character_set, *pointer)) {
11103
275k
      out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
11104
275k
    } else {
11105
96.9k
      out += *pointer;
11106
96.9k
    }
11107
371k
  }
11108
44.7k
  return true;
11109
141k
}
bool ada::unicode::percent_encode<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Line
Count
Source
11078
111k
                    std::string& out) {
11079
111k
  ada_log("percent_encode ", input, " to output string while ",
11080
111k
          append ? "appending" : "overwriting");
11081
111k
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
11082
111k
    return character_sets::bit_at(character_set, c);
11083
111k
  });
11084
111k
  ada_log("percent_encode done checking, moved to ",
11085
111k
          std::distance(input.begin(), pointer));
11086
11087
  // Optimization: Don't iterate if percent encode is not required
11088
111k
  if (pointer == input.end()) {
11089
77.1k
    ada_log("percent_encode encoding not needed.");
11090
77.1k
    return false;
11091
77.1k
  }
11092
34.1k
  if constexpr (!append) {
11093
34.1k
    out.clear();
11094
34.1k
  }
11095
34.1k
  ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
11096
34.1k
          " bytes");
11097
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
11098
34.1k
  out.append(input.data(), std::distance(input.begin(), pointer));
11099
34.1k
  ada_log("percent_encode processing ", std::distance(pointer, input.end()),
11100
34.1k
          " bytes");
11101
291k
  for (; pointer != input.end(); pointer++) {
11102
256k
    if (character_sets::bit_at(character_set, *pointer)) {
11103
179k
      out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
11104
179k
    } else {
11105
77.1k
      out += *pointer;
11106
77.1k
    }
11107
256k
  }
11108
34.1k
  return true;
11109
111k
}
bool ada::unicode::percent_encode<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, unsigned char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Line
Count
Source
11078
30.3k
                    std::string& out) {
11079
30.3k
  ada_log("percent_encode ", input, " to output string while ",
11080
30.3k
          append ? "appending" : "overwriting");
11081
30.3k
  auto pointer = std::ranges::find_if(input, [character_set](const char c) {
11082
30.3k
    return character_sets::bit_at(character_set, c);
11083
30.3k
  });
11084
30.3k
  ada_log("percent_encode done checking, moved to ",
11085
30.3k
          std::distance(input.begin(), pointer));
11086
11087
  // Optimization: Don't iterate if percent encode is not required
11088
30.3k
  if (pointer == input.end()) {
11089
19.7k
    ada_log("percent_encode encoding not needed.");
11090
19.7k
    return false;
11091
19.7k
  }
11092
  if constexpr (!append) {
11093
    out.clear();
11094
  }
11095
10.5k
  ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
11096
10.5k
          " bytes");
11097
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
11098
10.5k
  out.append(input.data(), std::distance(input.begin(), pointer));
11099
10.5k
  ada_log("percent_encode processing ", std::distance(pointer, input.end()),
11100
10.5k
          " bytes");
11101
125k
  for (; pointer != input.end(); pointer++) {
11102
115k
    if (character_sets::bit_at(character_set, *pointer)) {
11103
95.2k
      out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
11104
95.2k
    } else {
11105
19.7k
      out += *pointer;
11106
19.7k
    }
11107
115k
  }
11108
10.5k
  return true;
11109
30.3k
}
11110
11111
bool to_ascii(std::optional<std::string>& out, const std::string_view plain,
11112
135k
              size_t first_percent) {
11113
135k
  std::string percent_decoded_buffer;
11114
135k
  std::string_view input = plain;
11115
135k
  if (first_percent != std::string_view::npos) {
11116
44.4k
    percent_decoded_buffer = unicode::percent_decode(plain, first_percent);
11117
44.4k
    input = percent_decoded_buffer;
11118
44.4k
  }
11119
  // input is a non-empty UTF-8 string, must be percent decoded
11120
135k
  std::string idna_ascii = ada::idna::to_ascii(input);
11121
135k
  if (idna_ascii.empty() || contains_forbidden_domain_code_point(
11122
84.6k
                                idna_ascii.data(), idna_ascii.size())) {
11123
76.6k
    return false;
11124
76.6k
  }
11125
58.6k
  out = std::move(idna_ascii);
11126
58.6k
  return true;
11127
135k
}
11128
11129
std::string percent_encode(const std::string_view input,
11130
1.51k
                           const uint8_t character_set[], size_t index) {
11131
1.51k
  std::string out;
11132
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
11133
1.51k
  out.append(input.data(), index);
11134
1.51k
  auto pointer = input.begin() + index;
11135
7.26k
  for (; pointer != input.end(); pointer++) {
11136
5.74k
    if (character_sets::bit_at(character_set, *pointer)) {
11137
4.85k
      out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
11138
4.85k
    } else {
11139
892
      out += *pointer;
11140
892
    }
11141
5.74k
  }
11142
1.51k
  return out;
11143
1.51k
}
11144
11145
}  // namespace ada::unicode
11146
/* end file src/unicode.cpp */
11147
/* begin file src/serializers.cpp */
11148
#include <array>
11149
#include <charconv>
11150
#include <string>
11151
11152
namespace ada::serializers {
11153
11154
void find_longest_sequence_of_ipv6_pieces(
11155
    const std::array<uint16_t, 8>& address, size_t& compress,
11156
3.09k
    size_t& compress_length) noexcept {
11157
9.74k
  for (size_t i = 0; i < 8; i++) {
11158
7.73k
    if (address[i] == 0) {
11159
4.30k
      size_t next = i + 1;
11160
19.7k
      while (next != 8 && address[next] == 0) ++next;
11161
4.30k
      const size_t count = next - i;
11162
4.30k
      if (compress_length < count) {
11163
3.25k
        compress_length = count;
11164
3.25k
        compress = i;
11165
3.25k
        if (next == 8) break;
11166
2.17k
        i = next;
11167
2.17k
      }
11168
4.30k
    }
11169
7.73k
  }
11170
3.09k
}
11171
11172
3.09k
std::string ipv6(const std::array<uint16_t, 8>& address) {
11173
3.09k
  size_t compress_length = 0;  // The length of a long sequence of zeros.
11174
3.09k
  size_t compress = 0;         // The start of a long sequence of zeros.
11175
3.09k
  find_longest_sequence_of_ipv6_pieces(address, compress, compress_length);
11176
11177
3.09k
  if (compress_length <= 1) {
11178
    // Optimization opportunity: Find a faster way then snprintf for imploding
11179
    // and return here.
11180
116
    compress = compress_length = 8;
11181
116
  }
11182
11183
3.09k
  std::string output(4 * 8 + 7 + 2, '\0');
11184
3.09k
  size_t piece_index = 0;
11185
3.09k
  char* point = output.data();
11186
3.09k
  char* point_end = output.data() + output.size();
11187
3.09k
  *point++ = '[';
11188
8.17k
  while (true) {
11189
8.17k
    if (piece_index == compress) {
11190
2.97k
      *point++ = ':';
11191
      // If we skip a value initially, we need to write '::', otherwise
11192
      // a single ':' will do since it follows a previous ':'.
11193
2.97k
      if (piece_index == 0) {
11194
1.58k
        *point++ = ':';
11195
1.58k
      }
11196
2.97k
      piece_index += compress_length;
11197
2.97k
      if (piece_index == 8) {
11198
1.08k
        break;
11199
1.08k
      }
11200
2.97k
    }
11201
7.09k
    point = std::to_chars(point, point_end, address[piece_index], 16).ptr;
11202
7.09k
    piece_index++;
11203
7.09k
    if (piece_index == 8) {
11204
2.01k
      break;
11205
2.01k
    }
11206
5.08k
    *point++ = ':';
11207
5.08k
  }
11208
3.09k
  *point++ = ']';
11209
3.09k
  output.resize(point - output.data());
11210
3.09k
  return output;
11211
3.09k
}
11212
11213
34.0k
std::string ipv4(const uint64_t address) {
11214
34.0k
  std::string output(15, '\0');
11215
34.0k
  char* point = output.data();
11216
34.0k
  char* point_end = output.data() + output.size();
11217
34.0k
  point = std::to_chars(point, point_end, uint8_t(address >> 24)).ptr;
11218
136k
  for (int i = 2; i >= 0; i--) {
11219
102k
    *point++ = '.';
11220
102k
    point = std::to_chars(point, point_end, uint8_t(address >> (i * 8))).ptr;
11221
102k
  }
11222
34.0k
  output.resize(point - output.data());
11223
34.0k
  return output;
11224
34.0k
}
11225
11226
}  // namespace ada::serializers
11227
/* end file src/serializers.cpp */
11228
/* begin file src/implementation.cpp */
11229
11230
#include <atomic>
11231
#include <limits>
11232
#include <optional>
11233
#include <string_view>
11234
11235
11236
namespace ada {
11237
11238
static std::atomic<uint32_t> max_input_length_{
11239
    std::numeric_limits<uint32_t>::max()};
11240
11241
0
void set_max_input_length(uint32_t length) {
11242
0
  max_input_length_.store(length, std::memory_order_relaxed);
11243
0
}
11244
11245
1.21M
uint32_t get_max_input_length() {
11246
1.21M
  return max_input_length_.load(std::memory_order_relaxed);
11247
1.21M
}
11248
11249
namespace {
11250
11251
// @private
11252
// Fast-path validator for can_parse.
11253
//
11254
// Validates absolute special (non-file) URLs without constructing any
11255
// url_aggregator object and without running the state machine.
11256
// Performs a single forward scan over the input bytes.
11257
//
11258
// Returns:
11259
//   true      -- URL is structurally valid
11260
//   false     -- URL is definitely invalid
11261
//   nullopt   -- edge case; fall through to the full parser
11262
//               (credentials, IDNA, IPv4/6, tabs/newlines, relative URLs, ...)
11263
std::optional<bool> try_can_parse_absolute_fast(
11264
0
    std::string_view input) noexcept {
11265
0
  const uint8_t* b = reinterpret_cast<const uint8_t*>(input.data());
11266
0
  size_t len = input.size();
11267
11268
  // -- Inline C0 whitespace trim (no allocation) --------------------------
11269
  // Note: \t (0x09), \n (0x0a), \r (0x0d) are all <= 0x20, so any
11270
  // leading/trailing tabs or newlines are correctly stripped here, matching
11271
  // the WHATWG spec's "remove leading/trailing C0 control and space" step.
11272
0
  while (len > 0 && b[0] <= 0x20) {
11273
0
    b++;
11274
0
    len--;
11275
0
  }
11276
0
  while (len > 0 && b[len - 1] <= 0x20) {
11277
0
    len--;
11278
0
  }
11279
0
  if (len == 0) return false;
11280
11281
  // -- Scheme detection -----------------------------------------------------
11282
  // Fast path for HTTP and HTTPS (covers ~90%+ of real-world URLs).
11283
  // Avoids the general scheme loop, buffer copy, and perfect hash lookup.
11284
  // We know HTTP and HTTPS are special non-file schemes, so no further
11285
  // scheme_type checks are needed on the fast path -- only `pos` matters.
11286
0
  size_t pos;
11287
11288
0
  if (len >= 7 && (b[0] | 0x20) == 'h' && (b[1] | 0x20) == 't' &&
11289
0
      (b[2] | 0x20) == 't' && (b[3] | 0x20) == 'p') {
11290
0
    if (b[4] == ':' && b[5] == '/' && b[6] == '/') {
11291
0
      pos = 7;
11292
0
      goto skip_extra_slashes;
11293
0
    }
11294
0
    if (len >= 8 && (b[4] | 0x20) == 's' && b[5] == ':' && b[6] == '/' &&
11295
0
        b[7] == '/') {
11296
0
      pos = 8;
11297
0
      goto skip_extra_slashes;
11298
0
    }
11299
    // Fall through: could be "httpe://", tabs in scheme, etc.
11300
0
  }
11301
11302
0
  {
11303
    // General scheme detection for ws, wss, ftp, and edge cases.
11304
0
    if (!checkers::is_alpha(static_cast<char>(b[0]))) return false;
11305
11306
    // Scan for ':' within the first 7 bytes. All special schemes are <= 5
11307
    // chars ("https"), so any URL whose first ':' is beyond byte 6 is either
11308
    // non-special or relative -- both require the full parser.
11309
0
    size_t colon_pos = 0;
11310
0
    for (size_t i = 1;; ++i) {
11311
0
      if (i >= 7 || i >= len) return std::nullopt;
11312
0
      const char c = static_cast<char>(b[i]);
11313
0
      if (c == ':') {
11314
0
        colon_pos = i;
11315
0
        break;
11316
0
      }
11317
      // Tabs/newlines in the scheme require the full parser to strip them.
11318
0
      if (c == '\t' || c == '\n' || c == '\r') return std::nullopt;
11319
0
      if (!unicode::is_alnum_plus(c)) return false;
11320
0
    }
11321
11322
    // Lowercase scheme bytes inline and classify via the existing perfect
11323
    // hash.
11324
0
    char scheme_buf[6];
11325
0
    scheme_buf[0] = static_cast<char>(b[0] | 0x20);
11326
0
    for (size_t i = 1; i < colon_pos; ++i)
11327
0
      scheme_buf[i] = static_cast<char>(b[i] | 0x20);
11328
11329
0
    const ada::scheme::type scheme_type =
11330
0
        ada::scheme::get_scheme_type({scheme_buf, colon_pos});
11331
11332
    // Only handle special, non-file schemes.
11333
0
    if (scheme_type == ada::scheme::NOT_SPECIAL) return std::nullopt;
11334
0
    if (scheme_type == ada::scheme::FILE) return std::nullopt;
11335
11336
    // Per WHATWG, special URLs don't require "//": "http:example.com" is valid
11337
    // (SPECIAL_AUTHORITY_IGNORE_SLASHES just skips leading slashes and
11338
    // proceeds to AUTHORITY).  Defer to the inline fallback for any input
11339
    // without "://".
11340
0
    pos = colon_pos + 1;
11341
0
    if (pos + 2 > len || b[pos] != '/' || b[pos + 1] != '/') {
11342
0
      return std::nullopt;
11343
0
    }
11344
0
    pos += 2;
11345
0
  }
11346
11347
0
skip_extra_slashes:
11348
  // SPECIAL_AUTHORITY_IGNORE_SLASHES: the full parser skips any additional
11349
  // leading '/' or '\' after the initial "//".  Mirror that here so we don't
11350
  // mis-identify the host as empty when there are extra slashes.
11351
0
  while (pos < len && (b[pos] == '/' || b[pos] == '\\')) {
11352
0
    ++pos;
11353
0
  }
11354
11355
  // Early IPv6 bail-out: if the authority starts with '[', it's an IPv6
11356
  // literal which requires the full parser.  Checking here avoids scanning
11357
  // the entire bracketed address only to bail out afterward.
11358
0
  if (pos < len && b[pos] == '[') return std::nullopt;
11359
11360
  // -- Merged authority + host scan ------------------------------------------
11361
  // A single forward pass over the authority bytes that simultaneously:
11362
  //   - finds the authority end and port colon
11363
  //   - validates host characters (forbidden domain code points)
11364
  //   - tracks IPv4 indicators (all-decimal-dots, last non-dot char)
11365
  //   - detects xn-- prefixes (IDNA punycode)
11366
  //   - detects tabs/newlines (which require the full parser to strip)
11367
  // This replaces 4 separate scans over the host bytes.
11368
0
  const size_t auth_start = pos;
11369
0
  size_t auth_end = pos;
11370
0
  size_t port_colon = SIZE_MAX;
11371
0
  bool all_dec_dots = true;
11372
0
  uint8_t last_non_dot = 0;
11373
11374
0
  for (; auth_end < len; ++auth_end) {
11375
0
    const uint8_t c = b[auth_end];
11376
11377
    // Non-ASCII -> needs IDNA processing -> full parser.
11378
0
    if (c >= 0x80) return std::nullopt;
11379
11380
    // Authority delimiters.
11381
0
    if (c == '/' || c == '?' || c == '#' || c == '\\') break;
11382
11383
    // Port separator.
11384
0
    if (c == ':') {
11385
0
      if (port_colon == SIZE_MAX) port_colon = auth_end;
11386
0
      continue;
11387
0
    }
11388
11389
    // Credentials or percent-encoding -> full parser.
11390
0
    if (c == '@' || c == '%') return std::nullopt;
11391
11392
    // Tabs/newlines anywhere in the authority require the full parser to
11393
    // strip them before validation.  Without this, a tab in the port (e.g.
11394
    // "http://host:8\t0/") would be mis-rejected by port validation.
11395
0
    if (c == '\t' || c == '\n' || c == '\r') return std::nullopt;
11396
11397
    // Skip remaining host-specific checks for port bytes.  Port digits are
11398
    // validated separately below, and no forbidden-domain-code-point check
11399
    // is needed on port characters.
11400
0
    if (port_colon != SIZE_MAX) continue;
11401
11402
    // -- Host byte validation (inlined) ------------------------------------
11403
    // Forbidden domain code points that are not already caught above:
11404
    //   C0 controls and space (0x00-0x20), DEL (0x7F), <, >, [, ], ^, |.
11405
    // At this stage, the input may still be userinfo or be normalized later
11406
    // (e.g., percent-encoded), so we do not reject here and defer to the
11407
    // parser. Characters already caught: >= 0x80 (non-ASCII), '/' '?' '#' '\\'
11408
    // (delimiters), ':' (port), '@' '%' (bail), '\t' '\n' '\r' (bail).
11409
0
    if (c <= 0x20 || c == 0x7F || c == '<' || c == '>' || c == '[' ||
11410
0
        c == ']' || c == '^' || c == '|') {
11411
0
      return std::nullopt;
11412
0
    }
11413
11414
    // Track whether host is all decimal digits and dots (potential IPv4).
11415
0
    if (c != '.' && (c < '0' || c > '9')) all_dec_dots = false;
11416
11417
    // Track last non-dot character for the IPv4 hex/octal heuristic.
11418
0
    if (c != '.') last_non_dot = c;
11419
11420
    // Detect xn-- prefix inline (IDNA punycode -> needs full parser).
11421
    // Checking at every position mirrors the original behavior: any
11422
    // occurrence of "xn--" in the host (not just at label boundaries)
11423
    // triggers a bail-out to the full IDNA validator.
11424
0
    if ((c | 0x20) == 'x' && auth_end + 4 <= len &&
11425
0
        (b[auth_end + 1] | 0x20) == 'n' && b[auth_end + 2] == '-' &&
11426
0
        b[auth_end + 3] == '-') {
11427
0
      return std::nullopt;
11428
0
    }
11429
0
  }
11430
11431
0
  const size_t host_end = (port_colon != SIZE_MAX) ? port_colon : auth_end;
11432
11433
  // Empty host is invalid for special URLs.
11434
0
  if (auth_start == host_end) return false;
11435
11436
  // -- IPv4 handling ---------------------------------------------------------
11437
0
  const char* host_ptr = reinterpret_cast<const char*>(b + auth_start);
11438
0
  const size_t host_len = host_end - auth_start;
11439
11440
0
  if (all_dec_dots) {
11441
    // Host is all decimal digits and dots -> try the fast IPv4 parser.
11442
0
    if (checkers::try_parse_ipv4_fast({host_ptr, host_len}) !=
11443
0
        checkers::ipv4_fast_fail) {
11444
      // Valid decimal IPv4 host.  Do NOT return true yet: the port still
11445
      // needs to be validated below before we can declare the URL valid.
11446
0
      goto validate_port;
11447
0
    }
11448
    // Fast IPv4 parsing failed (e.g. host is ".", "..", "1.2.3.500").
11449
    // Such hosts may still be valid domain names; defer to the full parser.
11450
0
    return std::nullopt;
11451
0
  }
11452
11453
  // Last-significant-character heuristic for non-decimal IPv4 (hex/octal):
11454
  // if the last non-dot char is a digit, 'a'-'f', or 'x' the host might be
11455
  // an IPv4 address that the fast path can't validate -- fall through.
11456
  // last_non_dot was tracked during the authority scan above.
11457
0
  {
11458
0
    const uint8_t lc = last_non_dot | 0x20;
11459
0
    if ((last_non_dot >= '0' && last_non_dot <= '9') ||
11460
0
        (lc >= 'a' && lc <= 'f') || lc == 'x') {
11461
0
      return std::nullopt;
11462
0
    }
11463
0
  }
11464
11465
  // -- Port validation -------------------------------------------------------
11466
0
validate_port:
11467
0
  if (port_colon != SIZE_MAX) {
11468
0
    const uint8_t* pp = b + port_colon + 1;
11469
0
    size_t pl = auth_end - port_colon - 1;
11470
0
    if (pl > 0) {
11471
      // Strip leading zeros: "0000001" == 1, "0000000000000" == 0, both valid.
11472
      // Only the significant digits count toward the 5-digit maximum.
11473
0
      while (pl > 0 && *pp == '0') {
11474
0
        ++pp;
11475
0
        --pl;
11476
0
      }
11477
0
      if (pl > 5) return false;  // significant digits > 99999
11478
0
      uint32_t pv = 0;
11479
0
      for (size_t i = 0; i < pl; ++i) {
11480
0
        if (pp[i] < '0' || pp[i] > '9') return false;
11481
0
        pv = pv * 10 + (pp[i] - '0');
11482
0
      }
11483
0
      if (pv > 65535) return false;
11484
0
    }
11485
0
  }
11486
11487
  // Path, query, and fragment are structurally always valid for can_parse --
11488
  // the parser would encode whatever is there.
11489
0
  return true;
11490
0
}
11491
11492
}  // namespace
11493
11494
template <class result_type>
11495
ada_warn_unused tl::expected<result_type, errors> parse(
11496
1.20M
    std::string_view input, const result_type* base_url) {
11497
1.20M
  result_type u = ada::parser::parse_url_impl<result_type>(input, base_url);
11498
1.20M
  if (!u.is_valid) {
11499
523k
    return tl::unexpected(errors::type_error);
11500
523k
  }
11501
684k
  return u;
11502
1.20M
}
Unexecuted instantiation: tl::expected<ada::url, ada::errors> ada::parse<ada::url>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*)
tl::expected<ada::url_aggregator, ada::errors> ada::parse<ada::url_aggregator>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)
Line
Count
Source
11496
1.20M
    std::string_view input, const result_type* base_url) {
11497
1.20M
  result_type u = ada::parser::parse_url_impl<result_type>(input, base_url);
11498
1.20M
  if (!u.is_valid) {
11499
523k
    return tl::unexpected(errors::type_error);
11500
523k
  }
11501
684k
  return u;
11502
1.20M
}
11503
11504
template ada::result<url> parse<url>(std::string_view input,
11505
                                     const url* base_url = nullptr);
11506
template ada::result<url_aggregator> parse<url_aggregator>(
11507
    std::string_view input, const url_aggregator* base_url = nullptr);
11508
11509
0
std::string href_from_file(std::string_view input) {
11510
  // This is going to be much faster than constructing a URL.
11511
0
  std::string tmp_buffer;
11512
0
  std::string_view internal_input;
11513
0
  if (unicode::has_tabs_or_newline(input)) {
11514
0
    tmp_buffer = input;
11515
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
11516
0
    internal_input = tmp_buffer;
11517
0
  } else {
11518
0
    internal_input = input;
11519
0
  }
11520
0
  std::string path;
11521
0
  if (internal_input.empty()) {
11522
0
    path = "/";
11523
0
  } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
11524
0
    helpers::parse_prepared_path(internal_input.substr(1),
11525
0
                                 ada::scheme::type::FILE, path);
11526
0
  } else {
11527
0
    helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path);
11528
0
  }
11529
0
  return "file://" + path;
11530
0
}
11531
11532
0
bool can_parse(std::string_view input, const std::string_view* base_input) {
11533
  // Fast path: handles the overwhelming majority of inputs -- absolute special
11534
  // URLs with an ASCII domain, no credentials, and no base -- with a single
11535
  // forward scan and zero allocations.
11536
0
  if (base_input == nullptr) {
11537
0
    if (const auto r = try_can_parse_absolute_fast(input)) {
11538
0
      return *r;
11539
0
    }
11540
0
  }
11541
11542
  // Reject inputs that exceed the configurable maximum length.
11543
  // This check is placed after the fast path so the common case (default 4 GB
11544
  // limit, absolute URLs) pays no overhead.
11545
  // Note: can_parse() does not perform normalization (percent-encoding, IDNA),
11546
  // so it cannot detect cases where a short input normalizes into a long URL.
11547
  // In such edge cases can_parse() may return true while parse() fails.
11548
0
  const uint32_t max_length = ada::get_max_input_length();
11549
0
  if (input.size() > max_length) {
11550
0
    return false;
11551
0
  }
11552
0
  if (base_input != nullptr && base_input->size() > max_length) {
11553
0
    return false;
11554
0
  }
11555
11556
  // Fallback: run the parser in validation-only mode (store_values=false),
11557
  // which skips all the expensive work that isn't needed to determine validity:
11558
  // buffer reservation, credential encoding, path normalisation, query and
11559
  // fragment percent-encoding.  The host is still fully validated (IDNA, IPv4,
11560
  // IPv6) because parse_host() must run for correctness.
11561
0
  ada::url_aggregator base_agg;
11562
0
  ada::url_aggregator* base_ptr = nullptr;
11563
0
  if (base_input != nullptr) {
11564
0
    base_agg = ada::parser::parse_url_impl<ada::url_aggregator, false>(
11565
0
        *base_input, nullptr);
11566
0
    if (!base_agg.is_valid) return false;
11567
0
    base_ptr = &base_agg;
11568
0
  }
11569
0
  return ada::parser::parse_url_impl<ada::url_aggregator, false>(input,
11570
0
                                                                 base_ptr)
11571
0
      .is_valid;
11572
0
}
11573
11574
0
ada_warn_unused std::string_view to_string(ada::encoding_type type) {
11575
0
  switch (type) {
11576
0
    case ada::encoding_type::UTF8:
11577
0
      return "UTF-8";
11578
0
    case ada::encoding_type::UTF_16LE:
11579
0
      return "UTF-16LE";
11580
0
    case ada::encoding_type::UTF_16BE:
11581
0
      return "UTF-16BE";
11582
0
    default:
11583
0
      unreachable();
11584
0
  }
11585
0
}
11586
11587
}  // namespace ada
11588
/* end file src/implementation.cpp */
11589
/* begin file src/helpers.cpp */
11590
#include <cstdint>
11591
#include <cstring>
11592
#include <sstream>
11593
11594
11595
#if ADA_SSSE3
11596
#include <tmmintrin.h>
11597
#endif
11598
11599
namespace ada::helpers {
11600
11601
template <typename out_iter>
11602
0
void encode_json(std::string_view view, out_iter out) {
11603
  // trivial implementation. could be faster.
11604
0
  const char* hexvalues =
11605
0
      "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
11606
0
  for (uint8_t c : view) {
11607
0
    if (c == '\\') {
11608
0
      *out++ = '\\';
11609
0
      *out++ = '\\';
11610
0
    } else if (c == '"') {
11611
0
      *out++ = '\\';
11612
0
      *out++ = '"';
11613
0
    } else if (c <= 0x1f) {
11614
0
      *out++ = '\\';
11615
0
      *out++ = 'u';
11616
0
      *out++ = '0';
11617
0
      *out++ = '0';
11618
0
      *out++ = hexvalues[2 * c];
11619
0
      *out++ = hexvalues[2 * c + 1];
11620
0
    } else {
11621
0
      *out++ = c;
11622
0
    }
11623
0
  }
11624
0
}
11625
11626
0
ada_unused std::string get_state(ada::state s) {
11627
0
  switch (s) {
11628
0
    case ada::state::AUTHORITY:
11629
0
      return "Authority";
11630
0
    case ada::state::SCHEME_START:
11631
0
      return "Scheme Start";
11632
0
    case ada::state::SCHEME:
11633
0
      return "Scheme";
11634
0
    case ada::state::HOST:
11635
0
      return "Host";
11636
0
    case ada::state::NO_SCHEME:
11637
0
      return "No Scheme";
11638
0
    case ada::state::FRAGMENT:
11639
0
      return "Fragment";
11640
0
    case ada::state::RELATIVE_SCHEME:
11641
0
      return "Relative Scheme";
11642
0
    case ada::state::RELATIVE_SLASH:
11643
0
      return "Relative Slash";
11644
0
    case ada::state::FILE:
11645
0
      return "File";
11646
0
    case ada::state::FILE_HOST:
11647
0
      return "File Host";
11648
0
    case ada::state::FILE_SLASH:
11649
0
      return "File Slash";
11650
0
    case ada::state::PATH_OR_AUTHORITY:
11651
0
      return "Path or Authority";
11652
0
    case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES:
11653
0
      return "Special Authority Ignore Slashes";
11654
0
    case ada::state::SPECIAL_AUTHORITY_SLASHES:
11655
0
      return "Special Authority Slashes";
11656
0
    case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY:
11657
0
      return "Special Relative or Authority";
11658
0
    case ada::state::QUERY:
11659
0
      return "Query";
11660
0
    case ada::state::PATH:
11661
0
      return "Path";
11662
0
    case ada::state::PATH_START:
11663
0
      return "Path Start";
11664
0
    case ada::state::OPAQUE_PATH:
11665
0
      return "Opaque Path";
11666
0
    case ada::state::PORT:
11667
0
      return "Port";
11668
0
    default:
11669
0
      return "unknown state";
11670
0
  }
11671
0
}
11672
11673
ada_really_inline std::optional<std::string_view> prune_hash(
11674
1.20M
    std::string_view& input) noexcept {
11675
  // compiles down to 20--30 instructions including a class to memchr (C
11676
  // function). this function should be quite fast.
11677
1.20M
  size_t location_of_first = input.find('#');
11678
1.20M
  if (location_of_first == std::string_view::npos) {
11679
1.19M
    return std::nullopt;
11680
1.19M
  }
11681
16.0k
  std::string_view hash = input;
11682
16.0k
  hash.remove_prefix(location_of_first + 1);
11683
16.0k
  input.remove_suffix(input.size() - location_of_first);
11684
16.0k
  return hash;
11685
1.20M
}
11686
11687
7.43k
ada_really_inline bool shorten_path(std::string& path, ada::scheme::type type) {
11688
  // Let path be url's path.
11689
  // If url's scheme is "file", path's size is 1, and path[0] is a normalized
11690
  // Windows drive letter, then return.
11691
7.43k
  if (type == ada::scheme::type::FILE &&
11692
0
      path.find('/', 1) == std::string_view::npos && !path.empty()) {
11693
0
    if (checkers::is_normalized_windows_drive_letter(
11694
0
            helpers::substring(path, 1))) {
11695
0
      return false;
11696
0
    }
11697
0
  }
11698
11699
  // Remove path's last item, if any.
11700
7.43k
  size_t last_delimiter = path.rfind('/');
11701
7.43k
  if (last_delimiter != std::string::npos) {
11702
5.40k
    path.erase(last_delimiter);
11703
5.40k
    return true;
11704
5.40k
  }
11705
11706
2.02k
  return false;
11707
7.43k
}
11708
11709
ada_really_inline bool shorten_path(std::string_view& path,
11710
0
                                    ada::scheme::type type) {
11711
  // Let path be url's path.
11712
  // If url's scheme is "file", path's size is 1, and path[0] is a normalized
11713
  // Windows drive letter, then return.
11714
0
  if (type == ada::scheme::type::FILE &&
11715
0
      path.find('/', 1) == std::string_view::npos && !path.empty()) {
11716
0
    if (checkers::is_normalized_windows_drive_letter(
11717
0
            helpers::substring(path, 1))) {
11718
0
      return false;
11719
0
    }
11720
0
  }
11721
11722
  // Remove path's last item, if any.
11723
0
  if (!path.empty()) {
11724
0
    size_t slash_loc = path.rfind('/');
11725
0
    if (slash_loc != std::string_view::npos) {
11726
0
      path.remove_suffix(path.size() - slash_loc);
11727
0
      return true;
11728
0
    }
11729
0
  }
11730
11731
0
  return false;
11732
0
}
11733
11734
12.6k
ada_really_inline void remove_ascii_tab_or_newline(std::string& input) {
11735
  // if this ever becomes a performance issue, we could use an approach similar
11736
  // to has_tabs_or_newline
11737
12.6k
  std::erase_if(input, ada::unicode::is_ascii_tab_or_newline);
11738
12.6k
}
11739
11740
ada_really_inline constexpr std::string_view substring(std::string_view input,
11741
12.0k
                                                       size_t pos) {
11742
12.0k
  ADA_ASSERT_TRUE(pos <= input.size());
11743
  // The following is safer but unneeded if we have the above line:
11744
  // return pos > input.size() ? std::string_view() : input.substr(pos);
11745
12.0k
  return input.substr(pos);
11746
12.0k
}
11747
11748
0
ada_really_inline void resize(std::string_view& input, size_t pos) noexcept {
11749
0
  ADA_ASSERT_TRUE(pos <= input.size());
11750
0
  input.remove_suffix(input.size() - pos);
11751
0
}
11752
11753
// computes the number of trailing zeroes
11754
// this is a private inline function only defined in this source file.
11755
269k
ada_really_inline int trailing_zeroes(uint32_t input_num) noexcept {
11756
#ifdef ADA_REGULAR_VISUAL_STUDIO
11757
  unsigned long ret;
11758
  // Search the mask data from least significant bit (LSB)
11759
  // to the most significant bit (MSB) for a set bit (1).
11760
  _BitScanForward(&ret, input_num);
11761
  return (int)ret;
11762
#else   // ADA_REGULAR_VISUAL_STUDIO
11763
269k
  return __builtin_ctzl(input_num);
11764
269k
#endif  // ADA_REGULAR_VISUAL_STUDIO
11765
269k
}
11766
11767
// starting at index location, this finds the next location of a character
11768
// :, /, \\, ? or [. If none is found, view.size() is returned.
11769
// For use within get_host_delimiter_location.
11770
#if ADA_SSSE3
11771
ada_really_inline size_t find_next_host_delimiter_special(
11772
    std::string_view view, size_t location) noexcept {
11773
  // first check for short strings in which case we do it naively.
11774
  if (view.size() - location < 16) {  // slow path
11775
    for (size_t i = location; i < view.size(); i++) {
11776
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
11777
          view[i] == '?' || view[i] == '[') {
11778
        return i;
11779
      }
11780
    }
11781
    return size_t(view.size());
11782
  }
11783
  // fast path for long strings (expected to be common)
11784
  // Using SSSE3's _mm_shuffle_epi8 for table lookup (same approach as NEON)
11785
  size_t i = location;
11786
  const __m128i low_mask =
11787
      _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11788
                    0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
11789
  const __m128i high_mask =
11790
      _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
11791
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
11792
  const __m128i fmask = _mm_set1_epi8(0xf);
11793
  const __m128i zero = _mm_setzero_si128();
11794
  for (; i + 15 < view.size(); i += 16) {
11795
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
11796
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
11797
    __m128i highpart = _mm_shuffle_epi8(
11798
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
11799
    __m128i classify = _mm_and_si128(lowpart, highpart);
11800
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
11801
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
11802
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
11803
    // avoid false positives.
11804
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
11805
    if (mask != 0) {
11806
      return i + trailing_zeroes(static_cast<uint32_t>(mask));
11807
    }
11808
  }
11809
  if (i < view.size()) {
11810
    __m128i word =
11811
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
11812
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
11813
    __m128i highpart = _mm_shuffle_epi8(
11814
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
11815
    __m128i classify = _mm_and_si128(lowpart, highpart);
11816
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
11817
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
11818
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
11819
    // avoid false positives.
11820
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
11821
    if (mask != 0) {
11822
      return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask));
11823
    }
11824
  }
11825
  return size_t(view.size());
11826
}
11827
#elif ADA_NEON
11828
// The ada_make_uint8x16_t macro is necessary because Visual Studio does not
11829
// support direct initialization of uint8x16_t. See
11830
// https://developercommunity.visualstudio.com/t/error-C2078:-too-many-initializers-whe/402911?q=backend+neon
11831
#ifndef ada_make_uint8x16_t
11832
#define ada_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \
11833
                            x13, x14, x15, x16)                                \
11834
  ([=]() {                                                                     \
11835
    static uint8_t array[16] = {x1, x2,  x3,  x4,  x5,  x6,  x7,  x8,          \
11836
                                x9, x10, x11, x12, x13, x14, x15, x16};        \
11837
    return vld1q_u8(array);                                                    \
11838
  }())
11839
#endif
11840
11841
ada_really_inline size_t find_next_host_delimiter_special(
11842
    std::string_view view, size_t location) noexcept {
11843
  // first check for short strings in which case we do it naively.
11844
  if (view.size() - location < 16) {  // slow path
11845
    for (size_t i = location; i < view.size(); i++) {
11846
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
11847
          view[i] == '?' || view[i] == '[') {
11848
        return i;
11849
      }
11850
    }
11851
    return size_t(view.size());
11852
  }
11853
  auto to_bitmask = [](uint8x16_t input) -> uint16_t {
11854
    uint8x16_t bit_mask =
11855
        ada_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01,
11856
                            0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
11857
    uint8x16_t minput = vandq_u8(input, bit_mask);
11858
    uint8x16_t tmp = vpaddq_u8(minput, minput);
11859
    tmp = vpaddq_u8(tmp, tmp);
11860
    tmp = vpaddq_u8(tmp, tmp);
11861
    return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0);
11862
  };
11863
11864
  // fast path for long strings (expected to be common)
11865
  size_t i = location;
11866
  uint8x16_t low_mask =
11867
      ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11868
                          0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
11869
  uint8x16_t high_mask =
11870
      ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
11871
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
11872
  uint8x16_t fmask = vmovq_n_u8(0xf);
11873
  uint8x16_t zero{0};
11874
  for (; i + 15 < view.size(); i += 16) {
11875
    uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
11876
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
11877
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
11878
    uint8x16_t classify = vandq_u8(lowpart, highpart);
11879
    if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
11880
      uint8x16_t is_zero = vceqq_u8(classify, zero);
11881
      uint16_t is_non_zero = static_cast<uint16_t>(~to_bitmask(is_zero));
11882
      return i + trailing_zeroes(is_non_zero);
11883
    }
11884
  }
11885
11886
  if (i < view.size()) {
11887
    uint8x16_t word =
11888
        vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
11889
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
11890
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
11891
    uint8x16_t classify = vandq_u8(lowpart, highpart);
11892
    if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
11893
      uint8x16_t is_zero = vceqq_u8(classify, zero);
11894
      uint16_t is_non_zero = static_cast<uint16_t>(~to_bitmask(is_zero));
11895
      return view.length() - 16 + trailing_zeroes(is_non_zero);
11896
    }
11897
  }
11898
  return size_t(view.size());
11899
}
11900
#elif ADA_SSE2
11901
ada_really_inline size_t find_next_host_delimiter_special(
11902
955k
    std::string_view view, size_t location) noexcept {
11903
  // first check for short strings in which case we do it naively.
11904
955k
  if (view.size() - location < 16) {  // slow path
11905
4.81M
    for (size_t i = location; i < view.size(); i++) {
11906
4.12M
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
11907
3.94M
          view[i] == '?' || view[i] == '[') {
11908
207k
        return i;
11909
207k
      }
11910
4.12M
    }
11911
693k
    return size_t(view.size());
11912
900k
  }
11913
  // fast path for long strings (expected to be common)
11914
54.3k
  size_t i = location;
11915
54.3k
  const __m128i mask1 = _mm_set1_epi8(':');
11916
54.3k
  const __m128i mask2 = _mm_set1_epi8('/');
11917
54.3k
  const __m128i mask3 = _mm_set1_epi8('\\');
11918
54.3k
  const __m128i mask4 = _mm_set1_epi8('?');
11919
54.3k
  const __m128i mask5 = _mm_set1_epi8('[');
11920
11921
86.8k
  for (; i + 15 < view.size(); i += 16) {
11922
57.2k
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
11923
57.2k
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
11924
57.2k
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
11925
57.2k
    __m128i m3 = _mm_cmpeq_epi8(word, mask3);
11926
57.2k
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
11927
57.2k
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
11928
57.2k
    __m128i m = _mm_or_si128(
11929
57.2k
        _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
11930
57.2k
    int mask = _mm_movemask_epi8(m);
11931
57.2k
    if (mask != 0) {
11932
24.7k
      return i + trailing_zeroes(mask);
11933
24.7k
    }
11934
57.2k
  }
11935
29.5k
  if (i < view.size()) {
11936
29.0k
    __m128i word =
11937
29.0k
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
11938
29.0k
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
11939
29.0k
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
11940
29.0k
    __m128i m3 = _mm_cmpeq_epi8(word, mask3);
11941
29.0k
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
11942
29.0k
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
11943
29.0k
    __m128i m = _mm_or_si128(
11944
29.0k
        _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
11945
29.0k
    int mask = _mm_movemask_epi8(m);
11946
29.0k
    if (mask != 0) {
11947
28.1k
      return view.length() - 16 + trailing_zeroes(mask);
11948
28.1k
    }
11949
29.0k
  }
11950
1.45k
  return size_t(view.length());
11951
29.5k
}
11952
#elif ADA_LSX
11953
ada_really_inline size_t find_next_host_delimiter_special(
11954
    std::string_view view, size_t location) noexcept {
11955
  // first check for short strings in which case we do it naively.
11956
  if (view.size() - location < 16) {  // slow path
11957
    for (size_t i = location; i < view.size(); i++) {
11958
      if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
11959
          view[i] == '?' || view[i] == '[') {
11960
        return i;
11961
      }
11962
    }
11963
    return size_t(view.size());
11964
  }
11965
  // fast path for long strings (expected to be common)
11966
  size_t i = location;
11967
  const __m128i mask1 = __lsx_vrepli_b(':');
11968
  const __m128i mask2 = __lsx_vrepli_b('/');
11969
  const __m128i mask3 = __lsx_vrepli_b('\\');
11970
  const __m128i mask4 = __lsx_vrepli_b('?');
11971
  const __m128i mask5 = __lsx_vrepli_b('[');
11972
11973
  for (; i + 15 < view.size(); i += 16) {
11974
    __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0);
11975
    __m128i m1 = __lsx_vseq_b(word, mask1);
11976
    __m128i m2 = __lsx_vseq_b(word, mask2);
11977
    __m128i m3 = __lsx_vseq_b(word, mask3);
11978
    __m128i m4 = __lsx_vseq_b(word, mask4);
11979
    __m128i m5 = __lsx_vseq_b(word, mask5);
11980
    __m128i m =
11981
        __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5);
11982
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
11983
    if (mask != 0) {
11984
      return i + trailing_zeroes(mask);
11985
    }
11986
  }
11987
  if (i < view.size()) {
11988
    __m128i word =
11989
        __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0);
11990
    __m128i m1 = __lsx_vseq_b(word, mask1);
11991
    __m128i m2 = __lsx_vseq_b(word, mask2);
11992
    __m128i m3 = __lsx_vseq_b(word, mask3);
11993
    __m128i m4 = __lsx_vseq_b(word, mask4);
11994
    __m128i m5 = __lsx_vseq_b(word, mask5);
11995
    __m128i m =
11996
        __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5);
11997
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
11998
    if (mask != 0) {
11999
      return view.length() - 16 + trailing_zeroes(mask);
12000
    }
12001
  }
12002
  return size_t(view.length());
12003
}
12004
#elif ADA_RVV
12005
ada_really_inline size_t find_next_host_delimiter_special(
12006
    std::string_view view, size_t location) noexcept {
12007
  // The LUT approach was a bit slower on the SpacemiT X60, but I could see it
12008
  // being faster on future hardware.
12009
#if 0
12010
  // LUT generated using: s=":/\\?["; list(zip([((ord(c)>>2)&0xF)for c in s],s))
12011
  static const uint8_t tbl[16] = {
12012
    0xF, 0, 0, 0, 0, 0, '[', '\\', 0, 0, 0, '/', 0, 0, ':', '?'
12013
  };
12014
  vuint8m1_t vtbl = __riscv_vle8_v_u8m1(tbl, 16);
12015
#endif
12016
  uint8_t* src = (uint8_t*)view.data() + location;
12017
  for (size_t vl, n = view.size() - location; n > 0;
12018
       n -= vl, src += vl, location += vl) {
12019
    vl = __riscv_vsetvl_e8m1(n);
12020
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
12021
#if 0
12022
    vuint8m1_t vidx = __riscv_vand(__riscv_vsrl(v, 2, vl), 0xF, vl);
12023
    vuint8m1_t vlut = __riscv_vrgather(vtbl, vidx, vl);
12024
    vbool8_t m = __riscv_vmseq(v, vlut, vl);
12025
#else
12026
    vbool8_t m1 = __riscv_vmseq(v, ':', vl);
12027
    vbool8_t m2 = __riscv_vmseq(v, '/', vl);
12028
    vbool8_t m3 = __riscv_vmseq(v, '?', vl);
12029
    vbool8_t m4 = __riscv_vmseq(v, '[', vl);
12030
    vbool8_t m5 = __riscv_vmseq(v, '\\', vl);
12031
    vbool8_t m = __riscv_vmor(
12032
        __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl),
12033
        m5, vl);
12034
#endif
12035
    long idx = __riscv_vfirst(m, vl);
12036
    if (idx >= 0) return location + idx;
12037
  }
12038
  return size_t(view.size());
12039
}
12040
#else
12041
// : / [ \\ ?
12042
static constexpr std::array<uint8_t, 256> special_host_delimiters =
12043
    []() consteval {
12044
      std::array<uint8_t, 256> result{};
12045
      for (int i : {':', '/', '[', '\\', '?'}) {
12046
        result[i] = 1;
12047
      }
12048
      return result;
12049
    }();
12050
// credit: @the-moisrex recommended a table-based approach
12051
ada_really_inline size_t find_next_host_delimiter_special(
12052
    std::string_view view, size_t location) noexcept {
12053
  auto const str = view.substr(location);
12054
  for (auto pos = str.begin(); pos != str.end(); ++pos) {
12055
    if (special_host_delimiters[(uint8_t)*pos]) {
12056
      return pos - str.begin() + location;
12057
    }
12058
  }
12059
  return size_t(view.size());
12060
}
12061
#endif
12062
12063
// starting at index location, this finds the next location of a character
12064
// :, /, ? or [. If none is found, view.size() is returned.
12065
// For use within get_host_delimiter_location.
12066
#if ADA_SSSE3
12067
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
12068
                                                  size_t location) noexcept {
12069
  // first check for short strings in which case we do it naively.
12070
  if (view.size() - location < 16) {  // slow path
12071
    for (size_t i = location; i < view.size(); i++) {
12072
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
12073
          view[i] == '[') {
12074
        return i;
12075
      }
12076
    }
12077
    return size_t(view.size());
12078
  }
12079
  // fast path for long strings (expected to be common)
12080
  size_t i = location;
12081
  // Lookup tables for bit classification:
12082
  // ':' (0x3A): low[0xA]=0x01, high[0x3]=0x01 -> match
12083
  // '/' (0x2F): low[0xF]=0x02, high[0x2]=0x02 -> match
12084
  // '?' (0x3F): low[0xF]=0x01, high[0x3]=0x01 -> match
12085
  // '[' (0x5B): low[0xB]=0x04, high[0x5]=0x04 -> match
12086
  const __m128i low_mask =
12087
      _mm_setr_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12088
                    0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
12089
  const __m128i high_mask =
12090
      _mm_setr_epi8(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
12091
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
12092
  const __m128i fmask = _mm_set1_epi8(0xf);
12093
  const __m128i zero = _mm_setzero_si128();
12094
12095
  for (; i + 15 < view.size(); i += 16) {
12096
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
12097
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
12098
    __m128i highpart = _mm_shuffle_epi8(
12099
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
12100
    __m128i classify = _mm_and_si128(lowpart, highpart);
12101
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
12102
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
12103
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
12104
    // avoid false positives.
12105
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
12106
    if (mask != 0) {
12107
      return i + trailing_zeroes(static_cast<uint32_t>(mask));
12108
    }
12109
  }
12110
12111
  if (i < view.size()) {
12112
    __m128i word =
12113
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
12114
    __m128i lowpart = _mm_shuffle_epi8(low_mask, _mm_and_si128(word, fmask));
12115
    __m128i highpart = _mm_shuffle_epi8(
12116
        high_mask, _mm_and_si128(_mm_srli_epi16(word, 4), fmask));
12117
    __m128i classify = _mm_and_si128(lowpart, highpart);
12118
    __m128i is_zero = _mm_cmpeq_epi8(classify, zero);
12119
    // _mm_movemask_epi8 returns a 16-bit mask in bits 0-15, with bits 16-31
12120
    // zero. After NOT (~), bits 16-31 become 1. We must mask to 16 bits to
12121
    // avoid false positives.
12122
    int mask = ~_mm_movemask_epi8(is_zero) & 0xFFFF;
12123
    if (mask != 0) {
12124
      return view.length() - 16 + trailing_zeroes(static_cast<uint32_t>(mask));
12125
    }
12126
  }
12127
  return size_t(view.size());
12128
}
12129
#elif ADA_NEON
12130
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
12131
                                                  size_t location) noexcept {
12132
  // first check for short strings in which case we do it naively.
12133
  if (view.size() - location < 16) {  // slow path
12134
    for (size_t i = location; i < view.size(); i++) {
12135
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
12136
          view[i] == '[') {
12137
        return i;
12138
      }
12139
    }
12140
    return size_t(view.size());
12141
  }
12142
  auto to_bitmask = [](uint8x16_t input) -> uint16_t {
12143
    uint8x16_t bit_mask =
12144
        ada_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01,
12145
                            0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
12146
    uint8x16_t minput = vandq_u8(input, bit_mask);
12147
    uint8x16_t tmp = vpaddq_u8(minput, minput);
12148
    tmp = vpaddq_u8(tmp, tmp);
12149
    tmp = vpaddq_u8(tmp, tmp);
12150
    return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0);
12151
  };
12152
12153
  // fast path for long strings (expected to be common)
12154
  size_t i = location;
12155
  uint8x16_t low_mask =
12156
      ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12157
                          0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
12158
  uint8x16_t high_mask =
12159
      ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
12160
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
12161
  uint8x16_t fmask = vmovq_n_u8(0xf);
12162
  uint8x16_t zero{0};
12163
  for (; i + 15 < view.size(); i += 16) {
12164
    uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
12165
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
12166
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
12167
    uint8x16_t classify = vandq_u8(lowpart, highpart);
12168
    if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
12169
      uint8x16_t is_zero = vceqq_u8(classify, zero);
12170
      uint16_t is_non_zero = static_cast<uint16_t>(~to_bitmask(is_zero));
12171
      return i + trailing_zeroes(is_non_zero);
12172
    }
12173
  }
12174
12175
  if (i < view.size()) {
12176
    uint8x16_t word =
12177
        vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
12178
    uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
12179
    uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
12180
    uint8x16_t classify = vandq_u8(lowpart, highpart);
12181
    if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
12182
      uint8x16_t is_zero = vceqq_u8(classify, zero);
12183
      uint16_t is_non_zero = static_cast<uint16_t>(~to_bitmask(is_zero));
12184
      return view.length() - 16 + trailing_zeroes(is_non_zero);
12185
    }
12186
  }
12187
  return size_t(view.size());
12188
}
12189
#elif ADA_SSE2
12190
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
12191
218k
                                                  size_t location) noexcept {
12192
  // first check for short strings in which case we do it naively.
12193
218k
  if (view.size() - location < 16) {  // slow path
12194
11.6k
    for (size_t i = location; i < view.size(); i++) {
12195
11.4k
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
12196
10.1k
          view[i] == '[') {
12197
1.45k
        return i;
12198
1.45k
      }
12199
11.4k
    }
12200
233
    return size_t(view.size());
12201
1.68k
  }
12202
  // fast path for long strings (expected to be common)
12203
216k
  size_t i = location;
12204
216k
  const __m128i mask1 = _mm_set1_epi8(':');
12205
216k
  const __m128i mask2 = _mm_set1_epi8('/');
12206
216k
  const __m128i mask4 = _mm_set1_epi8('?');
12207
216k
  const __m128i mask5 = _mm_set1_epi8('[');
12208
12209
217k
  for (; i + 15 < view.size(); i += 16) {
12210
216k
    __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
12211
216k
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
12212
216k
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
12213
216k
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
12214
216k
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
12215
216k
    __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
12216
216k
    int mask = _mm_movemask_epi8(m);
12217
216k
    if (mask != 0) {
12218
216k
      return i + trailing_zeroes(mask);
12219
216k
    }
12220
216k
  }
12221
22
  if (i < view.size()) {
12222
15
    __m128i word =
12223
15
        _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
12224
15
    __m128i m1 = _mm_cmpeq_epi8(word, mask1);
12225
15
    __m128i m2 = _mm_cmpeq_epi8(word, mask2);
12226
15
    __m128i m4 = _mm_cmpeq_epi8(word, mask4);
12227
15
    __m128i m5 = _mm_cmpeq_epi8(word, mask5);
12228
15
    __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
12229
15
    int mask = _mm_movemask_epi8(m);
12230
15
    if (mask != 0) {
12231
6
      return view.length() - 16 + trailing_zeroes(mask);
12232
6
    }
12233
15
  }
12234
16
  return size_t(view.length());
12235
22
}
12236
#elif ADA_LSX
12237
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
12238
                                                  size_t location) noexcept {
12239
  // first check for short strings in which case we do it naively.
12240
  if (view.size() - location < 16) {  // slow path
12241
    for (size_t i = location; i < view.size(); i++) {
12242
      if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
12243
          view[i] == '[') {
12244
        return i;
12245
      }
12246
    }
12247
    return size_t(view.size());
12248
  }
12249
  // fast path for long strings (expected to be common)
12250
  size_t i = location;
12251
  const __m128i mask1 = __lsx_vrepli_b(':');
12252
  const __m128i mask2 = __lsx_vrepli_b('/');
12253
  const __m128i mask4 = __lsx_vrepli_b('?');
12254
  const __m128i mask5 = __lsx_vrepli_b('[');
12255
12256
  for (; i + 15 < view.size(); i += 16) {
12257
    __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0);
12258
    __m128i m1 = __lsx_vseq_b(word, mask1);
12259
    __m128i m2 = __lsx_vseq_b(word, mask2);
12260
    __m128i m4 = __lsx_vseq_b(word, mask4);
12261
    __m128i m5 = __lsx_vseq_b(word, mask5);
12262
    __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5));
12263
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
12264
    if (mask != 0) {
12265
      return i + trailing_zeroes(mask);
12266
    }
12267
  }
12268
  if (i < view.size()) {
12269
    __m128i word =
12270
        __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0);
12271
    __m128i m1 = __lsx_vseq_b(word, mask1);
12272
    __m128i m2 = __lsx_vseq_b(word, mask2);
12273
    __m128i m4 = __lsx_vseq_b(word, mask4);
12274
    __m128i m5 = __lsx_vseq_b(word, mask5);
12275
    __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5));
12276
    int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0);
12277
    if (mask != 0) {
12278
      return view.length() - 16 + trailing_zeroes(mask);
12279
    }
12280
  }
12281
  return size_t(view.length());
12282
}
12283
#elif ADA_RVV
12284
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
12285
                                                  size_t location) noexcept {
12286
  uint8_t* src = (uint8_t*)view.data() + location;
12287
  for (size_t vl, n = view.size() - location; n > 0;
12288
       n -= vl, src += vl, location += vl) {
12289
    vl = __riscv_vsetvl_e8m1(n);
12290
    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
12291
    vbool8_t m1 = __riscv_vmseq(v, ':', vl);
12292
    vbool8_t m2 = __riscv_vmseq(v, '/', vl);
12293
    vbool8_t m3 = __riscv_vmseq(v, '?', vl);
12294
    vbool8_t m4 = __riscv_vmseq(v, '[', vl);
12295
    vbool8_t m =
12296
        __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl);
12297
    long idx = __riscv_vfirst(m, vl);
12298
    if (idx >= 0) return location + idx;
12299
  }
12300
  return size_t(view.size());
12301
}
12302
#else
12303
// : / [ ?
12304
static constexpr std::array<uint8_t, 256> host_delimiters = []() consteval {
12305
  std::array<uint8_t, 256> result{};
12306
  for (int i : {':', '/', '?', '['}) {
12307
    result[i] = 1;
12308
  }
12309
  return result;
12310
}();
12311
// credit: @the-moisrex recommended a table-based approach
12312
ada_really_inline size_t find_next_host_delimiter(std::string_view view,
12313
                                                  size_t location) noexcept {
12314
  auto const str = view.substr(location);
12315
  for (auto pos = str.begin(); pos != str.end(); ++pos) {
12316
    if (host_delimiters[(uint8_t)*pos]) {
12317
      return pos - str.begin() + location;
12318
    }
12319
  }
12320
  return size_t(view.size());
12321
}
12322
#endif
12323
12324
ada_really_inline std::pair<size_t, bool> get_host_delimiter_location(
12325
1.16M
    const bool is_special, std::string_view& view) noexcept {
12326
  /**
12327
   * The spec at https://url.spec.whatwg.org/#hostname-state expects us to
12328
   * compute a variable called insideBrackets but this variable is only used
12329
   * once, to check whether a ':' character was found outside brackets. Exact
12330
   * text: "Otherwise, if c is U+003A (:) and insideBrackets is false, then:".
12331
   * It is conceptually simpler and arguably more efficient to just return a
12332
   * Boolean indicating whether ':' was found outside brackets.
12333
   */
12334
1.16M
  const size_t view_size = view.size();
12335
1.16M
  size_t location = 0;
12336
1.16M
  bool found_colon = false;
12337
  /**
12338
   * Performance analysis:
12339
   *
12340
   * We are basically seeking the end of the hostname which can be indicated
12341
   * by the end of the view, or by one of the characters ':', '/', '?', '\\'
12342
   * (where '\\' is only applicable for special URLs). However, these must
12343
   * appear outside a bracket range. E.g., if you have [something?]fd: then the
12344
   * '?' does not count.
12345
   *
12346
   * So we can skip ahead to the next delimiter, as long as we include '[' in
12347
   * the set of delimiters, and that we handle it first.
12348
   *
12349
   * So the trick is to have a fast function that locates the next delimiter.
12350
   * Unless we find '[', then it only needs to be called once! Ideally, such a
12351
   * function would be provided by the C++ standard library, but it seems that
12352
   * find_first_of is not very fast, so we are forced to roll our own.
12353
   *
12354
   * We do not break into two loops for speed, but for clarity.
12355
   */
12356
1.16M
  if (is_special) {
12357
    // We move to the next delimiter.
12358
941k
    location = find_next_host_delimiter_special(view, location);
12359
    // Unless we find '[' then we are going only going to have to call
12360
    // find_next_host_delimiter_special once.
12361
955k
    for (; location < view_size;
12362
941k
         location = find_next_host_delimiter_special(view, location)) {
12363
260k
      if (view[location] == '[') {
12364
24.7k
        location = view.find(']', location);
12365
24.7k
        if (location == std::string_view::npos) {
12366
          // performance: view.find might get translated to a memchr, which
12367
          // has no notion of std::string_view::npos, so the code does not
12368
          // reflect the assembly.
12369
11.2k
          location = view_size;
12370
11.2k
          break;
12371
11.2k
        }
12372
235k
      } else {
12373
235k
        found_colon = view[location] == ':';
12374
235k
        break;
12375
235k
      }
12376
260k
    }
12377
941k
  } else {
12378
    // We move to the next delimiter.
12379
218k
    location = find_next_host_delimiter(view, location);
12380
    // Unless we find '[' then we are going only going to have to call
12381
    // find_next_host_delimiter_special once.
12382
218k
    for (; location < view_size;
12383
218k
         location = find_next_host_delimiter(view, location)) {
12384
218k
      if (view[location] == '[') {
12385
184
        location = view.find(']', location);
12386
184
        if (location == std::string_view::npos) {
12387
          // performance: view.find might get translated to a memchr, which
12388
          // has no notion of std::string_view::npos, so the code does not
12389
          // reflect the assembly.
12390
34
          location = view_size;
12391
34
          break;
12392
34
        }
12393
218k
      } else {
12394
218k
        found_colon = view[location] == ':';
12395
218k
        break;
12396
218k
      }
12397
218k
    }
12398
218k
  }
12399
  // performance: remove_suffix may translate into a single instruction.
12400
1.16M
  view.remove_suffix(view_size - location);
12401
1.16M
  return {location, found_colon};
12402
1.16M
}
12403
12404
1.20M
void trim_c0_whitespace(std::string_view& input) noexcept {
12405
1.20M
  while (!input.empty() &&
12406
1.20M
         ada::unicode::is_c0_control_or_space(input.front())) {
12407
0
    input.remove_prefix(1);
12408
0
  }
12409
1.21M
  while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) {
12410
5.95k
    input.remove_suffix(1);
12411
5.95k
  }
12412
1.20M
}
12413
12414
ada_really_inline void parse_prepared_path(std::string_view input,
12415
                                           ada::scheme::type type,
12416
0
                                           std::string& path) {
12417
0
  ada_log("parse_prepared_path ", input);
12418
0
  uint8_t accumulator = checkers::path_signature(input);
12419
  // Let us first detect a trivial case.
12420
  // If it is special, we check that we have no dot, no %,  no \ and no
12421
  // character needing percent encoding. Otherwise, we check that we have no %,
12422
  // no dot, and no character needing percent encoding.
12423
0
  constexpr uint8_t need_encoding = 1;
12424
0
  constexpr uint8_t backslash_char = 2;
12425
0
  constexpr uint8_t dot_char = 4;
12426
0
  constexpr uint8_t percent_char = 8;
12427
0
  bool special = type != ada::scheme::NOT_SPECIAL;
12428
0
  bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
12429
0
                                      checkers::is_windows_drive_letter(input));
12430
0
  bool trivial_path =
12431
0
      (special ? (accumulator == 0)
12432
0
               : ((accumulator & (need_encoding | dot_char | percent_char)) ==
12433
0
                  0)) &&
12434
0
      (!may_need_slow_file_handling);
12435
0
  if (accumulator == dot_char && !may_need_slow_file_handling) {
12436
    // '4' means that we have at least one dot, but nothing that requires
12437
    // percent encoding or decoding. The only part that is not trivial is
12438
    // that we may have single dots and double dots path segments.
12439
    // If we have such segments, then we either have a path that begins
12440
    // with '.' (easy to check), or we have the sequence './'.
12441
    // Note: input cannot be empty, it must at least contain one character ('.')
12442
    // Note: we know that '\' is not present.
12443
0
    if (input[0] != '.') {
12444
0
      size_t slashdot = 0;
12445
0
      bool dot_is_file = true;
12446
0
      for (;;) {
12447
0
        slashdot = input.find("/.", slashdot);
12448
0
        if (slashdot == std::string_view::npos) {  // common case
12449
0
          break;
12450
0
        } else {  // uncommon
12451
          // only three cases matter: /./, /.. or a final /
12452
0
          slashdot += 2;
12453
0
          dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' ||
12454
0
                           input[slashdot] == '/');
12455
0
        }
12456
0
      }
12457
0
      trivial_path = dot_is_file;
12458
0
    }
12459
0
  }
12460
0
  if (trivial_path) {
12461
0
    ada_log("parse_path trivial");
12462
0
    path += '/';
12463
0
    path += input;
12464
0
    return;
12465
0
  }
12466
  // We are going to need to look a bit at the path, but let us see if we can
12467
  // ignore percent encoding *and* backslashes *and* percent characters.
12468
  // Except for the trivial case, this is likely to capture 99% of paths out
12469
  // there.
12470
0
  bool fast_path =
12471
0
      (special &&
12472
0
       (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
12473
0
      (type != ada::scheme::type::FILE);
12474
0
  if (fast_path) {
12475
0
    ada_log("parse_prepared_path fast");
12476
    // Here we don't need to worry about \ or percent encoding.
12477
    // We also do not have a file protocol. We might have dots, however,
12478
    // but dots must as appear as '.', and they cannot be encoded because
12479
    // the symbol '%' is not present.
12480
0
    size_t previous_location = 0;  // We start at 0.
12481
0
    do {
12482
0
      size_t new_location = input.find('/', previous_location);
12483
      // std::string_view path_view = input;
12484
      //  We process the last segment separately:
12485
0
      if (new_location == std::string_view::npos) {
12486
0
        std::string_view path_view = input.substr(previous_location);
12487
0
        if (path_view == "..") {  // The path ends with ..
12488
          // e.g., if you receive ".." with an empty path, you go to "/".
12489
0
          if (path.empty()) {
12490
0
            path = '/';
12491
0
            return;
12492
0
          }
12493
          // Fast case where we have nothing to do:
12494
0
          if (path.back() == '/') {
12495
0
            return;
12496
0
          }
12497
          // If you have the path "/joe/myfriend",
12498
          // then you delete 'myfriend'.
12499
0
          path.resize(path.rfind('/') + 1);
12500
0
          return;
12501
0
        }
12502
0
        path += '/';
12503
0
        if (path_view != ".") {
12504
0
          path.append(path_view);
12505
0
        }
12506
0
        return;
12507
0
      } else {
12508
        // This is a non-final segment.
12509
0
        std::string_view path_view =
12510
0
            input.substr(previous_location, new_location - previous_location);
12511
0
        previous_location = new_location + 1;
12512
0
        if (path_view == "..") {
12513
0
          size_t last_delimiter = path.rfind('/');
12514
0
          if (last_delimiter != std::string::npos) {
12515
0
            path.erase(last_delimiter);
12516
0
          }
12517
0
        } else if (path_view != ".") {
12518
0
          path += '/';
12519
0
          path.append(path_view);
12520
0
        }
12521
0
      }
12522
0
    } while (true);
12523
0
  } else {
12524
0
    ada_log("parse_path slow");
12525
    // we have reached the general case
12526
0
    bool needs_percent_encoding = (accumulator & 1);
12527
0
    std::string path_buffer_tmp;
12528
0
    do {
12529
0
      size_t location = (special && (accumulator & 2))
12530
0
                            ? input.find_first_of("/\\")
12531
0
                            : input.find('/');
12532
0
      std::string_view path_view = input;
12533
0
      if (location != std::string_view::npos) {
12534
0
        path_view.remove_suffix(path_view.size() - location);
12535
0
        input.remove_prefix(location + 1);
12536
0
      }
12537
      // path_buffer is either path_view or it might point at a percent encoded
12538
      // temporary file.
12539
0
      std::string_view path_buffer =
12540
0
          (needs_percent_encoding &&
12541
0
           ada::unicode::percent_encode<false>(
12542
0
               path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
12543
0
              ? path_buffer_tmp
12544
0
              : path_view;
12545
0
      if (unicode::is_double_dot_path_segment(path_buffer)) {
12546
0
        helpers::shorten_path(path, type);
12547
0
        if (location == std::string_view::npos) {
12548
0
          path += '/';
12549
0
        }
12550
0
      } else if (unicode::is_single_dot_path_segment(path_buffer) &&
12551
0
                 (location == std::string_view::npos)) {
12552
0
        path += '/';
12553
0
      }
12554
      // Otherwise, if path_buffer is not a single-dot path segment, then:
12555
0
      else if (!unicode::is_single_dot_path_segment(path_buffer)) {
12556
        // If url's scheme is "file", url's path is empty, and path_buffer is a
12557
        // Windows drive letter, then replace the second code point in
12558
        // path_buffer with U+003A (:).
12559
0
        if (type == ada::scheme::type::FILE && path.empty() &&
12560
0
            checkers::is_windows_drive_letter(path_buffer)) {
12561
0
          path += '/';
12562
0
          path += path_buffer[0];
12563
0
          path += ':';
12564
0
          path_buffer.remove_prefix(2);
12565
0
          path.append(path_buffer);
12566
0
        } else {
12567
          // Append path_buffer to url's path.
12568
0
          path += '/';
12569
0
          path.append(path_buffer);
12570
0
        }
12571
0
      }
12572
0
      if (location == std::string_view::npos) {
12573
0
        return;
12574
0
      }
12575
0
    } while (true);
12576
0
  }
12577
0
}
12578
12579
0
bool overlaps(std::string_view input1, const std::string& input2) noexcept {
12580
0
  ada_log("helpers::overlaps check if string_view '", input1, "' [",
12581
0
          input1.size(), " bytes] is part of string '", input2, "' [",
12582
0
          input2.size(), " bytes]");
12583
0
  return !input1.empty() && !input2.empty() && input1.data() >= input2.data() &&
12584
0
         input1.data() < input2.data() + input2.size();
12585
0
}
12586
12587
template <class url_type>
12588
0
ada_really_inline void strip_trailing_spaces_from_opaque_path(url_type& url) {
12589
0
  ada_log("helpers::strip_trailing_spaces_from_opaque_path");
12590
0
  if (!url.has_opaque_path) return;
12591
0
  if (url.has_hash()) return;
12592
0
  if (url.has_search()) return;
12593
12594
0
  auto path = std::string(url.get_pathname());
12595
0
  while (!path.empty() && path.back() == ' ') {
12596
0
    path.resize(path.size() - 1);
12597
0
  }
12598
0
  url.update_base_pathname(path);
12599
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&)
12600
12601
// @ / \\ ?
12602
static constexpr std::array<uint8_t, 256> authority_delimiter_special =
12603
    []() consteval {
12604
      std::array<uint8_t, 256> result{};
12605
      for (uint8_t i : {'@', '/', '\\', '?'}) {
12606
        result[i] = 1;
12607
      }
12608
      return result;
12609
    }();
12610
// credit: @the-moisrex recommended a table-based approach
12611
ada_really_inline size_t
12612
92.4k
find_authority_delimiter_special(std::string_view view) noexcept {
12613
  // performance note: we might be able to gain further performance
12614
  // with SIMD intrinsics.
12615
283k
  for (auto pos = view.begin(); pos != view.end(); ++pos) {
12616
280k
    if (authority_delimiter_special[(uint8_t)*pos]) {
12617
89.3k
      return pos - view.begin();
12618
89.3k
    }
12619
280k
  }
12620
3.04k
  return size_t(view.size());
12621
92.4k
}
12622
12623
// @ / ?
12624
static constexpr std::array<uint8_t, 256> authority_delimiter = []() consteval {
12625
  std::array<uint8_t, 256> result{};
12626
  for (uint8_t i : {'@', '/', '?'}) {
12627
    result[i] = 1;
12628
  }
12629
  return result;
12630
}();
12631
// credit: @the-moisrex recommended a table-based approach
12632
ada_really_inline size_t
12633
10.3k
find_authority_delimiter(std::string_view view) noexcept {
12634
  // performance note: we might be able to gain further performance
12635
  // with SIMD instrinsics.
12636
91.2k
  for (auto pos = view.begin(); pos != view.end(); ++pos) {
12637
91.1k
    if (authority_delimiter[(uint8_t)*pos]) {
12638
10.2k
      return pos - view.begin();
12639
10.2k
    }
12640
91.1k
  }
12641
87
  return size_t(view.size());
12642
10.3k
}
12643
12644
}  // namespace ada::helpers
12645
12646
namespace ada {
12647
0
ada_warn_unused std::string to_string(ada::state state) {
12648
0
  return ada::helpers::get_state(state);
12649
0
}
12650
#undef ada_make_uint8x16_t
12651
}  // namespace ada
12652
/* end file src/helpers.cpp */
12653
/* begin file src/url.cpp */
12654
12655
#include <algorithm>
12656
#include <iterator>
12657
#include <numeric>
12658
#include <ranges>
12659
#include <string>
12660
#include <string_view>
12661
12662
namespace ada {
12663
12664
0
bool url::parse_opaque_host(std::string_view input) {
12665
0
  ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
12666
0
  if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) {
12667
0
    return is_valid = false;
12668
0
  }
12669
12670
  // Return the result of running UTF-8 percent-encode on input using the C0
12671
  // control percent-encode set.
12672
0
  host = ada::unicode::percent_encode(
12673
0
      input, ada::character_sets::C0_CONTROL_PERCENT_ENCODE);
12674
0
  return true;
12675
0
}
12676
12677
0
bool url::parse_ipv4(std::string_view input) {
12678
0
  ada_log("parse_ipv4 ", input, " [", input.size(), " bytes]");
12679
0
  if (input.back() == '.') {
12680
0
    input.remove_suffix(1);
12681
0
  }
12682
0
  size_t digit_count{0};
12683
0
  int pure_decimal_count = 0;  // entries that are decimal
12684
0
  std::string_view original_input =
12685
0
      input;  // we might use this if pure_decimal_count == 4.
12686
0
  uint64_t ipv4{0};
12687
  // we could unroll for better performance?
12688
0
  for (; (digit_count < 4) && !(input.empty()); digit_count++) {
12689
0
    uint32_t
12690
0
        segment_result{};  // If any number exceeds 32 bits, we have an error.
12691
0
    bool is_hex = checkers::has_hex_prefix(input);
12692
0
    if (is_hex && ((input.length() == 2) ||
12693
0
                   ((input.length() > 2) && (input[2] == '.')))) {
12694
      // special case
12695
0
      segment_result = 0;
12696
0
      input.remove_prefix(2);
12697
0
    } else {
12698
0
      std::from_chars_result r{};
12699
0
      if (is_hex) {
12700
0
        r = std::from_chars(input.data() + 2, input.data() + input.size(),
12701
0
                            segment_result, 16);
12702
0
      } else if ((input.length() >= 2) && input[0] == '0' &&
12703
0
                 checkers::is_digit(input[1])) {
12704
0
        r = std::from_chars(input.data() + 1, input.data() + input.size(),
12705
0
                            segment_result, 8);
12706
0
      } else {
12707
0
        pure_decimal_count++;
12708
0
        r = std::from_chars(input.data(), input.data() + input.size(),
12709
0
                            segment_result, 10);
12710
0
      }
12711
0
      if (r.ec != std::errc()) {
12712
0
        return is_valid = false;
12713
0
      }
12714
0
      input.remove_prefix(r.ptr - input.data());
12715
0
    }
12716
0
    if (input.empty()) {
12717
      // We have the last value.
12718
      // At this stage, ipv4 contains digit_count*8 bits.
12719
      // So we have 32-digit_count*8 bits left.
12720
0
      if (segment_result >= (uint64_t(1) << (32 - digit_count * 8))) {
12721
0
        return is_valid = false;
12722
0
      }
12723
0
      ipv4 <<= (32 - digit_count * 8);
12724
0
      ipv4 |= segment_result;
12725
0
      goto final;
12726
0
    } else {
12727
      // There is more, so that the value must no be larger than 255
12728
      // and we must have a '.'.
12729
0
      if ((segment_result > 255) || (input[0] != '.')) {
12730
0
        return is_valid = false;
12731
0
      }
12732
0
      ipv4 <<= 8;
12733
0
      ipv4 |= segment_result;
12734
0
      input.remove_prefix(1);  // remove '.'
12735
0
    }
12736
0
  }
12737
0
  if ((digit_count != 4) || (!input.empty())) {
12738
0
    return is_valid = false;
12739
0
  }
12740
0
final:
12741
  // We could also check r.ptr to see where the parsing ended.
12742
0
  if (pure_decimal_count == 4) {
12743
0
    host = original_input;  // The original input was already all decimal and we
12744
                            // validated it.
12745
0
  } else {
12746
0
    host = ada::serializers::ipv4(ipv4);  // We have to reserialize the address.
12747
0
  }
12748
0
  host_type = IPV4;
12749
0
  return true;
12750
0
}
12751
12752
0
bool url::parse_ipv6(std::string_view input) {
12753
0
  ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
12754
12755
0
  if (input.empty()) {
12756
0
    return is_valid = false;
12757
0
  }
12758
  // Let address be a new IPv6 address whose IPv6 pieces are all 0.
12759
0
  std::array<uint16_t, 8> address{};
12760
12761
  // Let pieceIndex be 0.
12762
0
  int piece_index = 0;
12763
12764
  // Let compress be null.
12765
0
  std::optional<int> compress{};
12766
12767
  // Let pointer be a pointer for input.
12768
0
  std::string_view::iterator pointer = input.begin();
12769
12770
  // If c is U+003A (:), then:
12771
0
  if (input[0] == ':') {
12772
    // If remaining does not start with U+003A (:), validation error, return
12773
    // failure.
12774
0
    if (input.size() == 1 || input[1] != ':') {
12775
0
      ada_log("parse_ipv6 starts with : but the rest does not start with :");
12776
0
      return is_valid = false;
12777
0
    }
12778
12779
    // Increase pointer by 2.
12780
0
    pointer += 2;
12781
12782
    // Increase pieceIndex by 1 and then set compress to pieceIndex.
12783
0
    compress = ++piece_index;
12784
0
  }
12785
12786
  // While c is not the EOF code point:
12787
0
  while (pointer != input.end()) {
12788
    // If pieceIndex is 8, validation error, return failure.
12789
0
    if (piece_index == 8) {
12790
0
      ada_log("parse_ipv6 piece_index == 8");
12791
0
      return is_valid = false;
12792
0
    }
12793
12794
    // If c is U+003A (:), then:
12795
0
    if (*pointer == ':') {
12796
      // If compress is non-null, validation error, return failure.
12797
0
      if (compress.has_value()) {
12798
0
        ada_log("parse_ipv6 compress is non-null");
12799
0
        return is_valid = false;
12800
0
      }
12801
12802
      // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
12803
      // then continue.
12804
0
      pointer++;
12805
0
      compress = ++piece_index;
12806
0
      continue;
12807
0
    }
12808
12809
    // Let value and length be 0.
12810
0
    uint16_t value = 0, length = 0;
12811
12812
    // While length is less than 4 and c is an ASCII hex digit,
12813
    // set value to value times 0x10 + c interpreted as hexadecimal number, and
12814
    // increase pointer and length by 1.
12815
0
    while (length < 4 && pointer != input.end() &&
12816
0
           unicode::is_ascii_hex_digit(*pointer)) {
12817
      // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
12818
0
      value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
12819
0
      pointer++;
12820
0
      length++;
12821
0
    }
12822
12823
    // If c is U+002E (.), then:
12824
0
    if (pointer != input.end() && *pointer == '.') {
12825
      // If length is 0, validation error, return failure.
12826
0
      if (length == 0) {
12827
0
        ada_log("parse_ipv6 length is 0");
12828
0
        return is_valid = false;
12829
0
      }
12830
12831
      // Decrease pointer by length.
12832
0
      pointer -= length;
12833
12834
      // If pieceIndex is greater than 6, validation error, return failure.
12835
0
      if (piece_index > 6) {
12836
0
        ada_log("parse_ipv6 piece_index > 6");
12837
0
        return is_valid = false;
12838
0
      }
12839
12840
      // Let numbersSeen be 0.
12841
0
      int numbers_seen = 0;
12842
12843
      // While c is not the EOF code point:
12844
0
      while (pointer != input.end()) {
12845
        // Let ipv4Piece be null.
12846
0
        std::optional<uint16_t> ipv4_piece{};
12847
12848
        // If numbersSeen is greater than 0, then:
12849
0
        if (numbers_seen > 0) {
12850
          // If c is a U+002E (.) and numbersSeen is less than 4, then increase
12851
          // pointer by 1.
12852
0
          if (*pointer == '.' && numbers_seen < 4) {
12853
0
            pointer++;
12854
0
          }
12855
          // Otherwise, validation error, return failure.
12856
0
          else {
12857
0
            ada_log("parse_ipv6 Otherwise, validation error, return failure");
12858
0
            return is_valid = false;
12859
0
          }
12860
0
        }
12861
12862
        // If c is not an ASCII digit, validation error, return failure.
12863
0
        if (pointer == input.end() || !checkers::is_digit(*pointer)) {
12864
0
          ada_log(
12865
0
              "parse_ipv6 If c is not an ASCII digit, validation error, return "
12866
0
              "failure");
12867
0
          return is_valid = false;
12868
0
        }
12869
12870
        // While c is an ASCII digit:
12871
0
        while (pointer != input.end() && checkers::is_digit(*pointer)) {
12872
          // Let number be c interpreted as decimal number.
12873
0
          int number = *pointer - '0';
12874
12875
          // If ipv4Piece is null, then set ipv4Piece to number.
12876
0
          if (!ipv4_piece.has_value()) {
12877
0
            ipv4_piece = number;
12878
0
          }
12879
          // Otherwise, if ipv4Piece is 0, validation error, return failure.
12880
0
          else if (ipv4_piece == 0) {
12881
0
            ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
12882
0
            return is_valid = false;
12883
0
          }
12884
          // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
12885
0
          else {
12886
0
            ipv4_piece = *ipv4_piece * 10 + number;
12887
0
          }
12888
12889
          // If ipv4Piece is greater than 255, validation error, return failure.
12890
0
          if (ipv4_piece > 255) {
12891
0
            ada_log("parse_ipv6 ipv4_piece > 255");
12892
0
            return is_valid = false;
12893
0
          }
12894
12895
          // Increase pointer by 1.
12896
0
          pointer++;
12897
0
        }
12898
12899
        // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
12900
        // ipv4Piece.
12901
        // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
12902
0
        address[piece_index] =
12903
0
            uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
12904
12905
        // Increase numbersSeen by 1.
12906
0
        numbers_seen++;
12907
12908
        // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
12909
0
        if (numbers_seen == 2 || numbers_seen == 4) {
12910
0
          piece_index++;
12911
0
        }
12912
0
      }
12913
12914
      // If numbersSeen is not 4, validation error, return failure.
12915
0
      if (numbers_seen != 4) {
12916
0
        return is_valid = false;
12917
0
      }
12918
12919
      // Break.
12920
0
      break;
12921
0
    }
12922
    // Otherwise, if c is U+003A (:):
12923
0
    else if ((pointer != input.end()) && (*pointer == ':')) {
12924
      // Increase pointer by 1.
12925
0
      pointer++;
12926
12927
      // If c is the EOF code point, validation error, return failure.
12928
0
      if (pointer == input.end()) {
12929
0
        ada_log(
12930
0
            "parse_ipv6 If c is the EOF code point, validation error, return "
12931
0
            "failure");
12932
0
        return is_valid = false;
12933
0
      }
12934
0
    }
12935
    // Otherwise, if c is not the EOF code point, validation error, return
12936
    // failure.
12937
0
    else if (pointer != input.end()) {
12938
0
      ada_log(
12939
0
          "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
12940
0
          "error, return failure");
12941
0
      return is_valid = false;
12942
0
    }
12943
12944
    // Set address[pieceIndex] to value.
12945
0
    address[piece_index] = value;
12946
12947
    // Increase pieceIndex by 1.
12948
0
    piece_index++;
12949
0
  }
12950
12951
  // If compress is non-null, then:
12952
0
  if (compress.has_value()) {
12953
    // Let swaps be pieceIndex - compress.
12954
0
    int swaps = piece_index - *compress;
12955
12956
    // Set pieceIndex to 7.
12957
0
    piece_index = 7;
12958
12959
    // While pieceIndex is not 0 and swaps is greater than 0,
12960
    // swap address[pieceIndex] with address[compress + swaps - 1], and then
12961
    // decrease both pieceIndex and swaps by 1.
12962
0
    while (piece_index != 0 && swaps > 0) {
12963
0
      std::swap(address[piece_index], address[*compress + swaps - 1]);
12964
0
      piece_index--;
12965
0
      swaps--;
12966
0
    }
12967
0
  }
12968
  // Otherwise, if compress is null and pieceIndex is not 8, validation error,
12969
  // return failure.
12970
0
  else if (piece_index != 8) {
12971
0
    ada_log(
12972
0
        "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
12973
0
        "error, return failure");
12974
0
    return is_valid = false;
12975
0
  }
12976
0
  host = ada::serializers::ipv6(address);
12977
0
  ada_log("parse_ipv6 ", *host);
12978
0
  host_type = IPV6;
12979
0
  return true;
12980
0
}
12981
12982
template <bool has_state_override>
12983
0
ada_really_inline bool url::parse_scheme(const std::string_view input) {
12984
0
  auto parsed_type = ada::scheme::get_scheme_type(input);
12985
0
  bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
12986
  /**
12987
   * In the common case, we will immediately recognize a special scheme (e.g.,
12988
   *http, https), in which case, we can go really fast.
12989
   **/
12990
0
  if (is_input_special) {  // fast path!!!
12991
0
    if constexpr (has_state_override) {
12992
      // If url's scheme is not a special scheme and buffer is a special scheme,
12993
      // then return.
12994
0
      if (is_special() != is_input_special) {
12995
0
        return false;
12996
0
      }
12997
12998
      // If url includes credentials or has a non-null port, and buffer is
12999
      // "file", then return.
13000
0
      if ((has_credentials() || port.has_value()) &&
13001
0
          parsed_type == ada::scheme::type::FILE) {
13002
0
        return false;
13003
0
      }
13004
13005
      // If url's scheme is "file" and its host is an empty host, then return.
13006
      // An empty host is the empty string.
13007
0
      if (type == ada::scheme::type::FILE && host.has_value() &&
13008
0
          host->empty()) {
13009
0
        return false;
13010
0
      }
13011
0
    }
13012
13013
0
    type = parsed_type;
13014
13015
0
    if constexpr (has_state_override) {
13016
      // This is uncommon.
13017
0
      uint16_t urls_scheme_port = get_special_port();
13018
13019
0
      if (urls_scheme_port) {
13020
        // If url's port is url's scheme's default port, then set url's port to
13021
        // null.
13022
0
        if (port.has_value() && *port == urls_scheme_port) {
13023
0
          port = std::nullopt;
13024
0
        }
13025
0
      }
13026
0
    }
13027
0
  } else {  // slow path
13028
0
    std::string _buffer(input);
13029
    // Next function is only valid if the input is ASCII and returns false
13030
    // otherwise, but it seems that we always have ascii content so we do not
13031
    // need to check the return value.
13032
    // bool is_ascii =
13033
0
    unicode::to_lower_ascii(_buffer.data(), _buffer.size());
13034
13035
0
    if constexpr (has_state_override) {
13036
      // The state-override validation errors below ("return" in the WHATWG URL
13037
      // parser) leave the URL unchanged. The setter contract is
13038
      // "true on success, false if the scheme is invalid" -- the fast path
13039
      // above already returns false here, so the slow path must agree.
13040
13041
      // If url's scheme is a special scheme and buffer is not a special scheme,
13042
      // then return. If url's scheme is not a special scheme and buffer is a
13043
      // special scheme, then return.
13044
0
      if (is_special() != ada::scheme::is_special(_buffer)) {
13045
0
        return false;
13046
0
      }
13047
13048
      // If url includes credentials or has a non-null port, and buffer is
13049
      // "file", then return.
13050
0
      if ((has_credentials() || port.has_value()) && _buffer == "file") {
13051
0
        return false;
13052
0
      }
13053
13054
      // If url's scheme is "file" and its host is an empty host, then return.
13055
      // An empty host is the empty string.
13056
0
      if (type == ada::scheme::type::FILE && host.has_value() &&
13057
0
          host->empty()) {
13058
0
        return false;
13059
0
      }
13060
0
    }
13061
13062
0
    set_scheme(std::move(_buffer));
13063
13064
0
    if constexpr (has_state_override) {
13065
      // This is uncommon.
13066
0
      uint16_t urls_scheme_port = get_special_port();
13067
13068
0
      if (urls_scheme_port) {
13069
        // If url's port is url's scheme's default port, then set url's port to
13070
        // null.
13071
0
        if (port.has_value() && *port == urls_scheme_port) {
13072
0
          port = std::nullopt;
13073
0
        }
13074
0
      }
13075
0
    }
13076
0
  }
13077
13078
0
  return true;
13079
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> >)
13080
13081
0
ada_really_inline bool url::parse_host(std::string_view input) {
13082
0
  ada_log("parse_host ", input, " [", input.size(), " bytes]");
13083
0
  if (input.empty()) {
13084
0
    return is_valid = false;
13085
0
  }  // technically unnecessary.
13086
  // If input starts with U+005B ([), then:
13087
0
  if (input[0] == '[') {
13088
    // If input does not end with U+005D (]), validation error, return failure.
13089
0
    if (input.back() != ']') {
13090
0
      return is_valid = false;
13091
0
    }
13092
0
    ada_log("parse_host ipv6");
13093
13094
    // Return the result of IPv6 parsing input with its leading U+005B ([) and
13095
    // trailing U+005D (]) removed.
13096
0
    input.remove_prefix(1);
13097
0
    input.remove_suffix(1);
13098
0
    return parse_ipv6(input);
13099
0
  }
13100
13101
  // If isNotSpecial is true, then return the result of opaque-host parsing
13102
  // input.
13103
0
  if (!is_special()) {
13104
0
    return parse_opaque_host(input);
13105
0
  }
13106
13107
  // Fast path: try to parse as pure decimal IPv4(a.b.c.d) first.
13108
0
  const uint64_t fast_result = checkers::try_parse_ipv4_fast(input);
13109
0
  if (fast_result < checkers::ipv4_fast_fail) {
13110
    // Fast path succeeded - input is pure decimal IPv4
13111
0
    if (!input.empty() && input.back() == '.') {
13112
0
      host = input.substr(0, input.size() - 1);
13113
0
    } else {
13114
0
      host = input;
13115
0
    }
13116
0
    host_type = IPV4;
13117
0
    is_valid = true;
13118
0
    ada_log("parse_host fast path decimal ipv4");
13119
0
    return true;
13120
0
  }
13121
  // Let domain be the result of running UTF-8 decode without BOM on the
13122
  // percent-decoding of input. Let asciiDomain be the result of running domain
13123
  // to ASCII with domain and false. The most common case is an ASCII input, in
13124
  // which case we do not need to call the expensive 'to_ascii' if a few
13125
  // conditions are met: no '%' and no 'xn-' subsequence.
13126
0
  std::string buffer = std::string(input);
13127
  // This next function checks that the result is ascii, but we are going to
13128
  // to check anyhow with is_forbidden.
13129
  // bool is_ascii =
13130
0
  unicode::to_lower_ascii(buffer.data(), buffer.size());
13131
0
  bool is_forbidden = unicode::contains_forbidden_domain_code_point(
13132
0
      buffer.data(), buffer.size());
13133
0
  if (is_forbidden == 0 && buffer.find("xn-") == std::string_view::npos) {
13134
    // fast path
13135
0
    host = std::move(buffer);
13136
13137
    // Check for other IPv4 formats (hex, octal, etc.)
13138
0
    if (checkers::is_ipv4(host.value())) {
13139
0
      ada_log("parse_host fast path ipv4");
13140
0
      return parse_ipv4(host.value());
13141
0
    }
13142
0
    ada_log("parse_host fast path ", *host);
13143
0
    is_valid = true;
13144
0
    return true;
13145
0
  }
13146
0
  ada_log("parse_host calling to_ascii");
13147
0
  is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
13148
0
  if (!is_valid || !host.has_value()) {
13149
0
    ada_log("parse_host to_ascii returns false");
13150
0
    return is_valid = false;
13151
0
  }
13152
0
  ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
13153
0
          " bytes]");
13154
13155
0
  if (std::any_of(host->begin(), host->end(),
13156
0
                  ada::unicode::is_forbidden_domain_code_point)) {
13157
0
    host = std::nullopt;
13158
0
    return is_valid = false;
13159
0
  }
13160
13161
  // If asciiDomain ends in a number, then return the result of IPv4 parsing
13162
  // asciiDomain.
13163
0
  if (checkers::is_ipv4(*host)) {
13164
0
    ada_log("parse_host got ipv4 ", *host);
13165
0
    return parse_ipv4(*host);
13166
0
  }
13167
13168
0
  return true;
13169
0
}
13170
13171
0
ada_really_inline void url::parse_path(std::string_view input) {
13172
0
  ada_log("parse_path ", input);
13173
0
  std::string tmp_buffer;
13174
0
  std::string_view internal_input;
13175
0
  if (unicode::has_tabs_or_newline(input)) {
13176
0
    tmp_buffer = input;
13177
    // Optimization opportunity: Instead of copying and then pruning, we could
13178
    // just directly build the string from user_input.
13179
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
13180
0
    internal_input = tmp_buffer;
13181
0
  } else {
13182
0
    internal_input = input;
13183
0
  }
13184
13185
  // If url is special, then:
13186
0
  if (is_special()) {
13187
0
    if (internal_input.empty()) {
13188
0
      path = "/";
13189
0
    } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
13190
0
      helpers::parse_prepared_path(internal_input.substr(1), type, path);
13191
0
    } else {
13192
0
      helpers::parse_prepared_path(internal_input, type, path);
13193
0
    }
13194
0
  } else if (!internal_input.empty()) {
13195
0
    if (internal_input[0] == '/') {
13196
0
      helpers::parse_prepared_path(internal_input.substr(1), type, path);
13197
0
    } else {
13198
0
      helpers::parse_prepared_path(internal_input, type, path);
13199
0
    }
13200
0
  } else {
13201
0
    if (!host.has_value()) {
13202
0
      path = "/";
13203
0
    }
13204
0
  }
13205
0
}
13206
13207
0
[[nodiscard]] std::string url::to_string() const {
13208
0
  if (!is_valid) {
13209
0
    return "null";
13210
0
  }
13211
0
  std::string answer;
13212
0
  auto back = std::back_insert_iterator(answer);
13213
0
  answer.append("{\n");
13214
0
  answer.append("\t\"protocol\":\"");
13215
0
  helpers::encode_json(get_protocol(), back);
13216
0
  answer.append("\",\n");
13217
0
  if (has_credentials()) {
13218
0
    answer.append("\t\"username\":\"");
13219
0
    helpers::encode_json(username, back);
13220
0
    answer.append("\",\n");
13221
0
    answer.append("\t\"password\":\"");
13222
0
    helpers::encode_json(password, back);
13223
0
    answer.append("\",\n");
13224
0
  }
13225
0
  if (host.has_value()) {
13226
0
    answer.append("\t\"host\":\"");
13227
0
    helpers::encode_json(host.value(), back);
13228
0
    answer.append("\",\n");
13229
0
  }
13230
0
  if (port.has_value()) {
13231
0
    answer.append("\t\"port\":\"");
13232
0
    answer.append(std::to_string(port.value()));
13233
0
    answer.append("\",\n");
13234
0
  }
13235
0
  answer.append("\t\"path\":\"");
13236
0
  helpers::encode_json(path, back);
13237
0
  answer.append("\",\n");
13238
0
  answer.append("\t\"opaque path\":");
13239
0
  answer.append((has_opaque_path ? "true" : "false"));
13240
0
  if (has_search()) {
13241
0
    answer.append(",\n");
13242
0
    answer.append("\t\"query\":\"");
13243
    // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
13244
0
    helpers::encode_json(query.value(), back);
13245
0
    answer.append("\"");
13246
0
  }
13247
0
  if (hash.has_value()) {
13248
0
    answer.append(",\n");
13249
0
    answer.append("\t\"hash\":\"");
13250
0
    helpers::encode_json(hash.value(), back);
13251
0
    answer.append("\"");
13252
0
  }
13253
0
  answer.append("\n}");
13254
0
  return answer;
13255
0
}
13256
13257
0
[[nodiscard]] bool url::has_valid_domain() const noexcept {
13258
0
  if (!host.has_value()) {
13259
0
    return false;
13260
0
  }
13261
0
  return checkers::verify_dns_length(*host);
13262
0
}
13263
13264
0
[[nodiscard]] std::string url::get_origin() const {
13265
0
  if (is_special()) {
13266
    // Return a new opaque origin.
13267
0
    if (type == scheme::FILE) {
13268
0
      return "null";
13269
0
    }
13270
0
    return ada::helpers::concat(get_protocol(), "//", get_host());
13271
0
  }
13272
13273
0
  if (non_special_scheme == "blob") {
13274
0
    if (!path.empty()) {
13275
0
      auto result = ada::parse<ada::url>(path);
13276
0
      if (result &&
13277
0
          (result->type == scheme::HTTP || result->type == scheme::HTTPS)) {
13278
        // If pathURL's scheme is not "http" and not "https", then return a
13279
        // new opaque origin.
13280
0
        return ada::helpers::concat(result->get_protocol(), "//",
13281
0
                                    result->get_host());
13282
0
      }
13283
0
    }
13284
0
  }
13285
13286
  // Return a new opaque origin.
13287
0
  return "null";
13288
0
}
13289
13290
0
[[nodiscard]] std::string url::get_protocol() const {
13291
0
  if (is_special()) {
13292
0
    return helpers::concat(ada::scheme::details::is_special_list[type], ":");
13293
0
  }
13294
  // We only move the 'scheme' if it is non-special.
13295
0
  return helpers::concat(non_special_scheme, ":");
13296
0
}
13297
13298
0
[[nodiscard]] std::string url::get_host() const {
13299
  // If url's host is null, then return the empty string.
13300
  // If url's port is null, return url's host, serialized.
13301
  // Return url's host, serialized, followed by U+003A (:) and url's port,
13302
  // serialized.
13303
0
  if (!host.has_value()) {
13304
0
    return "";
13305
0
  }
13306
0
  if (port.has_value()) {
13307
0
    return host.value() + ":" + get_port();
13308
0
  }
13309
0
  return host.value();
13310
0
}
13311
13312
0
[[nodiscard]] std::string url::get_hostname() const {
13313
0
  return host.value_or("");
13314
0
}
13315
13316
0
[[nodiscard]] std::string url::get_search() const {
13317
  // If this's URL's query is either null or the empty string, then return the
13318
  // empty string. Return U+003F (?), followed by this's URL's query.
13319
0
  return (!query.has_value() || (query->empty())) ? "" : "?" + query.value();
13320
0
}
13321
13322
0
[[nodiscard]] const std::string& url::get_username() const noexcept {
13323
0
  return username;
13324
0
}
13325
13326
0
[[nodiscard]] const std::string& url::get_password() const noexcept {
13327
0
  return password;
13328
0
}
13329
13330
0
[[nodiscard]] std::string url::get_port() const {
13331
0
  return port.has_value() ? std::to_string(port.value()) : "";
13332
0
}
13333
13334
0
[[nodiscard]] std::string url::get_hash() const {
13335
  // If this's URL's fragment is either null or the empty string, then return
13336
  // the empty string. Return U+0023 (#), followed by this's URL's fragment.
13337
0
  return (!hash.has_value() || (hash->empty())) ? "" : "#" + hash.value();
13338
0
}
13339
13340
template <bool override_hostname>
13341
0
bool url::set_host_or_hostname(const std::string_view input) {
13342
0
  if (has_opaque_path) {
13343
0
    return false;
13344
0
  }
13345
13346
0
  url saved_url(*this);
13347
13348
0
  std::optional<std::string> previous_host = host;
13349
0
  std::optional<uint16_t> previous_port = port;
13350
13351
0
  size_t host_end_pos = input.find('#');
13352
0
  std::string _host(input.data(), host_end_pos != std::string_view::npos
13353
0
                                      ? host_end_pos
13354
0
                                      : input.size());
13355
0
  helpers::remove_ascii_tab_or_newline(_host);
13356
0
  std::string_view new_host(_host);
13357
13358
0
  auto check_url_size = [&]() -> bool {
13359
0
    if (get_href_size() > ada::get_max_input_length()) {
13360
0
      *this = std::move(saved_url);
13361
0
      return false;
13362
0
    }
13363
0
    return true;
13364
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
13365
13366
  // If url's scheme is "file", then set state to file host state, instead of
13367
  // host state.
13368
0
  if (type != ada::scheme::type::FILE) {
13369
0
    std::string_view host_view(_host.data(), _host.length());
13370
0
    auto [location, found_colon] =
13371
0
        helpers::get_host_delimiter_location(is_special(), host_view);
13372
13373
    // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
13374
    // Note: the 'found_colon' value is true if and only if a colon was
13375
    // encountered while not inside brackets.
13376
0
    if (found_colon) {
13377
      // If buffer is the empty string, host-missing validation error, return
13378
      // failure.
13379
0
      std::string_view buffer = host_view.substr(0, location);
13380
0
      if (buffer.empty()) {
13381
0
        return false;
13382
0
      }
13383
13384
      // If state override is given and state override is hostname state, then
13385
      // return failure.
13386
0
      if constexpr (override_hostname) {
13387
0
        return false;
13388
0
      }
13389
13390
      // Let host be the result of host parsing buffer with url is not special.
13391
0
      bool succeeded = parse_host(buffer);
13392
0
      if (!succeeded) {
13393
0
        host = std::move(previous_host);
13394
0
        update_base_port(previous_port);
13395
0
        return false;
13396
0
      }
13397
13398
      // Set url's host to host, buffer to the empty string, and state to port
13399
      // state.
13400
0
      std::string_view port_buffer = new_host.substr(location + 1);
13401
0
      if (!port_buffer.empty()) {
13402
0
        set_port(port_buffer);
13403
0
      }
13404
0
      return check_url_size();
13405
0
    }
13406
    // Otherwise, if one of the following is true:
13407
    // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
13408
    // - url is special and c is U+005C (\)
13409
0
    else {
13410
      // If url is special and host_view is the empty string, host-missing
13411
      // validation error, return failure.
13412
0
      if (host_view.empty() && is_special()) {
13413
0
        return false;
13414
0
      }
13415
13416
      // Otherwise, if state override is given, host_view is the empty string,
13417
      // and either url includes credentials or url's port is non-null, then
13418
      // return failure.
13419
0
      if (host_view.empty() && (has_credentials() || port.has_value())) {
13420
0
        return false;
13421
0
      }
13422
13423
      // Let host be the result of host parsing host_view with url is not
13424
      // special.
13425
0
      if (host_view.empty() && !is_special()) {
13426
0
        host = "";
13427
0
        return check_url_size();
13428
0
      }
13429
13430
0
      bool succeeded = parse_host(host_view);
13431
0
      if (!succeeded) {
13432
0
        host = std::move(previous_host);
13433
0
        update_base_port(previous_port);
13434
0
        return false;
13435
0
      }
13436
0
      return check_url_size();
13437
0
    }
13438
0
  }
13439
13440
0
  size_t location = new_host.find_first_of("/\\?");
13441
0
  if (location != std::string_view::npos) {
13442
0
    new_host.remove_suffix(new_host.length() - location);
13443
0
  }
13444
13445
0
  if (new_host.empty()) {
13446
    // Set url's host to the empty string.
13447
0
    host = "";
13448
0
  } else {
13449
    // Let host be the result of host parsing buffer with url is not special.
13450
0
    if (!parse_host(new_host)) {
13451
0
      host = std::move(previous_host);
13452
0
      update_base_port(previous_port);
13453
0
      return false;
13454
0
    }
13455
13456
    // If host is "localhost", then set host to the empty string.
13457
0
    if (host == "localhost") {
13458
0
      host = "";
13459
0
    }
13460
0
  }
13461
0
  return check_url_size();
13462
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> >)
13463
13464
0
bool url::set_host(const std::string_view input) {
13465
0
  return set_host_or_hostname<false>(input);
13466
0
}
13467
13468
0
bool url::set_hostname(const std::string_view input) {
13469
0
  return set_host_or_hostname<true>(input);
13470
0
}
13471
13472
0
bool url::set_username(const std::string_view input) {
13473
0
  if (cannot_have_credentials_or_port()) {
13474
0
    return false;
13475
0
  }
13476
0
  auto previous_username = std::move(username);
13477
0
  username = ada::unicode::percent_encode(
13478
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
13479
0
  if (get_href_size() > ada::get_max_input_length()) {
13480
0
    username = std::move(previous_username);
13481
0
    return false;
13482
0
  }
13483
0
  return true;
13484
0
}
13485
13486
0
bool url::set_password(const std::string_view input) {
13487
0
  if (cannot_have_credentials_or_port()) {
13488
0
    return false;
13489
0
  }
13490
0
  auto previous_password = std::move(password);
13491
0
  password = ada::unicode::percent_encode(
13492
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
13493
0
  if (get_href_size() > ada::get_max_input_length()) {
13494
0
    password = std::move(previous_password);
13495
0
    return false;
13496
0
  }
13497
0
  return true;
13498
0
}
13499
13500
0
bool url::set_port(const std::string_view input) {
13501
0
  if (cannot_have_credentials_or_port()) {
13502
0
    return false;
13503
0
  }
13504
13505
0
  if (input.empty()) {
13506
0
    port = std::nullopt;
13507
0
    return true;
13508
0
  }
13509
13510
0
  std::string trimmed(input);
13511
0
  helpers::remove_ascii_tab_or_newline(trimmed);
13512
13513
0
  if (trimmed.empty()) {
13514
0
    return true;
13515
0
  }
13516
13517
  // Input should not start with a non-digit character.
13518
0
  if (!ada::unicode::is_ascii_digit(trimmed.front())) {
13519
0
    return false;
13520
0
  }
13521
13522
  // Find the first non-digit character to determine the length of digits
13523
0
  auto first_non_digit =
13524
0
      std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit);
13525
0
  std::string_view digits_to_parse =
13526
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
13527
13528
  // Revert changes if parse_port fails.
13529
0
  std::optional<uint16_t> previous_port = port;
13530
0
  parse_port(digits_to_parse);
13531
0
  if (is_valid) {
13532
0
    if (get_href_size() > ada::get_max_input_length()) {
13533
0
      port = std::move(previous_port);
13534
0
      return false;
13535
0
    }
13536
0
    return true;
13537
0
  }
13538
0
  port = std::move(previous_port);
13539
0
  is_valid = true;
13540
0
  return false;
13541
0
}
13542
13543
0
void url::set_hash(const std::string_view input) {
13544
0
  if (input.empty()) {
13545
0
    hash = std::nullopt;
13546
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
13547
0
    return;
13548
0
  }
13549
13550
0
  std::string new_value;
13551
0
  new_value = input[0] == '#' ? input.substr(1) : input;
13552
0
  helpers::remove_ascii_tab_or_newline(new_value);
13553
0
  auto previous_hash = std::move(hash);
13554
0
  hash = unicode::percent_encode(new_value,
13555
0
                                 ada::character_sets::FRAGMENT_PERCENT_ENCODE);
13556
0
  if (get_href_size() > ada::get_max_input_length()) {
13557
0
    hash = std::move(previous_hash);
13558
0
  }
13559
0
}
13560
13561
0
void url::set_search(const std::string_view input) {
13562
0
  if (input.empty()) {
13563
0
    query = std::nullopt;
13564
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
13565
0
    return;
13566
0
  }
13567
13568
0
  std::string new_value;
13569
0
  new_value = input[0] == '?' ? input.substr(1) : input;
13570
0
  helpers::remove_ascii_tab_or_newline(new_value);
13571
13572
0
  auto query_percent_encode_set =
13573
0
      is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
13574
0
                   : ada::character_sets::QUERY_PERCENT_ENCODE;
13575
13576
0
  auto previous_query = std::move(query);
13577
0
  query = ada::unicode::percent_encode(new_value, query_percent_encode_set);
13578
0
  if (get_href_size() > ada::get_max_input_length()) {
13579
0
    query = std::move(previous_query);
13580
0
  }
13581
0
}
13582
13583
0
bool url::set_pathname(const std::string_view input) {
13584
0
  if (has_opaque_path) {
13585
0
    return false;
13586
0
  }
13587
0
  auto previous_path = std::move(path);
13588
0
  path.clear();
13589
0
  parse_path(input);
13590
0
  if (get_href_size() > ada::get_max_input_length()) {
13591
0
    path = std::move(previous_path);
13592
0
    return false;
13593
0
  }
13594
0
  return true;
13595
0
}
13596
13597
0
bool url::set_protocol(const std::string_view input) {
13598
0
  std::string view(input);
13599
0
  helpers::remove_ascii_tab_or_newline(view);
13600
0
  if (view.empty()) {
13601
0
    return true;
13602
0
  }
13603
13604
  // Schemes should start with alpha values.
13605
0
  if (!checkers::is_alpha(view[0])) {
13606
0
    return false;
13607
0
  }
13608
13609
0
  view.append(":");
13610
13611
0
  std::string::iterator pointer =
13612
0
      std::ranges::find_if_not(view, unicode::is_alnum_plus);
13613
13614
0
  if (pointer != view.end() && *pointer == ':') {
13615
0
    url saved_url(*this);
13616
0
    bool result = parse_scheme<true>(
13617
0
        std::string_view(view.data(), pointer - view.begin()));
13618
0
    if (result && get_href_size() > ada::get_max_input_length()) {
13619
0
      *this = std::move(saved_url);
13620
0
      return false;
13621
0
    }
13622
0
    return result;
13623
0
  }
13624
0
  return false;
13625
0
}
13626
13627
0
bool url::set_href(const std::string_view input) {
13628
0
  ada::result<ada::url> out = ada::parse<ada::url>(input);
13629
13630
0
  if (out) {
13631
    // The parser enforces get_max_input_length() on both the input and the
13632
    // normalized result. This is a defense-in-depth check.
13633
0
    if (out->get_href_size() > ada::get_max_input_length()) {
13634
0
      return false;
13635
0
    }
13636
0
    *this = *out;
13637
0
  }
13638
13639
0
  return out.has_value();
13640
0
}
13641
13642
}  // namespace ada
13643
/* end file src/url.cpp */
13644
/* begin file src/parser.cpp */
13645
13646
#include <limits>
13647
#include <ranges>
13648
13649
13650
namespace ada::parser {
13651
13652
template <class result_type, bool store_values>
13653
result_type parse_url_impl(std::string_view user_input,
13654
1.20M
                           const result_type* base_url) {
13655
  // We can specialize the implementation per type.
13656
  // Important: result_type_is_ada_url is evaluated at *compile time*. This
13657
  // means that doing if constexpr(result_type_is_ada_url) { something } else {
13658
  // something else } is free (at runtime). This means that ada::url_aggregator
13659
  // and ada::url **do not have to support the exact same API**.
13660
1.20M
  constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>;
13661
1.20M
  constexpr bool result_type_is_ada_url_aggregator =
13662
1.20M
      std::is_same_v<url_aggregator, result_type>;
13663
1.20M
  static_assert(result_type_is_ada_url ||
13664
1.20M
                result_type_is_ada_url_aggregator);  // We don't support
13665
                                                     // anything else for now.
13666
13667
1.20M
  ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
13668
1.20M
          " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
13669
1.20M
          ")");
13670
13671
1.20M
  state state = state::SCHEME_START;
13672
1.20M
  result_type url{};
13673
13674
1.20M
  const uint32_t max_input_length = ada::get_max_input_length();
13675
13676
  // We refuse to parse URL strings that exceed the maximum input length.
13677
  // By default, this is 4GB but can be configured via
13678
  // ada::set_max_input_length().
13679
1.20M
  if (user_input.size() > max_input_length) [[unlikely]] {
13680
0
    url.is_valid = false;
13681
0
  }
13682
  // Going forward, user_input.size() is in [0,
13683
  // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
13684
  // base, or the optional_url was invalid, we must return.
13685
1.20M
  if (base_url != nullptr) {
13686
541k
    url.is_valid &= base_url->is_valid;
13687
541k
  }
13688
1.20M
  if (!url.is_valid) {
13689
0
    return url;
13690
0
  }
13691
1.20M
  if constexpr (result_type_is_ada_url_aggregator && store_values) {
13692
    // Most of the time, we just need user_input.size().
13693
    // In some instances, we may need a bit more.
13694
    ///////////////////////////
13695
    // This is *very* important. This line should *not* be removed
13696
    // hastily. There are principled reasons why reserve is important
13697
    // for performance. If you have a benchmark with small inputs,
13698
    // it may not matter, but in other instances, it could.
13699
    ////
13700
    // This rounds up to the next power of two.
13701
    // We know that user_input.size() is in [0,
13702
    // std::numeric_limits<uint32_t>::max).
13703
1.20M
    uint32_t reserve_capacity =
13704
1.20M
        (0xFFFFFFFF >>
13705
1.20M
         helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
13706
1.20M
        1;
13707
1.20M
    url.reserve(reserve_capacity);
13708
1.20M
  }
13709
1.20M
  std::string tmp_buffer;
13710
1.20M
  std::string_view url_data;
13711
1.20M
  if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] {
13712
7.69k
    tmp_buffer = user_input;
13713
    // Optimization opportunity: Instead of copying and then pruning, we could
13714
    // just directly build the string from user_input.
13715
7.69k
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
13716
7.69k
    url_data = tmp_buffer;
13717
1.20M
  } else [[likely]] {
13718
1.20M
    url_data = user_input;
13719
1.20M
  }
13720
13721
  // Leading and trailing control characters are uncommon and easy to deal with
13722
  // (no performance concern).
13723
1.20M
  helpers::trim_c0_whitespace(url_data);
13724
13725
  // Optimization opportunity. Most websites do not have fragment.
13726
1.20M
  std::optional<std::string_view> fragment = helpers::prune_hash(url_data);
13727
  // We add it last so that an implementation like ada::url_aggregator
13728
  // can append it last to its internal buffer, thus improving performance.
13729
13730
  // Here url_data no longer has its fragment.
13731
  // We are going to access the data from url_data (it is immutable).
13732
  // At any given time, we are pointing at byte 'input_position' in url_data.
13733
  // The input_position variable should range from 0 to input_size.
13734
  // It is illegal to access url_data at input_size.
13735
1.20M
  size_t input_position = 0;
13736
1.20M
  const size_t input_size = url_data.size();
13737
  // Keep running the following state machine by switching on state.
13738
  // If after a run pointer points to the EOF code point, go to the next step.
13739
  // Otherwise, increase pointer by 1 and continue with the state machine.
13740
  // We never decrement input_position.
13741
7.57M
  while (input_position <= input_size) {
13742
7.20M
    ada_log("In parsing at ", input_position, " out of ", input_size,
13743
7.20M
            " in state ", ada::to_string(state));
13744
7.20M
    switch (state) {
13745
1.20M
      case state::SCHEME_START: {
13746
1.20M
        ada_log("SCHEME_START ", helpers::substring(url_data, input_position));
13747
        // If c is an ASCII alpha, append c, lowercased, to buffer, and set
13748
        // state to scheme state.
13749
1.20M
        if ((input_position != input_size) &&
13750
1.20M
            checkers::is_alpha(url_data[input_position])) {
13751
1.18M
          state = state::SCHEME;
13752
1.18M
          input_position++;
13753
1.18M
        } else {
13754
          // Otherwise, if state override is not given, set state to no scheme
13755
          // state and decrease pointer by 1.
13756
24.0k
          state = state::NO_SCHEME;
13757
24.0k
        }
13758
1.20M
        break;
13759
0
      }
13760
1.18M
      case state::SCHEME: {
13761
1.18M
        ada_log("SCHEME ", helpers::substring(url_data, input_position));
13762
        // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),
13763
        // append c, lowercased, to buffer.
13764
5.68M
        while ((input_position != input_size) &&
13765
5.68M
               (unicode::is_alnum_plus(url_data[input_position]))) {
13766
4.49M
          input_position++;
13767
4.49M
        }
13768
        // Otherwise, if c is U+003A (:), then:
13769
1.18M
        if ((input_position != input_size) &&
13770
1.18M
            (url_data[input_position] == ':')) {
13771
1.18M
          ada_log("SCHEME the scheme should be ",
13772
1.18M
                  url_data.substr(0, input_position));
13773
1.18M
          if constexpr (result_type_is_ada_url) {
13774
0
            if (!url.parse_scheme(url_data.substr(0, input_position))) {
13775
0
              return url;
13776
0
            }
13777
1.18M
          } else {
13778
            // we pass the colon along instead of painfully adding it back.
13779
1.18M
            if (!url.parse_scheme_with_colon(
13780
1.18M
                    url_data.substr(0, input_position + 1))) {
13781
0
              return url;
13782
0
            }
13783
1.18M
          }
13784
1.18M
          ada_log("SCHEME the scheme is ", url.get_protocol());
13785
13786
          // If url's scheme is "file", then:
13787
          // NOLINTNEXTLINE(bugprone-branch-clone)
13788
1.18M
          if (url.type == scheme::type::FILE) {
13789
            // Set state to file state.
13790
0
            state = state::FILE;
13791
0
          }
13792
          // Otherwise, if url is special, base is non-null, and base's scheme
13793
          // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url
13794
          // != nullptr is false.
13795
1.18M
          else if (url.is_special() && base_url != nullptr &&
13796
541k
                   base_url->type == url.type) {
13797
            // Set state to special relative or authority state.
13798
216k
            state = state::SPECIAL_RELATIVE_OR_AUTHORITY;
13799
216k
          }
13800
          // Otherwise, if url is special, set state to special authority
13801
          // slashes state.
13802
967k
          else if (url.is_special()) {
13803
728k
            state = state::SPECIAL_AUTHORITY_SLASHES;
13804
728k
          }
13805
          // Otherwise, if remaining starts with an U+002F (/), set state to
13806
          // path or authority state and increase pointer by 1.
13807
239k
          else if (input_position + 1 < input_size &&
13808
239k
                   url_data[input_position + 1] == '/') {
13809
238k
            state = state::PATH_OR_AUTHORITY;
13810
238k
            input_position++;
13811
238k
          }
13812
          // Otherwise, set url's path to the empty string and set state to
13813
          // opaque path state.
13814
838
          else {
13815
838
            state = state::OPAQUE_PATH;
13816
838
          }
13817
1.18M
        }
13818
        // Otherwise, if state override is not given, set buffer to the empty
13819
        // string, state to no scheme state, and start over (from the first code
13820
        // point in input).
13821
0
        else {
13822
0
          state = state::NO_SCHEME;
13823
0
          input_position = 0;
13824
0
          break;
13825
0
        }
13826
1.18M
        input_position++;
13827
1.18M
        break;
13828
1.18M
      }
13829
24.0k
      case state::NO_SCHEME: {
13830
24.0k
        ada_log("NO_SCHEME ", helpers::substring(url_data, input_position));
13831
        // If base is null, or base has an opaque path and c is not U+0023 (#),
13832
        // validation error, return failure.
13833
24.0k
        if (base_url == nullptr ||
13834
24.0k
            (base_url->has_opaque_path && !fragment.has_value())) {
13835
24.0k
          ada_log("NO_SCHEME validation error");
13836
24.0k
          url.is_valid = false;
13837
24.0k
          return url;
13838
24.0k
        }
13839
        // Otherwise, if base has an opaque path and c is U+0023 (#),
13840
        // set url's scheme to base's scheme, url's path to base's path, url's
13841
        // query to base's query, and set state to fragment state.
13842
0
        else if (base_url->has_opaque_path && fragment.has_value() &&
13843
0
                 input_position == input_size) {
13844
0
          ada_log("NO_SCHEME opaque base with fragment");
13845
0
          url.copy_scheme(*base_url);
13846
0
          url.has_opaque_path = base_url->has_opaque_path;
13847
13848
0
          if constexpr (result_type_is_ada_url) {
13849
0
            url.path = base_url->path;
13850
0
            url.query = base_url->query;
13851
0
          } else {
13852
0
            url.update_base_pathname(base_url->get_pathname());
13853
0
            if (base_url->has_search()) {
13854
              // get_search() returns "" for an empty query string (URL ends
13855
              // with '?'). update_base_search("") would incorrectly clear the
13856
              // query, so pass "?" to preserve the empty query distinction.
13857
0
              auto s = base_url->get_search();
13858
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
13859
0
            }
13860
0
          }
13861
0
          url.update_unencoded_base_hash(*fragment);
13862
0
          return url;
13863
0
        }
13864
        // Otherwise, if base's scheme is not "file", set state to relative
13865
        // state and decrease pointer by 1.
13866
        // NOLINTNEXTLINE(bugprone-branch-clone)
13867
0
        else if (base_url->type != scheme::type::FILE) {
13868
0
          ada_log("NO_SCHEME non-file relative path");
13869
0
          state = state::RELATIVE_SCHEME;
13870
0
        }
13871
        // Otherwise, set state to file state and decrease pointer by 1.
13872
0
        else {
13873
0
          ada_log("NO_SCHEME file base type");
13874
0
          state = state::FILE;
13875
0
        }
13876
0
        break;
13877
24.0k
      }
13878
1.16M
      case state::AUTHORITY: {
13879
1.16M
        ada_log("AUTHORITY ", helpers::substring(url_data, input_position));
13880
        // most URLs have no @. Having no @ tells us that we don't have to worry
13881
        // about AUTHORITY. Of course, we could have @ and still not have to
13882
        // worry about AUTHORITY.
13883
        // TODO: Instead of just collecting a bool, collect the location of the
13884
        // '@' and do something useful with it.
13885
        // TODO: We could do various processing early on, using a single pass
13886
        // over the string to collect information about it, e.g., telling us
13887
        // whether there is a @ and if so, where (or how many).
13888
13889
        // Check if url data contains an @.
13890
1.16M
        if (url_data.find('@', input_position) == std::string_view::npos) {
13891
1.12M
          state = state::HOST;
13892
1.12M
          break;
13893
1.12M
        }
13894
40.3k
        bool at_sign_seen{false};
13895
40.3k
        bool password_token_seen{false};
13896
        /**
13897
         * We expect something of the sort...
13898
         * https://user:pass@example.com:1234/foo/bar?baz#quux
13899
         * --------^
13900
         */
13901
102k
        do {
13902
102k
          std::string_view view = url_data.substr(input_position);
13903
          // The delimiters are @, /, ? \\.
13904
102k
          size_t location =
13905
102k
              url.is_special() ? helpers::find_authority_delimiter_special(view)
13906
102k
                               : helpers::find_authority_delimiter(view);
13907
102k
          std::string_view authority_view = view.substr(0, location);
13908
102k
          size_t end_of_authority = input_position + authority_view.size();
13909
          // If c is U+0040 (@), then:
13910
102k
          if ((end_of_authority != input_size) &&
13911
99.6k
              (url_data[end_of_authority] == '@')) {
13912
            // If atSignSeen is true, then prepend "%40" to buffer.
13913
62.4k
            if (at_sign_seen) {
13914
33.9k
              if (password_token_seen) {
13915
13.2k
                if constexpr (result_type_is_ada_url) {
13916
0
                  url.password += "%40";
13917
13.2k
                } else {
13918
13.2k
                  url.append_base_password("%40");
13919
13.2k
                }
13920
20.6k
              } else {
13921
20.6k
                if constexpr (result_type_is_ada_url) {
13922
0
                  url.username += "%40";
13923
20.6k
                } else {
13924
20.6k
                  url.append_base_username("%40");
13925
20.6k
                }
13926
20.6k
              }
13927
33.9k
            }
13928
13929
62.4k
            at_sign_seen = true;
13930
13931
62.4k
            if (!password_token_seen) {
13932
49.2k
              size_t password_token_location = authority_view.find(':');
13933
49.2k
              password_token_seen =
13934
49.2k
                  password_token_location != std::string_view::npos;
13935
13936
49.2k
              if constexpr (store_values) {
13937
49.2k
                if (!password_token_seen) {
13938
40.2k
                  if constexpr (result_type_is_ada_url) {
13939
0
                    url.username += unicode::percent_encode(
13940
0
                        authority_view,
13941
0
                        character_sets::USERINFO_PERCENT_ENCODE);
13942
40.2k
                  } else {
13943
40.2k
                    url.append_base_username(unicode::percent_encode(
13944
40.2k
                        authority_view,
13945
40.2k
                        character_sets::USERINFO_PERCENT_ENCODE));
13946
40.2k
                  }
13947
40.2k
                } else {
13948
9.03k
                  if constexpr (result_type_is_ada_url) {
13949
0
                    url.username += unicode::percent_encode(
13950
0
                        authority_view.substr(0, password_token_location),
13951
0
                        character_sets::USERINFO_PERCENT_ENCODE);
13952
0
                    url.password += unicode::percent_encode(
13953
0
                        authority_view.substr(password_token_location + 1),
13954
0
                        character_sets::USERINFO_PERCENT_ENCODE);
13955
9.03k
                  } else {
13956
9.03k
                    url.append_base_username(unicode::percent_encode(
13957
9.03k
                        authority_view.substr(0, password_token_location),
13958
9.03k
                        character_sets::USERINFO_PERCENT_ENCODE));
13959
9.03k
                    url.append_base_password(unicode::percent_encode(
13960
9.03k
                        authority_view.substr(password_token_location + 1),
13961
9.03k
                        character_sets::USERINFO_PERCENT_ENCODE));
13962
9.03k
                  }
13963
9.03k
                }
13964
49.2k
              }
13965
49.2k
            } else if constexpr (store_values) {
13966
13.2k
              if constexpr (result_type_is_ada_url) {
13967
0
                url.password += unicode::percent_encode(
13968
0
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE);
13969
13.2k
              } else {
13970
13.2k
                url.append_base_password(unicode::percent_encode(
13971
13.2k
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE));
13972
13.2k
              }
13973
13.2k
            }
13974
62.4k
          }
13975
          // Otherwise, if one of the following is true:
13976
          // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
13977
          // - url is special and c is U+005C (\)
13978
40.3k
          else if (end_of_authority == input_size ||
13979
37.2k
                   url_data[end_of_authority] == '/' ||
13980
1.04k
                   url_data[end_of_authority] == '?' ||
13981
40.3k
                   (url.is_special() && url_data[end_of_authority] == '\\')) {
13982
            // If atSignSeen is true and authority_view is the empty string,
13983
            // validation error, return failure.
13984
40.3k
            if (at_sign_seen && authority_view.empty()) {
13985
6.45k
              url.is_valid = false;
13986
6.45k
              return url;
13987
6.45k
            }
13988
33.8k
            state = state::HOST;
13989
33.8k
            break;
13990
40.3k
          }
13991
62.4k
          if (end_of_authority == input_size) {
13992
0
            if constexpr (store_values) {
13993
0
              if (fragment.has_value()) {
13994
0
                url.update_unencoded_base_hash(*fragment);
13995
0
              }
13996
0
            }
13997
0
            return url;
13998
0
          }
13999
62.4k
          input_position = end_of_authority + 1;
14000
62.4k
        } while (true);
14001
14002
33.8k
        break;
14003
40.3k
      }
14004
216k
      case state::SPECIAL_RELATIVE_OR_AUTHORITY: {
14005
216k
        ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ",
14006
216k
                helpers::substring(url_data, input_position));
14007
14008
        // If c is U+002F (/) and remaining starts with U+002F (/),
14009
        // then set state to special authority ignore slashes state and increase
14010
        // pointer by 1.
14011
216k
        if (url_data.substr(input_position, 2) == "//") {
14012
216k
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
14013
216k
          input_position += 2;
14014
216k
        } else {
14015
          // Otherwise, validation error, set state to relative state and
14016
          // decrease pointer by 1.
14017
0
          state = state::RELATIVE_SCHEME;
14018
0
        }
14019
14020
216k
        break;
14021
40.3k
      }
14022
238k
      case state::PATH_OR_AUTHORITY: {
14023
238k
        ada_log("PATH_OR_AUTHORITY ",
14024
238k
                helpers::substring(url_data, input_position));
14025
14026
        // If c is U+002F (/), then set state to authority state.
14027
238k
        if ((input_position != input_size) &&
14028
219k
            (url_data[input_position] == '/')) {
14029
218k
          state = state::AUTHORITY;
14030
218k
          input_position++;
14031
218k
        } else {
14032
          // Otherwise, set state to path state, and decrease pointer by 1.
14033
20.2k
          state = state::PATH;
14034
20.2k
        }
14035
14036
238k
        break;
14037
40.3k
      }
14038
0
      case state::RELATIVE_SCHEME: {
14039
0
        ada_log("RELATIVE_SCHEME ",
14040
0
                helpers::substring(url_data, input_position));
14041
14042
        // Set url's scheme to base's scheme.
14043
0
        url.copy_scheme(*base_url);
14044
14045
        // If c is U+002F (/), then set state to relative slash state.
14046
0
        if ((input_position != input_size) &&
14047
            // NOLINTNEXTLINE(bugprone-branch-clone)
14048
0
            (url_data[input_position] == '/')) {
14049
0
          ada_log(
14050
0
              "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
14051
0
              "slash state");
14052
0
          state = state::RELATIVE_SLASH;
14053
0
        } else if (url.is_special() && (input_position != input_size) &&
14054
0
                   (url_data[input_position] == '\\')) {
14055
          // Otherwise, if url is special and c is U+005C (\), validation error,
14056
          // set state to relative slash state.
14057
0
          ada_log(
14058
0
              "RELATIVE_SCHEME  if url is special and c is U+005C, validation "
14059
0
              "error, set state to relative slash state");
14060
0
          state = state::RELATIVE_SLASH;
14061
0
        } else {
14062
0
          ada_log("RELATIVE_SCHEME otherwise");
14063
          // Set url's username to base's username, url's password to base's
14064
          // password, url's host to base's host, url's port to base's port,
14065
          // url's path to a clone of base's path, and url's query to base's
14066
          // query.
14067
0
          if constexpr (result_type_is_ada_url) {
14068
0
            url.username = base_url->username;
14069
0
            url.password = base_url->password;
14070
0
            url.host = base_url->host;
14071
0
            url.port = base_url->port;
14072
            // cloning the base path includes cloning the has_opaque_path flag
14073
0
            url.has_opaque_path = base_url->has_opaque_path;
14074
0
            url.path = base_url->path;
14075
0
            url.query = base_url->query;
14076
0
          } else {
14077
0
            url.update_base_authority(base_url->get_href(),
14078
0
                                      base_url->get_components());
14079
0
            url.update_host_to_base_host(base_url->get_hostname());
14080
0
            url.update_base_port(base_url->retrieve_base_port());
14081
            // cloning the base path includes cloning the has_opaque_path flag
14082
0
            url.has_opaque_path = base_url->has_opaque_path;
14083
0
            url.update_base_pathname(base_url->get_pathname());
14084
0
            if (base_url->has_search()) {
14085
              // get_search() returns "" for an empty query string (URL ends
14086
              // with '?'). update_base_search("") would incorrectly clear the
14087
              // query, so pass "?" to preserve the empty query distinction.
14088
0
              auto s = base_url->get_search();
14089
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
14090
0
            }
14091
0
          }
14092
14093
0
          url.has_opaque_path = base_url->has_opaque_path;
14094
14095
          // If c is U+003F (?), then set url's query to the empty string, and
14096
          // state to query state.
14097
0
          if ((input_position != input_size) &&
14098
0
              (url_data[input_position] == '?')) {
14099
0
            state = state::QUERY;
14100
0
          }
14101
          // Otherwise, if c is not the EOF code point:
14102
0
          else if (input_position != input_size) {
14103
            // Set url's query to null.
14104
0
            url.clear_search();
14105
0
            if constexpr (result_type_is_ada_url) {
14106
              // Shorten url's path.
14107
0
              helpers::shorten_path(url.path, url.type);
14108
0
            } else {
14109
0
              std::string_view path = url.get_pathname();
14110
0
              if (helpers::shorten_path(path, url.type)) {
14111
0
                url.update_base_pathname(std::move(std::string(path)));
14112
0
              }
14113
0
            }
14114
            // Set state to path state and decrease pointer by 1.
14115
0
            state = state::PATH;
14116
0
            break;
14117
0
          }
14118
0
        }
14119
0
        input_position++;
14120
0
        break;
14121
0
      }
14122
0
      case state::RELATIVE_SLASH: {
14123
0
        ada_log("RELATIVE_SLASH ",
14124
0
                helpers::substring(url_data, input_position));
14125
14126
        // If url is special and c is U+002F (/) or U+005C (\), then:
14127
        // NOLINTNEXTLINE(bugprone-branch-clone)
14128
0
        if (url.is_special() && (input_position != input_size) &&
14129
0
            (url_data[input_position] == '/' ||
14130
0
             url_data[input_position] == '\\')) {
14131
          // Set state to special authority ignore slashes state.
14132
0
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
14133
0
        }
14134
        // Otherwise, if c is U+002F (/), then set state to authority state.
14135
0
        else if ((input_position != input_size) &&
14136
0
                 (url_data[input_position] == '/')) {
14137
0
          state = state::AUTHORITY;
14138
0
        }
14139
        // Otherwise, set
14140
        // - url's username to base's username,
14141
        // - url's password to base's password,
14142
        // - url's host to base's host,
14143
        // - url's port to base's port,
14144
        // - state to path state, and then, decrease pointer by 1.
14145
0
        else {
14146
0
          if constexpr (result_type_is_ada_url) {
14147
0
            url.username = base_url->username;
14148
0
            url.password = base_url->password;
14149
0
            url.host = base_url->host;
14150
0
            url.port = base_url->port;
14151
0
          } else {
14152
0
            url.update_base_authority(base_url->get_href(),
14153
0
                                      base_url->get_components());
14154
0
            url.update_host_to_base_host(base_url->get_hostname());
14155
0
            url.update_base_port(base_url->retrieve_base_port());
14156
0
          }
14157
0
          state = state::PATH;
14158
0
          break;
14159
0
        }
14160
14161
0
        input_position++;
14162
0
        break;
14163
0
      }
14164
728k
      case state::SPECIAL_AUTHORITY_SLASHES: {
14165
728k
        ada_log("SPECIAL_AUTHORITY_SLASHES ",
14166
728k
                helpers::substring(url_data, input_position));
14167
14168
        // If c is U+002F (/) and remaining starts with U+002F (/),
14169
        // then set state to special authority ignore slashes state and increase
14170
        // pointer by 1.
14171
728k
        if (url_data.substr(input_position, 2) == "//") {
14172
728k
          input_position += 2;
14173
728k
        }
14174
14175
728k
        [[fallthrough]];
14176
728k
      }
14177
944k
      case state::SPECIAL_AUTHORITY_IGNORE_SLASHES: {
14178
944k
        ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ",
14179
944k
                helpers::substring(url_data, input_position));
14180
14181
        // If c is neither U+002F (/) nor U+005C (\), then set state to
14182
        // authority state and decrease pointer by 1.
14183
1.34M
        while ((input_position != input_size) &&
14184
957k
               ((url_data[input_position] == '/') ||
14185
559k
                (url_data[input_position] == '\\'))) {
14186
405k
          input_position++;
14187
405k
        }
14188
944k
        state = state::AUTHORITY;
14189
14190
944k
        break;
14191
728k
      }
14192
17.1k
      case state::QUERY: {
14193
17.1k
        ada_log("QUERY ", helpers::substring(url_data, input_position));
14194
17.1k
        if constexpr (store_values) {
14195
          // Let queryPercentEncodeSet be the special-query percent-encode set
14196
          // if url is special; otherwise the query percent-encode set.
14197
17.1k
          const uint8_t* query_percent_encode_set =
14198
17.1k
              url.is_special() ? character_sets::SPECIAL_QUERY_PERCENT_ENCODE
14199
17.1k
                               : character_sets::QUERY_PERCENT_ENCODE;
14200
14201
          // Percent-encode after encoding, with encoding, buffer, and
14202
          // queryPercentEncodeSet, and append the result to url's query.
14203
17.1k
          url.update_base_search(url_data.substr(input_position),
14204
17.1k
                                 query_percent_encode_set);
14205
17.1k
          ada_log("QUERY update_base_search completed ");
14206
17.1k
          if (fragment.has_value()) {
14207
2.88k
            url.update_unencoded_base_hash(*fragment);
14208
2.88k
          }
14209
17.1k
        }
14210
17.1k
        return url;
14211
728k
      }
14212
1.15M
      case state::HOST: {
14213
1.15M
        ada_log("HOST ", helpers::substring(url_data, input_position));
14214
14215
1.15M
        std::string_view host_view = url_data.substr(input_position);
14216
1.15M
        auto [location, found_colon] =
14217
1.15M
            helpers::get_host_delimiter_location(url.is_special(), host_view);
14218
1.15M
        input_position = (location != std::string_view::npos)
14219
1.15M
                             ? input_position + location
14220
1.15M
                             : input_size;
14221
        // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
14222
        // Note: the 'found_colon' value is true if and only if a colon was
14223
        // encountered while not inside brackets.
14224
1.15M
        if (found_colon) {
14225
          // If buffer is the empty string, validation error, return failure.
14226
          // Let host be the result of host parsing buffer with url is not
14227
          // special.
14228
24.5k
          ada_log("HOST parsing ", host_view);
14229
24.5k
          if (!url.parse_host(host_view)) {
14230
4.17k
            return url;
14231
4.17k
          }
14232
20.3k
          ada_log("HOST parsing results in ", url.get_hostname());
14233
          // Set url's host to host, buffer to the empty string, and state to
14234
          // port state.
14235
20.3k
          state = state::PORT;
14236
20.3k
          input_position++;
14237
20.3k
        }
14238
        // Otherwise, if one of the following is true:
14239
        // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
14240
        // - url is special and c is U+005C (\)
14241
        // The get_host_delimiter_location function either brings us to
14242
        // the colon outside of the bracket, or to one of those characters.
14243
1.13M
        else {
14244
          // If url is special and host_view is the empty string, validation
14245
          // error, return failure.
14246
1.13M
          if (host_view.empty() && url.is_special()) {
14247
394k
            url.is_valid = false;
14248
394k
            return url;
14249
394k
          }
14250
738k
          ada_log("HOST parsing ", host_view, " href=", url.get_href());
14251
          // Let host be the result of host parsing host_view with url is not
14252
          // special.
14253
738k
          if (host_view.empty()) {
14254
67
            url.update_base_hostname("");
14255
738k
          } else if (!url.parse_host(host_view)) {
14256
91.7k
            return url;
14257
91.7k
          }
14258
646k
          ada_log("HOST parsing results in ", url.get_hostname(),
14259
646k
                  " href=", url.get_href());
14260
14261
          // Set url's host to host, and state to path start state.
14262
646k
          state = state::PATH_START;
14263
646k
        }
14264
14265
666k
        break;
14266
1.15M
      }
14267
666k
      case state::OPAQUE_PATH: {
14268
838
        ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position));
14269
        // Opaque path, query, and fragment are structurally always valid:
14270
        // the parser would just percent-encode whatever is there. When we
14271
        // are not storing values (can_parse), we can return immediately.
14272
        // We must set has_opaque_path = true before returning so that when
14273
        // this URL is used as an internal base inside can_parse, NO_SCHEME
14274
        // correctly rejects relative inputs against an opaque-path base
14275
        // (e.g. can_parse("", &"W:") must return false).
14276
838
        if constexpr (!store_values) {
14277
0
          url.has_opaque_path = true;
14278
0
          return url;
14279
0
        }
14280
0
        std::string_view view = url_data.substr(input_position);
14281
        // If c is U+003F (?), then set url's query to the empty string and
14282
        // state to query state.
14283
838
        size_t location = view.find('?');
14284
838
        if (location != std::string_view::npos) {
14285
44
          view.remove_suffix(view.size() - location);
14286
44
          state = state::QUERY;
14287
44
          input_position += location + 1;
14288
794
        } else {
14289
794
          input_position = input_size + 1;
14290
794
        }
14291
838
        url.has_opaque_path = true;
14292
14293
        // This is a really unlikely scenario in real world. We should not seek
14294
        // to optimize it.
14295
838
        if (view.ends_with(' ')) {
14296
41
          std::string modified_view =
14297
41
              std::string(view.substr(0, view.size() - 1)) + "%20";
14298
41
          url.update_base_pathname(unicode::percent_encode(
14299
41
              modified_view, character_sets::C0_CONTROL_PERCENT_ENCODE));
14300
797
        } else {
14301
797
          url.update_base_pathname(unicode::percent_encode(
14302
797
              view, character_sets::C0_CONTROL_PERCENT_ENCODE));
14303
797
        }
14304
838
        break;
14305
1.15M
      }
14306
20.3k
      case state::PORT: {
14307
20.3k
        ada_log("PORT ", helpers::substring(url_data, input_position));
14308
20.3k
        std::string_view port_view = url_data.substr(input_position);
14309
20.3k
        input_position += url.parse_port(port_view, true);
14310
20.3k
        if (!url.is_valid) {
14311
3.37k
          return url;
14312
3.37k
        }
14313
16.9k
        state = state::PATH_START;
14314
16.9k
        [[fallthrough]];
14315
16.9k
      }
14316
663k
      case state::PATH_START: {
14317
663k
        ada_log("PATH_START ", helpers::substring(url_data, input_position));
14318
        // Path, query, and fragment are structurally always valid: the
14319
        // parser would just percent-encode whatever is there. When we are
14320
        // not storing values (can_parse), we can return immediately since
14321
        // no subsequent state can invalidate the URL.
14322
663k
        if constexpr (!store_values) {
14323
0
          return url;
14324
0
        }
14325
14326
        // If url is special, then:
14327
663k
        if (url.is_special()) {
14328
          // Set state to path state.
14329
445k
          state = state::PATH;
14330
14331
          // Optimization: Avoiding going into PATH state improves the
14332
          // performance of urls ending with /.
14333
445k
          if (input_position == input_size) {
14334
298k
            if constexpr (store_values) {
14335
298k
              url.update_base_pathname("/");
14336
298k
              if (fragment.has_value()) {
14337
5.75k
                url.update_unencoded_base_hash(*fragment);
14338
5.75k
              }
14339
298k
            }
14340
298k
            return url;
14341
298k
          }
14342
          // If c is neither U+002F (/) nor U+005C (\), then decrease pointer
14343
          // by 1. We know that (input_position == input_size) is impossible
14344
          // here, because of the previous if-check.
14345
147k
          if ((url_data[input_position] != '/') &&
14346
11.6k
              (url_data[input_position] != '\\')) {
14347
9.14k
            break;
14348
9.14k
          }
14349
147k
        }
14350
        // Otherwise, if state override is not given and c is U+003F (?),
14351
        // set url's query to the empty string and state to query state.
14352
218k
        else if ((input_position != input_size) &&
14353
218k
                 (url_data[input_position] == '?')) {
14354
14
          state = state::QUERY;
14355
14
        }
14356
        // Otherwise, if c is not the EOF code point:
14357
218k
        else if (input_position != input_size) {
14358
          // Set state to path state.
14359
218k
          state = state::PATH;
14360
14361
          // If c is not U+002F (/), then decrease pointer by 1.
14362
218k
          if (url_data[input_position] != '/') {
14363
0
            break;
14364
0
          }
14365
218k
        }
14366
14367
356k
        input_position++;
14368
356k
        break;
14369
663k
      }
14370
385k
      case state::PATH: {
14371
385k
        ada_log("PATH ", helpers::substring(url_data, input_position));
14372
        // Path, query, and fragment are structurally always valid: the
14373
        // parser would just percent-encode whatever is there. When we are
14374
        // not storing values (can_parse), we can return immediately since
14375
        // no subsequent state can invalidate the URL.
14376
385k
        if constexpr (!store_values) {
14377
0
          return url;
14378
0
        }
14379
0
        std::string_view view = url_data.substr(input_position);
14380
14381
        // Most time, we do not need percent encoding.
14382
        // Furthermore, we can immediately locate the '?'.
14383
385k
        size_t locofquestionmark = view.find('?');
14384
385k
        if (locofquestionmark != std::string_view::npos) {
14385
17.0k
          state = state::QUERY;
14386
17.0k
          view.remove_suffix(view.size() - locofquestionmark);
14387
17.0k
          input_position += locofquestionmark + 1;
14388
368k
        } else {
14389
368k
          input_position = input_size + 1;
14390
368k
        }
14391
385k
        if constexpr (store_values) {
14392
385k
          if constexpr (result_type_is_ada_url) {
14393
0
            helpers::parse_prepared_path(view, url.type, url.path);
14394
385k
          } else {
14395
385k
            url.consume_prepared_path(view);
14396
385k
            ADA_ASSERT_TRUE(url.validate());
14397
385k
          }
14398
385k
        }
14399
385k
        break;
14400
663k
      }
14401
0
      case state::FILE_SLASH: {
14402
0
        ada_log("FILE_SLASH ", helpers::substring(url_data, input_position));
14403
14404
        // If c is U+002F (/) or U+005C (\), then:
14405
0
        if ((input_position != input_size) &&
14406
0
            (url_data[input_position] == '/' ||
14407
0
             url_data[input_position] == '\\')) {
14408
0
          ada_log("FILE_SLASH c is U+002F or U+005C");
14409
          // Set state to file host state.
14410
0
          state = state::FILE_HOST;
14411
0
          input_position++;
14412
0
        } else {
14413
0
          ada_log("FILE_SLASH otherwise");
14414
          // If base is non-null and base's scheme is "file", then:
14415
          // Note: it is unsafe to do base_url->scheme unless you know that
14416
          // base_url_has_value() is true.
14417
0
          if (base_url != nullptr && base_url->type == scheme::type::FILE) {
14418
            // Set url's host to base's host.
14419
0
            if constexpr (result_type_is_ada_url) {
14420
0
              url.host = base_url->host;
14421
0
            } else {
14422
0
              url.update_host_to_base_host(base_url->get_host());
14423
0
            }
14424
            // If the code point substring from pointer to the end of input does
14425
            // not start with a Windows drive letter and base's path[0] is a
14426
            // normalized Windows drive letter, then append base's path[0] to
14427
            // url's path.
14428
0
            if (!base_url->get_pathname().empty()) {
14429
0
              if (!checkers::is_windows_drive_letter(
14430
0
                      url_data.substr(input_position))) {
14431
0
                std::string_view first_base_url_path =
14432
0
                    base_url->get_pathname().substr(1);
14433
0
                size_t loc = first_base_url_path.find('/');
14434
0
                if (loc != std::string_view::npos) {
14435
0
                  helpers::resize(first_base_url_path, loc);
14436
0
                }
14437
0
                if (checkers::is_normalized_windows_drive_letter(
14438
0
                        first_base_url_path)) {
14439
0
                  if constexpr (result_type_is_ada_url) {
14440
0
                    url.path += '/';
14441
0
                    url.path += first_base_url_path;
14442
0
                  } else {
14443
0
                    url.append_base_pathname(
14444
0
                        helpers::concat("/", first_base_url_path));
14445
0
                  }
14446
0
                }
14447
0
              }
14448
0
            }
14449
0
          }
14450
14451
          // Set state to path state, and decrease pointer by 1.
14452
0
          state = state::PATH;
14453
0
        }
14454
14455
0
        break;
14456
663k
      }
14457
0
      case state::FILE_HOST: {
14458
0
        ada_log("FILE_HOST ", helpers::substring(url_data, input_position));
14459
0
        std::string_view view = url_data.substr(input_position);
14460
14461
0
        size_t location = view.find_first_of("/\\?");
14462
0
        std::string_view file_host_buffer = view.substr(
14463
0
            0, (location != std::string_view::npos) ? location : view.size());
14464
14465
0
        if (checkers::is_windows_drive_letter(file_host_buffer)) {
14466
0
          state = state::PATH;
14467
0
        } else if (file_host_buffer.empty()) {
14468
          // Set url's host to the empty string.
14469
0
          if constexpr (result_type_is_ada_url) {
14470
0
            url.host = "";
14471
0
          } else {
14472
0
            url.update_base_hostname("");
14473
0
          }
14474
          // Set state to path start state.
14475
0
          state = state::PATH_START;
14476
0
        } else {
14477
0
          size_t consumed_bytes = file_host_buffer.size();
14478
0
          input_position += consumed_bytes;
14479
          // Let host be the result of host parsing buffer with url is not
14480
          // special.
14481
0
          if (!url.parse_host(file_host_buffer)) {
14482
0
            return url;
14483
0
          }
14484
14485
0
          if constexpr (result_type_is_ada_url) {
14486
            // If host is "localhost", then set host to the empty string.
14487
0
            if (url.host.has_value() && url.host.value() == "localhost") {
14488
0
              url.host = "";
14489
0
            }
14490
0
          } else {
14491
0
            if (url.get_hostname() == "localhost") {
14492
0
              url.update_base_hostname("");
14493
0
            }
14494
0
          }
14495
14496
          // Set buffer to the empty string and state to path start state.
14497
0
          state = state::PATH_START;
14498
0
        }
14499
14500
0
        break;
14501
0
      }
14502
0
      case state::FILE: {
14503
0
        ada_log("FILE ", helpers::substring(url_data, input_position));
14504
0
        std::string_view file_view = url_data.substr(input_position);
14505
14506
0
        url.set_protocol_as_file();
14507
0
        if constexpr (result_type_is_ada_url) {
14508
          // Set url's host to the empty string.
14509
0
          url.host = "";
14510
0
        } else {
14511
0
          url.update_base_hostname("");
14512
0
        }
14513
        // If c is U+002F (/) or U+005C (\), then:
14514
0
        if (input_position != input_size &&
14515
0
            (url_data[input_position] == '/' ||
14516
0
             url_data[input_position] == '\\')) {
14517
0
          ada_log("FILE c is U+002F or U+005C");
14518
          // Set state to file slash state.
14519
0
          state = state::FILE_SLASH;
14520
0
        }
14521
        // Otherwise, if base is non-null and base's scheme is "file":
14522
0
        else if (base_url != nullptr && base_url->type == scheme::type::FILE) {
14523
          // Set url's host to base's host, url's path to a clone of base's
14524
          // path, and url's query to base's query.
14525
0
          ada_log("FILE base non-null");
14526
0
          if constexpr (result_type_is_ada_url) {
14527
0
            url.host = base_url->host;
14528
0
            url.path = base_url->path;
14529
0
            url.query = base_url->query;
14530
0
          } else {
14531
0
            url.update_host_to_base_host(base_url->get_hostname());
14532
0
            url.update_base_pathname(base_url->get_pathname());
14533
0
            if (base_url->has_search()) {
14534
              // get_search() returns "" for an empty query string (URL ends
14535
              // with '?'). update_base_search("") would incorrectly clear the
14536
              // query, so pass "?" to preserve the empty query distinction.
14537
0
              auto s = base_url->get_search();
14538
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
14539
0
            }
14540
0
          }
14541
0
          url.has_opaque_path = base_url->has_opaque_path;
14542
14543
          // If c is U+003F (?), then set url's query to the empty string and
14544
          // state to query state.
14545
0
          if (input_position != input_size && url_data[input_position] == '?') {
14546
0
            state = state::QUERY;
14547
0
          }
14548
          // Otherwise, if c is not the EOF code point:
14549
0
          else if (input_position != input_size) {
14550
            // Set url's query to null.
14551
0
            url.clear_search();
14552
            // If the code point substring from pointer to the end of input does
14553
            // not start with a Windows drive letter, then shorten url's path.
14554
0
            if (!checkers::is_windows_drive_letter(file_view)) {
14555
0
              if constexpr (result_type_is_ada_url) {
14556
0
                helpers::shorten_path(url.path, url.type);
14557
0
              } else {
14558
0
                std::string_view path = url.get_pathname();
14559
0
                if (helpers::shorten_path(path, url.type)) {
14560
0
                  url.update_base_pathname(std::move(std::string(path)));
14561
0
                }
14562
0
              }
14563
0
            }
14564
            // Otherwise:
14565
0
            else {
14566
              // Set url's path to an empty list.
14567
0
              url.clear_pathname();
14568
0
              url.has_opaque_path = true;
14569
0
            }
14570
14571
            // Set state to path state and decrease pointer by 1.
14572
0
            state = state::PATH;
14573
0
            break;
14574
0
          }
14575
0
        }
14576
        // Otherwise, set state to path state, and decrease pointer by 1.
14577
0
        else {
14578
0
          ada_log("FILE go to path");
14579
0
          state = state::PATH;
14580
0
          break;
14581
0
        }
14582
14583
0
        input_position++;
14584
0
        break;
14585
0
      }
14586
0
      default:
14587
0
        unreachable();
14588
7.20M
    }
14589
7.20M
  }
14590
369k
  if constexpr (store_values) {
14591
369k
    if (fragment.has_value()) {
14592
4.54k
      url.update_unencoded_base_hash(*fragment);
14593
4.54k
    }
14594
369k
  }
14595
  // Check the resulting (normalized) URL size against the maximum input length.
14596
  // Normalization (percent-encoding, IDNA, etc.) can expand the URL beyond the
14597
  // original input size.
14598
369k
  if constexpr (store_values) {
14599
369k
    if (url.is_valid) {
14600
369k
      if constexpr (result_type_is_ada_url_aggregator) {
14601
369k
        if (url.buffer.size() > max_input_length) {
14602
0
          url.is_valid = false;
14603
0
        }
14604
369k
      } else {
14605
0
        if (url.get_href_size() > max_input_length) {
14606
0
          url.is_valid = false;
14607
0
        }
14608
0
      }
14609
369k
    }
14610
369k
  }
14611
369k
  return url;
14612
1.20M
}
Unexecuted instantiation: ada::url ada::parser::parse_url_impl<ada::url, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url const*)
ada::url_aggregator ada::parser::parse_url_impl<ada::url_aggregator, true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, ada::url_aggregator const*)
Line
Count
Source
13654
1.20M
                           const result_type* base_url) {
13655
  // We can specialize the implementation per type.
13656
  // Important: result_type_is_ada_url is evaluated at *compile time*. This
13657
  // means that doing if constexpr(result_type_is_ada_url) { something } else {
13658
  // something else } is free (at runtime). This means that ada::url_aggregator
13659
  // and ada::url **do not have to support the exact same API**.
13660
1.20M
  constexpr bool result_type_is_ada_url = std::is_same_v<url, result_type>;
13661
1.20M
  constexpr bool result_type_is_ada_url_aggregator =
13662
1.20M
      std::is_same_v<url_aggregator, result_type>;
13663
1.20M
  static_assert(result_type_is_ada_url ||
13664
1.20M
                result_type_is_ada_url_aggregator);  // We don't support
13665
                                                     // anything else for now.
13666
13667
1.20M
  ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
13668
1.20M
          " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
13669
1.20M
          ")");
13670
13671
1.20M
  state state = state::SCHEME_START;
13672
1.20M
  result_type url{};
13673
13674
1.20M
  const uint32_t max_input_length = ada::get_max_input_length();
13675
13676
  // We refuse to parse URL strings that exceed the maximum input length.
13677
  // By default, this is 4GB but can be configured via
13678
  // ada::set_max_input_length().
13679
1.20M
  if (user_input.size() > max_input_length) [[unlikely]] {
13680
0
    url.is_valid = false;
13681
0
  }
13682
  // Going forward, user_input.size() is in [0,
13683
  // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
13684
  // base, or the optional_url was invalid, we must return.
13685
1.20M
  if (base_url != nullptr) {
13686
541k
    url.is_valid &= base_url->is_valid;
13687
541k
  }
13688
1.20M
  if (!url.is_valid) {
13689
0
    return url;
13690
0
  }
13691
1.20M
  if constexpr (result_type_is_ada_url_aggregator && store_values) {
13692
    // Most of the time, we just need user_input.size().
13693
    // In some instances, we may need a bit more.
13694
    ///////////////////////////
13695
    // This is *very* important. This line should *not* be removed
13696
    // hastily. There are principled reasons why reserve is important
13697
    // for performance. If you have a benchmark with small inputs,
13698
    // it may not matter, but in other instances, it could.
13699
    ////
13700
    // This rounds up to the next power of two.
13701
    // We know that user_input.size() is in [0,
13702
    // std::numeric_limits<uint32_t>::max).
13703
1.20M
    uint32_t reserve_capacity =
13704
1.20M
        (0xFFFFFFFF >>
13705
1.20M
         helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
13706
1.20M
        1;
13707
1.20M
    url.reserve(reserve_capacity);
13708
1.20M
  }
13709
1.20M
  std::string tmp_buffer;
13710
1.20M
  std::string_view url_data;
13711
1.20M
  if (unicode::has_tabs_or_newline(user_input)) [[unlikely]] {
13712
7.69k
    tmp_buffer = user_input;
13713
    // Optimization opportunity: Instead of copying and then pruning, we could
13714
    // just directly build the string from user_input.
13715
7.69k
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
13716
7.69k
    url_data = tmp_buffer;
13717
1.20M
  } else [[likely]] {
13718
1.20M
    url_data = user_input;
13719
1.20M
  }
13720
13721
  // Leading and trailing control characters are uncommon and easy to deal with
13722
  // (no performance concern).
13723
1.20M
  helpers::trim_c0_whitespace(url_data);
13724
13725
  // Optimization opportunity. Most websites do not have fragment.
13726
1.20M
  std::optional<std::string_view> fragment = helpers::prune_hash(url_data);
13727
  // We add it last so that an implementation like ada::url_aggregator
13728
  // can append it last to its internal buffer, thus improving performance.
13729
13730
  // Here url_data no longer has its fragment.
13731
  // We are going to access the data from url_data (it is immutable).
13732
  // At any given time, we are pointing at byte 'input_position' in url_data.
13733
  // The input_position variable should range from 0 to input_size.
13734
  // It is illegal to access url_data at input_size.
13735
1.20M
  size_t input_position = 0;
13736
1.20M
  const size_t input_size = url_data.size();
13737
  // Keep running the following state machine by switching on state.
13738
  // If after a run pointer points to the EOF code point, go to the next step.
13739
  // Otherwise, increase pointer by 1 and continue with the state machine.
13740
  // We never decrement input_position.
13741
7.57M
  while (input_position <= input_size) {
13742
7.20M
    ada_log("In parsing at ", input_position, " out of ", input_size,
13743
7.20M
            " in state ", ada::to_string(state));
13744
7.20M
    switch (state) {
13745
1.20M
      case state::SCHEME_START: {
13746
1.20M
        ada_log("SCHEME_START ", helpers::substring(url_data, input_position));
13747
        // If c is an ASCII alpha, append c, lowercased, to buffer, and set
13748
        // state to scheme state.
13749
1.20M
        if ((input_position != input_size) &&
13750
1.20M
            checkers::is_alpha(url_data[input_position])) {
13751
1.18M
          state = state::SCHEME;
13752
1.18M
          input_position++;
13753
1.18M
        } else {
13754
          // Otherwise, if state override is not given, set state to no scheme
13755
          // state and decrease pointer by 1.
13756
24.0k
          state = state::NO_SCHEME;
13757
24.0k
        }
13758
1.20M
        break;
13759
0
      }
13760
1.18M
      case state::SCHEME: {
13761
1.18M
        ada_log("SCHEME ", helpers::substring(url_data, input_position));
13762
        // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),
13763
        // append c, lowercased, to buffer.
13764
5.68M
        while ((input_position != input_size) &&
13765
5.68M
               (unicode::is_alnum_plus(url_data[input_position]))) {
13766
4.49M
          input_position++;
13767
4.49M
        }
13768
        // Otherwise, if c is U+003A (:), then:
13769
1.18M
        if ((input_position != input_size) &&
13770
1.18M
            (url_data[input_position] == ':')) {
13771
1.18M
          ada_log("SCHEME the scheme should be ",
13772
1.18M
                  url_data.substr(0, input_position));
13773
          if constexpr (result_type_is_ada_url) {
13774
            if (!url.parse_scheme(url_data.substr(0, input_position))) {
13775
              return url;
13776
            }
13777
1.18M
          } else {
13778
            // we pass the colon along instead of painfully adding it back.
13779
1.18M
            if (!url.parse_scheme_with_colon(
13780
1.18M
                    url_data.substr(0, input_position + 1))) {
13781
0
              return url;
13782
0
            }
13783
1.18M
          }
13784
1.18M
          ada_log("SCHEME the scheme is ", url.get_protocol());
13785
13786
          // If url's scheme is "file", then:
13787
          // NOLINTNEXTLINE(bugprone-branch-clone)
13788
1.18M
          if (url.type == scheme::type::FILE) {
13789
            // Set state to file state.
13790
0
            state = state::FILE;
13791
0
          }
13792
          // Otherwise, if url is special, base is non-null, and base's scheme
13793
          // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url
13794
          // != nullptr is false.
13795
1.18M
          else if (url.is_special() && base_url != nullptr &&
13796
541k
                   base_url->type == url.type) {
13797
            // Set state to special relative or authority state.
13798
216k
            state = state::SPECIAL_RELATIVE_OR_AUTHORITY;
13799
216k
          }
13800
          // Otherwise, if url is special, set state to special authority
13801
          // slashes state.
13802
967k
          else if (url.is_special()) {
13803
728k
            state = state::SPECIAL_AUTHORITY_SLASHES;
13804
728k
          }
13805
          // Otherwise, if remaining starts with an U+002F (/), set state to
13806
          // path or authority state and increase pointer by 1.
13807
239k
          else if (input_position + 1 < input_size &&
13808
239k
                   url_data[input_position + 1] == '/') {
13809
238k
            state = state::PATH_OR_AUTHORITY;
13810
238k
            input_position++;
13811
238k
          }
13812
          // Otherwise, set url's path to the empty string and set state to
13813
          // opaque path state.
13814
838
          else {
13815
838
            state = state::OPAQUE_PATH;
13816
838
          }
13817
1.18M
        }
13818
        // Otherwise, if state override is not given, set buffer to the empty
13819
        // string, state to no scheme state, and start over (from the first code
13820
        // point in input).
13821
0
        else {
13822
0
          state = state::NO_SCHEME;
13823
0
          input_position = 0;
13824
0
          break;
13825
0
        }
13826
1.18M
        input_position++;
13827
1.18M
        break;
13828
1.18M
      }
13829
24.0k
      case state::NO_SCHEME: {
13830
24.0k
        ada_log("NO_SCHEME ", helpers::substring(url_data, input_position));
13831
        // If base is null, or base has an opaque path and c is not U+0023 (#),
13832
        // validation error, return failure.
13833
24.0k
        if (base_url == nullptr ||
13834
24.0k
            (base_url->has_opaque_path && !fragment.has_value())) {
13835
24.0k
          ada_log("NO_SCHEME validation error");
13836
24.0k
          url.is_valid = false;
13837
24.0k
          return url;
13838
24.0k
        }
13839
        // Otherwise, if base has an opaque path and c is U+0023 (#),
13840
        // set url's scheme to base's scheme, url's path to base's path, url's
13841
        // query to base's query, and set state to fragment state.
13842
0
        else if (base_url->has_opaque_path && fragment.has_value() &&
13843
0
                 input_position == input_size) {
13844
0
          ada_log("NO_SCHEME opaque base with fragment");
13845
0
          url.copy_scheme(*base_url);
13846
0
          url.has_opaque_path = base_url->has_opaque_path;
13847
13848
          if constexpr (result_type_is_ada_url) {
13849
            url.path = base_url->path;
13850
            url.query = base_url->query;
13851
0
          } else {
13852
0
            url.update_base_pathname(base_url->get_pathname());
13853
0
            if (base_url->has_search()) {
13854
              // get_search() returns "" for an empty query string (URL ends
13855
              // with '?'). update_base_search("") would incorrectly clear the
13856
              // query, so pass "?" to preserve the empty query distinction.
13857
0
              auto s = base_url->get_search();
13858
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
13859
0
            }
13860
0
          }
13861
0
          url.update_unencoded_base_hash(*fragment);
13862
0
          return url;
13863
0
        }
13864
        // Otherwise, if base's scheme is not "file", set state to relative
13865
        // state and decrease pointer by 1.
13866
        // NOLINTNEXTLINE(bugprone-branch-clone)
13867
0
        else if (base_url->type != scheme::type::FILE) {
13868
0
          ada_log("NO_SCHEME non-file relative path");
13869
0
          state = state::RELATIVE_SCHEME;
13870
0
        }
13871
        // Otherwise, set state to file state and decrease pointer by 1.
13872
0
        else {
13873
0
          ada_log("NO_SCHEME file base type");
13874
0
          state = state::FILE;
13875
0
        }
13876
0
        break;
13877
24.0k
      }
13878
1.16M
      case state::AUTHORITY: {
13879
1.16M
        ada_log("AUTHORITY ", helpers::substring(url_data, input_position));
13880
        // most URLs have no @. Having no @ tells us that we don't have to worry
13881
        // about AUTHORITY. Of course, we could have @ and still not have to
13882
        // worry about AUTHORITY.
13883
        // TODO: Instead of just collecting a bool, collect the location of the
13884
        // '@' and do something useful with it.
13885
        // TODO: We could do various processing early on, using a single pass
13886
        // over the string to collect information about it, e.g., telling us
13887
        // whether there is a @ and if so, where (or how many).
13888
13889
        // Check if url data contains an @.
13890
1.16M
        if (url_data.find('@', input_position) == std::string_view::npos) {
13891
1.12M
          state = state::HOST;
13892
1.12M
          break;
13893
1.12M
        }
13894
40.3k
        bool at_sign_seen{false};
13895
40.3k
        bool password_token_seen{false};
13896
        /**
13897
         * We expect something of the sort...
13898
         * https://user:pass@example.com:1234/foo/bar?baz#quux
13899
         * --------^
13900
         */
13901
102k
        do {
13902
102k
          std::string_view view = url_data.substr(input_position);
13903
          // The delimiters are @, /, ? \\.
13904
102k
          size_t location =
13905
102k
              url.is_special() ? helpers::find_authority_delimiter_special(view)
13906
102k
                               : helpers::find_authority_delimiter(view);
13907
102k
          std::string_view authority_view = view.substr(0, location);
13908
102k
          size_t end_of_authority = input_position + authority_view.size();
13909
          // If c is U+0040 (@), then:
13910
102k
          if ((end_of_authority != input_size) &&
13911
99.6k
              (url_data[end_of_authority] == '@')) {
13912
            // If atSignSeen is true, then prepend "%40" to buffer.
13913
62.4k
            if (at_sign_seen) {
13914
33.9k
              if (password_token_seen) {
13915
                if constexpr (result_type_is_ada_url) {
13916
                  url.password += "%40";
13917
13.2k
                } else {
13918
13.2k
                  url.append_base_password("%40");
13919
13.2k
                }
13920
20.6k
              } else {
13921
                if constexpr (result_type_is_ada_url) {
13922
                  url.username += "%40";
13923
20.6k
                } else {
13924
20.6k
                  url.append_base_username("%40");
13925
20.6k
                }
13926
20.6k
              }
13927
33.9k
            }
13928
13929
62.4k
            at_sign_seen = true;
13930
13931
62.4k
            if (!password_token_seen) {
13932
49.2k
              size_t password_token_location = authority_view.find(':');
13933
49.2k
              password_token_seen =
13934
49.2k
                  password_token_location != std::string_view::npos;
13935
13936
49.2k
              if constexpr (store_values) {
13937
49.2k
                if (!password_token_seen) {
13938
                  if constexpr (result_type_is_ada_url) {
13939
                    url.username += unicode::percent_encode(
13940
                        authority_view,
13941
                        character_sets::USERINFO_PERCENT_ENCODE);
13942
40.2k
                  } else {
13943
40.2k
                    url.append_base_username(unicode::percent_encode(
13944
40.2k
                        authority_view,
13945
40.2k
                        character_sets::USERINFO_PERCENT_ENCODE));
13946
40.2k
                  }
13947
40.2k
                } else {
13948
                  if constexpr (result_type_is_ada_url) {
13949
                    url.username += unicode::percent_encode(
13950
                        authority_view.substr(0, password_token_location),
13951
                        character_sets::USERINFO_PERCENT_ENCODE);
13952
                    url.password += unicode::percent_encode(
13953
                        authority_view.substr(password_token_location + 1),
13954
                        character_sets::USERINFO_PERCENT_ENCODE);
13955
9.03k
                  } else {
13956
9.03k
                    url.append_base_username(unicode::percent_encode(
13957
9.03k
                        authority_view.substr(0, password_token_location),
13958
9.03k
                        character_sets::USERINFO_PERCENT_ENCODE));
13959
9.03k
                    url.append_base_password(unicode::percent_encode(
13960
9.03k
                        authority_view.substr(password_token_location + 1),
13961
9.03k
                        character_sets::USERINFO_PERCENT_ENCODE));
13962
9.03k
                  }
13963
9.03k
                }
13964
49.2k
              }
13965
49.2k
            } else if constexpr (store_values) {
13966
              if constexpr (result_type_is_ada_url) {
13967
                url.password += unicode::percent_encode(
13968
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE);
13969
13.2k
              } else {
13970
13.2k
                url.append_base_password(unicode::percent_encode(
13971
13.2k
                    authority_view, character_sets::USERINFO_PERCENT_ENCODE));
13972
13.2k
              }
13973
13.2k
            }
13974
62.4k
          }
13975
          // Otherwise, if one of the following is true:
13976
          // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
13977
          // - url is special and c is U+005C (\)
13978
40.3k
          else if (end_of_authority == input_size ||
13979
37.2k
                   url_data[end_of_authority] == '/' ||
13980
1.04k
                   url_data[end_of_authority] == '?' ||
13981
40.3k
                   (url.is_special() && url_data[end_of_authority] == '\\')) {
13982
            // If atSignSeen is true and authority_view is the empty string,
13983
            // validation error, return failure.
13984
40.3k
            if (at_sign_seen && authority_view.empty()) {
13985
6.45k
              url.is_valid = false;
13986
6.45k
              return url;
13987
6.45k
            }
13988
33.8k
            state = state::HOST;
13989
33.8k
            break;
13990
40.3k
          }
13991
62.4k
          if (end_of_authority == input_size) {
13992
0
            if constexpr (store_values) {
13993
0
              if (fragment.has_value()) {
13994
0
                url.update_unencoded_base_hash(*fragment);
13995
0
              }
13996
0
            }
13997
0
            return url;
13998
0
          }
13999
62.4k
          input_position = end_of_authority + 1;
14000
62.4k
        } while (true);
14001
14002
33.8k
        break;
14003
40.3k
      }
14004
216k
      case state::SPECIAL_RELATIVE_OR_AUTHORITY: {
14005
216k
        ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ",
14006
216k
                helpers::substring(url_data, input_position));
14007
14008
        // If c is U+002F (/) and remaining starts with U+002F (/),
14009
        // then set state to special authority ignore slashes state and increase
14010
        // pointer by 1.
14011
216k
        if (url_data.substr(input_position, 2) == "//") {
14012
216k
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
14013
216k
          input_position += 2;
14014
216k
        } else {
14015
          // Otherwise, validation error, set state to relative state and
14016
          // decrease pointer by 1.
14017
0
          state = state::RELATIVE_SCHEME;
14018
0
        }
14019
14020
216k
        break;
14021
40.3k
      }
14022
238k
      case state::PATH_OR_AUTHORITY: {
14023
238k
        ada_log("PATH_OR_AUTHORITY ",
14024
238k
                helpers::substring(url_data, input_position));
14025
14026
        // If c is U+002F (/), then set state to authority state.
14027
238k
        if ((input_position != input_size) &&
14028
219k
            (url_data[input_position] == '/')) {
14029
218k
          state = state::AUTHORITY;
14030
218k
          input_position++;
14031
218k
        } else {
14032
          // Otherwise, set state to path state, and decrease pointer by 1.
14033
20.2k
          state = state::PATH;
14034
20.2k
        }
14035
14036
238k
        break;
14037
40.3k
      }
14038
0
      case state::RELATIVE_SCHEME: {
14039
0
        ada_log("RELATIVE_SCHEME ",
14040
0
                helpers::substring(url_data, input_position));
14041
14042
        // Set url's scheme to base's scheme.
14043
0
        url.copy_scheme(*base_url);
14044
14045
        // If c is U+002F (/), then set state to relative slash state.
14046
0
        if ((input_position != input_size) &&
14047
            // NOLINTNEXTLINE(bugprone-branch-clone)
14048
0
            (url_data[input_position] == '/')) {
14049
0
          ada_log(
14050
0
              "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
14051
0
              "slash state");
14052
0
          state = state::RELATIVE_SLASH;
14053
0
        } else if (url.is_special() && (input_position != input_size) &&
14054
0
                   (url_data[input_position] == '\\')) {
14055
          // Otherwise, if url is special and c is U+005C (\), validation error,
14056
          // set state to relative slash state.
14057
0
          ada_log(
14058
0
              "RELATIVE_SCHEME  if url is special and c is U+005C, validation "
14059
0
              "error, set state to relative slash state");
14060
0
          state = state::RELATIVE_SLASH;
14061
0
        } else {
14062
0
          ada_log("RELATIVE_SCHEME otherwise");
14063
          // Set url's username to base's username, url's password to base's
14064
          // password, url's host to base's host, url's port to base's port,
14065
          // url's path to a clone of base's path, and url's query to base's
14066
          // query.
14067
          if constexpr (result_type_is_ada_url) {
14068
            url.username = base_url->username;
14069
            url.password = base_url->password;
14070
            url.host = base_url->host;
14071
            url.port = base_url->port;
14072
            // cloning the base path includes cloning the has_opaque_path flag
14073
            url.has_opaque_path = base_url->has_opaque_path;
14074
            url.path = base_url->path;
14075
            url.query = base_url->query;
14076
0
          } else {
14077
0
            url.update_base_authority(base_url->get_href(),
14078
0
                                      base_url->get_components());
14079
0
            url.update_host_to_base_host(base_url->get_hostname());
14080
0
            url.update_base_port(base_url->retrieve_base_port());
14081
            // cloning the base path includes cloning the has_opaque_path flag
14082
0
            url.has_opaque_path = base_url->has_opaque_path;
14083
0
            url.update_base_pathname(base_url->get_pathname());
14084
0
            if (base_url->has_search()) {
14085
              // get_search() returns "" for an empty query string (URL ends
14086
              // with '?'). update_base_search("") would incorrectly clear the
14087
              // query, so pass "?" to preserve the empty query distinction.
14088
0
              auto s = base_url->get_search();
14089
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
14090
0
            }
14091
0
          }
14092
14093
0
          url.has_opaque_path = base_url->has_opaque_path;
14094
14095
          // If c is U+003F (?), then set url's query to the empty string, and
14096
          // state to query state.
14097
0
          if ((input_position != input_size) &&
14098
0
              (url_data[input_position] == '?')) {
14099
0
            state = state::QUERY;
14100
0
          }
14101
          // Otherwise, if c is not the EOF code point:
14102
0
          else if (input_position != input_size) {
14103
            // Set url's query to null.
14104
0
            url.clear_search();
14105
            if constexpr (result_type_is_ada_url) {
14106
              // Shorten url's path.
14107
              helpers::shorten_path(url.path, url.type);
14108
0
            } else {
14109
0
              std::string_view path = url.get_pathname();
14110
0
              if (helpers::shorten_path(path, url.type)) {
14111
0
                url.update_base_pathname(std::move(std::string(path)));
14112
0
              }
14113
0
            }
14114
            // Set state to path state and decrease pointer by 1.
14115
0
            state = state::PATH;
14116
0
            break;
14117
0
          }
14118
0
        }
14119
0
        input_position++;
14120
0
        break;
14121
0
      }
14122
0
      case state::RELATIVE_SLASH: {
14123
0
        ada_log("RELATIVE_SLASH ",
14124
0
                helpers::substring(url_data, input_position));
14125
14126
        // If url is special and c is U+002F (/) or U+005C (\), then:
14127
        // NOLINTNEXTLINE(bugprone-branch-clone)
14128
0
        if (url.is_special() && (input_position != input_size) &&
14129
0
            (url_data[input_position] == '/' ||
14130
0
             url_data[input_position] == '\\')) {
14131
          // Set state to special authority ignore slashes state.
14132
0
          state = state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
14133
0
        }
14134
        // Otherwise, if c is U+002F (/), then set state to authority state.
14135
0
        else if ((input_position != input_size) &&
14136
0
                 (url_data[input_position] == '/')) {
14137
0
          state = state::AUTHORITY;
14138
0
        }
14139
        // Otherwise, set
14140
        // - url's username to base's username,
14141
        // - url's password to base's password,
14142
        // - url's host to base's host,
14143
        // - url's port to base's port,
14144
        // - state to path state, and then, decrease pointer by 1.
14145
0
        else {
14146
          if constexpr (result_type_is_ada_url) {
14147
            url.username = base_url->username;
14148
            url.password = base_url->password;
14149
            url.host = base_url->host;
14150
            url.port = base_url->port;
14151
0
          } else {
14152
0
            url.update_base_authority(base_url->get_href(),
14153
0
                                      base_url->get_components());
14154
0
            url.update_host_to_base_host(base_url->get_hostname());
14155
0
            url.update_base_port(base_url->retrieve_base_port());
14156
0
          }
14157
0
          state = state::PATH;
14158
0
          break;
14159
0
        }
14160
14161
0
        input_position++;
14162
0
        break;
14163
0
      }
14164
728k
      case state::SPECIAL_AUTHORITY_SLASHES: {
14165
728k
        ada_log("SPECIAL_AUTHORITY_SLASHES ",
14166
728k
                helpers::substring(url_data, input_position));
14167
14168
        // If c is U+002F (/) and remaining starts with U+002F (/),
14169
        // then set state to special authority ignore slashes state and increase
14170
        // pointer by 1.
14171
728k
        if (url_data.substr(input_position, 2) == "//") {
14172
728k
          input_position += 2;
14173
728k
        }
14174
14175
728k
        [[fallthrough]];
14176
728k
      }
14177
944k
      case state::SPECIAL_AUTHORITY_IGNORE_SLASHES: {
14178
944k
        ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ",
14179
944k
                helpers::substring(url_data, input_position));
14180
14181
        // If c is neither U+002F (/) nor U+005C (\), then set state to
14182
        // authority state and decrease pointer by 1.
14183
1.34M
        while ((input_position != input_size) &&
14184
957k
               ((url_data[input_position] == '/') ||
14185
559k
                (url_data[input_position] == '\\'))) {
14186
405k
          input_position++;
14187
405k
        }
14188
944k
        state = state::AUTHORITY;
14189
14190
944k
        break;
14191
728k
      }
14192
17.1k
      case state::QUERY: {
14193
17.1k
        ada_log("QUERY ", helpers::substring(url_data, input_position));
14194
17.1k
        if constexpr (store_values) {
14195
          // Let queryPercentEncodeSet be the special-query percent-encode set
14196
          // if url is special; otherwise the query percent-encode set.
14197
17.1k
          const uint8_t* query_percent_encode_set =
14198
17.1k
              url.is_special() ? character_sets::SPECIAL_QUERY_PERCENT_ENCODE
14199
17.1k
                               : character_sets::QUERY_PERCENT_ENCODE;
14200
14201
          // Percent-encode after encoding, with encoding, buffer, and
14202
          // queryPercentEncodeSet, and append the result to url's query.
14203
17.1k
          url.update_base_search(url_data.substr(input_position),
14204
17.1k
                                 query_percent_encode_set);
14205
17.1k
          ada_log("QUERY update_base_search completed ");
14206
17.1k
          if (fragment.has_value()) {
14207
2.88k
            url.update_unencoded_base_hash(*fragment);
14208
2.88k
          }
14209
17.1k
        }
14210
17.1k
        return url;
14211
728k
      }
14212
1.15M
      case state::HOST: {
14213
1.15M
        ada_log("HOST ", helpers::substring(url_data, input_position));
14214
14215
1.15M
        std::string_view host_view = url_data.substr(input_position);
14216
1.15M
        auto [location, found_colon] =
14217
1.15M
            helpers::get_host_delimiter_location(url.is_special(), host_view);
14218
1.15M
        input_position = (location != std::string_view::npos)
14219
1.15M
                             ? input_position + location
14220
1.15M
                             : input_size;
14221
        // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
14222
        // Note: the 'found_colon' value is true if and only if a colon was
14223
        // encountered while not inside brackets.
14224
1.15M
        if (found_colon) {
14225
          // If buffer is the empty string, validation error, return failure.
14226
          // Let host be the result of host parsing buffer with url is not
14227
          // special.
14228
24.5k
          ada_log("HOST parsing ", host_view);
14229
24.5k
          if (!url.parse_host(host_view)) {
14230
4.17k
            return url;
14231
4.17k
          }
14232
20.3k
          ada_log("HOST parsing results in ", url.get_hostname());
14233
          // Set url's host to host, buffer to the empty string, and state to
14234
          // port state.
14235
20.3k
          state = state::PORT;
14236
20.3k
          input_position++;
14237
20.3k
        }
14238
        // Otherwise, if one of the following is true:
14239
        // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
14240
        // - url is special and c is U+005C (\)
14241
        // The get_host_delimiter_location function either brings us to
14242
        // the colon outside of the bracket, or to one of those characters.
14243
1.13M
        else {
14244
          // If url is special and host_view is the empty string, validation
14245
          // error, return failure.
14246
1.13M
          if (host_view.empty() && url.is_special()) {
14247
394k
            url.is_valid = false;
14248
394k
            return url;
14249
394k
          }
14250
738k
          ada_log("HOST parsing ", host_view, " href=", url.get_href());
14251
          // Let host be the result of host parsing host_view with url is not
14252
          // special.
14253
738k
          if (host_view.empty()) {
14254
67
            url.update_base_hostname("");
14255
738k
          } else if (!url.parse_host(host_view)) {
14256
91.7k
            return url;
14257
91.7k
          }
14258
646k
          ada_log("HOST parsing results in ", url.get_hostname(),
14259
646k
                  " href=", url.get_href());
14260
14261
          // Set url's host to host, and state to path start state.
14262
646k
          state = state::PATH_START;
14263
646k
        }
14264
14265
666k
        break;
14266
1.15M
      }
14267
666k
      case state::OPAQUE_PATH: {
14268
838
        ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position));
14269
        // Opaque path, query, and fragment are structurally always valid:
14270
        // the parser would just percent-encode whatever is there. When we
14271
        // are not storing values (can_parse), we can return immediately.
14272
        // We must set has_opaque_path = true before returning so that when
14273
        // this URL is used as an internal base inside can_parse, NO_SCHEME
14274
        // correctly rejects relative inputs against an opaque-path base
14275
        // (e.g. can_parse("", &"W:") must return false).
14276
        if constexpr (!store_values) {
14277
          url.has_opaque_path = true;
14278
          return url;
14279
        }
14280
838
        std::string_view view = url_data.substr(input_position);
14281
        // If c is U+003F (?), then set url's query to the empty string and
14282
        // state to query state.
14283
838
        size_t location = view.find('?');
14284
838
        if (location != std::string_view::npos) {
14285
44
          view.remove_suffix(view.size() - location);
14286
44
          state = state::QUERY;
14287
44
          input_position += location + 1;
14288
794
        } else {
14289
794
          input_position = input_size + 1;
14290
794
        }
14291
838
        url.has_opaque_path = true;
14292
14293
        // This is a really unlikely scenario in real world. We should not seek
14294
        // to optimize it.
14295
838
        if (view.ends_with(' ')) {
14296
41
          std::string modified_view =
14297
41
              std::string(view.substr(0, view.size() - 1)) + "%20";
14298
41
          url.update_base_pathname(unicode::percent_encode(
14299
41
              modified_view, character_sets::C0_CONTROL_PERCENT_ENCODE));
14300
797
        } else {
14301
797
          url.update_base_pathname(unicode::percent_encode(
14302
797
              view, character_sets::C0_CONTROL_PERCENT_ENCODE));
14303
797
        }
14304
838
        break;
14305
1.15M
      }
14306
20.3k
      case state::PORT: {
14307
20.3k
        ada_log("PORT ", helpers::substring(url_data, input_position));
14308
20.3k
        std::string_view port_view = url_data.substr(input_position);
14309
20.3k
        input_position += url.parse_port(port_view, true);
14310
20.3k
        if (!url.is_valid) {
14311
3.37k
          return url;
14312
3.37k
        }
14313
16.9k
        state = state::PATH_START;
14314
16.9k
        [[fallthrough]];
14315
16.9k
      }
14316
663k
      case state::PATH_START: {
14317
663k
        ada_log("PATH_START ", helpers::substring(url_data, input_position));
14318
        // Path, query, and fragment are structurally always valid: the
14319
        // parser would just percent-encode whatever is there. When we are
14320
        // not storing values (can_parse), we can return immediately since
14321
        // no subsequent state can invalidate the URL.
14322
        if constexpr (!store_values) {
14323
          return url;
14324
        }
14325
14326
        // If url is special, then:
14327
663k
        if (url.is_special()) {
14328
          // Set state to path state.
14329
445k
          state = state::PATH;
14330
14331
          // Optimization: Avoiding going into PATH state improves the
14332
          // performance of urls ending with /.
14333
445k
          if (input_position == input_size) {
14334
298k
            if constexpr (store_values) {
14335
298k
              url.update_base_pathname("/");
14336
298k
              if (fragment.has_value()) {
14337
5.75k
                url.update_unencoded_base_hash(*fragment);
14338
5.75k
              }
14339
298k
            }
14340
298k
            return url;
14341
298k
          }
14342
          // If c is neither U+002F (/) nor U+005C (\), then decrease pointer
14343
          // by 1. We know that (input_position == input_size) is impossible
14344
          // here, because of the previous if-check.
14345
147k
          if ((url_data[input_position] != '/') &&
14346
11.6k
              (url_data[input_position] != '\\')) {
14347
9.14k
            break;
14348
9.14k
          }
14349
147k
        }
14350
        // Otherwise, if state override is not given and c is U+003F (?),
14351
        // set url's query to the empty string and state to query state.
14352
218k
        else if ((input_position != input_size) &&
14353
218k
                 (url_data[input_position] == '?')) {
14354
14
          state = state::QUERY;
14355
14
        }
14356
        // Otherwise, if c is not the EOF code point:
14357
218k
        else if (input_position != input_size) {
14358
          // Set state to path state.
14359
218k
          state = state::PATH;
14360
14361
          // If c is not U+002F (/), then decrease pointer by 1.
14362
218k
          if (url_data[input_position] != '/') {
14363
0
            break;
14364
0
          }
14365
218k
        }
14366
14367
356k
        input_position++;
14368
356k
        break;
14369
663k
      }
14370
385k
      case state::PATH: {
14371
385k
        ada_log("PATH ", helpers::substring(url_data, input_position));
14372
        // Path, query, and fragment are structurally always valid: the
14373
        // parser would just percent-encode whatever is there. When we are
14374
        // not storing values (can_parse), we can return immediately since
14375
        // no subsequent state can invalidate the URL.
14376
        if constexpr (!store_values) {
14377
          return url;
14378
        }
14379
385k
        std::string_view view = url_data.substr(input_position);
14380
14381
        // Most time, we do not need percent encoding.
14382
        // Furthermore, we can immediately locate the '?'.
14383
385k
        size_t locofquestionmark = view.find('?');
14384
385k
        if (locofquestionmark != std::string_view::npos) {
14385
17.0k
          state = state::QUERY;
14386
17.0k
          view.remove_suffix(view.size() - locofquestionmark);
14387
17.0k
          input_position += locofquestionmark + 1;
14388
368k
        } else {
14389
368k
          input_position = input_size + 1;
14390
368k
        }
14391
385k
        if constexpr (store_values) {
14392
          if constexpr (result_type_is_ada_url) {
14393
            helpers::parse_prepared_path(view, url.type, url.path);
14394
385k
          } else {
14395
385k
            url.consume_prepared_path(view);
14396
385k
            ADA_ASSERT_TRUE(url.validate());
14397
385k
          }
14398
385k
        }
14399
385k
        break;
14400
663k
      }
14401
0
      case state::FILE_SLASH: {
14402
0
        ada_log("FILE_SLASH ", helpers::substring(url_data, input_position));
14403
14404
        // If c is U+002F (/) or U+005C (\), then:
14405
0
        if ((input_position != input_size) &&
14406
0
            (url_data[input_position] == '/' ||
14407
0
             url_data[input_position] == '\\')) {
14408
0
          ada_log("FILE_SLASH c is U+002F or U+005C");
14409
          // Set state to file host state.
14410
0
          state = state::FILE_HOST;
14411
0
          input_position++;
14412
0
        } else {
14413
0
          ada_log("FILE_SLASH otherwise");
14414
          // If base is non-null and base's scheme is "file", then:
14415
          // Note: it is unsafe to do base_url->scheme unless you know that
14416
          // base_url_has_value() is true.
14417
0
          if (base_url != nullptr && base_url->type == scheme::type::FILE) {
14418
            // Set url's host to base's host.
14419
            if constexpr (result_type_is_ada_url) {
14420
              url.host = base_url->host;
14421
0
            } else {
14422
0
              url.update_host_to_base_host(base_url->get_host());
14423
0
            }
14424
            // If the code point substring from pointer to the end of input does
14425
            // not start with a Windows drive letter and base's path[0] is a
14426
            // normalized Windows drive letter, then append base's path[0] to
14427
            // url's path.
14428
0
            if (!base_url->get_pathname().empty()) {
14429
0
              if (!checkers::is_windows_drive_letter(
14430
0
                      url_data.substr(input_position))) {
14431
0
                std::string_view first_base_url_path =
14432
0
                    base_url->get_pathname().substr(1);
14433
0
                size_t loc = first_base_url_path.find('/');
14434
0
                if (loc != std::string_view::npos) {
14435
0
                  helpers::resize(first_base_url_path, loc);
14436
0
                }
14437
0
                if (checkers::is_normalized_windows_drive_letter(
14438
0
                        first_base_url_path)) {
14439
                  if constexpr (result_type_is_ada_url) {
14440
                    url.path += '/';
14441
                    url.path += first_base_url_path;
14442
0
                  } else {
14443
0
                    url.append_base_pathname(
14444
0
                        helpers::concat("/", first_base_url_path));
14445
0
                  }
14446
0
                }
14447
0
              }
14448
0
            }
14449
0
          }
14450
14451
          // Set state to path state, and decrease pointer by 1.
14452
0
          state = state::PATH;
14453
0
        }
14454
14455
0
        break;
14456
663k
      }
14457
0
      case state::FILE_HOST: {
14458
0
        ada_log("FILE_HOST ", helpers::substring(url_data, input_position));
14459
0
        std::string_view view = url_data.substr(input_position);
14460
14461
0
        size_t location = view.find_first_of("/\\?");
14462
0
        std::string_view file_host_buffer = view.substr(
14463
0
            0, (location != std::string_view::npos) ? location : view.size());
14464
14465
0
        if (checkers::is_windows_drive_letter(file_host_buffer)) {
14466
0
          state = state::PATH;
14467
0
        } else if (file_host_buffer.empty()) {
14468
          // Set url's host to the empty string.
14469
          if constexpr (result_type_is_ada_url) {
14470
            url.host = "";
14471
0
          } else {
14472
0
            url.update_base_hostname("");
14473
0
          }
14474
          // Set state to path start state.
14475
0
          state = state::PATH_START;
14476
0
        } else {
14477
0
          size_t consumed_bytes = file_host_buffer.size();
14478
0
          input_position += consumed_bytes;
14479
          // Let host be the result of host parsing buffer with url is not
14480
          // special.
14481
0
          if (!url.parse_host(file_host_buffer)) {
14482
0
            return url;
14483
0
          }
14484
14485
          if constexpr (result_type_is_ada_url) {
14486
            // If host is "localhost", then set host to the empty string.
14487
            if (url.host.has_value() && url.host.value() == "localhost") {
14488
              url.host = "";
14489
            }
14490
0
          } else {
14491
0
            if (url.get_hostname() == "localhost") {
14492
0
              url.update_base_hostname("");
14493
0
            }
14494
0
          }
14495
14496
          // Set buffer to the empty string and state to path start state.
14497
0
          state = state::PATH_START;
14498
0
        }
14499
14500
0
        break;
14501
0
      }
14502
0
      case state::FILE: {
14503
0
        ada_log("FILE ", helpers::substring(url_data, input_position));
14504
0
        std::string_view file_view = url_data.substr(input_position);
14505
14506
0
        url.set_protocol_as_file();
14507
        if constexpr (result_type_is_ada_url) {
14508
          // Set url's host to the empty string.
14509
          url.host = "";
14510
0
        } else {
14511
0
          url.update_base_hostname("");
14512
0
        }
14513
        // If c is U+002F (/) or U+005C (\), then:
14514
0
        if (input_position != input_size &&
14515
0
            (url_data[input_position] == '/' ||
14516
0
             url_data[input_position] == '\\')) {
14517
0
          ada_log("FILE c is U+002F or U+005C");
14518
          // Set state to file slash state.
14519
0
          state = state::FILE_SLASH;
14520
0
        }
14521
        // Otherwise, if base is non-null and base's scheme is "file":
14522
0
        else if (base_url != nullptr && base_url->type == scheme::type::FILE) {
14523
          // Set url's host to base's host, url's path to a clone of base's
14524
          // path, and url's query to base's query.
14525
0
          ada_log("FILE base non-null");
14526
          if constexpr (result_type_is_ada_url) {
14527
            url.host = base_url->host;
14528
            url.path = base_url->path;
14529
            url.query = base_url->query;
14530
0
          } else {
14531
0
            url.update_host_to_base_host(base_url->get_hostname());
14532
0
            url.update_base_pathname(base_url->get_pathname());
14533
0
            if (base_url->has_search()) {
14534
              // get_search() returns "" for an empty query string (URL ends
14535
              // with '?'). update_base_search("") would incorrectly clear the
14536
              // query, so pass "?" to preserve the empty query distinction.
14537
0
              auto s = base_url->get_search();
14538
0
              url.update_base_search(s.empty() ? std::string_view("?") : s);
14539
0
            }
14540
0
          }
14541
0
          url.has_opaque_path = base_url->has_opaque_path;
14542
14543
          // If c is U+003F (?), then set url's query to the empty string and
14544
          // state to query state.
14545
0
          if (input_position != input_size && url_data[input_position] == '?') {
14546
0
            state = state::QUERY;
14547
0
          }
14548
          // Otherwise, if c is not the EOF code point:
14549
0
          else if (input_position != input_size) {
14550
            // Set url's query to null.
14551
0
            url.clear_search();
14552
            // If the code point substring from pointer to the end of input does
14553
            // not start with a Windows drive letter, then shorten url's path.
14554
0
            if (!checkers::is_windows_drive_letter(file_view)) {
14555
              if constexpr (result_type_is_ada_url) {
14556
                helpers::shorten_path(url.path, url.type);
14557
0
              } else {
14558
0
                std::string_view path = url.get_pathname();
14559
0
                if (helpers::shorten_path(path, url.type)) {
14560
0
                  url.update_base_pathname(std::move(std::string(path)));
14561
0
                }
14562
0
              }
14563
0
            }
14564
            // Otherwise:
14565
0
            else {
14566
              // Set url's path to an empty list.
14567
0
              url.clear_pathname();
14568
0
              url.has_opaque_path = true;
14569
0
            }
14570
14571
            // Set state to path state and decrease pointer by 1.
14572
0
            state = state::PATH;
14573
0
            break;
14574
0
          }
14575
0
        }
14576
        // Otherwise, set state to path state, and decrease pointer by 1.
14577
0
        else {
14578
0
          ada_log("FILE go to path");
14579
0
          state = state::PATH;
14580
0
          break;
14581
0
        }
14582
14583
0
        input_position++;
14584
0
        break;
14585
0
      }
14586
0
      default:
14587
0
        unreachable();
14588
7.20M
    }
14589
7.20M
  }
14590
369k
  if constexpr (store_values) {
14591
369k
    if (fragment.has_value()) {
14592
4.54k
      url.update_unencoded_base_hash(*fragment);
14593
4.54k
    }
14594
369k
  }
14595
  // Check the resulting (normalized) URL size against the maximum input length.
14596
  // Normalization (percent-encoding, IDNA, etc.) can expand the URL beyond the
14597
  // original input size.
14598
369k
  if constexpr (store_values) {
14599
369k
    if (url.is_valid) {
14600
369k
      if constexpr (result_type_is_ada_url_aggregator) {
14601
369k
        if (url.buffer.size() > max_input_length) {
14602
0
          url.is_valid = false;
14603
0
        }
14604
      } else {
14605
        if (url.get_href_size() > max_input_length) {
14606
          url.is_valid = false;
14607
        }
14608
      }
14609
369k
    }
14610
369k
  }
14611
369k
  return url;
14612
1.20M
}
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*)
14613
14614
template url parse_url_impl<url, true>(std::string_view user_input,
14615
                                       const url* base_url = nullptr);
14616
template url_aggregator parse_url_impl<url_aggregator, true>(
14617
    std::string_view user_input, const url_aggregator* base_url = nullptr);
14618
template url_aggregator parse_url_impl<url_aggregator, false>(
14619
    std::string_view user_input, const url_aggregator* base_url = nullptr);
14620
14621
template <class result_type>
14622
result_type parse_url(std::string_view user_input,
14623
0
                      const result_type* base_url) {
14624
0
  return parse_url_impl<result_type, true>(user_input, base_url);
14625
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*)
14626
14627
template url parse_url<url>(std::string_view user_input,
14628
                            const url* base_url = nullptr);
14629
template url_aggregator parse_url<url_aggregator>(
14630
    std::string_view user_input, const url_aggregator* base_url = nullptr);
14631
}  // namespace ada::parser
14632
/* end file src/parser.cpp */
14633
/* begin file src/url_components.cpp */
14634
14635
#include <iterator>
14636
#include <string>
14637
14638
namespace ada {
14639
14640
0
[[nodiscard]] std::string url_components::to_string() const {
14641
0
  std::string answer;
14642
0
  auto back = std::back_insert_iterator(answer);
14643
0
  answer.append("{\n");
14644
14645
0
  answer.append("\t\"protocol_end\":\"");
14646
0
  helpers::encode_json(std::to_string(protocol_end), back);
14647
0
  answer.append("\",\n");
14648
14649
0
  answer.append("\t\"username_end\":\"");
14650
0
  helpers::encode_json(std::to_string(username_end), back);
14651
0
  answer.append("\",\n");
14652
14653
0
  answer.append("\t\"host_start\":\"");
14654
0
  helpers::encode_json(std::to_string(host_start), back);
14655
0
  answer.append("\",\n");
14656
14657
0
  answer.append("\t\"host_end\":\"");
14658
0
  helpers::encode_json(std::to_string(host_end), back);
14659
0
  answer.append("\",\n");
14660
14661
0
  answer.append("\t\"port\":\"");
14662
0
  helpers::encode_json(std::to_string(port), back);
14663
0
  answer.append("\",\n");
14664
14665
0
  answer.append("\t\"pathname_start\":\"");
14666
0
  helpers::encode_json(std::to_string(pathname_start), back);
14667
0
  answer.append("\",\n");
14668
14669
0
  answer.append("\t\"search_start\":\"");
14670
0
  helpers::encode_json(std::to_string(search_start), back);
14671
0
  answer.append("\",\n");
14672
14673
0
  answer.append("\t\"hash_start\":\"");
14674
0
  helpers::encode_json(std::to_string(hash_start), back);
14675
0
  answer.append("\",\n");
14676
14677
0
  answer.append("\n}");
14678
0
  return answer;
14679
0
}
14680
14681
}  // namespace ada
14682
/* end file src/url_components.cpp */
14683
/* begin file src/url_aggregator.cpp */
14684
14685
#include <iterator>
14686
#include <ranges>
14687
#include <string>
14688
#include <string_view>
14689
14690
namespace {
14691
14692
ada_really_inline void apply_shifted_non_scheme_offsets(
14693
1.18M
    ada::url_components& components, uint32_t new_difference) {
14694
1.18M
  components.username_end += new_difference;
14695
1.18M
  components.host_start += new_difference;
14696
1.18M
  components.host_end += new_difference;
14697
1.18M
  components.pathname_start += new_difference;
14698
1.18M
  if (components.search_start != ada::url_components::omitted) {
14699
0
    components.search_start += new_difference;
14700
0
  }
14701
1.18M
  if (components.hash_start != ada::url_components::omitted) {
14702
0
    components.hash_start += new_difference;
14703
0
  }
14704
1.18M
}
14705
14706
}  // namespace
14707
14708
namespace ada {
14709
template <bool has_state_override>
14710
[[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon(
14711
1.18M
    const std::string_view input_with_colon) {
14712
1.18M
  ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon);
14713
1.18M
  ADA_ASSERT_TRUE(validate());
14714
1.18M
  ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));
14715
1.18M
  std::string_view input{input_with_colon};
14716
1.18M
  input.remove_suffix(1);
14717
1.18M
  auto parsed_type = ada::scheme::get_scheme_type(input);
14718
1.18M
  const bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
14719
  /**
14720
   * In the common case, we will immediately recognize a special scheme (e.g.,
14721
   *http, https), in which case, we can go really fast.
14722
   **/
14723
1.18M
  if (is_input_special) {  // fast path!!!
14724
944k
    if constexpr (has_state_override) {
14725
      // If url's scheme is not a special scheme and buffer is a special scheme,
14726
      // then return.
14727
0
      if (is_special() != is_input_special) {
14728
0
        return false;
14729
0
      }
14730
14731
      // If url includes credentials or has a non-null port, and buffer is
14732
      // "file", then return.
14733
0
      if ((has_credentials() || components.port != url_components::omitted) &&
14734
0
          parsed_type == ada::scheme::type::FILE) {
14735
0
        return false;
14736
0
      }
14737
14738
      // If url's scheme is "file" and its host is an empty host, then return.
14739
      // An empty host is the empty string.
14740
0
      if (type == ada::scheme::type::FILE &&
14741
0
          components.host_start == components.host_end) {
14742
0
        return false;
14743
0
      }
14744
0
    }
14745
14746
0
    type = parsed_type;
14747
944k
    set_scheme_from_view_with_colon(input_with_colon);
14748
14749
944k
    if constexpr (has_state_override) {
14750
      // This is uncommon.
14751
0
      uint16_t urls_scheme_port = get_special_port();
14752
14753
      // If url's port is url's scheme's default port, then set url's port to
14754
      // null.
14755
0
      if (components.port == urls_scheme_port) {
14756
0
        clear_port();
14757
0
      }
14758
0
    }
14759
944k
  } else {  // slow path
14760
239k
    std::string _buffer(input);
14761
    // Next function is only valid if the input is ASCII and returns false
14762
    // otherwise, but it seems that we always have ascii content so we do not
14763
    // need to check the return value.
14764
239k
    unicode::to_lower_ascii(_buffer.data(), _buffer.size());
14765
14766
239k
    if constexpr (has_state_override) {
14767
      // The state-override validation errors below ("return" in the WHATWG URL
14768
      // parser) leave the URL unchanged. The setter contract is
14769
      // "true on success, false if the scheme is invalid" -- the fast path
14770
      // above already returns false here, so the slow path must agree.
14771
14772
      // If url's scheme is a special scheme and buffer is not a special scheme,
14773
      // then return. If url's scheme is not a special scheme and buffer is a
14774
      // special scheme, then return.
14775
0
      if (is_special() != ada::scheme::is_special(_buffer)) {
14776
0
        return false;
14777
0
      }
14778
14779
      // If url includes credentials or has a non-null port, and buffer is
14780
      // "file", then return.
14781
0
      if ((has_credentials() || components.port != url_components::omitted) &&
14782
0
          _buffer == "file") {
14783
0
        return false;
14784
0
      }
14785
14786
      // If url's scheme is "file" and its host is an empty host, then return.
14787
      // An empty host is the empty string.
14788
0
      if (type == ada::scheme::type::FILE &&
14789
0
          components.host_start == components.host_end) {
14790
0
        return false;
14791
0
      }
14792
0
    }
14793
14794
0
    set_scheme(_buffer);
14795
14796
239k
    if constexpr (has_state_override) {
14797
      // This is uncommon.
14798
0
      uint16_t urls_scheme_port = get_special_port();
14799
14800
      // If url's port is url's scheme's default port, then set url's port to
14801
      // null.
14802
0
      if (components.port == urls_scheme_port) {
14803
0
        clear_port();
14804
0
      }
14805
0
    }
14806
239k
  }
14807
0
  ADA_ASSERT_TRUE(validate());
14808
1.18M
  return true;
14809
1.18M
}
bool ada::url_aggregator::parse_scheme_with_colon<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Line
Count
Source
14711
1.18M
    const std::string_view input_with_colon) {
14712
1.18M
  ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon);
14713
1.18M
  ADA_ASSERT_TRUE(validate());
14714
1.18M
  ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));
14715
1.18M
  std::string_view input{input_with_colon};
14716
1.18M
  input.remove_suffix(1);
14717
1.18M
  auto parsed_type = ada::scheme::get_scheme_type(input);
14718
1.18M
  const bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
14719
  /**
14720
   * In the common case, we will immediately recognize a special scheme (e.g.,
14721
   *http, https), in which case, we can go really fast.
14722
   **/
14723
1.18M
  if (is_input_special) {  // fast path!!!
14724
    if constexpr (has_state_override) {
14725
      // If url's scheme is not a special scheme and buffer is a special scheme,
14726
      // then return.
14727
      if (is_special() != is_input_special) {
14728
        return false;
14729
      }
14730
14731
      // If url includes credentials or has a non-null port, and buffer is
14732
      // "file", then return.
14733
      if ((has_credentials() || components.port != url_components::omitted) &&
14734
          parsed_type == ada::scheme::type::FILE) {
14735
        return false;
14736
      }
14737
14738
      // If url's scheme is "file" and its host is an empty host, then return.
14739
      // An empty host is the empty string.
14740
      if (type == ada::scheme::type::FILE &&
14741
          components.host_start == components.host_end) {
14742
        return false;
14743
      }
14744
    }
14745
14746
944k
    type = parsed_type;
14747
944k
    set_scheme_from_view_with_colon(input_with_colon);
14748
14749
    if constexpr (has_state_override) {
14750
      // This is uncommon.
14751
      uint16_t urls_scheme_port = get_special_port();
14752
14753
      // If url's port is url's scheme's default port, then set url's port to
14754
      // null.
14755
      if (components.port == urls_scheme_port) {
14756
        clear_port();
14757
      }
14758
    }
14759
944k
  } else {  // slow path
14760
239k
    std::string _buffer(input);
14761
    // Next function is only valid if the input is ASCII and returns false
14762
    // otherwise, but it seems that we always have ascii content so we do not
14763
    // need to check the return value.
14764
239k
    unicode::to_lower_ascii(_buffer.data(), _buffer.size());
14765
14766
    if constexpr (has_state_override) {
14767
      // The state-override validation errors below ("return" in the WHATWG URL
14768
      // parser) leave the URL unchanged. The setter contract is
14769
      // "true on success, false if the scheme is invalid" -- the fast path
14770
      // above already returns false here, so the slow path must agree.
14771
14772
      // If url's scheme is a special scheme and buffer is not a special scheme,
14773
      // then return. If url's scheme is not a special scheme and buffer is a
14774
      // special scheme, then return.
14775
      if (is_special() != ada::scheme::is_special(_buffer)) {
14776
        return false;
14777
      }
14778
14779
      // If url includes credentials or has a non-null port, and buffer is
14780
      // "file", then return.
14781
      if ((has_credentials() || components.port != url_components::omitted) &&
14782
          _buffer == "file") {
14783
        return false;
14784
      }
14785
14786
      // If url's scheme is "file" and its host is an empty host, then return.
14787
      // An empty host is the empty string.
14788
      if (type == ada::scheme::type::FILE &&
14789
          components.host_start == components.host_end) {
14790
        return false;
14791
      }
14792
    }
14793
14794
239k
    set_scheme(_buffer);
14795
14796
    if constexpr (has_state_override) {
14797
      // This is uncommon.
14798
      uint16_t urls_scheme_port = get_special_port();
14799
14800
      // If url's port is url's scheme's default port, then set url's port to
14801
      // null.
14802
      if (components.port == urls_scheme_port) {
14803
        clear_port();
14804
      }
14805
    }
14806
239k
  }
14807
1.18M
  ADA_ASSERT_TRUE(validate());
14808
1.18M
  return true;
14809
1.18M
}
Unexecuted instantiation: bool ada::url_aggregator::parse_scheme_with_colon<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
14810
14811
0
inline void url_aggregator::copy_scheme(const url_aggregator& u) {
14812
0
  ada_log("url_aggregator::copy_scheme ", u.buffer);
14813
0
  ADA_ASSERT_TRUE(validate());
14814
  // next line could overflow but unsigned arithmetic has well-defined
14815
  // overflows.
14816
0
  uint32_t new_difference = u.components.protocol_end - components.protocol_end;
14817
14818
0
  type = u.type;
14819
0
  buffer.erase(0, components.protocol_end);
14820
0
  buffer.insert(0, u.get_protocol());
14821
0
  components.protocol_end = u.components.protocol_end;
14822
14823
  // No need to update the components
14824
0
  if (new_difference == 0) {
14825
0
    return;
14826
0
  }
14827
14828
0
  apply_shifted_non_scheme_offsets(components, new_difference);
14829
0
  ADA_ASSERT_TRUE(validate());
14830
0
}
14831
14832
inline void url_aggregator::set_scheme_from_view_with_colon(
14833
944k
    std::string_view new_scheme_with_colon) {
14834
944k
  ada_log("url_aggregator::set_scheme_from_view_with_colon ",
14835
944k
          new_scheme_with_colon);
14836
944k
  ADA_ASSERT_TRUE(validate());
14837
944k
  ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() &&
14838
944k
                  new_scheme_with_colon.back() == ':');
14839
  // next line could overflow but unsigned arithmetic has well-defined
14840
  // overflows.
14841
944k
  uint32_t new_difference =
14842
944k
      uint32_t(new_scheme_with_colon.size()) - components.protocol_end;
14843
14844
944k
  if (buffer.empty()) {
14845
944k
    buffer.append(new_scheme_with_colon);
14846
944k
  } else {
14847
0
    buffer.erase(0, components.protocol_end);
14848
0
    buffer.insert(0, new_scheme_with_colon);
14849
0
  }
14850
944k
  components.protocol_end += new_difference;
14851
14852
944k
  apply_shifted_non_scheme_offsets(components, new_difference);
14853
944k
  ADA_ASSERT_TRUE(validate());
14854
944k
}
14855
14856
239k
inline void url_aggregator::set_scheme(std::string_view new_scheme) {
14857
239k
  ada_log("url_aggregator::set_scheme ", new_scheme);
14858
239k
  ADA_ASSERT_TRUE(validate());
14859
239k
  ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':');
14860
  // next line could overflow but unsigned arithmetic has well-defined
14861
  // overflows.
14862
239k
  uint32_t new_difference =
14863
239k
      uint32_t(new_scheme.size()) - components.protocol_end + 1;
14864
14865
239k
  type = ada::scheme::get_scheme_type(new_scheme);
14866
239k
  if (buffer.empty()) {
14867
239k
    buffer.append(helpers::concat(new_scheme, ":"));
14868
239k
  } else {
14869
0
    buffer.erase(0, components.protocol_end);
14870
0
    buffer.insert(0, helpers::concat(new_scheme, ":"));
14871
0
  }
14872
239k
  components.protocol_end = uint32_t(new_scheme.size() + 1);
14873
14874
239k
  apply_shifted_non_scheme_offsets(components, new_difference);
14875
239k
  ADA_ASSERT_TRUE(validate());
14876
239k
}
14877
14878
0
bool url_aggregator::set_protocol(const std::string_view input) {
14879
0
  ada_log("url_aggregator::set_protocol ", input);
14880
0
  ADA_ASSERT_TRUE(validate());
14881
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14882
0
  std::string view(input);
14883
0
  helpers::remove_ascii_tab_or_newline(view);
14884
0
  if (view.empty()) {
14885
0
    return true;
14886
0
  }
14887
14888
  // Schemes should start with alpha values.
14889
0
  if (!checkers::is_alpha(view[0])) {
14890
0
    return false;
14891
0
  }
14892
14893
0
  view.append(":");
14894
14895
0
  std::string::iterator pointer =
14896
0
      std::ranges::find_if_not(view, unicode::is_alnum_plus);
14897
14898
0
  if (pointer != view.end() && *pointer == ':') {
14899
0
    url_aggregator saved_url(*this);
14900
0
    bool result = parse_scheme_with_colon<true>(
14901
0
        view.substr(0, pointer - view.begin() + 1));
14902
0
    if (result && buffer.size() > ada::get_max_input_length()) {
14903
0
      *this = std::move(saved_url);
14904
0
      return false;
14905
0
    }
14906
0
    return result;
14907
0
  }
14908
0
  return false;
14909
0
}
14910
14911
0
bool url_aggregator::set_username(const std::string_view input) {
14912
0
  ada_log("url_aggregator::set_username '", input, "' ");
14913
0
  ADA_ASSERT_TRUE(validate());
14914
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14915
0
  if (cannot_have_credentials_or_port()) {
14916
0
    return false;
14917
0
  }
14918
0
  url_aggregator saved_url(*this);
14919
0
  size_t idx = ada::unicode::percent_encode_index(
14920
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
14921
0
  if (idx == input.size()) {
14922
0
    update_base_username(input);
14923
0
  } else {
14924
    // We only create a temporary string if we have to!
14925
0
    update_base_username(ada::unicode::percent_encode(
14926
0
        input, character_sets::USERINFO_PERCENT_ENCODE, idx));
14927
0
  }
14928
0
  if (buffer.size() > ada::get_max_input_length()) {
14929
0
    *this = std::move(saved_url);
14930
0
    return false;
14931
0
  }
14932
0
  ADA_ASSERT_TRUE(validate());
14933
0
  return true;
14934
0
}
14935
14936
0
bool url_aggregator::set_password(const std::string_view input) {
14937
0
  ada_log("url_aggregator::set_password '", input, "'");
14938
0
  ADA_ASSERT_TRUE(validate());
14939
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14940
0
  if (cannot_have_credentials_or_port()) {
14941
0
    return false;
14942
0
  }
14943
0
  url_aggregator saved_url(*this);
14944
0
  size_t idx = ada::unicode::percent_encode_index(
14945
0
      input, character_sets::USERINFO_PERCENT_ENCODE);
14946
0
  if (idx == input.size()) {
14947
0
    update_base_password(input);
14948
0
  } else {
14949
    // We only create a temporary string if we have to!
14950
0
    update_base_password(ada::unicode::percent_encode(
14951
0
        input, character_sets::USERINFO_PERCENT_ENCODE, idx));
14952
0
  }
14953
0
  if (buffer.size() > ada::get_max_input_length()) {
14954
0
    *this = std::move(saved_url);
14955
0
    return false;
14956
0
  }
14957
0
  ADA_ASSERT_TRUE(validate());
14958
0
  return true;
14959
0
}
14960
14961
0
bool url_aggregator::set_port(const std::string_view input) {
14962
0
  ada_log("url_aggregator::set_port ", input);
14963
0
  ADA_ASSERT_TRUE(validate());
14964
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14965
0
  if (cannot_have_credentials_or_port()) {
14966
0
    return false;
14967
0
  }
14968
14969
0
  if (input.empty()) {
14970
0
    clear_port();
14971
0
    return true;
14972
0
  }
14973
14974
0
  std::string trimmed(input);
14975
0
  helpers::remove_ascii_tab_or_newline(trimmed);
14976
14977
0
  if (trimmed.empty()) {
14978
0
    return true;
14979
0
  }
14980
14981
  // Input should not start with a non-digit character.
14982
0
  if (!ada::unicode::is_ascii_digit(trimmed.front())) {
14983
0
    return false;
14984
0
  }
14985
14986
  // Find the first non-digit character to determine the length of digits
14987
0
  auto first_non_digit =
14988
0
      std::ranges::find_if_not(trimmed, ada::unicode::is_ascii_digit);
14989
0
  std::string_view digits_to_parse =
14990
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
14991
14992
  // Revert changes if parse_port fails.
14993
0
  url_aggregator saved_url(*this);
14994
0
  parse_port(digits_to_parse);
14995
0
  if (is_valid) {
14996
0
    if (buffer.size() > ada::get_max_input_length()) {
14997
0
      *this = std::move(saved_url);
14998
0
      return false;
14999
0
    }
15000
0
    return true;
15001
0
  }
15002
0
  *this = std::move(saved_url);
15003
0
  is_valid = true;
15004
0
  ADA_ASSERT_TRUE(validate());
15005
0
  return false;
15006
0
}
15007
15008
0
bool url_aggregator::set_pathname(const std::string_view input) {
15009
0
  ada_log("url_aggregator::set_pathname ", input);
15010
0
  ADA_ASSERT_TRUE(validate());
15011
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15012
0
  if (has_opaque_path) {
15013
0
    return false;
15014
0
  }
15015
0
  url_aggregator saved_url(*this);
15016
0
  clear_pathname();
15017
0
  parse_path(input);
15018
0
  if (get_pathname().starts_with("//") && !has_authority() && !has_dash_dot()) {
15019
0
    buffer.insert(components.pathname_start, "/.");
15020
0
    components.pathname_start += 2;
15021
0
    if (components.search_start != url_components::omitted) {
15022
0
      components.search_start += 2;
15023
0
    }
15024
0
    if (components.hash_start != url_components::omitted) {
15025
0
      components.hash_start += 2;
15026
0
    }
15027
0
  }
15028
0
  if (buffer.size() > ada::get_max_input_length()) {
15029
0
    *this = std::move(saved_url);
15030
0
    return false;
15031
0
  }
15032
0
  ADA_ASSERT_TRUE(validate());
15033
0
  return true;
15034
0
}
15035
15036
0
ada_really_inline void url_aggregator::parse_path(std::string_view input) {
15037
0
  ada_log("url_aggregator::parse_path ", input);
15038
0
  ADA_ASSERT_TRUE(validate());
15039
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15040
0
  std::string tmp_buffer;
15041
0
  std::string_view internal_input;
15042
0
  if (unicode::has_tabs_or_newline(input)) {
15043
0
    tmp_buffer = input;
15044
    // Optimization opportunity: Instead of copying and then pruning, we could
15045
    // just directly build the string from user_input.
15046
0
    helpers::remove_ascii_tab_or_newline(tmp_buffer);
15047
0
    internal_input = tmp_buffer;
15048
0
  } else {
15049
0
    internal_input = input;
15050
0
  }
15051
15052
  // If url is special, then:
15053
0
  if (is_special()) {
15054
0
    if (internal_input.empty()) {
15055
0
      update_base_pathname("/");
15056
0
    } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
15057
0
      consume_prepared_path(internal_input.substr(1));
15058
0
    } else {
15059
0
      consume_prepared_path(internal_input);
15060
0
    }
15061
0
  } else if (!internal_input.empty()) {
15062
0
    if (internal_input[0] == '/') {
15063
0
      consume_prepared_path(internal_input.substr(1));
15064
0
    } else {
15065
0
      consume_prepared_path(internal_input);
15066
0
    }
15067
0
  } else {
15068
    // Non-special URLs with an empty host can have their paths erased
15069
    // Path-only URLs cannot have their paths erased
15070
0
    if (components.host_start == components.host_end && !has_authority()) {
15071
0
      update_base_pathname("/");
15072
0
    }
15073
0
  }
15074
0
  ADA_ASSERT_TRUE(validate());
15075
0
}
15076
15077
0
void url_aggregator::set_search(const std::string_view input) {
15078
0
  ada_log("url_aggregator::set_search ", input);
15079
0
  ADA_ASSERT_TRUE(validate());
15080
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15081
0
  if (input.empty()) {
15082
0
    clear_search();
15083
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
15084
0
    return;
15085
0
  }
15086
15087
0
  std::string new_value;
15088
0
  new_value = input[0] == '?' ? input.substr(1) : input;
15089
0
  helpers::remove_ascii_tab_or_newline(new_value);
15090
15091
0
  auto query_percent_encode_set =
15092
0
      is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
15093
0
                   : ada::character_sets::QUERY_PERCENT_ENCODE;
15094
15095
0
  url_aggregator saved_url(*this);
15096
0
  update_base_search(new_value, query_percent_encode_set);
15097
0
  if (buffer.size() > ada::get_max_input_length()) {
15098
0
    *this = std::move(saved_url);
15099
0
    return;
15100
0
  }
15101
0
  ADA_ASSERT_TRUE(validate());
15102
0
}
15103
15104
0
void url_aggregator::set_hash(const std::string_view input) {
15105
0
  ada_log("url_aggregator::set_hash ", input);
15106
0
  ADA_ASSERT_TRUE(validate());
15107
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15108
0
  if (input.empty()) {
15109
0
    if (components.hash_start != url_components::omitted) {
15110
0
      buffer.resize(components.hash_start);
15111
0
      components.hash_start = url_components::omitted;
15112
0
    }
15113
0
    helpers::strip_trailing_spaces_from_opaque_path(*this);
15114
0
    return;
15115
0
  }
15116
15117
0
  std::string new_value;
15118
0
  new_value = input[0] == '#' ? input.substr(1) : input;
15119
0
  helpers::remove_ascii_tab_or_newline(new_value);
15120
0
  url_aggregator saved_url(*this);
15121
0
  update_unencoded_base_hash(new_value);
15122
0
  if (buffer.size() > ada::get_max_input_length()) {
15123
0
    *this = std::move(saved_url);
15124
0
    return;
15125
0
  }
15126
0
  ADA_ASSERT_TRUE(validate());
15127
0
}
15128
15129
0
bool url_aggregator::set_href(const std::string_view input) {
15130
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15131
0
  ada_log("url_aggregator::set_href ", input, " [", input.size(), " bytes]");
15132
0
  ada::result<url_aggregator> out = ada::parse<url_aggregator>(input);
15133
0
  ada_log("url_aggregator::set_href, success :", out.has_value());
15134
15135
0
  if (out) {
15136
    // The parser enforces get_max_input_length() on both the input and the
15137
    // normalized result. This is a defense-in-depth check.
15138
0
    if (out->buffer.size() > ada::get_max_input_length()) {
15139
0
      return false;
15140
0
    }
15141
0
    ada_log("url_aggregator::set_href, parsed ", out->to_string());
15142
    // TODO: Figure out why the following line puts test to never finish.
15143
0
    *this = *out;
15144
0
  }
15145
15146
0
  return out.has_value();
15147
0
}
15148
15149
765k
ada_really_inline bool url_aggregator::parse_host(std::string_view input) {
15150
765k
  ada_log("url_aggregator:parse_host \"", input, "\" [", input.size(),
15151
765k
          " bytes]");
15152
765k
  ADA_ASSERT_TRUE(validate());
15153
765k
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15154
765k
  if (input.empty()) {
15155
498
    return is_valid = false;
15156
498
  }  // technically unnecessary.
15157
  // If input starts with U+005B ([), then:
15158
765k
  if (input[0] == '[') {
15159
    // If input does not end with U+005D (]), validation error, return failure.
15160
11.6k
    if (input.back() != ']') {
15161
2.99k
      return is_valid = false;
15162
2.99k
    }
15163
8.67k
    ada_log("parse_host ipv6");
15164
15165
    // Return the result of IPv6 parsing input with its leading U+005B ([) and
15166
    // trailing U+005D (]) removed.
15167
8.67k
    input.remove_prefix(1);
15168
8.67k
    input.remove_suffix(1);
15169
8.67k
    return parse_ipv6(input);
15170
11.6k
  }
15171
15172
  // If isNotSpecial is true, then return the result of opaque-host parsing
15173
  // input.
15174
753k
  if (!is_special()) {
15175
218k
    return parse_opaque_host(input);
15176
218k
  }
15177
  // Let domain be the result of running UTF-8 decode without BOM on the
15178
  // percent-decoding of input. Let asciiDomain be the result of running domain
15179
  // to ASCII with domain and false. The most common case is an ASCII input, in
15180
  // which case we do not need to call the expensive 'to_ascii' if a few
15181
  // conditions are met: no '%' and no 'xn-' subsequence.
15182
15183
  // Often, the input does not contain any forbidden code points, and no upper
15184
  // case ASCII letter, then we can just copy it to the buffer. We want to
15185
  // optimize for such a common case.
15186
15187
  // Fast path: try to parse as pure decimal IPv4(a.b.c.d) first.
15188
535k
  const uint64_t fast_result = checkers::try_parse_ipv4_fast(input);
15189
535k
  if (fast_result < checkers::ipv4_fast_fail) {
15190
    // Fast path succeeded - input is pure decimal IPv4
15191
435
    if (!input.empty() && input.back() == '.') {
15192
188
      update_base_hostname(input.substr(0, input.size() - 1));
15193
247
    } else {
15194
247
      update_base_hostname(input);
15195
247
    }
15196
435
    host_type = IPV4;
15197
435
    is_valid = true;
15198
435
    ada_log("parse_host fast path decimal ipv4");
15199
435
    ADA_ASSERT_TRUE(validate());
15200
435
    return true;
15201
435
  }
15202
534k
  uint8_t is_forbidden_or_upper =
15203
534k
      unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
15204
534k
                                                             input.size());
15205
  // Minor optimization opportunity:
15206
  // contains_forbidden_domain_code_point_or_upper could be extend to check for
15207
  // the presence of characters that cannot appear in the ipv4 address and we
15208
  // could also check whether x and n and - are present, and so we could skip
15209
  // some of the checks below. However, the gains are likely to be small, and
15210
  // the code would be more complex.
15211
534k
  if (is_forbidden_or_upper == 0 &&
15212
413k
      input.find("xn-") == std::string_view::npos) {
15213
    // fast path
15214
399k
    update_base_hostname(input);
15215
15216
    // Check for other IPv4 formats (hex, octal, etc.)
15217
399k
    if (checkers::is_ipv4(get_hostname())) {
15218
38.9k
      ada_log("parse_host fast path ipv4");
15219
38.9k
      return parse_ipv4(get_hostname(), true);
15220
38.9k
    }
15221
360k
    ada_log("parse_host fast path ", get_hostname());
15222
360k
    is_valid = true;
15223
360k
    return true;
15224
399k
  }
15225
  // We have encountered at least one forbidden code point or the input contains
15226
  // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full
15227
  // conversion.
15228
15229
135k
  ada_log("parse_host calling to_ascii");
15230
135k
  std::optional<std::string> host = std::string(get_hostname());
15231
135k
  is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
15232
135k
  if (!is_valid) {
15233
76.6k
    ada_log("parse_host to_ascii returns false");
15234
76.6k
    return is_valid = false;
15235
76.6k
  }
15236
58.6k
  ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
15237
58.6k
          " bytes]");
15238
15239
58.6k
  if (std::ranges::any_of(host.value(),
15240
58.6k
                          ada::unicode::is_forbidden_domain_code_point)) {
15241
0
    return is_valid = false;
15242
0
  }
15243
15244
  // If asciiDomain ends in a number, then return the result of IPv4 parsing
15245
  // asciiDomain.
15246
58.6k
  if (checkers::is_ipv4(host.value())) {
15247
6.35k
    ada_log("parse_host got ipv4 ", *host);
15248
6.35k
    return parse_ipv4(host.value(), false);
15249
6.35k
  }
15250
15251
52.2k
  update_base_hostname(host.value());
15252
52.2k
  ADA_ASSERT_TRUE(validate());
15253
52.2k
  return true;
15254
58.6k
}
15255
15256
template <bool override_hostname>
15257
3.12k
bool url_aggregator::set_host_or_hostname(const std::string_view input) {
15258
3.12k
  ada_log("url_aggregator::set_host_or_hostname ", input);
15259
3.12k
  ADA_ASSERT_TRUE(validate());
15260
3.12k
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15261
3.12k
  if (has_opaque_path) {
15262
0
    return false;
15263
0
  }
15264
15265
3.12k
  url_aggregator saved_url(*this);
15266
15267
3.12k
  std::string previous_host(get_hostname());
15268
3.12k
  uint32_t previous_port = components.port;
15269
15270
3.12k
  size_t host_end_pos = input.find('#');
15271
3.12k
  std::string _host(input.data(), host_end_pos != std::string_view::npos
15272
3.12k
                                      ? host_end_pos
15273
3.12k
                                      : input.size());
15274
3.12k
  helpers::remove_ascii_tab_or_newline(_host);
15275
3.12k
  std::string_view new_host(_host);
15276
15277
3.12k
  auto check_url_size = [&]() -> bool {
15278
1.96k
    if (buffer.size() > ada::get_max_input_length()) {
15279
0
      *this = std::move(saved_url);
15280
0
      return false;
15281
0
    }
15282
1.96k
    return true;
15283
1.96k
  };
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
ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)::{lambda()#1}::operator()() const
Line
Count
Source
15277
1.96k
  auto check_url_size = [&]() -> bool {
15278
1.96k
    if (buffer.size() > ada::get_max_input_length()) {
15279
0
      *this = std::move(saved_url);
15280
0
      return false;
15281
0
    }
15282
1.96k
    return true;
15283
1.96k
  };
15284
15285
  // If url's scheme is "file", then set state to file host state, instead of
15286
  // host state.
15287
3.12k
  if (type != ada::scheme::type::FILE) {
15288
3.12k
    std::string_view host_view(_host.data(), _host.length());
15289
3.12k
    auto [location, found_colon] =
15290
3.12k
        helpers::get_host_delimiter_location(is_special(), host_view);
15291
15292
    // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
15293
    // Note: the 'found_colon' value is true if and only if a colon was
15294
    // encountered while not inside brackets.
15295
3.12k
    if (found_colon) {
15296
      // If buffer is the empty string, host-missing validation error, return
15297
      // failure.
15298
11
      std::string_view host_buffer = host_view.substr(0, location);
15299
11
      if (host_buffer.empty()) {
15300
10
        return false;
15301
10
      }
15302
15303
      // If state override is given and state override is hostname state, then
15304
      // return failure.
15305
1
      if constexpr (override_hostname) {
15306
1
        return false;
15307
1
      }
15308
15309
      // Let host be the result of host parsing buffer with url is not special.
15310
0
      bool succeeded = parse_host(host_buffer);
15311
1
      if (!succeeded) {
15312
0
        update_base_hostname(previous_host);
15313
0
        update_base_port(previous_port);
15314
0
        return false;
15315
0
      }
15316
15317
      // Set url's host to host, buffer to the empty string, and state to port
15318
      // state.
15319
1
      std::string_view port_buffer = new_host.substr(location + 1);
15320
1
      if (!port_buffer.empty()) {
15321
0
        set_port(port_buffer);
15322
0
      }
15323
1
      return check_url_size();
15324
1
    }
15325
    // Otherwise, if one of the following is true:
15326
    // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
15327
    // - url is special and c is U+005C (\)
15328
3.11k
    else {
15329
      // If url is special and host_view is the empty string, host-missing
15330
      // validation error, return failure.
15331
3.11k
      if (host_view.empty() && is_special()) {
15332
76
        return false;
15333
76
      }
15334
15335
      // Otherwise, if state override is given, host_view is the empty string,
15336
      // and either url includes credentials or url's port is non-null, then
15337
      // return failure.
15338
3.03k
      if (host_view.empty() && (has_credentials() || has_port())) {
15339
0
        return false;
15340
0
      }
15341
15342
      // Let host be the result of host parsing host_view with url is not
15343
      // special.
15344
3.03k
      if (host_view.empty() && !is_special()) {
15345
0
        if (has_hostname()) {
15346
0
          clear_hostname();  // easy!
15347
0
        } else if (has_dash_dot()) {
15348
0
          add_authority_slashes_if_needed();
15349
0
          delete_dash_dot();
15350
0
        }
15351
0
        return check_url_size();
15352
0
      }
15353
15354
3.03k
      bool succeeded = parse_host(host_view);
15355
3.03k
      if (!succeeded) {
15356
1.07k
        update_base_hostname(previous_host);
15357
1.07k
        update_base_port(previous_port);
15358
1.07k
        return false;
15359
1.96k
      } else if (has_dash_dot()) {
15360
        // Should remove dash_dot from pathname
15361
0
        delete_dash_dot();
15362
0
      }
15363
1.96k
      return check_url_size();
15364
3.03k
    }
15365
3.12k
  }
15366
15367
0
  size_t location = new_host.find_first_of("/\\?");
15368
0
  if (location != std::string_view::npos) {
15369
0
    new_host.remove_suffix(new_host.length() - location);
15370
0
  }
15371
15372
0
  if (new_host.empty()) {
15373
    // Set url's host to the empty string.
15374
0
    clear_hostname();
15375
0
  } else {
15376
    // Let host be the result of host parsing buffer with url is not special.
15377
0
    if (!parse_host(new_host)) {
15378
0
      update_base_hostname(previous_host);
15379
0
      update_base_port(previous_port);
15380
0
      return false;
15381
0
    }
15382
15383
    // If host is "localhost", then set host to the empty string.
15384
0
    if (helpers::substring(buffer, components.host_start,
15385
0
                           components.host_end) == "localhost") {
15386
0
      clear_hostname();
15387
0
    }
15388
0
  }
15389
0
  ADA_ASSERT_TRUE(validate());
15390
0
  return check_url_size();
15391
0
}
Unexecuted instantiation: bool ada::url_aggregator::set_host_or_hostname<false>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
bool ada::url_aggregator::set_host_or_hostname<true>(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Line
Count
Source
15257
3.12k
bool url_aggregator::set_host_or_hostname(const std::string_view input) {
15258
3.12k
  ada_log("url_aggregator::set_host_or_hostname ", input);
15259
3.12k
  ADA_ASSERT_TRUE(validate());
15260
3.12k
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15261
3.12k
  if (has_opaque_path) {
15262
0
    return false;
15263
0
  }
15264
15265
3.12k
  url_aggregator saved_url(*this);
15266
15267
3.12k
  std::string previous_host(get_hostname());
15268
3.12k
  uint32_t previous_port = components.port;
15269
15270
3.12k
  size_t host_end_pos = input.find('#');
15271
3.12k
  std::string _host(input.data(), host_end_pos != std::string_view::npos
15272
3.12k
                                      ? host_end_pos
15273
3.12k
                                      : input.size());
15274
3.12k
  helpers::remove_ascii_tab_or_newline(_host);
15275
3.12k
  std::string_view new_host(_host);
15276
15277
3.12k
  auto check_url_size = [&]() -> bool {
15278
3.12k
    if (buffer.size() > ada::get_max_input_length()) {
15279
3.12k
      *this = std::move(saved_url);
15280
3.12k
      return false;
15281
3.12k
    }
15282
3.12k
    return true;
15283
3.12k
  };
15284
15285
  // If url's scheme is "file", then set state to file host state, instead of
15286
  // host state.
15287
3.12k
  if (type != ada::scheme::type::FILE) {
15288
3.12k
    std::string_view host_view(_host.data(), _host.length());
15289
3.12k
    auto [location, found_colon] =
15290
3.12k
        helpers::get_host_delimiter_location(is_special(), host_view);
15291
15292
    // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
15293
    // Note: the 'found_colon' value is true if and only if a colon was
15294
    // encountered while not inside brackets.
15295
3.12k
    if (found_colon) {
15296
      // If buffer is the empty string, host-missing validation error, return
15297
      // failure.
15298
11
      std::string_view host_buffer = host_view.substr(0, location);
15299
11
      if (host_buffer.empty()) {
15300
10
        return false;
15301
10
      }
15302
15303
      // If state override is given and state override is hostname state, then
15304
      // return failure.
15305
1
      if constexpr (override_hostname) {
15306
1
        return false;
15307
1
      }
15308
15309
      // Let host be the result of host parsing buffer with url is not special.
15310
0
      bool succeeded = parse_host(host_buffer);
15311
1
      if (!succeeded) {
15312
0
        update_base_hostname(previous_host);
15313
0
        update_base_port(previous_port);
15314
0
        return false;
15315
0
      }
15316
15317
      // Set url's host to host, buffer to the empty string, and state to port
15318
      // state.
15319
1
      std::string_view port_buffer = new_host.substr(location + 1);
15320
1
      if (!port_buffer.empty()) {
15321
0
        set_port(port_buffer);
15322
0
      }
15323
1
      return check_url_size();
15324
1
    }
15325
    // Otherwise, if one of the following is true:
15326
    // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
15327
    // - url is special and c is U+005C (\)
15328
3.11k
    else {
15329
      // If url is special and host_view is the empty string, host-missing
15330
      // validation error, return failure.
15331
3.11k
      if (host_view.empty() && is_special()) {
15332
76
        return false;
15333
76
      }
15334
15335
      // Otherwise, if state override is given, host_view is the empty string,
15336
      // and either url includes credentials or url's port is non-null, then
15337
      // return failure.
15338
3.03k
      if (host_view.empty() && (has_credentials() || has_port())) {
15339
0
        return false;
15340
0
      }
15341
15342
      // Let host be the result of host parsing host_view with url is not
15343
      // special.
15344
3.03k
      if (host_view.empty() && !is_special()) {
15345
0
        if (has_hostname()) {
15346
0
          clear_hostname();  // easy!
15347
0
        } else if (has_dash_dot()) {
15348
0
          add_authority_slashes_if_needed();
15349
0
          delete_dash_dot();
15350
0
        }
15351
0
        return check_url_size();
15352
0
      }
15353
15354
3.03k
      bool succeeded = parse_host(host_view);
15355
3.03k
      if (!succeeded) {
15356
1.07k
        update_base_hostname(previous_host);
15357
1.07k
        update_base_port(previous_port);
15358
1.07k
        return false;
15359
1.96k
      } else if (has_dash_dot()) {
15360
        // Should remove dash_dot from pathname
15361
0
        delete_dash_dot();
15362
0
      }
15363
1.96k
      return check_url_size();
15364
3.03k
    }
15365
3.12k
  }
15366
15367
0
  size_t location = new_host.find_first_of("/\\?");
15368
0
  if (location != std::string_view::npos) {
15369
0
    new_host.remove_suffix(new_host.length() - location);
15370
0
  }
15371
15372
0
  if (new_host.empty()) {
15373
    // Set url's host to the empty string.
15374
0
    clear_hostname();
15375
0
  } else {
15376
    // Let host be the result of host parsing buffer with url is not special.
15377
0
    if (!parse_host(new_host)) {
15378
0
      update_base_hostname(previous_host);
15379
0
      update_base_port(previous_port);
15380
0
      return false;
15381
0
    }
15382
15383
    // If host is "localhost", then set host to the empty string.
15384
0
    if (helpers::substring(buffer, components.host_start,
15385
0
                           components.host_end) == "localhost") {
15386
0
      clear_hostname();
15387
0
    }
15388
0
  }
15389
0
  ADA_ASSERT_TRUE(validate());
15390
0
  return check_url_size();
15391
0
}
15392
15393
0
bool url_aggregator::set_host(const std::string_view input) {
15394
0
  ada_log("url_aggregator::set_host '", input, "'");
15395
0
  ADA_ASSERT_TRUE(validate());
15396
0
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15397
0
  return set_host_or_hostname<false>(input);
15398
0
}
15399
15400
3.12k
bool url_aggregator::set_hostname(const std::string_view input) {
15401
3.12k
  ada_log("url_aggregator::set_hostname '", input, "'");
15402
3.12k
  ADA_ASSERT_TRUE(validate());
15403
3.12k
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15404
3.12k
  return set_host_or_hostname<true>(input);
15405
3.12k
}
15406
15407
0
[[nodiscard]] std::string url_aggregator::get_origin() const {
15408
0
  ada_log("url_aggregator::get_origin");
15409
0
  if (is_special()) {
15410
    // Return a new opaque origin.
15411
0
    if (type == scheme::FILE) {
15412
0
      return "null";
15413
0
    }
15414
15415
0
    return helpers::concat(get_protocol(), "//", get_host());
15416
0
  }
15417
15418
0
  if (get_protocol() == "blob:") {
15419
0
    std::string_view path = get_pathname();
15420
0
    if (!path.empty()) {
15421
0
      auto out = ada::parse<ada::url_aggregator>(path);
15422
0
      if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) {
15423
        // If pathURL's scheme is not "http" and not "https", then return a
15424
        // new opaque origin.
15425
0
        return helpers::concat(out->get_protocol(), "//", out->get_host());
15426
0
      }
15427
0
    }
15428
0
  }
15429
15430
  // Return a new opaque origin.
15431
0
  return "null";
15432
0
}
15433
15434
[[nodiscard]] std::string_view url_aggregator::get_username() const
15435
174k
    ada_lifetime_bound {
15436
174k
  ada_log("url_aggregator::get_username");
15437
174k
  if (has_non_empty_username()) {
15438
15.4k
    return helpers::substring(buffer, components.protocol_end + 2,
15439
15.4k
                              components.username_end);
15440
15.4k
  }
15441
159k
  return "";
15442
174k
}
15443
15444
[[nodiscard]] std::string_view url_aggregator::get_password() const
15445
174k
    ada_lifetime_bound {
15446
174k
  ada_log("url_aggregator::get_password");
15447
174k
  if (has_non_empty_password()) {
15448
6.96k
    return helpers::substring(buffer, components.username_end + 1,
15449
6.96k
                              components.host_start);
15450
6.96k
  }
15451
167k
  return "";
15452
174k
}
15453
15454
[[nodiscard]] std::string_view url_aggregator::get_port() const
15455
200k
    ada_lifetime_bound {
15456
200k
  ada_log("url_aggregator::get_port");
15457
200k
  if (components.port == url_components::omitted) {
15458
192k
    return "";
15459
192k
  }
15460
7.62k
  return helpers::substring(buffer, components.host_end + 1,
15461
7.62k
                            components.pathname_start);
15462
200k
}
15463
15464
[[nodiscard]] std::string_view url_aggregator::get_hash() const
15465
95.7k
    ada_lifetime_bound {
15466
95.7k
  ada_log("url_aggregator::get_hash");
15467
  // If this's URL's fragment is either null or the empty string, then return
15468
  // the empty string. Return U+0023 (#), followed by this's URL's fragment.
15469
95.7k
  if (components.hash_start == url_components::omitted) {
15470
82.7k
    return "";
15471
82.7k
  }
15472
12.9k
  if (buffer.size() - components.hash_start <= 1) {
15473
942
    return "";
15474
942
  }
15475
12.0k
  return helpers::substring(buffer, components.hash_start);
15476
12.9k
}
15477
15478
[[nodiscard]] std::string_view url_aggregator::get_host() const
15479
0
    ada_lifetime_bound {
15480
0
  ada_log("url_aggregator::get_host");
15481
  // Technically, we should check if there is a hostname, but
15482
  // the code below works even if there isn't.
15483
  // if(!has_hostname()) { return ""; }
15484
0
  size_t start = components.host_start;
15485
0
  if (components.host_end > components.host_start &&
15486
0
      buffer[components.host_start] == '@') {
15487
0
    start++;
15488
0
  }
15489
  // if we have an empty host, then the space between components.host_end and
15490
  // components.pathname_start may be occupied by /.
15491
0
  if (start == components.host_end) {
15492
0
    return {};
15493
0
  }
15494
0
  return helpers::substring(buffer, start, components.pathname_start);
15495
0
}
15496
15497
[[nodiscard]] std::string_view url_aggregator::get_hostname() const
15498
779k
    ada_lifetime_bound {
15499
779k
  ada_log("url_aggregator::get_hostname");
15500
  // Technically, we should check if there is a hostname, but
15501
  // the code below works even if there isn't.
15502
  // if(!has_hostname()) { return ""; }
15503
779k
  size_t start = components.host_start;
15504
  // So host_start is not where the host begins.
15505
779k
  if (components.host_end > components.host_start &&
15506
649k
      buffer[components.host_start] == '@') {
15507
45.3k
    start++;
15508
45.3k
  }
15509
779k
  return helpers::substring(buffer, start, components.host_end);
15510
779k
}
15511
15512
[[nodiscard]] std::string_view url_aggregator::get_search() const
15513
98.7k
    ada_lifetime_bound {
15514
98.7k
  ada_log("url_aggregator::get_search");
15515
  // If this's URL's query is either null or the empty string, then return the
15516
  // empty string. Return U+003F (?), followed by this's URL's query.
15517
98.7k
  if (components.search_start == url_components::omitted) {
15518
81.3k
    return "";
15519
81.3k
  }
15520
17.4k
  auto ending_index = uint32_t(buffer.size());
15521
17.4k
  if (components.hash_start != url_components::omitted) {
15522
3.03k
    ending_index = components.hash_start;
15523
3.03k
  }
15524
17.4k
  if (ending_index - components.search_start <= 1) {
15525
708
    return "";
15526
708
  }
15527
16.6k
  return helpers::substring(buffer, components.search_start, ending_index);
15528
17.4k
}
15529
15530
[[nodiscard]] std::string_view url_aggregator::get_protocol() const
15531
287k
    ada_lifetime_bound {
15532
287k
  ada_log("url_aggregator::get_protocol");
15533
287k
  return helpers::substring(buffer, 0, components.protocol_end);
15534
287k
}
15535
15536
0
[[nodiscard]] std::string ada::url_aggregator::to_string() const {
15537
0
  ada_log("url_aggregator::to_string buffer:", buffer, " [", buffer.size(),
15538
0
          " bytes]");
15539
0
  if (!is_valid) {
15540
0
    return "null";
15541
0
  }
15542
15543
0
  std::string answer;
15544
0
  auto back = std::back_insert_iterator(answer);
15545
0
  answer.append("{\n");
15546
15547
0
  answer.append("\t\"buffer\":\"");
15548
0
  helpers::encode_json(buffer, back);
15549
0
  answer.append("\",\n");
15550
15551
0
  answer.append("\t\"protocol\":\"");
15552
0
  helpers::encode_json(get_protocol(), back);
15553
0
  answer.append("\",\n");
15554
15555
0
  if (has_credentials()) {
15556
0
    answer.append("\t\"username\":\"");
15557
0
    helpers::encode_json(get_username(), back);
15558
0
    answer.append("\",\n");
15559
0
    answer.append("\t\"password\":\"");
15560
0
    helpers::encode_json(get_password(), back);
15561
0
    answer.append("\",\n");
15562
0
  }
15563
15564
0
  answer.append("\t\"host\":\"");
15565
0
  helpers::encode_json(get_host(), back);
15566
0
  answer.append("\",\n");
15567
15568
0
  answer.append("\t\"path\":\"");
15569
0
  helpers::encode_json(get_pathname(), back);
15570
0
  answer.append("\",\n");
15571
0
  answer.append("\t\"opaque path\":");
15572
0
  answer.append((has_opaque_path ? "true" : "false"));
15573
0
  answer.append(",\n");
15574
15575
0
  if (components.search_start != url_components::omitted) {
15576
0
    answer.append("\t\"query\":\"");
15577
0
    helpers::encode_json(get_search(), back);
15578
0
    answer.append("\",\n");
15579
0
  }
15580
0
  if (components.hash_start != url_components::omitted) {
15581
0
    answer.append("\t\"fragment\":\"");
15582
0
    helpers::encode_json(get_hash(), back);
15583
0
    answer.append("\",\n");
15584
0
  }
15585
15586
0
  auto convert_offset_to_string = [](uint32_t offset) -> std::string {
15587
0
    if (offset == url_components::omitted) {
15588
0
      return "null";
15589
0
    } else {
15590
0
      return std::to_string(offset);
15591
0
    }
15592
0
  };
15593
15594
0
  answer.append("\t\"protocol_end\":");
15595
0
  answer.append(convert_offset_to_string(components.protocol_end));
15596
0
  answer.append(",\n");
15597
15598
0
  answer.append("\t\"username_end\":");
15599
0
  answer.append(convert_offset_to_string(components.username_end));
15600
0
  answer.append(",\n");
15601
15602
0
  answer.append("\t\"host_start\":");
15603
0
  answer.append(convert_offset_to_string(components.host_start));
15604
0
  answer.append(",\n");
15605
15606
0
  answer.append("\t\"host_end\":");
15607
0
  answer.append(convert_offset_to_string(components.host_end));
15608
0
  answer.append(",\n");
15609
15610
0
  answer.append("\t\"port\":");
15611
0
  answer.append(convert_offset_to_string(components.port));
15612
0
  answer.append(",\n");
15613
15614
0
  answer.append("\t\"pathname_start\":");
15615
0
  answer.append(convert_offset_to_string(components.pathname_start));
15616
0
  answer.append(",\n");
15617
15618
0
  answer.append("\t\"search_start\":");
15619
0
  answer.append(convert_offset_to_string(components.search_start));
15620
0
  answer.append(",\n");
15621
15622
0
  answer.append("\t\"hash_start\":");
15623
0
  answer.append(convert_offset_to_string(components.hash_start));
15624
0
  answer.append("\n}");
15625
15626
0
  return answer;
15627
0
}
15628
15629
0
[[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept {
15630
0
  if (components.host_start == components.host_end) {
15631
0
    return false;
15632
0
  }
15633
  // Avoid allocation: construct a string_view directly into the buffer.
15634
0
  size_t start = components.host_start;
15635
0
  if (components.host_end > components.host_start &&
15636
0
      buffer[components.host_start] == '@') {
15637
0
    start++;
15638
0
  }
15639
0
  return checkers::verify_dns_length(
15640
0
      std::string_view(buffer.data() + start, components.host_end - start));
15641
0
}
15642
15643
45.3k
bool url_aggregator::parse_ipv4(std::string_view input, bool in_place) {
15644
45.3k
  ada_log("parse_ipv4 ", input, " [", input.size(),
15645
45.3k
          " bytes], overlaps with buffer: ",
15646
45.3k
          helpers::overlaps(input, buffer) ? "yes" : "no");
15647
45.3k
  ADA_ASSERT_TRUE(validate());
15648
45.3k
  const bool trailing_dot = (input.back() == '.');
15649
45.3k
  if (trailing_dot) {
15650
886
    input.remove_suffix(1);
15651
886
  }
15652
45.3k
  size_t digit_count{0};
15653
45.3k
  int pure_decimal_count = 0;  // entries that are decimal
15654
45.3k
  uint64_t ipv4{0};
15655
  // we could unroll for better performance?
15656
53.9k
  for (; (digit_count < 4) && !(input.empty()); digit_count++) {
15657
53.7k
    uint32_t
15658
53.7k
        segment_result{};  // If any number exceeds 32 bits, we have an error.
15659
53.7k
    bool is_hex = checkers::has_hex_prefix(input);
15660
53.7k
    if (is_hex && ((input.length() == 2) ||
15661
12.0k
                   ((input.length() > 2) && (input[2] == '.')))) {
15662
      // special case
15663
706
      segment_result = 0;
15664
706
      input.remove_prefix(2);
15665
53.0k
    } else {
15666
53.0k
      std::from_chars_result r{};
15667
53.0k
      if (is_hex) {
15668
11.7k
        ada_log("parse_ipv4 trying to parse hex number");
15669
11.7k
        r = std::from_chars(input.data() + 2, input.data() + input.size(),
15670
11.7k
                            segment_result, 16);
15671
41.3k
      } else if ((input.length() >= 2) && input[0] == '0' &&
15672
10.5k
                 checkers::is_digit(input[1])) {
15673
7.83k
        ada_log("parse_ipv4 trying to parse octal number");
15674
7.83k
        r = std::from_chars(input.data() + 1, input.data() + input.size(),
15675
7.83k
                            segment_result, 8);
15676
33.4k
      } else {
15677
33.4k
        ada_log("parse_ipv4 trying to parse decimal number");
15678
33.4k
        pure_decimal_count++;
15679
33.4k
        r = std::from_chars(input.data(), input.data() + input.size(),
15680
33.4k
                            segment_result, 10);
15681
33.4k
      }
15682
53.0k
      if (r.ec != std::errc()) {
15683
6.99k
        ada_log("parse_ipv4 parsing failed");
15684
6.99k
        return is_valid = false;
15685
6.99k
      }
15686
46.0k
      ada_log("parse_ipv4 parsed ", segment_result);
15687
46.0k
      input.remove_prefix(r.ptr - input.data());
15688
46.0k
    }
15689
46.7k
    if (input.empty()) {
15690
      // We have the last value.
15691
      // At this stage, ipv4 contains digit_count*8 bits.
15692
      // So we have 32-digit_count*8 bits left.
15693
35.2k
      if (segment_result >= (uint64_t(1) << (32 - digit_count * 8))) {
15694
1.24k
        return is_valid = false;
15695
1.24k
      }
15696
34.0k
      ipv4 <<= (32 - digit_count * 8);
15697
34.0k
      ipv4 |= segment_result;
15698
34.0k
      goto final;
15699
35.2k
    } else {
15700
      // There is more, so that the value must no be larger than 255
15701
      // and we must have a '.'.
15702
11.4k
      if ((segment_result > 255) || (input[0] != '.')) {
15703
2.87k
        return is_valid = false;
15704
2.87k
      }
15705
8.61k
      ipv4 <<= 8;
15706
8.61k
      ipv4 |= segment_result;
15707
8.61k
      input.remove_prefix(1);  // remove '.'
15708
8.61k
    }
15709
46.7k
  }
15710
165
  if ((digit_count != 4) || (!input.empty())) {
15711
165
    ada_log("parse_ipv4 found invalid (more than 4 numbers or empty) ");
15712
165
    return is_valid = false;
15713
165
  }
15714
34.0k
final:
15715
34.0k
  ada_log("url_aggregator::parse_ipv4 completed ", get_href(),
15716
34.0k
          " host: ", get_host());
15717
15718
  // We could also check r.ptr to see where the parsing ended.
15719
34.0k
  if (in_place && pure_decimal_count == 4 && !trailing_dot) {
15720
0
    ada_log(
15721
0
        "url_aggregator::parse_ipv4 completed and was already correct in the "
15722
0
        "buffer");
15723
    // The original input was already all decimal and we validated it. So we
15724
    // don't need to do anything.
15725
34.0k
  } else {
15726
34.0k
    ada_log("url_aggregator::parse_ipv4 completed and we need to update it");
15727
    // Optimization opportunity: Get rid of unnecessary string return in ipv4
15728
    // serializer.
15729
    // TODO: This is likely a bug because it goes back update_base_hostname, not
15730
    // what we want to do.
15731
34.0k
    update_base_hostname(
15732
34.0k
        ada::serializers::ipv4(ipv4));  // We have to reserialize the address.
15733
34.0k
  }
15734
34.0k
  host_type = IPV4;
15735
34.0k
  ADA_ASSERT_TRUE(validate());
15736
34.0k
  return true;
15737
165
}
15738
15739
8.67k
bool url_aggregator::parse_ipv6(std::string_view input) {
15740
  // TODO: Implement in_place optimization: we know that input points
15741
  // in the buffer, so we can just check whether the buffer is already
15742
  // well formatted.
15743
  // TODO: Find a way to merge parse_ipv6 with url.cpp implementation.
15744
8.67k
  ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
15745
8.67k
  ADA_ASSERT_TRUE(validate());
15746
8.67k
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15747
8.67k
  if (input.empty()) {
15748
231
    return is_valid = false;
15749
231
  }
15750
  // Let address be a new IPv6 address whose IPv6 pieces are all 0.
15751
8.44k
  std::array<uint16_t, 8> address{};
15752
15753
  // Let pieceIndex be 0.
15754
8.44k
  int piece_index = 0;
15755
15756
  // Let compress be null.
15757
8.44k
  std::optional<int> compress{};
15758
15759
  // Let pointer be a pointer for input.
15760
8.44k
  std::string_view::iterator pointer = input.begin();
15761
15762
  // If c is U+003A (:), then:
15763
8.44k
  if (input[0] == ':') {
15764
    // If remaining does not start with U+003A (:), validation error, return
15765
    // failure.
15766
2.09k
    if (input.size() == 1 || input[1] != ':') {
15767
180
      ada_log("parse_ipv6 starts with : but the rest does not start with :");
15768
180
      return is_valid = false;
15769
180
    }
15770
15771
    // Increase pointer by 2.
15772
1.91k
    pointer += 2;
15773
15774
    // Increase pieceIndex by 1 and then set compress to pieceIndex.
15775
1.91k
    compress = ++piece_index;
15776
1.91k
  }
15777
15778
  // While c is not the EOF code point:
15779
21.6k
  while (pointer != input.end()) {
15780
    // If pieceIndex is 8, validation error, return failure.
15781
17.4k
    if (piece_index == 8) {
15782
85
      ada_log("parse_ipv6 piece_index == 8");
15783
85
      return is_valid = false;
15784
85
    }
15785
15786
    // If c is U+003A (:), then:
15787
17.3k
    if (*pointer == ':') {
15788
      // If compress is non-null, validation error, return failure.
15789
1.71k
      if (compress.has_value()) {
15790
142
        ada_log("parse_ipv6 compress is non-null");
15791
142
        return is_valid = false;
15792
142
      }
15793
15794
      // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
15795
      // then continue.
15796
1.57k
      pointer++;
15797
1.57k
      compress = ++piece_index;
15798
1.57k
      continue;
15799
1.71k
    }
15800
15801
    // Let value and length be 0.
15802
15.6k
    uint16_t value = 0, length = 0;
15803
15804
    // While length is less than 4 and c is an ASCII hex digit,
15805
    // set value to value times 0x10 + c interpreted as hexadecimal number, and
15806
    // increase pointer and length by 1.
15807
41.1k
    while (length < 4 && pointer != input.end() &&
15808
36.6k
           unicode::is_ascii_hex_digit(*pointer)) {
15809
      // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
15810
25.4k
      value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
15811
25.4k
      pointer++;
15812
25.4k
      length++;
15813
25.4k
    }
15814
15815
    // If c is U+002E (.), then:
15816
15.6k
    if (pointer != input.end() && *pointer == '.') {
15817
      // If length is 0, validation error, return failure.
15818
2.13k
      if (length == 0) {
15819
161
        ada_log("parse_ipv6 length is 0");
15820
161
        return is_valid = false;
15821
161
      }
15822
15823
      // Decrease pointer by length.
15824
1.97k
      pointer -= length;
15825
15826
      // If pieceIndex is greater than 6, validation error, return failure.
15827
1.97k
      if (piece_index > 6) {
15828
85
        ada_log("parse_ipv6 piece_index > 6");
15829
85
        return is_valid = false;
15830
85
      }
15831
15832
      // Let numbersSeen be 0.
15833
1.88k
      int numbers_seen = 0;
15834
15835
      // While c is not the EOF code point:
15836
5.04k
      while (pointer != input.end()) {
15837
        // Let ipv4Piece be null.
15838
4.51k
        std::optional<uint16_t> ipv4_piece{};
15839
15840
        // If numbersSeen is greater than 0, then:
15841
4.51k
        if (numbers_seen > 0) {
15842
          // If c is a U+002E (.) and numbersSeen is less than 4, then increase
15843
          // pointer by 1.
15844
2.62k
          if (*pointer == '.' && numbers_seen < 4) {
15845
2.13k
            pointer++;
15846
2.13k
          } else {
15847
            // Otherwise, validation error, return failure.
15848
498
            ada_log("parse_ipv6 Otherwise, validation error, return failure");
15849
498
            return is_valid = false;
15850
498
          }
15851
2.62k
        }
15852
15853
        // If c is not an ASCII digit, validation error, return failure.
15854
4.01k
        if (pointer == input.end() || !checkers::is_digit(*pointer)) {
15855
407
          ada_log(
15856
407
              "parse_ipv6 If c is not an ASCII digit, validation error, return "
15857
407
              "failure");
15858
407
          return is_valid = false;
15859
407
        }
15860
15861
        // While c is an ASCII digit:
15862
8.93k
        while (pointer != input.end() && checkers::is_digit(*pointer)) {
15863
          // Let number be c interpreted as decimal number.
15864
5.77k
          int number = *pointer - '0';
15865
15866
          // If ipv4Piece is null, then set ipv4Piece to number.
15867
5.77k
          if (!ipv4_piece.has_value()) {
15868
3.60k
            ipv4_piece = number;
15869
3.60k
          }
15870
          // Otherwise, if ipv4Piece is 0, validation error, return failure.
15871
2.16k
          else if (ipv4_piece == 0) {
15872
90
            ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
15873
90
            return is_valid = false;
15874
90
          }
15875
          // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
15876
2.07k
          else {
15877
2.07k
            ipv4_piece = *ipv4_piece * 10 + number;
15878
2.07k
          }
15879
15880
          // If ipv4Piece is greater than 255, validation error, return failure.
15881
5.68k
          if (ipv4_piece > 255) {
15882
361
            ada_log("parse_ipv6 ipv4_piece > 255");
15883
361
            return is_valid = false;
15884
361
          }
15885
15886
          // Increase pointer by 1.
15887
5.32k
          pointer++;
15888
5.32k
        }
15889
15890
        // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
15891
        // ipv4Piece.
15892
        // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
15893
3.15k
        if (!ipv4_piece.has_value()) {
15894
0
          return is_valid = false;
15895
0
        }
15896
3.15k
        address[piece_index] =
15897
3.15k
            uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
15898
15899
        // Increase numbersSeen by 1.
15900
3.15k
        numbers_seen++;
15901
15902
        // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
15903
3.15k
        if (numbers_seen == 2 || numbers_seen == 4) {
15904
1.21k
          piece_index++;
15905
1.21k
        }
15906
3.15k
      }
15907
15908
      // If numbersSeen is not 4, validation error, return failure.
15909
529
      if (numbers_seen != 4) {
15910
382
        return is_valid = false;
15911
382
      }
15912
15913
      // Break.
15914
147
      break;
15915
529
    }
15916
    // Otherwise, if c is U+003A (:):
15917
13.5k
    else if ((pointer != input.end()) && (*pointer == ':')) {
15918
      // Increase pointer by 1.
15919
8.72k
      pointer++;
15920
15921
      // If c is the EOF code point, validation error, return failure.
15922
8.72k
      if (pointer == input.end()) {
15923
144
        ada_log(
15924
144
            "parse_ipv6 If c is the EOF code point, validation error, return "
15925
144
            "failure");
15926
144
        return is_valid = false;
15927
144
      }
15928
8.72k
    }
15929
    // Otherwise, if c is not the EOF code point, validation error, return
15930
    // failure.
15931
4.81k
    else if (pointer != input.end()) {
15932
1.61k
      ada_log(
15933
1.61k
          "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
15934
1.61k
          "error, return failure");
15935
1.61k
      return is_valid = false;
15936
1.61k
    }
15937
15938
    // Set address[pieceIndex] to value.
15939
11.7k
    address[piece_index] = value;
15940
15941
    // Increase pieceIndex by 1.
15942
11.7k
    piece_index++;
15943
11.7k
  }
15944
15945
  // If compress is non-null, then:
15946
4.29k
  if (compress.has_value()) {
15947
    // Let swaps be pieceIndex - compress.
15948
3.00k
    int swaps = piece_index - *compress;
15949
15950
    // Set pieceIndex to 7.
15951
3.00k
    piece_index = 7;
15952
15953
    // While pieceIndex is not 0 and swaps is greater than 0,
15954
    // swap address[pieceIndex] with address[compress + swaps - 1], and then
15955
    // decrease both pieceIndex and swaps by 1.
15956
7.52k
    while (piece_index != 0 && swaps > 0) {
15957
4.51k
      std::swap(address[piece_index], address[*compress + swaps - 1]);
15958
4.51k
      piece_index--;
15959
4.51k
      swaps--;
15960
4.51k
    }
15961
3.00k
  }
15962
  // Otherwise, if compress is null and pieceIndex is not 8, validation error,
15963
  // return failure.
15964
1.28k
  else if (piece_index != 8) {
15965
1.20k
    ada_log(
15966
1.20k
        "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
15967
1.20k
        "error, return failure");
15968
1.20k
    return is_valid = false;
15969
1.20k
  }
15970
  // TODO: Optimization opportunity: Get rid of unnecessary string creation.
15971
  // TODO: This is likely a bug because it goes back update_base_hostname, not
15972
  // what we want to do.
15973
3.09k
  update_base_hostname(ada::serializers::ipv6(address));
15974
3.09k
  ada_log("parse_ipv6 ", get_hostname());
15975
3.09k
  ADA_ASSERT_TRUE(validate());
15976
3.09k
  host_type = IPV6;
15977
3.09k
  return true;
15978
4.29k
}
15979
15980
218k
bool url_aggregator::parse_opaque_host(std::string_view input) {
15981
218k
  ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
15982
218k
  ADA_ASSERT_TRUE(validate());
15983
218k
  ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
15984
218k
  if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) {
15985
29
    return is_valid = false;
15986
29
  }
15987
15988
  // Return the result of running UTF-8 percent-encode on input using the C0
15989
  // control percent-encode set.
15990
218k
  size_t idx = ada::unicode::percent_encode_index(
15991
218k
      input, character_sets::C0_CONTROL_PERCENT_ENCODE);
15992
218k
  if (idx == input.size()) {
15993
218k
    update_base_hostname(input);
15994
218k
  } else {
15995
    // We only create a temporary string if we need to.
15996
167
    update_base_hostname(ada::unicode::percent_encode(
15997
167
        input, character_sets::C0_CONTROL_PERCENT_ENCODE, idx));
15998
167
  }
15999
218k
  ADA_ASSERT_TRUE(validate());
16000
218k
  return true;
16001
218k
}
16002
16003
0
[[nodiscard]] std::string url_aggregator::to_diagram() const {
16004
0
  if (!is_valid) {
16005
0
    return "invalid";
16006
0
  }
16007
0
  std::string answer;
16008
0
  answer.append(buffer);
16009
0
  answer.append(" [");
16010
0
  answer.append(std::to_string(buffer.size()));
16011
0
  answer.append(" bytes]");
16012
0
  answer.append("\n");
16013
  // first line
16014
0
  std::string line1;
16015
0
  line1.resize(buffer.size(), ' ');
16016
0
  if (components.hash_start != url_components::omitted) {
16017
0
    line1[components.hash_start] = '|';
16018
0
  }
16019
0
  if (components.search_start != url_components::omitted) {
16020
0
    line1[components.search_start] = '|';
16021
0
  }
16022
0
  if (components.pathname_start != buffer.size()) {
16023
0
    line1[components.pathname_start] = '|';
16024
0
  }
16025
0
  if (components.host_end != buffer.size()) {
16026
0
    line1[components.host_end] = '|';
16027
0
  }
16028
0
  if (components.host_start != buffer.size()) {
16029
0
    line1[components.host_start] = '|';
16030
0
  }
16031
0
  if (components.username_end != buffer.size()) {
16032
0
    line1[components.username_end] = '|';
16033
0
  }
16034
0
  if (components.protocol_end != buffer.size()) {
16035
0
    line1[components.protocol_end] = '|';
16036
0
  }
16037
0
  answer.append(line1);
16038
0
  answer.append("\n");
16039
16040
0
  std::string line2 = line1;
16041
0
  if (components.hash_start != url_components::omitted) {
16042
0
    line2[components.hash_start] = '`';
16043
0
    line1[components.hash_start] = ' ';
16044
16045
0
    for (size_t i = components.hash_start + 1; i < line2.size(); i++) {
16046
0
      line2[i] = '-';
16047
0
    }
16048
0
    line2.append(" hash_start");
16049
0
    answer.append(line2);
16050
0
    answer.append("\n");
16051
0
  }
16052
16053
0
  std::string line3 = line1;
16054
0
  if (components.search_start != url_components::omitted) {
16055
0
    line3[components.search_start] = '`';
16056
0
    line1[components.search_start] = ' ';
16057
16058
0
    for (size_t i = components.search_start + 1; i < line3.size(); i++) {
16059
0
      line3[i] = '-';
16060
0
    }
16061
0
    line3.append(" search_start ");
16062
0
    line3.append(std::to_string(components.search_start));
16063
0
    answer.append(line3);
16064
0
    answer.append("\n");
16065
0
  }
16066
16067
0
  std::string line4 = line1;
16068
0
  if (components.pathname_start != buffer.size()) {
16069
0
    line4[components.pathname_start] = '`';
16070
0
    line1[components.pathname_start] = ' ';
16071
0
    for (size_t i = components.pathname_start + 1; i < line4.size(); i++) {
16072
0
      line4[i] = '-';
16073
0
    }
16074
0
    line4.append(" pathname_start ");
16075
0
    line4.append(std::to_string(components.pathname_start));
16076
0
    answer.append(line4);
16077
0
    answer.append("\n");
16078
0
  }
16079
16080
0
  std::string line5 = line1;
16081
0
  if (components.host_end != buffer.size()) {
16082
0
    line5[components.host_end] = '`';
16083
0
    line1[components.host_end] = ' ';
16084
16085
0
    for (size_t i = components.host_end + 1; i < line5.size(); i++) {
16086
0
      line5[i] = '-';
16087
0
    }
16088
0
    line5.append(" host_end ");
16089
0
    line5.append(std::to_string(components.host_end));
16090
0
    answer.append(line5);
16091
0
    answer.append("\n");
16092
0
  }
16093
16094
0
  std::string line6 = line1;
16095
0
  if (components.host_start != buffer.size()) {
16096
0
    line6[components.host_start] = '`';
16097
0
    line1[components.host_start] = ' ';
16098
16099
0
    for (size_t i = components.host_start + 1; i < line6.size(); i++) {
16100
0
      line6[i] = '-';
16101
0
    }
16102
0
    line6.append(" host_start ");
16103
0
    line6.append(std::to_string(components.host_start));
16104
0
    answer.append(line6);
16105
0
    answer.append("\n");
16106
0
  }
16107
16108
0
  std::string line7 = line1;
16109
0
  if (components.username_end != buffer.size()) {
16110
0
    line7[components.username_end] = '`';
16111
0
    line1[components.username_end] = ' ';
16112
16113
0
    for (size_t i = components.username_end + 1; i < line7.size(); i++) {
16114
0
      line7[i] = '-';
16115
0
    }
16116
0
    line7.append(" username_end ");
16117
0
    line7.append(std::to_string(components.username_end));
16118
0
    answer.append(line7);
16119
0
    answer.append("\n");
16120
0
  }
16121
16122
0
  std::string line8 = line1;
16123
0
  if (components.protocol_end != buffer.size()) {
16124
0
    line8[components.protocol_end] = '`';
16125
0
    line1[components.protocol_end] = ' ';
16126
16127
0
    for (size_t i = components.protocol_end + 1; i < line8.size(); i++) {
16128
0
      line8[i] = '-';
16129
0
    }
16130
0
    line8.append(" protocol_end ");
16131
0
    line8.append(std::to_string(components.protocol_end));
16132
0
    answer.append(line8);
16133
0
    answer.append("\n");
16134
0
  }
16135
16136
0
  if (components.hash_start == url_components::omitted) {
16137
0
    answer.append("note: hash omitted\n");
16138
0
  }
16139
0
  if (components.search_start == url_components::omitted) {
16140
0
    answer.append("note: search omitted\n");
16141
0
  }
16142
0
  if (components.protocol_end > buffer.size()) {
16143
0
    answer.append("warning: protocol_end overflows\n");
16144
0
  }
16145
0
  if (components.username_end > buffer.size()) {
16146
0
    answer.append("warning: username_end overflows\n");
16147
0
  }
16148
0
  if (components.host_start > buffer.size()) {
16149
0
    answer.append("warning: host_start overflows\n");
16150
0
  }
16151
0
  if (components.host_end > buffer.size()) {
16152
0
    answer.append("warning: host_end overflows\n");
16153
0
  }
16154
0
  if (components.pathname_start > buffer.size()) {
16155
0
    answer.append("warning: pathname_start overflows\n");
16156
0
  }
16157
0
  return answer;
16158
0
}
16159
16160
0
void url_aggregator::delete_dash_dot() {
16161
0
  ada_log("url_aggregator::delete_dash_dot");
16162
0
  ADA_ASSERT_TRUE(validate());
16163
0
  ADA_ASSERT_TRUE(has_dash_dot());
16164
0
  buffer.erase(components.host_end, 2);
16165
0
  components.pathname_start -= 2;
16166
0
  if (components.search_start != url_components::omitted) {
16167
0
    components.search_start -= 2;
16168
0
  }
16169
0
  if (components.hash_start != url_components::omitted) {
16170
0
    components.hash_start -= 2;
16171
0
  }
16172
0
  ADA_ASSERT_TRUE(validate());
16173
0
  ADA_ASSERT_TRUE(!has_dash_dot());
16174
0
}
16175
16176
385k
inline void url_aggregator::consume_prepared_path(std::string_view input) {
16177
385k
  ada_log("url_aggregator::consume_prepared_path ", input);
16178
  /***
16179
   * This is largely duplicated code from helpers::parse_prepared_path, which is
16180
   * unfortunate. This particular function is nearly identical, except that it
16181
   * is a method on url_aggregator. The idea is that the trivial path (which is
16182
   * very common) merely appends to the buffer. This is the same trivial path as
16183
   * with helpers::parse_prepared_path, except that we have the additional check
16184
   * for is_at_path(). Otherwise, we grab a copy of the current path and we
16185
   * modify it, and then insert it back into the buffer.
16186
   */
16187
385k
  uint8_t accumulator = checkers::path_signature(input);
16188
  // Let us first detect a trivial case.
16189
  // If it is special, we check that we have no dot, no %,  no \ and no
16190
  // character needing percent encoding. Otherwise, we check that we have no %,
16191
  // no dot, and no character needing percent encoding.
16192
385k
  constexpr uint8_t need_encoding = 1;
16193
385k
  constexpr uint8_t backslash_char = 2;
16194
385k
  constexpr uint8_t dot_char = 4;
16195
385k
  constexpr uint8_t percent_char = 8;
16196
385k
  bool special = type != ada::scheme::NOT_SPECIAL;
16197
385k
  bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
16198
0
                                      checkers::is_windows_drive_letter(input));
16199
385k
  bool trivial_path =
16200
385k
      (special ? (accumulator == 0)
16201
385k
               : ((accumulator & (need_encoding | dot_char | percent_char)) ==
16202
238k
                  0)) &&
16203
315k
      (!may_need_slow_file_handling);
16204
385k
  if (accumulator == dot_char && !may_need_slow_file_handling) {
16205
    // '4' means that we have at least one dot, but nothing that requires
16206
    // percent encoding or decoding. The only part that is not trivial is
16207
    // that we may have single dots and double dots path segments.
16208
    // If we have such segments, then we either have a path that begins
16209
    // with '.' (easy to check), or we have the sequence './'.
16210
    // Note: input cannot be empty, it must at least contain one character ('.')
16211
    // Note: we know that '\' is not present.
16212
26.6k
    if (input[0] != '.') {
16213
17.0k
      size_t slashdot = 0;
16214
17.0k
      bool dot_is_file = true;
16215
32.1k
      for (;;) {
16216
32.1k
        slashdot = input.find("/.", slashdot);
16217
32.1k
        if (slashdot == std::string_view::npos) {  // common case
16218
17.0k
          break;
16219
17.0k
        } else {  // uncommon
16220
          // only three cases matter: /./, /.. or a final /
16221
15.0k
          slashdot += 2;
16222
15.0k
          dot_is_file &= !(slashdot == input.size() || input[slashdot] == '.' ||
16223
7.13k
                           input[slashdot] == '/');
16224
15.0k
        }
16225
32.1k
      }
16226
17.0k
      trivial_path = dot_is_file;
16227
17.0k
    }
16228
26.6k
  }
16229
385k
  if (trivial_path && is_at_path()) {
16230
324k
    ada_log("parse_path trivial");
16231
324k
    buffer += '/';
16232
324k
    buffer += input;
16233
324k
    return;
16234
324k
  }
16235
60.7k
  std::string path = std::string(get_pathname());
16236
  // We are going to need to look a bit at the path, but let us see if we can
16237
  // ignore percent encoding *and* backslashes *and* percent characters.
16238
  // Except for the trivial case, this is likely to capture 99% of paths out
16239
  // there.
16240
60.7k
  bool fast_path =
16241
60.7k
      (special &&
16242
24.9k
       (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
16243
12.9k
      (type != ada::scheme::type::FILE);
16244
60.7k
  if (fast_path) {
16245
12.9k
    ada_log("parse_prepared_path fast");
16246
    // Here we don't need to worry about \ or percent encoding.
16247
    // We also do not have a file protocol. We might have dots, however,
16248
    // but dots must as appear as '.', and they cannot be encoded because
16249
    // the symbol '%' is not present.
16250
12.9k
    size_t previous_location = 0;  // We start at 0.
16251
60.1k
    do {
16252
60.1k
      size_t new_location = input.find('/', previous_location);
16253
      // std::string_view path_view = input;
16254
      //  We process the last segment separately:
16255
60.1k
      if (new_location == std::string_view::npos) {
16256
12.9k
        std::string_view path_view = input.substr(previous_location);
16257
12.9k
        if (path_view == "..") {  // The path ends with ..
16258
          // e.g., if you receive ".." with an empty path, you go to "/".
16259
1.26k
          if (path.empty()) {
16260
435
            path = '/';
16261
435
            update_base_pathname(path);
16262
435
            return;
16263
435
          }
16264
          // Fast case where we have nothing to do:
16265
830
          if (path.back() == '/') {
16266
225
            update_base_pathname(path);
16267
225
            return;
16268
225
          }
16269
          // If you have the path "/joe/myfriend",
16270
          // then you delete 'myfriend'.
16271
605
          path.resize(path.rfind('/') + 1);
16272
605
          update_base_pathname(path);
16273
605
          return;
16274
830
        }
16275
11.6k
        path += '/';
16276
11.6k
        if (path_view != ".") {
16277
11.2k
          path.append(path_view);
16278
11.2k
        }
16279
11.6k
        update_base_pathname(path);
16280
11.6k
        return;
16281
47.1k
      } else {
16282
        // This is a non-final segment.
16283
47.1k
        std::string_view path_view =
16284
47.1k
            input.substr(previous_location, new_location - previous_location);
16285
47.1k
        previous_location = new_location + 1;
16286
47.1k
        if (path_view == "..") {
16287
6.66k
          size_t last_delimiter = path.rfind('/');
16288
6.66k
          if (last_delimiter != std::string::npos) {
16289
2.31k
            path.erase(last_delimiter);
16290
2.31k
          }
16291
40.5k
        } else if (path_view != ".") {
16292
35.4k
          path += '/';
16293
35.4k
          path.append(path_view);
16294
35.4k
        }
16295
47.1k
      }
16296
60.1k
    } while (true);
16297
47.7k
  } else {
16298
47.7k
    ada_log("parse_path slow");
16299
    // we have reached the general case
16300
47.7k
    bool needs_percent_encoding = (accumulator & 1);
16301
47.7k
    std::string path_buffer_tmp;
16302
199k
    do {
16303
199k
      size_t location = (special && (accumulator & 2))
16304
199k
                            ? input.find_first_of("/\\")
16305
199k
                            : input.find('/');
16306
199k
      std::string_view path_view = input;
16307
199k
      if (location != std::string_view::npos) {
16308
152k
        path_view.remove_suffix(path_view.size() - location);
16309
152k
        input.remove_prefix(location + 1);
16310
152k
      }
16311
      // path_buffer is either path_view or it might point at a percent encoded
16312
      // temporary string.
16313
199k
      std::string_view path_buffer =
16314
199k
          (needs_percent_encoding &&
16315
111k
           ada::unicode::percent_encode<false>(
16316
111k
               path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
16317
199k
              ? path_buffer_tmp
16318
199k
              : path_view;
16319
199k
      if (unicode::is_double_dot_path_segment(path_buffer)) {
16320
7.43k
        helpers::shorten_path(path, type);
16321
7.43k
        if (location == std::string_view::npos) {
16322
1.00k
          path += '/';
16323
1.00k
        }
16324
192k
      } else if (unicode::is_single_dot_path_segment(path_buffer) &&
16325
6.62k
                 (location == std::string_view::npos)) {
16326
1.08k
        path += '/';
16327
1.08k
      }
16328
      // Otherwise, if path_buffer is not a single-dot path segment, then:
16329
191k
      else if (!unicode::is_single_dot_path_segment(path_buffer)) {
16330
        // If url's scheme is "file", url's path is empty, and path_buffer is a
16331
        // Windows drive letter, then replace the second code point in
16332
        // path_buffer with U+003A (:).
16333
185k
        if (type == ada::scheme::type::FILE && path.empty() &&
16334
0
            checkers::is_windows_drive_letter(path_buffer)) {
16335
0
          path += '/';
16336
0
          path += path_buffer[0];
16337
0
          path += ':';
16338
0
          path_buffer.remove_prefix(2);
16339
0
          path.append(path_buffer);
16340
185k
        } else {
16341
          // Append path_buffer to url's path.
16342
185k
          path += '/';
16343
185k
          path.append(path_buffer);
16344
185k
        }
16345
185k
      }
16346
199k
      if (location == std::string_view::npos) {
16347
47.7k
        update_base_pathname(path);
16348
47.7k
        return;
16349
47.7k
      }
16350
199k
    } while (true);
16351
47.7k
  }
16352
60.7k
}
16353
}  // namespace ada
16354
/* end file src/url_aggregator.cpp */
16355
16356
#if ADA_INCLUDE_URL_PATTERN
16357
/* begin file src/url_pattern.cpp */
16358
#if ADA_INCLUDE_URL_PATTERN
16359
16360
16361
#include <algorithm>
16362
#include <optional>
16363
#include <string>
16364
16365
namespace ada {
16366
16367
tl::expected<url_pattern_init, errors> url_pattern_init::process(
16368
    const url_pattern_init& init, url_pattern_init::process_type type,
16369
    std::optional<std::string_view> protocol,
16370
    std::optional<std::string_view> username,
16371
    std::optional<std::string_view> password,
16372
    std::optional<std::string_view> hostname,
16373
    std::optional<std::string_view> port,
16374
    std::optional<std::string_view> pathname,
16375
    std::optional<std::string_view> search,
16376
378k
    std::optional<std::string_view> hash) {
16377
  // Let result be the result of creating a new URLPatternInit.
16378
378k
  auto result = url_pattern_init{};
16379
16380
  // If protocol is not null, set result["protocol"] to protocol.
16381
378k
  if (protocol.has_value()) result.protocol = *protocol;
16382
16383
  // If username is not null, set result["username"] to username.
16384
378k
  if (username.has_value()) result.username = *username;
16385
16386
  // If password is not null, set result["password"] to password.
16387
378k
  if (password.has_value()) result.password = *password;
16388
16389
  // If hostname is not null, set result["hostname"] to hostname.
16390
378k
  if (hostname.has_value()) result.hostname = *hostname;
16391
16392
  // If port is not null, set result["port"] to port.
16393
378k
  if (port.has_value()) result.port = *port;
16394
16395
  // If pathname is not null, set result["pathname"] to pathname.
16396
378k
  if (pathname.has_value()) result.pathname = *pathname;
16397
16398
  // If search is not null, set result["search"] to search.
16399
378k
  if (search.has_value()) result.search = *search;
16400
16401
  // If hash is not null, set result["hash"] to hash.
16402
378k
  if (hash.has_value()) result.hash = *hash;
16403
16404
  // Let baseURL be null.
16405
378k
  std::optional<url_aggregator> base_url{};
16406
16407
  // If init["baseURL"] exists:
16408
378k
  if (init.base_url.has_value()) {
16409
    // Set baseURL to the result of parsing init["baseURL"].
16410
99.2k
    auto parsing_result = ada::parse<url_aggregator>(*init.base_url);
16411
    // If baseURL is failure, then throw a TypeError.
16412
99.2k
    if (!parsing_result) {
16413
48.2k
      return tl::unexpected(errors::type_error);
16414
48.2k
    }
16415
50.9k
    base_url = std::move(*parsing_result);
16416
16417
    // If init["protocol"] does not exist, then set result["protocol"] to the
16418
    // result of processing a base URL string given baseURL's scheme and type.
16419
50.9k
    if (!init.protocol.has_value()) {
16420
25.9k
      ADA_ASSERT_TRUE(base_url.has_value());
16421
25.9k
      std::string_view base_url_protocol = base_url->get_protocol();
16422
25.9k
      if (base_url_protocol.ends_with(":")) base_url_protocol.remove_suffix(1);
16423
25.9k
      result.protocol =
16424
25.9k
          url_pattern_helpers::process_base_url_string(base_url_protocol, type);
16425
25.9k
    }
16426
16427
    // If type is not "pattern" and init contains none of "protocol",
16428
    // "hostname", "port" and "username", then set result["username"] to the
16429
    // result of processing a base URL string given baseURL's username and type.
16430
50.9k
    if (type != process_type::pattern && !init.protocol && !init.hostname &&
16431
0
        !init.port && !init.username) {
16432
0
      result.username = url_pattern_helpers::process_base_url_string(
16433
0
          base_url->get_username(), type);
16434
0
    }
16435
16436
    // TODO: Optimization opportunity: Merge this with the previous check.
16437
    // If type is not "pattern" and init contains none of "protocol",
16438
    // "hostname", "port", "username" and "password", then set
16439
    // result["password"] to the result of processing a base URL string given
16440
    // baseURL's password and type.
16441
50.9k
    if (type != process_type::pattern && !init.protocol && !init.hostname &&
16442
0
        !init.port && !init.username && !init.password) {
16443
0
      result.password = url_pattern_helpers::process_base_url_string(
16444
0
          base_url->get_password(), type);
16445
0
    }
16446
16447
    // If init contains neither "protocol" nor "hostname", then:
16448
50.9k
    if (!init.protocol && !init.hostname) {
16449
      // Let baseHost be baseURL's host.
16450
      // If baseHost is null, then set baseHost to the empty string.
16451
25.9k
      auto base_host = base_url->get_hostname();
16452
      // Set result["hostname"] to the result of processing a base URL string
16453
      // given baseHost and type.
16454
25.9k
      result.hostname =
16455
25.9k
          url_pattern_helpers::process_base_url_string(base_host, type);
16456
25.9k
    }
16457
16458
    // If init contains none of "protocol", "hostname", and "port", then:
16459
50.9k
    if (!init.protocol && !init.hostname && !init.port) {
16460
      // If baseURL's port is null, then set result["port"] to the empty string.
16461
      // Otherwise, set result["port"] to baseURL's port, serialized.
16462
25.9k
      result.port = base_url->get_port();
16463
25.9k
    }
16464
16465
    // If init contains none of "protocol", "hostname", "port", and "pathname",
16466
    // then set result["pathname"] to the result of processing a base URL string
16467
    // given the result of URL path serializing baseURL and type.
16468
50.9k
    if (!init.protocol && !init.hostname && !init.port && !init.pathname) {
16469
0
      result.pathname = url_pattern_helpers::process_base_url_string(
16470
0
          base_url->get_pathname(), type);
16471
0
    }
16472
16473
    // If init contains none of "protocol", "hostname", "port", "pathname", and
16474
    // "search", then:
16475
50.9k
    if (!init.protocol && !init.hostname && !init.port && !init.pathname &&
16476
0
        !init.search) {
16477
      // Let baseQuery be baseURL's query.
16478
      // Set result["search"] to the result of processing a base URL string
16479
      // given baseQuery and type.
16480
0
      result.search = url_pattern_helpers::process_base_url_string(
16481
0
          base_url->get_search(), type);
16482
0
    }
16483
16484
    // If init contains none of "protocol", "hostname", "port", "pathname",
16485
    // "search", and "hash", then:
16486
50.9k
    if (!init.protocol && !init.hostname && !init.port && !init.pathname &&
16487
0
        !init.search && !init.hash) {
16488
      // Let baseFragment be baseURL's fragment.
16489
      // Set result["hash"] to the result of processing a base URL string given
16490
      // baseFragment and type.
16491
0
      result.hash = url_pattern_helpers::process_base_url_string(
16492
0
          base_url->get_hash(), type);
16493
0
    }
16494
50.9k
  }
16495
16496
  // If init["protocol"] exists, then set result["protocol"] to the result of
16497
  // process protocol for init given init["protocol"] and type.
16498
330k
  if (init.protocol) {
16499
63.2k
    auto process_result = process_protocol(*init.protocol, type);
16500
63.2k
    if (!process_result) {
16501
0
      return tl::unexpected(process_result.error());
16502
0
    }
16503
63.2k
    result.protocol = std::move(*process_result);
16504
63.2k
  }
16505
16506
  // If init["username"] exists, then set result["username"] to the result of
16507
  // process username for init given init["username"] and type.
16508
330k
  if (init.username.has_value()) {
16509
25.9k
    auto process_result = process_username(*init.username, type);
16510
25.9k
    if (!process_result) {
16511
0
      return tl::unexpected(process_result.error());
16512
0
    }
16513
25.9k
    result.username = std::move(*process_result);
16514
25.9k
  }
16515
16516
  // If init["password"] exists, then set result["password"] to the result of
16517
  // process password for init given init["password"] and type.
16518
330k
  if (init.password.has_value()) {
16519
25.4k
    auto process_result = process_password(*init.password, type);
16520
25.4k
    if (!process_result) {
16521
0
      return tl::unexpected(process_result.error());
16522
0
    }
16523
25.4k
    result.password = std::move(*process_result);
16524
25.4k
  }
16525
16526
  // If init["hostname"] exists, then set result["hostname"] to the result of
16527
  // process hostname for init given init["hostname"] and type.
16528
330k
  if (init.hostname.has_value()) {
16529
63.3k
    auto process_result = process_hostname(*init.hostname, type);
16530
63.3k
    if (!process_result) {
16531
0
      return tl::unexpected(process_result.error());
16532
0
    }
16533
63.3k
    result.hostname = std::move(*process_result);
16534
63.3k
  }
16535
16536
  // If init["port"] exists, then set result["port"] to the result of process
16537
  // port for init given init["port"], result["protocol"], and type.
16538
330k
  if (init.port) {
16539
63.3k
    auto process_result =
16540
63.3k
        process_port(*init.port, result.protocol.value_or("fake"), type);
16541
63.3k
    if (!process_result) {
16542
0
      return tl::unexpected(process_result.error());
16543
0
    }
16544
63.3k
    result.port = std::move(*process_result);
16545
63.3k
  }
16546
16547
  // If init["pathname"] exists:
16548
330k
  if (init.pathname.has_value()) {
16549
    // Set result["pathname"] to init["pathname"].
16550
306k
    result.pathname = init.pathname;
16551
16552
    // If the following are all true:
16553
    // - baseURL is not null;
16554
    // - baseURL has an opaque path; and
16555
    // - the result of running is an absolute pathname given result["pathname"]
16556
    // and type is false,
16557
306k
    if (base_url && !base_url->has_opaque_path &&
16558
50.9k
        !url_pattern_helpers::is_absolute_pathname(*result.pathname, type)) {
16559
      // Let baseURLPath be the result of running process a base URL string
16560
      // given the result of URL path serializing baseURL and type.
16561
      // TODO: Optimization opportunity: Avoid returning a string if no slash
16562
      // exist.
16563
0
      std::string base_url_path = url_pattern_helpers::process_base_url_string(
16564
0
          base_url->get_pathname(), type);
16565
16566
      // Let slash index be the index of the last U+002F (/) code point found in
16567
      // baseURLPath, interpreted as a sequence of code points, or null if there
16568
      // are no instances of the code point.
16569
0
      auto slash_index = base_url_path.find_last_of('/');
16570
16571
      // If slash index is not null:
16572
0
      if (slash_index != std::string::npos) {
16573
        // Let new pathname be the code point substring from 0 to slash index +
16574
        // 1 within baseURLPath.
16575
0
        base_url_path.resize(slash_index + 1);
16576
        // Append result["pathname"] to the end of new pathname.
16577
0
        ADA_ASSERT_TRUE(result.pathname.has_value());
16578
0
        base_url_path.append(std::move(*result.pathname));
16579
        // Set result["pathname"] to new pathname.
16580
0
        result.pathname = std::move(base_url_path);
16581
0
      }
16582
0
    }
16583
16584
    // Set result["pathname"] to the result of process pathname for init given
16585
    // result["pathname"], result["protocol"], and type.
16586
306k
    auto pathname_processing_result =
16587
306k
        process_pathname(*result.pathname, result.protocol.value_or(""), type);
16588
306k
    if (!pathname_processing_result) {
16589
568
      return tl::unexpected(pathname_processing_result.error());
16590
568
    }
16591
305k
    result.pathname = std::move(*pathname_processing_result);
16592
305k
  }
16593
16594
  // If init["search"] exists then set result["search"] to the result of process
16595
  // search for init given init["search"] and type.
16596
329k
  if (init.search) {
16597
25.7k
    auto process_result = process_search(*init.search, type);
16598
25.7k
    if (!process_result) {
16599
0
      return tl::unexpected(process_result.error());
16600
0
    }
16601
25.7k
    result.search = std::move(*process_result);
16602
25.7k
  }
16603
16604
  // If init["hash"] exists then set result["hash"] to the result of process
16605
  // hash for init given init["hash"] and type.
16606
329k
  if (init.hash) {
16607
25.9k
    auto process_result = process_hash(*init.hash, type);
16608
25.9k
    if (!process_result) {
16609
0
      return tl::unexpected(process_result.error());
16610
0
    }
16611
25.9k
    result.hash = std::move(*process_result);
16612
25.9k
  }
16613
  // Return result.
16614
329k
  return result;
16615
329k
}
16616
16617
tl::expected<std::string, errors> url_pattern_init::process_protocol(
16618
63.2k
    std::string_view value, process_type type) {
16619
63.2k
  ada_log("process_protocol=", value, " [", type, "]");
16620
  // Let strippedValue be the given value with a single trailing U+003A (:)
16621
  // removed, if any.
16622
63.2k
  if (value.ends_with(":")) {
16623
45
    value.remove_suffix(1);
16624
45
  }
16625
  // If type is "pattern" then return strippedValue.
16626
63.2k
  if (type == process_type::pattern) {
16627
63.2k
    return std::string(value);
16628
63.2k
  }
16629
  // Return the result of running canonicalize a protocol given strippedValue.
16630
0
  return url_pattern_helpers::canonicalize_protocol(value);
16631
63.2k
}
16632
16633
tl::expected<std::string, errors> url_pattern_init::process_username(
16634
25.9k
    std::string_view value, process_type type) {
16635
  // If type is "pattern" then return value.
16636
25.9k
  if (type == process_type::pattern) {
16637
25.9k
    return std::string(value);
16638
25.9k
  }
16639
  // Return the result of running canonicalize a username given value.
16640
0
  return url_pattern_helpers::canonicalize_username(value);
16641
25.9k
}
16642
16643
tl::expected<std::string, errors> url_pattern_init::process_password(
16644
25.4k
    std::string_view value, process_type type) {
16645
  // If type is "pattern" then return value.
16646
25.4k
  if (type == process_type::pattern) {
16647
25.4k
    return std::string(value);
16648
25.4k
  }
16649
  // Return the result of running canonicalize a password given value.
16650
0
  return url_pattern_helpers::canonicalize_password(value);
16651
25.4k
}
16652
16653
tl::expected<std::string, errors> url_pattern_init::process_hostname(
16654
63.3k
    std::string_view value, process_type type) {
16655
63.3k
  ada_log("process_hostname value=", value, " type=", type);
16656
  // If type is "pattern" then return value.
16657
63.3k
  if (type == process_type::pattern) {
16658
63.3k
    return std::string(value);
16659
63.3k
  }
16660
  // Return the result of running canonicalize a hostname given value.
16661
0
  return url_pattern_helpers::canonicalize_hostname(value);
16662
63.3k
}
16663
16664
tl::expected<std::string, errors> url_pattern_init::process_port(
16665
63.3k
    std::string_view port, std::string_view protocol, process_type type) {
16666
  // If type is "pattern" then return portValue.
16667
63.3k
  if (type == process_type::pattern) {
16668
63.3k
    return std::string(port);
16669
63.3k
  }
16670
  // Return the result of running canonicalize a port given portValue and
16671
  // protocolValue.
16672
0
  return url_pattern_helpers::canonicalize_port_with_protocol(port, protocol);
16673
63.3k
}
16674
16675
tl::expected<std::string, errors> url_pattern_init::process_pathname(
16676
306k
    std::string_view value, std::string_view protocol, process_type type) {
16677
  // If type is "pattern" then return pathnameValue.
16678
306k
  if (type == process_type::pattern) {
16679
89.4k
    return std::string(value);
16680
89.4k
  }
16681
16682
  // If protocolValue is a special scheme or the empty string, then return the
16683
  // result of running canonicalize a pathname given pathnameValue.
16684
216k
  if (protocol.empty() || scheme::is_special(protocol)) {
16685
216k
    return url_pattern_helpers::canonicalize_pathname(value);
16686
216k
  }
16687
16688
  // Return the result of running canonicalize an opaque pathname given
16689
  // pathnameValue.
16690
0
  return url_pattern_helpers::canonicalize_opaque_pathname(value);
16691
216k
}
16692
16693
tl::expected<std::string, errors> url_pattern_init::process_search(
16694
25.7k
    std::string_view value, process_type type) {
16695
  // Let strippedValue be the given value with a single leading U+003F (?)
16696
  // removed, if any.
16697
25.7k
  if (value.starts_with("?")) {
16698
12
    value.remove_prefix(1);
16699
12
  }
16700
  // We cannot assert that the value is no longer starting with a single
16701
  // question mark because technically it can start. The question is whether or
16702
  // not we should remove the first question mark. Ref:
16703
  // https://github.com/ada-url/ada/pull/992 The spec is not clear on this.
16704
16705
  // If type is "pattern" then return strippedValue.
16706
25.7k
  if (type == process_type::pattern) {
16707
25.7k
    return std::string(value);
16708
25.7k
  }
16709
  // Return the result of running canonicalize a search given strippedValue.
16710
0
  return url_pattern_helpers::canonicalize_search(value);
16711
25.7k
}
16712
16713
tl::expected<std::string, errors> url_pattern_init::process_hash(
16714
25.9k
    std::string_view value, process_type type) {
16715
  // Let strippedValue be the given value with a single leading U+0023 (#)
16716
  // removed, if any.
16717
25.9k
  if (value.starts_with("#")) {
16718
23
    value.remove_prefix(1);
16719
23
  }
16720
25.9k
  ADA_ASSERT_TRUE(!value.starts_with("#"));
16721
  // If type is "pattern" then return strippedValue.
16722
25.9k
  if (type == process_type::pattern) {
16723
25.9k
    return std::string(value);
16724
25.9k
  }
16725
  // Return the result of running canonicalize a hash given strippedValue.
16726
0
  return url_pattern_helpers::canonicalize_hash(value);
16727
25.9k
}
16728
16729
}  // namespace ada
16730
16731
#endif  // ADA_INCLUDE_URL_PATTERN
16732
/* end file src/url_pattern.cpp */
16733
/* begin file src/url_pattern_helpers.cpp */
16734
#if ADA_INCLUDE_URL_PATTERN
16735
16736
#include <algorithm>
16737
#include <array>
16738
#include <charconv>
16739
#include <optional>
16740
#include <ranges>
16741
#include <string>
16742
16743
16744
namespace ada::url_pattern_helpers {
16745
16746
std::tuple<std::string, std::vector<std::string>>
16747
generate_regular_expression_and_name_list(
16748
    const std::vector<url_pattern_part>& part_list,
16749
44.0k
    url_pattern_compile_component_options options) {
16750
  // Let result be "^"
16751
44.0k
  std::string result = "^";
16752
  // Reserve capacity to reduce reallocations
16753
44.0k
  result.reserve(part_list.size() * 16);
16754
16755
  // Let name list be a new list
16756
44.0k
  std::vector<std::string> name_list{};
16757
44.0k
  name_list.reserve(part_list.size());
16758
16759
  // Pre-generate segment wildcard regexp if needed (avoids repeated generation)
16760
44.0k
  std::string segment_wildcard_regexp;
16761
16762
  // For each part of part list:
16763
56.1k
  for (const url_pattern_part& part : part_list) {
16764
    // If part's type is "fixed-text":
16765
56.1k
    if (part.type == url_pattern_part_type::FIXED_TEXT) {
16766
      // If part's modifier is "none"
16767
6.20k
      if (part.modifier == url_pattern_part_modifier::none) {
16768
5.85k
        result.append(escape_regexp_string(part.value));
16769
5.85k
      } else {
16770
        // (?:<fixed text>)<modifier>
16771
345
        result.append("(?:");
16772
345
        result.append(escape_regexp_string(part.value));
16773
345
        result.push_back(')');
16774
345
        result.append(convert_modifier_to_string(part.modifier));
16775
345
      }
16776
6.20k
      continue;
16777
6.20k
    }
16778
16779
    // Assert: part's name is not the empty string
16780
49.9k
    ADA_ASSERT_TRUE(!part.name.empty());
16781
49.9k
    name_list.push_back(part.name);
16782
16783
    // Use string_view to avoid copies where possible
16784
49.9k
    std::string_view regexp_value = part.value;
16785
16786
49.9k
    if (part.type == url_pattern_part_type::SEGMENT_WILDCARD) {
16787
      // Lazy generate segment wildcard regexp
16788
1.80k
      if (segment_wildcard_regexp.empty()) {
16789
1.36k
        segment_wildcard_regexp = generate_segment_wildcard_regexp(options);
16790
1.36k
      }
16791
1.80k
      regexp_value = segment_wildcard_regexp;
16792
48.1k
    } else if (part.type == url_pattern_part_type::FULL_WILDCARD) {
16793
45.8k
      regexp_value = ".*";
16794
45.8k
    }
16795
16796
    // If part's prefix is the empty string and part's suffix is the empty
16797
    // string
16798
49.9k
    if (part.prefix.empty() && part.suffix.empty()) {
16799
      // If part's modifier is "none" or "optional"
16800
9.72k
      if (part.modifier == url_pattern_part_modifier::none ||
16801
7.80k
          part.modifier == url_pattern_part_modifier::optional) {
16802
        // (<regexp value>)<modifier>
16803
7.80k
        result.push_back('(');
16804
7.80k
        result.append(regexp_value);
16805
7.80k
        result.push_back(')');
16806
7.80k
        result.append(convert_modifier_to_string(part.modifier));
16807
7.80k
      } else {
16808
        // ((?:<regexp value>)<modifier>)
16809
1.92k
        result.append("((?:");
16810
1.92k
        result.append(regexp_value);
16811
1.92k
        result.push_back(')');
16812
1.92k
        result.append(convert_modifier_to_string(part.modifier));
16813
1.92k
        result.push_back(')');
16814
1.92k
      }
16815
9.72k
      continue;
16816
9.72k
    }
16817
16818
    // If part's modifier is "none" or "optional"
16819
40.2k
    if (part.modifier == url_pattern_part_modifier::none ||
16820
38.6k
        part.modifier == url_pattern_part_modifier::optional) {
16821
      // (?:<prefix>(<regexp value>)<suffix>)<modifier>
16822
38.6k
      result.append("(?:");
16823
38.6k
      result.append(escape_regexp_string(part.prefix));
16824
38.6k
      result.push_back('(');
16825
38.6k
      result.append(regexp_value);
16826
38.6k
      result.push_back(')');
16827
38.6k
      result.append(escape_regexp_string(part.suffix));
16828
38.6k
      result.push_back(')');
16829
38.6k
      result.append(convert_modifier_to_string(part.modifier));
16830
38.6k
      continue;
16831
38.6k
    }
16832
16833
    // Assert: part's modifier is "zero-or-more" or "one-or-more"
16834
1.53k
    ADA_ASSERT_TRUE(part.modifier == url_pattern_part_modifier::zero_or_more ||
16835
1.53k
                    part.modifier == url_pattern_part_modifier::one_or_more);
16836
16837
    // Assert: part's prefix is not the empty string or part's suffix is not the
16838
    // empty string
16839
1.53k
    ADA_ASSERT_TRUE(!part.prefix.empty() || !part.suffix.empty());
16840
16841
    // (?:<prefix>((?:<regexp value>)(?:<suffix><prefix>(?:<regexp
16842
    // value>))*)<suffix>)?
16843
    // Append "(?:" to the end of result.
16844
1.53k
    result.append("(?:");
16845
    // Append the result of running escape a regexp string given part's prefix
16846
    // to the end of result.
16847
1.53k
    result.append(escape_regexp_string(part.prefix));
16848
    // Append "((?:" to the end of result.
16849
1.53k
    result.append("((?:");
16850
    // Append regexp value to the end of result.
16851
1.53k
    result.append(regexp_value);
16852
    // Append ")(?:" to the end of result.
16853
1.53k
    result.append(")(?:");
16854
    // Append the result of running escape a regexp string given part's suffix
16855
    // to the end of result.
16856
1.53k
    result.append(escape_regexp_string(part.suffix));
16857
    // Append the result of running escape a regexp string given part's prefix
16858
    // to the end of result.
16859
1.53k
    result.append(escape_regexp_string(part.prefix));
16860
    // Append "(?:" to the end of result.
16861
1.53k
    result.append("(?:");
16862
    // Append regexp value to the end of result.
16863
1.53k
    result.append(regexp_value);
16864
    // Append "))*)" to the end of result.
16865
1.53k
    result.append("))*)");
16866
    // Append the result of running escape a regexp string given part's suffix
16867
    // to the end of result.
16868
1.53k
    result.append(escape_regexp_string(part.suffix));
16869
    // Append ")" to the end of result.
16870
1.53k
    result.append(")");
16871
16872
    // If part's modifier is "zero-or-more" then append "?" to the end of result
16873
1.53k
    if (part.modifier == url_pattern_part_modifier::zero_or_more) {
16874
1.10k
      result += "?";
16875
1.10k
    }
16876
1.53k
  }
16877
16878
  // Append "$" to the end of result
16879
44.0k
  result += "$";
16880
16881
  // Return (result, name list)
16882
44.0k
  return {std::move(result), std::move(name_list)};
16883
44.0k
}
16884
16885
111k
bool is_ipv6_address(std::string_view input) noexcept {
16886
  // If input's code point length is less than 2, then return false.
16887
111k
  if (input.size() < 2) return false;
16888
16889
  // Let input code points be input interpreted as a list of code points.
16890
  // If input code points[0] is U+005B ([), then return true.
16891
65.7k
  if (input.front() == '[') return true;
16892
  // If input code points[0] is U+007B ({) and input code points[1] is U+005B
16893
  // ([), then return true.
16894
65.6k
  if (input.starts_with("{[")) return true;
16895
  // If input code points[0] is U+005C (\) and input code points[1] is U+005B
16896
  // ([), then return true.
16897
65.6k
  return input.starts_with("\\[");
16898
65.6k
}
16899
16900
std::string_view convert_modifier_to_string(
16901
544k
    url_pattern_part_modifier modifier) {
16902
544k
  switch (modifier) {
16903
      // If modifier is "zero-or-more", then return "*".
16904
5.03k
    case url_pattern_part_modifier::zero_or_more:
16905
5.03k
      return "*";
16906
    // If modifier is "optional", then return "?".
16907
746
    case url_pattern_part_modifier::optional:
16908
746
      return "?";
16909
    // If modifier is "one-or-more", then return "+".
16910
868
    case url_pattern_part_modifier::one_or_more:
16911
868
      return "+";
16912
    // Return the empty string.
16913
537k
    default:
16914
537k
      return "";
16915
544k
  }
16916
544k
}
16917
16918
std::string generate_segment_wildcard_regexp(
16919
927k
    url_pattern_compile_component_options options) {
16920
  // Let result be "[^".
16921
927k
  std::string result = "[^";
16922
  // Append the result of running escape a regexp string given options's
16923
  // delimiter code point to the end of result.
16924
927k
  result.append(escape_regexp_string(options.get_delimiter()));
16925
  // Append "]+?" to the end of result.
16926
927k
  result.append("]+?");
16927
  // Return result.
16928
927k
  ada_log("generate_segment_wildcard_regexp result: ", result);
16929
927k
  return result;
16930
927k
}
16931
16932
namespace {
16933
// Unified lookup table for URL pattern character classification
16934
// Bit flags for different character types
16935
constexpr uint8_t CHAR_SCHEME = 1;  // valid in scheme (a-z, A-Z, 0-9, +, -, .)
16936
constexpr uint8_t CHAR_UPPER = 2;   // uppercase letter (needs lowercasing)
16937
constexpr uint8_t CHAR_SIMPLE_HOSTNAME = 4;  // simple hostname (a-z, 0-9, -, .)
16938
constexpr uint8_t CHAR_SIMPLE_PATHNAME =
16939
    8;  // simple pathname (a-z, A-Z, 0-9, /, -, _, ~)
16940
16941
constexpr std::array<uint8_t, 256> char_class_table = []() consteval {
16942
  std::array<uint8_t, 256> table{};
16943
  for (int c = 'a'; c <= 'z'; c++)
16944
    table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
16945
  for (int c = 'A'; c <= 'Z'; c++)
16946
    table[c] = CHAR_SCHEME | CHAR_UPPER | CHAR_SIMPLE_PATHNAME;
16947
  for (int c = '0'; c <= '9'; c++)
16948
    table[c] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
16949
  table['+'] = CHAR_SCHEME;
16950
  table['-'] = CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME | CHAR_SIMPLE_PATHNAME;
16951
  table['.'] =
16952
      CHAR_SCHEME | CHAR_SIMPLE_HOSTNAME;  // not pathname (needs normalization)
16953
  table['/'] = CHAR_SIMPLE_PATHNAME;
16954
  table['_'] = CHAR_SIMPLE_PATHNAME;
16955
  table['~'] = CHAR_SIMPLE_PATHNAME;
16956
  return table;
16957
}();
16958
}  // namespace
16959
16960
tl::expected<std::string, errors> canonicalize_protocol(
16961
160k
    std::string_view input) {
16962
160k
  ada_log("canonicalize_protocol called with input=", input);
16963
160k
  if (input.empty()) [[unlikely]] {
16964
56.3k
    return "";
16965
56.3k
  }
16966
16967
103k
  if (input.ends_with(":")) {
16968
19
    input.remove_suffix(1);
16969
19
  }
16970
16971
  // Fast path: special schemes are already canonical
16972
103k
  if (scheme::is_special(input)) {
16973
101k
    return std::string(input);
16974
101k
  }
16975
16976
  // Fast path: validate scheme chars and check for uppercase
16977
  // First char must be alpha (not +, -, ., or digit)
16978
2.82k
  uint8_t first_flags = char_class_table[static_cast<uint8_t>(input[0])];
16979
2.82k
  if (!(first_flags & CHAR_SCHEME) || input[0] == '+' || input[0] == '-' ||
16980
1.90k
      input[0] == '.' || unicode::is_ascii_digit(input[0])) {
16981
1.90k
    return tl::unexpected(errors::type_error);
16982
1.90k
  }
16983
16984
923
  uint8_t needs_lowercase = first_flags & CHAR_UPPER;
16985
1.45k
  for (size_t i = 1; i < input.size(); i++) {
16986
563
    uint8_t flags = char_class_table[static_cast<uint8_t>(input[i])];
16987
563
    if (!(flags & CHAR_SCHEME)) {
16988
28
      return tl::unexpected(errors::type_error);
16989
28
    }
16990
535
    needs_lowercase |= flags & CHAR_UPPER;
16991
535
  }
16992
16993
895
  if (needs_lowercase == 0) {
16994
477
    return std::string(input);
16995
477
  }
16996
16997
418
  std::string result(input);
16998
418
  unicode::to_lower_ascii(result.data(), result.size());
16999
418
  return result;
17000
895
}
17001
17002
tl::expected<std::string, errors> canonicalize_username(
17003
178k
    std::string_view input) {
17004
  // If value is the empty string, return value.
17005
178k
  if (input.empty()) [[unlikely]] {
17006
177k
    return "";
17007
177k
  }
17008
  // Percent-encode the input using the userinfo percent-encode set.
17009
1.18k
  size_t idx = ada::unicode::percent_encode_index(
17010
1.18k
      input, character_sets::USERINFO_PERCENT_ENCODE);
17011
1.18k
  if (idx == input.size()) {
17012
    // No encoding needed, return input as-is
17013
635
    return std::string(input);
17014
635
  }
17015
  // Percent-encode from the first character that needs encoding
17016
550
  return ada::unicode::percent_encode(
17017
550
      input, character_sets::USERINFO_PERCENT_ENCODE, idx);
17018
1.18k
}
17019
17020
tl::expected<std::string, errors> canonicalize_password(
17021
177k
    std::string_view input) {
17022
  // If value is the empty string, return value.
17023
177k
  if (input.empty()) [[unlikely]] {
17024
177k
    return "";
17025
177k
  }
17026
  // Percent-encode the input using the userinfo percent-encode set.
17027
798
  size_t idx = ada::unicode::percent_encode_index(
17028
798
      input, character_sets::USERINFO_PERCENT_ENCODE);
17029
798
  if (idx == input.size()) {
17030
    // No encoding needed, return input as-is
17031
437
    return std::string(input);
17032
437
  }
17033
  // Percent-encode from the first character that needs encoding
17034
361
  return ada::unicode::percent_encode(
17035
361
      input, character_sets::USERINFO_PERCENT_ENCODE, idx);
17036
798
}
17037
17038
tl::expected<std::string, errors> canonicalize_hostname(
17039
120k
    std::string_view input) {
17040
120k
  ada_log("canonicalize_hostname input=", input);
17041
120k
  if (input.empty()) [[unlikely]] {
17042
53.4k
    return "";
17043
53.4k
  }
17044
17045
  // Fast path: simple hostnames (lowercase ASCII, digits, -, .) need no IDNA
17046
66.6k
  bool needs_processing = false;
17047
710k
  for (char c : input) {
17048
710k
    needs_processing |=
17049
710k
        !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_HOSTNAME);
17050
710k
  }
17051
66.6k
  if (!needs_processing) {
17052
63.5k
    return std::string(input);
17053
63.5k
  }
17054
17055
  // Let dummyURL be a new URL record.
17056
  // Let parseResult be the result of running the basic URL parser given value
17057
  // with dummyURL as url and hostname state as state override.
17058
17059
  // IMPORTANT: The protocol needs to be a special protocol, otherwise the
17060
  // hostname will not be converted using IDNA.
17061
3.12k
  auto url = ada::parse<url_aggregator>("https://dummy.test", nullptr);
17062
3.12k
  ADA_ASSERT_TRUE(url);
17063
  // if (!isValidHostnameInput(hostname)) return kj::none;
17064
3.12k
  if (!url->set_hostname(input)) {
17065
    // If parseResult is failure, then throw a TypeError.
17066
1.16k
    return tl::unexpected(errors::type_error);
17067
1.16k
  }
17068
  // Return dummyURL's host, serialized, or empty string if it is null.
17069
1.96k
  return std::string(url->get_hostname());
17070
3.12k
}
17071
17072
tl::expected<std::string, errors> canonicalize_ipv6_hostname(
17073
374
    std::string_view input) {
17074
374
  ada_log("canonicalize_ipv6_hostname input=", input);
17075
  // TODO: Optimization opportunity: Use lookup table to speed up checking
17076
998
  if (std::ranges::any_of(input, [](char c) {
17077
998
        return c != '[' && c != ']' && c != ':' &&
17078
437
               !unicode::is_ascii_hex_digit(c);
17079
998
      })) {
17080
23
    return tl::unexpected(errors::type_error);
17081
23
  }
17082
  // Append the result of running ASCII lowercase given code point to the end of
17083
  // result.
17084
351
  auto hostname = std::string(input);
17085
351
  unicode::to_lower_ascii(hostname.data(), hostname.size());
17086
351
  return hostname;
17087
374
}
17088
17089
tl::expected<std::string, errors> canonicalize_port(
17090
49.1k
    std::string_view port_value) {
17091
  // If portValue is the empty string, return portValue.
17092
49.1k
  if (port_value.empty()) [[unlikely]] {
17093
48.4k
    return "";
17094
48.4k
  }
17095
17096
  // Remove ASCII tab or newline characters
17097
648
  std::string trimmed(port_value);
17098
648
  helpers::remove_ascii_tab_or_newline(trimmed);
17099
17100
648
  if (trimmed.empty()) {
17101
127
    return "";
17102
127
  }
17103
17104
  // Input should start with a digit character
17105
521
  if (!unicode::is_ascii_digit(trimmed.front())) {
17106
262
    return tl::unexpected(errors::type_error);
17107
262
  }
17108
17109
  // Find the first non-digit character
17110
259
  auto first_non_digit =
17111
259
      std::ranges::find_if_not(trimmed, unicode::is_ascii_digit);
17112
259
  std::string_view digits_to_parse =
17113
259
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
17114
17115
  // Here we have that a range of ASCII digit characters identified
17116
  // by digits_to_parse. It is none empty.
17117
  // We want to determine whether it is a valid port number (0-65535).
17118
  // Clearly, if the length is greater than 5, it is invalid.
17119
  // If the length is 5, we need to compare lexicographically to "65535".
17120
  // Otherwise it is valid.
17121
259
  if (digits_to_parse.size() == 5) {
17122
34
    if (digits_to_parse > "65535") {
17123
7
      return tl::unexpected(errors::type_error);
17124
7
    }
17125
225
  } else if (digits_to_parse.size() > 5) {
17126
0
    return tl::unexpected(errors::type_error);
17127
0
  }
17128
252
  if (digits_to_parse[0] == '0' && digits_to_parse.size() > 1) {
17129
    // Leading zeros are not allowed for multi-digit ports
17130
12
    return tl::unexpected(errors::type_error);
17131
12
  }
17132
  // It is valid! Most times, we do not need to parse it into an integer.
17133
240
  return std::string(digits_to_parse);
17134
252
}
17135
17136
tl::expected<std::string, errors> canonicalize_port_with_protocol(
17137
0
    std::string_view port_value, std::string_view protocol) {
17138
  // If portValue is the empty string, return portValue.
17139
0
  if (port_value.empty()) [[unlikely]] {
17140
0
    return "";
17141
0
  }
17142
17143
  // Handle empty or trailing colon in protocol
17144
0
  if (protocol.empty()) {
17145
0
    protocol = "fake";
17146
0
  } else if (protocol.ends_with(":")) {
17147
0
    protocol.remove_suffix(1);
17148
0
  }
17149
17150
  // Remove ASCII tab or newline characters
17151
0
  std::string trimmed(port_value);
17152
0
  helpers::remove_ascii_tab_or_newline(trimmed);
17153
17154
0
  if (trimmed.empty()) {
17155
0
    return "";
17156
0
  }
17157
17158
  // Input should start with a digit character
17159
0
  if (!unicode::is_ascii_digit(trimmed.front())) {
17160
0
    return tl::unexpected(errors::type_error);
17161
0
  }
17162
17163
  // Find the first non-digit character
17164
0
  auto first_non_digit =
17165
0
      std::ranges::find_if_not(trimmed, unicode::is_ascii_digit);
17166
0
  std::string_view digits_to_parse =
17167
0
      std::string_view(trimmed.data(), first_non_digit - trimmed.begin());
17168
17169
  // Parse the port number
17170
0
  uint16_t parsed_port{};
17171
  // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
17172
0
  auto result = std::from_chars(digits_to_parse.data(),
17173
0
                                digits_to_parse.data() + digits_to_parse.size(),
17174
0
                                parsed_port);
17175
17176
0
  if (result.ec == std::errc::result_out_of_range) {
17177
0
    return tl::unexpected(errors::type_error);
17178
0
  }
17179
17180
0
  if (result.ec == std::errc()) {
17181
    // Check if this is the default port for the scheme
17182
0
    uint16_t default_port = scheme::get_special_port(protocol);
17183
17184
    // If it's the default port for a special scheme, return empty string
17185
0
    if (default_port != 0 && default_port == parsed_port) {
17186
0
      return "";
17187
0
    }
17188
17189
    // Successfully parsed, return as string
17190
0
    return std::to_string(parsed_port);
17191
0
  }
17192
17193
0
  return tl::unexpected(errors::type_error);
17194
0
}
17195
17196
tl::expected<std::string, errors> canonicalize_pathname(
17197
372k
    std::string_view input) {
17198
372k
  if (input.empty()) [[unlikely]] {
17199
88.7k
    return "";
17200
88.7k
  }
17201
17202
  // Fast path: simple pathnames (no . which needs normalization) can be
17203
  // returned as-is
17204
283k
  bool needs_processing = false;
17205
2.90M
  for (char c : input) {
17206
2.90M
    needs_processing |=
17207
2.90M
        !(char_class_table[static_cast<uint8_t>(c)] & CHAR_SIMPLE_PATHNAME);
17208
2.90M
  }
17209
283k
  if (!needs_processing) {
17210
65.6k
    return std::string(input);
17211
65.6k
  }
17212
17213
  // Let leading slash be true if the first code point in value is U+002F (/)
17214
  // and otherwise false.
17215
218k
  const bool leading_slash = input.starts_with("/");
17216
  // Let modified value be "/-" if leading slash is false and otherwise the
17217
  // empty string.
17218
218k
  const auto modified_value = leading_slash ? "" : "/-";
17219
218k
  const auto full_url =
17220
218k
      std::string("fake://fake-url") + modified_value + std::string(input);
17221
218k
  if (auto url = ada::parse<url_aggregator>(full_url, nullptr)) {
17222
218k
    const auto pathname = url->get_pathname();
17223
    // If leading slash is false, then set result to the code point substring
17224
    // from 2 to the end of the string within result.
17225
218k
    if (!leading_slash) {
17226
      // pathname should start with "/-" but path traversal (e.g. "../../")
17227
      // can reduce it to just "/" which is shorter than 2 characters.
17228
217k
      if (pathname.size() < 2) {
17229
583
        return tl::unexpected(errors::type_error);
17230
583
      }
17231
216k
      return std::string(pathname.substr(2));
17232
217k
    }
17233
507
    return std::string(pathname);
17234
218k
  }
17235
  // If parseResult is failure, then throw a TypeError.
17236
0
  return tl::unexpected(errors::type_error);
17237
218k
}
17238
17239
tl::expected<std::string, errors> canonicalize_opaque_pathname(
17240
24.0k
    std::string_view input) {
17241
  // If value is the empty string, return value.
17242
24.0k
  if (input.empty()) [[unlikely]] {
17243
2.41k
    return "";
17244
2.41k
  }
17245
  // Let dummyURL be a new URL record.
17246
  // Set dummyURL's path to the empty string.
17247
  // Let parseResult be the result of running URL parsing given value with
17248
  // dummyURL as url and opaque path state as state override.
17249
21.6k
  if (auto url =
17250
21.6k
          ada::parse<url_aggregator>("fake:" + std::string(input), nullptr)) {
17251
    // Return the result of URL path serializing dummyURL.
17252
21.3k
    return std::string(url->get_pathname());
17253
21.3k
  }
17254
  // If parseResult is failure, then throw a TypeError.
17255
238
  return tl::unexpected(errors::type_error);
17256
21.6k
}
17257
17258
174k
tl::expected<std::string, errors> canonicalize_search(std::string_view input) {
17259
  // If value is the empty string, return value.
17260
174k
  if (input.empty()) [[unlikely]] {
17261
173k
    return "";
17262
173k
  }
17263
  // Remove leading '?' if present
17264
687
  std::string new_value;
17265
687
  new_value = input[0] == '?' ? input.substr(1) : input;
17266
  // Remove ASCII tab or newline characters
17267
687
  helpers::remove_ascii_tab_or_newline(new_value);
17268
17269
687
  if (new_value.empty()) {
17270
126
    return "";
17271
126
  }
17272
17273
  // Percent-encode using QUERY_PERCENT_ENCODE (for non-special URLs)
17274
  // Note: "fake://dummy.test" is not a special URL, so we use
17275
  // QUERY_PERCENT_ENCODE
17276
561
  size_t idx = ada::unicode::percent_encode_index(
17277
561
      new_value, character_sets::QUERY_PERCENT_ENCODE);
17278
561
  if (idx == new_value.size()) {
17279
    // No encoding needed
17280
304
    return new_value;
17281
304
  }
17282
  // Percent-encode from the first character that needs encoding
17283
257
  return ada::unicode::percent_encode(
17284
257
      new_value, character_sets::QUERY_PERCENT_ENCODE, idx);
17285
561
}
17286
17287
173k
tl::expected<std::string, errors> canonicalize_hash(std::string_view input) {
17288
  // If value is the empty string, return value.
17289
173k
  if (input.empty()) [[unlikely]] {
17290
173k
    return "";
17291
173k
  }
17292
  // Remove leading '#' if present
17293
504
  std::string new_value;
17294
504
  new_value = input[0] == '#' ? input.substr(1) : input;
17295
  // Remove ASCII tab or newline characters
17296
504
  helpers::remove_ascii_tab_or_newline(new_value);
17297
17298
504
  if (new_value.empty()) {
17299
105
    return "";
17300
105
  }
17301
17302
  // Percent-encode using FRAGMENT_PERCENT_ENCODE
17303
399
  size_t idx = ada::unicode::percent_encode_index(
17304
399
      new_value, character_sets::FRAGMENT_PERCENT_ENCODE);
17305
399
  if (idx == new_value.size()) {
17306
    // No encoding needed
17307
219
    return new_value;
17308
219
  }
17309
  // Percent-encode from the first character that needs encoding
17310
180
  return ada::unicode::percent_encode(
17311
180
      new_value, character_sets::FRAGMENT_PERCENT_ENCODE, idx);
17312
399
}
17313
17314
tl::expected<std::vector<token>, errors> tokenize(std::string_view input,
17315
1.00M
                                                  token_policy policy) {
17316
1.00M
  ada_log("tokenize input: ", input);
17317
  // Let tokenizer be a new tokenizer.
17318
  // Set tokenizer's input to input.
17319
  // Set tokenizer's policy to policy.
17320
1.00M
  auto tokenizer = Tokenizer(input, policy);
17321
  // While tokenizer's index is less than tokenizer's input's code point length:
17322
3.76M
  while (tokenizer.index < tokenizer.input.size()) {
17323
    // Run seek and get the next code point given tokenizer and tokenizer's
17324
    // index.
17325
2.76M
    tokenizer.seek_and_get_next_code_point(tokenizer.index);
17326
17327
    // Malformed UTF-8 must not stall tokenization: report an invalid-char
17328
    // token (lenient) or fail fast (strict), while always making progress.
17329
2.76M
    if (tokenizer.had_invalid_code_point()) {
17330
0
      if (auto error = tokenizer.process_tokenizing_error(tokenizer.next_index,
17331
0
                                                          tokenizer.index)) {
17332
0
        return tl::unexpected(*error);
17333
0
      }
17334
0
      continue;
17335
0
    }
17336
17337
    // If tokenizer's code point is U+002A (*):
17338
2.76M
    if (tokenizer.code_point == '*') {
17339
      // Run add a token with default position and length given tokenizer and
17340
      // "asterisk".
17341
534k
      tokenizer.add_token_with_defaults(token_type::ASTERISK);
17342
534k
      ada_log("add ASTERISK token");
17343
      // Continue.
17344
534k
      continue;
17345
534k
    }
17346
17347
    // If tokenizer's code point is U+002B (+) or U+003F (?):
17348
2.22M
    if (tokenizer.code_point == '+' || tokenizer.code_point == '?') {
17349
      // Run add a token with default position and length given tokenizer and
17350
      // "other-modifier".
17351
4.76k
      tokenizer.add_token_with_defaults(token_type::OTHER_MODIFIER);
17352
      // Continue.
17353
4.76k
      continue;
17354
4.76k
    }
17355
17356
    // If tokenizer's code point is U+005C (\):
17357
2.22M
    if (tokenizer.code_point == '\\') {
17358
      // If tokenizer's index is equal to tokenizer's input's code point length
17359
      // - 1:
17360
4.28k
      if (tokenizer.index == tokenizer.input.size() - 1) {
17361
        // Run process a tokenizing error given tokenizer, tokenizer's next
17362
        // index, and tokenizer's index.
17363
637
        if (auto error = tokenizer.process_tokenizing_error(
17364
637
                tokenizer.next_index, tokenizer.index)) {
17365
574
          ada_log("process_tokenizing_error failed");
17366
574
          return tl::unexpected(*error);
17367
574
        }
17368
63
        continue;
17369
637
      }
17370
17371
      // Let escaped index be tokenizer's next index.
17372
3.65k
      auto escaped_index = tokenizer.next_index;
17373
      // Run get the next code point given tokenizer.
17374
3.65k
      tokenizer.get_next_code_point();
17375
3.65k
      if (tokenizer.had_invalid_code_point()) {
17376
0
        if (auto error = tokenizer.process_tokenizing_error(tokenizer.next_index,
17377
0
                                                            escaped_index)) {
17378
0
          return tl::unexpected(*error);
17379
0
        }
17380
0
        continue;
17381
0
      }
17382
      // Run add a token with default length given tokenizer, "escaped-char",
17383
      // tokenizer's next index, and escaped index.
17384
3.65k
      tokenizer.add_token_with_default_length(
17385
3.65k
          token_type::ESCAPED_CHAR, tokenizer.next_index, escaped_index);
17386
3.65k
      ada_log("add ESCAPED_CHAR token on next_index ", tokenizer.next_index,
17387
3.65k
              " with escaped index ", escaped_index);
17388
      // Continue.
17389
3.65k
      continue;
17390
3.65k
    }
17391
17392
    // If tokenizer's code point is U+007B ({):
17393
2.21M
    if (tokenizer.code_point == '{') {
17394
      // Run add a token with default position and length given tokenizer and
17395
      // "open".
17396
4.67k
      tokenizer.add_token_with_defaults(token_type::OPEN);
17397
4.67k
      ada_log("add OPEN token");
17398
4.67k
      continue;
17399
4.67k
    }
17400
17401
    // If tokenizer's code point is U+007D (}):
17402
2.21M
    if (tokenizer.code_point == '}') {
17403
      // Run add a token with default position and length given tokenizer and
17404
      // "close".
17405
4.94k
      tokenizer.add_token_with_defaults(token_type::CLOSE);
17406
4.94k
      ada_log("add CLOSE token");
17407
4.94k
      continue;
17408
4.94k
    }
17409
17410
    // If tokenizer's code point is U+003A (:):
17411
2.20M
    if (tokenizer.code_point == ':') {
17412
      // Let name position be tokenizer's next index.
17413
44.9k
      auto name_position = tokenizer.next_index;
17414
      // Let name start be name position.
17415
44.9k
      auto name_start = name_position;
17416
44.9k
      bool invalid_name = false;
17417
      // While name position is less than tokenizer's input's code point length:
17418
53.6k
      while (name_position < tokenizer.input.size()) {
17419
        // Run seek and get the next code point given tokenizer and name
17420
        // position.
17421
52.2k
        tokenizer.seek_and_get_next_code_point(name_position);
17422
52.2k
        if (tokenizer.had_invalid_code_point()) {
17423
0
          if (auto error = tokenizer.process_tokenizing_error(
17424
0
                  tokenizer.next_index, name_position)) {
17425
0
            return tl::unexpected(*error);
17426
0
          }
17427
0
          invalid_name = true;
17428
0
          break;
17429
0
        }
17430
        // Let first code point be true if name position equals name start and
17431
        // false otherwise.
17432
52.2k
        bool first_code_point = name_position == name_start;
17433
        // Let valid code point be the result of running is a valid name code
17434
        // point given tokenizer's code point and first code point.
17435
52.2k
        auto valid_code_point =
17436
52.2k
            idna::valid_name_code_point(tokenizer.code_point, first_code_point);
17437
52.2k
        ada_log("tokenizer.code_point=", uint32_t(tokenizer.code_point),
17438
52.2k
                " first_code_point=", first_code_point,
17439
52.2k
                " valid_code_point=", valid_code_point);
17440
        // If valid code point is false break.
17441
52.2k
        if (!valid_code_point) break;
17442
        // Set name position to tokenizer's next index.
17443
8.62k
        name_position = tokenizer.next_index;
17444
8.62k
      }
17445
17446
44.9k
      if (invalid_name) {
17447
0
        continue;
17448
0
      }
17449
17450
      // If name position is less than or equal to name start:
17451
44.9k
      if (name_position <= name_start) {
17452
        // Run process a tokenizing error given tokenizer, name start, and
17453
        // tokenizer's index.
17454
40.6k
        if (auto error = tokenizer.process_tokenizing_error(name_start,
17455
40.6k
                                                            tokenizer.index)) {
17456
272
          ada_log("process_tokenizing_error failed");
17457
272
          return tl::unexpected(*error);
17458
272
        }
17459
        // Continue
17460
40.3k
        continue;
17461
40.6k
      }
17462
17463
      // Run add a token with default length given tokenizer, "name", name
17464
      // position, and name start.
17465
4.34k
      tokenizer.add_token_with_default_length(token_type::NAME, name_position,
17466
4.34k
                                              name_start);
17467
4.34k
      continue;
17468
44.9k
    }
17469
17470
    // If tokenizer's code point is U+0028 (():
17471
2.16M
    if (tokenizer.code_point == '(') {
17472
      // Let depth be 1.
17473
6.63k
      size_t depth = 1;
17474
      // Let regexp position be tokenizer's next index.
17475
6.63k
      auto regexp_position = tokenizer.next_index;
17476
      // Let regexp start be regexp position.
17477
6.63k
      auto regexp_start = regexp_position;
17478
      // Let error be false.
17479
6.63k
      bool error = false;
17480
17481
      // While regexp position is less than tokenizer's input's code point
17482
      // length:
17483
23.5k
      while (regexp_position < tokenizer.input.size()) {
17484
        // Run seek and get the next code point given tokenizer and regexp
17485
        // position.
17486
22.9k
        tokenizer.seek_and_get_next_code_point(regexp_position);
17487
22.9k
        if (tokenizer.had_invalid_code_point()) {
17488
0
          if (auto process_error = tokenizer.process_tokenizing_error(
17489
0
                  tokenizer.next_index, regexp_position)) {
17490
0
            return tl::unexpected(*process_error);
17491
0
          }
17492
0
          error = true;
17493
0
          break;
17494
0
        }
17495
17496
        // TODO: Optimization opportunity: The next 2 if statements can be
17497
        // merged. If the result of running is ASCII given tokenizer's code
17498
        // point is false:
17499
22.9k
        if (!unicode::is_ascii(tokenizer.code_point)) {
17500
          // Run process a tokenizing error given tokenizer, regexp start, and
17501
          // tokenizer's index.
17502
0
          if (auto process_error = tokenizer.process_tokenizing_error(
17503
0
                  regexp_start, tokenizer.index)) {
17504
0
            return tl::unexpected(*process_error);
17505
0
          }
17506
          // Set error to true.
17507
0
          error = true;
17508
0
          break;
17509
0
        }
17510
17511
        // If regexp position equals regexp start and tokenizer's code point is
17512
        // U+003F (?):
17513
22.9k
        if (regexp_position == regexp_start && tokenizer.code_point == '?') {
17514
          // Run process a tokenizing error given tokenizer, regexp start, and
17515
          // tokenizer's index.
17516
531
          if (auto process_error = tokenizer.process_tokenizing_error(
17517
531
                  regexp_start, tokenizer.index)) {
17518
12
            return tl::unexpected(*process_error);
17519
12
          }
17520
          // Set error to true;
17521
519
          error = true;
17522
519
          break;
17523
531
        }
17524
17525
        // If tokenizer's code point is U+005C (\):
17526
22.4k
        if (tokenizer.code_point == '\\') {
17527
          // If regexp position equals tokenizer's input's code point length - 1
17528
1.89k
          if (regexp_position == tokenizer.input.size() - 1) {
17529
            // Run process a tokenizing error given tokenizer, regexp start, and
17530
            // tokenizer's index.
17531
38
            if (auto process_error = tokenizer.process_tokenizing_error(
17532
38
                    regexp_start, tokenizer.index)) {
17533
20
              return tl::unexpected(*process_error);
17534
20
            }
17535
            // Set error to true.
17536
18
            error = true;
17537
18
            break;
17538
38
          }
17539
          // Run get the next code point given tokenizer.
17540
1.86k
          auto escaped_index = tokenizer.next_index;
17541
1.86k
          tokenizer.get_next_code_point();
17542
1.86k
          if (tokenizer.had_invalid_code_point()) {
17543
0
            if (auto process_error = tokenizer.process_tokenizing_error(
17544
0
                    tokenizer.next_index, escaped_index)) {
17545
0
              return tl::unexpected(*process_error);
17546
0
            }
17547
0
            error = true;
17548
0
            break;
17549
0
          }
17550
          // If the result of running is ASCII given tokenizer's code point is
17551
          // false:
17552
1.86k
          if (!unicode::is_ascii(tokenizer.code_point)) {
17553
            // Run process a tokenizing error given tokenizer, regexp start, and
17554
            // tokenizer's index.
17555
0
            if (auto process_error = tokenizer.process_tokenizing_error(
17556
0
                    regexp_start, tokenizer.index);
17557
0
                process_error.has_value()) {
17558
0
              return tl::unexpected(*process_error);
17559
0
            }
17560
            // Set error to true.
17561
0
            error = true;
17562
0
            break;
17563
0
          }
17564
          // Set regexp position to tokenizer's next index.
17565
1.86k
          regexp_position = tokenizer.next_index;
17566
1.86k
          continue;
17567
1.86k
        }
17568
17569
        // If tokenizer's code point is U+0029 ()):
17570
20.5k
        if (tokenizer.code_point == ')') {
17571
          // Decrement depth by 1.
17572
4.19k
          depth--;
17573
          // If depth is 0:
17574
4.19k
          if (depth == 0) {
17575
            // Set regexp position to tokenizer's next index.
17576
3.74k
            regexp_position = tokenizer.next_index;
17577
            // Break.
17578
3.74k
            break;
17579
3.74k
          }
17580
16.3k
        } else if (tokenizer.code_point == '(') {
17581
          // Otherwise if tokenizer's code point is U+0028 (():
17582
          // Increment depth by 1.
17583
2.54k
          depth++;
17584
          // If regexp position equals tokenizer's input's code point length -
17585
          // 1:
17586
2.54k
          if (regexp_position == tokenizer.input.size() - 1) {
17587
            // Run process a tokenizing error given tokenizer, regexp start, and
17588
            // tokenizer's index.
17589
31
            if (auto process_error = tokenizer.process_tokenizing_error(
17590
31
                    regexp_start, tokenizer.index)) {
17591
22
              return tl::unexpected(*process_error);
17592
22
            }
17593
            // Set error to true.
17594
9
            error = true;
17595
9
            break;
17596
31
          }
17597
          // Let temporary position be tokenizer's next index.
17598
2.51k
          auto temporary_position = tokenizer.next_index;
17599
          // Run get the next code point given tokenizer.
17600
2.51k
          tokenizer.get_next_code_point();
17601
2.51k
          if (tokenizer.had_invalid_code_point()) {
17602
0
            if (auto process_error = tokenizer.process_tokenizing_error(
17603
0
                    tokenizer.next_index, temporary_position)) {
17604
0
              return tl::unexpected(*process_error);
17605
0
            }
17606
0
            error = true;
17607
0
            break;
17608
0
          }
17609
          // If tokenizer's code point is not U+003F (?):
17610
2.51k
          if (tokenizer.code_point != '?') {
17611
            // Run process a tokenizing error given tokenizer, regexp start, and
17612
            // tokenizer's index.
17613
1.72k
            if (auto process_error = tokenizer.process_tokenizing_error(
17614
1.72k
                    regexp_start, tokenizer.index)) {
17615
21
              return tl::unexpected(*process_error);
17616
21
            }
17617
            // Set error to true.
17618
1.70k
            error = true;
17619
1.70k
            break;
17620
1.72k
          }
17621
          // Set tokenizer's next index to temporary position.
17622
788
          tokenizer.next_index = temporary_position;
17623
788
        }
17624
        // Set regexp position to tokenizer's next index.
17625
15.0k
        regexp_position = tokenizer.next_index;
17626
15.0k
      }
17627
17628
      // If error is true continue.
17629
6.55k
      if (error) continue;
17630
      // If depth is not zero:
17631
4.31k
      if (depth != 0) {
17632
        // Run process a tokenizing error given tokenizer, regexp start, and
17633
        // tokenizer's index.
17634
569
        if (auto process_error = tokenizer.process_tokenizing_error(
17635
569
                regexp_start, tokenizer.index)) {
17636
248
          return tl::unexpected(*process_error);
17637
248
        }
17638
321
        continue;
17639
569
      }
17640
      // Let regexp length be regexp position - regexp start - 1.
17641
3.74k
      auto regexp_length = regexp_position - regexp_start - 1;
17642
      // If regexp length is zero:
17643
3.74k
      if (regexp_length == 0) {
17644
        // Run process a tokenizing error given tokenizer, regexp start, and
17645
        // tokenizer's index.
17646
285
        if (auto process_error = tokenizer.process_tokenizing_error(
17647
285
                regexp_start, tokenizer.index)) {
17648
36
          ada_log("process_tokenizing_error failed");
17649
36
          return tl::unexpected(*process_error);
17650
36
        }
17651
249
        continue;
17652
285
      }
17653
      // Run add a token given tokenizer, "regexp", regexp position, regexp
17654
      // start, and regexp length.
17655
3.45k
      tokenizer.add_token(token_type::REGEXP, regexp_position, regexp_start,
17656
3.45k
                          regexp_length);
17657
3.45k
      continue;
17658
3.74k
    }
17659
    // Run add a token with default position and length given tokenizer and
17660
    // "char".
17661
2.15M
    tokenizer.add_token_with_defaults(token_type::CHAR);
17662
2.15M
  }
17663
  // Run add a token with default length given tokenizer, "end", tokenizer's
17664
  // index, and tokenizer's index.
17665
999k
  tokenizer.add_token_with_default_length(token_type::END, tokenizer.index,
17666
999k
                                          tokenizer.index);
17667
17668
999k
  ada_log("tokenizer.token_list size is: ", tokenizer.token_list.size());
17669
  // Return tokenizer's token list.
17670
999k
  return tokenizer.token_list;
17671
1.00M
}
17672
17673
namespace {
17674
constexpr std::array<uint8_t, 256> escape_pattern_table = []() consteval {
17675
  std::array<uint8_t, 256> out{};
17676
  for (auto& c : {'+', '*', '?', ':', '{', '}', '(', ')', '\\'}) {
17677
    out[c] = 1;
17678
  }
17679
  return out;
17680
}();
17681
17682
1.73M
constexpr bool should_escape_pattern_char(char c) {
17683
1.73M
  return escape_pattern_table[static_cast<uint8_t>(c)];
17684
1.73M
}
17685
}  // namespace
17686
17687
1.26M
std::string escape_pattern_string(std::string_view input) {
17688
1.26M
  ada_log("escape_pattern_string called with input=", input);
17689
1.26M
  if (input.empty()) [[unlikely]] {
17690
951k
    return "";
17691
951k
  }
17692
  // Assert: input is an ASCII string.
17693
309k
  ADA_ASSERT_TRUE(ada::idna::is_ascii(input));
17694
  // Let result be the empty string.
17695
309k
  std::string result{};
17696
  // Reserve extra space for potential escapes
17697
309k
  result.reserve(input.size() * 2);
17698
17699
  // While index is less than input's length:
17700
1.73M
  for (const char c : input) {
17701
1.73M
    if (should_escape_pattern_char(c)) {
17702
      // Append U+005C (\) to the end of result.
17703
1.20k
      result.push_back('\\');
17704
1.20k
    }
17705
    // Append c to the end of result.
17706
1.73M
    result.push_back(c);
17707
1.73M
  }
17708
  // Return result.
17709
309k
  return result;
17710
1.26M
}
17711
17712
namespace {
17713
constexpr std::array<uint8_t, 256> escape_regexp_table = []() consteval {
17714
  std::array<uint8_t, 256> out{};
17715
  for (auto& c : {'.', '+', '*', '?', '^', '$', '{', '}', '(', ')', '[', ']',
17716
                  '|', '/', '\\'}) {
17717
    out[c] = 1;
17718
  }
17719
  return out;
17720
}();
17721
17722
275k
constexpr bool should_escape_regexp_char(char c) {
17723
275k
  return escape_regexp_table[(uint8_t)c];
17724
275k
}
17725
}  // namespace
17726
17727
1.01M
std::string escape_regexp_string(std::string_view input) {
17728
  // Assert: input is an ASCII string.
17729
1.01M
  ADA_ASSERT_TRUE(idna::is_ascii(input));
17730
  // Let result be the empty string.
17731
1.01M
  std::string result{};
17732
  // Reserve extra space for potential escapes (worst case: all chars escaped)
17733
1.01M
  result.reserve(input.size() * 2);
17734
1.01M
  for (const char c : input) {
17735
275k
    if (should_escape_regexp_char(c)) {
17736
      // Avoid temporary string allocation - directly append characters
17737
244k
      result.push_back('\\');
17738
244k
      result.push_back(c);
17739
244k
    } else {
17740
30.5k
      result.push_back(c);
17741
30.5k
    }
17742
275k
  }
17743
1.01M
  return result;
17744
1.01M
}
17745
17746
std::string process_base_url_string(std::string_view input,
17747
51.8k
                                    url_pattern_init::process_type type) {
17748
  // If type is not "pattern" return input.
17749
51.8k
  if (type != url_pattern_init::process_type::pattern) {
17750
0
    return std::string(input);
17751
0
  }
17752
  // Return the result of escaping a pattern string given input.
17753
51.8k
  return escape_pattern_string(input);
17754
51.8k
}
17755
17756
constexpr bool is_absolute_pathname(
17757
50.9k
    std::string_view input, url_pattern_init::process_type type) noexcept {
17758
  // If input is the empty string, then return false.
17759
50.9k
  if (input.empty()) [[unlikely]] {
17760
0
    return false;
17761
0
  }
17762
  // If input[0] is U+002F (/), then return true.
17763
50.9k
  if (input.starts_with("/")) return true;
17764
  // If type is "url", then return false.
17765
0
  if (type == url_pattern_init::process_type::url) return false;
17766
  // If input's code point length is less than 2, then return false.
17767
0
  if (input.size() < 2) return false;
17768
  // If input[0] is U+005C (\) and input[1] is U+002F (/), then return true.
17769
  // If input[0] is U+007B ({) and input[1] is U+002F (/), then return true.
17770
  // Return false.
17771
0
  return input[1] == '/' && (input[0] == '\\' || input[0] == '{');
17772
0
}
17773
17774
std::string generate_pattern_string(
17775
    std::vector<url_pattern_part>& part_list,
17776
920k
    url_pattern_compile_component_options& options) {
17777
  // Let result be the empty string.
17778
920k
  std::string result{};
17779
  // Let index list be the result of getting the indices for part list.
17780
  // For each index of index list:
17781
1.63M
  for (size_t index = 0; index < part_list.size(); index++) {
17782
    // Let part be part list[index].
17783
    // Use reference to avoid copy
17784
714k
    const auto& part = part_list[index];
17785
    // Let previous part be part list[index - 1] if index is greater than 0,
17786
    // otherwise let it be null.
17787
    // Use pointer to avoid copy
17788
714k
    const url_pattern_part* previous_part =
17789
714k
        index == 0 ? nullptr : &part_list[index - 1];
17790
    // Let next part be part list[index + 1] if index is less than index list's
17791
    // size - 1, otherwise let it be null.
17792
714k
    const url_pattern_part* next_part =
17793
714k
        index < part_list.size() - 1 ? &part_list[index + 1] : nullptr;
17794
    // If part's type is "fixed-text" then:
17795
714k
    if (part.type == url_pattern_part_type::FIXED_TEXT) {
17796
      // If part's modifier is "none" then:
17797
218k
      if (part.modifier == url_pattern_part_modifier::none) {
17798
        // Append the result of running escape a pattern string given part's
17799
        // value to the end of result.
17800
218k
        result.append(escape_pattern_string(part.value));
17801
218k
        continue;
17802
218k
      }
17803
      // Append "{" to the end of result.
17804
345
      result += "{";
17805
      // Append the result of running escape a pattern string given part's value
17806
      // to the end of result.
17807
345
      result.append(escape_pattern_string(part.value));
17808
      // Append "}" to the end of result.
17809
345
      result += "}";
17810
      // Append the result of running convert a modifier to a string given
17811
      // part's modifier to the end of result.
17812
345
      result.append(convert_modifier_to_string(part.modifier));
17813
345
      continue;
17814
218k
    }
17815
    // Let custom name be true if part's name[0] is not an ASCII digit;
17816
    // otherwise false.
17817
495k
    bool custom_name = !unicode::is_ascii_digit(part.name[0]);
17818
    // Let needs grouping be true if at least one of the following are true,
17819
    // otherwise let it be false:
17820
    // - part's suffix is not the empty string.
17821
    // - part's prefix is not the empty string and is not options's prefix code
17822
    // point.
17823
495k
    bool needs_grouping =
17824
495k
        !part.suffix.empty() ||
17825
494k
        (!part.prefix.empty() && !options.get_prefix().empty() &&
17826
39.1k
         part.prefix[0] != options.get_prefix()[0]);
17827
17828
    // If all of the following are true:
17829
    // - needs grouping is false; and
17830
    // - custom name is true; and
17831
    // - part's type is "segment-wildcard"; and
17832
    // - part's modifier is "none"; and
17833
    // - next part is not null; and
17834
    // - next part's prefix is the empty string; and
17835
    // - next part's suffix is the empty string
17836
495k
    if (!needs_grouping && custom_name &&
17837
1.61k
        part.type == url_pattern_part_type::SEGMENT_WILDCARD &&
17838
1.59k
        part.modifier == url_pattern_part_modifier::none && next_part &&
17839
620
        next_part->prefix.empty() && next_part->suffix.empty()) {
17840
      // If next part's type is "fixed-text":
17841
567
      if (next_part->type == url_pattern_part_type::FIXED_TEXT) {
17842
        // Set needs grouping to true if the result of running is a valid name
17843
        // code point given next part's value's first code point and the boolean
17844
        // false is true.
17845
221
        if (idna::valid_name_code_point(next_part->value[0], false)) {
17846
60
          needs_grouping = true;
17847
60
        }
17848
346
      } else {
17849
        // Set needs grouping to true if next part's name[0] is an ASCII digit.
17850
346
        needs_grouping = !next_part->name.empty() &&
17851
346
                         unicode::is_ascii_digit(next_part->name[0]);
17852
346
      }
17853
567
    }
17854
17855
    // If all of the following are true:
17856
    // - needs grouping is false; and
17857
    // - part's prefix is the empty string; and
17858
    // - previous part is not null; and
17859
    // - previous part's type is "fixed-text"; and
17860
    // - previous part's value's last code point is options's prefix code point.
17861
    // then set needs grouping to true.
17862
495k
    if (!needs_grouping && part.prefix.empty() && previous_part &&
17863
6.68k
        previous_part->type == url_pattern_part_type::FIXED_TEXT &&
17864
3.91k
        !previous_part->value.empty() && !options.get_prefix().empty() &&
17865
567
        previous_part->value.back() == options.get_prefix()[0]) {
17866
170
      needs_grouping = true;
17867
170
    }
17868
17869
    // Assert: part's name is not the empty string or null.
17870
495k
    ADA_ASSERT_TRUE(!part.name.empty());
17871
17872
    // If needs grouping is true, then append "{" to the end of result.
17873
495k
    if (needs_grouping) {
17874
823
      result.append("{");
17875
823
    }
17876
17877
    // Append the result of running escape a pattern string given part's prefix
17878
    // to the end of result.
17879
495k
    result.append(escape_pattern_string(part.prefix));
17880
17881
    // If custom name is true:
17882
495k
    if (custom_name) {
17883
      // Append ":" to the end of result.
17884
1.79k
      result.append(":");
17885
      // Append part's name to the end of result.
17886
1.79k
      result.append(part.name);
17887
1.79k
    }
17888
17889
    // If part's type is "regexp" then:
17890
495k
    if (part.type == url_pattern_part_type::REGEXP) {
17891
      // Append "(" to the end of result.
17892
2.29k
      result.append("(");
17893
      // Append part's value to the end of result.
17894
2.29k
      result.append(part.value);
17895
      // Append ")" to the end of result.
17896
2.29k
      result.append(")");
17897
493k
    } else if (part.type == url_pattern_part_type::SEGMENT_WILDCARD &&
17898
1.80k
               !custom_name) {
17899
      // Otherwise if part's type is "segment-wildcard" and custom name is
17900
      // false: Append "(" to the end of result.
17901
35
      result.append("(");
17902
      // Append the result of running generate a segment wildcard regexp given
17903
      // options to the end of result.
17904
35
      result.append(generate_segment_wildcard_regexp(options));
17905
      // Append ")" to the end of result.
17906
35
      result.append(")");
17907
493k
    } else if (part.type == url_pattern_part_type::FULL_WILDCARD) {
17908
      // Otherwise if part's type is "full-wildcard":
17909
      // If custom name is false and one of the following is true:
17910
      // - previous part is null; or
17911
      // - previous part's type is "fixed-text"; or
17912
      // - previous part's modifier is not "none"; or
17913
      // - needs grouping is true; or
17914
      // - part's prefix is not the empty string
17915
      // - then append "*" to the end of result.
17916
491k
      if (!custom_name &&
17917
491k
          (!previous_part ||
17918
6.05k
           previous_part->type == url_pattern_part_type::FIXED_TEXT ||
17919
2.27k
           previous_part->modifier != url_pattern_part_modifier::none ||
17920
491k
           needs_grouping || !part.prefix.empty())) {
17921
491k
        result.append("*");
17922
491k
      } else {
17923
        // Append "(" to the end of result.
17924
        // Append full wildcard regexp value to the end of result.
17925
        // Append ")" to the end of result.
17926
53
        result.append("(.*)");
17927
53
      }
17928
491k
    }
17929
17930
    // If all of the following are true:
17931
    // - part's type is "segment-wildcard"; and
17932
    // - custom name is true; and
17933
    // - part's suffix is not the empty string; and
17934
    // - The result of running is a valid name code point given part's suffix's
17935
    // first code point and the boolean false is true then append U+005C (\) to
17936
    // the end of result.
17937
495k
    if (part.type == url_pattern_part_type::SEGMENT_WILDCARD && custom_name &&
17938
1.77k
        !part.suffix.empty() &&
17939
175
        idna::valid_name_code_point(part.suffix[0], false)) {
17940
91
      result.append("\\");
17941
91
    }
17942
17943
    // Append the result of running escape a pattern string given part's suffix
17944
    // to the end of result.
17945
495k
    result.append(escape_pattern_string(part.suffix));
17946
    // If needs grouping is true, then append "}" to the end of result.
17947
495k
    if (needs_grouping) result.append("}");
17948
    // Append the result of running convert a modifier to a string given part's
17949
    // modifier to the end of result.
17950
495k
    result.append(convert_modifier_to_string(part.modifier));
17951
495k
  }
17952
  // Return result.
17953
920k
  return result;
17954
920k
}
17955
}  // namespace ada::url_pattern_helpers
17956
17957
#endif  // ADA_INCLUDE_URL_PATTERN
17958
/* end file src/url_pattern_helpers.cpp */
17959
/* begin file src/url_pattern_regex.cpp */
17960
#if ADA_INCLUDE_URL_PATTERN
17961
17962
17963
namespace ada::url_pattern_regex {
17964
17965
#ifdef ADA_USE_UNSAFE_STD_REGEX_PROVIDER
17966
std::optional<std::regex> std_regex_provider::create_instance(
17967
44.0k
    std::string_view pattern, bool ignore_case) {
17968
  // Let flags be an empty string.
17969
  // If options's ignore case is true then set flags to "vi".
17970
  // Otherwise set flags to "v"
17971
44.0k
  auto flags = ignore_case
17972
44.0k
                   ? std::regex::icase | std::regex_constants::ECMAScript
17973
44.0k
                   : std::regex_constants::ECMAScript;
17974
44.0k
  try {
17975
44.0k
    return std::regex(pattern.data(), pattern.size(), flags);
17976
44.0k
  } catch (const std::regex_error& e) {
17977
1.17k
    (void)e;
17978
1.17k
    ada_log("std_regex_provider::create_instance failed:", e.what());
17979
1.17k
    return std::nullopt;
17980
1.17k
  }
17981
44.0k
}
17982
17983
std::optional<std::vector<std::optional<std::string>>>
17984
std_regex_provider::regex_search(std::string_view input,
17985
7.37k
                                 const std::regex& pattern) {
17986
  // Use iterator-based regex_search to avoid string allocation
17987
7.37k
  std::match_results<std::string_view::const_iterator> match_result;
17988
7.37k
  try {
17989
7.37k
    if (!std::regex_search(input.begin(), input.end(), match_result, pattern,
17990
7.37k
                           std::regex_constants::match_any)) {
17991
3.32k
      return std::nullopt;
17992
3.32k
    }
17993
7.37k
  } catch (const std::regex_error& e) {
17994
66
    (void)e;
17995
66
    ada_log("std_regex_provider::regex_search failed:", e.what());
17996
66
    return std::nullopt;
17997
66
  }
17998
3.98k
  std::vector<std::optional<std::string>> matches;
17999
  // If input is empty, let's assume the result will be empty as well.
18000
3.98k
  if (input.empty() || match_result.empty()) {
18001
1.20k
    return matches;
18002
1.20k
  }
18003
2.78k
  matches.reserve(match_result.size());
18004
9.25k
  for (size_t i = 1; i < match_result.size(); ++i) {
18005
6.47k
    if (auto entry = match_result[i]; entry.matched) {
18006
6.13k
      matches.emplace_back(entry.str());
18007
6.13k
    } else {
18008
      // A capture group that did not participate in the match is undefined,
18009
      // not absent. Emitting nullopt keeps the result aligned by position with
18010
      // the component's group name list; dropping it shifts every later group
18011
      // onto the wrong name.
18012
339
      matches.emplace_back(std::nullopt);
18013
339
    }
18014
6.47k
  }
18015
2.78k
  return matches;
18016
3.98k
}
18017
18018
bool std_regex_provider::regex_match(std::string_view input,
18019
11.4k
                                     const std::regex& pattern) {
18020
11.4k
  try {
18021
11.4k
    return std::regex_match(input.begin(), input.end(), pattern);
18022
11.4k
  } catch (const std::regex_error& e) {
18023
83
    (void)e;
18024
83
    ada_log("std_regex_provider::regex_match failed:", e.what());
18025
83
    return false;
18026
83
  }
18027
11.4k
}
18028
18029
#endif  // ADA_USE_UNSAFE_STD_REGEX_PROVIDER
18030
18031
}  // namespace ada::url_pattern_regex
18032
18033
#endif  // ADA_INCLUDE_URL_PATTERN
18034
/* end file src/url_pattern_regex.cpp */
18035
#endif  // ADA_INCLUDE_URL_PATTERN
18036
18037
/* begin file src/ada_c.cpp */
18038
// NOLINTBEGIN(bugprone-exception-escape,
18039
// bugprone-suspicious-stringview-data-usage)
18040
18041
0
ada::result<ada::url_aggregator>& get_instance(void* result) noexcept {
18042
0
  return *(ada::result<ada::url_aggregator>*)result;
18043
0
}
18044
18045
extern "C" {
18046
typedef void* ada_url;
18047
typedef void* ada_url_search_params;
18048
typedef void* ada_strings;
18049
typedef void* ada_url_search_params_keys_iter;
18050
typedef void* ada_url_search_params_values_iter;
18051
typedef void* ada_url_search_params_entries_iter;
18052
18053
struct ada_string {
18054
  const char* data;
18055
  size_t length;
18056
};
18057
18058
struct ada_owned_string {
18059
  const char* data;
18060
  size_t length;
18061
};
18062
18063
struct ada_string_pair {
18064
  ada_string key;
18065
  ada_string value;
18066
};
18067
18068
0
ada_string ada_string_create(const char* data, size_t length) {
18069
0
  ada_string out{};
18070
0
  out.data = data;
18071
0
  out.length = length;
18072
0
  return out;
18073
0
}
18074
18075
struct ada_url_components {
18076
  /*
18077
   * By using 32-bit integers, we implicitly assume that the URL string
18078
   * cannot exceed 4 GB.
18079
   *
18080
   * https://user:pass@example.com:1234/foo/bar?baz#quux
18081
   *       |     |    |          | ^^^^|       |   |
18082
   *       |     |    |          | |   |       |   `----- hash_start
18083
   *       |     |    |          | |   |       `--------- search_start
18084
   *       |     |    |          | |   `----------------- pathname_start
18085
   *       |     |    |          | `--------------------- port
18086
   *       |     |    |          `----------------------- host_end
18087
   *       |     |    `---------------------------------- host_start
18088
   *       |     `--------------------------------------- username_end
18089
   *       `--------------------------------------------- protocol_end
18090
   */
18091
  uint32_t protocol_end;
18092
  /**
18093
   * Username end is not `omitted` by default (-1) to make username and password
18094
   * getters less costly to implement.
18095
   */
18096
  uint32_t username_end;
18097
  uint32_t host_start;
18098
  uint32_t host_end;
18099
  uint32_t port;
18100
  uint32_t pathname_start;
18101
  uint32_t search_start;
18102
  uint32_t hash_start;
18103
};
18104
18105
0
ada_url ada_parse(const char* input, size_t length) noexcept {
18106
0
  return new ada::result<ada::url_aggregator>(
18107
0
      ada::parse<ada::url_aggregator>(std::string_view(input, length)));
18108
0
}
18109
18110
ada_url ada_parse_with_base(const char* input, size_t input_length,
18111
0
                            const char* base, size_t base_length) noexcept {
18112
0
  auto base_out =
18113
0
      ada::parse<ada::url_aggregator>(std::string_view(base, base_length));
18114
18115
0
  if (!base_out) {
18116
0
    return new ada::result<ada::url_aggregator>(base_out);
18117
0
  }
18118
18119
0
  return new ada::result<ada::url_aggregator>(ada::parse<ada::url_aggregator>(
18120
0
      std::string_view(input, input_length), &base_out.value()));
18121
0
}
18122
18123
0
bool ada_can_parse(const char* input, size_t length) noexcept {
18124
0
  return ada::can_parse(std::string_view(input, length));
18125
0
}
18126
18127
bool ada_can_parse_with_base(const char* input, size_t input_length,
18128
0
                             const char* base, size_t base_length) noexcept {
18129
0
  std::string_view base_view(base, base_length);
18130
0
  return ada::can_parse(std::string_view(input, input_length), &base_view);
18131
0
}
18132
18133
0
void ada_free(ada_url result) noexcept {
18134
0
  auto* r = (ada::result<ada::url_aggregator>*)result;
18135
0
  delete r;
18136
0
}
18137
18138
0
ada_url ada_copy(ada_url input) noexcept {
18139
0
  ada::result<ada::url_aggregator>& r = get_instance(input);
18140
0
  return new ada::result<ada::url_aggregator>(r);
18141
0
}
18142
18143
0
bool ada_is_valid(ada_url result) noexcept {
18144
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18145
0
  return r.has_value();
18146
0
}
18147
18148
// caller must free the result with ada_free_owned_string
18149
0
ada_owned_string ada_get_origin(ada_url result) noexcept {
18150
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18151
0
  ada_owned_string owned{};
18152
0
  if (!r) {
18153
0
    owned.data = nullptr;
18154
0
    owned.length = 0;
18155
0
    return owned;
18156
0
  }
18157
0
  std::string out = r->get_origin();
18158
0
  owned.length = out.size();
18159
0
  owned.data = new char[owned.length];
18160
0
  memcpy((void*)owned.data, out.data(), owned.length);
18161
0
  return owned;
18162
0
}
18163
18164
0
void ada_free_owned_string(ada_owned_string owned) noexcept {
18165
0
  delete[] owned.data;
18166
0
}
18167
18168
0
ada_string ada_get_href(ada_url result) noexcept {
18169
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18170
0
  if (!r) {
18171
0
    return ada_string_create(nullptr, 0);
18172
0
  }
18173
0
  std::string_view out = r->get_href();
18174
0
  return ada_string_create(out.data(), out.length());
18175
0
}
18176
18177
0
ada_string ada_get_username(ada_url result) noexcept {
18178
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18179
0
  if (!r) {
18180
0
    return ada_string_create(nullptr, 0);
18181
0
  }
18182
0
  std::string_view out = r->get_username();
18183
0
  return ada_string_create(out.data(), out.length());
18184
0
}
18185
18186
0
ada_string ada_get_password(ada_url result) noexcept {
18187
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18188
0
  if (!r) {
18189
0
    return ada_string_create(nullptr, 0);
18190
0
  }
18191
0
  std::string_view out = r->get_password();
18192
0
  return ada_string_create(out.data(), out.length());
18193
0
}
18194
18195
0
ada_string ada_get_port(ada_url result) noexcept {
18196
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18197
0
  if (!r) {
18198
0
    return ada_string_create(nullptr, 0);
18199
0
  }
18200
0
  std::string_view out = r->get_port();
18201
0
  return ada_string_create(out.data(), out.length());
18202
0
}
18203
18204
0
ada_string ada_get_hash(ada_url result) noexcept {
18205
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18206
0
  if (!r) {
18207
0
    return ada_string_create(nullptr, 0);
18208
0
  }
18209
0
  std::string_view out = r->get_hash();
18210
0
  return ada_string_create(out.data(), out.length());
18211
0
}
18212
18213
0
ada_string ada_get_host(ada_url result) noexcept {
18214
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18215
0
  if (!r) {
18216
0
    return ada_string_create(nullptr, 0);
18217
0
  }
18218
0
  std::string_view out = r->get_host();
18219
0
  return ada_string_create(out.data(), out.length());
18220
0
}
18221
18222
0
ada_string ada_get_hostname(ada_url result) noexcept {
18223
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18224
0
  if (!r) {
18225
0
    return ada_string_create(nullptr, 0);
18226
0
  }
18227
0
  std::string_view out = r->get_hostname();
18228
0
  return ada_string_create(out.data(), out.length());
18229
0
}
18230
18231
0
ada_string ada_get_pathname(ada_url result) noexcept {
18232
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18233
0
  if (!r) {
18234
0
    return ada_string_create(nullptr, 0);
18235
0
  }
18236
0
  std::string_view out = r->get_pathname();
18237
0
  return ada_string_create(out.data(), out.length());
18238
0
}
18239
18240
0
ada_string ada_get_search(ada_url result) noexcept {
18241
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18242
0
  if (!r) {
18243
0
    return ada_string_create(nullptr, 0);
18244
0
  }
18245
0
  std::string_view out = r->get_search();
18246
0
  return ada_string_create(out.data(), out.length());
18247
0
}
18248
18249
0
ada_string ada_get_protocol(ada_url result) noexcept {
18250
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18251
0
  if (!r) {
18252
0
    return ada_string_create(nullptr, 0);
18253
0
  }
18254
0
  std::string_view out = r->get_protocol();
18255
0
  return ada_string_create(out.data(), out.length());
18256
0
}
18257
18258
0
uint8_t ada_get_host_type(ada_url result) noexcept {
18259
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18260
0
  if (!r) {
18261
0
    return 0;
18262
0
  }
18263
0
  return r->host_type;
18264
0
}
18265
18266
0
uint8_t ada_get_scheme_type(ada_url result) noexcept {
18267
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18268
0
  if (!r) {
18269
0
    return 0;
18270
0
  }
18271
0
  return r->type;
18272
0
}
18273
18274
0
bool ada_set_href(ada_url result, const char* input, size_t length) noexcept {
18275
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18276
0
  if (!r) {
18277
0
    return false;
18278
0
  }
18279
0
  return r->set_href(std::string_view(input, length));
18280
0
}
18281
18282
0
bool ada_set_host(ada_url result, const char* input, size_t length) noexcept {
18283
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18284
0
  if (!r) {
18285
0
    return false;
18286
0
  }
18287
0
  return r->set_host(std::string_view(input, length));
18288
0
}
18289
18290
bool ada_set_hostname(ada_url result, const char* input,
18291
0
                      size_t length) noexcept {
18292
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18293
0
  if (!r) {
18294
0
    return false;
18295
0
  }
18296
0
  return r->set_hostname(std::string_view(input, length));
18297
0
}
18298
18299
bool ada_set_protocol(ada_url result, const char* input,
18300
0
                      size_t length) noexcept {
18301
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18302
0
  if (!r) {
18303
0
    return false;
18304
0
  }
18305
0
  return r->set_protocol(std::string_view(input, length));
18306
0
}
18307
18308
bool ada_set_username(ada_url result, const char* input,
18309
0
                      size_t length) noexcept {
18310
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18311
0
  if (!r) {
18312
0
    return false;
18313
0
  }
18314
0
  return r->set_username(std::string_view(input, length));
18315
0
}
18316
18317
bool ada_set_password(ada_url result, const char* input,
18318
0
                      size_t length) noexcept {
18319
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18320
0
  if (!r) {
18321
0
    return false;
18322
0
  }
18323
0
  return r->set_password(std::string_view(input, length));
18324
0
}
18325
18326
0
bool ada_set_port(ada_url result, const char* input, size_t length) noexcept {
18327
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18328
0
  if (!r) {
18329
0
    return false;
18330
0
  }
18331
0
  return r->set_port(std::string_view(input, length));
18332
0
}
18333
18334
bool ada_set_pathname(ada_url result, const char* input,
18335
0
                      size_t length) noexcept {
18336
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18337
0
  if (!r) {
18338
0
    return false;
18339
0
  }
18340
0
  return r->set_pathname(std::string_view(input, length));
18341
0
}
18342
18343
/**
18344
 * Update the search/query of the URL.
18345
 *
18346
 * If a URL has `?` as the search value, passing empty string to this function
18347
 * does not remove the attribute. If you need to remove it, please use
18348
 * `ada_clear_search` method.
18349
 */
18350
0
void ada_set_search(ada_url result, const char* input, size_t length) noexcept {
18351
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18352
0
  if (r) {
18353
0
    r->set_search(std::string_view(input, length));
18354
0
  }
18355
0
}
18356
18357
/**
18358
 * Update the hash/fragment of the URL.
18359
 *
18360
 * If a URL has `#` as the hash value, passing empty string to this function
18361
 * does not remove the attribute. If you need to remove it, please use
18362
 * `ada_clear_hash` method.
18363
 */
18364
0
void ada_set_hash(ada_url result, const char* input, size_t length) noexcept {
18365
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18366
0
  if (r) {
18367
0
    r->set_hash(std::string_view(input, length));
18368
0
  }
18369
0
}
18370
18371
0
void ada_clear_port(ada_url result) noexcept {
18372
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18373
0
  if (r) {
18374
0
    r->clear_port();
18375
0
  }
18376
0
}
18377
18378
/**
18379
 * Removes the hash of the URL.
18380
 *
18381
 * Despite `ada_set_hash` method, this function allows the complete
18382
 * removal of the hash attribute, even if it has a value of `#`.
18383
 */
18384
0
void ada_clear_hash(ada_url result) noexcept {
18385
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18386
0
  if (r) {
18387
0
    r->clear_hash();
18388
0
  }
18389
0
}
18390
18391
/**
18392
 * Removes the search of the URL.
18393
 *
18394
 * Despite `ada_set_search` method, this function allows the complete
18395
 * removal of the search attribute, even if it has a value of `?`.
18396
 */
18397
0
void ada_clear_search(ada_url result) noexcept {
18398
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18399
0
  if (r) {
18400
0
    r->clear_search();
18401
0
  }
18402
0
}
18403
18404
0
bool ada_has_credentials(ada_url result) noexcept {
18405
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18406
0
  if (!r) {
18407
0
    return false;
18408
0
  }
18409
0
  return r->has_credentials();
18410
0
}
18411
18412
0
bool ada_has_empty_hostname(ada_url result) noexcept {
18413
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18414
0
  if (!r) {
18415
0
    return false;
18416
0
  }
18417
0
  return r->has_empty_hostname();
18418
0
}
18419
18420
0
bool ada_has_hostname(ada_url result) noexcept {
18421
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18422
0
  if (!r) {
18423
0
    return false;
18424
0
  }
18425
0
  return r->has_hostname();
18426
0
}
18427
18428
0
bool ada_has_non_empty_username(ada_url result) noexcept {
18429
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18430
0
  if (!r) {
18431
0
    return false;
18432
0
  }
18433
0
  return r->has_non_empty_username();
18434
0
}
18435
18436
0
bool ada_has_non_empty_password(ada_url result) noexcept {
18437
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18438
0
  if (!r) {
18439
0
    return false;
18440
0
  }
18441
0
  return r->has_non_empty_password();
18442
0
}
18443
18444
0
bool ada_has_port(ada_url result) noexcept {
18445
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18446
0
  if (!r) {
18447
0
    return false;
18448
0
  }
18449
0
  return r->has_port();
18450
0
}
18451
18452
0
bool ada_has_password(ada_url result) noexcept {
18453
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18454
0
  if (!r) {
18455
0
    return false;
18456
0
  }
18457
0
  return r->has_password();
18458
0
}
18459
18460
0
bool ada_has_hash(ada_url result) noexcept {
18461
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18462
0
  if (!r) {
18463
0
    return false;
18464
0
  }
18465
0
  return r->has_hash();
18466
0
}
18467
18468
0
bool ada_has_search(ada_url result) noexcept {
18469
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18470
0
  if (!r) {
18471
0
    return false;
18472
0
  }
18473
0
  return r->has_search();
18474
0
}
18475
18476
// returns a pointer to the internal url_aggregator::url_components
18477
0
const ada_url_components* ada_get_components(ada_url result) noexcept {
18478
0
  static_assert(sizeof(ada_url_components) == sizeof(ada::url_components));
18479
0
  ada::result<ada::url_aggregator>& r = get_instance(result);
18480
0
  if (!r) {
18481
0
    return nullptr;
18482
0
  }
18483
0
  return reinterpret_cast<const ada_url_components*>(&r->get_components());
18484
0
}
18485
18486
0
ada_owned_string ada_idna_to_unicode(const char* input, size_t length) {
18487
0
  std::string out = ada::idna::to_unicode(std::string_view(input, length));
18488
0
  ada_owned_string owned{};
18489
0
  owned.length = out.length();
18490
0
  owned.data = new char[owned.length];
18491
0
  memcpy((void*)owned.data, out.data(), owned.length);
18492
0
  return owned;
18493
0
}
18494
18495
0
ada_owned_string ada_idna_to_ascii(const char* input, size_t length) {
18496
0
  std::string out = ada::idna::to_ascii(std::string_view(input, length));
18497
0
  ada_owned_string owned{};
18498
0
  owned.length = out.size();
18499
0
  owned.data = new char[owned.length];
18500
0
  memcpy((void*)owned.data, out.data(), owned.length);
18501
0
  return owned;
18502
0
}
18503
18504
ada_url_search_params ada_parse_search_params(const char* input,
18505
0
                                              size_t length) {
18506
0
  return new ada::result<ada::url_search_params>(
18507
0
      ada::url_search_params(std::string_view(input, length)));
18508
0
}
18509
18510
0
void ada_free_search_params(ada_url_search_params result) {
18511
0
  auto* r = (ada::result<ada::url_search_params>*)result;
18512
0
  delete r;
18513
0
}
18514
18515
0
ada_owned_string ada_search_params_to_string(ada_url_search_params result) {
18516
0
  ada::result<ada::url_search_params>& r =
18517
0
      *(ada::result<ada::url_search_params>*)result;
18518
0
  if (!r) return ada_owned_string{nullptr, 0};
18519
0
  std::string out = r->to_string();
18520
0
  ada_owned_string owned{};
18521
0
  owned.length = out.size();
18522
0
  owned.data = new char[owned.length];
18523
0
  memcpy((void*)owned.data, out.data(), owned.length);
18524
0
  return owned;
18525
0
}
18526
18527
0
size_t ada_search_params_size(ada_url_search_params result) {
18528
0
  ada::result<ada::url_search_params>& r =
18529
0
      *(ada::result<ada::url_search_params>*)result;
18530
0
  if (!r) {
18531
0
    return 0;
18532
0
  }
18533
0
  return r->size();
18534
0
}
18535
18536
0
void ada_search_params_sort(ada_url_search_params result) {
18537
0
  ada::result<ada::url_search_params>& r =
18538
0
      *(ada::result<ada::url_search_params>*)result;
18539
0
  if (r) {
18540
0
    r->sort();
18541
0
  }
18542
0
}
18543
18544
void ada_search_params_reset(ada_url_search_params result, const char* input,
18545
0
                             size_t length) {
18546
0
  ada::result<ada::url_search_params>& r =
18547
0
      *(ada::result<ada::url_search_params>*)result;
18548
0
  if (r) {
18549
0
    r->reset(std::string_view(input, length));
18550
0
  }
18551
0
}
18552
18553
void ada_search_params_append(ada_url_search_params result, const char* key,
18554
                              size_t key_length, const char* value,
18555
0
                              size_t value_length) {
18556
0
  ada::result<ada::url_search_params>& r =
18557
0
      *(ada::result<ada::url_search_params>*)result;
18558
0
  if (r) {
18559
0
    r->append(std::string_view(key, key_length),
18560
0
              std::string_view(value, value_length));
18561
0
  }
18562
0
}
18563
18564
void ada_search_params_set(ada_url_search_params result, const char* key,
18565
                           size_t key_length, const char* value,
18566
0
                           size_t value_length) {
18567
0
  ada::result<ada::url_search_params>& r =
18568
0
      *(ada::result<ada::url_search_params>*)result;
18569
0
  if (r) {
18570
0
    r->set(std::string_view(key, key_length),
18571
0
           std::string_view(value, value_length));
18572
0
  }
18573
0
}
18574
18575
void ada_search_params_remove(ada_url_search_params result, const char* key,
18576
0
                              size_t key_length) {
18577
0
  ada::result<ada::url_search_params>& r =
18578
0
      *(ada::result<ada::url_search_params>*)result;
18579
0
  if (r) {
18580
0
    r->remove(std::string_view(key, key_length));
18581
0
  }
18582
0
}
18583
18584
void ada_search_params_remove_value(ada_url_search_params result,
18585
                                    const char* key, size_t key_length,
18586
0
                                    const char* value, size_t value_length) {
18587
0
  ada::result<ada::url_search_params>& r =
18588
0
      *(ada::result<ada::url_search_params>*)result;
18589
0
  if (r) {
18590
0
    r->remove(std::string_view(key, key_length),
18591
0
              std::string_view(value, value_length));
18592
0
  }
18593
0
}
18594
18595
bool ada_search_params_has(ada_url_search_params result, const char* key,
18596
0
                           size_t key_length) {
18597
0
  ada::result<ada::url_search_params>& r =
18598
0
      *(ada::result<ada::url_search_params>*)result;
18599
0
  if (!r) {
18600
0
    return false;
18601
0
  }
18602
0
  return r->has(std::string_view(key, key_length));
18603
0
}
18604
18605
bool ada_search_params_has_value(ada_url_search_params result, const char* key,
18606
                                 size_t key_length, const char* value,
18607
0
                                 size_t value_length) {
18608
0
  ada::result<ada::url_search_params>& r =
18609
0
      *(ada::result<ada::url_search_params>*)result;
18610
0
  if (!r) {
18611
0
    return false;
18612
0
  }
18613
0
  return r->has(std::string_view(key, key_length),
18614
0
                std::string_view(value, value_length));
18615
0
}
18616
18617
ada_string ada_search_params_get(ada_url_search_params result, const char* key,
18618
0
                                 size_t key_length) {
18619
0
  ada::result<ada::url_search_params>& r =
18620
0
      *(ada::result<ada::url_search_params>*)result;
18621
0
  if (!r) {
18622
0
    return ada_string_create(nullptr, 0);
18623
0
  }
18624
0
  auto found = r->get(std::string_view(key, key_length));
18625
0
  if (!found.has_value()) {
18626
0
    return ada_string_create(nullptr, 0);
18627
0
  }
18628
0
  return ada_string_create(found->data(), found->length());
18629
0
}
18630
18631
ada_strings ada_search_params_get_all(ada_url_search_params result,
18632
0
                                      const char* key, size_t key_length) {
18633
0
  ada::result<ada::url_search_params>& r =
18634
0
      *(ada::result<ada::url_search_params>*)result;
18635
0
  if (!r) {
18636
0
    return new ada::result<std::vector<std::string>>(
18637
0
        std::vector<std::string>());
18638
0
  }
18639
0
  return new ada::result<std::vector<std::string>>(
18640
0
      r->get_all(std::string_view(key, key_length)));
18641
0
}
18642
18643
ada_url_search_params_keys_iter ada_search_params_get_keys(
18644
0
    ada_url_search_params result) {
18645
0
  ada::result<ada::url_search_params>& r =
18646
0
      *(ada::result<ada::url_search_params>*)result;
18647
0
  if (!r) {
18648
0
    return new ada::result<ada::url_search_params_keys_iter>(
18649
0
        ada::url_search_params_keys_iter());
18650
0
  }
18651
0
  return new ada::result<ada::url_search_params_keys_iter>(r->get_keys());
18652
0
}
18653
18654
ada_url_search_params_values_iter ada_search_params_get_values(
18655
0
    ada_url_search_params result) {
18656
0
  ada::result<ada::url_search_params>& r =
18657
0
      *(ada::result<ada::url_search_params>*)result;
18658
0
  if (!r) {
18659
0
    return new ada::result<ada::url_search_params_values_iter>(
18660
0
        ada::url_search_params_values_iter());
18661
0
  }
18662
0
  return new ada::result<ada::url_search_params_values_iter>(r->get_values());
18663
0
}
18664
18665
ada_url_search_params_entries_iter ada_search_params_get_entries(
18666
0
    ada_url_search_params result) {
18667
0
  ada::result<ada::url_search_params>& r =
18668
0
      *(ada::result<ada::url_search_params>*)result;
18669
0
  if (!r) {
18670
0
    return new ada::result<ada::url_search_params_entries_iter>(
18671
0
        ada::url_search_params_entries_iter());
18672
0
  }
18673
0
  return new ada::result<ada::url_search_params_entries_iter>(r->get_entries());
18674
0
}
18675
18676
0
void ada_free_strings(ada_strings result) {
18677
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
18678
0
  delete r;
18679
0
}
18680
18681
0
size_t ada_strings_size(ada_strings result) {
18682
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
18683
0
  if (!r) {
18684
0
    return 0;
18685
0
  }
18686
0
  return (*r)->size();
18687
0
}
18688
18689
0
ada_string ada_strings_get(ada_strings result, size_t index) {
18690
0
  auto* r = (ada::result<std::vector<std::string>>*)result;
18691
0
  if (!r) {
18692
0
    return ada_string_create(nullptr, 0);
18693
0
  }
18694
0
  std::string_view view = (*r)->at(index);
18695
0
  return ada_string_create(view.data(), view.length());
18696
0
}
18697
18698
0
void ada_free_search_params_keys_iter(ada_url_search_params_keys_iter result) {
18699
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
18700
0
  delete r;
18701
0
}
18702
18703
ada_string ada_search_params_keys_iter_next(
18704
0
    ada_url_search_params_keys_iter result) {
18705
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
18706
0
  if (!r) {
18707
0
    return ada_string_create(nullptr, 0);
18708
0
  }
18709
0
  auto next = (*r)->next();
18710
0
  if (!next.has_value()) {
18711
0
    return ada_string_create(nullptr, 0);
18712
0
  }
18713
0
  return ada_string_create(next->data(), next->length());
18714
0
}
18715
18716
bool ada_search_params_keys_iter_has_next(
18717
0
    ada_url_search_params_keys_iter result) {
18718
0
  auto* r = (ada::result<ada::url_search_params_keys_iter>*)result;
18719
0
  if (!r) {
18720
0
    return false;
18721
0
  }
18722
0
  return (*r)->has_next();
18723
0
}
18724
18725
void ada_free_search_params_values_iter(
18726
0
    ada_url_search_params_values_iter result) {
18727
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
18728
0
  delete r;
18729
0
}
18730
18731
ada_string ada_search_params_values_iter_next(
18732
0
    ada_url_search_params_values_iter result) {
18733
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
18734
0
  if (!r) {
18735
0
    return ada_string_create(nullptr, 0);
18736
0
  }
18737
0
  auto next = (*r)->next();
18738
0
  if (!next.has_value()) {
18739
0
    return ada_string_create(nullptr, 0);
18740
0
  }
18741
0
  return ada_string_create(next->data(), next->length());
18742
0
}
18743
18744
bool ada_search_params_values_iter_has_next(
18745
0
    ada_url_search_params_values_iter result) {
18746
0
  auto* r = (ada::result<ada::url_search_params_values_iter>*)result;
18747
0
  if (!r) {
18748
0
    return false;
18749
0
  }
18750
0
  return (*r)->has_next();
18751
0
}
18752
18753
void ada_free_search_params_entries_iter(
18754
0
    ada_url_search_params_entries_iter result) {
18755
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
18756
0
  delete r;
18757
0
}
18758
18759
ada_string_pair ada_search_params_entries_iter_next(
18760
0
    ada_url_search_params_entries_iter result) {
18761
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
18762
0
  if (!r) return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
18763
0
  auto next = (*r)->next();
18764
0
  if (!next.has_value()) {
18765
0
    return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
18766
0
  }
18767
0
  return ada_string_pair{
18768
0
      ada_string_create(next->first.data(), next->first.length()),
18769
0
      ada_string_create(next->second.data(), next->second.length())};
18770
0
}
18771
18772
bool ada_search_params_entries_iter_has_next(
18773
0
    ada_url_search_params_entries_iter result) {
18774
0
  auto* r = (ada::result<ada::url_search_params_entries_iter>*)result;
18775
0
  if (!r) {
18776
0
    return false;
18777
0
  }
18778
0
  return (*r)->has_next();
18779
0
}
18780
18781
0
void ada_set_max_input_length(uint32_t length) noexcept {
18782
0
  ada::set_max_input_length(length);
18783
0
}
18784
18785
0
uint32_t ada_get_max_input_length() noexcept {
18786
0
  return ada::get_max_input_length();
18787
0
}
18788
18789
typedef struct {
18790
  int major;
18791
  int minor;
18792
  int revision;
18793
} ada_version_components;
18794
18795
0
const char* ada_get_version() { return ADA_VERSION; }
18796
18797
0
ada_version_components ada_get_version_components() {
18798
0
  return ada_version_components{
18799
0
      .major = ada::ADA_VERSION_MAJOR,
18800
0
      .minor = ada::ADA_VERSION_MINOR,
18801
0
      .revision = ada::ADA_VERSION_REVISION,
18802
0
  };
18803
0
}
18804
18805
}  // extern "C"
18806
// NOLINTEND(bugprone-exception-escape,
18807
// bugprone-suspicious-stringview-data-usage)
18808
/* end file src/ada_c.cpp */
18809
/* end file src/ada.cpp */