Skip to main content

core/unicode/
unicode_data.rs

1//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!
2// Alphabetic                  :  1763 bytes, 160202 codepoints in 773 ranges (U+0000AA - U+03FC40) using skiplist
3// Case_Ignorable              :  1071 bytes,   2885 codepoints in 463 ranges (U+0000A8 - U+0E01F0) using skiplist
4// Cf                          :    87 bytes,    170 codepoints in  21 ranges (U+0000AD - U+0E0080) using skiplist
5// Cn_Planes_0_3               :  1701 bytes,  81158 codepoints in 730 ranges (U+000378 - U+03FFFE) using skiplist
6// Default_Ignorable_Code_Point:    83 bytes,   4174 codepoints in  17 ranges (U+0000AD - U+0E1000) using skiplist
7// Grapheme_Extend             :   911 bytes,   2269 codepoints in 389 ranges (U+000300 - U+0E01F0) using skiplist
8// Lowercase                   :   981 bytes,   2714 codepoints in 695 ranges (U+0000AA - U+01E944) using bitset
9// Lt                          :    33 bytes,     31 codepoints in  10 ranges (U+0001C5 - U+001FFD) using skiplist
10// N                           :   471 bytes,   2237 codepoints in 147 ranges (U+0000B2 - U+01FBFA) using skiplist
11// Uppercase                   :   847 bytes,   2000 codepoints in 677 ranges (U+0000C0 - U+01F18A) using bitset
12// White_Space                 :   256 bytes,     19 codepoints in   8 ranges (U+000085 - U+003001) using cascading
13// to_lower                    :  1166 bytes,   1482 codepoints in 194 ranges (U+0000C0 - U+01E921) using 2-level LUT
14// to_upper                    :  2068 bytes,   1575 codepoints in 308 ranges (U+0000B5 - U+01E943) using 2-level LUT
15// to_title                    :   356 bytes,    136 codepoints in  49 ranges (U+0000DF - U+01DF95) using 2-level LUT
16// to_casefold                 :    32 bytes,    174 codepoints in   5 ranges (U+000131 - U+00ABBF) using 2-level LUT
17// Total                       : 11826 bytes
18
19#[inline(always)]
20const fn bitset_search<
21    const N: usize,
22    const CHUNK_SIZE: usize,
23    const N1: usize,
24    const CANONICAL: usize,
25    const CANONICALIZED: usize,
26>(
27    needle: u32,
28    chunk_idx_map: &[u8; N],
29    bitset_chunk_idx: &[[u8; CHUNK_SIZE]; N1],
30    bitset_canonical: &[u64; CANONICAL],
31    bitset_canonicalized: &[(u8, u8); CANONICALIZED],
32) -> bool {
33    let bucket_idx = (needle / 64) as usize;
34    let chunk_map_idx = bucket_idx / CHUNK_SIZE;
35    let chunk_piece = bucket_idx % CHUNK_SIZE;
36    // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
37    let chunk_idx = if chunk_map_idx < chunk_idx_map.len() {
38        chunk_idx_map[chunk_map_idx]
39    } else {
40        return false;
41    };
42    let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize;
43    // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
44    let word = if idx < bitset_canonical.len() {
45        bitset_canonical[idx]
46    } else {
47        let (real_idx, mapping) = bitset_canonicalized[idx - bitset_canonical.len()];
48        let mut word = bitset_canonical[real_idx as usize];
49        let should_invert = mapping & (1 << 6) != 0;
50        if should_invert {
51            word = !word;
52        }
53        // Lower 6 bits
54        let quantity = mapping & ((1 << 6) - 1);
55        if mapping & (1 << 7) != 0 {
56            // shift
57            word >>= quantity as u64;
58        } else {
59            word = word.rotate_left(quantity as u32);
60        }
61        word
62    };
63    (word & (1 << (needle % 64) as u64)) != 0
64}
65
66#[repr(transparent)]
67struct ShortOffsetRunHeader(u32);
68
69impl ShortOffsetRunHeader {
70    const fn new(start_index: usize, prefix_sum: u32) -> Self {
71        assert!(start_index < (1 << 11));
72        assert!(prefix_sum < (1 << 21));
73
74        Self((start_index as u32) << 21 | prefix_sum)
75    }
76
77    #[inline]
78    const fn start_index(&self) -> usize {
79        (self.0 >> 21) as usize
80    }
81
82    #[inline]
83    const fn prefix_sum(&self) -> u32 {
84        self.0 & ((1 << 21) - 1)
85    }
86}
87
88/// # Safety
89///
90/// - The last element of `short_offset_runs` must be greater than `std::char::MAX`.
91/// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`.
92#[inline(always)]
93unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
94    needle: char,
95    short_offset_runs: &[ShortOffsetRunHeader; SOR],
96    offsets: &[u8; OFFSETS],
97) -> bool {
98    let needle = needle as u32;
99
100    let last_idx =
101        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) {
102            Ok(idx) => idx + 1,
103            Err(idx) => idx,
104        };
105    // SAFETY: `last_idx` *cannot* be past the end of the array, as the last
106    // element is greater than `std::char::MAX` (the largest possible needle)
107    // as guaranteed by the caller.
108    //
109    // So, we cannot have found it (i.e. `Ok(idx) => idx + 1 != length`) and the
110    // correct location cannot be past it, so `Err(idx) => idx != length` either.
111    //
112    // This means that we can avoid bounds checking for the accesses below, too.
113    //
114    // We need to use `intrinsics::assume` since the `panic_nounwind` contained
115    // in `hint::assert_unchecked` may not be optimized out.
116    unsafe { crate::intrinsics::assume(last_idx < SOR) };
117
118    let mut offset_idx = short_offset_runs[last_idx].start_index();
119    let length = if let Some(next) = short_offset_runs.get(last_idx + 1) {
120        (*next).start_index() - offset_idx
121    } else {
122        offsets.len() - offset_idx
123    };
124
125    let prev =
126        last_idx.checked_sub(1).map(|prev| short_offset_runs[prev].prefix_sum()).unwrap_or(0);
127
128    let total = needle - prev;
129    let mut prefix_sum = 0;
130    for _ in 0..(length - 1) {
131        // SAFETY: It is guaranteed that `length <= OFFSETS - offset_idx`,
132        // so it follows that `length - 1 + offset_idx < OFFSETS`, therefore
133        // `offset_idx < OFFSETS` is always true in this loop.
134        //
135        // We need to use `intrinsics::assume` since the `panic_nounwind` contained
136        // in `hint::assert_unchecked` may not be optimized out.
137        unsafe { crate::intrinsics::assume(offset_idx < OFFSETS) };
138        let offset = offsets[offset_idx];
139        prefix_sum += offset as u32;
140        if prefix_sum > total {
141            break;
142        }
143        offset_idx += 1;
144    }
145    offset_idx % 2 == 1
146}
147
148pub const UNICODE_VERSION: (u8, u8, u8) = (18, 0, 0);
149
150#[rustfmt::skip]
151pub mod alphabetic {
152    use super::ShortOffsetRunHeader;
153
154    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 54] = [
155        ShortOffsetRunHeader::new(0, 706), ShortOffsetRunHeader::new(12, 4681),
156        ShortOffsetRunHeader::new(416, 5741), ShortOffsetRunHeader::new(454, 7958),
157        ShortOffsetRunHeader::new(554, 9398), ShortOffsetRunHeader::new(625, 11264),
158        ShortOffsetRunHeader::new(627, 12293), ShortOffsetRunHeader::new(665, 13312),
159        ShortOffsetRunHeader::new(689, 19904), ShortOffsetRunHeader::new(690, 42125),
160        ShortOffsetRunHeader::new(692, 42509), ShortOffsetRunHeader::new(696, 55204),
161        ShortOffsetRunHeader::new(784, 63744), ShortOffsetRunHeader::new(789, 64110),
162        ShortOffsetRunHeader::new(790, 64830), ShortOffsetRunHeader::new(812, 66176),
163        ShortOffsetRunHeader::new(853, 67383), ShortOffsetRunHeader::new(900, 74650),
164        ShortOffsetRunHeader::new(1248, 75399), ShortOffsetRunHeader::new(1254, 77712),
165        ShortOffsetRunHeader::new(1255, 78896), ShortOffsetRunHeader::new(1258, 82939),
166        ShortOffsetRunHeader::new(1262, 83527), ShortOffsetRunHeader::new(1264, 90368),
167        ShortOffsetRunHeader::new(1265, 92160), ShortOffsetRunHeader::new(1267, 92729),
168        ShortOffsetRunHeader::new(1268, 93504), ShortOffsetRunHeader::new(1283, 101595),
169        ShortOffsetRunHeader::new(1304, 102802), ShortOffsetRunHeader::new(1310, 110576),
170        ShortOffsetRunHeader::new(1313, 110889), ShortOffsetRunHeader::new(1320, 111356),
171        ShortOffsetRunHeader::new(1330, 113664), ShortOffsetRunHeader::new(1331, 119808),
172        ShortOffsetRunHeader::new(1341, 120487), ShortOffsetRunHeader::new(1378, 122624),
173        ShortOffsetRunHeader::new(1401, 123536), ShortOffsetRunHeader::new(1425, 124112),
174        ShortOffsetRunHeader::new(1429, 126464), ShortOffsetRunHeader::new(1457, 127280),
175        ShortOffsetRunHeader::new(1523, 131072), ShortOffsetRunHeader::new(1529, 173792),
176        ShortOffsetRunHeader::new(1530, 178207), ShortOffsetRunHeader::new(1532, 183982),
177        ShortOffsetRunHeader::new(1534, 191457), ShortOffsetRunHeader::new(1536, 192094),
178        ShortOffsetRunHeader::new(1538, 194560), ShortOffsetRunHeader::new(1539, 195102),
179        ShortOffsetRunHeader::new(1540, 196608), ShortOffsetRunHeader::new(1541, 201547),
180        ShortOffsetRunHeader::new(1542, 210042), ShortOffsetRunHeader::new(1544, 249856),
181        ShortOffsetRunHeader::new(1545, 261184), ShortOffsetRunHeader::new(1546, 1375296),
182    ];
183    static OFFSETS: [u8; 1547] = [
184        170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 29, 18, 1, 2, 2,
185        4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 1, 2, 6, 41, 2, 2, 35, 14,
186        1, 1, 1, 2, 1, 2, 1, 3, 6, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10, 3,
187        2, 1, 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 7, 7, 1,
188        8, 42, 10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4,
189        3, 8, 2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2,
190        1, 2, 1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2,
191        1, 5, 3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8,
192        2, 2, 2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3,
193        3, 12, 4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1,
194        3, 1, 2, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 5, 3, 1, 4,
195        13, 3, 12, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24,
196        1, 9, 1, 1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1,
197        1, 1, 19, 1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 19, 4, 16, 1, 36, 67, 55,
198        1, 1, 2, 5, 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1,
199        4, 2, 33, 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2,
200        17, 1, 26, 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4,
201        1, 67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2,
202        20, 50, 1, 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3,
203        10, 36, 2, 11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, 0, 2, 6, 2, 38, 2,
204        6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1,
205        7, 116, 1, 13, 1, 15, 17, 98, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2,
206        4, 5, 5, 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23,
207        9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4,
208        86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10,
209        2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 83, 4, 1, 14, 21, 1, 33, 24, 52, 12, 68, 1, 1,
210        44, 6, 3, 1, 1, 3, 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1, 55, 9, 14,
211        18, 23, 3, 69, 1, 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 43, 1, 14,
212        2, 2, 2, 123, 21, 0, 12, 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1, 1, 1,
213        2, 1, 2, 1, 108, 33, 0, 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89, 3, 6,
214        2, 6, 2, 6, 2, 3, 35, 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3, 49,
215        47, 32, 13, 30, 5, 43, 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52, 12,
216        11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6, 1, 42,
217        1, 14, 64, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26,
218        6, 26, 38, 56, 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54,
219        10, 22, 10, 19, 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, 42, 1, 2,
220        3, 2, 16, 6, 3, 3, 11, 22, 4, 1, 1, 1, 1, 2, 1, 3, 3, 29, 10, 1, 8, 22, 42, 18, 46, 21, 27,
221        23, 9, 70, 43, 5, 10, 57, 9, 1, 13, 25, 23, 51, 17, 4, 8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10,
222        1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 4, 62, 7, 1, 1, 1, 4, 1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2,
223        2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6, 1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38,
224        1, 10, 1, 1, 2, 1, 1, 4, 1, 2, 3, 1, 1, 1, 44, 66, 1, 3, 1, 4, 20, 3, 30, 66, 2, 2, 1, 1,
225        184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1, 71, 27, 2, 14, 21, 7, 185, 57, 103,
226        64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4, 93, 8, 2, 46, 2, 6, 1, 1, 1, 2, 27,
227        51, 2, 10, 17, 72, 5, 1, 18, 73, 17, 1, 85, 8, 88, 33, 31, 9, 1, 45, 1, 7, 1, 1, 49, 30, 2,
228        22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6, 1, 2, 1, 37, 1, 2, 1, 4,
229        1, 1, 23, 44, 20, 2, 238, 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, 102, 112, 5, 207, 12, 0, 0,
230        97, 15, 0, 17, 6, 25, 0, 5, 0, 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, 48, 16, 4, 31, 21, 5,
231        19, 0, 45, 211, 64, 32, 25, 2, 25, 44, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 7, 9, 0, 36, 34,
232        95, 115, 13, 0, 14, 51, 0, 4, 1, 7, 1, 2, 1, 0, 9, 1, 29, 3, 2, 1, 14, 5, 7, 0, 0, 107, 5,
233        13, 3, 9, 7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4,
234        2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 1, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25,
235        1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 130, 14, 7, 54, 58, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33,
236        1, 112, 45, 10, 7, 16, 1, 0, 30, 18, 44, 0, 28, 228, 30, 2, 1, 207, 31, 1, 22, 8, 2, 224, 7,
237        1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4,
238        1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
239        1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0,
240        32, 0, 1, 0, 2, 0, 15, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0,
241    ];
242    #[inline]
243    pub fn lookup(c: char) -> bool {
244        debug_assert!(!c.is_ascii());
245        (c as u32) >= 0xaa && lookup_slow(c)
246    }
247
248    #[inline(never)]
249    fn lookup_slow(c: char) -> bool {
250        const {
251            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
252            let mut i = 0;
253            while i < SHORT_OFFSET_RUNS.len() {
254                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
255                i += 1;
256            }
257        }
258        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
259        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
260        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
261    }
262}
263
264#[rustfmt::skip]
265pub mod case_ignorable {
266    use super::ShortOffsetRunHeader;
267
268    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 36] = [
269        ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(11, 4957),
270        ShortOffsetRunHeader::new(265, 5906), ShortOffsetRunHeader::new(267, 8125),
271        ShortOffsetRunHeader::new(377, 11388), ShortOffsetRunHeader::new(411, 12293),
272        ShortOffsetRunHeader::new(423, 40981), ShortOffsetRunHeader::new(435, 42232),
273        ShortOffsetRunHeader::new(437, 42508), ShortOffsetRunHeader::new(439, 64286),
274        ShortOffsetRunHeader::new(535, 65024), ShortOffsetRunHeader::new(539, 66045),
275        ShortOffsetRunHeader::new(569, 67456), ShortOffsetRunHeader::new(575, 68097),
276        ShortOffsetRunHeader::new(581, 68900), ShortOffsetRunHeader::new(593, 69291),
277        ShortOffsetRunHeader::new(601, 71727), ShortOffsetRunHeader::new(729, 71995),
278        ShortOffsetRunHeader::new(733, 73459), ShortOffsetRunHeader::new(801, 78896),
279        ShortOffsetRunHeader::new(813, 90398), ShortOffsetRunHeader::new(817, 92912),
280        ShortOffsetRunHeader::new(821, 93504), ShortOffsetRunHeader::new(827, 94031),
281        ShortOffsetRunHeader::new(831, 110576), ShortOffsetRunHeader::new(841, 113821),
282        ShortOffsetRunHeader::new(847, 118528), ShortOffsetRunHeader::new(851, 119079),
283        ShortOffsetRunHeader::new(855, 121344), ShortOffsetRunHeader::new(869, 122829),
284        ShortOffsetRunHeader::new(881, 123566), ShortOffsetRunHeader::new(897, 124139),
285        ShortOffsetRunHeader::new(901, 125136), ShortOffsetRunHeader::new(915, 127995),
286        ShortOffsetRunHeader::new(919, 917505), ShortOffsetRunHeader::new(921, 2032112),
287    ];
288    static OFFSETS: [u8; 927] = [
289        168, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2, 1, 1, 251, 7, 206, 2, 5, 1, 43,
290        2, 4, 45, 1, 1, 1, 2, 1, 2, 1, 3, 42, 1, 11, 6, 10, 11, 1, 1, 35, 1, 10, 21, 16, 1, 101, 8,
291        1, 10, 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24, 24, 43, 3, 44, 1, 7, 2, 5,
292        9, 41, 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1, 20, 2, 26,
293        1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2,
294        22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 5, 4, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3, 1, 55, 1,
295        1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8,
296        1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 7, 73, 2, 27,
297        1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4,
298        3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8,
299        1, 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1,
300        58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 65, 15, 4, 48, 1, 1, 5, 1, 1, 5, 1,
301        40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13,
302        1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2, 12,
303        5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 15, 17, 48, 33, 0, 2, 113, 3, 125, 1,
304        15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10,
305        1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 102, 4, 3, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151,
306        2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2,
307        12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5,
308        9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6,
309        1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 14,
310        0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, 26, 5, 1, 1, 0, 2, 24, 1, 3, 7, 32, 16,
311        70, 11, 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3,
312        36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 2, 1, 157, 1, 3, 8,
313        21, 2, 57, 2, 3, 1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1,
314        84, 6, 1, 1, 4, 2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6,
315        1, 1, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10,
316        40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6, 1, 1, 82, 22,
317        2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 65, 1, 22, 1, 0, 2, 11,
318        2, 52, 5, 5, 1, 1, 1, 23, 1, 0, 17, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 9, 4, 0, 3, 40, 2, 0,
319        1, 63, 17, 64, 2, 1, 2, 13, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0, 46, 2, 23, 0, 2, 62, 3, 9,
320        16, 2, 7, 30, 4, 148, 3, 22, 2, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 58, 1, 17, 2, 7,
321        1, 2, 1, 5, 5, 62, 33, 1, 160, 14, 0, 1, 61, 4, 0, 5, 254, 2, 243, 1, 2, 1, 7, 2, 5, 1, 9,
322        1, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0,
323    ];
324    #[inline]
325    pub fn lookup(c: char) -> bool {
326        debug_assert!(!c.is_ascii());
327        (c as u32) >= 0xa8 && lookup_slow(c)
328    }
329
330    #[inline(never)]
331    fn lookup_slow(c: char) -> bool {
332        const {
333            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
334            let mut i = 0;
335            while i < SHORT_OFFSET_RUNS.len() {
336                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
337                i += 1;
338            }
339        }
340        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
341        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
342        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
343    }
344}
345
346#[rustfmt::skip]
347pub mod cf {
348    use super::ShortOffsetRunHeader;
349
350    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 11] = [
351        ShortOffsetRunHeader::new(0, 1536), ShortOffsetRunHeader::new(3, 2192),
352        ShortOffsetRunHeader::new(11, 6158), ShortOffsetRunHeader::new(15, 8203),
353        ShortOffsetRunHeader::new(17, 65279), ShortOffsetRunHeader::new(25, 69821),
354        ShortOffsetRunHeader::new(29, 78896), ShortOffsetRunHeader::new(33, 113824),
355        ShortOffsetRunHeader::new(35, 119155), ShortOffsetRunHeader::new(37, 917505),
356        ShortOffsetRunHeader::new(39, 2031744),
357    ];
358    static OFFSETS: [u8; 43] = [
359        173, 1, 0, 6, 22, 1, 192, 1, 49, 1, 0, 2, 80, 1, 0, 1, 0, 5, 26, 5, 49, 5, 1, 10, 0, 1,
360        249, 3, 0, 1, 15, 1, 0, 16, 0, 4, 0, 8, 0, 1, 30, 96, 0,
361    ];
362    #[inline]
363    pub fn lookup(c: char) -> bool {
364        debug_assert!(!c.is_ascii());
365        (c as u32) >= 0xad && lookup_slow(c)
366    }
367
368    #[inline(never)]
369    fn lookup_slow(c: char) -> bool {
370        const {
371            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
372            let mut i = 0;
373            while i < SHORT_OFFSET_RUNS.len() {
374                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
375                i += 1;
376            }
377        }
378        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
379        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
380        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
381    }
382}
383
384#[rustfmt::skip]
385pub mod cn_planes_0_3 {
386    use super::ShortOffsetRunHeader;
387
388    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 60] = [
389        ShortOffsetRunHeader::new(0, 888), ShortOffsetRunHeader::new(1, 1328),
390        ShortOffsetRunHeader::new(11, 1806), ShortOffsetRunHeader::new(23, 4681),
391        ShortOffsetRunHeader::new(323, 5789), ShortOffsetRunHeader::new(363, 7958),
392        ShortOffsetRunHeader::new(441, 9258), ShortOffsetRunHeader::new(483, 11124),
393        ShortOffsetRunHeader::new(487, 11508), ShortOffsetRunHeader::new(489, 42125),
394        ShortOffsetRunHeader::new(543, 42540), ShortOffsetRunHeader::new(547, 55204),
395        ShortOffsetRunHeader::new(601, 64110), ShortOffsetRunHeader::new(607, 64976),
396        ShortOffsetRunHeader::new(625, 67383), ShortOffsetRunHeader::new(731, 74650),
397        ShortOffsetRunHeader::new(1065, 75076), ShortOffsetRunHeader::new(1067, 75399),
398        ShortOffsetRunHeader::new(1069, 77712), ShortOffsetRunHeader::new(1070, 78934),
399        ShortOffsetRunHeader::new(1073, 82939), ShortOffsetRunHeader::new(1075, 83527),
400        ShortOffsetRunHeader::new(1077, 90368), ShortOffsetRunHeader::new(1078, 92160),
401        ShortOffsetRunHeader::new(1080, 92729), ShortOffsetRunHeader::new(1081, 93504),
402        ShortOffsetRunHeader::new(1104, 101595), ShortOffsetRunHeader::new(1123, 102802),
403        ShortOffsetRunHeader::new(1129, 110576), ShortOffsetRunHeader::new(1132, 110889),
404        ShortOffsetRunHeader::new(1139, 111356), ShortOffsetRunHeader::new(1149, 113664),
405        ShortOffsetRunHeader::new(1150, 117760), ShortOffsetRunHeader::new(1160, 118452),
406        ShortOffsetRunHeader::new(1163, 119366), ShortOffsetRunHeader::new(1179, 120487),
407        ShortOffsetRunHeader::new(1227, 120780), ShortOffsetRunHeader::new(1229, 121484),
408        ShortOffsetRunHeader::new(1231, 122624), ShortOffsetRunHeader::new(1238, 123536),
409        ShortOffsetRunHeader::new(1264, 124112), ShortOffsetRunHeader::new(1270, 126065),
410        ShortOffsetRunHeader::new(1300, 126976), ShortOffsetRunHeader::new(1372, 128730),
411        ShortOffsetRunHeader::new(1397, 129624), ShortOffsetRunHeader::new(1423, 131072),
412        ShortOffsetRunHeader::new(1442, 173792), ShortOffsetRunHeader::new(1443, 178207),
413        ShortOffsetRunHeader::new(1445, 183982), ShortOffsetRunHeader::new(1447, 191457),
414        ShortOffsetRunHeader::new(1449, 192094), ShortOffsetRunHeader::new(1451, 194560),
415        ShortOffsetRunHeader::new(1452, 195102), ShortOffsetRunHeader::new(1453, 196608),
416        ShortOffsetRunHeader::new(1454, 201547), ShortOffsetRunHeader::new(1455, 210042),
417        ShortOffsetRunHeader::new(1457, 249856), ShortOffsetRunHeader::new(1458, 261184),
418        ShortOffsetRunHeader::new(1459, 262142), ShortOffsetRunHeader::new(1460, 1376254),
419    ];
420    static OFFSETS: [u8; 1461] = [
421        0, 2, 6, 4, 7, 1, 1, 1, 20, 1, 0, 1, 38, 1, 56, 1, 57, 6, 27, 4, 6, 11, 0, 1, 60, 2, 101,
422        14, 59, 2, 49, 2, 15, 1, 28, 2, 1, 1, 11, 5, 34, 5, 237, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3,
423        4, 2, 9, 2, 2, 2, 4, 8, 1, 4, 2, 1, 5, 2, 25, 2, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2, 1,
424        2, 2, 1, 1, 5, 4, 2, 2, 3, 3, 1, 7, 4, 1, 1, 7, 17, 10, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1,
425        5, 2, 10, 1, 3, 1, 3, 2, 1, 15, 4, 2, 12, 7, 7, 1, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5,
426        2, 9, 2, 2, 2, 3, 5, 5, 4, 2, 1, 5, 2, 18, 10, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2,
427        3, 3, 3, 12, 4, 5, 3, 3, 1, 4, 2, 1, 6, 1, 14, 21, 5, 13, 1, 3, 1, 23, 1, 16, 2, 9, 1, 3, 1,
428        4, 7, 2, 1, 3, 1, 2, 2, 4, 2, 10, 7, 22, 1, 3, 1, 23, 1, 10, 1, 5, 2, 9, 1, 3, 1, 4, 7, 2,
429        5, 3, 1, 4, 2, 10, 1, 3, 12, 13, 1, 3, 1, 51, 1, 3, 1, 6, 4, 16, 2, 26, 1, 3, 1, 18, 3, 24,
430        1, 9, 1, 1, 2, 7, 3, 1, 4, 6, 1, 1, 1, 8, 6, 10, 2, 3, 12, 58, 4, 29, 37, 2, 1, 1, 1, 5, 1,
431        24, 1, 1, 1, 23, 2, 5, 1, 1, 1, 7, 1, 10, 2, 4, 32, 72, 1, 36, 4, 39, 1, 36, 1, 15, 1, 13,
432        37, 198, 1, 1, 5, 1, 2, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33, 1, 4, 2, 7, 1, 1, 1,
433        4, 2, 15, 1, 57, 1, 4, 2, 67, 2, 32, 3, 26, 6, 86, 2, 6, 2, 0, 3, 89, 7, 22, 9, 24, 9, 20,
434        12, 13, 1, 3, 1, 2, 12, 94, 2, 10, 6, 10, 6, 26, 6, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 12,
435        4, 1, 3, 42, 2, 5, 11, 44, 4, 26, 6, 11, 3, 62, 2, 65, 1, 29, 2, 11, 6, 10, 6, 14, 2, 65,
436        15, 77, 1, 166, 8, 60, 3, 15, 3, 62, 5, 43, 2, 11, 8, 43, 5, 0, 2, 6, 2, 38, 2, 6, 2, 8, 1,
437        1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 15, 1, 14, 2, 6, 1, 19, 2, 3, 1, 9, 1, 101, 1, 12, 2, 81,
438        11, 33, 15, 140, 4, 0, 22, 11, 21, 0, 2, 0, 5, 45, 1, 1, 5, 1, 2, 56, 7, 2, 14, 24, 9, 7, 1,
439        7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 126, 2, 4, 28, 26, 1, 89, 12, 214, 26, 80, 1, 86,
440        2, 103, 5, 43, 1, 94, 1, 86, 9, 48, 1, 0, 3, 55, 9, 0, 20, 184, 8, 222, 4, 1, 14, 60, 3, 10,
441        6, 56, 8, 70, 8, 12, 6, 116, 11, 30, 3, 78, 1, 11, 4, 33, 1, 55, 9, 14, 2, 10, 2, 103, 24,
442        28, 10, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 62, 2, 126, 2, 10, 6, 0, 12, 23, 4, 49, 4, 0, 2, 106,
443        38, 7, 12, 5, 5, 26, 1, 5, 1, 1, 1, 2, 1, 2, 1, 0, 32, 42, 6, 51, 1, 19, 1, 4, 4, 5, 1, 135,
444        2, 1, 1, 190, 3, 6, 2, 6, 2, 6, 2, 3, 3, 7, 1, 7, 10, 5, 2, 12, 1, 26, 1, 19, 1, 2, 1, 15,
445        2, 14, 34, 123, 5, 3, 4, 45, 3, 88, 1, 13, 3, 1, 47, 46, 130, 29, 3, 49, 15, 28, 4, 36, 9,
446        30, 5, 43, 5, 30, 1, 37, 4, 14, 42, 158, 2, 10, 6, 36, 4, 36, 4, 40, 8, 52, 11, 12, 1, 15,
447        1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1, 14, 64,
448        6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 1, 72, 8, 9, 48, 19, 1, 2, 5, 33, 3, 27, 5, 27, 38, 56,
449        4, 20, 2, 50, 1, 2, 5, 8, 1, 3, 1, 29, 2, 3, 4, 10, 7, 9, 7, 64, 32, 39, 4, 12, 9, 54, 3,
450        29, 2, 27, 5, 26, 7, 4, 12, 7, 80, 73, 55, 51, 13, 51, 7, 46, 8, 10, 6, 38, 3, 29, 8, 2,
451        208, 31, 1, 42, 1, 3, 2, 2, 16, 6, 1, 38, 1, 56, 8, 42, 22, 26, 38, 28, 20, 23, 9, 78, 4,
452        36, 9, 68, 10, 1, 2, 25, 7, 10, 6, 53, 1, 18, 8, 39, 9, 96, 1, 20, 11, 18, 1, 47, 62, 7, 1,
453        1, 1, 4, 1, 15, 1, 11, 6, 59, 5, 10, 6, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 1, 10, 2, 2,
454        2, 3, 2, 1, 6, 1, 5, 7, 2, 7, 3, 5, 11, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1, 4, 1,
455        10, 1, 2, 8, 2, 29, 92, 1, 5, 30, 72, 8, 10, 166, 54, 2, 38, 34, 69, 11, 10, 6, 13, 19, 58,
456        6, 10, 6, 20, 28, 27, 2, 15, 4, 23, 185, 60, 100, 83, 12, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2,
457        2, 12, 9, 10, 70, 8, 2, 46, 2, 11, 27, 72, 8, 83, 13, 73, 7, 11, 85, 8, 88, 34, 14, 10, 6,
458        9, 1, 45, 1, 14, 10, 29, 3, 32, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 9, 8, 10,
459        6, 6, 1, 2, 1, 37, 1, 2, 1, 6, 7, 10, 6, 44, 4, 10, 6, 2, 238, 25, 7, 17, 1, 41, 3, 29, 85,
460        1, 15, 50, 13, 0, 102, 0, 12, 0, 0, 99, 13, 0, 10, 0, 5, 0, 0, 58, 0, 0, 7, 31, 1, 10, 4,
461        81, 1, 10, 6, 30, 2, 6, 10, 70, 10, 10, 1, 7, 1, 21, 5, 19, 0, 58, 198, 91, 5, 25, 2, 25,
462        44, 75, 4, 57, 7, 17, 64, 5, 11, 7, 9, 0, 36, 34, 95, 115, 13, 0, 14, 51, 0, 4, 1, 7, 1, 2,
463        1, 0, 9, 1, 29, 3, 2, 1, 14, 5, 7, 0, 0, 107, 5, 13, 3, 9, 7, 10, 2, 8, 0, 253, 3, 0, 6, 23,
464        1, 3, 8, 33, 2, 46, 2, 23, 9, 116, 60, 246, 10, 0, 10, 50, 62, 20, 12, 20, 12, 87, 9, 25,
465        135, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28,
466        1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 1, 0, 2, 0, 15, 5, 1, 15, 80, 29, 0, 130, 14, 7, 54, 58, 1,
467        17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 112, 45, 3, 14, 2, 10, 4, 2, 0, 31, 17, 58, 5, 1, 0, 42,
468        214, 43, 4, 1, 192, 31, 1, 22, 8, 2, 224, 7, 1, 4, 1, 2, 1, 15, 1, 197, 2, 16, 41, 76, 4,
469        10, 4, 2, 0, 68, 76, 61, 194, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4,
470        1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4,
471        1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 52, 2, 0, 44, 4, 100, 12, 15, 2, 15, 1, 15, 1,
472        37, 10, 175, 55, 29, 13, 44, 4, 9, 7, 2, 14, 6, 154, 0, 2, 17, 3, 13, 3, 220, 4, 12, 4, 28,
473        4, 56, 8, 10, 6, 40, 8, 30, 2, 12, 4, 2, 14, 9, 39, 0, 8, 14, 2, 13, 3, 71, 1, 1, 3, 18, 1,
474        13, 3, 12, 5, 147, 1, 103, 0, 0, 32, 0, 1, 0, 2, 0, 15, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
475    ];
476    #[inline]
477    pub fn lookup(c: char) -> bool {
478        debug_assert!(!c.is_ascii());
479        (c as u32) >= 0x378 && lookup_slow(c)
480    }
481
482    #[inline(never)]
483    fn lookup_slow(c: char) -> bool {
484        const {
485            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
486            let mut i = 0;
487            while i < SHORT_OFFSET_RUNS.len() {
488                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
489                i += 1;
490            }
491        }
492        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
493        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
494        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
495    }
496}
497
498#[rustfmt::skip]
499pub mod default_ignorable_code_point {
500    use super::ShortOffsetRunHeader;
501
502    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 12] = [
503        ShortOffsetRunHeader::new(0, 847), ShortOffsetRunHeader::new(3, 1564),
504        ShortOffsetRunHeader::new(5, 4447), ShortOffsetRunHeader::new(7, 6068),
505        ShortOffsetRunHeader::new(9, 8203), ShortOffsetRunHeader::new(13, 12644),
506        ShortOffsetRunHeader::new(19, 65024), ShortOffsetRunHeader::new(21, 113824),
507        ShortOffsetRunHeader::new(29, 119155), ShortOffsetRunHeader::new(31, 917504),
508        ShortOffsetRunHeader::new(33, 921600), ShortOffsetRunHeader::new(34, 2035712),
509    ];
510    static OFFSETS: [u8; 35] = [
511        173, 1, 0, 1, 0, 1, 0, 2, 0, 2, 85, 5, 0, 5, 26, 5, 49, 16, 0, 1, 0, 16, 239, 1, 160, 1,
512        79, 9, 0, 4, 0, 8, 0, 0, 0,
513    ];
514    #[inline]
515    pub fn lookup(c: char) -> bool {
516        debug_assert!(!c.is_ascii());
517        (c as u32) >= 0xad && lookup_slow(c)
518    }
519
520    #[inline(never)]
521    fn lookup_slow(c: char) -> bool {
522        const {
523            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
524            let mut i = 0;
525            while i < SHORT_OFFSET_RUNS.len() {
526                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
527                i += 1;
528            }
529        }
530        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
531        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
532        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
533    }
534}
535
536#[rustfmt::skip]
537pub mod grapheme_extend {
538    use super::ShortOffsetRunHeader;
539
540    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 33] = [
541        ShortOffsetRunHeader::new(0, 768), ShortOffsetRunHeader::new(1, 1155),
542        ShortOffsetRunHeader::new(3, 1425), ShortOffsetRunHeader::new(5, 4957),
543        ShortOffsetRunHeader::new(249, 5906), ShortOffsetRunHeader::new(251, 8204),
544        ShortOffsetRunHeader::new(345, 11503), ShortOffsetRunHeader::new(349, 12330),
545        ShortOffsetRunHeader::new(355, 42607), ShortOffsetRunHeader::new(359, 43010),
546        ShortOffsetRunHeader::new(367, 64286), ShortOffsetRunHeader::new(433, 65024),
547        ShortOffsetRunHeader::new(435, 65438), ShortOffsetRunHeader::new(439, 66045),
548        ShortOffsetRunHeader::new(441, 68097), ShortOffsetRunHeader::new(447, 68900),
549        ShortOffsetRunHeader::new(459, 69291), ShortOffsetRunHeader::new(463, 71727),
550        ShortOffsetRunHeader::new(601, 73459), ShortOffsetRunHeader::new(671, 78912),
551        ShortOffsetRunHeader::new(681, 90398), ShortOffsetRunHeader::new(685, 92912),
552        ShortOffsetRunHeader::new(689, 94031), ShortOffsetRunHeader::new(693, 113821),
553        ShortOffsetRunHeader::new(701, 118528), ShortOffsetRunHeader::new(703, 119079),
554        ShortOffsetRunHeader::new(707, 121344), ShortOffsetRunHeader::new(729, 122880),
555        ShortOffsetRunHeader::new(741, 123566), ShortOffsetRunHeader::new(755, 124140),
556        ShortOffsetRunHeader::new(759, 125136), ShortOffsetRunHeader::new(771, 917536),
557        ShortOffsetRunHeader::new(775, 2032112),
558    ];
559    static OFFSETS: [u8; 779] = [
560        0, 112, 0, 7, 0, 45, 1, 1, 1, 2, 1, 2, 1, 3, 70, 11, 48, 21, 16, 1, 101, 7, 2, 6, 2, 2, 1,
561        4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 59, 9, 42, 24, 1, 32,
562        55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2,
563        2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6,
564        1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 5, 5, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1,
565        55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 2, 1, 1, 3, 3, 1, 4, 7, 2, 11, 2, 28,
566        2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7,
567        12, 8, 98, 1, 2, 9, 11, 7, 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
568        102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 4, 28, 3,
569        29, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 1, 1, 117, 2, 34, 1, 118, 3, 4, 2, 9,
570        1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 65, 15, 4, 48, 10, 4,
571        3, 38, 9, 12, 2, 32, 4, 2, 6, 56, 1, 1, 2, 3, 1, 1, 5, 56, 8, 2, 2, 152, 3, 1, 13, 1, 7, 4,
572        1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0, 4, 1, 10, 32,
573        2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 1, 1, 44, 3,
574        48, 1, 2, 4, 2, 2, 2, 1, 36, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3, 2, 2, 5,
575        2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1, 149, 5,
576        0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 65, 5, 0, 2, 30, 5, 32, 16, 70, 11, 49, 4, 123,
577        1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9,
578        1, 1, 8, 4, 2, 1, 95, 3, 2, 4, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 1, 1, 1, 1, 12, 1, 9,
579        1, 14, 7, 3, 5, 67, 1, 2, 6, 1, 1, 2, 1, 1, 3, 4, 3, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1,
580        81, 1, 2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2,
581        106, 1, 1, 1, 2, 8, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 4, 4, 1, 144, 4, 2, 2,
582        4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6,
583        1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 88, 1, 0,
584        2, 11, 2, 52, 5, 5, 3, 23, 1, 0, 1, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 0, 1, 63, 4, 81, 1, 11,
585        2, 0, 2, 0, 46, 2, 23, 0, 2, 60, 5, 3, 6, 8, 8, 2, 7, 30, 4, 148, 3, 11, 3, 8, 2, 2, 1, 32,
586        2, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 100, 1, 160, 7,
587        0, 1, 61, 4, 0, 4, 254, 2, 243, 1, 2, 1, 7, 2, 5, 1, 0, 7, 109, 7, 0, 96, 128, 240, 0,
588    ];
589    #[inline]
590    pub fn lookup(c: char) -> bool {
591        debug_assert!(!c.is_ascii());
592        (c as u32) >= 0x300 && lookup_slow(c)
593    }
594
595    #[inline(never)]
596    fn lookup_slow(c: char) -> bool {
597        const {
598            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
599            let mut i = 0;
600            while i < SHORT_OFFSET_RUNS.len() {
601                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
602                i += 1;
603            }
604        }
605        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
606        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
607        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
608    }
609}
610
611#[rustfmt::skip]
612pub mod lowercase {
613    static BITSET_CHUNKS_MAP: [u8; 123] = [
614        12, 17, 0, 0, 8, 0, 0, 13, 14, 9, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
615        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
616        0, 0, 4, 1, 0, 15, 0, 11, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
617        0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 2,
618        18, 0, 7,
619    ];
620    static BITSET_INDEX_CHUNKS: [[u8; 16]; 20] = [
621        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
622        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0],
623        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 58, 48, 5],
624        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 62, 0],
625        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0],
626        [0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 20, 66, 0, 0, 0, 0],
627        [0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 46, 0, 57, 53, 55, 36],
628        [0, 0, 0, 0, 9, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
629        [0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30],
630        [0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
631        [0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
632        [0, 0, 0, 76, 0, 16, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0],
633        [0, 0, 37, 18, 26, 59, 60, 54, 52, 6, 38, 45, 0, 31, 12, 34],
634        [0, 0, 51, 0, 62, 62, 62, 0, 24, 24, 82, 24, 39, 28, 27, 40],
635        [0, 25, 77, 0, 32, 15, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0],
636        [10, 65, 0, 35, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 17, 0],
637        [16, 29, 24, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
638        [16, 56, 4, 23, 81, 7, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0],
639        [16, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
640        [71, 43, 61, 11, 72, 69, 19, 13, 1, 70, 44, 22, 78, 3, 79, 50],
641    ];
642    static BITSET_CANONICAL: [u64; 62] = [
643        0b0000000000000000000000000000000000000000000000000000000000000000,
644        0b0000111111111111111111111111110000000000000000000000000011111111,
645        0b1111111111111111111111111111111111111111111111111111101111111111,
646        0b1111111111111111000000000000000000000000001111110111111111111111,
647        0b1010101010101010101010101010101010101010101010101010100000000010,
648        0b1111111111111111111111111111111111111111111111111110000000000000,
649        0b1111111111111111111111111111111111111111111111111010101010000101,
650        0b1111111111111111111111111111111100000001000000000000000000000000,
651        0b1111111111111111111111111111111100000000000000000000000000000000,
652        0b1111111111111111111111111111110000000000000000000000000000000000,
653        0b1111111111111111111111110000000000000000000000000000000000000000,
654        0b1111111111111111111111000000000000000000000000001111111111101111,
655        0b1111111111111111111100000000000000000000000000010000000000000000,
656        0b1111111111111111110000000000000000000000000011111111111111111111,
657        0b1111111111111111000000111111111111110111111111111111111111111111,
658        0b1111111111111111000000000000000000000000000000000100001111000000,
659        0b1111111111111111000000000000000000000000000000000000000000000000,
660        0b1111111111111101111111111111111111111111111111111111111110111001,
661        0b1111111101111111111111111111111110000000000000000000000000000000,
662        0b1111110000000000000000000000000011111111111111111111111111000000,
663        0b1111100000000000000000000000000000000000000000000000000000000000,
664        0b1111011111111111111111111111111111111111111111110000000000000000,
665        0b1111000000000000000000000000001111110111111111111111111111111100,
666        0b1010101010101010101010101010101010101010101010101101010101010100,
667        0b1010101010101010101010101010101010101010101010101010101010101010,
668        0b1000000000000010000000000000000000000000000000000000000000000000,
669        0b0101010110101010101010101010101010101010101010101010101010101010,
670        0b0100000011011111000000001111111100000000111111110000000011111111,
671        0b0011111111111111000000001111111100000000111111110000000000111111,
672        0b0011111111011010000101010110001011111111111111111111111111111111,
673        0b0011111100000000000000000000000000000000000000000000000000000000,
674        0b0011110010001010000000000000000000000000000000000000000000100000,
675        0b0011001000010000100000000000000000000000000010001100010000000000,
676        0b0001101111111011111111111111101111111111100000000000000000000000,
677        0b0001100100101111101010101010101010101010111000110111111111111111,
678        0b0000111111111111111111111111111111111111000000000000000000000000,
679        0b0000011101011110000000000000000000001010101010101010010100001010,
680        0b0000010000100000000001000000000000000000000000000000000000000000,
681        0b0000000111111111111111111111111111111111110011111111111111111111,
682        0b0000000011111111000000001111111100000000001111110000000011111111,
683        0b0000000011011100000000001111111100000000110011110000000011011100,
684        0b0000000000001000010100000001101010101010101010101010101010101010,
685        0b0000000000000000001000001011111111111111111111111111111111111111,
686        0b0000000000000000000000001111111111111111110111111100000000000000,
687        0b0000000000000000000000000111111111111111111111111111110000000000,
688        0b0000000000000000000000000001111100000000000000000000000000000011,
689        0b0000000000000000000000000000000000111010101010101010101010101010,
690        0b0000000000000000000000000000000000000000111110000000000001111111,
691        0b0000000000000000000000000000000000000000011111110000000000000000,
692        0b0000000000000000000000000000000000000000000000000001100111111111,
693        0b0000000000000000000000000000000000000000000000000000101111110111,
694        0b0000000000000000000000000000000000000000000000000000010111111111,
695        0b1001001111111010101010101010101010101010101010101010101010101010,
696        0b1001010111111111101010101010101010101010101010101010101010101010,
697        0b1010101000101001101010101010101010110101010101010101001001000000,
698        0b1010101010100000100000101010101010101010101110100101000010101010,
699        0b1010101010101010101010101010101011111111111111111111111111111111,
700        0b1010101010101011101010101010100000000000000000000000000000000000,
701        0b1010101010101011101010101111111111111111111111011101101011111110,
702        0b1101010010101010101010101010101010101010101010101010101101010101,
703        0b1110011001010001001011010010101001001110001001000011000100101001,
704        0b1110101111000000000000000000000000001111111111111111111111111100,
705    ];
706    static BITSET_MAPPING: [(u8, u8); 21] = [
707        (0, 64), (1, 184), (1, 182), (1, 172), (1, 168), (1, 161), (1, 146), (1, 144), (1, 140),
708        (1, 136), (1, 132), (2, 122), (2, 160), (2, 146), (2, 141), (3, 160), (3, 6), (3, 58),
709        (4, 146), (4, 144), (4, 83),
710    ];
711
712    pub const fn lookup(c: char) -> bool {
713        debug_assert!(!c.is_ascii());
714        (c as u32) >= 0xaa &&
715        super::bitset_search(
716            c as u32,
717            &BITSET_CHUNKS_MAP,
718            &BITSET_INDEX_CHUNKS,
719            &BITSET_CANONICAL,
720            &BITSET_MAPPING,
721        )
722    }
723}
724
725#[rustfmt::skip]
726pub mod lt {
727    use super::ShortOffsetRunHeader;
728
729    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 3] = [
730        ShortOffsetRunHeader::new(0, 453), ShortOffsetRunHeader::new(1, 8072),
731        ShortOffsetRunHeader::new(9, 1122301),
732    ];
733    static OFFSETS: [u8; 21] = [
734        0, 1, 2, 1, 2, 1, 38, 1, 0, 8, 8, 8, 8, 8, 12, 1, 15, 1, 47, 1, 0,
735    ];
736    #[inline]
737    pub fn lookup(c: char) -> bool {
738        debug_assert!(!c.is_ascii());
739        (c as u32) >= 0x1c5 && lookup_slow(c)
740    }
741
742    #[inline(never)]
743    fn lookup_slow(c: char) -> bool {
744        const {
745            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
746            let mut i = 0;
747            while i < SHORT_OFFSET_RUNS.len() {
748                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
749                i += 1;
750            }
751        }
752        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
753        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
754        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
755    }
756}
757
758#[rustfmt::skip]
759pub mod n {
760    use super::ShortOffsetRunHeader;
761
762    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 44] = [
763        ShortOffsetRunHeader::new(0, 1632), ShortOffsetRunHeader::new(7, 2406),
764        ShortOffsetRunHeader::new(13, 4160), ShortOffsetRunHeader::new(47, 4969),
765        ShortOffsetRunHeader::new(51, 5870), ShortOffsetRunHeader::new(53, 6470),
766        ShortOffsetRunHeader::new(61, 8304), ShortOffsetRunHeader::new(77, 9312),
767        ShortOffsetRunHeader::new(87, 10102), ShortOffsetRunHeader::new(91, 11517),
768        ShortOffsetRunHeader::new(93, 12295), ShortOffsetRunHeader::new(95, 12690),
769        ShortOffsetRunHeader::new(101, 42528), ShortOffsetRunHeader::new(113, 43056),
770        ShortOffsetRunHeader::new(117, 44016), ShortOffsetRunHeader::new(129, 65296),
771        ShortOffsetRunHeader::new(131, 65799), ShortOffsetRunHeader::new(133, 66273),
772        ShortOffsetRunHeader::new(139, 67672), ShortOffsetRunHeader::new(151, 68858),
773        ShortOffsetRunHeader::new(181, 69216), ShortOffsetRunHeader::new(187, 70736),
774        ShortOffsetRunHeader::new(207, 71248), ShortOffsetRunHeader::new(211, 71904),
775        ShortOffsetRunHeader::new(219, 72688), ShortOffsetRunHeader::new(223, 73552),
776        ShortOffsetRunHeader::new(233, 74752), ShortOffsetRunHeader::new(237, 75399),
777        ShortOffsetRunHeader::new(242, 90416), ShortOffsetRunHeader::new(243, 92768),
778        ShortOffsetRunHeader::new(245, 93552), ShortOffsetRunHeader::new(253, 93824),
779        ShortOffsetRunHeader::new(255, 94196), ShortOffsetRunHeader::new(257, 118000),
780        ShortOffsetRunHeader::new(259, 119488), ShortOffsetRunHeader::new(261, 120782),
781        ShortOffsetRunHeader::new(267, 123200), ShortOffsetRunHeader::new(269, 123632),
782        ShortOffsetRunHeader::new(271, 124144), ShortOffsetRunHeader::new(273, 125127),
783        ShortOffsetRunHeader::new(277, 126065), ShortOffsetRunHeader::new(281, 127232),
784        ShortOffsetRunHeader::new(291, 130032), ShortOffsetRunHeader::new(293, 1244154),
785    ];
786    static OFFSETS: [u8; 295] = [
787        178, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118, 10, 118,
788        10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10, 70, 20,
789        0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, 182, 10,
790        86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, 1, 0, 1,
791        25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, 154, 10,
792        38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, 29, 1, 8,
793        1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, 52, 2,
794        30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 6, 10, 0, 31, 158, 10, 42, 4, 112, 7, 134,
795        30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 6, 20, 76, 12,
796        0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 54, 10, 0, 10, 102, 21, 0, 112, 5, 11, 208,
797        0, 0, 10, 0, 10, 86, 10, 134, 10, 1, 7, 0, 10, 0, 23, 0, 3, 0, 10, 0, 20, 12, 20, 108, 25,
798        0, 50, 0, 10, 0, 10, 0, 10, 247, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13,
799        0, 10, 0,
800    ];
801    #[inline]
802    pub fn lookup(c: char) -> bool {
803        debug_assert!(!c.is_ascii());
804        (c as u32) >= 0xb2 && lookup_slow(c)
805    }
806
807    #[inline(never)]
808    fn lookup_slow(c: char) -> bool {
809        const {
810            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
811            let mut i = 0;
812            while i < SHORT_OFFSET_RUNS.len() {
813                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
814                i += 1;
815            }
816        }
817        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
818        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
819        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
820    }
821}
822
823#[rustfmt::skip]
824pub mod uppercase {
825    static BITSET_CHUNKS_MAP: [u8; 125] = [
826        3, 16, 8, 8, 0, 8, 8, 2, 5, 14, 8, 17, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
827        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 11, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
828        8, 8, 8, 8, 9, 8, 15, 8, 13, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
829        8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 18, 8,
830        6, 8, 8, 12, 8, 4,
831    ];
832    static BITSET_INDEX_CHUNKS: [[u8; 16]; 19] = [
833        [46, 46, 5, 37, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 5, 0],
834        [46, 46, 5, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46],
835        [46, 46, 42, 46, 46, 46, 46, 46, 17, 17, 68, 17, 45, 30, 25, 24],
836        [46, 46, 46, 34, 38, 22, 23, 15, 13, 36, 46, 46, 46, 11, 32, 41],
837        [46, 46, 46, 46, 9, 8, 47, 46, 46, 46, 46, 46, 46, 46, 46, 46],
838        [46, 46, 46, 46, 39, 29, 69, 46, 46, 46, 46, 46, 46, 46, 46, 46],
839        [46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 21, 46, 46],
840        [46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 31, 46, 46],
841        [46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46],
842        [46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 59, 46, 46, 46],
843        [46, 46, 46, 46, 46, 46, 46, 46, 46, 51, 65, 46, 46, 46, 46, 46],
844        [46, 46, 46, 46, 46, 46, 46, 46, 46, 67, 66, 46, 20, 14, 16, 4],
845        [46, 46, 46, 46, 52, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46],
846        [46, 46, 55, 46, 46, 33, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46],
847        [46, 46, 56, 48, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46],
848        [53, 46, 9, 49, 46, 44, 35, 46, 46, 46, 46, 46, 46, 46, 46, 46],
849        [54, 19, 3, 18, 10, 50, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46],
850        [54, 40, 17, 28, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46],
851        [60, 1, 27, 57, 12, 7, 26, 58, 43, 61, 6, 2, 64, 63, 62, 70],
852    ];
853    static BITSET_CANONICAL: [u64; 46] = [
854        0b0000000000111111111111111111111111111111111111111111111111111111,
855        0b1111111111111111111111110000000000000000000000000011111111111111,
856        0b0000011111111111111111111111110000000000000000000000000000000001,
857        0b0101010101010101010101010101010101010101010101010101010000000001,
858        0b0000000000100000000000000000010000110101010101010101101011110101,
859        0b1111111111111111111111111111111100000000000000000000000000000000,
860        0b1111111111111111111111110000000000000000000000000000001111111111,
861        0b1111111111111111111100000000000000000000000000011111110001011111,
862        0b1111111111111111000000111111111111111111111111110000001111111111,
863        0b1111111111111111000000000000000000000000000000000000000000000000,
864        0b1111111111111110010101010101010101010101010101010101010101010101,
865        0b1000000001000101000000000000000000000000000000000000000000000000,
866        0b0111101100000000000000000000000000011111110111111110011110110000,
867        0b0110110000000101010101010101010101010101010101010101010101010101,
868        0b0110101000000000010101010101010101010101010101010101010101010101,
869        0b0101010111010010010101010101010101001010101010101010010010010000,
870        0b0101010101011111011111010101010101010101010001010010100001010101,
871        0b0101010101010101010101010101010101010101010101010101010101010101,
872        0b0101010101010101010101010101010101010101010101010010101010101011,
873        0b0101010101010101010101010101010100000000000000000000000000000000,
874        0b0101010101010100010101010101010000000000000000000000000000000000,
875        0b0101010101010100010101010000000000000000000000100010010100000001,
876        0b0010101101010101010101010101010101010101010101010101010010101010,
877        0b0001000110101110110100101101010110110001110110111100111011010110,
878        0b0000111100000000000111110000000000001111000000000000111100000000,
879        0b0000111100000000000000000000000000000000000000000000000000000000,
880        0b0000001111111111111111111111111100000000000000000000000000111111,
881        0b0000000000111111110111100110010011010000000000000000000000000011,
882        0b0000000000000100001010000000010101010101010101010101010101010101,
883        0b0000000000000000111111111111111100000000000000000000000000100000,
884        0b0000000000000000111111110000000010101010000000000011111100000000,
885        0b0000000000000000001100000000000000000000000000000000000000000000,
886        0b0000000000000000000011111111101111111111111111101101011101000000,
887        0b0000000000000000000000000011111111111111111111110000000000000000,
888        0b0000000000000000000000000000000001111111011111111111111111111111,
889        0b0000000000000000000000000000000000000000001101111111011111111111,
890        0b0000000000000000000000000000000000000000000000000101010101111010,
891        0b0000000000000000000000000000000000000000000000000010000010111111,
892        0b1010101001010101010101010101010101010101010101010101010101010101,
893        0b1100000000001111001111010101000000111110001001110011100010000100,
894        0b1100000000100101111010101001110100000000000000000000000000000000,
895        0b1110011010010000010101010101010101010101000111001000000000000000,
896        0b1110011111111111111111111111111111111111111111110000001000000000,
897        0b1111000000000000000000000000001111111111111111111111111100000000,
898        0b1111011111111111000000000000000000000000000000000000000000000000,
899        0b1111111100000000111111110000000000111111000000001111111100000000,
900    ];
901    static BITSET_MAPPING: [(u8, u8); 25] = [
902        (0, 182), (0, 74), (0, 166), (0, 162), (0, 159), (0, 150), (0, 148), (0, 142), (0, 134),
903        (0, 131), (0, 64), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 146), (2, 140), (2, 134),
904        (2, 130), (3, 164), (3, 146), (3, 20), (4, 178), (4, 171),
905    ];
906
907    pub const fn lookup(c: char) -> bool {
908        debug_assert!(!c.is_ascii());
909        (c as u32) >= 0xc0 &&
910        super::bitset_search(
911            c as u32,
912            &BITSET_CHUNKS_MAP,
913            &BITSET_INDEX_CHUNKS,
914            &BITSET_CANONICAL,
915            &BITSET_MAPPING,
916        )
917    }
918}
919
920#[rustfmt::skip]
921pub mod white_space {
922    static WHITESPACE_MAP: [u8; 256] = [
923        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
924        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
925        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
926        0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
927        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
928        0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
929        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
930        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
931        0, 0, 0, 0, 0, 0, 0, 0, 0,
932    ];
933    #[inline]
934    pub const fn lookup(c: char) -> bool {
935        debug_assert!(!c.is_ascii());
936        match c as u32 >> 8 {
937            0 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0,
938            22 => c as u32 == 0x1680,
939            32 => WHITESPACE_MAP[c as usize & 0xff] & 2 != 0,
940            48 => c as u32 == 0x3000,
941            _ => false,
942        }
943    }
944}
945
946#[rustfmt::skip]
947pub mod conversions {
948
949
950    use crate::ops::RangeInclusive;
951
952    struct L1Lut {
953        l2_luts: [L2Lut; 2],
954    }
955
956    struct L2Lut {
957        singles: &'static [(Range, i16)],
958        multis: &'static [(u16, [u16; 3])],
959        exceptions: &'static [(u16, [char; 3])],
960    }
961
962    #[derive(Copy, Clone)]
963    struct Range {
964        start: u16,
965        len: u8,
966        parity: bool,
967    }
968
969    impl Range {
970        const fn new(range: RangeInclusive<u16>, parity: bool) -> Self {
971            let start = *range.start();
972            let end = *range.end();
973            assert!(start <= end);
974
975            let len = end - start;
976            assert!(len <= 255);
977
978            Self { start, len: len as u8, parity }
979        }
980
981        const fn singleton(start: u16) -> Self {
982            Self::new(start..=start, false)
983        }
984
985        const fn step_by_1(range: RangeInclusive<u16>) -> Self {
986            Self::new(range, false)
987        }
988
989        const fn step_by_2(range: RangeInclusive<u16>) -> Self {
990            Self::new(range, true)
991        }
992
993        const fn start(&self) -> u16 {
994            self.start
995        }
996
997        const fn end(&self) -> u16 {
998            self.start + self.len as u16
999        }
1000    }
1001
1002    fn deconstruct(c: char) -> (u16, u16) {
1003        let c = c as u32;
1004        let plane = (c >> 16) as u16;
1005        let low = c as u16;
1006        (plane, low)
1007    }
1008
1009    unsafe fn reconstruct(plane: u16, low: u16) -> char {
1010        // SAFETY: The caller must ensure that the result is a valid `char`.
1011        unsafe { char::from_u32_unchecked(((plane as u32) << 16) | (low as u32)) }
1012    }
1013
1014    fn lookup(input: char, l1_lut: &L1Lut) -> Option<[char; 3]> {
1015        let (input_high, input_low) = deconstruct(input);
1016        let Some(l2_lut) = l1_lut.l2_luts.get(input_high as usize) else {
1017            return None;
1018        };
1019
1020        let idx = l2_lut.singles.binary_search_by(|(range, _)| {
1021            use crate::cmp::Ordering;
1022
1023            if input_low < range.start() {
1024                Ordering::Greater
1025            } else if input_low > range.end() {
1026                Ordering::Less
1027            } else {
1028                Ordering::Equal
1029            }
1030        });
1031
1032        if let Ok(idx) = idx {
1033            // SAFETY: binary search guarantees that the index is in bounds.
1034            let &(range, output_delta) = unsafe { l2_lut.singles.get_unchecked(idx) };
1035            let mask = range.parity as u16;
1036            if input_low & mask == range.start() & mask {
1037                let output_low = input_low.wrapping_add_signed(output_delta);
1038                // SAFETY: Table data are guaranteed to be valid Unicode.
1039                let output = unsafe { reconstruct(input_high, output_low) };
1040                return Some([output, '\0', '\0']);
1041            }
1042        };
1043
1044        if let Ok(idx) = l2_lut.multis.binary_search_by_key(&input_low, |&(p, _)| p) {
1045            // SAFETY: binary search guarantees that the index is in bounds.
1046            let &(_, output_lows) = unsafe { l2_lut.multis.get_unchecked(idx) };
1047            // SAFETY: Table data are guaranteed to be valid Unicode.
1048            let output = output_lows.map(|output_low| unsafe { reconstruct(input_high, output_low) });
1049            return Some(output);
1050        };
1051
1052        for &(key, output) in l2_lut.exceptions {
1053            if key == input_low {
1054                return Some(output)
1055            }
1056        }
1057
1058        None
1059    }
1060
1061    pub fn to_lower(c: char) -> [char; 3] {
1062        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Lowercased:]-[:ASCII:]&abb=on
1063        if c < '\u{C0}' {
1064            return [c.to_ascii_lowercase(), '\0', '\0'];
1065        }
1066
1067        lookup(c, &LOWERCASE_LUT).unwrap_or([c, '\0', '\0'])
1068    }
1069
1070    pub fn to_upper(c: char) -> [char; 3] {
1071        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Uppercased:]-[:ASCII:]&abb=on
1072        if c < '\u{B5}' {
1073            return [c.to_ascii_uppercase(), '\0', '\0'];
1074        }
1075
1076        lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0'])
1077    }
1078
1079    pub fn to_title(c: char) -> [char; 3] {
1080        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Titlecased:]-[:ASCII:]&abb=on
1081        if c < '\u{B5}' {
1082            return [c.to_ascii_uppercase(), '\0', '\0'];
1083        }
1084
1085        lookup(c, &TITLECASE_LUT).or_else(|| lookup(c, &UPPERCASE_LUT)).unwrap_or([c, '\0', '\0'])
1086    }
1087
1088    pub fn to_casefold(c: char) -> [char; 3] {
1089        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Casefolded:]-[:ASCII:]&abb=on
1090        if c < '\u{B5}' {
1091            return [c.to_ascii_lowercase(), '\0', '\0'];
1092        }
1093
1094
1095        lookup(c, &CASEFOLD_LUT).unwrap_or_else(|| {
1096            // Fall back to lowercase of uppercase
1097
1098            let uppercase = lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0']);
1099
1100            // We need to take the lowercase of each character in `uppercase`,
1101            // and then concatenate them together.
1102
1103            // Lowercase the first uppercased char
1104            let mut final_result = to_lower(uppercase[0]);
1105
1106            if uppercase[1] != '\0' {
1107                // There's a 2nd uppercase char, lowercase it as well
1108                let lowercase_1 = to_lower(uppercase[1]);
1109
1110                // The lowercase of the second uppercase character
1111                // can't be 3 chars long;
1112                // that would bring the total case-folding length
1113                // above 3 characters, which would violate
1114                // a Unicode stability guarantee.
1115                debug_assert_eq!(lowercase_1[2], '\0');
1116
1117                // Currently, in every case where there
1118                // are multiple uppercased characters,
1119                // the lowercase of the first uppercase
1120                // has length 1. However, Unicode doesn't
1121                // guarantee this.
1122                // If, after updating the Unicode data
1123                // to a new Unicode version, the below
1124                // assertion starts to fail in
1125                // `coretests/tests/unicode.rs` `to_casefold()`,
1126                // delete it, and uncomment the
1127                // `if` condition and corresponding
1128                // `else` block below it.
1129                debug_assert_eq!(final_result[1], '\0');
1130                //if final_result[1] == '\0' {
1131
1132                final_result[1] = lowercase_1[0];
1133
1134                if uppercase[2] != '\0' {
1135                    // There's a 3rd uppercased char, lowercase it as well.
1136                    // Because of the Unicode stability guarantee that case-folding
1137                    // does not expand a string more than 3x in length,
1138                    // we know this lowercase must be 1 char long.
1139
1140                    debug_assert_eq!(lowercase_1[1], '\0');
1141                    let lowercase_2 = to_lower(uppercase[2]);
1142                    debug_assert_eq!(lowercase_2[1], '\0');
1143                    debug_assert_eq!(lowercase_2[2], '\0');
1144                    final_result[2] = lowercase_2[0];
1145                } else {
1146                    // Currently, the lowercase of
1147                    // the second uppercase character
1148                    // can't be 2 chars long either,
1149                    // but Unicode doesn't guarantee this.
1150                    // If, after updating the Unicode data
1151                    // to a new Unicode version, the below
1152                    // assertion starts to fail in
1153                    // `coretests/tests/unicode.rs` `to_casefold()`,
1154                    // delete it and uncomment the line
1155                    // below it.
1156                    debug_assert_eq!(lowercase_1[1], '\0');
1157                    //final_result[2] = lowercase_1[1];
1158                }
1159
1160                /*} else {
1161                    final_result[2] = lowercase_1[0];
1162                    debug_assert_eq!(lowercase_1[1], '\0');
1163                    debug_assert_eq!(uppercase[2], '\0')
1164                }*/
1165            }
1166            final_result
1167        })
1168    }
1169
1170    static LOWERCASE_LUT: L1Lut = L1Lut {
1171        l2_luts: [
1172            L2Lut {
1173                singles: &[ // 175 entries, 1050 bytes
1174                    (Range::step_by_1(0x00c0..=0x00d6), 32), (Range::step_by_1(0x00d8..=0x00de), 32),
1175                    (Range::step_by_2(0x0100..=0x012e), 1), (Range::step_by_2(0x0132..=0x0136), 1),
1176                    (Range::step_by_2(0x0139..=0x0147), 1), (Range::step_by_2(0x014a..=0x0176), 1),
1177                    (Range::singleton(0x0178), -121), (Range::step_by_2(0x0179..=0x017d), 1),
1178                    (Range::singleton(0x0181), 210), (Range::step_by_2(0x0182..=0x0184), 1),
1179                    (Range::singleton(0x0186), 206), (Range::singleton(0x0187), 1),
1180                    (Range::step_by_1(0x0189..=0x018a), 205), (Range::singleton(0x018b), 1),
1181                    (Range::singleton(0x018e), 79), (Range::singleton(0x018f), 202),
1182                    (Range::singleton(0x0190), 203), (Range::singleton(0x0191), 1),
1183                    (Range::singleton(0x0193), 205), (Range::singleton(0x0194), 207),
1184                    (Range::singleton(0x0196), 211), (Range::singleton(0x0197), 209),
1185                    (Range::singleton(0x0198), 1), (Range::singleton(0x019c), 211),
1186                    (Range::singleton(0x019d), 213), (Range::singleton(0x019f), 214),
1187                    (Range::step_by_2(0x01a0..=0x01a4), 1), (Range::singleton(0x01a6), 218),
1188                    (Range::singleton(0x01a7), 1), (Range::singleton(0x01a9), 218),
1189                    (Range::singleton(0x01ac), 1), (Range::singleton(0x01ae), 218),
1190                    (Range::singleton(0x01af), 1), (Range::step_by_1(0x01b1..=0x01b2), 217),
1191                    (Range::step_by_2(0x01b3..=0x01b5), 1), (Range::singleton(0x01b7), 219),
1192                    (Range::singleton(0x01b8), 1), (Range::singleton(0x01bc), 1), (Range::singleton(0x01c4), 2),
1193                    (Range::singleton(0x01c5), 1), (Range::singleton(0x01c7), 2), (Range::singleton(0x01c8), 1),
1194                    (Range::singleton(0x01ca), 2), (Range::step_by_2(0x01cb..=0x01db), 1),
1195                    (Range::step_by_2(0x01de..=0x01ee), 1), (Range::singleton(0x01f1), 2),
1196                    (Range::step_by_2(0x01f2..=0x01f4), 1), (Range::singleton(0x01f6), -97),
1197                    (Range::singleton(0x01f7), -56), (Range::step_by_2(0x01f8..=0x021e), 1),
1198                    (Range::singleton(0x0220), -130), (Range::step_by_2(0x0222..=0x0232), 1),
1199                    (Range::singleton(0x023a), 10795), (Range::singleton(0x023b), 1),
1200                    (Range::singleton(0x023d), -163), (Range::singleton(0x023e), 10792),
1201                    (Range::singleton(0x0241), 1), (Range::singleton(0x0243), -195),
1202                    (Range::singleton(0x0244), 69), (Range::singleton(0x0245), 71),
1203                    (Range::step_by_2(0x0246..=0x024e), 1), (Range::step_by_2(0x0370..=0x0372), 1),
1204                    (Range::singleton(0x0376), 1), (Range::singleton(0x037f), 116),
1205                    (Range::singleton(0x0386), 38), (Range::step_by_1(0x0388..=0x038a), 37),
1206                    (Range::singleton(0x038c), 64), (Range::step_by_1(0x038e..=0x038f), 63),
1207                    (Range::step_by_1(0x0391..=0x03a1), 32), (Range::step_by_1(0x03a3..=0x03ab), 32),
1208                    (Range::singleton(0x03cf), 8), (Range::step_by_2(0x03d8..=0x03ee), 1),
1209                    (Range::singleton(0x03f4), -60), (Range::singleton(0x03f7), 1),
1210                    (Range::singleton(0x03f9), -7), (Range::singleton(0x03fa), 1),
1211                    (Range::step_by_1(0x03fd..=0x03ff), -130), (Range::step_by_1(0x0400..=0x040f), 80),
1212                    (Range::step_by_1(0x0410..=0x042f), 32), (Range::step_by_2(0x0460..=0x0480), 1),
1213                    (Range::step_by_2(0x048a..=0x04be), 1), (Range::singleton(0x04c0), 15),
1214                    (Range::step_by_2(0x04c1..=0x04cd), 1), (Range::step_by_2(0x04d0..=0x052e), 1),
1215                    (Range::step_by_1(0x0531..=0x0556), 48), (Range::step_by_1(0x10a0..=0x10c5), 7264),
1216                    (Range::singleton(0x10c7), 7264), (Range::singleton(0x10cd), 7264),
1217                    (Range::step_by_1(0x13a0..=0x13ef), -26672), (Range::step_by_1(0x13f0..=0x13f5), 8),
1218                    (Range::singleton(0x1c89), 1), (Range::step_by_1(0x1c90..=0x1cba), -3008),
1219                    (Range::step_by_1(0x1cbd..=0x1cbf), -3008), (Range::step_by_2(0x1e00..=0x1e94), 1),
1220                    (Range::singleton(0x1e9e), -7615), (Range::step_by_2(0x1ea0..=0x1efe), 1),
1221                    (Range::step_by_1(0x1f08..=0x1f0f), -8), (Range::step_by_1(0x1f18..=0x1f1d), -8),
1222                    (Range::step_by_1(0x1f28..=0x1f2f), -8), (Range::step_by_1(0x1f38..=0x1f3f), -8),
1223                    (Range::step_by_1(0x1f48..=0x1f4d), -8), (Range::step_by_2(0x1f59..=0x1f5f), -8),
1224                    (Range::step_by_1(0x1f68..=0x1f6f), -8), (Range::step_by_1(0x1f88..=0x1f8f), -8),
1225                    (Range::step_by_1(0x1f98..=0x1f9f), -8), (Range::step_by_1(0x1fa8..=0x1faf), -8),
1226                    (Range::step_by_1(0x1fb8..=0x1fb9), -8), (Range::step_by_1(0x1fba..=0x1fbb), -74),
1227                    (Range::singleton(0x1fbc), -9), (Range::step_by_1(0x1fc8..=0x1fcb), -86),
1228                    (Range::singleton(0x1fcc), -9), (Range::step_by_1(0x1fd8..=0x1fd9), -8),
1229                    (Range::step_by_1(0x1fda..=0x1fdb), -100), (Range::step_by_1(0x1fe8..=0x1fe9), -8),
1230                    (Range::step_by_1(0x1fea..=0x1feb), -112), (Range::singleton(0x1fec), -7),
1231                    (Range::step_by_1(0x1ff8..=0x1ff9), -128), (Range::step_by_1(0x1ffa..=0x1ffb), -126),
1232                    (Range::singleton(0x1ffc), -9), (Range::singleton(0x2126), -7517),
1233                    (Range::singleton(0x212a), -8383), (Range::singleton(0x212b), -8262),
1234                    (Range::singleton(0x2132), 28), (Range::step_by_1(0x2160..=0x216f), 16),
1235                    (Range::singleton(0x2183), 1), (Range::step_by_1(0x24b6..=0x24cf), 26),
1236                    (Range::step_by_1(0x2c00..=0x2c2f), 48), (Range::singleton(0x2c60), 1),
1237                    (Range::singleton(0x2c62), -10743), (Range::singleton(0x2c63), -3814),
1238                    (Range::singleton(0x2c64), -10727), (Range::step_by_2(0x2c67..=0x2c6b), 1),
1239                    (Range::singleton(0x2c6d), -10780), (Range::singleton(0x2c6e), -10749),
1240                    (Range::singleton(0x2c6f), -10783), (Range::singleton(0x2c70), -10782),
1241                    (Range::singleton(0x2c72), 1), (Range::singleton(0x2c75), 1),
1242                    (Range::step_by_1(0x2c7e..=0x2c7f), -10815), (Range::step_by_2(0x2c80..=0x2ce2), 1),
1243                    (Range::step_by_2(0x2ceb..=0x2ced), 1), (Range::singleton(0x2cf2), 1),
1244                    (Range::step_by_2(0xa640..=0xa66c), 1), (Range::step_by_2(0xa680..=0xa69a), 1),
1245                    (Range::step_by_2(0xa722..=0xa72e), 1), (Range::step_by_2(0xa732..=0xa76e), 1),
1246                    (Range::step_by_2(0xa779..=0xa77b), 1), (Range::singleton(0xa77d), 30204),
1247                    (Range::step_by_2(0xa77e..=0xa786), 1), (Range::singleton(0xa78b), 1),
1248                    (Range::singleton(0xa78d), 23256), (Range::step_by_2(0xa790..=0xa792), 1),
1249                    (Range::step_by_2(0xa796..=0xa7a8), 1), (Range::singleton(0xa7aa), 23228),
1250                    (Range::singleton(0xa7ab), 23217), (Range::singleton(0xa7ac), 23221),
1251                    (Range::singleton(0xa7ad), 23231), (Range::singleton(0xa7ae), 23228),
1252                    (Range::singleton(0xa7b0), 23278), (Range::singleton(0xa7b1), 23254),
1253                    (Range::singleton(0xa7b2), 23275), (Range::singleton(0xa7b3), 928),
1254                    (Range::step_by_2(0xa7b4..=0xa7c2), 1), (Range::singleton(0xa7c4), -48),
1255                    (Range::singleton(0xa7c5), 23229), (Range::singleton(0xa7c6), 30152),
1256                    (Range::step_by_2(0xa7c7..=0xa7c9), 1), (Range::singleton(0xa7cb), 23193),
1257                    (Range::step_by_2(0xa7cc..=0xa7da), 1), (Range::singleton(0xa7dc), 22975),
1258                    (Range::singleton(0xa7dd), 23194), (Range::singleton(0xa7e2), 23194),
1259                    (Range::singleton(0xa7f5), 1), (Range::step_by_1(0xab6c..=0xab6d), -33),
1260                    (Range::step_by_1(0xff21..=0xff3a), 32),
1261                ],
1262                multis: &[ // 1 entries, 8 bytes
1263                    (0x0130, [0x0069, 0x0307, 0x0000]),
1264                ],
1265                exceptions: &[ // 0 entries, 0 bytes
1266                ],
1267            },
1268            L2Lut {
1269                singles: &[ // 18 entries, 108 bytes
1270                    (Range::step_by_1(0x0400..=0x0427), 40), (Range::step_by_1(0x04b0..=0x04d3), 40),
1271                    (Range::step_by_1(0x0570..=0x057a), 39), (Range::step_by_1(0x057c..=0x058a), 39),
1272                    (Range::step_by_1(0x058c..=0x0592), 39), (Range::step_by_1(0x0594..=0x0595), 39),
1273                    (Range::step_by_1(0x0c80..=0x0cb2), 64), (Range::step_by_1(0x0d50..=0x0d65), 32),
1274                    (Range::step_by_1(0x18a0..=0x18bf), 32), (Range::step_by_1(0x6e40..=0x6e5f), 32),
1275                    (Range::step_by_1(0x6ea0..=0x6eb8), 27), (Range::singleton(0xdf40), 1),
1276                    (Range::step_by_2(0xdf48..=0xdf4a), 1), (Range::singleton(0xdf4d), 1),
1277                    (Range::singleton(0xdf51), 1), (Range::step_by_2(0xdf68..=0xdf6e), 1),
1278                    (Range::step_by_2(0xdf72..=0xdf7e), 1), (Range::step_by_1(0xe900..=0xe921), 34),
1279                ],
1280                multis: &[ // 0 entries, 0 bytes
1281                ],
1282                exceptions: &[ // 0 entries, 0 bytes
1283                ],
1284            },
1285        ],
1286    };
1287
1288    static UPPERCASE_LUT: L1Lut = L1Lut {
1289        l2_luts: [
1290            L2Lut {
1291                singles: &[ // 188 entries, 1128 bytes
1292                    (Range::singleton(0x00b5), 743), (Range::step_by_1(0x00e0..=0x00f6), -32),
1293                    (Range::step_by_1(0x00f8..=0x00fe), -32), (Range::singleton(0x00ff), 121),
1294                    (Range::step_by_2(0x0101..=0x012f), -1), (Range::singleton(0x0131), -232),
1295                    (Range::step_by_2(0x0133..=0x0137), -1), (Range::step_by_2(0x013a..=0x0148), -1),
1296                    (Range::step_by_2(0x014b..=0x0177), -1), (Range::step_by_2(0x017a..=0x017e), -1),
1297                    (Range::singleton(0x017f), -300), (Range::singleton(0x0180), 195),
1298                    (Range::step_by_2(0x0183..=0x0185), -1), (Range::singleton(0x0188), -1),
1299                    (Range::singleton(0x018c), -1), (Range::singleton(0x0192), -1),
1300                    (Range::singleton(0x0195), 97), (Range::singleton(0x0199), -1),
1301                    (Range::singleton(0x019a), 163), (Range::singleton(0x019b), -22975),
1302                    (Range::singleton(0x019e), 130), (Range::step_by_2(0x01a1..=0x01a5), -1),
1303                    (Range::singleton(0x01a8), -1), (Range::singleton(0x01ad), -1),
1304                    (Range::singleton(0x01b0), -1), (Range::step_by_2(0x01b4..=0x01b6), -1),
1305                    (Range::singleton(0x01b9), -1), (Range::singleton(0x01bd), -1),
1306                    (Range::singleton(0x01bf), 56), (Range::singleton(0x01c5), -1),
1307                    (Range::singleton(0x01c6), -2), (Range::singleton(0x01c8), -1),
1308                    (Range::singleton(0x01c9), -2), (Range::singleton(0x01cb), -1),
1309                    (Range::singleton(0x01cc), -2), (Range::step_by_2(0x01ce..=0x01dc), -1),
1310                    (Range::singleton(0x01dd), -79), (Range::step_by_2(0x01df..=0x01ef), -1),
1311                    (Range::singleton(0x01f2), -1), (Range::singleton(0x01f3), -2),
1312                    (Range::singleton(0x01f5), -1), (Range::step_by_2(0x01f9..=0x021f), -1),
1313                    (Range::step_by_2(0x0223..=0x0233), -1), (Range::singleton(0x023c), -1),
1314                    (Range::step_by_1(0x023f..=0x0240), 10815), (Range::singleton(0x0242), -1),
1315                    (Range::step_by_2(0x0247..=0x024f), -1), (Range::singleton(0x0250), 10783),
1316                    (Range::singleton(0x0251), 10780), (Range::singleton(0x0252), 10782),
1317                    (Range::singleton(0x0253), -210), (Range::singleton(0x0254), -206),
1318                    (Range::step_by_1(0x0256..=0x0257), -205), (Range::singleton(0x0259), -202),
1319                    (Range::singleton(0x025b), -203), (Range::singleton(0x025c), -23217),
1320                    (Range::singleton(0x0260), -205), (Range::singleton(0x0261), -23221),
1321                    (Range::singleton(0x0263), -207), (Range::singleton(0x0264), -23193),
1322                    (Range::singleton(0x0265), -23256), (Range::singleton(0x0266), -23228),
1323                    (Range::singleton(0x0268), -209), (Range::singleton(0x0269), -211),
1324                    (Range::singleton(0x026a), -23228), (Range::singleton(0x026b), 10743),
1325                    (Range::singleton(0x026c), -23231), (Range::singleton(0x026f), -211),
1326                    (Range::singleton(0x0271), 10749), (Range::singleton(0x0272), -213),
1327                    (Range::singleton(0x0275), -214), (Range::singleton(0x0277), -23194),
1328                    (Range::singleton(0x027c), -23194), (Range::singleton(0x027d), 10727),
1329                    (Range::singleton(0x0280), -218), (Range::singleton(0x0282), -23229),
1330                    (Range::singleton(0x0283), -218), (Range::singleton(0x0287), -23254),
1331                    (Range::singleton(0x0288), -218), (Range::singleton(0x0289), -69),
1332                    (Range::step_by_1(0x028a..=0x028b), -217), (Range::singleton(0x028c), -71),
1333                    (Range::singleton(0x0292), -219), (Range::singleton(0x029d), -23275),
1334                    (Range::singleton(0x029e), -23278), (Range::singleton(0x0345), 84),
1335                    (Range::step_by_2(0x0371..=0x0373), -1), (Range::singleton(0x0377), -1),
1336                    (Range::step_by_1(0x037b..=0x037d), 130), (Range::singleton(0x03ac), -38),
1337                    (Range::step_by_1(0x03ad..=0x03af), -37), (Range::step_by_1(0x03b1..=0x03c1), -32),
1338                    (Range::singleton(0x03c2), -31), (Range::step_by_1(0x03c3..=0x03cb), -32),
1339                    (Range::singleton(0x03cc), -64), (Range::step_by_1(0x03cd..=0x03ce), -63),
1340                    (Range::singleton(0x03d0), -62), (Range::singleton(0x03d1), -57),
1341                    (Range::singleton(0x03d5), -47), (Range::singleton(0x03d6), -54),
1342                    (Range::singleton(0x03d7), -8), (Range::step_by_2(0x03d9..=0x03ef), -1),
1343                    (Range::singleton(0x03f0), -86), (Range::singleton(0x03f1), -80),
1344                    (Range::singleton(0x03f2), 7), (Range::singleton(0x03f3), -116),
1345                    (Range::singleton(0x03f5), -96), (Range::singleton(0x03f8), -1),
1346                    (Range::singleton(0x03fb), -1), (Range::step_by_1(0x0430..=0x044f), -32),
1347                    (Range::step_by_1(0x0450..=0x045f), -80), (Range::step_by_2(0x0461..=0x0481), -1),
1348                    (Range::step_by_2(0x048b..=0x04bf), -1), (Range::step_by_2(0x04c2..=0x04ce), -1),
1349                    (Range::singleton(0x04cf), -15), (Range::step_by_2(0x04d1..=0x052f), -1),
1350                    (Range::step_by_1(0x0561..=0x0586), -48), (Range::step_by_1(0x10d0..=0x10fa), 3008),
1351                    (Range::step_by_1(0x10fd..=0x10ff), 3008), (Range::step_by_1(0x13f8..=0x13fd), -8),
1352                    (Range::singleton(0x1c80), -6254), (Range::singleton(0x1c81), -6253),
1353                    (Range::singleton(0x1c82), -6244), (Range::step_by_1(0x1c83..=0x1c84), -6242),
1354                    (Range::singleton(0x1c85), -6243), (Range::singleton(0x1c86), -6236),
1355                    (Range::singleton(0x1c87), -6181), (Range::singleton(0x1c88), -30270),
1356                    (Range::singleton(0x1c8a), -1), (Range::singleton(0x1d79), -30204),
1357                    (Range::singleton(0x1d7d), 3814), (Range::singleton(0x1d8e), -30152),
1358                    (Range::step_by_2(0x1e01..=0x1e95), -1), (Range::singleton(0x1e9b), -59),
1359                    (Range::step_by_2(0x1ea1..=0x1eff), -1), (Range::step_by_1(0x1f00..=0x1f07), 8),
1360                    (Range::step_by_1(0x1f10..=0x1f15), 8), (Range::step_by_1(0x1f20..=0x1f27), 8),
1361                    (Range::step_by_1(0x1f30..=0x1f37), 8), (Range::step_by_1(0x1f40..=0x1f45), 8),
1362                    (Range::step_by_2(0x1f51..=0x1f57), 8), (Range::step_by_1(0x1f60..=0x1f67), 8),
1363                    (Range::step_by_1(0x1f70..=0x1f71), 74), (Range::step_by_1(0x1f72..=0x1f75), 86),
1364                    (Range::step_by_1(0x1f76..=0x1f77), 100), (Range::step_by_1(0x1f78..=0x1f79), 128),
1365                    (Range::step_by_1(0x1f7a..=0x1f7b), 112), (Range::step_by_1(0x1f7c..=0x1f7d), 126),
1366                    (Range::step_by_1(0x1fb0..=0x1fb1), 8), (Range::singleton(0x1fbe), -7205),
1367                    (Range::step_by_1(0x1fd0..=0x1fd1), 8), (Range::step_by_1(0x1fe0..=0x1fe1), 8),
1368                    (Range::singleton(0x1fe5), 7), (Range::singleton(0x214e), -28),
1369                    (Range::step_by_1(0x2170..=0x217f), -16), (Range::singleton(0x2184), -1),
1370                    (Range::step_by_1(0x24d0..=0x24e9), -26), (Range::step_by_1(0x2c30..=0x2c5f), -48),
1371                    (Range::singleton(0x2c61), -1), (Range::singleton(0x2c65), -10795),
1372                    (Range::singleton(0x2c66), -10792), (Range::step_by_2(0x2c68..=0x2c6c), -1),
1373                    (Range::singleton(0x2c73), -1), (Range::singleton(0x2c76), -1),
1374                    (Range::step_by_2(0x2c81..=0x2ce3), -1), (Range::step_by_2(0x2cec..=0x2cee), -1),
1375                    (Range::singleton(0x2cf3), -1), (Range::step_by_1(0x2d00..=0x2d25), -7264),
1376                    (Range::singleton(0x2d27), -7264), (Range::singleton(0x2d2d), -7264),
1377                    (Range::step_by_2(0xa641..=0xa66d), -1), (Range::step_by_2(0xa681..=0xa69b), -1),
1378                    (Range::step_by_2(0xa723..=0xa72f), -1), (Range::step_by_2(0xa733..=0xa76f), -1),
1379                    (Range::step_by_2(0xa77a..=0xa77c), -1), (Range::step_by_2(0xa77f..=0xa787), -1),
1380                    (Range::singleton(0xa78c), -1), (Range::step_by_2(0xa791..=0xa793), -1),
1381                    (Range::singleton(0xa794), 48), (Range::step_by_2(0xa797..=0xa7a9), -1),
1382                    (Range::step_by_2(0xa7b5..=0xa7c3), -1), (Range::step_by_2(0xa7c8..=0xa7ca), -1),
1383                    (Range::step_by_2(0xa7cd..=0xa7db), -1), (Range::singleton(0xa7f6), -1),
1384                    (Range::step_by_1(0xab4b..=0xab4c), 33), (Range::singleton(0xab53), -928),
1385                    (Range::step_by_1(0xab70..=0xabbf), 26672), (Range::step_by_1(0xff41..=0xff5a), -32),
1386                ],
1387                multis: &[ // 102 entries, 816 bytes
1388                    (0x00df, [0x0053, 0x0053, 0x0000]), (0x0149, [0x02bc, 0x004e, 0x0000]),
1389                    (0x01f0, [0x004a, 0x030c, 0x0000]), (0x0390, [0x0399, 0x0308, 0x0301]),
1390                    (0x03b0, [0x03a5, 0x0308, 0x0301]), (0x0587, [0x0535, 0x0552, 0x0000]),
1391                    (0x1e96, [0x0048, 0x0331, 0x0000]), (0x1e97, [0x0054, 0x0308, 0x0000]),
1392                    (0x1e98, [0x0057, 0x030a, 0x0000]), (0x1e99, [0x0059, 0x030a, 0x0000]),
1393                    (0x1e9a, [0x0041, 0x02be, 0x0000]), (0x1f50, [0x03a5, 0x0313, 0x0000]),
1394                    (0x1f52, [0x03a5, 0x0313, 0x0300]), (0x1f54, [0x03a5, 0x0313, 0x0301]),
1395                    (0x1f56, [0x03a5, 0x0313, 0x0342]), (0x1f80, [0x1f08, 0x0399, 0x0000]),
1396                    (0x1f81, [0x1f09, 0x0399, 0x0000]), (0x1f82, [0x1f0a, 0x0399, 0x0000]),
1397                    (0x1f83, [0x1f0b, 0x0399, 0x0000]), (0x1f84, [0x1f0c, 0x0399, 0x0000]),
1398                    (0x1f85, [0x1f0d, 0x0399, 0x0000]), (0x1f86, [0x1f0e, 0x0399, 0x0000]),
1399                    (0x1f87, [0x1f0f, 0x0399, 0x0000]), (0x1f88, [0x1f08, 0x0399, 0x0000]),
1400                    (0x1f89, [0x1f09, 0x0399, 0x0000]), (0x1f8a, [0x1f0a, 0x0399, 0x0000]),
1401                    (0x1f8b, [0x1f0b, 0x0399, 0x0000]), (0x1f8c, [0x1f0c, 0x0399, 0x0000]),
1402                    (0x1f8d, [0x1f0d, 0x0399, 0x0000]), (0x1f8e, [0x1f0e, 0x0399, 0x0000]),
1403                    (0x1f8f, [0x1f0f, 0x0399, 0x0000]), (0x1f90, [0x1f28, 0x0399, 0x0000]),
1404                    (0x1f91, [0x1f29, 0x0399, 0x0000]), (0x1f92, [0x1f2a, 0x0399, 0x0000]),
1405                    (0x1f93, [0x1f2b, 0x0399, 0x0000]), (0x1f94, [0x1f2c, 0x0399, 0x0000]),
1406                    (0x1f95, [0x1f2d, 0x0399, 0x0000]), (0x1f96, [0x1f2e, 0x0399, 0x0000]),
1407                    (0x1f97, [0x1f2f, 0x0399, 0x0000]), (0x1f98, [0x1f28, 0x0399, 0x0000]),
1408                    (0x1f99, [0x1f29, 0x0399, 0x0000]), (0x1f9a, [0x1f2a, 0x0399, 0x0000]),
1409                    (0x1f9b, [0x1f2b, 0x0399, 0x0000]), (0x1f9c, [0x1f2c, 0x0399, 0x0000]),
1410                    (0x1f9d, [0x1f2d, 0x0399, 0x0000]), (0x1f9e, [0x1f2e, 0x0399, 0x0000]),
1411                    (0x1f9f, [0x1f2f, 0x0399, 0x0000]), (0x1fa0, [0x1f68, 0x0399, 0x0000]),
1412                    (0x1fa1, [0x1f69, 0x0399, 0x0000]), (0x1fa2, [0x1f6a, 0x0399, 0x0000]),
1413                    (0x1fa3, [0x1f6b, 0x0399, 0x0000]), (0x1fa4, [0x1f6c, 0x0399, 0x0000]),
1414                    (0x1fa5, [0x1f6d, 0x0399, 0x0000]), (0x1fa6, [0x1f6e, 0x0399, 0x0000]),
1415                    (0x1fa7, [0x1f6f, 0x0399, 0x0000]), (0x1fa8, [0x1f68, 0x0399, 0x0000]),
1416                    (0x1fa9, [0x1f69, 0x0399, 0x0000]), (0x1faa, [0x1f6a, 0x0399, 0x0000]),
1417                    (0x1fab, [0x1f6b, 0x0399, 0x0000]), (0x1fac, [0x1f6c, 0x0399, 0x0000]),
1418                    (0x1fad, [0x1f6d, 0x0399, 0x0000]), (0x1fae, [0x1f6e, 0x0399, 0x0000]),
1419                    (0x1faf, [0x1f6f, 0x0399, 0x0000]), (0x1fb2, [0x1fba, 0x0399, 0x0000]),
1420                    (0x1fb3, [0x0391, 0x0399, 0x0000]), (0x1fb4, [0x0386, 0x0399, 0x0000]),
1421                    (0x1fb6, [0x0391, 0x0342, 0x0000]), (0x1fb7, [0x0391, 0x0342, 0x0399]),
1422                    (0x1fbc, [0x0391, 0x0399, 0x0000]), (0x1fc2, [0x1fca, 0x0399, 0x0000]),
1423                    (0x1fc3, [0x0397, 0x0399, 0x0000]), (0x1fc4, [0x0389, 0x0399, 0x0000]),
1424                    (0x1fc6, [0x0397, 0x0342, 0x0000]), (0x1fc7, [0x0397, 0x0342, 0x0399]),
1425                    (0x1fcc, [0x0397, 0x0399, 0x0000]), (0x1fd2, [0x0399, 0x0308, 0x0300]),
1426                    (0x1fd3, [0x0399, 0x0308, 0x0301]), (0x1fd6, [0x0399, 0x0342, 0x0000]),
1427                    (0x1fd7, [0x0399, 0x0308, 0x0342]), (0x1fe2, [0x03a5, 0x0308, 0x0300]),
1428                    (0x1fe3, [0x03a5, 0x0308, 0x0301]), (0x1fe4, [0x03a1, 0x0313, 0x0000]),
1429                    (0x1fe6, [0x03a5, 0x0342, 0x0000]), (0x1fe7, [0x03a5, 0x0308, 0x0342]),
1430                    (0x1ff2, [0x1ffa, 0x0399, 0x0000]), (0x1ff3, [0x03a9, 0x0399, 0x0000]),
1431                    (0x1ff4, [0x038f, 0x0399, 0x0000]), (0x1ff6, [0x03a9, 0x0342, 0x0000]),
1432                    (0x1ff7, [0x03a9, 0x0342, 0x0399]), (0x1ffc, [0x03a9, 0x0399, 0x0000]),
1433                    (0xfb00, [0x0046, 0x0046, 0x0000]), (0xfb01, [0x0046, 0x0049, 0x0000]),
1434                    (0xfb02, [0x0046, 0x004c, 0x0000]), (0xfb03, [0x0046, 0x0046, 0x0049]),
1435                    (0xfb04, [0x0046, 0x0046, 0x004c]), (0xfb05, [0x0053, 0x0054, 0x0000]),
1436                    (0xfb06, [0x0053, 0x0054, 0x0000]), (0xfb13, [0x0544, 0x0546, 0x0000]),
1437                    (0xfb14, [0x0544, 0x0535, 0x0000]), (0xfb15, [0x0544, 0x053b, 0x0000]),
1438                    (0xfb16, [0x054e, 0x0546, 0x0000]), (0xfb17, [0x0544, 0x053d, 0x0000]),
1439                ],
1440                exceptions: &[ // 0 entries, 0 bytes
1441                ],
1442            },
1443            L2Lut {
1444                singles: &[ // 18 entries, 108 bytes
1445                    (Range::step_by_1(0x0428..=0x044f), -40), (Range::step_by_1(0x04d8..=0x04fb), -40),
1446                    (Range::step_by_1(0x0597..=0x05a1), -39), (Range::step_by_1(0x05a3..=0x05b1), -39),
1447                    (Range::step_by_1(0x05b3..=0x05b9), -39), (Range::step_by_1(0x05bb..=0x05bc), -39),
1448                    (Range::step_by_1(0x0cc0..=0x0cf2), -64), (Range::step_by_1(0x0d70..=0x0d85), -32),
1449                    (Range::step_by_1(0x18c0..=0x18df), -32), (Range::step_by_1(0x6e60..=0x6e7f), -32),
1450                    (Range::step_by_1(0x6ebb..=0x6ed3), -27), (Range::singleton(0xdf41), -1),
1451                    (Range::step_by_2(0xdf49..=0xdf4b), -1), (Range::singleton(0xdf4e), -1),
1452                    (Range::singleton(0xdf52), -1), (Range::step_by_2(0xdf69..=0xdf6f), -1),
1453                    (Range::step_by_2(0xdf73..=0xdf7f), -1), (Range::step_by_1(0xe922..=0xe943), -34),
1454                ],
1455                multis: &[ // 0 entries, 0 bytes
1456                ],
1457                exceptions: &[ // 1 entries, 16 bytes
1458                    (0xdf95, ['S', 'S', '\u{0}']),
1459                ],
1460            },
1461        ],
1462    };
1463
1464    static TITLECASE_LUT: L1Lut = L1Lut {
1465        l2_luts: [
1466            L2Lut {
1467                singles: &[ // 26 entries, 156 bytes
1468                    (Range::singleton(0x01c4), 1), (Range::singleton(0x01c5), 0),
1469                    (Range::singleton(0x01c6), -1), (Range::singleton(0x01c7), 1),
1470                    (Range::singleton(0x01c8), 0), (Range::singleton(0x01c9), -1),
1471                    (Range::singleton(0x01ca), 1), (Range::singleton(0x01cb), 0),
1472                    (Range::singleton(0x01cc), -1), (Range::singleton(0x01f1), 1),
1473                    (Range::singleton(0x01f2), 0), (Range::singleton(0x01f3), -1),
1474                    (Range::step_by_1(0x10d0..=0x10fa), 0), (Range::step_by_1(0x10fd..=0x10ff), 0),
1475                    (Range::step_by_1(0x1f80..=0x1f87), 8), (Range::step_by_1(0x1f88..=0x1f8f), 0),
1476                    (Range::step_by_1(0x1f90..=0x1f97), 8), (Range::step_by_1(0x1f98..=0x1f9f), 0),
1477                    (Range::step_by_1(0x1fa0..=0x1fa7), 8), (Range::step_by_1(0x1fa8..=0x1faf), 0),
1478                    (Range::singleton(0x1fb3), 9), (Range::singleton(0x1fbc), 0), (Range::singleton(0x1fc3), 9),
1479                    (Range::singleton(0x1fcc), 0), (Range::singleton(0x1ff3), 9), (Range::singleton(0x1ffc), 0),
1480                ],
1481                multis: &[ // 23 entries, 184 bytes
1482                    (0x00df, [0x0053, 0x0073, 0x0000]), (0x0587, [0x0535, 0x0582, 0x0000]),
1483                    (0x1fb2, [0x1fba, 0x0345, 0x0000]), (0x1fb4, [0x0386, 0x0345, 0x0000]),
1484                    (0x1fb7, [0x0391, 0x0342, 0x0345]), (0x1fc2, [0x1fca, 0x0345, 0x0000]),
1485                    (0x1fc4, [0x0389, 0x0345, 0x0000]), (0x1fc7, [0x0397, 0x0342, 0x0345]),
1486                    (0x1ff2, [0x1ffa, 0x0345, 0x0000]), (0x1ff4, [0x038f, 0x0345, 0x0000]),
1487                    (0x1ff7, [0x03a9, 0x0342, 0x0345]), (0xfb00, [0x0046, 0x0066, 0x0000]),
1488                    (0xfb01, [0x0046, 0x0069, 0x0000]), (0xfb02, [0x0046, 0x006c, 0x0000]),
1489                    (0xfb03, [0x0046, 0x0066, 0x0069]), (0xfb04, [0x0046, 0x0066, 0x006c]),
1490                    (0xfb05, [0x0053, 0x0074, 0x0000]), (0xfb06, [0x0053, 0x0074, 0x0000]),
1491                    (0xfb13, [0x0544, 0x0576, 0x0000]), (0xfb14, [0x0544, 0x0565, 0x0000]),
1492                    (0xfb15, [0x0544, 0x056b, 0x0000]), (0xfb16, [0x054e, 0x0576, 0x0000]),
1493                    (0xfb17, [0x0544, 0x056d, 0x0000]),
1494                ],
1495                exceptions: &[ // 0 entries, 0 bytes
1496                ],
1497            },
1498            L2Lut {
1499                singles: &[ // 0 entries, 0 bytes
1500                ],
1501                multis: &[ // 0 entries, 0 bytes
1502                ],
1503                exceptions: &[ // 1 entries, 16 bytes
1504                    (0xdf95, ['S', 's', '\u{0}']),
1505                ],
1506            },
1507        ],
1508    };
1509
1510    static CASEFOLD_LUT: L1Lut = L1Lut {
1511        l2_luts: [
1512            L2Lut {
1513                singles: &[ // 4 entries, 24 bytes
1514                    (Range::singleton(0x0131), 0), (Range::step_by_1(0x13a0..=0x13f5), 0),
1515                    (Range::step_by_1(0x13f8..=0x13fd), -8), (Range::step_by_1(0xab70..=0xabbf), 26672),
1516                ],
1517                multis: &[ // 1 entries, 8 bytes
1518                    (0x1e9e, [0x0073, 0x0073, 0x0000]),
1519                ],
1520                exceptions: &[ // 0 entries, 0 bytes
1521                ],
1522            },
1523            L2Lut {
1524                singles: &[ // 0 entries, 0 bytes
1525                ],
1526                multis: &[ // 0 entries, 0 bytes
1527                ],
1528                exceptions: &[ // 0 entries, 0 bytes
1529                ],
1530            },
1531        ],
1532    };
1533}