Files
plezy/lib/data/ducet_order.dart
T

246 lines
263 KiB
Dart
Raw Normal View History

/// Sorted BMP codepoints per DUCET (Unicode 13.0) + CLDR 39 CJK radical-stroke.
/// Katakana sorts before hiragana (CLDR root tailoring).
/// Generated by scripts/generate_ducet_ranks.dart — do not edit.
2026-02-23 13:48:23 +01:00
library;
2026-04-18 12:40:35 +02:00
const String _ducetOrder =
'\u0332\u0313\u0343\u0486\u2cf1\u0314\u0485\u2cf0\u0301\u0341\u0954\u0300\u0340\u0953\u0306\u0302\u030c\u030a\u0342\u0308\u030b\u0303\u0307\u0338\u0327\u0328\u0304\u030d\u030e\u0312\u0315\u031a\u033d\u033e\u033f\u0346\u034a\u034b\u034c\u0350\u0351\u0352\u0357\u035b\u035d\u035e\u0484\u0487\u0741\u0745\u0b55\u17cb\u17cc\u17cd\u17ce\u17cf\u17d0\u17d1\u17dd\u1ab0\u1ab1\u1ab2\u1ab3\u1ab4\u1abb\u1abc\u1dc0\u1dc1\u1dc3\u1dc4\u1dc5\u1dc6\u1dc7\u1dc8\u1dc9\u1dcb\u1dcc\u1dcd\u1dce\u1dd1\u1df5\u1df6\u1df7\u1df8\u1dfb\u1dfe\u20f0\u2cef\ua67c\ua67d\u0316\u0317\u0318\u0319\u031c\u031d\u031e\u031f\u0320\u0329\u032a\u032b\u032c\u032f\u0333\u033a\u033b\u033c\u0347\u0348\u0349\u034d\u034e\u0353\u0354\u0355\u0356\u0359\u035a\u035c\u035f\u0362\u0742\u0746\u07fd\u0859\u085a\u085b\u1ab5\u1ab6\u1ab7\u1ab8\u1ab9\u1aba\u1abd\u1dc2\u1dcf\u1dd0\u1df9\u1dfc\u1dfd\u1dff\u20ec\u20ed\u20ee\u20ef\ufe27\u0336\u0337\u20d8\u20d9\u20da\u20e5\u20ea\u20eb\u1abe\u20dd\u20de\u20df\u20e0\u20e2\u20e3\u20e4\u3099\uff9e\u309a\uff9f\u0335\u0305\u0309\u030f\u0310\u0311\u031b\u0321\u0322\u0323\u0324\u0325\u0326\u032d\u032e\u0330\u0331\u0334\u0339\u0345\u0358\u0360\ufe22\ufe29\u0361\ufe20\u0483\ufe2e\ua66f\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05c7\u05b9\u05ba\u05bb\u05c2\u05c1\u05bc\u05bf\ufb1e\u081c\u081d\u081e\u081f\u0820\u0821\u0822\u0823\u0824\u0825\u0826\u0827\u0828\u0829\u082a\u082b\u082c\u0818\u0819\u082d\u064b\ufe71\ufe70\u08f0\u08e7\u064c\ufe72\u08f1\u08e8\u064d\ufe74\u08f2\u08e9\u064e\ufe77\ufe76\u08e4\u08f4\u08f5\u064f\ufe79\ufe78\u08e5\u08fe\u0650\ufe7b\ufe7a\u08e6\u08f6\u0651\u0afb\ufe7d\ufe7c\u0652\u0afa\ufe7f\ufe7e\u0653\u0afc\u0654\u0655\u065f\u0656\u0657\u0658\u08ff\u0659\u065a\u065b\u065c\u065d\u065e\u08e3\u08f7\u08f8\u08fd\u08fb\u08fc\u08f9\u08fa\u0670\u0711\u0730\u0731\u0732\u0733\u0734\u0735\u0736\u0737\u0738\u0739\u073a\u073b\u073c\u073d\u073e\u073f\u07eb\u07ec\u07ed\u07ee\u07ef\u07f0\u07f1\u07f2\u07f3\u135f\u135e\u135d\ua6f0\ua6f1\u093c\u09bc\u0a3c\u0abc\u0afd\u0afe\u0aff\u0b3c\u0cbc\u1b34\u1be6\u1c37\ua9b3\u0900\u0901\u0981\u0a01\u0a81\u0b01\u0c00\u0c01\u0c81\u0d01\u0d81\u1b00\u1b01\ua8c5\ua980\u0902\u0982\u0a02\u0a82\u0b02\u0b82\u0c02\u0c04\u0c82\u0d00\u0d02\u0d82\u0f7e\u1036\u17c6\u1a74\u1b02\u1b80\u1ced\ua80b\ua880\ua981\u0903\u0983\u0a03\u0a83\u0b03\u0c03\u0c83\u0d03\u0d83\u0f7f\u1038\u17c7\u1b04\u1b82\u1cf2\u1cf3\ua881\ua983\u09fe\u0a70\u0a71\u1b03\ua982\u1b81\uabec\u0e4e\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0ec8\u0ec9\u0eca\u0ecb\u0ecc\u0ecd\uaabf\uaac1\u0f39\ua92b\ua92c\ua92d\u1037\u17c8\u17c9\u17ca\u1a75\u1a76\u1a77\u1a78\u1a79\u1a7a\u1a7b\u1a7c\u1939\u193a\u193b\u302a\u302b\u302c\u302d\u302e\u302f\u20d0\u20d1\u20d2\u20d3\u20d4\u20d5\u20d6\u20d7\u20db\u20dc\u20e1\u20e6\u20e7\u20e8\u20e9\u0344\ufc5e\ufc5f\ufcf2\ufc60\ufcf3\ufc61\ufcf4\ufc62\ufc63\u0009\u000a\u000b\u000c\u000d\u0085\u2028\u2029\u0020\u3000\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2008\u2009\u200a\u205f\u00a0\u2007\u202f\u203e\ufe49\ufe4a\ufe4b\ufe4c\u005f\uff3f\ufe4d\ufe4e\ufe4f\ufe33\ufe34\u2017\u002d\uff0d\ufe63\u058a\u1400\u1b60\u1806\u1807\u2010\u2011\u2012\u2013\ufe32\u2014\ufe58\ufe31\u2015\u2e3a\u2e3b\u2053\u2e43\u2e17\u2e40\u301c\u3030\u30a0\u30fb\uff65\u002c\uff0c\ufe50\ufe10\u2e34\u2e32\u2e41\u2e4c\u2e4e\u2e4f\u055d\u060c\u060d\u066b\u066c\u07f8\u1802\u1808\ua4fe\ua60d\ua6f5\u3001\ufe51\uff64\ufe11\ufe45\ufe46\u003b\u037e\uff1b\ufe54\ufe14\u061b\u204f\u2e35\ua6f6\u2e49\u003a\uff1a\ufe55\ufe13\u2a74\u0589\u061e\u0703\u0704\u0705\u0706\u0707\u0708\u0830\u0831\u0832\u0833\u0834\u0835\u0836\u0837\u0838\u0839\u083a\u083b\u083c\u083d\u083e\u1361\u1363\u1364\u1365\u1366\u1804\u1805\u0f14\u17d6\u1b5d\ua9c7\u16eb\u16ec\u16ed\ua6f4\u0021\uff01\ufe57\ufe15\u203c\u2049\u00a1\u055c\u07f9\u1944\u003f\uff1f\ufe56\ufe16\u2048\u2047\u00bf\u2e2e\u055e\u061f\u0709\u1367\u1945\u2cfa\u2cfb\ua60f\ua6f7\uaaf1\u203d\u2e18\u002e\uff0e\u2024\ufe52\u2025\ufe30\u2026\ufe19\u1801\u06d4\u0701\u0702\u1362\u1803\u1809\u166e\u1b5c\u2cf9\u2cfe\u2e30\u2e3c\ua4ff\ua60e\ua6f3\u3002\uff61\ufe12\u00b7\u0387\u2e31\u2e33\u0964\u0965\ua8ce\ua8cf\u1c3b\u1c3c\ua876\ua8
/// Kangxi Radicals (U+2F00-U+2FD5) → CJK Unified equivalents.
/// ICU decomposes these via NFD before collation.
const Map<int, int> _kangxiDecomp = {
0x2F00: 0x4E00,
0x2F01: 0x4E28,
0x2F02: 0x4E36,
0x2F03: 0x4E3F,
0x2F04: 0x4E59,
0x2F05: 0x4E85,
0x2F06: 0x4E8C,
0x2F07: 0x4EA0,
0x2F08: 0x4EBA,
0x2F09: 0x513F,
0x2F0A: 0x5165,
0x2F0B: 0x516B,
0x2F0C: 0x5182,
0x2F0D: 0x5196,
0x2F0E: 0x51AB,
0x2F0F: 0x51E0,
0x2F10: 0x51F5,
0x2F11: 0x5200,
0x2F12: 0x529B,
0x2F13: 0x52F9,
0x2F14: 0x5315,
0x2F15: 0x531A,
0x2F16: 0x5338,
0x2F17: 0x5341,
0x2F18: 0x535C,
0x2F19: 0x5369,
0x2F1A: 0x5382,
0x2F1B: 0x53B6,
0x2F1C: 0x53C8,
0x2F1D: 0x53E3,
0x2F1E: 0x56D7,
0x2F1F: 0x571F,
0x2F20: 0x58EB,
0x2F21: 0x5902,
0x2F22: 0x590A,
0x2F23: 0x5915,
0x2F24: 0x5927,
0x2F25: 0x5973,
0x2F26: 0x5B50,
0x2F27: 0x5B80,
0x2F28: 0x5BF8,
0x2F29: 0x5C0F,
0x2F2A: 0x5C22,
0x2F2B: 0x5C38,
0x2F2C: 0x5C6E,
0x2F2D: 0x5C71,
0x2F2E: 0x5DDB,
0x2F2F: 0x5DE5,
0x2F30: 0x5DF1,
0x2F31: 0x5DFE,
0x2F32: 0x5E72,
0x2F33: 0x5E7A,
0x2F34: 0x5E7F,
0x2F35: 0x5EF4,
0x2F36: 0x5EFE,
0x2F37: 0x5F0B,
0x2F38: 0x5F13,
0x2F39: 0x5F50,
0x2F3A: 0x5F61,
0x2F3B: 0x5F73,
0x2F3C: 0x5FC3,
0x2F3D: 0x6208,
0x2F3E: 0x6236,
0x2F3F: 0x624B,
0x2F40: 0x652F,
0x2F41: 0x6534,
0x2F42: 0x6587,
0x2F43: 0x6597,
0x2F44: 0x65A4,
0x2F45: 0x65B9,
0x2F46: 0x65E0,
0x2F47: 0x65E5,
0x2F48: 0x66F0,
0x2F49: 0x6708,
0x2F4A: 0x6728,
0x2F4B: 0x6B20,
0x2F4C: 0x6B62,
0x2F4D: 0x6B79,
0x2F4E: 0x6BB3,
0x2F4F: 0x6BCB,
0x2F50: 0x6BD4,
0x2F51: 0x6BDB,
0x2F52: 0x6C0F,
0x2F53: 0x6C14,
0x2F54: 0x6C34,
0x2F55: 0x706B,
0x2F56: 0x722A,
0x2F57: 0x7236,
0x2F58: 0x723B,
0x2F59: 0x723F,
0x2F5A: 0x7247,
0x2F5B: 0x7259,
0x2F5C: 0x725B,
0x2F5D: 0x72AC,
0x2F5E: 0x7384,
0x2F5F: 0x7389,
0x2F60: 0x74DC,
0x2F61: 0x74E6,
0x2F62: 0x7518,
0x2F63: 0x751F,
0x2F64: 0x7528,
0x2F65: 0x7530,
0x2F66: 0x758B,
0x2F67: 0x7592,
0x2F68: 0x7676,
0x2F69: 0x767D,
0x2F6A: 0x76AE,
0x2F6B: 0x76BF,
0x2F6C: 0x76EE,
0x2F6D: 0x77DB,
0x2F6E: 0x77E2,
0x2F6F: 0x77F3,
0x2F70: 0x793A,
0x2F71: 0x79B8,
0x2F72: 0x79BE,
0x2F73: 0x7A74,
0x2F74: 0x7ACB,
0x2F75: 0x7AF9,
0x2F76: 0x7C73,
0x2F77: 0x7CF8,
0x2F78: 0x7F36,
0x2F79: 0x7F51,
0x2F7A: 0x7F8A,
0x2F7B: 0x7FBD,
0x2F7C: 0x8001,
0x2F7D: 0x800C,
0x2F7E: 0x8012,
0x2F7F: 0x8033,
0x2F80: 0x807F,
0x2F81: 0x8089,
0x2F82: 0x81E3,
0x2F83: 0x81EA,
0x2F84: 0x81F3,
0x2F85: 0x81FC,
0x2F86: 0x820C,
0x2F87: 0x821B,
0x2F88: 0x821F,
0x2F89: 0x826E,
0x2F8A: 0x8272,
0x2F8B: 0x8278,
0x2F8C: 0x864D,
0x2F8D: 0x866B,
0x2F8E: 0x8840,
0x2F8F: 0x884C,
0x2F90: 0x8863,
0x2F91: 0x897E,
0x2F92: 0x898B,
0x2F93: 0x89D2,
0x2F94: 0x8A00,
0x2F95: 0x8C37,
0x2F96: 0x8C46,
0x2F97: 0x8C55,
0x2F98: 0x8C78,
0x2F99: 0x8C9D,
0x2F9A: 0x8D64,
0x2F9B: 0x8D70,
0x2F9C: 0x8DB3,
0x2F9D: 0x8EAB,
0x2F9E: 0x8ECA,
0x2F9F: 0x8F9B,
0x2FA0: 0x8FB0,
0x2FA1: 0x8FB5,
0x2FA2: 0x9091,
0x2FA3: 0x9149,
0x2FA4: 0x91C6,
0x2FA5: 0x91CC,
0x2FA6: 0x91D1,
0x2FA7: 0x9577,
0x2FA8: 0x9580,
0x2FA9: 0x961C,
0x2FAA: 0x96B6,
0x2FAB: 0x96B9,
0x2FAC: 0x96E8,
0x2FAD: 0x9751,
0x2FAE: 0x975E,
0x2FAF: 0x9762,
0x2FB0: 0x9769,
0x2FB1: 0x97CB,
0x2FB2: 0x97ED,
0x2FB3: 0x97F3,
0x2FB4: 0x9801,
0x2FB5: 0x98A8,
0x2FB6: 0x98DB,
0x2FB7: 0x98DF,
0x2FB8: 0x9996,
0x2FB9: 0x9999,
0x2FBA: 0x99AC,
0x2FBB: 0x9AA8,
0x2FBC: 0x9AD8,
0x2FBD: 0x9ADF,
0x2FBE: 0x9B25,
0x2FBF: 0x9B2F,
0x2FC0: 0x9B32,
0x2FC1: 0x9B3C,
0x2FC2: 0x9B5A,
0x2FC3: 0x9CE5,
0x2FC4: 0x9E75,
0x2FC5: 0x9E7F,
0x2FC6: 0x9EA5,
0x2FC7: 0x9EBB,
0x2FC8: 0x9EC3,
0x2FC9: 0x9ECD,
0x2FCA: 0x9ED1,
0x2FCB: 0x9EF9,
0x2FCC: 0x9EFD,
0x2FCD: 0x9F0E,
0x2FCE: 0x9F13,
0x2FCF: 0x9F20,
0x2FD0: 0x9F3B,
0x2FD1: 0x9F4A,
0x2FD2: 0x9F52,
0x2FD3: 0x9F8D,
0x2FD4: 0x9F9C,
0x2FD5: 0x9FA0,
};
2026-02-23 13:48:23 +01:00
final Map<int, int> _ranks = _buildRanks();
Map<int, int> _buildRanks() {
2026-04-18 12:40:35 +02:00
return {for (var i = 0; i < _ducetOrder.length; i++) _ducetOrder.codeUnitAt(i): i};
}
/// Compare two characters using DUCET + CLDR ordering.
/// Decomposes Kangxi radicals to CJK equivalents before lookup.
/// Falls back to codepoint order for characters not in the table.
int ducetCompare(String a, String b) {
var cpA = a.runes.first;
var cpB = b.runes.first;
cpA = _kangxiDecomp[cpA] ?? cpA;
cpB = _kangxiDecomp[cpB] ?? cpB;
final rankA = _ranks[cpA] ?? (0x100000 + cpA);
final rankB = _ranks[cpB] ?? (0x100000 + cpB);
return rankA.compareTo(rankB);
}