From 08978e2c6cf3befb54320c9ca8ab33f7775e6ec4 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Fri, 4 Jun 2021 00:54:33 +0200 Subject: [PATCH 0001/1315] IWYU: another (failed) attempt to get usable output from iwyu As of version 0.16 it is still virtually unusable with our code base. I manually went through all the noise and picked what seemed to make sense. This fixes #232 but with future compiler upgrades this kind of error will resurface. --- core/src/BarcodeFormat.cpp | 1 - core/src/BarcodeFormat.h | 1 - core/src/BitArray.h | 1 + core/src/CharacterSetECI.cpp | 1 - core/src/DecodeHints.h | 3 ++- core/src/GenericGF.h | 2 -- core/src/GlobalHistogramBinarizer.cpp | 1 - core/src/HybridBinarizer.cpp | 3 --- core/src/PerspectiveTransform.h | 2 -- core/src/ReadBarcode.cpp | 3 --- core/src/TextUtfEncoding.cpp | 1 - core/src/aztec/AZReader.cpp | 1 - core/src/datamatrix/DMReader.cpp | 2 -- core/src/oned/ODCodabarReader.cpp | 5 +---- core/src/oned/ODCode128Reader.cpp | 2 -- core/src/oned/ODCode39Reader.cpp | 2 -- core/src/oned/ODCode93Reader.cpp | 1 - core/src/oned/ODITFReader.cpp | 1 - core/src/oned/ODMultiUPCEANReader.cpp | 3 --- core/src/oned/ODReader.cpp | 1 - core/src/oned/ODRowReader.h | 2 +- core/src/oned/rss/ODRSSFieldParser.cpp | 2 ++ core/src/pdf417/PDFCodewordDecoder.cpp | 2 +- core/src/pdf417/PDFEncoder.cpp | 1 - core/src/pdf417/PDFModulusGF.h | 1 + core/src/pdf417/PDFReader.cpp | 11 +++++++---- core/src/pdf417/PDFScanningDecoder.cpp | 1 - core/src/qrcode/QRBitMatrixParser.cpp | 2 ++ core/src/qrcode/QRDataBlock.cpp | 1 - core/src/qrcode/QRDecoder.cpp | 2 +- core/src/qrcode/QRDetector.cpp | 7 ++++--- core/src/qrcode/QRMaskUtil.cpp | 1 + core/src/qrcode/QRMatrixUtil.cpp | 1 - core/src/qrcode/QRReader.cpp | 3 --- example/ZXingReader.cpp | 2 +- example/ZXingWriter.cpp | 3 --- test/blackbox/ImageLoader.cpp | 3 --- test/blackbox/TestReaderMain.cpp | 1 - test/blackbox/TestWriterMain.cpp | 1 - 39 files changed, 25 insertions(+), 59 deletions(-) diff --git a/core/src/BarcodeFormat.cpp b/core/src/BarcodeFormat.cpp index fd9ab7cad5..fddb6eface 100644 --- a/core/src/BarcodeFormat.cpp +++ b/core/src/BarcodeFormat.cpp @@ -17,7 +17,6 @@ #include "BarcodeFormat.h" -#include "BitHacks.h" #include "ZXContainerAlgorithms.h" #include diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index cc540c44dc..509e65282e 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -19,7 +19,6 @@ #include "Flags.h" #include -#include namespace ZXing { diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 24a399c453..4de8fe14b4 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/core/src/CharacterSetECI.cpp b/core/src/CharacterSetECI.cpp index be2b065372..6d6dbb5300 100644 --- a/core/src/CharacterSetECI.cpp +++ b/core/src/CharacterSetECI.cpp @@ -21,7 +21,6 @@ #include #include #include -#include namespace ZXing::CharacterSetECI { diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 017c166769..7f0a2cd9e8 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -18,8 +18,9 @@ #include "BarcodeFormat.h" -#include #include +#include +#include namespace ZXing { diff --git a/core/src/GenericGF.h b/core/src/GenericGF.h index 489826c3b5..320f6234ab 100644 --- a/core/src/GenericGF.h +++ b/core/src/GenericGF.h @@ -19,8 +19,6 @@ #include "GenericGFPoly.h" #include "ZXConfig.h" -#include -#include #include #include diff --git a/core/src/GlobalHistogramBinarizer.cpp b/core/src/GlobalHistogramBinarizer.cpp index 1e3fd111b7..dbb4f766f0 100644 --- a/core/src/GlobalHistogramBinarizer.cpp +++ b/core/src/GlobalHistogramBinarizer.cpp @@ -17,7 +17,6 @@ #include "GlobalHistogramBinarizer.h" -#include "BitArray.h" #include "BitMatrix.h" #include "ByteArray.h" #include "LuminanceSource.h" diff --git a/core/src/HybridBinarizer.cpp b/core/src/HybridBinarizer.cpp index fa0162f99b..864ac44ea2 100644 --- a/core/src/HybridBinarizer.cpp +++ b/core/src/HybridBinarizer.cpp @@ -24,13 +24,10 @@ #include "Matrix.h" #include "ZXContainerAlgorithms.h" -#include #include -#include #include #include #include -#include namespace ZXing { diff --git a/core/src/PerspectiveTransform.h b/core/src/PerspectiveTransform.h index 75894ed3ce..b02ce66fe1 100644 --- a/core/src/PerspectiveTransform.h +++ b/core/src/PerspectiveTransform.h @@ -20,8 +20,6 @@ #include "Point.h" #include "Quadrilateral.h" -#include - namespace ZXing { /** diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index c96115a63c..81a0236e4d 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -16,9 +16,6 @@ #include "ReadBarcode.h" -#include "BinaryBitmap.h" -#include "BitArray.h" -#include "BitMatrix.h" #include "DecodeHints.h" #include "GenericLuminanceSource.h" #include "GlobalHistogramBinarizer.h" diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index 57674383f6..b2e3e1e4e7 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -19,7 +19,6 @@ #include #include #include -#include namespace ZXing::TextUtfEncoding { diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 42b4d18cbf..287e26d134 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -27,7 +27,6 @@ #include #include -#include namespace ZXing::Aztec { diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index 4939f5f337..ee02ec408d 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -18,7 +18,6 @@ #include "DMReader.h" #include "BinaryBitmap.h" -#include "BitMatrix.h" #include "DMDecoder.h" #include "DMDetector.h" #include "DecodeHints.h" @@ -27,7 +26,6 @@ #include "Result.h" #include -#include namespace ZXing::DataMatrix { diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index f4ea0cd92f..0d6ebc33e6 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -18,15 +18,12 @@ #include "ODCodabarReader.h" -#include "BitArray.h" #include "DecodeHints.h" #include "Result.h" #include "ZXContainerAlgorithms.h" -#include -#include #include -#include +#include namespace ZXing::OneD { diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index a0276f92e4..0629a01857 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -17,14 +17,12 @@ #include "ODCode128Reader.h" -#include "BitArray.h" #include "DecodeHints.h" #include "ODCode128Patterns.h" #include "Result.h" #include "ZXContainerAlgorithms.h" #include -#include #include #include #include diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index 25ab91f043..926473278f 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -17,13 +17,11 @@ #include "ODCode39Reader.h" -#include "BitArray.h" #include "DecodeHints.h" #include "Result.h" #include "ZXContainerAlgorithms.h" #include -#include namespace ZXing::OneD { diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index b769f767ec..5926dfba18 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -18,7 +18,6 @@ #include "ODCode93Reader.h" -#include "BitArray.h" #include "Result.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index f6fb1359af..42ddd592d9 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -17,7 +17,6 @@ #include "ODITFReader.h" -#include "BitArray.h" #include "DecodeHints.h" #include "Result.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index eda63dd552..30ac3d5ea0 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -24,9 +24,6 @@ #include "GTIN.h" #include "ODUPCEANCommon.h" #include "Result.h" -#include "TextDecoder.h" - -#include namespace ZXing::OneD { diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index fd96babce4..3bdd923361 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -19,7 +19,6 @@ #include "ODReader.h" #include "BinaryBitmap.h" -#include "BitArray.h" #include "DecodeHints.h" #include "ODCodabarReader.h" #include "ODCode128Reader.h" diff --git a/core/src/oned/ODRowReader.h b/core/src/oned/ODRowReader.h index 57ad645fd4..ca12e55270 100644 --- a/core/src/oned/ODRowReader.h +++ b/core/src/oned/ODRowReader.h @@ -25,8 +25,8 @@ #include #include #include +#include #include -#include /* Code39 : 1:2/3, 5+4+1 (0x3|2x1 wide) -> 12-15 mods, v1-? | ToNarrowWide(OMG 1) == * diff --git a/core/src/oned/rss/ODRSSFieldParser.cpp b/core/src/oned/rss/ODRSSFieldParser.cpp index 9f0d2d4486..b15d6edc88 100644 --- a/core/src/oned/rss/ODRSSFieldParser.cpp +++ b/core/src/oned/rss/ODRSSFieldParser.cpp @@ -22,6 +22,8 @@ #include #include +#include +#include namespace ZXing::OneD::DataBar { diff --git a/core/src/pdf417/PDFCodewordDecoder.cpp b/core/src/pdf417/PDFCodewordDecoder.cpp index 9570422b39..ec84e962ac 100644 --- a/core/src/pdf417/PDFCodewordDecoder.cpp +++ b/core/src/pdf417/PDFCodewordDecoder.cpp @@ -19,9 +19,9 @@ #include "BitArray.h" #include "ZXContainerAlgorithms.h" +#include #include #include -#include #include namespace ZXing { diff --git a/core/src/pdf417/PDFEncoder.cpp b/core/src/pdf417/PDFEncoder.cpp index 662ff4f70f..ac4e1e4510 100644 --- a/core/src/pdf417/PDFEncoder.cpp +++ b/core/src/pdf417/PDFEncoder.cpp @@ -19,7 +19,6 @@ #include "PDFEncoder.h" #include "PDFHighLevelEncoder.h" #include -#include #include #include diff --git a/core/src/pdf417/PDFModulusGF.h b/core/src/pdf417/PDFModulusGF.h index 01630c8d21..12095c9491 100644 --- a/core/src/pdf417/PDFModulusGF.h +++ b/core/src/pdf417/PDFModulusGF.h @@ -20,6 +20,7 @@ #include "ZXConfig.h" #include +#include namespace ZXing { namespace Pdf417 { diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 992c1a03a5..bec478ebf9 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -20,7 +20,6 @@ #include "PDFDetector.h" #include "PDFScanningDecoder.h" #include "PDFCodewordDecoder.h" -#include "PDFDecoderResultExtra.h" #include "DecodeHints.h" #include "DecoderResult.h" #include "Result.h" @@ -30,9 +29,6 @@ #include "BitArray.h" #include "DecodeStatus.h" #include "Pattern.h" -#include "PDFDecodedBitStreamParser.h" -#include "BitMatrixIO.h" -#include #include #include @@ -40,6 +36,13 @@ #include #include +#ifdef PRINT_DEBUG +#include "PDFDecoderResultExtra.h" +#include "PDFDecodedBitStreamParser.h" +#include "BitMatrixIO.h" +#include +#endif + namespace ZXing { namespace Pdf417 { diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index a56fe7d298..978b090829 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -32,7 +32,6 @@ #include "ZXTestSupport.h" #include -#include #include #include diff --git a/core/src/qrcode/QRBitMatrixParser.cpp b/core/src/qrcode/QRBitMatrixParser.cpp index 23c92f62df..ab599a7b67 100644 --- a/core/src/qrcode/QRBitMatrixParser.cpp +++ b/core/src/qrcode/QRBitMatrixParser.cpp @@ -24,6 +24,8 @@ #include "QRFormatInformation.h" #include "QRVersion.h" +#include + namespace ZXing::QRCode { static bool getBit(const BitMatrix& bitMatrix, int x, int y, bool mirrored) diff --git a/core/src/qrcode/QRDataBlock.cpp b/core/src/qrcode/QRDataBlock.cpp index 59b88b6b9e..7c04f5e760 100644 --- a/core/src/qrcode/QRDataBlock.cpp +++ b/core/src/qrcode/QRDataBlock.cpp @@ -17,7 +17,6 @@ #include "QRDataBlock.h" -#include "DecodeStatus.h" #include "QRErrorCorrectionLevel.h" #include "QRVersion.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index a31b6f023c..0b03a4dec6 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -27,10 +27,10 @@ #include "QRBitMatrixParser.h" #include "QRCodecMode.h" #include "QRDataBlock.h" -#include "QRDataMask.h" #include "QRDecoderMetadata.h" #include "QRFormatInformation.h" #include "ReedSolomonDecoder.h" +#include "StructuredAppend.h" #include "TextDecoder.h" #include "ZXContainerAlgorithms.h" #include "ZXTestSupport.h" diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index f0953b87c6..34581dc323 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -24,8 +24,8 @@ #include "DetectorResult.h" #include "GridSampler.h" #include "LogMatrix.h" -#include "PerspectiveTransform.h" -#include "QRVersion.h" +#include "Pattern.h" +#include "Quadrilateral.h" #include "RegressionLine.h" #include "BitMatrixIO.h" @@ -33,9 +33,10 @@ #include #include #include -#include +#include #include #include +#include namespace ZXing::QRCode { diff --git a/core/src/qrcode/QRMaskUtil.cpp b/core/src/qrcode/QRMaskUtil.cpp index 12d1a8a2f0..2f327e4f2a 100644 --- a/core/src/qrcode/QRMaskUtil.cpp +++ b/core/src/qrcode/QRMaskUtil.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace ZXing::QRCode::MaskUtil { diff --git a/core/src/qrcode/QRMatrixUtil.cpp b/core/src/qrcode/QRMatrixUtil.cpp index e248a8dc3f..f937a08f5b 100644 --- a/core/src/qrcode/QRMatrixUtil.cpp +++ b/core/src/qrcode/QRMatrixUtil.cpp @@ -23,7 +23,6 @@ #include "QRErrorCorrectionLevel.h" #include "QRVersion.h" -#include #include #include diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 7ce9180b1b..208e1222b5 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -18,15 +18,12 @@ #include "QRReader.h" #include "BinaryBitmap.h" -#include "BitMatrix.h" #include "DecodeHints.h" #include "DecoderResult.h" #include "DetectorResult.h" #include "QRDecoder.h" -#include "QRDecoderMetadata.h" #include "QRDetector.h" #include "Result.h" -#include "ResultPoint.h" #include diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index a16068155a..7e2c5066c7 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -18,12 +18,12 @@ #include "TextUtfEncoding.h" #include "GTIN.h" -#include #include #include #include #include #include +#include #include #include diff --git a/example/ZXingWriter.cpp b/example/ZXingWriter.cpp index b038365ee5..060b342712 100644 --- a/example/ZXingWriter.cpp +++ b/example/ZXingWriter.cpp @@ -16,16 +16,13 @@ #include "BarcodeFormat.h" #include "BitMatrix.h" -#include "ByteMatrix.h" #include "MultiFormatWriter.h" #include "TextUtfEncoding.h" #include #include -#include #include #include -#include #include #define STB_IMAGE_WRITE_IMPLEMENTATION diff --git a/test/blackbox/ImageLoader.cpp b/test/blackbox/ImageLoader.cpp index 2375c978d2..b02f469f2b 100644 --- a/test/blackbox/ImageLoader.cpp +++ b/test/blackbox/ImageLoader.cpp @@ -18,10 +18,7 @@ #include "ImageLoader.h" #include "BinaryBitmap.h" -#include "GenericLuminanceSource.h" -#include "HybridBinarizer.h" #include "ReadBarcode.h" -#include "ThresholdBinarizer.h" #include #include diff --git a/test/blackbox/TestReaderMain.cpp b/test/blackbox/TestReaderMain.cpp index 4efc7b566e..cabc70267f 100644 --- a/test/blackbox/TestReaderMain.cpp +++ b/test/blackbox/TestReaderMain.cpp @@ -16,7 +16,6 @@ */ #include "BlackboxTestRunner.h" -#include "ByteArray.h" #include "ImageLoader.h" #include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" diff --git a/test/blackbox/TestWriterMain.cpp b/test/blackbox/TestWriterMain.cpp index 041f7c2645..d3e84ae9a9 100644 --- a/test/blackbox/TestWriterMain.cpp +++ b/test/blackbox/TestWriterMain.cpp @@ -16,7 +16,6 @@ */ #include "BitMatrix.h" -#include "ByteMatrix.h" #include "MultiFormatWriter.h" #include From cad4aa216303d0244326993b63793de0e97c95b1 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Sat, 10 Jul 2021 15:57:27 +0200 Subject: [PATCH 0002/1315] example: add missing '-encoding' command line parameter in ZXingWriter This fixes #231. --- example/ZXingWriter.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/example/ZXingWriter.cpp b/example/ZXingWriter.cpp index 060b342712..dccfd6b2bc 100644 --- a/example/ZXingWriter.cpp +++ b/example/ZXingWriter.cpp @@ -18,6 +18,7 @@ #include "BitMatrix.h" #include "MultiFormatWriter.h" #include "TextUtfEncoding.h" +#include "CharacterSetECI.h" #include #include @@ -57,7 +58,8 @@ static bool ParseSize(std::string str, int* width, int* height) return false; } -static bool ParseOptions(int argc, char* argv[], int* width, int* height, int* margin, int* eccLevel, BarcodeFormat* format, std::string* text, std::string* filePath) +static bool ParseOptions(int argc, char* argv[], int* width, int* height, int* margin, CharacterSet* encoding, + int* eccLevel, BarcodeFormat* format, std::string* text, std::string* filePath) { int nonOptArgCount = 0; for (int i = 1; i < argc; ++i) { @@ -79,6 +81,11 @@ static bool ParseOptions(int argc, char* argv[], int* width, int* height, int* m return false; *eccLevel = std::stoi(argv[i]); } + else if (strcmp(argv[i], "-encoding") == 0) { + if (++i == argc) + return false; + *encoding = CharacterSetECI::CharsetFromName(argv[i]); + } else if (nonOptArgCount == 0) { *format = BarcodeFormatFromString(argv[i]); if (*format == BarcodeFormat::None) { @@ -118,16 +125,17 @@ int main(int argc, char* argv[]) int width = 100, height = 100; int margin = 10; int eccLevel = -1; + CharacterSet encoding = CharacterSet::Unknown; std::string text, filePath; BarcodeFormat format; - if (!ParseOptions(argc, argv, &width, &height, &margin, &eccLevel, &format, &text, &filePath)) { + if (!ParseOptions(argc, argv, &width, &height, &margin, &encoding, &eccLevel, &format, &text, &filePath)) { PrintUsage(argv[0]); return -1; } try { - auto writer = MultiFormatWriter(format).setMargin(margin).setEccLevel(eccLevel); + auto writer = MultiFormatWriter(format).setMargin(margin).setEncoding(encoding).setEccLevel(eccLevel); auto bitmap = ToMatrix(writer.encode(TextUtfEncoding::FromUtf8(text), width, height)); auto ext = GetExtension(filePath); From cc980d08dbaa57c38ca23bb388dca8ea268756ba Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 14 Jul 2021 21:42:53 +0200 Subject: [PATCH 0003/1315] Fix typos: "quite zone" -> "quiet zone" --- core/src/BitArray.h | 8 ++++---- core/src/BitMatrix.h | 4 ++-- core/src/BitMatrixIO.cpp | 4 ++-- core/src/BitMatrixIO.h | 2 +- core/src/MultiFormatWriter.h | 2 +- core/src/Pattern.h | 22 +++++++++++----------- core/src/datamatrix/DMDetector.cpp | 2 +- core/src/datamatrix/DMWriter.cpp | 4 ++-- core/src/datamatrix/DMWriter.h | 4 ++-- core/src/oned/ODCodabarReader.cpp | 8 ++++---- core/src/oned/ODCode128Reader.cpp | 8 ++++---- core/src/oned/ODCode39Reader.cpp | 8 ++++---- core/src/oned/ODCode93Reader.cpp | 10 +++++----- core/src/oned/ODITFReader.cpp | 6 +++--- core/src/oned/ODMultiUPCEANReader.cpp | 6 +++--- 15 files changed, 49 insertions(+), 49 deletions(-) diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 4de8fe14b4..966fca547a 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -275,9 +275,9 @@ class BitArray #endif // Little helper method to make common isRange use case more readable. - // Pass positive zone size to look for quite zone after i and negative for zone in front of i. + // Pass positive zone size to look for quiet zone after i and negative for zone in front of i. // Set allowClippedZone to false if clipping the zone at the image border is not acceptable. - bool hasQuiteZone(Iterator i, int signedZoneSize, bool allowClippedZone = true) const { + bool hasQuietZone(Iterator i, int signedZoneSize, bool allowClippedZone = true) const { int index = static_cast(i - begin()); if (signedZoneSize > 0) { if (!allowClippedZone && index + signedZoneSize >= size()) @@ -290,8 +290,8 @@ class BitArray } } - bool hasQuiteZone(ReverseIterator i, int signedZoneSize, bool allowClippedZone = true) const { - return hasQuiteZone(i.base(), -signedZoneSize, allowClippedZone); + bool hasQuietZone(ReverseIterator i, int signedZoneSize, bool allowClippedZone = true) const { + return hasQuietZone(i.base(), -signedZoneSize, allowClippedZone); } /** diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index 780ed82af8..b8ce4edf0d 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -284,11 +284,11 @@ class BitMatrix }; /** - * @brief Inflate scales a BitMatrix up and adds a quite Zone plus padding + * @brief Inflate scales a BitMatrix up and adds a quiet Zone plus padding * @param matrix input to be expanded * @param width new width in bits (pixel) * @param height new height in bits (pixel) - * @param quietZone size of quite zone to add in modules + * @param quietZone size of quiet zone to add in modules * @return expanded BitMatrix, maybe move(input) if size did not change */ BitMatrix Inflate(BitMatrix&& input, int width, int height, int quietZone); diff --git a/core/src/BitMatrixIO.cpp b/core/src/BitMatrixIO.cpp index c796833932..be1732326c 100644 --- a/core/src/BitMatrixIO.cpp +++ b/core/src/BitMatrixIO.cpp @@ -64,9 +64,9 @@ BitMatrix ParseBitMatrix(const std::string& str, char one, bool expectSpace) return mat; } -void SaveAsPBM(const BitMatrix& matrix, const std::string filename, int quiteZone) +void SaveAsPBM(const BitMatrix& matrix, const std::string filename, int quietZone) { - auto out = Inflate(matrix.copy(), 0, 0, quiteZone); + auto out = Inflate(matrix.copy(), 0, 0, quietZone); std::ofstream file(filename); file << "P1\n" << out.width() << ' ' << out.height() << '\n'; file << ToString(out, '1', '0', true); diff --git a/core/src/BitMatrixIO.h b/core/src/BitMatrixIO.h index fde09e0252..6946b33905 100644 --- a/core/src/BitMatrixIO.h +++ b/core/src/BitMatrixIO.h @@ -25,6 +25,6 @@ namespace ZXing { std::string ToString(const BitMatrix& matrix, char one = 'X', char zero = ' ', bool addSpace = true, bool printAsCString = false); BitMatrix ParseBitMatrix(const std::string& str, char one = 'X', bool expectSpace = true); -void SaveAsPBM(const BitMatrix& matrix, const std::string filename, int quiteZone = 0); +void SaveAsPBM(const BitMatrix& matrix, const std::string filename, int quietZone = 0); } // ZXing diff --git a/core/src/MultiFormatWriter.h b/core/src/MultiFormatWriter.h index 7816b5023c..1ec252aa0f 100644 --- a/core/src/MultiFormatWriter.h +++ b/core/src/MultiFormatWriter.h @@ -52,7 +52,7 @@ class MultiFormatWriter } /** - * Used for all formats, sets the minimum number of quite zone pixels. + * Used for all formats, sets the minimum number of quiet zone pixels. */ MultiFormatWriter& setMargin(int margin) { _margin = margin; diff --git a/core/src/Pattern.h b/core/src/Pattern.h index c4a3f7c512..ce1cfda8c8 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -78,13 +78,13 @@ class PatternView bool isValid() const { return isValid(size()); } template - bool hasQuiteZoneBefore(float scale) const + bool hasQuietZoneBefore(float scale) const { return (acceptIfAtFirstBar && isAtFirstBar()) || _data[-1] >= sum() * scale; } template - bool hasQuiteZoneAfter(float scale) const + bool hasQuietZoneAfter(float scale) const { return (acceptIfAtLastBar && isAtLastBar()) || _data[_size] >= sum() * scale; } @@ -168,7 +168,7 @@ using FixedSparcePattern = FixedPattern; template float IsPattern(const PatternView& view, const FixedPattern& pattern, int spaceInPixel = 0, - float minQuiteZone = 0, float moduleSizeRef = 0.f) + float minQuietZone = 0, float moduleSizeRef = 0) { int width = view.sum(N); if (SUM > N && width < SUM) @@ -176,7 +176,7 @@ float IsPattern(const PatternView& view, const FixedPattern& patt const float moduleSize = (float)width / SUM; - if (minQuiteZone && spaceInPixel < minQuiteZone * moduleSize - 1) + if (minQuietZone && spaceInPixel < minQuietZone * moduleSize - 1) return 0; if (!moduleSizeRef) @@ -195,7 +195,7 @@ float IsPattern(const PatternView& view, const FixedPattern& patt template float IsPattern(const PatternView& view, const FixedPattern& pattern, int spaceInPixel = 0, - float minQuiteZone = 0, float moduleSizeRef = 0.f) + float minQuietZone = 0, float moduleSizeRef = 0) { // pattern contains the indices with the bars/spaces that need to be equally wide int width = 0; @@ -204,7 +204,7 @@ float IsPattern(const PatternView& view, const FixedPattern& patte const float moduleSize = (float)width / SUM; - if (minQuiteZone && spaceInPixel < minQuiteZone * moduleSize - 1) + if (minQuietZone && spaceInPixel < minQuietZone * moduleSize - 1) return 0; if (!moduleSizeRef) @@ -222,11 +222,11 @@ float IsPattern(const PatternView& view, const FixedPattern& patte } template -bool IsRightGuard(const PatternView& view, const FixedPattern& pattern, float minQuiteZone, +bool IsRightGuard(const PatternView& view, const FixedPattern& pattern, float minQuietZone, float moduleSizeRef = 0.f) { int spaceInPixel = view.isAtLastBar() ? std::numeric_limits::max() : *view.end(); - return IsPattern(view, pattern, spaceInPixel, minQuiteZone, moduleSizeRef) != 0; + return IsPattern(view, pattern, spaceInPixel, minQuietZone, moduleSizeRef) != 0; } template @@ -247,11 +247,11 @@ PatternView FindLeftGuard(const PatternView& view, int minSize, Pred isGuard) template PatternView FindLeftGuard(const PatternView& view, int minSize, const FixedPattern& pattern, - float minQuiteZone) + float minQuietZone) { return FindLeftGuard(view, std::max(minSize, LEN), - [&pattern, minQuiteZone](const PatternView& window, int spaceInPixel) { - return IsPattern(window, pattern, spaceInPixel, minQuiteZone); + [&pattern, minQuietZone](const PatternView& window, int spaceInPixel) { + return IsPattern(window, pattern, spaceInPixel, minQuietZone); }); } diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 92eefc3c07..675edbd988 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -409,7 +409,7 @@ static DetectorResult DetectOld(const BitMatrix& image) * It is performing something like a (back) trace search along edges through the bit matrix, first looking for * the 'L'-pattern, then tracing the black/white borders at the top/right. Advantages over the old code are: * * works with lower resolution scans (around 2 pixel per module), due to sub-pixel precision grid placement -* * works with real-world codes that have just one module wide quite-zone (which is perfectly in spec) +* * works with real-world codes that have just one module wide quiet-zone (which is perfectly in spec) */ class DMRegressionLine : public RegressionLine diff --git a/core/src/datamatrix/DMWriter.cpp b/core/src/datamatrix/DMWriter.cpp index 1f792820ea..fe79e603cb 100644 --- a/core/src/datamatrix/DMWriter.cpp +++ b/core/src/datamatrix/DMWriter.cpp @@ -117,8 +117,8 @@ Writer::encode(const std::wstring& contents, int width, int height) const //4. step: low-level encoding BitMatrix result = EncodeLowLevel(symbolData, *symbolInfo); - //5. step: scale-up to requested size, minimum required quite zone is 1 - return Inflate(std::move(result), width, height, _quiteZone); + //5. step: scale-up to requested size, minimum required quiet zone is 1 + return Inflate(std::move(result), width, height, _quietZone); } } // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMWriter.h b/core/src/datamatrix/DMWriter.h index ef9c5513f4..e90e8bfda7 100644 --- a/core/src/datamatrix/DMWriter.h +++ b/core/src/datamatrix/DMWriter.h @@ -32,7 +32,7 @@ class Writer Writer(); Writer& setMargin(int margin) { - _quiteZone = margin; + _quietZone = margin; return *this; } @@ -57,7 +57,7 @@ class Writer private: SymbolShape _shapeHint; - int _quiteZone = 1, _minWidth = -1, _minHeight = -1, _maxWidth = -1, _maxHeight = -1; + int _quietZone = 1, _minWidth = -1, _minHeight = -1, _maxWidth = -1, _maxHeight = -1; }; } // DataMatrix diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index 0d6ebc33e6..b81978de06 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -48,8 +48,8 @@ CodabarReader::CodabarReader(const DecodeHints& hints) // each character has 4 bars and 3 spaces constexpr int CHAR_LEN = 7; -// quite zone is half the width of a character symbol -constexpr float QUITE_ZONE_SCALE = 0.5f; +// quiet zone is half the width of a character symbol +constexpr float QUIET_ZONE_SCALE = 0.5f; // official start and stop symbols are "ABCD" // some codabar generator allow the codabar string to be closed by every @@ -57,7 +57,7 @@ constexpr float QUITE_ZONE_SCALE = 0.5f; bool IsLeftGuard(const PatternView& view, int spaceInPixel) { - return spaceInPixel > view.sum() * QUITE_ZONE_SCALE && + return spaceInPixel > view.sum() * QUIET_ZONE_SCALE && Contains({0x1A, 0x29, 0x0B, 0x0E}, RowReader::NarrowWideBitPattern(view)); } @@ -96,7 +96,7 @@ CodabarReader::decodePattern(int rowNumber, const PatternView& row, std::unique_ // next now points to the last decoded symbol // check txt length and whitespace after the last char. See also FindStartPattern. - if (Size(txt) < minCharCount || !next.hasQuiteZoneAfter(QUITE_ZONE_SCALE)) + if (Size(txt) < minCharCount || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) return Result(DecodeStatus::NotFound); // remove stop/start characters diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index 0629a01857..5af91d0455 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -183,7 +183,7 @@ Code128Reader::Code128Reader(const DecodeHints& hints) : // all 3 start patterns share the same 2-1-1 prefix constexpr auto START_PATTERN_PREFIX = FixedPattern<3, 4>{2, 1, 1}; constexpr int CHAR_LEN = 6; -constexpr float QUITE_ZONE = 8; // quite zone spec is 10 modules +constexpr float QUIET_ZONE = 8; // quiet zone spec is 10 modules //#define USE_FAST_1_TO_4_BIT_PATTERN_DECODING #ifdef USE_FAST_1_TO_4_BIT_PATTERN_DECODING @@ -229,7 +229,7 @@ Result Code128Reader::decodePattern(int rowNumber, const PatternView& row, std:: #endif }; - auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, START_PATTERN_PREFIX, QUITE_ZONE); + auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, START_PATTERN_PREFIX, QUIET_ZONE); if (!next.isValid()) return Result(DecodeStatus::NotFound); @@ -266,10 +266,10 @@ Result Code128Reader::decodePattern(int rowNumber, const PatternView& row, std:: if (Size(rawCodes) < minCharCount - 1) // stop code is missing in rawCodes return Result(DecodeStatus::NotFound); - // check termination bar (is present and not wider than about 2 modules) and quite zone (next is now 13 modules + // check termination bar (is present and not wider than about 2 modules) and quiet zone (next is now 13 modules // wide, require at least 8) next = next.subView(0, CHAR_LEN + 1); - if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuiteZoneAfter(QUITE_ZONE/13)) + if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuietZoneAfter(QUIET_ZONE/13)) return Result(DecodeStatus::NotFound); int checksum = rawCodes.front(); diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index 926473278f..9cea7bdbf3 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -100,10 +100,10 @@ Result Code39Reader::decodePattern(int rowNumber, const PatternView& row, std::u // provide the indices with the narrow bars/spaces which have to be equally wide constexpr auto START_PATTERN = FixedSparcePattern{0, 2, 3, 5, 7, 8}; - // quite zone is half the width of a character symbol - constexpr float QUITE_ZONE_SCALE = 0.5f; + // quiet zone is half the width of a character symbol + constexpr float QUIET_ZONE_SCALE = 0.5f; - auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, START_PATTERN, QUITE_ZONE_SCALE * 12); + auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, START_PATTERN, QUIET_ZONE_SCALE * 12); if (!next.isValid()) return Result(DecodeStatus::NotFound); @@ -129,7 +129,7 @@ Result Code39Reader::decodePattern(int rowNumber, const PatternView& row, std::u txt.pop_back(); // remove asterisk // check txt length and whitespace after the last char. See also FindStartPattern. - if (Size(txt) < minCharCount - 2 || !next.hasQuiteZoneAfter(QUITE_ZONE_SCALE)) + if (Size(txt) < minCharCount - 2 || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) return Result(DecodeStatus::NotFound); if (_usingCheckDigit) { diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index 5926dfba18..8a36775944 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -77,8 +77,8 @@ bool DecodeExtendedCode39AndCode93(std::string& encoded, const char ctrl[4]); constexpr int CHAR_LEN = 6; constexpr int CHAR_SUM = 9; -// quite zone is half the width of a character symbol -constexpr float QUITE_ZONE_SCALE = 0.5f; +// quiet zone is half the width of a character symbol +constexpr float QUIET_ZONE_SCALE = 0.5f; static bool IsStartGuard(const PatternView& window, int spaceInPixel) { @@ -86,7 +86,7 @@ static bool IsStartGuard(const PatternView& window, int spaceInPixel) // Use only the first 4 elements which results in more than a 2x speedup. This is counter-intuitive since we save at // most 1/3rd of the loop iterations in FindPattern. The reason might be a successful vectorization with the limited // pattern size that is missed otherwise. We check for the remaining 2 slots for plausibility of the 4:1 ratio. - return IsPattern(window, FixedPattern<4, 4>{1, 1, 1, 1}, spaceInPixel, QUITE_ZONE_SCALE * 12) && + return IsPattern(window, FixedPattern<4, 4>{1, 1, 1, 1}, spaceInPixel, QUIET_ZONE_SCALE * 12) && window[4] > 3 * window[5] - 2 && RowReader::OneToFourBitPattern(window) == ASTERISK_ENCODING; } @@ -120,9 +120,9 @@ Result Code93Reader::decodePattern(int rowNumber, const PatternView& row, std::u if (Size(txt) < minCharCount - 2) return Result(DecodeStatus::NotFound); - // check termination bar (is present and not wider than about 2 modules) and quite zone + // check termination bar (is present and not wider than about 2 modules) and quiet zone next = next.subView(0, CHAR_LEN + 1); - if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuiteZoneAfter(QUITE_ZONE_SCALE)) + if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) return Result(DecodeStatus::NotFound); if (!CheckChecksums(txt)) diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 42ddd592d9..5b1224952d 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -43,9 +43,9 @@ constexpr auto STOP_PATTERN_2 = FixedPattern<3, 5>{3, 1, 1}; Result ITFReader::decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const { const int minCharCount = 6; - const int minQuiteZone = 10; + const int minQuietZone = 10; - auto next = FindLeftGuard(row, 4 + minCharCount/2 + 3, START_PATTERN_, minQuiteZone); + auto next = FindLeftGuard(row, 4 + minCharCount/2 + 3, START_PATTERN_, minQuietZone); if (!next.isValid()) return Result(DecodeStatus::NotFound); @@ -83,7 +83,7 @@ Result ITFReader::decodePattern(int rowNumber, const PatternView& row, std::uniq if (Size(txt) < minCharCount) return Result(DecodeStatus::NotFound); - if (!IsRightGuard(next, STOP_PATTERN_1, minQuiteZone) && !IsRightGuard(next, STOP_PATTERN_2, minQuiteZone)) + if (!IsRightGuard(next, STOP_PATTERN_1, minQuietZone) && !IsRightGuard(next, STOP_PATTERN_2, minQuietZone)) return Result(DecodeStatus::NotFound); int xStop = next.pixelsTillEnd(); diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 30ac3d5ea0..136a724c92 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -48,7 +48,7 @@ static const int FIRST_DIGIT_ENCODINGS[] = { 0x00, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A }; -// The GS1 specification has the following to say about quite zones +// The GS1 specification has the following to say about quiet zones // Type: EAN-13 | EAN-8 | UPC-A | UPC-E | EAN Add-on | UPC Add-on // QZ L: 11 | 7 | 9 | 9 | 7-12 | 9-12 // QZ R: 7 | 7 | 9 | 7 | 5 | 5 @@ -57,7 +57,7 @@ constexpr float QUIET_ZONE_LEFT = 6; constexpr float QUIET_ZONE_RIGHT = 6; // There is a single sample (ean13-1/12.png) that fails to decode with these (new) settings because -// it has a right-side quite zone of only about 4.5 modules, which is clearly out of spec. +// it has a right-side quiet zone of only about 4.5 modules, which is clearly out of spec. static bool DecodeDigit(const PatternView& view, std::string& txt, int* lgPattern = nullptr) { @@ -265,7 +265,7 @@ static bool AddOn(PartialResult& res, PatternView begin, int digitCount) } } - //TODO: check right quite zone + //TODO: check right quiet zone if (digitCount == 2) { CHECK(std::stoi(res.txt) % 4 == lgPattern); From 7067c1c8d5d9b9a8ba1511ad61e71b7726a17e4b Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 14 Jul 2021 21:51:23 +0200 Subject: [PATCH 0004/1315] [[deprecated]]: remove the (trivially removable) deprecated APIs If this breaks your code, you have been warned ;). --- core/src/BarcodeFormat.h | 1 - core/src/BinaryBitmap.h | 6 -- core/src/BitMatrix.cpp | 10 --- core/src/BitMatrix.h | 3 - core/src/DecodeHints.h | 22 ------ core/src/ReadBarcode.h | 9 --- core/src/Result.cpp | 8 -- core/src/Result.h | 30 -------- core/src/ResultMetadata.cpp | 140 ----------------------------------- core/src/ResultMetadata.h | 142 ------------------------------------ 10 files changed, 371 deletions(-) delete mode 100644 core/src/ResultMetadata.cpp delete mode 100644 core/src/ResultMetadata.h diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index 509e65282e..2858ed57e6 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -70,7 +70,6 @@ enum class BarcodeFormat UPC_A [[deprecated]] = UPCA, UPC_E [[deprecated]] = UPCE, - FORMAT_COUNT [[deprecated]] = None, ///> DEPRECATED: will be removed _max = UPCE, ///> implementation detail, don't use }; diff --git a/core/src/BinaryBitmap.h b/core/src/BinaryBitmap.h index 357a4d1a12..14b9d01890 100644 --- a/core/src/BinaryBitmap.h +++ b/core/src/BinaryBitmap.h @@ -39,12 +39,6 @@ class BinaryBitmap public: virtual ~BinaryBitmap() = default; - /** - * Image is a pure monochrome image of a barcode. - */ - [[deprecated]] - virtual bool isPureBarcode() const { return false; } - /** * @return The width of the bitmap. */ diff --git a/core/src/BitMatrix.cpp b/core/src/BitMatrix.cpp index 5868b5fa23..2f484f7d1c 100644 --- a/core/src/BitMatrix.cpp +++ b/core/src/BitMatrix.cpp @@ -18,7 +18,6 @@ #include "BitMatrix.h" #include "BitArray.h" -#include "ByteMatrix.h" #include "Pattern.h" #ifndef ZX_FAST_BIT_STORAGE @@ -46,15 +45,6 @@ BitMatrix::getRow(int y, BitArray& row) const #endif } -ByteMatrix BitMatrix::toByteMatrix(int black, int white) const -{ - ByteMatrix res(width(), height()); - for (int y = 0; y < height(); ++y) - for (int x = 0; x < width(); ++x) - res.set(x, y, get(x, y) ? black : white); - return res; -} - void BitMatrix::setRegion(int left, int top, int width, int height) { diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index b8ce4edf0d..1569e885a5 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -100,9 +100,6 @@ class BitMatrix return *this; } - [[deprecated]] - ByteMatrix toByteMatrix(int black = 0, int white = 255) const; - #ifdef ZX_FAST_BIT_STORAGE // experimental iterator based access template diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 7f0a2cd9e8..4b18dca106 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -121,28 +121,6 @@ class DecodeHints bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f); } bool hasNoFormat() const noexcept { return _formats.empty(); } - - [[deprecated]] DecodeHints& setPossibleFormats(const std::vector& formats) - { - _formats.clear(); - for (auto f : formats) - _formats |= f; - return *this; - } - - [[deprecated]] bool requireEanAddOnSymbol() const { return _eanAddOnSymbol == EanAddOnSymbol::Require; } - [[deprecated]] DecodeHints& setRequireEanAddOnSymbol(bool v) - { - return setEanAddOnSymbol(v ? EanAddOnSymbol::Require : EanAddOnSymbol::Ignore); - } - [[deprecated]] std::vector allowedEanExtensions() const - { - return _eanAddOnSymbol == EanAddOnSymbol::Require ? std::vector{2, 5} : std::vector{}; - } - [[deprecated]] DecodeHints& setAllowedEanExtensions(const std::vector& v) - { - return setEanAddOnSymbol(v.empty() ? EanAddOnSymbol::Ignore : EanAddOnSymbol::Require); - } }; } // ZXing diff --git a/core/src/ReadBarcode.h b/core/src/ReadBarcode.h index 4204ec3764..901c78d37e 100644 --- a/core/src/ReadBarcode.h +++ b/core/src/ReadBarcode.h @@ -99,14 +99,5 @@ class ImageView */ Result ReadBarcode(const ImageView& buffer, const DecodeHints& hints = {}); - -[[deprecated]] -Result ReadBarcode(int width, int height, const uint8_t* data, int rowStride, - BarcodeFormats formats = {}, bool tryRotate = true, bool tryHarder = true); - -[[deprecated]] -Result ReadBarcode(int width, int height, const uint8_t* data, int rowStride, int pixelStride, int rIndex, int gIndex, int bIndex, - BarcodeFormats formats = {}, bool tryRotate = true, bool tryHarder = true); - } // ZXing diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 4b37224b58..abafb2fd49 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -43,14 +43,6 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), _ecLevel(decodeResult.ecLevel()), _sai(decodeResult.structuredAppend()), _readerInit(decodeResult.readerInit()) { - // TODO: keep that for one release so people get the deprecation warning with a still intact functionality - if (isPartOfSequence()) { - _metadata.put(ResultMetadata::STRUCTURED_APPEND_SEQUENCE, sequenceIndex()); - _metadata.put(ResultMetadata::STRUCTURED_APPEND_CODE_COUNT, sequenceSize()); - if (_format == BarcodeFormat::QRCode) - _metadata.put(ResultMetadata::STRUCTURED_APPEND_PARITY, std::stoi(sequenceId())); - } - // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } diff --git a/core/src/Result.h b/core/src/Result.h index 0d3363a85d..0ae693ea8a 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -21,13 +21,9 @@ #include "ByteArray.h" #include "DecodeStatus.h" #include "Quadrilateral.h" -#include "ResultMetadata.h" -#include "ResultPoint.h" #include "StructuredAppend.h" #include -#include -#include namespace ZXing { @@ -66,20 +62,10 @@ class Result return _format; } - [[deprecated]] - void setFormat(BarcodeFormat format) { - _format = format; - } - const std::wstring& text() const { return _text; } - [[deprecated]] - void setText(std::wstring&& text) { - _text = std::move(text); - } - const Position& position() const { return _position; } @@ -101,21 +87,6 @@ class Result return _ecLevel; } - [[deprecated]] - std::vector resultPoints() const { - return {position().begin(), position().end()}; - } - - [[deprecated]] - const ResultMetadata& metadata() const { - return _metadata; - } - - [[deprecated]] - ResultMetadata& metadata() { - return _metadata; - } - /** * @brief sequenceSize number of symbols in a structured append sequence. * @@ -157,7 +128,6 @@ class Result ByteArray _rawBytes; int _numBits = 0; std::wstring _ecLevel; - ResultMetadata _metadata; StructuredAppendInfo _sai; bool _readerInit = false; }; diff --git a/core/src/ResultMetadata.cpp b/core/src/ResultMetadata.cpp deleted file mode 100644 index ec228e266a..0000000000 --- a/core/src/ResultMetadata.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "ResultMetadata.h" - -#include "ByteArray.h" - -#include - -namespace ZXing { - -struct ResultMetadata::Value -{ - virtual ~Value() = default; - virtual int toInteger(int fallback) const { - return fallback; - } - virtual std::wstring toString() const { - return std::wstring(); - } - virtual std::list toByteArrayList() const { - return std::list(); - } - virtual std::shared_ptr toCustomData() const { - return nullptr; - } -}; - -struct ResultMetadata::IntegerValue : public Value -{ - int value; - explicit IntegerValue(int v) : value(v) {} - int toInteger(int) const override { - return value; - } - std::wstring toString() const override { - return std::to_wstring(value); - } -}; - -struct ResultMetadata::StringValue : public Value -{ - std::wstring value; - explicit StringValue(std::wstring v) : value(std::move(v)) {} - std::wstring toString() const override { - return value; - } -}; - -struct ResultMetadata::ByteArrayListValue : public Value -{ - std::list value; - explicit ByteArrayListValue(std::list v) : value(std::move(v)) {} - std::list toByteArrayList() const override { - return value; - } -}; - -struct ResultMetadata::CustomDataValue : public Value -{ - std::shared_ptr value; - explicit CustomDataValue(std::shared_ptr v) : value(std::move(v)) {} - std::shared_ptr toCustomData() const override { - return value; - } -}; - -int -ResultMetadata::getInt(Key key, int fallbackValue) const -{ - auto it = _contents.find(key); - return it != _contents.end() ? it->second->toInteger(fallbackValue) : fallbackValue; -} - -std::wstring -ResultMetadata::getString(Key key) const -{ - auto it = _contents.find(key); - return it != _contents.end() ? it->second->toString() : std::wstring(); -} - -std::list -ResultMetadata::getByteArrayList(Key key) const -{ - auto it = _contents.find(key); - return it != _contents.end() ? it->second->toByteArrayList() : std::list(); -} - -std::shared_ptr -ResultMetadata::getCustomData(Key key) const -{ - auto it = _contents.find(key); - return it != _contents.end() ? it->second->toCustomData() : nullptr; -} - -void -ResultMetadata::put(Key key, int value) -{ - _contents[key] = std::make_shared(value); -} - -void -ResultMetadata::put(Key key, const std::wstring& value) -{ - _contents[key] = std::make_shared(value); -} - -void -ResultMetadata::put(Key key, const std::list& value) -{ - _contents[key] = std::make_shared(value); -} - -void -ResultMetadata::put(Key key, const std::shared_ptr& value) -{ - _contents[key] = std::make_shared(value); -} - -void -ResultMetadata::putAll(const ResultMetadata& other) -{ - _contents.insert(other._contents.begin(), other._contents.end()); -} - -} // ZXing diff --git a/core/src/ResultMetadata.h b/core/src/ResultMetadata.h deleted file mode 100644 index 314a8a1ace..0000000000 --- a/core/src/ResultMetadata.h +++ /dev/null @@ -1,142 +0,0 @@ -#pragma once -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include -#include -#include -#include - -namespace ZXing { - -class ByteArray; -class CustomData; - -/** -* @author Sean Owen -*/ -class ResultMetadata -{ -public: - - /** - * Represents some type of metadata about the result of the decoding that the decoder - * wishes to communicate back to the caller. - */ - enum Key { - - /** - * Unspecified, application-specific metadata. Maps to an unspecified {@link CustomData}. - */ - OTHER [[deprecated]], - - /** - * Denotes the likely approximate orientation of the barcode in the image. This value - * is given as degrees rotated clockwise from the normal, upright orientation. - * For example a 1D barcode which was found by reading top-to-bottom would be - * said to have orientation "90". This key maps to an {@link Integer} whose - * value is in the range [0,360). - */ - ORIENTATION [[deprecated]], - - /** - *

2D barcode formats typically encode text, but allow for a sort of 'byte mode' - * which is sometimes used to encode binary data. While {@link Result} makes available - * the complete raw bytes in the barcode for these formats, it does not offer the bytes - * from the byte segments alone.

- * - *

This maps to a {@link java.util.List} of byte arrays corresponding to the - * raw bytes in the byte segments in the barcode, in order.

- */ - BYTE_SEGMENTS [[deprecated]], - - /** - * Error correction level used, if applicable. The value type depends on the - * format, but is typically a String. - */ - ERROR_CORRECTION_LEVEL [[deprecated]], - - /** - * For some periodicals, indicates the issue number as an {@link Integer}. - */ - ISSUE_NUMBER [[deprecated]], - - /** - * For some products, indicates the suggested retail price in the barcode as a - * formatted {@link String}. - */ - SUGGESTED_PRICE [[deprecated]], - - /** - * For some products, the possible country of manufacture as a {@link String} denoting the - * ISO country code. Some map to multiple possible countries, like "US/CA". - */ - POSSIBLE_COUNTRY [[deprecated]], - - /** - * For some products, the extension text - */ - UPC_EAN_EXTENSION [[deprecated]], - - /** - * PDF417-specific metadata - */ - PDF417_EXTRA_METADATA [[deprecated]], - - /** - * If the code format supports structured append and the current scanned code is part of one then the - * sequence number is given with it. - */ - STRUCTURED_APPEND_SEQUENCE [[deprecated]], - - /** - * If the code format supports structured append and the current scanned code is part of one then the - * total code count is given with it. - */ - STRUCTURED_APPEND_CODE_COUNT [[deprecated]], - - /** - * If the code format supports structured append and the current scanned code is part of one then the - * parity is given with it. - */ - STRUCTURED_APPEND_PARITY [[deprecated]], - - }; - - int getInt(Key key, int fallbackValue = 0) const; - std::wstring getString(Key key) const; - std::list getByteArrayList(Key key) const; - std::shared_ptr getCustomData(Key key) const; - - void put(Key key, int value); - void put(Key key, const std::wstring& value); - void put(Key key, const std::list& value); - void put(Key key, const std::shared_ptr& value); - - void putAll(const ResultMetadata& other); - -private: - struct Value; - struct IntegerValue; - struct StringValue; - struct ByteArrayListValue; - struct CustomDataValue; - - std::map> _contents; -}; - -} // ZXing From e76b4723b28c4cb6d15c325516b98f1be66932b7 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 14 Jul 2021 21:57:42 +0200 Subject: [PATCH 0005/1315] [[deprecated]]: fix build regression (overlooked hunk in CMakeLists.txt) --- core/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 7a2db607cf..e2c2c9421b 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -107,8 +107,6 @@ if (BUILD_READERS) src/ReedSolomonDecoder.cpp src/Result.h src/Result.cpp - src/ResultMetadata.h - src/ResultMetadata.cpp src/ResultPoint.h src/ResultPoint.cpp src/TextDecoder.h From 92e17f3cb1b445f2ef98a725f082587a20848e07 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 15 Jul 2021 16:29:06 +0200 Subject: [PATCH 0006/1315] [[deprecated]]: remove another overlooked hunk (amend last commit) --- core/src/ReadBarcode.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 81a0236e4d..67cfa03b4b 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -62,18 +62,4 @@ Result ReadBarcode(const ImageView& iv, const DecodeHints& hints) } } -Result ReadBarcode(int width, int height, const uint8_t* data, int rowStride, BarcodeFormats formats, bool tryRotate, - bool tryHarder) -{ - return ReadBarcode({0, 0, width, height, data, rowStride, 1, 0, 0, 0, nullptr}, - DecodeHints().setTryHarder(tryHarder).setTryRotate(tryRotate).setFormats(formats)); -} - -Result ReadBarcode(int width, int height, const uint8_t* data, int rowStride, int pixelStride, int rIndex, int gIndex, - int bIndex, BarcodeFormats formats, bool tryRotate, bool tryHarder) -{ - return ReadBarcode({0, 0, width, height, data, rowStride, pixelStride, rIndex, gIndex, bIndex, nullptr}, - DecodeHints().setTryHarder(tryHarder).setTryRotate(tryRotate).setFormats(formats)); -} - } // ZXing From 89012b4b002db71f0d6b85fd6630c47c509d9e93 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Mon, 19 Jul 2021 10:46:34 +0200 Subject: [PATCH 0007/1315] [[deprecated]]: Remove LuminanceSource API * replace LuminanceSource constructors of Binarizers with ImageView * remove all unnecessary memcopies of the image buffer * don't rotate the whole buffer for 1D readers, only the checked lines * move BitMatrix cache into the BinaryBitmap base class * simplify BinaryBitmap interface (drop cropped() and rotated()) * move ImageView class into separate header This does indeed result in a slight performance improvement of the ReaderTest blackbox testing on a modern Core i9 (approx. 4% faster). --- core/CMakeLists.txt | 5 +- core/src/BinaryBitmap.cpp | 17 ++ core/src/BinaryBitmap.h | 75 ++------ core/src/GenericLuminanceSource.cpp | 242 -------------------------- core/src/GenericLuminanceSource.h | 84 --------- core/src/GlobalHistogramBinarizer.cpp | 130 +++----------- core/src/GlobalHistogramBinarizer.h | 23 +-- core/src/HybridBinarizer.cpp | 80 +++------ core/src/HybridBinarizer.h | 9 +- core/src/ImageView.h | 100 +++++++++++ core/src/LuminanceSource.cpp | 146 ---------------- core/src/LuminanceSource.h | 114 ------------ core/src/ReadBarcode.cpp | 74 +++++--- core/src/ReadBarcode.h | 71 +------- core/src/ThresholdBinarizer.h | 76 ++++---- core/src/aztec/AZReader.cpp | 2 +- core/src/datamatrix/DMReader.cpp | 2 +- core/src/maxicode/MCReader.cpp | 2 +- core/src/oned/ODReader.cpp | 23 ++- core/src/pdf417/PDFDetector.cpp | 6 +- core/src/pdf417/PDFReader.cpp | 2 +- core/src/qrcode/QRReader.cpp | 2 +- thirdparty/stb/stb_image.h | 2 +- 23 files changed, 293 insertions(+), 994 deletions(-) delete mode 100644 core/src/GenericLuminanceSource.cpp delete mode 100644 core/src/GenericLuminanceSource.h create mode 100644 core/src/ImageView.h delete mode 100644 core/src/LuminanceSource.cpp delete mode 100644 core/src/LuminanceSource.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index e2c2c9421b..7f5bbbef2a 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -86,16 +86,13 @@ if (BUILD_READERS) src/DecodeStatus.cpp src/DecoderResult.h src/DetectorResult.h - src/GenericLuminanceSource.h - src/GenericLuminanceSource.cpp src/GlobalHistogramBinarizer.h src/GlobalHistogramBinarizer.cpp src/GridSampler.h src/GridSampler.cpp src/HybridBinarizer.h src/HybridBinarizer.cpp - src/LuminanceSource.h - src/LuminanceSource.cpp + src/ImageView.h src/MultiFormatReader.h src/MultiFormatReader.cpp src/PerspectiveTransform.h diff --git a/core/src/BinaryBitmap.cpp b/core/src/BinaryBitmap.cpp index 93ad54ccde..e68cccd2bc 100644 --- a/core/src/BinaryBitmap.cpp +++ b/core/src/BinaryBitmap.cpp @@ -16,7 +16,24 @@ #include "BinaryBitmap.h" +#include + namespace ZXing { +struct BinaryBitmap::Cache +{ + std::once_flag once; + std::shared_ptr matrix; +}; + +BinaryBitmap::BinaryBitmap(const ImageView& buffer) : _cache(new Cache), _buffer(buffer) {} + +BinaryBitmap::~BinaryBitmap() = default; + +const BitMatrix* BinaryBitmap::getBitMatrix() const +{ + std::call_once(_cache->once, [&](){_cache->matrix = getBlackMatrix();}); + return _cache->matrix.get(); +} } // ZXing diff --git a/core/src/BinaryBitmap.h b/core/src/BinaryBitmap.h index 14b9d01890..896294db73 100644 --- a/core/src/BinaryBitmap.h +++ b/core/src/BinaryBitmap.h @@ -2,6 +2,7 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2021 Axel Waggershauser * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +17,14 @@ * limitations under the License. */ -#include -#include +#include "ReadBarcode.h" + #include +#include #include namespace ZXing { -class BitArray; class BitMatrix; using PatternRow = std::vector; @@ -31,75 +32,35 @@ using PatternRow = std::vector; /** * This class is the core bitmap class used by ZXing to represent 1 bit data. Reader objects * accept a BinaryBitmap and attempt to decode it. -* -* @author dswitkin@google.com (Daniel Switkin) */ class BinaryBitmap { -public: - virtual ~BinaryBitmap() = default; - - /** - * @return The width of the bitmap. - */ - virtual int width() const = 0; - - /** - * @return The height of the bitmap. - */ - virtual int height() const = 0; + struct Cache; + std::unique_ptr _cache; - /** - * Converts one row of luminance data to a vector of ints denoting the widths of the bars and spaces. - */ - virtual bool getPatternRow(int y, PatternRow& res) const = 0; +protected: + const ImageView _buffer; /** - * Converts a 2D array of luminance data to 1 bit. This method is intended for decoding 2D - * barcodes and may or may not apply sharpening. Therefore, a row from this matrix may not be - * identical to one fetched using getBlackRow(), so don't mix and match between them. + * Converts a 2D array of luminance data to 1 bit (true means black). * - * @return The 2D array of bits for the image (true means black). - * @return null if image can't be binarized to make a matrix + * @return The 2D array of bits for the image, nullptr on error. */ virtual std::shared_ptr getBlackMatrix() const = 0; - /** - * @return Whether this bitmap can be cropped. - */ - virtual bool canCrop() const { return false; } +public: + BinaryBitmap(const ImageView& buffer); + virtual ~BinaryBitmap(); - /** - * Returns a new object with cropped image data. Implementations may keep a reference to the - * original data rather than a copy. Only callable if isCropSupported() is true. - * - * @param left The left coordinate, which must be in [0,getWidth()) - * @param top The top coordinate, which must be in [0,getHeight()) - * @param width The width of the rectangle to crop. - * @param height The height of the rectangle to crop. - * @return A cropped version of this object. - */ - virtual std::shared_ptr cropped(int /*left*/, int /*top*/, int /*width*/, int /*height*/) const - { - throw std::runtime_error("This binarizer does not support cropping."); - } + int width() const { return _buffer.width(); } + int height() const { return _buffer.height(); } /** - * @return Whether this bitmap supports counter-clockwise rotation. + * Converts one row of luminance data to a vector of ints denoting the widths of the bars and spaces. */ - virtual bool canRotate() const { return false; } + virtual bool getPatternRow(int row, int rotation, PatternRow& res) const = 0; - /** - * Returns a new object with rotated image data by 90 degrees clockwise. - * Only callable if {@link #isRotateSupported()} is true. - * - * @param degreeCW degree in clockwise direction, possible values are 90, 180 and 270 - * @return A rotated version of this object. - */ - virtual std::shared_ptr rotated(int /*degreeCW*/) const - { - throw std::runtime_error("This binarizer does not support rotation."); - } + const BitMatrix* getBitMatrix() const; }; } // ZXing diff --git a/core/src/GenericLuminanceSource.cpp b/core/src/GenericLuminanceSource.cpp deleted file mode 100644 index 501fd2631e..0000000000 --- a/core/src/GenericLuminanceSource.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#if defined(_MSC_VER) && (_MSC_VER >= 1915) -#pragma warning(disable : 4996) -#endif - -#include "GenericLuminanceSource.h" - -#include "ByteArray.h" -#include "ZXContainerAlgorithms.h" - -#include -#include -#include -#include -#include - -namespace ZXing { - -static uint8_t RGBToGray(unsigned r, unsigned g, unsigned b) -{ - // This optimization is not necessary as the computation below is cheap enough. - //if (r == g && g == b) { - // // Image is already greyscale, so pick any channel. - // return static_cast(r); - //} - - // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC), - // (306*R) >> 10 is approximately equal to R*0.299, and so on. - // 0x200 >> 10 is 0.5, it implements rounding. - return static_cast((306 * r + 601 * g + 117 * b + 0x200) >> 10); -} - -static std::shared_ptr MakeCopy(const void* src, int rowBytes, int left, int top, int width, int height) -{ - auto result = std::make_shared(); - result->resize(width * height); - const uint8_t* srcRow = static_cast(src) + top * rowBytes + left; - uint8_t* destRow = result->data(); - for (int y = 0; y < height; ++y, srcRow += rowBytes, destRow += width) { - std::copy_n(srcRow, width, destRow); - } - return result; -} - -static std::shared_ptr MakeCopy(const ByteArray& pixels, int rowBytes, int left, int top, int width, int height) -{ - if (top == 0 && left == 0 && width * height == Size(pixels)) { - return std::make_shared(pixels); - } - return MakeCopy(pixels.data(), rowBytes, left, top, width, height); -} - -GenericLuminanceSource::GenericLuminanceSource(int left, int top, int width, int height, const void* bytes, int rowBytes, int pixelBytes, int redIndex, int greenIndex, int blueIndex, void*) : - _left(0), // since we copy the pixels - _top(0), - _width(width), - _height(height), - _rowBytes(width) -{ - if (left < 0 || top < 0 || width < 0 || height < 0) { - throw std::out_of_range("Requested offset is outside the image"); - } - - if (pixelBytes == 1) - _pixels = MakeCopy(bytes, rowBytes, left, top, width, height); - else { - auto pixels = std::make_shared(width * height); - const uint8_t *rgbSource = static_cast(bytes) + top * rowBytes; - uint8_t *destRow = pixels->data(); - for (int y = 0; y < height; ++y, rgbSource += rowBytes, destRow += width) { - const uint8_t *src = rgbSource + left * pixelBytes; - for (int x = 0; x < width; ++x, src += pixelBytes) { - destRow[x] = RGBToGray(src[redIndex], src[greenIndex], src[blueIndex]); - } - } - _pixels = std::move(pixels); - } -} - -GenericLuminanceSource::GenericLuminanceSource(int left, int top, int width, int height, std::shared_ptr pixels, int rowBytes) : - _pixels(std::move(pixels)), - _left(left), - _top(top), - _width(width), - _height(height), - _rowBytes(rowBytes) -{ - if (left < 0 || top < 0 || width < 0 || height < 0) { - throw std::out_of_range("Requested offset is outside the image"); - } -} - -// Defined here instead of inlining in header to avoid link error since WINDOWS_EXPORT_ALL_SYMBOLS does not cover vtable. -GenericLuminanceSource::GenericLuminanceSource(int width, int height, const void* bytes, int rowBytes, int pixelBytes, int redIndex, int greenIndex, int blueIndex) : - GenericLuminanceSource(0, 0, width, height, bytes, rowBytes, pixelBytes, redIndex, greenIndex, blueIndex, nullptr) -{ -} - -// Defined here instead of inlining in header to avoid link error since WINDOWS_EXPORT_ALL_SYMBOLS does not cover vtable. -GenericLuminanceSource::GenericLuminanceSource(int left, int top, int width, int height, const void* bytes, int rowBytes, int pixelBytes, int redIndex, int greenIndex, int blueIndex) : - GenericLuminanceSource(left, top, width, height, bytes, rowBytes, pixelBytes, redIndex, greenIndex, blueIndex, nullptr) -{ -} - -// Defined here instead of inlining in header to avoid link error since WINDOWS_EXPORT_ALL_SYMBOLS does not cover vtable. -GenericLuminanceSource::GenericLuminanceSource(int width, int height, const void* bytes, int rowBytes) : - GenericLuminanceSource(0, 0, width, height, bytes, rowBytes, 1, 0, 0, 0, nullptr) -{ -} - -// Defined here instead of inlining in header to avoid link error since WINDOWS_EXPORT_ALL_SYMBOLS does not cover vtable. -GenericLuminanceSource::GenericLuminanceSource(int left, int top, int width, int height, const void* bytes, int rowBytes) : - GenericLuminanceSource(left, top, width, height, bytes, rowBytes, 1, 0, 0, 0, nullptr) -{ -} - -int -GenericLuminanceSource::width() const -{ - return _width; -} - -int -GenericLuminanceSource::height() const -{ - return _height; -} - - - -const uint8_t * -GenericLuminanceSource::getRow(int y, ByteArray& buffer, bool forceCopy) const -{ - if (y < 0 || y >= _height) { - throw std::out_of_range("Requested row is outside the image"); - } - - const uint8_t* row = _pixels->data() + (y + _top)*_rowBytes + _left; - if (!forceCopy) { - return row; - } - - buffer.resize(_width); - std::copy_n(row, _width, buffer.begin()); - return buffer.data(); -} - -const uint8_t * -GenericLuminanceSource::getMatrix(ByteArray& buffer, int& outRowBytes, bool forceCopy) const -{ - const uint8_t* row = _pixels->data() + _top*_rowBytes + _left; - if (!forceCopy) { - outRowBytes = _rowBytes; - return row; - } - - outRowBytes = _width; - buffer.resize(_width * _height); - uint8_t* dest = buffer.data(); - for (int y = 0; y < _height; ++y, row += _rowBytes, dest += _width) { - std::copy_n(row, _width, dest); - } - return buffer.data(); -} - -bool -GenericLuminanceSource::canCrop() const -{ - return true; -} - -std::shared_ptr -GenericLuminanceSource::cropped(int left, int top, int width, int height) const -{ - if (left < 0 || top < 0 || width < 0 || height < 0 || left + width > _width || top + height > _height) { - throw std::out_of_range("Crop rectangle does not fit within image data."); - } - return std::make_shared(_left + left, _top + top, width, height, _pixels, _rowBytes); -} - -bool -GenericLuminanceSource::canRotate() const -{ - return true; -} - -std::shared_ptr -GenericLuminanceSource::rotated(int degreeCW) const -{ - degreeCW = (degreeCW + 360) % 360; - if (degreeCW == 90) - { - auto pixels = std::make_shared(_width * _height); - const uint8_t* srcRow = _pixels->data() + _top * _rowBytes + _left; - uint8_t* dest = pixels->data(); - for (int y = 0; y < _height; ++y, srcRow += _rowBytes) { - for (int x = 0; x < _width; ++x) { - dest[x * _height + (_height - y - 1)] = srcRow[x]; - } - } - return std::make_shared(0, 0, _height, _width, pixels, _height); - } - else if (degreeCW == 180) { - // same as a vertical flip followed a horizontal flip - auto pixels = MakeCopy(*_pixels, _rowBytes, _left, _top, _width, _height); - std::reverse(pixels->begin(), pixels->end()); - return std::make_shared(0, 0, _width, _height, pixels, _width); - } - else if (degreeCW == 270) { - auto pixels = std::make_shared(_width * _height); - const uint8_t* srcRow = _pixels->data() + _top * _rowBytes + _left; - uint8_t* dest = pixels->data(); - for (int y = 0; y < _height; ++y, srcRow += _rowBytes) { - for (int x = 0; x < _width; ++x) { - dest[(_width - x - 1) * _height + y] = srcRow[x]; - } - } - return std::make_shared(0, 0, _height, _width, pixels, _height); - } - else if (degreeCW == 0) { - return std::make_shared(0, 0, _width, _height, _pixels, _width); - } - throw std::invalid_argument("Unsupported rotation"); -} - -} // ZXing diff --git a/core/src/GenericLuminanceSource.h b/core/src/GenericLuminanceSource.h deleted file mode 100644 index cfb5ad2a19..0000000000 --- a/core/src/GenericLuminanceSource.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "LuminanceSource.h" - -#include -#include - -namespace ZXing { - -/** -* This decode images from an address in memory as RGB or ARGB data. -*/ -class GenericLuminanceSource : public LuminanceSource -{ -public: - virtual ~GenericLuminanceSource() = default; - - // Don't use in client code. Used internally for now to prevent lots of deprecation warning noise until the GenericLuminanceSource is completely removed. - GenericLuminanceSource(int left, int top, int width, int height, const void* bytes, int rowBytes, int pixelBytes, int redIndex, int greenIndex, int blueIndex, void* deprecation_tag); - /** - * Init with a RGB source. - */ - [[deprecated]] // please use interface from ReadBarcode.h - GenericLuminanceSource(int width, int height, const void* bytes, int rowBytes, int pixelBytes, int redIndex, int greenIndex, int blueIndex); - - /** - * Init with a RGB source, left, top, width, height specify the subregion area in original image; 'bytes' points to the beginning of image buffer (i.e. pixel (0,0)). - */ - [[deprecated]] // please use interface from ReadBarcode.h - GenericLuminanceSource(int left, int top, int width, int height, const void* bytes, int rowBytes, int pixelBytes, int redIndex, int greenIndex, int blueIndex); - - /** - * Init with a grayscale source. - */ - [[deprecated]] // please use interface from ReadBarcode.h - GenericLuminanceSource(int width, int height, const void* bytes, int rowBytes); - - /** - * Init with a grayscale source, left, top, width, height specify the subregion area in original image; 'bytes' points to the beginning of image buffer (i.e. pixel (0,0)). - */ - [[deprecated]] // please use interface from ReadBarcode.h - GenericLuminanceSource(int left, int top, int width, int height, const void* bytes, int rowBytes); - - /** - * Init with a grayscale source, left, top, width, height specify the subregion area in original image; 'bytes' points the beginning of image buffer (i.e. pixel (0,0)). - */ - [[deprecated]] // please use interface from ReadBarcode.h - GenericLuminanceSource(int left, int top, int width, int height, std::shared_ptr pixels, int rowBytes); - - virtual int width() const override; - virtual int height() const override; - virtual const uint8_t* getRow(int y, ByteArray& buffer, bool forceCopy = false) const override; - virtual const uint8_t* getMatrix(ByteArray& buffer, int& outRowBytes, bool forceCopy = false) const override; - virtual bool canCrop() const override; - virtual std::shared_ptr cropped(int left, int top, int width, int height) const override; - virtual bool canRotate() const override; - virtual std::shared_ptr rotated(int degreeCW) const override; - -private: - std::shared_ptr _pixels; - int _left; - int _top; - int _width; - int _height; - int _rowBytes; -}; - -} // ZXing diff --git a/core/src/GlobalHistogramBinarizer.cpp b/core/src/GlobalHistogramBinarizer.cpp index dbb4f766f0..2b25ac629c 100644 --- a/core/src/GlobalHistogramBinarizer.cpp +++ b/core/src/GlobalHistogramBinarizer.cpp @@ -19,13 +19,11 @@ #include "BitMatrix.h" #include "ByteArray.h" -#include "LuminanceSource.h" #include #include #include #include -#include #include namespace ZXing { @@ -34,34 +32,10 @@ static const int LUMINANCE_BITS = 5; static const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; static const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; - -struct GlobalHistogramBinarizer::DataCache -{ - std::once_flag once; - std::shared_ptr matrix; -}; - -GlobalHistogramBinarizer::GlobalHistogramBinarizer(std::shared_ptr source) : - _source(std::move(source)), - _cache(new DataCache) -{ -} +GlobalHistogramBinarizer::GlobalHistogramBinarizer(const ImageView& buffer) : BinaryBitmap(buffer) {} GlobalHistogramBinarizer::~GlobalHistogramBinarizer() = default; -int -GlobalHistogramBinarizer::width() const -{ - return _source->width(); -} - -int -GlobalHistogramBinarizer::height() const -{ - return _source->height(); -} - - // Return -1 on error static int EstimateBlackPoint(const std::array& buckets) { @@ -110,20 +84,21 @@ static int EstimateBlackPoint(const std::array& buckets) return bestValley << LUMINANCE_SHIFT; } -bool GlobalHistogramBinarizer::getPatternRow(int y, PatternRow& res) const +bool GlobalHistogramBinarizer::getPatternRow(int row, int rotation, PatternRow& res) const { - int width = _source->width(); - if (width < 3) + auto buffer = _buffer.rotated(rotation); + + if (buffer.width() < 3) return false; // special casing the code below for a width < 3 makes no sense res.clear(); - ByteArray buffer; - const uint8_t* luminances = _source->getRow(y, buffer); + const uint8_t* luminances = buffer.data(0, row); + const int pixStride = buffer.pixStride(); std::array buckets = {}; - for (int x = 0; x < width; x++) { - buckets[luminances[x] >> LUMINANCE_SHIFT]++; - } + for (int x = 0; x < buffer.width(); x++) + buckets[luminances[x * pixStride] >> LUMINANCE_SHIFT]++; + int blackPoint = EstimateBlackPoint(buckets); if (blackPoint <= 0) return false; @@ -135,20 +110,20 @@ bool GlobalHistogramBinarizer::getPatternRow(int y, PatternRow& res) const auto process = [&](bool val, const uint8_t* p) { if (val != lastVal) { - res.push_back(static_cast(p - lastPos)); + res.push_back(static_cast(p - lastPos) / pixStride); lastVal = val; lastPos = p; } }; - for (auto* p = luminances + 1; p < luminances + width - 1; ++p) - process((-*(p - 1) + (int(*p) * 4) - *(p + 1)) / 2 < blackPoint, p); + for (auto *p = luminances + pixStride, *e = luminances + (buffer.width() - 1) * pixStride; p < e; p += pixStride) + process((-*(p - pixStride) + (int(*p) * 4) - *(p + pixStride)) / 2 < blackPoint, p); - auto* backPos = luminances + width - 1; + auto* backPos = buffer.data(buffer.width() - 1, row); bool backVal = *backPos < blackPoint; process(backVal, backPos); - res.push_back(static_cast(backPos - lastPos + 1)); + res.push_back(static_cast((backPos - lastPos) / pixStride + 1)); if (backVal) res.push_back(0); // last value is number of white pixels, here 0 @@ -158,85 +133,36 @@ bool GlobalHistogramBinarizer::getPatternRow(int y, PatternRow& res) const return true; } -static void InitBlackMatrix(const LuminanceSource& source, std::shared_ptr& outMatrix) +// Does not sharpen the data, as this call is intended to only be used by 2D Readers. +std::shared_ptr +GlobalHistogramBinarizer::getBlackMatrix() const { - int width = source.width(); - int height = source.height(); - auto matrix = std::make_shared(width, height); - // Quickly calculates the histogram by sampling four rows from the image. This proved to be // more robust on the blackbox tests than sampling a diagonal as we used to do. std::array localBuckets = {}; { - ByteArray buffer; for (int y = 1; y < 5; y++) { - int row = height * y / 5; - const uint8_t* luminances = source.getRow(row, buffer); - int right = (width * 4) / 5; - for (int x = width / 5; x < right; x++) { + int row = height() * y / 5; + const uint8_t* luminances = _buffer.data(0, row); + int right = (width() * 4) / 5; + for (int x = width() / 5; x < right; x++) localBuckets[luminances[x] >> LUMINANCE_SHIFT]++; - } } } int blackPoint = EstimateBlackPoint(localBuckets); if (blackPoint <= 0) - return; + return {}; // We delay reading the entire image luminance until the black point estimation succeeds. // Although we end up reading four rows twice, it is consistent with our motto of // "fail quickly" which is necessary for continuous scanning. - ByteArray buffer; - int stride; - const uint8_t* luminances = source.getMatrix(buffer, stride); - for (int y = 0; y < height; y++) { - int offset = y * stride; - for (int x = 0; x < width; x++) { - if (luminances[offset + x] < blackPoint) { - matrix->set(x, y); - } - } - } - outMatrix = matrix; -} + auto matrix = std::make_shared(width(), height()); + for(int y = 0; y < height(); ++y) + for(int x = 0; x < width(); ++x) + matrix->set(x, y, *_buffer.data(x, y) < blackPoint); -// Does not sharpen the data, as this call is intended to only be used by 2D Readers. -std::shared_ptr -GlobalHistogramBinarizer::getBlackMatrix() const -{ - std::call_once(_cache->once, &InitBlackMatrix, std::cref(*_source), std::ref(_cache->matrix)); - return _cache->matrix; -} - -bool -GlobalHistogramBinarizer::canCrop() const -{ - return _source->canCrop(); -} - -std::shared_ptr -GlobalHistogramBinarizer::cropped(int left, int top, int width, int height) const -{ - return newInstance(_source->cropped(left, top, width, height)); + return matrix; } -bool -GlobalHistogramBinarizer::canRotate() const -{ - return _source->canRotate(); -} - -std::shared_ptr -GlobalHistogramBinarizer::rotated(int degreeCW) const -{ - return newInstance(_source->rotated(degreeCW)); -} - -std::shared_ptr -GlobalHistogramBinarizer::newInstance(const std::shared_ptr& source) const -{ - return std::make_shared(source); -} - - } // ZXing diff --git a/core/src/GlobalHistogramBinarizer.h b/core/src/GlobalHistogramBinarizer.h index 391969d29d..fbeac5d9df 100644 --- a/core/src/GlobalHistogramBinarizer.h +++ b/core/src/GlobalHistogramBinarizer.h @@ -18,12 +18,8 @@ #include "BinaryBitmap.h" -#include - namespace ZXing { -class LuminanceSource; - /** * This Binarizer implementation uses the old ZXing global histogram approach. It is suitable * for low-end mobile devices which don't have enough CPU or memory to use a local thresholding @@ -37,27 +33,12 @@ class LuminanceSource; */ class GlobalHistogramBinarizer : public BinaryBitmap { -protected: - std::shared_ptr _source; - public: - explicit GlobalHistogramBinarizer(std::shared_ptr source); + explicit GlobalHistogramBinarizer(const ImageView& buffer); ~GlobalHistogramBinarizer() override; - int width() const override; - int height() const override; - bool getPatternRow(int y, PatternRow &res) const override; + bool getPatternRow(int row, int rotation, PatternRow &res) const override; std::shared_ptr getBlackMatrix() const override; - bool canCrop() const override; - std::shared_ptr cropped(int left, int top, int width, int height) const override; - bool canRotate() const override; - std::shared_ptr rotated(int degreeCW) const override; - - virtual std::shared_ptr newInstance(const std::shared_ptr& source) const; - -private: - struct DataCache; - std::unique_ptr _cache; }; } // ZXing diff --git a/core/src/HybridBinarizer.cpp b/core/src/HybridBinarizer.cpp index 864ac44ea2..2a9bb7aea5 100644 --- a/core/src/HybridBinarizer.cpp +++ b/core/src/HybridBinarizer.cpp @@ -20,7 +20,6 @@ #include "BitMatrix.h" #include "BitMatrixIO.h" #include "ByteArray.h" -#include "LuminanceSource.h" #include "Matrix.h" #include "ZXContainerAlgorithms.h" @@ -37,17 +36,7 @@ static const int BLOCK_SIZE = 8; static const int MINIMUM_DIMENSION = BLOCK_SIZE * 5; static const int MIN_DYNAMIC_RANGE = 24; -struct HybridBinarizer::DataCache -{ - std::once_flag once; - std::shared_ptr matrix; -}; - -HybridBinarizer::HybridBinarizer(const std::shared_ptr& source) : - GlobalHistogramBinarizer(source), - _cache(new DataCache) -{ -} +HybridBinarizer::HybridBinarizer(const ImageView& iv) : GlobalHistogramBinarizer(iv) {} HybridBinarizer::~HybridBinarizer() = default; @@ -56,7 +45,7 @@ HybridBinarizer::~HybridBinarizer() = default; * See the following thread for a discussion of this algorithm: * http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0 */ -static Matrix CalculateBlackPoints(const uint8_t* luminances, int subWidth, int subHeight, int width, int height, int stride) +static Matrix CalculateBlackPoints(const uint8_t* luminances, int subWidth, int subHeight, int width, int height, int rowStride) { Matrix blackPoints(subWidth, subHeight); @@ -67,7 +56,7 @@ static Matrix CalculateBlackPoints(const uint8_t* luminances, int subWidth, int sum = 0; uint8_t min = 0xFF; uint8_t max = 0; - for (int yy = 0, offset = yoffset * stride + xoffset; yy < BLOCK_SIZE; yy++, offset += stride) { + for (int yy = 0, offset = yoffset * rowStride + xoffset; yy < BLOCK_SIZE; yy++, offset += rowStride) { for (int xx = 0; xx < BLOCK_SIZE; xx++) { auto pixel = luminances[offset + xx]; sum += pixel; @@ -77,7 +66,7 @@ static Matrix CalculateBlackPoints(const uint8_t* luminances, int subWidth, // short-circuit min/max tests once dynamic range is met if (max - min > MIN_DYNAMIC_RANGE) { // finish the rest of the rows quickly - for (yy++, offset += stride; yy < BLOCK_SIZE; yy++, offset += stride) { + for (yy++, offset += rowStride; yy < BLOCK_SIZE; yy++, offset += rowStride) { for (int xx = 0; xx < BLOCK_SIZE; xx++) { sum += luminances[offset + xx]; } @@ -121,17 +110,17 @@ static Matrix CalculateBlackPoints(const uint8_t* luminances, int subWidth, /** * Applies a single threshold to a block of pixels. */ -static void ThresholdBlock(const uint8_t* luminances, int xoffset, int yoffset, int threshold, int stride, BitMatrix& matrix) +static void ThresholdBlock(const uint8_t* luminances, int xoffset, int yoffset, int threshold, int rowStride, BitMatrix& matrix) { #ifdef ZX_FAST_BIT_STORAGE for (int y = yoffset; y < yoffset + BLOCK_SIZE; ++y) { - auto* src = luminances + y * stride + xoffset; + auto* src = luminances + y * rowStride + xoffset; auto* const dstBegin = matrix.row(y).begin() + xoffset; for (auto* dst = dstBegin; dst < dstBegin + BLOCK_SIZE; ++dst, ++src) *dst = *src <= threshold; } #else - for (int y = 0, offset = yoffset * stride + xoffset; y < BLOCK_SIZE; y++, offset += stride) { + for (int y = 0, offset = yoffset * rowStride + xoffset; y < BLOCK_SIZE; y++, offset += rowStride) { for (int x = 0; x < BLOCK_SIZE; x++) { // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0. if (luminances[offset + x] <= threshold) { @@ -147,9 +136,11 @@ static void ThresholdBlock(const uint8_t* luminances, int xoffset, int yoffset, * of the blocks around it. Also handles the corner cases (fractional blocks are computed based * on the last pixels in the row/column which are also used in the previous block). */ -static void CalculateThresholdForBlock(const uint8_t* luminances, int subWidth, int subHeight, int width, int height, - int stride, const Matrix& blackPoints, BitMatrix& matrix) +static std::shared_ptr CalculateMatrix(const uint8_t* luminances, int subWidth, int subHeight, int width, + int height, int rowStride, const Matrix& blackPoints) { + auto matrix = std::make_shared(width, height); + for (int y = 0; y < subHeight; y++) { int yoffset = std::min(y * BLOCK_SIZE, height - BLOCK_SIZE); for (int x = 0; x < subWidth; x++) { @@ -163,52 +154,27 @@ static void CalculateThresholdForBlock(const uint8_t* luminances, int subWidth, } } int average = sum / 25; - ThresholdBlock(luminances, xoffset, yoffset, average, stride, matrix); + ThresholdBlock(luminances, xoffset, yoffset, average, rowStride, *matrix); } } -} - -/** -* Calculates the final BitMatrix once for all requests. This could be called once from the -* constructor instead, but there are some advantages to doing it lazily, such as making -* profiling easier, and not doing heavy lifting when callers don't expect it. -*/ -static void InitBlackMatrix(const LuminanceSource& source, std::shared_ptr& outMatrix) -{ - int width = source.width(); - int height = source.height(); - ByteArray buffer; - int stride; - const uint8_t* luminances = source.getMatrix(buffer, stride); - int subWidth = (width + BLOCK_SIZE - 1) / BLOCK_SIZE; // ceil(width/BS) - int subHeight = (height + BLOCK_SIZE - 1) / BLOCK_SIZE; // ceil(height/BS) - auto blackPoints = CalculateBlackPoints(luminances, subWidth, subHeight, width, height, stride); - - auto matrix = std::make_shared(width, height); - CalculateThresholdForBlock(luminances, subWidth, subHeight, width, height, stride, blackPoints, *matrix); - outMatrix = std::move(matrix); + return matrix; } -std::shared_ptr -HybridBinarizer::getBlackMatrix() const +std::shared_ptr HybridBinarizer::getBlackMatrix() const { - int width = _source->width(); - int height = _source->height(); - if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) { - std::call_once(_cache->once, &InitBlackMatrix, std::cref(*_source), std::ref(_cache->matrix)); - return _cache->matrix; - } - else { + if (width() >= MINIMUM_DIMENSION && height() >= MINIMUM_DIMENSION) { + const uint8_t* luminances = _buffer.data(0, 0); + int subWidth = (width() + BLOCK_SIZE - 1) / BLOCK_SIZE; // ceil(width/BS) + int subHeight = (height() + BLOCK_SIZE - 1) / BLOCK_SIZE; // ceil(height/BS) + auto blackPoints = + CalculateBlackPoints(luminances, subWidth, subHeight, width(), height(), _buffer.rowStride()); + + return CalculateMatrix(luminances, subWidth, subHeight, width(), height(), _buffer.rowStride(), blackPoints); + } else { // If the image is too small, fall back to the global histogram approach. return GlobalHistogramBinarizer::getBlackMatrix(); } } -std::shared_ptr -HybridBinarizer::newInstance(const std::shared_ptr& source) const -{ - return std::make_shared(source); -} - } // ZXing diff --git a/core/src/HybridBinarizer.h b/core/src/HybridBinarizer.h index dcee037428..53fd8851d8 100644 --- a/core/src/HybridBinarizer.h +++ b/core/src/HybridBinarizer.h @@ -18,8 +18,6 @@ #include "GlobalHistogramBinarizer.h" -#include - namespace ZXing { /** @@ -42,15 +40,10 @@ namespace ZXing { class HybridBinarizer : public GlobalHistogramBinarizer { public: - explicit HybridBinarizer(const std::shared_ptr& source); + explicit HybridBinarizer(const ImageView& iv); ~HybridBinarizer() override; std::shared_ptr getBlackMatrix() const override; - std::shared_ptr newInstance(const std::shared_ptr& source) const override; - -private: - struct DataCache; - std::unique_ptr _cache; }; } // ZXing diff --git a/core/src/ImageView.h b/core/src/ImageView.h new file mode 100644 index 0000000000..dd1deb74ab --- /dev/null +++ b/core/src/ImageView.h @@ -0,0 +1,100 @@ +#pragma once +/* +* Copyright 2019 Axel Waggershauser +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include + +namespace ZXing { + +enum class ImageFormat : uint32_t +{ + None = 0, + Lum = 0x01000000, + RGB = 0x03000102, + BGR = 0x03020100, + RGBX = 0x04000102, + XRGB = 0x04010203, + BGRX = 0x04020100, + XBGR = 0x04030201, +}; + +constexpr inline int PixStride(ImageFormat format) { return (static_cast(format) >> 3*8) & 0xFF; } +constexpr inline int RedIndex(ImageFormat format) { return (static_cast(format) >> 2*8) & 0xFF; } +constexpr inline int GreenIndex(ImageFormat format) { return (static_cast(format) >> 1*8) & 0xFF; } +constexpr inline int BlueIndex(ImageFormat format) { return (static_cast(format) >> 0*8) & 0xFF; } + +/** + * Simple class that stores a non-owning const pointer to image data plus layout and format information. + */ +class ImageView +{ +protected: + const uint8_t* _data = nullptr; + ImageFormat _format; + int _width = 0, _height = 0, _pixStride = 0, _rowStride = 0; + +// friend class ThresholdBinarizer; +// friend class GlobalHistogramBinarizer; +// friend class HybridBinarizer; +// friend class BinaryBitmap; + +public: + /** + * ImageView contructor + * + * @param data pointer to image buffer + * @param width image width in pixels + * @param height image height in pixels + * @param format image/pixel format + * @param rowStride optional row stride in bytes, default is width * pixStride + * @param pixStride optional pixel stride in bytes, default is calculated from format + */ + ImageView(const uint8_t* data, int width, int height, ImageFormat format, int rowStride = 0, int pixStride = 0) + : _data(data), _format(format), _width(width), _height(height), + _pixStride(pixStride ? pixStride : PixStride(format)), _rowStride(rowStride ? rowStride : width * _pixStride) + {} + + int width() const { return _width; } + int height() const { return _height; } + int pixStride() const { return _pixStride; } + int rowStride() const { return _rowStride; } + ImageFormat format() const { return _format; } + + const uint8_t* data(int x, int y) const { return _data + y * _rowStride + x * _pixStride; } + + ImageView cropped(int left, int top, int width, int height) const + { + left = std::max(0, left); + top = std::max(0, top); + width = width <= 0 ? (_width - left) : std::min(_width - left, width); + height = height <= 0 ? (_height - top) : std::min(_height - top, height); + return {data(left, top), width, height, _format, _rowStride, _pixStride}; + } + + ImageView rotated(int degree) const + { + switch ((degree + 360) % 360) { + case 90: return {data(0, _height - 1), _height, _width, _format, _pixStride, -_rowStride}; + case 180: return {data(_width - 1, _height - 1), _width, _height, _format, -_rowStride, -_pixStride}; + case 270: return {data(_width - 1, 0), _height, _width, _format, -_pixStride, _rowStride}; + } + return *this; + } +}; + +} // ZXing + diff --git a/core/src/LuminanceSource.cpp b/core/src/LuminanceSource.cpp deleted file mode 100644 index d80d51efcd..0000000000 --- a/core/src/LuminanceSource.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "LuminanceSource.h" - -#include "ByteArray.h" - -#include -#include -#include - -namespace ZXing { - -namespace { - -/** -* A wrapper implementation of {@link LuminanceSource} which inverts the luminances it returns -- black becomes -* white and vice versa, and each value becomes (255-value). -* -* @author Sean Owen -*/ -class InvertedLuminanceSource : public LuminanceSource -{ - std::shared_ptr _src; - -public: - explicit InvertedLuminanceSource(std::shared_ptr src) : _src(std::move(src)) {} - - const uint8_t* getRow(int y, ByteArray& outBytes, bool) const override - { - _src->getRow(y, outBytes, true); - std::transform(outBytes.begin(), outBytes.end(), outBytes.begin(), [](uint8_t b) { return 255 - b; }); - return outBytes.data(); - } - - const uint8_t* getMatrix(ByteArray& outBytes, int& outRowBytes, bool) const override - { - _src->getMatrix(outBytes, outRowBytes, true); - std::transform(outBytes.begin(), outBytes.end(), outBytes.begin(), [](uint8_t b) { return 255 - b; }); - return outBytes.data(); - } - - int width() const override - { - return _src->width(); - } - - /** - * @return The height of the bitmap. - */ - int height() const override - { - return _src->height(); - } - - bool canCrop() const override - { - return _src->canCrop(); - } - - std::shared_ptr cropped(int left, int top, int width, int height) const override - { - return CreateInverted(_src->cropped(left, top, width, height)); - } - - bool canRotate() const override - { - return _src->canRotate(); - } - - std::shared_ptr rotated(int degreeCW) const override - { - return CreateInverted(_src->rotated(degreeCW)); - } - -protected: - std::shared_ptr getInverted() const override - { - return _src; - } - -}; // InvertedLuminanceSource - -} // anonymous - - -bool -LuminanceSource::canCrop() const -{ - return false; -} - -std::shared_ptr -LuminanceSource::cropped(int, int, int, int) const -{ - throw std::runtime_error("This luminance source does not support cropping."); -} - -bool -LuminanceSource::canRotate() const -{ - return false; -} - -/** -* Returns a new object with rotated image data by 90 degrees counterclockwise. -* Only callable if {@link #isRotateSupported()} is true. -* -* @return A rotated version of this object. -*/ -std::shared_ptr -LuminanceSource::rotated(int) const -{ - throw std::runtime_error("This luminance source does not support rotation by 90 degrees."); -} - -std::shared_ptr -LuminanceSource::getInverted() const -{ - return nullptr; -} - -std::shared_ptr -LuminanceSource::CreateInverted(const std::shared_ptr& src) -{ - auto result = src->getInverted(); - if (result == nullptr) - result = std::make_shared(src); - return result; -} - -} // ZXing diff --git a/core/src/LuminanceSource.h b/core/src/LuminanceSource.h deleted file mode 100644 index 8f7b2bf769..0000000000 --- a/core/src/LuminanceSource.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include - -namespace ZXing { - -class ByteArray; - -/** -* The purpose of this class hierarchy is to abstract different bitmap implementations across -* platforms into a standard interface for requesting greyscale luminance values. The interface -* only provides immutable methods; therefore crop and rotation create copies. This is to ensure -* that one Reader does not modify the original luminance source and leave it in an unknown state -* for other Readers in the chain. -* -* @author dswitkin@google.com (Daniel Switkin) -*/ -class LuminanceSource -{ -public: - virtual ~LuminanceSource() = default; - - /** - * @return The width of the bitmap. - */ - virtual int width() const = 0; - - /** - * @return The height of the bitmap. - */ - virtual int height() const = 0; - - /** - * Fetches one row of luminance data from the underlying platform's bitmap. Values range from - * 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have - * to bitwise and with 0xff for each value. It is preferable for implementations of this method - * to only fetch this row rather than the whole image, since no 2D Readers may be installed and - * getMatrix() may never be called. - * - * @param y The row to fetch, which must be in [0,getHeight()) - * @param row An optional preallocated array. If null or too small, it will be ignored. - * Always use the returned object, and ignore the .length of the array. - * @return An array containing the luminance data. - */ - virtual const uint8_t* getRow(int y, ByteArray& buffer, bool forceCopy = false) const = 0; - - /** - * Fetches luminance data for the underlying bitmap. Values should be fetched using: - * {@code int luminance = array[y * width + x] & 0xff} - * - * @return A row-major 2D array of luminance values. Do not use result.length as it may be - * larger than width * height bytes on some platforms. Do not modify the contents - * of the result. - */ - virtual const uint8_t* getMatrix(ByteArray& buffer, int& outRowBytes, bool forceCopy = false) const = 0; - - /** - * @return Whether this subclass supports cropping. - */ - virtual bool canCrop() const; - - /** - * Returns a new object with cropped image data. Implementations may keep a reference to the - * original data rather than a copy. Only callable if isCropSupported() is true. - * - * @param left The left coordinate, which must be in [0,getWidth()) - * @param top The top coordinate, which must be in [0,getHeight()) - * @param width The width of the rectangle to crop. - * @param height The height of the rectangle to crop. - * @return A cropped version of this object. - */ - virtual std::shared_ptr cropped(int left, int top, int width, int height) const; - - /** - * @return Whether this subclass supports counter-clockwise rotation. - */ - virtual bool canRotate() const; - - /** - * Returns a new object with rotated image data by 90 degrees counterclockwise. - * Only callable if {@link #isRotateSupported()} is true. - * - * @return A rotated version of this object. - */ - virtual std::shared_ptr rotated(int degreeCW) const; - - /** - * @return a wrapper of this {@code LuminanceSource} which inverts the luminances it returns -- black becomes - * white and vice versa, and each value becomes (255-value). - */ - static std::shared_ptr CreateInverted(const std::shared_ptr& src); - -protected: - virtual std::shared_ptr getInverted() const; - -}; - -} // ZXing diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 67cfa03b4b..3c25862c1c 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -17,7 +17,6 @@ #include "ReadBarcode.h" #include "DecodeHints.h" -#include "GenericLuminanceSource.h" #include "GlobalHistogramBinarizer.h" #include "HybridBinarizer.h" #include "MultiFormatReader.h" @@ -27,38 +26,63 @@ namespace ZXing { -static Result ReadBarcode(GenericLuminanceSource&& source, const DecodeHints& hints) +class LumImage : public ImageView { - MultiFormatReader reader(hints); - auto srcPtr = std::shared_ptr(&source, [](void*) {}); + std::unique_ptr _memory; + LumImage(std::unique_ptr&& data, int w, int h) + : ImageView(data.get(), w, h, ImageFormat::Lum), _memory(std::move(data)) + {} - if (hints.binarizer() == Binarizer::LocalAverage) - return reader.read(HybridBinarizer(srcPtr)); - else - return reader.read(GlobalHistogramBinarizer(srcPtr)); +public: + LumImage() : ImageView(nullptr, 0, 0, ImageFormat::Lum) {} + LumImage(int w, int h) : LumImage(std::make_unique(w * h), w, h) {} + + uint8_t* data() { return _memory.get(); } +}; + +static uint8_t RGBToGray(unsigned r, unsigned g, unsigned b) +{ + // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC), + // (306*R) >> 10 is approximately equal to R*0.299, and so on. + // 0x200 >> 10 is 0.5, it implements rounding. + return static_cast((306 * r + 601 * g + 117 * b + 0x200) >> 10); } -Result ReadBarcode(const ImageView& iv, const DecodeHints& hints) +template +static LumImage ExtractLum(const ImageView& iv, P projection) { + LumImage res(iv.width(), iv.height()); + + auto* dst = res.data(); + for(int y = 0; y < iv.height(); ++y) + for(int x = 0; x < iv.width(); ++x) + *dst++ = projection(iv.data(x, y)); + + return res; +} + +Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) +{ + LumImage lum; + ImageView iv = _iv; + + if (hints.binarizer() == Binarizer::GlobalHistogram || hints.binarizer() == Binarizer::LocalAverage) { + if (iv.format() != ImageFormat::Lum) { + lum = ExtractLum(iv, [r = RedIndex(iv.format()), g = GreenIndex(iv.format()), b = BlueIndex(iv.format())]( + const uint8_t* src) { return RGBToGray(src[r], src[g], src[b]); }); + } else if (iv.pixStride() != 1) { + // GlobalHistogram and LocalAverage need dense line memory layout + lum = ExtractLum(iv, [](const uint8_t* src) { return *src; }); + } + if (lum.data()) + iv = lum; + } + switch (hints.binarizer()) { case Binarizer::BoolCast: return MultiFormatReader(hints).read(ThresholdBinarizer(iv, 0)); case Binarizer::FixedThreshold: return MultiFormatReader(hints).read(ThresholdBinarizer(iv, 127)); - default: - return ReadBarcode( - { - 0, - 0, - iv._width, - iv._height, - iv._data, - iv._rowStride, - iv._pixStride, - RedIndex(iv._format), - GreenIndex(iv._format), - BlueIndex(iv._format), - nullptr - }, - hints); + case Binarizer::GlobalHistogram: return MultiFormatReader(hints).read(GlobalHistogramBinarizer(iv)); + case Binarizer::LocalAverage: return MultiFormatReader(hints).read(HybridBinarizer(iv)); } } diff --git a/core/src/ReadBarcode.h b/core/src/ReadBarcode.h index 901c78d37e..93e0ec938c 100644 --- a/core/src/ReadBarcode.h +++ b/core/src/ReadBarcode.h @@ -16,80 +16,11 @@ */ #include "DecodeHints.h" +#include "ImageView.h" #include "Result.h" -#include - namespace ZXing { -enum class ImageFormat : uint32_t -{ - None = 0, - Lum = 0x01000000, - RGB = 0x03000102, - BGR = 0x03020100, - RGBX = 0x04000102, - XRGB = 0x04010203, - BGRX = 0x04020100, - XBGR = 0x04030201, -}; - -constexpr inline int PixStride(ImageFormat format) { return (static_cast(format) >> 3*8) & 0xFF; } -constexpr inline int RedIndex(ImageFormat format) { return (static_cast(format) >> 2*8) & 0xFF; } -constexpr inline int GreenIndex(ImageFormat format) { return (static_cast(format) >> 1*8) & 0xFF; } -constexpr inline int BlueIndex(ImageFormat format) { return (static_cast(format) >> 0*8) & 0xFF; } - -/** - * Simple class that stores a non-owning const pointer to image data plus layout and format information. - */ -class ImageView -{ -protected: - const uint8_t* _data = nullptr; - ImageFormat _format; - int _width = 0, _height = 0, _pixStride = 0, _rowStride = 0; - - friend Result ReadBarcode(const ImageView&, const DecodeHints&); - friend class ThresholdBinarizer; - -public: - /** - * ImageView contructor - * - * @param data pointer to image buffer - * @param width image width in pixels - * @param height image height in pixels - * @param format image/pixel format - * @param rowStride optional row stride in bytes, default is width * pixStride - * @param pixStride optional pixel stride in bytes, default is calculated from format - */ - ImageView(const uint8_t* data, int width, int height, ImageFormat format, int rowStride = 0, int pixStride = 0) - : _data(data), _format(format), _width(width), _height(height), - _pixStride(pixStride ? pixStride : PixStride(format)), _rowStride(rowStride ? rowStride : width * _pixStride) - {} - - const uint8_t* data(int x, int y) const { return _data + y * _rowStride + x * _pixStride; } - - ImageView cropped(int left, int top, int width, int height) const - { - left = std::max(0, left); - top = std::max(0, top); - width = width <= 0 ? (_width - left) : std::min(_width - left, width); - height = height <= 0 ? (_height - top) : std::min(_height - top, height); - return {data(left, top), width, height, _format, _rowStride, _pixStride}; - } - - ImageView rotated(int degree) const - { - switch ((degree + 360) % 360) { - case 90: return {data(0, _height - 1), _height, _width, _format, _pixStride, -_rowStride}; - case 180: return {data(_width - 1, _height - 1), _width, _height, _format, -_rowStride, -_pixStride}; - case 270: return {data(_width - 1, 0), _height, _width, _format, -_pixStride, _rowStride}; - } - return *this; - } -}; - /** * Read barcode from an ImageView * diff --git a/core/src/ThresholdBinarizer.h b/core/src/ThresholdBinarizer.h index 51411082a1..32d27f96b1 100644 --- a/core/src/ThresholdBinarizer.h +++ b/core/src/ThresholdBinarizer.h @@ -17,32 +17,25 @@ #include "BinaryBitmap.h" #include "BitMatrix.h" -#include "ReadBarcode.h" #include -#include namespace ZXing { -class LuminanceSource; - class ThresholdBinarizer : public BinaryBitmap { - const ImageView _buffer; const uint8_t _threshold = 0; - mutable std::shared_ptr _cache; public: - ThresholdBinarizer(const ImageView& buffer, uint8_t threshold = 1) : _buffer(buffer), _threshold(threshold) {} - - int width() const override { return _buffer._width; } - int height() const override { return _buffer._height; } + ThresholdBinarizer(const ImageView& buffer, uint8_t threshold = 1) : BinaryBitmap(buffer), _threshold(threshold) {} - bool getPatternRow(int y, PatternRow& res) const override + bool getPatternRow(int row, int rotation, PatternRow& res) const override { - const int stride = _buffer._pixStride; - const uint8_t* begin = _buffer.data(0, y) + GreenIndex(_buffer._format); - const uint8_t* end = begin + _buffer._width * stride; + auto buffer = _buffer.rotated(rotation); + + const int stride = buffer.pixStride(); + const uint8_t* begin = buffer.data(0, row) + GreenIndex(buffer.format()); + const uint8_t* end = begin + buffer.width() * stride; auto* lastPos = begin; bool lastVal = false; @@ -66,40 +59,37 @@ class ThresholdBinarizer : public BinaryBitmap std::shared_ptr getBlackMatrix() const override { - if (!_cache) { - BitMatrix res(width(), height()); + BitMatrix res(width(), height()); #ifdef ZX_FAST_BIT_STORAGE - if (_buffer._pixStride == 1 && _buffer._rowStride == _buffer._width) { - // Specialize for a packed buffer with pixStride 1 to support auto vectorization (16x speedup on AVX2) - auto dst = res.row(0).begin(); - for (auto src = _buffer.data(0, 0), end = _buffer.data(0, height()); src != end; ++src, ++dst) - *dst = *src <= _threshold; - } else { - auto processLine = [this, &res](int y, const auto* src, const int stride) { - for (auto& dst : res.row(y)) { - dst = *src <= _threshold; - src += stride; - } - }; - for (int y = 0; y < res.height(); ++y) { - auto src = _buffer.data(0, y) + GreenIndex(_buffer._format); - // Specialize the inner loop for strides 1 and 4 to support auto vectorization - switch (_buffer._pixStride) { - case 1: processLine(y, src, 1); break; - case 4: processLine(y, src, 4); break; - default: processLine(y, src, _buffer._pixStride); break; - } + if (_buffer.pixStride() == 1 && _buffer.rowStride() == _buffer.width()) { + // Specialize for a packed buffer with pixStride 1 to support auto vectorization (16x speedup on AVX2) + auto dst = res.row(0).begin(); + for (auto src = _buffer.data(0, 0), end = _buffer.data(0, height()); src != end; ++src, ++dst) + *dst = *src <= _threshold; + } else { + auto processLine = [this, &res](int y, const auto* src, const int stride) { + for (auto& dst : res.row(y)) { + dst = *src <= _threshold; + src += stride; + } + }; + for (int y = 0; y < res.height(); ++y) { + auto src = _buffer.data(0, y) + GreenIndex(_buffer.format()); + // Specialize the inner loop for strides 1 and 4 to support auto vectorization + switch (_buffer.pixStride()) { + case 1: processLine(y, src, 1); break; + case 4: processLine(y, src, 4); break; + default: processLine(y, src, _buffer.pixStride()); break; } } + } #else - const int channel = GreenIndex(_buffer._format); - for (int y = 0; y < res.height(); ++y) - for (int x = 0; x < res.width(); ++x) - res.set(x, y, _buffer.data(x, y)[channel] <= _threshold); + const int channel = GreenIndex(_buffer.format()); + for (int y = 0; y < res.height(); ++y) + for (int x = 0; x < res.width(); ++x) + res.set(x, y, _buffer.data(x, y)[channel] <= _threshold); #endif - _cache = std::make_shared(std::move(res)); - } - return _cache; + return std::make_shared(std::move(res)); } }; diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 287e26d134..4091f30dac 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -38,7 +38,7 @@ Reader::Reader(const DecodeHints& hints) Result Reader::decode(const BinaryBitmap& image) const { - auto binImg = image.getBlackMatrix(); + auto binImg = image.getBitMatrix(); if (binImg == nullptr) { return Result(DecodeStatus::NotFound); } diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index ee02ec408d..d134f778bb 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -46,7 +46,7 @@ Reader::Reader(const DecodeHints& hints) Result Reader::decode(const BinaryBitmap& image) const { - auto binImg = image.getBlackMatrix(); + auto binImg = image.getBitMatrix(); if (binImg == nullptr) { return Result(DecodeStatus::NotFound); } diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index 6d464010f2..36c5a53607 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -59,7 +59,7 @@ Reader::Reader(const DecodeHints& hints) : _isPure(hints.isPure()), _characterSe Result Reader::decode(const BinaryBitmap& image) const { - auto binImg = image.getBlackMatrix(); + auto binImg = image.getBitMatrix(); if (binImg == nullptr) { return Result(DecodeStatus::NotFound); } diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 3bdd923361..a278312387 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -73,20 +73,18 @@ Reader::~Reader() = default; * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the * image if "trying harder". -* -* @param image The image to decode -* @param hints Any hints that were requested -* @return The contents of the decoded barcode -* @throws NotFoundException Any spontaneous errors which occur */ -static Result -DoDecode(const std::vector>& readers, const BinaryBitmap& image, bool tryHarder, bool isPure) +static Result DoDecode(const std::vector>& readers, const BinaryBitmap& image, + bool tryHarder, bool rotate, bool isPure) { std::vector> decodingState(readers.size()); int width = image.width(); int height = image.height(); + if (rotate) + std::swap(width, height); + int middle = height / 2; int rowStep = std::max(1, height / (tryHarder ? 256 : 32)); int maxLines = tryHarder ? @@ -107,7 +105,7 @@ DoDecode(const std::vector>& readers, const BinaryBit break; } - if (!image.getPatternRow(rowNumber, bars)) + if (!image.getPatternRow(rowNumber, rotate ? 270 : 0, bars)) continue; // While we have the image data in a PatternRow, it's fairly cheap to reverse it in place to @@ -150,15 +148,14 @@ DoDecode(const std::vector>& readers, const BinaryBit Result Reader::decode(const BinaryBitmap& image) const { - Result result = DoDecode(_readers, image, _tryHarder, _isPure); + Result result = DoDecode(_readers, image, _tryHarder, false, _isPure); - if (!result.isValid() && _tryRotate && image.canRotate()) { - auto rotatedImage = image.rotated(270); - result = DoDecode(_readers, *rotatedImage, _tryHarder, _isPure); + if (!result.isValid() && _tryRotate) { + result = DoDecode(_readers, image, _tryHarder, true, _isPure); if (result.isValid()) { // Update position auto points = result.position(); - int height = rotatedImage->height(); + int height = image.width(); for (auto& p : points) { p = {height - p.y - 1, p.x}; } diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 11f8fa2b2b..4570d075b3 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -348,8 +348,10 @@ bool HasStartPattern(const BitMatrix& m) DecodeStatus Detector::Detect(const BinaryBitmap& image, bool multiple, Result& result) { - auto binImg = image.getBlackMatrix(); - if (binImg == nullptr) { + // construct a 'dummy' shared pointer, just be able to pass it up the call chain in DecodeStatus + // TODO: reimplement PDF Detector + auto binImg = std::shared_ptr(image.getBitMatrix(), [](const BitMatrix*){}); + if (!binImg) { return DecodeStatus::NotFound; } diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index bec478ebf9..93ed83d9e3 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -271,7 +271,7 @@ DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const st static Result DecodePure(const BinaryBitmap& image_, const std::string& characterSet) { - auto pimage = image_.getBlackMatrix(); + auto pimage = image_.getBitMatrix(); if (!pimage) return Result(DecodeStatus::NotFound); auto& image = *pimage; diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 208e1222b5..7e54648579 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -37,7 +37,7 @@ Reader::Reader(const DecodeHints& hints) Result Reader::decode(const BinaryBitmap& image) const { - auto binImg = image.getBlackMatrix(); + auto binImg = image.getBitMatrix(); if (binImg == nullptr) { return Result(DecodeStatus::NotFound); } diff --git a/thirdparty/stb/stb_image.h b/thirdparty/stb/stb_image.h index bf283b7bf7..ee8f61c95a 100644 --- a/thirdparty/stb/stb_image.h +++ b/thirdparty/stb/stb_image.h @@ -1646,7 +1646,7 @@ static stbi_uc stbi__compute_y(int r, int g, int b) { #if 0 // ori return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); -#else // zxing (see GenericLuminanceSource.cpp:RGBToGray) +#else // zxing (see ReadBarcode.cpp:RGBToGray) return (stbi_uc) ((306 * r + 601 * g + 117 * b + 0x200) >> 10); #endif } From 293d4230f0c4bb0f5dba39dc38d081e3811a7dd4 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Mon, 19 Jul 2021 10:47:25 +0200 Subject: [PATCH 0008/1315] fuzzer: fix unnoticed build regression from RSS->DataBar renaming --- test/fuzz/fuzzDBEDecoder.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/fuzz/fuzzDBEDecoder.cpp b/test/fuzz/fuzzDBEDecoder.cpp index e9d624c93c..4a14761611 100644 --- a/test/fuzz/fuzzDBEDecoder.cpp +++ b/test/fuzz/fuzzDBEDecoder.cpp @@ -5,7 +5,6 @@ #include "oned/rss/ODRSSExpandedBinaryDecoder.h" using namespace ZXing; -using namespace ZXing::OneD::RSS; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -16,7 +15,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) for (size_t i = 0; i < size; ++i) bits.appendBits(data[i], 8); - ExpandedBinaryDecoder::Decode(bits); + OneD::DataBar::DecodeExpandedBits(bits); return 0; } From ca4b3c27296b2f343b3c7db14ce833d6c705228c Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 20 Jul 2021 14:21:53 +0200 Subject: [PATCH 0009/1315] [[deprecated]]: fix regression with rotated 1D symbols (uint_16 overflow) --- core/src/GlobalHistogramBinarizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/GlobalHistogramBinarizer.cpp b/core/src/GlobalHistogramBinarizer.cpp index 2b25ac629c..59ad786b43 100644 --- a/core/src/GlobalHistogramBinarizer.cpp +++ b/core/src/GlobalHistogramBinarizer.cpp @@ -110,7 +110,7 @@ bool GlobalHistogramBinarizer::getPatternRow(int row, int rotation, PatternRow& auto process = [&](bool val, const uint8_t* p) { if (val != lastVal) { - res.push_back(static_cast(p - lastPos) / pixStride); + res.push_back(static_cast((p - lastPos) / pixStride)); lastVal = val; lastPos = p; } From a5895c596bd32045181745e91ab7d1339cefdfb9 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 20 Jul 2021 14:36:04 +0200 Subject: [PATCH 0010/1315] OneD: scan the whole line, not only until the first of the left-guard If a line contained a valid symbol after a truncated (invalid) one, it would never detect the valid symbol. This fixes this limitation. This fixes #220 and finds 2 more existing black-box samples. It also prepares #138. --- core/src/Pattern.h | 2 +- core/src/oned/ODCodabarReader.cpp | 4 ++-- core/src/oned/ODCodabarReader.h | 2 +- core/src/oned/ODCode128Reader.cpp | 4 ++-- core/src/oned/ODCode128Reader.h | 2 +- core/src/oned/ODCode39Reader.cpp | 4 ++-- core/src/oned/ODCode39Reader.h | 2 +- core/src/oned/ODCode93Reader.cpp | 4 ++-- core/src/oned/ODCode93Reader.h | 2 +- core/src/oned/ODDataBarExpandedReader.cpp | 13 ++++++----- core/src/oned/ODDataBarExpandedReader.h | 2 +- core/src/oned/ODDataBarReader.cpp | 9 +++++--- core/src/oned/ODDataBarReader.h | 2 +- core/src/oned/ODITFReader.cpp | 6 ++--- core/src/oned/ODITFReader.h | 2 +- core/src/oned/ODMultiUPCEANReader.cpp | 9 +++++--- core/src/oned/ODMultiUPCEANReader.h | 2 +- core/src/oned/ODReader.cpp | 26 +++++++++++++--------- core/src/oned/ODRowReader.cpp | 3 ++- core/src/oned/ODRowReader.h | 2 +- test/blackbox/BlackboxTestRunner.cpp | 14 ++++++------ test/samples/itf-1/#220.png | Bin 0 -> 314 bytes test/samples/itf-1/#220.txt | 1 + test/unit/oned/ODCode128ReaderTest.cpp | 3 ++- 24 files changed, 68 insertions(+), 52 deletions(-) create mode 100644 test/samples/itf-1/#220.png create mode 100644 test/samples/itf-1/#220.txt diff --git a/core/src/Pattern.h b/core/src/Pattern.h index ce1cfda8c8..c317be3e57 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -124,7 +124,7 @@ class PatternView void extend() { - _size = static_cast(_end - _data); + _size = std::max(0, static_cast(_end - _data)); } }; diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index b81978de06..d528d043e4 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -62,7 +62,7 @@ bool IsLeftGuard(const PatternView& view, int spaceInPixel) } Result -CodabarReader::decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const +CodabarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { // minimal number of characters that must be present (including start, stop and checksum characters) // absolute minimum would be 2 (meaning 0 'content'). everything below 4 produces too many false @@ -70,7 +70,7 @@ CodabarReader::decodePattern(int rowNumber, const PatternView& row, std::unique_ const int minCharCount = 4; auto isStartOrStopSymbol = [](char c) { return 'A' <= c && c <= 'D'; }; - auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, IsLeftGuard); + next = FindLeftGuard(next, minCharCount * CHAR_LEN, IsLeftGuard); if (!next.isValid()) return Result(DecodeStatus::NotFound); diff --git a/core/src/oned/ODCodabarReader.h b/core/src/oned/ODCodabarReader.h index b004c5064c..69945c3d6d 100644 --- a/core/src/oned/ODCodabarReader.h +++ b/core/src/oned/ODCodabarReader.h @@ -34,7 +34,7 @@ class CodabarReader : public RowReader { public: explicit CodabarReader(const DecodeHints& hints); - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr& state) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const override; private: bool _returnStartEnd; diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index 5af91d0455..5f8038f4e1 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -214,7 +214,7 @@ constexpr int CHARACTER_ENCODINGS[] = { }; #endif -Result Code128Reader::decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const +Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { int minCharCount = 4; // start + payload + checksum + stop auto decodePattern = [](const PatternView& view, bool start = false) { @@ -229,7 +229,7 @@ Result Code128Reader::decodePattern(int rowNumber, const PatternView& row, std:: #endif }; - auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, START_PATTERN_PREFIX, QUIET_ZONE); + next = FindLeftGuard(next, minCharCount * CHAR_LEN, START_PATTERN_PREFIX, QUIET_ZONE); if (!next.isValid()) return Result(DecodeStatus::NotFound); diff --git a/core/src/oned/ODCode128Reader.h b/core/src/oned/ODCode128Reader.h index 624784641b..6116f13dfe 100644 --- a/core/src/oned/ODCode128Reader.h +++ b/core/src/oned/ODCode128Reader.h @@ -33,7 +33,7 @@ class Code128Reader : public RowReader { public: explicit Code128Reader(const DecodeHints& hints); - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; private: bool _convertFNC1; diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index 9cea7bdbf3..d4bde47b4f 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -92,7 +92,7 @@ Code39Reader::Code39Reader(const DecodeHints& hints) : { } -Result Code39Reader::decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const +Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { // minimal number of characters that must be present (including start, stop and checksum characters) int minCharCount = _usingCheckDigit ? 4 : 3; @@ -103,7 +103,7 @@ Result Code39Reader::decodePattern(int rowNumber, const PatternView& row, std::u // quiet zone is half the width of a character symbol constexpr float QUIET_ZONE_SCALE = 0.5f; - auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, START_PATTERN, QUIET_ZONE_SCALE * 12); + next = FindLeftGuard(next, minCharCount * CHAR_LEN, START_PATTERN, QUIET_ZONE_SCALE * 12); if (!next.isValid()) return Result(DecodeStatus::NotFound); diff --git a/core/src/oned/ODCode39Reader.h b/core/src/oned/ODCode39Reader.h index c6a53448d3..0573f756fb 100644 --- a/core/src/oned/ODCode39Reader.h +++ b/core/src/oned/ODCode39Reader.h @@ -45,7 +45,7 @@ class Code39Reader : public RowReader */ explicit Code39Reader(const DecodeHints& hints); - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; private: bool _extendedMode; diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index 8a36775944..22298f8972 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -91,12 +91,12 @@ static bool IsStartGuard(const PatternView& window, int spaceInPixel) RowReader::OneToFourBitPattern(window) == ASTERISK_ENCODING; } -Result Code93Reader::decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const +Result Code93Reader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { // minimal number of characters that must be present (including start, stop, checksum and 1 payload characters) int minCharCount = 5; - auto next = FindLeftGuard(row, minCharCount * CHAR_LEN, IsStartGuard); + next = FindLeftGuard(next, minCharCount * CHAR_LEN, IsStartGuard); if (!next.isValid()) return Result(DecodeStatus::NotFound); diff --git a/core/src/oned/ODCode93Reader.h b/core/src/oned/ODCode93Reader.h index 9455019a90..95a385e0ad 100644 --- a/core/src/oned/ODCode93Reader.h +++ b/core/src/oned/ODCode93Reader.h @@ -30,7 +30,7 @@ namespace OneD { class Code93Reader : public RowReader { public: - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; }; } // OneD diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 3bf1683c09..3db777b30d 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -201,16 +201,15 @@ static Pair ReadPair(const PatternView& view, Direction dir) } template -static Pairs ReadRowOfPairs(const PatternView& view, int rowNumber) +static Pairs ReadRowOfPairs(PatternView& next, int rowNumber) { Pairs pairs; Pair pair; - PatternView next; if constexpr (STACKED) { // a possible first pair is either left2right starting on a space or right2left starting on a bar. // it might be a half-pair - next = view.subView(0, HALF_PAIR_SIZE); + next = next.subView(0, HALF_PAIR_SIZE); while (next.shift(1)) { if (IsL2RPair(next) && (pair = ReadPair(next, Direction::Right)) && (pair.finder != FINDER_A || IsGuard(next[-1], next[11]))) @@ -221,7 +220,7 @@ static Pairs ReadRowOfPairs(const PatternView& view, int rowNumber) } else { // the only possible first pair is a full, left2right FINDER_A pair starting on a space // with a guard bar on the left - next = view.subView(-1, FULL_PAIR_SIZE); + next = next.subView(-1, FULL_PAIR_SIZE); while (next.shift(2)) { if (IsL2RPair(next) && IsGuard(next[-1], next[11]) && (pair = ReadPair(next, Direction::Right)).finder == FINDER_A) @@ -231,8 +230,10 @@ static Pairs ReadRowOfPairs(const PatternView& view, int rowNumber) next = next.subView(0, HALF_PAIR_SIZE); } - if (!pair) + if (!pair) { + next = {}; // if we didn't find a single pair, consume the rest of the row return {}; + } auto flippedDir = [](Pair p) { return p.finder < 0 ? Direction::Right : Direction::Left; }; auto isValidPair = [](Pair p, PatternView v) { return p.right || IsGuard(v[p.finder < 0 ? 9 : 11], v[13]); }; @@ -333,7 +334,7 @@ struct DBERState : public RowReader::DecodingState PairMap allPairs; }; -Result DataBarExpandedReader::decodePattern(int rowNumber, const PatternView& view, +Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, std::unique_ptr& state) const { #if 0 // non-stacked version diff --git a/core/src/oned/ODDataBarExpandedReader.h b/core/src/oned/ODDataBarExpandedReader.h index bbc93411df..a2e9a306d6 100644 --- a/core/src/oned/ODDataBarExpandedReader.h +++ b/core/src/oned/ODDataBarExpandedReader.h @@ -33,7 +33,7 @@ class DataBarExpandedReader : public RowReader explicit DataBarExpandedReader(const DecodeHints& hints); ~DataBarExpandedReader() override; - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr& state) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const override; }; } // OneD diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index 3be9fe5b38..ab0f276a72 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -163,11 +163,11 @@ struct State : public RowReader::DecodingState std::unordered_set rightPairs; }; -Result DataBarReader::decodePattern(int rowNumber, const PatternView& view, +Result DataBarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const { #if 0 // non-stacked version - auto next = view.subView(-1, FULL_PAIR_SIZE + 2); + next = next.subView(-1, FULL_PAIR_SIZE + 2); // yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern) while (next.shift(2)) { if (IsLeftPair(next)) { @@ -184,7 +184,7 @@ Result DataBarReader::decodePattern(int rowNumber, const PatternView& view, state.reset(new State); auto* prevState = static_cast(state.get()); - auto next = view.subView(0, FULL_PAIR_SIZE + 2); // +2 reflects the guard pattern on the right + next = next.subView(0, FULL_PAIR_SIZE + 2); // +2 reflects the guard pattern on the right // yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern) while (next.shift(1)) { if (IsLeftPair(next)) { @@ -210,6 +210,9 @@ Result DataBarReader::decodePattern(int rowNumber, const PatternView& view, EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar}; #endif + // guaratee progress (see loop in ODReader.cpp) + next = {}; + return Result(DecodeStatus::NotFound); } diff --git a/core/src/oned/ODDataBarReader.h b/core/src/oned/ODDataBarReader.h index 1402b6991d..2da0109691 100644 --- a/core/src/oned/ODDataBarReader.h +++ b/core/src/oned/ODDataBarReader.h @@ -33,7 +33,7 @@ class DataBarReader : public RowReader explicit DataBarReader(const DecodeHints& hints); ~DataBarReader() override; - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr& state) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const override; }; } // OneD diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 5b1224952d..124a009a7d 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -40,12 +40,12 @@ constexpr auto START_PATTERN_ = FixedPattern<4, 4>{1, 1, 1, 1}; constexpr auto STOP_PATTERN_1 = FixedPattern<3, 4>{2, 1, 1}; constexpr auto STOP_PATTERN_2 = FixedPattern<3, 5>{3, 1, 1}; -Result ITFReader::decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const +Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { const int minCharCount = 6; const int minQuietZone = 10; - auto next = FindLeftGuard(row, 4 + minCharCount/2 + 3, START_PATTERN_, minQuietZone); + next = FindLeftGuard(next, 4 + minCharCount/2 + 3, START_PATTERN_, minQuietZone); if (!next.isValid()) return Result(DecodeStatus::NotFound); @@ -56,7 +56,7 @@ Result ITFReader::decodePattern(int rowNumber, const PatternView& row, std::uniq int xStart = next.pixelsInFront(); next = next.subView(4, 10); - while (next.index() < row.size() - (10 + 3)) { + while (next.isValid()) { const auto threshold = NarrowWideThreshold(next); if (!threshold.isValid()) break; diff --git a/core/src/oned/ODITFReader.h b/core/src/oned/ODITFReader.h index 45085b9eb6..b7a05be3cc 100644 --- a/core/src/oned/ODITFReader.h +++ b/core/src/oned/ODITFReader.h @@ -46,7 +46,7 @@ class ITFReader : public RowReader { public: explicit ITFReader(const DecodeHints& hints); - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; private: std::vector _allowedLengths; diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 136a724c92..0d8e8d825f 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -277,15 +277,16 @@ static bool AddOn(PartialResult& res, PatternView begin, int digitCount) return true; } -Result MultiUPCEANReader::decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const +Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { const int minSize = 3 + 6*4 + 6; // UPC-E - auto begin = FindLeftGuard(row, minSize, END_PATTERN, QUIET_ZONE_LEFT); - if (!begin.isValid()) + next = FindLeftGuard(next, minSize, END_PATTERN, QUIET_ZONE_LEFT); + if (!next.isValid()) return Result(DecodeStatus::NotFound); PartialResult res; + auto begin = next; if (!(((_hints.hasFormat(BarcodeFormat::EAN13 | BarcodeFormat::UPCA)) && EAN13(res, begin)) || (_hints.hasFormat(BarcodeFormat::EAN8) && EAN8(res, begin)) || @@ -312,6 +313,8 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, const PatternView& row, s res.txt += " " + addOnRes.txt; } + next = res.end; + if (_hints.eanAddOnSymbol() == EanAddOnSymbol::Require && !addOnRes.isValid()) return Result(DecodeStatus::NotFound); diff --git a/core/src/oned/ODMultiUPCEANReader.h b/core/src/oned/ODMultiUPCEANReader.h index 9fa6281f62..9d3154331e 100644 --- a/core/src/oned/ODMultiUPCEANReader.h +++ b/core/src/oned/ODMultiUPCEANReader.h @@ -36,7 +36,7 @@ class MultiUPCEANReader : public RowReader explicit MultiUPCEANReader(const DecodeHints& hints); ~MultiUPCEANReader() override; - Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr&) const override; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; private: bool _canReturnUPCA = false; diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index a278312387..6626e03cc6 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -123,18 +123,24 @@ static Result DoDecode(const std::vector>& readers, c } // Look for a barcode for (size_t r = 0; r < readers.size(); ++r) { - Result result = readers[r]->decodePattern(rowNumber, bars, decodingState[r]); - if (result.isValid()) { - if (upsideDown) { - // update position (flip horizontally). - auto points = result.position(); - for (auto& p : points) { - p = {width - p.x - 1, p.y}; + PatternView next(bars); + do { + Result result = readers[r]->decodePattern(rowNumber, next, decodingState[r]); + if (result.isValid()) { + if (upsideDown) { + // update position (flip horizontally). + auto points = result.position(); + for (auto& p : points) { + p = {width - p.x - 1, p.y}; + } + result.setPosition(std::move(points)); } - result.setPosition(std::move(points)); + return result; } - return result; - } + // make sure we make progress and we start the next try on a bar + next.shift(2 - (next.index() % 2)); + next.extend(); + } while (tryHarder && next.isValid()); } } diff --git a/core/src/oned/ODRowReader.cpp b/core/src/oned/ODRowReader.cpp index c3de5c5532..de0febc20e 100644 --- a/core/src/oned/ODRowReader.cpp +++ b/core/src/oned/ODRowReader.cpp @@ -39,7 +39,8 @@ Result RowReader::decodeSingleRow(int rowNumber, const BitArray& row) const if (*(i-1)) res.push_back(0); - return decodePattern(rowNumber, res, state); + PatternView view(res); + return decodePattern(rowNumber, view, state); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODRowReader.h b/core/src/oned/ODRowReader.h index ca12e55270..45fbcdef40 100644 --- a/core/src/oned/ODRowReader.h +++ b/core/src/oned/ODRowReader.h @@ -70,7 +70,7 @@ class RowReader virtual ~RowReader() {} - virtual Result decodePattern(int rowNumber, const PatternView& row, std::unique_ptr& state) const = 0; + virtual Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const = 0; /** * Determines how closely a set of observed counts of runs of black/white values matches a given diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 0df58ba4a4..168886adfb 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -384,8 +384,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("ean13-2", "EAN-13", 24, { - { 7, 13, 0 }, - { 7, 13, 180 }, + { 7, 14, 0 }, + { 7, 14, 180 }, }); runTests("ean13-3", "EAN-13", 21, { @@ -403,9 +403,9 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 3, 5, 180 }, }, DecodeHints().setEanAddOnSymbol(EanAddOnSymbol::Require)); - runTests("itf-1", "ITF", 10, { - { 10, 10, 0 }, - { 10, 10, 180 }, + runTests("itf-1", "ITF", 11, { + { 10, 11, 0 }, + { 10, 11, 180 }, }); runTests("itf-2", "ITF", 6, { @@ -427,8 +427,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("upca-2", "UPC-A", 36, { - { 17, 22, 0 }, - { 18, 22, 180 }, + { 17, 23, 0 }, + { 18, 23, 180 }, }); runTests("upca-3", "UPC-A", 21, { diff --git a/test/samples/itf-1/#220.png b/test/samples/itf-1/#220.png new file mode 100644 index 0000000000000000000000000000000000000000..67e8eda6ea980a363dd19923c011ff3c82767ca8 GIT binary patch literal 314 zcmV-A0mc4_P)B~x7Pt$G#T4JYP9)^?2vz state; DecodeHints hints; Code128Reader reader(hints); - return reader.decodePattern(0, row, state); + PatternView next(row); + return reader.decodePattern(0, next, state); } TEST(ODCode128ReaderTest, ReaderInit) From 79a21c037b199268430315933bc3d3993da2b7d1 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 20 Jul 2021 20:36:33 +0200 Subject: [PATCH 0011/1315] Multi-Barcode: initial (experimental) API and backend for 1D symbologies This partly implements the feature as discussed in #138. The detection of multiple (stacked) DataBar(Expanded) symbols is not supported. Next steps: * implement backend support for the individual 2D codes * get feedback on the top-level API choice --- core/src/MultiFormatReader.cpp | 13 ++++- core/src/MultiFormatReader.h | 5 ++ core/src/ReadBarcode.cpp | 27 +++++++-- core/src/ReadBarcode.h | 3 + core/src/Reader.h | 9 ++- core/src/Result.h | 7 +++ core/src/oned/ODReader.cpp | 52 ++++++++++------- core/src/oned/ODReader.h | 1 + example/ZXingReader.cpp | 93 ++++++++++++++++--------------- test/samples/multi-1/3xean-8.png | Bin 0 -> 364 bytes 10 files changed, 138 insertions(+), 72 deletions(-) create mode 100644 test/samples/multi-1/3xean-8.png diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 7418803c30..9b1e05efdc 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -19,7 +19,6 @@ #include "BarcodeFormat.h" #include "DecodeHints.h" -#include "Result.h" #include "aztec/AZReader.h" #include "datamatrix/DMReader.h" #include "maxicode/MCReader.h" @@ -75,4 +74,16 @@ MultiFormatReader::read(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); } +Results MultiFormatReader::readMultiple(const BinaryBitmap& image) const +{ + std::vector res; + + for (const auto& reader : _readers) { + auto r = reader->decode(image, 10); + res.insert(res.end(), r.begin(), r.end()); + } + + return res; +} + } // ZXing diff --git a/core/src/MultiFormatReader.h b/core/src/MultiFormatReader.h index 0da0a140d1..4532766666 100644 --- a/core/src/MultiFormatReader.h +++ b/core/src/MultiFormatReader.h @@ -16,6 +16,8 @@ * limitations under the License. */ +#include "Result.h" + #include #include @@ -42,6 +44,9 @@ class MultiFormatReader Result read(const BinaryBitmap& image) const; + // WARNING: this API is experimental and may change/disappear + Results readMultiple(const BinaryBitmap& image) const; + private: std::vector> _readers; }; diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 3c25862c1c..03907e7e11 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -61,11 +61,8 @@ static LumImage ExtractLum(const ImageView& iv, P projection) return res; } -Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) +ImageView SetupLumImageView(const ImageView& iv, LumImage& lum, const DecodeHints& hints) { - LumImage lum; - ImageView iv = _iv; - if (hints.binarizer() == Binarizer::GlobalHistogram || hints.binarizer() == Binarizer::LocalAverage) { if (iv.format() != ImageFormat::Lum) { lum = ExtractLum(iv, [r = RedIndex(iv.format()), g = GreenIndex(iv.format()), b = BlueIndex(iv.format())]( @@ -75,8 +72,15 @@ Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) lum = ExtractLum(iv, [](const uint8_t* src) { return *src; }); } if (lum.data()) - iv = lum; + return lum; } + return iv; +} + +Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) +{ + LumImage lum; + ImageView iv = SetupLumImageView(_iv, lum, hints); switch (hints.binarizer()) { case Binarizer::BoolCast: return MultiFormatReader(hints).read(ThresholdBinarizer(iv, 0)); @@ -86,4 +90,17 @@ Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) } } +Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) +{ + LumImage lum; + ImageView iv = SetupLumImageView(_iv, lum, hints); + + switch (hints.binarizer()) { + case Binarizer::BoolCast: return MultiFormatReader(hints).readMultiple(ThresholdBinarizer(iv, 0)); + case Binarizer::FixedThreshold: return MultiFormatReader(hints).readMultiple(ThresholdBinarizer(iv, 127)); + case Binarizer::GlobalHistogram: return MultiFormatReader(hints).readMultiple(GlobalHistogramBinarizer(iv)); + case Binarizer::LocalAverage: return MultiFormatReader(hints).readMultiple(HybridBinarizer(iv)); + } +} + } // ZXing diff --git a/core/src/ReadBarcode.h b/core/src/ReadBarcode.h index 93e0ec938c..3bbc48f7b4 100644 --- a/core/src/ReadBarcode.h +++ b/core/src/ReadBarcode.h @@ -30,5 +30,8 @@ namespace ZXing { */ Result ReadBarcode(const ImageView& buffer, const DecodeHints& hints = {}); +// WARNING: this API is experimental and may change/disappear +Results ReadBarcodes(const ImageView& buffer, const DecodeHints& hints = {}); + } // ZXing diff --git a/core/src/Reader.h b/core/src/Reader.h index 1ae56ca51a..642ac9c35f 100644 --- a/core/src/Reader.h +++ b/core/src/Reader.h @@ -16,10 +16,11 @@ * limitations under the License. */ +#include "Result.h" + namespace ZXing { class BinaryBitmap; -class Result; /** * Implementations of this interface can decode an image of a barcode in some format into @@ -55,6 +56,12 @@ class Reader * @throws FormatException if a potential barcode is found but format is invalid */ virtual Result decode(const BinaryBitmap& image) const = 0; + + // WARNING: this API is experimental and may change/disappear + virtual Results decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const { + auto res = decode(image); + return res.isValid() ? Results{std::move(res)} : Results{}; + } }; } // ZXing diff --git a/core/src/Result.h b/core/src/Result.h index 0ae693ea8a..e0d5c0b87d 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -24,6 +24,7 @@ #include "StructuredAppend.h" #include +#include namespace ZXing { @@ -120,6 +121,10 @@ class Result return _readerInit; } + bool operator==(const Result& o) const { + return text() == o.text() && format() == o.format(); + } + private: DecodeStatus _status = DecodeStatus::NoError; BarcodeFormat _format = BarcodeFormat::None; @@ -132,4 +137,6 @@ class Result bool _readerInit = false; }; +using Results = std::vector; + } // ZXing diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 6626e03cc6..9209db4bd2 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -74,9 +74,11 @@ Reader::~Reader() = default; * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the * image if "trying harder". */ -static Result DoDecode(const std::vector>& readers, const BinaryBitmap& image, - bool tryHarder, bool rotate, bool isPure) +static Results DoDecode(const std::vector>& readers, const BinaryBitmap& image, + bool tryHarder, bool rotate, bool isPure, int maxSymbols) { + Results res; + std::vector> decodingState(readers.size()); int width = image.width(); @@ -126,7 +128,7 @@ static Result DoDecode(const std::vector>& readers, c PatternView next(bars); do { Result result = readers[r]->decodePattern(rowNumber, next, decodingState[r]); - if (result.isValid()) { + if (result.isValid() && !Contains(res, result)) { if (upsideDown) { // update position (flip horizontally). auto points = result.position(); @@ -135,7 +137,16 @@ static Result DoDecode(const std::vector>& readers, c } result.setPosition(std::move(points)); } - return result; + if (rotate) { + auto points = result.position(); + for (auto& p : points) { + p = {height - p.y - 1, p.x}; + } + result.setPosition(std::move(points)); + } + res.push_back(std::move(result)); + if (maxSymbols && Size(res) == maxSymbols) + return res; } // make sure we make progress and we start the next try on a bar next.shift(2 - (next.index() % 2)); @@ -148,28 +159,29 @@ static Result DoDecode(const std::vector>& readers, c if (isPure) break; } - return Result(DecodeStatus::NotFound); + + return res; } Result Reader::decode(const BinaryBitmap& image) const { - Result result = DoDecode(_readers, image, _tryHarder, false, _isPure); - - if (!result.isValid() && _tryRotate) { - result = DoDecode(_readers, image, _tryHarder, true, _isPure); - if (result.isValid()) { - // Update position - auto points = result.position(); - int height = image.width(); - for (auto& p : points) { - p = {height - p.y - 1, p.x}; - } - result.setPosition(std::move(points)); - } - } + auto result = DoDecode(_readers, image, _tryHarder, false, _isPure, 1); - return result; + if (result.empty() && _tryRotate) + result = DoDecode(_readers, image, _tryHarder, true, _isPure, 1); + + return result.empty() ? Result(DecodeStatus::NotFound) : result.front(); +} + +Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const +{ + auto resH = DoDecode(_readers, image, _tryHarder, false, _isPure, maxSymbols); + if (Size(resH) < maxSymbols && _tryRotate) { + auto resV = DoDecode(_readers, image, _tryHarder, true, _isPure, maxSymbols); + resH.insert(resH.end(), resV.begin(), resV.end()); + } + return resH; } } // namespace ZXing::OneD diff --git a/core/src/oned/ODReader.h b/core/src/oned/ODReader.h index 3603acb93f..70f6dbf257 100644 --- a/core/src/oned/ODReader.h +++ b/core/src/oned/ODReader.h @@ -40,6 +40,7 @@ class Reader : public ZXing::Reader ~Reader() override; Result decode(const BinaryBitmap& image) const override; + Results decode(const BinaryBitmap& image, int maxSymbols) const override; private: std::vector> _readers; diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 7e2c5066c7..5df8de3e9e 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -122,54 +122,57 @@ int main(int argc, char* argv[]) return -1; } - const auto& result = ReadBarcode({buffer.get(), width, height, ImageFormat::RGBX}, hints); - - ret |= static_cast(result.status()); - - if (oneLine) { - std::cout << filePath << " " << ToString(result.format()); - if (result.isValid()) - std::cout << " \"" << ToUtf8(result.text(), angleEscape) << "\""; - else if (result.format() != BarcodeFormat::None) - std::cout << " " << ToString(result.status()); - std::cout << "\n"; - continue; - } - - if (filePaths.size() > 1) { - static bool firstFile = true; - if (!firstFile) + const auto& results = ReadBarcodes({buffer.get(), width, height, ImageFormat::RGBX}, hints); + for (auto&& result : results) { + ret |= static_cast(result.status()); + + if (oneLine) { + std::cout << filePath << " " << ToString(result.format()); + if (result.isValid()) + std::cout << " \"" << ToUtf8(result.text(), angleEscape) << "\""; + else if (result.format() != BarcodeFormat::None) + std::cout << " " << ToString(result.status()); std::cout << "\n"; - std::cout << "File: " << filePath << "\n"; - firstFile = false; - } - std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" - << "Format: " << ToString(result.format()) << "\n" - << "Position: " << result.position() << "\n" - << "Rotation: " << result.orientation() << " deg\n" - << "Error: " << ToString(result.status()) << "\n"; - - auto printOptional = [](const char* key, const std::string& v) { - if (!v.empty()) - std::cout << key << v << "\n"; - }; - - printOptional("EC Level: ", ToUtf8(result.ecLevel())); - - if ((BarcodeFormat::EAN13 | BarcodeFormat::EAN8 | BarcodeFormat::UPCA | BarcodeFormat::UPCE) - .testFlag(result.format())) { - printOptional("Country: ", GTIN::LookupCountryIdentifier(ToUtf8(result.text()))); - printOptional("Add-On: ", GTIN::EanAddOn(result)); - printOptional("Price: ", GTIN::Price(GTIN::EanAddOn(result))); - printOptional("Issue #: ", GTIN::IssueNr(GTIN::EanAddOn(result))); - } + continue; + } - if (result.isPartOfSequence()) - std::cout << "Structured Append: symbol " << result.sequenceIndex() + 1 << " of " << result.sequenceSize() - << " (parity/id: '" << result.sequenceId() << "')\n"; + if (filePaths.size() > 1 || results.size() > 1) { + static bool firstFile = true; + if (!firstFile) + std::cout << "\n"; + if (filePaths.size() > 1) + std::cout << "File: " << filePath << "\n"; + firstFile = false; + } + std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" + << "Format: " << ToString(result.format()) << "\n" + << "Position: " << result.position() << "\n" + << "Rotation: " << result.orientation() << " deg\n" + << "Error: " << ToString(result.status()) << "\n"; + + auto printOptional = [](const char* key, const std::string& v) { + if (!v.empty()) + std::cout << key << v << "\n"; + }; + + printOptional("EC Level: ", ToUtf8(result.ecLevel())); + + if ((BarcodeFormat::EAN13 | BarcodeFormat::EAN8 | BarcodeFormat::UPCA | BarcodeFormat::UPCE) + .testFlag(result.format())) { + printOptional("Country: ", GTIN::LookupCountryIdentifier(ToUtf8(result.text()))); + printOptional("Add-On: ", GTIN::EanAddOn(result)); + printOptional("Price: ", GTIN::Price(GTIN::EanAddOn(result))); + printOptional("Issue #: ", GTIN::IssueNr(GTIN::EanAddOn(result))); + } + + if (result.isPartOfSequence()) + std::cout << "Structured Append: symbol " << result.sequenceIndex() + 1 << " of " + << result.sequenceSize() << " (parity/id: '" << result.sequenceId() << "')\n"; + + if (result.readerInit()) + std::cout << "Reader Initialisation/Programming\n"; + } - if (result.readerInit()) - std::cout << "Reader Initialisation/Programming\n"; } return ret; diff --git a/test/samples/multi-1/3xean-8.png b/test/samples/multi-1/3xean-8.png new file mode 100644 index 0000000000000000000000000000000000000000..77d2fd730f5b51a2c42a06de3b7bce47a1d18fd3 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0y~yVAcV$#W;Wj1N$3yaRvrPV^0^ykcwMxFYnc3Nt9@N z_*{1Kgn*odj+%aMixymdrC~ZHIMZ~K`-2D&%3U7bN<~@)H-@+ukEyw=iZ)$4{v|l*=q9tiH)wv{QEIK-2^9H z%laL$@y8^)%;oJ#m+wst@dz@k@(o|;bgA(z?@_<1=&0?*@f-id-F~?}@Wq8~*|&Fo zt^Jc_)i2_G{_F{_4E@;K*B3szbFL)qSE1voH@9Bi%1r-l|L9DehVrT{#Rrl#SswUz xuquc(L@*>VLKy0T literal 0 HcmV?d00001 From a0a3a0cc138cb64bc6837470ac8bbd3c77abcbfb Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 20 Jul 2021 21:26:57 +0200 Subject: [PATCH 0012/1315] python: add new Multi-Barcode API (`read_barcodes`) This can be considered a fix for #131 as it provides a solution and works for both presented examples. --- wrappers/python/zxing.cpp | 48 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index c7843c750b..be52eb3edf 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -34,8 +34,9 @@ std::ostream& operator<<(std::ostream& os, const Position& points) { return os; } -Result read_barcode(py::object _image, const BarcodeFormats& formats, bool try_rotate, Binarizer binarizer, - bool is_pure, EanAddOnSymbol ean_add_on_symbol) +template +auto read_barcode_impl(FUNC func, py::object _image, const BarcodeFormats& formats, bool try_rotate, + Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol) { const auto hints = DecodeHints() .setFormats(formats) @@ -80,7 +81,19 @@ Result read_barcode(py::object _image, const BarcodeFormats& formats, bool try_r } const auto bytes = image.data(); - return ReadBarcode({bytes, width, height, imgfmt, width * channels, channels}, hints); + return func({bytes, width, height, imgfmt, width * channels, channels}, hints); +} + +Result read_barcode(py::object _image, const BarcodeFormats& formats, bool try_rotate, Binarizer binarizer, + bool is_pure, EanAddOnSymbol ean_add_on_symbol) +{ + return read_barcode_impl(ReadBarcode, _image, formats, try_rotate, binarizer, is_pure, ean_add_on_symbol); +} + +Results read_barcodes(py::object _image, const BarcodeFormats& formats, bool try_rotate, Binarizer binarizer, + bool is_pure, EanAddOnSymbol ean_add_on_symbol) +{ + return read_barcode_impl(ReadBarcodes, _image, formats, try_rotate, binarizer, is_pure, ean_add_on_symbol); } Image write_barcode(BarcodeFormat format, std::string text, int width, int height, int quiet_zone, int ec_level) @@ -226,6 +239,35 @@ PYBIND11_MODULE(zxingcpp, m) ":rtype: zxing.Result\n" ":return: a zxing result containing decoded symbol if found." ); + m.def("read_barcodes", &read_barcodes, + py::arg("image"), + py::arg("formats") = BarcodeFormats{}, + py::arg("try_rotate") = true, + py::arg("binarizer") = Binarizer::LocalAverage, + py::arg("is_pure") = false, + py::arg("ean_add_on_symbol") = EanAddOnSymbol::Ignore, + "Read (decode) multiple barcodes from a numpy BGR or grayscale image array or from a PIL image.\n\n" + ":type image: numpy.ndarray|PIL.Image.Image\n" + ":param image: The image object to decode. The image can be either:\n" + " - a numpy array containing image either in grayscale (1 byte per pixel) or BGR mode (3 bytes per pixel)\n" + " - a PIL Image\n" + ":type formats: zxing.BarcodeFormat|zxing.BarcodeFormats\n" + ":param formats: the format(s) to decode. If ``None``, decode all formats.\n" + ":type try_rotate: bool\n" + ":param try_rotate: if ``True`` (the default), decoder searched for barcodes in any direction; \n" + " if ``False``, it will not search for 90° / 270° rotated barcodes.\n" + ":type binarizer: zxing.Binarizer\n" + ":param binarizer: the binarizer used to convert image before decoding barcodes.\n" + " Defaults to :py:attr:`zxing.Binarizer.LocalAverage`." + ":type is_pure: bool\n" + ":param is_pure: Set to True if the input contains nothing but a perfectly aligned barcode (generated image).\n" + " Speeds up detection in that case. Default is False." + ":type ean_add_on_symbol: zxing.EanAddOnSymbol\n" + ":param ean_add_on_symbol: Specify whether to Ignore, Read or Require EAN-2/5 add-on symbols while scanning \n" + " EAN/UPC codes. Default is ``Ignore``.\n" + ":rtype: zxing.Result\n" + ":return: a list of zxing results containing decoded symbols, the list is empty if none is found" + ); m.def("write_barcode", &write_barcode, py::arg("format"), py::arg("text"), From 0c0c42d5f47ec44601571c086ceb8279e36f4c2a Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 21 Jul 2021 14:02:45 +0200 Subject: [PATCH 0013/1315] fuzzer: make fuzzODDecoders test the new 'check the whole line' feature --- test/fuzz/fuzzODDecoders.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/fuzz/fuzzODDecoders.cpp b/test/fuzz/fuzzODDecoders.cpp index 4426c1317f..df39599041 100644 --- a/test/fuzz/fuzzODDecoders.cpp +++ b/test/fuzz/fuzzODDecoders.cpp @@ -46,8 +46,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) } row.back() = 0; - for (size_t r = 0; r < readers.size(); ++r) - readers[r]->decodePattern(0, row, decodingState[r]); + for (size_t r = 0; r < readers.size(); ++r) { + PatternView next(row); + while (next.isValid()) { + readers[r]->decodePattern(0, next, decodingState[r]); + // make sure we make progress and we start the next try on a bar + next.shift(2 - (next.index() % 2)); + next.extend(); + } + } return 0; } From 9716ed3cc51e1e759c4377b069cf0913a35a9b53 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 21 Jul 2021 14:03:36 +0200 Subject: [PATCH 0014/1315] fuzzer: fix out-of-bounds access in ODITFReader.cpp --- core/src/oned/ODITFReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 124a009a7d..ad9881b0fd 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -80,7 +80,7 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt next = next.subView(0, 3); - if (Size(txt) < minCharCount) + if (Size(txt) < minCharCount || !next.isValid()) return Result(DecodeStatus::NotFound); if (!IsRightGuard(next, STOP_PATTERN_1, minQuietZone) && !IsRightGuard(next, STOP_PATTERN_2, minQuietZone)) From 3065bad7fede2cbcff6a571cc7046d5e3b040027 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 21 Jul 2021 14:46:38 +0200 Subject: [PATCH 0015/1315] fuzzer: add DMDecoder fuzzer --- test/fuzz/CMakeLists.txt | 2 ++ test/fuzz/fuzzDMDecoder.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/fuzz/fuzzDMDecoder.cpp diff --git a/test/fuzz/CMakeLists.txt b/test/fuzz/CMakeLists.txt index 73ab9f71d0..a416ea791e 100644 --- a/test/fuzz/CMakeLists.txt +++ b/test/fuzz/CMakeLists.txt @@ -9,10 +9,12 @@ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -march=native -fsanitize=address,fuz set (BUILD_WRITERS ON) set (BUILD_READERS ON) +add_definitions (-DZXING_BUILD_FOR_TEST) add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/../../core ${CMAKE_BINARY_DIR}/ZXing) set (TESTS DBEDecoder + DMDecoder DMEncoder ODDecoders ) diff --git a/test/fuzz/fuzzDMDecoder.cpp b/test/fuzz/fuzzDMDecoder.cpp new file mode 100644 index 0000000000..455679c70c --- /dev/null +++ b/test/fuzz/fuzzDMDecoder.cpp @@ -0,0 +1,26 @@ +#include +#include + +#include "ByteArray.h" +#include "DecoderResult.h" + +using namespace ZXing; + +namespace ZXing::DataMatrix::DecodedBitStreamParser { +DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + if (size < 2) + return 0; + + ByteArray ba; + ba.insert(ba.begin(), data, data + size); + try { + DataMatrix::DecodedBitStreamParser::Decode(std::move(ba), ""); + } catch (...) { + } + + return 0; +} From 47a94e5e2eba47a63ae145fc4adaf7a75c89e8a6 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Wed, 21 Jul 2021 14:48:01 +0200 Subject: [PATCH 0016/1315] fuzzer: fix out-of-bounds access in DMDecoder.cpp:DecodeAnsiX12Segment() --- core/src/datamatrix/DMDecoder.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index d12ba7a6e2..8010e5ab1b 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -301,7 +301,9 @@ static bool DecodeAnsiX12Segment(BitSource& bits, std::string& result) for (int cValue : *triple) { // X12 segment terminator , separator *, sub-element separator >, space static const char segChars[4] = {'\r', '*', '>', ' '}; - if (cValue < 4) + if (cValue < 0) + return false; + else if (cValue < 4) result.push_back(segChars[cValue]); else if (cValue < 14) // 0 - 9 result.push_back((char)(cValue + 44)); From 0bda9542492c223742a4c65afb99c257563ccc7b Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 13:02:27 +0200 Subject: [PATCH 0017/1315] Multi-Barcode: sort list of detected symbols based on their position --- core/src/MultiFormatReader.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 9b1e05efdc..767a64c685 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -83,6 +83,13 @@ Results MultiFormatReader::readMultiple(const BinaryBitmap& image) const res.insert(res.end(), r.begin(), r.end()); } + // sort results based on their position on the image + std::sort(res.begin(), res.end(), [](const Result& l, const Result& r) { + auto lp = l.position().topLeft(); + auto rp = r.position().topLeft(); + return lp.y < rp.y || (lp.y == rp.y && lp.x <= rp.x); + }); + return res; } From 98f9990896902a45625a326fa58b5dbbe6ef4991 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 13:03:58 +0200 Subject: [PATCH 0018/1315] Multi-Barcode: increase scanning density in tryHarder use case --- core/src/oned/ODReader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 9209db4bd2..5de623cd0e 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -88,7 +88,8 @@ static Results DoDecode(const std::vector>& readers, std::swap(width, height); int middle = height / 2; - int rowStep = std::max(1, height / (tryHarder ? 256 : 32)); + // TODO: find a better heuristic/parameterization if maxSymbols != 1 + int rowStep = std::max(1, height / (tryHarder ? (maxSymbols == 1 ? 256 : 512) : 32)); int maxLines = tryHarder ? height : // Look at the whole image, not just the center 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image From ba88001dd69556e326d36ffd6269397bedfcf56b Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 13:10:40 +0200 Subject: [PATCH 0019/1315] Multi-Barcode: differentiate between multiple 1D-symbols of the same code This implements a simple heuristic based on the relation between the distance between a new line and an existing compared to the length of the symbol. This feature adds the benefit that 1D symbols now can have a "height" other than 1 reported back in their position. This detects now all 6 symbols from the 'second example' in #138. --- core/src/oned/ODReader.cpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 5de623cd0e..a8cb2cd90a 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -129,7 +129,7 @@ static Results DoDecode(const std::vector>& readers, PatternView next(bars); do { Result result = readers[r]->decodePattern(rowNumber, next, decodingState[r]); - if (result.isValid() && !Contains(res, result)) { + if (result.isValid()) { if (upsideDown) { // update position (flip horizontally). auto points = result.position(); @@ -145,9 +145,39 @@ static Results DoDecode(const std::vector>& readers, } result.setPosition(std::move(points)); } - res.push_back(std::move(result)); - if (maxSymbols && Size(res) == maxSymbols) - return res; + + // check if we know this code already + for (auto& other : res) { + if (other == result) { + auto dTop = maxAbsComponent(other.position().topLeft() - result.position().topLeft()); + auto dBot = maxAbsComponent(other.position().bottomLeft() - result.position().topLeft()); + auto length = maxAbsComponent(other.position().topLeft() - other.position().bottomRight()); + // if the new line is less than half the length of the existing result away from the + // latter, we consider it to belong to the same symbol + if (std::min(dTop, dBot) < length / 2) { + // if so, merge the position information + auto points = other.position(); + if (dTop < dBot || + (dTop == dBot && rotate ^ (sumAbsComponent(points[0]) > + sumAbsComponent(result.position()[0])))) { + points[0] = result.position()[0]; + points[1] = result.position()[1]; + } else { + points[2] = result.position()[2]; + points[3] = result.position()[3]; + } + other.setPosition(points); + // clear the result below, so we don't insert it again + result = Result(DecodeStatus::NotFound); + } + } + } + + if (result.isValid()) { + res.push_back(std::move(result)); + if (maxSymbols && Size(res) == maxSymbols) + return res; + } } // make sure we make progress and we start the next try on a bar next.shift(2 - (next.index() % 2)); From 347ae97266746574b2ca9d4d5078f000bdb997b0 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 21:05:12 +0200 Subject: [PATCH 0020/1315] Multi-Barcode: drop hard coded limit of maxSymbols --- core/src/MultiFormatReader.cpp | 2 +- core/src/oned/ODReader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 767a64c685..ceacf1e315 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -79,7 +79,7 @@ Results MultiFormatReader::readMultiple(const BinaryBitmap& image) const std::vector res; for (const auto& reader : _readers) { - auto r = reader->decode(image, 10); + auto r = reader->decode(image, 0); res.insert(res.end(), r.begin(), r.end()); } diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index a8cb2cd90a..b923b618ad 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -208,7 +208,7 @@ Reader::decode(const BinaryBitmap& image) const Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const { auto resH = DoDecode(_readers, image, _tryHarder, false, _isPure, maxSymbols); - if (Size(resH) < maxSymbols && _tryRotate) { + if ((!maxSymbols || Size(resH) < maxSymbols) && _tryRotate) { auto resV = DoDecode(_readers, image, _tryHarder, true, _isPure, maxSymbols); resH.insert(resH.end(), resV.begin(), resV.end()); } From 81a148217c3f220df1f8a520da21bdf966ec0c2f Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 21:09:27 +0200 Subject: [PATCH 0021/1315] example: add `-pngout` option to `ZXingReader` This is helpful for debugging when one wants to see where a symbol or which symbols were found. The written png copy of the input image has a red outline for each detected barcode. This is experimental and might later be removed again. --- example/ZXingReader.cpp | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 5df8de3e9e..62f8fa15c3 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -29,19 +29,22 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "stb_image_write.h" using namespace ZXing; using namespace TextUtfEncoding; static void PrintUsage(const char* exePath) { - std::cout << "Usage: " << exePath << " [-fast] [-norotate] [-format ] [-ispure] [-1] ...\n" + std::cout << "Usage: " << exePath << " [-fast] [-norotate] [-format ] [-pngout ] [-ispure] [-1] ...\n" << " -fast Skip some lines/pixels during detection (faster)\n" << " -norotate Don't try rotated image during detection (faster)\n" << " -format Only detect given format(s) (faster)\n" << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" << " -1 Print only file name, text and status on one line per file\n" << " -escape Escape non-graphical characters in angle brackets (ignored for -1 option, which always escapes)\n" + << " -pngout Write a copy of the input image with barcodes outlined by a red line\n" << "\n" << "Supported formats are:\n"; for (auto f : BarcodeFormats::all()) { @@ -50,7 +53,8 @@ static void PrintUsage(const char* exePath) std::cout << "Formats can be lowercase, with or without '-', separated by ',' and/or '|'\n"; } -static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& angleEscape, std::vector& filePaths) +static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& angleEscape, + std::vector& filePaths, std::string& outPath) { for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "-fast") == 0) { @@ -79,6 +83,11 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi else if (strcmp(argv[i], "-escape") == 0) { angleEscape = true; } + else if (strcmp(argv[i], "-pngout") == 0) { + if (++i == argc) + return false; + outPath = argv[i]; + } else { filePaths.push_back(argv[i]); } @@ -93,15 +102,32 @@ std::ostream& operator<<(std::ostream& os, const Position& points) { return os; } +void drawLine(const ImageView& image, PointI a, PointI b) +{ + int steps = maxAbsComponent(b - a); + PointF dir = bresenhamDirection(PointF(b - a)); + for (int i = 0; i < steps; ++i) { + auto p = centered(a + i * dir); + *((uint32_t*)image.data(p.x, p.y)) = 0xff0000ff; + } +} + +void drawRect(const ImageView& image, const Position& pos) +{ + for(int i=0;i<4;++i) + drawLine(image, pos[i], pos[(i+1)%4]); +} + int main(int argc, char* argv[]) { DecodeHints hints; std::vector filePaths; + std::string outPath; bool oneLine = false; bool angleEscape = false; int ret = 0; - if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, filePaths)) { + if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, filePaths, outPath)) { PrintUsage(argv[0]); return -1; } @@ -124,6 +150,10 @@ int main(int argc, char* argv[]) const auto& results = ReadBarcodes({buffer.get(), width, height, ImageFormat::RGBX}, hints); for (auto&& result : results) { + + if (!outPath.empty()) + drawRect(image, result.position()); + ret |= static_cast(result.status()); if (oneLine) { @@ -173,6 +203,9 @@ int main(int argc, char* argv[]) std::cout << "Reader Initialisation/Programming\n"; } + if (!outPath.empty()) + stbi_write_png(outPath.c_str(), image.width(), image.height(), 4, image.data(0, 0), image.rowStride()); + } return ret; From 46c5082ca0dfe882768b6466157b534262850386 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 21:12:06 +0200 Subject: [PATCH 0022/1315] Multi-Barcode: implement feature in QRCode backend This fixes #105. --- core/src/qrcode/QRDetector.cpp | 19 +++++++++---------- core/src/qrcode/QRDetector.h | 15 +++++++++++++++ core/src/qrcode/QRReader.cpp | 32 ++++++++++++++++++++++++++++++++ core/src/qrcode/QRReader.h | 2 ++ 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 34581dc323..e8a8a381ff 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -87,13 +87,6 @@ static auto FindFinderPatterns(const BitMatrix& image, bool tryHarder) return res; } -struct FinderPatternSet -{ - ConcentricPattern bl, tl, tr; -}; - -using FinderPatternSets = std::vector; - /** * @brief GenerateFinderPatternSets * @param patterns list of ConcentricPattern objects, i.e. found finder pattern squares @@ -153,9 +146,10 @@ static FinderPatternSets GenerateFinderPatternSets(std::vectorfirst > d) { + const auto setSizeLimit = 16; + if (sets.size() < setSizeLimit || sets.crbegin()->first > d) { sets.emplace(d, FinderPatternSet{*a, *b, *c}); - if (sets.size() > 16) + if (sets.size() > setSizeLimit) sets.erase(std::prev(sets.end())); } } @@ -244,7 +238,7 @@ static RegressionLine TraceLine(const BitMatrix& image, PointF p, PointF d, int return line; } -static DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatternSet& fp) +DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatternSet& fp) { auto top = EstimateDimension(image, fp.tl, fp.tr); auto left = EstimateDimension(image, fp.tl, fp.bl); @@ -353,6 +347,11 @@ static DetectorResult DetectPure(const BitMatrix& image) {{left, top}, {right, top}, {right, bottom}, {left, bottom}}}; } +FinderPatternSets FindFinderPatternSets(const BitMatrix& image, bool tryHarder) +{ + return GenerateFinderPatternSets(FindFinderPatterns(image, tryHarder)); +} + DetectorResult Detect(const BitMatrix& image, bool tryHarder, bool isPure) { #ifdef PRINT_DEBUG diff --git a/core/src/qrcode/QRDetector.h b/core/src/qrcode/QRDetector.h index 67c9d91110..b11975fffa 100644 --- a/core/src/qrcode/QRDetector.h +++ b/core/src/qrcode/QRDetector.h @@ -2,6 +2,7 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2021 Axel Waggershauser * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +17,10 @@ * limitations under the License. */ +#include "ConcentricFinder.h" + +#include + namespace ZXing { class DetectorResult; @@ -23,6 +28,16 @@ class BitMatrix; namespace QRCode { +struct FinderPatternSet +{ + ConcentricPattern bl, tl, tr; +}; + +using FinderPatternSets = std::vector; + +FinderPatternSets FindFinderPatternSets(const BitMatrix& image, bool tryHarder); +DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatternSet& fp); + /** * @brief Detects a QR Code in an image. */ diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 7e54648579..4c2a8ecc2b 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -55,4 +55,36 @@ Reader::decode(const BinaryBitmap& image) const return Result(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); } +Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const +{ + auto binImg = image.getBitMatrix(); + if (binImg == nullptr) + return {}; + + FinderPatternSets allFPSets = FindFinderPatternSets(*binImg, _tryHarder); + std::vector usedFPs; + Results results; + + for(auto& fpSet : allFPSets) { + if (Contains(usedFPs, fpSet.bl) || Contains(usedFPs, fpSet.tl) || Contains(usedFPs, fpSet.tr)) + continue; + + auto detectorResult = SampleAtFinderPatternSet(*binImg, fpSet); + if (detectorResult.isValid()) { + auto decoderResult = Decode(detectorResult.bits(), _charset); + auto position = detectorResult.position(); + if (decoderResult.isValid()) { + usedFPs.push_back(fpSet.bl); + usedFPs.push_back(fpSet.tl); + usedFPs.push_back(fpSet.tr); + results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); + if (maxSymbols && Size(results) == maxSymbols) + break; + } + } + } + + return results; +} + } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRReader.h b/core/src/qrcode/QRReader.h index 78e5f50911..1df4e8f2b1 100644 --- a/core/src/qrcode/QRReader.h +++ b/core/src/qrcode/QRReader.h @@ -37,6 +37,8 @@ class Reader : public ZXing::Reader explicit Reader(const DecodeHints& hints); Result decode(const BinaryBitmap& image) const override; + Results decode(const BinaryBitmap& image, int maxSymbols) const override; + private: bool _tryHarder, _isPure; std::string _charset; From 0932324845a3aca0b8d66d5411f30a122c2fd7f8 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 21:31:09 +0200 Subject: [PATCH 0023/1315] example: fix build regression --- example/ZXingReader.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 62f8fa15c3..4ec2942849 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -148,7 +148,9 @@ int main(int argc, char* argv[]) return -1; } - const auto& results = ReadBarcodes({buffer.get(), width, height, ImageFormat::RGBX}, hints); + ImageView image{buffer.get(), width, height, ImageFormat::RGBX}; + const auto& results = ReadBarcodes(image, hints); + for (auto&& result : results) { if (!outPath.empty()) From 31caf34b0fbe5443e28b09c22cd5b8ad22567eac Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Thu, 22 Jul 2021 22:19:03 +0200 Subject: [PATCH 0024/1315] Multi-Barcode: hook up existing PDF417 backend to `ReadBardcodes` Also use `ReadBarcodes` in structured append black box tests. --- core/src/pdf417/PDFReader.cpp | 7 +++++++ core/src/pdf417/PDFReader.h | 4 +++- test/blackbox/BlackboxTestRunner.cpp | 12 ++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 93ed83d9e3..64c7344c97 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -338,6 +338,13 @@ Reader::decode(const BinaryBitmap& image) const return Result(status); } +Results Reader::decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const +{ + std::list results; + DoDecode(image, true, results, _characterSet); + return Results(results.begin(), results.end()); +} + std::list Reader::decodeMultiple(const BinaryBitmap& image) const { diff --git a/core/src/pdf417/PDFReader.h b/core/src/pdf417/PDFReader.h index 0f8777b309..138d31ef1e 100644 --- a/core/src/pdf417/PDFReader.h +++ b/core/src/pdf417/PDFReader.h @@ -41,7 +41,9 @@ class Reader : public ZXing::Reader explicit Reader(const DecodeHints& hints); Result decode(const BinaryBitmap& image) const override; - std::list decodeMultiple(const BinaryBitmap& image) const; + Results decode(const BinaryBitmap& image, int maxSymbols) const override; + + [[deprecated]] std::list decodeMultiple(const BinaryBitmap& image) const; }; } // Pdf417 diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 168886adfb..3d31d4ee9e 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -191,15 +191,12 @@ static void doRunTests( } } -static auto readPDF417s = [](const BinaryBitmap& image) { return Pdf417::Reader({}).decodeMultiple(image); }; -static auto readQRCodes = [](const BinaryBitmap& image) { return std::list{QRCode::Reader({}).decode(image)}; }; - -template -static Result readMultiple(const std::vector& imgPaths, int rotation, READER read) +static Result readMultiple(const std::vector& imgPaths, std::string_view format) { std::list allResults; for (const auto& imgPath : imgPaths) { - auto results = read(ThresholdBinarizer(ImageLoader::load(imgPath), 127)); + auto results = + ReadBarcodes(ImageLoader::load(imgPath), DecodeHints().setFormats(BarcodeFormatFromString(format.data()))); allResults.insert(allResults.end(), results.begin(), results.end()); } @@ -243,8 +240,7 @@ static void doRunStructuredAppendTest( auto startTime = std::chrono::steady_clock::now(); for (const auto& [testPath, testImgPaths] : imageGroups) { - auto result = format == "QRCode" ? readMultiple(testImgPaths, test.rotation, readQRCodes) - : readMultiple(testImgPaths, test.rotation, readPDF417s); + auto result = readMultiple(testImgPaths, format); if (result.isValid()) { auto error = checkResult(testPath, format, result); if (!error.empty()) From 81cadadc9d235120fc182d4e74a83b49f5de6dba Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 27 Jul 2021 01:26:14 +0200 Subject: [PATCH 0025/1315] ImageView: remove dead code --- core/src/ImageView.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/src/ImageView.h b/core/src/ImageView.h index dd1deb74ab..ed1c2bd2f2 100644 --- a/core/src/ImageView.h +++ b/core/src/ImageView.h @@ -47,11 +47,6 @@ class ImageView ImageFormat _format; int _width = 0, _height = 0, _pixStride = 0, _rowStride = 0; -// friend class ThresholdBinarizer; -// friend class GlobalHistogramBinarizer; -// friend class HybridBinarizer; -// friend class BinaryBitmap; - public: /** * ImageView contructor From 6fb30c3df62a571fb4c7d2df66313722e2636836 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 27 Jul 2021 01:29:36 +0200 Subject: [PATCH 0026/1315] test: fix wrong number of expected working upca-extension-1 tests --- test/blackbox/BlackboxTestRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 3d31d4ee9e..0bd7ea448d 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -443,7 +443,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("upca-extension-1", "UPC-A", 6, { - { 3, 6, 0 }, + { 4, 6, 0 }, { 4, 6, 180 }, }, DecodeHints().setEanAddOnSymbol(EanAddOnSymbol::Require)); From 18102c1cbc052b1ee879e89377a5d26038e7ebdb Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 27 Jul 2021 01:31:05 +0200 Subject: [PATCH 0027/1315] EAN-Addon: implement check for right quiet zone --- core/src/oned/ODMultiUPCEANReader.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 0d8e8d825f..d7f03a6902 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -55,6 +55,7 @@ static const int FIRST_DIGIT_ENCODINGS[] = { constexpr float QUIET_ZONE_LEFT = 6; constexpr float QUIET_ZONE_RIGHT = 6; +constexpr float QUIET_ZONE_ADDON = 3; // There is a single sample (ean13-1/12.png) that fails to decode with these (new) settings because // it has a right-side quiet zone of only about 4.5 modules, which is clearly out of spec. @@ -251,6 +252,8 @@ static bool AddOn(PartialResult& res, PatternView begin, int digitCount) auto moduleSize = IsPattern(ext, EXT_START_PATTERN); CHECK(moduleSize); + CHECK(ext.isAtLastBar() || *ext.end() > QUIET_ZONE_ADDON * moduleSize - 1); + res.end = ext; ext = ext.subView(EXT_START_PATTERN.size(), CHAR_LEN); int lgPattern = 0; @@ -265,8 +268,6 @@ static bool AddOn(PartialResult& res, PatternView begin, int digitCount) } } - //TODO: check right quiet zone - if (digitCount == 2) { CHECK(std::stoi(res.txt) % 4 == lgPattern); } else { From a818f4be2df5ea113b31de1aaadcb4bf416ac6d9 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 27 Jul 2021 01:33:15 +0200 Subject: [PATCH 0028/1315] Code128: reduce quiet zone requirement to accommodate real world data --- core/src/oned/ODCode128Reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index 5f8038f4e1..3ffc95ba4f 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -183,7 +183,7 @@ Code128Reader::Code128Reader(const DecodeHints& hints) : // all 3 start patterns share the same 2-1-1 prefix constexpr auto START_PATTERN_PREFIX = FixedPattern<3, 4>{2, 1, 1}; constexpr int CHAR_LEN = 6; -constexpr float QUIET_ZONE = 8; // quiet zone spec is 10 modules +constexpr float QUIET_ZONE = 5; // quiet zone spec is 10 modules, real world examples ignore that, see #138 //#define USE_FAST_1_TO_4_BIT_PATTERN_DECODING #ifdef USE_FAST_1_TO_4_BIT_PATTERN_DECODING From 73564446e9b56181781a5b465c3b7167fb8d3e4e Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Tue, 27 Jul 2021 01:34:26 +0200 Subject: [PATCH 0029/1315] example: ignore -pngout parameter when processing multiple files --- example/ZXingReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 4ec2942849..d1969784a4 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -205,7 +205,7 @@ int main(int argc, char* argv[]) std::cout << "Reader Initialisation/Programming\n"; } - if (!outPath.empty()) + if (Size(filePaths) == 1 && !outPath.empty()) stbi_write_png(outPath.c_str(), image.width(), image.height(), 4, image.data(0, 0), image.rowStride()); } From 22f23533d1d457b06ed40691d001075d7fa12423 Mon Sep 17 00:00:00 2001 From: Huy Cuong Nguyen Date: Sat, 31 Jul 2021 12:21:37 -0400 Subject: [PATCH 0030/1315] Add missing argument for ApiKey when publishing Nuget package --- .github/workflows/build-winrt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-winrt.yml b/.github/workflows/build-winrt.yml index 31183f902b..5be49b7f2c 100644 --- a/.github/workflows/build-winrt.yml +++ b/.github/workflows/build-winrt.yml @@ -76,7 +76,7 @@ jobs: - name: Publish NuGet package shell: cmd - run: nuget push huycn.zxingcpp.winrt.nupkg ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json + run: nuget push huycn.zxingcpp.winrt.nupkg -ApiKey ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json - uses: actions/upload-artifact@v2 with: From d7ce34b658a4683509be2bb5be8602b8e3d631b5 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Sun, 8 Aug 2021 14:00:23 +0200 Subject: [PATCH 0031/1315] android: update IDE + gradle + dependencies --- wrappers/android/.idea/compiler.xml | 2 +- wrappers/android/.idea/gradle.xml | 3 +-- wrappers/android/.idea/misc.xml | 2 +- wrappers/android/app/build.gradle | 12 ++++++------ wrappers/android/build.gradle | 4 ++-- .../android/gradle/wrapper/gradle-wrapper.properties | 2 +- wrappers/android/zxingcpp/build.gradle | 6 ++---- 7 files changed, 14 insertions(+), 17 deletions(-) diff --git a/wrappers/android/.idea/compiler.xml b/wrappers/android/.idea/compiler.xml index 245a82c827..7d7ec2eaff 100644 --- a/wrappers/android/.idea/compiler.xml +++ b/wrappers/android/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/wrappers/android/.idea/gradle.xml b/wrappers/android/.idea/gradle.xml index 1323a8a56b..3498dab2d9 100644 --- a/wrappers/android/.idea/gradle.xml +++ b/wrappers/android/.idea/gradle.xml @@ -4,7 +4,7 @@ diff --git a/wrappers/android/.idea/misc.xml b/wrappers/android/.idea/misc.xml index 2925c9621f..59135fb6a1 100644 --- a/wrappers/android/.idea/misc.xml +++ b/wrappers/android/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/wrappers/android/app/build.gradle b/wrappers/android/app/build.gradle index ad12bda949..6b6b5e32ea 100644 --- a/wrappers/android/app/build.gradle +++ b/wrappers/android/app/build.gradle @@ -38,17 +38,17 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.3.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.0' // CameraX - def camerax_version = "1.0.0-rc04" + def camerax_version = "1.0.1" implementation "androidx.camera:camera-core:${camerax_version}" implementation "androidx.camera:camera-camera2:${camerax_version}" implementation "androidx.camera:camera-lifecycle:${camerax_version}" - implementation 'androidx.camera:camera-view:1.0.0-alpha23' + implementation 'androidx.camera:camera-view:1.0.0-alpha27' // Java 'upstream' version of zxing (to compare performance) implementation 'com.google.zxing:core:3.4.1' diff --git a/wrappers/android/build.gradle b/wrappers/android/build.gradle index ddd04db827..7340b5d07c 100644 --- a/wrappers/android/build.gradle +++ b/wrappers/android/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.4.32" + ext.kotlin_version = "1.5.21" repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.3' + classpath 'com.android.tools.build:gradle:7.0.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/wrappers/android/gradle/wrapper/gradle-wrapper.properties b/wrappers/android/gradle/wrapper/gradle-wrapper.properties index 44de1b9d20..5ad631ef9a 100644 --- a/wrappers/android/gradle/wrapper/gradle-wrapper.properties +++ b/wrappers/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip diff --git a/wrappers/android/zxingcpp/build.gradle b/wrappers/android/zxingcpp/build.gradle index 09d957a5db..3a743bf141 100644 --- a/wrappers/android/zxingcpp/build.gradle +++ b/wrappers/android/zxingcpp/build.gradle @@ -11,8 +11,6 @@ android { defaultConfig { minSdkVersion 26 targetSdkVersion 30 - versionCode 1 - versionName "1.0" ndk { // speed up build: compile only arm versions @@ -51,9 +49,9 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.core:core-ktx:1.6.0' - def camerax_version = "1.0.0-rc04" + def camerax_version = "1.0.1" implementation "androidx.camera:camera-core:${camerax_version}" } From 04772e59ad78341dd45ec0cb79875365a718ee64 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Sun, 8 Aug 2021 14:01:05 +0200 Subject: [PATCH 0032/1315] android: build native lib with debug info --- wrappers/android/zxingcpp/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/android/zxingcpp/build.gradle b/wrappers/android/zxingcpp/build.gradle index 3a743bf141..08b624a02b 100644 --- a/wrappers/android/zxingcpp/build.gradle +++ b/wrappers/android/zxingcpp/build.gradle @@ -18,7 +18,7 @@ android { } externalNativeBuild { cmake { - arguments "-DCMAKE_BUILD_TYPE=Release" + arguments "-DCMAKE_BUILD_TYPE=RelWithDebInfo" } } } From 855ed4c9e88b5558be985cad4256d271a5239004 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Sun, 8 Aug 2021 14:14:37 +0200 Subject: [PATCH 0033/1315] test: update libfmt dependency to 8.0.1 --- test/blackbox/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index cf24f0c96c..3da26dd048 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) include(FetchContent) FetchContent_Declare (fmtlib GIT_REPOSITORY https://github.com/fmtlib/fmt.git - GIT_TAG 7.1.2) + GIT_TAG 8.0.1) FetchContent_MakeAvailable (fmtlib) # Adds fmt::fmt if (BUILD_READERS) From 317e2238ed512539b6e009e44f6f95f1de434db0 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Sun, 8 Aug 2021 14:15:20 +0200 Subject: [PATCH 0034/1315] python: update pybind dependency to 2.7.1 --- wrappers/python/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/CMakeLists.txt b/wrappers/python/CMakeLists.txt index 7df364be98..0dd2190e4c 100644 --- a/wrappers/python/CMakeLists.txt +++ b/wrappers/python/CMakeLists.txt @@ -6,7 +6,7 @@ include(FetchContent) #set(FETCHCONTENT_QUIET Off) FetchContent_Declare (pybind11 GIT_REPOSITORY https://github.com/pybind/pybind11.git - GIT_TAG v2.6.2) + GIT_TAG v2.7.1) FetchContent_MakeAvailable (pybind11) # check if we are called from the top-level ZXing project From 63523d2306563c0e4bab69ea845995ac8e5728d6 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Sun, 8 Aug 2021 14:17:26 +0200 Subject: [PATCH 0035/1315] ODReader: fix comment about size of EAN-13 symbol --- core/src/oned/ODReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index b923b618ad..104cfcb6c5 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -95,7 +95,7 @@ static Results DoDecode(const std::vector>& readers, 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image PatternRow bars; - bars.reserve(128); // e.g. EAN-13 has 96 bars + bars.reserve(128); // e.g. EAN-13 has 59 bars/spaces for (int i = 0; i < maxLines; i++) { From 3d14886838d5b12946ea73d7802c57622b167422 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Mon, 9 Aug 2021 17:42:32 +0200 Subject: [PATCH 0036/1315] android: avoid buffer copy from ImageProxy and fix #238 This basically implements the direct buffer access, suggested in #239 by @kim-ninh (Thanks for the input and the help!) while at the same time fixing 238. --- .../zxingcpp/src/main/cpp/BarcodeReader.cpp | 121 ++++++++++-------- .../com/example/zxingcpp/BarcodeReader.kt | 48 +++++-- 2 files changed, 108 insertions(+), 61 deletions(-) diff --git a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp index 4b85af741d..31083202e1 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp @@ -58,53 +58,10 @@ static jstring ThrowJavaException(JNIEnv* env, const char* message) return nullptr; } -struct LockedPixels +jstring Read(JNIEnv *env, ImageView image, jstring formats, jboolean tryHarder, jboolean tryRotate, + jobject result) { - JNIEnv* env; - jobject bitmap; - void *pixels = nullptr; - - LockedPixels(JNIEnv* env, jobject bitmap) : env(env), bitmap(bitmap) { - if (AndroidBitmap_lockPixels(env, bitmap, &pixels) != ANDROID_BITMAP_RESUT_SUCCESS) - pixels = nullptr; - } - - operator const uint8_t*() const { return static_cast(pixels); } - - ~LockedPixels() { - if (pixels) - AndroidBitmap_unlockPixels(env, bitmap); - } -}; - -extern "C" JNIEXPORT jstring JNICALL -Java_com_example_zxingcpp_BarcodeReader_read( - JNIEnv* env, jobject thiz, jobject bitmap, - jint left, jint top, jint width, jint height, jint rotation, - jstring formats, jboolean tryHarder, jboolean tryRotate, - jobject result) -{ - using namespace ZXing; - try { - AndroidBitmapInfo bmInfo; - AndroidBitmap_getInfo(env, bitmap, &bmInfo); - - ImageFormat fmt = ImageFormat::None; - switch (bmInfo.format) { - case ANDROID_BITMAP_FORMAT_A_8: fmt = ImageFormat::Lum; break; - case ANDROID_BITMAP_FORMAT_RGBA_8888: fmt = ImageFormat::RGBX; break; - default: return ThrowJavaException(env, "Unsupported format"); - } - - auto pixels = LockedPixels(env, bitmap); - - if (!pixels) - return ThrowJavaException(env, "Failed to lock/read AndroidBitmap data"); - - auto image = ImageView{pixels, (int)bmInfo.width, (int)bmInfo.height, fmt, (int)bmInfo.stride} - .cropped(left, top, width, height) - .rotated(rotation); auto hints = DecodeHints() .setFormats(BarcodeFormatsFromString(J2CString(env, formats))) .setTryHarder(tryHarder) @@ -117,13 +74,13 @@ Java_com_example_zxingcpp_BarcodeReader_read( auto duration = std::chrono::high_resolution_clock::now() - startTime; // LOGD("time: %4d ms\n", (int)std::chrono::duration_cast(duration).count()); - if (res.isValid()) { - jclass clResult = env->GetObjectClass(result); + jclass clResult = env->GetObjectClass(result); - jfieldID fidTime = env->GetFieldID(clResult, "time", "Ljava/lang/String;"); - auto time = std::to_wstring(std::chrono::duration_cast(duration).count()); - env->SetObjectField(result, fidTime, C2JString(env, time)); + jfieldID fidTime = env->GetFieldID(clResult, "time", "Ljava/lang/String;"); + auto time = std::to_wstring(std::chrono::duration_cast(duration).count()); + env->SetObjectField(result, fidTime, C2JString(env, time)); + if (res.isValid()) { jfieldID fidText = env->GetFieldID(clResult, "text", "Ljava/lang/String;"); env->SetObjectField(result, fidText, C2JString(env, res.text())); @@ -136,3 +93,67 @@ Java_com_example_zxingcpp_BarcodeReader_read( return ThrowJavaException(env, "Unknown exception"); } } + +extern "C" JNIEXPORT jstring JNICALL +Java_com_example_zxingcpp_BarcodeReader_readYBuffer( + JNIEnv *env, jobject thiz, jobject yBuffer, jint rowStride, + jint left, jint top, jint width, jint height, jint rotation, + jstring formats, jboolean tryHarder, jboolean tryRotate, + jobject result) +{ + const uint8_t* pixels = static_cast(env->GetDirectBufferAddress(yBuffer)); + + auto image = + ImageView{pixels + top * rowStride + left, width, height, ImageFormat::Lum, rowStride} + .rotated(rotation); + + return Read(env, image, formats, tryHarder, tryRotate, result); +} + +struct LockedPixels +{ + JNIEnv* env; + jobject bitmap; + void *pixels = nullptr; + + LockedPixels(JNIEnv* env, jobject bitmap) : env(env), bitmap(bitmap) { + if (AndroidBitmap_lockPixels(env, bitmap, &pixels) != ANDROID_BITMAP_RESUT_SUCCESS) + pixels = nullptr; + } + + operator const uint8_t*() const { return static_cast(pixels); } + + ~LockedPixels() { + if (pixels) + AndroidBitmap_unlockPixels(env, bitmap); + } +}; + +extern "C" JNIEXPORT jstring JNICALL +Java_com_example_zxingcpp_BarcodeReader_readBitmap( + JNIEnv* env, jobject thiz, jobject bitmap, + jint left, jint top, jint width, jint height, jint rotation, + jstring formats, jboolean tryHarder, jboolean tryRotate, + jobject result) +{ + AndroidBitmapInfo bmInfo; + AndroidBitmap_getInfo(env, bitmap, &bmInfo); + + ImageFormat fmt = ImageFormat::None; + switch (bmInfo.format) { + case ANDROID_BITMAP_FORMAT_A_8: fmt = ImageFormat::Lum; break; + case ANDROID_BITMAP_FORMAT_RGBA_8888: fmt = ImageFormat::RGBX; break; + default: return ThrowJavaException(env, "Unsupported format"); + } + + auto pixels = LockedPixels(env, bitmap); + + if (!pixels) + return ThrowJavaException(env, "Failed to lock/Read AndroidBitmap data"); + + auto image = ImageView{pixels, (int)bmInfo.width, (int)bmInfo.height, fmt, (int)bmInfo.stride} + .cropped(left, top, width, height) + .rotated(rotation); + + return Read(env, image, formats, tryHarder, tryRotate, result); +} diff --git a/wrappers/android/zxingcpp/src/main/java/com/example/zxingcpp/BarcodeReader.kt b/wrappers/android/zxingcpp/src/main/java/com/example/zxingcpp/BarcodeReader.kt index 9ded3dcc3a..6f98544a68 100644 --- a/wrappers/android/zxingcpp/src/main/java/com/example/zxingcpp/BarcodeReader.kt +++ b/wrappers/android/zxingcpp/src/main/java/com/example/zxingcpp/BarcodeReader.kt @@ -21,6 +21,7 @@ import android.graphics.ImageFormat import android.graphics.Rect import androidx.camera.core.ImageProxy import java.lang.RuntimeException +import java.nio.ByteBuffer class BarcodeReader { @@ -43,18 +44,35 @@ class BarcodeReader { val time: String? = null, // for development/debug purposes only ) - private lateinit var bitmapBuffer: Bitmap var options : Options = Options() fun read(image: ImageProxy): Result? { - if (!::bitmapBuffer.isInitialized || bitmapBuffer.width != image.width || bitmapBuffer.height != image.height) { - if (image.format != ImageFormat.YUV_420_888) { - error("invalid image format") - } - bitmapBuffer = Bitmap.createBitmap(image.width, image.height, Bitmap.Config.ALPHA_8) + val supportedYUVFormats = arrayOf(ImageFormat.YUV_420_888, ImageFormat.YUV_422_888, ImageFormat.YUV_444_888) + if (image.format !in supportedYUVFormats) { + error("invalid image format") + } + + var result = Result() + val status = image.use { + readYBuffer( + it.planes[0].buffer, + it.planes[0].rowStride, + it.cropRect.left, + it.cropRect.top, + it.cropRect.width(), + it.cropRect.height(), + it.imageInfo.rotationDegrees, + options.formats.joinToString(), + options.tryHarder, + options.tryRotate, + result + ) + } + return try { + result.copy(format = Format.valueOf(status!!)) + } catch (e: Throwable) { + if (status == "NotFound") null else throw RuntimeException(status!!) } - image.use { bitmapBuffer.copyPixelsFromBuffer(image.planes[0].buffer) } - return read(bitmapBuffer, image.cropRect, image.imageInfo.rotationDegrees) } fun read(bitmap: Bitmap, cropRect: Rect = Rect(), rotation: Int = 0): Result? { @@ -64,8 +82,10 @@ class BarcodeReader { fun read(bitmap: Bitmap, options: Options, cropRect: Rect = Rect(), rotation: Int = 0): Result? { var result = Result() val status = with(options) { - read(bitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height(), rotation, - formats.joinToString(), tryHarder, tryRotate, result) + readBitmap( + bitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height(), rotation, + formats.joinToString(), tryHarder, tryRotate, result + ) } return try { result.copy(format = Format.valueOf(status!!)) @@ -75,7 +95,13 @@ class BarcodeReader { } // setting the format enum from inside the JNI code is a hassle -> use returned String instead - private external fun read( + private external fun readYBuffer( + yBuffer: ByteBuffer, rowStride: Int, left: Int, top: Int, width: Int, height: Int, rotation: Int, + formats: String, tryHarder: Boolean, tryRotate: Boolean, + result: Result, + ): String? + + private external fun readBitmap( bitmap: Bitmap, left: Int, top: Int, width: Int, height: Int, rotation: Int, formats: String, tryHarder: Boolean, tryRotate: Boolean, result: Result, From bbdd03756641bc537204c065f46bd9c36b4ba58b Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Mon, 9 Aug 2021 17:43:11 +0200 Subject: [PATCH 0037/1315] android: update some style settings for the c++ editor --- wrappers/android/.idea/codeStyles/Project.xml | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/wrappers/android/.idea/codeStyles/Project.xml b/wrappers/android/.idea/codeStyles/Project.xml index b5f2664b65..c4a490d90b 100644 --- a/wrappers/android/.idea/codeStyles/Project.xml +++ b/wrappers/android/.idea/codeStyles/Project.xml @@ -1,27 +1,18 @@ - - + + \ No newline at end of file diff --git a/wrappers/android/app/build.gradle b/wrappers/android/app/build.gradle index 43b31d6bcd..08b2c89fdf 100644 --- a/wrappers/android/app/build.gradle +++ b/wrappers/android/app/build.gradle @@ -4,14 +4,14 @@ plugins { } android { - compileSdkVersion 30 - buildToolsVersion "30.0.3" + compileSdkVersion 31 + buildToolsVersion "32.0.0" // ndkVersion "21.1.6352462" defaultConfig { applicationId 'com.example.zxingdemo' minSdkVersion 26 - targetSdkVersion 30 + targetSdkVersion 31 versionCode 1 versionName "1.0" } @@ -32,25 +32,25 @@ android { kotlinOptions { jvmTarget = '1.8' } - lintOptions { - disable "UnsafeExperimentalUsageError" + lint { + disable 'UnsafeExperimentalUsageError' } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.core:core-ktx:1.6.0' - implementation 'androidx.appcompat:appcompat:1.3.1' - implementation 'com.google.android.material:material:1.4.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.0' + implementation 'androidx.core:core-ktx:1.7.0' + implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'com.google.android.material:material:1.5.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.3' // CameraX - def camerax_version = "1.0.1" + def camerax_version = "1.0.2" implementation "androidx.camera:camera-core:${camerax_version}" implementation "androidx.camera:camera-camera2:${camerax_version}" implementation "androidx.camera:camera-lifecycle:${camerax_version}" - implementation 'androidx.camera:camera-view:1.0.0-alpha27' + implementation 'androidx.camera:camera-view:1.0.0-alpha32' // Java 'upstream' version of zxing (to compare performance) implementation 'com.google.zxing:core:3.4.1' diff --git a/wrappers/android/app/src/main/AndroidManifest.xml b/wrappers/android/app/src/main/AndroidManifest.xml index 986de7e03d..540de48834 100644 --- a/wrappers/android/app/src/main/AndroidManifest.xml +++ b/wrappers/android/app/src/main/AndroidManifest.xml @@ -15,7 +15,9 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/wrappers/android/build.gradle b/wrappers/android/build.gradle index 7340b5d07c..2eec1a2072 100644 --- a/wrappers/android/build.gradle +++ b/wrappers/android/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.5.21" + ext.kotlin_version = "1.6.20" repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.0' + classpath 'com.android.tools.build:gradle:7.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -17,7 +17,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } } diff --git a/wrappers/android/gradle.properties b/wrappers/android/gradle.properties index a38cbbbb4c..5b0930c074 100644 --- a/wrappers/android/gradle.properties +++ b/wrappers/android/gradle.properties @@ -18,4 +18,5 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official +# org.gradle.warning.mode=all \ No newline at end of file diff --git a/wrappers/android/gradle/wrapper/gradle-wrapper.properties b/wrappers/android/gradle/wrapper/gradle-wrapper.properties index 5ad631ef9a..e506aad560 100644 --- a/wrappers/android/gradle/wrapper/gradle-wrapper.properties +++ b/wrappers/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip diff --git a/wrappers/android/zxingcpp/build.gradle b/wrappers/android/zxingcpp/build.gradle index 277b20f6c7..fdb5a83403 100644 --- a/wrappers/android/zxingcpp/build.gradle +++ b/wrappers/android/zxingcpp/build.gradle @@ -4,13 +4,13 @@ plugins { } android { - compileSdkVersion 30 - buildToolsVersion "30.0.3" + compileSdkVersion 31 + buildToolsVersion "32.0.0" // ndkVersion '21.1.6352462' defaultConfig { minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 31 ndk { // speed up build: compile only arm versions @@ -35,17 +35,17 @@ android { path file('src/main/cpp/CMakeLists.txt') } } - lintOptions { - disable "UnsafeExperimentalUsageError" + lint { + disable 'UnsafeExperimentalUsageError' } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.core:core-ktx:1.7.0' - def camerax_version = "1.0.1" + def camerax_version = "1.0.2" implementation "androidx.camera:camera-core:${camerax_version}" } From 6983b89d893a0eef6d7e430e5b029f83061b7645 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 11 Apr 2022 22:29:28 +0200 Subject: [PATCH 0123/1315] OneD: fix a bug in the isPure code path for the stacked DataBar codes Stacked DataBar (Extended) symbology is actually a 2D not 1D input, hence, my former isPure shortcut had to fail for those. (thanks to @gitlost for implicitly bringing that to my attention ;)). So for those DataBar symbols, we actually need to process more than one non-empty line. This code now requires that the middle line of the image passes through the pure 1D barcode, which is a reasonable assumption imho. --- core/src/oned/ODReader.cpp | 11 ++++++----- test/blackbox/BlackboxTestRunner.cpp | 5 +++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 4268e19de1..af900ca079 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -97,7 +97,7 @@ static Results DoDecode(const std::vector>& readers, int middle = height / 2; // TODO: find a better heuristic/parameterization if maxSymbols != 1 - int rowStep = std::max(1, height / (tryHarder ? (maxSymbols == 1 ? 256 : 512) : 32)); + int rowStep = std::max(1, height / ((tryHarder && !isPure) ? (maxSymbols == 1 ? 256 : 512) : 32)); int maxLines = tryHarder ? height : // Look at the whole image, not just the center 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image @@ -134,6 +134,11 @@ static Results DoDecode(const std::vector>& readers, } // Look for a barcode for (size_t r = 0; r < readers.size(); ++r) { + // If this is a pure symbol, then checking a single non-empty line is sufficient for all but the stacked + // DataBar codes. They are the only ones using the decodingState, which we can use a flag here. + if (isPure && i && !decodingState[r]) + continue; + PatternView next(bars); do { Result result = readers[r]->decodePattern(rowNumber, next, decodingState[r]); @@ -197,10 +202,6 @@ static Results DoDecode(const std::vector>& readers, } while (tryHarder && next.isValid()); } } - - // If this is a pure symbol, then checking a single non-empty line is sufficient - if (isPure) - break; } out: diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index cf65d7f35a..703c88dc94 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -438,6 +438,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set runTests("ean8-1", "EAN-8", 8, { { 8, 8, 0 }, { 8, 8, 180 }, + { 7, 0, pure }, }); runTests("ean13-1", "EAN-13", 31, { @@ -516,6 +517,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set runTests("upce-1", "UPC-E", 3, { { 3, 3, 0 }, { 3, 3, 180 }, + { 3, 0, pure }, }); runTests("upce-2", "UPC-E", 28, { @@ -541,6 +543,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set runTests("rssexpanded-1", "DataBarExpanded", 33, { { 33, 33, 0 }, { 33, 33, 180 }, + { 33, 0, pure }, }); runTests("rssexpanded-2", "DataBarExpanded", 15, { @@ -551,11 +554,13 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set runTests("rssexpanded-3", "DataBarExpanded", 118, { { 118, 118, 0 }, { 118, 118, 180 }, + { 118, 0, pure }, }); runTests("rssexpandedstacked-1", "DataBarExpanded", 65, { { 60, 65, 0 }, { 60, 65, 180 }, + { 60, 0, pure }, }); runTests("rssexpandedstacked-2", "DataBarExpanded", 7, { From 40b61a7eead3ef2344570d88a8bd676d31a90611 Mon Sep 17 00:00:00 2001 From: Markus Fisch Date: Tue, 12 Apr 2022 13:15:52 +0200 Subject: [PATCH 0124/1315] android: draw result points/position on screen To highlight a detected barcode. --- .../com/example/zxingcppdemo/DetectorView.kt | 48 ++++++++++++++++ .../com/example/zxingcppdemo/MainActivity.kt | 56 ++++++++++++++++--- .../main/res/layout-land/activity_camera.xml | 7 ++- .../src/main/res/layout/activity_camera.xml | 7 ++- 4 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt new file mode 100644 index 0000000000..72710cd6ad --- /dev/null +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt @@ -0,0 +1,48 @@ +package com.example.zxingcppdemo + +import android.content.Context +import android.graphics.* +import android.util.AttributeSet +import android.view.View + +class DetectorView : View { + private val paint = Paint(Paint.ANTI_ALIAS_FLAG) + private val path = Path() + + init { + paint.style = Paint.Style.STROKE + paint.color = 0xffffffff.toInt() + paint.strokeWidth = context.resources.displayMetrics.density + } + + constructor(context: Context, attrs: AttributeSet) : + super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : + super(context, attrs, defStyleAttr) + + fun update(points: List? = null) { + path.apply { + rewind() + if (!points.isNullOrEmpty()) { + moveTo(points[0]) + val size = points.size + for (i in 1 until size) { + lineTo(points[i]) + } + close() + } + } + invalidate() + } + + override fun onDraw(canvas: Canvas) { + canvas.drawColor(0, PorterDuff.Mode.CLEAR) + if (!path.isEmpty) { + canvas.drawPath(path, paint) + } + } +} + +private fun Path.lineTo(point: PointF) = lineTo(point.x, point.y) +private fun Path.moveTo(point: PointF) = moveTo(point.x, point.y) diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt index dcedd338cf..8497e7d6cd 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt @@ -19,7 +19,9 @@ package com.example.zxingcppdemo import android.Manifest import android.content.Context import android.content.pm.PackageManager -import android.graphics.* +import android.graphics.Point +import android.graphics.PointF +import android.graphics.Rect import android.hardware.camera2.CaptureRequest import android.media.AudioManager import android.media.ToneGenerator @@ -29,20 +31,25 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.camera.camera2.interop.Camera2CameraControl import androidx.camera.camera2.interop.CaptureRequestOptions -import androidx.camera.core.* +import androidx.camera.core.AspectRatio +import androidx.camera.core.CameraSelector +import androidx.camera.core.ImageAnalysis +import androidx.camera.core.Preview import androidx.camera.lifecycle.ProcessCameraProvider import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.graphics.toPoint +import androidx.core.graphics.toPointF import androidx.lifecycle.LifecycleOwner -import com.zxingcpp.BarcodeReader -import com.zxingcpp.BarcodeReader.Format +import com.example.zxingcppdemo.databinding.ActivityCameraBinding import com.google.zxing.* import com.google.zxing.common.HybridBinarizer +import com.zxingcpp.BarcodeReader +import com.zxingcpp.BarcodeReader.Format import java.util.concurrent.Executors import kotlin.math.abs +import kotlin.math.roundToInt import kotlin.random.Random -import com.example.zxingcppdemo.databinding.ActivityCameraBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityCameraBinding @@ -122,6 +129,7 @@ class MainActivity : AppCompatActivity() { val startTime = System.currentTimeMillis() var resultText: String + var resultPoints: List? = null if (binding.java.isChecked) { val yBuffer = image.planes[0].buffer // Y @@ -145,6 +153,7 @@ class MainActivity : AppCompatActivity() { ) ) val result = readerJava.decode(bitmap, hints) + resultPoints = mapPoints(result?.resultPoints) result?.let { "${it.barcodeFormat}: ${it.text}" } ?: "" } catch (e: Throwable) { if (e.toString() != "com.google.zxing.NotFoundException") e.toString() else "" @@ -161,6 +170,7 @@ class MainActivity : AppCompatActivity() { resultText = try { val result = readerCpp.read(image) runtime2 += result?.time?.toInt() ?: 0 + resultPoints = mapPoints(result?.position) (result?.let { "${it.format}: ${it.text}" } ?: "") } catch (e: Throwable) { e.message ?: "Error" @@ -182,6 +192,7 @@ class MainActivity : AppCompatActivity() { runtime2 = 0 } + binding.detectorView.update(resultPoints) showResult(resultText, infoText) }) @@ -210,6 +221,33 @@ class MainActivity : AppCompatActivity() { }, ContextCompat.getMainExecutor(this)) } + private fun mapPoints(resultPoints: Array?) = resultPoints?.map { + image2View(Point(it.x.roundToInt(), it.y.roundToInt())).toPointF() + } + + private fun mapPoints(position: BarcodeReader.Position?) = position?.let { + val w: Int + val h: Int + if (imageRotation == 90 || imageRotation == 270) { + w = imageHeight + h = imageWidth + } else { + w = imageWidth + h = imageHeight + } + val vf = binding.viewFinder + val xf = vf.width / w.toFloat() + val yf = vf.height / h.toFloat() + listOf( + it.topLeft, + it.topRight, + it.bottomRight, + it.bottomLeft + ).map { p -> + PointF(p.x * xf, p.y * yf) + } + } + private fun showResult(resultText: String, fpsText: String?) = binding.viewFinder.post { // Update the text and UI binding.result.text = resultText @@ -234,11 +272,15 @@ class MainActivity : AppCompatActivity() { } } - private fun image2View(p: Point) : Point { + private fun image2View(p: Point): Point { val s = kotlin.math.min(binding.viewFinder.width, binding.viewFinder.height).toFloat() / imageHeight val o = (kotlin.math.max(binding.viewFinder.width, binding.viewFinder.height) - (imageWidth * s).toInt()) / 2 val res = PointF(p.x * s + o, p.y * s).toPoint() - return if (imageRotation % 180 == 0) res else Point(binding.viewFinder.width - res.y, res.x) + return when (imageRotation) { + 0 -> res + 180 -> Point(binding.viewFinder.width - res.x, binding.viewFinder.height - res.y) + else -> Point(binding.viewFinder.width - res.y, res.x) + } } override fun onResume() { diff --git a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml index 1b1684ce3d..1c038688f4 100644 --- a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml +++ b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml @@ -13,6 +13,11 @@ android:layout_height="match_parent" app:scaleType="fitCenter" /> + + - \ No newline at end of file + diff --git a/wrappers/android/app/src/main/res/layout/activity_camera.xml b/wrappers/android/app/src/main/res/layout/activity_camera.xml index 62bab293db..971a7f64bb 100644 --- a/wrappers/android/app/src/main/res/layout/activity_camera.xml +++ b/wrappers/android/app/src/main/res/layout/activity_camera.xml @@ -13,6 +13,11 @@ android:layout_height="match_parent" app:scaleType="fitCenter" /> + + - \ No newline at end of file + From 776ef6178463aca92576fd9bd1339e8d39bb6c0d Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 13 Apr 2022 13:29:31 +0200 Subject: [PATCH 0125/1315] android: fix and simplify preview overlay in demo app cropRect and symbol position are now both drawn on the canvas. This also fixes a scale/offset issue with the recently introduced position outlining. Position info in the java/upstream code path was dropped (not important). --- .../com/example/zxingcppdemo/DetectorView.kt | 48 -------- .../com/example/zxingcppdemo/MainActivity.kt | 112 +++++------------- .../example/zxingcppdemo/PreviewOverlay.kt | 87 ++++++++++++++ .../main/res/layout-land/activity_camera.xml | 14 +-- .../src/main/res/layout/activity_camera.xml | 12 +- 5 files changed, 120 insertions(+), 153 deletions(-) delete mode 100644 wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt create mode 100644 wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt deleted file mode 100644 index 72710cd6ad..0000000000 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/DetectorView.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.example.zxingcppdemo - -import android.content.Context -import android.graphics.* -import android.util.AttributeSet -import android.view.View - -class DetectorView : View { - private val paint = Paint(Paint.ANTI_ALIAS_FLAG) - private val path = Path() - - init { - paint.style = Paint.Style.STROKE - paint.color = 0xffffffff.toInt() - paint.strokeWidth = context.resources.displayMetrics.density - } - - constructor(context: Context, attrs: AttributeSet) : - super(context, attrs) - - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : - super(context, attrs, defStyleAttr) - - fun update(points: List? = null) { - path.apply { - rewind() - if (!points.isNullOrEmpty()) { - moveTo(points[0]) - val size = points.size - for (i in 1 until size) { - lineTo(points[i]) - } - close() - } - } - invalidate() - } - - override fun onDraw(canvas: Canvas) { - canvas.drawColor(0, PorterDuff.Mode.CLEAR) - if (!path.isEmpty) { - canvas.drawPath(path, paint) - } - } -} - -private fun Path.lineTo(point: PointF) = lineTo(point.x, point.y) -private fun Path.moveTo(point: PointF) = moveTo(point.x, point.y) diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt index 8497e7d6cd..40768ba4b3 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt @@ -19,22 +19,16 @@ package com.example.zxingcppdemo import android.Manifest import android.content.Context import android.content.pm.PackageManager -import android.graphics.Point -import android.graphics.PointF -import android.graphics.Rect +import android.graphics.* import android.hardware.camera2.CaptureRequest import android.media.AudioManager import android.media.ToneGenerator import android.os.Bundle import android.view.View -import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.camera.camera2.interop.Camera2CameraControl import androidx.camera.camera2.interop.CaptureRequestOptions -import androidx.camera.core.AspectRatio -import androidx.camera.core.CameraSelector -import androidx.camera.core.ImageAnalysis -import androidx.camera.core.Preview +import androidx.camera.core.* import androidx.camera.lifecycle.ProcessCameraProvider import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -47,10 +41,9 @@ import com.google.zxing.common.HybridBinarizer import com.zxingcpp.BarcodeReader import com.zxingcpp.BarcodeReader.Format import java.util.concurrent.Executors -import kotlin.math.abs -import kotlin.math.roundToInt import kotlin.random.Random + class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityCameraBinding private val executor = Executors.newSingleThreadExecutor() @@ -59,10 +52,6 @@ class MainActivity : AppCompatActivity() { private val beeper = ToneGenerator(AudioManager.STREAM_NOTIFICATION, 50) private var lastText = String() - private var cropRect = Rect() - private var imageRotation: Int = 0 - private var imageWidth: Int = 0 - private var imageHeight: Int = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -108,10 +97,6 @@ class MainActivity : AppCompatActivity() { val readerCpp = BarcodeReader() imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { image -> - imageRotation = image.imageInfo.rotationDegrees - imageWidth = image.width - imageHeight = image.height - // Early exit: image analysis is in paused state if (binding.pause.isChecked) { image.close() @@ -119,13 +104,14 @@ class MainActivity : AppCompatActivity() { } val cropSize = image.height / 3 * 2 - cropRect = if (binding.crop.isChecked) + val cropRect = if (binding.crop.isChecked) Rect( (image.width - cropSize) / 2, (image.height - cropSize) / 2, (image.width - cropSize) / 2 + cropSize, (image.height - cropSize) / 2 + cropSize ) else Rect(0, 0, image.width, image.height) + image.setCropRect(cropRect) val startTime = System.currentTimeMillis() var resultText: String @@ -146,14 +132,13 @@ class MainActivity : AppCompatActivity() { val bitmap = BinaryBitmap( HybridBinarizer( PlanarYUVLuminanceSource( - data, imageWidth, imageHeight, + data, image.width, image.height, cropRect.left, cropRect.top, cropRect.width(), cropRect.height(), false ) ) ) val result = readerJava.decode(bitmap, hints) - resultPoints = mapPoints(result?.resultPoints) result?.let { "${it.barcodeFormat}: ${it.text}" } ?: "" } catch (e: Throwable) { if (e.toString() != "com.google.zxing.NotFoundException") e.toString() else "" @@ -165,12 +150,19 @@ class MainActivity : AppCompatActivity() { tryRotate = binding.tryRotate.isChecked ) - image.setCropRect(cropRect) - resultText = try { val result = readerCpp.read(image) runtime2 += result?.time?.toInt() ?: 0 - resultPoints = mapPoints(result?.position) + resultPoints = result?.position?.let { + listOf( + it.topLeft, + it.topRight, + it.bottomRight, + it.bottomLeft + ).map { p -> + p.toPointF() + } + } (result?.let { "${it.format}: ${it.text}" } ?: "") } catch (e: Throwable) { e.message ?: "Error" @@ -192,8 +184,7 @@ class MainActivity : AppCompatActivity() { runtime2 = 0 } - binding.detectorView.update(resultPoints) - showResult(resultText, infoText) + showResult(resultText, infoText, resultPoints, image) }) // Create a new camera selector each time, enforcing lens facing @@ -221,67 +212,22 @@ class MainActivity : AppCompatActivity() { }, ContextCompat.getMainExecutor(this)) } - private fun mapPoints(resultPoints: Array?) = resultPoints?.map { - image2View(Point(it.x.roundToInt(), it.y.roundToInt())).toPointF() - } - - private fun mapPoints(position: BarcodeReader.Position?) = position?.let { - val w: Int - val h: Int - if (imageRotation == 90 || imageRotation == 270) { - w = imageHeight - h = imageWidth - } else { - w = imageWidth - h = imageHeight - } - val vf = binding.viewFinder - val xf = vf.width / w.toFloat() - val yf = vf.height / h.toFloat() - listOf( - it.topLeft, - it.topRight, - it.bottomRight, - it.bottomLeft - ).map { p -> - PointF(p.x * xf, p.y * yf) - } - } - - private fun showResult(resultText: String, fpsText: String?) = binding.viewFinder.post { - // Update the text and UI - binding.result.text = resultText - binding.result.visibility = View.VISIBLE - - val tl = image2View(Point(cropRect.left, cropRect.top)) - val br = image2View(Point(cropRect.right, cropRect.bottom)) - (binding.cropRect.layoutParams as ViewGroup.MarginLayoutParams).apply { - leftMargin = kotlin.math.min(tl.x, br.x) - topMargin = kotlin.math.min(tl.y, br.y) - width = abs(br.x - tl.x) - height = abs(br.y - tl.y) - } - binding.cropRect.visibility = if (binding.crop.isChecked) View.VISIBLE else View.GONE + private fun showResult(resultText: String, fpsText: String?, points: List?, image: ImageProxy) = + binding.viewFinder.post { + // Update the text and UI + binding.result.text = resultText + binding.result.visibility = View.VISIBLE - if (fpsText != null) - binding.fps.text = fpsText + binding.overlay.update(binding.viewFinder, image, points) - if (resultText.isNotEmpty() && lastText != resultText) { - lastText = resultText - beeper.startTone(ToneGenerator.TONE_PROP_BEEP) - } - } + if (fpsText != null) + binding.fps.text = fpsText - private fun image2View(p: Point): Point { - val s = kotlin.math.min(binding.viewFinder.width, binding.viewFinder.height).toFloat() / imageHeight - val o = (kotlin.math.max(binding.viewFinder.width, binding.viewFinder.height) - (imageWidth * s).toInt()) / 2 - val res = PointF(p.x * s + o, p.y * s).toPoint() - return when (imageRotation) { - 0 -> res - 180 -> Point(binding.viewFinder.width - res.x, binding.viewFinder.height - res.y) - else -> Point(binding.viewFinder.width - res.y, res.x) + if (resultText.isNotEmpty() && lastText != resultText) { + lastText = resultText + beeper.startTone(ToneGenerator.TONE_PROP_BEEP) + } } - } override fun onResume() { super.onResume() diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt new file mode 100644 index 0000000000..0bc84a5300 --- /dev/null +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt @@ -0,0 +1,87 @@ +/* +* Copyright 2022 Axel Waggershauser +* Copyright 2022 Markus Fisch +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.example.zxingcppdemo + +import android.content.Context +import android.graphics.* +import android.util.AttributeSet +import android.view.View +import androidx.camera.core.ImageProxy +import kotlin.math.max +import kotlin.math.min + +class PreviewOverlay constructor(context: Context, attributeSet: AttributeSet?) : + View(context, attributeSet) { + + private val paintPath = Paint(Paint.ANTI_ALIAS_FLAG).apply { + style = Paint.Style.STROKE + color = 0xff00ff00.toInt() + strokeWidth = 2 * context.resources.displayMetrics.density + } + private val paintRect = Paint().apply { + style = Paint.Style.STROKE + color = 0x80ffffff.toInt() + strokeWidth = 3 * context.resources.displayMetrics.density + } + private val path = Path() + private var cropRect = Rect() + private var rotation = 0 + private var s: Float = 0f + private var o: Float = 0f + + fun update(viewFinder: View, image: ImageProxy, points: List?) { + cropRect = image.cropRect + rotation = image.imageInfo.rotationDegrees + s = min(viewFinder.width, viewFinder.height).toFloat() / image.height + o = (max(viewFinder.width, viewFinder.height) - (image.width * s).toInt()).toFloat() / 2 + + path.apply { + rewind() + if (!points.isNullOrEmpty()) { + moveTo(points.last().x, points.last().y) + for (p in points) + lineTo(p.x, p.y) + } + } + invalidate() + } + + override fun onDraw(canvas: Canvas) { + canvas.apply { + drawColor(0, PorterDuff.Mode.CLEAR) + // draw the cropRect, which is relative to the original image orientation + save() + if (rotation == 90) { + translate(width.toFloat(), 0f) + rotate(rotation.toFloat()) + } + translate(o, 0f) + scale(s, s) + drawRect(cropRect, paintRect) + restore() + + // draw the path, which is relative to the (centered) rotated cropRect + when (rotation) { + 0, 180 -> translate(o + cropRect.left * s, cropRect.top * s) + 90 -> translate(cropRect.top * s, o + cropRect.left * s) + } + scale(s, s) + drawPath(path, paintPath) + } + } +} diff --git a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml index 1c038688f4..3f7859de28 100644 --- a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml +++ b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml @@ -13,21 +13,11 @@ android:layout_height="match_parent" app:scaleType="fitCenter" /> - - - - - - - - Date: Thu, 14 Apr 2022 09:21:37 +0200 Subject: [PATCH 0126/1315] OneD: comment and trivial logic fixes --- core/src/oned/ODReader.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index af900ca079..7be4265a80 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -135,15 +135,15 @@ static Results DoDecode(const std::vector>& readers, // Look for a barcode for (size_t r = 0; r < readers.size(); ++r) { // If this is a pure symbol, then checking a single non-empty line is sufficient for all but the stacked - // DataBar codes. They are the only ones using the decodingState, which we can use a flag here. + // DataBar codes. They are the only ones using the decodingState, which we can use as a flag here. if (isPure && i && !decodingState[r]) continue; PatternView next(bars); do { Result result = readers[r]->decodePattern(rowNumber, next, decodingState[r]); - result.incrementLineCount(); if (result.isValid()) { + result.incrementLineCount(); if (upsideDown) { // update position (flip horizontally). auto points = result.position(); @@ -182,18 +182,21 @@ static Results DoDecode(const std::vector>& readers, } other.setPosition(points); other.incrementLineCount(); - // clear the result below, so we don't insert it again + // clear the result, so we don't insert it again below result = Result(DecodeStatus::NotFound); + break; } } } - if (result.isValid()) { + if (result.isValid()) res.push_back(std::move(result)); - if (maxSymbols && Reduce(res, 0, [&](int s, const Result& r) { - return s + (r.lineCount() >= minLineCount); - }) == maxSymbols) - goto out; + + if (maxSymbols && Reduce(res, 0, [&](int s, const Result& r) { + return s + (r.lineCount() >= minLineCount); + }) == maxSymbols) { + goto out; + } } } // make sure we make progress and we start the next try on a bar From e697808640596c8db29bb3a58321726c97ea276c Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Apr 2022 10:41:36 +0200 Subject: [PATCH 0127/1315] DataBar: EstimateLineCount for stacked versions to support minLineCount This is a bit of a hack/workaround for the fact that stacked DataBar symbols are actually 2D codes but are handled as 1D codes. Without this some stacked DataBar symbols necessarily failed in non-tryHarder-mode. --- core/src/Result.cpp | 4 ++-- core/src/Result.h | 3 ++- core/src/oned/ODDataBarCommon.cpp | 6 ++++++ core/src/oned/ODDataBarCommon.h | 1 + core/src/oned/ODDataBarExpandedReader.cpp | 3 ++- core/src/oned/ODDataBarReader.cpp | 4 ++-- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index f1064fec80..60faebe943 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -26,9 +26,9 @@ namespace ZXing { Result::Result(std::wstring&& text, Position&& position, BarcodeFormat format, ByteArray&& rawBytes, - std::string symbologyIdentifier, StructuredAppendInfo sai, const bool readerInit) + std::string symbologyIdentifier, StructuredAppendInfo sai, const bool readerInit, int lineCount) : _format(format), _text(std::move(text)), _position(std::move(position)), _rawBytes(std::move(rawBytes)), - _symbologyIdentifier(symbologyIdentifier), _sai(sai), _readerInit(readerInit) + _symbologyIdentifier(symbologyIdentifier), _sai(sai), _readerInit(readerInit), _lineCount(lineCount) { _numBits = Size(_rawBytes) * 8; } diff --git a/core/src/Result.h b/core/src/Result.h index 50543889dd..789af3d956 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -43,7 +43,8 @@ class Result explicit Result(DecodeStatus status) : _status(status) {} Result(std::wstring&& text, Position&& position, BarcodeFormat format, ByteArray&& rawBytes = {}, - std::string symbologyIdentifier = "", StructuredAppendInfo sai = {}, const bool readerInit = false); + std::string symbologyIdentifier = "", StructuredAppendInfo sai = {}, const bool readerInit = false, + int lineCount = 0); // 1D convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, ByteArray&& rawBytes = {}, diff --git a/core/src/oned/ODDataBarCommon.cpp b/core/src/oned/ODDataBarCommon.cpp index b47d55025d..aba8505311 100644 --- a/core/src/oned/ODDataBarCommon.cpp +++ b/core/src/oned/ODDataBarCommon.cpp @@ -163,4 +163,10 @@ Position EstimatePosition(const Pair& first, const Pair& last) return Position{{first.xStart, first.y}, {first.xStop, first.y}, {last.xStop, last.y}, {last.xStart, last.y}}; } +int EstimateLineCount(const Pair& first, const Pair& last) +{ + // see incrementLineCount() in ODReader.cpp for the -1 here + return std::min(first.count, last.count) * ((first.y == last.y) ? 1 : 2) - 1; +} + } // namespace ZXing::OneD::DataBar diff --git a/core/src/oned/ODDataBarCommon.h b/core/src/oned/ODDataBarCommon.h index ce8e98683e..08669b208e 100644 --- a/core/src/oned/ODDataBarCommon.h +++ b/core/src/oned/ODDataBarCommon.h @@ -138,5 +138,6 @@ bool ReadDataCharacterRaw(const PatternView& view, int numModules, bool reversed int GetValue(const Array4I& widths, int maxWidth, bool noNarrow); Position EstimatePosition(const Pair& first, const Pair& last); +int EstimateLineCount(const Pair& first, const Pair& last); } // namespace ZXing::OneD::DataBar diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 740e344359..5a9bfdbe02 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -377,7 +377,8 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, std::string symbologyIdentifier("]e0"); return {TextDecoder::FromLatin1(txt), EstimatePosition(pairs.front(), pairs.back()), - BarcodeFormat::DataBarExpanded, {}, symbologyIdentifier}; + BarcodeFormat::DataBarExpanded, {}, symbologyIdentifier, {}, false, + EstimateLineCount(pairs.front(), pairs.back())}; } } // namespace ZXing::OneD diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index ac9844f3fa..fa5ce47f14 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -210,8 +210,8 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, for (const auto& rightPair : prevState->rightPairs) if (ChecksumIsValid(leftPair, rightPair)) return {TextDecoder::FromLatin1(ConstructText(leftPair, rightPair)), - EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar, - {}, std::move(symbologyIdentifier)}; + EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar, {}, + std::move(symbologyIdentifier), {}, false, EstimateLineCount(leftPair, rightPair)}; #endif // guaratee progress (see loop in ODReader.cpp) From 17fd4fdc3e392f52e58f0b2b591b0e0e8b6ccf53 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Apr 2022 11:38:44 +0200 Subject: [PATCH 0128/1315] ODReader: fix build regression (insufficient attention on my side...) --- core/src/oned/ODReader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 7be4265a80..2eea069d55 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -197,7 +197,6 @@ static Results DoDecode(const std::vector>& readers, }) == maxSymbols) { goto out; } - } } // make sure we make progress and we start the next try on a bar next.shift(2 - (next.index() % 2)); From e47f28244296c03c5788b082f0b673ef385e80cf Mon Sep 17 00:00:00 2001 From: Markus Fisch Date: Thu, 14 Apr 2022 11:20:43 +0200 Subject: [PATCH 0129/1315] android: remove clearing overlay canvas It's unnecessary, and clears out the camera frame when the underlying surface is the same, which it is for some devices/graphics drivers. --- .../app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt index 0bc84a5300..7c2db15c12 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/PreviewOverlay.kt @@ -63,7 +63,6 @@ class PreviewOverlay constructor(context: Context, attributeSet: AttributeSet?) override fun onDraw(canvas: Canvas) { canvas.apply { - drawColor(0, PorterDuff.Mode.CLEAR) // draw the cropRect, which is relative to the original image orientation save() if (rotation == 90) { From 59b68f854d7f320f7e7e4690f09952993cec629b Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Apr 2022 14:51:27 +0200 Subject: [PATCH 0130/1315] ODReader: improve detection with minLineCount > 1 If minLineCount > 1 then we can improve the likelyhood of a detection by checking additional rows very close to the first detected valid row. This is especially true for the non-tryHarder mode. This prepares the switch to a default minLineCount of 2. --- core/src/oned/ODReader.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 2eea069d55..31b79df8a1 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -102,6 +102,10 @@ static Results DoDecode(const std::vector>& readers, height : // Look at the whole image, not just the center 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image + if (isPure) + minLineCount = 1; + std::vector checkRows; + PatternRow bars; bars.reserve(128); // e.g. EAN-13 has 59 bars/spaces @@ -116,6 +120,15 @@ static Results DoDecode(const std::vector>& readers, break; } + // See if we have additional check rows (see below) to process + if (checkRows.size()) { + --i; + rowNumber = checkRows.back(); + checkRows.pop_back(); + if (rowNumber < 0 || rowNumber >= height) + continue; + } + if (!image.getPatternRow(rowNumber, rotate ? 270 : 0, bars)) continue; @@ -197,6 +210,14 @@ static Results DoDecode(const std::vector>& readers, }) == maxSymbols) { goto out; } + + // if we found a valid code but have a minLineCount > 1, add additional check rows above and + // below the current one + if (checkRows.empty() && minLineCount > 1 && rowStep > 1) { + checkRows = {rowNumber - 1, rowNumber + 1}; + if (rowStep > 2) + checkRows.insert(checkRows.end(), {rowNumber - 2, rowNumber + 2}); + } } // make sure we make progress and we start the next try on a bar next.shift(2 - (next.index() % 2)); From 11fc1d889071562a9eb4fb7ac94e65f220dd86ab Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Apr 2022 14:58:42 +0200 Subject: [PATCH 0131/1315] ODReader: change default value of DecodingHints::minLineCount to 2 This change prioritizes quality over quantity as the default setting. It results in a few 'lost' samples from the test images set but removes almost all remaining misreads. The user can get back to the old behavior my setting minLineCount to 1. This fixes #255. --- core/src/DecodeHints.h | 4 +-- test/blackbox/BlackboxTestRunner.cpp | 46 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 7b308e9ebf..a19f56e17b 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -62,7 +62,7 @@ class DecodeHints std::string _characterSet; std::vector _allowedLengths; BarcodeFormats _formats = BarcodeFormat::None; - uint8_t _minLineCount = 1; + uint8_t _minLineCount = 2; public: // bitfields don't get default initialized to 0. @@ -95,7 +95,7 @@ class DecodeHints /// Set to true if the input contains nothing but a perfectly aligned barcode (generated image) ZX_PROPERTY(bool, isPure, setIsPure) - /// The number of scan lines in a 1D barcode that have to be equal to accept the result, default is 1 + /// The number of scan lines in a 1D barcode that have to be equal to accept the result, default is 2 ZX_PROPERTY(uint8_t, minLineCount, setMinLineCount) /// Specifies what character encoding to use when decoding, where applicable. diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 703c88dc94..7e6112eaf1 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -396,8 +396,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("codabar-2", "Codabar", 4, { - { 3, 3, 0 }, - { 3, 3, 180 }, + { 2, 3, 0 }, + { 2, 3, 180 }, }); runTests("code39-1", "Code39", 4, { @@ -426,7 +426,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("code128-2", "Code128", 21, { - { 19, 21, 0 }, + { 18, 21, 0 }, { 19, 21, 180 }, }); @@ -442,13 +442,13 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("ean13-1", "EAN-13", 31, { - { 26, 29, 0 }, + { 24, 29, 0 }, { 23, 29, 180 }, }); runTests("ean13-2", "EAN-13", 24, { - { 7, 14, 0 }, - { 7, 14, 180 }, + { 7, 13, 0 }, + { 7, 13, 180 }, }); runTests("ean13-3", "EAN-13", 21, { @@ -457,12 +457,12 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("ean13-4", "EAN-13", 22, { - { 7, 14, 0 }, - { 8, 14, 180 }, + { 6, 13, 0 }, + { 8, 13, 180 }, }); runTests("ean13-extension-1", "EAN-13", 5, { - { 4, 5, 0 }, + { 3, 5, 0 }, { 3, 5, 180 }, }, DecodeHints().setEanAddOnSymbol(EanAddOnSymbol::Require)); @@ -485,33 +485,33 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("upca-1", "UPC-A", 12, { - { 9, 12, 0, 1, 0 }, - { 11, 12, 0, 1, 180 }, + { 9, 12, 0 }, + { 11, 12, 180 }, }); runTests("upca-2", "UPC-A", 36, { - { 17, 23, 0 }, - { 18, 23, 180 }, + { 17, 22, 0 }, + { 16, 22, 180 }, }); runTests("upca-3", "UPC-A", 21, { - { 7, 10, 0, 1, 0 }, - { 8, 10, 0, 1, 180 }, + { 7, 10, 0 }, + { 8, 10, 180 }, }); runTests("upca-4", "UPC-A", 19, { - { 9, 11, 0, 1, 0 }, - { 9, 11, 0, 1, 180 }, + { 8, 12, 0 }, + { 9, 12, 180 }, }); runTests("upca-5", "UPC-A", 32, { { 17, 20, 0 }, - { 19, 20, 180 }, + { 18, 20, 180 }, }); runTests("upca-extension-1", "UPC-A", 6, { - { 4, 6, 0 }, - { 4, 6, 180 }, + { 4, 4, 0 }, + { 3, 4, 180 }, }, DecodeHints().setEanAddOnSymbol(EanAddOnSymbol::Require)); runTests("upce-1", "UPC-E", 3, { @@ -521,13 +521,13 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("upce-2", "UPC-E", 28, { - { 19, 22, 0, 1, 0 }, + { 17, 22, 0, 1, 0 }, { 20, 22, 1, 1, 180 }, }); runTests("upce-3", "UPC-E", 11, { - { 6, 8, 0 }, - { 6, 8, 180 }, + { 5, 7, 0 }, + { 6, 7, 180 }, }); runTests("rss14-1", "DataBar", 6, { From e9a3d56fbe94b98dfa3e519389734ae1afb9bec3 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Apr 2022 20:50:22 +0200 Subject: [PATCH 0132/1315] DataBar: fix numerous issues related to the position estimation Position and Linecount estimation was completely broken. --- core/src/oned/ODDataBarReader.cpp | 28 +++++++++++++++++----------- test/blackbox/BlackboxTestRunner.cpp | 4 ++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index fa5ce47f14..e2d8af00d1 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -127,8 +127,8 @@ static Pair ReadPair(const PatternView& view, bool rightPair) if (auto outside = ReadDataCharacter(rightPair ? RightChar(view) : LeftChar(view), true, rightPair)) if (auto inside = ReadDataCharacter(rightPair ? LeftChar(view) : RightChar(view), false, rightPair)) { // include left and right guards - int xStart = view.pixelsInFront() - (rightPair ? 0 : view[-1] + std::min(view[-2], view[-1])); - int xStop = view.pixelsTillEnd() + (rightPair ? view[FULL_PAIR_SIZE] + view[FULL_PAIR_SIZE + 1] : 0); + int xStart = view.pixelsInFront() - view[-1]; + int xStop = view.pixelsTillEnd() + 2 * view[FULL_PAIR_SIZE]; return {outside, inside, pattern, xStart, xStop}; } @@ -167,7 +167,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const { #if 0 // non-stacked version - next = next.subView(-1, FULL_PAIR_SIZE + 2); + next = next.subView(-1, FULL_PAIR_SIZE); // yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern) while (next.shift(2)) { if (IsLeftPair(next)) { @@ -184,7 +184,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, state.reset(new State); auto* prevState = static_cast(state.get()); - next = next.subView(0, FULL_PAIR_SIZE + 2); // +2 reflects the guard pattern on the right + next = next.subView(0, FULL_PAIR_SIZE); // yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern) while (next.shift(1)) { if (IsLeftPair(next)) { @@ -203,15 +203,21 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, } } - // Symbology identifier ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - std::string symbologyIdentifier("]e0"); - for (const auto& leftPair : prevState->leftPairs) for (const auto& rightPair : prevState->rightPairs) - if (ChecksumIsValid(leftPair, rightPair)) - return {TextDecoder::FromLatin1(ConstructText(leftPair, rightPair)), - EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar, {}, - std::move(symbologyIdentifier), {}, false, EstimateLineCount(leftPair, rightPair)}; + if (ChecksumIsValid(leftPair, rightPair)) { + // Symbology identifier ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 + std::string symbologyIdentifier("]e0"); + + Result res{TextDecoder::FromLatin1(ConstructText(leftPair, rightPair)), + EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar, + {}, std::move(symbologyIdentifier), {}, false, + EstimateLineCount(leftPair, rightPair)}; + + prevState->leftPairs.erase(leftPair); + prevState->rightPairs.erase(rightPair); + return res; + } #endif // guaratee progress (see loop in ODReader.cpp) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 7e6112eaf1..146309d123 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -536,8 +536,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("rss14-2", "DataBar", 16, { - { 8 , 10, 0 }, - { 10, 10, 180 }, + { 8, 10, 0 }, + { 9, 10, 180 }, }); runTests("rssexpanded-1", "DataBarExpanded", 33, { From 5c8898fee887347f13abfe676d22f75a59cf1ed7 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Apr 2022 20:54:24 +0200 Subject: [PATCH 0133/1315] DataBar: skip view of right pair to make optimal progress (performance fix) --- core/src/oned/ODDataBarReader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index e2d8af00d1..1c4f2a38c9 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -199,6 +199,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, if (auto rightPair = ReadPair(next, true)) { rightPair.y = rowNumber; prevState->rightPairs.insert(rightPair); + next.shift(FULL_PAIR_SIZE + 2); } } } From b4abea93b1ba02b4e87ef297ec04666046be013c Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Apr 2022 20:57:32 +0200 Subject: [PATCH 0134/1315] ODReader: check for next.size() instead of isValid() (performance fix) An empty PatternView after `extend()` is valid but uninteresting to look at again. --- core/src/oned/ODReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 31b79df8a1..db7ec26593 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -222,7 +222,7 @@ static Results DoDecode(const std::vector>& readers, // make sure we make progress and we start the next try on a bar next.shift(2 - (next.index() % 2)); next.extend(); - } while (tryHarder && next.isValid()); + } while (tryHarder && next.size()); } } } From 922cd41c332c7b8a8fb4e771d0f1713405c284ca Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Apr 2022 21:35:16 +0200 Subject: [PATCH 0135/1315] DataBarExpanded: fix position estimate (see also earlier DataBar fix) --- core/src/oned/ODDataBarExpandedReader.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 5a9bfdbe02..bccc384467 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -316,6 +316,14 @@ static Pairs FindValidSequence(PairMap& all) return stack; } +static void RemovePairs(PairMap& all, const Pairs& pairs) +{ + for(const auto& p : pairs) + if (auto i = Find(all[p.finder], p); i != all[p.finder].end()) + if (--i->count == 0) + all[p.finder].erase(i); +} + static BitArray BuildBitArray(const Pairs& pairs) { BitArray res; @@ -373,9 +381,13 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, if (txt.empty()) return Result(DecodeStatus::NotFound); + RemovePairs(allPairs, pairs); + // Symbology identifier ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 std::string symbologyIdentifier("]e0"); + // TODO: EstimatePosition misses part of the symbol in the stacked case where the last row contains less pairs than + // the first return {TextDecoder::FromLatin1(txt), EstimatePosition(pairs.front(), pairs.back()), BarcodeFormat::DataBarExpanded, {}, symbologyIdentifier, {}, false, EstimateLineCount(pairs.front(), pairs.back())}; From 52e0235b1ed06c77e0aa7b52223502d028860f05 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Apr 2022 21:42:57 +0200 Subject: [PATCH 0136/1315] Result: move intersection check of symbol position into operator==() Two results are now only considered equal if they are believed to represent the same symbol, not only the same data/format. In the 1D case, we use the heuristic from the `ODReader` that incorporates distance and length of the 2 symbols. This prepares the upcoming multi-resolution disambiguation. --- core/src/Quadrilateral.h | 8 ++++++++ core/src/Result.cpp | 17 +++++++++++++++++ core/src/Result.h | 4 +--- core/src/oned/ODReader.cpp | 34 ++++++++++++++-------------------- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/core/src/Quadrilateral.h b/core/src/Quadrilateral.h index d11117a4ea..90f5aaae7f 100644 --- a/core/src/Quadrilateral.h +++ b/core/src/Quadrilateral.h @@ -102,6 +102,14 @@ bool IsConvex(const Quadrilateral& poly) return M / m < 4.0; } +template +bool IsIntersecting(const Quadrilateral& a, const Quadrilateral& b) +{ + // TODO: this is only a quick and dirty approximation that works for the trivial standard cases + bool x = b.topRight().x < a.topLeft().x || b.topLeft().x > a.topRight().x; + bool y = b.bottomLeft().y < a.topLeft().y || b.topLeft().y > a.bottomLeft().y; + return !(x || y); +} } // ZXing diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 60faebe943..2d959d4ec5 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -55,4 +55,21 @@ int Result::orientation() const return std::lround(_position.orientation() * 180 / std_numbers_pi_v); } +bool Result::operator==(const Result& o) const +{ + if (format() != o.format() || text() != o.text()) + return false; + + if (BarcodeFormats(BarcodeFormat::TwoDCodes).testFlag(format())) + return IsIntersecting(position(), o.position()); + + // if one line is less than half the length of the other away from the + // latter, we consider it to belong to the same symbol + auto dTop = maxAbsComponent(o.position().topLeft() - position().topLeft()); + auto dBot = maxAbsComponent(o.position().bottomLeft() - position().topLeft()); + auto length = maxAbsComponent(position().topLeft() - position().bottomRight()); + + return std::min(dTop, dBot) < length / 2; +} + } // ZXing diff --git a/core/src/Result.h b/core/src/Result.h index 789af3d956..20116a6884 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -139,9 +139,7 @@ class Result ++_lineCount; } - bool operator==(const Result& o) const { - return text() == o.text() && format() == o.format(); - } + bool operator==(const Result& o) const; private: DecodeStatus _status = DecodeStatus::NoError; diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index db7ec26593..851427e0d4 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -176,29 +176,23 @@ static Results DoDecode(const std::vector>& readers, // check if we know this code already for (auto& other : res) { if (other == result) { + // merge the position information auto dTop = maxAbsComponent(other.position().topLeft() - result.position().topLeft()); auto dBot = maxAbsComponent(other.position().bottomLeft() - result.position().topLeft()); - auto length = maxAbsComponent(other.position().topLeft() - other.position().bottomRight()); - // if the new line is less than half the length of the existing result away from the - // latter, we consider it to belong to the same symbol - if (std::min(dTop, dBot) < length / 2) { - // if so, merge the position information - auto points = other.position(); - if (dTop < dBot || - (dTop == dBot && rotate ^ (sumAbsComponent(points[0]) > - sumAbsComponent(result.position()[0])))) { - points[0] = result.position()[0]; - points[1] = result.position()[1]; - } else { - points[2] = result.position()[2]; - points[3] = result.position()[3]; - } - other.setPosition(points); - other.incrementLineCount(); - // clear the result, so we don't insert it again below - result = Result(DecodeStatus::NotFound); - break; + auto points = other.position(); + if (dTop < dBot || (dTop == dBot && rotate ^ (sumAbsComponent(points[0]) > + sumAbsComponent(result.position()[0])))) { + points[0] = result.position()[0]; + points[1] = result.position()[1]; + } else { + points[2] = result.position()[2]; + points[3] = result.position()[3]; } + other.setPosition(points); + other.incrementLineCount(); + // clear the result, so we don't insert it again below + result = Result(DecodeStatus::NotFound); + break; } } From f17785ee66b981955c43bd5e45ab6e6a69ea62f7 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 15:46:27 +0200 Subject: [PATCH 0137/1315] Implement MultiResolution detection option This adds 2 new DecodingHints properties: a) `multiResolutionThreshold` Every input image with a higher resolution as the given threshold will be additionally scanned in downsampled resolutions. This helps with noise in very high res images and specifically in 2D codes where the module size is >8 pixels. See #282 for an example. This feature is currently only enabled in the `ReadBarcodes` function. This is currently an experimental feature to gather some feedback. b) `maxNumberOfSymbols` Specify the maximum number of results to produce. Setting this to 1 makes `ReadBarcodes` conceptually behave like `ReadBardcode` (and will likely do exactly that in the future). --- core/src/DecodeHints.h | 10 +++- core/src/MultiFormatReader.cpp | 9 ++-- core/src/MultiFormatReader.h | 2 +- core/src/Quadrilateral.h | 6 +++ core/src/ReadBarcode.cpp | 97 ++++++++++++++++++++++++++++------ 5 files changed, 104 insertions(+), 20 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index a19f56e17b..dffbee6f35 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -62,7 +62,9 @@ class DecodeHints std::string _characterSet; std::vector _allowedLengths; BarcodeFormats _formats = BarcodeFormat::None; + uint16_t _multiResolutionThreshold = 0xffff; uint8_t _minLineCount = 2; + uint8_t _maxNumberOfSymbols = 0xff; public: // bitfields don't get default initialized to 0. @@ -92,12 +94,18 @@ class DecodeHints /// Binarizer to use internally when using the ReadBarcode function ZX_PROPERTY(Binarizer, binarizer, setBinarizer) - /// Set to true if the input contains nothing but a perfectly aligned barcode (generated image) + /// Set to true if the input contains nothing but a single perfectly aligned barcode (generated image) ZX_PROPERTY(bool, isPure, setIsPure) + /// Image size (width or height) threshold at which to start multi-resolution scanning + ZX_PROPERTY(uint16_t, multiResolutionThreshold, setMultiResolutionThreshold) + /// The number of scan lines in a 1D barcode that have to be equal to accept the result, default is 2 ZX_PROPERTY(uint8_t, minLineCount, setMinLineCount) + /// The maximum number of symbols (barcodes) to detect / look for in the image with ReadBarcodes + ZX_PROPERTY(uint8_t, maxNumberOfSymbols, setMaxNumberOfSymbols) + /// Specifies what character encoding to use when decoding, where applicable. ZX_PROPERTY(std::string, characterSet, setCharacterSet) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index ceacf1e315..7f01e33ee7 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -74,13 +74,16 @@ MultiFormatReader::read(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); } -Results MultiFormatReader::readMultiple(const BinaryBitmap& image) const +Results MultiFormatReader::readMultiple(const BinaryBitmap& image, int maxSymbols) const { std::vector res; for (const auto& reader : _readers) { - auto r = reader->decode(image, 0); - res.insert(res.end(), r.begin(), r.end()); + auto r = reader->decode(image, maxSymbols); + maxSymbols -= r.size(); + res.insert(res.end(), std::move_iterator(r.begin()), std::move_iterator(r.end())); + if (maxSymbols <= 0) + break; } // sort results based on their position on the image diff --git a/core/src/MultiFormatReader.h b/core/src/MultiFormatReader.h index 4532766666..defafc4b1f 100644 --- a/core/src/MultiFormatReader.h +++ b/core/src/MultiFormatReader.h @@ -45,7 +45,7 @@ class MultiFormatReader Result read(const BinaryBitmap& image) const; // WARNING: this API is experimental and may change/disappear - Results readMultiple(const BinaryBitmap& image) const; + Results readMultiple(const BinaryBitmap& image, int maxSymbols = 0xFF) const; private: std::vector> _readers; diff --git a/core/src/Quadrilateral.h b/core/src/Quadrilateral.h index 90f5aaae7f..e95a74e172 100644 --- a/core/src/Quadrilateral.h +++ b/core/src/Quadrilateral.h @@ -102,6 +102,12 @@ bool IsConvex(const Quadrilateral& poly) return M / m < 4.0; } +template +Quadrilateral Scale(const Quadrilateral& q, int factor) +{ + return {factor * q[0], factor * q[1], factor * q[2], factor * q[3]}; +} + template bool IsIntersecting(const Quadrilateral& a, const Quadrilateral& b) { diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 7084ac06c4..be885b5053 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -54,7 +54,47 @@ static LumImage ExtractLum(const ImageView& iv, P projection) return res; } -ImageView SetupLumImageView(const ImageView& iv, LumImage& lum, const DecodeHints& hints) +class LumImagePyramid +{ + static constexpr int N = 3; + std::vector buffers; + + void addLayer() + { + auto siv = layers.back(); + buffers.emplace_back(siv.width() / N, siv.height() / N); + layers.push_back(buffers.back()); + auto& div = buffers.back(); + auto* d = div.data(); + + for (int dy = 0; dy < div.height(); ++dy) + for (int dx = 0; dx < div.width(); ++dx) { + int sum = (N * N) / 2; + for (int ty = 0; ty < N; ++ty) + for (int tx = 0; tx < N; ++tx) + sum += *siv.data(dx * N + tx, dy * N + ty); + *d++ = sum / (N * N); + } + } + +public: + std::vector layers; + + LumImagePyramid(const ImageView& iv, int threshold) + { + layers.push_back(iv); + while (threshold > 0 && std::max(layers.back().width(), layers.back().height()) > threshold) + addLayer(); +#if 0 + // Reversing the layers means we'd start with the smallest. that can make sense if we are only looking for a + // single symbol. If we start with the higher resolution, we get better (high res) position information. + // TODO: see if masking out higher res layers based on found symbols in lower res helps overall performance. + std::reverse(layers.begin(), layers.end()); +#endif + } +}; + +ImageView SetupLumImageView(ImageView iv, LumImage& lum, const DecodeHints& hints) { if (iv.format() == ImageFormat::None) throw std::invalid_argument("Invalid image format"); @@ -73,32 +113,59 @@ ImageView SetupLumImageView(const ImageView& iv, LumImage& lum, const DecodeHint return iv; } +std::unique_ptr CreateBitmap(ZXing::Binarizer binarizer, const ImageView& iv) +{ + switch (binarizer) { + case Binarizer::BoolCast: return std::make_unique(iv, 0); + case Binarizer::FixedThreshold: return std::make_unique(iv, 127); + case Binarizer::GlobalHistogram: return std::make_unique(iv); + case Binarizer::LocalAverage: return std::make_unique(iv); + } + return {}; // silence gcc warning +} + Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) { +#if 0 + auto ress = ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1)); + return ress.empty() ? Result(DecodeStatus::NotFound) : ress.front(); +#else LumImage lum; ImageView iv = SetupLumImageView(_iv, lum, hints); - switch (hints.binarizer()) { - case Binarizer::BoolCast: return MultiFormatReader(hints).read(ThresholdBinarizer(iv, 0)); - case Binarizer::FixedThreshold: return MultiFormatReader(hints).read(ThresholdBinarizer(iv, 127)); - case Binarizer::GlobalHistogram: return MultiFormatReader(hints).read(GlobalHistogramBinarizer(iv)); - case Binarizer::LocalAverage: return MultiFormatReader(hints).read(HybridBinarizer(iv)); - } - return Result(DecodeStatus::FormatError); + return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)); +#endif } Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) { LumImage lum; ImageView iv = SetupLumImageView(_iv, lum, hints); - - switch (hints.binarizer()) { - case Binarizer::BoolCast: return MultiFormatReader(hints).readMultiple(ThresholdBinarizer(iv, 0)); - case Binarizer::FixedThreshold: return MultiFormatReader(hints).readMultiple(ThresholdBinarizer(iv, 127)); - case Binarizer::GlobalHistogram: return MultiFormatReader(hints).readMultiple(GlobalHistogramBinarizer(iv)); - case Binarizer::LocalAverage: return MultiFormatReader(hints).readMultiple(HybridBinarizer(iv)); + MultiFormatReader reader(hints); + + if (hints.isPure()) + return {reader.read(*CreateBitmap(hints.binarizer(), iv))}; + + LumImagePyramid pyramid(iv, hints.multiResolutionThreshold()); + + Results results; + int maxSymbols = hints.maxNumberOfSymbols(); + for (auto&& iv : pyramid.layers) { + auto bitmap = CreateBitmap(hints.binarizer(), iv); + auto rs = reader.readMultiple(*bitmap, maxSymbols); + for (auto& r : rs) { + if (iv.width() != _iv.width()) + r.setPosition(Scale(r.position(), _iv.width() / iv.width())); + if (!Contains(results, r)) { + results.push_back(std::move(r)); + --maxSymbols; + } + } + if (maxSymbols <= 0) + break; } - return {}; + + return results; } } // ZXing From c54920165db25f6e25889e2958189efed591c728 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 15:47:24 +0200 Subject: [PATCH 0138/1315] cleanup: remove stale IsIntercting function that was overlooked before --- core/src/oned/ODReader.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 851427e0d4..0506d54e1a 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -66,13 +66,6 @@ Reader::Reader(const DecodeHints& hints) : Reader::~Reader() = default; -static bool IsIntersecting(QuadrilateralI a, QuadrilateralI b) -{ - bool x = b.topRight().x < a.topLeft().x || b.topLeft().x > a.topRight().x; - bool y = b.bottomLeft().y < a.topLeft().y || b.topLeft().y > a.bottomLeft().y; - return !(x || y); -} - /** * We're going to examine rows from the middle outward, searching alternately above and below the * middle, and farther out each time. rowStep is the number of rows between each successive From f97c382af2165362667131febfe597b20c46d4b0 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 20:53:00 +0200 Subject: [PATCH 0139/1315] example: enable the use of the new multi resolution scanning --- example/ZXingReader.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 0db343bbdc..1da3a84ba7 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -41,6 +41,7 @@ static void PrintUsage(const char* exePath) << " -fast Skip some lines/pixels during detection (faster)\n" << " -norotate Don't try rotated image during detection (faster)\n" << " -format Only detect given format(s) (faster)\n" + << " -multires Image size threshold at which to start multi-resolution scanning, 0 disables it\n" << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" << " -1 Print only file name, text and status on one line per file/barcode\n" << " -escape Escape non-graphical characters in angle brackets (ignored for -1 option, which always escapes)\n" @@ -73,6 +74,15 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi std::cerr << e.what() << "\n"; return false; } + } else if (strcmp(argv[i], "-multires") == 0) { + if (++i == argc) + return false; + try { + hints.setMultiResolutionThreshold(std::stoi(argv[i])); + } catch (const std::exception& e) { + std::cerr << e.what() << "\n"; + return false; + } } else if (strcmp(argv[i], "-1") == 0) { oneLine = true; } else if (strcmp(argv[i], "-escape") == 0) { @@ -121,6 +131,8 @@ int main(int argc, char* argv[]) bool angleEscape = false; int ret = 0; + hints.setMultiResolutionThreshold(500); // enable the feature by default + if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, filePaths, outPath)) { PrintUsage(argv[0]); return -1; From c74a8553606fbb6f7673f910039d45f557df6fd0 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 22:39:35 +0200 Subject: [PATCH 0140/1315] ITFReader: code cosmetic --- core/src/oned/ODITFReader.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 6ae6c47c2e..26051f2205 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -27,15 +27,14 @@ namespace ZXing::OneD { /** Valid ITF lengths. Anything longer than the largest value is also allowed. */ -static const std::array DEFAULT_ALLOWED_LENGTHS = { 6, 8, 10, 12, 14 }; +constexpr auto DEFAULT_ALLOWED_LENGTHS = { 6, 8, 10, 12, 14 }; ITFReader::ITFReader(const DecodeHints& hints) : _allowedLengths(hints.allowedLengths()), _usingCheckDigit(hints.assumeITFCheckDigit()) { - if (_allowedLengths.empty()) { + if (_allowedLengths.empty()) _allowedLengths.assign(DEFAULT_ALLOWED_LENGTHS.begin(), DEFAULT_ALLOWED_LENGTHS.end()); - } } constexpr auto START_PATTERN_ = FixedPattern<4, 4>{1, 1, 1, 1}; @@ -88,13 +87,13 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt if (!IsRightGuard(next, STOP_PATTERN_1, minQuietZone) && !IsRightGuard(next, STOP_PATTERN_2, minQuietZone)) return Result(DecodeStatus::NotFound); + if (_usingCheckDigit && !GTIN::IsCheckDigitValid(txt)) + return Result(DecodeStatus::ChecksumError); + // Symbology identifier ISO/IEC 16390:2007 Annex C Table C.1 // See also GS1 General Specifications 5.1.3 Figure 5.1.3-2 std::string symbologyIdentifier("]I0"); // No check character validation - if (_usingCheckDigit && !GTIN::IsCheckDigitValid(txt)) - return Result(DecodeStatus::ChecksumError); - if (_usingCheckDigit || (txt.size() == 14 && GTIN::IsCheckDigitValid(txt))) // If no hint test if valid ITF-14 symbologyIdentifier = "]I1"; // Modulo 10 symbol check character validated and transmitted From fb495c8641276d9e0914d1be7a2dacb0cf0d1ffe Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 22:46:15 +0200 Subject: [PATCH 0141/1315] DecodingHints: rename `assume...CheckDigit` to `validate...CheckSum` Fixes #298. See there for details. --- core/src/DecodeHints.h | 36 +++++++++++++-------------- core/src/oned/ODCode39Reader.cpp | 8 +++--- core/src/oned/ODCode39Reader.h | 2 +- core/src/oned/ODITFReader.cpp | 6 ++--- core/src/oned/ODITFReader.h | 2 +- test/unit/oned/ODCode39ReaderTest.cpp | 4 +-- 6 files changed, 28 insertions(+), 30 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index dffbee6f35..b18bcb576a 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -2,6 +2,7 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2020 Axel Waggershauser * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,9 +53,8 @@ class DecodeHints bool _tryRotate : 1; bool _isPure : 1; bool _tryCode39ExtendedMode : 1; - bool _assumeCode39CheckDigit : 1; - bool _assumeITFCheckDigit : 1; - bool _assumeGS1 : 1; + bool _validateCode39CheckSum : 1; + bool _validateITFCheckSum : 1; bool _returnCodabarStartEnd : 1; Binarizer _binarizer : 2; EanAddOnSymbol _eanAddOnSymbol : 2; @@ -69,8 +69,8 @@ class DecodeHints public: // bitfields don't get default initialized to 0. DecodeHints() - : _tryHarder(1), _tryRotate(1), _isPure(0), _tryCode39ExtendedMode(0), _assumeCode39CheckDigit(0), - _assumeITFCheckDigit(0), _assumeGS1(0), _returnCodabarStartEnd(0), _binarizer(Binarizer::LocalAverage), + : _tryHarder(1), _tryRotate(1), _isPure(0), _tryCode39ExtendedMode(0), _validateCode39CheckSum(0), + _validateITFCheckSum(0), _returnCodabarStartEnd(0), _binarizer(Binarizer::LocalAverage), _eanAddOnSymbol(EanAddOnSymbol::Ignore) {} @@ -78,10 +78,6 @@ class DecodeHints TYPE GETTER() const noexcept { return _##GETTER; } \ DecodeHints& SETTER(TYPE v) { return _##GETTER = std::move(v), *this; } -#define ZX_PROPERTY_DEPRECATED(TYPE, GETTER, SETTER) \ - [[deprecated]] TYPE GETTER() const noexcept { return _##GETTER; } \ - [[deprecated]] DecodeHints& SETTER(TYPE v) { return _##GETTER = std::move(v), *this; } - /// Specify a set of BarcodeFormats that should be searched for, the default is all supported formats. ZX_PROPERTY(BarcodeFormats, formats, setFormats) @@ -115,17 +111,11 @@ class DecodeHints /// If true, the Code-39 reader will try to read extended mode. ZX_PROPERTY(bool, tryCode39ExtendedMode, setTryCode39ExtendedMode) - /// Assume Code-39 codes employ a check digit. - ZX_PROPERTY(bool, assumeCode39CheckDigit, setAssumeCode39CheckDigit) - - /// Assume ITF codes employ a GS1 check digit. - ZX_PROPERTY(bool, assumeITFCheckDigit, setAssumeITFCheckDigit) + /// Assume Code-39 codes employ a check digit and validate it. + ZX_PROPERTY(bool, validateCode39CheckSum, setValidateCode39CheckSum) - /** - * Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed. - * NOTE: used to affect FNC1 handling for Code 128 (aka GS1-128) but behavior now based on position of FNC1. - */ - ZX_PROPERTY_DEPRECATED(bool, assumeGS1, setAssumeGS1) + /// Assume ITF codes employ a GS1 check digit and validate it. + ZX_PROPERTY(bool, validateITFCheckSum, setValidateITFCheckSum) /** * If true, return the start and end digits in a Codabar barcode instead of stripping them. They @@ -140,6 +130,14 @@ class DecodeHints #undef ZX_PROPERTY #undef ZX_PROPERTY_DEPRECATED + /// NOTE: used to affect FNC1 handling for Code 128 (aka GS1-128) but behavior now based on position of FNC1. + [[deprecated]] bool assumeGS1() const noexcept { return true; } + [[deprecated]] DecodeHints& setAssumeGS1(bool v [[maybe_unused]]) { return *this; } + + /// NOTE: use validateCode39CheckSum + [[deprecated]] bool assumeCode39CheckDigit() const noexcept { return validateCode39CheckSum(); } + [[deprecated]] DecodeHints& setAssumeCode39CheckDigit(bool v) { return setValidateCode39CheckSum(v); } + bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f); } bool hasNoFormat() const noexcept { return _formats.empty(); } }; diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index dd25f1ae4c..cfe376326c 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -88,14 +88,14 @@ DecodeExtendedCode39AndCode93(std::string& encoded, const char ctrl[4]) Code39Reader::Code39Reader(const DecodeHints& hints) : _extendedMode(hints.tryCode39ExtendedMode()), - _usingCheckDigit(hints.assumeCode39CheckDigit()) + _validateCheckSum(hints.validateCode39CheckSum()) { } Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { // minimal number of characters that must be present (including start, stop and checksum characters) - int minCharCount = _usingCheckDigit ? 4 : 3; + int minCharCount = _validateCheckSum ? 4 : 3; auto isStartOrStopSymbol = [](char c) { return c == '*'; }; // provide the indices with the narrow bars/spaces which have to be equally wide @@ -132,7 +132,7 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique if (Size(txt) < minCharCount - 2 || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) return Result(DecodeStatus::NotFound); - if (_usingCheckDigit) { + if (_validateCheckSum) { auto checkDigit = txt.back(); txt.pop_back(); int checksum = TransformReduce(txt, 0, [](char c) { return IndexOf(ALPHABET, c); }); @@ -145,7 +145,7 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique // Symbology identifier modifiers ISO/IEC 16388:2007 Annex C Table C.1 static const int symbologyModifiers[4] = { 0, 3 /*checksum*/, 4 /*extended*/, 7 /*checksum,extended*/ }; - int symbologyIdModifier = symbologyModifiers[(int)_extendedMode * 2 + (int)_usingCheckDigit]; + int symbologyIdModifier = symbologyModifiers[(int)_extendedMode * 2 + (int)_validateCheckSum]; std::string symbologyIdentifier("]A" + std::to_string(symbologyIdModifier)); diff --git a/core/src/oned/ODCode39Reader.h b/core/src/oned/ODCode39Reader.h index 0573f756fb..5c5daef9f8 100644 --- a/core/src/oned/ODCode39Reader.h +++ b/core/src/oned/ODCode39Reader.h @@ -49,7 +49,7 @@ class Code39Reader : public RowReader private: bool _extendedMode; - bool _usingCheckDigit; + bool _validateCheckSum; }; } // OneD diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 26051f2205..7b0b30cac1 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -31,7 +31,7 @@ constexpr auto DEFAULT_ALLOWED_LENGTHS = { 6, 8, 10, 12, 14 }; ITFReader::ITFReader(const DecodeHints& hints) : _allowedLengths(hints.allowedLengths()), - _usingCheckDigit(hints.assumeITFCheckDigit()) + _validateCheckSum(hints.validateITFCheckSum()) { if (_allowedLengths.empty()) _allowedLengths.assign(DEFAULT_ALLOWED_LENGTHS.begin(), DEFAULT_ALLOWED_LENGTHS.end()); @@ -87,14 +87,14 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt if (!IsRightGuard(next, STOP_PATTERN_1, minQuietZone) && !IsRightGuard(next, STOP_PATTERN_2, minQuietZone)) return Result(DecodeStatus::NotFound); - if (_usingCheckDigit && !GTIN::IsCheckDigitValid(txt)) + if (_validateCheckSum && !GTIN::IsCheckDigitValid(txt)) return Result(DecodeStatus::ChecksumError); // Symbology identifier ISO/IEC 16390:2007 Annex C Table C.1 // See also GS1 General Specifications 5.1.3 Figure 5.1.3-2 std::string symbologyIdentifier("]I0"); // No check character validation - if (_usingCheckDigit || (txt.size() == 14 && GTIN::IsCheckDigitValid(txt))) // If no hint test if valid ITF-14 + if (_validateCheckSum || (txt.size() == 14 && GTIN::IsCheckDigitValid(txt))) // If no hint test if valid ITF-14 symbologyIdentifier = "]I1"; // Modulo 10 symbol check character validated and transmitted int xStop = next.pixelsTillEnd(); diff --git a/core/src/oned/ODITFReader.h b/core/src/oned/ODITFReader.h index 960067775c..322ee17d20 100644 --- a/core/src/oned/ODITFReader.h +++ b/core/src/oned/ODITFReader.h @@ -49,7 +49,7 @@ class ITFReader : public RowReader private: std::vector _allowedLengths; - bool _usingCheckDigit; + bool _validateCheckSum; }; } // OneD diff --git a/test/unit/oned/ODCode39ReaderTest.cpp b/test/unit/oned/ODCode39ReaderTest.cpp index cc265c8d45..c92d88202f 100644 --- a/test/unit/oned/ODCode39ReaderTest.cpp +++ b/test/unit/oned/ODCode39ReaderTest.cpp @@ -49,7 +49,7 @@ TEST(ODCode39ReaderTest, SymbologyIdentifier) { // "A" with checksum PatternRow row({ 2, 1, 1, 1, 1, 2, 1, 1, 2, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2 }); - auto result = parse(row, DecodeHints().setAssumeCode39CheckDigit(true)); + auto result = parse(row, DecodeHints().setValidateCode39CheckSum(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A3"); EXPECT_EQ(result.text(), L"A"); @@ -71,7 +71,7 @@ TEST(ODCode39ReaderTest, SymbologyIdentifier) { // Extended "a" with checksum PatternRow row({ 1, 2, 1, 1, 1, 2, 1, 2, 1, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2, 0, 2, 1, 1, 2, 1, 1, 2, 1, 1 }); - auto result = parse(row, DecodeHints().setTryCode39ExtendedMode(true).setAssumeCode39CheckDigit(true)); + auto result = parse(row, DecodeHints().setTryCode39ExtendedMode(true).setValidateCode39CheckSum(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A7"); EXPECT_EQ(result.text(), L"a"); From 3836f4c998bf059a643cb2e59ad35a96f02bd40b Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 23:41:58 +0200 Subject: [PATCH 0142/1315] Result: add `isMirrored` property This lets the client know whether or not the symbol was mirrored/flipped. This is currently only implemented for QRCode and DataMatrix symbology. The now unnecessary QRDecoderMetadata class has been removed. --- core/src/DecoderResult.h | 2 + core/src/Result.cpp | 3 +- core/src/Result.h | 8 ++++ core/src/datamatrix/DMDecoder.cpp | 5 ++- core/src/qrcode/QRDecoder.cpp | 3 +- core/src/qrcode/QRDecoderMetadata.h | 45 ------------------- core/src/qrcode/QRReader.cpp | 3 -- example/ZXingReader.cpp | 1 + test/blackbox/BlackboxTestRunner.cpp | 2 + .../datamatrix-1/0123456789.result.txt | 1 + .../abcd-36x12-mirrored.result.txt | 1 + 11 files changed, 21 insertions(+), 53 deletions(-) delete mode 100644 core/src/qrcode/QRDecoderMetadata.h create mode 100644 test/samples/datamatrix-1/abcd-36x12-mirrored.result.txt diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 9d736725bd..30abc8c772 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -47,6 +47,7 @@ class DecoderResult int _erasures = -1; std::string _symbologyIdentifier; StructuredAppendInfo _structuredAppend; + bool _isMirrored = false; bool _readerInit = false; std::shared_ptr _extra; @@ -92,6 +93,7 @@ class DecoderResult ZX_PROPERTY(int, erasures, setErasures) ZX_PROPERTY(std::string, symbologyIdentifier, setSymbologyIdentifier) ZX_PROPERTY(StructuredAppendInfo, structuredAppend, setStructuredAppend) + ZX_PROPERTY(bool, isMirrored, setIsMirrored) ZX_PROPERTY(bool, readerInit, setReaderInit) ZX_PROPERTY(std::shared_ptr, extra, setExtra) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 2d959d4ec5..b5eaa7ab7d 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -43,7 +43,8 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat : _status(decodeResult.errorCode()), _format(format), _text(std::move(decodeResult).text()), _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), _ecLevel(decodeResult.ecLevel()), _symbologyIdentifier(decodeResult.symbologyIdentifier()), - _sai(decodeResult.structuredAppend()), _readerInit(decodeResult.readerInit()) + _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), + _readerInit(decodeResult.readerInit()) { // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) diff --git a/core/src/Result.h b/core/src/Result.h index 20116a6884..4cb8b48369 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -77,6 +77,13 @@ class Result int orientation() const; //< orientation of barcode in degree, see also Position::orientation() + /** + * @brief isMirrored is the symbol mirrored (currently only supported by QRCode and DataMatrix) + */ + bool isMirrored() const { + return _isMirrored; + } + const ByteArray& rawBytes() const { return _rawBytes; } @@ -151,6 +158,7 @@ class Result std::wstring _ecLevel; std::string _symbologyIdentifier; StructuredAppendInfo _sai; + bool _isMirrored = false; bool _readerInit = false; int _lineCount = 0; }; diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 3636938cfd..feb469cb38 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -540,11 +540,12 @@ DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet) return res; //TODO: - // * report mirrored state (see also QRReader) // * unify bit mirroring helper code with QRReader? // * rectangular symbols with the a size of 8 x Y are not supported a.t.m. - if (auto mirroredRes = DoDecode(FlippedL(bits), characterSet); mirroredRes.isValid()) + if (auto mirroredRes = DoDecode(FlippedL(bits), characterSet); mirroredRes.isValid()) { + mirroredRes.setIsMirrored(true); return mirroredRes; + } return res; } diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 342681dd00..cc0899d7c7 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -27,7 +27,6 @@ #include "QRBitMatrixParser.h" #include "QRCodecMode.h" #include "QRDataBlock.h" -#include "QRDecoderMetadata.h" #include "QRFormatInformation.h" #include "ReedSolomonDecoder.h" #include "StructuredAppend.h" @@ -487,7 +486,7 @@ DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) return res; if (auto resMirrored = DoDecode(bits, *version, hintedCharset, true); resMirrored.isValid()) { - resMirrored.setExtra(std::make_shared(true)); + resMirrored.setIsMirrored(true); return resMirrored; } diff --git a/core/src/qrcode/QRDecoderMetadata.h b/core/src/qrcode/QRDecoderMetadata.h deleted file mode 100644 index 6a23e8002f..0000000000 --- a/core/src/qrcode/QRDecoderMetadata.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "CustomData.h" - -namespace ZXing { -namespace QRCode { - -/** -* Meta-data container for QR Code decoding. Instances of this class may be used to convey information back to the -* decoding caller. Callers are expected to process this. -*/ - -class DecoderMetadata : public CustomData -{ - bool _mirrored; - -public: - explicit DecoderMetadata(bool mirrored) : _mirrored(mirrored) {} - - /** - * @return true if the QR Code was mirrored. - */ - bool isMirrored() const { - return _mirrored; - } -}; - -} // QRCode -} // ZXing diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 5942898075..effd0e44e1 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -57,9 +57,6 @@ Reader::decode(const BinaryBitmap& image) const auto decoderResult = Decode(detectorResult.bits(), _charset); auto position = detectorResult.position(); - // TODO: report the information that the symbol was mirrored back to the caller - //bool isMirrored = decoderResult.extra() && static_cast(decoderResult.extra().get())->isMirrored(); - return Result(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); } diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 1da3a84ba7..8b9355254e 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -191,6 +191,7 @@ int main(int argc, char* argv[]) << "Identifier: " << result.symbologyIdentifier() << "\n" << "Position: " << result.position() << "\n" << "Rotation: " << result.orientation() << " deg\n" + << "IsMirrored: " << (result.isMirrored() ? "true" : "false") << "\n" << "Error: " << ToString(result.status()) << "\n"; auto printOptional = [](const char* key, const std::string& v) { diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 146309d123..1d166babb3 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -94,6 +94,8 @@ static std::string getResultValue(const Result& result, const std::string& key) return result.isLastInSequence() ? "true" : "false"; if (key == "isPartOfSequence") return result.isPartOfSequence() ? "true" : "false"; + if (key == "isMirrored") + return result.isMirrored() ? "true" : "false"; if (key == "readerInit") return result.readerInit() ? "true" : "false"; diff --git a/test/samples/datamatrix-1/0123456789.result.txt b/test/samples/datamatrix-1/0123456789.result.txt index bbec5f6fa7..771cae78da 100644 --- a/test/samples/datamatrix-1/0123456789.result.txt +++ b/test/samples/datamatrix-1/0123456789.result.txt @@ -1 +1,2 @@ symbologyIdentifier=]d1 +isMirrored=false diff --git a/test/samples/datamatrix-1/abcd-36x12-mirrored.result.txt b/test/samples/datamatrix-1/abcd-36x12-mirrored.result.txt new file mode 100644 index 0000000000..f32b8d9e10 --- /dev/null +++ b/test/samples/datamatrix-1/abcd-36x12-mirrored.result.txt @@ -0,0 +1 @@ +isMirrored=true From 7fa9c403507ad22efc4454fa2d93ae8b3a89856b Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 23:43:31 +0200 Subject: [PATCH 0143/1315] DecodeHints: add WARNING experimental comment to multiResolutionThreshold --- core/src/DecodeHints.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index b18bcb576a..a67820b80e 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -94,6 +94,7 @@ class DecodeHints ZX_PROPERTY(bool, isPure, setIsPure) /// Image size (width or height) threshold at which to start multi-resolution scanning + // WARNING: this API is experimental and may change/disappear ZX_PROPERTY(uint16_t, multiResolutionThreshold, setMultiResolutionThreshold) /// The number of scan lines in a 1D barcode that have to be equal to accept the result, default is 2 From ca9996f871063d2d14797e5c90c6fc317abfb0c6 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 16 Apr 2022 23:47:21 +0200 Subject: [PATCH 0144/1315] cmake: fix build regression (remove QRDecoderMetadata.h from CMakeLists) --- core/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index f6f8561349..0d4bff9f0c 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -339,7 +339,6 @@ if (BUILD_READERS) src/qrcode/QRDataMask.h src/qrcode/QRDecoder.h src/qrcode/QRDecoder.cpp - src/qrcode/QRDecoderMetadata.h src/qrcode/QRDetector.h src/qrcode/QRDetector.cpp src/qrcode/QRECB.h From 47cad821c640d08657a9adeb944b4fd6e19ae839 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 17 Apr 2022 19:26:51 +0200 Subject: [PATCH 0145/1315] Result: micro optimization of construction (more movable parameters) --- core/src/Result.cpp | 15 ++++++++------- core/src/Result.h | 8 ++++---- core/src/oned/ODCodabarReader.cpp | 2 +- core/src/oned/ODCode128Reader.cpp | 6 +++--- core/src/oned/ODCode39Reader.cpp | 2 +- core/src/oned/ODCode93Reader.cpp | 2 +- core/src/oned/ODDataBarExpandedReader.cpp | 2 +- core/src/oned/ODDataBarReader.cpp | 2 +- core/src/oned/ODITFReader.cpp | 2 +- core/src/oned/ODMultiUPCEANReader.cpp | 4 ++-- test/blackbox/BlackboxTestRunner.cpp | 3 ++- 11 files changed, 25 insertions(+), 23 deletions(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index b5eaa7ab7d..1e5bc4d442 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -25,18 +25,19 @@ namespace ZXing { -Result::Result(std::wstring&& text, Position&& position, BarcodeFormat format, ByteArray&& rawBytes, - std::string symbologyIdentifier, StructuredAppendInfo sai, const bool readerInit, int lineCount) +Result::Result(std::wstring&& text, Position&& position, BarcodeFormat format, std::string&& symbologyIdentifier, + ByteArray&& rawBytes, StructuredAppendInfo&& sai, const bool readerInit, int lineCount) : _format(format), _text(std::move(text)), _position(std::move(position)), _rawBytes(std::move(rawBytes)), - _symbologyIdentifier(symbologyIdentifier), _sai(sai), _readerInit(readerInit), _lineCount(lineCount) + _symbologyIdentifier(std::move(symbologyIdentifier)), _sai(std::move(sai)), _readerInit(readerInit), + _lineCount(lineCount) { _numBits = Size(_rawBytes) * 8; } -Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, ByteArray&& rawBytes, - std::string symbologyIdentifier, const bool readerInit) - : Result(TextDecoder::FromLatin1(text), Line(y, xStart, xStop), format, std::move(rawBytes), symbologyIdentifier, - {}, readerInit) +Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, + std::string&& symbologyIdentifier, ByteArray&& rawBytes, const bool readerInit) + : Result(TextDecoder::FromLatin1(text), Line(y, xStart, xStop), format, std::move(symbologyIdentifier), + std::move(rawBytes), {}, readerInit) {} Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format) diff --git a/core/src/Result.h b/core/src/Result.h index 4cb8b48369..c44c95455c 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -42,13 +42,13 @@ class Result public: explicit Result(DecodeStatus status) : _status(status) {} - Result(std::wstring&& text, Position&& position, BarcodeFormat format, ByteArray&& rawBytes = {}, - std::string symbologyIdentifier = "", StructuredAppendInfo sai = {}, const bool readerInit = false, + Result(std::wstring&& text, Position&& position, BarcodeFormat format, std::string&& symbologyIdentifier = "", + ByteArray&& rawBytes = {}, StructuredAppendInfo&& sai = {}, const bool readerInit = false, int lineCount = 0); // 1D convenience constructor - Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, ByteArray&& rawBytes = {}, - std::string symbologyIdentifier = "", const bool readerInit = false); + Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, + std::string&& symbologyIdentifier = "", ByteArray&& rawBytes = {}, const bool readerInit = false); Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index aff361fcbe..354f068511 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -108,7 +108,7 @@ CodabarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptrleftPairs.erase(leftPair); diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 7b0b30cac1..e314b99368 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -98,7 +98,7 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt symbologyIdentifier = "]I1"; // Modulo 10 symbol check character validated and transmitted int xStop = next.pixelsTillEnd(); - return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::ITF, {}, std::move(symbologyIdentifier)); + return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::ITF, std::move(symbologyIdentifier)); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 0d7bb86086..e567a07a84 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -329,8 +329,8 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u if (_hints.eanAddOnSymbol() == EanAddOnSymbol::Require && !addOnRes.isValid()) return Result(DecodeStatus::NotFound); - return {res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, {}, - std::move(symbologyIdentifier)}; + return { + res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, std::move(symbologyIdentifier)}; } } // namespace ZXing::OneD diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 1d166babb3..278cd7171c 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -282,7 +282,8 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi const auto& first = allResults.front(); StructuredAppendInfo sai{ first.sequenceIndex(), first.sequenceSize(), first.sequenceId() }; - return Result(std::move(text), {}, first.format(), {}, first.symbologyIdentifier(), sai, first.readerInit()); + return Result(std::move(text), {}, first.format(), std::string(first.symbologyIdentifier()), {}, std::move(sai), + first.readerInit()); } static void doRunStructuredAppendTest( From eddca679158dd30683785a2bd8e36305e37517d6 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 17 Apr 2022 19:27:48 +0200 Subject: [PATCH 0146/1315] ODReader: update TODO comment --- core/src/oned/ODReader.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 0506d54e1a..c68ca28d89 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -127,11 +127,10 @@ static Results DoDecode(const std::vector>& readers, // While we have the image data in a PatternRow, it's fairly cheap to reverse it in place to // handle decoding upside down barcodes. - // Note: the DataBarExpanded decoder depends on seeing each line from both directions. This - // 'surprising' and inconsistent. It also requires the decoderState to be shared between - // normal and reversed scans, which makes no sense in general because it would mix partial - // detection data from two codes of the same type next to each other. TODO.. - // See also https://github.com/nu-book/zxing-cpp/issues/87 + // TODO: the DataBarExpanded (stacked) decoder depends on seeing each line from both directions. This + // 'surprising' and inconsistent. It also requires the decoderState to be shared between normal and reversed + // scans, which makes no sense in general because it would mix partial detection data from two codes of the same + // type next to each other. See also https://github.com/nu-book/zxing-cpp/issues/87 for (bool upsideDown : {false, true}) { // trying again? if (upsideDown) { From 1e39cbe0505dd3ae25836a123a0498ea90a850d1 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 17 Apr 2022 19:40:10 +0200 Subject: [PATCH 0147/1315] example: use green instead of red to outline the found symbols in -pngout --- example/ZXingReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 8b9355254e..8211565e26 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -112,7 +112,7 @@ void drawLine(const ImageView& image, PointI a, PointI b) PointF dir = bresenhamDirection(PointF(b - a)); for (int i = 0; i < steps; ++i) { auto p = PointI(centered(a + i * dir)); - *((uint32_t*)image.data(p.x, p.y)) = 0xff0000ff; + *((uint32_t*)image.data(p.x, p.y)) = 0xff00ff00; } } From 45c7906ada4ff12e26f0d3dfc4cc29d6310199b8 Mon Sep 17 00:00:00 2001 From: Ralph Corby Date: Tue, 19 Apr 2022 15:27:05 +0100 Subject: [PATCH 0148/1315] Fix threshold test in VS2019 Debug build. The setup code for the test creates a buffer using vector's reserve. This works for the release build but in debug build VS uses checked iterators which causes an error to be generated. Changed reserve to resize. --- test/unit/ThresholdBinarizerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/ThresholdBinarizerTest.cpp b/test/unit/ThresholdBinarizerTest.cpp index ce474938cd..0a9e54f189 100644 --- a/test/unit/ThresholdBinarizerTest.cpp +++ b/test/unit/ThresholdBinarizerTest.cpp @@ -41,7 +41,7 @@ static BitMatrix ParseBitMatrix(const std::string& str, const int width) // Helper to convert a BitMatrix into a black/white ImageView static ImageView getImageView(std::vector &buf, const BitMatrix &bits) { - buf.reserve(bits.width() * bits.height()); + buf.resize(bits.width() * bits.height()); for (int r = 0; r < bits.height(); r++) { const int k = r * bits.width(); for (int c = 0; c < bits.width(); c++) { From 6a0c7fc6aaf93aa7bf831d802cef9122ef8a5048 Mon Sep 17 00:00:00 2001 From: Markus Fisch Date: Tue, 19 Apr 2022 16:59:39 +0200 Subject: [PATCH 0149/1315] android: use row stride for Java impl too There are some really strange row strides on some devices when using the Camera2/CameraX API. Without this, the Java implementation would see a distorted image. --- .../src/main/java/com/example/zxingcppdemo/MainActivity.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt index 40768ba4b3..cffb77c455 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt @@ -118,7 +118,9 @@ class MainActivity : AppCompatActivity() { var resultPoints: List? = null if (binding.java.isChecked) { - val yBuffer = image.planes[0].buffer // Y + val yPlane = image.planes[0] + val yBuffer = yPlane.buffer + val yStride = yPlane.rowStride val data = ByteArray(yBuffer.remaining()) yBuffer.get(data, 0, data.size) image.close() @@ -132,7 +134,7 @@ class MainActivity : AppCompatActivity() { val bitmap = BinaryBitmap( HybridBinarizer( PlanarYUVLuminanceSource( - data, image.width, image.height, + data, yStride, image.height, cropRect.left, cropRect.top, cropRect.width(), cropRect.height(), false ) From 534f853c6bff1692d4482a55c945a48c607deee7 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 19 Apr 2022 21:17:48 +0200 Subject: [PATCH 0150/1315] example: support all pixel formats in drawLine and switch to RGB from RGBX --- example/ZXingReader.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 8211565e26..84b488de44 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -106,13 +106,16 @@ std::ostream& operator<<(std::ostream& os, const Position& points) return os; } -void drawLine(const ImageView& image, PointI a, PointI b) +void drawLine(const ImageView& iv, PointI a, PointI b) { int steps = maxAbsComponent(b - a); PointF dir = bresenhamDirection(PointF(b - a)); + int R = RedIndex(iv.format()), G = GreenIndex(iv.format()), B = BlueIndex(iv.format()); for (int i = 0; i < steps; ++i) { auto p = PointI(centered(a + i * dir)); - *((uint32_t*)image.data(p.x, p.y)) = 0xff00ff00; + auto* dst = const_cast(iv.data(p.x, p.y)); + dst[R] = dst[B] = 0; + dst[G] = 0xff; } } @@ -148,13 +151,13 @@ int main(int argc, char* argv[]) for (const auto& filePath : filePaths) { int width, height, channels; - std::unique_ptr buffer(stbi_load(filePath.c_str(), &width, &height, &channels, 4), stbi_image_free); + std::unique_ptr buffer(stbi_load(filePath.c_str(), &width, &height, &channels, 3), stbi_image_free); if (buffer == nullptr) { std::cerr << "Failed to read image: " << filePath << "\n"; return -1; } - ImageView image{buffer.get(), width, height, ImageFormat::RGBX}; + ImageView image{buffer.get(), width, height, ImageFormat::RGB}; auto results = ReadBarcodes(image, hints); // if we did not find anything, insert a dummy to produce some output for each file @@ -223,7 +226,7 @@ int main(int argc, char* argv[]) } if (Size(filePaths) == 1 && !outPath.empty()) - stbi_write_png(outPath.c_str(), image.width(), image.height(), 4, image.data(0, 0), image.rowStride()); + stbi_write_png(outPath.c_str(), image.width(), image.height(), 3, image.data(0, 0), image.rowStride()); } From 46fdb2f9661e434ea952a86d2ed5ae0a205dbc7b Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 19 Apr 2022 21:20:31 +0200 Subject: [PATCH 0151/1315] QRCode: slightly improve EstimateModuleSize in presence of noise --- core/src/qrcode/QRDetector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 8d7b41525f..f886f30b72 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -183,9 +183,9 @@ static double EstimateModuleSize(const BitMatrix& image, PointF a, PointF b) assert(cur.isBlack()); - auto pattern = cur.readPattern>(); + auto pattern = cur.readPattern>(); - return Reduce(pattern) / 6.0 * length(cur.d); + return (2 * Reduce(pattern) - pattern[0] - pattern[4]) / 12.0 * length(cur.d); } struct DimensionEstimate From 3eea8fead876faff220bd6ccd0bb290ffb14b9a7 Mon Sep 17 00:00:00 2001 From: Qingnan Duan Date: Wed, 20 Apr 2022 15:21:10 +0800 Subject: [PATCH 0152/1315] Fix inf loop --- core/src/pdf417/PDFDetector.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 4570d075b3..5ddf915927 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -162,10 +162,11 @@ FindRowsWithPattern(const BitMatrix& matrix, int height, int width, int startRow { bool found = false; int startPos, endPos; + int minStartRow = startRow; std::vector counters(pattern.size(), 0); for (; startRow < height; startRow += ROW_STEP) { if (FindGuardPattern(matrix, startColumn, startRow, width, false, pattern, counters, startPos, endPos)) { - while (startRow > 0) { + while (startRow > minStartRow + 1) { if (!FindGuardPattern(matrix, startColumn, --startRow, width, false, pattern, counters, startPos, endPos)) { startRow++; break; From d61c3285208c5fdef9365d86a5c4c230f352108f Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 20 Apr 2022 17:56:26 +0200 Subject: [PATCH 0153/1315] MultiRes: fix issue with removing duplicate (rotated) 2D symbols --- core/src/Quadrilateral.h | 18 +++++++++++++++++- core/src/Result.cpp | 2 +- core/src/oned/ODReader.cpp | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/core/src/Quadrilateral.h b/core/src/Quadrilateral.h index e95a74e172..23d7e76a8f 100644 --- a/core/src/Quadrilateral.h +++ b/core/src/Quadrilateral.h @@ -109,7 +109,23 @@ Quadrilateral Scale(const Quadrilateral& q, int factor) } template -bool IsIntersecting(const Quadrilateral& a, const Quadrilateral& b) +PointT Center(const Quadrilateral& q) +{ + return Reduce(q) / Size(q); +} + +template +bool IsInside(const PointT& p, const Quadrilateral& q) +{ + // Test if p is on the same side (right or left) of all polygon segments + int pos = 0, neg = 0; + for (int i = 0; i < Size(q); ++i) + (cross(p - q[i], q[(i + 1) % Size(q)] - q[i]) < 0 ? neg : pos)++; + return pos == 0 || neg == 0; +} + +template +bool HaveIntersectingBoundingBoxes(const Quadrilateral& a, const Quadrilateral& b) { // TODO: this is only a quick and dirty approximation that works for the trivial standard cases bool x = b.topRight().x < a.topLeft().x || b.topLeft().x > a.topRight().x; diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 1e5bc4d442..19ef576fac 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -63,7 +63,7 @@ bool Result::operator==(const Result& o) const return false; if (BarcodeFormats(BarcodeFormat::TwoDCodes).testFlag(format())) - return IsIntersecting(position(), o.position()); + return IsInside(Center(o.position()), position()); // if one line is less than half the length of the other away from the // latter, we consider it to belong to the same symbol diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index c68ca28d89..eb4d4fbcdb 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -221,7 +221,7 @@ static Results DoDecode(const std::vector>& readers, // if symbols overlap, remove the one with a lower line count for (auto a = res.begin(); a != res.end(); ++a) for (auto b = std::next(a); b != res.end(); ++b) - if (IsIntersecting(a->position(), b->position())) + if (HaveIntersectingBoundingBoxes(a->position(), b->position())) *(a->lineCount() < b->lineCount() ? a : b) = Result(DecodeStatus::NotFound); //TODO: C++20 res.erase_if() From e8d640f840db5d67f5f0d15e9172875937339277 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 20 Apr 2022 17:58:09 +0200 Subject: [PATCH 0154/1315] ImageView: add `subsampled` member function (not used, yet) --- core/src/ImageView.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/ImageView.h b/core/src/ImageView.h index 12d0582962..ec72d18ae2 100644 --- a/core/src/ImageView.h +++ b/core/src/ImageView.h @@ -97,6 +97,12 @@ class ImageView } return *this; } + + ImageView subsampled(int scale) const + { + return {_data, _width / scale, _height / scale, _format, _rowStride * scale, _pixStride * scale}; + } + }; } // ZXing From 0f6977c9d5e36f8c0d069de9a21349eba96619c1 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 20 Apr 2022 18:02:12 +0200 Subject: [PATCH 0155/1315] gitignore: add filters to hide build outputs from in-tree android builds --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 1661636184..a4223377f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ CMakeLists.txt.user +*.o +*.so +*.lib +*.d +*.a From c7098b48c1096a432ba503a75947a9bb7447f975 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 21 Apr 2022 23:43:27 +0200 Subject: [PATCH 0156/1315] QRCode: implement yet another (hopefully simpler) fix for #300 and #308 Instead of stepping too far and then back, step only as far as we need. --- core/src/qrcode/QRDetector.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index f886f30b72..4650b2603f 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -170,18 +170,12 @@ static double EstimateModuleSize(const BitMatrix& image, PointF a, PointF b) BitMatrixCursorF cur(image, a, b - a); assert(cur.isBlack()); - if (!cur.stepToEdge(3, distance(a, b) / 3)) + if (!cur.stepToEdge(3, distance(a, b) / 3, true)) return -1; + assert(cur.isBlack()); cur.turnBack(); - // the following is basically a simple "cur.step()" that reverts the very last step that crossed from back into - // white, but due to a numerical instability near an integer boundary (think .999999999995) it might be required - // to back up two steps. See issues #300 and #308. - if (!cur.stepToEdge(1, 2)) - return -1; - - assert(cur.isBlack()); auto pattern = cur.readPattern>(); @@ -217,12 +211,10 @@ static RegressionLine TraceLine(const BitMatrix& image, PointF p, PointF d, int RegressionLine line; line.setDirectionInward(cur.back()); - cur.stepToEdge(edge); - if (edge == 3) { - // collect points inside the black line -> go one step back + // collect points inside the black line -> backup on 3rd edge + cur.stepToEdge(edge, 0, edge == 3); + if (edge == 3) cur.turnBack(); - cur.step(); - } for (auto dir : {Direction::LEFT, Direction::RIGHT}) { auto c = BitMatrixCursorI(image, PointI(cur.p), PointI(mainDirection(cur.direction(dir)))); From d74213523aa132162f068a654ba0fe2574b603ee Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 21 Apr 2022 23:46:24 +0200 Subject: [PATCH 0157/1315] QRCode: fix finder pattern order on very slanted symbols --- core/src/qrcode/QRDetector.cpp | 14 ++++++++++---- .../qrcode-2/fix-finderpattern-order.jpg | Bin 0 -> 11524 bytes .../qrcode-2/fix-finderpattern-order.txt | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 test/samples/qrcode-2/fix-finderpattern-order.jpg create mode 100644 test/samples/qrcode-2/fix-finderpattern-order.txt diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 4650b2603f..2cfbd6fb0a 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -98,7 +98,13 @@ static FinderPatternSets GenerateFinderPatternSets(std::vector(); - auto squaredDistance = [](PointF a, PointF b) { return dot((a - b), (a - b)); }; + auto squaredDistance = [](const auto* a, const auto* b) { + // The scaling of the distance by the b/a size ratio is a very coarse compensation for the shortening effect of + // the camera projection on slanted symbols. The fact that the size of the finder pattern is proportional to the + // distance from the camera is used here. This approximation only works if a < b < 2*a (see below). + // Test image: fix-finderpattern-order.jpg + return dot((*a - *b), (*a - *b)) * std::pow(double(b->size) / a->size, 2); + }; int nbPatterns = Size(patterns); for (int i = 0; i < nbPatterns - 2; i++) { @@ -115,9 +121,9 @@ static FinderPatternSets GenerateFinderPatternSets(std::vector= distAB && distBC >= distAC) { std::swap(a, b); diff --git a/test/samples/qrcode-2/fix-finderpattern-order.jpg b/test/samples/qrcode-2/fix-finderpattern-order.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0250a0e5be617e2c41f56f1486dfa8712c4cdf81 GIT binary patch literal 11524 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 X7Azll7zJcweI(^{=*c;?_vQZs(&}`6 literal 0 HcmV?d00001 diff --git a/test/samples/qrcode-2/fix-finderpattern-order.txt b/test/samples/qrcode-2/fix-finderpattern-order.txt new file mode 100644 index 0000000000..97268c5c8a --- /dev/null +++ b/test/samples/qrcode-2/fix-finderpattern-order.txt @@ -0,0 +1 @@ +VERSION 2 8CM \ No newline at end of file From 654905538a20c229cb2a8e547f6e08c14a450ca4 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 21 Apr 2022 23:57:08 +0200 Subject: [PATCH 0158/1315] QRCode: fix the orientation of the cursor in TraceLine --- core/src/qrcode/QRDetector.cpp | 25 ++++++++++++------------ test/blackbox/BlackboxTestRunner.cpp | 10 +++++----- test/samples/qrcode-2/fix-traceline.jpg | Bin 0 -> 15215 bytes test/samples/qrcode-2/fix-traceline.txt | 1 + 4 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 test/samples/qrcode-2/fix-traceline.jpg create mode 100644 test/samples/qrcode-2/fix-traceline.txt diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 2cfbd6fb0a..54572b05ec 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -222,19 +222,20 @@ static RegressionLine TraceLine(const BitMatrix& image, PointF p, PointF d, int if (edge == 3) cur.turnBack(); - for (auto dir : {Direction::LEFT, Direction::RIGHT}) { - auto c = BitMatrixCursorI(image, PointI(cur.p), PointI(mainDirection(cur.direction(dir)))); - // if cur.d is near diagonal, it could be c.p is at a corner, i.e. c is not currently at an edge and hence, - // stepAlongEdge() would fail. Going either a step forward or backward should do the trick. - if (!c.edgeAt(dir)) { - c.step(); - if (!c.edgeAt(dir)) { - c.step(-2); - if (!c.edgeAt(dir)) - return {}; - } - } + auto curI = BitMatrixCursorI(image, PointI(cur.p), PointI(mainDirection(cur.d))); + // make sure curI positioned such that the white->black edge is directly behind + // Test image: fix-traceline.jpg + while (!curI.edgeAtBack()) { + if (curI.edgeAtLeft()) + curI.turnRight(); + else if (curI.edgeAtRight()) + curI.turnLeft(); + else + curI.step(-1); + } + for (auto dir : {Direction::LEFT, Direction::RIGHT}) { + auto c = BitMatrixCursorI(image, curI.p, curI.direction(dir)); auto stepCount = static_cast(maxAbsComponent(cur.p - p)); do { line.add(centered(c.p)); diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 278cd7171c..119345aefa 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -578,11 +578,11 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 16, 16, 270 }, }); - runTests("qrcode-2", "QRCode", 43, { - { 41, 41, 0 }, - { 41, 41, 90 }, - { 41, 41, 180 }, - { 41, 41, 270 }, + runTests("qrcode-2", "QRCode", 45, { + { 43, 43, 0 }, + { 43, 43, 90 }, + { 43, 43, 180 }, + { 43, 43, 270 }, { 21, 1, pure }, // the misread is the 'outer' symbol in 16.png }); diff --git a/test/samples/qrcode-2/fix-traceline.jpg b/test/samples/qrcode-2/fix-traceline.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4bea7b8a99c2d7ea560c82ef61d471bfbeca2327 GIT binary patch literal 15215 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 literal 0 HcmV?d00001 diff --git a/test/samples/qrcode-2/fix-traceline.txt b/test/samples/qrcode-2/fix-traceline.txt new file mode 100644 index 0000000000..97268c5c8a --- /dev/null +++ b/test/samples/qrcode-2/fix-traceline.txt @@ -0,0 +1 @@ +VERSION 2 8CM \ No newline at end of file From 131bb0df0b31bf83173be42a7497ee2b61afbc41 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 22 Apr 2022 00:00:08 +0200 Subject: [PATCH 0159/1315] QRCode: fix build regression of c7098b48c1096a432ba503a75947a9bb7447f975 Overlooked a hunk, again... --- core/src/BitMatrixCursor.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/BitMatrixCursor.h b/core/src/BitMatrixCursor.h index 57a36550eb..a7a98e1b61 100644 --- a/core/src/BitMatrixCursor.h +++ b/core/src/BitMatrixCursor.h @@ -119,9 +119,10 @@ class BitMatrixCursor * @brief stepToEdge advances cursor to one step behind the next (or n-th) edge. * @param nth number of edges to pass * @param range max number of steps to take + * @param backup whether or not to backup one step so we land in front of the edge * @return number of steps taken or 0 if moved outside of range/image */ - int stepToEdge(int nth = 1, int range = 0) + int stepToEdge(int nth = 1, int range = 0, bool backup = false) { // TODO: provide an alternative and faster out-of-bounds check than isIn() inside testAt() int steps = 0; @@ -135,6 +136,8 @@ class BitMatrixCursor --nth; } } + if (backup) + --steps; p += steps * d; return steps * (nth == 0); } From e448c0fd91b07929469e4a3e59db3dc4572257ec Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 22 Apr 2022 00:53:56 +0200 Subject: [PATCH 0160/1315] QRCode: use EstimateTilt(fp) to choose best sampling grid postition This is related to #199. --- core/src/qrcode/QRDetector.cpp | 14 +++++++++++--- test/blackbox/BlackboxTestRunner.cpp | 10 +++++----- test/samples/qrcode-2/estimate-tilt.jpg | Bin 0 -> 3173 bytes test/samples/qrcode-2/estimate-tilt.txt | 1 + 4 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 test/samples/qrcode-2/estimate-tilt.jpg create mode 100644 test/samples/qrcode-2/estimate-tilt.txt diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 54572b05ec..e2834481bb 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -250,6 +250,14 @@ static RegressionLine TraceLine(const BitMatrix& image, PointF p, PointF d, int return line; } +// estimate how tilted the symbol is (return value between 1 and 2, see also above) +static double EstimateTilt(const FinderPatternSet& fp) +{ + int min = std::min({fp.bl.size, fp.tl.size, fp.tr.size}); + int max = std::max({fp.bl.size, fp.tl.size, fp.tr.size}); + return double(max) / min; +} + DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatternSet& fp) { auto top = EstimateDimension(image, fp.tl, fp.tr); @@ -301,9 +309,9 @@ DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatt } } - // if the resolution of the RegressionLines is sufficient, use their intersection as the best estimate - // (see discussion in #199, TODO: tune threshold in RegressionLine::isHighRes()) - if (bl2.isHighRes() && bl3.isHighRes() && tr2.isHighRes() && tr3.isHighRes()) + // if the symbol is tilted or the resolution of the RegressionLines is sufficient, use their intersection + // as the best estimate (see discussion in #199 and test image estimate-tilt.jpg ) + if (EstimateTilt(fp) > 1.1 || (bl2.isHighRes() && bl3.isHighRes() && tr2.isHighRes() && tr3.isHighRes())) return sample(brInter, quad[2] - PointF(3, 3)); } } diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 119345aefa..900d664e6c 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -578,11 +578,11 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 16, 16, 270 }, }); - runTests("qrcode-2", "QRCode", 45, { - { 43, 43, 0 }, - { 43, 43, 90 }, - { 43, 43, 180 }, - { 43, 43, 270 }, + runTests("qrcode-2", "QRCode", 46, { + { 44, 44, 0 }, + { 44, 44, 90 }, + { 44, 44, 180 }, + { 44, 44, 270 }, { 21, 1, pure }, // the misread is the 'outer' symbol in 16.png }); diff --git a/test/samples/qrcode-2/estimate-tilt.jpg b/test/samples/qrcode-2/estimate-tilt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e30b300588c2041e74c94fe59da131b8edf52911 GIT binary patch literal 3173 zcmbtWi8qu{AAV=Ei?J11X2uptWS8C8lYNY(AtfZqzEvU_A&e}f57+qz4zR6?s?DedG2%0ea^Etw)X+xHa9ji20$PH05KZan*ibf zroY9^%*4vZXig4xb`DOy16+*e6XO-&Wqe|Xk%t8tOHm4il2TMZe(bn9T3Z{9vB6xq zk_GyI2kdnKa2CJL>AzuvC2CxNXv>6wX{tCacKA^puI$*;@fLry}oBJ(Tvy-y5~UA}JSp-W>npdx#V<3(HC@(5 zVwm2o0cWqIwG6AnMd|A#UBc@EnXWJ%3=_Ct{Mm{8FBkkIASYA zf$(v0ONCrM;bLtlAi^iw^L$x)Jvv^+;b3pAHVsR0mRZ5sI&yJz_B^i3t)LGVatm6L zNo3+(AJ$*UIe6eVZG0%qAvw6B--}q-g37rY=vkkJuPjkhJhu~&c;rK{n*PG2d_VGF zXjJvcPCfO7g=NQVHPS-JLb>H_2W=(m!ZuEJXWOg8v835fV;rh|v0U%g^dvRyQfNcr z@&peTQ+{p)y&}JcS|1V`p(Ju71W0r2ox7j%Pk_1i|_0vWcmD;(XN;PI5!wF`G_W()}|3Lofiy=@@ zFeldjlGZJ%|I{8}e`wo=Li${0P{-- z>M^(1lLE|Pd1&+Pvk6r8`rhT6!oDHz3P*n=N2raK=V8xQ>zq^oYf5g25||Ay5Tpw% z&BYD3qRCr7@A=RySH4d4j}&EP)udkhW_bH~qbeQ~5<}>xw5iHY!qy2X876^fXPpLx z-CZd|HQXpYNc6tN(QV_J0o>HY_{0l8S2G8%5&tq$--BEppX`XOYj<+nz^RH-H-}qtXC09l8E!Aq$BxxDvndH)@W4LW= zFpmVRYB^=?yp(DbqQd7O?n%Y($4=x}ch#wxUrHGt&{lp9U+=?MPP*CVdaPX99+h|YS_hiBU5FYj)JEn8{uY8eFtcZ znTvIc`KzEb4vrp;d3lF;j!gHRCb~9NR74H8uvo!V!x~Vg_m(A6Yt)*2sgYRUM$o%=)*41-))q%u^sEFA;V06=KT4byH+WIs9 zeNWKj{$mJW2!s{J`o|O)mHPSpJ%Rh;yaiGDB2T+6!D2uMF6)x<*C;C3(e8=iin`9(|4@HF|AQ}pFR|}j(T0lbb&j( zrX`W)+M>jRyvsYM<$apF=GF{rlgQlC1YmE3coIfq0(2#Qd1u!M{uw(CPy9X!I1+IhjpBjLfh-m6BgtR>lcw+l0#{PfBw zK$NHQ=6Z)Ur@)Sg^}LMY7D~FC_TJ!AL8Q>Ssl(%V!BFjBEwO+esbcHt$TiK1~bWaEmV(#;ntjRgCgnl8($KKhmB^Q%*GJA) zZ#SKwsZ_*z@61lQp&%&>%-M!P!}1Ysk_RTivf|B%@60!`!ck@Vx@_cDSLq+I2d3|{ zJ-y{(Ve>ml82;s}y*X!Q?w#`~9{TdD$%j&0Vu$2Ws8!n;fLP+X+T)V?+ zM|lyZUX>j?GOs?FLVT3iY*xI|8`kW-_9;Ik+M$|jUG3L>R1k7^<&r%IM_Ukx&#IX7tNcFZux_RsvOR!Asp2?K z*8a||YjoF{!zTP3qn_zYM?DM>A_0LVqPw7vmR}rUbOi5;A(tn5vYiEZn9a zEz+DFY@ zcy6*nipr-Jp6>5jZBpfvqb?%9`=WywE^`zPfFNKf6!tH7?8i_r9KsFdQPhVS*c9<2 zkhW)ePw06N{zfSfNEfj8)~rreV=;Y(c%@b0p^*^E4L&@P{#%+qOMe`?03h z?8#LKaqK`s0iua0c2vwt8*E%etBm74gWs(sJa&~ia@PiExJiy;7j+KBGW8Jsb&2zt zNOrMIB&@S6Yn1Yyt)1l|mpvPSqAQR=p?q+`b9qk3G+^It~6Z1T5CuJIP?3BJW+6uhRQSvaWRq{5B Jc6ZyO{Raz5fXV;> literal 0 HcmV?d00001 diff --git a/test/samples/qrcode-2/estimate-tilt.txt b/test/samples/qrcode-2/estimate-tilt.txt new file mode 100644 index 0000000000..a837ad36a0 --- /dev/null +++ b/test/samples/qrcode-2/estimate-tilt.txt @@ -0,0 +1 @@ +VERSION 1 6CM \ No newline at end of file From 2c009d66035aaec2511602bf3a0a7775c3042735 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 25 Apr 2022 14:36:55 +0200 Subject: [PATCH 0161/1315] multi-res: introduce `tryDownscale` hint and rename threshold property Make the `DecodingHints` interface more consistent this way, enable the feature by default (the `ReadBarcode` function does not use it, yet) and set a proper default for the threshold. --- core/src/DecodeHints.h | 14 +++++++++----- core/src/ReadBarcode.cpp | 2 +- example/ZXingReader.cpp | 14 +++----------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index a67820b80e..6b37c0a62a 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -51,6 +51,7 @@ class DecodeHints { bool _tryHarder : 1; bool _tryRotate : 1; + bool _tryDownscale : 1; bool _isPure : 1; bool _tryCode39ExtendedMode : 1; bool _validateCode39CheckSum : 1; @@ -62,16 +63,16 @@ class DecodeHints std::string _characterSet; std::vector _allowedLengths; BarcodeFormats _formats = BarcodeFormat::None; - uint16_t _multiResolutionThreshold = 0xffff; + uint16_t _downscaleThreshold = 500; uint8_t _minLineCount = 2; uint8_t _maxNumberOfSymbols = 0xff; public: // bitfields don't get default initialized to 0. DecodeHints() - : _tryHarder(1), _tryRotate(1), _isPure(0), _tryCode39ExtendedMode(0), _validateCode39CheckSum(0), - _validateITFCheckSum(0), _returnCodabarStartEnd(0), _binarizer(Binarizer::LocalAverage), - _eanAddOnSymbol(EanAddOnSymbol::Ignore) + : _tryHarder(1), _tryRotate(1), _tryDownscale(1), _isPure(0), _tryCode39ExtendedMode(0), + _validateCode39CheckSum(0), _validateITFCheckSum(0), _returnCodabarStartEnd(0), + _binarizer(Binarizer::LocalAverage), _eanAddOnSymbol(EanAddOnSymbol::Ignore) {} #define ZX_PROPERTY(TYPE, GETTER, SETTER) \ @@ -87,6 +88,9 @@ class DecodeHints /// Also try detecting code in 90, 180 and 270 degree rotated images. ZX_PROPERTY(bool, tryRotate, setTryRotate) + /// Also try detecting code in downscaled images (depending on image size). + ZX_PROPERTY(bool, tryDownscale, setTryDownscale) + /// Binarizer to use internally when using the ReadBarcode function ZX_PROPERTY(Binarizer, binarizer, setBinarizer) @@ -95,7 +99,7 @@ class DecodeHints /// Image size (width or height) threshold at which to start multi-resolution scanning // WARNING: this API is experimental and may change/disappear - ZX_PROPERTY(uint16_t, multiResolutionThreshold, setMultiResolutionThreshold) + ZX_PROPERTY(uint16_t, downscaleThreshold, setDownscaleThreshold) /// The number of scan lines in a 1D barcode that have to be equal to accept the result, default is 2 ZX_PROPERTY(uint8_t, minLineCount, setMinLineCount) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index be885b5053..5375ccb9ac 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -146,7 +146,7 @@ Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) if (hints.isPure()) return {reader.read(*CreateBitmap(hints.binarizer(), iv))}; - LumImagePyramid pyramid(iv, hints.multiResolutionThreshold()); + LumImagePyramid pyramid(iv, hints.downscaleThreshold() * hints.tryDownscale()); Results results; int maxSymbols = hints.maxNumberOfSymbols(); diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 84b488de44..83eb038c29 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -40,8 +40,8 @@ static void PrintUsage(const char* exePath) std::cout << "Usage: " << exePath << " [-fast] [-norotate] [-format ] [-pngout ] [-ispure] [-1] ...\n" << " -fast Skip some lines/pixels during detection (faster)\n" << " -norotate Don't try rotated image during detection (faster)\n" + << " -noscale Don't try downscaled images during detection (faster)\n" << " -format Only detect given format(s) (faster)\n" - << " -multires Image size threshold at which to start multi-resolution scanning, 0 disables it\n" << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" << " -1 Print only file name, text and status on one line per file/barcode\n" << " -escape Escape non-graphical characters in angle brackets (ignored for -1 option, which always escapes)\n" @@ -62,6 +62,8 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi hints.setTryHarder(false); } else if (strcmp(argv[i], "-norotate") == 0) { hints.setTryRotate(false); + } else if (strcmp(argv[i], "-noscale") == 0) { + hints.setDownscaleThreshold(0); } else if (strcmp(argv[i], "-ispure") == 0) { hints.setIsPure(true); hints.setBinarizer(Binarizer::FixedThreshold); @@ -74,15 +76,6 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi std::cerr << e.what() << "\n"; return false; } - } else if (strcmp(argv[i], "-multires") == 0) { - if (++i == argc) - return false; - try { - hints.setMultiResolutionThreshold(std::stoi(argv[i])); - } catch (const std::exception& e) { - std::cerr << e.what() << "\n"; - return false; - } } else if (strcmp(argv[i], "-1") == 0) { oneLine = true; } else if (strcmp(argv[i], "-escape") == 0) { @@ -134,7 +127,6 @@ int main(int argc, char* argv[]) bool angleEscape = false; int ret = 0; - hints.setMultiResolutionThreshold(500); // enable the feature by default if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, filePaths, outPath)) { PrintUsage(argv[0]); From 5ab1a3de03ef63799d3aeba9a0b17ec4a041eeca Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 25 Apr 2022 14:38:32 +0200 Subject: [PATCH 0162/1315] android: introduce tryDownscale option (in lib and demo app) --- .../com/example/zxingcppdemo/MainActivity.kt | 3 ++- .../main/res/layout-land/activity_camera.xml | 5 +++++ .../src/main/res/layout/activity_camera.xml | 5 +++++ .../zxingcpp/src/main/cpp/BarcodeReader.cpp | 18 +++++++++++------- .../main/java/com/zxingcpp/BarcodeReader.kt | 10 ++++++---- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt index cffb77c455..d023a70676 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt @@ -149,7 +149,8 @@ class MainActivity : AppCompatActivity() { readerCpp.options = BarcodeReader.Options( formats = if (binding.qrcode.isChecked) setOf(Format.QR_CODE) else setOf(), tryHarder = binding.tryHarder.isChecked, - tryRotate = binding.tryRotate.isChecked + tryRotate = binding.tryRotate.isChecked, + tryDownscale = binding.tryDownscale.isChecked ) resultText = try { diff --git a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml index 3f7859de28..9cb819f82d 100644 --- a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml +++ b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml @@ -89,6 +89,11 @@ style="@style/Chip" android:text="tryRotate" /> + + + + (duration).count()); @@ -136,7 +140,7 @@ extern "C" JNIEXPORT jstring JNICALL Java_com_zxingcpp_BarcodeReader_readYBuffer( JNIEnv *env, jobject thiz, jobject yBuffer, jint rowStride, jint left, jint top, jint width, jint height, jint rotation, - jstring formats, jboolean tryHarder, jboolean tryRotate, + jstring formats, jboolean tryHarder, jboolean tryRotate, jboolean tryDownscale, jobject result) { const uint8_t* pixels = static_cast(env->GetDirectBufferAddress(yBuffer)); @@ -145,7 +149,7 @@ Java_com_zxingcpp_BarcodeReader_readYBuffer( ImageView{pixels + top * rowStride + left, width, height, ImageFormat::Lum, rowStride} .rotated(rotation); - return Read(env, image, formats, tryHarder, tryRotate, result); + return Read(env, image, formats, tryHarder, tryRotate, tryDownscale, result); } struct LockedPixels @@ -171,7 +175,7 @@ extern "C" JNIEXPORT jstring JNICALL Java_com_zxingcpp_BarcodeReader_readBitmap( JNIEnv* env, jobject thiz, jobject bitmap, jint left, jint top, jint width, jint height, jint rotation, - jstring formats, jboolean tryHarder, jboolean tryRotate, + jstring formats, jboolean tryHarder, jboolean tryRotate, jboolean tryDownscale, jobject result) { AndroidBitmapInfo bmInfo; @@ -193,5 +197,5 @@ Java_com_zxingcpp_BarcodeReader_readBitmap( .cropped(left, top, width, height) .rotated(rotation); - return Read(env, image, formats, tryHarder, tryRotate, result); + return Read(env, image, formats, tryHarder, tryRotate, tryDownscale, result); } diff --git a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt index 1174683a51..52e4b3b380 100644 --- a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt +++ b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt @@ -36,7 +36,8 @@ class BarcodeReader { data class Options( val formats: Set = setOf(), val tryHarder: Boolean = false, - val tryRotate: Boolean = false + val tryRotate: Boolean = false, + val tryDownscale: Boolean = false ) data class Position( @@ -78,6 +79,7 @@ class BarcodeReader { options.formats.joinToString(), options.tryHarder, options.tryRotate, + options.tryDownscale, result ) } @@ -97,7 +99,7 @@ class BarcodeReader { val status = with(options) { readBitmap( bitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height(), rotation, - formats.joinToString(), tryHarder, tryRotate, result + formats.joinToString(), tryHarder, tryRotate, tryDownscale, result ) } return try { @@ -110,13 +112,13 @@ class BarcodeReader { // setting the format enum from inside the JNI code is a hassle -> use returned String instead private external fun readYBuffer( yBuffer: ByteBuffer, rowStride: Int, left: Int, top: Int, width: Int, height: Int, rotation: Int, - formats: String, tryHarder: Boolean, tryRotate: Boolean, + formats: String, tryHarder: Boolean, tryRotate: Boolean, tryDownscale: Boolean, result: Result, ): String? private external fun readBitmap( bitmap: Bitmap, left: Int, top: Int, width: Int, height: Int, rotation: Int, - formats: String, tryHarder: Boolean, tryRotate: Boolean, + formats: String, tryHarder: Boolean, tryRotate: Boolean, tryDownscale: Boolean, result: Result, ): String? From 154af6cd60e0d983b210d1daeb1292dad432b5b9 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 25 Apr 2022 15:21:42 +0200 Subject: [PATCH 0163/1315] multi-res: disable downscaling in black box test runner --- test/blackbox/BlackboxTestRunner.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 900d664e6c..9899cef628 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -262,7 +262,8 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi std::list allResults; for (const auto& imgPath : imgPaths) { auto results = - ReadBarcodes(ImageLoader::load(imgPath), DecodeHints().setFormats(BarcodeFormatFromString(format.data()))); + ReadBarcodes(ImageLoader::load(imgPath), + DecodeHints().setFormats(BarcodeFormatFromString(format.data())).setTryDownscale(false)); allResults.insert(allResults.end(), results.begin(), results.end()); } From 950c3b89d74fd22bc4baf46e7a41a90bf6cb4835 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 25 Apr 2022 22:23:16 +0200 Subject: [PATCH 0164/1315] multi-res: add hack to be able to call downscale code in ReadBarcode This is currently used in the android and python wrapper. See discussion in #282 why this is not generally enabled at the moment. It basically comes down to the fact, that we can not have different default values for `tryDownscale` based on whether we call the single or multi symbol function. --- core/src/ReadBarcode.cpp | 20 ++++++++++--------- .../zxingcpp/src/main/cpp/BarcodeReader.cpp | 8 +++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 5375ccb9ac..912b9763f4 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -126,15 +126,17 @@ std::unique_ptr CreateBitmap(ZXing::Binarizer binarizer, const Ima Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) { -#if 0 - auto ress = ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1)); - return ress.empty() ? Result(DecodeStatus::NotFound) : ress.front(); -#else - LumImage lum; - ImageView iv = SetupLumImageView(_iv, lum, hints); - - return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)); -#endif + if (hints.maxNumberOfSymbols() == 1) { + // HACK: use the maxNumberOfSymbols value as a switch to ReadBarcodes to enable the downscaling + // see python and android wrapper + auto ress = ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1)); + return ress.empty() ? Result(DecodeStatus::NotFound) : ress.front(); + } else { + LumImage lum; + ImageView iv = SetupLumImageView(_iv, lum, hints); + + return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)); + } } Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) diff --git a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp index 6c19adb05a..965ed6e2a1 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp @@ -92,15 +92,13 @@ jstring Read(JNIEnv *env, ImageView image, jstring formats, jboolean tryHarder, .setFormats(BarcodeFormatsFromString(J2CString(env, formats))) .setTryHarder(tryHarder) .setTryRotate( tryRotate ) - .setTryDownscale(tryDownscale); + .setTryDownscale(tryDownscale) + .setMaxNumberOfSymbols(1); // see ReadBarcode implementation // return C2JString(env, ToString(DecodeStatus::NotFound)); auto startTime = std::chrono::high_resolution_clock::now(); - Result res(DecodeStatus::NotFound); - auto results = ReadBarcodes(image, DecodeHints(hints).setMaxNumberOfSymbols(1)); - if (!results.empty()) - res = results.front(); + auto res = ReadBarcode(image, hints); auto duration = std::chrono::high_resolution_clock::now() - startTime; // LOGD("time: %4d ms\n", (int)std::chrono::duration_cast(duration).count()); From 1291b9cc60626a741ae7a5743719640488621bb7 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 25 Apr 2022 22:27:04 +0200 Subject: [PATCH 0165/1315] python: add try_downscale option to read_barcode(s) functions --- wrappers/python/zxing.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 2e815d2985..e7fdfa1425 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -35,14 +35,17 @@ std::ostream& operator<<(std::ostream& os, const Position& points) { } template -auto read_barcode_impl(FUNC func, py::object _image, const BarcodeFormats& formats, bool try_rotate, - Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol) +auto read_barcode_impl(FUNC func, py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, + Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol, + uint8_t max_number_of_symbols = 0xff) { const auto hints = DecodeHints() .setFormats(formats) .setTryRotate(try_rotate) + .setTryDownscale(try_downscale) .setBinarizer(binarizer) .setIsPure(is_pure) + .setMaxNumberOfSymbols(max_number_of_symbols) .setEanAddOnSymbol(ean_add_on_symbol); const auto _type = std::string(py::str(py::type::of(_image))); Image image; @@ -84,16 +87,18 @@ auto read_barcode_impl(FUNC func, py::object _image, const BarcodeFormats& forma return func({bytes, width, height, imgfmt, width * channels, channels}, hints); } -Result read_barcode(py::object _image, const BarcodeFormats& formats, bool try_rotate, Binarizer binarizer, - bool is_pure, EanAddOnSymbol ean_add_on_symbol) +Result read_barcode(py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, + Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol) { - return read_barcode_impl(ReadBarcode, _image, formats, try_rotate, binarizer, is_pure, ean_add_on_symbol); + return read_barcode_impl(ReadBarcode, _image, formats, try_rotate, try_downscale, binarizer, is_pure, + ean_add_on_symbol, 1); } -Results read_barcodes(py::object _image, const BarcodeFormats& formats, bool try_rotate, Binarizer binarizer, - bool is_pure, EanAddOnSymbol ean_add_on_symbol) +Results read_barcodes(py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, + Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol) { - return read_barcode_impl(ReadBarcodes, _image, formats, try_rotate, binarizer, is_pure, ean_add_on_symbol); + return read_barcode_impl(ReadBarcodes, _image, formats, try_rotate, try_downscale, binarizer, is_pure, + ean_add_on_symbol); } Image write_barcode(BarcodeFormat format, std::string text, int width, int height, int quiet_zone, int ec_level) @@ -222,6 +227,7 @@ PYBIND11_MODULE(zxingcpp, m) py::arg("image"), py::arg("formats") = BarcodeFormats{}, py::arg("try_rotate") = true, + py::arg("try_downscale") = true, py::arg("binarizer") = Binarizer::LocalAverage, py::arg("is_pure") = false, py::arg("ean_add_on_symbol") = EanAddOnSymbol::Ignore, @@ -233,8 +239,11 @@ PYBIND11_MODULE(zxingcpp, m) ":type formats: zxing.BarcodeFormat|zxing.BarcodeFormats\n" ":param formats: the format(s) to decode. If ``None``, decode all formats.\n" ":type try_rotate: bool\n" - ":param try_rotate: if ``True`` (the default), decoder searched for barcodes in any direction; \n" + ":param try_rotate: if ``True`` (the default), decoder searches for barcodes in any direction; \n" " if ``False``, it will not search for 90° / 270° rotated barcodes.\n" + ":type try_downscale: bool\n" + ":param try_downscale: if ``True`` (the default), decoder also scans downscaled versions of the input; \n" + " if ``False``, it will only search in the resolution provided.\n" ":type binarizer: zxing.Binarizer\n" ":param binarizer: the binarizer used to convert image before decoding barcodes.\n" " Defaults to :py:attr:`zxing.Binarizer.LocalAverage`." @@ -251,6 +260,7 @@ PYBIND11_MODULE(zxingcpp, m) py::arg("image"), py::arg("formats") = BarcodeFormats{}, py::arg("try_rotate") = true, + py::arg("try_downscale") = true, py::arg("binarizer") = Binarizer::LocalAverage, py::arg("is_pure") = false, py::arg("ean_add_on_symbol") = EanAddOnSymbol::Ignore, @@ -262,8 +272,11 @@ PYBIND11_MODULE(zxingcpp, m) ":type formats: zxing.BarcodeFormat|zxing.BarcodeFormats\n" ":param formats: the format(s) to decode. If ``None``, decode all formats.\n" ":type try_rotate: bool\n" - ":param try_rotate: if ``True`` (the default), decoder searched for barcodes in any direction; \n" + ":param try_rotate: if ``True`` (the default), decoder searches for barcodes in any direction; \n" " if ``False``, it will not search for 90° / 270° rotated barcodes.\n" + ":type try_downscale: bool\n" + ":param try_downscale: if ``True`` (the default), decoder also scans downscaled versions of the input; \n" + " if ``False``, it will only search in the resolution provided.\n" ":type binarizer: zxing.Binarizer\n" ":param binarizer: the binarizer used to convert image before decoding barcodes.\n" " Defaults to :py:attr:`zxing.Binarizer.LocalAverage`." From fc4f2d5693b530e660ae7f9369cfffe8e6033347 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 25 Apr 2022 23:10:26 +0200 Subject: [PATCH 0166/1315] ci: drop python 3.7 and add 3.10 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f3f5a0046..f1654eb90d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,7 +92,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.7, 3.8, 3.9] + python-version: [3.8, 3.9, 3.10] os: [ubuntu-latest, macos-latest, windows-latest] steps: From 5d7d95e3bf7eb7fb26fa7eda8c3f87a2214a76e0 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 25 Apr 2022 23:21:00 +0200 Subject: [PATCH 0167/1315] ci: fix python builds ('3.10' but be put in quotes for the YAML parser) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1654eb90d..79becdffc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,7 +92,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8, 3.9, 3.10] + python-version: ['3.8', '3.9', '3.10'] os: [ubuntu-latest, macos-latest, windows-latest] steps: From 2d232b7b9b79d3dacf0627d5be4bd05a2ddb13ae Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Apr 2022 09:40:04 +0200 Subject: [PATCH 0168/1315] multi-res: use min(width, height) in threshold check --- core/src/DecodeHints.h | 2 +- core/src/ReadBarcode.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 6b37c0a62a..bbe73d50e8 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -97,7 +97,7 @@ class DecodeHints /// Set to true if the input contains nothing but a single perfectly aligned barcode (generated image) ZX_PROPERTY(bool, isPure, setIsPure) - /// Image size (width or height) threshold at which to start multi-resolution scanning + /// Image size ( min(width, height) ) threshold at which to start downscaled scanning // WARNING: this API is experimental and may change/disappear ZX_PROPERTY(uint16_t, downscaleThreshold, setDownscaleThreshold) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 912b9763f4..90c33bdad5 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -83,7 +83,7 @@ class LumImagePyramid LumImagePyramid(const ImageView& iv, int threshold) { layers.push_back(iv); - while (threshold > 0 && std::max(layers.back().width(), layers.back().height()) > threshold) + while (threshold > 0 && std::min(layers.back().width(), layers.back().height()) > threshold) addLayer(); #if 0 // Reversing the layers means we'd start with the smallest. that can make sense if we are only looking for a From 457ad4ca643b86888a915b9a4f17f8059ef00642 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Apr 2022 09:41:24 +0200 Subject: [PATCH 0169/1315] ReadBarcode: micro performance optimization in ExtractLum --- core/src/ReadBarcode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 90c33bdad5..d65dabcf3c 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -48,7 +48,7 @@ static LumImage ExtractLum(const ImageView& iv, P projection) auto* dst = res.data(); for(int y = 0; y < iv.height(); ++y) - for(int x = 0; x < iv.width(); ++x) + for(int x = 0, w = iv.width(); x < w; ++x) *dst++ = projection(iv.data(x, y)); return res; From 00d07c57b416d41afaa3e4a59acfcdc940387803 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Apr 2022 16:07:43 +0200 Subject: [PATCH 0170/1315] ci: update python-build-dist (new cibuildwheel + cp310-* output) --- .github/workflows/python-build.yml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml index 71dafce622..ca5e4f5e35 100644 --- a/.github/workflows/python-build.yml +++ b/.github/workflows/python-build.yml @@ -26,24 +26,23 @@ jobs: steps: - uses: actions/checkout@v2 - with: - submodules: recursive + - name: Set up Python uses: actions/setup-python@v2 - with: - python-version: 3.8 + + - name: Install cibuildwheel + run: python -m pip install cibuildwheel==2.4.0 - name: Build wheels - uses: joerick/cibuildwheel@v1.10.0 - with: - package-dir: ./wrappers/python - output-dir: ./wrappers/python/wheelhouse + run: python -m cibuildwheel --output-dir wheelhouse wrappers/python env: - CIBW_BUILD: cp37-* cp38-* cp39-* + CIBW_BUILD: cp38-* cp39-* cp310-* + # "Installing Python cp310" fails on macOS on 2022-04-26 -> disable + CIBW_SKIP: "*musllinux* *310-macos*" - uses: actions/upload-artifact@v2 with: - path: ./wrappers/python/wheelhouse/*.whl + path: ./wheelhouse/*.whl build-sdist: name: Build source distribution @@ -55,8 +54,6 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 - with: - python-version: 3.8 - name: Build sdist working-directory: wrappers/python From f57b760162bb6aff3ba3e1f777f731b0dbfc61e5 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 01:18:57 +0200 Subject: [PATCH 0171/1315] example: fix usage/help text of ZXingReader (red -> green outline color) --- example/ZXingReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 83eb038c29..15150e2897 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -45,7 +45,7 @@ static void PrintUsage(const char* exePath) << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" << " -1 Print only file name, text and status on one line per file/barcode\n" << " -escape Escape non-graphical characters in angle brackets (ignored for -1 option, which always escapes)\n" - << " -pngout Write a copy of the input image with barcodes outlined by a red line\n" + << " -pngout Write a copy of the input image with barcodes outlined by a green line\n" << "\n" << "Supported formats are:\n"; for (auto f : BarcodeFormats::all()) { From 62e3b2cc715b2958d0ef169ee16680bbd310be5a Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 01:35:23 +0200 Subject: [PATCH 0172/1315] python: prepare the 1.3.0 release --- wrappers/python/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index 4aef419662..873767a51d 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -59,7 +59,7 @@ def build_extension(self, ext): # "local_scheme": "no-local-version", # "tag_regex": "v?([0-9]+.[0-9]+.[0-9]+)", # }, - version='1.2.0', + version='1.3.0', description='Python bindings for the zxing-cpp barcode library', long_description=long_description, long_description_content_type="text/markdown", From 0f2ed91b7d41772f48afb575560604cc7ee992d9 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 01:49:52 +0200 Subject: [PATCH 0173/1315] README: minor text improvements and clarifications --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9b6132fb70..58a274cf5f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ ## Features -* In pure C++17, no third-party dependencies +* In pure C++17, no third-party dependencies (for the library) * Stateless, thread-safe readers/scanners and writers/generators * Wrapper/Bindings for: * WinRT @@ -27,7 +27,7 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ | DataBar | ITF | MaxiCode (beta) | | DataBar Expanded | -Note: DataBar used to be called RSS. +Note: DataBar used to be called RSS. DataBar is not supported for writing. ## Getting Started @@ -57,20 +57,21 @@ PM> Install-Package huycn.zxingcpp.winrt ## Build Instructions ### Standard setup on Windows/macOS/Linux -1. Make sure [CMake](https://cmake.org) version 3.10 or newer is installed. -2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8 / gcc 7 / clang 5) +1. Make sure [CMake](https://cmake.org) version 3.14 or newer is installed. +2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8 / gcc 7 / clang 5). 3. See the cmake `BUILD_...` options to enable the testing code, python wrapper, etc. ### Windows Universal Platform -1. Download and install [CMake](https://cmake.org) 3.4 or more recent if it's not already installed. -2. Edit the file [`wrappers/winrt/BuildWinCom.bat`](wrappers/winrt/BuildWinCom.bat) to adjust the path to your CMake installation. -3. Double-click on the batch script to run it. -4. If the build succeeds, it will put the results in the folder UAP which is ready-to-use SDK extension. +1. Make sure [CMake](https://cmake.org) version 3.4 or newer is installed. +2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8). +3. Edit the file [`wrappers/winrt/BuildWinCom.bat`](wrappers/winrt/BuildWinCom.bat) to adjust the path to your CMake installation. +4. Double-click on the batch script to run it. +5. If the build succeeds, it will put the results in the folder UAP which is ready-to-use SDK extension. ### Android 1. Install AndroidStudio including NDK and CMake (see 'SDK Tools'). 2. Open the project in folder [wrappers/android](wrappers/android). -3. The project contains 2 modules: `zxingcpp` is the wrapper library, `app` is the demo app using `zxingcpp` +3. The project contains 2 modules: `zxingcpp` is the wrapper library, `app` is the demo app using `zxingcpp`. ### WebAssembly 1. [Install Emscripten](https://kripken.github.io/emscripten-site/docs/getting_started/) if not done already. From c92fb9c87114800f80260530ab148a1f634f284b Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 02:25:15 +0200 Subject: [PATCH 0174/1315] python: update demo code to use new `read_barcodes()` function --- wrappers/python/README.md | 11 ++++++----- wrappers/python/demo_reader.py | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/wrappers/python/README.md b/wrappers/python/README.md index b6d43c81c8..00bd382893 100644 --- a/wrappers/python/README.md +++ b/wrappers/python/README.md @@ -21,9 +21,10 @@ import cv2 import zxingcpp img = cv2.imread('myimage.png') -result = zxingcpp.read_barcode(img) -if result.valid: - print("Found barcode with value '{}' (format: {})".format(result.text, str(result.format))) -else: - print("could not read barcode") +results = zxingcpp.read_barcodes(img) +for result in results: + print("Found barcode:\n Text: '{}'\n Format: {}\n Position: {}" + .format(result.text, result.format, result.position)) +if len(results) == 0: + print("Could not find any barcode.") ``` diff --git a/wrappers/python/demo_reader.py b/wrappers/python/demo_reader.py index 93de1f3a5c..d8e95cb9ef 100644 --- a/wrappers/python/demo_reader.py +++ b/wrappers/python/demo_reader.py @@ -2,9 +2,9 @@ from PIL import Image img = Image.open(sys.argv[1]) -result = zxingcpp.read_barcode(img) -if result.valid: +results = zxingcpp.read_barcodes(img) +for result in results: print("Found barcode:\n Text: '{}'\n Format: {}\n Position: {}" .format(result.text, result.format, result.position)) -else: - print("Could not read barcode") +if len(results) == 0: + print("Could not find any barcode.") From 45cf13287d08b99d6c544643f4059e8da9a3e97f Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 02:33:50 +0200 Subject: [PATCH 0175/1315] python: add test for new `read_barcodes()` function --- wrappers/python/test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wrappers/python/test.py b/wrappers/python/test.py index cfcc760b9a..350d08cd0e 100644 --- a/wrappers/python/test.py +++ b/wrappers/python/test.py @@ -51,6 +51,14 @@ def test_write_read_oned_cycle(self): self.check_res(res, format, text) self.assertEqual(res.position.top_left.x, 61) + def test_write_read_multi_cycle(self): + format = BF.QRCode + text = "I have the best words." + img = zxingcpp.write_barcode(format, text) + + res = zxingcpp.read_barcodes(img)[0] + self.check_res(res, format, text) + def test_failed_read(self): import numpy as np res = zxingcpp.read_barcode( From d3acd6d6e7b188e5e8746a34cddf06ca8a68bece Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 10:09:43 +0200 Subject: [PATCH 0176/1315] multi-res: add DecodeHints::downscaleFactor property For a discussion see #282. --- core/src/DecodeHints.h | 5 +++++ core/src/ReadBarcode.cpp | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index bbe73d50e8..d4ef5e6e32 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -64,6 +64,7 @@ class DecodeHints std::vector _allowedLengths; BarcodeFormats _formats = BarcodeFormat::None; uint16_t _downscaleThreshold = 500; + uint8_t _downscaleFactor = 3; uint8_t _minLineCount = 2; uint8_t _maxNumberOfSymbols = 0xff; @@ -101,6 +102,10 @@ class DecodeHints // WARNING: this API is experimental and may change/disappear ZX_PROPERTY(uint16_t, downscaleThreshold, setDownscaleThreshold) + /// Scale factor used during downscaling, meaningful values are 2, 3 and 4 + // WARNING: this API is experimental and may change/disappear + ZX_PROPERTY(uint8_t, downscaleFactor, setDownscaleFactor) + /// The number of scan lines in a 1D barcode that have to be equal to accept the result, default is 2 ZX_PROPERTY(uint8_t, minLineCount, setMinLineCount) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index d65dabcf3c..add15b2db7 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -56,7 +56,7 @@ static LumImage ExtractLum(const ImageView& iv, P projection) class LumImagePyramid { - static constexpr int N = 3; + int N = 3; std::vector buffers; void addLayer() @@ -80,8 +80,11 @@ class LumImagePyramid public: std::vector layers; - LumImagePyramid(const ImageView& iv, int threshold) + LumImagePyramid(const ImageView& iv, int threshold, int factor) : N(factor) { + if (factor < 2) + throw std::invalid_argument("Invalid DecodeHints::downscaleFactor"); + layers.push_back(iv); while (threshold > 0 && std::min(layers.back().width(), layers.back().height()) > threshold) addLayer(); @@ -148,7 +151,7 @@ Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) if (hints.isPure()) return {reader.read(*CreateBitmap(hints.binarizer(), iv))}; - LumImagePyramid pyramid(iv, hints.downscaleThreshold() * hints.tryDownscale()); + LumImagePyramid pyramid(iv, hints.downscaleThreshold() * hints.tryDownscale(), hints.downscaleFactor()); Results results; int maxSymbols = hints.maxNumberOfSymbols(); From 513ae351c17015de633f649d2de36608b7e15c39 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 14:15:15 +0200 Subject: [PATCH 0177/1315] style: add .clang-format configuration (not applied consistently, yet) --- .clang-format | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..5520e59df9 --- /dev/null +++ b/.clang-format @@ -0,0 +1,32 @@ +--- +Language: Cpp +Standard: c++17 +BasedOnStyle: LLVM + +IndentWidth: 4 +TabWidth: 4 +UseTab: ForContinuationAndIndentation # ForIndentation + +AccessModifierOffset: -4 +BreakBeforeBraces: Mozilla +ColumnLimit: 120 + +#AlignConsecutiveAssignments: true +AlignEscapedNewlines: DontAlign +AlignTrailingComments: true +AllowShortCaseLabelsOnASingleLine: true + +AllowShortFunctionsOnASingleLine: Inline +#AllowShortLambdasOnASingleLine: Inline + +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Mozilla +BreakBeforeTernaryOperators: true +ConstructorInitializerAllOnOneLineOrOnePerLine: false +FixNamespaceComments: true +IncludeBlocks: Regroup +KeepEmptyLinesAtTheStartOfBlocks: false +PointerAlignment: Left +ReflowComments: true +SortIncludes: true From e3556b544be6eb767d4f14714f80295a76ab4ba4 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Apr 2022 14:17:49 +0200 Subject: [PATCH 0178/1315] style: make formatting of switch statement more consistent --- core/src/aztec/AZHighLevelEncoder.cpp | 22 +-- core/src/datamatrix/DMHighLevelEncoder.cpp | 34 ++--- core/src/datamatrix/DMSymbolInfo.cpp | 36 ++--- core/src/maxicode/MCDecoder.cpp | 74 +++++----- core/src/oned/ODCode128Writer.cpp | 49 +++---- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 114 +++++++-------- core/src/pdf417/PDFHighLevelEncoder.cpp | 134 ++++++++---------- core/src/qrcode/QRCodecMode.cpp | 10 +- core/src/qrcode/QREncoder.cpp | 19 +-- core/src/qrcode/QRErrorCorrectionLevel.cpp | 13 +- 10 files changed, 211 insertions(+), 294 deletions(-) diff --git a/core/src/aztec/AZHighLevelEncoder.cpp b/core/src/aztec/AZHighLevelEncoder.cpp index 2a473f180b..f27bac3b5f 100644 --- a/core/src/aztec/AZHighLevelEncoder.cpp +++ b/core/src/aztec/AZHighLevelEncoder.cpp @@ -367,28 +367,18 @@ HighLevelEncoder::Encode(const std::string& text) int pairCode; int nextChar = index + 1 < Size(text) ? text[index + 1] : 0; switch (text[index]) { - case '\r': - pairCode = nextChar == '\n' ? 2 : 0; - break; - case '.': - pairCode = nextChar == ' ' ? 3 : 0; - break; - case ',': - pairCode = nextChar == ' ' ? 4 : 0; - break; - case ':': - pairCode = nextChar == ' ' ? 5 : 0; - break; - default: - pairCode = 0; + case '\r': pairCode = nextChar == '\n' ? 2 : 0; break; + case '.': pairCode = nextChar == ' ' ? 3 : 0; break; + case ',': pairCode = nextChar == ' ' ? 4 : 0; break; + case ':': pairCode = nextChar == ' ' ? 5 : 0; break; + default: pairCode = 0; } if (pairCode > 0) { // We have one of the four special PUNCT pairs. Treat them specially. // Get a new set of states for the two new characters. states = UpdateStateListForPair(states, index, pairCode); index++; - } - else { + } else { // Get a new set of states for the new character. states = UpdateStateListForChar(states, text, index); } diff --git a/core/src/datamatrix/DMHighLevelEncoder.cpp b/core/src/datamatrix/DMHighLevelEncoder.cpp index dc44a53a4c..0b43f6a7eb 100644 --- a/core/src/datamatrix/DMHighLevelEncoder.cpp +++ b/core/src/datamatrix/DMHighLevelEncoder.cpp @@ -607,26 +607,16 @@ namespace X12Encoder { static int EncodeChar(int c, std::string& sb) { switch (c) { - case '\r': - sb.push_back('\0'); - break; - case '*': - sb.push_back('\1'); - break; - case '>': - sb.push_back('\2'); - break; - case ' ': - sb.push_back('\3'); - break; + case '\r': sb.push_back('\0'); break; + case '*': sb.push_back('\1'); break; + case '>': sb.push_back('\2'); break; + case ' ': sb.push_back('\3'); break; default: if (c >= '0' && c <= '9') { sb.push_back((char)(c - 48 + 4)); - } - else if (c >= 'A' && c <= 'Z') { + } else if (c >= 'A' && c <= 'Z') { sb.push_back((char)(c - 65 + 14)); - } - else { + } else { throw std::invalid_argument("Illegal character: " + ToHexString(c)); } break; @@ -915,12 +905,12 @@ ByteArray Encode(const std::wstring& msg, SymbolShape shape, int minWidth, int m int encodingMode = ASCII_ENCODATION; //Default mode while (context.hasMoreCharacters()) { switch (encodingMode) { - case ASCII_ENCODATION: ASCIIEncoder::EncodeASCII(context); break; - case C40_ENCODATION: C40Encoder::EncodeC40(context); break; - case TEXT_ENCODATION: DMTextEncoder::EncodeText(context); break; - case X12_ENCODATION: X12Encoder::EncodeX12(context); break; - case EDIFACT_ENCODATION: EdifactEncoder::EncodeEdifact(context); break; - case BASE256_ENCODATION: Base256Encoder::EncodeBase256(context); break; + case ASCII_ENCODATION: ASCIIEncoder::EncodeASCII(context); break; + case C40_ENCODATION: C40Encoder::EncodeC40(context); break; + case TEXT_ENCODATION: DMTextEncoder::EncodeText(context); break; + case X12_ENCODATION: X12Encoder::EncodeX12(context); break; + case EDIFACT_ENCODATION: EdifactEncoder::EncodeEdifact(context); break; + case BASE256_ENCODATION: Base256Encoder::EncodeBase256(context); break; } if (context.newEncoding() >= 0) { encodingMode = context.newEncoding(); diff --git a/core/src/datamatrix/DMSymbolInfo.cpp b/core/src/datamatrix/DMSymbolInfo.cpp index 97ac6c0b90..344a0d4832 100644 --- a/core/src/datamatrix/DMSymbolInfo.cpp +++ b/core/src/datamatrix/DMSymbolInfo.cpp @@ -129,36 +129,24 @@ int SymbolInfo::horizontalDataRegions() const { switch (_dataRegions) { - case 1: - return 1; - case 2: - return 2; - case 4: - return 2; - case 16: - return 4; - case 36: - return 6; - default: - throw std::out_of_range("Cannot handle this number of data regions"); + case 1: return 1; + case 2: return 2; + case 4: return 2; + case 16: return 4; + case 36: return 6; + default: throw std::out_of_range("Cannot handle this number of data regions"); } } int SymbolInfo::verticalDataRegions() const { switch (_dataRegions) { - case 1: - return 1; - case 2: - return 1; - case 4: - return 2; - case 16: - return 4; - case 36: - return 6; - default: - throw std::out_of_range("Cannot handle this number of data regions"); + case 1: return 1; + case 2: return 1; + case 4: return 2; + case 16: return 4; + case 36: return 6; + default: throw std::out_of_range("Cannot handle this number of data regions"); } } diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 5c4a28b71d..15b9a7bfa5 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -294,27 +294,22 @@ namespace DecodedBitStreamParser result.reserve(144); StructuredAppendInfo sai; switch (mode) { - case 2: - case 3: { - auto postcode = mode == 2 ? ToString(GetPostCode2(bytes), GetPostCode2Length(bytes)) : GetPostCode3(bytes); - auto country = ToString(GetCountry(bytes), 3); - auto service = ToString(GetServiceClass(bytes), 3); - result.append(GetMessage(bytes, 10, 84, characterSet, sai)); - if (result.size() >= 9 && result.compare(0, 7, L"[)>\u001E01\u001D") == 0) { // "[)>" + RS + "01" + GS - result.insert(9, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); - } - else { - result.insert(0, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); - } - break; + case 2: + case 3: { + auto postcode = mode == 2 ? ToString(GetPostCode2(bytes), GetPostCode2Length(bytes)) : GetPostCode3(bytes); + auto country = ToString(GetCountry(bytes), 3); + auto service = ToString(GetServiceClass(bytes), 3); + result.append(GetMessage(bytes, 10, 84, characterSet, sai)); + if (result.size() >= 9 && result.compare(0, 7, L"[)>\u001E01\u001D") == 0) { // "[)>" + RS + "01" + GS + result.insert(9, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); + } else { + result.insert(0, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); } - case 4: - case 6: - result.append(GetMessage(bytes, 1, 93, characterSet, sai)); - break; - case 5: - result.append(GetMessage(bytes, 1, 77, characterSet, sai)); - break; + break; + } + case 4: + case 6: result.append(GetMessage(bytes, 1, 93, characterSet, sai)); break; + case 5: result.append(GetMessage(bytes, 1, 77, characterSet, sai)); break; } // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using modifiers @@ -350,27 +345,24 @@ Decoder::Decode(const BitMatrix& bits, const std::string& characterSet) int mode = codewords[0] & 0x0F; ByteArray datawords; switch (mode) { - case 2: // Structured Carrier Message (numeric postcode) - case 3: // Structured Carrier Message (alphanumeric postcode) - case 4: // Standard Symbol - case 6: // Reader Programming - if (CorrectErrors(codewords, 20, 84, 40, EVEN) && CorrectErrors(codewords, 20, 84, 40, ODD)) { - datawords.resize(94, 0); - } - else { - return DecodeStatus::ChecksumError; - } - break; - case 5: // Full ECC - if (CorrectErrors(codewords, 20, 68, 56, EVEN) && CorrectErrors(codewords, 20, 68, 56, ODD)) { - datawords.resize(78, 0); - } - else { - return DecodeStatus::ChecksumError; - } - break; - default: - return DecodeStatus::FormatError; + case 2: // Structured Carrier Message (numeric postcode) + case 3: // Structured Carrier Message (alphanumeric postcode) + case 4: // Standard Symbol + case 6: // Reader Programming + if (CorrectErrors(codewords, 20, 84, 40, EVEN) && CorrectErrors(codewords, 20, 84, 40, ODD)) { + datawords.resize(94, 0); + } else { + return DecodeStatus::ChecksumError; + } + break; + case 5: // Full ECC + if (CorrectErrors(codewords, 20, 68, 56, EVEN) && CorrectErrors(codewords, 20, 68, 56, ODD)) { + datawords.resize(78, 0); + } else { + return DecodeStatus::ChecksumError; + } + break; + default: return DecodeStatus::FormatError; } std::copy_n(codewords.begin(), 10, datawords.begin()); diff --git a/core/src/oned/ODCode128Writer.cpp b/core/src/oned/ODCode128Writer.cpp index 9c3f2d2f51..24a097e3bf 100644 --- a/core/src/oned/ODCode128Writer.cpp +++ b/core/src/oned/ODCode128Writer.cpp @@ -155,16 +155,15 @@ Code128Writer::encode(const std::wstring& contents, int width, int height) const for (int i = 0; i < length; ++i) { int c = contents[i]; switch (c) { - case ESCAPE_FNC_1: - case ESCAPE_FNC_2: - case ESCAPE_FNC_3: - case ESCAPE_FNC_4: - break; - default: - if (c > 127) { - // support for FNC4 isn't implemented, no full Latin-1 character set available at the moment - throw std::invalid_argument(std::string("Bad character in input: ") + static_cast(c)); - } + case ESCAPE_FNC_1: + case ESCAPE_FNC_2: + case ESCAPE_FNC_3: + case ESCAPE_FNC_4: break; + default: + if (c > 127) { + // support for FNC4 isn't implemented, no full Latin-1 character set available at the moment + throw std::invalid_argument(std::string("Bad character in input: ") + static_cast(c)); + } } } @@ -184,23 +183,10 @@ Code128Writer::encode(const std::wstring& contents, int width, int height) const // Encode the current character // First handle escapes switch (contents[position]) { - case ESCAPE_FNC_1: - patternIndex = CODE_FNC_1; - break; - case ESCAPE_FNC_2: - patternIndex = CODE_FNC_2; - break; - case ESCAPE_FNC_3: - patternIndex = CODE_FNC_3; - break; - case ESCAPE_FNC_4: - if (codeSet == CODE_CODE_A) { - patternIndex = CODE_FNC_4_A; - } - else { - patternIndex = CODE_FNC_4_B; - } - break; + case ESCAPE_FNC_1: patternIndex = CODE_FNC_1; break; + case ESCAPE_FNC_2: patternIndex = CODE_FNC_2; break; + case ESCAPE_FNC_3: patternIndex = CODE_FNC_3; break; + case ESCAPE_FNC_4: patternIndex = (codeSet == CODE_CODE_A) ? CODE_FNC_4_A : CODE_FNC_4_B; break; default: // Then handle normal characters otherwise if (codeSet == CODE_CODE_A) { @@ -209,12 +195,11 @@ Code128Writer::encode(const std::wstring& contents, int width, int height) const // everything below a space character comes behind the underscore in the code patterns table patternIndex += '`'; } - } - else if (codeSet == CODE_CODE_B) { + } else if (codeSet == CODE_CODE_B) { patternIndex = contents[position] - ' '; - } - else { // CODE_CODE_C - patternIndex = (contents[position] - '0') * 10 + (position+1 < length ? contents[position+1] - '0' : 0); + } else { // CODE_CODE_C + patternIndex = + (contents[position] - '0') * 10 + (position + 1 < length ? contents[position + 1] - '0' : 0); position++; // Also incremented below } } diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 7bfc311703..51b1f8f088 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -91,9 +91,7 @@ static bool TerminatesCompaction(int code) case BYTE_COMPACTION_MODE_LATCH_6: case BEGIN_MACRO_PDF417_CONTROL_BLOCK: case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: - case MACRO_PDF417_TERMINATOR: - return true; - break; + case MACRO_PDF417_TERMINATOR: return true; } return false; } @@ -683,70 +681,64 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, while (codeIndex < codewords[0]) { switch (codewords[codeIndex]) { - case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: { - codeIndex++; - if (codeIndex >= codewords[0]) { - break; - } - switch (codewords[codeIndex]) { - case MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: { - std::string fileName; - codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, fileName); - resultMetadata.setFileName(fileName); - break; - } - case MACRO_PDF417_OPTIONAL_FIELD_SENDER: { - std::string sender; - codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, sender); - resultMetadata.setSender(sender); - break; - } - case MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE: { - std::string addressee; - codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, addressee); - resultMetadata.setAddressee(addressee); - break; - } - case MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: { - uint64_t segmentCount; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, segmentCount); - resultMetadata.setSegmentCount(static_cast(segmentCount)); - break; - } - case MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: { - uint64_t timestamp; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, timestamp); - resultMetadata.setTimestamp(timestamp); - break; - } - case MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: { - uint64_t checksum; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, checksum); - resultMetadata.setChecksum(static_cast(checksum)); - break; - } - case MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: { - uint64_t fileSize; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, fileSize); - resultMetadata.setFileSize(fileSize); - break; - } - default: { - status = DecodeStatus::FormatError; - break; - } - } + case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: { + codeIndex++; + if (codeIndex >= codewords[0]) { break; } - case MACRO_PDF417_TERMINATOR: { - codeIndex++; - resultMetadata.setLastSegment(true); + switch (codewords[codeIndex]) { + case MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: { + std::string fileName; + codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, fileName); + resultMetadata.setFileName(fileName); break; } - default: { - status = DecodeStatus::FormatError; + case MACRO_PDF417_OPTIONAL_FIELD_SENDER: { + std::string sender; + codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, sender); + resultMetadata.setSender(sender); + break; + } + case MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE: { + std::string addressee; + codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, addressee); + resultMetadata.setAddressee(addressee); break; } + case MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: { + uint64_t segmentCount; + codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, segmentCount); + resultMetadata.setSegmentCount(static_cast(segmentCount)); + break; + } + case MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: { + uint64_t timestamp; + codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, timestamp); + resultMetadata.setTimestamp(timestamp); + break; + } + case MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: { + uint64_t checksum; + codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, checksum); + resultMetadata.setChecksum(static_cast(checksum)); + break; + } + case MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: { + uint64_t fileSize; + codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, fileSize); + resultMetadata.setFileSize(fileSize); + break; + } + default: status = DecodeStatus::FormatError; break; + } + break; + } + case MACRO_PDF417_TERMINATOR: { + codeIndex++; + resultMetadata.setLastSegment(true); + break; + } + default: status = DecodeStatus::FormatError; break; } if (StatusIsError(status)) { return status; diff --git a/core/src/pdf417/PDFHighLevelEncoder.cpp b/core/src/pdf417/PDFHighLevelEncoder.cpp index 6bd2f4a6ab..c37b41c11b 100644 --- a/core/src/pdf417/PDFHighLevelEncoder.cpp +++ b/core/src/pdf417/PDFHighLevelEncoder.cpp @@ -231,80 +231,70 @@ static int EncodeText(const std::wstring& msg, int startpos, int count, int subm while (true) { int ch = msg[startpos + idx]; switch (submode) { - case SUBMODE_ALPHA: - if (IsAlphaUpper(ch)) { - tmp.push_back(ch == ' ' ? 26 : (ch - 65)); //space - } - else if (IsAlphaLower(ch)) { - submode = SUBMODE_LOWER; - tmp.push_back(27); //ll - continue; - } - else if (IsMixed(ch)) { - submode = SUBMODE_MIXED; - tmp.push_back(28); //ml - continue; - } - else { - tmp.push_back(29); //ps - tmp.push_back(PUNCTUATION[ch]); - } - break; - case SUBMODE_LOWER: - if (IsAlphaLower(ch)) { - tmp.push_back(ch == ' ' ? 26 : (ch - 97)); //space - } - else if (IsAlphaUpper(ch)) { - tmp.push_back(27); //as - tmp.push_back(ch - 65); - //space cannot happen here, it is also in "Lower" - } - else if (IsMixed(ch)) { - submode = SUBMODE_MIXED; - tmp.push_back(28); //ml - continue; - } - else { - tmp.push_back(29); //ps - tmp.push_back(PUNCTUATION[ch]); - } - break; - case SUBMODE_MIXED: - if (IsMixed(ch)) { - tmp.push_back(MIXED[ch]); - } - else if (IsAlphaUpper(ch)) { - submode = SUBMODE_ALPHA; - tmp.push_back(28); //al - continue; - } - else if (IsAlphaLower(ch)) { - submode = SUBMODE_LOWER; - tmp.push_back(27); //ll - continue; - } - else { - if (startpos + idx + 1 < count) { - int next = msg[startpos + idx + 1]; - if (IsPunctuation(next)) { - submode = SUBMODE_PUNCTUATION; - tmp.push_back(25); //pl - continue; - } + case SUBMODE_ALPHA: + if (IsAlphaUpper(ch)) { + tmp.push_back(ch == ' ' ? 26 : (ch - 65)); // space + } else if (IsAlphaLower(ch)) { + submode = SUBMODE_LOWER; + tmp.push_back(27); // ll + continue; + } else if (IsMixed(ch)) { + submode = SUBMODE_MIXED; + tmp.push_back(28); // ml + continue; + } else { + tmp.push_back(29); // ps + tmp.push_back(PUNCTUATION[ch]); + } + break; + case SUBMODE_LOWER: + if (IsAlphaLower(ch)) { + tmp.push_back(ch == ' ' ? 26 : (ch - 97)); // space + } else if (IsAlphaUpper(ch)) { + tmp.push_back(27); // as + tmp.push_back(ch - 65); + // space cannot happen here, it is also in "Lower" + } else if (IsMixed(ch)) { + submode = SUBMODE_MIXED; + tmp.push_back(28); // ml + continue; + } else { + tmp.push_back(29); // ps + tmp.push_back(PUNCTUATION[ch]); + } + break; + case SUBMODE_MIXED: + if (IsMixed(ch)) { + tmp.push_back(MIXED[ch]); + } else if (IsAlphaUpper(ch)) { + submode = SUBMODE_ALPHA; + tmp.push_back(28); // al + continue; + } else if (IsAlphaLower(ch)) { + submode = SUBMODE_LOWER; + tmp.push_back(27); // ll + continue; + } else { + if (startpos + idx + 1 < count) { + int next = msg[startpos + idx + 1]; + if (IsPunctuation(next)) { + submode = SUBMODE_PUNCTUATION; + tmp.push_back(25); // pl + continue; } - tmp.push_back(29); //ps - tmp.push_back(PUNCTUATION[ch]); - } - break; - default: //SUBMODE_PUNCTUATION - if (IsPunctuation(ch)) { - tmp.push_back(PUNCTUATION[ch]); - } - else { - submode = SUBMODE_ALPHA; - tmp.push_back(29); //al - continue; } + tmp.push_back(29); // ps + tmp.push_back(PUNCTUATION[ch]); + } + break; + default: // SUBMODE_PUNCTUATION + if (IsPunctuation(ch)) { + tmp.push_back(PUNCTUATION[ch]); + } else { + submode = SUBMODE_ALPHA; + tmp.push_back(29); // al + continue; + } } idx++; if (idx >= count) { diff --git a/core/src/qrcode/QRCodecMode.cpp b/core/src/qrcode/QRCodecMode.cpp index 05e32038a9..a64e6bd9c6 100644 --- a/core/src/qrcode/QRCodecMode.cpp +++ b/core/src/qrcode/QRCodecMode.cpp @@ -44,12 +44,12 @@ int CharacterCountBits(CodecMode mode, const Version& version) i = 2; switch (mode) { - case CodecMode::NUMERIC: return std::array{10, 12, 14}[i]; + case CodecMode::NUMERIC: return std::array{10, 12, 14}[i]; case CodecMode::ALPHANUMERIC: return std::array{9, 11, 13}[i]; - case CodecMode::BYTE: return std::array{8, 16, 16}[i]; - case CodecMode::KANJI: [[fallthrough]]; - case CodecMode::HANZI: return std::array{8, 10, 12}[i]; - default: return 0; + case CodecMode::BYTE: return std::array{8, 16, 16}[i]; + case CodecMode::KANJI: [[fallthrough]]; + case CodecMode::HANZI: return std::array{8, 10, 12}[i]; + default: return 0; } } diff --git a/core/src/qrcode/QREncoder.cpp b/core/src/qrcode/QREncoder.cpp index 9c05877482..297da96a31 100644 --- a/core/src/qrcode/QREncoder.cpp +++ b/core/src/qrcode/QREncoder.cpp @@ -250,20 +250,11 @@ ZXING_EXPORT_TEST_ONLY void AppendBytes(const std::wstring& content, CodecMode mode, CharacterSet encoding, BitArray& bits) { switch (mode) { - case CodecMode::NUMERIC: - AppendNumericBytes(content, bits); - break; - case CodecMode::ALPHANUMERIC: - AppendAlphanumericBytes(content, bits); - break; - case CodecMode::BYTE: - Append8BitBytes(content, encoding, bits); - break; - case CodecMode::KANJI: - AppendKanjiBytes(content, bits); - break; - default: - throw std::invalid_argument("Invalid mode: " + std::to_string(static_cast(mode))); + case CodecMode::NUMERIC: AppendNumericBytes(content, bits); break; + case CodecMode::ALPHANUMERIC: AppendAlphanumericBytes(content, bits); break; + case CodecMode::BYTE: Append8BitBytes(content, encoding, bits); break; + case CodecMode::KANJI: AppendKanjiBytes(content, bits); break; + default: throw std::invalid_argument("Invalid mode: " + std::to_string(static_cast(mode))); } } diff --git a/core/src/qrcode/QRErrorCorrectionLevel.cpp b/core/src/qrcode/QRErrorCorrectionLevel.cpp index 80890161f0..7ff749a515 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.cpp +++ b/core/src/qrcode/QRErrorCorrectionLevel.cpp @@ -30,13 +30,12 @@ const wchar_t* ToString(ErrorCorrectionLevel l) ErrorCorrectionLevel ECLevelFromString(const char* str) { - switch (str[0]) - { - case 'L': return ErrorCorrectionLevel::Low; - case 'M': return ErrorCorrectionLevel::Medium; - case 'Q': return ErrorCorrectionLevel::Quality; - case 'H': return ErrorCorrectionLevel::High; - default: return ErrorCorrectionLevel::Invalid; + switch (str[0]) { + case 'L': return ErrorCorrectionLevel::Low; + case 'M': return ErrorCorrectionLevel::Medium; + case 'Q': return ErrorCorrectionLevel::Quality; + case 'H': return ErrorCorrectionLevel::High; + default: return ErrorCorrectionLevel::Invalid; } } From 00c649898c995b1a3076edc9dfa5dbfc4d405551 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 3 May 2022 01:38:30 +0200 Subject: [PATCH 0179/1315] c++: remove unused variable in PDFScanningDecoder --- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 51b1f8f088..ab61c4c6c8 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -668,8 +668,9 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, // the fileId using text compaction, so in those cases the fileId will appear mangled. std::ostringstream fileId; fileId.fill('0'); - for (int i = 0; codeIndex < codewords[0] && codewords[codeIndex] != MACRO_PDF417_TERMINATOR - && codewords[codeIndex] != BEGIN_MACRO_PDF417_OPTIONAL_FIELD; i++, codeIndex++) { + for (; codeIndex < codewords[0] && codewords[codeIndex] != MACRO_PDF417_TERMINATOR && + codewords[codeIndex] != BEGIN_MACRO_PDF417_OPTIONAL_FIELD; + codeIndex++) { fileId << std::setw(3) << codewords[codeIndex]; } resultMetadata.setFileId(fileId.str()); From 840d8d779ab9ef88c6d524101f0cca6d672a785b Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 3 May 2022 01:43:21 +0200 Subject: [PATCH 0180/1315] c++: remove unused variables in textcodecs (fix clang warning) --- core/src/textcodec/Big5TextDecoder.cpp | 8 ++++---- core/src/textcodec/GBTextDecoder.cpp | 22 +++++++++++----------- core/src/textcodec/JPTextDecoder.cpp | 18 +++++++++--------- core/src/textcodec/KRTextDecoder.cpp | 10 +++++----- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/core/src/textcodec/Big5TextDecoder.cpp b/core/src/textcodec/Big5TextDecoder.cpp index 04ffc71c40..48ec9bdf16 100644 --- a/core/src/textcodec/Big5TextDecoder.cpp +++ b/core/src/textcodec/Big5TextDecoder.cpp @@ -1747,7 +1747,7 @@ Big5TextDecoder::AppendBig5(std::vector& result, const uint8_t* bytes, { uint8_t buf[2] = { 0 }; int nbuf = 0; - int invalid = 0; +// int invalid = 0; result.reserve(length); for (size_t i = 0; i& result, const uint8_t* bytes, else { // Invalid result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } break; case 1: @@ -1779,13 +1779,13 @@ Big5TextDecoder::AppendBig5(std::vector& result, const uint8_t* bytes, else { // Error result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } } else { // Error result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } nbuf = 0; break; diff --git a/core/src/textcodec/GBTextDecoder.cpp b/core/src/textcodec/GBTextDecoder.cpp index cef0368897..e104b595e9 100644 --- a/core/src/textcodec/GBTextDecoder.cpp +++ b/core/src/textcodec/GBTextDecoder.cpp @@ -3433,7 +3433,7 @@ GBTextDecoder::AppendGB18030(std::vector& result, const uint8_t* bytes { uint8_t buf[4]; int nbuf = 0; - int invalid = 0; +// int invalid = 0; result.resize(length); int unicodeLen = 0; @@ -3454,7 +3454,7 @@ GBTextDecoder::AppendGB18030(std::vector& result, const uint8_t* bytes else { // Invalid result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; } break; case 1: @@ -3468,7 +3468,7 @@ GBTextDecoder::AppendGB18030(std::vector& result, const uint8_t* bytes } else { result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; } nbuf = 0; } @@ -3479,7 +3479,7 @@ GBTextDecoder::AppendGB18030(std::vector& result, const uint8_t* bytes else { // Error result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; nbuf = 0; } break; @@ -3491,7 +3491,7 @@ GBTextDecoder::AppendGB18030(std::vector& result, const uint8_t* bytes } else { result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; nbuf = 0; } break; @@ -3506,12 +3506,12 @@ GBTextDecoder::AppendGB18030(std::vector& result, const uint8_t* bytes } else { result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; } } else { result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; } nbuf = 0; break; @@ -3525,7 +3525,7 @@ GBTextDecoder::AppendGB2312(std::vector& result, const uint8_t* bytes, { uint8_t buf[2]; int nbuf = 0; - int invalid = 0; +// int invalid = 0; result.resize(length); int unicodeLen = 0; @@ -3545,7 +3545,7 @@ GBTextDecoder::AppendGB2312(std::vector& result, const uint8_t* bytes, else { // Invalid result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; } break; case 1: @@ -3559,14 +3559,14 @@ GBTextDecoder::AppendGB2312(std::vector& result, const uint8_t* bytes, } else { result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; } nbuf = 0; } else { // Error result[unicodeLen++] = REPLACEMENT; - ++invalid; +// ++invalid; nbuf = 0; } break; diff --git a/core/src/textcodec/JPTextDecoder.cpp b/core/src/textcodec/JPTextDecoder.cpp index 4859e647ec..22874a4961 100644 --- a/core/src/textcodec/JPTextDecoder.cpp +++ b/core/src/textcodec/JPTextDecoder.cpp @@ -2634,7 +2634,7 @@ JPTextDecoder::AppendShiftJIS(std::vector& result, const uint8_t* byte { uint8_t buf[1] = { 0 }; int nbuf = 0; - int invalid = 0; +// int invalid = 0; unsigned u = 0; for (size_t i = 0; i& result, const uint8_t* byte else { // Invalid result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } break; case 1: @@ -2675,7 +2675,7 @@ JPTextDecoder::AppendShiftJIS(std::vector& result, const uint8_t* byte else { // Invalid result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } nbuf = 0; break; @@ -2696,7 +2696,7 @@ JPTextDecoder::AppendEUCJP(std::vector& result, const uint8_t* bytes, uint8_t buf[2] = { 0, 0 }; int nbuf = 0; - int invalid = 0; +// int invalid = 0; for (size_t i = 0; i& result, const uint8_t* bytes, else { // Invalid result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } break; case 1: @@ -2730,7 +2730,7 @@ JPTextDecoder::AppendEUCJP(std::vector& result, const uint8_t* bytes, } else { result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } nbuf = 0; } @@ -2743,7 +2743,7 @@ JPTextDecoder::AppendEUCJP(std::vector& result, const uint8_t* bytes, else { // Error result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; nbuf = 0; } } @@ -2755,7 +2755,7 @@ JPTextDecoder::AppendEUCJP(std::vector& result, const uint8_t* bytes, else { // Error result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } nbuf = 0; } @@ -2767,7 +2767,7 @@ JPTextDecoder::AppendEUCJP(std::vector& result, const uint8_t* bytes, } else { result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } nbuf = 0; } diff --git a/core/src/textcodec/KRTextDecoder.cpp b/core/src/textcodec/KRTextDecoder.cpp index 08e0b61895..dcbc0646ac 100644 --- a/core/src/textcodec/KRTextDecoder.cpp +++ b/core/src/textcodec/KRTextDecoder.cpp @@ -1029,7 +1029,7 @@ KRTextDecoder::AppendEucKr(std::vector& result, const uint8_t* bytes, { uint8_t buf[2] = { 0, 0 }; int nbuf = 0; - int invalid = 0; +// int invalid = 0; for (size_t i = 0; i& result, const uint8_t* bytes, else { // Invalid result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; } break; case 1: @@ -1072,7 +1072,7 @@ KRTextDecoder::AppendEucKr(std::vector& result, const uint8_t* bytes, column = ch - 0x81 + 52; else { result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; break; } @@ -1084,7 +1084,7 @@ KRTextDecoder::AppendEucKr(std::vector& result, const uint8_t* bytes, // check whether the conversion avialble in the table. if (internal_code < 0 || internal_code >= 8822) { result.push_back(REPLACEMENT); - ++invalid; +// ++invalid; break; } else @@ -1094,4 +1094,4 @@ KRTextDecoder::AppendEucKr(std::vector& result, const uint8_t* bytes, break; } } -} \ No newline at end of file +} From 75648494b0e378721e3a76fd2f440bbfebe4f6a2 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 3 May 2022 01:44:09 +0200 Subject: [PATCH 0181/1315] wasm: enable new `tryDownscale` hint --- wrappers/wasm/BarcodeReader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wrappers/wasm/BarcodeReader.cpp b/wrappers/wasm/BarcodeReader.cpp index 6c25aa4cc4..5dd2dab2bf 100644 --- a/wrappers/wasm/BarcodeReader.cpp +++ b/wrappers/wasm/BarcodeReader.cpp @@ -39,6 +39,7 @@ ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, DecodeHints hints; hints.setTryHarder(tryHarder); hints.setTryRotate(tryHarder); + hints.setTryDownscale(tryHarder); hints.setFormats(BarcodeFormatsFromString(format)); int width, height, channels; @@ -71,6 +72,7 @@ ReadResult readBarcodeFromPixmap(int bufferPtr, int imgWidth, int imgHeight, boo DecodeHints hints; hints.setTryHarder(tryHarder); hints.setTryRotate(tryHarder); + hints.setTryDownscale(tryHarder); hints.setFormats(BarcodeFormatsFromString(format)); auto result = From d529003f4ae37507e11dc8fff57f173b9c844226 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 3 May 2022 01:52:25 +0200 Subject: [PATCH 0182/1315] c++: remove unused variables in (more) textcodecs (fix clang warning) --- core/src/textcodec/GBTextEncoder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/textcodec/GBTextEncoder.cpp b/core/src/textcodec/GBTextEncoder.cpp index 707ae60594..8bbb84826d 100644 --- a/core/src/textcodec/GBTextEncoder.cpp +++ b/core/src/textcodec/GBTextEncoder.cpp @@ -3977,7 +3977,7 @@ void GBTextEncoder::EncodeGB18030(const std::wstring& str, std::string& bytes) { static const char replacement = '?'; unsigned high = 0; - int invalid = 0; +// int invalid = 0; bytes.resize(4 * str.length() + 1); int index = 0; @@ -3998,14 +3998,14 @@ void GBTextEncoder::EncodeGB18030(const std::wstring& str, std::string& bytes) } else { bytes[index++] = replacement; - ++invalid; +// ++invalid; } high = 0; continue; } else { bytes[index++] = replacement; - ++invalid; +// ++invalid; high = 0; } } @@ -4026,7 +4026,7 @@ void GBTextEncoder::EncodeGB18030(const std::wstring& str, std::string& bytes) else { // Error bytes[index++] = replacement; - ++invalid; +// ++invalid; } } bytes.resize(index); From 00af76cd724aeec64a47fa7e7b7abf943e109bc8 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 3 May 2022 02:03:42 +0200 Subject: [PATCH 0183/1315] android: upgrade kotlin-plugin to 1.6.21 --- wrappers/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/android/build.gradle b/wrappers/android/build.gradle index 2eec1a2072..68b25395d4 100644 --- a/wrappers/android/build.gradle +++ b/wrappers/android/build.gradle @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.6.20" + ext.kotlin_version = "1.6.21" repositories { google() mavenCentral() From bdddf42ba366aaa2842ef746e5f1d13a821b1848 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 3 May 2022 02:04:48 +0200 Subject: [PATCH 0184/1315] android: use latest ZXing upstream version 3.5.0 in demo app --- wrappers/android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/android/app/build.gradle b/wrappers/android/app/build.gradle index 08b2c89fdf..c430af75f7 100644 --- a/wrappers/android/app/build.gradle +++ b/wrappers/android/app/build.gradle @@ -53,7 +53,7 @@ dependencies { implementation 'androidx.camera:camera-view:1.0.0-alpha32' // Java 'upstream' version of zxing (to compare performance) - implementation 'com.google.zxing:core:3.4.1' + implementation 'com.google.zxing:core:3.5.0' implementation project(':zxingcpp') } From 50f53ef73f610788feaebd4159f8e4b32e6d38d8 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 3 May 2022 09:36:14 +0200 Subject: [PATCH 0185/1315] Release 1.3.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ebe586975..7d01ee88b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.14) -project (ZXing VERSION "1.2.0" LANGUAGES CXX) +project (ZXing VERSION "1.3.0" LANGUAGES CXX) option (BUILD_WRITERS "Build with writer support (encoders)" ON) option (BUILD_READERS "Build with reader support (decoders)" ON) From 0bbf2ce2ad23a15b737512a007a3a991380ff918 Mon Sep 17 00:00:00 2001 From: Biswapriyo Nath Date: Tue, 3 May 2022 21:52:50 +0530 Subject: [PATCH 0186/1315] cmake: Install pkgconfig file in mingw --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d01ee88b4..b9052cac91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ if (NOT DEFINED INSTALLDIR) get_filename_component(INSTALLDIR ${INSTALLDIR} ABSOLUTE) endif() -IF (NOT WIN32) +IF (NOT WIN32 OR MINGW) configure_file(zxing.pc.in zxing.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zxing.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) ENDIF() From d6d13e4da49b231d046a30673de87b3aa71024e7 Mon Sep 17 00:00:00 2001 From: ptc-brainer <69149788+ptc-brainer@users.noreply.github.com> Date: Wed, 4 May 2022 16:18:05 +0200 Subject: [PATCH 0187/1315] Fixed comparison bug in MultiFormatReader.cpp Changed comparison of x position from lesser-or-equal to lesser which, in some cases, could result in invalid comparison result (i.e. a > b == b > a). Depending on the compiler and platform this can cause a crash if during sort, an object is tried to be moved onto itself. --- core/src/MultiFormatReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 7f01e33ee7..391bd72584 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -90,7 +90,7 @@ Results MultiFormatReader::readMultiple(const BinaryBitmap& image, int maxSymbol std::sort(res.begin(), res.end(), [](const Result& l, const Result& r) { auto lp = l.position().topLeft(); auto rp = r.position().topLeft(); - return lp.y < rp.y || (lp.y == rp.y && lp.x <= rp.x); + return lp.y < rp.y || (lp.y == rp.y && lp.x < rp.x); }); return res; From bd7a9509075e9531261c65c180119a9c710034bf Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Wed, 4 May 2022 18:11:35 +0200 Subject: [PATCH 0188/1315] Generate the PDF417 ratio table at compile time This not only avoids the entire computation at runtime, it also moves the required memory from .bss (allocated at runtime per process) to .rodata (shared between all processes and only loaded on demand), cutting down the .bss section size by about 90%. --- core/src/pdf417/PDFCodewordDecoder.cpp | 15 +++++++-------- core/src/pdf417/PDFCodewordDecoder.h | 8 ++++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/core/src/pdf417/PDFCodewordDecoder.cpp b/core/src/pdf417/PDFCodewordDecoder.cpp index ec84e962ac..cddb572723 100644 --- a/core/src/pdf417/PDFCodewordDecoder.cpp +++ b/core/src/pdf417/PDFCodewordDecoder.cpp @@ -27,7 +27,7 @@ namespace ZXing { namespace Pdf417 { -static const int SYMBOL_COUNT = 2787; +static constexpr const int SYMBOL_COUNT = 2787; /** @@ -35,7 +35,7 @@ static const int SYMBOL_COUNT = 2787; * specification. The index of a symbol in this table corresponds to the * index into the codeword table. */ -const std::array SYMBOL_TABLE = { +static constexpr const std::array SYMBOL_TABLE = { 0x1025e, 0x1027a, 0x1029e, 0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, 0x1035c, 0x10396, 0x103a6, 0x103ac, 0x10422, 0x10428, 0x10436, 0x10442, 0x10444, 0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482, 0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2, 0x104f4, 0x10504, 0x10508, 0x10510, 0x1051e, @@ -274,7 +274,7 @@ const std::array SYMBOL_TABLE = { /** * This table contains to codewords for all symbols. */ -static const std::array CODEWORD_TABLE = { +static constexpr const std::array CODEWORD_TABLE = { 2627, 1819, 2622, 2621, 1813, 1812, 2729, 2724, 2723, 2779, 2774, 2773, 902, 896, 908, 868, 865, 861, 859, 2511, 873, 871, 1780, 835, 2493, 825, 2491, 842, 837, 844, 1764, 1762, 811, 810, 809, 2483, 807, 2482, 806, 2480, 815, 814, 813, 812, 2484, 817, 816, 1745, 1744, 1742, 1746, 2655, 2637, 2635, 2626, 2625, 2623, 2628, 1820, 2752, @@ -423,7 +423,8 @@ using ModuleBitCountType = std::array; static const RatioTableType& GetRatioTable() { - auto initTable = [](RatioTableType& table) -> RatioTableType& { + static constexpr RatioTableType table{[]() constexpr { + RatioTableType table{}; for (int i = 0; i < SYMBOL_COUNT; i++) { int currentSymbol = SYMBOL_TABLE[i]; int currentBit = currentSymbol & 0x1; @@ -438,11 +439,9 @@ static const RatioTableType& GetRatioTable() } } return table; - }; + }()}; - static RatioTableType table; - static const auto& ref = initTable(table); - return ref; + return table; } static ModuleBitCountType SampleBitCounts(const ModuleBitCountType& moduleBitCount) diff --git a/core/src/pdf417/PDFCodewordDecoder.h b/core/src/pdf417/PDFCodewordDecoder.h index 12b63b5de8..5b8dc0a0ec 100644 --- a/core/src/pdf417/PDFCodewordDecoder.h +++ b/core/src/pdf417/PDFCodewordDecoder.h @@ -28,13 +28,13 @@ namespace Pdf417 { class CodewordDecoder { public: - static const int NUMBER_OF_CODEWORDS = 929; + static constexpr const int NUMBER_OF_CODEWORDS = 929; // Maximum Codewords (Data + Error). - static const int MAX_CODEWORDS_IN_BARCODE = NUMBER_OF_CODEWORDS - 1; + static constexpr const int MAX_CODEWORDS_IN_BARCODE = NUMBER_OF_CODEWORDS - 1; // One left row indication column + max 30 data columns + one right row indicator column //public static final int MAX_CODEWORDS_IN_ROW = 32; - static const int MODULES_IN_CODEWORD = 17; - static const int BARS_IN_MODULE = 8; + static constexpr const int MODULES_IN_CODEWORD = 17; + static constexpr const int BARS_IN_MODULE = 8; /** * @param symbol encoded symbol to translate to a codeword From edd19499e1fb5f6a24b16243d68346b0a95adf88 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Thu, 5 May 2022 18:31:44 +0200 Subject: [PATCH 0189/1315] Generate the DataMatrix PROD_SYMBOLS table at compilation time Avoids runtime code and moves the needed memory to the .rodata section. --- core/src/datamatrix/DMSymbolInfo.cpp | 2 +- core/src/datamatrix/DMSymbolInfo.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/datamatrix/DMSymbolInfo.cpp b/core/src/datamatrix/DMSymbolInfo.cpp index 344a0d4832..3aac399de0 100644 --- a/core/src/datamatrix/DMSymbolInfo.cpp +++ b/core/src/datamatrix/DMSymbolInfo.cpp @@ -26,7 +26,7 @@ namespace ZXing::DataMatrix { -static const SymbolInfo PROD_SYMBOLS[] = { +static constexpr const SymbolInfo PROD_SYMBOLS[] = { { false, 3, 5, 8, 8, 1 }, { false, 5, 7, 10, 10, 1 }, { true, 5, 7, 16, 6, 1 }, diff --git a/core/src/datamatrix/DMSymbolInfo.h b/core/src/datamatrix/DMSymbolInfo.h index feb5276b67..90756f0d9d 100644 --- a/core/src/datamatrix/DMSymbolInfo.h +++ b/core/src/datamatrix/DMSymbolInfo.h @@ -33,10 +33,10 @@ class SymbolInfo int _rsBlockError; public: - SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions) : + constexpr SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions) : SymbolInfo(rectangular, dataCapacity, errorCodewords, matrixWidth, matrixHeight, dataRegions, dataCapacity, errorCodewords) {} - SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions, int rsBlockData, int rsBlockError) : + constexpr SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions, int rsBlockData, int rsBlockError) : _rectangular(rectangular), _dataCapacity(dataCapacity), _errorCodewords(errorCodewords), _matrixWidth(matrixWidth), _matrixHeight(matrixHeight), _dataRegions(dataRegions), _rsBlockData(rsBlockData), _rsBlockError(rsBlockError) From bec670de591e83406159f40ef3c05f820c9b883a Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 6 May 2022 13:38:45 +0200 Subject: [PATCH 0190/1315] style: experiment with clang-format / random indentation fixes Two goals: a) come closer to what the current code base looks like b) make up my mind about what I prefer This is a WIP and definitively not globally applicable, yet. This partly fixes inconsistencies with what was already established style. --- .clang-format | 12 ++- core/src/BitArray.h | 85 +++++++++---------- core/src/BitMatrix.h | 55 ++++++------ core/src/BitMatrixCursor.h | 2 +- core/src/DecodeHints.h | 39 +++++---- core/src/DecoderResult.h | 3 +- core/src/DetectorResult.h | 4 +- core/src/ImageView.h | 10 ++- core/src/Result.cpp | 24 ++++-- core/src/Result.h | 56 +++--------- core/src/aztec/AZHighLevelEncoder.cpp | 12 +-- core/src/datamatrix/DMDetector.cpp | 6 +- core/src/datamatrix/DMHighLevelEncoder.cpp | 9 +- core/src/datamatrix/DMReader.cpp | 13 ++- core/src/datamatrix/DMSymbolInfo.h | 77 +++++++---------- core/src/oned/ODCode128Writer.cpp | 19 +++-- core/src/oned/ODMultiUPCEANReader.cpp | 27 +++--- .../oned/rss/ODRSSExpandedBinaryDecoder.cpp | 38 +++------ .../src/oned/rss/ODRSSGenericAppIdDecoder.cpp | 6 +- core/src/pdf417/PDFCodewordDecoder.cpp | 4 +- core/src/qrcode/QRDataBlock.h | 12 +-- core/src/qrcode/QRDecoder.cpp | 54 +++++------- core/src/qrcode/QRDetector.cpp | 6 +- core/src/qrcode/QRECB.h | 17 ++-- core/src/qrcode/QREncoder.cpp | 22 ++--- core/src/qrcode/QRErrorCorrectionLevel.cpp | 9 +- core/src/qrcode/QRErrorCorrectionLevel.h | 10 +-- core/src/qrcode/QRFormatInformation.h | 11 +-- core/src/qrcode/QRMaskUtil.cpp | 23 ++--- core/src/qrcode/QRMaskUtil.h | 10 ++- core/src/qrcode/QRMatrixUtil.cpp | 6 +- core/src/qrcode/QRMatrixUtil.h | 3 +- core/src/qrcode/QRReader.cpp | 8 +- core/src/qrcode/QRVersion.cpp | 16 ++-- core/src/qrcode/QRVersion.h | 26 ++---- core/src/qrcode/QRWriter.cpp | 22 +++-- 36 files changed, 330 insertions(+), 426 deletions(-) diff --git a/.clang-format b/.clang-format index 5520e59df9..51ba5e80f4 100644 --- a/.clang-format +++ b/.clang-format @@ -8,22 +8,26 @@ TabWidth: 4 UseTab: ForContinuationAndIndentation # ForIndentation AccessModifierOffset: -4 -BreakBeforeBraces: Mozilla -ColumnLimit: 120 +ColumnLimit: 135 #AlignConsecutiveAssignments: true +AlignConsecutiveBitFields: true AlignEscapedNewlines: DontAlign AlignTrailingComments: true -AllowShortCaseLabelsOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: Inline #AllowShortLambdasOnASingleLine: Inline +AllowShortEnumsOnASingleLine: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakTemplateDeclarations: Yes BreakBeforeBraces: Mozilla +BreakBeforeBinaryOperators: NonAssignment BreakBeforeTernaryOperators: true -ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true FixNamespaceComments: true IncludeBlocks: Regroup KeepEmptyLinesAtTheStartOfBlocks: false diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 2fdb4a567e..490c0d6e6d 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -36,7 +36,8 @@ namespace ZXing { class ByteArray; template -struct Range { +struct Range +{ Iterator begin, end; explicit operator bool() const { return begin < end; } int size() const { return static_cast(end - begin); } @@ -129,20 +130,24 @@ class BitArray BitArray() = default; - explicit BitArray(int size) : + explicit BitArray(int size) + : #ifdef ZX_FAST_BIT_STORAGE - _bits(size, 0) {} + _bits(size, 0) {} #else - _size(size), _bits((size + 31) / 32, 0) {} + _size(size), + _bits((size + 31) / 32, 0) {} #endif - BitArray(BitArray&& other) noexcept : + BitArray(BitArray&& other) noexcept + : #ifndef ZX_FAST_BIT_STORAGE - _size(other._size), + _size(other._size), #endif - _bits(std::move(other._bits)) {} + _bits(std::move(other._bits)) {} - BitArray& operator=(BitArray&& other) noexcept { + BitArray& operator=(BitArray&& other) noexcept + { #ifndef ZX_FAST_BIT_STORAGE _size = other._size; #endif @@ -150,27 +155,25 @@ class BitArray return *this; } - BitArray copy() const { - return *this; - } + BitArray copy() const { return *this; } - int size() const noexcept { + int size() const noexcept + { #ifdef ZX_FAST_BIT_STORAGE return Size(_bits); #else return _size; #endif } - - int sizeInBytes() const noexcept { - return (size() + 7) / 8; - } + + int sizeInBytes() const noexcept { return (size() + 7) / 8; } /** * @param i bit to get * @return true iff bit i is set */ - bool get(int i) const { + bool get(int i) const + { #ifdef ZX_FAST_BIT_STORAGE return _bits.at(i) != 0; #else @@ -188,7 +191,8 @@ class BitArray Iterator end() const noexcept { return _bits.cend(); } template - static ITER getNextSetTo(ITER begin, ITER end, bool v) noexcept { + static ITER getNextSetTo(ITER begin, ITER end, bool v) noexcept + { while( begin != end && *begin != static_cast(v) ) ++begin; return begin; @@ -198,7 +202,8 @@ class BitArray Iterator begin() const noexcept { return iterAt(0); } Iterator end() const noexcept { return iterAt(_size); } - static Iterator getNextSetTo(Iterator begin, Iterator end, bool v) { + static Iterator getNextSetTo(Iterator begin, Iterator end, bool v) + { auto i = begin; // reconstruct _bits.end() auto bitsEnd = end._mask == 0x1 ? end._value : std::next(end._value); @@ -216,16 +221,15 @@ class BitArray return i; } - static ReverseIterator getNextSetTo(ReverseIterator begin, ReverseIterator end, bool v) { + static ReverseIterator getNextSetTo(ReverseIterator begin, ReverseIterator end, bool v) + { while( begin != end && *begin != v ) ++begin; return begin; } #endif - Iterator getNextSetTo(Iterator i, bool v) const { - return getNextSetTo(i, end(), v); - } + Iterator getNextSetTo(Iterator i, bool v) const { return getNextSetTo(i, end(), v); } Iterator getNextSet(Iterator i) const { return getNextSetTo(i, true); } Iterator getNextUnset(Iterator i) const { return getNextSetTo(i, false); } @@ -238,7 +242,8 @@ class BitArray * * @param i bit to set */ - void set(int i, bool val) { + void set(int i, bool val) + { #ifdef ZX_FAST_BIT_STORAGE _bits.at(i) = val; #else @@ -252,9 +257,7 @@ class BitArray /** * Clears all bits (sets to false). */ - void clearBits() { - std::fill(_bits.begin(), _bits.end(), 0); - } + void clearBits() { std::fill(_bits.begin(), _bits.end(), 0); } /** * Efficient method to check if a range of bits is set, or not set. @@ -266,7 +269,8 @@ class BitArray * @throws IllegalArgumentException if end is less than or equal to start */ #ifdef ZX_FAST_BIT_STORAGE - bool isRange(int start, int end, bool value) const { + bool isRange(int start, int end, bool value) const + { return std::all_of(std::begin(_bits) + start, std::begin(_bits) + end, [value](uint8_t v) { return v == static_cast(value); }); } #else @@ -276,7 +280,8 @@ class BitArray // Little helper method to make common isRange use case more readable. // Pass positive zone size to look for quiet zone after i and negative for zone in front of i. // Set allowClippedZone to false if clipping the zone at the image border is not acceptable. - bool hasQuietZone(Iterator i, int signedZoneSize, bool allowClippedZone = true) const { + bool hasQuietZone(Iterator i, int signedZoneSize, bool allowClippedZone = true) const + { int index = static_cast(i - begin()); if (signedZoneSize > 0) { if (!allowClippedZone && index + signedZoneSize >= size()) @@ -289,7 +294,8 @@ class BitArray } } - bool hasQuietZone(ReverseIterator i, int signedZoneSize, bool allowClippedZone = true) const { + bool hasQuietZone(ReverseIterator i, int signedZoneSize, bool allowClippedZone = true) const + { return hasQuietZone(i.base(), -signedZoneSize, allowClippedZone); } @@ -302,25 +308,20 @@ class BitArray * @param numBits bits from value to append */ #ifdef ZX_FAST_BIT_STORAGE - void appendBits(int value, int numBits) { + void appendBits(int value, int numBits) + { for (; numBits; --numBits) _bits.push_back((value >> (numBits-1)) & 1); } - void appendBit(bool bit) { - _bits.push_back(bit); - } + void appendBit(bool bit) { _bits.push_back(bit); } - void appendBitArray(const BitArray& other) { - _bits.insert(_bits.end(), other.begin(), other.end()); - } + void appendBitArray(const BitArray& other) { _bits.insert(_bits.end(), other.begin(), other.end()); } /** * Reverses all bits in the array. */ - void reverse() { - std::reverse(_bits.begin(), _bits.end()); - } + void reverse() { std::reverse(_bits.begin(), _bits.end()); } #else void appendBits(int value, int numBits); @@ -331,9 +332,7 @@ class BitArray /** * Reverses all bits in the array. */ - void reverse() { - BitHacks::Reverse(_bits, _bits.size() * 32 - _size); - } + void reverse() { BitHacks::Reverse(_bits, _bits.size() * 32 - _size); } #endif void bitwiseXOR(const BitArray& other); diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index 1569e885a5..01c5d51e03 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -81,14 +81,19 @@ class BitMatrix BitMatrix(int width, int height) : _width(width), _height(height), _rowSize(width), _bits(width * height, UNSET_V) {} #else - BitMatrix(int width, int height) : _width(width), _height(height), _rowSize((width + 31) / 32), _bits(((width + 31) / 32) * _height, 0) {} + BitMatrix(int width, int height) + : _width(width), _height(height), _rowSize((width + 31) / 32), _bits(((width + 31) / 32) * _height, 0) + {} #endif explicit BitMatrix(int dimension) : BitMatrix(dimension, dimension) {} // Construct a square matrix. - BitMatrix(BitMatrix&& other) noexcept : _width(other._width), _height(other._height), _rowSize(other._rowSize), _bits(std::move(other._bits)) {} + BitMatrix(BitMatrix&& other) noexcept + : _width(other._width), _height(other._height), _rowSize(other._rowSize), _bits(std::move(other._bits)) + {} - BitMatrix& operator=(BitMatrix&& other) noexcept { + BitMatrix& operator=(BitMatrix&& other) noexcept + { _width = other._width; _height = other._height; _rowSize = other._rowSize; @@ -96,13 +101,11 @@ class BitMatrix return *this; } - BitMatrix copy() const { - return *this; - } + BitMatrix copy() const { return *this; } #ifdef ZX_FAST_BIT_STORAGE // experimental iterator based access - template + template struct Row { iterator _begin, _end; @@ -120,7 +123,8 @@ class BitMatrix * @param y The vertical component (i.e. which row) * @return value of given bit in matrix */ - bool get(int x, int y) const { + bool get(int x, int y) const + { #ifdef ZX_FAST_BIT_STORAGE return isSet(get(y * _width + x)); #else @@ -134,7 +138,8 @@ class BitMatrix * @param x The horizontal component (i.e. which column) * @param y The vertical component (i.e. which row) */ - void set(int x, int y) { + void set(int x, int y) + { #ifdef ZX_FAST_BIT_STORAGE get(y * _width + x) = SET_V; #else @@ -142,7 +147,8 @@ class BitMatrix #endif } - void unset(int x, int y) { + void unset(int x, int y) + { #ifdef ZX_FAST_BIT_STORAGE get(y * _width + x) = UNSET_V; #else @@ -150,7 +156,8 @@ class BitMatrix #endif } - void set(int x, int y, bool val) { + void set(int x, int y, bool val) + { #ifdef ZX_FAST_BIT_STORAGE get(y * _width + x) = val ? SET_V : UNSET_V; #else @@ -164,7 +171,8 @@ class BitMatrix * @param x The horizontal component (i.e. which column) * @param y The vertical component (i.e. which row) */ - void flip(int x, int y) { + void flip(int x, int y) + { #ifdef ZX_FAST_BIT_STORAGE auto& v =get(y * _width + x); v = !v; @@ -173,7 +181,8 @@ class BitMatrix #endif } - void flipAll() { + void flipAll() + { for (auto& i : _bits) { i = ~i; } @@ -182,9 +191,7 @@ class BitMatrix /** * Clears all bits (sets to false). */ - void clear() { - std::fill(_bits.begin(), _bits.end(), 0); - } + void clear() { std::fill(_bits.begin(), _bits.end(), 0); } /** *

Sets a square region of the bit matrix to true.

@@ -241,27 +248,19 @@ class BitMatrix /** * @return The width of the matrix */ - int width() const { - return _width; - } + int width() const { return _width; } /** * @return The height of the matrix */ - int height() const { - return _height; - } + int height() const { return _height; } /** * @return The row size of the matrix. That is the number of 32-bits blocks that one row takes. */ - int rowSize() const { - return _rowSize; - } + int rowSize() const { return _rowSize; } - bool empty() const { - return _bits.empty(); - } + bool empty() const { return _bits.empty(); } friend bool operator==(const BitMatrix& a, const BitMatrix& b) { diff --git a/core/src/BitMatrixCursor.h b/core/src/BitMatrixCursor.h index a7a98e1b61..a8f3f0b6b6 100644 --- a/core/src/BitMatrixCursor.h +++ b/core/src/BitMatrixCursor.h @@ -21,7 +21,7 @@ namespace ZXing { -enum class Direction {LEFT = -1, RIGHT = 1}; +enum class Direction { LEFT = -1, RIGHT = 1 }; inline Direction opposite(Direction dir) noexcept { diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index d4ef5e6e32..8014bee4e5 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -49,31 +49,38 @@ enum class EanAddOnSymbol : unsigned char // see above class DecodeHints { - bool _tryHarder : 1; - bool _tryRotate : 1; - bool _tryDownscale : 1; - bool _isPure : 1; - bool _tryCode39ExtendedMode : 1; - bool _validateCode39CheckSum : 1; - bool _validateITFCheckSum : 1; - bool _returnCodabarStartEnd : 1; - Binarizer _binarizer : 2; + bool _tryHarder : 1; + bool _tryRotate : 1; + bool _tryDownscale : 1; + bool _isPure : 1; + bool _tryCode39ExtendedMode : 1; + bool _validateCode39CheckSum : 1; + bool _validateITFCheckSum : 1; + bool _returnCodabarStartEnd : 1; + Binarizer _binarizer : 2; EanAddOnSymbol _eanAddOnSymbol : 2; std::string _characterSet; std::vector _allowedLengths; - BarcodeFormats _formats = BarcodeFormat::None; + BarcodeFormats _formats = BarcodeFormat::None; uint16_t _downscaleThreshold = 500; - uint8_t _downscaleFactor = 3; - uint8_t _minLineCount = 2; - uint8_t _maxNumberOfSymbols = 0xff; + uint8_t _downscaleFactor = 3; + uint8_t _minLineCount = 2; + uint8_t _maxNumberOfSymbols = 0xff; public: // bitfields don't get default initialized to 0. DecodeHints() - : _tryHarder(1), _tryRotate(1), _tryDownscale(1), _isPure(0), _tryCode39ExtendedMode(0), - _validateCode39CheckSum(0), _validateITFCheckSum(0), _returnCodabarStartEnd(0), - _binarizer(Binarizer::LocalAverage), _eanAddOnSymbol(EanAddOnSymbol::Ignore) + : _tryHarder(1), + _tryRotate(1), + _tryDownscale(1), + _isPure(0), + _tryCode39ExtendedMode(0), + _validateCode39CheckSum(0), + _validateITFCheckSum(0), + _returnCodabarStartEnd(0), + _binarizer(Binarizer::LocalAverage), + _eanAddOnSymbol(EanAddOnSymbol::Ignore) {} #define ZX_PROPERTY(TYPE, GETTER, SETTER) \ diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 30abc8c772..ea158eff18 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -56,7 +56,8 @@ class DecoderResult public: DecoderResult(DecodeStatus status) : _status(status) {} - DecoderResult(ByteArray&& rawBytes, std::wstring&& text) : _rawBytes(std::move(rawBytes)), _text(std::move(text)) { + DecoderResult(ByteArray&& rawBytes, std::wstring&& text) : _rawBytes(std::move(rawBytes)), _text(std::move(text)) + { _numBits = 8 * Size(_rawBytes); } diff --git a/core/src/DetectorResult.h b/core/src/DetectorResult.h index a3549c0505..67db3b6b12 100644 --- a/core/src/DetectorResult.h +++ b/core/src/DetectorResult.h @@ -41,9 +41,7 @@ class DetectorResult DetectorResult(DetectorResult&&) = default; DetectorResult& operator=(DetectorResult&&) = default; - DetectorResult(BitMatrix&& bits, QuadrilateralI&& position) - : _bits(std::move(bits)), _position(std::move(position)) - {} + DetectorResult(BitMatrix&& bits, QuadrilateralI&& position) : _bits(std::move(bits)), _position(std::move(position)) {} const BitMatrix& bits() const & { return _bits; } BitMatrix&& bits() && { return std::move(_bits); } diff --git a/core/src/ImageView.h b/core/src/ImageView.h index ec72d18ae2..7d8058d7cd 100644 --- a/core/src/ImageView.h +++ b/core/src/ImageView.h @@ -67,8 +67,12 @@ class ImageView * @param pixStride optional pixel stride in bytes, default is calculated from format */ ImageView(const uint8_t* data, int width, int height, ImageFormat format, int rowStride = 0, int pixStride = 0) - : _data(data), _format(format), _width(width), _height(height), - _pixStride(pixStride ? pixStride : PixStride(format)), _rowStride(rowStride ? rowStride : width * _pixStride) + : _data(data), + _format(format), + _width(width), + _height(height), + _pixStride(pixStride ? pixStride : PixStride(format)), + _rowStride(rowStride ? rowStride : width * _pixStride) {} int width() const { return _width; } @@ -91,7 +95,7 @@ class ImageView ImageView rotated(int degree) const { switch ((degree + 360) % 360) { - case 90: return {data(0, _height - 1), _height, _width, _format, _pixStride, -_rowStride}; + case 90: return {data(0, _height - 1), _height, _width, _format, _pixStride, -_rowStride}; case 180: return {data(_width - 1, _height - 1), _width, _height, _format, -_rowStride, -_pixStride}; case 270: return {data(_width - 1, 0), _height, _width, _format, -_pixStride, _rowStride}; } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 19ef576fac..0aad42a4ec 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -27,8 +27,13 @@ namespace ZXing { Result::Result(std::wstring&& text, Position&& position, BarcodeFormat format, std::string&& symbologyIdentifier, ByteArray&& rawBytes, StructuredAppendInfo&& sai, const bool readerInit, int lineCount) - : _format(format), _text(std::move(text)), _position(std::move(position)), _rawBytes(std::move(rawBytes)), - _symbologyIdentifier(std::move(symbologyIdentifier)), _sai(std::move(sai)), _readerInit(readerInit), + : _format(format), + _text(std::move(text)), + _position(std::move(position)), + _rawBytes(std::move(rawBytes)), + _symbologyIdentifier(std::move(symbologyIdentifier)), + _sai(std::move(sai)), + _readerInit(readerInit), _lineCount(lineCount) { _numBits = Size(_rawBytes) * 8; @@ -41,13 +46,18 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor {} Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format) - : _status(decodeResult.errorCode()), _format(format), _text(std::move(decodeResult).text()), - _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), - _ecLevel(decodeResult.ecLevel()), _symbologyIdentifier(decodeResult.symbologyIdentifier()), - _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), + : _status(decodeResult.errorCode()), + _format(format), + _text(std::move(decodeResult).text()), + _position(std::move(position)), + _rawBytes(std::move(decodeResult).rawBytes()), + _numBits(decodeResult.numBits()), + _ecLevel(decodeResult.ecLevel()), + _symbologyIdentifier(decodeResult.symbologyIdentifier()), + _sai(decodeResult.structuredAppend()), + _isMirrored(decodeResult.isMirrored()), _readerInit(decodeResult.readerInit()) { - // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } diff --git a/core/src/Result.h b/core/src/Result.h index c44c95455c..1d90b835e3 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -52,56 +52,34 @@ class Result Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); - bool isValid() const { - return StatusIsOK(_status); - } + bool isValid() const { return StatusIsOK(_status); } - DecodeStatus status() const { - return _status; - } + DecodeStatus status() const { return _status; } - BarcodeFormat format() const { - return _format; - } + BarcodeFormat format() const { return _format; } - const std::wstring& text() const { - return _text; - } + const std::wstring& text() const { return _text; } - const Position& position() const { - return _position; - } - void setPosition(Position pos) { - _position = pos; - } + const Position& position() const { return _position; } + void setPosition(Position pos) { _position = pos; } int orientation() const; //< orientation of barcode in degree, see also Position::orientation() /** * @brief isMirrored is the symbol mirrored (currently only supported by QRCode and DataMatrix) */ - bool isMirrored() const { - return _isMirrored; - } + bool isMirrored() const { return _isMirrored; } - const ByteArray& rawBytes() const { - return _rawBytes; - } + const ByteArray& rawBytes() const { return _rawBytes; } - int numBits() const { - return _numBits; - } + int numBits() const { return _numBits; } - const std::wstring& ecLevel() const { - return _ecLevel; - } + const std::wstring& ecLevel() const { return _ecLevel; } /** * @brief symbologyIdentifier Symbology identifier "]cm" where "c" is symbology code character, "m" the modifier. */ - const std::string& symbologyIdentifier() const { - return _symbologyIdentifier; - } + const std::string& symbologyIdentifier() const { return _symbologyIdentifier; } /** * @brief sequenceSize number of symbols in a structured append sequence. @@ -132,19 +110,13 @@ class Result /** * @brief readerInit Set if Reader Initialisation/Programming symbol. */ - bool readerInit() const { - return _readerInit; - } + bool readerInit() const { return _readerInit; } /** * @brief How many lines have been detected with this code (applies only to 1D symbologies) */ - int lineCount() const { - return _lineCount; - } - void incrementLineCount() { - ++_lineCount; - } + int lineCount() const { return _lineCount; } + void incrementLineCount() { ++_lineCount; } bool operator==(const Result& o) const; diff --git a/core/src/aztec/AZHighLevelEncoder.cpp b/core/src/aztec/AZHighLevelEncoder.cpp index f27bac3b5f..d307e28229 100644 --- a/core/src/aztec/AZHighLevelEncoder.cpp +++ b/core/src/aztec/AZHighLevelEncoder.cpp @@ -95,18 +95,14 @@ static const std::array, 5>& InitCharMap() charmap[MODE_DIGIT][','] = 12; charmap[MODE_DIGIT]['.'] = 13; const int8_t mixedTable[] = { - 0x00, 0x20, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x0c, 0x0d, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x40, 0x5c, 0x5e, - 0x5f, 0x60, 0x7c, 0x7d, 0x7f, + 0x00, 0x20, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x40, 0x5c, 0x5e, 0x5f, 0x60, 0x7c, 0x7d, 0x7f, }; for (uint8_t i = 0; i < Size(mixedTable); i++) { charmap[MODE_MIXED][mixedTable[i]] = i; } - const char punctTable[] = { - '\0', '\r', '\0', '\0', '\0', '\0', '!', '\'', '#', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', - '[', ']', '{', '}' - }; + const char punctTable[] = {'\0', '\r', '\0', '\0', '\0', '\0', '!', '\'', '#', '$', '%', '&', '\'', '(', ')', '*', + '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '[', ']', '{', '}'}; for (uint8_t i = 0; i < Size(punctTable); i++) { if (punctTable[i] > 0) { charmap[MODE_PUNCT][punctTable[i]] = i; diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 68cc5fff5f..10df1a6691 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -863,9 +863,9 @@ static DetectorResult DetectPure(const BitMatrix& image) auto modSizeY = float(height) / dimR; auto modSize = (modSizeX + modSizeY) / 2; - if (dimT % 2 != 0 || dimR % 2 != 0 || dimT < 10 || dimT > 144 || dimR < 8 || dimR > 144 || - std::abs(modSizeX - modSizeY) > 1 || - !image.isIn(PointF{left + modSizeX / 2 + (dimT - 1) * modSize, top + modSizeY / 2 + (dimR - 1) * modSize})) + if (dimT % 2 != 0 || dimR % 2 != 0 || dimT < 10 || dimT > 144 || dimR < 8 || dimR > 144 + || std::abs(modSizeX - modSizeY) > 1 + || !image.isIn(PointF{left + modSizeX / 2 + (dimT - 1) * modSize, top + modSizeY / 2 + (dimR - 1) * modSize})) return {}; int right = left + width - 1; diff --git a/core/src/datamatrix/DMHighLevelEncoder.cpp b/core/src/datamatrix/DMHighLevelEncoder.cpp index 0b43f6a7eb..627750909e 100644 --- a/core/src/datamatrix/DMHighLevelEncoder.cpp +++ b/core/src/datamatrix/DMHighLevelEncoder.cpp @@ -168,7 +168,8 @@ static int LookAheadTest(const std::string& msg, size_t startpos, int currentMod //step K if ((startpos + charsProcessed) == msg.length()) { int min = std::numeric_limits::max(); - std::transform(charCounts.begin(), charCounts.end(), intCharCounts.begin(), [](float x) { return static_cast(std::ceil(x)); }); + std::transform(charCounts.begin(), charCounts.end(), intCharCounts.begin(), + [](float x) { return static_cast(std::ceil(x)); }); min = FindMinimums(intCharCounts, min, mins); int minCount = Reduce(mins); @@ -260,7 +261,8 @@ static int LookAheadTest(const std::string& msg, size_t startpos, int currentMod //step R if (charsProcessed >= 4) { - std::transform(charCounts.begin(), charCounts.end(), intCharCounts.begin(), [](float x) { return static_cast(std::ceil(x)); }); + std::transform(charCounts.begin(), charCounts.end(), intCharCounts.begin(), + [](float x) { return static_cast(std::ceil(x)); }); FindMinimums(intCharCounts, std::numeric_limits::max(), mins); int minCount = Reduce(mins); @@ -421,7 +423,8 @@ namespace C40Encoder { return len; } - static int BacktrackOneCharacter(EncoderContext& context, std::string& buffer, std::string& removed, int lastCharSize, std::function encodeChar) + static int BacktrackOneCharacter(EncoderContext& context, std::string& buffer, std::string& removed, int lastCharSize, + std::function encodeChar) { buffer.resize(buffer.size() - lastCharSize); context.setCurrentPos(context.currentPos() - 1); diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index d134f778bb..5d6aad0a09 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -30,10 +30,11 @@ namespace ZXing::DataMatrix { Reader::Reader(const DecodeHints& hints) - : _tryRotate(hints.tryRotate()), _tryHarder(hints.tryHarder()), _isPure(hints.isPure()), + : _tryRotate(hints.tryRotate()), + _tryHarder(hints.tryHarder()), + _isPure(hints.isPure()), _characterSet(hints.characterSet()) -{ -} +{} /** * Locates and decodes a Data Matrix code in an image. @@ -47,16 +48,14 @@ Result Reader::decode(const BinaryBitmap& image) const { auto binImg = image.getBitMatrix(); - if (binImg == nullptr) { + if (binImg == nullptr) return Result(DecodeStatus::NotFound); - } auto detectorResult = Detect(*binImg, _tryHarder, _tryRotate, _isPure); if (!detectorResult.isValid()) return Result(DecodeStatus::NotFound); - return Result(Decode(detectorResult.bits(), _characterSet), - std::move(detectorResult).position(), BarcodeFormat::DataMatrix); + return Result(Decode(detectorResult.bits(), _characterSet), std::move(detectorResult).position(), BarcodeFormat::DataMatrix); } } // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMSymbolInfo.h b/core/src/datamatrix/DMSymbolInfo.h index 90756f0d9d..e033fbfb4e 100644 --- a/core/src/datamatrix/DMSymbolInfo.h +++ b/core/src/datamatrix/DMSymbolInfo.h @@ -33,15 +33,21 @@ class SymbolInfo int _rsBlockError; public: - constexpr SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions) : - SymbolInfo(rectangular, dataCapacity, errorCodewords, matrixWidth, matrixHeight, dataRegions, dataCapacity, errorCodewords) {} - - constexpr SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions, int rsBlockData, int rsBlockError) : - _rectangular(rectangular), _dataCapacity(dataCapacity), _errorCodewords(errorCodewords), - _matrixWidth(matrixWidth), _matrixHeight(matrixHeight), _dataRegions(dataRegions), - _rsBlockData(rsBlockData), _rsBlockError(rsBlockError) - { - } + constexpr SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions) + : SymbolInfo(rectangular, dataCapacity, errorCodewords, matrixWidth, matrixHeight, dataRegions, dataCapacity, errorCodewords) + {} + + constexpr SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords, int matrixWidth, int matrixHeight, int dataRegions, + int rsBlockData, int rsBlockError) + : _rectangular(rectangular), + _dataCapacity(dataCapacity), + _errorCodewords(errorCodewords), + _matrixWidth(matrixWidth), + _matrixHeight(matrixHeight), + _dataRegions(dataRegions), + _rsBlockData(rsBlockData), + _rsBlockError(rsBlockError) + {} static const SymbolInfo* Lookup(int dataCodewords); static const SymbolInfo* Lookup(int dataCodewords, SymbolShape shape); @@ -52,57 +58,32 @@ class SymbolInfo int verticalDataRegions() const; - int symbolDataWidth() const { - return horizontalDataRegions() * _matrixWidth; - } + int symbolDataWidth() const { return horizontalDataRegions() * _matrixWidth; } - int symbolDataHeight() const { - return verticalDataRegions() * _matrixHeight; - } + int symbolDataHeight() const { return verticalDataRegions() * _matrixHeight; } - int symbolWidth() const { - return symbolDataWidth() + (horizontalDataRegions() * 2); - } + int symbolWidth() const { return symbolDataWidth() + (horizontalDataRegions() * 2); } - int symbolHeight() const { - return symbolDataHeight() + (verticalDataRegions() * 2); - } + int symbolHeight() const { return symbolDataHeight() + (verticalDataRegions() * 2); } - int matrixWidth() const { - return _matrixWidth; - } + int matrixWidth() const { return _matrixWidth; } - int matrixHeight() const { - return _matrixHeight; - } + int matrixHeight() const { return _matrixHeight; } - int codewordCount() const { - return _dataCapacity + _errorCodewords; - } + int codewordCount() const { return _dataCapacity + _errorCodewords; } - int interleavedBlockCount() const { - if (_rsBlockData > 0) - return _dataCapacity / _rsBlockData; - return 10; // Symbol 144 - } + int interleavedBlockCount() const { return _rsBlockData > 0 ? _dataCapacity / _rsBlockData : 10; /* Symbol 144 */ } - int dataCapacity() const { - return _dataCapacity; - } + int dataCapacity() const { return _dataCapacity; } - int errorCodewords() const { - return _errorCodewords; - } + int errorCodewords() const { return _errorCodewords; } - int dataLengthForInterleavedBlock(int index) const { - if (_rsBlockData > 0) - return _rsBlockData; - return index <= 8 ? 156 : 155; // Symbol 144 + int dataLengthForInterleavedBlock(int index) const + { + return _rsBlockData > 0 ? _rsBlockData : (index <= 8 ? 156 : 155); /* Symbol 144 */ } - int errorLengthForInterleavedBlock() const { - return _rsBlockError; - } + int errorLengthForInterleavedBlock() const { return _rsBlockError; } }; } // DataMatrix diff --git a/core/src/oned/ODCode128Writer.cpp b/core/src/oned/ODCode128Writer.cpp index 24a097e3bf..32133eac3b 100644 --- a/core/src/oned/ODCode128Writer.cpp +++ b/core/src/oned/ODCode128Writer.cpp @@ -30,10 +30,10 @@ namespace ZXing::OneD { static const int CODE_START_A = 103; static const int CODE_START_B = 104; static const int CODE_START_C = 105; -static const int CODE_CODE_A = 101; -static const int CODE_CODE_B = 100; -static const int CODE_CODE_C = 99; -static const int CODE_STOP = 106; +static const int CODE_CODE_A = 101; +static const int CODE_CODE_B = 100; +static const int CODE_CODE_C = 99; +static const int CODE_STOP = 106; // Dummy characters used to specify control characters in input static const auto ESCAPE_FNC_1 = L'\u00f1'; @@ -41,14 +41,15 @@ static const auto ESCAPE_FNC_2 = L'\u00f2'; static const auto ESCAPE_FNC_3 = L'\u00f3'; static const auto ESCAPE_FNC_4 = L'\u00f4'; -static const int CODE_FNC_1 = 102; // Code A, Code B, Code C -static const int CODE_FNC_2 = 97; // Code A, Code B -static const int CODE_FNC_3 = 96; // Code A, Code B +static const int CODE_FNC_1 = 102; // Code A, Code B, Code C +static const int CODE_FNC_2 = 97; // Code A, Code B +static const int CODE_FNC_3 = 96; // Code A, Code B static const int CODE_FNC_4_A = 101; // Code A static const int CODE_FNC_4_B = 100; // Code B - // Results of minimal lookahead for code C -enum class CType { +// Results of minimal lookahead for code C +enum class CType +{ UNCODABLE, ONE_DIGIT, TWO_DIGITS, diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index e567a07a84..21783f001d 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -38,15 +38,13 @@ MultiUPCEANReader::~MultiUPCEANReader() = default; constexpr int CHAR_LEN = 4; -constexpr auto END_PATTERN = FixedPattern<3, 3>{1, 1, 1}; -constexpr auto MID_PATTERN = FixedPattern<5, 5>{1, 1, 1, 1, 1}; -constexpr auto UPCE_END_PATTERN = FixedPattern<6, 6>{1, 1, 1, 1, 1, 1}; -constexpr auto EXT_START_PATTERN = FixedPattern<3, 4>{1, 1, 2}; +constexpr auto END_PATTERN = FixedPattern<3, 3>{1, 1, 1}; +constexpr auto MID_PATTERN = FixedPattern<5, 5>{1, 1, 1, 1, 1}; +constexpr auto UPCE_END_PATTERN = FixedPattern<6, 6>{1, 1, 1, 1, 1, 1}; +constexpr auto EXT_START_PATTERN = FixedPattern<3, 4>{1, 1, 2}; constexpr auto EXT_SEPARATOR_PATTERN = FixedPattern<2, 2>{1, 1}; -static const int FIRST_DIGIT_ENCODINGS[] = { - 0x00, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A -}; +static const int FIRST_DIGIT_ENCODINGS[] = {0x00, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}; // The GS1 specification has the following to say about quiet zones // Type: EAN-13 | EAN-8 | UPC-A | UPC-E | EAN Add-on | UPC Add-on @@ -69,10 +67,9 @@ static bool DecodeDigit(const PatternView& view, std::string& txt, int* lgPatter static constexpr float MAX_AVG_VARIANCE = 0.48f; static constexpr float MAX_INDIVIDUAL_VARIANCE = 0.7f; - int bestMatch = lgPattern ? RowReader::DecodeDigit(view, UPCEANCommon::L_AND_G_PATTERNS, MAX_AVG_VARIANCE, - MAX_INDIVIDUAL_VARIANCE, false) - : RowReader::DecodeDigit(view, UPCEANCommon::L_PATTERNS, MAX_AVG_VARIANCE, - MAX_INDIVIDUAL_VARIANCE, false); + int bestMatch = + lgPattern ? RowReader::DecodeDigit(view, UPCEANCommon::L_AND_G_PATTERNS, MAX_AVG_VARIANCE, MAX_INDIVIDUAL_VARIANCE, false) + : RowReader::DecodeDigit(view, UPCEANCommon::L_PATTERNS, MAX_AVG_VARIANCE, MAX_INDIVIDUAL_VARIANCE, false); txt += '0' + (bestMatch % 10); if (lgPattern) AppendBit(*lgPattern, bestMatch >= 10); @@ -312,9 +309,8 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u auto ext = res.end; PartialResult addOnRes; - if (_hints.eanAddOnSymbol() != EanAddOnSymbol::Ignore && ext.skipSymbol() && - ext.skipSingle(static_cast(begin.sum() * 3.5)) && (AddOn(addOnRes, ext, 5) || AddOn(addOnRes, ext, 2))) { - + if (_hints.eanAddOnSymbol() != EanAddOnSymbol::Ignore && ext.skipSymbol() && ext.skipSingle(static_cast(begin.sum() * 3.5)) + && (AddOn(addOnRes, ext, 5) || AddOn(addOnRes, ext, 2))) { // ISO/IEC 15420:2009 states that the content for "]E3" should be 15 or 18 digits, i.e. converted to EAN-13 // and extended with no separator, and that the content for "]E4" should be 8 digits, i.e. no add-on //TODO: extend position in include extension @@ -329,8 +325,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u if (_hints.eanAddOnSymbol() == EanAddOnSymbol::Require && !addOnRes.isValid()) return Result(DecodeStatus::NotFound); - return { - res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, std::move(symbologyIdentifier)}; + return {res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, std::move(symbologyIdentifier)}; } } // namespace ZXing::OneD diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp index f2785d6be0..315a41b903 100644 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp +++ b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp @@ -37,8 +37,7 @@ namespace ZXing::OneD::DataBar { static const int AI01_GTIN_SIZE = 40; -static void -AI01AppendCheckDigit(std::string& buffer, int currentPos) +static void AI01AppendCheckDigit(std::string& buffer, int currentPos) { int checkDigit = 0; for (int i = 0; i < 13; i++) { @@ -53,8 +52,7 @@ AI01AppendCheckDigit(std::string& buffer, int currentPos) buffer.append(std::to_string(checkDigit)); } -static void -AI01EncodeCompressedGtinWithoutAI(std::string& buffer, const BitArray& bits, int currentPos, int initialBufferPosition) +static void AI01EncodeCompressedGtinWithoutAI(std::string& buffer, const BitArray& bits, int currentPos, int initialBufferPosition) { for (int i = 0; i < 4; ++i) { int currentBlock = ToInt(bits, currentPos + 10 * i, 10); @@ -69,8 +67,7 @@ AI01EncodeCompressedGtinWithoutAI(std::string& buffer, const BitArray& bits, int AI01AppendCheckDigit(buffer, initialBufferPosition); } -static void -AI01EncodeCompressedGtin(std::string& buffer, const BitArray& bits, int currentPos) +static void AI01EncodeCompressedGtin(std::string& buffer, const BitArray& bits, int currentPos) { buffer.append("(01)"); int initialPosition = Size(buffer); @@ -82,7 +79,7 @@ using AddWeightCodeFunc = const std::function; using CheckWeightFunc = const std::function; static void AI01EncodeCompressedWeight(std::string& buffer, const BitArray& bits, int currentPos, int weightSize, - const AddWeightCodeFunc& addWeightCode, const CheckWeightFunc& checkWeight) + const AddWeightCodeFunc& addWeightCode, const CheckWeightFunc& checkWeight) { int originalWeightNumeric = ToInt(bits, currentPos, weightSize); addWeightCode(buffer, originalWeightNumeric); @@ -103,8 +100,7 @@ static void AI01EncodeCompressedWeight(std::string& buffer, const BitArray& bits * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) */ -static std::string -DecodeAI01AndOtherAIs(const BitArray& bits) +static std::string DecodeAI01AndOtherAIs(const BitArray& bits) { static const int HEADER_SIZE = 1 + 1 + 2; // first bit encodes the linkage flag, the second one is the encodation // method, and the other two are for the variable length @@ -125,8 +121,7 @@ DecodeAI01AndOtherAIs(const BitArray& bits) return {}; } -static std::string -DecodeAnyAI(const BitArray& bits) +static std::string DecodeAnyAI(const BitArray& bits) { static const int HEADER_SIZE = 2 + 1 + 2; std::string buffer; @@ -136,8 +131,7 @@ DecodeAnyAI(const BitArray& bits) return std::string(); } -static std::string -DecodeAI013103(const BitArray& bits) +static std::string DecodeAI013103(const BitArray& bits) { static const int HEADER_SIZE = 4 + 1; static const int WEIGHT_SIZE = 15; @@ -157,8 +151,7 @@ DecodeAI013103(const BitArray& bits) return buffer; } -static std::string -DecodeAI01320x(const BitArray& bits) +static std::string DecodeAI01320x(const BitArray& bits) { static const int HEADER_SIZE = 4 + 1; static const int WEIGHT_SIZE = 15; @@ -169,7 +162,8 @@ DecodeAI01320x(const BitArray& bits) std::string buffer; AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); - AI01EncodeCompressedWeight(buffer, bits, HEADER_SIZE + AI01_GTIN_SIZE, WEIGHT_SIZE, + AI01EncodeCompressedWeight( + buffer, bits, HEADER_SIZE + AI01_GTIN_SIZE, WEIGHT_SIZE, // addWeightCode [](std::string& buf, int weight) { buf.append(weight < 10000 ? "(3202)" : "(3203)"); }, // checkWeight @@ -178,8 +172,7 @@ DecodeAI01320x(const BitArray& bits) return buffer; } -static std::string -DecodeAI01392x(const BitArray& bits) +static std::string DecodeAI01392x(const BitArray& bits) { static const int HEADER_SIZE = 5 + 1 + 2; static const int LAST_DIGIT_SIZE = 2; @@ -205,8 +198,7 @@ DecodeAI01392x(const BitArray& bits) return std::string(); } -static std::string -DecodeAI01393x(const BitArray& bits) +static std::string DecodeAI01393x(const BitArray& bits) { static const int HEADER_SIZE = 5 + 1 + 2; static const int LAST_DIGIT_SIZE = 2; @@ -243,8 +235,7 @@ DecodeAI01393x(const BitArray& bits) return std::string(); } -static std::string -DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdigits, const char* dateCode) +static std::string DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdigits, const char* dateCode) { static const int HEADER_SIZE = 7 + 1; static const int WEIGHT_SIZE = 20; @@ -299,8 +290,7 @@ DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdigits, const char* da return buffer; } -std::string -DecodeExpandedBits(const BitArray& bits) +std::string DecodeExpandedBits(const BitArray& bits) { if (bits.get(1)) { return DecodeAI01AndOtherAIs(bits); diff --git a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp b/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp index 6f4881aa68..7e88ec0b9b 100644 --- a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp +++ b/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp @@ -107,11 +107,7 @@ struct DecodedNumeric : public DecodedValue struct ParsingState { - enum State { - NUMERIC, - ALPHA, - ISO_IEC_646 - }; + enum State { NUMERIC, ALPHA, ISO_IEC_646 }; int position = 0; State encoding = NUMERIC; diff --git a/core/src/pdf417/PDFCodewordDecoder.cpp b/core/src/pdf417/PDFCodewordDecoder.cpp index cddb572723..f3f17bba53 100644 --- a/core/src/pdf417/PDFCodewordDecoder.cpp +++ b/core/src/pdf417/PDFCodewordDecoder.cpp @@ -423,7 +423,7 @@ using ModuleBitCountType = std::array; static const RatioTableType& GetRatioTable() { - static constexpr RatioTableType table{[]() constexpr { + static constexpr RatioTableType table = []() constexpr { RatioTableType table{}; for (int i = 0; i < SYMBOL_COUNT; i++) { int currentSymbol = SYMBOL_TABLE[i]; @@ -439,7 +439,7 @@ static const RatioTableType& GetRatioTable() } } return table; - }()}; + }(); return table; } diff --git a/core/src/qrcode/QRDataBlock.h b/core/src/qrcode/QRDataBlock.h index 73df72b5b5..e63c326dac 100644 --- a/core/src/qrcode/QRDataBlock.h +++ b/core/src/qrcode/QRDataBlock.h @@ -36,17 +36,11 @@ enum class ErrorCorrectionLevel; class DataBlock { public: - int numDataCodewords() const { - return _numDataCodewords; - } + int numDataCodewords() const { return _numDataCodewords; } - const ByteArray& codewords() const { - return _codewords; - } + const ByteArray& codewords() const { return _codewords; } - ByteArray& codewords() { - return _codewords; - } + ByteArray& codewords() { return _codewords; } /** *

When QR Codes use multiple data blocks, they are actually interleaved. diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index cc0899d7c7..8092147adc 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -49,8 +49,7 @@ namespace ZXing::QRCode { * @param numDataCodewords number of codewords that are data bytes * @throws ChecksumException if error correction fails */ -static bool -CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) +static bool CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) { // First read into an array of ints std::vector codewordsInts(codewordBytes.begin(), codewordBytes.end()); @@ -69,8 +68,7 @@ CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) /** * See specification GBT 18284-2000 */ -static DecodeStatus -DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) +static DecodeStatus DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) { // Don't crash trying to read more bits than we have available. if (count * 13 > bits.available()) { @@ -102,8 +100,7 @@ DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) return DecodeStatus::NoError; } -static DecodeStatus -DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) +static DecodeStatus DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) { // Don't crash trying to read more bits than we have available. if (count * 13 > bits.available()) { @@ -135,8 +132,8 @@ DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) return DecodeStatus::NoError; } -static DecodeStatus -DecodeByteSegment(BitSource& bits, int count, CharacterSet currentCharset, const std::string& hintedCharset, std::wstring& result) +static DecodeStatus DecodeByteSegment(BitSource& bits, int count, CharacterSet currentCharset, const std::string& hintedCharset, + std::wstring& result) { // Don't crash trying to read more bits than we have available. if (8 * count > bits.available()) { @@ -166,8 +163,7 @@ DecodeByteSegment(BitSource& bits, int count, CharacterSet currentCharset, const return DecodeStatus::NoError; } -static char -ToAlphaNumericChar(int value) +static char ToAlphaNumericChar(int value) { /** * See ISO 18004:2006, 6.4.4 Table 5 @@ -185,8 +181,7 @@ ToAlphaNumericChar(int value) return ALPHANUMERIC_CHARS[value]; } -static DecodeStatus -DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, std::wstring& result) +static DecodeStatus DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, std::wstring& result) { // Read two characters at a time std::string buffer; @@ -226,8 +221,7 @@ DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, std::wst return DecodeStatus::NoError; } -static DecodeStatus -DecodeNumericSegment(BitSource& bits, int count, std::wstring& result) +static DecodeStatus DecodeNumericSegment(BitSource& bits, int count, std::wstring& result) { // Read three digits at a time std::string buffer; @@ -273,8 +267,7 @@ DecodeNumericSegment(BitSource& bits, int count, std::wstring& result) return DecodeStatus::NoError; } -static DecodeStatus -ParseECIValue(BitSource& bits, int &outValue) +static DecodeStatus ParseECIValue(BitSource& bits, int& outValue) { int firstByte = bits.readBits(8); if ((firstByte & 0x80) == 0) { @@ -303,8 +296,9 @@ ParseECIValue(BitSource& bits, int &outValue) * *

See ISO 18004:2006, 6.4.3 - 6.4.7

*/ -ZXING_EXPORT_TEST_ONLY DecoderResult -DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel, const std::string& hintedCharset) +ZXING_EXPORT_TEST_ONLY +DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel, + const std::string& hintedCharset) { BitSource bits(bytes); std::wstring result; @@ -350,7 +344,7 @@ DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel // Read next 4 bits of index, 4 bits of symbol count, and 8 bits of parity data, then continue structuredAppend.index = bits.readBits(4); structuredAppend.count = bits.readBits(4) + 1; - structuredAppend.id = std::to_string(bits.readBits(8)); + structuredAppend.id = std::to_string(bits.readBits(8)); break; case CodecMode::ECI: { // Count doesn't apply to ECI @@ -384,20 +378,11 @@ DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel int count = bits.readBits(CharacterCountBits(mode, version)); DecodeStatus status; switch (mode) { - case CodecMode::NUMERIC: - status = DecodeNumericSegment(bits, count, result); - break; - case CodecMode::ALPHANUMERIC: - status = DecodeAlphanumericSegment(bits, count, fc1InEffect, result); - break; - case CodecMode::BYTE: - status = DecodeByteSegment(bits, count, currentCharset, hintedCharset, result); - break; - case CodecMode::KANJI: - status = DecodeKanjiSegment(bits, count, result); - break; - default: - status = DecodeStatus::FormatError; + case CodecMode::NUMERIC: status = DecodeNumericSegment(bits, count, result); break; + case CodecMode::ALPHANUMERIC: status = DecodeAlphanumericSegment(bits, count, fc1InEffect, result); break; + case CodecMode::BYTE: status = DecodeByteSegment(bits, count, currentCharset, hintedCharset, result); break; + case CodecMode::KANJI: status = DecodeKanjiSegment(bits, count, result); break; + default: status = DecodeStatus::FormatError; } if (StatusIsError(status)) { return status; @@ -436,8 +421,7 @@ DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel .setStructuredAppend(structuredAppend); } -static DecoderResult -DoDecode(const BitMatrix& bits, const Version& version, const std::string& hintedCharset, bool mirrored) +static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, const std::string& hintedCharset, bool mirrored) { auto formatInfo = ReadFormatInformation(bits, mirrored); if (!formatInfo.isValid()) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index e2834481bb..48afd325ae 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -134,8 +134,7 @@ static FinderPatternSets GenerateFinderPatternSets(std::vectorsize + b->size + c->size) / (3 * 7.f)) + 7; + if (auto moduleCount = (std::sqrt(distAB) + std::sqrt(distBC)) / (2 * (a->size + b->size + c->size) / (3 * 7.f)) + 7; moduleCount < 21 * 0.9 || moduleCount > 177 * 1.05) continue; @@ -303,8 +302,7 @@ DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatt // if we did not land on a black pixel or the concentric pattern finder fails, // leave the intersection of the lines as the best guess if (image.get(brCoR)) { - if (auto brCP = - LocateConcentricPattern(image, FixedPattern<3, 3>{1, 1, 1}, brCoR, moduleSize * 3)) + if (auto brCP = LocateConcentricPattern(image, FixedPattern<3, 3>{1, 1, 1}, brCoR, moduleSize * 3)) return sample(*brCP, quad[2] - PointF(3, 3)); } } diff --git a/core/src/qrcode/QRECB.h b/core/src/qrcode/QRECB.h index 5bb8017819..689d44f6f2 100644 --- a/core/src/qrcode/QRECB.h +++ b/core/src/qrcode/QRECB.h @@ -47,22 +47,17 @@ struct ECBlocks int codewordsPerBlock; std::array blocks; - int numBlocks() const { - return blocks[0].count + blocks[1].count; - } + int numBlocks() const { return blocks[0].count + blocks[1].count; } - int totalCodewords() const { - return codewordsPerBlock * numBlocks(); - } + int totalCodewords() const { return codewordsPerBlock * numBlocks(); } - int totalDataCodewords() const { + int totalDataCodewords() const + { return blocks[0].count * (blocks[0].dataCodewords + codewordsPerBlock) - + blocks[1].count * (blocks[1].dataCodewords + codewordsPerBlock); + + blocks[1].count * (blocks[1].dataCodewords + codewordsPerBlock); } - const std::array& blockArray() const { - return blocks; - } + const std::array& blockArray() const { return blocks; } }; diff --git a/core/src/qrcode/QREncoder.cpp b/core/src/qrcode/QREncoder.cpp index 297da96a31..20285e9379 100644 --- a/core/src/qrcode/QREncoder.cpp +++ b/core/src/qrcode/QREncoder.cpp @@ -38,7 +38,7 @@ namespace ZXing::QRCode { static const CharacterSet DEFAULT_BYTE_MODE_ENCODING = CharacterSet::ISO8859_1; // The original table is defined in the table 5 of JISX0510:2004 (p.19). -static const std::array ALPHANUMERIC_TABLE = { +static const std::array ALPHANUMERIC_TABLE = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00-0x0f -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x10-0x1f 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, // 0x20-0x2f @@ -294,7 +294,8 @@ void TerminateBits(int numDataBytes, BitArray& bits) { int capacity = numDataBytes * 8; if (bits.size() > capacity) { - throw std::invalid_argument("data bits cannot fit in the QR Code" + std::to_string(bits.size()) + " > " + std::to_string(capacity)); + throw std::invalid_argument("data bits cannot fit in the QR Code" + std::to_string(bits.size()) + " > " + + std::to_string(capacity)); } for (int i = 0; i < 4 && bits.size() < capacity; ++i) { bits.appendBit(false); @@ -330,7 +331,8 @@ struct BlockPair * JISX0510:2004 (p.30) */ ZXING_EXPORT_TEST_ONLY -void GetNumDataBytesAndNumECBytesForBlockID(int numTotalBytes, int numDataBytes, int numRSBlocks, int blockID, int& numDataBytesInBlock, int& numECBytesInBlock) +void GetNumDataBytesAndNumECBytesForBlockID(int numTotalBytes, int numDataBytes, int numRSBlocks, int blockID, + int& numDataBytesInBlock, int& numECBytesInBlock) { if (blockID >= numRSBlocks) { throw std::invalid_argument("Block ID too large"); @@ -361,11 +363,9 @@ void GetNumDataBytesAndNumECBytesForBlockID(int numTotalBytes, int numDataBytes, throw std::invalid_argument("RS blocks mismatch"); } // 196 = (13 + 26) * 4 + (14 + 26) * 1 - if (numTotalBytes != - ((numDataBytesInGroup1 + numEcBytesInGroup1) * - numRsBlocksInGroup1) + - ((numDataBytesInGroup2 + numEcBytesInGroup2) * - numRsBlocksInGroup2)) { + if (numTotalBytes + != ((numDataBytesInGroup1 + numEcBytesInGroup1) * numRsBlocksInGroup1) + + ((numDataBytesInGroup2 + numEcBytesInGroup2) * numRsBlocksInGroup2)) { throw std::invalid_argument("Total bytes mismatch"); } @@ -387,8 +387,7 @@ void GenerateECBytes(const ByteArray& dataBytes, int numEcBytes, ByteArray& ecBy ReedSolomonEncode(GenericGF::QRCodeField256(), message, numEcBytes); ecBytes.resize(numEcBytes); - std::transform(message.end() - numEcBytes, message.end(), ecBytes.begin(), - [](auto c) { return static_cast(c); }); + std::transform(message.end() - numEcBytes, message.end(), ecBytes.begin(), [](auto c) { return static_cast(c); }); } @@ -447,7 +446,8 @@ BitArray InterleaveWithECBytes(const BitArray& bits, int numTotalBytes, int numD } } if (numTotalBytes != output.sizeInBytes()) { // Should be same. - throw std::invalid_argument("Interleaving error: " + std::to_string(numTotalBytes) + " and " + std::to_string(output.sizeInBytes()) + " differ."); + throw std::invalid_argument("Interleaving error: " + std::to_string(numTotalBytes) + " and " + std::to_string(output.sizeInBytes()) + + " differ."); } return output; } diff --git a/core/src/qrcode/QRErrorCorrectionLevel.cpp b/core/src/qrcode/QRErrorCorrectionLevel.cpp index 7ff749a515..3c9f9c9f86 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.cpp +++ b/core/src/qrcode/QRErrorCorrectionLevel.cpp @@ -24,7 +24,7 @@ namespace ZXing::QRCode { const wchar_t* ToString(ErrorCorrectionLevel l) { assert(l != ErrorCorrectionLevel::Invalid); - static const wchar_t* const LEVEL_STR[] = { L"L", L"M", L"Q", L"H", nullptr }; + static const wchar_t* const LEVEL_STR[] = {L"L", L"M", L"Q", L"H", nullptr}; return LEVEL_STR[static_cast(l)]; } @@ -35,20 +35,21 @@ ErrorCorrectionLevel ECLevelFromString(const char* str) case 'M': return ErrorCorrectionLevel::Medium; case 'Q': return ErrorCorrectionLevel::Quality; case 'H': return ErrorCorrectionLevel::High; - default: return ErrorCorrectionLevel::Invalid; + default: return ErrorCorrectionLevel::Invalid; } } ErrorCorrectionLevel ECLevelFromBits(int bits) { - static const ErrorCorrectionLevel LEVEL_FOR_BITS[] = { ErrorCorrectionLevel::Medium, ErrorCorrectionLevel::Low, ErrorCorrectionLevel::High, ErrorCorrectionLevel::Quality }; + static const ErrorCorrectionLevel LEVEL_FOR_BITS[] = {ErrorCorrectionLevel::Medium, ErrorCorrectionLevel::Low, + ErrorCorrectionLevel::High, ErrorCorrectionLevel::Quality}; return LEVEL_FOR_BITS[bits & 0x3]; } int BitsFromECLevel(ErrorCorrectionLevel l) { assert(l != ErrorCorrectionLevel::Invalid); - static const int BITS[] = { 1, 0, 3, 2, -1 }; + static const int BITS[] = {1, 0, 3, 2, -1}; return BITS[(int)l]; } diff --git a/core/src/qrcode/QRErrorCorrectionLevel.h b/core/src/qrcode/QRErrorCorrectionLevel.h index 1241b1451b..2000543da0 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.h +++ b/core/src/qrcode/QRErrorCorrectionLevel.h @@ -27,11 +27,11 @@ namespace QRCode { */ enum class ErrorCorrectionLevel { - Low, // L = ~7 % correction - Medium, // M = ~15% correction - Quality, // Q = ~25% correction - High, // H = ~30% correction - Invalid, // denotes in invalid/unknown value + Low, // L = ~7 % correction + Medium, // M = ~15% correction + Quality, // Q = ~25% correction + High, // H = ~30% correction + Invalid, // denotes in invalid/unknown value }; const wchar_t* ToString(ErrorCorrectionLevel l); diff --git a/core/src/qrcode/QRFormatInformation.h b/core/src/qrcode/QRFormatInformation.h index fbfe967da6..29a3f72e18 100644 --- a/core/src/qrcode/QRFormatInformation.h +++ b/core/src/qrcode/QRFormatInformation.h @@ -38,17 +38,14 @@ class FormatInformation static FormatInformation DecodeFormatInformation(uint32_t formatInfoBits1, uint32_t formatInfoBits2); - ErrorCorrectionLevel errorCorrectionLevel() const { - return _errorCorrectionLevel; - } + ErrorCorrectionLevel errorCorrectionLevel() const { return _errorCorrectionLevel; } - uint8_t dataMask() const { - return _dataMask; - } + uint8_t dataMask() const { return _dataMask; } bool isValid() const { return _errorCorrectionLevel != ErrorCorrectionLevel::Invalid; } - bool operator==(const FormatInformation& other) const { + bool operator==(const FormatInformation& other) const + { return _dataMask == other._dataMask && _errorCorrectionLevel == other._errorCorrectionLevel; } diff --git a/core/src/qrcode/QRMaskUtil.cpp b/core/src/qrcode/QRMaskUtil.cpp index 2f327e4f2a..e94236377a 100644 --- a/core/src/qrcode/QRMaskUtil.cpp +++ b/core/src/qrcode/QRMaskUtil.cpp @@ -35,7 +35,8 @@ static const int N4 = 10; * Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both * vertical and horizontal orders respectively. */ -static int ApplyMaskPenaltyRule1Internal(const TritMatrix& matrix, bool isHorizontal) { +static int ApplyMaskPenaltyRule1Internal(const TritMatrix& matrix, bool isHorizontal) +{ int penalty = 0; int width = matrix.width(); int height = matrix.height(); @@ -64,7 +65,6 @@ static int ApplyMaskPenaltyRule1Internal(const TritMatrix& matrix, bool isHorizo return penalty; } - /** * Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and * give penalty to them. Example: 00000 or 11111. @@ -93,8 +93,9 @@ static int ApplyMaskPenaltyRule2(const TritMatrix& matrix) return N2 * penalty; } -template -static bool HasPatternAt(const std::array& pattern, const Trit* begin, int count, int stride) { +template +static bool HasPatternAt(const std::array& pattern, const Trit* begin, int count, int stride) +{ assert(std::abs(count) <= (int)N); auto end = begin + count * stride; if (count < 0) @@ -124,14 +125,14 @@ static int ApplyMaskPenaltyRule3(const TritMatrix& matrix) for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { auto i = &matrix.get(x, y); - if (x <= width - finderSize && HasPatternAt(finder, i, finderSize, 1) && - (HasPatternAt(white, i, -std::min(x, whiteSize), 1) || - HasPatternAt(white, i + finderSize, std::min(width - x - finderSize, whiteSize), 1))) { + if (x <= width - finderSize && HasPatternAt(finder, i, finderSize, 1) + && (HasPatternAt(white, i, -std::min(x, whiteSize), 1) + || HasPatternAt(white, i + finderSize, std::min(width - x - finderSize, whiteSize), 1))) { numPenalties++; } - if (y <= height - finderSize && HasPatternAt(finder, i, finderSize, width) && - (HasPatternAt(white, i, -std::min(y, whiteSize), width) || - HasPatternAt(white, i + finderSize * width, std::min(height - y - finderSize, whiteSize), width))) { + if (y <= height - finderSize && HasPatternAt(finder, i, finderSize, width) + && (HasPatternAt(white, i, -std::min(y, whiteSize), width) + || HasPatternAt(white, i + finderSize * width, std::min(height - y - finderSize, whiteSize), width))) { numPenalties++; } } @@ -145,7 +146,7 @@ static int ApplyMaskPenaltyRule3(const TritMatrix& matrix) */ static int ApplyMaskPenaltyRule4(const TritMatrix& matrix) { - auto numDarkCells = std::count_if(matrix.begin(), matrix.end(), [](Trit cell){ return cell; }); + auto numDarkCells = std::count_if(matrix.begin(), matrix.end(), [](Trit cell) { return cell; }); auto numTotalCells = matrix.size(); auto fivePercentVariances = std::abs(numDarkCells * 2 - numTotalCells) * 10 / numTotalCells; return static_cast(fivePercentVariances * N4); diff --git a/core/src/qrcode/QRMaskUtil.h b/core/src/qrcode/QRMaskUtil.h index 9e2d4d355d..67d4da08f0 100644 --- a/core/src/qrcode/QRMaskUtil.h +++ b/core/src/qrcode/QRMaskUtil.h @@ -21,7 +21,9 @@ namespace ZXing { namespace QRCode { namespace MaskUtil { - int CalculateMaskPenalty(const TritMatrix& matrix); -} -} // QRCode -} // ZXing + +int CalculateMaskPenalty(const TritMatrix& matrix); + +} // namespace MaskUtil +} // namespace QRCode +} // namespace ZXing diff --git a/core/src/qrcode/QRMatrixUtil.cpp b/core/src/qrcode/QRMatrixUtil.cpp index f937a08f5b..825cd40ba2 100644 --- a/core/src/qrcode/QRMatrixUtil.cpp +++ b/core/src/qrcode/QRMatrixUtil.cpp @@ -151,7 +151,8 @@ static int FindMSBSet(unsigned value) // // Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit // operations. We don't care if cofficients are positive or negative. -static int CalculateBCHCode(int value, int poly) { +static int CalculateBCHCode(int value, int poly) +{ // If poly is "1 1111 0010 0101" (version info poly), msbSetInPoly is 13. We'll subtract 1 // from 13 to make it 12. int msbSetInPoly = FindMSBSet(poly); @@ -306,8 +307,7 @@ static void EmbedDataBits(const BitArray& dataBits, int maskPattern, TritMatrix& // Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On // success, store the result in "matrix" and return true. -void BuildMatrix(const BitArray& dataBits, ErrorCorrectionLevel ecLevel, const Version& version, int maskPattern, - TritMatrix& matrix) +void BuildMatrix(const BitArray& dataBits, ErrorCorrectionLevel ecLevel, const Version& version, int maskPattern, TritMatrix& matrix) { matrix.clear(); // Let's get started with embedding big squares at corners. diff --git a/core/src/qrcode/QRMatrixUtil.h b/core/src/qrcode/QRMatrixUtil.h index 837bf99c28..4ca09a33d6 100644 --- a/core/src/qrcode/QRMatrixUtil.h +++ b/core/src/qrcode/QRMatrixUtil.h @@ -29,8 +29,7 @@ class Version; constexpr int NUM_MASK_PATTERNS = 8; -void BuildMatrix(const BitArray& dataBits, ErrorCorrectionLevel ecLevel, const Version& version, int maskPattern, - TritMatrix& matrix); +void BuildMatrix(const BitArray& dataBits, ErrorCorrectionLevel ecLevel, const Version& version, int maskPattern, TritMatrix& matrix); } // QRCode } // ZXing diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index effd0e44e1..eb7c5c9b93 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -30,13 +30,9 @@ namespace ZXing::QRCode { -Reader::Reader(const DecodeHints& hints) - : _tryHarder(hints.tryHarder()), _isPure(hints.isPure()), _charset(hints.characterSet()) -{ -} +Reader::Reader(const DecodeHints& hints) : _tryHarder(hints.tryHarder()), _isPure(hints.isPure()), _charset(hints.characterSet()) {} -Result -Reader::decode(const BinaryBitmap& image) const +Result Reader::decode(const BinaryBitmap& image) const { #if 1 if (!_isPure) { diff --git a/core/src/qrcode/QRVersion.cpp b/core/src/qrcode/QRVersion.cpp index 248afbc671..96a9f91fe2 100644 --- a/core/src/qrcode/QRVersion.cpp +++ b/core/src/qrcode/QRVersion.cpp @@ -290,16 +290,13 @@ Version::AllVersions() return allVersions; } -Version::Version(int versionNumber, std::initializer_list alignmentPatternCenters, const std::array &ecBlocks) : - _versionNumber(versionNumber), - _alignmentPatternCenters(alignmentPatternCenters), - _ecBlocks(ecBlocks) +Version::Version(int versionNumber, std::initializer_list alignmentPatternCenters, const std::array& ecBlocks) + : _versionNumber(versionNumber), _alignmentPatternCenters(alignmentPatternCenters), _ecBlocks(ecBlocks) { _totalCodewords = ecBlocks[0].totalDataCodewords(); } -const Version * -Version::VersionForNumber(int versionNumber) +const Version* Version::VersionForNumber(int versionNumber) { if (versionNumber < 1 || versionNumber > 40) { //throw std::invalid_argument("Version should be in range [1-40]."); @@ -308,8 +305,7 @@ Version::VersionForNumber(int versionNumber) return &AllVersions()[versionNumber - 1]; } -const Version * -Version::ProvisionalVersionForDimension(int dimension) +const Version* Version::ProvisionalVersionForDimension(int dimension) { if (dimension % 4 != 1) { //throw std::invalid_argument("Unexpected dimension"); @@ -318,9 +314,7 @@ Version::ProvisionalVersionForDimension(int dimension) return VersionForNumber((dimension - 17) / 4); } - -const Version * -Version::DecodeVersionInformation(int versionBits) +const Version* Version::DecodeVersionInformation(int versionBits) { int bestDifference = std::numeric_limits::max(); int bestVersion = 0; diff --git a/core/src/qrcode/QRVersion.h b/core/src/qrcode/QRVersion.h index 1c415fd71b..2de4988e86 100644 --- a/core/src/qrcode/QRVersion.h +++ b/core/src/qrcode/QRVersion.h @@ -37,25 +37,15 @@ namespace QRCode { class Version { public: - int versionNumber() const { - return _versionNumber; - } + int versionNumber() const { return _versionNumber; } - const std::vector& alignmentPatternCenters() const { - return _alignmentPatternCenters; - } - - int totalCodewords() const { - return _totalCodewords; - } - - int dimensionForVersion() const { - return 17 + 4 * _versionNumber; - } - - const ECBlocks & ecBlocksForLevel(ErrorCorrectionLevel ecLevel) const { - return _ecBlocks[(int)ecLevel]; - } + const std::vector& alignmentPatternCenters() const { return _alignmentPatternCenters; } + + int totalCodewords() const { return _totalCodewords; } + + int dimensionForVersion() const { return 17 + 4 * _versionNumber; } + + const ECBlocks& ecBlocksForLevel(ErrorCorrectionLevel ecLevel) const { return _ecBlocks[(int)ecLevel]; } BitMatrix buildFunctionPattern() const; diff --git a/core/src/qrcode/QRWriter.cpp b/core/src/qrcode/QRWriter.cpp index daf97e3b50..52d6f065da 100644 --- a/core/src/qrcode/QRWriter.cpp +++ b/core/src/qrcode/QRWriter.cpp @@ -30,18 +30,16 @@ namespace ZXing::QRCode { static const int QUIET_ZONE_SIZE = 4; -Writer::Writer() : - _margin(QUIET_ZONE_SIZE), - _ecLevel(ErrorCorrectionLevel::Low), - _encoding(CharacterSet::Unknown), - _version(0), - _useGs1Format(false), - _maskPattern(-1) -{ -} - -BitMatrix -Writer::encode(const std::wstring& contents, int width, int height) const +Writer::Writer() + : _margin(QUIET_ZONE_SIZE), + _ecLevel(ErrorCorrectionLevel::Low), + _encoding(CharacterSet::Unknown), + _version(0), + _useGs1Format(false), + _maskPattern(-1) +{} + +BitMatrix Writer::encode(const std::wstring& contents, int width, int height) const { if (contents.empty()) { throw std::invalid_argument("Found empty contents"); From 9b0cc6038737952fb8e40ac6f72879cd7c9f0485 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 6 May 2022 17:54:23 +0200 Subject: [PATCH 0191/1315] example: minor performance/readability improvements in ZXingQtReader.h --- example/ZXingQtReader.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 8a316ca206..44ed865b2b 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -167,7 +167,7 @@ inline Result ReadBarcode(const QImage& img, const DecodeHints& hints = {}) {img.bits(), img.width(), img.height(), ImgFmtFromQImg(img), img.bytesPerLine()}, hints)); }; - return ImgFmtFromQImg(img) == ImageFormat::None ? exec(img.convertToFormat(QImage::Format_RGBX8888)) : exec(img); + return ImgFmtFromQImg(img) == ImageFormat::None ? exec(img.convertToFormat(QImage::Format_Grayscale8)) : exec(img); } #ifdef QT_MULTIMEDIA_LIB @@ -256,9 +256,8 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { ZXing::ReadBarcode({img.bits() + pixOffset, img.width(), img.height(), fmt, img.bytesPerLine(), pixStride}, hints)); } else { - auto qfmt = QVideoFrame::imageFormatFromPixelFormat(img.pixelFormat()); - if (qfmt != QImage::Format_Invalid) - res = ReadBarcode(QImage(img.bits(), img.width(), img.height(), qfmt), hints); + if (QVideoFrame::imageFormatFromPixelFormat(img.pixelFormat()) != QImage::Format_Invalid) + res = ReadBarcode(img.image(), hints); } img.unmap(); From ec547b349f354049a18bfb495a8f8291633a95b2 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 6 May 2022 22:12:36 +0200 Subject: [PATCH 0192/1315] ODReader: fix performance and lineCount bug in checkRows handling If the last checkRow returned a valid result, we ended up adding checkRows that have already been processed. --- core/src/oned/ODReader.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index eb4d4fbcdb..d84d1d0e65 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -108,6 +108,7 @@ static Results DoDecode(const std::vector>& readers, int rowStepsAboveOrBelow = (i + 1) / 2; bool isAbove = (i & 0x01) == 0; // i.e. is x even? int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow); + bool isCheckRow = false; if (rowNumber < 0 || rowNumber >= height) { // Oops, if we run off the top or bottom, stop break; @@ -118,6 +119,7 @@ static Results DoDecode(const std::vector>& readers, --i; rowNumber = checkRows.back(); checkRows.pop_back(); + isCheckRow = true; if (rowNumber < 0 || rowNumber >= height) continue; } @@ -199,7 +201,7 @@ static Results DoDecode(const std::vector>& readers, // if we found a valid code but have a minLineCount > 1, add additional check rows above and // below the current one - if (checkRows.empty() && minLineCount > 1 && rowStep > 1) { + if (!isCheckRow && minLineCount > 1 && rowStep > 1) { checkRows = {rowNumber - 1, rowNumber + 1}; if (rowStep > 2) checkRows.insert(checkRows.end(), {rowNumber - 2, rowNumber + 2}); From 2ab9fa6e78ae54cbf2d8e017953cf8bc6e77fef0 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 7 May 2022 02:22:46 +0200 Subject: [PATCH 0193/1315] AZDetector: switch float to double to fix surprising clang-13 regression Switching from clang-12 to clang-13 resulted in a failure of the samples/aztec-1/readerinit-compact-15x15.png test, due to a numerical instability. Seemingly, older clang and also g++-11 and g++-12 internally operate in double precision with the 'ratio' value even though it used to be a float, while clang-13 does no anymore. --- core/src/aztec/AZDetector.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index 6ff3089a8e..d0dfc2e5c7 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -340,21 +340,21 @@ static PointI GetFirstDifferent(const BitMatrix& image, const PointI& init, bool */ static void ExpandSquare(std::array& cornerPoints, float oldSide, float newSide) { - float ratio = newSide / (2 * oldSide); - float dx = cornerPoints[0].x() - cornerPoints[2].x(); - float dy = cornerPoints[0].y() - cornerPoints[2].y(); - float centerx = (cornerPoints[0].x() + cornerPoints[2].x()) / 2.0f; - float centery = (cornerPoints[0].y() + cornerPoints[2].y()) / 2.0f; + double ratio = newSide / (2.0 * oldSide); + double dx = cornerPoints[0].x() - cornerPoints[2].x(); + double dy = cornerPoints[0].y() - cornerPoints[2].y(); + double centerx = (cornerPoints[0].x() + cornerPoints[2].x()) / 2.0f; + double centery = (cornerPoints[0].y() + cornerPoints[2].y()) / 2.0f; - cornerPoints[0] = ResultPoint(centerx + ratio * dx, centery + ratio * dy); - cornerPoints[2] = ResultPoint(centerx - ratio * dx, centery - ratio * dy); + cornerPoints[0] = PointF(centerx + ratio * dx, centery + ratio * dy); + cornerPoints[2] = PointF(centerx - ratio * dx, centery - ratio * dy); dx = cornerPoints[1].x() - cornerPoints[3].x(); dy = cornerPoints[1].y() - cornerPoints[3].y(); centerx = (cornerPoints[1].x() + cornerPoints[3].x()) / 2.0f; centery = (cornerPoints[1].y() + cornerPoints[3].y()) / 2.0f; - cornerPoints[1] = ResultPoint(centerx + ratio * dx, centery + ratio * dy); - cornerPoints[3] = ResultPoint(centerx - ratio * dx, centery - ratio * dy); + cornerPoints[1] = PointF(centerx + ratio * dx, centery + ratio * dy); + cornerPoints[3] = PointF(centerx - ratio * dx, centery - ratio * dy); } From f009fe774794c4761dd4c739318b5dea0b16470f Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 9 May 2022 14:23:22 +0200 Subject: [PATCH 0194/1315] example: limit the list of 'supported' formats to those that actually are --- example/ZXingWriter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/ZXingWriter.cpp b/example/ZXingWriter.cpp index cd6188bcf8..18acc5cd41 100644 --- a/example/ZXingWriter.cpp +++ b/example/ZXingWriter.cpp @@ -40,9 +40,8 @@ static void PrintUsage(const char* exePath) << " -ecc Error correction level, [0-8]\n" << "\n" << "Supported formats are:\n"; - for (auto f : BarcodeFormats::all()) { + for (auto f : BarcodeFormatsFromString("Aztec Codabar Code39 Code93 Code128 DataMatrix EAN8 EAN13 ITF PDF417 QRCode UPCA UPCE")) std::cout << " " << ToString(f) << "\n"; - } std::cout << "Format can be lowercase letters, with or without '-'.\n"; } From a2c64fe7b136b56afe7f6456ce21ef48bd1f50be Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 9 May 2022 14:25:58 +0200 Subject: [PATCH 0195/1315] example: support writing barcode as SVG --- core/src/BitMatrixIO.cpp | 24 ++++++++++++++++++++++++ core/src/BitMatrixIO.h | 4 ++-- example/ZXingWriter.cpp | 11 +++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core/src/BitMatrixIO.cpp b/core/src/BitMatrixIO.cpp index be1732326c..dcdd090d9d 100644 --- a/core/src/BitMatrixIO.cpp +++ b/core/src/BitMatrixIO.cpp @@ -20,6 +20,7 @@ #include "BitArray.h" #include +#include namespace ZXing { @@ -44,6 +45,29 @@ std::string ToString(const BitMatrix& matrix, char one, char zero, bool addSpace return result; } +std::string ToSVG(const BitMatrix& matrix) +{ + // see https://stackoverflow.com/questions/10789059/create-qr-code-in-vector-image/60638350#60638350 + + const int width = matrix.width(); + const int height = matrix.height(); + std::ostringstream out; + + out << "\n" + << "\n" + << "\n"; + + return out.str(); +} + BitMatrix ParseBitMatrix(const std::string& str, char one, bool expectSpace) { auto lineLength = str.find('\n'); diff --git a/core/src/BitMatrixIO.h b/core/src/BitMatrixIO.h index 6946b33905..3178ac01a6 100644 --- a/core/src/BitMatrixIO.h +++ b/core/src/BitMatrixIO.h @@ -22,8 +22,8 @@ namespace ZXing { -std::string ToString(const BitMatrix& matrix, char one = 'X', char zero = ' ', bool addSpace = true, - bool printAsCString = false); +std::string ToString(const BitMatrix& matrix, char one = 'X', char zero = ' ', bool addSpace = true, bool printAsCString = false); +std::string ToSVG(const BitMatrix& matrix); BitMatrix ParseBitMatrix(const std::string& str, char one = 'X', bool expectSpace = true); void SaveAsPBM(const BitMatrix& matrix, const std::string filename, int quietZone = 0); diff --git a/example/ZXingWriter.cpp b/example/ZXingWriter.cpp index 18acc5cd41..2cec15e0b1 100644 --- a/example/ZXingWriter.cpp +++ b/example/ZXingWriter.cpp @@ -16,6 +16,7 @@ #include "BarcodeFormat.h" #include "BitMatrix.h" +#include "BitMatrixIO.h" #include "MultiFormatWriter.h" #include "TextUtfEncoding.h" #include "CharacterSetECI.h" @@ -23,6 +24,7 @@ #include #include #include +#include #include #include @@ -42,7 +44,9 @@ static void PrintUsage(const char* exePath) << "Supported formats are:\n"; for (auto f : BarcodeFormatsFromString("Aztec Codabar Code39 Code93 Code128 DataMatrix EAN8 EAN13 ITF PDF417 QRCode UPCA UPCE")) std::cout << " " << ToString(f) << "\n"; - std::cout << "Format can be lowercase letters, with or without '-'.\n"; + + std::cout << "Format can be lowercase letters, with or without '-'.\n" + << "Output format is determined by file name, supported are png, jpg and svg.\n"; } static bool ParseSize(std::string str, int* width, int* height) @@ -128,7 +132,8 @@ int main(int argc, char* argv[]) try { auto writer = MultiFormatWriter(format).setMargin(margin).setEncoding(encoding).setEccLevel(eccLevel); - auto bitmap = ToMatrix(writer.encode(TextUtfEncoding::FromUtf8(text), width, height)); + auto matrix = writer.encode(TextUtfEncoding::FromUtf8(text), width, height); + auto bitmap = ToMatrix(matrix); auto ext = GetExtension(filePath); int success = 0; @@ -136,6 +141,8 @@ int main(int argc, char* argv[]) success = stbi_write_png(filePath.c_str(), bitmap.width(), bitmap.height(), 1, bitmap.data(), 0); } else if (ext == "jpg" || ext == "jpeg") { success = stbi_write_jpg(filePath.c_str(), bitmap.width(), bitmap.height(), 1, bitmap.data(), 0); + } else if (ext == "svg") { + success = (std::ofstream(filePath) << ToSVG(matrix)).good(); } if (!success) { From 7da0382b5cc7815dddc91160ee77fe1dda951ec7 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 16 May 2022 11:08:23 +0200 Subject: [PATCH 0196/1315] ConcentricFinder: add FindConcentricPatternCorners This adds infrastructure for later MircoQRCode and Aztec additions. --- core/src/ConcentricFinder.cpp | 93 +++++++++++++++++++++++++++++++++++ core/src/ConcentricFinder.h | 3 ++ core/src/Quadrilateral.h | 8 +++ core/src/RegressionLine.h | 27 ++++++++-- 4 files changed, 127 insertions(+), 4 deletions(-) diff --git a/core/src/ConcentricFinder.cpp b/core/src/ConcentricFinder.cpp index 66ece3d655..830e31bd2b 100644 --- a/core/src/ConcentricFinder.cpp +++ b/core/src/ConcentricFinder.cpp @@ -17,6 +17,7 @@ #include "ConcentricFinder.h" #include "LogMatrix.h" +#include "RegressionLine.h" namespace ZXing { @@ -106,4 +107,96 @@ std::optional FinetuneConcentricPatternCenter(const BitMatrix& image, Po return res; } +static std::vector CollectRingPoints(const BitMatrix& image, PointF center, int range, int edgeIndex, bool backup) +{ + PointI centerI(center); + BitMatrixCursorI cur(image, centerI, {0, 1}); + cur.stepToEdge(edgeIndex, range, backup); + cur.turnRight(); // move clock wise and keep edge on the right/left depending on backup + const auto edgeDir = backup ? Direction::LEFT : Direction::RIGHT; + + uint32_t neighbourMask = 0; + auto start = cur.p; + std::vector points; + points.reserve(4 * range); + + do { + log(cur.p, 4); + points.push_back(centered(cur.p)); + + // find out if we come full circle around the center. 8 bits have to be set in the end. + neighbourMask |= (1 << (4 + dot(bresenhamDirection(cur.p - centerI), PointI(1, 3)))); + + if (!cur.stepAlongEdge(edgeDir)) + return {}; + + // use L-inf norm, simply because it is a lot faster than L2-norm and sufficiently accurate + if (maxAbsComponent(cur.p - center) > range || centerI == cur.p || Size(points) > 4 * 2 * range) + return {}; + + } while (cur.p != start); + + if (neighbourMask != 0b111101111) + return {}; + + return points; +} + +static QuadrilateralF FitQadrilateralToPoints(PointF center, std::vector& points) +{ + auto dist2Center = [c = center](auto a, auto b) { return distance(a, c) < distance(b, c); }; + // rotate points such that the first one is the furthest away from the center (hence, a corner) + std::rotate(points.begin(), std::max_element(points.begin(), points.end(), dist2Center), points.end()); + + std::array corners; + corners[0] = &points[0]; + // find the oposite corner by looking for the farthest point near the oposite point + corners[2] = std::max_element(&points[Size(points) * 3 / 8], &points[Size(points) * 5 / 8], dist2Center); + + // find the two in between corners by looking for the points farthest from the long diagonal + auto dist2Diagonal = [l = RegressionLine(*corners[0], *corners[2])](auto a, auto b) { return l.distance(a) < l.distance(b); }; + corners[1] = std::max_element(&points[Size(points) * 1 / 8], &points[Size(points) * 3 / 8], dist2Diagonal); + corners[3] = std::max_element(&points[Size(points) * 5 / 8], &points[Size(points) * 7 / 8], dist2Diagonal); + + std::array lines{RegressionLine{corners[0] + 1, corners[1]}, RegressionLine{corners[1] + 1, corners[2]}, + RegressionLine{corners[2] + 1, corners[3]}, RegressionLine{corners[3] + 1, &(*points.end())}}; + + QuadrilateralF res; + for (int i = 0; i < 4; ++i) + res[i] = intersect(lines[i], lines[(i + 1) % 4]); + + return res; +} + +std::optional FindConcentricPatternCorners(const BitMatrix& image, PointF center, int range, int lineIndex) +{ + auto innerPoints = CollectRingPoints(image, center, range, lineIndex, false); + auto outerPoints = CollectRingPoints(image, center, range, lineIndex + 1, true); + + if (innerPoints.empty() || outerPoints.empty()) + return {}; + + auto innerCorners = FitQadrilateralToPoints(center, innerPoints); + auto outerCorners = FitQadrilateralToPoints(center, outerPoints); + + auto dist2First = [c = innerCorners[0]](auto a, auto b) { return distance(a, c) < distance(b, c); }; + // rotate points such that the the two topLeft points are closest to each other + std::rotate(outerCorners.begin(), std::min_element(outerCorners.begin(), outerCorners.end(), dist2First), outerCorners.end()); + + QuadrilateralF res; + for (int i=0; i<4; ++i) + res[i] = (innerCorners[i] + outerCorners[i]) / 2; + + for (auto p : innerCorners) + log(p, 3); + + for (auto p : outerCorners) + log(p, 3); + + for (auto p : res) + log(p, 3); + + return res; +} + } // ZXing diff --git a/core/src/ConcentricFinder.h b/core/src/ConcentricFinder.h index 1cfbb6c825..64b47d1bbf 100644 --- a/core/src/ConcentricFinder.h +++ b/core/src/ConcentricFinder.h @@ -17,6 +17,7 @@ #include "BitMatrixCursor.h" #include "Pattern.h" +#include "Quadrilateral.h" #include "ZXContainerAlgorithms.h" #include @@ -76,6 +77,8 @@ std::optional CenterOfRing(const BitMatrix& image, PointI center, int ra std::optional FinetuneConcentricPatternCenter(const BitMatrix& image, PointF center, int range, int finderPatternSize); +std::optional FindConcentricPatternCorners(const BitMatrix& image, PointF center, int range, int ringIndex); + struct ConcentricPattern : public PointF { int size = 0; diff --git a/core/src/Quadrilateral.h b/core/src/Quadrilateral.h index 23d7e76a8f..ba2679d6bc 100644 --- a/core/src/Quadrilateral.h +++ b/core/src/Quadrilateral.h @@ -114,6 +114,14 @@ PointT Center(const Quadrilateral& q) return Reduce(q) / Size(q); } +template +Quadrilateral RotatedCorners(const Quadrilateral& q, int n = 1) +{ + Quadrilateral res; + std::rotate_copy(q.begin(), q.begin() + ((n + 4) % 4), q.end(), res.begin()); + return res; +} + template bool IsInside(const PointT& p, const Quadrilateral& q) { diff --git a/core/src/RegressionLine.h b/core/src/RegressionLine.h index 8be690fc72..a0ff880f80 100644 --- a/core/src/RegressionLine.h +++ b/core/src/RegressionLine.h @@ -22,6 +22,10 @@ #include #include +#ifdef PRINT_DEBUG +#include +#endif + namespace ZXing { class RegressionLine @@ -33,12 +37,12 @@ class RegressionLine friend PointF intersect(const RegressionLine& l1, const RegressionLine& l2); - bool evaluate(const std::vector& ps) + template bool evaluate(const PointT* begin, const PointT* end) { - auto mean = std::accumulate(ps.begin(), ps.end(), PointF()) / ps.size(); + auto mean = std::accumulate(begin, end, PointF()) / std::distance(begin, end); PointF::value_t sumXX = 0, sumYY = 0, sumXY = 0; - for (auto& p : ps) { - auto d = p - mean; + for (auto p = begin; p != end; ++p) { + auto d = *p - mean; sumXX += d.x * d.x; sumYY += d.y * d.y; sumXY += d.x * d.y; @@ -60,14 +64,29 @@ class RegressionLine return dot(_directionInward, normal()) > 0.5f; // angle between original and new direction is at most 60 degree } + template bool evaluate(const std::vector>& points) { return evaluate(&points.front(), &points.back() + 1); } + + template static auto distance(PointT a, PointT b) { return ZXing::distance(a, b); } + public: RegressionLine() { _points.reserve(16); } // arbitrary but plausible start size (tiny performance improvement) + template RegressionLine(PointT a, PointT b) + { + evaluate(std::vector{a, b}); + } + + template RegressionLine(const PointT* b, const PointT* e) + { + evaluate(b, e); + } + const auto& points() const { return _points; } int length() const { return _points.size() >= 2 ? int(distance(_points.front(), _points.back())) : 0; } bool isValid() const { return !std::isnan(a); } PointF normal() const { return isValid() ? PointF(a, b) : _directionInward; } auto signedDistance(PointF p) const { return dot(normal(), p) - c; } + template auto distance(PointT p) const { return std::abs(signedDistance(PointF(p))); } PointF project(PointF p) const { return p - signedDistance(p) * normal(); } void reset() From 86fca5ed176f060c221e851e4e85b78efc5e879c Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 16 May 2022 11:09:57 +0200 Subject: [PATCH 0197/1315] DecodeHints: hasFormat() maps `None` to `Any` --- core/src/DecodeHints.h | 2 +- core/src/oned/ODMultiUPCEANReader.cpp | 9 ++------- core/src/oned/ODMultiUPCEANReader.h | 1 - 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 8014bee4e5..d098e0a9c1 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -155,7 +155,7 @@ class DecodeHints [[deprecated]] bool assumeCode39CheckDigit() const noexcept { return validateCode39CheckSum(); } [[deprecated]] DecodeHints& setAssumeCode39CheckDigit(bool v) { return setValidateCode39CheckSum(v); } - bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f); } + bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f) || _formats.empty(); } bool hasNoFormat() const noexcept { return _formats.empty(); } }; diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 21783f001d..06218ac1e1 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -27,12 +27,7 @@ namespace ZXing::OneD { -MultiUPCEANReader::MultiUPCEANReader(const DecodeHints& hints) : _hints(hints) -{ - _canReturnUPCA = _hints.formats().empty() || _hints.hasFormat(BarcodeFormat::UPCA); - if (_hints.formats().empty()) - _hints.setFormats(BarcodeFormat::Any); -} +MultiUPCEANReader::MultiUPCEANReader(const DecodeHints& hints) : _hints(hints) {} MultiUPCEANReader::~MultiUPCEANReader() = default; @@ -297,7 +292,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u // If UPC-A was a requested format and we detected a EAN-13 code with a leading '0', then we drop the '0' and call it // a UPC-A code. // TODO: this is questionable - if (_canReturnUPCA && res.format == BarcodeFormat::EAN13 && res.txt.front() == '0') { + if (_hints.hasFormat(BarcodeFormat::UPCA) && res.format == BarcodeFormat::EAN13 && res.txt.front() == '0') { res.txt = res.txt.substr(1); res.format = BarcodeFormat::UPCA; } diff --git a/core/src/oned/ODMultiUPCEANReader.h b/core/src/oned/ODMultiUPCEANReader.h index 9d3154331e..7385001210 100644 --- a/core/src/oned/ODMultiUPCEANReader.h +++ b/core/src/oned/ODMultiUPCEANReader.h @@ -39,7 +39,6 @@ class MultiUPCEANReader : public RowReader Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; private: - bool _canReturnUPCA = false; DecodeHints _hints; }; From 9d71f099c991f8bbac8ce720be1a6929f86940a1 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 17 May 2022 10:13:02 +0200 Subject: [PATCH 0198/1315] python: remove pip from `requires` in toml file (hopefully fix CI build) --- wrappers/python/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/wrappers/python/pyproject.toml b/wrappers/python/pyproject.toml index d4b45410cf..dbeaae43ca 100644 --- a/wrappers/python/pyproject.toml +++ b/wrappers/python/pyproject.toml @@ -3,7 +3,6 @@ requires = [ "setuptools>=42", "setuptools_scm", "wheel", - "pip>=21", "cmake>=3.14", ] build-backend = "setuptools.build_meta" From d2031396c853e1013f5752ed94e894c135d34cc9 Mon Sep 17 00:00:00 2001 From: corbers <30796414+corbers@users.noreply.github.com> Date: Tue, 17 May 2022 09:44:29 +0100 Subject: [PATCH 0199/1315] Add micro qr code detector (#324) This adds support to detect Micro QR Codes. The code was originally based on an implementation ported from Java that was completely separate from the `QR*` files. It has been rewritten such that it merges with the existing `QRCode` functionality, thereby increasing its performance (both detection rate and runtime speed). For the sake of a cleaner git history, the PR has been squashed to prevent around 3k lines of code of going in and out again immediately. Co-authored-by: axxel --- core/src/BarcodeFormat.cpp | 1 + core/src/BarcodeFormat.h | 5 +- core/src/BitSource.cpp | 17 ++- core/src/BitSource.h | 7 + core/src/ConcentricFinder.cpp | 2 +- core/src/MultiFormatReader.cpp | 2 +- core/src/qrcode/QRBitMatrixParser.cpp | 93 ++++++++++-- core/src/qrcode/QRBitMatrixParser.h | 6 +- core/src/qrcode/QRCodecMode.cpp | 34 ++++- core/src/qrcode/QRCodecMode.h | 17 ++- core/src/qrcode/QRDataBlock.cpp | 2 + core/src/qrcode/QRDataMask.h | 16 ++- core/src/qrcode/QRDecoder.cpp | 45 ++++-- core/src/qrcode/QRDecoder.h | 2 +- core/src/qrcode/QRDetector.cpp | 92 +++++++++++- core/src/qrcode/QRDetector.h | 9 +- core/src/qrcode/QRErrorCorrectionLevel.cpp | 12 +- core/src/qrcode/QRErrorCorrectionLevel.h | 2 +- core/src/qrcode/QRFormatInformation.cpp | 102 ++++++++++--- core/src/qrcode/QRFormatInformation.h | 7 +- core/src/qrcode/QRReader.cpp | 78 +++++++--- core/src/qrcode/QRReader.h | 2 +- core/src/qrcode/QRVersion.cpp | 88 ++++++++---- core/src/qrcode/QRVersion.h | 22 ++- example/ZXingQtReader.h | 3 +- test/blackbox/BlackboxTestRunner.cpp | 8 ++ test/samples/microqrcode-1/1.png | Bin 0 -> 8513 bytes test/samples/microqrcode-1/1.txt | 1 + test/samples/microqrcode-1/11.jpg | Bin 0 -> 29581 bytes test/samples/microqrcode-1/11.txt | 1 + test/samples/microqrcode-1/12.jpg | Bin 0 -> 19328 bytes test/samples/microqrcode-1/12.txt | 1 + test/samples/microqrcode-1/3.jpg | Bin 0 -> 27818 bytes test/samples/microqrcode-1/3.txt | 1 + test/samples/microqrcode-1/7.jpg | Bin 0 -> 27342 bytes test/samples/microqrcode-1/7.txt | 1 + test/samples/microqrcode-1/9.jpg | Bin 0 -> 9245 bytes test/samples/microqrcode-1/9.txt | 1 + test/samples/microqrcode-1/M1-Numeric.png | Bin 0 -> 131 bytes test/samples/microqrcode-1/M1-Numeric.txt | 1 + test/samples/microqrcode-1/M2-Alpha.png | Bin 0 -> 146 bytes test/samples/microqrcode-1/M2-Alpha.txt | 1 + test/samples/microqrcode-1/M2-Numeric.png | Bin 0 -> 144 bytes test/samples/microqrcode-1/M2-Numeric.txt | 1 + test/samples/microqrcode-1/M3-Binary.png | Bin 0 -> 152 bytes test/samples/microqrcode-1/M3-Binary.txt | 1 + test/samples/microqrcode-1/M3-Kanji.png | Bin 0 -> 153 bytes test/samples/microqrcode-1/M3-Kanji.txt | 1 + test/samples/microqrcode-1/M3-Mixed.png | Bin 0 -> 150 bytes test/samples/microqrcode-1/M3-Mixed.txt | 1 + test/samples/microqrcode-1/M4-Binary.png | Bin 0 -> 168 bytes test/samples/microqrcode-1/M4-Binary.txt | 1 + test/samples/microqrcode-1/M4-Mixed.png | Bin 0 -> 167 bytes test/samples/microqrcode-1/M4-Mixed.txt | 1 + .../microqrcode-1/MQR-needs-br-update.jpg | Bin 0 -> 2002 bytes .../microqrcode-1/MQR-needs-br-update.txt | 1 + test/samples/microqrcode-1/NoQuietZone.png | Bin 0 -> 112 bytes test/samples/microqrcode-1/NoQuietZone.txt | 1 + test/unit/CMakeLists.txt | 2 + test/unit/qrcode/MQRDecoderTest.cpp | 135 ++++++++++++++++++ test/unit/qrcode/QRBitMatrixParserTest.cpp | 84 +++++++++++ test/unit/qrcode/QRDataMaskTest.cpp | 39 ++++- .../qrcode/QRErrorCorrectionLevelTest.cpp | 23 +++ test/unit/qrcode/QRFormatInformationTest.cpp | 47 +++++- test/unit/qrcode/QRModeTest.cpp | 32 +++++ test/unit/qrcode/QRVersionTest.cpp | 44 +++++- .../zxingcpp/src/main/cpp/BarcodeReader.cpp | 1 + .../main/java/com/zxingcpp/BarcodeReader.kt | 2 +- wrappers/python/zxing.cpp | 1 + wrappers/winrt/BarcodeReader.cpp | 4 + wrappers/winrt/BarcodeReader.h | 1 + 71 files changed, 965 insertions(+), 140 deletions(-) create mode 100644 test/samples/microqrcode-1/1.png create mode 100644 test/samples/microqrcode-1/1.txt create mode 100644 test/samples/microqrcode-1/11.jpg create mode 100644 test/samples/microqrcode-1/11.txt create mode 100644 test/samples/microqrcode-1/12.jpg create mode 100644 test/samples/microqrcode-1/12.txt create mode 100644 test/samples/microqrcode-1/3.jpg create mode 100644 test/samples/microqrcode-1/3.txt create mode 100644 test/samples/microqrcode-1/7.jpg create mode 100644 test/samples/microqrcode-1/7.txt create mode 100644 test/samples/microqrcode-1/9.jpg create mode 100644 test/samples/microqrcode-1/9.txt create mode 100644 test/samples/microqrcode-1/M1-Numeric.png create mode 100644 test/samples/microqrcode-1/M1-Numeric.txt create mode 100644 test/samples/microqrcode-1/M2-Alpha.png create mode 100644 test/samples/microqrcode-1/M2-Alpha.txt create mode 100644 test/samples/microqrcode-1/M2-Numeric.png create mode 100644 test/samples/microqrcode-1/M2-Numeric.txt create mode 100644 test/samples/microqrcode-1/M3-Binary.png create mode 100644 test/samples/microqrcode-1/M3-Binary.txt create mode 100644 test/samples/microqrcode-1/M3-Kanji.png create mode 100644 test/samples/microqrcode-1/M3-Kanji.txt create mode 100644 test/samples/microqrcode-1/M3-Mixed.png create mode 100644 test/samples/microqrcode-1/M3-Mixed.txt create mode 100644 test/samples/microqrcode-1/M4-Binary.png create mode 100644 test/samples/microqrcode-1/M4-Binary.txt create mode 100644 test/samples/microqrcode-1/M4-Mixed.png create mode 100644 test/samples/microqrcode-1/M4-Mixed.txt create mode 100644 test/samples/microqrcode-1/MQR-needs-br-update.jpg create mode 100644 test/samples/microqrcode-1/MQR-needs-br-update.txt create mode 100644 test/samples/microqrcode-1/NoQuietZone.png create mode 100644 test/samples/microqrcode-1/NoQuietZone.txt create mode 100644 test/unit/qrcode/MQRDecoderTest.cpp create mode 100644 test/unit/qrcode/QRBitMatrixParserTest.cpp diff --git a/core/src/BarcodeFormat.cpp b/core/src/BarcodeFormat.cpp index fddb6eface..e83df3ecfb 100644 --- a/core/src/BarcodeFormat.cpp +++ b/core/src/BarcodeFormat.cpp @@ -48,6 +48,7 @@ static BarcodeFormatName NAMES[] = { {BarcodeFormat::EAN13, "EAN-13"}, {BarcodeFormat::ITF, "ITF"}, {BarcodeFormat::MaxiCode, "MaxiCode"}, + {BarcodeFormat::MicroQRCode, "MicroQRCode"}, {BarcodeFormat::PDF417, "PDF417"}, {BarcodeFormat::QRCode, "QRCode"}, {BarcodeFormat::UPCA, "UPC-A"}, diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index 2858ed57e6..8bb5d3681a 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -47,9 +47,10 @@ enum class BarcodeFormat QRCode = (1 << 13), ///< QR Code (2D) UPCA = (1 << 14), ///< UPC-A (1D) UPCE = (1 << 15), ///< UPC-E (1D) + MicroQRCode = (1 << 16), ///< Micro QR Code (2D) OneDCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, - TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode, + TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, Any = OneDCodes | TwoDCodes, // Deprecated names, kept for compatibility at the moment @@ -70,7 +71,7 @@ enum class BarcodeFormat UPC_A [[deprecated]] = UPCA, UPC_E [[deprecated]] = UPCE, - _max = UPCE, ///> implementation detail, don't use + _max = MicroQRCode, ///> implementation detail, don't use }; ZX_DECLARE_FLAGS(BarcodeFormats, BarcodeFormat) diff --git a/core/src/BitSource.cpp b/core/src/BitSource.cpp index 6580bd6649..569014354c 100644 --- a/core/src/BitSource.cpp +++ b/core/src/BitSource.cpp @@ -30,10 +30,9 @@ BitSource::available() const return 8 * (Size(_bytes) - _byteOffset) - _bitOffset; } -int -BitSource::readBits(int numBits) +static int ReadBitsImpl(int numBits, const ByteArray& _bytes, int available, int& _byteOffset, int& _bitOffset) { - if (numBits < 1 || numBits > 32 || numBits > available()) { + if (numBits < 1 || numBits > 32 || numBits > available) { throw std::out_of_range("BitSource::readBits: out of range"); } @@ -74,4 +73,16 @@ BitSource::readBits(int numBits) return result; } +int BitSource::readBits(int numBits) +{ + return ReadBitsImpl(numBits, _bytes, available(), _byteOffset, _bitOffset); +} + +int BitSource::peakBits(int numBits) const +{ + int bitOffset = _bitOffset; + int byteOffset = _byteOffset; + return ReadBitsImpl(numBits, _bytes, available(), byteOffset, bitOffset); +} + } // ZXing diff --git a/core/src/BitSource.h b/core/src/BitSource.h index be55d42158..f9d0c2b064 100644 --- a/core/src/BitSource.h +++ b/core/src/BitSource.h @@ -68,6 +68,13 @@ class BitSource */ int readBits(int numBits); + /** + * @param numBits number of bits to peak + * @return int representing the bits peaked. The bits will appear as the least-significant + * bits of the int + */ + int peakBits(int numBits) const; + /** * @return number of bits that can be read successfully */ diff --git a/core/src/ConcentricFinder.cpp b/core/src/ConcentricFinder.cpp index 830e31bd2b..e53740d595 100644 --- a/core/src/ConcentricFinder.cpp +++ b/core/src/ConcentricFinder.cpp @@ -159,7 +159,7 @@ static QuadrilateralF FitQadrilateralToPoints(PointF center, std::vector corners[3] = std::max_element(&points[Size(points) * 5 / 8], &points[Size(points) * 7 / 8], dist2Diagonal); std::array lines{RegressionLine{corners[0] + 1, corners[1]}, RegressionLine{corners[1] + 1, corners[2]}, - RegressionLine{corners[2] + 1, corners[3]}, RegressionLine{corners[3] + 1, &(*points.end())}}; + RegressionLine{corners[2] + 1, corners[3]}, RegressionLine{corners[3] + 1, &points.back() + 1}}; QuadrilateralF res; for (int i = 0; i < 4; ++i) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 391bd72584..3b9a4b2d3f 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -39,7 +39,7 @@ MultiFormatReader::MultiFormatReader(const DecodeHints& hints) if (formats.testFlags(BarcodeFormat::OneDCodes) && !tryHarder) _readers.emplace_back(new OneD::Reader(hints)); - if (formats.testFlag(BarcodeFormat::QRCode)) + if (formats.testFlags(BarcodeFormat::QRCode | BarcodeFormat::MicroQRCode)) _readers.emplace_back(new QRCode::Reader(hints)); if (formats.testFlag(BarcodeFormat::DataMatrix)) _readers.emplace_back(new DataMatrix::Reader(hints)); diff --git a/core/src/qrcode/QRBitMatrixParser.cpp b/core/src/qrcode/QRBitMatrixParser.cpp index ab599a7b67..d54991cbaf 100644 --- a/core/src/qrcode/QRBitMatrixParser.cpp +++ b/core/src/qrcode/QRBitMatrixParser.cpp @@ -33,22 +33,26 @@ static bool getBit(const BitMatrix& bitMatrix, int x, int y, bool mirrored) return mirrored ? bitMatrix.get(y, x) : bitMatrix.get(x, y); } -static bool hasValidDimension(const BitMatrix& bitMatrix) +static bool hasValidDimension(const BitMatrix& bitMatrix, bool isMicro) { int dimension = bitMatrix.height(); - return dimension >= 21 && dimension <= 177 && (dimension % 4) == 1; + if (isMicro) + return dimension >= 11 && dimension <= 17 && (dimension % 2) == 1; + else + return dimension >= 21 && dimension <= 177 && (dimension % 4) == 1; } -const Version* ReadVersion(const BitMatrix& bitMatrix) +const Version* ReadVersion(const BitMatrix& bitMatrix, bool isMicro) { - if (!hasValidDimension(bitMatrix)) + if (!hasValidDimension(bitMatrix, isMicro)) return nullptr; int dimension = bitMatrix.height(); - int provisionalVersion = (dimension - 17) / 4; + int provisionalVersion = (dimension - Version::DimensionOffset(isMicro)) / Version::DimensionStep(isMicro); + if (provisionalVersion <= 6) - return Version::VersionForNumber(provisionalVersion); + return Version::VersionForNumber(provisionalVersion, isMicro); for (bool mirror : {false, true}) { // Read top-right/bottom-left version info: 3 wide by 6 tall (depending on mirrored) @@ -66,11 +70,22 @@ const Version* ReadVersion(const BitMatrix& bitMatrix) return nullptr; } -FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrored) +FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrored, bool isMicro) { - if (!hasValidDimension(bitMatrix)) + if (!hasValidDimension(bitMatrix, isMicro)) return {}; + if (isMicro) { + // Read top-left format info bits + int formatInfoBits = 0; + for (int x = 1; x < 9; x++) + AppendBit(formatInfoBits, getBit(bitMatrix, x, 8, mirrored)); + for (int y = 7; y >= 1; y--) + AppendBit(formatInfoBits, getBit(bitMatrix, 8, y, mirrored)); + + return FormatInformation::DecodeFormatInformation(formatInfoBits); + } + // Read top-left format info bits int formatInfoBits1 = 0; for (int x = 0; x < 6; x++) @@ -94,11 +109,8 @@ FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrore return FormatInformation::DecodeFormatInformation(formatInfoBits1, formatInfoBits2); } -ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, int maskIndex, bool mirrored) +static ByteArray ReadQRCodewords(const BitMatrix& bitMatrix, const Version& version, int maskIndex, bool mirrored) { - if (!hasValidDimension(bitMatrix)) - return {}; - BitMatrix functionPattern = version.buildFunctionPattern(); ByteArray result; @@ -135,4 +147,61 @@ ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, int return result; } +static ByteArray ReadMQRCodewords(const BitMatrix& bitMatrix, const QRCode::Version& version, + const FormatInformation& formatInformation, bool mirrored) +{ + BitMatrix functionPattern = version.buildFunctionPattern(); + + // D3 in a Version M1 symbol, D11 in a Version M3-L symbol and D9 + // in a Version M3-M symbol is a 2x2 square 4-module block. + // See ISO 18004:2006 6.7.3. + bool hasD4mBlock = version.versionNumber() % 2 == 1; + int d4mBlockIndex = + version.versionNumber() == 1 ? 3 : (formatInformation.errorCorrectionLevel() == QRCode::ErrorCorrectionLevel::Low ? 11 : 9); + + ByteArray result; + result.reserve(version.totalCodewords()); + uint8_t currentByte = 0; + bool readingUp = true; + int bitsRead = 0; + int dimension = bitMatrix.height(); + // Read columns in pairs, from right to left + for (int x = dimension - 1; x > 0; x -= 2) { + // Read alternatingly from bottom to top then top to bottom + for (int row = 0; row < dimension; row++) { + int y = readingUp ? dimension - 1 - row : row; + for (int col = 0; col < 2; col++) { + int xx = x - col; + // Ignore bits covered by the function pattern + if (!functionPattern.get(xx, y)) { + // Read a bit + AppendBit(currentByte, + GetDataMaskBit(formatInformation.dataMask(), xx, y, true) != getBit(bitMatrix, xx, y, mirrored)); + ++bitsRead; + // If we've made a whole byte, save it off; save early if 2x2 data block. + if (bitsRead == 8 || (bitsRead == 4 && hasD4mBlock && Size(result) == d4mBlockIndex - 1)) { + result.push_back(std::exchange(currentByte, 0)); + bitsRead = 0; + } + } + } + } + readingUp = !readingUp; // switch directions + } + if (Size(result) != version.totalCodewords()) + return {}; + + return result; +} + +ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, const FormatInformation& formatInformation, + bool mirrored) +{ + if (!hasValidDimension(bitMatrix, version.isMicroQRCode())) + return {}; + + return version.isMicroQRCode() ? ReadMQRCodewords(bitMatrix, version, formatInformation, mirrored) + : ReadQRCodewords(bitMatrix, version, formatInformation.dataMask(), mirrored); +} + } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRBitMatrixParser.h b/core/src/qrcode/QRBitMatrixParser.h index 3f0a9d9900..c911389b6f 100644 --- a/core/src/qrcode/QRBitMatrixParser.h +++ b/core/src/qrcode/QRBitMatrixParser.h @@ -30,20 +30,20 @@ class FormatInformation; * @brief Reads version information from the QR Code. * @return {@link Version} encapsulating the QR Code's version, nullptr if neither location can be parsed */ -const Version* ReadVersion(const BitMatrix& bitMatrix); +const Version* ReadVersion(const BitMatrix& bitMatrix, bool isMicro); /** * @brief Reads format information from one of its two locations within the QR Code. * @return {@link FormatInformation} encapsulating the QR Code's format info, result is invalid if both format * information locations cannot be parsed as the valid encoding of format information */ -FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrored); +FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrored, bool isMicro); /** * @brief Reads the codewords from the BitMatrix. * @return bytes encoded within the QR Code or empty array if the exact number of bytes expected is not read */ -ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, int maskIndex, bool mirrored); +ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, const FormatInformation& formatInformation, bool mirrored); } // QRCode } // ZXing diff --git a/core/src/qrcode/QRCodecMode.cpp b/core/src/qrcode/QRCodecMode.cpp index a64e6bd9c6..f0e635128a 100644 --- a/core/src/qrcode/QRCodecMode.cpp +++ b/core/src/qrcode/QRCodecMode.cpp @@ -18,16 +18,23 @@ #include "QRCodecMode.h" #include "QRVersion.h" +#include "ZXContainerAlgorithms.h" #include #include namespace ZXing::QRCode { -CodecMode CodecModeForBits(int bits) +CodecMode CodecModeForBits(int bits, bool isMirco) { - if ((bits >= 0x00 && bits <= 0x05) || (bits >= 0x07 && bits <= 0x09) || bits == 0x0d) - return static_cast(bits); + if (!isMirco) { + if ((bits >= 0x00 && bits <= 0x05) || (bits >= 0x07 && bits <= 0x09) || bits == 0x0d) + return static_cast(bits); + } else { + constexpr CodecMode Bits2Mode[4] = {CodecMode::NUMERIC, CodecMode::ALPHANUMERIC, CodecMode::BYTE, CodecMode::KANJI}; + if (bits < Size(Bits2Mode)) + return Bits2Mode[bits]; + } throw std::invalid_argument("Invalid mode"); } @@ -35,6 +42,17 @@ CodecMode CodecModeForBits(int bits) int CharacterCountBits(CodecMode mode, const Version& version) { int number = version.versionNumber(); + if (version.isMicroQRCode()) { + switch (mode) { + case CodecMode::NUMERIC: return std::array{3, 4, 5, 6}[number - 1]; + case CodecMode::ALPHANUMERIC: return std::array{3, 4, 5}[number - 2]; + case CodecMode::BYTE: return std::array{4, 5}[number - 3]; + case CodecMode::KANJI: [[fallthrough]]; + case CodecMode::HANZI: return std::array{3, 4}[number - 3]; + default: return 0; + } + } + int i; if (number <= 9) i = 0; @@ -53,4 +71,14 @@ int CharacterCountBits(CodecMode mode, const Version& version) } } +int CodecModeBitsLength(const Version& version) +{ + return version.isMicroQRCode() ? version.versionNumber() - 1 : 4; +} + +int TerminatorBitsLength(const Version& version) +{ + return version.isMicroQRCode() ? version.versionNumber() * 2 + 1 : 4; +} + } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRCodecMode.h b/core/src/qrcode/QRCodecMode.h index 066c143fd4..eca59e12ca 100644 --- a/core/src/qrcode/QRCodecMode.h +++ b/core/src/qrcode/QRCodecMode.h @@ -40,11 +40,12 @@ enum class CodecMode }; /** - * @param bits four bits encoding a QR Code data mode + * @param bits variable number of bits encoding a QR Code data mode + * @param isMicro is this a MicroQRCode * @return Mode encoded by these bits * @throws IllegalArgumentException if bits do not correspond to a known mode */ -CodecMode CodecModeForBits(int bits); +CodecMode CodecModeForBits(int bits, bool isMirco = false); /** * @param version version in question @@ -53,5 +54,17 @@ CodecMode CodecModeForBits(int bits); */ int CharacterCountBits(CodecMode mode, const Version& version); +/** + * @param version version in question + * @return number of bits used to encode a codec mode. + */ +int CodecModeBitsLength(const Version& version); + +/** + * @param version version in question + * @return number of bits in the Terminator code. + */ +int TerminatorBitsLength(const Version& version); + } // QRCode } // ZXing diff --git a/core/src/qrcode/QRDataBlock.cpp b/core/src/qrcode/QRDataBlock.cpp index 7c04f5e760..2b005aa48f 100644 --- a/core/src/qrcode/QRDataBlock.cpp +++ b/core/src/qrcode/QRDataBlock.cpp @@ -34,6 +34,8 @@ std::vector DataBlock::GetDataBlocks(const ByteArray& rawCodewords, c // First count the total number of data blocks int totalBlocks = ecBlocks.numBlocks(); + if (totalBlocks == 0) + return {}; std::vector result(totalBlocks); // Now establish DataBlocks of the appropriate size and number of data codewords diff --git a/core/src/qrcode/QRDataMask.h b/core/src/qrcode/QRDataMask.h index 50045cda3a..8b43b9ab86 100644 --- a/core/src/qrcode/QRDataMask.h +++ b/core/src/qrcode/QRDataMask.h @@ -18,20 +18,27 @@ #include "BitMatrix.h" +#include #include namespace ZXing { namespace QRCode { /** -*

Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8.

+*

Encapsulates data masks for the data bits in a QR and micro QR code, per ISO 18004:2006 6.8.

* *

Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position * and j is row position. In fact, as the text says, i is row position and j is column position.

*/ -inline bool GetDataMaskBit(int maskIndex, int x, int y) +inline bool GetDataMaskBit(int maskIndex, int x, int y, bool isMicro = false) { + if (isMicro) { + if (maskIndex < 0 || maskIndex >= 4) + throw std::invalid_argument("QRCode maskIndex out of range"); + maskIndex = std::array{1, 4, 6, 7}[maskIndex]; // map from MQR to QR indices + } + switch (maskIndex) { case 0: return (y + x) % 2 == 0; case 1: return y % 2 == 0; @@ -42,12 +49,13 @@ inline bool GetDataMaskBit(int maskIndex, int x, int y) case 6: return ((y * x) % 6) < 3; case 7: return (y + x + ((y * x) % 3)) % 2 == 0; } + throw std::invalid_argument("QRCode maskIndex out of range"); } -inline bool GetMaskedBit(const BitMatrix& bits, int x, int y, int maskIndex) +inline bool GetMaskedBit(const BitMatrix& bits, int x, int y, int maskIndex, bool isMicro = false) { - return GetDataMaskBit(maskIndex, x, y) != bits.get(x, y); + return GetDataMaskBit(maskIndex, x, y, isMicro) != bits.get(x, y); } } // QRCode diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 8092147adc..6e5c259814 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -28,6 +28,7 @@ #include "QRCodecMode.h" #include "QRDataBlock.h" #include "QRFormatInformation.h" +#include "QRVersion.h" #include "ReedSolomonDecoder.h" #include "StructuredAppend.h" #include "TextDecoder.h" @@ -290,6 +291,30 @@ static DecodeStatus ParseECIValue(BitSource& bits, int& outValue) return DecodeStatus::FormatError; } +/** + * QR codes encode mode indicators and terminator codes into a constant bit length of 4. + * Micro QR codes have terminator codes that vary in bit length but are always longer than + * the mode indicators. + * M1 - 0 length mode code, 3 bits terminator code + * M2 - 1 bit mode code, 5 bits terminator code + * M3 - 2 bit mode code, 7 bits terminator code + * M4 - 3 bit mode code, 9 bits terminator code + * IsTerminator peaks into the bit stream to see if the current position is at the start of + * a terminator code. If true, then the decoding can finish. If false, then the decoding + * can read off the next mode code. + * + * See ISO 18004:2006, 6.4.1 Table 2 + * + * @param bits the stream of bits that might have a terminator code + * @param version the QR or micro QR code version + */ +bool IsTerminator(const BitSource& bits, const Version& version) +{ + const int bitsRequired = TerminatorBitsLength(version); + const int bitsAvailable = std::min(bits.available(), bitsRequired); + return bits.peakBits(bitsAvailable) == 0; +} + /** *

QR Codes can encode text as bits in one of several modes, and can use multiple modes * in one QR Code. This method decodes the bits back into text.

@@ -306,6 +331,8 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo int appIndValue = -1; // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position) StructuredAppendInfo structuredAppend; static const int GB2312_SUBSET = 1; + const int modeBitLength = CodecModeBitsLength(version); + const int minimumBitsRequired = modeBitLength + CharacterCountBits(CodecMode::NUMERIC, version); try { @@ -314,12 +341,14 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo CodecMode mode; do { // While still another segment to read... - if (bits.available() < 4) { + if (bits.available() < minimumBitsRequired || IsTerminator(bits, version)) { // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here mode = CodecMode::TERMINATOR; - } - else { - mode = CodecModeForBits(bits.readBits(4)); // mode is encoded by 4 bits + } else if (modeBitLength == 0) { + // MicroQRCode version 1 is always NUMERIC and modeBitLength is 0 + mode = CodecMode::NUMERIC; + } else { + mode = CodecModeForBits(bits.readBits(modeBitLength), version.isMicroQRCode()); } switch (mode) { case CodecMode::TERMINATOR: @@ -423,12 +452,12 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, const std::string& hintedCharset, bool mirrored) { - auto formatInfo = ReadFormatInformation(bits, mirrored); + auto formatInfo = ReadFormatInformation(bits, mirrored, version.isMicroQRCode()); if (!formatInfo.isValid()) return DecodeStatus::FormatError; // Read codewords - ByteArray codewords = ReadCodewords(bits, version, formatInfo.dataMask(), mirrored); + ByteArray codewords = ReadCodewords(bits, version, formatInfo, mirrored); if (codewords.empty()) return DecodeStatus::FormatError; @@ -459,9 +488,9 @@ static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, con return DecodeBitStream(std::move(resultBytes), version, formatInfo.errorCorrectionLevel(), hintedCharset); } -DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) +DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset, const bool isMicroQRCode) { - const Version* version = ReadVersion(bits); + const Version* version = ReadVersion(bits, isMicroQRCode); if (!version) return DecodeStatus::FormatError; diff --git a/core/src/qrcode/QRDecoder.h b/core/src/qrcode/QRDecoder.h index e66a7c1229..e8171b036b 100644 --- a/core/src/qrcode/QRDecoder.h +++ b/core/src/qrcode/QRDecoder.h @@ -28,7 +28,7 @@ namespace QRCode { /** * @brief Decodes a QR Code from the BitMatrix and the hinted charset. */ -DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset); +DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset, const bool isMicroQRCode = false); } // QRCode } // ZXing diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 48afd325ae..a50202c97a 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -18,13 +18,15 @@ #include "QRDetector.h" +#include "BitArray.h" #include "BitMatrix.h" #include "BitMatrixCursor.h" #include "ConcentricFinder.h" -#include "DetectorResult.h" #include "GridSampler.h" #include "LogMatrix.h" #include "Pattern.h" +#include "QRFormatInformation.h" +#include "QRVersion.h" #include "Quadrilateral.h" #include "RegressionLine.h" @@ -41,10 +43,8 @@ namespace ZXing::QRCode { constexpr auto PATTERN = FixedPattern<5, 7>{1, 1, 3, 1, 1}; -constexpr int MIN_MODULES = 1 * 4 + 17; // version 1 -constexpr int MAX_MODULES = 40 * 4 + 17; // version 40 -static auto FindFinderPatterns(const BitMatrix& image, bool tryHarder) +std::vector FindFinderPatterns(const BitMatrix& image, bool tryHarder) { constexpr int MIN_SKIP = 3; // 1 pixel/module times 3 modules/center constexpr int MAX_MODULES_FAST = 20 * 4 + 17; // support up to version 20 for mobile clients @@ -93,7 +93,7 @@ static auto FindFinderPatterns(const BitMatrix& image, bool tryHarder) * @param patterns list of ConcentricPattern objects, i.e. found finder pattern squares * @return list of plausible finder pattern sets, sorted by decreasing plausibility */ -static FinderPatternSets GenerateFinderPatternSets(std::vector&& patterns) +FinderPatternSets GenerateFinderPatternSets(FinderPatterns&& patterns) { std::sort(patterns.begin(), patterns.end(), [](const auto& a, const auto& b) { return a.size < b.size; }); @@ -324,7 +324,7 @@ DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatt * around it. This is a specialized method that works exceptionally fast in this special * case. */ -static DetectorResult DetectPure(const BitMatrix& image) +DetectorResult DetectPure(const BitMatrix& image) { using Pattern = std::array; @@ -332,6 +332,9 @@ static DetectorResult DetectPure(const BitMatrix& image) SaveAsPBM(image, "weg.pbm"); #endif + constexpr int MIN_MODULES = Version::DimensionOfVersion(1, false); + constexpr int MAX_MODULES = Version::DimensionOfVersion(40, false); + int left, top, width, height; if (!image.findBoundingBox(left, top, width, height, MIN_MODULES) || std::abs(width - height) > 1) return {}; @@ -369,6 +372,46 @@ static DetectorResult DetectPure(const BitMatrix& image) {{left, top}, {right, top}, {right, bottom}, {left, bottom}}}; } +DetectorResult DetectPureMicroQR(const BitMatrix& image) +{ + using Pattern = std::array; + + constexpr int MIN_MODULES = Version::DimensionOfVersion(1, true); + constexpr int MAX_MODULES = Version::DimensionOfVersion(4, true); + + int left, top, width, height; + if (!image.findBoundingBox(left, top, width, height, MIN_MODULES) || std::abs(width - height) > 1) + return {}; + int right = left + width - 1; + int bottom = top + height - 1; + + // allow corners be moved one pixel inside to accommodate for possible aliasing artifacts + auto diagonal = BitMatrixCursorI(image, {left, top}, {1, 1}).readPatternFromBlack(1); + if (!IsPattern(diagonal, PATTERN)) + return {}; + + auto fpWidth = Reduce(diagonal); + float moduleSize = float(fpWidth) / 7; + auto dimension = width / moduleSize; + + if (dimension < MIN_MODULES || dimension > MAX_MODULES || + !image.isIn(PointF{left + moduleSize / 2 + (dimension - 1) * moduleSize, + top + moduleSize / 2 + (dimension - 1) * moduleSize})) + return {}; + +#ifdef PRINT_DEBUG + LogMatrix log; + LogMatrixWriter lmw(log, image, 5, "grid2.pnm"); + for (int y = 0; y < dimension; y++) + for (int x = 0; x < dimension; x++) + log(PointF(left + (x + .5f) * moduleSize, top + (y + .5f) * moduleSize)); +#endif + + // Now just read off the bits (this is a crop + subsample) + return {Deflate(image, dimension, dimension, top + moduleSize / 2, left + moduleSize / 2, moduleSize), + {{left, top}, {right, top}, {right, bottom}, {left, bottom}}}; +} + FinderPatternSets FindFinderPatternSets(const BitMatrix& image, bool tryHarder) { return GenerateFinderPatternSets(FindFinderPatterns(image, tryHarder)); @@ -395,4 +438,41 @@ DetectorResult Detect(const BitMatrix& image, bool tryHarder, bool isPure) return SampleAtFinderPatternSet(image, sets[0]); } +DetectorResult SampleAtFinderPattern(const BitMatrix& image, const ConcentricPattern& fp) +{ + auto fpQuad = FindConcentricPatternCorners(image, fp, fp.size, 2); + if (!fpQuad) + return {}; + + auto srcQuad = Rectangle(7, 7, 0.5); + + constexpr PointI FORMAT_INFO_COORDS[] = {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, + {8, 7}, {8, 6}, {8, 5}, {8, 4}, {8, 3}, {8, 2}, {8, 1}, {8, 0}}; + + for (int i = 0; i < 4; ++i) { + auto mod2Pix = PerspectiveTransform(srcQuad, RotatedCorners(*fpQuad, i)); + + auto check = [&](int i, bool checkOne) { + auto p = mod2Pix(centered(FORMAT_INFO_COORDS[i])); + return image.isIn(p) && (!checkOne || image.get(p)); + }; + + // check that we see both innermost timing pattern modules + if (!check(0, true) || !check(8, false) || !check(16, true)) + continue; + + int formatInfoBits = 0; + for (int i = 1; i <= 15; ++i) + AppendBit(formatInfoBits, image.get(mod2Pix(centered(FORMAT_INFO_COORDS[i])))); + + auto fi = FormatInformation::DecodeFormatInformation(formatInfoBits); + if (fi.isValid() && fi.microVersion()) { + const int dim = Version::DimensionOfVersion(fi.microVersion(), true); + return SampleGrid(image, dim, dim, mod2Pix); + } + } + + return {}; +} + } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRDetector.h b/core/src/qrcode/QRDetector.h index b11975fffa..36f1b90bd1 100644 --- a/core/src/qrcode/QRDetector.h +++ b/core/src/qrcode/QRDetector.h @@ -18,6 +18,7 @@ */ #include "ConcentricFinder.h" +#include "DetectorResult.h" #include @@ -33,10 +34,16 @@ struct FinderPatternSet ConcentricPattern bl, tl, tr; }; +using FinderPatterns = std::vector; using FinderPatternSets = std::vector; -FinderPatternSets FindFinderPatternSets(const BitMatrix& image, bool tryHarder); +FinderPatterns FindFinderPatterns(const BitMatrix& image, bool tryHarder); +FinderPatternSets GenerateFinderPatternSets(FinderPatterns&& patterns); DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatternSet& fp); +DetectorResult SampleAtFinderPattern(const BitMatrix& image, const ConcentricPattern& fp); + +DetectorResult DetectPureMicroQR(const BitMatrix& image); +DetectorResult DetectPure(const BitMatrix& image); /** * @brief Detects a QR Code in an image. diff --git a/core/src/qrcode/QRErrorCorrectionLevel.cpp b/core/src/qrcode/QRErrorCorrectionLevel.cpp index 3c9f9c9f86..2a3b93ff15 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.cpp +++ b/core/src/qrcode/QRErrorCorrectionLevel.cpp @@ -39,10 +39,16 @@ ErrorCorrectionLevel ECLevelFromString(const char* str) } } -ErrorCorrectionLevel ECLevelFromBits(int bits) +ErrorCorrectionLevel ECLevelFromBits(int bits, const bool isMicro) { - static const ErrorCorrectionLevel LEVEL_FOR_BITS[] = {ErrorCorrectionLevel::Medium, ErrorCorrectionLevel::Low, - ErrorCorrectionLevel::High, ErrorCorrectionLevel::Quality}; + if (isMicro) { + constexpr ErrorCorrectionLevel LEVEL_FOR_BITS[] = { + ErrorCorrectionLevel::Low, ErrorCorrectionLevel::Low, ErrorCorrectionLevel::Medium, ErrorCorrectionLevel::Low, + ErrorCorrectionLevel::Medium, ErrorCorrectionLevel::Low, ErrorCorrectionLevel::Medium, ErrorCorrectionLevel::Quality}; + return LEVEL_FOR_BITS[bits & 0x07]; + } + constexpr ErrorCorrectionLevel LEVEL_FOR_BITS[] = {ErrorCorrectionLevel::Medium, ErrorCorrectionLevel::Low, + ErrorCorrectionLevel::High, ErrorCorrectionLevel::Quality}; return LEVEL_FOR_BITS[bits & 0x3]; } diff --git a/core/src/qrcode/QRErrorCorrectionLevel.h b/core/src/qrcode/QRErrorCorrectionLevel.h index 2000543da0..1993fffdda 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.h +++ b/core/src/qrcode/QRErrorCorrectionLevel.h @@ -36,7 +36,7 @@ enum class ErrorCorrectionLevel const wchar_t* ToString(ErrorCorrectionLevel l); ErrorCorrectionLevel ECLevelFromString(const char* str); -ErrorCorrectionLevel ECLevelFromBits(int bits); +ErrorCorrectionLevel ECLevelFromBits(int bits, const bool isMicro = false); int BitsFromECLevel(ErrorCorrectionLevel l); } // QRCode diff --git a/core/src/qrcode/QRFormatInformation.cpp b/core/src/qrcode/QRFormatInformation.cpp index bc32436f2d..9bea8c0247 100644 --- a/core/src/qrcode/QRFormatInformation.cpp +++ b/core/src/qrcode/QRFormatInformation.cpp @@ -28,7 +28,7 @@ static const int FORMAT_INFO_MASK_QR = 0x5412; /** * See ISO 18004:2006, Annex C, Table C.1 */ -static const std::array FORMAT_INFO_DECODE_LOOKUP[] = { +static const std::array, 32> FORMAT_INFO_DECODE_LOOKUP = {{ {0x5412, 0x00}, {0x5125, 0x01}, {0x5E7C, 0x02}, @@ -61,14 +61,64 @@ static const std::array FORMAT_INFO_DECODE_LOOKUP[] = { {0x2183, 0x1D}, {0x2EDA, 0x1E}, {0x2BED, 0x1F}, -}; +}}; -FormatInformation::FormatInformation(int formatInfo) +static const std::array, 32> FORMAT_INFO_DECODE_LOOKUP_MICRO = {{ + {0x4445, 0x00}, + {0x4172, 0x01}, + {0x4E2B, 0x02}, + {0x4B1C, 0x03}, + {0x55AE, 0x04}, + {0x5099, 0x05}, + {0x5FC0, 0x06}, + {0x5AF7, 0x07}, + {0x6793, 0x08}, + {0x62A4, 0x09}, + {0x6DFD, 0x0A}, + {0x68CA, 0x0B}, + {0x7678, 0x0C}, + {0x734F, 0x0D}, + {0x7C16, 0x0E}, + {0x7921, 0x0F}, + {0x06DE, 0x10}, + {0x03E9, 0x11}, + {0x0CB0, 0x12}, + {0x0987, 0x13}, + {0x1735, 0x14}, + {0x1202, 0x15}, + {0x1D5B, 0x16}, + {0x186C, 0x17}, + {0x2508, 0x18}, + {0x203F, 0x19}, + {0x2F66, 0x1A}, + {0x2A51, 0x1B}, + {0x34E3, 0x1C}, + {0x31D4, 0x1D}, + {0x3E8D, 0x1E}, + {0x3BBA, 0x1F}, +}}; + +static int FindBestFormatInfo(int mask, const std::array, 32> lookup, const std::vector& bits) { - // Bits 3,4 - _errorCorrectionLevel = ECLevelFromBits((formatInfo >> 3) & 0x03); - // Bottom 3 bits - _dataMask = static_cast(formatInfo & 0x07); + // Find the int in lookup with fewest bits differing + int bestDifference = 32; + int bestFormatInfo = -1; + + // Some QR codes apparently do not apply the XOR mask. Try without and with additional masking. + for (auto mask : {0, mask}) + for (uint32_t bits : bits) + for (const auto& [pattern, decodedInfo] : lookup) + if (int bitsDifference = BitHacks::CountBitsSet((bits ^ mask) ^ pattern); bitsDifference < bestDifference) { + bestFormatInfo = decodedInfo; + bestDifference = bitsDifference; + } + + // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits + // differing means we found a match + if (bestDifference <= 3) + return bestFormatInfo; + + return -1; } /** @@ -81,25 +131,31 @@ FormatInformation::FormatInformation(int formatInfo) FormatInformation FormatInformation::DecodeFormatInformation(uint32_t formatInfoBits1, uint32_t formatInfoBits2) { - // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing - int bestDifference = 32; - int bestFormatInfo = -1; + int bestFormatInfo = FindBestFormatInfo(FORMAT_INFO_MASK_QR, FORMAT_INFO_DECODE_LOOKUP, {formatInfoBits1, formatInfoBits2}); + if (bestFormatInfo < 0) + return {}; - // Some QR codes apparently do not apply the XOR mask. Try without and with additional masking. - for (auto mask : {0, FORMAT_INFO_MASK_QR}) - for (uint32_t bits : {formatInfoBits1 ^ mask, formatInfoBits2 ^ mask}) - for (auto& [pattern, decodedInfo] : FORMAT_INFO_DECODE_LOOKUP) - if (int bitsDifference = BitHacks::CountBitsSet(bits ^ pattern); bitsDifference < bestDifference) { - bestFormatInfo = decodedInfo; - bestDifference = bitsDifference; - } + // Use bits 3/4 for error correction, and 0-2 for mask. + return {ECLevelFromBits((bestFormatInfo >> 3) & 0x03), static_cast(bestFormatInfo & 0x07)}; +} - // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits - // differing means we found a match - if (bestDifference <= 3) - return {bestFormatInfo}; +/** + * @param formatInfoBits format info indicator, with mask still applied + * @return information about the format it specifies, or {@code null} + * if doesn't seem to match any known pattern + */ +FormatInformation FormatInformation::DecodeFormatInformation(uint32_t formatInfoBits) +{ + // We don't use the additional masking (with 0x4445) to work around potentially non complying MircoQRCode encoders + int bestFormatInfo = FindBestFormatInfo(0, FORMAT_INFO_DECODE_LOOKUP_MICRO, {formatInfoBits}); + if (bestFormatInfo < 0) + return {}; + + constexpr uint8_t BITS_TO_VERSION[] = {1, 2, 2, 3, 3, 4, 4, 4}; - return {}; + // Bits 2/3/4 contain both error correction level and version, 0/1 contain mask. + return {ECLevelFromBits((bestFormatInfo >> 2) & 0x07, true), static_cast(bestFormatInfo & 0x03), + BITS_TO_VERSION[(bestFormatInfo >> 2) & 0x07]}; } } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRFormatInformation.h b/core/src/qrcode/QRFormatInformation.h index 29a3f72e18..a560c62d33 100644 --- a/core/src/qrcode/QRFormatInformation.h +++ b/core/src/qrcode/QRFormatInformation.h @@ -37,10 +37,12 @@ class FormatInformation FormatInformation() = default; static FormatInformation DecodeFormatInformation(uint32_t formatInfoBits1, uint32_t formatInfoBits2); + static FormatInformation DecodeFormatInformation(uint32_t formatInfoBits); ErrorCorrectionLevel errorCorrectionLevel() const { return _errorCorrectionLevel; } uint8_t dataMask() const { return _dataMask; } + uint8_t microVersion() const { return _microVersion; } bool isValid() const { return _errorCorrectionLevel != ErrorCorrectionLevel::Invalid; } @@ -52,8 +54,11 @@ class FormatInformation private: ErrorCorrectionLevel _errorCorrectionLevel = ErrorCorrectionLevel::Invalid; uint8_t _dataMask = 0; + uint8_t _microVersion = 0; - FormatInformation(int formatInfo); + FormatInformation(const ErrorCorrectionLevel& errorCorrectionLevel, uint8_t dataMask, uint8_t microVersion = 0) + : _errorCorrectionLevel(errorCorrectionLevel), _dataMask(dataMask), _microVersion(microVersion) + {} }; } // QRCode diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index eb7c5c9b93..3d30b0f05b 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -1,6 +1,7 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +19,7 @@ #include "QRReader.h" #include "BinaryBitmap.h" +#include "ConcentricFinder.h" #include "DecodeHints.h" #include "DecoderResult.h" #include "DetectorResult.h" @@ -30,7 +32,13 @@ namespace ZXing::QRCode { -Reader::Reader(const DecodeHints& hints) : _tryHarder(hints.tryHarder()), _isPure(hints.isPure()), _charset(hints.characterSet()) {} +Reader::Reader(const DecodeHints& hints) + : _tryHarder(hints.tryHarder()), + _isPure(hints.isPure()), + _testQR(hints.hasFormat(BarcodeFormat::QRCode)), + _testMQR(hints.hasFormat(BarcodeFormat::MicroQRCode)), + _charset(hints.characterSet()) +{} Result Reader::decode(const BinaryBitmap& image) const { @@ -46,14 +54,22 @@ Result Reader::decode(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); } - auto detectorResult = Detect(*binImg, _tryHarder, _isPure); + bool isMicro = false; + DetectorResult detectorResult; + if (_testQR) + detectorResult = DetectPure(*binImg); + if (_testMQR && !detectorResult.isValid()) { + isMicro = true; + detectorResult = DetectPureMicroQR(*binImg); + } + if (!detectorResult.isValid()) return Result(DecodeStatus::NotFound); - auto decoderResult = Decode(detectorResult.bits(), _charset); + auto decoderResult = Decode(detectorResult.bits(), _charset, isMicro); auto position = detectorResult.position(); - return Result(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); + return Result(std::move(decoderResult), std::move(position), isMicro ? BarcodeFormat::MicroQRCode : BarcodeFormat::QRCode); } Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const @@ -66,25 +82,47 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const LogMatrixWriter lmw(log, *binImg, 5, "qr-log.pnm"); #endif - FinderPatternSets allFPSets = FindFinderPatternSets(*binImg, _tryHarder); + auto allFPs = FindFinderPatterns(*binImg, _tryHarder); + auto allFPSets = GenerateFinderPatternSets(std::move(allFPs)); + std::vector usedFPs; Results results; - for(auto& fpSet : allFPSets) { - if (Contains(usedFPs, fpSet.bl) || Contains(usedFPs, fpSet.tl) || Contains(usedFPs, fpSet.tr)) - continue; - - auto detectorResult = SampleAtFinderPatternSet(*binImg, fpSet); - if (detectorResult.isValid()) { - auto decoderResult = Decode(detectorResult.bits(), _charset); - auto position = detectorResult.position(); - if (decoderResult.isValid()) { - usedFPs.push_back(fpSet.bl); - usedFPs.push_back(fpSet.tl); - usedFPs.push_back(fpSet.tr); - results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); - if (maxSymbols && Size(results) == maxSymbols) - break; + if (_testQR) { + for (auto& fpSet : allFPSets) { + if (Contains(usedFPs, fpSet.bl) || Contains(usedFPs, fpSet.tl) || Contains(usedFPs, fpSet.tr)) + continue; + + auto detectorResult = SampleAtFinderPatternSet(*binImg, fpSet); + if (detectorResult.isValid()) { + auto decoderResult = Decode(detectorResult.bits(), _charset); + auto position = detectorResult.position(); + if (decoderResult.isValid()) { + usedFPs.push_back(fpSet.bl); + usedFPs.push_back(fpSet.tl); + usedFPs.push_back(fpSet.tr); + results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); + if (maxSymbols && Size(results) == maxSymbols) + break; + } + } + } + } + + if (_testMQR && !(maxSymbols && Size(results) == maxSymbols)) { + for (auto fp : allFPs) { + if (Contains(usedFPs, fp)) + continue; + + auto detectorResult = SampleAtFinderPattern(*binImg, fp); + if (detectorResult.isValid()) { + auto decoderResult = Decode(detectorResult.bits(), _charset, true); + auto position = detectorResult.position(); + if (decoderResult.isValid()) { + results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MicroQRCode); + if (maxSymbols && Size(results) == maxSymbols) + break; + } } } } diff --git a/core/src/qrcode/QRReader.h b/core/src/qrcode/QRReader.h index 1df4e8f2b1..e93a05afad 100644 --- a/core/src/qrcode/QRReader.h +++ b/core/src/qrcode/QRReader.h @@ -40,7 +40,7 @@ class Reader : public ZXing::Reader Results decode(const BinaryBitmap& image, int maxSymbols) const override; private: - bool _tryHarder, _isPure; + bool _tryHarder, _isPure, _testQR, _testMQR; std::string _charset; }; diff --git a/core/src/qrcode/QRVersion.cpp b/core/src/qrcode/QRVersion.cpp index 96a9f91fe2..0833b19340 100644 --- a/core/src/qrcode/QRVersion.cpp +++ b/core/src/qrcode/QRVersion.cpp @@ -290,28 +290,47 @@ Version::AllVersions() return allVersions; } +const Version* Version::AllMicroVersions() +{ + /** + * See ISO 18004:2006 6.5.1 Table 9 + */ + static const Version allVersions[] = { + {1, {2, 1, 3, 0, 0}}, + {2, {5, 1, 5, 0, 0, 6, 1, 4, 0, 0}}, + {3, {6, 1, 11, 0, 0, 8, 1, 9, 0, 0}}, + {4, {8, 1, 16, 0, 0, 10, 1, 14, 0, 0, 14, 1, 10, 0, 0}}}; + return allVersions; +} + Version::Version(int versionNumber, std::initializer_list alignmentPatternCenters, const std::array& ecBlocks) - : _versionNumber(versionNumber), _alignmentPatternCenters(alignmentPatternCenters), _ecBlocks(ecBlocks) + : _versionNumber(versionNumber), _alignmentPatternCenters(alignmentPatternCenters), _ecBlocks(ecBlocks), _isMicro(false) +{ + _totalCodewords = ecBlocks[0].totalDataCodewords(); +} + +Version::Version(int versionNumber, const std::array& ecBlocks) + : _versionNumber(versionNumber), _ecBlocks(ecBlocks), _isMicro(true) { _totalCodewords = ecBlocks[0].totalDataCodewords(); } -const Version* Version::VersionForNumber(int versionNumber) +const Version* Version::VersionForNumber(int versionNumber, bool isMicro) { - if (versionNumber < 1 || versionNumber > 40) { + if (versionNumber < 1 || versionNumber > (isMicro ? 4 : 40)) { //throw std::invalid_argument("Version should be in range [1-40]."); return nullptr; } - return &AllVersions()[versionNumber - 1]; + return &(isMicro ? AllMicroVersions() : AllVersions())[versionNumber - 1]; } -const Version* Version::ProvisionalVersionForDimension(int dimension) +const Version* Version::ProvisionalVersionForDimension(int dimension, bool isMicro) { - if (dimension % 4 != 1) { + if (dimension % DimensionStep(isMicro) != 1) { //throw std::invalid_argument("Unexpected dimension"); return nullptr; } - return VersionForNumber((dimension - 17) / 4); + return VersionForNumber((dimension - DimensionOffset(isMicro)) / DimensionStep(isMicro), isMicro); } const Version* Version::DecodeVersionInformation(int versionBits) @@ -352,34 +371,43 @@ BitMatrix Version::buildFunctionPattern() const // Top left finder pattern + separator + format bitMatrix.setRegion(0, 0, 9, 9); - // Top right finder pattern + separator + format - bitMatrix.setRegion(dimension - 8, 0, 8, 9); - // Bottom left finder pattern + separator + format - bitMatrix.setRegion(0, dimension - 8, 9, 8); - // Alignment patterns - size_t max = _alignmentPatternCenters.size(); - for (size_t x = 0; x < max; ++x) { - int i = _alignmentPatternCenters[x] - 2; - for (size_t y = 0; y < max; ++y) { - if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) { - // No alignment patterns near the three finder patterns - continue; + if (!_isMicro) { + // Top right finder pattern + separator + format + bitMatrix.setRegion(dimension - 8, 0, 8, 9); + // Bottom left finder pattern + separator + format + bitMatrix.setRegion(0, dimension - 8, 9, 8); + + // Alignment patterns + size_t max = _alignmentPatternCenters.size(); + for (size_t x = 0; x < max; ++x) { + int i = _alignmentPatternCenters[x] - 2; + for (size_t y = 0; y < max; ++y) { + if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) { + // No alignment patterns near the three finder patterns + continue; + } + bitMatrix.setRegion(_alignmentPatternCenters[y] - 2, i, 5, 5); } - bitMatrix.setRegion(_alignmentPatternCenters[y] - 2, i, 5, 5); } - } - // Vertical timing pattern - bitMatrix.setRegion(6, 9, 1, dimension - 17); - // Horizontal timing pattern - bitMatrix.setRegion(9, 6, dimension - 17, 1); + // Vertical timing pattern + bitMatrix.setRegion(6, 9, 1, dimension - 17); + // Horizontal timing pattern + bitMatrix.setRegion(9, 6, dimension - 17, 1); + + if (_versionNumber > 6) { + // Version info, top right + bitMatrix.setRegion(dimension - 11, 0, 3, 6); + // Version info, bottom left + bitMatrix.setRegion(0, dimension - 11, 6, 3); + } + } else { + // Vertical timing pattern + bitMatrix.setRegion(9, 0, dimension - 9, 1); - if (_versionNumber > 6) { - // Version info, top right - bitMatrix.setRegion(dimension - 11, 0, 3, 6); - // Version info, bottom left - bitMatrix.setRegion(0, dimension - 11, 6, 3); + // Horizontal timing pattern + bitMatrix.setRegion(0, 9, 1, dimension - 9); } return bitMatrix; diff --git a/core/src/qrcode/QRVersion.h b/core/src/qrcode/QRVersion.h index 2de4988e86..393bcbc0e2 100644 --- a/core/src/qrcode/QRVersion.h +++ b/core/src/qrcode/QRVersion.h @@ -43,33 +43,43 @@ class Version int totalCodewords() const { return _totalCodewords; } - int dimensionForVersion() const { return 17 + 4 * _versionNumber; } + int dimensionForVersion() const { return DimensionOfVersion(_versionNumber, _isMicro); } const ECBlocks& ecBlocksForLevel(ErrorCorrectionLevel ecLevel) const { return _ecBlocks[(int)ecLevel]; } BitMatrix buildFunctionPattern() const; + bool isMicroQRCode() const { return _isMicro; } + + static constexpr int DimensionStep(bool isMicro) { return std::array{4, 2}[isMicro]; } + static constexpr int DimensionOffset(bool isMicro) { return std::array{17, 9}[isMicro]; } + static constexpr int DimensionOfVersion(int version, bool isMicro) + { + return DimensionOffset(isMicro) + DimensionStep(isMicro) * version; + } + /** - *

Deduces version information purely from QR Code dimensions.

+ *

Deduces version information purely from micro QR or QR Code dimensions.

* * @param dimension dimension in modules * @return Version for a QR Code of that dimension - * @throws FormatException if dimension is not 1 mod 4 */ - static const Version* ProvisionalVersionForDimension(int dimension); + static const Version* ProvisionalVersionForDimension(int dimension, bool isMicro = false); - static const Version* VersionForNumber(int versionNumber); + static const Version* VersionForNumber(int versionNumber, bool isMicro = false); static const Version* DecodeVersionInformation(int versionBits); - private: int _versionNumber; std::vector _alignmentPatternCenters; std::array _ecBlocks; int _totalCodewords; + bool _isMicro; Version(int versionNumber, std::initializer_list alignmentPatternCenters, const std::array &ecBlocks); + Version(int versionNumber, const std::array& ecBlocks); static const Version* AllVersions(); + static const Version* AllMicroVersions(); }; } // QRCode diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 44ed865b2b..05a87bad2b 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -54,9 +54,10 @@ enum class BarcodeFormat QRCode = (1 << 13), ///< QR Code (2D) UPCA = (1 << 14), ///< UPC-A (1D) UPCE = (1 << 15), ///< UPC-E (1D) + MicroQRCode = (1 << 16), ///< Micro QR Code (2D) OneDCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, - TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode, + TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, }; enum class DecodeStatus diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 9899cef628..cca643fbd0 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -620,6 +620,14 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 1, 1, 0 }, }); + runTests("microqrcode-1", "MicroQRCode", 16, { + { 15, 15, 0 }, + { 15, 15, 90 }, + { 15, 15, 180 }, + { 14, 14, 270 }, + { 9, 0, pure }, + }); + runTests("pdf417-1", "PDF417", 17, { { 16, 16, 0 }, { 1, 1, 90 }, diff --git a/test/samples/microqrcode-1/1.png b/test/samples/microqrcode-1/1.png new file mode 100644 index 0000000000000000000000000000000000000000..35c855d0d795380bf539cd29a05ce54fbe9a16fa GIT binary patch literal 8513 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 literal 0 HcmV?d00001 diff --git a/test/samples/microqrcode-1/1.txt b/test/samples/microqrcode-1/1.txt new file mode 100644 index 0000000000..121eab0377 --- /dev/null +++ b/test/samples/microqrcode-1/1.txt @@ -0,0 +1 @@ +Wikipedia \ No newline at end of file diff --git a/test/samples/microqrcode-1/11.jpg b/test/samples/microqrcode-1/11.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bfff33fbba145c21e8fdf08ec13fe20102b9d204 GIT binary patch literal 29581 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 literal 0 HcmV?d00001 diff --git a/test/samples/microqrcode-1/11.txt b/test/samples/microqrcode-1/11.txt new file mode 100644 index 0000000000..64209c1239 --- /dev/null +++ b/test/samples/microqrcode-1/11.txt @@ -0,0 +1 @@ +Loser \ No newline at end of file diff --git a/test/samples/microqrcode-1/12.jpg b/test/samples/microqrcode-1/12.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4724b6c948f5887d7262cfad1e7191360ab318a7 GIT binary patch literal 19328 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 J#7O@D|JjxW2Jip? literal 0 HcmV?d00001 diff --git a/test/samples/microqrcode-1/12.txt b/test/samples/microqrcode-1/12.txt new file mode 100644 index 0000000000..7d3298dfa5 --- /dev/null +++ b/test/samples/microqrcode-1/12.txt @@ -0,0 +1 @@ +SN888623311 \ No newline at end of file diff --git a/test/samples/microqrcode-1/3.jpg b/test/samples/microqrcode-1/3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9a984ddc0947b00355acb80a17e393f81a60d5f4 GIT binary patch literal 27818 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 literal 0 HcmV?d00001 diff --git a/test/samples/microqrcode-1/7.txt b/test/samples/microqrcode-1/7.txt new file mode 100644 index 0000000000..ae75576b8f --- /dev/null +++ b/test/samples/microqrcode-1/7.txt @@ -0,0 +1 @@ +Victus \ No newline at end of file diff --git a/test/samples/microqrcode-1/9.jpg b/test/samples/microqrcode-1/9.jpg new file mode 100644 index 0000000000000000000000000000000000000000..682f4d11f3a182f5336dc7b412cf67404d58e3f9 GIT binary patch literal 9245 zcmbt)bx<5k^X6hfU)3Q9{@v^U2of?nD%vXyl$T`y#(&4J zC;-LH12G^j5;PPpc}flpr2Ad=eC^NVMyhh`EM$~}Q(%m;r*cQuHxwqIus(V$1_1@; z3dT76CwJ1T8@iKSiCj@aV=k=vuy7Wv2*5~e-$i}>jemQCMPUH<010xrO#Kpu9v~eK z*q-lr0Za!+7XJ1p`u?Lyk0jO+FQ%&crYlquO&tU0aNS4 zFlt=Mh_xa?veG!a*DnBtqZ}oe=k;LwjKCNMsgahJoKAOHT0XTS?6~a)Z|n(g*8XHY zS0aazu*!ylF^#}N*$_$Rd-3)zjPr0^@@jiN5N)H;ukbHotqM%Ys16XQlJXXEYSwj- zU|#aLo-a+8-LklgF9+pDBSunYFr0o5IW;EoJ>>Sh_71+9gcg4V#g-_u7p7=V-*0Qb z*Cl~mI*+#&1Q<-4p6%}bUXL2WN3JH&b~33$Q0dyZX!eD6Z@7t2)1sq<&RkSr54E~< zzzQU2I`WE_%+n)#2UOXc9w)mC?9zLkJF2Tia&A3VZIh?Wc#!T)5b6EXM!!FpcTGLh z>7nW@xjJ5JW=@lD>kk089ibhPQKM_ORX>coVA~hh?dJQMuQ4@y9$dMjN<3ZUB}>0P z+aah3cYpmkO@9*j(`*oaR0#V#p!Zu`KBes2f-#-D&E*Rq^5W%*U|#KBb4Sudi+f;RIP8FS|D7ZCz4=?;e?;@@ejDAEuC0xk9qOG) z#T~U*dzZK@F8c&@9r@L~dc5e6K0JKGHrf@YEzNe^A^F@jO=|oL@d5~&kyiA60q{U> zy<6`6&z&TH?lnfKjy!xCJ>Ytdxt4l8;go2#&nunYzbfIPn7hz9>mAgv?}E4Aed@EC zJG)Wr+JAGP!9ed|hdr}^E-AZAvTm+a0UarrH?Q1-~0D@0i=>$O7_hXF+GP+$S-m0~{ zuE|bU?jLn+E(RGlowkZD()LweWa6f~Uq2LG`TNgEuqOVx?Gmm(c*?Us5SMrX(0G=2 z7F~7NqDP=ielhvK)B^vN3QQD*j-s*Pm{}J8#-Ia7ARNH(>Rn)n>#w(|$VBSAA zfB#J4y=sd)%RhR1HS`+`D3EN--mLKgI5>e++)+mPKAp5Q52idSncGW1IN4~&uvy>& zSg+)I(<)JZxZdvf9k=B2HeLKNn11Ne-i}cnU@t3on6^^|vjgGc(zc5ptt)H6!dVZQ zQHE+929bKCTt)~kwH-KklpT&KHGAj&)z4|Gg>eAGY}^Jc&m$C|P9=KWq}Ez+ ztV$ME86pyvO$D21Zfyyua!*fzDoC54F)>zEr9dN6qE-JIOLC7$>>o3VdUzQG!LnG)jfECW6$sqUkrNmt3^ z{cHD@A1;P#ttfN#8YX{;(id%OS+8a(PR4YEk~@>fU}|lmD;g=P<<_tea|MiaV=Pr{ zREY8qKYS!vQq*E@L}T|Mgw!1CevhMX=&8EI-}obR;uueEcn?uSY(jroK?aREcIX(G#10yn99^{08mvH z={;d6F}O~S1dxWRldLmbhRQ(-T*6YdCJt|HRDG2?K=Rt)FQ&Kn03;L?z$>&@IH<2s z{^uM4XaukD2^sjci5LZBEr^-;|qJn{NJx5 zk~Gqd&rkzkptv`|%qWRRI*pt|_^fVT03{KHI|x z2YujF7}5)UoPAK>cD!O>S4zCnubhGN7We>awuHA z*1tWlJSp>pJ?h4(+Ud->5xzFStju6gWve_&G^*bJV8!;>WOA`1AT?Q+k$lB`?Z`3C z0n%nM9=Y%Cp*%@Zi(%IgwhcrIL9-{`0>mcy9XNzxrv6x_Y>fHyrQA`n;WxI@mn9pG zly8|3e+-?;iq|^p;22!7TEipc#vod-HM;RgAJUJ??W!?fzNkf<{#O_gI}Pey`eIO=g?ZA^p-4&C6ZN!29k*yPY?t z|G7Q#oomKKnO08P28ifP2$xBl5<})T*V8TY3nXoG`zVRh^9LA)@Hh-SCP=tr2(?15kSd&1A2Y|D-TA4R`p)NUP}-1nQX6svE$f^B%vp zLAT%aahPFx3f?H0BWz3+c&%p2ee6u`%dy%$V`>pVtF*6b`MP{3&-?UBc~FHhY}&I-wS=c!wx=5x`jp-7Zw4@ffrO zL1Rm~&J;=F+xq5dPj>YJ2yq-KVO6n`BpOv03T_b|kPUi3m}S7`3>Q6aE2|4y*>w}* z#iWgNKwurki!0*hCTeCvd*|xT8Rh$$c((hdz?6z@I3M>c3B}%mGPQzmiN3-G#QsTe zEp_onuVv7mxwz`4z>EaC&af%nM&dWVdo54K4-M{a?jWV&>6Lrn^FlSV=0)GH0BiQ* zFp*FC<(&rPM9Z3#Gvq4RYH10hCw^)H%1-Dz&C?=SLbS|2!&)PwMjMSF!1Ul{S zdK>LQhqN?{m05wzWV1;IUf=w%P0PNED^)C>m0tTXI9)5qnh73*oO_`-1Vcu|TE*pT zKH}wKDolk-T+FqHww@p;Bj{$$Ow&6mAE!mpi{xG(BfG8V%&L<$}}`Nf2&wclv*XNrN9B&DXONWr<*Us=F^qjUSPre<+Hn*4m1QU+Vq!Ws@Cvb}cnNsFvReig|nN#f!o~G8;PHA!A2?O&Mo>Ub z!+KM#(iTAm+FNg=a$5}T9nQCDp8~Rv7SJ7&I%|w*V=mWIGq!oCw+igQUmA+OSu-fh zT{@~JsRoDq2$S~v>=BAuKL_i@iqg-W#ukj=UTfhLH%=03FtKTHzhhQ>rl<<9N_ece zFN|#+2d8jadGW_i|9qVuef9={Jo+PN&Udzyr^UDIK``NWQ8z}^iNlQI6((@V#+-8A z6XkOXB-)lHQ)?$dciB464f0i@#$D$2bba1skf7iPZ z*T0qEFC$FFIIVQ*A5A1VM*387OI8xCkN%Ftrm2iw*(WeXW7r}mH>Eo}XDQ$AtnxDr z>X2?c&gqY$^6&7RT+F$5uJA)iCo8>YE0=Pd{QdW5^G;1XI$X5tVl_x{D)wBa=l(Su}En$-I=DdmG zVFz&#q%Q<$-87br&|B|zXyA2OnRuouJ0q`*_nT$k=NMl8n?k$IdAF4>3o2CzqPLpEdyUo?p zO5&+28mvjvuAh2?%PWKTA|jM2PB6OW=^-%(@rgr)H{`t1j7?0uhL9WTAGGYs@C11tc$~E%WY@4yST2vc{l&jOP)6+_m`BujSMx7br z#+_W`nq~cK%uyQx`D%dJyw|sY*Kg>)9NZ|AKOUT^ay`x>(RH#mSX`ta9n9*u!=kRFK&N=?pT@!RC>97-c`lZtr&Itkw`*m*sO~yw zSu<-8iM8mBkwx>!i1J`1G~>`+>}^{zkR%32gc{;+?d`zCL?YFDvkap{W1BxK`Gr7Z z#|=peG=7iav@L4XlH;8fZBaOiXBwPeq|G8qveULs@Gz&Et-`${LRfSCS$#bEC|2vi zofA@8DwD7b0bFXn066@Vr_8lei?7CC7vmeW8Y@c)&fU3sF*9A|=lc(qQad-EaLY1f zR7Tu4!qo@Yf^uwBJ(yELWjII%UM$kCzAdqRL!q1c7_-|l7}*`Af3Lo`-Vt}K@ppvi zDhx75Q7T9|;|>3zYhe7a8t!b7j6d2ecmHb+ecQOvQZNSRBqVPQu5hPtX81n0y=+)4|4~2Z#%i44K4^=B(6*=$%#e);WK^fgIG;pzOw| z^NNQSmvPX4YMGrB?6YyHVv!PJu`@m`N9O=CJ2Zal6G$~vroTEZPD=~RC12IqQ;JSN z7$nMnn;+cywcnh$gF70;Oi?2rAd*Y7-CMM3A(bpYqO#+yi@;E4112X;3PHNAW4H%~ zCrKzlb5Jzq-=Px@t8Ok<9LK)hVtx9rJYtQemO<(H$>QUtt_puj3|H3uTIa+YTXMj) z_H+v1wN%6(<$nJJ;b25%Bb;fCgA7B%%ev@lK>1tG`+$<=R@UM*n{VevB-7#N$VG?j zOZ}0ED|I1Xgy^65pGS<#4MZ?0F2lhc^cE-tgUhYC#9803+YvMSkD6Hi${)BzWIz)3 zjyfYci7Iymw;|o0hPMmTKQciJIh%?R6Mnj(EIy^yQfH$gaQ}(2PY$}6dt1SQ1}}gJ zRJtcGKj*qWsL=;|?H0b3!TD+0X^v{%!)br{o>ZL~-P7X3t1M<9{$qmCuNhZY6>e@0 zj$_x0%8nz3`jW+j8fYP5jj2)n$^x|maXGWB!6;jAcAec__--%jbF?!X)@s^9{JL3d z{Y9#g3MfR=tMY!JDTq_~dfcqEzS|y~oaSy_Q#o)OMy)d$a~E&Q#+Q@6&LGh;J3|}j z?^0E6CKZFowwHA-gUfej&Zux`nqp}0_h!$$Q~EkX^e~q(Q~cBre&_8tnLqxa;ZVSH z`EwH_R=VqEzS!f`E%SYkt+Rru^U|uk8gD{C72aKn?sdyWTyyA?%i!)9Z!x($Ye4&JJ2)IR}MZ-V~`AaKHE z>F;ymW`hivIC&k%&a`qnv*Vy-ddP8&ZqBfsRVv00Hi2|c#F}hGdMeYSMn3c3b5AV& z)Q4y_%54n{3PzdB%|z^6%@>beK|XHk8OF7S7LF0OB1a`{|*^t&+WR_9|z z;@#NOp_qcJg#4$|g1~0FV}di40?+2k@W!CIj1-bydD{ytY`GS8x|rgjNhQsjygYAz zYHF>(>l-t}CvaBy^?BOaW0{$Y{R==q^BWeF|K1U_rmsxCnUr~2^xM!&yz6ZF`Rq?I zfR=5E9&32FQfl$^KIP_L=bRP)Z}b)!3H5IT7w{iH_HVqI0H1-MURE1o5z3cRS1`SK z{(oFm{Hs`~gw>>iZLo&;nUrm|E9E4SVFPZ!$E!P%ES7+MCB17F+rTj7-aTL4Drfr)kdM*Ce&?Bl>lpti z@I&wQabcTK@{ zt{*Su6LKKvXia2fy4r>C(vwEd^ljDID_+34hI0k05Xio9Zcc2Y*vG|(iw>8!GB;5y z*Z0YPK>Zd{WhQmu{y?GObJ$u_k#kCZ7LviUhKyfR;6xo*)OJp={Zpn5z1Fkh!XNvM z(w3>Mdz<)`pddEVg1rX*KAD{bvWJqkE!Ef>E}X9K#?4&(LBuq5MT4|+EZjyZ^1XMH6y~LhZkr$0G_iSn@!_t&d09hyxtN-?~`gAUw6NFw^=v)VNvjDPE z3p}QN4=~V<`$XP}S@wRtNCH|@E|pT2fAxeE2hAA|F`Kc#z{r;j=a|NTx-}-M1d2jN1bF8c41FU0KUBpFS!n%w60#kR*@e^Bc zMtM6(QExrcaq`^8JPuZdyVF6L-p|4`{-w&R{rIf4by9}+AGD$JJWTB;skURz4t36G zVN)yh+d5;!8Qn-c@hBJL7y3FPx_7G!$}L@y1yW>KRKsJ!Jg*N>ZDKgf;Z%AW6h&NB zYq%*wj!SjgV9TD-0 zXC9PHAL}h%>F-{5tkpE9u5O@gUsa*jju_}0kbWCzJ!1cenNZ?Qx zmNf*DK(e|msZ-umFiyeJSucME>|9}X=<1WTUzJ_Fc_xXt&^ZpSzZ3K=e^y8hrjQl< zhd4@kufo3d!=pocuI)td&ysb~s*1#mP8{V!3>=h5rn%3Y7FPCJdKOcP57?RgF`C0x ziMmLTHr^(xFo)F7J5kwG0&`O2L?2+S1Ygwy!Z*v89cc&)Y&M)3OY7=%3LYs@Mh8Qs zKDe`Iz9Qhd!Hdyy|5vNRAQh#wU=|}#?<#lg< zG9*yy1Or}u7}uula{|{^C3N!8Uc9qCJ*A>&XUa+|?UnKRWYL~$dS0mKyExj(T0z(q zPRa;QVA48h_snA=q-7I!Kj-WiyUEsMiE@AlLJHPHBO&0XU$8tOA@YPu@*u&eJ#E0I zKV78mN6{BRLvv>XG$f3X4~cN-%kEVW@z@?}o%3pWIVg@qivOb}4>#XK^N(mkyb@%I z8^!<)EA|Upem3I|2TbM<84}f*nS8xD?aEk;A@QqeSB%v^$Mq?u7;B2fO@m?-Os^Mw z2b6SU#%I4nZe9SG&O5x?l2137i<;2U9tY{B%v40a2*az0tTI%^)WUmsX-ce(a|_9o zmQplJ>H*kwG+(?*p3+(Vv==^Wy5z%vz8Uph?=m1|20S9@>|F-5?QGw6WSLf|LZ+{}1E)K1!Q+8|#wa#qxt z6B;?HLX7&v!)FIF$po>~0jh{6`mqRKpns2WvkSDJl7 z%>rN0SY~}N0aA``AZYnptRXT#$7X5%--O6!wm~c}fEpf>0IJozUw-JTLv6K>YZmgl z{GdH{@K@lSi-31x5pA29oQiK5cid1~yM>z$rW0kwoS|mO(VNvC7ZY7#R84H0JPjW1 zU`N$FJn1#6P}7`#0^Oz*7ST3SEAK-CA-Y)cGweU7z?n`0vIx~m;6b}`+^_{TR&T&r9P+z;bYTfP5a2f?3l=o_Zac&6{V}O(4aLAUsub?IE_Q9Ei#frg z8=cOQM>r+SBD4(g&8^q)C$8Fs$iNuZZ~#dlcCVnrH%PHy^sdGTy|s@j%xN&AB_i$C z@DRmJb#EiP3e01rf=lDxBfEj&6%f2hC;=M01iN=KkhUq3w^(l6ed49_X@?DI(nuS+ zUO2J_dOpwwPrsjB>t%3Vq%0!T>4p;y1hu+W`$R?Vm22I%I=kJF^-aH{UTHvY4Scgz z7fkq2S$RriU$w4DaW%b|=iX_R9M(5$!zbiDpV|?~5fpR4r@Iahe=dV7v5mg~+)Iz) z&)!8zM7lrnZZ>-o{dgr;{`pdq$Fi5i!(p@y8R)?;YlP9ym5+M-A z+F$uCSr_C!*Ls{W$YbJhoFBP788f7kb+BF78l{<=tKMQ`(`o?wXUG5J(;6_)Q|e;1 zr%IUmt_plM?fcEK`fwj|#Fhie+G-e5e6Tz4*yG)}R^{I!`B_-u8;93Z{(Js+&V>fv*tOszemTfx}Xv; z!N%+l_MFyP&We&n&&or!6=fR{+NZjZ!f~OoF6Q2Hqy-WkdC=CDdFo=;AX@si9G16> z5GvC@DTi7lN&3(FyT0Iwm1Q<~{LGqYYoFV#?)N040%-oK?W-j^Lsz+)u{x&OG5}e1 zw1TQtZGC%_ZMm5KxfUB6k@)%_FF{xu>VxFd5Ba7qa4nd{{76zDMJ+Xj52&*BiAYHOC01tiY^gPeI^lVIP>6oL&R@`A;UvFSqoE zv;DU|o59w*^IKdDBMi+;*FyLT0z<#@7HOIEb_`4ICBoCO#ueV6p5ZszO)m+UdByru1g$&`d_lLS~ bjOk@xqA0r3wtBTU&TV8Fw2fPE|5`cDh4Ex5`msjynYrXhIGB5l5m!ns{$!9PF#HMa^gS=^N! r&=BtEZ@MgaZH<<7`s%N2A-@^inAIGG%=Tyljb!k2^>bP0l+XkK5>ziW literal 0 HcmV?d00001 diff --git a/test/samples/microqrcode-1/M2-Alpha.txt b/test/samples/microqrcode-1/M2-Alpha.txt new file mode 100644 index 0000000000..48b83b862e --- /dev/null +++ b/test/samples/microqrcode-1/M2-Alpha.txt @@ -0,0 +1 @@ +ABC \ No newline at end of file diff --git a/test/samples/microqrcode-1/M2-Numeric.png b/test/samples/microqrcode-1/M2-Numeric.png new file mode 100644 index 0000000000000000000000000000000000000000..ea9810f9fb070c7caa238776a53f4653a33f65d6 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^av;pe3?v!<**pYNYymzYuK)l42QotsU9JOCuAVNA zAsp9jk8I>*Fyvu&XuQq7Ua3I(!>cx(ln)F)om9eQK0M*niki};n7=wdtZQ0GcXEFyLWvXpCwM6RgSpag|w4VYS2^wkNMT*IR7nmcHcXEFyLWvXpC+Ss|?Woag{lfH_r6|KthUPb(y!<)X#?eof= y#Tmwayt<74`hZOx?BgOVm)0P zLpZMc9@)rwz<`J40Q+{P^`91mJ-Eu6$s6Z7!R&#_`w7~7KO}F@oyB|oW`0ENclP^h zjAyHUyt<74`hZOx?BgOVmw_O zLpZMc9x>!$rKl{(#``$VCopfG{`@ zl=pBBKzzM;(DXP@I>^)UPiehZ@2f&9nfQlB6E4BW{Gna-2a1MCrzjnkl&NS>363gd zfuFCkA^>mjHx(feAr! zPi%fb!5QVONUMZ<{m*RZm+TR9AZPrXIjrJ4Zn82GfItBd3In0=uP<;z2%HB%i6TYB zFbd)tM!aYoLF?P6fP%p4l>jv&!|=0S$I$)Ysvf8I`;au@hGYY~;C6`)&|aBs);=K^Bu?RfvJW6gy+kE@Jx zQu-nJM&({bQ~dhd{b^1n**6mrA00z#%YyqdNEZKPqx}1Fu(Zz_%7geOoG*BX7B~o-Cv@h*jo` z&daRo(y%kO5wWgB_K2_N=g~`qVP%SFI~ArIvP)j0*Ll9Bu0Bv&e19n~=QJ~PB*`aM zoRT++#MJNelbjia36h_M5M4QNhFo$nx06iw>9QKh zg0ondP2FfYG4>Pp?NhK%?IUaLlLEGs8U^v+E;!v%?NS`m>FEtPPKhx+`-y#EGg&y( zEi>^t-+x0<*43$nUo>uJ&+nk*Z>!yEEj#p@ZrwE%dOt~0Tkc}I5y3VX81b`@uK{6A z`8m^tMVoPIa?95{%i$!Rl;Sm3Q=LhZyhP5db@`W><1T z2)@I(EP)QGKDjn)yhq}q`W?<}|QDm$geig1O{@6>ch zxW@{F1|D^k9;toB3l#q(K$N;!^L^f>bk#9|+J!@4i7>VQ)ZqwoI?wsIM=qH#;N7mi5vMDs>A>+N>3vY<%0@nO6@4HPn%;^bt0znk?rn(qgt5 zhdUT#lW$*Jghti5W%-9@YnA&=35oYmQUf{#J3bc8**HfN1qv=>+PtO_0X!$?`rBP3 z!icsJ&R4Fz;b8dLN{g;#Uh5nBvZ1!QA<=i%IcuT~H1&?z+LN%x)$O3dIG6n}=wo$# zx9K6yK+@XB;)1Z+VRlkj(thKoc)Q*W-Cutzp~sZjtZ&UX{iBVN^LAL+mpJwS%a-6{ujoN&tzL{j}x z)xq()ou%xVx7-OAGIla~n3_H>OW~)%C<)C{cLhG{ZIk?uD^~|Xg8)7Lh-hmDAnJhyko{CP2(h_0G$z(l-E^e9IkUO~h zVay@`wqgT-F5|o%0D9C>6H<}nvFslj9U;$WTrp4MX%xeagsf;D8LV&X^U!Yipm&5_ z9l{@F0D{R||`og7I(U-sBoh{3y-%J|B%A-#MZuE!e3_3 zbQYLmnkLWSb7A$@oBJF6A!fzP zyKzljQyGCjbM>4U35VSh-R&zcaAcFC3vMb_J8^o`vohb@;7*?`3V=YM|0Mz_5Q9`8 zXxM$#0T46*SVQC!CVIoN@`%-isciYsPSm$buF(CbdVnY-MnS{K=SwBGsR7_$q=jQL Us3OC$@&&u8O5s|128Xl%1V(o;jQ{`u literal 0 HcmV?d00001 diff --git a/test/samples/microqrcode-1/MQR-needs-br-update.txt b/test/samples/microqrcode-1/MQR-needs-br-update.txt new file mode 100644 index 0000000000..222d0af5dc --- /dev/null +++ b/test/samples/microqrcode-1/MQR-needs-br-update.txt @@ -0,0 +1 @@ +Micro QR Code \ No newline at end of file diff --git a/test/samples/microqrcode-1/NoQuietZone.png b/test/samples/microqrcode-1/NoQuietZone.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a917df87544f92e8df693a4db88545e5f77839 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LI=AJH&Asp9zPwnJA;2^+s;NY!) z(Z>$XlV@rjb`qD^7Qx*?d@M!N-Yae-&>9U-synmwuM_UzjN0{L9zXKt_4G L`njxgN@xNAb>Ap^ literal 0 HcmV?d00001 diff --git a/test/samples/microqrcode-1/NoQuietZone.txt b/test/samples/microqrcode-1/NoQuietZone.txt new file mode 100644 index 0000000000..bd41cba781 --- /dev/null +++ b/test/samples/microqrcode-1/NoQuietZone.txt @@ -0,0 +1 @@ +12345 \ No newline at end of file diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 1c33901a39..57f1dfafd0 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -45,6 +45,8 @@ add_executable (UnitTest oned/ODUPCEWriterTest.cpp oned/rss/ODRSSExpandedBinaryDecoderTest.cpp oned/rss/ODRSSFieldParserTest.cpp + qrcode/MQRDecoderTest.cpp + qrcode/QRBitMatrixParserTest.cpp qrcode/QRDataMaskTest.cpp qrcode/QRDecodedBitStreamParserTest.cpp qrcode/QREncoderTest.cpp diff --git a/test/unit/qrcode/MQRDecoderTest.cpp b/test/unit/qrcode/MQRDecoderTest.cpp new file mode 100644 index 0000000000..47ebe2ef73 --- /dev/null +++ b/test/unit/qrcode/MQRDecoderTest.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2017 Huy Cuong Nguyen + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "qrcode/QRDecoder.h" + +#include "BitMatrix.h" +#include "BitMatrixIO.h" +#include "DecoderResult.h" + +#include "gtest/gtest.h" + +using namespace ZXing; +using namespace ZXing::QRCode; + +TEST(MQRDecoderTest, MQRCodeM3L) +{ + const auto bitMatrix = ParseBitMatrix("XXXXXXX X X X X\n" + "X X X X \n" + "X XXX X XXXXXXX\n" + "X XXX X X X XX\n" + "X XXX X X XX\n" + "X X X X X X\n" + "XXXXXXX X XX \n" + " X X X\n" + "XXXXXX X X X\n" + " X XX XXX\n" + "XXX XX XXXX XXX\n" + " X X XXX X \n" + "X XXXXX XXX X X\n" + " X X X XXX \n" + "XXX XX X X XXXX\n", + 88, false); + + const auto result = Decode(bitMatrix, {}, true); + EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); +} + +TEST(MQRDecoderTest, MQRCodeM3M) +{ + const auto bitMatrix = ParseBitMatrix("XXXXXXX X X X X\n" + "X X XX\n" + "X XXX X X XX XX\n" + "X XXX X X X \n" + "X XXX X XX XXXX\n" + "X X XX \n" + "XXXXXXX X XXXX\n" + " X XXX \n" + "X XX XX X X\n" + " X X XX \n" + "XX XX XXXXXXX\n" + " X X X\n" + "XX X X X \n" + " X X X \n" + "X X XXXX XXX\n", + 88, false); + + const auto result = Decode(bitMatrix, {}, true); + EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); +} + +TEST(MQRDecoderTest, MQRCodeM1) +{ + const auto bitMatrix = ParseBitMatrix("XXXXXXX X X\n" + "X X \n" + "X XXX X XXX\n" + "X XXX X XX\n" + "X XXX X X\n" + "X X XX \n" + "XXXXXXX X \n" + " X \n" + "XX X \n" + " X XXXXX X\n" + "X XXXXXX X\n", + 88, false); + const auto result = Decode(bitMatrix, {}, true); + EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); + EXPECT_EQ(L"123", result.text()); +} + +TEST(MQRDecoderTest, MQRCodeM1Error4Bits) +{ + const auto bitMatrix = ParseBitMatrix("XXXXXXX X X\n" + "X X XX\n" + "X XXX X X \n" + "X XXX X XX\n" + "X XXX X X\n" + "X X XX \n" + "XXXXXXX X \n" + " X \n" + "XX X \n" + " X XXXXXX \n" + "X XXXXXXX \n", + 88, false); + const auto result = Decode(bitMatrix, {}, true); + EXPECT_EQ(DecodeStatus::ChecksumError, result.errorCode()); + EXPECT_TRUE(result.text().empty()); +} + +TEST(MQRDecoderTest, MQRCodeM4) +{ + const auto bitMatrix = ParseBitMatrix("XXXXXXX X X X X X\n" + "X X XX X XX\n" + "X XXX X X X XX\n" + "X XXX X XX XX XX\n" + "X XXX X X XXXXX\n" + "X X XX X\n" + "XXXXXXX XX X XX\n" + " X XX XX\n" + "X X XXX X XXX\n" + " XX X XX XX X \n" + "XX XXXX X XX XX\n" + " XX XX X XX XX\n" + "XXX XXX XXX XX XX\n" + " X X X XX X\n" + "X X XX XXXXX \n" + " X X X X X \n" + "X XXXXXXX X X X\n", + 88, false); + const auto result = Decode(bitMatrix, {}, true); + EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); +} diff --git a/test/unit/qrcode/QRBitMatrixParserTest.cpp b/test/unit/qrcode/QRBitMatrixParserTest.cpp new file mode 100644 index 0000000000..1eea005bf6 --- /dev/null +++ b/test/unit/qrcode/QRBitMatrixParserTest.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Huy Cuong Nguyen + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BitMatrix.h" +#include "BitMatrixIO.h" +#include "ByteArray.h" +#include "qrcode/QRBitMatrixParser.h" +#include "qrcode/QRFormatInformation.h" +#include "qrcode/QRVersion.h" + +#include "gtest/gtest.h" + +using namespace ZXing; +using namespace ZXing::QRCode; + +TEST(QRBitMatrixParserTest, MQRCodeM3L) +{ + const auto bitMatrix = ParseBitMatrix("XXXXXXX X X X X\n" + "X X X X \n" + "X XXX X XXXXXXX\n" + "X XXX X X X XX\n" + "X XXX X X XX\n" + "X X X X X X\n" + "XXXXXXX X XX \n" + " X X X\n" + "XXXXXX X X X\n" + " X XX XXX\n" + "XXX XX XXXX XXX\n" + " X X XXX X \n" + "X XXXXX XXX X X\n" + " X X X XXX \n" + "XXX XX X X XXXX\n", + 88, false); + + const auto version = ReadVersion(bitMatrix, true); + EXPECT_EQ(3, version->versionNumber()); + const auto format = ReadFormatInformation(bitMatrix, false, true); + const auto codewords = ReadCodewords(bitMatrix, *version, format, false); + EXPECT_EQ(17, codewords.size()); + EXPECT_EQ(0x0, codewords[10]); + EXPECT_EQ(0xd1, codewords[11]); +} + +TEST(QRBitMatrixParserTest, MQRCodeM3M) +{ + const auto bitMatrix = ParseBitMatrix("XXXXXXX X X X X\n" + "X X XX\n" + "X XXX X X XX XX\n" + "X XXX X X X \n" + "X XXX X XX XXXX\n" + "X X XX \n" + "XXXXXXX X XXXX\n" + " X XXX \n" + "X XX XX X X\n" + " X X XX \n" + "XX XX XXXXXXX\n" + " X X X\n" + "XX X X X \n" + " X X X \n" + "X X XXXX XXX\n", + 88, false); + + const auto version = ReadVersion(bitMatrix, true); + EXPECT_EQ(3, version->versionNumber()); + const auto format = ReadFormatInformation(bitMatrix, false, true); + const auto codewords = ReadCodewords(bitMatrix, *version, format, false); + EXPECT_EQ(17, codewords.size()); + EXPECT_EQ(0x0, codewords[8]); + EXPECT_EQ(0x89, codewords[9]); +} diff --git a/test/unit/qrcode/QRDataMaskTest.cpp b/test/unit/qrcode/QRDataMaskTest.cpp index 4f55545f7f..e71387ce74 100644 --- a/test/unit/qrcode/QRDataMaskTest.cpp +++ b/test/unit/qrcode/QRDataMaskTest.cpp @@ -26,17 +26,28 @@ using namespace ZXing::QRCode; namespace { - void TestMaskAcrossDimensions(int maskIndex, std::function condition) { - for (int version = 1; version <= 40; version++) { - int dimension = 17 + 4 * version; + void TestMaskAcrossDimensionsImpl(int maskIndex, bool isMicro, const int versionMax, const int dimensionStart, const int dimensionStep, std::function condition) + { + for (int version = 1; version <= versionMax; version++) { + int dimension = dimensionStart + dimensionStep * version; BitMatrix bits(dimension); for (int i = 0; i < dimension; i++) for (int j = 0; j < dimension; j++) - EXPECT_EQ(GetMaskedBit(bits, j, i, maskIndex), condition(i, j)) << "(" << i << ',' << j << ')'; + EXPECT_EQ(GetMaskedBit(bits, j, i, maskIndex, isMicro), condition(i, j)) << "(" << i << ',' << j << ')'; } } + void TestMaskAcrossDimensions(int maskIndex, std::function condition) + { + TestMaskAcrossDimensionsImpl(maskIndex, false, 40, 17, 4, condition); + } + + void TestMicroMaskAcrossDimensions(int maskIndex, std::function condition) + { + TestMaskAcrossDimensionsImpl(maskIndex, true, 4, 9, 2, condition); + } + } TEST(QRDataMaskTest, Mask0) @@ -78,3 +89,23 @@ TEST(QRDataMaskTest, Mask7) { TestMaskAcrossDimensions(7, [](int i, int j) { return ((i + j) % 2 + (i * j) % 3) % 2 == 0; }); } + +TEST(QRDataMaskTest, MicroMask0) +{ + TestMicroMaskAcrossDimensions(0, [](int i, int) { return i % 2 == 0; }); +} + +TEST(QRDataMaskTest, MicroMask1) +{ + TestMicroMaskAcrossDimensions(1, [](int i, int j) { return (i / 2 + j / 3) % 2 == 0; }); +} + +TEST(QRDataMaskTest, MicroMask2) +{ + TestMicroMaskAcrossDimensions(2, [](int i, int j) { return ((i * j) % 2 + (i * j) % 3) % 2 == 0; }); +} + +TEST(QRDataMaskTest, MicroMask3) +{ + TestMicroMaskAcrossDimensions(3, [](int i, int j) { return ((i + j) % 2 + (i * j) % 3) % 2 == 0; }); +} diff --git a/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp b/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp index 35f8b870fc..c09c226559 100644 --- a/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp +++ b/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp @@ -29,3 +29,26 @@ TEST(QRErrorCorrectionLevelTest, ForBits) EXPECT_EQ(ErrorCorrectionLevel::High, ECLevelFromBits(2)); EXPECT_EQ(ErrorCorrectionLevel::Quality, ECLevelFromBits(3)); } + +TEST(QRErrorCorrectionLevelTest, ForMicroBits) +{ + EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(0, true)); + EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(1, true)); + EXPECT_EQ(ErrorCorrectionLevel::Medium, ECLevelFromBits(2, true)); + EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(3, true)); + EXPECT_EQ(ErrorCorrectionLevel::Medium, ECLevelFromBits(4, true)); + EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(5, true)); + EXPECT_EQ(ErrorCorrectionLevel::Medium, ECLevelFromBits(6, true)); + EXPECT_EQ(ErrorCorrectionLevel::Quality, ECLevelFromBits(7, true)); + + EXPECT_EQ(ErrorCorrectionLevel::Quality, ECLevelFromBits(-1, true)); + EXPECT_EQ(ErrorCorrectionLevel::Low, ECLevelFromBits(8, true)); +} + +TEST(QRErrorCorrectionLevelTest, ToString) +{ + EXPECT_EQ(L"L", std::wstring(ToString(ErrorCorrectionLevel::Low))); + EXPECT_EQ(L"M", std::wstring(ToString(ErrorCorrectionLevel::Medium))); + EXPECT_EQ(L"Q", std::wstring(ToString(ErrorCorrectionLevel::Quality))); + EXPECT_EQ(L"H", std::wstring(ToString(ErrorCorrectionLevel::High))); +} diff --git a/test/unit/qrcode/QRFormatInformationTest.cpp b/test/unit/qrcode/QRFormatInformationTest.cpp index 62df090171..d4eb47dc87 100644 --- a/test/unit/qrcode/QRFormatInformationTest.cpp +++ b/test/unit/qrcode/QRFormatInformationTest.cpp @@ -22,9 +22,18 @@ using namespace ZXing; using namespace ZXing::QRCode; - static const int MASKED_TEST_FORMAT_INFO = 0x2BED; static const int UNMASKED_TEST_FORMAT_INFO = MASKED_TEST_FORMAT_INFO ^ 0x5412; +static const int MICRO_MASKED_TEST_FORMAT_INFO = 0x3BBA; +static const int MICRO_UNMASKED_TEST_FORMAT_INFO = MICRO_MASKED_TEST_FORMAT_INFO ^ 0x4445; + +static void DoFormatInformationTest(const int formatInfo, const uint8_t expectedMask, const ErrorCorrectionLevel& expectedECL) +{ + FormatInformation parsedFormat = FormatInformation::DecodeFormatInformation(formatInfo); + EXPECT_TRUE(parsedFormat.isValid()); + EXPECT_EQ(expectedMask, parsedFormat.dataMask()); + EXPECT_EQ(expectedECL, parsedFormat.errorCorrectionLevel()); +} TEST(QRFormatInformationTest, Decode) { @@ -52,3 +61,39 @@ TEST(QRFormatInformationTest, DecodeWithMisread) FormatInformation expected = FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x03, MASKED_TEST_FORMAT_INFO ^ 0x0F)); } + +TEST(QRFormatInformationTest, DecodeMicro) +{ + // Normal cases. + DoFormatInformationTest(0x4445, 0x0, ErrorCorrectionLevel::Low); + DoFormatInformationTest(0x4172, 0x1, ErrorCorrectionLevel::Low); + DoFormatInformationTest(0x5fc0, 0x2, ErrorCorrectionLevel::Low); + DoFormatInformationTest(0x5af7, 0x3, ErrorCorrectionLevel::Low); + DoFormatInformationTest(0x6793, 0x0, ErrorCorrectionLevel::Medium); + DoFormatInformationTest(0x62a4, 0x1, ErrorCorrectionLevel::Medium); + DoFormatInformationTest(0x3e8d, 0x2, ErrorCorrectionLevel::Quality); + DoFormatInformationTest(MICRO_MASKED_TEST_FORMAT_INFO, 0x3, ErrorCorrectionLevel::Quality); + + // where the code forgot the mask! +// DoFormatInformationTest(MICRO_UNMASKED_TEST_FORMAT_INFO, 0x3, ErrorCorrectionLevel::Quality); +} + +// This doesn't work as expected because the implementation of the decode tries with +// and without the mask (0x4445). This effectively adds a tolerance of 5 bits to the Hamming +// distance calculation. +TEST(QRFormatInformationTest, DecodeMicroWithBitDifference) +{ + FormatInformation expected = FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO); + + // 1,2,3 bits difference + EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x01)); + EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x03)); + EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x07)); + + // Bigger bit differences can return valid FormatInformation objects but the data mask and error + // correction levels do not match. +// EXPECT_TRUE(FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x3f).isValid()); +// EXPECT_NE(expected.dataMask(), FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x3f).dataMask()); +// EXPECT_NE(expected.errorCorrectionLevel(), +// FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x3f).errorCorrectionLevel()); +} diff --git a/test/unit/qrcode/QRModeTest.cpp b/test/unit/qrcode/QRModeTest.cpp index 368ce1b07b..77a1611350 100644 --- a/test/unit/qrcode/QRModeTest.cpp +++ b/test/unit/qrcode/QRModeTest.cpp @@ -43,3 +43,35 @@ TEST(QRModeTest, CharacterCount) ASSERT_EQ(8, CharacterCountBits(CodecMode::BYTE, *Version::VersionForNumber(7))); ASSERT_EQ(8, CharacterCountBits(CodecMode::KANJI, *Version::VersionForNumber(8))); } + +TEST(QRModeTest, MicroForBits) +{ + // M1 + ASSERT_EQ(CodecMode::NUMERIC, CodecModeForBits(0x00, true)); + // M2 + ASSERT_EQ(CodecMode::NUMERIC, CodecModeForBits(0x00, true)); + ASSERT_EQ(CodecMode::ALPHANUMERIC, CodecModeForBits(0x01, true)); + // M3 + ASSERT_EQ(CodecMode::NUMERIC, CodecModeForBits(0x00, true)); + ASSERT_EQ(CodecMode::ALPHANUMERIC, CodecModeForBits(0x01, true)); + ASSERT_EQ(CodecMode::BYTE, CodecModeForBits(0x02, true)); + ASSERT_EQ(CodecMode::KANJI, CodecModeForBits(0x03, true)); + // M4 + ASSERT_EQ(CodecMode::NUMERIC, CodecModeForBits(0x00, true)); + ASSERT_EQ(CodecMode::ALPHANUMERIC, CodecModeForBits(0x01, true)); + ASSERT_EQ(CodecMode::BYTE, CodecModeForBits(0x02, true)); + ASSERT_EQ(CodecMode::KANJI, CodecModeForBits(0x03, true)); + + ASSERT_THROW(CodecModeForBits(0x04, true), std::invalid_argument); +} + +TEST(QRModeTest, MicroCharacterCount) +{ + // Spot check a few values + ASSERT_EQ(3, CharacterCountBits(CodecMode::NUMERIC, *Version::VersionForNumber(1, true))); + ASSERT_EQ(4, CharacterCountBits(CodecMode::NUMERIC, *Version::VersionForNumber(2, true))); + ASSERT_EQ(6, CharacterCountBits(CodecMode::NUMERIC, *Version::VersionForNumber(4, true))); + ASSERT_EQ(3, CharacterCountBits(CodecMode::ALPHANUMERIC, *Version::VersionForNumber(2, true))); + ASSERT_EQ(4, CharacterCountBits(CodecMode::BYTE, *Version::VersionForNumber(3, true))); + ASSERT_EQ(4, CharacterCountBits(CodecMode::KANJI, *Version::VersionForNumber(4, true))); +} diff --git a/test/unit/qrcode/QRVersionTest.cpp b/test/unit/qrcode/QRVersionTest.cpp index 5f8e821382..4e6fd8eb0c 100644 --- a/test/unit/qrcode/QRVersionTest.cpp +++ b/test/unit/qrcode/QRVersionTest.cpp @@ -17,6 +17,8 @@ #include "qrcode/QRVersion.h" +#include "BitMatrix.h" + #include "gtest/gtest.h" using namespace ZXing; @@ -27,7 +29,7 @@ namespace { void CheckVersion(const Version* version, int number, int dimension) { ASSERT_NE(version, nullptr); EXPECT_EQ(number, version->versionNumber()); - if (number > 1) { + if (number > 1 && !version->isMicroQRCode()) { EXPECT_FALSE(version->alignmentPatternCenters().empty()); } EXPECT_EQ(dimension, version->dimensionForVersion()); @@ -38,6 +40,7 @@ namespace { ASSERT_NE(version, nullptr); EXPECT_EQ(expectedVersion, version->versionNumber()); } + } TEST(QRVersionTest, VersionForNumber) @@ -71,3 +74,42 @@ TEST(QRVersionTest, DecodeVersionInformation) DoTestVersion(32, 0x209D5); } +TEST(QRVersionTest, MicroVersionForNumber) +{ + auto version = Version::VersionForNumber(0, true); + EXPECT_EQ(version, nullptr) << "There is version with number 0"; + + for (int i = 1; i <= 4; i++) { + CheckVersion(Version::VersionForNumber(i, true), i, 2 * i + 9); + } +} + +TEST(QRVersionTest, GetProvisionalMicroVersionForDimension) +{ + for (int i = 1; i <= 4; i++) { + auto prov = Version::ProvisionalVersionForDimension(2 * i + 9, true); + ASSERT_NE(prov, nullptr); + EXPECT_EQ(i, prov->versionNumber()); + } +} + +TEST(QRVersionTest, FunctionPattern) +{ + auto testFinderPatternRegion = [](const BitMatrix& bitMatrix) { + for (int row = 0; row < 9; row++) + for (int col = 0; col < 9; col++) + EXPECT_TRUE(bitMatrix.get(col, row)); + }; + for (int i = 1; i <= 4; i++) { + const auto version = Version::VersionForNumber(i, true); + const auto functionPattern = version->buildFunctionPattern(); + testFinderPatternRegion(functionPattern); + + // Check timing pattern areas. + const auto dimension = version->dimensionForVersion(); + for (int row = dimension; row < functionPattern.height(); row++) + EXPECT_TRUE(functionPattern.get(0, row)); + for (int col = dimension; col < functionPattern.width(); col++) + EXPECT_TRUE(functionPattern.get(col, 0)); + } +} diff --git a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp index 965ed6e2a1..32994d5934 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp @@ -41,6 +41,7 @@ static const char* JavaBarcodeFormatName(BarcodeFormat format) case BarcodeFormat::MaxiCode: return "MAXICODE"; case BarcodeFormat::PDF417: return "PDF_417"; case BarcodeFormat::QRCode: return "QR_CODE"; + case BarcodeFormat::MicroQRCode: return "MICRO_QR_CODE"; case BarcodeFormat::DataBar: return "DATA_BAR"; case BarcodeFormat::DataBarExpanded: return "DATA_BAR_EXPANDED"; case BarcodeFormat::UPCA: return "UPC_A"; diff --git a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt index 52e4b3b380..6dbddecdac 100644 --- a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt +++ b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt @@ -30,7 +30,7 @@ class BarcodeReader { // Note that this has to be kept synchronized with native (C++/JNI) side. enum class Format { NONE, AZTEC, CODABAR, CODE_39, CODE_93, CODE_128, DATA_BAR, DATA_BAR_EXPANDED, - DATA_MATRIX, EAN_8, EAN_13, ITF, MAXICODE, PDF_417, QR_CODE, UPC_A, UPC_E, + DATA_MATRIX, EAN_8, EAN_13, ITF, MAXICODE, PDF_417, QR_CODE, MICRO_QR_CODE, UPC_A, UPC_E } data class Options( diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index e7fdfa1425..2756a20f8e 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -136,6 +136,7 @@ PYBIND11_MODULE(zxingcpp, m) .value("MaxiCode", BarcodeFormat::MaxiCode) .value("PDF417", BarcodeFormat::PDF417) .value("QRCode", BarcodeFormat::QRCode) + .value("MircoQRCode", BarcodeFormat::MicroQRCode) .value("DataBar", BarcodeFormat::DataBar) .value("DataBarExpanded", BarcodeFormat::DataBarExpanded) .value("UPCA", BarcodeFormat::UPCA) diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index 2a57e48df3..9695d26400 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -100,6 +100,8 @@ BarcodeFormat BarcodeReader::ConvertRuntimeToNative(BarcodeType type) return BarcodeFormat::PDF_417; case BarcodeType::QR_CODE: return BarcodeFormat::QR_CODE; + case BarcodeType::MICRO_QR_CODE: + return BarcodeFormat::MicroQRCode; case BarcodeType::RSS_14: return BarcodeFormat::RSS_14; case BarcodeType::RSS_EXPANDED: @@ -141,6 +143,8 @@ BarcodeType BarcodeReader::ConvertNativeToRuntime(BarcodeFormat format) return BarcodeType::PDF_417; case BarcodeFormat::QR_CODE: return BarcodeType::QR_CODE; + case BarcodeFormat::MicroQRCode: + return BarcodeType::MICRO_QR_CODE; case BarcodeFormat::RSS_14: return BarcodeType::RSS_14; case BarcodeFormat::RSS_EXPANDED: diff --git a/wrappers/winrt/BarcodeReader.h b/wrappers/winrt/BarcodeReader.h index 6b5dd8c83c..7455007449 100644 --- a/wrappers/winrt/BarcodeReader.h +++ b/wrappers/winrt/BarcodeReader.h @@ -34,6 +34,7 @@ public enum class BarcodeType : int { MAXICODE, PDF_417, QR_CODE, + MICRO_QR_CODE, RSS_14, RSS_EXPANDED, UPC_A, From 31c21de94187bfad44a82651edcd5190e197505f Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 17 May 2022 12:21:31 +0200 Subject: [PATCH 0200/1315] README: add info about new MicroQRCode support --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 58a274cf5f..ddaf4a862d 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,11 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ | 1D product | 1D industrial | 2D | ---------- | ----------------- | -------------- | UPC-A | Code 39 | QR Code -| UPC-E | Code 93 | DataMatrix +| UPC-E | Code 93 | Micro QR Code | EAN-8 | Code 128 | Aztec -| EAN-13 | Codabar | PDF417 -| DataBar | ITF | MaxiCode (beta) -| | DataBar Expanded | +| EAN-13 | Codabar | DataMatrix +| DataBar | ITF | PDF417 +| | DataBar Expanded | MaxiCode (beta) Note: DataBar used to be called RSS. DataBar is not supported for writing. From 345bc0450be64557efc0387724715e85fbfbf220 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 17 May 2022 12:46:23 +0200 Subject: [PATCH 0201/1315] QRCode: dead code removal and function name refactoring --- core/src/qrcode/QRBitMatrixParser.cpp | 4 +-- core/src/qrcode/QRDetector.cpp | 38 ++++---------------- core/src/qrcode/QRDetector.h | 12 +++---- core/src/qrcode/QRFormatInformation.cpp | 6 ++-- core/src/qrcode/QRFormatInformation.h | 4 +-- core/src/qrcode/QRReader.cpp | 9 ++--- test/unit/qrcode/QRFormatInformationTest.cpp | 28 +++++++-------- 7 files changed, 36 insertions(+), 65 deletions(-) diff --git a/core/src/qrcode/QRBitMatrixParser.cpp b/core/src/qrcode/QRBitMatrixParser.cpp index d54991cbaf..c9cc5ebbe0 100644 --- a/core/src/qrcode/QRBitMatrixParser.cpp +++ b/core/src/qrcode/QRBitMatrixParser.cpp @@ -83,7 +83,7 @@ FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrore for (int y = 7; y >= 1; y--) AppendBit(formatInfoBits, getBit(bitMatrix, 8, y, mirrored)); - return FormatInformation::DecodeFormatInformation(formatInfoBits); + return FormatInformation::DecodeMQR(formatInfoBits); } // Read top-left format info bits @@ -106,7 +106,7 @@ FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrore for (int x = dimension - 8; x < dimension; x++) AppendBit(formatInfoBits2, getBit(bitMatrix, x, 8, mirrored)); - return FormatInformation::DecodeFormatInformation(formatInfoBits1, formatInfoBits2); + return FormatInformation::DecodeQR(formatInfoBits1, formatInfoBits2); } static ByteArray ReadQRCodewords(const BitMatrix& bitMatrix, const Version& version, int maskIndex, bool mirrored) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index a50202c97a..bf218c54d1 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -42,7 +42,7 @@ namespace ZXing::QRCode { -constexpr auto PATTERN = FixedPattern<5, 7>{1, 1, 3, 1, 1}; +constexpr auto PATTERN = FixedPattern<5, 7>{1, 1, 3, 1, 1}; std::vector FindFinderPatterns(const BitMatrix& image, bool tryHarder) { @@ -257,7 +257,7 @@ static double EstimateTilt(const FinderPatternSet& fp) return double(max) / min; } -DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatternSet& fp) +DetectorResult SampleQR(const BitMatrix& image, const FinderPatternSet& fp) { auto top = EstimateDimension(image, fp.tl, fp.tr); auto left = EstimateDimension(image, fp.tl, fp.bl); @@ -324,7 +324,7 @@ DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatt * around it. This is a specialized method that works exceptionally fast in this special * case. */ -DetectorResult DetectPure(const BitMatrix& image) +DetectorResult DetectPureQR(const BitMatrix& image) { using Pattern = std::array; @@ -372,7 +372,7 @@ DetectorResult DetectPure(const BitMatrix& image) {{left, top}, {right, top}, {right, bottom}, {left, bottom}}}; } -DetectorResult DetectPureMicroQR(const BitMatrix& image) +DetectorResult DetectPureMQR(const BitMatrix& image) { using Pattern = std::array; @@ -412,33 +412,7 @@ DetectorResult DetectPureMicroQR(const BitMatrix& image) {{left, top}, {right, top}, {right, bottom}, {left, bottom}}}; } -FinderPatternSets FindFinderPatternSets(const BitMatrix& image, bool tryHarder) -{ - return GenerateFinderPatternSets(FindFinderPatterns(image, tryHarder)); -} - -DetectorResult Detect(const BitMatrix& image, bool tryHarder, bool isPure) -{ -#ifdef PRINT_DEBUG - LogMatrixWriter lmw(log, image, 5, "qr-log.pnm"); -#endif - - if (isPure) - return DetectPure(image); - - auto sets = GenerateFinderPatternSets(FindFinderPatterns(image, tryHarder)); - - if (sets.empty()) - return {}; - -#ifdef PRINT_DEBUG - printf("size of sets: %d\n", Size(sets)); -#endif - - return SampleAtFinderPatternSet(image, sets[0]); -} - -DetectorResult SampleAtFinderPattern(const BitMatrix& image, const ConcentricPattern& fp) +DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp) { auto fpQuad = FindConcentricPatternCorners(image, fp, fp.size, 2); if (!fpQuad) @@ -465,7 +439,7 @@ DetectorResult SampleAtFinderPattern(const BitMatrix& image, const ConcentricPat for (int i = 1; i <= 15; ++i) AppendBit(formatInfoBits, image.get(mod2Pix(centered(FORMAT_INFO_COORDS[i])))); - auto fi = FormatInformation::DecodeFormatInformation(formatInfoBits); + auto fi = FormatInformation::DecodeMQR(formatInfoBits); if (fi.isValid() && fi.microVersion()) { const int dim = Version::DimensionOfVersion(fi.microVersion(), true); return SampleGrid(image, dim, dim, mod2Pix); diff --git a/core/src/qrcode/QRDetector.h b/core/src/qrcode/QRDetector.h index 36f1b90bd1..bfb9bc2591 100644 --- a/core/src/qrcode/QRDetector.h +++ b/core/src/qrcode/QRDetector.h @@ -39,16 +39,12 @@ using FinderPatternSets = std::vector; FinderPatterns FindFinderPatterns(const BitMatrix& image, bool tryHarder); FinderPatternSets GenerateFinderPatternSets(FinderPatterns&& patterns); -DetectorResult SampleAtFinderPatternSet(const BitMatrix& image, const FinderPatternSet& fp); -DetectorResult SampleAtFinderPattern(const BitMatrix& image, const ConcentricPattern& fp); -DetectorResult DetectPureMicroQR(const BitMatrix& image); -DetectorResult DetectPure(const BitMatrix& image); +DetectorResult SampleQR(const BitMatrix& image, const FinderPatternSet& fp); +DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp); -/** - * @brief Detects a QR Code in an image. - */ -DetectorResult Detect(const BitMatrix& image, bool tryHarder, bool isPure); +DetectorResult DetectPureQR(const BitMatrix& image); +DetectorResult DetectPureMQR(const BitMatrix& image); } // QRCode } // ZXing diff --git a/core/src/qrcode/QRFormatInformation.cpp b/core/src/qrcode/QRFormatInformation.cpp index 9bea8c0247..f5bae8ed83 100644 --- a/core/src/qrcode/QRFormatInformation.cpp +++ b/core/src/qrcode/QRFormatInformation.cpp @@ -105,6 +105,7 @@ static int FindBestFormatInfo(int mask, const std::array, 32 int bestFormatInfo = -1; // Some QR codes apparently do not apply the XOR mask. Try without and with additional masking. + // TODO: test for mirrored format for (auto mask : {0, mask}) for (uint32_t bits : bits) for (const auto& [pattern, decodedInfo] : lookup) @@ -128,8 +129,7 @@ static int FindBestFormatInfo(int mask, const std::array, 32 * @return information about the format it specifies, or {@code null} * if doesn't seem to match any known pattern */ -FormatInformation -FormatInformation::DecodeFormatInformation(uint32_t formatInfoBits1, uint32_t formatInfoBits2) +FormatInformation FormatInformation::DecodeQR(uint32_t formatInfoBits1, uint32_t formatInfoBits2) { int bestFormatInfo = FindBestFormatInfo(FORMAT_INFO_MASK_QR, FORMAT_INFO_DECODE_LOOKUP, {formatInfoBits1, formatInfoBits2}); if (bestFormatInfo < 0) @@ -144,7 +144,7 @@ FormatInformation::DecodeFormatInformation(uint32_t formatInfoBits1, uint32_t fo * @return information about the format it specifies, or {@code null} * if doesn't seem to match any known pattern */ -FormatInformation FormatInformation::DecodeFormatInformation(uint32_t formatInfoBits) +FormatInformation FormatInformation::DecodeMQR(uint32_t formatInfoBits) { // We don't use the additional masking (with 0x4445) to work around potentially non complying MircoQRCode encoders int bestFormatInfo = FindBestFormatInfo(0, FORMAT_INFO_DECODE_LOOKUP_MICRO, {formatInfoBits}); diff --git a/core/src/qrcode/QRFormatInformation.h b/core/src/qrcode/QRFormatInformation.h index a560c62d33..a8680b8023 100644 --- a/core/src/qrcode/QRFormatInformation.h +++ b/core/src/qrcode/QRFormatInformation.h @@ -36,8 +36,8 @@ class FormatInformation public: FormatInformation() = default; - static FormatInformation DecodeFormatInformation(uint32_t formatInfoBits1, uint32_t formatInfoBits2); - static FormatInformation DecodeFormatInformation(uint32_t formatInfoBits); + static FormatInformation DecodeQR(uint32_t formatInfoBits1, uint32_t formatInfoBits2); + static FormatInformation DecodeMQR(uint32_t formatInfoBits); ErrorCorrectionLevel errorCorrectionLevel() const { return _errorCorrectionLevel; } diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 3d30b0f05b..f533e7af12 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -57,10 +57,10 @@ Result Reader::decode(const BinaryBitmap& image) const bool isMicro = false; DetectorResult detectorResult; if (_testQR) - detectorResult = DetectPure(*binImg); + detectorResult = DetectPureQR(*binImg); if (_testMQR && !detectorResult.isValid()) { isMicro = true; - detectorResult = DetectPureMicroQR(*binImg); + detectorResult = DetectPureMQR(*binImg); } if (!detectorResult.isValid()) @@ -93,7 +93,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const if (Contains(usedFPs, fpSet.bl) || Contains(usedFPs, fpSet.tl) || Contains(usedFPs, fpSet.tr)) continue; - auto detectorResult = SampleAtFinderPatternSet(*binImg, fpSet); + auto detectorResult = SampleQR(*binImg, fpSet); if (detectorResult.isValid()) { auto decoderResult = Decode(detectorResult.bits(), _charset); auto position = detectorResult.position(); @@ -114,7 +114,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const if (Contains(usedFPs, fp)) continue; - auto detectorResult = SampleAtFinderPattern(*binImg, fp); + auto detectorResult = SampleMQR(*binImg, fp); if (detectorResult.isValid()) { auto decoderResult = Decode(detectorResult.bits(), _charset, true); auto position = detectorResult.position(); @@ -123,6 +123,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const if (maxSymbols && Size(results) == maxSymbols) break; } + } } } diff --git a/test/unit/qrcode/QRFormatInformationTest.cpp b/test/unit/qrcode/QRFormatInformationTest.cpp index d4eb47dc87..c87184585b 100644 --- a/test/unit/qrcode/QRFormatInformationTest.cpp +++ b/test/unit/qrcode/QRFormatInformationTest.cpp @@ -29,7 +29,7 @@ static const int MICRO_UNMASKED_TEST_FORMAT_INFO = MICRO_MASKED_TEST_FORMAT_INFO static void DoFormatInformationTest(const int formatInfo, const uint8_t expectedMask, const ErrorCorrectionLevel& expectedECL) { - FormatInformation parsedFormat = FormatInformation::DecodeFormatInformation(formatInfo); + FormatInformation parsedFormat = FormatInformation::DecodeMQR(formatInfo); EXPECT_TRUE(parsedFormat.isValid()); EXPECT_EQ(expectedMask, parsedFormat.dataMask()); EXPECT_EQ(expectedECL, parsedFormat.errorCorrectionLevel()); @@ -38,28 +38,28 @@ static void DoFormatInformationTest(const int formatInfo, const uint8_t expected TEST(QRFormatInformationTest, Decode) { // Normal case - FormatInformation expected = FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); + FormatInformation expected = FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); EXPECT_TRUE(expected.isValid()); EXPECT_EQ(0x07, expected.dataMask()); EXPECT_EQ(ErrorCorrectionLevel::Quality, expected.errorCorrectionLevel()); // where the code forgot the mask! - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(UNMASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO)); + EXPECT_EQ(expected, FormatInformation::DecodeQR(UNMASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO)); } TEST(QRFormatInformationTest, DecodeWithBitDifference) { - FormatInformation expected = FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); + FormatInformation expected = FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); // 1,2,3,4 bits difference - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x01, MASKED_TEST_FORMAT_INFO ^ 0x01)); - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x03, MASKED_TEST_FORMAT_INFO ^ 0x03)); - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x07, MASKED_TEST_FORMAT_INFO ^ 0x07)); - EXPECT_TRUE(!FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x0F, MASKED_TEST_FORMAT_INFO ^ 0x0F).isValid()); + EXPECT_EQ(expected, FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO ^ 0x01, MASKED_TEST_FORMAT_INFO ^ 0x01)); + EXPECT_EQ(expected, FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO ^ 0x03, MASKED_TEST_FORMAT_INFO ^ 0x03)); + EXPECT_EQ(expected, FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO ^ 0x07, MASKED_TEST_FORMAT_INFO ^ 0x07)); + EXPECT_TRUE(!FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO ^ 0x0F, MASKED_TEST_FORMAT_INFO ^ 0x0F).isValid()); } TEST(QRFormatInformationTest, DecodeWithMisread) { - FormatInformation expected = FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x03, MASKED_TEST_FORMAT_INFO ^ 0x0F)); + FormatInformation expected = FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); + EXPECT_EQ(expected, FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO ^ 0x03, MASKED_TEST_FORMAT_INFO ^ 0x0F)); } TEST(QRFormatInformationTest, DecodeMicro) @@ -83,12 +83,12 @@ TEST(QRFormatInformationTest, DecodeMicro) // distance calculation. TEST(QRFormatInformationTest, DecodeMicroWithBitDifference) { - FormatInformation expected = FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO); + FormatInformation expected = FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO); // 1,2,3 bits difference - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x01)); - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x03)); - EXPECT_EQ(expected, FormatInformation::DecodeFormatInformation(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x07)); + EXPECT_EQ(expected, FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x01)); + EXPECT_EQ(expected, FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x03)); + EXPECT_EQ(expected, FormatInformation::DecodeMQR(MICRO_MASKED_TEST_FORMAT_INFO ^ 0x07)); // Bigger bit differences can return valid FormatInformation objects but the data mask and error // correction levels do not match. From 8566392d25d60a3c1ff5e6f0eec441a269f6bb08 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 17 May 2022 13:03:38 +0200 Subject: [PATCH 0202/1315] QRCode: simplify Decode API by determining isMicro from symbol size --- core/src/qrcode/QRBitMatrixParser.cpp | 7 ++++--- core/src/qrcode/QRBitMatrixParser.h | 2 +- core/src/qrcode/QRDecoder.cpp | 4 ++-- core/src/qrcode/QRDecoder.h | 2 +- core/src/qrcode/QRReader.cpp | 12 +++++------- test/unit/qrcode/MQRDecoderTest.cpp | 10 +++++----- test/unit/qrcode/QRBitMatrixParserTest.cpp | 4 ++-- 7 files changed, 20 insertions(+), 21 deletions(-) diff --git a/core/src/qrcode/QRBitMatrixParser.cpp b/core/src/qrcode/QRBitMatrixParser.cpp index c9cc5ebbe0..97d484dbdd 100644 --- a/core/src/qrcode/QRBitMatrixParser.cpp +++ b/core/src/qrcode/QRBitMatrixParser.cpp @@ -42,13 +42,14 @@ static bool hasValidDimension(const BitMatrix& bitMatrix, bool isMicro) return dimension >= 21 && dimension <= 177 && (dimension % 4) == 1; } -const Version* ReadVersion(const BitMatrix& bitMatrix, bool isMicro) +const Version* ReadVersion(const BitMatrix& bitMatrix) { + int dimension = bitMatrix.height(); + bool isMicro = dimension < 21; + if (!hasValidDimension(bitMatrix, isMicro)) return nullptr; - int dimension = bitMatrix.height(); - int provisionalVersion = (dimension - Version::DimensionOffset(isMicro)) / Version::DimensionStep(isMicro); if (provisionalVersion <= 6) diff --git a/core/src/qrcode/QRBitMatrixParser.h b/core/src/qrcode/QRBitMatrixParser.h index c911389b6f..b8aa567adf 100644 --- a/core/src/qrcode/QRBitMatrixParser.h +++ b/core/src/qrcode/QRBitMatrixParser.h @@ -30,7 +30,7 @@ class FormatInformation; * @brief Reads version information from the QR Code. * @return {@link Version} encapsulating the QR Code's version, nullptr if neither location can be parsed */ -const Version* ReadVersion(const BitMatrix& bitMatrix, bool isMicro); +const Version* ReadVersion(const BitMatrix& bitMatrix); /** * @brief Reads format information from one of its two locations within the QR Code. diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 6e5c259814..8aaf06ade1 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -488,9 +488,9 @@ static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, con return DecodeBitStream(std::move(resultBytes), version, formatInfo.errorCorrectionLevel(), hintedCharset); } -DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset, const bool isMicroQRCode) +DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) { - const Version* version = ReadVersion(bits, isMicroQRCode); + const Version* version = ReadVersion(bits); if (!version) return DecodeStatus::FormatError; diff --git a/core/src/qrcode/QRDecoder.h b/core/src/qrcode/QRDecoder.h index e8171b036b..2f10bddc59 100644 --- a/core/src/qrcode/QRDecoder.h +++ b/core/src/qrcode/QRDecoder.h @@ -28,7 +28,7 @@ namespace QRCode { /** * @brief Decodes a QR Code from the BitMatrix and the hinted charset. */ -DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset, const bool isMicroQRCode = false); +DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset = {}); } // QRCode } // ZXing diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index f533e7af12..505ab6ab0d 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -54,22 +54,20 @@ Result Reader::decode(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); } - bool isMicro = false; DetectorResult detectorResult; if (_testQR) detectorResult = DetectPureQR(*binImg); - if (_testMQR && !detectorResult.isValid()) { - isMicro = true; + if (_testMQR && !detectorResult.isValid()) detectorResult = DetectPureMQR(*binImg); - } if (!detectorResult.isValid()) return Result(DecodeStatus::NotFound); - auto decoderResult = Decode(detectorResult.bits(), _charset, isMicro); + auto decoderResult = Decode(detectorResult.bits(), _charset); auto position = detectorResult.position(); - return Result(std::move(decoderResult), std::move(position), isMicro ? BarcodeFormat::MicroQRCode : BarcodeFormat::QRCode); + return Result(std::move(decoderResult), std::move(position), + detectorResult.bits().width() < 21 ? BarcodeFormat::MicroQRCode : BarcodeFormat::QRCode); } Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const @@ -116,7 +114,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const auto detectorResult = SampleMQR(*binImg, fp); if (detectorResult.isValid()) { - auto decoderResult = Decode(detectorResult.bits(), _charset, true); + auto decoderResult = Decode(detectorResult.bits(), _charset); auto position = detectorResult.position(); if (decoderResult.isValid()) { results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MicroQRCode); diff --git a/test/unit/qrcode/MQRDecoderTest.cpp b/test/unit/qrcode/MQRDecoderTest.cpp index 47ebe2ef73..c49f1217d2 100644 --- a/test/unit/qrcode/MQRDecoderTest.cpp +++ b/test/unit/qrcode/MQRDecoderTest.cpp @@ -45,7 +45,7 @@ TEST(MQRDecoderTest, MQRCodeM3L) "XXX XX X X XXXX\n", 88, false); - const auto result = Decode(bitMatrix, {}, true); + const auto result = Decode(bitMatrix); EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); } @@ -68,7 +68,7 @@ TEST(MQRDecoderTest, MQRCodeM3M) "X X XXXX XXX\n", 88, false); - const auto result = Decode(bitMatrix, {}, true); + const auto result = Decode(bitMatrix); EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); } @@ -86,7 +86,7 @@ TEST(MQRDecoderTest, MQRCodeM1) " X XXXXX X\n" "X XXXXXX X\n", 88, false); - const auto result = Decode(bitMatrix, {}, true); + const auto result = Decode(bitMatrix); EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); EXPECT_EQ(L"123", result.text()); } @@ -105,7 +105,7 @@ TEST(MQRDecoderTest, MQRCodeM1Error4Bits) " X XXXXXX \n" "X XXXXXXX \n", 88, false); - const auto result = Decode(bitMatrix, {}, true); + const auto result = Decode(bitMatrix); EXPECT_EQ(DecodeStatus::ChecksumError, result.errorCode()); EXPECT_TRUE(result.text().empty()); } @@ -130,6 +130,6 @@ TEST(MQRDecoderTest, MQRCodeM4) " X X X X X \n" "X XXXXXXX X X X\n", 88, false); - const auto result = Decode(bitMatrix, {}, true); + const auto result = Decode(bitMatrix); EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); } diff --git a/test/unit/qrcode/QRBitMatrixParserTest.cpp b/test/unit/qrcode/QRBitMatrixParserTest.cpp index 1eea005bf6..023c4614d0 100644 --- a/test/unit/qrcode/QRBitMatrixParserTest.cpp +++ b/test/unit/qrcode/QRBitMatrixParserTest.cpp @@ -46,7 +46,7 @@ TEST(QRBitMatrixParserTest, MQRCodeM3L) "XXX XX X X XXXX\n", 88, false); - const auto version = ReadVersion(bitMatrix, true); + const auto version = ReadVersion(bitMatrix); EXPECT_EQ(3, version->versionNumber()); const auto format = ReadFormatInformation(bitMatrix, false, true); const auto codewords = ReadCodewords(bitMatrix, *version, format, false); @@ -74,7 +74,7 @@ TEST(QRBitMatrixParserTest, MQRCodeM3M) "X X XXXX XXX\n", 88, false); - const auto version = ReadVersion(bitMatrix, true); + const auto version = ReadVersion(bitMatrix); EXPECT_EQ(3, version->versionNumber()); const auto format = ReadFormatInformation(bitMatrix, false, true); const auto codewords = ReadCodewords(bitMatrix, *version, format, false); From b4cb588b5de70d195944245f7f2b938a20e06732 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 17 May 2022 13:05:06 +0200 Subject: [PATCH 0203/1315] BlackboxTestRunner: random clang-format whitespace fixes --- test/blackbox/BlackboxTestRunner.cpp | 31 ++++++++++++---------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index cca643fbd0..ab75e6169e 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -59,9 +59,7 @@ namespace { TC tc[2] = {}; int rotation = 0; // The rotation in degrees clockwise to use for this test. - TestCase(int mntf, int mnts, int mmf, int mms, int r) - : tc{{"fast", mntf, mmf}, {"slow", mnts, mms}}, rotation(r) - {} + TestCase(int mntf, int mnts, int mmf, int mms, int r) : tc{{"fast", mntf, mmf}, {"slow", mnts, mms}}, rotation(r) {} TestCase(int mntf, int mnts, int r) : TestCase(mntf, mnts, 0, 0, r) {} TestCase(int mntp, int mmp, PureTag) : tc{{"pure", mntp, mmp}} {} }; @@ -185,8 +183,7 @@ static void printPositiveTestStats(int imageCount, const TestCase::TC& tc) { int passCount = imageCount - Size(tc.misReadFiles) - Size(tc.notDetectedFiles); - fmt::print(" | {}: {:3} of {:3}, misread {} of {}", tc.name, passCount, tc.minPassCount, Size(tc.misReadFiles), - tc.maxMisreads); + fmt::print(" | {}: {:3} of {:3}, misread {} of {}", tc.name, passCount, tc.minPassCount, Size(tc.misReadFiles), tc.maxMisreads); if (passCount < tc.minPassCount && !tc.notDetectedFiles.empty()) { fmt::print("\nFAILED: Not detected ({}):", tc.name); @@ -217,8 +214,8 @@ static std::vector getImagesInDirectory(const fs::path& directory) return result; } -static void doRunTests( - const fs::path& directory, std::string_view format, int totalTests, const std::vector& tests, DecodeHints hints) +static void doRunTests(const fs::path& directory, std::string_view format, int totalTests, const std::vector& tests, + DecodeHints hints) { auto imgPaths = getImagesInDirectory(directory); auto folderName = directory.stem(); @@ -261,9 +258,8 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi { std::list allResults; for (const auto& imgPath : imgPaths) { - auto results = - ReadBarcodes(ImageLoader::load(imgPath), - DecodeHints().setFormats(BarcodeFormatFromString(format.data())).setTryDownscale(false)); + auto results = ReadBarcodes(ImageLoader::load(imgPath), + DecodeHints().setFormats(BarcodeFormatFromString(format.data())).setTryDownscale(false)); allResults.insert(allResults.end(), results.begin(), results.end()); } @@ -282,13 +278,12 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi text.append(r.text()); const auto& first = allResults.front(); - StructuredAppendInfo sai{ first.sequenceIndex(), first.sequenceSize(), first.sequenceId() }; - return Result(std::move(text), {}, first.format(), std::string(first.symbologyIdentifier()), {}, std::move(sai), - first.readerInit()); + StructuredAppendInfo sai{first.sequenceIndex(), first.sequenceSize(), first.sequenceId()}; + return {std::move(text), {}, first.format(), std::string(first.symbologyIdentifier()), {}, std::move(sai), first.readerInit()}; } -static void doRunStructuredAppendTest( - const fs::path& directory, std::string_view format, int totalTests, const std::vector& tests) +static void doRunStructuredAppendTest(const fs::path& directory, std::string_view format, int totalTests, + const std::vector& tests) { auto imgPaths = getImagesInDirectory(directory); auto folderName = directory.stem(); @@ -301,8 +296,7 @@ static void doRunStructuredAppendTest( } if (Size(imageGroups) != totalTests) - fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName, totalTests, - imageGroups.size()); + fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName, totalTests, imageGroups.size()); for (auto& test : tests) { fmt::print("{:20} @ {:3}, {:3}", folderName.string(), test.rotation, Size(imgPaths)); @@ -339,7 +333,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set doRunTests(testPathPrefix / directory, format, total, tests, hints); }; - auto runStructuredAppendTest = [&](std::string_view directory, std::string_view format, int total, const std::vector& tests) { + auto runStructuredAppendTest = [&](std::string_view directory, std::string_view format, int total, + const std::vector& tests) { if (hasTest(directory)) doRunStructuredAppendTest(testPathPrefix / directory, format, total, tests); }; From cff0440d2caffe83ec8a3840c94943582841c5de Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 17 May 2022 13:15:57 +0200 Subject: [PATCH 0204/1315] QRDecoder: code style fixes --- core/src/qrcode/QRDecoder.cpp | 96 ++++++++++++++--------------------- 1 file changed, 39 insertions(+), 57 deletions(-) diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 8aaf06ade1..24d017a7e3 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -72,9 +72,8 @@ static bool CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) static DecodeStatus DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) { // Don't crash trying to read more bits than we have available. - if (count * 13 > bits.available()) { + if (count * 13 > bits.available()) return DecodeStatus::FormatError; - } // Each character will require 2 bytes. Read the characters as 2-byte pairs // and decode as GB2312 afterwards @@ -87,8 +86,7 @@ static DecodeStatus DecodeHanziSegment(BitSource& bits, int count, std::wstring& if (assembledTwoBytes < 0x00A00) { // In the 0xA1A1 to 0xAAFE range assembledTwoBytes += 0x0A1A1; - } - else { + } else { // In the 0xB0A1 to 0xFAFE range assembledTwoBytes += 0x0A6A1; } @@ -104,9 +102,8 @@ static DecodeStatus DecodeHanziSegment(BitSource& bits, int count, std::wstring& static DecodeStatus DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) { // Don't crash trying to read more bits than we have available. - if (count * 13 > bits.available()) { + if (count * 13 > bits.available()) return DecodeStatus::FormatError; - } // Each character will require 2 bytes. Read the characters as 2-byte pairs // and decode as Shift_JIS afterwards @@ -119,8 +116,7 @@ static DecodeStatus DecodeKanjiSegment(BitSource& bits, int count, std::wstring& if (assembledTwoBytes < 0x01F00) { // In the 0x8140 to 0x9FFC range assembledTwoBytes += 0x08140; - } - else { + } else { // In the 0xE040 to 0xEBBF range assembledTwoBytes += 0x0C140; } @@ -137,28 +133,24 @@ static DecodeStatus DecodeByteSegment(BitSource& bits, int count, CharacterSet c std::wstring& result) { // Don't crash trying to read more bits than we have available. - if (8 * count > bits.available()) { + if (8 * count > bits.available()) return DecodeStatus::FormatError; - } ByteArray readBytes(count); - for (int i = 0; i < count; i++) { + for (int i = 0; i < count; i++) readBytes[i] = static_cast(bits.readBits(8)); - } - if (currentCharset == CharacterSet::Unknown) { + + if (currentCharset == CharacterSet::Unknown) { // The spec isn't clear on this mode; see // section 6.4.5: t does not say which encoding to assuming // upon decoding. I have seen ISO-8859-1 used as well as // Shift_JIS -- without anything like an ECI designator to // give a hint. if (!hintedCharset.empty()) - { currentCharset = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); - } + if (currentCharset == CharacterSet::Unknown) - { currentCharset = TextDecoder::GuessEncoding(readBytes.data(), Size(readBytes)); - } } TextDecoder::Append(result, readBytes.data(), Size(readBytes), currentCharset); return DecodeStatus::NoError; @@ -176,9 +168,9 @@ static char ToAlphaNumericChar(int value) ' ', '$', '%', '*', '+', '-', '.', '/', ':' }; - if (value < 0 || value >= Size(ALPHANUMERIC_CHARS)) { + if (value < 0 || value >= Size(ALPHANUMERIC_CHARS)) throw std::out_of_range("ToAlphaNumericChar: out of range"); - } + return ALPHANUMERIC_CHARS[value]; } @@ -187,9 +179,8 @@ static DecodeStatus DecodeAlphanumericSegment(BitSource& bits, int count, bool f // Read two characters at a time std::string buffer; while (count > 1) { - if (bits.available() < 11) { + if (bits.available() < 11) return DecodeStatus::FormatError; - } int nextTwoCharsBits = bits.readBits(11); buffer += ToAlphaNumericChar(nextTwoCharsBits / 45); buffer += ToAlphaNumericChar(nextTwoCharsBits % 45); @@ -197,9 +188,8 @@ static DecodeStatus DecodeAlphanumericSegment(BitSource& bits, int count, bool f } if (count == 1) { // special case: one character left - if (bits.available() < 6) { + if (bits.available() < 6) return DecodeStatus::FormatError; - } buffer += ToAlphaNumericChar(bits.readBits(6)); } // See section 6.4.8.1, 6.4.8.2 @@ -210,8 +200,7 @@ static DecodeStatus DecodeAlphanumericSegment(BitSource& bits, int count, bool f if (i < buffer.length() - 1 && buffer[i + 1] == '%') { // %% is rendered as % buffer.erase(i + 1); - } - else { + } else { // In alpha mode, % should be converted to FNC1 separator 0x1D buffer[i] = static_cast(0x1D); } @@ -228,39 +217,39 @@ static DecodeStatus DecodeNumericSegment(BitSource& bits, int count, std::wstrin std::string buffer; while (count >= 3) { // Each 10 bits encodes three digits - if (bits.available() < 10) { + if (bits.available() < 10) return DecodeStatus::FormatError; - } + int threeDigitsBits = bits.readBits(10); - if (threeDigitsBits >= 1000) { + if (threeDigitsBits >= 1000) return DecodeStatus::FormatError; - } + buffer += ToAlphaNumericChar(threeDigitsBits / 100); buffer += ToAlphaNumericChar((threeDigitsBits / 10) % 10); buffer += ToAlphaNumericChar(threeDigitsBits % 10); count -= 3; } + if (count == 2) { // Two digits left over to read, encoded in 7 bits - if (bits.available() < 7) { + if (bits.available() < 7) return DecodeStatus::FormatError; - } + int twoDigitsBits = bits.readBits(7); - if (twoDigitsBits >= 100) { + if (twoDigitsBits >= 100) return DecodeStatus::FormatError; - } + buffer += ToAlphaNumericChar(twoDigitsBits / 10); buffer += ToAlphaNumericChar(twoDigitsBits % 10); - } - else if (count == 1) { + } else if (count == 1) { // One digit left over to read - if (bits.available() < 4) { + if (bits.available() < 4) return DecodeStatus::FormatError; - } + int digitBits = bits.readBits(4); - if (digitBits >= 10) { + if (digitBits >= 10) return DecodeStatus::FormatError; - } + buffer += ToAlphaNumericChar(digitBits); } @@ -366,9 +355,9 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo appIndValue = bits.readBits(8); // Number 00-99 or ASCII value + 100; prefixed to data below break; case CodecMode::STRUCTURED_APPEND: - if (bits.available() < 16) { + if (bits.available() < 16) return DecodeStatus::FormatError; - } + // sequence number and parity is added later to the result metadata // Read next 4 bits of index, 4 bits of symbol count, and 8 bits of parity data, then continue structuredAppend.index = bits.readBits(4); @@ -379,13 +368,12 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo // Count doesn't apply to ECI int value; auto status = ParseECIValue(bits, value); - if (StatusIsError(status)) { + if (StatusIsError(status)) return status; - } + currentCharset = CharacterSetECI::CharsetFromValue(value); - if (currentCharset == CharacterSet::Unknown) { + if (currentCharset == CharacterSet::Unknown) return DecodeStatus::FormatError; - } break; } case CodecMode::HANZI: { @@ -395,9 +383,8 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo int countHanzi = bits.readBits(CharacterCountBits(mode, version)); if (subset == GB2312_SUBSET) { auto status = DecodeHanziSegment(bits, countHanzi, result); - if (StatusIsError(status)) { + if (StatusIsError(status)) return status; - } } break; } @@ -413,9 +400,8 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo case CodecMode::KANJI: status = DecodeKanjiSegment(bits, count, result); break; default: status = DecodeStatus::FormatError; } - if (StatusIsError(status)) { + if (StatusIsError(status)) return status; - } break; } } @@ -428,18 +414,14 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo } if (appIndValue >= 0) { - if (appIndValue < 10) { // "00-09" + if (appIndValue < 10) // "00-09" result.insert(0, L'0' + std::to_wstring(appIndValue)); - } - else if (appIndValue < 100) { // "10-99" + else if (appIndValue < 100) // "10-99" result.insert(0, std::to_wstring(appIndValue)); - } - else if ((appIndValue >= 165 && appIndValue <= 190) || (appIndValue >= 197 && appIndValue <= 222)) { // "A-Za-z" + else if ((appIndValue >= 165 && appIndValue <= 190) || (appIndValue >= 197 && appIndValue <= 222)) // "A-Za-z" result.insert(0, 1, static_cast(appIndValue - 100)); - } - else { + else return DecodeStatus::FormatError; - } } std::string symbologyIdentifier("]Q" + std::to_string(symbologyIdModifier)); From 3be35e239b5a4f791dab72d2965ca73ef533ef73 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 18 May 2022 02:18:36 +0200 Subject: [PATCH 0205/1315] QRDecoder: move to consistent exception based error handling The code was inconsistently using error status return values and exceptions. Decoded to consistently switch to exceptions as it leads to cleaner code and is less error prone in its usage. Note: the errors that might happen during decoding of the bit stream are indeed exceptional (not happening in any of the black box sample images) so this is an acceptable performance trade-off. --- core/src/qrcode/QRDecoder.cpp | 101 +++++++++------------------------- 1 file changed, 27 insertions(+), 74 deletions(-) diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 24d017a7e3..66b2a41c11 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -69,12 +69,8 @@ static bool CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) /** * See specification GBT 18284-2000 */ -static DecodeStatus DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) +static void DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) { - // Don't crash trying to read more bits than we have available. - if (count * 13 > bits.available()) - return DecodeStatus::FormatError; - // Each character will require 2 bytes. Read the characters as 2-byte pairs // and decode as GB2312 afterwards ByteArray buffer; @@ -96,15 +92,10 @@ static DecodeStatus DecodeHanziSegment(BitSource& bits, int count, std::wstring& } TextDecoder::Append(result, buffer.data(), Size(buffer), CharacterSet::GB2312); - return DecodeStatus::NoError; } -static DecodeStatus DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) +static void DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) { - // Don't crash trying to read more bits than we have available. - if (count * 13 > bits.available()) - return DecodeStatus::FormatError; - // Each character will require 2 bytes. Read the characters as 2-byte pairs // and decode as Shift_JIS afterwards ByteArray buffer; @@ -126,16 +117,11 @@ static DecodeStatus DecodeKanjiSegment(BitSource& bits, int count, std::wstring& } TextDecoder::Append(result, buffer.data(), Size(buffer), CharacterSet::Shift_JIS); - return DecodeStatus::NoError; } -static DecodeStatus DecodeByteSegment(BitSource& bits, int count, CharacterSet currentCharset, const std::string& hintedCharset, - std::wstring& result) +static void DecodeByteSegment(BitSource& bits, int count, CharacterSet currentCharset, const std::string& hintedCharset, + std::wstring& result) { - // Don't crash trying to read more bits than we have available. - if (8 * count > bits.available()) - return DecodeStatus::FormatError; - ByteArray readBytes(count); for (int i = 0; i < count; i++) readBytes[i] = static_cast(bits.readBits(8)); @@ -153,7 +139,6 @@ static DecodeStatus DecodeByteSegment(BitSource& bits, int count, CharacterSet c currentCharset = TextDecoder::GuessEncoding(readBytes.data(), Size(readBytes)); } TextDecoder::Append(result, readBytes.data(), Size(readBytes), currentCharset); - return DecodeStatus::NoError; } static char ToAlphaNumericChar(int value) @@ -174,13 +159,11 @@ static char ToAlphaNumericChar(int value) return ALPHANUMERIC_CHARS[value]; } -static DecodeStatus DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, std::wstring& result) +static void DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, std::wstring& result) { // Read two characters at a time std::string buffer; while (count > 1) { - if (bits.available() < 11) - return DecodeStatus::FormatError; int nextTwoCharsBits = bits.readBits(11); buffer += ToAlphaNumericChar(nextTwoCharsBits / 45); buffer += ToAlphaNumericChar(nextTwoCharsBits % 45); @@ -188,8 +171,6 @@ static DecodeStatus DecodeAlphanumericSegment(BitSource& bits, int count, bool f } if (count == 1) { // special case: one character left - if (bits.available() < 6) - return DecodeStatus::FormatError; buffer += ToAlphaNumericChar(bits.readBits(6)); } // See section 6.4.8.1, 6.4.8.2 @@ -208,21 +189,17 @@ static DecodeStatus DecodeAlphanumericSegment(BitSource& bits, int count, bool f } } TextDecoder::AppendLatin1(result, buffer); - return DecodeStatus::NoError; } -static DecodeStatus DecodeNumericSegment(BitSource& bits, int count, std::wstring& result) +static void DecodeNumericSegment(BitSource& bits, int count, std::wstring& result) { // Read three digits at a time std::string buffer; while (count >= 3) { // Each 10 bits encodes three digits - if (bits.available() < 10) - return DecodeStatus::FormatError; - int threeDigitsBits = bits.readBits(10); if (threeDigitsBits >= 1000) - return DecodeStatus::FormatError; + throw std::runtime_error("Invalid value in numeric segment"); buffer += ToAlphaNumericChar(threeDigitsBits / 100); buffer += ToAlphaNumericChar((threeDigitsBits / 10) % 10); @@ -232,52 +209,42 @@ static DecodeStatus DecodeNumericSegment(BitSource& bits, int count, std::wstrin if (count == 2) { // Two digits left over to read, encoded in 7 bits - if (bits.available() < 7) - return DecodeStatus::FormatError; - int twoDigitsBits = bits.readBits(7); if (twoDigitsBits >= 100) - return DecodeStatus::FormatError; + throw std::runtime_error("Invalid value in numeric segment"); buffer += ToAlphaNumericChar(twoDigitsBits / 10); buffer += ToAlphaNumericChar(twoDigitsBits % 10); } else if (count == 1) { // One digit left over to read - if (bits.available() < 4) - return DecodeStatus::FormatError; - int digitBits = bits.readBits(4); if (digitBits >= 10) - return DecodeStatus::FormatError; + throw std::runtime_error("Invalid value in numeric segment"); buffer += ToAlphaNumericChar(digitBits); } TextDecoder::AppendLatin1(result, buffer); - return DecodeStatus::NoError; } -static DecodeStatus ParseECIValue(BitSource& bits, int& outValue) +static int ParseECIValue(BitSource& bits) { int firstByte = bits.readBits(8); if ((firstByte & 0x80) == 0) { // just one byte - outValue = firstByte & 0x7F; - return DecodeStatus::NoError; + return firstByte & 0x7F; } if ((firstByte & 0xC0) == 0x80) { // two bytes int secondByte = bits.readBits(8); - outValue = ((firstByte & 0x3F) << 8) | secondByte; - return DecodeStatus::NoError; + return ((firstByte & 0x3F) << 8) | secondByte; } if ((firstByte & 0xE0) == 0xC0) { // three bytes int secondThirdBytes = bits.readBits(16); - outValue = ((firstByte & 0x1F) << 16) | secondThirdBytes; - return DecodeStatus::NoError; + return ((firstByte & 0x1F) << 16) | secondThirdBytes; } - return DecodeStatus::FormatError; + throw std::runtime_error("ParseECIValue: invalid value"); } /** @@ -355,9 +322,6 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo appIndValue = bits.readBits(8); // Number 00-99 or ASCII value + 100; prefixed to data below break; case CodecMode::STRUCTURED_APPEND: - if (bits.available() < 16) - return DecodeStatus::FormatError; - // sequence number and parity is added later to the result metadata // Read next 4 bits of index, 4 bits of symbol count, and 8 bits of parity data, then continue structuredAppend.index = bits.readBits(4); @@ -366,12 +330,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo break; case CodecMode::ECI: { // Count doesn't apply to ECI - int value; - auto status = ParseECIValue(bits, value); - if (StatusIsError(status)) - return status; - - currentCharset = CharacterSetECI::CharsetFromValue(value); + currentCharset = CharacterSetECI::CharsetFromValue(ParseECIValue(bits)); if (currentCharset == CharacterSet::Unknown) return DecodeStatus::FormatError; break; @@ -381,35 +340,31 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo // chinese mode contains a sub set indicator right after mode indicator int subset = bits.readBits(4); int countHanzi = bits.readBits(CharacterCountBits(mode, version)); - if (subset == GB2312_SUBSET) { - auto status = DecodeHanziSegment(bits, countHanzi, result); - if (StatusIsError(status)) - return status; - } + if (subset == GB2312_SUBSET) + DecodeHanziSegment(bits, countHanzi, result); break; } default: { // "Normal" QR code modes: // How many characters will follow, encoded in this mode? int count = bits.readBits(CharacterCountBits(mode, version)); - DecodeStatus status; switch (mode) { - case CodecMode::NUMERIC: status = DecodeNumericSegment(bits, count, result); break; - case CodecMode::ALPHANUMERIC: status = DecodeAlphanumericSegment(bits, count, fc1InEffect, result); break; - case CodecMode::BYTE: status = DecodeByteSegment(bits, count, currentCharset, hintedCharset, result); break; - case CodecMode::KANJI: status = DecodeKanjiSegment(bits, count, result); break; - default: status = DecodeStatus::FormatError; + case CodecMode::NUMERIC: DecodeNumericSegment(bits, count, result); break; + case CodecMode::ALPHANUMERIC: DecodeAlphanumericSegment(bits, count, fc1InEffect, result); break; + case CodecMode::BYTE: DecodeByteSegment(bits, count, currentCharset, hintedCharset, result); break; + case CodecMode::KANJI: DecodeKanjiSegment(bits, count, result); break; + default: return DecodeStatus::FormatError; } - if (StatusIsError(status)) - return status; break; } } } while (mode != CodecMode::TERMINATOR); } - catch (const std::exception &) + catch (const std::exception& e) { - // from readBits() calls +#ifndef NDEBUG + printf("QRDecoder error: %s\n", e.what()); +#endif return DecodeStatus::FormatError; } @@ -424,11 +379,9 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo return DecodeStatus::FormatError; } - std::string symbologyIdentifier("]Q" + std::to_string(symbologyIdModifier)); - return DecoderResult(std::move(bytes), std::move(result)) .setEcLevel(ToString(ecLevel)) - .setSymbologyIdentifier(std::move(symbologyIdentifier)) + .setSymbologyIdentifier("]Q" + std::to_string(symbologyIdModifier)) .setStructuredAppend(structuredAppend); } From 9bf977c24c938caeb2d6fa1b6e31581473c92549 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 18 May 2022 02:28:19 +0200 Subject: [PATCH 0206/1315] DMDecoder: move to consistent exception based error handling + cleanup The code was inconsistently using error status return values and exceptions. Decoded to consistently switch to exceptions as it leads to cleaner code and is less error prone in its usage. Note: the errors that might happen during decoding of the bit stream are indeed exceptional (not happening in any of the black box sample images) so this is an acceptable performance trade-off. Furthermore: removed the unnecessary complicated "mode latching" state machine code. --- core/src/datamatrix/DMDecoder.cpp | 271 +++++++++++------------------- 1 file changed, 99 insertions(+), 172 deletions(-) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index feb469cb38..9320659132 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -51,18 +51,6 @@ namespace ZXing::DataMatrix { */ namespace DecodedBitStreamParser { -enum Mode -{ - FORMAT_ERROR, - DONE, // reached end of code word sequence or a PAD codeword - ASCII_ENCODE, - C40_ENCODE, - TEXT_ENCODE, - ANSIX12_ENCODE, - EDIFACT_ENCODE, - BASE256_ENCODE -}; - /** * See ISO 16022:2006, Annex C Table C.1 * The C40 Basic Character Set (*'s used for placeholders for the shift values) @@ -96,17 +84,6 @@ static const char TEXT_SHIFT3_SET_CHARS[] = { 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 127 }; -// Decoding state -struct State -{ - CharacterSet encoding; - int symbologyIdModifier = 1; // ECC 200 (ISO 16022:2006 Annex N Table N.1) - struct StructuredAppendInfo sai; - bool readerInit = false; - bool firstCodeword = true; - int firstFNC1Position = 1; -}; - struct Shift128 { bool set = false; @@ -152,97 +129,6 @@ static void ParseStructuredAppend(BitSource& bits, StructuredAppendInfo& sai) sai.id = std::to_string((fileId1 << 8) | fileId2); } -/** -* See ISO 16022:2006, 5.2.3 and Annex C, Table C.2 -*/ -static Mode DecodeAsciiSegment(BitSource& bits, std::string& result, std::string& resultTrailer, - std::wstring& resultEncoded, State& state) -{ - Shift128 upperShift; - - while (bits.available() >= 8) { - int oneByte = bits.readBits(8); - switch (oneByte) { - case 0: - return Mode::FORMAT_ERROR; - case 129: // Pad - return Mode::DONE; - case 230: // Latch to C40 encodation - return Mode::C40_ENCODE; - case 231: // Latch to Base 256 encodation - return Mode::BASE256_ENCODE; - case 232: // FNC1 - if (bits.byteOffset() == state.firstFNC1Position || bits.byteOffset() == state.firstFNC1Position + 1) { - // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using - // modifiers that indicate ECI protocol (ISO 16022:2006 Annex N Table N.1, ISO 21471:2020 Annex G Table G.1) - - // Only recognizing an FNC1 as first/second by codeword position (aka symbol character position), not - // by decoded character position, i.e. not recognizing a C40/Text encoded FNC1 (which requires a latch - // and a shift) - if (bits.byteOffset() == state.firstFNC1Position) - state.symbologyIdModifier = 2; // GS1 - else { - state.symbologyIdModifier = 3; // AIM - // Note no AIM Application Indicator format defined, ISO 16022:2006 11.2 - } - } else - result.push_back((char)29); // translate as ASCII 29 - break; - case 233: // Structured Append - if (state.firstCodeword) { // Must be first ISO 16022:2006 5.6.1 - ParseStructuredAppend(bits, state.sai); - state.firstFNC1Position = 5; - } else - return Mode::FORMAT_ERROR; - break; - case 234: // Reader Programming - if (state.firstCodeword) // Must be first ISO 16022:2006 5.2.4.9 - state.readerInit = true; - else - return Mode::FORMAT_ERROR; - break; - case 235: // Upper Shift (shift to Extended ASCII) - upperShift.set = true; - break; - case 236: // 05 Macro - result.append("[)>\x1E""05\x1D"); - resultTrailer.insert(0, "\x1E\x04"); - break; - case 237: // 06 Macro - result.append("[)>\x1E""06\x1D"); - resultTrailer.insert(0, "\x1E\x04"); - break; - case 238: // Latch to ANSI X12 encodation - return Mode::ANSIX12_ENCODE; - case 239: // Latch to Text encodation - return Mode::TEXT_ENCODE; - case 240: // Latch to EDIFACT encodation - return Mode::EDIFACT_ENCODE; - case 241: // ECI Character - state.encoding = CharacterSetECI::OnChangeAppendReset(ParseECIValue(bits), resultEncoded, result, - state.encoding); - break; - default: - if (oneByte <= 128) { // ASCII data (ASCII value + 1) - result.push_back(upperShift(oneByte) - 1); - } else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130) - int value = oneByte - 130; - if (value < 10) // pad with '0' for single digit values - result.push_back('0'); - result.append(std::to_string(value)); - } else if (oneByte >= 242) { // Not to be used in ASCII encodation - // work around encoders that use unlatch to ASCII as last code word (ask upstream) - if (oneByte == 254 && bits.available() == 0) - break; - return Mode::FORMAT_ERROR; - } - } - state.firstCodeword = false; - } - - return Mode::DONE; -} - std::optional> DecodeNextTriple(BitSource& bits) { // Values are encoded in a 16-bit value as (1600 * C1) + (40 * C2) + C3 + 1 @@ -262,18 +148,20 @@ std::optional> DecodeNextTriple(BitSource& bits) return {{a, b, c}}; } +enum class Mode {C40, TEXT}; + /** * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1 (C40) * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2 (Text) */ -static bool DecodeC40OrTextSegment(BitSource& bits, std::string& result, Mode mode) +static void DecodeC40OrTextSegment(BitSource& bits, std::string& result, Mode mode) { // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time Shift128 upperShift; int shift = 0; - const char* BASIC_SET_CHARS = mode == Mode::C40_ENCODE ? C40_BASIC_SET_CHARS : TEXT_BASIC_SET_CHARS; - const char* SHIFT_SET_CHARS = mode == Mode::C40_ENCODE ? C40_SHIFT2_SET_CHARS : TEXT_SHIFT2_SET_CHARS; + const char* BASIC_SET_CHARS = mode == Mode::C40 ? C40_BASIC_SET_CHARS : TEXT_BASIC_SET_CHARS; + const char* SHIFT_SET_CHARS = mode == Mode::C40 ? C40_SHIFT2_SET_CHARS : TEXT_SHIFT2_SET_CHARS; while (auto triple = DecodeNextTriple(bits)) { for (int cValue : *triple) { @@ -284,7 +172,7 @@ static bool DecodeC40OrTextSegment(BitSource& bits, std::string& result, Mode mo else if (cValue < 40) // Size(BASIC_SET_CHARS) result.push_back(upperShift(BASIC_SET_CHARS[cValue])); else - return false; + throw std::runtime_error("invalid value in C40 or Text segment"); break; case 1: result.push_back(upperShift(cValue)); break; case 2: @@ -293,35 +181,33 @@ static bool DecodeC40OrTextSegment(BitSource& bits, std::string& result, Mode mo else if (cValue == 30) // Upper Shift upperShift.set = true; else - return false; + throw std::runtime_error("invalid value in C40 or Text segment"); break; case 3: - if (mode == Mode::C40_ENCODE) + if (mode == Mode::C40) result.push_back(upperShift(cValue + 96)); else if (cValue < Size(TEXT_SHIFT3_SET_CHARS)) result.push_back(upperShift(TEXT_SHIFT3_SET_CHARS[cValue])); else - return false; + throw std::runtime_error("invalid value in C40 or Text segment"); break; - default: return false; + default: throw std::runtime_error("invalid value in C40 or Text segment"); ; } } } - - return true; } /** * See ISO 16022:2006, 5.2.7 */ -static bool DecodeAnsiX12Segment(BitSource& bits, std::string& result) +static void DecodeAnsiX12Segment(BitSource& bits, std::string& result) { while (auto triple = DecodeNextTriple(bits)) { for (int cValue : *triple) { // X12 segment terminator , separator *, sub-element separator >, space static const char segChars[4] = {'\r', '*', '>', ' '}; if (cValue < 0) - return false; + throw std::runtime_error("invalid value in AnsiX12 segment"); else if (cValue < 4) result.push_back(segChars[cValue]); else if (cValue < 14) // 0 - 9 @@ -329,17 +215,15 @@ static bool DecodeAnsiX12Segment(BitSource& bits, std::string& result) else if (cValue < 40) // A - Z result.push_back((char)(cValue + 51)); else - return false; + throw std::runtime_error("invalid value in AnsiX12 segment"); } } - - return true; } /** * See ISO 16022:2006, 5.2.8 and Annex C Table C.3 */ -static bool DecodeEdifactSegment(BitSource& bits, std::string& result) +static void DecodeEdifactSegment(BitSource& bits, std::string& result) { // If there are less than 3 bytes left then it will be encoded as ASCII while (bits.available() >= 24) { @@ -351,7 +235,7 @@ static bool DecodeEdifactSegment(BitSource& bits, std::string& result) // Read rest of byte, which should be 0, and stop if (bits.bitOffset()) bits.readBits(8 - bits.bitOffset()); - return true; + return; } if ((edifactValue & 0x20) == 0) // no 1 in the leading (6th) bit @@ -359,8 +243,6 @@ static bool DecodeEdifactSegment(BitSource& bits, std::string& result) result.push_back(edifactValue); } } - - return true; } /** @@ -376,7 +258,7 @@ static int Unrandomize255State(int randomizedBase256Codeword, int base256Codewor /** * See ISO 16022:2006, 5.2.9 and Annex B, B.2 */ -static bool DecodeBase256Segment(BitSource& bits, std::string& result) +static void DecodeBase256Segment(BitSource& bits, std::string& result) { // Figure out how long the Base 256 Segment is. int codewordPosition = 1 + bits.byteOffset(); // position is 1-indexed @@ -391,21 +273,16 @@ static bool DecodeBase256Segment(BitSource& bits, std::string& result) // We're seeing NegativeArraySizeException errors from users. if (count < 0) - return false; + throw std::runtime_error("invalid count in Base256 segment"); ByteArray bytes(count); for (int i = 0; i < count; i++) { - // Have seen this particular error in the wild, such as at + // readBits(8) may fail, have seen this particular error in the wild, such as at // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2 - if (bits.available() < 8) - return false; - bytes[i] = (uint8_t)Unrandomize255State(bits.readBits(8), codewordPosition++); } result.append(reinterpret_cast(bytes.data()), bytes.size()); - - return true; } ZXING_EXPORT_TEST_ONLY @@ -416,46 +293,96 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b result.reserve(100); std::string resultTrailer; std::wstring resultEncoded; - Mode mode = Mode::ASCII_ENCODE; - State state; - state.encoding = CharacterSetECI::InitEncoding(characterSet); - - while (mode != Mode::FORMAT_ERROR && mode != Mode::DONE) { - if (mode == Mode::ASCII_ENCODE) { - mode = DecodeAsciiSegment(bits, result, resultTrailer, resultEncoded, state); - state.firstCodeword = false; - state.firstFNC1Position = -1; // Only recognize in first segment - } else { - bool decodeOK; - switch (mode) { - case C40_ENCODE: [[fallthrough]]; - case TEXT_ENCODE: decodeOK = DecodeC40OrTextSegment(bits, result, mode); break; - case ANSIX12_ENCODE: decodeOK = DecodeAnsiX12Segment(bits, result); break; - case EDIFACT_ENCODE: decodeOK = DecodeEdifactSegment(bits, result); break; - case BASE256_ENCODE: decodeOK = DecodeBase256Segment(bits, result); break; - default: decodeOK = false; break; - } - mode = decodeOK ? Mode::ASCII_ENCODE : Mode::FORMAT_ERROR; - } - } - if (mode == Mode::FORMAT_ERROR) - return DecodeStatus::FormatError; + CharacterSet encoding = CharacterSetECI::InitEncoding(characterSet); + int symbologyIdModifier = 1; // ECC 200 (ISO 16022:2006 Annex N Table N.1) + struct StructuredAppendInfo sai; + bool readerInit = false; + bool firstCodeword = true; + bool done = false; + int firstFNC1Position = 1; + Shift128 upperShift; - if (state.readerInit && state.sai.index > -1) // Not allowed together ISO 16022:2006 5.2.4.9 + // See ISO 16022:2006, 5.2.3 and Annex C, Table C.2 + try { + while (!done && bits.available() >= 8) { + int oneByte = bits.readBits(8); + switch (oneByte) { + case 0: return DecodeStatus::FormatError; + case 129: done = true; break; // Pad -> we are done, ignore the rest of the bits + case 230: DecodeC40OrTextSegment(bits, result, Mode::C40); break; + case 231: DecodeBase256Segment(bits, result); break; + case 232: // FNC1 + // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using + // modifiers that indicate ECI protocol (ISO 16022:2006 Annex N Table N.1, ISO 21471:2020 Annex G Table G.1) + + // Only recognizing an FNC1 as first/second by codeword position (aka symbol character position), not + // by decoded character position, i.e. not recognizing a C40/Text encoded FNC1 (which requires a latch + // and a shift) + if (bits.byteOffset() == firstFNC1Position) + symbologyIdModifier = 2; // GS1 + else if (bits.byteOffset() == firstFNC1Position + 1) + symbologyIdModifier = 3; // AIM, note no AIM Application Indicator format defined, ISO 16022:2006 11.2 + else + result.push_back((char)29); // translate as ASCII 29 + break; + case 233: // Structured Append + if (!firstCodeword) // Must be first ISO 16022:2006 5.6.1 + return DecodeStatus::FormatError; + ParseStructuredAppend(bits, sai); + firstFNC1Position = 5; + break; + case 234: // Reader Programming + if (!firstCodeword) // Must be first ISO 16022:2006 5.2.4.9 + return DecodeStatus::FormatError; + readerInit = true; + break; + case 235: upperShift.set = true; break; // Upper Shift (shift to Extended ASCII) + case 236: // 05 Macro + result.append("[)>\x1E" "05\x1D"); + resultTrailer.insert(0, "\x1E\x04"); + break; + case 237: // 06 Macro + result.append("[)>\x1E" "06\x1D"); + resultTrailer.insert(0, "\x1E\x04"); + break; + case 238: DecodeAnsiX12Segment(bits, result); break; + case 239: DecodeC40OrTextSegment(bits, result, Mode::TEXT); break; + case 240: DecodeEdifactSegment(bits, result); break; + case 241: encoding = CharacterSetECI::OnChangeAppendReset(ParseECIValue(bits), resultEncoded, result, encoding); break; + default: + if (oneByte <= 128) { // ASCII data (ASCII value + 1) + result.push_back(upperShift(oneByte) - 1); + } else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130) + int value = oneByte - 130; + if (value < 10) // pad with '0' for single digit values + result.push_back('0'); + result.append(std::to_string(value)); + } else if (oneByte >= 242) { // Not to be used in ASCII encodation + // work around encoders that use unlatch to ASCII as last code word (ask upstream) + if (oneByte == 254 && bits.available() == 0) + break; + return DecodeStatus::FormatError; + } + } + firstCodeword = false; + } + } catch (const std::exception& e) { +#ifndef NDEBUG + printf("DMDecoder error: %s\n", e.what()); +#endif return DecodeStatus::FormatError; + } if (resultTrailer.length() > 0) result.append(resultTrailer); - TextDecoder::Append(resultEncoded, reinterpret_cast(result.data()), result.size(), state.encoding); - - std::string symbologyIdentifier("]d" + std::to_string(state.symbologyIdModifier + (isDMRE ? 6 : 0))); + TextDecoder::Append(resultEncoded, reinterpret_cast(result.data()), result.size(), encoding); return DecoderResult(std::move(bytes), std::move(resultEncoded)) - .setSymbologyIdentifier(std::move(symbologyIdentifier)) - .setStructuredAppend(state.sai) - .setReaderInit(state.readerInit); + .setSymbologyIdentifier("]d" + std::to_string(symbologyIdModifier + (isDMRE ? 6 : 0))) + .setStructuredAppend(sai) + .setReaderInit(readerInit); } } // namespace DecodedBitStreamParser From 1925bd8a33f0254c900e92388d2de769aed1d711 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 19 May 2022 11:17:13 +0200 Subject: [PATCH 0207/1315] QRDecoder: simplify logic / increase specification conformance --- core/src/qrcode/QRDecoder.cpp | 63 ++++++++----------- .../qrcode/QRDecodedBitStreamParserTest.cpp | 9 +-- 2 files changed, 31 insertions(+), 41 deletions(-) diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 66b2a41c11..a36c9bbb49 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -264,11 +264,11 @@ static int ParseECIValue(BitSource& bits) * @param bits the stream of bits that might have a terminator code * @param version the QR or micro QR code version */ -bool IsTerminator(const BitSource& bits, const Version& version) +bool IsEndOfStream(const BitSource& bits, const Version& version) { const int bitsRequired = TerminatorBitsLength(version); const int bitsAvailable = std::min(bits.available(), bitsRequired); - return bits.peakBits(bitsAvailable) == 0; + return bitsAvailable == 0 || bits.peakBits(bitsAvailable) == 0; } /** @@ -284,42 +284,43 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo BitSource bits(bytes); std::wstring result; int symbologyIdModifier = 1; // ISO/IEC 18004:2015 Annex F Table F.1 - int appIndValue = -1; // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position) StructuredAppendInfo structuredAppend; - static const int GB2312_SUBSET = 1; const int modeBitLength = CodecModeBitsLength(version); - const int minimumBitsRequired = modeBitLength + CharacterCountBits(CodecMode::NUMERIC, version); try { CharacterSet currentCharset = CharacterSet::Unknown; bool fc1InEffect = false; - CodecMode mode; - do { - // While still another segment to read... - if (bits.available() < minimumBitsRequired || IsTerminator(bits, version)) { - // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here - mode = CodecMode::TERMINATOR; - } else if (modeBitLength == 0) { - // MicroQRCode version 1 is always NUMERIC and modeBitLength is 0 - mode = CodecMode::NUMERIC; - } else { + while(!IsEndOfStream(bits, version)) { + CodecMode mode; + if (modeBitLength == 0) + mode = CodecMode::NUMERIC; // MicroQRCode version 1 is always NUMERIC and modeBitLength is 0 + else mode = CodecModeForBits(bits.readBits(modeBitLength), version.isMicroQRCode()); - } + switch (mode) { - case CodecMode::TERMINATOR: - break; case CodecMode::FNC1_FIRST_POSITION: +// if (!result.empty()) // uncomment to enforce specification +// throw std::runtime_error("GS1 Indicator (FNC1 in first position) at illegal position"); fc1InEffect = true; // In Alphanumeric mode undouble doubled percents and treat single percent as // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using // modifiers that indicate ECI protocol (ISO/IEC 18004:2015 Annex F Table F.1) symbologyIdModifier = 3; break; case CodecMode::FNC1_SECOND_POSITION: + if (!result.empty()) + throw std::runtime_error("AIM Application Indicator (FNC1 in second position) at illegal position"); fc1InEffect = true; // As above symbologyIdModifier = 5; // As above - // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator "00-99" or "A-Za-z" - appIndValue = bits.readBits(8); // Number 00-99 or ASCII value + 100; prefixed to data below + // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position), "00-99" or "A-Za-z" + if (int appInd = bits.readBits(8); appInd < 10) // "00-09" + result += L'0' + std::to_wstring(appInd); + else if (appInd < 100) // "10-99" + result += std::to_wstring(appInd); + else if ((appInd >= 165 && appInd <= 190) || (appInd >= 197 && appInd <= 222)) // "A-Za-z" + result += static_cast(appInd - 100); + else + throw std::runtime_error("Invalid AIM Application Indicator"); break; case CodecMode::STRUCTURED_APPEND: // sequence number and parity is added later to the result metadata @@ -328,20 +329,19 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo structuredAppend.count = bits.readBits(4) + 1; structuredAppend.id = std::to_string(bits.readBits(8)); break; - case CodecMode::ECI: { + case CodecMode::ECI: // Count doesn't apply to ECI currentCharset = CharacterSetECI::CharsetFromValue(ParseECIValue(bits)); if (currentCharset == CharacterSet::Unknown) return DecodeStatus::FormatError; break; - } case CodecMode::HANZI: { // First handle Hanzi mode which does not start with character count // chinese mode contains a sub set indicator right after mode indicator int subset = bits.readBits(4); - int countHanzi = bits.readBits(CharacterCountBits(mode, version)); - if (subset == GB2312_SUBSET) - DecodeHanziSegment(bits, countHanzi, result); + int count = bits.readBits(CharacterCountBits(mode, version)); + if (subset == 1 ) // GB2312_SUBSET + DecodeHanziSegment(bits, count, result); break; } default: { @@ -358,7 +358,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo break; } } - } while (mode != CodecMode::TERMINATOR); + } } catch (const std::exception& e) { @@ -368,17 +368,6 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo return DecodeStatus::FormatError; } - if (appIndValue >= 0) { - if (appIndValue < 10) // "00-09" - result.insert(0, L'0' + std::to_wstring(appIndValue)); - else if (appIndValue < 100) // "10-99" - result.insert(0, std::to_wstring(appIndValue)); - else if ((appIndValue >= 165 && appIndValue <= 190) || (appIndValue >= 197 && appIndValue <= 222)) // "A-Za-z" - result.insert(0, 1, static_cast(appIndValue - 100)); - else - return DecodeStatus::FormatError; - } - return DecoderResult(std::move(bytes), std::move(result)) .setEcLevel(ToString(ecLevel)) .setSymbologyIdentifier("]Q" + std::to_string(symbologyIdModifier)) diff --git a/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp b/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp index 4888138a10..5ab4b15589 100644 --- a/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp +++ b/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp @@ -113,7 +113,7 @@ TEST(QRDecodedBitStreamParserTest, SymbologyIdentifier) EXPECT_EQ(result.symbologyIdentifier(), "]Q3"); EXPECT_EQ(result.text(), L"2001"); // "(20)01" - // GS1 "NUM(4) 2001 FNC1(1st) 301" - FNC1(1st) can occur anywhere + // GS1 "NUM(4) 2001 FNC1(1st) 301" - FNC1(1st) can occur anywhere (this actually violates the specification) result = DecodeBitStream({0x10, 0x10, 0xC8, 0x15, 0x10, 0x0D, 0x2D, 0x00}, version, ecLevel, ""); EXPECT_EQ(result.symbologyIdentifier(), "]Q3"); EXPECT_EQ(result.text(), L"2001301"); // "(20)01(30)1" @@ -124,9 +124,10 @@ TEST(QRDecodedBitStreamParserTest, SymbologyIdentifier) EXPECT_EQ(result.text(), L"99A"); // AIM "BYTE(1) A FNC1(2nd) 99 (0x63) BYTE(1) B" - FNC1(2nd) can occur anywhere - result = DecodeBitStream({0x40, 0x14, 0x19, 0x63, 0x40, 0x14, 0x20, 0x00}, version, ecLevel, ""); - EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); - EXPECT_EQ(result.text(), L"99AB"); // Application Indicator prefixed to data + // Disabled this test, since this violates the specification and the code does support it anymore +// result = DecodeBitStream({0x40, 0x14, 0x19, 0x63, 0x40, 0x14, 0x20, 0x00}, version, ecLevel, ""); +// EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); +// EXPECT_EQ(result.text(), L"99AB"); // Application Indicator prefixed to data // AIM "FNC1(2nd) A (100 + 61 = 0xA5) ANUM(1) B" result = DecodeBitStream({0x9A, 0x52, 0x00, 0x96, 0x00}, version, ecLevel, ""); From f302e1e19002a23ece41e9297e7c9e4bbe0b0f64 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 20 May 2022 16:28:02 +0200 Subject: [PATCH 0208/1315] MCDecoder: code format fixes --- core/src/maxicode/MCDecoder.cpp | 487 ++++++++++++++++---------------- 1 file changed, 238 insertions(+), 249 deletions(-) diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 15b9a7bfa5..922a8a477c 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -52,9 +52,8 @@ static bool CorrectErrors(ByteArray& codewordBytes, int start, int dataCodewords // First read into an array of ints std::vector codewordsInts(codewords / divisor, 0); for (int i = 0; i < codewords; i++) { - if ((mode == ALL) || (i % 2 == (mode - 1))) { + if ((mode == ALL) || (i % 2 == (mode - 1))) codewordsInts[i / divisor] = codewordBytes[i + start]; - } } if (!ReedSolomonDecode(GenericGF::MaxiCodeField64(), codewordsInts, ecCodewords / divisor)) @@ -63,10 +62,10 @@ static bool CorrectErrors(ByteArray& codewordBytes, int start, int dataCodewords // Copy back into array of bytes -- only need to worry about the bytes that were data // We don't care about errors in the error-correction codewords for (int i = 0; i < dataCodewords; i++) { - if ((mode == ALL) || (i % 2 == (mode - 1))) { + if ((mode == ALL) || (i % 2 == (mode - 1))) codewordBytes[i + start] = static_cast(codewordsInts[i / divisor]); - } } + return true; } @@ -77,271 +76,263 @@ static bool CorrectErrors(ByteArray& codewordBytes, int start, int dataCodewords * @author mike32767 * @author Manuel Kasten */ -namespace DecodedBitStreamParser +namespace DecodedBitStreamParser { + +static const short SHI0 = 0x100; +static const short SHI1 = 0x101; +static const short SHI2 = 0x102; +static const short SHI3 = 0x103; +static const short SHI4 = 0x104; +static const short TWSA = 0x105; // two shift A +static const short TRSA = 0x106; // three shift A +static const short LCHA = 0x107; // latch A +static const short LCHB = 0x108; // latch B +static const short LOCK = 0x109; +static const short ECI = 0x10A; +static const short NS = 0x10B; +static const short PAD = 0x10C; + +static const char FS = 0x1C; +static const char GS = 0x1D; +static const char RS = 0x1E; + +// clang-format off +const static std::array CHARSETS[] = { + { // set 0 (A) + '\n', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ECI, FS, GS, RS, NS, + ' ', PAD, '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', SHI1, SHI2, SHI3, SHI4, LCHB, + }, + { // set 1 (B) + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ECI, FS, GS, RS, NS, + '{', PAD, '}', '~', 0x7F, ';', '<', '=', '>', '?', '[', '\\', ']', '^', '_', ' ', + ',', '.', '/', ':', '@', '!', '|', PAD, TWSA, TRSA, PAD, SHI0, SHI2, SHI3, SHI4, LCHA, + }, + { // set 2 (C) + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, ECI, FS, GS, RS, NS, // Note that in original code in Java, NS is not there, which seems to be a bug + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xAA, 0xAC, 0xB1, 0xB2, 0xB3, 0xB5, 0xB9, 0xBA, 0xBC, 0xBD, 0xBE, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, LCHA, 0x20, LOCK, SHI3, SHI4, LCHB, + }, + { // set 3 (D) + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, ECI, FS, GS, RS, NS, + 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xA1, 0xA8, 0xAB, 0xAF, 0xB0, 0xB4, 0xB7, 0xB8, 0xBB, 0xBF, 0x8A, + 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, LCHA, 0x20, SHI2, LOCK, SHI4, LCHB, + }, + { // set 4 (E) + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, ECI, PAD, PAD, 0x1B, NS, + FS, GS, RS, 0x1F, 0x9F, 0xA0, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA9, 0xAD, 0xAE, 0xB6, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, LCHA, 0x20, SHI2, SHI3, LOCK, LCHB, + }, +}; +// clang-format on + +static int GetBit(int bit, const ByteArray& bytes) { - static const short SHI0 = 0x100; - static const short SHI1 = 0x101; - static const short SHI2 = 0x102; - static const short SHI3 = 0x103; - static const short SHI4 = 0x104; - static const short TWSA = 0x105; // two shift A - static const short TRSA = 0x106; // three shift A - static const short LCHA = 0x107; // latch A - static const short LCHB = 0x108; // latch B - static const short LOCK = 0x109; - static const short ECI = 0x10A; - static const short NS = 0x10B; - static const short PAD = 0x10C; - - static const char FS = 0x1C; - static const char GS = 0x1D; - static const char RS = 0x1E; - - const static std::array CHARSETS[] = { - { // set 0 (A) - '\n', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ECI, FS, GS, RS, NS, - ' ', PAD, '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', SHI1, SHI2, SHI3, SHI4, LCHB, - }, - { // set 1 (B) - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ECI, FS, GS, RS, NS, - '{', PAD, '}', '~', 0x7F, ';', '<', '=', '>', '?', '[', '\\', ']', '^', '_', ' ', - ',', '.', '/', ':', '@', '!', '|', PAD, TWSA, TRSA, PAD, SHI0, SHI2, SHI3, SHI4, LCHA, - }, - { // set 2 (C) - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, ECI, FS, GS, RS, NS, // Note that in original code in Java, NS is not there, which seems to be a bug - 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xAA, 0xAC, 0xB1, 0xB2, 0xB3, 0xB5, 0xB9, 0xBA, 0xBC, 0xBD, 0xBE, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, LCHA, 0x20, LOCK, SHI3, SHI4, LCHB, - }, - { // set 3 (D) - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, ECI, FS, GS, RS, NS, - 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xA1, 0xA8, 0xAB, 0xAF, 0xB0, 0xB4, 0xB7, 0xB8, 0xBB, 0xBF, 0x8A, - 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, LCHA, 0x20, SHI2, LOCK, SHI4, LCHB, - }, - { // set 4 (E) - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, ECI, PAD, PAD, 0x1B, NS, - FS, GS, RS, 0x1F, 0x9F, 0xA0, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA9, 0xAD, 0xAE, 0xB6, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, LCHA, 0x20, SHI2, SHI3, LOCK, LCHB, - }, - }; + bit--; + return (bytes[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1; +} - static int GetBit(int bit, const ByteArray& bytes) - { - bit--; - return (bytes[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1; - } +static int GetInt(const ByteArray& bytes, const ByteArray& x) +{ + int len = Size(x); + int val = 0; + for (int i = 0; i < len; i++) + val += GetBit(x[i], bytes) << (len - i - 1); - static int GetInt(const ByteArray& bytes, const ByteArray& x) - { - int len = Size(x); - int val = 0; - for (int i = 0; i < len; i++) { - val += GetBit(x[i], bytes) << (len - i - 1); - } - return val; - } + return val; +} - static int GetPostCode2(const ByteArray& bytes) - { - return GetInt(bytes, { 33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2 }); - } +static int GetPostCode2(const ByteArray& bytes) +{ + return GetInt(bytes, + {33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2}); +} - static int GetPostCode2Length(const ByteArray& bytes) { - return GetInt(bytes, { 39, 40, 41, 42, 31, 32 }); - } - - static std::string GetPostCode3(const ByteArray& bytes) - { - return { - (char) CHARSETS[0].at(GetInt(bytes, { 39, 40, 41, 42, 31, 32 })), - (char) CHARSETS[0].at(GetInt(bytes, { 33, 34, 35, 36, 25, 26 })), - (char) CHARSETS[0].at(GetInt(bytes, { 27, 28, 29, 30, 19, 20 })), - (char) CHARSETS[0].at(GetInt(bytes, { 21, 22, 23, 24, 13, 14 })), - (char) CHARSETS[0].at(GetInt(bytes, { 15, 16, 17, 18, 7, 8 })), - (char) CHARSETS[0].at(GetInt(bytes, { 9, 10, 11, 12, 1, 2 })), - }; - } +static int GetPostCode2Length(const ByteArray& bytes) +{ + return GetInt(bytes, {39, 40, 41, 42, 31, 32}); +} +static std::string GetPostCode3(const ByteArray& bytes) +{ + return { + (char) CHARSETS[0].at(GetInt(bytes, { 39, 40, 41, 42, 31, 32 })), + (char) CHARSETS[0].at(GetInt(bytes, { 33, 34, 35, 36, 25, 26 })), + (char) CHARSETS[0].at(GetInt(bytes, { 27, 28, 29, 30, 19, 20 })), + (char) CHARSETS[0].at(GetInt(bytes, { 21, 22, 23, 24, 13, 14 })), + (char) CHARSETS[0].at(GetInt(bytes, { 15, 16, 17, 18, 7, 8 })), + (char) CHARSETS[0].at(GetInt(bytes, { 9, 10, 11, 12, 1, 2 })), + }; +} - static std::string ToString(int x, int width) - { - std::stringstream buf; - buf << std::setw(width) << std::setfill('0') << x; - return buf.str(); - } +static std::string ToString(int x, int width) +{ + std::stringstream buf; + buf << std::setw(width) << std::setfill('0') << x; + return buf.str(); +} - static int GetCountry(const ByteArray& bytes) - { - return GetInt(bytes, { 53, 54, 43, 44, 45, 46, 47, 48, 37, 38 }); - } +static int GetCountry(const ByteArray& bytes) +{ + return GetInt(bytes, {53, 54, 43, 44, 45, 46, 47, 48, 37, 38}); +} - static int GetServiceClass(const ByteArray& bytes) - { - return GetInt(bytes, { 55, 56, 57, 58, 59, 60, 49, 50, 51, 52 }); - } +static int GetServiceClass(const ByteArray& bytes) +{ + return GetInt(bytes, {55, 56, 57, 58, 59, 60, 49, 50, 51, 52}); +} - /** - * See ISO/IEC 16023:2000 Section 4.6 Table 3 - */ - static int ParseECIValue(const ByteArray& bytes, int& i) - { - int firstByte = bytes[++i]; - if ((firstByte & 0x20) == 0) { - return firstByte; - } - int secondByte = bytes[++i]; - if ((firstByte & 0x10) == 0) { - return ((firstByte & 0x0F) << 6) | secondByte; - } - int thirdByte = bytes[++i]; - if ((firstByte & 0x08) == 0) { - return ((firstByte & 0x07) << 12) | (secondByte << 6) | thirdByte; - } - int fourthByte = bytes[++i]; - return ((firstByte & 0x03) << 18) | (secondByte << 12) | (thirdByte << 6) | fourthByte; - } +/** + * See ISO/IEC 16023:2000 Section 4.6 Table 3 + */ +static int ParseECIValue(const ByteArray& bytes, int& i) +{ + int firstByte = bytes[++i]; + if ((firstByte & 0x20) == 0) + return firstByte; - /** - * See ISO/IEC 16023:2000 Section 4.9.1 Table 5 - */ - static void ParseStructuredAppend(const ByteArray& bytes, int& i, StructuredAppendInfo& sai) - { - const int byte = bytes[++i]; - sai.index = (byte >> 3) & 0x07; - sai.count = (byte & 0x07) + 1; - if (sai.count == 1 || sai.count <= sai.index) { // If info doesn't make sense - sai.count = 0; // Choose to mark count as unknown - } - // No id - } + int secondByte = bytes[++i]; + if ((firstByte & 0x10) == 0) + return ((firstByte & 0x0F) << 6) | secondByte; - static std::wstring GetMessage(const ByteArray& bytes, int start, int len, const std::string& characterSet, - StructuredAppendInfo& sai) - { - std::string sb; - std::wstring sbEncoded; - int shift = -1; - int set = 0; - int lastset = 0; - CharacterSet encoding = CharacterSetECI::InitEncoding(characterSet); - - for (int i = start; i < start + len; i++) { - int c = CHARSETS[set].at(bytes[i]); - switch (c) { - case LCHA: - set = 0; - shift = -1; - break; - case LCHB: - set = 1; - shift = -1; - break; - case SHI0: - case SHI1: - case SHI2: - case SHI3: - case SHI4: - lastset = set; - set = c - SHI0; - shift = 1; - break; - case TWSA: - lastset = set; - set = 0; - shift = 2; - break; - case TRSA: - lastset = set; - set = 0; - shift = 3; - break; - case NS: - sb.append(ToString((bytes[i+1] << 24) + (bytes[i+2] << 18) + (bytes[i+3] << 12) + (bytes[i+4] << 6) + bytes[i+5], 9)); - i += 5; - break; - case LOCK: - shift = -1; - break; - case ECI: - encoding = CharacterSetECI::OnChangeAppendReset(ParseECIValue(bytes, i), sbEncoded, sb, encoding); - break; - case PAD: - if (i == start) { - ParseStructuredAppend(bytes, i, sai); - } - shift = -1; - break; - default: - sb.push_back((unsigned char) c); - } - if (shift-- == 0) { - set = lastset; - } - } - TextDecoder::Append(sbEncoded, reinterpret_cast(sb.data()), sb.size(), encoding); - return sbEncoded; - } + int thirdByte = bytes[++i]; + if ((firstByte & 0x08) == 0) + return ((firstByte & 0x07) << 12) | (secondByte << 6) | thirdByte; - ZXING_EXPORT_TEST_ONLY - DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& characterSet) - { - std::wstring result; - result.reserve(144); - StructuredAppendInfo sai; - switch (mode) { - case 2: - case 3: { - auto postcode = mode == 2 ? ToString(GetPostCode2(bytes), GetPostCode2Length(bytes)) : GetPostCode3(bytes); - auto country = ToString(GetCountry(bytes), 3); - auto service = ToString(GetServiceClass(bytes), 3); - result.append(GetMessage(bytes, 10, 84, characterSet, sai)); - if (result.size() >= 9 && result.compare(0, 7, L"[)>\u001E01\u001D") == 0) { // "[)>" + RS + "01" + GS - result.insert(9, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); - } else { - result.insert(0, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); - } - break; - } - case 4: - case 6: result.append(GetMessage(bytes, 1, 93, characterSet, sai)); break; - case 5: result.append(GetMessage(bytes, 1, 77, characterSet, sai)); break; - } + int fourthByte = bytes[++i]; + return ((firstByte & 0x03) << 18) | (secondByte << 12) | (thirdByte << 6) | fourthByte; +} - // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using modifiers - // that indicate ECI protocol (ISO/IEC 16023:2000 Annexe E Table E1) - std::string symbologyIdentifier; - if (mode == 4 || mode == 5) { - symbologyIdentifier = "]U0"; - } - else if (mode == 2 || mode == 3) { - symbologyIdentifier = "]U1"; +/** + * See ISO/IEC 16023:2000 Section 4.9.1 Table 5 + */ +static void ParseStructuredAppend(const ByteArray& bytes, int& i, StructuredAppendInfo& sai) +{ + int byte = bytes[++i]; + sai.index = (byte >> 3) & 0x07; + sai.count = (byte & 0x07) + 1; + if (sai.count == 1 || sai.count <= sai.index) // If info doesn't make sense + sai.count = 0; // Choose to mark count as unknown + // No id +} + +static std::wstring GetMessage(const ByteArray& bytes, int start, int len, const std::string& characterSet, StructuredAppendInfo& sai) +{ + std::string sb; + std::wstring sbEncoded; + int shift = -1; + int set = 0; + int lastset = 0; + CharacterSet encoding = CharacterSetECI::InitEncoding(characterSet); + + for (int i = start; i < start + len; i++) { + int c = CHARSETS[set].at(bytes[i]); + switch (c) { + case LCHA: + set = 0; + shift = -1; + break; + case LCHB: + set = 1; + shift = -1; + break; + case SHI0: + case SHI1: + case SHI2: + case SHI3: + case SHI4: + lastset = set; + set = c - SHI0; + shift = 1; + break; + case TWSA: + lastset = set; + set = 0; + shift = 2; + break; + case TRSA: + lastset = set; + set = 0; + shift = 3; + break; + case NS: + sb.append( + ToString((bytes[i + 1] << 24) + (bytes[i + 2] << 18) + (bytes[i + 3] << 12) + (bytes[i + 4] << 6) + bytes[i + 5], 9)); + i += 5; + break; + case LOCK: shift = -1; break; + case ECI: encoding = CharacterSetECI::OnChangeAppendReset(ParseECIValue(bytes, i), sbEncoded, sb, encoding); break; + case PAD: + if (i == start) + ParseStructuredAppend(bytes, i, sai); + shift = -1; + break; + default: sb.push_back((unsigned char)c); } - // No identifier defined for mode 6 - return DecoderResult(std::move(bytes), std::move(result)) - .setEcLevel(std::to_wstring(mode)) - .setSymbologyIdentifier(std::move(symbologyIdentifier)) - .setStructuredAppend(sai) - .setReaderInit(mode == 6); + if (shift-- == 0) + set = lastset; } + TextDecoder::Append(sbEncoded, reinterpret_cast(sb.data()), sb.size(), encoding); + return sbEncoded; +} + +ZXING_EXPORT_TEST_ONLY +DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& characterSet) +{ + std::wstring result; + result.reserve(144); + StructuredAppendInfo sai; + switch (mode) { + case 2: + case 3: { + auto postcode = mode == 2 ? ToString(GetPostCode2(bytes), GetPostCode2Length(bytes)) : GetPostCode3(bytes); + auto country = ToString(GetCountry(bytes), 3); + auto service = ToString(GetServiceClass(bytes), 3); + result.append(GetMessage(bytes, 10, 84, characterSet, sai)); + if (result.size() >= 9 && result.compare(0, 7, L"[)>\u001E01\u001D") == 0) // "[)>" + RS + "01" + GS + result.insert(9, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); + else + result.insert(0, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); + break; + } + case 4: + case 6: result.append(GetMessage(bytes, 1, 93, characterSet, sai)); break; + case 5: result.append(GetMessage(bytes, 1, 77, characterSet, sai)); break; + } + + // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using modifiers + // that indicate ECI protocol (ISO/IEC 16023:2000 Annexe E Table E1) + std::string symbologyIdentifier; + if (mode == 4 || mode == 5) + symbologyIdentifier = "]U0"; + else if (mode == 2 || mode == 3) + symbologyIdentifier = "]U1"; + // No identifier defined for mode 6 + + return DecoderResult(std::move(bytes), std::move(result)) + .setEcLevel(std::to_wstring(mode)) + .setSymbologyIdentifier(std::move(symbologyIdentifier)) + .setStructuredAppend(sai) + .setReaderInit(mode == 6); +} } // DecodedBitStreamParser -DecoderResult -Decoder::Decode(const BitMatrix& bits, const std::string& characterSet) +DecoderResult Decoder::Decode(const BitMatrix& bits, const std::string& characterSet) { ByteArray codewords = BitMatrixParser::ReadCodewords(bits); - if (!CorrectErrors(codewords, 0, 10, 10, ALL)) { + if (!CorrectErrors(codewords, 0, 10, 10, ALL)) return DecodeStatus::ChecksumError; - } + int mode = codewords[0] & 0x0F; ByteArray datawords; switch (mode) { @@ -349,18 +340,16 @@ Decoder::Decode(const BitMatrix& bits, const std::string& characterSet) case 3: // Structured Carrier Message (alphanumeric postcode) case 4: // Standard Symbol case 6: // Reader Programming - if (CorrectErrors(codewords, 20, 84, 40, EVEN) && CorrectErrors(codewords, 20, 84, 40, ODD)) { + if (CorrectErrors(codewords, 20, 84, 40, EVEN) && CorrectErrors(codewords, 20, 84, 40, ODD)) datawords.resize(94, 0); - } else { + else return DecodeStatus::ChecksumError; - } break; case 5: // Full ECC - if (CorrectErrors(codewords, 20, 68, 56, EVEN) && CorrectErrors(codewords, 20, 68, 56, ODD)) { + if (CorrectErrors(codewords, 20, 68, 56, EVEN) && CorrectErrors(codewords, 20, 68, 56, ODD)) datawords.resize(78, 0); - } else { + else return DecodeStatus::ChecksumError; - } break; default: return DecodeStatus::FormatError; } From ec50173369656b470a73f787041cd1c5f3dd356d Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 21 May 2022 13:23:18 +0200 Subject: [PATCH 0209/1315] AZDecoder: improve comments (non-functional change) --- core/src/aztec/AZDecoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 2e196ad3bc..1a122025fd 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -292,8 +292,8 @@ AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet) CharacterSet encoding = CharacterSetECI::InitEncoding(characterSet); // Check for Structured Append - need 4 5-bit words, beginning with ML UL, ending with index and count - bool haveStructuredAppend = Size(bits) > 20 && ToInt(bits, 0, 5) == 29 // ML (UPPER table) - && ToInt(bits, 5, 5) == 29; // UL (MIXED table) + bool haveStructuredAppend = Size(bits) > 20 && ToInt(bits, 0, 5) == 29 // latch to MIXED (from UPPER) + && ToInt(bits, 5, 5) == 29; // latch back to UPPER (from MIXED) bool haveFNC1 = false; auto remBits = bits.range(); From c7e71eba94e038c0cd286e1d43073d4535ac9067 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 21 May 2022 13:53:39 +0200 Subject: [PATCH 0210/1315] Result: remove one unnecessary constructor (go through DecoderResult) --- core/src/DecoderResult.h | 2 ++ core/src/Result.cpp | 26 +++++++++-------------- core/src/Result.h | 4 ---- core/src/oned/ODDataBarExpandedReader.cpp | 8 ++++--- core/src/oned/ODDataBarReader.cpp | 11 +++++----- test/blackbox/BlackboxTestRunner.cpp | 9 ++++++-- 6 files changed, 29 insertions(+), 31 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index ea158eff18..935a884648 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -45,6 +45,7 @@ class DecoderResult std::wstring _ecLevel; int _errorsCorrected = -1; int _erasures = -1; + int _lineCount = -1; std::string _symbologyIdentifier; StructuredAppendInfo _structuredAppend; bool _isMirrored = false; @@ -92,6 +93,7 @@ class DecoderResult ZX_PROPERTY(std::wstring, ecLevel, setEcLevel) ZX_PROPERTY(int, errorsCorrected, setErrorsCorrected) ZX_PROPERTY(int, erasures, setErasures) + ZX_PROPERTY(int, lineCount, setLineCount) ZX_PROPERTY(std::string, symbologyIdentifier, setSymbologyIdentifier) ZX_PROPERTY(StructuredAppendInfo, structuredAppend, setStructuredAppend) ZX_PROPERTY(bool, isMirrored, setIsMirrored) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 0aad42a4ec..5a9e6d4563 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -25,24 +25,17 @@ namespace ZXing { -Result::Result(std::wstring&& text, Position&& position, BarcodeFormat format, std::string&& symbologyIdentifier, - ByteArray&& rawBytes, StructuredAppendInfo&& sai, const bool readerInit, int lineCount) - : _format(format), - _text(std::move(text)), - _position(std::move(position)), +Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, + std::string&& symbologyIdentifier, ByteArray&& rawBytes, const bool readerInit) + : + _format(format), + _text(TextDecoder::FromLatin1(text)), + _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), + _numBits(Size(_rawBytes) * 8), _symbologyIdentifier(std::move(symbologyIdentifier)), - _sai(std::move(sai)), _readerInit(readerInit), - _lineCount(lineCount) -{ - _numBits = Size(_rawBytes) * 8; -} - -Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, - std::string&& symbologyIdentifier, ByteArray&& rawBytes, const bool readerInit) - : Result(TextDecoder::FromLatin1(text), Line(y, xStart, xStop), format, std::move(symbologyIdentifier), - std::move(rawBytes), {}, readerInit) + _lineCount(0) {} Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format) @@ -56,7 +49,8 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat _symbologyIdentifier(decodeResult.symbologyIdentifier()), _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), - _readerInit(decodeResult.readerInit()) + _readerInit(decodeResult.readerInit()), + _lineCount(decodeResult.lineCount()) { // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } diff --git a/core/src/Result.h b/core/src/Result.h index 1d90b835e3..a0cdeb0e5d 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -42,10 +42,6 @@ class Result public: explicit Result(DecodeStatus status) : _status(status) {} - Result(std::wstring&& text, Position&& position, BarcodeFormat format, std::string&& symbologyIdentifier = "", - ByteArray&& rawBytes = {}, StructuredAppendInfo&& sai = {}, const bool readerInit = false, - int lineCount = 0); - // 1D convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, std::string&& symbologyIdentifier = "", ByteArray&& rawBytes = {}, const bool readerInit = false); diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 769b279648..9421a4b7be 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -19,6 +19,7 @@ #include "ODDataBarExpandedReader.h" #include "BarcodeFormat.h" +#include "DecoderResult.h" #include "ODDataBarCommon.h" #include "Result.h" #include "TextDecoder.h" @@ -388,9 +389,10 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, // TODO: EstimatePosition misses part of the symbol in the stacked case where the last row contains less pairs than // the first - return {TextDecoder::FromLatin1(txt), EstimatePosition(pairs.front(), pairs.back()), - BarcodeFormat::DataBarExpanded, std::move(symbologyIdentifier), {}, {}, false, - EstimateLineCount(pairs.front(), pairs.back())}; + return {DecoderResult({}, TextDecoder::FromLatin1(txt)) + .setSymbologyIdentifier("]e0") + .setLineCount(EstimateLineCount(pairs.front(), pairs.back())), + EstimatePosition(pairs.front(), pairs.back()), BarcodeFormat::DataBarExpanded}; } } // namespace ZXing::OneD diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index f418fd64e8..e45ae3e8c9 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -19,6 +19,7 @@ #include "ODDataBarReader.h" #include "BarcodeFormat.h" +#include "DecoderResult.h" #include "GTIN.h" #include "ODDataBarCommon.h" #include "Result.h" @@ -208,12 +209,10 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, for (const auto& rightPair : prevState->rightPairs) if (ChecksumIsValid(leftPair, rightPair)) { // Symbology identifier ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - std::string symbologyIdentifier("]e0"); - - Result res{TextDecoder::FromLatin1(ConstructText(leftPair, rightPair)), - EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar, - std::move(symbologyIdentifier), {}, {}, false, - EstimateLineCount(leftPair, rightPair)}; + Result res{DecoderResult({}, TextDecoder::FromLatin1(ConstructText(leftPair, rightPair))) + .setSymbologyIdentifier("]e0") + .setLineCount(EstimateLineCount(leftPair, rightPair)), + EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar}; prevState->leftPairs.erase(leftPair); prevState->rightPairs.erase(rightPair); diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index ab75e6169e..fce059884f 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -17,6 +17,7 @@ #include "BlackboxTestRunner.h" +#include "DecoderResult.h" #include "ImageLoader.h" #include "ReadBarcode.h" #include "TextUtfEncoding.h" @@ -278,8 +279,12 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi text.append(r.text()); const auto& first = allResults.front(); - StructuredAppendInfo sai{first.sequenceIndex(), first.sequenceSize(), first.sequenceId()}; - return {std::move(text), {}, first.format(), std::string(first.symbologyIdentifier()), {}, std::move(sai), first.readerInit()}; + return {DecoderResult({}, std::move(text)) + .setStructuredAppend({first.sequenceIndex(), first.sequenceSize(), first.sequenceId()}) + .setSymbologyIdentifier(first.symbologyIdentifier()) + .setReaderInit(first.readerInit()), + {}, + first.format()}; } static void doRunStructuredAppendTest(const fs::path& directory, std::string_view format, int totalTests, From a93de020ae8ea87270fc26beadbe2c34360233fd Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 21 May 2022 15:42:56 +0200 Subject: [PATCH 0211/1315] CharacterSetECI: function renaming for better self-documentation --- core/src/CharacterSetECI.cpp | 6 +++--- core/src/CharacterSetECI.h | 4 ++-- core/src/pdf417/PDFHighLevelEncoder.cpp | 2 +- core/src/qrcode/QRDecoder.cpp | 2 +- core/src/qrcode/QREncoder.cpp | 2 +- test/unit/CharacterSetECITest.cpp | 14 +++++++------- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/src/CharacterSetECI.cpp b/core/src/CharacterSetECI.cpp index c9142f3891..86cd507042 100644 --- a/core/src/CharacterSetECI.cpp +++ b/core/src/CharacterSetECI.cpp @@ -134,7 +134,7 @@ static const std::map ECI_NAME_TO_CHA {"BINARY", CharacterSet::BINARY}, }; -CharacterSet CharsetFromValue(int value) +CharacterSet ECI2CharacterSet(int value) { auto it = ECI_VALUE_TO_CHARSET.find(value); if (it != ECI_VALUE_TO_CHARSET.end()) { @@ -143,7 +143,7 @@ CharacterSet CharsetFromValue(int value) return CharacterSet::Unknown; } -int ValueForCharset(CharacterSet charset) +int Charset2ECI(CharacterSet charset) { // Special case ISO8859_1 to avoid obsolete ECI 1 if (charset == CharacterSet::ISO8859_1) { @@ -183,7 +183,7 @@ CharacterSet OnChangeAppendReset(const int eci, std::wstring& encoded, std::stri { // Character set ECIs only if (eci >= 0 && eci <= 899) { - auto encodingNew = CharacterSetECI::CharsetFromValue(eci); + auto encodingNew = CharacterSetECI::ECI2CharacterSet(eci); if (encodingNew != CharacterSet::Unknown && encodingNew != encoding) { // Encode data so far in current encoding and reset TextDecoder::Append(encoded, reinterpret_cast(data.data()), data.size(), encoding); diff --git a/core/src/CharacterSetECI.h b/core/src/CharacterSetECI.h index ee66d55f21..03d52cc236 100644 --- a/core/src/CharacterSetECI.h +++ b/core/src/CharacterSetECI.h @@ -33,13 +33,13 @@ namespace CharacterSetECI { * @param value character set ECI value * @return {@code CharacterSet} representing ECI of given value, or {@code CharacterSet::Unknown} if it is unsupported */ -CharacterSet CharsetFromValue(int value); +CharacterSet ECI2CharacterSet(int value); /** * @param charset {@code CharacterSet} representing ECI * @return ECI of given {@code CharacterSet}, or -1 if it is unsupported */ -int ValueForCharset(CharacterSet charset); +int Charset2ECI(CharacterSet charset); /** * @param name character set ECI encoding name diff --git a/core/src/pdf417/PDFHighLevelEncoder.cpp b/core/src/pdf417/PDFHighLevelEncoder.cpp index c37b41c11b..2066d78c0b 100644 --- a/core/src/pdf417/PDFHighLevelEncoder.cpp +++ b/core/src/pdf417/PDFHighLevelEncoder.cpp @@ -514,7 +514,7 @@ HighLevelEncoder::EncodeHighLevel(const std::wstring& msg, Compaction compaction //the codewords 0..928 are encoded as Unicode characters if (encoding != CharacterSet::ISO8859_1) { - EncodingECI(CharacterSetECI::ValueForCharset(encoding), highLevel); + EncodingECI(CharacterSetECI::Charset2ECI(encoding), highLevel); } int len = Size(msg); diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index a36c9bbb49..cd59127196 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -331,7 +331,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo break; case CodecMode::ECI: // Count doesn't apply to ECI - currentCharset = CharacterSetECI::CharsetFromValue(ParseECIValue(bits)); + currentCharset = CharacterSetECI::ECI2CharacterSet(ParseECIValue(bits)); if (currentCharset == CharacterSet::Unknown) return DecodeStatus::FormatError; break; diff --git a/core/src/qrcode/QREncoder.cpp b/core/src/qrcode/QREncoder.cpp index 20285e9379..1601623196 100644 --- a/core/src/qrcode/QREncoder.cpp +++ b/core/src/qrcode/QREncoder.cpp @@ -114,7 +114,7 @@ CodecMode ChooseMode(const std::wstring& content, CharacterSet encoding) */ static void AppendECI(CharacterSet eci, BitArray& bits) { - int eciValue = CharacterSetECI::ValueForCharset(eci); + int eciValue = CharacterSetECI::Charset2ECI(eci); if (eciValue >= 0 && eciValue <= 999999) { bits.appendBits(static_cast(CodecMode::ECI), 4); if (eciValue <= 127) { diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index be587237d4..a5ced0a1ee 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -23,14 +23,14 @@ using namespace ZXing; using namespace ZXing::CharacterSetECI; using namespace testing; -TEST(CharacterSetECITest, ValueForCharset) +TEST(CharacterSetECITest, Charset2ECI) { - EXPECT_EQ(ValueForCharset(CharacterSet::ISO8859_1), 3); - EXPECT_EQ(ValueForCharset(CharacterSet::ISO8859_2), 4); - EXPECT_EQ(ValueForCharset(CharacterSet::ASCII), 27); - EXPECT_EQ(ValueForCharset(CharacterSet::EUC_KR), 30); - EXPECT_EQ(ValueForCharset(CharacterSet::BINARY), 899); - EXPECT_EQ(ValueForCharset(CharacterSet::Unknown), -1); + EXPECT_EQ(Charset2ECI(CharacterSet::ISO8859_1), 3); + EXPECT_EQ(Charset2ECI(CharacterSet::ISO8859_2), 4); + EXPECT_EQ(Charset2ECI(CharacterSet::ASCII), 27); + EXPECT_EQ(Charset2ECI(CharacterSet::EUC_KR), 30); + EXPECT_EQ(Charset2ECI(CharacterSet::BINARY), 899); + EXPECT_EQ(Charset2ECI(CharacterSet::Unknown), -1); } TEST(CharacterSetECITest, InitEncoding) From f5c6c62a05c46b55d6aa4bcb6abb07308421f43c Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 21 May 2022 16:21:44 +0200 Subject: [PATCH 0212/1315] Improve binary data support (1 of N) This is part of a somewhat larger effort to improve the out of the box support for reading barcode symbols that contain binary data. A lengthy discussion about the goals and design decisions can be found in #334. From the user facing API, this manifests in the new property `ByteArray Result::binary()`. This is still a WIP and may change in the future. --- core/CMakeLists.txt | 2 + core/src/ByteArray.h | 15 +++ core/src/Content.cpp | 92 +++++++++++++++ core/src/Content.h | 53 +++++++++ core/src/DecoderResult.h | 12 +- core/src/Result.cpp | 2 + core/src/Result.h | 4 + core/src/datamatrix/DMDecoder.cpp | 29 ++--- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 5 +- core/src/qrcode/QRDecoder.cpp | 108 ++++++++---------- example/ZXingReader.cpp | 1 + test/blackbox/BlackboxTestRunner.cpp | 14 ++- 12 files changed, 252 insertions(+), 85 deletions(-) create mode 100644 core/src/Content.cpp create mode 100644 core/src/Content.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 0d4bff9f0c..461b0832f3 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -84,6 +84,8 @@ if (BUILD_READERS) src/BinaryBitmap.cpp src/BitSource.h src/BitSource.cpp + src/Content.h + src/Content.cpp src/DecodeHints.h src/DecodeHints.cpp src/DecodeStatus.h diff --git a/core/src/ByteArray.h b/core/src/ByteArray.h index efbd3072c1..7dc5f96cea 100644 --- a/core/src/ByteArray.h +++ b/core/src/ByteArray.h @@ -16,6 +16,8 @@ */ #include +#include +#include #include namespace ZXing { @@ -29,6 +31,19 @@ class ByteArray : public std::vector ByteArray() = default; ByteArray(std::initializer_list list) : std::vector(list) {} explicit ByteArray(int len) : std::vector(len, 0) {} + explicit ByteArray(const std::string& str) : std::vector(str.begin(), str.end()) {} + + void append(const ByteArray& other) { insert(end(), other.begin(), other.end()); } }; +inline std::string ToHex(const ByteArray& bytes) +{ + std::string res(bytes.size() * 3, ' '); + + for (size_t i = 0; i < bytes.size(); ++i) + sprintf(&res[i * 3], "%02X ", bytes[i]); + + return res.substr(0, res.size()-1); +} + } // ZXing diff --git a/core/src/Content.cpp b/core/src/Content.cpp new file mode 100644 index 0000000000..4e2e983db0 --- /dev/null +++ b/core/src/Content.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2022 Axel Waggershauser + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Content.h" + +#include "CharacterSetECI.h" +#include "TextDecoder.h" +#include "ZXContainerAlgorithms.h" + +namespace ZXing { + +void Content::switchEncoding(CharacterSet cs, bool isECI) +{ + if (isECI || !hasECI) { + if (encodings.back().second == Size(binary)) + encodings.back().first = cs; // no point in recording 0 length segments + else + encodings.emplace_back(cs, Size(binary)); + } + hasECI |= isECI; +} + +std::wstring Content::text() const +{ + auto fallbackCS = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); + if (!hasECI && fallbackCS == CharacterSet::Unknown) + fallbackCS = guessEncoding(); + + std::wstring wstr; + for (int i = 0; i < Size(encodings); ++i) { + auto [cs, start] = encodings[i]; + int end = i + 1 == Size(encodings) ? Size(binary) : encodings[i + 1].second; + + if (cs == CharacterSet::Unknown) + cs = fallbackCS; + + TextDecoder::Append(wstr, binary.data() + start, end - start, cs); + } + return wstr; +} + +CharacterSet Content::guessEncoding() const +{ + // assemble all blocks with unknown encoding + ByteArray input; + for (int i = 0; i < Size(encodings); ++i) { + auto [cs, start] = encodings[i]; + int end = i + 1 == Size(encodings) ? Size(binary) : encodings[i + 1].second; + if (cs == CharacterSet::Unknown) + input.insert(input.end(), binary.begin() + start, binary.begin() + end); + } + + if (input.empty()) + return CharacterSet::Unknown; + + return TextDecoder::GuessEncoding(input.data(), input.size(), CharacterSet::BINARY); +} + +ContentType Content::type() const +{ + auto isBinary = [](Encoding e) { return e.first == CharacterSet::BINARY || e.first == CharacterSet::Unknown; }; + + if (hasECI) { + if (std::none_of(encodings.begin(), encodings.end(), isBinary)) + return ContentType::Text; + if (std::all_of(encodings.begin(), encodings.end(), isBinary)) + return ContentType::Binary; + } else { + if (std::none_of(encodings.begin(), encodings.end(), isBinary)) + return ContentType::Text; + auto cs = guessEncoding(); + if (cs == CharacterSet::BINARY) + return ContentType::Binary; + } + + return ContentType::Mixed; +} + +} // namespace ZXing diff --git a/core/src/Content.h b/core/src/Content.h new file mode 100644 index 0000000000..e6407ed2ea --- /dev/null +++ b/core/src/Content.h @@ -0,0 +1,53 @@ +#pragma once +/* +* Copyright 2022 Axel Waggershauser +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ByteArray.h" +#include "CharacterSet.h" + +namespace ZXing { + +enum class ContentType { Text, Binary, Mixed }; + +class Content +{ + bool hasECI = false; + +public: + ByteArray binary; + using Encoding = std::pair; + std::vector encodings = {{CharacterSet::Unknown, 0}}; + std::string hintedCharset; + + void switchEncoding(CharacterSet cs, bool isECI = false); + + void reserve(int count) { binary.reserve(binary.size() + count); } + + void push_back(uint8_t val) { binary.push_back(val); } + void append(const std::string& str) { binary.insert(binary.end(), str.begin(), str.end()); } + void append(const ByteArray& bytes) { binary.insert(binary.end(), bytes.begin(), bytes.end()); } + + void operator+=(char val) { push_back(val); } + void operator+=(const std::string& str) { append(str); } + + bool empty() const { return binary.empty(); } + + std::wstring text() const; + CharacterSet guessEncoding() const; + ContentType type() const; +}; + +} // ZXing diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 935a884648..81fc060479 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -17,6 +17,7 @@ */ #include "ByteArray.h" +#include "Content.h" #include "DecodeStatus.h" #include "StructuredAppend.h" #include "ZXContainerAlgorithms.h" @@ -40,6 +41,7 @@ class DecoderResult { DecodeStatus _status = DecodeStatus::NoError; ByteArray _rawBytes; + Content _content; int _numBits = 0; std::wstring _text; std::wstring _ecLevel; @@ -57,9 +59,15 @@ class DecoderResult public: DecoderResult(DecodeStatus status) : _status(status) {} - DecoderResult(ByteArray&& rawBytes, std::wstring&& text) : _rawBytes(std::move(rawBytes)), _text(std::move(text)) + DecoderResult(ByteArray&& rawBytes, std::wstring&& text, Content&& binary = {}) + : _rawBytes(std::move(rawBytes)), _content(std::move(binary)), _text(std::move(text)) { _numBits = 8 * Size(_rawBytes); + if (_text.empty()) + _text = _content.text(); + // provide some best guess fallback for barcodes not, yet supporting the content info + if (_content.empty() && std::all_of(_text.begin(), _text.end(), [](auto c) { return c < 256; })) + std::for_each(_text.begin(), _text.end(), [this](wchar_t c) { _content += static_cast(c); }); } DecoderResult() = default; @@ -73,6 +81,8 @@ class DecoderResult ByteArray&& rawBytes() && { return std::move(_rawBytes); } const std::wstring& text() const & { return _text; } std::wstring&& text() && { return std::move(_text); } + const ByteArray& binary() const & { return _content.binary; } + ByteArray&& binary() && { return std::move(_content.binary); } // Simple macro to set up getter/setter methods that save lots of boilerplate. // It sets up a standard 'const & () const', 2 setters for setting lvalues via diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 5a9e6d4563..2f0c4be75c 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -30,6 +30,7 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor : _format(format), _text(TextDecoder::FromLatin1(text)), + _binary(text), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), _numBits(Size(_rawBytes) * 8), @@ -42,6 +43,7 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat : _status(decodeResult.errorCode()), _format(format), _text(std::move(decodeResult).text()), + _binary(std::move(decodeResult).binary()), _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), diff --git a/core/src/Result.h b/core/src/Result.h index a0cdeb0e5d..3f7ee54f09 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -56,6 +56,9 @@ class Result const std::wstring& text() const { return _text; } + // WARNING: this is an experimental API and may change/disappear + const ByteArray& binary() const { return _binary; } + const Position& position() const { return _position; } void setPosition(Position pos) { _position = pos; } @@ -120,6 +123,7 @@ class Result DecodeStatus _status = DecodeStatus::NoError; BarcodeFormat _format = BarcodeFormat::None; std::wstring _text; + ByteArray _binary; Position _position; ByteArray _rawBytes; int _numBits = 0; diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 9320659132..c74be87345 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -154,7 +154,7 @@ enum class Mode {C40, TEXT}; * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1 (C40) * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2 (Text) */ -static void DecodeC40OrTextSegment(BitSource& bits, std::string& result, Mode mode) +static void DecodeC40OrTextSegment(BitSource& bits, Content& result, Mode mode) { // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time Shift128 upperShift; @@ -200,7 +200,7 @@ static void DecodeC40OrTextSegment(BitSource& bits, std::string& result, Mode mo /** * See ISO 16022:2006, 5.2.7 */ -static void DecodeAnsiX12Segment(BitSource& bits, std::string& result) +static void DecodeAnsiX12Segment(BitSource& bits, Content& result) { while (auto triple = DecodeNextTriple(bits)) { for (int cValue : *triple) { @@ -223,7 +223,7 @@ static void DecodeAnsiX12Segment(BitSource& bits, std::string& result) /** * See ISO 16022:2006, 5.2.8 and Annex C Table C.3 */ -static void DecodeEdifactSegment(BitSource& bits, std::string& result) +static void DecodeEdifactSegment(BitSource& bits, Content& result) { // If there are less than 3 bytes left then it will be encoded as ASCII while (bits.available() >= 24) { @@ -258,7 +258,7 @@ static int Unrandomize255State(int randomizedBase256Codeword, int base256Codewor /** * See ISO 16022:2006, 5.2.9 and Annex B, B.2 */ -static void DecodeBase256Segment(BitSource& bits, std::string& result) +static void DecodeBase256Segment(BitSource& bits, Content& result) { // Figure out how long the Base 256 Segment is. int codewordPosition = 1 + bits.byteOffset(); // position is 1-indexed @@ -275,26 +275,22 @@ static void DecodeBase256Segment(BitSource& bits, std::string& result) if (count < 0) throw std::runtime_error("invalid count in Base256 segment"); - ByteArray bytes(count); + result.reserve(count); for (int i = 0; i < count; i++) { // readBits(8) may fail, have seen this particular error in the wild, such as at // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2 - bytes[i] = (uint8_t)Unrandomize255State(bits.readBits(8), codewordPosition++); + result += static_cast(Unrandomize255State(bits.readBits(8), codewordPosition++)); } - - result.append(reinterpret_cast(bytes.data()), bytes.size()); } ZXING_EXPORT_TEST_ONLY DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const bool isDMRE) { BitSource bits(bytes); - std::string result; - result.reserve(100); + Content result; + result.hintedCharset = characterSet; std::string resultTrailer; - std::wstring resultEncoded; - CharacterSet encoding = CharacterSetECI::InitEncoding(characterSet); int symbologyIdModifier = 1; // ECC 200 (ISO 16022:2006 Annex N Table N.1) struct StructuredAppendInfo sai; bool readerInit = false; @@ -349,7 +345,7 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b case 238: DecodeAnsiX12Segment(bits, result); break; case 239: DecodeC40OrTextSegment(bits, result, Mode::TEXT); break; case 240: DecodeEdifactSegment(bits, result); break; - case 241: encoding = CharacterSetECI::OnChangeAppendReset(ParseECIValue(bits), resultEncoded, result, encoding); break; + case 241: result.switchEncoding(CharacterSetECI::ECI2CharacterSet(ParseECIValue(bits)), true); break; default: if (oneByte <= 128) { // ASCII data (ASCII value + 1) result.push_back(upperShift(oneByte) - 1); @@ -374,12 +370,9 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b return DecodeStatus::FormatError; } - if (resultTrailer.length() > 0) - result.append(resultTrailer); - - TextDecoder::Append(resultEncoded, reinterpret_cast(result.data()), result.size(), encoding); + result.append(resultTrailer); - return DecoderResult(std::move(bytes), std::move(resultEncoded)) + return DecoderResult(std::move(bytes), {}, std::move(result)) .setSymbologyIdentifier("]d" + std::to_string(symbologyIdModifier + (isDMRE ? 6 : 0))) .setStructuredAppend(sai) .setReaderInit(readerInit); diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index ab61c4c6c8..af57d17999 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -852,7 +852,10 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c sai.id = resultMetadata->fileId(); } - return DecoderResult(ByteArray(), std::move(resultEncoded)) + Content content; + content.append(result); + + return DecoderResult(ByteArray(), std::move(resultEncoded), std::move(content)) .setEcLevel(std::to_wstring(ecLevel)) // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using modifier // that indicates ECI protocol (ISO/IEC 15438:2015 Annex L Table L.1) diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index cd59127196..5065401fda 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -69,12 +69,12 @@ static bool CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) /** * See specification GBT 18284-2000 */ -static void DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) +static void DecodeHanziSegment(BitSource& bits, int count, Content& result) { - // Each character will require 2 bytes. Read the characters as 2-byte pairs - // and decode as GB2312 afterwards - ByteArray buffer; - buffer.reserve(2 * count); + // Each character will require 2 bytes, decode as GB2312 + result.switchEncoding(CharacterSet::GB2312); + result.reserve(2 * count); + while (count > 0) { // Each 13 bits encodes a 2-byte character int twoBytes = bits.readBits(13); @@ -86,20 +86,19 @@ static void DecodeHanziSegment(BitSource& bits, int count, std::wstring& result) // In the 0xB0A1 to 0xFAFE range assembledTwoBytes += 0x0A6A1; } - buffer.push_back(static_cast((assembledTwoBytes >> 8) & 0xFF)); - buffer.push_back(static_cast(assembledTwoBytes & 0xFF)); + result += static_cast((assembledTwoBytes >> 8) & 0xFF); + result += static_cast(assembledTwoBytes & 0xFF); count--; } - - TextDecoder::Append(result, buffer.data(), Size(buffer), CharacterSet::GB2312); } -static void DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) +static void DecodeKanjiSegment(BitSource& bits, int count, Content& result) { // Each character will require 2 bytes. Read the characters as 2-byte pairs // and decode as Shift_JIS afterwards - ByteArray buffer; - buffer.reserve(2 * count); + result.switchEncoding(CharacterSet::Shift_JIS); + result.reserve(2 * count); + while (count > 0) { // Each 13 bits encodes a 2-byte character int twoBytes = bits.readBits(13); @@ -111,34 +110,19 @@ static void DecodeKanjiSegment(BitSource& bits, int count, std::wstring& result) // In the 0xE040 to 0xEBBF range assembledTwoBytes += 0x0C140; } - buffer.push_back(static_cast(assembledTwoBytes >> 8)); - buffer.push_back(static_cast(assembledTwoBytes)); + result += static_cast(assembledTwoBytes >> 8); + result += static_cast(assembledTwoBytes); count--; } - - TextDecoder::Append(result, buffer.data(), Size(buffer), CharacterSet::Shift_JIS); } -static void DecodeByteSegment(BitSource& bits, int count, CharacterSet currentCharset, const std::string& hintedCharset, - std::wstring& result) +static void DecodeByteSegment(BitSource& bits, int count, Content& result) { - ByteArray readBytes(count); + result.switchEncoding(CharacterSet::Unknown); + result.reserve(count); + for (int i = 0; i < count; i++) - readBytes[i] = static_cast(bits.readBits(8)); - - if (currentCharset == CharacterSet::Unknown) { - // The spec isn't clear on this mode; see - // section 6.4.5: t does not say which encoding to assuming - // upon decoding. I have seen ISO-8859-1 used as well as - // Shift_JIS -- without anything like an ECI designator to - // give a hint. - if (!hintedCharset.empty()) - currentCharset = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); - - if (currentCharset == CharacterSet::Unknown) - currentCharset = TextDecoder::GuessEncoding(readBytes.data(), Size(readBytes)); - } - TextDecoder::Append(result, readBytes.data(), Size(readBytes), currentCharset); + result += static_cast(bits.readBits(8)); } static char ToAlphaNumericChar(int value) @@ -159,7 +143,7 @@ static char ToAlphaNumericChar(int value) return ALPHANUMERIC_CHARS[value]; } -static void DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, std::wstring& result) +static void DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, Content& result) { // Read two characters at a time std::string buffer; @@ -188,22 +172,26 @@ static void DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffe } } } - TextDecoder::AppendLatin1(result, buffer); + + result.switchEncoding(CharacterSet::ASCII); + result += buffer; } -static void DecodeNumericSegment(BitSource& bits, int count, std::wstring& result) +static void DecodeNumericSegment(BitSource& bits, int count, Content& result) { + result.switchEncoding(CharacterSet::ASCII); + result.reserve(count); + // Read three digits at a time - std::string buffer; while (count >= 3) { // Each 10 bits encodes three digits int threeDigitsBits = bits.readBits(10); if (threeDigitsBits >= 1000) throw std::runtime_error("Invalid value in numeric segment"); - buffer += ToAlphaNumericChar(threeDigitsBits / 100); - buffer += ToAlphaNumericChar((threeDigitsBits / 10) % 10); - buffer += ToAlphaNumericChar(threeDigitsBits % 10); + result += ToAlphaNumericChar(threeDigitsBits / 100); + result += ToAlphaNumericChar((threeDigitsBits / 10) % 10); + result += ToAlphaNumericChar(threeDigitsBits % 10); count -= 3; } @@ -213,18 +201,16 @@ static void DecodeNumericSegment(BitSource& bits, int count, std::wstring& resul if (twoDigitsBits >= 100) throw std::runtime_error("Invalid value in numeric segment"); - buffer += ToAlphaNumericChar(twoDigitsBits / 10); - buffer += ToAlphaNumericChar(twoDigitsBits % 10); + result += ToAlphaNumericChar(twoDigitsBits / 10); + result += ToAlphaNumericChar(twoDigitsBits % 10); } else if (count == 1) { // One digit left over to read int digitBits = bits.readBits(4); if (digitBits >= 10) throw std::runtime_error("Invalid value in numeric segment"); - buffer += ToAlphaNumericChar(digitBits); + result += ToAlphaNumericChar(digitBits); } - - TextDecoder::AppendLatin1(result, buffer); } static int ParseECIValue(BitSource& bits) @@ -282,15 +268,15 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo const std::string& hintedCharset) { BitSource bits(bytes); - std::wstring result; + Content result; + result.hintedCharset = hintedCharset.empty() ? "Auto" : hintedCharset; int symbologyIdModifier = 1; // ISO/IEC 18004:2015 Annex F Table F.1 StructuredAppendInfo structuredAppend; const int modeBitLength = CodecModeBitsLength(version); + bool fc1InEffect = false; try { - CharacterSet currentCharset = CharacterSet::Unknown; - bool fc1InEffect = false; while(!IsEndOfStream(bits, version)) { CodecMode mode; if (modeBitLength == 0) @@ -314,11 +300,11 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo symbologyIdModifier = 5; // As above // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position), "00-99" or "A-Za-z" if (int appInd = bits.readBits(8); appInd < 10) // "00-09" - result += L'0' + std::to_wstring(appInd); + result += '0' + std::to_string(appInd); else if (appInd < 100) // "10-99" - result += std::to_wstring(appInd); + result += std::to_string(appInd); else if ((appInd >= 165 && appInd <= 190) || (appInd >= 197 && appInd <= 222)) // "A-Za-z" - result += static_cast(appInd - 100); + result += static_cast(appInd - 100); else throw std::runtime_error("Invalid AIM Application Indicator"); break; @@ -329,19 +315,21 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo structuredAppend.count = bits.readBits(4) + 1; structuredAppend.id = std::to_string(bits.readBits(8)); break; - case CodecMode::ECI: + case CodecMode::ECI: { // Count doesn't apply to ECI - currentCharset = CharacterSetECI::ECI2CharacterSet(ParseECIValue(bits)); - if (currentCharset == CharacterSet::Unknown) + auto charset = CharacterSetECI::ECI2CharacterSet(ParseECIValue(bits)); + if (charset == CharacterSet::Unknown) return DecodeStatus::FormatError; + result.switchEncoding(charset, true); break; + } case CodecMode::HANZI: { // First handle Hanzi mode which does not start with character count // chinese mode contains a sub set indicator right after mode indicator - int subset = bits.readBits(4); + if (int subset = bits.readBits(4); subset != 1) // GB2312_SUBSET is the only supported one right now + return DecodeStatus::FormatError; int count = bits.readBits(CharacterCountBits(mode, version)); - if (subset == 1 ) // GB2312_SUBSET - DecodeHanziSegment(bits, count, result); + DecodeHanziSegment(bits, count, result); break; } default: { @@ -351,7 +339,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo switch (mode) { case CodecMode::NUMERIC: DecodeNumericSegment(bits, count, result); break; case CodecMode::ALPHANUMERIC: DecodeAlphanumericSegment(bits, count, fc1InEffect, result); break; - case CodecMode::BYTE: DecodeByteSegment(bits, count, currentCharset, hintedCharset, result); break; + case CodecMode::BYTE: DecodeByteSegment(bits, count, result); break; case CodecMode::KANJI: DecodeKanjiSegment(bits, count, result); break; default: return DecodeStatus::FormatError; } @@ -368,7 +356,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo return DecodeStatus::FormatError; } - return DecoderResult(std::move(bytes), std::move(result)) + return DecoderResult(std::move(bytes), {}, std::move(result)) .setEcLevel(ToString(ecLevel)) .setSymbologyIdentifier("]Q" + std::to_string(symbologyIdModifier)) .setStructuredAppend(structuredAppend); diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 15150e2897..844e077403 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -182,6 +182,7 @@ int main(int argc, char* argv[]) firstFile = false; } std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" + << "Binary: \"" << ToHex(result.binary()) << "\"\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" << "Position: " << result.position() << "\n" diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index fce059884f..ac66da3146 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -153,9 +153,10 @@ static std::string checkResult(const fs::path& imgPath, std::string_view expecte } if (auto expected = readFile(".bin")) { - std::string latin1Result(result.text().length(), '\0'); - std::transform(result.text().begin(), result.text().end(), latin1Result.begin(), [](wchar_t c) { return static_cast(c); }); - return latin1Result != *expected ? fmt::format("Content mismatch: expected '{}' but got '{}'", *expected, latin1Result) : ""; + ByteArray binaryExpected(*expected); + return result.binary() != binaryExpected + ? fmt::format("Content mismatch: expected '{}' but got '{}'", ToHex(binaryExpected), ToHex(result.binary())) + : ""; } return "Error reading file"; @@ -275,11 +276,14 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi return Result(DecodeStatus::FormatError); std::wstring text; - for (const auto& r : allResults) + Content content; + for (const auto& r : allResults) { text.append(r.text()); + content.append(r.binary()); + } const auto& first = allResults.front(); - return {DecoderResult({}, std::move(text)) + return {DecoderResult({}, std::move(text), std::move(content)) .setStructuredAppend({first.sequenceIndex(), first.sequenceSize(), first.sequenceId()}) .setSymbologyIdentifier(first.symbologyIdentifier()) .setReaderInit(first.readerInit()), From 65b6f5b983f7144268052f1df991f61b9d1fb298 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 21 May 2022 18:58:20 +0200 Subject: [PATCH 0213/1315] test: replace utf8 encoded dm-c.txt with dm-c.bin for appropriate testing --- test/samples/datamatrix-3/dm-c.bin | Bin 0 -> 84 bytes test/samples/datamatrix-3/dm-c.txt | Bin 111 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/samples/datamatrix-3/dm-c.bin delete mode 100644 test/samples/datamatrix-3/dm-c.txt diff --git a/test/samples/datamatrix-3/dm-c.bin b/test/samples/datamatrix-3/dm-c.bin new file mode 100644 index 0000000000000000000000000000000000000000..18dbeccbc88b2f3582a572dada2558160e68027c GIT binary patch literal 84 zcmZ>9bz~OPWs-aQmthr4SmH_rMg|7{z3!6CGahQ|u(rJ7pE;-Q>%7;lzW?qjoOyEf WQ_+dM43BvXAVoj|6I|ZcwgCXlQyPf? literal 0 HcmV?d00001 diff --git a/test/samples/datamatrix-3/dm-c.txt b/test/samples/datamatrix-3/dm-c.txt deleted file mode 100644 index 427bebc63e5f97cfa07c11e3de3e4850d5a5feeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111 zcmZ>9bz~OPWs*C*_V8YYL#tTA5)Z9ZU}Rw6KeX3flKIe#!wa=_SP!)vUd4ZC=Ak)t zhqoS@cX+j{@8Nxi=PDfTIlScX)We&K4tL~bcpRF?0M-U1F~Q- Date: Sat, 21 May 2022 19:00:42 +0200 Subject: [PATCH 0214/1315] ZXingReader: add option to only output binary content --- example/ZXingReader.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 844e077403..84dcff4eb6 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -44,7 +44,8 @@ static void PrintUsage(const char* exePath) << " -format Only detect given format(s) (faster)\n" << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" << " -1 Print only file name, text and status on one line per file/barcode\n" - << " -escape Escape non-graphical characters in angle brackets (ignored for -1 option, which always escapes)\n" + << " -escape Escape non-graphical characters in angle brackets (implicit for -1 option, which always escapes)\n" + << " -binary Write (only) the binary content of the symbol(s) to stdout\n" << " -pngout Write a copy of the input image with barcodes outlined by a green line\n" << "\n" << "Supported formats are:\n"; @@ -54,7 +55,7 @@ static void PrintUsage(const char* exePath) std::cout << "Formats can be lowercase, with or without '-', separated by ',' and/or '|'\n"; } -static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& angleEscape, +static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& angleEscape, bool& binaryOutput, std::vector& filePaths, std::string& outPath) { for (int i = 1; i < argc; ++i) { @@ -80,6 +81,8 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi oneLine = true; } else if (strcmp(argv[i], "-escape") == 0) { angleEscape = true; + } else if (strcmp(argv[i], "-binary") == 0) { + binaryOutput = true; } else if (strcmp(argv[i], "-pngout") == 0) { if (++i == argc) return false; @@ -125,10 +128,11 @@ int main(int argc, char* argv[]) std::string outPath; bool oneLine = false; bool angleEscape = false; + bool binaryOutput = false; int ret = 0; - if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, filePaths, outPath)) { + if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, binaryOutput, filePaths, outPath)) { PrintUsage(argv[0]); return -1; } @@ -163,6 +167,11 @@ int main(int argc, char* argv[]) ret |= static_cast(result.status()); + if (binaryOutput) { + std::cout.write(reinterpret_cast(result.binary().data()), result.binary().size()); + continue; + } + if (oneLine) { std::cout << filePath << " " << ToString(result.format()); if (result.isValid()) From e4c6a877c46b4ce01be5b59422d696b6d2ad7e05 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 22 May 2022 01:01:46 +0200 Subject: [PATCH 0215/1315] Introduce SPDX-License-Identifier into Apache licensed source files Also move `#pragma once` below the first header block, such that the 'auto fold first comment' feature of some IDEs (e.g. QtCreator) can work. Note: unfortunately, the SPDX-License-Identifier string needs to be in its own comment to be fully functional. --- core/src/BarcodeFormat.cpp | 13 +------------ core/src/BarcodeFormat.h | 16 +++------------- core/src/BinaryBitmap.cpp | 13 +------------ core/src/BinaryBitmap.h | 16 +++------------- core/src/BitArray.cpp | 13 +------------ core/src/BitArray.h | 16 +++------------- core/src/BitHacks.h | 16 +++------------- core/src/BitMatrix.cpp | 13 +------------ core/src/BitMatrix.h | 16 +++------------- core/src/BitMatrixCursor.h | 16 +++------------- core/src/BitMatrixIO.cpp | 13 +------------ core/src/BitMatrixIO.h | 16 +++------------- core/src/BitSource.cpp | 13 +------------ core/src/BitSource.h | 16 +++------------- core/src/ByteArray.h | 16 +++------------- core/src/ByteMatrix.h | 16 +++------------- core/src/CharacterSet.h | 16 +++------------- core/src/CharacterSetECI.cpp | 13 +------------ core/src/CharacterSetECI.h | 16 +++------------- core/src/ConcentricFinder.cpp | 13 +------------ core/src/ConcentricFinder.h | 16 +++------------- core/src/Content.cpp | 15 ++------------- core/src/Content.h | 16 +++------------- core/src/CustomData.h | 16 +++------------- core/src/DecodeHints.cpp | 13 +------------ core/src/DecodeHints.h | 16 +++------------- core/src/DecodeStatus.cpp | 13 +------------ core/src/DecodeStatus.h | 16 +++------------- core/src/DecoderResult.h | 16 +++------------- core/src/DetectorResult.h | 16 +++------------- core/src/Flags.h | 16 +++------------- core/src/GTIN.cpp | 13 +------------ core/src/GTIN.h | 16 +++------------- core/src/GenericGF.cpp | 13 +------------ core/src/GenericGF.h | 16 +++------------- core/src/GenericGFPoly.cpp | 13 +------------ core/src/GenericGFPoly.h | 16 +++------------- core/src/GlobalHistogramBinarizer.cpp | 13 +------------ core/src/GlobalHistogramBinarizer.h | 16 +++------------- core/src/GridSampler.cpp | 13 +------------ core/src/GridSampler.h | 16 +++------------- core/src/HybridBinarizer.cpp | 13 +------------ core/src/HybridBinarizer.h | 16 +++------------- core/src/ImageView.h | 16 +++------------- core/src/LogMatrix.h | 16 +++------------- core/src/Matrix.h | 16 +++------------- core/src/MultiFormatReader.cpp | 13 +------------ core/src/MultiFormatReader.h | 16 +++------------- core/src/MultiFormatWriter.cpp | 13 +------------ core/src/MultiFormatWriter.h | 16 +++------------- core/src/Pattern.h | 16 +++------------- core/src/PerspectiveTransform.cpp | 13 +------------ core/src/PerspectiveTransform.h | 16 +++------------- core/src/Point.h | 16 +++------------- core/src/Quadrilateral.h | 16 +++------------- core/src/ReadBarcode.cpp | 13 +------------ core/src/ReadBarcode.h | 16 +++------------- core/src/Reader.h | 16 +++------------- core/src/ReedSolomonDecoder.cpp | 13 +------------ core/src/ReedSolomonDecoder.h | 16 +++------------- core/src/ReedSolomonEncoder.cpp | 13 +------------ core/src/ReedSolomonEncoder.h | 16 +++------------- core/src/RegressionLine.h | 16 +++------------- core/src/Result.cpp | 13 +------------ core/src/Result.h | 16 +++------------- core/src/ResultPoint.cpp | 13 +------------ core/src/ResultPoint.h | 16 +++------------- core/src/Scope.h | 16 +++------------- core/src/StructuredAppend.h | 16 +++------------- core/src/TextDecoder.cpp | 13 +------------ core/src/TextDecoder.h | 16 +++------------- core/src/TextEncoder.cpp | 13 +------------ core/src/TextEncoder.h | 16 +++------------- core/src/TextUtfEncoding.cpp | 13 +------------ core/src/TextUtfEncoding.h | 16 +++------------- core/src/ThresholdBinarizer.h | 16 +++------------- core/src/TritMatrix.h | 16 +++------------- core/src/WhiteRectDetector.cpp | 13 +------------ core/src/WhiteRectDetector.h | 16 +++------------- core/src/ZXBigInteger.cpp | 13 +------------ core/src/ZXBigInteger.h | 16 +++------------- core/src/ZXConfig.h | 16 +++------------- core/src/ZXContainerAlgorithms.h | 16 +++------------- core/src/ZXNullable.h | 16 +++------------- core/src/aztec/AZDecoder.cpp | 13 +------------ core/src/aztec/AZDecoder.h | 16 +++------------- core/src/aztec/AZDetector.cpp | 13 +------------ core/src/aztec/AZDetector.h | 16 +++------------- core/src/aztec/AZDetectorResult.h | 16 +++------------- core/src/aztec/AZEncoder.cpp | 13 +------------ core/src/aztec/AZEncoder.h | 16 +++------------- core/src/aztec/AZEncodingState.h | 16 +++------------- core/src/aztec/AZHighLevelEncoder.cpp | 13 +------------ core/src/aztec/AZHighLevelEncoder.h | 16 +++------------- core/src/aztec/AZReader.cpp | 13 +------------ core/src/aztec/AZReader.h | 16 +++------------- core/src/aztec/AZToken.cpp | 13 +------------ core/src/aztec/AZToken.h | 16 +++------------- core/src/aztec/AZWriter.cpp | 13 +------------ core/src/aztec/AZWriter.h | 16 +++------------- core/src/datamatrix/DMBitLayout.cpp | 13 +------------ core/src/datamatrix/DMBitLayout.h | 16 +++------------- core/src/datamatrix/DMDataBlock.cpp | 13 +------------ core/src/datamatrix/DMDataBlock.h | 16 +++------------- core/src/datamatrix/DMDecoder.cpp | 13 +------------ core/src/datamatrix/DMDecoder.h | 16 +++------------- core/src/datamatrix/DMDetector.cpp | 13 +------------ core/src/datamatrix/DMDetector.h | 16 +++------------- core/src/datamatrix/DMECEncoder.cpp | 13 +------------ core/src/datamatrix/DMECEncoder.h | 16 +++------------- core/src/datamatrix/DMEncoderContext.h | 16 +++------------- core/src/datamatrix/DMHighLevelEncoder.cpp | 13 +------------ core/src/datamatrix/DMHighLevelEncoder.h | 16 +++------------- core/src/datamatrix/DMReader.cpp | 13 +------------ core/src/datamatrix/DMReader.h | 16 +++------------- core/src/datamatrix/DMSymbolInfo.cpp | 13 +------------ core/src/datamatrix/DMSymbolInfo.h | 16 +++------------- core/src/datamatrix/DMSymbolShape.h | 16 +++------------- core/src/datamatrix/DMVersion.cpp | 13 +------------ core/src/datamatrix/DMVersion.h | 16 +++------------- core/src/datamatrix/DMWriter.cpp | 13 +------------ core/src/datamatrix/DMWriter.h | 16 +++------------- core/src/maxicode/MCBitMatrixParser.cpp | 13 +------------ core/src/maxicode/MCBitMatrixParser.h | 16 +++------------- core/src/maxicode/MCDecoder.cpp | 13 +------------ core/src/maxicode/MCDecoder.h | 16 +++------------- core/src/maxicode/MCReader.cpp | 13 +------------ core/src/maxicode/MCReader.h | 16 +++------------- core/src/oned/ODCodabarReader.cpp | 13 +------------ core/src/oned/ODCodabarReader.h | 16 +++------------- core/src/oned/ODCodabarWriter.cpp | 13 +------------ core/src/oned/ODCodabarWriter.h | 16 +++------------- core/src/oned/ODCode128Patterns.cpp | 13 +------------ core/src/oned/ODCode128Patterns.h | 16 +++------------- core/src/oned/ODCode128Reader.cpp | 13 +------------ core/src/oned/ODCode128Reader.h | 16 +++------------- core/src/oned/ODCode128Writer.cpp | 13 +------------ core/src/oned/ODCode128Writer.h | 16 +++------------- core/src/oned/ODCode39Reader.cpp | 13 +------------ core/src/oned/ODCode39Reader.h | 16 +++------------- core/src/oned/ODCode39Writer.cpp | 13 +------------ core/src/oned/ODCode39Writer.h | 16 +++------------- core/src/oned/ODCode93Reader.cpp | 13 +------------ core/src/oned/ODCode93Reader.h | 16 +++------------- core/src/oned/ODCode93Writer.cpp | 13 +------------ core/src/oned/ODCode93Writer.h | 16 +++------------- core/src/oned/ODDataBarCommon.cpp | 13 +------------ core/src/oned/ODDataBarCommon.h | 16 +++------------- core/src/oned/ODDataBarExpandedReader.cpp | 13 +------------ core/src/oned/ODDataBarExpandedReader.h | 16 +++------------- core/src/oned/ODDataBarReader.cpp | 13 +------------ core/src/oned/ODDataBarReader.h | 16 +++------------- core/src/oned/ODEAN13Writer.cpp | 13 +------------ core/src/oned/ODEAN13Writer.h | 16 +++------------- core/src/oned/ODEAN8Writer.cpp | 13 +------------ core/src/oned/ODEAN8Writer.h | 16 +++------------- core/src/oned/ODITFReader.cpp | 13 +------------ core/src/oned/ODITFReader.h | 16 +++------------- core/src/oned/ODITFWriter.cpp | 13 +------------ core/src/oned/ODITFWriter.h | 16 +++------------- core/src/oned/ODMultiUPCEANReader.cpp | 13 +------------ core/src/oned/ODMultiUPCEANReader.h | 16 +++------------- core/src/oned/ODReader.cpp | 13 +------------ core/src/oned/ODReader.h | 16 +++------------- core/src/oned/ODRowReader.cpp | 13 +------------ core/src/oned/ODRowReader.h | 16 +++------------- core/src/oned/ODUPCAWriter.cpp | 13 +------------ core/src/oned/ODUPCAWriter.h | 16 +++------------- core/src/oned/ODUPCEANCommon.cpp | 13 +------------ core/src/oned/ODUPCEANCommon.h | 16 +++------------- core/src/oned/ODUPCEWriter.cpp | 13 +------------ core/src/oned/ODUPCEWriter.h | 16 +++------------- core/src/oned/ODWriterHelper.cpp | 13 +------------ core/src/oned/ODWriterHelper.h | 16 +++------------- core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp | 13 +------------ core/src/oned/rss/ODRSSExpandedBinaryDecoder.h | 16 +++------------- core/src/oned/rss/ODRSSFieldParser.cpp | 13 +------------ core/src/oned/rss/ODRSSFieldParser.h | 16 +++------------- core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp | 13 +------------ core/src/oned/rss/ODRSSGenericAppIdDecoder.h | 16 +++------------- core/src/pdf417/PDFBarcodeMetadata.h | 16 +++------------- core/src/pdf417/PDFBarcodeValue.cpp | 13 +------------ core/src/pdf417/PDFBarcodeValue.h | 16 +++------------- core/src/pdf417/PDFBoundingBox.cpp | 13 +------------ core/src/pdf417/PDFBoundingBox.h | 16 +++------------- core/src/pdf417/PDFCodeword.h | 16 +++------------- core/src/pdf417/PDFCodewordDecoder.cpp | 13 +------------ core/src/pdf417/PDFCodewordDecoder.h | 16 +++------------- core/src/pdf417/PDFCompaction.h | 16 +++------------- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 13 +------------ core/src/pdf417/PDFDecodedBitStreamParser.h | 16 +++------------- core/src/pdf417/PDFDecoderResultExtra.h | 16 +++------------- core/src/pdf417/PDFDetectionResult.cpp | 13 +------------ core/src/pdf417/PDFDetectionResult.h | 16 +++------------- core/src/pdf417/PDFDetectionResultColumn.cpp | 13 +------------ core/src/pdf417/PDFDetectionResultColumn.h | 16 +++------------- core/src/pdf417/PDFDetector.cpp | 13 +------------ core/src/pdf417/PDFDetector.h | 16 +++------------- core/src/pdf417/PDFEncoder.cpp | 13 +------------ core/src/pdf417/PDFEncoder.h | 16 +++------------- core/src/pdf417/PDFHighLevelEncoder.cpp | 13 +------------ core/src/pdf417/PDFHighLevelEncoder.h | 16 +++------------- core/src/pdf417/PDFModulusGF.cpp | 13 +------------ core/src/pdf417/PDFModulusGF.h | 16 +++------------- core/src/pdf417/PDFModulusPoly.cpp | 13 +------------ core/src/pdf417/PDFModulusPoly.h | 16 +++------------- core/src/pdf417/PDFReader.cpp | 13 +------------ core/src/pdf417/PDFReader.h | 16 +++------------- core/src/pdf417/PDFScanningDecoder.cpp | 13 +------------ core/src/pdf417/PDFScanningDecoder.h | 16 +++------------- core/src/pdf417/PDFWriter.cpp | 13 +------------ core/src/pdf417/PDFWriter.h | 16 +++------------- core/src/qrcode/QRBitMatrixParser.cpp | 13 +------------ core/src/qrcode/QRBitMatrixParser.h | 16 +++------------- core/src/qrcode/QRCodecMode.cpp | 13 +------------ core/src/qrcode/QRCodecMode.h | 16 +++------------- core/src/qrcode/QRDataBlock.cpp | 13 +------------ core/src/qrcode/QRDataBlock.h | 16 +++------------- core/src/qrcode/QRDataMask.h | 16 +++------------- core/src/qrcode/QRDecoder.cpp | 13 +------------ core/src/qrcode/QRDecoder.h | 16 +++------------- core/src/qrcode/QRDetector.cpp | 13 +------------ core/src/qrcode/QRDetector.h | 16 +++------------- core/src/qrcode/QRECB.h | 16 +++------------- core/src/qrcode/QREncodeResult.h | 16 +++------------- core/src/qrcode/QREncoder.cpp | 13 +------------ core/src/qrcode/QREncoder.h | 16 +++------------- core/src/qrcode/QRErrorCorrectionLevel.cpp | 13 +------------ core/src/qrcode/QRErrorCorrectionLevel.h | 16 +++------------- core/src/qrcode/QRFormatInformation.cpp | 13 +------------ core/src/qrcode/QRFormatInformation.h | 16 +++------------- core/src/qrcode/QRMaskUtil.cpp | 13 +------------ core/src/qrcode/QRMaskUtil.h | 16 +++------------- core/src/qrcode/QRMatrixUtil.cpp | 13 +------------ core/src/qrcode/QRMatrixUtil.h | 16 +++------------- core/src/qrcode/QRReader.cpp | 13 +------------ core/src/qrcode/QRReader.h | 16 +++------------- core/src/qrcode/QRVersion.cpp | 13 +------------ core/src/qrcode/QRVersion.h | 16 +++------------- core/src/qrcode/QRWriter.cpp | 13 +------------ core/src/qrcode/QRWriter.h | 16 +++------------- example/ZXingOpenCV.cpp | 15 ++------------- example/ZXingQtCamReader.cpp | 15 ++------------- example/ZXingQtReader.cpp | 15 ++------------- example/ZXingReader.cpp | 13 +------------ example/ZXingWriter.cpp | 13 +------------ test/blackbox/BlackboxTestRunner.cpp | 13 +------------ test/blackbox/BlackboxTestRunner.h | 16 +++------------- test/blackbox/ImageLoader.cpp | 13 +------------ test/blackbox/ImageLoader.h | 16 +++------------- test/blackbox/TestReaderMain.cpp | 13 +------------ test/blackbox/TestWriterMain.cpp | 13 +------------ test/blackbox/ZXFilesystem.h | 16 +++------------- test/unit/BarcodeFormatTest.cpp | 13 +------------ test/unit/BitArrayUtility.cpp | 13 +------------ test/unit/BitHacksTest.cpp | 13 +------------ test/unit/CharacterSetECITest.cpp | 13 +------------ test/unit/GTINTest.cpp | 13 +------------ test/unit/ReedSolomonTest.cpp | 13 +------------ test/unit/TextDecoderTest.cpp | 13 +------------ test/unit/TextUtfEncodingTest.cpp | 13 +------------ test/unit/ThresholdBinarizerTest.cpp | 13 +------------ test/unit/aztec/AZDecoderTest.cpp | 13 +------------ test/unit/aztec/AZDetectorTest.cpp | 13 +------------ test/unit/aztec/AZEncodeDecodeTest.cpp | 13 +------------ test/unit/aztec/AZEncoderTest.cpp | 13 +------------ test/unit/aztec/AZHighLevelEncoderTest.cpp | 13 +------------ .../datamatrix/DMDecodedBitStreamParserTest.cpp | 13 +------------ test/unit/datamatrix/DMEncodeDecodeTest.cpp | 13 +------------ test/unit/datamatrix/DMHighLevelEncodeTest.cpp | 13 +------------ test/unit/datamatrix/DMPlacementTest.cpp | 13 +------------ test/unit/datamatrix/DMSymbolInfoTest.cpp | 13 +------------ test/unit/datamatrix/DMWriterTest.cpp | 13 +------------ test/unit/maxicode/MCDecoderTest.cpp | 13 +------------ test/unit/oned/ODCodaBarWriterTest.cpp | 13 +------------ test/unit/oned/ODCode128ReaderTest.cpp | 13 +------------ test/unit/oned/ODCode128WriterTest.cpp | 13 +------------ test/unit/oned/ODCode39ExtendedModeTest.cpp | 13 +------------ test/unit/oned/ODCode39ReaderTest.cpp | 13 +------------ test/unit/oned/ODCode39WriterTest.cpp | 13 +------------ test/unit/oned/ODCode93ReaderTest.cpp | 13 +------------ test/unit/oned/ODCode93WriterTest.cpp | 13 +------------ test/unit/oned/ODEAN13WriterTest.cpp | 13 +------------ test/unit/oned/ODEAN8WriterTest.cpp | 13 +------------ test/unit/oned/ODITFWriterTest.cpp | 13 +------------ test/unit/oned/ODUPCAWriterTest.cpp | 13 +------------ test/unit/oned/ODUPCEWriterTest.cpp | 13 +------------ .../oned/rss/ODRSSExpandedBinaryDecoderTest.cpp | 13 +------------ test/unit/oned/rss/ODRSSFieldParserTest.cpp | 13 +------------ test/unit/pdf417/PDF417DecoderTest.cpp | 13 +------------ test/unit/pdf417/PDF417ErrorCorrectionTest.cpp | 13 +------------ test/unit/pdf417/PDF417HighLevelEncoderTest.cpp | 13 +------------ test/unit/pdf417/PDF417WriterTest.cpp | 13 +------------ test/unit/qrcode/MQRDecoderTest.cpp | 15 ++------------- test/unit/qrcode/QRBitMatrixParserTest.cpp | 15 ++------------- test/unit/qrcode/QRDataMaskTest.cpp | 13 +------------ .../unit/qrcode/QRDecodedBitStreamParserTest.cpp | 13 +------------ test/unit/qrcode/QREncoderTest.cpp | 15 ++------------- test/unit/qrcode/QRErrorCorrectionLevelTest.cpp | 13 +------------ test/unit/qrcode/QRFormatInformationTest.cpp | 13 +------------ test/unit/qrcode/QRModeTest.cpp | 13 +------------ test/unit/qrcode/QRVersionTest.cpp | 13 +------------ test/unit/qrcode/QRWriterTest.cpp | 13 +------------ .../zxingcpp/src/main/cpp/BarcodeReader.cpp | 13 +------------ .../android/zxingcpp/src/main/cpp/JNIUtils.cpp | 13 +------------ .../android/zxingcpp/src/main/cpp/JNIUtils.h | 16 +++------------- wrappers/wasm/BarcodeReader.cpp | 13 +------------ wrappers/wasm/BarcodeWriter.cpp | 13 +------------ wrappers/winrt/BarcodeReader.h | 16 +++------------- wrappers/winrt/ReadResult.h | 16 +++------------- 310 files changed, 605 insertions(+), 3871 deletions(-) diff --git a/core/src/BarcodeFormat.cpp b/core/src/BarcodeFormat.cpp index e83df3ecfb..232bcb854f 100644 --- a/core/src/BarcodeFormat.cpp +++ b/core/src/BarcodeFormat.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BarcodeFormat.h" diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index 8bb5d3681a..2d82784525 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Flags.h" diff --git a/core/src/BinaryBitmap.cpp b/core/src/BinaryBitmap.cpp index e68cccd2bc..e3676eef6a 100644 --- a/core/src/BinaryBitmap.cpp +++ b/core/src/BinaryBitmap.cpp @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BinaryBitmap.h" diff --git a/core/src/BinaryBitmap.h b/core/src/BinaryBitmap.h index 896294db73..0337d24abd 100644 --- a/core/src/BinaryBitmap.h +++ b/core/src/BinaryBitmap.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2021 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ReadBarcode.h" diff --git a/core/src/BitArray.cpp b/core/src/BitArray.cpp index 5566c65e47..718d025bac 100644 --- a/core/src/BitArray.cpp +++ b/core/src/BitArray.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitArray.h" diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 490c0d6e6d..b2164da1cb 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ZXConfig.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/BitHacks.h b/core/src/BitHacks.h index 7ee06fc38b..482b181a8b 100644 --- a/core/src/BitHacks.h +++ b/core/src/BitHacks.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/BitMatrix.cpp b/core/src/BitMatrix.cpp index 2f484f7d1c..d9449cfbe3 100644 --- a/core/src/BitMatrix.cpp +++ b/core/src/BitMatrix.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrix.h" diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index 01c5d51e03..a01f20a4f4 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Matrix.h" #include "Point.h" diff --git a/core/src/BitMatrixCursor.h b/core/src/BitMatrixCursor.h index a8f3f0b6b6..7e1f16c440 100644 --- a/core/src/BitMatrixCursor.h +++ b/core/src/BitMatrixCursor.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrix.h" diff --git a/core/src/BitMatrixIO.cpp b/core/src/BitMatrixIO.cpp index dcdd090d9d..10a7c86306 100644 --- a/core/src/BitMatrixIO.cpp +++ b/core/src/BitMatrixIO.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrixIO.h" diff --git a/core/src/BitMatrixIO.h b/core/src/BitMatrixIO.h index 3178ac01a6..022b48ec35 100644 --- a/core/src/BitMatrixIO.h +++ b/core/src/BitMatrixIO.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/BitSource.cpp b/core/src/BitSource.cpp index 569014354c..bc2771a932 100644 --- a/core/src/BitSource.cpp +++ b/core/src/BitSource.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitSource.h" diff --git a/core/src/BitSource.h b/core/src/BitSource.h index f9d0c2b064..1db7c9eeb8 100644 --- a/core/src/BitSource.h +++ b/core/src/BitSource.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/ByteArray.h b/core/src/ByteArray.h index 7dc5f96cea..85712f20e5 100644 --- a/core/src/ByteArray.h +++ b/core/src/ByteArray.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/ByteMatrix.h b/core/src/ByteMatrix.h index 06ffd1ddc3..09dc1eac32 100644 --- a/core/src/ByteMatrix.h +++ b/core/src/ByteMatrix.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Matrix.h" diff --git a/core/src/CharacterSet.h b/core/src/CharacterSet.h index dd34fd4fd0..e078f1fa89 100644 --- a/core/src/CharacterSet.h +++ b/core/src/CharacterSet.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/CharacterSetECI.cpp b/core/src/CharacterSetECI.cpp index 86cd507042..f99adc6b32 100644 --- a/core/src/CharacterSetECI.cpp +++ b/core/src/CharacterSetECI.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "CharacterSetECI.h" #include "TextDecoder.h" diff --git a/core/src/CharacterSetECI.h b/core/src/CharacterSetECI.h index 03d52cc236..1d6c1e6ed7 100644 --- a/core/src/CharacterSetECI.h +++ b/core/src/CharacterSetECI.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "CharacterSet.h" diff --git a/core/src/ConcentricFinder.cpp b/core/src/ConcentricFinder.cpp index e53740d595..57b94f4704 100644 --- a/core/src/ConcentricFinder.cpp +++ b/core/src/ConcentricFinder.cpp @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ConcentricFinder.h" diff --git a/core/src/ConcentricFinder.h b/core/src/ConcentricFinder.h index 64b47d1bbf..8fe07d2945 100644 --- a/core/src/ConcentricFinder.h +++ b/core/src/ConcentricFinder.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrixCursor.h" #include "Pattern.h" diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 4e2e983db0..dc17fcc8b9 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -1,18 +1,7 @@ /* * Copyright 2022 Axel Waggershauser - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +*/ +// SPDX-License-Identifier: Apache-2.0 #include "Content.h" diff --git a/core/src/Content.h b/core/src/Content.h index e6407ed2ea..1af33bac05 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2022 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ByteArray.h" #include "CharacterSet.h" diff --git a/core/src/CustomData.h b/core/src/CustomData.h index e80dbf533b..6578af5260 100644 --- a/core/src/CustomData.h +++ b/core/src/CustomData.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/DecodeHints.cpp b/core/src/DecodeHints.cpp index 25f34b717c..72ded6073c 100644 --- a/core/src/DecodeHints.cpp +++ b/core/src/DecodeHints.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DecodeHints.h" diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index d098e0a9c1..68ffe031b9 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BarcodeFormat.h" diff --git a/core/src/DecodeStatus.cpp b/core/src/DecodeStatus.cpp index 9f7ae1a8d2..8abff86b2d 100644 --- a/core/src/DecodeStatus.cpp +++ b/core/src/DecodeStatus.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DecodeStatus.h" diff --git a/core/src/DecodeStatus.h b/core/src/DecodeStatus.h index fe321dc3b2..5c8fba4a47 100644 --- a/core/src/DecodeStatus.h +++ b/core/src/DecodeStatus.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 81fc060479..0bb573bc7e 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ByteArray.h" #include "Content.h" diff --git a/core/src/DetectorResult.h b/core/src/DetectorResult.h index 67db3b6b12..dbeffe0b02 100644 --- a/core/src/DetectorResult.h +++ b/core/src/DetectorResult.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrix.h" #include "Quadrilateral.h" diff --git a/core/src/Flags.h b/core/src/Flags.h index 616082d85b..c5f2e2a8ab 100644 --- a/core/src/Flags.h +++ b/core/src/Flags.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitHacks.h" diff --git a/core/src/GTIN.cpp b/core/src/GTIN.cpp index 3dc969a66c..8d498206a8 100644 --- a/core/src/GTIN.cpp +++ b/core/src/GTIN.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "GTIN.h" diff --git a/core/src/GTIN.h b/core/src/GTIN.h index 310da18c84..9637be44ec 100644 --- a/core/src/GTIN.h +++ b/core/src/GTIN.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BarcodeFormat.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/GenericGF.cpp b/core/src/GenericGF.cpp index 6e28b4fd80..d6c03ab056 100644 --- a/core/src/GenericGF.cpp +++ b/core/src/GenericGF.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "GenericGF.h" diff --git a/core/src/GenericGF.h b/core/src/GenericGF.h index 5c11f22aac..4f25b62564 100644 --- a/core/src/GenericGF.h +++ b/core/src/GenericGF.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "GenericGFPoly.h" #include "ZXConfig.h" diff --git a/core/src/GenericGFPoly.cpp b/core/src/GenericGFPoly.cpp index 4fa4df5464..8abe394e93 100644 --- a/core/src/GenericGFPoly.cpp +++ b/core/src/GenericGFPoly.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "GenericGFPoly.h" diff --git a/core/src/GenericGFPoly.h b/core/src/GenericGFPoly.h index f87dfda3f4..7aa56b927d 100644 --- a/core/src/GenericGFPoly.h +++ b/core/src/GenericGFPoly.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ZXContainerAlgorithms.h" diff --git a/core/src/GlobalHistogramBinarizer.cpp b/core/src/GlobalHistogramBinarizer.cpp index 59ad786b43..000bbe9182 100644 --- a/core/src/GlobalHistogramBinarizer.cpp +++ b/core/src/GlobalHistogramBinarizer.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "GlobalHistogramBinarizer.h" diff --git a/core/src/GlobalHistogramBinarizer.h b/core/src/GlobalHistogramBinarizer.h index fbeac5d9df..8a0bcfa4e9 100644 --- a/core/src/GlobalHistogramBinarizer.h +++ b/core/src/GlobalHistogramBinarizer.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BinaryBitmap.h" diff --git a/core/src/GridSampler.cpp b/core/src/GridSampler.cpp index 260d763c27..b612f3a5ef 100644 --- a/core/src/GridSampler.cpp +++ b/core/src/GridSampler.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "GridSampler.h" diff --git a/core/src/GridSampler.h b/core/src/GridSampler.h index 01e1eb92f7..8fb4eea6a9 100644 --- a/core/src/GridSampler.h +++ b/core/src/GridSampler.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "DetectorResult.h" #include "PerspectiveTransform.h" diff --git a/core/src/HybridBinarizer.cpp b/core/src/HybridBinarizer.cpp index 2a9bb7aea5..bf14d51d6a 100644 --- a/core/src/HybridBinarizer.cpp +++ b/core/src/HybridBinarizer.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "HybridBinarizer.h" diff --git a/core/src/HybridBinarizer.h b/core/src/HybridBinarizer.h index 53fd8851d8..6e0a8b42d0 100644 --- a/core/src/HybridBinarizer.h +++ b/core/src/HybridBinarizer.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "GlobalHistogramBinarizer.h" diff --git a/core/src/ImageView.h b/core/src/ImageView.h index 7d8058d7cd..bee631b67a 100644 --- a/core/src/ImageView.h +++ b/core/src/ImageView.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2019 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/LogMatrix.h b/core/src/LogMatrix.h index 478545d962..1d366b9ca1 100644 --- a/core/src/LogMatrix.h +++ b/core/src/LogMatrix.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrix.h" #include "Matrix.h" diff --git a/core/src/Matrix.h b/core/src/Matrix.h index 3709f22738..a85ccf42c1 100644 --- a/core/src/Matrix.h +++ b/core/src/Matrix.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Point.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 3b9a4b2d3f..563c0397a1 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "MultiFormatReader.h" diff --git a/core/src/MultiFormatReader.h b/core/src/MultiFormatReader.h index defafc4b1f..f418f229e7 100644 --- a/core/src/MultiFormatReader.h +++ b/core/src/MultiFormatReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Result.h" diff --git a/core/src/MultiFormatWriter.cpp b/core/src/MultiFormatWriter.cpp index 1ed1b8ff21..464dbc8054 100644 --- a/core/src/MultiFormatWriter.cpp +++ b/core/src/MultiFormatWriter.cpp @@ -1,18 +1,7 @@ /* * Copyright 2017 Huy Cuong Nguyen -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "MultiFormatWriter.h" diff --git a/core/src/MultiFormatWriter.h b/core/src/MultiFormatWriter.h index 1ec252aa0f..88b1c61591 100644 --- a/core/src/MultiFormatWriter.h +++ b/core/src/MultiFormatWriter.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2017 Huy Cuong Nguyen -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BarcodeFormat.h" #include "CharacterSet.h" diff --git a/core/src/Pattern.h b/core/src/Pattern.h index c317be3e57..2226169d15 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ZXContainerAlgorithms.h" diff --git a/core/src/PerspectiveTransform.cpp b/core/src/PerspectiveTransform.cpp index 4aba2f1fd7..f3d1aaa2e9 100644 --- a/core/src/PerspectiveTransform.cpp +++ b/core/src/PerspectiveTransform.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PerspectiveTransform.h" diff --git a/core/src/PerspectiveTransform.h b/core/src/PerspectiveTransform.h index b02ce66fe1..0e99c3c101 100644 --- a/core/src/PerspectiveTransform.h +++ b/core/src/PerspectiveTransform.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Point.h" #include "Quadrilateral.h" diff --git a/core/src/Point.h b/core/src/Point.h index 66b8e41f4e..19e1366099 100644 --- a/core/src/Point.h +++ b/core/src/Point.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/Quadrilateral.h b/core/src/Quadrilateral.h index ba2679d6bc..9d3cea0201 100644 --- a/core/src/Quadrilateral.h +++ b/core/src/Quadrilateral.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Point.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index add15b2db7..4ffc2e8aab 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -1,18 +1,7 @@ /* * Copyright 2019 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ReadBarcode.h" diff --git a/core/src/ReadBarcode.h b/core/src/ReadBarcode.h index 3bbc48f7b4..a76d60c31b 100644 --- a/core/src/ReadBarcode.h +++ b/core/src/ReadBarcode.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2019 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "DecodeHints.h" #include "ImageView.h" diff --git a/core/src/Reader.h b/core/src/Reader.h index 642ac9c35f..99ea56d3ff 100644 --- a/core/src/Reader.h +++ b/core/src/Reader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Result.h" diff --git a/core/src/ReedSolomonDecoder.cpp b/core/src/ReedSolomonDecoder.cpp index ac38fc3f65..e521f4cb7e 100644 --- a/core/src/ReedSolomonDecoder.cpp +++ b/core/src/ReedSolomonDecoder.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ReedSolomonDecoder.h" diff --git a/core/src/ReedSolomonDecoder.h b/core/src/ReedSolomonDecoder.h index d6f001ffa0..7772adb9a8 100644 --- a/core/src/ReedSolomonDecoder.h +++ b/core/src/ReedSolomonDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/ReedSolomonEncoder.cpp b/core/src/ReedSolomonEncoder.cpp index 784d69cd5b..94741f1258 100644 --- a/core/src/ReedSolomonEncoder.cpp +++ b/core/src/ReedSolomonEncoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ReedSolomonEncoder.h" diff --git a/core/src/ReedSolomonEncoder.h b/core/src/ReedSolomonEncoder.h index 15c96e5bf1..ad1feee017 100644 --- a/core/src/ReedSolomonEncoder.h +++ b/core/src/ReedSolomonEncoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "GenericGFPoly.h" diff --git a/core/src/RegressionLine.h b/core/src/RegressionLine.h index a0ff880f80..be3dd0a813 100644 --- a/core/src/RegressionLine.h +++ b/core/src/RegressionLine.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Point.h" diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 2f0c4be75c..f69a8804db 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "Result.h" diff --git a/core/src/Result.h b/core/src/Result.h index 3f7ee54f09..be145a888c 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BarcodeFormat.h" #include "ByteArray.h" diff --git a/core/src/ResultPoint.cpp b/core/src/ResultPoint.cpp index 8ea41a47b3..134216aa01 100644 --- a/core/src/ResultPoint.cpp +++ b/core/src/ResultPoint.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ResultPoint.h" diff --git a/core/src/ResultPoint.h b/core/src/ResultPoint.h index 12cd7bda36..067b648f11 100644 --- a/core/src/ResultPoint.h +++ b/core/src/ResultPoint.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Point.h" diff --git a/core/src/Scope.h b/core/src/Scope.h index 1ba2297b0f..40506fa077 100644 --- a/core/src/Scope.h +++ b/core/src/Scope.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/StructuredAppend.h b/core/src/StructuredAppend.h index 6a778f91b3..105d5ebd65 100644 --- a/core/src/StructuredAppend.h +++ b/core/src/StructuredAppend.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2021 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/TextDecoder.cpp b/core/src/TextDecoder.cpp index 27063549bd..4df8a65f14 100644 --- a/core/src/TextDecoder.cpp +++ b/core/src/TextDecoder.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "TextDecoder.h" diff --git a/core/src/TextDecoder.h b/core/src/TextDecoder.h index 7a9118d8ae..ee35251867 100644 --- a/core/src/TextDecoder.h +++ b/core/src/TextDecoder.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/TextEncoder.cpp b/core/src/TextEncoder.cpp index e3553e4dfa..21af9ee744 100644 --- a/core/src/TextEncoder.cpp +++ b/core/src/TextEncoder.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "TextEncoder.h" diff --git a/core/src/TextEncoder.h b/core/src/TextEncoder.h index 83b7627cf6..d16972f104 100644 --- a/core/src/TextEncoder.h +++ b/core/src/TextEncoder.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index b2e3e1e4e7..500a017975 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "TextUtfEncoding.h" diff --git a/core/src/TextUtfEncoding.h b/core/src/TextUtfEncoding.h index ebbbca2e97..07ceca38df 100644 --- a/core/src/TextUtfEncoding.h +++ b/core/src/TextUtfEncoding.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/ThresholdBinarizer.h b/core/src/ThresholdBinarizer.h index 160ff5a960..620886a536 100644 --- a/core/src/ThresholdBinarizer.h +++ b/core/src/ThresholdBinarizer.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BinaryBitmap.h" #include "BitMatrix.h" diff --git a/core/src/TritMatrix.h b/core/src/TritMatrix.h index 584677ae30..8e70ff9fb1 100644 --- a/core/src/TritMatrix.h +++ b/core/src/TritMatrix.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Matrix.h" diff --git a/core/src/WhiteRectDetector.cpp b/core/src/WhiteRectDetector.cpp index 3741caaf15..5148e9cfdd 100644 --- a/core/src/WhiteRectDetector.cpp +++ b/core/src/WhiteRectDetector.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "WhiteRectDetector.h" diff --git a/core/src/WhiteRectDetector.h b/core/src/WhiteRectDetector.h index 3d1cf39625..834d5a6db6 100644 --- a/core/src/WhiteRectDetector.h +++ b/core/src/WhiteRectDetector.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/ZXBigInteger.cpp b/core/src/ZXBigInteger.cpp index 1bb9ee7b70..56e67300e9 100644 --- a/core/src/ZXBigInteger.cpp +++ b/core/src/ZXBigInteger.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Huy Cuong Nguyen -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ZXBigInteger.h" diff --git a/core/src/ZXBigInteger.h b/core/src/ZXBigInteger.h index e9dfab0056..92aa21b0f6 100644 --- a/core/src/ZXBigInteger.h +++ b/core/src/ZXBigInteger.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/ZXConfig.h b/core/src/ZXConfig.h index 434680caad..0a1e6a6ea1 100644 --- a/core/src/ZXConfig.h +++ b/core/src/ZXConfig.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #define ZX_HAVE_CONFIG diff --git a/core/src/ZXContainerAlgorithms.h b/core/src/ZXContainerAlgorithms.h index d6e9ad59a6..28a9b89a19 100644 --- a/core/src/ZXContainerAlgorithms.h +++ b/core/src/ZXContainerAlgorithms.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/ZXNullable.h b/core/src/ZXNullable.h index 05deb694fa..8cd6bd040f 100644 --- a/core/src/ZXNullable.h +++ b/core/src/ZXNullable.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 1a122025fd..9027a677e1 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "AZDecoder.h" diff --git a/core/src/aztec/AZDecoder.h b/core/src/aztec/AZDecoder.h index d9eb6dd1fd..9db9f80a3e 100644 --- a/core/src/aztec/AZDecoder.h +++ b/core/src/aztec/AZDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index d0dfc2e5c7..edfcff0295 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "AZDetector.h" diff --git a/core/src/aztec/AZDetector.h b/core/src/aztec/AZDetector.h index b8307310e1..08a1edda7e 100644 --- a/core/src/aztec/AZDetector.h +++ b/core/src/aztec/AZDetector.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/aztec/AZDetectorResult.h b/core/src/aztec/AZDetectorResult.h index 478ccf764d..54c6c5524e 100644 --- a/core/src/aztec/AZDetectorResult.h +++ b/core/src/aztec/AZDetectorResult.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "DetectorResult.h" diff --git a/core/src/aztec/AZEncoder.cpp b/core/src/aztec/AZEncoder.cpp index 9bf45cfac9..f45eb000db 100644 --- a/core/src/aztec/AZEncoder.cpp +++ b/core/src/aztec/AZEncoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "AZEncoder.h" diff --git a/core/src/aztec/AZEncoder.h b/core/src/aztec/AZEncoder.h index dae27bc897..3c8d5351a3 100644 --- a/core/src/aztec/AZEncoder.h +++ b/core/src/aztec/AZEncoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrix.h" diff --git a/core/src/aztec/AZEncodingState.h b/core/src/aztec/AZEncodingState.h index 95c2a996fd..71ee8d3292 100644 --- a/core/src/aztec/AZEncodingState.h +++ b/core/src/aztec/AZEncodingState.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "AZToken.h" diff --git a/core/src/aztec/AZHighLevelEncoder.cpp b/core/src/aztec/AZHighLevelEncoder.cpp index d307e28229..0060050cd6 100644 --- a/core/src/aztec/AZHighLevelEncoder.cpp +++ b/core/src/aztec/AZHighLevelEncoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "AZHighLevelEncoder.h" diff --git a/core/src/aztec/AZHighLevelEncoder.h b/core/src/aztec/AZHighLevelEncoder.h index 62deba6a4c..5152a0938c 100644 --- a/core/src/aztec/AZHighLevelEncoder.h +++ b/core/src/aztec/AZHighLevelEncoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 4cd8157778..0f6547ae4d 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "AZReader.h" diff --git a/core/src/aztec/AZReader.h b/core/src/aztec/AZReader.h index d21dc6d866..6997b57ad5 100644 --- a/core/src/aztec/AZReader.h +++ b/core/src/aztec/AZReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Reader.h" diff --git a/core/src/aztec/AZToken.cpp b/core/src/aztec/AZToken.cpp index cb549fa1a9..3ea839ef02 100644 --- a/core/src/aztec/AZToken.cpp +++ b/core/src/aztec/AZToken.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "AZToken.h" diff --git a/core/src/aztec/AZToken.h b/core/src/aztec/AZToken.h index 85385bb052..24b2081c12 100644 --- a/core/src/aztec/AZToken.h +++ b/core/src/aztec/AZToken.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/aztec/AZWriter.cpp b/core/src/aztec/AZWriter.cpp index 8c29c5eab2..b41a15a62a 100644 --- a/core/src/aztec/AZWriter.cpp +++ b/core/src/aztec/AZWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "AZWriter.h" diff --git a/core/src/aztec/AZWriter.h b/core/src/aztec/AZWriter.h index deecff0b4e..1a41f6267e 100644 --- a/core/src/aztec/AZWriter.h +++ b/core/src/aztec/AZWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/datamatrix/DMBitLayout.cpp b/core/src/datamatrix/DMBitLayout.cpp index 99fc86ee85..1acffdb662 100644 --- a/core/src/datamatrix/DMBitLayout.cpp +++ b/core/src/datamatrix/DMBitLayout.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Huy Cuong Nguyen * Copyright 2006 Jeremias Maerki * Copyright 2020 Axel Waggersauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMBitLayout.h" diff --git a/core/src/datamatrix/DMBitLayout.h b/core/src/datamatrix/DMBitLayout.h index d2b266dbe1..395ba23ffd 100644 --- a/core/src/datamatrix/DMBitLayout.h +++ b/core/src/datamatrix/DMBitLayout.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/datamatrix/DMDataBlock.cpp b/core/src/datamatrix/DMDataBlock.cpp index c5f96b79b7..241a160ac5 100644 --- a/core/src/datamatrix/DMDataBlock.cpp +++ b/core/src/datamatrix/DMDataBlock.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMDataBlock.h" diff --git a/core/src/datamatrix/DMDataBlock.h b/core/src/datamatrix/DMDataBlock.h index ca13d83777..54dc7fade7 100644 --- a/core/src/datamatrix/DMDataBlock.h +++ b/core/src/datamatrix/DMDataBlock.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ByteArray.h" diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index c74be87345..871ca9422a 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMDecoder.h" diff --git a/core/src/datamatrix/DMDecoder.h b/core/src/datamatrix/DMDecoder.h index cdd135cd96..b91fa0b47e 100644 --- a/core/src/datamatrix/DMDecoder.h +++ b/core/src/datamatrix/DMDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 10df1a6691..4a9b6eb57d 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMDetector.h" diff --git a/core/src/datamatrix/DMDetector.h b/core/src/datamatrix/DMDetector.h index 18d727a28b..e632b08681 100644 --- a/core/src/datamatrix/DMDetector.h +++ b/core/src/datamatrix/DMDetector.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/datamatrix/DMECEncoder.cpp b/core/src/datamatrix/DMECEncoder.cpp index bedf09442d..484a1d6e5a 100644 --- a/core/src/datamatrix/DMECEncoder.cpp +++ b/core/src/datamatrix/DMECEncoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2006 Jeremias Maerki. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMECEncoder.h" diff --git a/core/src/datamatrix/DMECEncoder.h b/core/src/datamatrix/DMECEncoder.h index a06a298503..aea7d3bce4 100644 --- a/core/src/datamatrix/DMECEncoder.h +++ b/core/src/datamatrix/DMECEncoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2006 Jeremias Maerki. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/datamatrix/DMEncoderContext.h b/core/src/datamatrix/DMEncoderContext.h index 5f19b85727..ac5a81555f 100644 --- a/core/src/datamatrix/DMEncoderContext.h +++ b/core/src/datamatrix/DMEncoderContext.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2006-2007 Jeremias Maerki. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ByteArray.h" #include "DMSymbolInfo.h" diff --git a/core/src/datamatrix/DMHighLevelEncoder.cpp b/core/src/datamatrix/DMHighLevelEncoder.cpp index 627750909e..d030aa05be 100644 --- a/core/src/datamatrix/DMHighLevelEncoder.cpp +++ b/core/src/datamatrix/DMHighLevelEncoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMHighLevelEncoder.h" diff --git a/core/src/datamatrix/DMHighLevelEncoder.h b/core/src/datamatrix/DMHighLevelEncoder.h index ae5f09abb5..1a17587300 100644 --- a/core/src/datamatrix/DMHighLevelEncoder.h +++ b/core/src/datamatrix/DMHighLevelEncoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2006-2007 Jeremias Maerki. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index 5d6aad0a09..a2ac999a84 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMReader.h" diff --git a/core/src/datamatrix/DMReader.h b/core/src/datamatrix/DMReader.h index 8a3e0070db..571a9c0e46 100644 --- a/core/src/datamatrix/DMReader.h +++ b/core/src/datamatrix/DMReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Reader.h" #include diff --git a/core/src/datamatrix/DMSymbolInfo.cpp b/core/src/datamatrix/DMSymbolInfo.cpp index 3aac399de0..0a3c0ce848 100644 --- a/core/src/datamatrix/DMSymbolInfo.cpp +++ b/core/src/datamatrix/DMSymbolInfo.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMSymbolInfo.h" diff --git a/core/src/datamatrix/DMSymbolInfo.h b/core/src/datamatrix/DMSymbolInfo.h index e033fbfb4e..fa366da4a1 100644 --- a/core/src/datamatrix/DMSymbolInfo.h +++ b/core/src/datamatrix/DMSymbolInfo.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { namespace DataMatrix { diff --git a/core/src/datamatrix/DMSymbolShape.h b/core/src/datamatrix/DMSymbolShape.h index 383c1421ca..3c15f5d156 100644 --- a/core/src/datamatrix/DMSymbolShape.h +++ b/core/src/datamatrix/DMSymbolShape.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { namespace DataMatrix { diff --git a/core/src/datamatrix/DMVersion.cpp b/core/src/datamatrix/DMVersion.cpp index f119e82865..79426eeb41 100644 --- a/core/src/datamatrix/DMVersion.cpp +++ b/core/src/datamatrix/DMVersion.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMVersion.h" diff --git a/core/src/datamatrix/DMVersion.h b/core/src/datamatrix/DMVersion.h index 87e22fa519..ad9837a78b 100644 --- a/core/src/datamatrix/DMVersion.h +++ b/core/src/datamatrix/DMVersion.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing::DataMatrix { diff --git a/core/src/datamatrix/DMWriter.cpp b/core/src/datamatrix/DMWriter.cpp index fe79e603cb..a95f5ad8a2 100644 --- a/core/src/datamatrix/DMWriter.cpp +++ b/core/src/datamatrix/DMWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DMWriter.h" diff --git a/core/src/datamatrix/DMWriter.h b/core/src/datamatrix/DMWriter.h index e90e8bfda7..61b0caba2a 100644 --- a/core/src/datamatrix/DMWriter.h +++ b/core/src/datamatrix/DMWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/maxicode/MCBitMatrixParser.cpp b/core/src/maxicode/MCBitMatrixParser.cpp index 895f2f7544..6b9ee368f7 100644 --- a/core/src/maxicode/MCBitMatrixParser.cpp +++ b/core/src/maxicode/MCBitMatrixParser.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "MCBitMatrixParser.h" diff --git a/core/src/maxicode/MCBitMatrixParser.h b/core/src/maxicode/MCBitMatrixParser.h index 5d405926f9..16c8867cdf 100644 --- a/core/src/maxicode/MCBitMatrixParser.h +++ b/core/src/maxicode/MCBitMatrixParser.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 922a8a477c..5bbeba0e95 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "MCDecoder.h" diff --git a/core/src/maxicode/MCDecoder.h b/core/src/maxicode/MCDecoder.h index cbc8bc6d0b..7a112c64ac 100644 --- a/core/src/maxicode/MCDecoder.h +++ b/core/src/maxicode/MCDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index 36c5a53607..dd6f7cc0f3 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "MCReader.h" diff --git a/core/src/maxicode/MCReader.h b/core/src/maxicode/MCReader.h index 5503c856b9..3dacd59f9c 100644 --- a/core/src/maxicode/MCReader.h +++ b/core/src/maxicode/MCReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Reader.h" diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index 354f068511..53d8dec94b 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCodabarReader.h" diff --git a/core/src/oned/ODCodabarReader.h b/core/src/oned/ODCodabarReader.h index 69945c3d6d..52e9c7a8f8 100644 --- a/core/src/oned/ODCodabarReader.h +++ b/core/src/oned/ODCodabarReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ODRowReader.h" diff --git a/core/src/oned/ODCodabarWriter.cpp b/core/src/oned/ODCodabarWriter.cpp index 48ad392b05..1d74711299 100644 --- a/core/src/oned/ODCodabarWriter.cpp +++ b/core/src/oned/ODCodabarWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCodabarWriter.h" diff --git a/core/src/oned/ODCodabarWriter.h b/core/src/oned/ODCodabarWriter.h index c4a3f960e8..7304d49efc 100644 --- a/core/src/oned/ODCodabarWriter.h +++ b/core/src/oned/ODCodabarWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODCode128Patterns.cpp b/core/src/oned/ODCode128Patterns.cpp index 1e9a354057..4500398e1e 100644 --- a/core/src/oned/ODCode128Patterns.cpp +++ b/core/src/oned/ODCode128Patterns.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCode128Patterns.h" diff --git a/core/src/oned/ODCode128Patterns.h b/core/src/oned/ODCode128Patterns.h index aeafd2e3cb..391e9be30d 100644 --- a/core/src/oned/ODCode128Patterns.h +++ b/core/src/oned/ODCode128Patterns.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index f730999853..5f986a04d4 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCode128Reader.h" diff --git a/core/src/oned/ODCode128Reader.h b/core/src/oned/ODCode128Reader.h index ebdc6bf19f..1a2a8db4d1 100644 --- a/core/src/oned/ODCode128Reader.h +++ b/core/src/oned/ODCode128Reader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ODRowReader.h" diff --git a/core/src/oned/ODCode128Writer.cpp b/core/src/oned/ODCode128Writer.cpp index 32133eac3b..2325376d5e 100644 --- a/core/src/oned/ODCode128Writer.cpp +++ b/core/src/oned/ODCode128Writer.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCode128Writer.h" diff --git a/core/src/oned/ODCode128Writer.h b/core/src/oned/ODCode128Writer.h index 4efb1c52cd..5e517a66a6 100644 --- a/core/src/oned/ODCode128Writer.h +++ b/core/src/oned/ODCode128Writer.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index 58c1a70871..3952025a4f 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCode39Reader.h" diff --git a/core/src/oned/ODCode39Reader.h b/core/src/oned/ODCode39Reader.h index 5c5daef9f8..58b4de493a 100644 --- a/core/src/oned/ODCode39Reader.h +++ b/core/src/oned/ODCode39Reader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ODRowReader.h" diff --git a/core/src/oned/ODCode39Writer.cpp b/core/src/oned/ODCode39Writer.cpp index 919e59f250..e05faa661f 100644 --- a/core/src/oned/ODCode39Writer.cpp +++ b/core/src/oned/ODCode39Writer.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCode39Writer.h" diff --git a/core/src/oned/ODCode39Writer.h b/core/src/oned/ODCode39Writer.h index 6d57e493d5..3342490301 100644 --- a/core/src/oned/ODCode39Writer.h +++ b/core/src/oned/ODCode39Writer.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index d9f3dd6859..484308aafc 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCode93Reader.h" diff --git a/core/src/oned/ODCode93Reader.h b/core/src/oned/ODCode93Reader.h index 95a385e0ad..86ea8ac593 100644 --- a/core/src/oned/ODCode93Reader.h +++ b/core/src/oned/ODCode93Reader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ODRowReader.h" diff --git a/core/src/oned/ODCode93Writer.cpp b/core/src/oned/ODCode93Writer.cpp index dfc42113aa..f84693ffce 100644 --- a/core/src/oned/ODCode93Writer.cpp +++ b/core/src/oned/ODCode93Writer.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODCode93Writer.h" diff --git a/core/src/oned/ODCode93Writer.h b/core/src/oned/ODCode93Writer.h index 1a6dd09e46..e33f4f512b 100644 --- a/core/src/oned/ODCode93Writer.h +++ b/core/src/oned/ODCode93Writer.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODDataBarCommon.cpp b/core/src/oned/ODDataBarCommon.cpp index aba8505311..57773f9dc6 100644 --- a/core/src/oned/ODDataBarCommon.cpp +++ b/core/src/oned/ODDataBarCommon.cpp @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODDataBarCommon.h" diff --git a/core/src/oned/ODDataBarCommon.h b/core/src/oned/ODDataBarCommon.h index 08669b208e..f1a53a3dcf 100644 --- a/core/src/oned/ODDataBarCommon.h +++ b/core/src/oned/ODDataBarCommon.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ODRowReader.h" #include "Pattern.h" diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 9421a4b7be..95832f52de 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODDataBarExpandedReader.h" diff --git a/core/src/oned/ODDataBarExpandedReader.h b/core/src/oned/ODDataBarExpandedReader.h index a2e9a306d6..290482470a 100644 --- a/core/src/oned/ODDataBarExpandedReader.h +++ b/core/src/oned/ODDataBarExpandedReader.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "DecodeHints.h" #include "ODRowReader.h" diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index e45ae3e8c9..c516370f4a 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODDataBarReader.h" diff --git a/core/src/oned/ODDataBarReader.h b/core/src/oned/ODDataBarReader.h index 2da0109691..0e10cebc1d 100644 --- a/core/src/oned/ODDataBarReader.h +++ b/core/src/oned/ODDataBarReader.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "DecodeHints.h" #include "ODRowReader.h" diff --git a/core/src/oned/ODEAN13Writer.cpp b/core/src/oned/ODEAN13Writer.cpp index aa36f8e851..156ac51999 100644 --- a/core/src/oned/ODEAN13Writer.cpp +++ b/core/src/oned/ODEAN13Writer.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODEAN13Writer.h" diff --git a/core/src/oned/ODEAN13Writer.h b/core/src/oned/ODEAN13Writer.h index 8ba0c652f9..bfed737bc1 100644 --- a/core/src/oned/ODEAN13Writer.h +++ b/core/src/oned/ODEAN13Writer.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODEAN8Writer.cpp b/core/src/oned/ODEAN8Writer.cpp index 1533e94d4d..f659a1cb18 100644 --- a/core/src/oned/ODEAN8Writer.cpp +++ b/core/src/oned/ODEAN8Writer.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODEAN8Writer.h" diff --git a/core/src/oned/ODEAN8Writer.h b/core/src/oned/ODEAN8Writer.h index c1c1044173..2bbabd265a 100644 --- a/core/src/oned/ODEAN8Writer.h +++ b/core/src/oned/ODEAN8Writer.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index e314b99368..704cc7bfaa 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODITFReader.h" diff --git a/core/src/oned/ODITFReader.h b/core/src/oned/ODITFReader.h index 322ee17d20..7f494d76bf 100644 --- a/core/src/oned/ODITFReader.h +++ b/core/src/oned/ODITFReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ODRowReader.h" diff --git a/core/src/oned/ODITFWriter.cpp b/core/src/oned/ODITFWriter.cpp index 34f49a12d6..27b8f58e58 100644 --- a/core/src/oned/ODITFWriter.cpp +++ b/core/src/oned/ODITFWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODITFWriter.h" diff --git a/core/src/oned/ODITFWriter.h b/core/src/oned/ODITFWriter.h index fcf699d4e2..de837dd3a5 100644 --- a/core/src/oned/ODITFWriter.h +++ b/core/src/oned/ODITFWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 06218ac1e1..cfa806ea17 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODMultiUPCEANReader.h" diff --git a/core/src/oned/ODMultiUPCEANReader.h b/core/src/oned/ODMultiUPCEANReader.h index 7385001210..999c542290 100644 --- a/core/src/oned/ODMultiUPCEANReader.h +++ b/core/src/oned/ODMultiUPCEANReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BarcodeFormat.h" #include "DecodeHints.h" diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index d84d1d0e65..59d61ad4e1 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODReader.h" diff --git a/core/src/oned/ODReader.h b/core/src/oned/ODReader.h index e07d8d4e57..bccd417c2e 100644 --- a/core/src/oned/ODReader.h +++ b/core/src/oned/ODReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Reader.h" diff --git a/core/src/oned/ODRowReader.cpp b/core/src/oned/ODRowReader.cpp index de0febc20e..ef5bb3458f 100644 --- a/core/src/oned/ODRowReader.cpp +++ b/core/src/oned/ODRowReader.cpp @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODRowReader.h" diff --git a/core/src/oned/ODRowReader.h b/core/src/oned/ODRowReader.h index ec6bc2882e..9bf55fc9d2 100644 --- a/core/src/oned/ODRowReader.h +++ b/core/src/oned/ODRowReader.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitArray.h" #include "DecodeStatus.h" diff --git a/core/src/oned/ODUPCAWriter.cpp b/core/src/oned/ODUPCAWriter.cpp index c5eedd925c..0a789b6e95 100644 --- a/core/src/oned/ODUPCAWriter.cpp +++ b/core/src/oned/ODUPCAWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODUPCAWriter.h" diff --git a/core/src/oned/ODUPCAWriter.h b/core/src/oned/ODUPCAWriter.h index 8d6bfb799c..467fbf0682 100644 --- a/core/src/oned/ODUPCAWriter.h +++ b/core/src/oned/ODUPCAWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODUPCEANCommon.cpp b/core/src/oned/ODUPCEANCommon.cpp index 997249baf1..7a9b4a8daa 100644 --- a/core/src/oned/ODUPCEANCommon.cpp +++ b/core/src/oned/ODUPCEANCommon.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODUPCEANCommon.h" diff --git a/core/src/oned/ODUPCEANCommon.h b/core/src/oned/ODUPCEANCommon.h index f2b8113f31..3c0eb59ac3 100644 --- a/core/src/oned/ODUPCEANCommon.h +++ b/core/src/oned/ODUPCEANCommon.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "GTIN.h" diff --git a/core/src/oned/ODUPCEWriter.cpp b/core/src/oned/ODUPCEWriter.cpp index b76b990080..5adf99cc4f 100644 --- a/core/src/oned/ODUPCEWriter.cpp +++ b/core/src/oned/ODUPCEWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODUPCEWriter.h" diff --git a/core/src/oned/ODUPCEWriter.h b/core/src/oned/ODUPCEWriter.h index b7f6177bfd..6e48975970 100644 --- a/core/src/oned/ODUPCEWriter.h +++ b/core/src/oned/ODUPCEWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/ODWriterHelper.cpp b/core/src/oned/ODWriterHelper.cpp index dc99babea5..e0f0a33bf8 100644 --- a/core/src/oned/ODWriterHelper.cpp +++ b/core/src/oned/ODWriterHelper.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODWriterHelper.h" diff --git a/core/src/oned/ODWriterHelper.h b/core/src/oned/ODWriterHelper.h index 63a2cbb060..f50f644df1 100644 --- a/core/src/oned/ODWriterHelper.h +++ b/core/src/oned/ODWriterHelper.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrix.h" diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp index 315a41b903..3a669a049f 100644 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp +++ b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 /* * These authors would like to acknowledge the Spanish Ministry of Industry, diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.h b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.h index 71900b66fe..2c708b4354 100644 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.h +++ b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/rss/ODRSSFieldParser.cpp b/core/src/oned/rss/ODRSSFieldParser.cpp index ef8552b847..6551cf1acf 100644 --- a/core/src/oned/rss/ODRSSFieldParser.cpp +++ b/core/src/oned/rss/ODRSSFieldParser.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODRSSFieldParser.h" diff --git a/core/src/oned/rss/ODRSSFieldParser.h b/core/src/oned/rss/ODRSSFieldParser.h index 16a37abd62..0d24839429 100644 --- a/core/src/oned/rss/ODRSSFieldParser.h +++ b/core/src/oned/rss/ODRSSFieldParser.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp b/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp index 7e88ec0b9b..5064abfd71 100644 --- a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp +++ b/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ODRSSGenericAppIdDecoder.h" diff --git a/core/src/oned/rss/ODRSSGenericAppIdDecoder.h b/core/src/oned/rss/ODRSSGenericAppIdDecoder.h index e93ccd2d2b..b6fe69485c 100644 --- a/core/src/oned/rss/ODRSSGenericAppIdDecoder.h +++ b/core/src/oned/rss/ODRSSGenericAppIdDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/pdf417/PDFBarcodeMetadata.h b/core/src/pdf417/PDFBarcodeMetadata.h index 33a3785722..335a7eb6f2 100644 --- a/core/src/pdf417/PDFBarcodeMetadata.h +++ b/core/src/pdf417/PDFBarcodeMetadata.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { namespace Pdf417 { diff --git a/core/src/pdf417/PDFBarcodeValue.cpp b/core/src/pdf417/PDFBarcodeValue.cpp index 2d02d0ff2f..da608efb7d 100644 --- a/core/src/pdf417/PDFBarcodeValue.cpp +++ b/core/src/pdf417/PDFBarcodeValue.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFBarcodeValue.h" diff --git a/core/src/pdf417/PDFBarcodeValue.h b/core/src/pdf417/PDFBarcodeValue.h index d7d8ca7e92..c15c0f365c 100644 --- a/core/src/pdf417/PDFBarcodeValue.h +++ b/core/src/pdf417/PDFBarcodeValue.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/pdf417/PDFBoundingBox.cpp b/core/src/pdf417/PDFBoundingBox.cpp index fb07c74df2..bd9ea35cc8 100644 --- a/core/src/pdf417/PDFBoundingBox.cpp +++ b/core/src/pdf417/PDFBoundingBox.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFBoundingBox.h" diff --git a/core/src/pdf417/PDFBoundingBox.h b/core/src/pdf417/PDFBoundingBox.h index a09eab4dd4..fe2f7344e5 100644 --- a/core/src/pdf417/PDFBoundingBox.h +++ b/core/src/pdf417/PDFBoundingBox.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ZXNullable.h" #include "ResultPoint.h" diff --git a/core/src/pdf417/PDFCodeword.h b/core/src/pdf417/PDFCodeword.h index 4a2d68de16..bc351e0c9c 100644 --- a/core/src/pdf417/PDFCodeword.h +++ b/core/src/pdf417/PDFCodeword.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { namespace Pdf417 { diff --git a/core/src/pdf417/PDFCodewordDecoder.cpp b/core/src/pdf417/PDFCodewordDecoder.cpp index f3f17bba53..9318156ad2 100644 --- a/core/src/pdf417/PDFCodewordDecoder.cpp +++ b/core/src/pdf417/PDFCodewordDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFCodewordDecoder.h" #include "BitArray.h" diff --git a/core/src/pdf417/PDFCodewordDecoder.h b/core/src/pdf417/PDFCodewordDecoder.h index 5b8dc0a0ec..cb661ff10b 100644 --- a/core/src/pdf417/PDFCodewordDecoder.h +++ b/core/src/pdf417/PDFCodewordDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/pdf417/PDFCompaction.h b/core/src/pdf417/PDFCompaction.h index ddaa0f3bee..b8ac5d7b02 100644 --- a/core/src/pdf417/PDFCompaction.h +++ b/core/src/pdf417/PDFCompaction.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { namespace Pdf417 { diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index af57d17999..1d0620ce23 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFDecodedBitStreamParser.h" diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.h b/core/src/pdf417/PDFDecodedBitStreamParser.h index 696d118e13..39b03fed41 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.h +++ b/core/src/pdf417/PDFDecodedBitStreamParser.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/pdf417/PDFDecoderResultExtra.h b/core/src/pdf417/PDFDecoderResultExtra.h index 01284bd2c4..8aaf60a253 100644 --- a/core/src/pdf417/PDFDecoderResultExtra.h +++ b/core/src/pdf417/PDFDecoderResultExtra.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "CustomData.h" diff --git a/core/src/pdf417/PDFDetectionResult.cpp b/core/src/pdf417/PDFDetectionResult.cpp index 07d31aa14f..c145a1be2e 100644 --- a/core/src/pdf417/PDFDetectionResult.cpp +++ b/core/src/pdf417/PDFDetectionResult.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFDetectionResult.h" #include "PDFCodewordDecoder.h" diff --git a/core/src/pdf417/PDFDetectionResult.h b/core/src/pdf417/PDFDetectionResult.h index 97fb116aa6..b5dedc64d9 100644 --- a/core/src/pdf417/PDFDetectionResult.h +++ b/core/src/pdf417/PDFDetectionResult.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "PDFBarcodeMetadata.h" #include "PDFBoundingBox.h" diff --git a/core/src/pdf417/PDFDetectionResultColumn.cpp b/core/src/pdf417/PDFDetectionResultColumn.cpp index 18131bcda7..8c85065889 100644 --- a/core/src/pdf417/PDFDetectionResultColumn.cpp +++ b/core/src/pdf417/PDFDetectionResultColumn.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFDetectionResultColumn.h" #include "PDFBarcodeMetadata.h" diff --git a/core/src/pdf417/PDFDetectionResultColumn.h b/core/src/pdf417/PDFDetectionResultColumn.h index 732d8724c4..0df6d7fc73 100644 --- a/core/src/pdf417/PDFDetectionResultColumn.h +++ b/core/src/pdf417/PDFDetectionResultColumn.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "PDFBoundingBox.h" #include "PDFCodeword.h" diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 5ddf915927..3d29fc59fb 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFDetector.h" #include "BinaryBitmap.h" diff --git a/core/src/pdf417/PDFDetector.h b/core/src/pdf417/PDFDetector.h index ce8fbff464..e129d6d2c0 100644 --- a/core/src/pdf417/PDFDetector.h +++ b/core/src/pdf417/PDFDetector.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ResultPoint.h" #include "ZXNullable.h" diff --git a/core/src/pdf417/PDFEncoder.cpp b/core/src/pdf417/PDFEncoder.cpp index c38a35ce2f..e53daeea7c 100644 --- a/core/src/pdf417/PDFEncoder.cpp +++ b/core/src/pdf417/PDFEncoder.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors * Copyright 2006 Jeremias Maerki -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFEncoder.h" #include "PDFHighLevelEncoder.h" diff --git a/core/src/pdf417/PDFEncoder.h b/core/src/pdf417/PDFEncoder.h index 459a8634c0..f58d1279ef 100644 --- a/core/src/pdf417/PDFEncoder.h +++ b/core/src/pdf417/PDFEncoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "CharacterSet.h" #include "PDFCompaction.h" #include "ZXContainerAlgorithms.h" diff --git a/core/src/pdf417/PDFHighLevelEncoder.cpp b/core/src/pdf417/PDFHighLevelEncoder.cpp index 2066d78c0b..c09a8fb536 100644 --- a/core/src/pdf417/PDFHighLevelEncoder.cpp +++ b/core/src/pdf417/PDFHighLevelEncoder.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFHighLevelEncoder.h" #include "PDFCompaction.h" diff --git a/core/src/pdf417/PDFHighLevelEncoder.h b/core/src/pdf417/PDFHighLevelEncoder.h index 0df789e0be..e0bbe89d28 100644 --- a/core/src/pdf417/PDFHighLevelEncoder.h +++ b/core/src/pdf417/PDFHighLevelEncoder.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors * Copyright 2006 Jeremias Maerki -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/pdf417/PDFModulusGF.cpp b/core/src/pdf417/PDFModulusGF.cpp index eebc090947..3859c1c7e4 100644 --- a/core/src/pdf417/PDFModulusGF.cpp +++ b/core/src/pdf417/PDFModulusGF.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFModulusGF.h" #include diff --git a/core/src/pdf417/PDFModulusGF.h b/core/src/pdf417/PDFModulusGF.h index 12095c9491..3ee80bc050 100644 --- a/core/src/pdf417/PDFModulusGF.h +++ b/core/src/pdf417/PDFModulusGF.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "PDFModulusPoly.h" #include "ZXConfig.h" diff --git a/core/src/pdf417/PDFModulusPoly.cpp b/core/src/pdf417/PDFModulusPoly.cpp index bfd414cb36..9883775f77 100644 --- a/core/src/pdf417/PDFModulusPoly.cpp +++ b/core/src/pdf417/PDFModulusPoly.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFModulusPoly.h" #include "PDFModulusGF.h" diff --git a/core/src/pdf417/PDFModulusPoly.h b/core/src/pdf417/PDFModulusPoly.h index ba33405f74..ed44abe7d3 100644 --- a/core/src/pdf417/PDFModulusPoly.h +++ b/core/src/pdf417/PDFModulusPoly.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ZXContainerAlgorithms.h" diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index dadc456117..7d179b37a7 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFReader.h" #include "PDFDetector.h" diff --git a/core/src/pdf417/PDFReader.h b/core/src/pdf417/PDFReader.h index 138d31ef1e..435a50f252 100644 --- a/core/src/pdf417/PDFReader.h +++ b/core/src/pdf417/PDFReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Reader.h" diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index c95f80a1dc..4d4217f31a 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFScanningDecoder.h" #include "PDFBoundingBox.h" diff --git a/core/src/pdf417/PDFScanningDecoder.h b/core/src/pdf417/PDFScanningDecoder.h index 7ff7248121..08d795649c 100644 --- a/core/src/pdf417/PDFScanningDecoder.h +++ b/core/src/pdf417/PDFScanningDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/pdf417/PDFWriter.cpp b/core/src/pdf417/PDFWriter.cpp index 60d8206bea..19543119d6 100644 --- a/core/src/pdf417/PDFWriter.cpp +++ b/core/src/pdf417/PDFWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PDFWriter.h" #include "PDFEncoder.h" diff --git a/core/src/pdf417/PDFWriter.h b/core/src/pdf417/PDFWriter.h index dad8e360aa..a9e01c943b 100644 --- a/core/src/pdf417/PDFWriter.h +++ b/core/src/pdf417/PDFWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/core/src/qrcode/QRBitMatrixParser.cpp b/core/src/qrcode/QRBitMatrixParser.cpp index 97d484dbdd..ed614fe9a3 100644 --- a/core/src/qrcode/QRBitMatrixParser.cpp +++ b/core/src/qrcode/QRBitMatrixParser.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRBitMatrixParser.h" diff --git a/core/src/qrcode/QRBitMatrixParser.h b/core/src/qrcode/QRBitMatrixParser.h index b8aa567adf..cabb260210 100644 --- a/core/src/qrcode/QRBitMatrixParser.h +++ b/core/src/qrcode/QRBitMatrixParser.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { diff --git a/core/src/qrcode/QRCodecMode.cpp b/core/src/qrcode/QRCodecMode.cpp index f0e635128a..4937b1c858 100644 --- a/core/src/qrcode/QRCodecMode.cpp +++ b/core/src/qrcode/QRCodecMode.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRCodecMode.h" diff --git a/core/src/qrcode/QRCodecMode.h b/core/src/qrcode/QRCodecMode.h index eca59e12ca..f55bc677f6 100644 --- a/core/src/qrcode/QRCodecMode.h +++ b/core/src/qrcode/QRCodecMode.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { namespace QRCode { diff --git a/core/src/qrcode/QRDataBlock.cpp b/core/src/qrcode/QRDataBlock.cpp index 2b005aa48f..0c63a52ef5 100644 --- a/core/src/qrcode/QRDataBlock.cpp +++ b/core/src/qrcode/QRDataBlock.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRDataBlock.h" diff --git a/core/src/qrcode/QRDataBlock.h b/core/src/qrcode/QRDataBlock.h index e63c326dac..d5f9858785 100644 --- a/core/src/qrcode/QRDataBlock.h +++ b/core/src/qrcode/QRDataBlock.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ByteArray.h" diff --git a/core/src/qrcode/QRDataMask.h b/core/src/qrcode/QRDataMask.h index 8b43b9ab86..b735baf9ec 100644 --- a/core/src/qrcode/QRDataMask.h +++ b/core/src/qrcode/QRDataMask.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrix.h" diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 5065401fda..31ed2bbbec 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRDecoder.h" diff --git a/core/src/qrcode/QRDecoder.h b/core/src/qrcode/QRDecoder.h index 2f10bddc59..32194d8899 100644 --- a/core/src/qrcode/QRDecoder.h +++ b/core/src/qrcode/QRDecoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index bf218c54d1..9c189bb3fe 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRDetector.h" diff --git a/core/src/qrcode/QRDetector.h b/core/src/qrcode/QRDetector.h index bfb9bc2591..77b5914615 100644 --- a/core/src/qrcode/QRDetector.h +++ b/core/src/qrcode/QRDetector.h @@ -1,21 +1,11 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2021 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ConcentricFinder.h" #include "DetectorResult.h" diff --git a/core/src/qrcode/QRECB.h b/core/src/qrcode/QRECB.h index 689d44f6f2..37cefea6df 100644 --- a/core/src/qrcode/QRECB.h +++ b/core/src/qrcode/QRECB.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/qrcode/QREncodeResult.h b/core/src/qrcode/QREncodeResult.h index 366a475215..8898c04dc3 100644 --- a/core/src/qrcode/QREncodeResult.h +++ b/core/src/qrcode/QREncodeResult.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BitMatrix.h" #include "ByteArray.h" diff --git a/core/src/qrcode/QREncoder.cpp b/core/src/qrcode/QREncoder.cpp index 1601623196..db3c90f6fb 100644 --- a/core/src/qrcode/QREncoder.cpp +++ b/core/src/qrcode/QREncoder.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QREncoder.h" diff --git a/core/src/qrcode/QREncoder.h b/core/src/qrcode/QREncoder.h index 95420dee0a..b8e364806a 100644 --- a/core/src/qrcode/QREncoder.h +++ b/core/src/qrcode/QREncoder.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/core/src/qrcode/QRErrorCorrectionLevel.cpp b/core/src/qrcode/QRErrorCorrectionLevel.cpp index 2a3b93ff15..6194e5c7b5 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.cpp +++ b/core/src/qrcode/QRErrorCorrectionLevel.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRErrorCorrectionLevel.h" diff --git a/core/src/qrcode/QRErrorCorrectionLevel.h b/core/src/qrcode/QRErrorCorrectionLevel.h index 1993fffdda..58d689240f 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.h +++ b/core/src/qrcode/QRErrorCorrectionLevel.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { namespace QRCode { diff --git a/core/src/qrcode/QRFormatInformation.cpp b/core/src/qrcode/QRFormatInformation.cpp index f5bae8ed83..44db397c06 100644 --- a/core/src/qrcode/QRFormatInformation.cpp +++ b/core/src/qrcode/QRFormatInformation.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRFormatInformation.h" diff --git a/core/src/qrcode/QRFormatInformation.h b/core/src/qrcode/QRFormatInformation.h index a8680b8023..e83775b0fc 100644 --- a/core/src/qrcode/QRFormatInformation.h +++ b/core/src/qrcode/QRFormatInformation.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "QRErrorCorrectionLevel.h" diff --git a/core/src/qrcode/QRMaskUtil.cpp b/core/src/qrcode/QRMaskUtil.cpp index e94236377a..0213730b2d 100644 --- a/core/src/qrcode/QRMaskUtil.cpp +++ b/core/src/qrcode/QRMaskUtil.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRMaskUtil.h" diff --git a/core/src/qrcode/QRMaskUtil.h b/core/src/qrcode/QRMaskUtil.h index 67d4da08f0..f7a0c06ddd 100644 --- a/core/src/qrcode/QRMaskUtil.h +++ b/core/src/qrcode/QRMaskUtil.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "TritMatrix.h" diff --git a/core/src/qrcode/QRMatrixUtil.cpp b/core/src/qrcode/QRMatrixUtil.cpp index 825cd40ba2..4767eebc23 100644 --- a/core/src/qrcode/QRMatrixUtil.cpp +++ b/core/src/qrcode/QRMatrixUtil.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRMatrixUtil.h" diff --git a/core/src/qrcode/QRMatrixUtil.h b/core/src/qrcode/QRMatrixUtil.h index 4ca09a33d6..11f922865f 100644 --- a/core/src/qrcode/QRMatrixUtil.h +++ b/core/src/qrcode/QRMatrixUtil.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "TritMatrix.h" diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 505ab6ab0d..60007c87a4 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -2,19 +2,8 @@ * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors * Copyright 2022 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRReader.h" diff --git a/core/src/qrcode/QRReader.h b/core/src/qrcode/QRReader.h index e93a05afad..d7e96f935f 100644 --- a/core/src/qrcode/QRReader.h +++ b/core/src/qrcode/QRReader.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "Reader.h" diff --git a/core/src/qrcode/QRVersion.cpp b/core/src/qrcode/QRVersion.cpp index 0833b19340..537bc91fc7 100644 --- a/core/src/qrcode/QRVersion.cpp +++ b/core/src/qrcode/QRVersion.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRVersion.h" diff --git a/core/src/qrcode/QRVersion.h b/core/src/qrcode/QRVersion.h index 393bcbc0e2..024f1a7387 100644 --- a/core/src/qrcode/QRVersion.h +++ b/core/src/qrcode/QRVersion.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "QRECB.h" #include "QRErrorCorrectionLevel.h" diff --git a/core/src/qrcode/QRWriter.cpp b/core/src/qrcode/QRWriter.cpp index 52d6f065da..63a161150e 100644 --- a/core/src/qrcode/QRWriter.cpp +++ b/core/src/qrcode/QRWriter.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "QRWriter.h" diff --git a/core/src/qrcode/QRWriter.h b/core/src/qrcode/QRWriter.h index c5a12aaae3..5aef3b70b8 100644 --- a/core/src/qrcode/QRWriter.h +++ b/core/src/qrcode/QRWriter.h @@ -1,20 +1,10 @@ -#pragma once /* * Copyright 2016 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include diff --git a/example/ZXingOpenCV.cpp b/example/ZXingOpenCV.cpp index 7507068ba7..d4c3e4c06f 100644 --- a/example/ZXingOpenCV.cpp +++ b/example/ZXingOpenCV.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 Axel Waggershauser - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +*/ +// SPDX-License-Identifier: Apache-2.0 #include "ZXingOpenCV.h" diff --git a/example/ZXingQtCamReader.cpp b/example/ZXingQtCamReader.cpp index db11009b25..102312e0e6 100644 --- a/example/ZXingQtCamReader.cpp +++ b/example/ZXingQtCamReader.cpp @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +*/ +// SPDX-License-Identifier: Apache-2.0 #include #include diff --git a/example/ZXingQtReader.cpp b/example/ZXingQtReader.cpp index dedd621780..2fa90d1a8e 100644 --- a/example/ZXingQtReader.cpp +++ b/example/ZXingQtReader.cpp @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +*/ +// SPDX-License-Identifier: Apache-2.0 #include "ZXingQtReader.h" diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 84dcff4eb6..b3c9958ff8 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ReadBarcode.h" #include "TextUtfEncoding.h" diff --git a/example/ZXingWriter.cpp b/example/ZXingWriter.cpp index 2cec15e0b1..14934d62bf 100644 --- a/example/ZXingWriter.cpp +++ b/example/ZXingWriter.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BarcodeFormat.h" #include "BitMatrix.h" diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index ac66da3146..f03a369b48 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2019 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BlackboxTestRunner.h" diff --git a/test/blackbox/BlackboxTestRunner.h b/test/blackbox/BlackboxTestRunner.h index e1229a4508..a4527b100f 100644 --- a/test/blackbox/BlackboxTestRunner.h +++ b/test/blackbox/BlackboxTestRunner.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ZXFilesystem.h" diff --git a/test/blackbox/ImageLoader.cpp b/test/blackbox/ImageLoader.cpp index 51e0066886..69d1d7c303 100644 --- a/test/blackbox/ImageLoader.cpp +++ b/test/blackbox/ImageLoader.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2019 Axel Waggersauser. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ImageLoader.h" diff --git a/test/blackbox/ImageLoader.h b/test/blackbox/ImageLoader.h index ff1497b690..29469ce989 100644 --- a/test/blackbox/ImageLoader.h +++ b/test/blackbox/ImageLoader.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ReadBarcode.h" #include "ZXFilesystem.h" diff --git a/test/blackbox/TestReaderMain.cpp b/test/blackbox/TestReaderMain.cpp index cabc70267f..4aad4905cc 100644 --- a/test/blackbox/TestReaderMain.cpp +++ b/test/blackbox/TestReaderMain.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2017 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BlackboxTestRunner.h" #include "ImageLoader.h" diff --git a/test/blackbox/TestWriterMain.cpp b/test/blackbox/TestWriterMain.cpp index 8dfc63e841..cb8e728198 100644 --- a/test/blackbox/TestWriterMain.cpp +++ b/test/blackbox/TestWriterMain.cpp @@ -1,19 +1,8 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2019 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrix.h" #include "MultiFormatWriter.h" diff --git a/test/blackbox/ZXFilesystem.h b/test/blackbox/ZXFilesystem.h index add9236e41..45f08d3455 100644 --- a/test/blackbox/ZXFilesystem.h +++ b/test/blackbox/ZXFilesystem.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2019 Axel Waggershauser. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #if __has_include() # include diff --git a/test/unit/BarcodeFormatTest.cpp b/test/unit/BarcodeFormatTest.cpp index 425ce40066..7dfcbf3ab8 100644 --- a/test/unit/BarcodeFormatTest.cpp +++ b/test/unit/BarcodeFormatTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BarcodeFormat.h" diff --git a/test/unit/BitArrayUtility.cpp b/test/unit/BitArrayUtility.cpp index a5d67f6586..e6ab50deb0 100644 --- a/test/unit/BitArrayUtility.cpp +++ b/test/unit/BitArrayUtility.cpp @@ -1,18 +1,7 @@ /* * Copyright 2017 Huy Cuong Nguyen -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitArrayUtility.h" #include "BitArray.h" diff --git a/test/unit/BitHacksTest.cpp b/test/unit/BitHacksTest.cpp index 554f55f8e7..8edfb96252 100644 --- a/test/unit/BitHacksTest.cpp +++ b/test/unit/BitHacksTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2018 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitHacks.h" diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index a5ced0a1ee..2542fcd7c2 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "CharacterSetECI.h" diff --git a/test/unit/GTINTest.cpp b/test/unit/GTINTest.cpp index ddaf02db2b..10f89909e9 100644 --- a/test/unit/GTINTest.cpp +++ b/test/unit/GTINTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2022 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "GTIN.h" diff --git a/test/unit/ReedSolomonTest.cpp b/test/unit/ReedSolomonTest.cpp index 9be8b6fca4..870c33b268 100644 --- a/test/unit/ReedSolomonTest.cpp +++ b/test/unit/ReedSolomonTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2013 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "GenericGF.h" #include "PseudoRandom.h" diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index b782df3638..6d3ec55d09 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "CharacterSet.h" #include "TextDecoder.h" diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index e7c2deaadb..2c6c0773a5 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "TextUtfEncoding.h" diff --git a/test/unit/ThresholdBinarizerTest.cpp b/test/unit/ThresholdBinarizerTest.cpp index 0a9e54f189..ae6449f8dd 100644 --- a/test/unit/ThresholdBinarizerTest.cpp +++ b/test/unit/ThresholdBinarizerTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2022 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ThresholdBinarizer.h" #include "oned/ODReader.h" diff --git a/test/unit/aztec/AZDecoderTest.cpp b/test/unit/aztec/AZDecoderTest.cpp index 242348897c..56c323a6a6 100644 --- a/test/unit/aztec/AZDecoderTest.cpp +++ b/test/unit/aztec/AZDecoderTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2014 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "aztec/AZDecoder.h" #include "BitArray.h" diff --git a/test/unit/aztec/AZDetectorTest.cpp b/test/unit/aztec/AZDetectorTest.cpp index 42a9885ee9..fd7a4f1191 100644 --- a/test/unit/aztec/AZDetectorTest.cpp +++ b/test/unit/aztec/AZDetectorTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2013 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "aztec/AZDetector.h" diff --git a/test/unit/aztec/AZEncodeDecodeTest.cpp b/test/unit/aztec/AZEncodeDecodeTest.cpp index d09f0bd6f9..d968371719 100644 --- a/test/unit/aztec/AZEncodeDecodeTest.cpp +++ b/test/unit/aztec/AZEncodeDecodeTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2013 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrix.h" #include "CharacterSet.h" diff --git a/test/unit/aztec/AZEncoderTest.cpp b/test/unit/aztec/AZEncoderTest.cpp index 7fa4b69d53..045f15e3f3 100644 --- a/test/unit/aztec/AZEncoderTest.cpp +++ b/test/unit/aztec/AZEncoderTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2013 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "aztec/AZEncoder.h" #include "BitArray.h" diff --git a/test/unit/aztec/AZHighLevelEncoderTest.cpp b/test/unit/aztec/AZHighLevelEncoderTest.cpp index 2b55de86a9..7643f1e9b9 100644 --- a/test/unit/aztec/AZHighLevelEncoderTest.cpp +++ b/test/unit/aztec/AZHighLevelEncoderTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2013 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "aztec/AZHighLevelEncoder.h" #include "BitArray.h" diff --git a/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp b/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp index ad3db44716..13d7f99cd0 100644 --- a/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp +++ b/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ByteArray.h" #include "DecoderResult.h" diff --git a/test/unit/datamatrix/DMEncodeDecodeTest.cpp b/test/unit/datamatrix/DMEncodeDecodeTest.cpp index bb98ef01e4..10a4f7b98d 100644 --- a/test/unit/datamatrix/DMEncodeDecodeTest.cpp +++ b/test/unit/datamatrix/DMEncodeDecodeTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Axel Waggershauser * Copyright 2013 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrixIO.h" #include "DecoderResult.h" diff --git a/test/unit/datamatrix/DMHighLevelEncodeTest.cpp b/test/unit/datamatrix/DMHighLevelEncodeTest.cpp index 05e368e01e..3c0d437e53 100644 --- a/test/unit/datamatrix/DMHighLevelEncodeTest.cpp +++ b/test/unit/datamatrix/DMHighLevelEncodeTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2006 Jeremias Maerki. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ByteArray.h" #include "ZXContainerAlgorithms.h" diff --git a/test/unit/datamatrix/DMPlacementTest.cpp b/test/unit/datamatrix/DMPlacementTest.cpp index a7ad679936..091d365fbf 100644 --- a/test/unit/datamatrix/DMPlacementTest.cpp +++ b/test/unit/datamatrix/DMPlacementTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2006 Jeremias Maerki -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrixIO.h" #include "ByteArray.h" diff --git a/test/unit/datamatrix/DMSymbolInfoTest.cpp b/test/unit/datamatrix/DMSymbolInfoTest.cpp index 7a5c13562a..bae53e8542 100644 --- a/test/unit/datamatrix/DMSymbolInfoTest.cpp +++ b/test/unit/datamatrix/DMSymbolInfoTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2006 Jeremias Maerki -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "datamatrix/DMSymbolInfo.h" #include "datamatrix/DMSymbolShape.h" diff --git a/test/unit/datamatrix/DMWriterTest.cpp b/test/unit/datamatrix/DMWriterTest.cpp index b60d4818ff..4aa0738e51 100644 --- a/test/unit/datamatrix/DMWriterTest.cpp +++ b/test/unit/datamatrix/DMWriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "datamatrix/DMWriter.h" #include "BitMatrixIO.h" diff --git a/test/unit/maxicode/MCDecoderTest.cpp b/test/unit/maxicode/MCDecoderTest.cpp index 150f4542ec..21f9447d9e 100644 --- a/test/unit/maxicode/MCDecoderTest.cpp +++ b/test/unit/maxicode/MCDecoderTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ByteArray.h" #include "DecoderResult.h" diff --git a/test/unit/oned/ODCodaBarWriterTest.cpp b/test/unit/oned/ODCodaBarWriterTest.cpp index 5958cc13c9..f4071c33b7 100644 --- a/test/unit/oned/ODCodaBarWriterTest.cpp +++ b/test/unit/oned/ODCodaBarWriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2011 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODCodabarWriter.h" #include "BitArray.h" diff --git a/test/unit/oned/ODCode128ReaderTest.cpp b/test/unit/oned/ODCode128ReaderTest.cpp index 87af89dbfb..ed37bcf79c 100644 --- a/test/unit/oned/ODCode128ReaderTest.cpp +++ b/test/unit/oned/ODCode128ReaderTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODCode128Reader.h" diff --git a/test/unit/oned/ODCode128WriterTest.cpp b/test/unit/oned/ODCode128WriterTest.cpp index 65636d64ec..010854357f 100644 --- a/test/unit/oned/ODCode128WriterTest.cpp +++ b/test/unit/oned/ODCode128WriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2014 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODCode128Writer.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/ODCode39ExtendedModeTest.cpp b/test/unit/oned/ODCode39ExtendedModeTest.cpp index dd92d53b75..0c256971a4 100644 --- a/test/unit/oned/ODCode39ExtendedModeTest.cpp +++ b/test/unit/oned/ODCode39ExtendedModeTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitArray.h" #include "BitArrayUtility.h" diff --git a/test/unit/oned/ODCode39ReaderTest.cpp b/test/unit/oned/ODCode39ReaderTest.cpp index c92d88202f..42da6c6ce0 100644 --- a/test/unit/oned/ODCode39ReaderTest.cpp +++ b/test/unit/oned/ODCode39ReaderTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2022 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODCode39Reader.h" diff --git a/test/unit/oned/ODCode39WriterTest.cpp b/test/unit/oned/ODCode39WriterTest.cpp index 7ab6e8fb47..0d98c4c250 100644 --- a/test/unit/oned/ODCode39WriterTest.cpp +++ b/test/unit/oned/ODCode39WriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODCode39Writer.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/ODCode93ReaderTest.cpp b/test/unit/oned/ODCode93ReaderTest.cpp index 1fc060c6f4..221d37d957 100644 --- a/test/unit/oned/ODCode93ReaderTest.cpp +++ b/test/unit/oned/ODCode93ReaderTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODCode93Reader.h" #include "BitArray.h" diff --git a/test/unit/oned/ODCode93WriterTest.cpp b/test/unit/oned/ODCode93WriterTest.cpp index f1c560982c..beaf6965b5 100644 --- a/test/unit/oned/ODCode93WriterTest.cpp +++ b/test/unit/oned/ODCode93WriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODCode93Writer.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/ODEAN13WriterTest.cpp b/test/unit/oned/ODEAN13WriterTest.cpp index 7021bfac1e..22cfd92da9 100644 --- a/test/unit/oned/ODEAN13WriterTest.cpp +++ b/test/unit/oned/ODEAN13WriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2009 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODEAN13Writer.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/ODEAN8WriterTest.cpp b/test/unit/oned/ODEAN8WriterTest.cpp index 19f77bb615..c2bebf5d54 100644 --- a/test/unit/oned/ODEAN8WriterTest.cpp +++ b/test/unit/oned/ODEAN8WriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2009 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODEAN8Writer.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/ODITFWriterTest.cpp b/test/unit/oned/ODITFWriterTest.cpp index 89c7ebf04c..34a9d0392a 100644 --- a/test/unit/oned/ODITFWriterTest.cpp +++ b/test/unit/oned/ODITFWriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODITFWriter.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/ODUPCAWriterTest.cpp b/test/unit/oned/ODUPCAWriterTest.cpp index 1b83a168be..f015c6cfbc 100644 --- a/test/unit/oned/ODUPCAWriterTest.cpp +++ b/test/unit/oned/ODUPCAWriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2010 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODUPCAWriter.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/ODUPCEWriterTest.cpp b/test/unit/oned/ODUPCEWriterTest.cpp index 1d7970f3d5..9db92ee6cd 100644 --- a/test/unit/oned/ODUPCEWriterTest.cpp +++ b/test/unit/oned/ODUPCEWriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/ODUPCEWriter.h" #include "BitMatrixIO.h" diff --git a/test/unit/oned/rss/ODRSSExpandedBinaryDecoderTest.cpp b/test/unit/oned/rss/ODRSSExpandedBinaryDecoderTest.cpp index 12df29d4bb..c11b7528ef 100644 --- a/test/unit/oned/rss/ODRSSExpandedBinaryDecoderTest.cpp +++ b/test/unit/oned/rss/ODRSSExpandedBinaryDecoderTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitArray.h" #include "BitArrayUtility.h" diff --git a/test/unit/oned/rss/ODRSSFieldParserTest.cpp b/test/unit/oned/rss/ODRSSFieldParserTest.cpp index dab4897508..a6cf3ffd79 100644 --- a/test/unit/oned/rss/ODRSSFieldParserTest.cpp +++ b/test/unit/oned/rss/ODRSSFieldParserTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2022 gitlost -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "oned/rss/ODRSSFieldParser.h" diff --git a/test/unit/pdf417/PDF417DecoderTest.cpp b/test/unit/pdf417/PDF417DecoderTest.cpp index 34055006fd..cf9e4359e2 100644 --- a/test/unit/pdf417/PDF417DecoderTest.cpp +++ b/test/unit/pdf417/PDF417DecoderTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "DecoderResult.h" #include "DecodeStatus.h" diff --git a/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp b/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp index 3b8bd94eee..763d9e4dbf 100644 --- a/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp +++ b/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2012 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "PseudoRandom.h" #include "ZXContainerAlgorithms.h" diff --git a/test/unit/pdf417/PDF417HighLevelEncoderTest.cpp b/test/unit/pdf417/PDF417HighLevelEncoderTest.cpp index 412f6e2586..bbcc492d03 100644 --- a/test/unit/pdf417/PDF417HighLevelEncoderTest.cpp +++ b/test/unit/pdf417/PDF417HighLevelEncoderTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright (C) 2014 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "CharacterSet.h" #include "pdf417/PDFCompaction.h" diff --git a/test/unit/pdf417/PDF417WriterTest.cpp b/test/unit/pdf417/PDF417WriterTest.cpp index c88b732490..747d2c5524 100644 --- a/test/unit/pdf417/PDF417WriterTest.cpp +++ b/test/unit/pdf417/PDF417WriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2016 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrixIO.h" #include "pdf417/PDFWriter.h" diff --git a/test/unit/qrcode/MQRDecoderTest.cpp b/test/unit/qrcode/MQRDecoderTest.cpp index c49f1217d2..34bf5add5e 100644 --- a/test/unit/qrcode/MQRDecoderTest.cpp +++ b/test/unit/qrcode/MQRDecoderTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +*/ +// SPDX-License-Identifier: Apache-2.0 #include "qrcode/QRDecoder.h" diff --git a/test/unit/qrcode/QRBitMatrixParserTest.cpp b/test/unit/qrcode/QRBitMatrixParserTest.cpp index 023c4614d0..2cd7a9c5cf 100644 --- a/test/unit/qrcode/QRBitMatrixParserTest.cpp +++ b/test/unit/qrcode/QRBitMatrixParserTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +*/ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrix.h" #include "BitMatrixIO.h" diff --git a/test/unit/qrcode/QRDataMaskTest.cpp b/test/unit/qrcode/QRDataMaskTest.cpp index e71387ce74..24baa4a417 100644 --- a/test/unit/qrcode/QRDataMaskTest.cpp +++ b/test/unit/qrcode/QRDataMaskTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2007 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "qrcode/QRDataMask.h" #include "BitMatrix.h" diff --git a/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp b/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp index 5ab4b15589..81d5f97c9b 100644 --- a/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp +++ b/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitArray.h" #include "ByteArray.h" diff --git a/test/unit/qrcode/QREncoderTest.cpp b/test/unit/qrcode/QREncoderTest.cpp index ccd9807fdc..78e2715fc8 100644 --- a/test/unit/qrcode/QREncoderTest.cpp +++ b/test/unit/qrcode/QREncoderTest.cpp @@ -1,18 +1,7 @@ /* * Copyright 2008 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +*/ +// SPDX-License-Identifier: Apache-2.0 #include "BitArray.h" #include "BitArrayUtility.h" diff --git a/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp b/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp index c09c226559..f3870b4bbe 100644 --- a/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp +++ b/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "qrcode/QRErrorCorrectionLevel.h" diff --git a/test/unit/qrcode/QRFormatInformationTest.cpp b/test/unit/qrcode/QRFormatInformationTest.cpp index c87184585b..959f5ae42e 100644 --- a/test/unit/qrcode/QRFormatInformationTest.cpp +++ b/test/unit/qrcode/QRFormatInformationTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2007 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "qrcode/QRFormatInformation.h" diff --git a/test/unit/qrcode/QRModeTest.cpp b/test/unit/qrcode/QRModeTest.cpp index 77a1611350..94ab70243f 100644 --- a/test/unit/qrcode/QRModeTest.cpp +++ b/test/unit/qrcode/QRModeTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "qrcode/QRCodecMode.h" #include "qrcode/QRVersion.h" diff --git a/test/unit/qrcode/QRVersionTest.cpp b/test/unit/qrcode/QRVersionTest.cpp index 4e6fd8eb0c..bf4fbe377b 100644 --- a/test/unit/qrcode/QRVersionTest.cpp +++ b/test/unit/qrcode/QRVersionTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "qrcode/QRVersion.h" diff --git a/test/unit/qrcode/QRWriterTest.cpp b/test/unit/qrcode/QRWriterTest.cpp index 869d66a94e..bcb63f4443 100644 --- a/test/unit/qrcode/QRWriterTest.cpp +++ b/test/unit/qrcode/QRWriterTest.cpp @@ -1,19 +1,8 @@ /* * Copyright 2017 Huy Cuong Nguyen * Copyright 2008 ZXing authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BitMatrixIO.h" #include "qrcode/QRWriter.h" diff --git a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp index 32994d5934..ce37a1ecde 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp @@ -1,18 +1,7 @@ /* * Copyright 2021 Axel Waggershauser -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "JNIUtils.h" #include "ReadBarcode.h" diff --git a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp index 85dc3827c7..e552c912d8 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "JNIUtils.h" #include diff --git a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.h b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.h index 6400a41289..ed1391e022 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.h +++ b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include #include diff --git a/wrappers/wasm/BarcodeReader.cpp b/wrappers/wasm/BarcodeReader.cpp index 5dd2dab2bf..eb6e437b5a 100644 --- a/wrappers/wasm/BarcodeReader.cpp +++ b/wrappers/wasm/BarcodeReader.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "ReadBarcode.h" diff --git a/wrappers/wasm/BarcodeWriter.cpp b/wrappers/wasm/BarcodeWriter.cpp index 4b6e23c350..209fec1a89 100644 --- a/wrappers/wasm/BarcodeWriter.cpp +++ b/wrappers/wasm/BarcodeWriter.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #include "BarcodeFormat.h" #include "MultiFormatWriter.h" diff --git a/wrappers/winrt/BarcodeReader.h b/wrappers/winrt/BarcodeReader.h index 7455007449..e68383e0e7 100644 --- a/wrappers/winrt/BarcodeReader.h +++ b/wrappers/winrt/BarcodeReader.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "BarcodeFormat.h" diff --git a/wrappers/winrt/ReadResult.h b/wrappers/winrt/ReadResult.h index 65e8251afe..9361441605 100644 --- a/wrappers/winrt/ReadResult.h +++ b/wrappers/winrt/ReadResult.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once namespace ZXing { From 59e76b00a4dfc09748cec2d43e480a7b0ef65eb5 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 22 May 2022 01:57:41 +0200 Subject: [PATCH 0216/1315] Fix a few missing/missed license comments --- example/ZXingOpenCV.h | 18 ++++-------------- example/ZXingQtReader.h | 16 +++------------- example/ZXingReader.cpp | 1 + test/fuzz/fuzzDBEDecoder.cpp | 5 +++++ test/fuzz/fuzzDMDecoder.cpp | 5 +++++ test/fuzz/fuzzDMEncoder.cpp | 5 +++++ test/fuzz/fuzzODDecoders.cpp | 5 +++++ wrappers/python/zxing.cpp | 7 +++++++ 8 files changed, 35 insertions(+), 27 deletions(-) diff --git a/example/ZXingOpenCV.h b/example/ZXingOpenCV.h index b096b0d770..bf9cca06e7 100644 --- a/example/ZXingOpenCV.h +++ b/example/ZXingOpenCV.h @@ -1,19 +1,9 @@ -#pragma once /* - * Copyright 2021 Axel Waggershauser - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2020 Axel Waggershauser */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ReadBarcode.h" #include "TextUtfEncoding.h" diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 05a87bad2b..2a05bbf5d8 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2020 Axel Waggershauser - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once #include "ReadBarcode.h" diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index b3c9958ff8..95cbb3a8c8 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -1,5 +1,6 @@ /* * Copyright 2016 Nu-book Inc. +* Copyright 2019 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 diff --git a/test/fuzz/fuzzDBEDecoder.cpp b/test/fuzz/fuzzDBEDecoder.cpp index 4a14761611..292a7b9ce7 100644 --- a/test/fuzz/fuzzDBEDecoder.cpp +++ b/test/fuzz/fuzzDBEDecoder.cpp @@ -1,3 +1,8 @@ +/* + * Copyright 2021 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + #include #include diff --git a/test/fuzz/fuzzDMDecoder.cpp b/test/fuzz/fuzzDMDecoder.cpp index 455679c70c..f6e7a26d3b 100644 --- a/test/fuzz/fuzzDMDecoder.cpp +++ b/test/fuzz/fuzzDMDecoder.cpp @@ -1,3 +1,8 @@ +/* + * Copyright 2021 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + #include #include diff --git a/test/fuzz/fuzzDMEncoder.cpp b/test/fuzz/fuzzDMEncoder.cpp index 2d9d85c6fd..0a56d9b0fc 100644 --- a/test/fuzz/fuzzDMEncoder.cpp +++ b/test/fuzz/fuzzDMEncoder.cpp @@ -1,3 +1,8 @@ +/* + * Copyright 2021 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + #include #include diff --git a/test/fuzz/fuzzODDecoders.cpp b/test/fuzz/fuzzODDecoders.cpp index df39599041..9fc55dec73 100644 --- a/test/fuzz/fuzzODDecoders.cpp +++ b/test/fuzz/fuzzODDecoders.cpp @@ -1,3 +1,8 @@ +/* + * Copyright 2021 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + #include #include diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 2756a20f8e..60db5387a2 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -1,3 +1,10 @@ +/* + * Copyright 2019 Tim Rae + * Copyright 2021 Antoine Humbert + * Copyright 2021 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + #include "BarcodeFormat.h" // Reader From 7578181156cd48dca6ea5df642c4be561192c6e5 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 22 May 2022 01:57:59 +0200 Subject: [PATCH 0217/1315] fuzzer: fix build regressions --- test/fuzz/fuzzDMDecoder.cpp | 4 ++-- test/fuzz/fuzzODDecoders.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/fuzz/fuzzDMDecoder.cpp b/test/fuzz/fuzzDMDecoder.cpp index f6e7a26d3b..d0c07f070c 100644 --- a/test/fuzz/fuzzDMDecoder.cpp +++ b/test/fuzz/fuzzDMDecoder.cpp @@ -12,7 +12,7 @@ using namespace ZXing; namespace ZXing::DataMatrix::DecodedBitStreamParser { -DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet); +DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const bool isDMRE); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) @@ -23,7 +23,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ByteArray ba; ba.insert(ba.begin(), data, data + size); try { - DataMatrix::DecodedBitStreamParser::Decode(std::move(ba), ""); + DataMatrix::DecodedBitStreamParser::Decode(std::move(ba), "", false); } catch (...) { } diff --git a/test/fuzz/fuzzODDecoders.cpp b/test/fuzz/fuzzODDecoders.cpp index 9fc55dec73..2ffd01392d 100644 --- a/test/fuzz/fuzzODDecoders.cpp +++ b/test/fuzz/fuzzODDecoders.cpp @@ -27,7 +27,7 @@ bool init() readers.emplace_back(new MultiUPCEANReader(hints)); readers.emplace_back(new Code39Reader(hints)); readers.emplace_back(new Code93Reader()); - readers.emplace_back(new Code128Reader(hints)); + readers.emplace_back(new Code128Reader()); readers.emplace_back(new ITFReader(hints)); readers.emplace_back(new CodabarReader(hints)); readers.emplace_back(new DataBarReader(hints)); From 4db362a83d0ead168bcdc0376f5f24a1f7466a85 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 22 May 2022 11:21:32 +0200 Subject: [PATCH 0218/1315] ODDataBarReader: fix heap overflow regression --- core/src/oned/ODDataBarReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index c516370f4a..b9f4fa9601 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -157,7 +157,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const { #if 0 // non-stacked version - next = next.subView(-1, FULL_PAIR_SIZE); + next = next.subView(-1, FULL_PAIR_SIZE + 1); // +1 reflects the guard pattern on the right, see IsRightPair()); // yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern) while (next.shift(2)) { if (IsLeftPair(next)) { @@ -174,7 +174,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, state.reset(new State); auto* prevState = static_cast(state.get()); - next = next.subView(0, FULL_PAIR_SIZE); + next = next.subView(0, FULL_PAIR_SIZE + 1); // +1 reflects the guard pattern on the right, see IsRightPair() // yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern) while (next.shift(1)) { if (IsLeftPair(next)) { From fba9e3c49191d9ac5e98c2569dd7245fc0b10c01 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 24 May 2022 08:42:54 +0200 Subject: [PATCH 0219/1315] DecoderResult: init _lineCount with 0 instead of -1 --- core/src/DecoderResult.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 0bb573bc7e..0b04d449cb 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -37,7 +37,7 @@ class DecoderResult std::wstring _ecLevel; int _errorsCorrected = -1; int _erasures = -1; - int _lineCount = -1; + int _lineCount = 0; std::string _symbologyIdentifier; StructuredAppendInfo _structuredAppend; bool _isMirrored = false; From edee1f8de3634cfd311f6211dd92af65a599bf2b Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 24 May 2022 08:53:21 +0200 Subject: [PATCH 0220/1315] Result: implement preview of utf8 based ECI protocol channel See https://github.com/nu-book/zxing-cpp/issues/334#issuecomment-1134493465 for a discussion about this in the context of the potentially upcoming ISO standard regarding barcode scanner interfaces. Also add `applicationIndicator` property conveying the presence of either `GS1` or AIM application indicators (`FNC1` tags). Note: all of this experimental and may change at any time. --- core/src/CharacterSetECI.cpp | 9 ++++ core/src/CharacterSetECI.h | 6 +++ core/src/Content.cpp | 85 ++++++++++++++++++++++++------- core/src/Content.h | 21 ++++++-- core/src/DecoderResult.h | 4 +- core/src/Result.cpp | 4 +- core/src/Result.h | 7 ++- core/src/datamatrix/DMDecoder.cpp | 2 +- core/src/qrcode/QRDecoder.cpp | 26 ++++------ example/ZXingReader.cpp | 2 + 10 files changed, 124 insertions(+), 42 deletions(-) diff --git a/core/src/CharacterSetECI.cpp b/core/src/CharacterSetECI.cpp index f99adc6b32..fe59c044d6 100644 --- a/core/src/CharacterSetECI.cpp +++ b/core/src/CharacterSetECI.cpp @@ -8,7 +8,9 @@ #include "TextDecoder.h" #include +#include #include +#include #include namespace ZXing::CharacterSetECI { @@ -123,6 +125,13 @@ static const std::map ECI_NAME_TO_CHA {"BINARY", CharacterSet::BINARY}, }; +std::string ECI2String(int eci) +{ + std::ostringstream oss; + oss << '\\' << std::setw(6) << std::setfill('0') << eci; + return oss.str(); +} + CharacterSet ECI2CharacterSet(int value) { auto it = ECI_VALUE_TO_CHARSET.find(value); diff --git a/core/src/CharacterSetECI.h b/core/src/CharacterSetECI.h index 1d6c1e6ed7..8c586d7a55 100644 --- a/core/src/CharacterSetECI.h +++ b/core/src/CharacterSetECI.h @@ -19,6 +19,12 @@ namespace ZXing { */ namespace CharacterSetECI { +/** + * @brief ECI2String converts the numerical ECI value to a 7 character string as used in the ECI protocol + * @return e.g. "\000020" + */ +std::string ECI2String(int eci); + /** * @param value character set ECI value * @return {@code CharacterSet} representing ECI of given value, or {@code CharacterSet::Unknown} if it is unsupported diff --git a/core/src/Content.cpp b/core/src/Content.cpp index dc17fcc8b9..3085283e0d 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -7,21 +7,44 @@ #include "CharacterSetECI.h" #include "TextDecoder.h" +#include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" namespace ZXing { -void Content::switchEncoding(CharacterSet cs, bool isECI) +constexpr bool ECIIsBinary(int eci) { + return eci < 0 || eci > 32; +} + +template +void Content::ForEachECIBlock(FUNC func) const +{ + for (int i = 0; i < Size(encodings); ++i) { + auto [eci, start] = encodings[i]; + int end = i + 1 == Size(encodings) ? Size(binary) : encodings[i + 1].pos; + + func(eci, start, end); + } +} + +void Content::switchEncoding(int eci, bool isECI) +{ + // TODO: replace non-ECI entries on first ECI entry with default ECI if (isECI || !hasECI) { - if (encodings.back().second == Size(binary)) - encodings.back().first = cs; // no point in recording 0 length segments + if (encodings.back().pos == Size(binary)) + encodings.back().eci = eci; // no point in recording 0 length segments else - encodings.emplace_back(cs, Size(binary)); + encodings.push_back({eci, Size(binary)}); } hasECI |= isECI; } +void Content::switchEncoding(CharacterSet cs) +{ + switchEncoding(CharacterSetECI::Charset2ECI(cs), false); +} + std::wstring Content::text() const { auto fallbackCS = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); @@ -29,28 +52,56 @@ std::wstring Content::text() const fallbackCS = guessEncoding(); std::wstring wstr; - for (int i = 0; i < Size(encodings); ++i) { - auto [cs, start] = encodings[i]; - int end = i + 1 == Size(encodings) ? Size(binary) : encodings[i + 1].second; - + ForEachECIBlock([&](int eci, int begin, int end) { + CharacterSet cs = CharacterSetECI::ECI2CharacterSet(eci); if (cs == CharacterSet::Unknown) cs = fallbackCS; - TextDecoder::Append(wstr, binary.data() + start, end - start, cs); - } + TextDecoder::Append(wstr, binary.data() + begin, end - begin, cs); + }); return wstr; } +std::string Content::utf8Protocol() const +{ + std::wstring res; + int lastECI = -1; + + ForEachECIBlock([&](int eci, int begin, int end) { + if (!hasECI) + eci = CharacterSetECI::Charset2ECI(guessEncoding()); + CharacterSet cs = CharacterSetECI::ECI2CharacterSet(eci); + if (cs == CharacterSet::Unknown) + cs = CharacterSet::BINARY; + if (eci == -1) + eci = 899; // 26 == binary ECI + else if (!ECIIsBinary(eci)) + eci = 26; // 26 == utf8 ECI + + if (lastECI != eci) + TextDecoder::AppendLatin1(res, CharacterSetECI::ECI2String(eci)); + lastECI = eci; + + std::wstring tmp; + TextDecoder::Append(tmp, binary.data() + begin, end - begin, cs); + for (auto c : tmp) { + res += c; + if (c == L'\\') // in the ECI protocol a '\' has to be doubled + res += c; + } + }); + + return TextUtfEncoding::ToUtf8(res); +} + CharacterSet Content::guessEncoding() const { // assemble all blocks with unknown encoding ByteArray input; - for (int i = 0; i < Size(encodings); ++i) { - auto [cs, start] = encodings[i]; - int end = i + 1 == Size(encodings) ? Size(binary) : encodings[i + 1].second; - if (cs == CharacterSet::Unknown) - input.insert(input.end(), binary.begin() + start, binary.begin() + end); - } + ForEachECIBlock([&](int eci, int begin, int end) { + if (eci == -1) + input.insert(input.end(), binary.begin() + begin, binary.begin() + end); + }); if (input.empty()) return CharacterSet::Unknown; @@ -60,7 +111,7 @@ CharacterSet Content::guessEncoding() const ContentType Content::type() const { - auto isBinary = [](Encoding e) { return e.first == CharacterSet::BINARY || e.first == CharacterSet::Unknown; }; + auto isBinary = [](Encoding e) { return ECIIsBinary(e.eci); }; if (hasECI) { if (std::none_of(encodings.begin(), encodings.end(), isBinary)) diff --git a/core/src/Content.h b/core/src/Content.h index 1af33bac05..78b8682734 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -16,13 +16,27 @@ class Content { bool hasECI = false; + template + void ForEachECIBlock(FUNC f) const; + + void switchEncoding(int eci, bool isECI); + public: + struct Encoding + { + int eci, pos; + }; + ByteArray binary; - using Encoding = std::pair; - std::vector encodings = {{CharacterSet::Unknown, 0}}; + std::vector encodings = {{-1, 0}}; std::string hintedCharset; + std::string applicationIndicator; + + Content() = default; + Content(ByteArray&& binary, int defaultECI) : binary(binary), encodings{{defaultECI, 0}} {} - void switchEncoding(CharacterSet cs, bool isECI = false); + void switchEncoding(int eci) { switchEncoding(eci, true); } + void switchEncoding(CharacterSet cs); void reserve(int count) { binary.reserve(binary.size() + count); } @@ -36,6 +50,7 @@ class Content bool empty() const { return binary.empty(); } std::wstring text() const; + std::string utf8Protocol() const; CharacterSet guessEncoding() const; ContentType type() const; }; diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 0b04d449cb..c239d07e03 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -71,8 +71,8 @@ class DecoderResult ByteArray&& rawBytes() && { return std::move(_rawBytes); } const std::wstring& text() const & { return _text; } std::wstring&& text() && { return std::move(_text); } - const ByteArray& binary() const & { return _content.binary; } - ByteArray&& binary() && { return std::move(_content.binary); } + const Content& content() const & { return _content; } + Content&& content() && { return std::move(_content); } // Simple macro to set up getter/setter methods that save lots of boilerplate. // It sets up a standard 'const & () const', 2 setters for setting lvalues via diff --git a/core/src/Result.cpp b/core/src/Result.cpp index f69a8804db..0a6ea4ab5e 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -18,8 +18,8 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor std::string&& symbologyIdentifier, ByteArray&& rawBytes, const bool readerInit) : _format(format), + _content({ByteArray(text), 3}), _text(TextDecoder::FromLatin1(text)), - _binary(text), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), _numBits(Size(_rawBytes) * 8), @@ -31,8 +31,8 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format) : _status(decodeResult.errorCode()), _format(format), + _content(std::move(decodeResult).content()), _text(std::move(decodeResult).text()), - _binary(std::move(decodeResult).binary()), _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), diff --git a/core/src/Result.h b/core/src/Result.h index be145a888c..c869e188c9 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -9,6 +9,7 @@ #include "BarcodeFormat.h" #include "ByteArray.h" +#include "Content.h" #include "DecodeStatus.h" #include "Quadrilateral.h" #include "StructuredAppend.h" @@ -47,7 +48,9 @@ class Result const std::wstring& text() const { return _text; } // WARNING: this is an experimental API and may change/disappear - const ByteArray& binary() const { return _binary; } + const ByteArray& binary() const { return _content.binary; } + const std::string utf8Protocol() const { return _content.utf8Protocol(); } + const std::string applicationIndicator() const { return _content.applicationIndicator; } const Position& position() const { return _position; } void setPosition(Position pos) { _position = pos; } @@ -112,8 +115,8 @@ class Result private: DecodeStatus _status = DecodeStatus::NoError; BarcodeFormat _format = BarcodeFormat::None; + Content _content; std::wstring _text; - ByteArray _binary; Position _position; ByteArray _rawBytes; int _numBits = 0; diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 871ca9422a..c76f208e87 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -334,7 +334,7 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b case 238: DecodeAnsiX12Segment(bits, result); break; case 239: DecodeC40OrTextSegment(bits, result, Mode::TEXT); break; case 240: DecodeEdifactSegment(bits, result); break; - case 241: result.switchEncoding(CharacterSetECI::ECI2CharacterSet(ParseECIValue(bits)), true); break; + case 241: result.switchEncoding(ParseECIValue(bits)); break; default: if (oneByte <= 128) { // ASCII data (ASCII value + 1) result.push_back(upperShift(oneByte) - 1); diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 31ed2bbbec..70476b71cd 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -61,7 +61,8 @@ static bool CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) static void DecodeHanziSegment(BitSource& bits, int count, Content& result) { // Each character will require 2 bytes, decode as GB2312 - result.switchEncoding(CharacterSet::GB2312); + // There is no ECI value for GB2312, use GB18030 which is a superset + result.switchEncoding(CharacterSet::GB18030); result.reserve(2 * count); while (count > 0) { @@ -132,7 +133,7 @@ static char ToAlphaNumericChar(int value) return ALPHANUMERIC_CHARS[value]; } -static void DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffect, Content& result) +static void DecodeAlphanumericSegment(BitSource& bits, int count, Content& result) { // Read two characters at a time std::string buffer; @@ -147,7 +148,7 @@ static void DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffe buffer += ToAlphaNumericChar(bits.readBits(6)); } // See section 6.4.8.1, 6.4.8.2 - if (fc1InEffect) { + if (!result.applicationIndicator.empty()) { // We need to massage the result a bit if in an FNC1 mode: for (size_t i = 0; i < buffer.length(); i++) { if (buffer[i] == '%') { @@ -162,13 +163,13 @@ static void DecodeAlphanumericSegment(BitSource& bits, int count, bool fc1InEffe } } - result.switchEncoding(CharacterSet::ASCII); + result.switchEncoding(CharacterSet::ISO8859_1); result += buffer; } static void DecodeNumericSegment(BitSource& bits, int count, Content& result) { - result.switchEncoding(CharacterSet::ASCII); + result.switchEncoding(CharacterSet::ISO8859_1); result.reserve(count); // Read three digits at a time @@ -262,7 +263,6 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo int symbologyIdModifier = 1; // ISO/IEC 18004:2015 Annex F Table F.1 StructuredAppendInfo structuredAppend; const int modeBitLength = CodecModeBitsLength(version); - bool fc1InEffect = false; try { @@ -277,15 +277,14 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo case CodecMode::FNC1_FIRST_POSITION: // if (!result.empty()) // uncomment to enforce specification // throw std::runtime_error("GS1 Indicator (FNC1 in first position) at illegal position"); - fc1InEffect = true; // In Alphanumeric mode undouble doubled percents and treat single percent as // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using // modifiers that indicate ECI protocol (ISO/IEC 18004:2015 Annex F Table F.1) symbologyIdModifier = 3; + result.applicationIndicator = "GS1"; // In Alphanumeric mode undouble doubled percents and treat single percent as break; case CodecMode::FNC1_SECOND_POSITION: if (!result.empty()) throw std::runtime_error("AIM Application Indicator (FNC1 in second position) at illegal position"); - fc1InEffect = true; // As above symbologyIdModifier = 5; // As above // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position), "00-99" or "A-Za-z" if (int appInd = bits.readBits(8); appInd < 10) // "00-09" @@ -296,6 +295,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo result += static_cast(appInd - 100); else throw std::runtime_error("Invalid AIM Application Indicator"); + result.applicationIndicator = std::string(result.binary.begin(), result.binary.end()); // see also above break; case CodecMode::STRUCTURED_APPEND: // sequence number and parity is added later to the result metadata @@ -304,14 +304,10 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo structuredAppend.count = bits.readBits(4) + 1; structuredAppend.id = std::to_string(bits.readBits(8)); break; - case CodecMode::ECI: { + case CodecMode::ECI: // Count doesn't apply to ECI - auto charset = CharacterSetECI::ECI2CharacterSet(ParseECIValue(bits)); - if (charset == CharacterSet::Unknown) - return DecodeStatus::FormatError; - result.switchEncoding(charset, true); + result.switchEncoding(ParseECIValue(bits)); break; - } case CodecMode::HANZI: { // First handle Hanzi mode which does not start with character count // chinese mode contains a sub set indicator right after mode indicator @@ -327,7 +323,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo int count = bits.readBits(CharacterCountBits(mode, version)); switch (mode) { case CodecMode::NUMERIC: DecodeNumericSegment(bits, count, result); break; - case CodecMode::ALPHANUMERIC: DecodeAlphanumericSegment(bits, count, fc1InEffect, result); break; + case CodecMode::ALPHANUMERIC: DecodeAlphanumericSegment(bits, count, result); break; case CodecMode::BYTE: DecodeByteSegment(bits, count, result); break; case CodecMode::KANJI: DecodeKanjiSegment(bits, count, result); break; default: return DecodeStatus::FormatError; diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 95cbb3a8c8..f4ca2d427f 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -182,6 +182,7 @@ int main(int argc, char* argv[]) } std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" << "Binary: \"" << ToHex(result.binary()) << "\"\n" + << "ECI-Proto: \"" << result.utf8Protocol() << "\"\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" << "Position: " << result.position() << "\n" @@ -195,6 +196,7 @@ int main(int argc, char* argv[]) }; printOptional("EC Level: ", ToUtf8(result.ecLevel())); + printOptional("App-Ind.: ", result.applicationIndicator()); if (result.lineCount()) std::cout << "Lines: " << result.lineCount() << "\n"; From d498cd8ab58bfcb568808b6c9da05dc755d8b7f4 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 24 May 2022 13:32:19 +0200 Subject: [PATCH 0221/1315] ECI: introduce type safe abstraction via enum and simplify API naming --- core/CMakeLists.txt | 2 + core/src/CharacterSetECI.cpp | 68 +--------------------- core/src/CharacterSetECI.h | 18 ------ core/src/Content.cpp | 37 ++++++------ core/src/Content.h | 13 +++-- core/src/ECI.cpp | 76 +++++++++++++++++++++++++ core/src/ECI.h | 66 +++++++++++++++++++++ core/src/Result.cpp | 2 +- core/src/datamatrix/DMDecoder.cpp | 8 +-- core/src/pdf417/PDFHighLevelEncoder.cpp | 6 +- core/src/qrcode/QRDecoder.cpp | 8 +-- core/src/qrcode/QREncoder.cpp | 4 +- test/unit/CharacterSetECITest.cpp | 13 +++-- 13 files changed, 191 insertions(+), 130 deletions(-) create mode 100644 core/src/ECI.cpp create mode 100644 core/src/ECI.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 461b0832f3..d52b08570d 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -54,6 +54,8 @@ set (COMMON_FILES src/ConcentricFinder.h src/ConcentricFinder.cpp src/CustomData.h + src/ECI.h + src/ECI.cpp src/Flags.h src/GenericGF.h src/GenericGF.cpp diff --git a/core/src/CharacterSetECI.cpp b/core/src/CharacterSetECI.cpp index fe59c044d6..d5640e3e32 100644 --- a/core/src/CharacterSetECI.cpp +++ b/core/src/CharacterSetECI.cpp @@ -5,6 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 #include "CharacterSetECI.h" + +#include "ECI.h" #include "TextDecoder.h" #include @@ -15,40 +17,6 @@ namespace ZXing::CharacterSetECI { -static const std::map ECI_VALUE_TO_CHARSET = { - {0, CharacterSet::Cp437}, // Obsolete - {1, CharacterSet::ISO8859_1}, // Obsolete - {2, CharacterSet::Cp437}, // Obsolete but still used by PDF417 Macro fields (ISO/IEC 15438:2015 Annex H.2.3) - {3, CharacterSet::ISO8859_1}, - {4, CharacterSet::ISO8859_2}, - {5, CharacterSet::ISO8859_3}, - {6, CharacterSet::ISO8859_4}, - {7, CharacterSet::ISO8859_5}, - {8, CharacterSet::ISO8859_6}, - {9, CharacterSet::ISO8859_7}, - {10, CharacterSet::ISO8859_8}, - {11, CharacterSet::ISO8859_9}, - {12, CharacterSet::ISO8859_10}, - {13, CharacterSet::ISO8859_11}, - {15, CharacterSet::ISO8859_13}, - {16, CharacterSet::ISO8859_14}, - {17, CharacterSet::ISO8859_15}, - {18, CharacterSet::ISO8859_16}, - {20, CharacterSet::Shift_JIS}, - {21, CharacterSet::Cp1250}, - {22, CharacterSet::Cp1251}, - {23, CharacterSet::Cp1252}, - {24, CharacterSet::Cp1256}, - {25, CharacterSet::UnicodeBig}, - {26, CharacterSet::UTF8}, - {27, CharacterSet::ASCII}, - {28, CharacterSet::Big5}, - {29, CharacterSet::GB18030}, - {30, CharacterSet::EUC_KR}, - {170, CharacterSet::ASCII}, - {899, CharacterSet::BINARY}, -}; - struct CompareNoCase { bool operator ()(const char* a, const char* b) const { while (*a != '\0' && *b != '\0') { @@ -125,36 +93,6 @@ static const std::map ECI_NAME_TO_CHA {"BINARY", CharacterSet::BINARY}, }; -std::string ECI2String(int eci) -{ - std::ostringstream oss; - oss << '\\' << std::setw(6) << std::setfill('0') << eci; - return oss.str(); -} - -CharacterSet ECI2CharacterSet(int value) -{ - auto it = ECI_VALUE_TO_CHARSET.find(value); - if (it != ECI_VALUE_TO_CHARSET.end()) { - return it->second; - } - return CharacterSet::Unknown; -} - -int Charset2ECI(CharacterSet charset) -{ - // Special case ISO8859_1 to avoid obsolete ECI 1 - if (charset == CharacterSet::ISO8859_1) { - return 3; - } - for (auto& [key, value] : ECI_VALUE_TO_CHARSET) { - if (value == charset) { - return key; - } - } - return -1; -} - CharacterSet CharsetFromName(const char* name) { auto it = ECI_NAME_TO_CHARSET.find(name); @@ -181,7 +119,7 @@ CharacterSet OnChangeAppendReset(const int eci, std::wstring& encoded, std::stri { // Character set ECIs only if (eci >= 0 && eci <= 899) { - auto encodingNew = CharacterSetECI::ECI2CharacterSet(eci); + auto encodingNew = ToCharacterSet(ECI(eci)); if (encodingNew != CharacterSet::Unknown && encodingNew != encoding) { // Encode data so far in current encoding and reset TextDecoder::Append(encoded, reinterpret_cast(data.data()), data.size(), encoding); diff --git a/core/src/CharacterSetECI.h b/core/src/CharacterSetECI.h index 8c586d7a55..e665f920dd 100644 --- a/core/src/CharacterSetECI.h +++ b/core/src/CharacterSetECI.h @@ -19,24 +19,6 @@ namespace ZXing { */ namespace CharacterSetECI { -/** - * @brief ECI2String converts the numerical ECI value to a 7 character string as used in the ECI protocol - * @return e.g. "\000020" - */ -std::string ECI2String(int eci); - -/** - * @param value character set ECI value - * @return {@code CharacterSet} representing ECI of given value, or {@code CharacterSet::Unknown} if it is unsupported - */ -CharacterSet ECI2CharacterSet(int value); - -/** - * @param charset {@code CharacterSet} representing ECI - * @return ECI of given {@code CharacterSet}, or -1 if it is unsupported - */ -int Charset2ECI(CharacterSet charset); - /** * @param name character set ECI encoding name * @return {@code CharacterSet} representing ECI of given value, or {@code CharacterSet::Unknown} if it is diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 3085283e0d..be17d65eb0 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -12,11 +12,6 @@ namespace ZXing { -constexpr bool ECIIsBinary(int eci) -{ - return eci < 0 || eci > 32; -} - template void Content::ForEachECIBlock(FUNC func) const { @@ -28,7 +23,7 @@ void Content::ForEachECIBlock(FUNC func) const } } -void Content::switchEncoding(int eci, bool isECI) +void Content::switchEncoding(ECI eci, bool isECI) { // TODO: replace non-ECI entries on first ECI entry with default ECI if (isECI || !hasECI) { @@ -42,7 +37,7 @@ void Content::switchEncoding(int eci, bool isECI) void Content::switchEncoding(CharacterSet cs) { - switchEncoding(CharacterSetECI::Charset2ECI(cs), false); + switchEncoding(ToECI(cs), false); } std::wstring Content::text() const @@ -52,8 +47,8 @@ std::wstring Content::text() const fallbackCS = guessEncoding(); std::wstring wstr; - ForEachECIBlock([&](int eci, int begin, int end) { - CharacterSet cs = CharacterSetECI::ECI2CharacterSet(eci); + ForEachECIBlock([&](ECI eci, int begin, int end) { + CharacterSet cs = ToCharacterSet(eci); if (cs == CharacterSet::Unknown) cs = fallbackCS; @@ -65,21 +60,21 @@ std::wstring Content::text() const std::string Content::utf8Protocol() const { std::wstring res; - int lastECI = -1; + ECI lastECI = ECI::Unknown; - ForEachECIBlock([&](int eci, int begin, int end) { + ForEachECIBlock([&](ECI eci, int begin, int end) { if (!hasECI) - eci = CharacterSetECI::Charset2ECI(guessEncoding()); - CharacterSet cs = CharacterSetECI::ECI2CharacterSet(eci); + eci = ToECI(guessEncoding()); + CharacterSet cs = ToCharacterSet(eci); if (cs == CharacterSet::Unknown) cs = CharacterSet::BINARY; - if (eci == -1) - eci = 899; // 26 == binary ECI - else if (!ECIIsBinary(eci)) - eci = 26; // 26 == utf8 ECI + if (eci == ECI::Unknown) + eci = ECI::Binary; + else if (IsText(eci)) + eci = ECI::UTF8; if (lastECI != eci) - TextDecoder::AppendLatin1(res, CharacterSetECI::ECI2String(eci)); + TextDecoder::AppendLatin1(res, ToString(eci)); lastECI = eci; std::wstring tmp; @@ -98,8 +93,8 @@ CharacterSet Content::guessEncoding() const { // assemble all blocks with unknown encoding ByteArray input; - ForEachECIBlock([&](int eci, int begin, int end) { - if (eci == -1) + ForEachECIBlock([&](ECI eci, int begin, int end) { + if (eci == ECI::Unknown) input.insert(input.end(), binary.begin() + begin, binary.begin() + end); }); @@ -111,7 +106,7 @@ CharacterSet Content::guessEncoding() const ContentType Content::type() const { - auto isBinary = [](Encoding e) { return ECIIsBinary(e.eci); }; + auto isBinary = [](Encoding e) { return !IsText(e.eci); }; if (hasECI) { if (std::none_of(encodings.begin(), encodings.end(), isBinary)) diff --git a/core/src/Content.h b/core/src/Content.h index 78b8682734..7b7dce5af1 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -6,7 +6,7 @@ #pragma once #include "ByteArray.h" -#include "CharacterSet.h" +#include "ECI.h" namespace ZXing { @@ -19,23 +19,24 @@ class Content template void ForEachECIBlock(FUNC f) const; - void switchEncoding(int eci, bool isECI); + void switchEncoding(ECI eci, bool isECI); public: struct Encoding { - int eci, pos; + ECI eci; + int pos; }; ByteArray binary; - std::vector encodings = {{-1, 0}}; + std::vector encodings = {{ECI::Unknown, 0}}; std::string hintedCharset; std::string applicationIndicator; Content() = default; - Content(ByteArray&& binary, int defaultECI) : binary(binary), encodings{{defaultECI, 0}} {} + Content(ByteArray&& binary, ECI defaultECI) : binary(binary), encodings{{defaultECI, 0}} {} - void switchEncoding(int eci) { switchEncoding(eci, true); } + void switchEncoding(ECI eci) { switchEncoding(eci, true); } void switchEncoding(CharacterSet cs); void reserve(int count) { binary.reserve(binary.size() + count); } diff --git a/core/src/ECI.cpp b/core/src/ECI.cpp new file mode 100644 index 0000000000..a8ee347009 --- /dev/null +++ b/core/src/ECI.cpp @@ -0,0 +1,76 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "ECI.h" + +#include +#include +#include + +namespace ZXing { + +static const std::map ECI_TO_CHARSET = { + {ECI(0), CharacterSet::Cp437}, // Obsolete + {ECI(1), CharacterSet::ISO8859_1}, // Obsolete + {ECI(2), CharacterSet::Cp437}, // Obsolete but still used by PDF417 Macro fields (ISO/IEC 15438:2015 Annex H.2.3) + {ECI::ISO8859_1, CharacterSet::ISO8859_1}, + {ECI::ISO8859_2, CharacterSet::ISO8859_2}, + {ECI::ISO8859_3, CharacterSet::ISO8859_3}, + {ECI::ISO8859_4, CharacterSet::ISO8859_4}, + {ECI::ISO8859_5, CharacterSet::ISO8859_5}, + {ECI::ISO8859_6, CharacterSet::ISO8859_6}, + {ECI::ISO8859_7, CharacterSet::ISO8859_7}, + {ECI::ISO8859_8, CharacterSet::ISO8859_8}, + {ECI::ISO8859_9, CharacterSet::ISO8859_9}, + {ECI::ISO8859_10, CharacterSet::ISO8859_10}, + {ECI::ISO8859_11, CharacterSet::ISO8859_11}, + {ECI::ISO8859_13, CharacterSet::ISO8859_13}, + {ECI::ISO8859_14, CharacterSet::ISO8859_14}, + {ECI::ISO8859_15, CharacterSet::ISO8859_15}, + {ECI::ISO8859_16, CharacterSet::ISO8859_16}, + {ECI::Shift_JIS, CharacterSet::Shift_JIS}, + {ECI::Cp1250, CharacterSet::Cp1250}, + {ECI::Cp1251, CharacterSet::Cp1251}, + {ECI::Cp1252, CharacterSet::Cp1252}, + {ECI::Cp1256, CharacterSet::Cp1256}, + {ECI::UTF16, CharacterSet::UnicodeBig}, + {ECI::UTF8, CharacterSet::UTF8}, + {ECI::ASCII, CharacterSet::ASCII}, + {ECI::Big5, CharacterSet::Big5}, + {ECI::GB18030, CharacterSet::GB18030}, + {ECI::EUC_KR, CharacterSet::EUC_KR}, + {ECI(170), CharacterSet::ASCII}, + {ECI::Binary, CharacterSet::BINARY}, +}; + +std::string ToString(ECI eci) +{ + std::ostringstream oss; + oss << '\\' << std::setw(6) << std::setfill('0') << ToInt(eci); + return oss.str(); +} + +CharacterSet ToCharacterSet(ECI eci) +{ + if (auto it = ECI_TO_CHARSET.find(eci); it != ECI_TO_CHARSET.end()) + return it->second; + + return CharacterSet::Unknown; +} + +ECI ToECI(CharacterSet cs) +{ + // Special case ISO8859_1 to avoid obsolete ECI 1 + if (cs == CharacterSet::ISO8859_1) + return ECI::ISO8859_1; + + for (auto& [key, value] : ECI_TO_CHARSET) + if (value == cs) + return key; + + return ECI::Unknown; +} + +} // namespace ZXing diff --git a/core/src/ECI.h b/core/src/ECI.h new file mode 100644 index 0000000000..ac2f65dfb8 --- /dev/null +++ b/core/src/ECI.h @@ -0,0 +1,66 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "CharacterSet.h" + +#include + +namespace ZXing { + +enum class ECI : int +{ + Unknown = -1, + ISO8859_1 = 3, + ISO8859_2 = 4, + ISO8859_3 = 5, + ISO8859_4 = 6, + ISO8859_5 = 7, + ISO8859_6 = 8, + ISO8859_7 = 9, + ISO8859_8 = 10, + ISO8859_9 = 11, + ISO8859_10 = 12, + ISO8859_11 = 13, + ISO8859_13 = 15, + ISO8859_14 = 16, + ISO8859_15 = 17, + ISO8859_16 = 18, + Shift_JIS = 20, + Cp1250 = 21, + Cp1251 = 22, + Cp1252 = 23, + Cp1256 = 24, + UTF16 = 25, + UTF8 = 26, + ASCII = 27, + Big5 = 28, + GB18030 = 29, + EUC_KR = 30, + Binary = 899 +}; + +inline constexpr int ToInt(ECI eci) +{ + return static_cast(eci); +} + +inline constexpr bool IsText(ECI eci) +{ + return ToInt(eci) >= 0 && ToInt(eci) <= 32; +} + +/** + * @brief ToString converts the numerical ECI value to a 7 character string as used in the ECI protocol + * @return e.g. "\000020" + */ +std::string ToString(ECI eci); + +CharacterSet ToCharacterSet(ECI eci); + +ECI ToECI(CharacterSet cs); + +} // namespace ZXing diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 0a6ea4ab5e..f397219f9b 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -18,7 +18,7 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor std::string&& symbologyIdentifier, ByteArray&& rawBytes, const bool readerInit) : _format(format), - _content({ByteArray(text), 3}), + _content({ByteArray(text), ECI::ISO8859_1}), _text(TextDecoder::FromLatin1(text)), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index c76f208e87..af58169cbf 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -82,19 +82,19 @@ struct Shift128 /** * See ISO 16022:2006, 5.4.1, Table 6 */ -static int ParseECIValue(BitSource& bits) +static ECI ParseECIValue(BitSource& bits) { int firstByte = bits.readBits(8); if (firstByte <= 127) - return firstByte - 1; + return ECI(firstByte - 1); int secondByte = bits.readBits(8); if (firstByte <= 191) - return (firstByte - 128) * 254 + 127 + secondByte - 1; + return ECI((firstByte - 128) * 254 + 127 + secondByte - 1); int thirdByte = bits.readBits(8); - return (firstByte - 192) * 64516 + 16383 + (secondByte - 1) * 254 + thirdByte - 1; + return ECI((firstByte - 192) * 64516 + 16383 + (secondByte - 1) * 254 + thirdByte - 1); } /** diff --git a/core/src/pdf417/PDFHighLevelEncoder.cpp b/core/src/pdf417/PDFHighLevelEncoder.cpp index c09a8fb536..ea394d11c2 100644 --- a/core/src/pdf417/PDFHighLevelEncoder.cpp +++ b/core/src/pdf417/PDFHighLevelEncoder.cpp @@ -8,7 +8,7 @@ #include "PDFHighLevelEncoder.h" #include "PDFCompaction.h" #include "CharacterSet.h" -#include "CharacterSetECI.h" +#include "ECI.h" #include "TextEncoder.h" #include "ZXBigInteger.h" #include "ZXContainerAlgorithms.h" @@ -502,8 +502,8 @@ HighLevelEncoder::EncodeHighLevel(const std::wstring& msg, Compaction compaction highLevel.reserve(highLevel.size() + msg.length()); //the codewords 0..928 are encoded as Unicode characters - if (encoding != CharacterSet::ISO8859_1) { - EncodingECI(CharacterSetECI::Charset2ECI(encoding), highLevel); + if (encoding != CharacterSet::ISO8859_1) { + EncodingECI(ToInt(ToECI(encoding)), highLevel); } int len = Size(msg); diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 70476b71cd..ad0b2b27fb 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -203,22 +203,22 @@ static void DecodeNumericSegment(BitSource& bits, int count, Content& result) } } -static int ParseECIValue(BitSource& bits) +static ECI ParseECIValue(BitSource& bits) { int firstByte = bits.readBits(8); if ((firstByte & 0x80) == 0) { // just one byte - return firstByte & 0x7F; + return ECI(firstByte & 0x7F); } if ((firstByte & 0xC0) == 0x80) { // two bytes int secondByte = bits.readBits(8); - return ((firstByte & 0x3F) << 8) | secondByte; + return ECI(((firstByte & 0x3F) << 8) | secondByte); } if ((firstByte & 0xE0) == 0xC0) { // three bytes int secondThirdBytes = bits.readBits(16); - return ((firstByte & 0x1F) << 16) | secondThirdBytes; + return ECI(((firstByte & 0x1F) << 16) | secondThirdBytes); } throw std::runtime_error("ParseECIValue: invalid value"); } diff --git a/core/src/qrcode/QREncoder.cpp b/core/src/qrcode/QREncoder.cpp index db3c90f6fb..2ce915fd0d 100644 --- a/core/src/qrcode/QREncoder.cpp +++ b/core/src/qrcode/QREncoder.cpp @@ -7,7 +7,7 @@ #include "QREncoder.h" #include "BitArray.h" -#include "CharacterSetECI.h" +#include "ECI.h" #include "GenericGF.h" #include "QREncodeResult.h" #include "QRErrorCorrectionLevel.h" @@ -103,7 +103,7 @@ CodecMode ChooseMode(const std::wstring& content, CharacterSet encoding) */ static void AppendECI(CharacterSet eci, BitArray& bits) { - int eciValue = CharacterSetECI::Charset2ECI(eci); + int eciValue = ToInt(ToECI(eci)); if (eciValue >= 0 && eciValue <= 999999) { bits.appendBits(static_cast(CodecMode::ECI), 4); if (eciValue <= 127) { diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index 2542fcd7c2..d83c208741 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "CharacterSetECI.h" +#include "ECI.h" #include "gtest/gtest.h" #include "gmock/gmock.h" @@ -14,12 +15,12 @@ using namespace testing; TEST(CharacterSetECITest, Charset2ECI) { - EXPECT_EQ(Charset2ECI(CharacterSet::ISO8859_1), 3); - EXPECT_EQ(Charset2ECI(CharacterSet::ISO8859_2), 4); - EXPECT_EQ(Charset2ECI(CharacterSet::ASCII), 27); - EXPECT_EQ(Charset2ECI(CharacterSet::EUC_KR), 30); - EXPECT_EQ(Charset2ECI(CharacterSet::BINARY), 899); - EXPECT_EQ(Charset2ECI(CharacterSet::Unknown), -1); + EXPECT_EQ(ToInt(ToECI(CharacterSet::ISO8859_1)), 3); + EXPECT_EQ(ToInt(ToECI(CharacterSet::ISO8859_2)), 4); + EXPECT_EQ(ToInt(ToECI(CharacterSet::ASCII)), 27); + EXPECT_EQ(ToInt(ToECI(CharacterSet::EUC_KR)), 30); + EXPECT_EQ(ToInt(ToECI(CharacterSet::BINARY)), 899); + EXPECT_EQ(ToInt(ToECI(CharacterSet::Unknown)), -1); } TEST(CharacterSetECITest, InitEncoding) From 6f9fc1fa04f426bb2d2b6ab9049a2560267b7c3b Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 02:38:14 +0200 Subject: [PATCH 0222/1315] Result: return empty utf8Protocol string if no image barcode was found --- core/src/Content.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index be17d65eb0..a7bdd2ec0e 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -59,6 +59,9 @@ std::wstring Content::text() const std::string Content::utf8Protocol() const { + if (binary.empty()) + return {}; + std::wstring res; ECI lastECI = ECI::Unknown; From b7695b1f112a561c393519afeca739d1bcfb4f1e Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 03:01:02 +0200 Subject: [PATCH 0223/1315] QRCode: prevent MicroQRCode detection 'inside' standard QRCode We check for a sufficiently empty quite zone while still accepting 'dirty' symbols. --- core/src/qrcode/QRDetector.cpp | 19 +++++++++++++++--- test/blackbox/BlackboxTestRunner.cpp | 2 +- .../falsepositives-1/MQR-falsepositive.jpg | Bin 0 -> 1025 bytes 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 test/samples/falsepositives-1/MQR-falsepositive.jpg diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 9c189bb3fe..3b0ea99766 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -429,10 +429,23 @@ DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp) AppendBit(formatInfoBits, image.get(mod2Pix(centered(FORMAT_INFO_COORDS[i])))); auto fi = FormatInformation::DecodeMQR(formatInfoBits); - if (fi.isValid() && fi.microVersion()) { - const int dim = Version::DimensionOfVersion(fi.microVersion(), true); - return SampleGrid(image, dim, dim, mod2Pix); + if (!fi.isValid()) + continue; + + const int dim = Version::DimensionOfVersion(fi.microVersion(), true); + + // check that we are in fact not looking at a corner of a non-micro QRCode symbol + // we accept at most 1/3rd black pixels in the quite zone (in a QRCode symbol we expect about 1/2). + int blackPixels = 0; + for (int i = 0; i < dim; ++i) { + auto px = mod2Pix(centered(PointI{i, dim})); + auto py = mod2Pix(centered(PointI{dim, i})); + blackPixels += (image.isIn(px) && image.get(px)) + (image.isIn(py) && image.get(py)); } + if (blackPixels > 2 * dim / 3) + continue; + + return SampleGrid(image, dim, dim, mod2Pix); } return {}; diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index f03a369b48..9f16fa2aa3 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -644,7 +644,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 2, 2, 0 }, }); - runTests("falsepositives-1", "None", 25, { + runTests("falsepositives-1", "None", 26, { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 90 }, { 0, 0, 0, 0, 180 }, diff --git a/test/samples/falsepositives-1/MQR-falsepositive.jpg b/test/samples/falsepositives-1/MQR-falsepositive.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fdb661127fbfad5f5c7894bf41dfca27fc8d3e0a GIT binary patch literal 1025 zcmV+c1pfQ~*#F=F5K2Z#MgRc;000310RRC1+Wau05K2%0R#aA00RXF z1poj5000010s{mE1^@>U5)&iR5EK?MQ3xSHR+N>~CNn}qV*lCz2mt{A0Y3oL{JRyZ zl5u~>Af_dYf z5KfM9g#*I#8Z?o}AkSyjp`2kKohUzXW7VOYVIQ3+KXGH#>`pn3UG5g-NxG+MaEBHO zn@fY9Jf2S)smwNB;?lmgowr&Xl>2NTsiyh@v&Z1QW0X}G{_12gDxftIKf}@7@Q@E) z#nL$%k+xQIF{I^DrKQwLvRfiD8d8>kT`2BKb$_z*=qkmdchKyBeUupSkfODPt4(cI z-v*ohlw;&S*!QnPRVqUB&DD+LwA+ryf`oTh1Cq(r2FBP^UQ}5*mD9M0ve|f{3s))# zR-ii5yR(!nDhmn6Vge9{wf4a*GbW83maStc8)!;^wxhM%YWAYB1_~(Va1T^}bvw zE%y0xwXa*lM|X-*#%7_|jN>fKWou$a99@kkD_JMbclf=TzSd#)X}-Ui5=ow@jyc^gr~tN`;X2B5S_@6D z#PPU}yl2971@xB4K;b7_Aab#YME9XwYWxQce@^~Ce&?STSw<5!ZNb0X*Vsc+5Yz~Q znMeEo0N@rKPNL>n&eTbPgSi%+#){CiETzX+(o+7RXw#o(yfx*m({Fvs$x-3fe~Z}m z7h9WW+lJkpm7^@h5qva7d^R{+T%JOLwTj+~d6`Zr8Z$0HqJYVO>&BGlXE7{;Sa{>>R4^o#9*lZ v03*>zR<_3}mz(ZQwUxwJq0vmH0$4!^;S2gWSEIBQ3grA}mwvS#jeq~yVkXWF literal 0 HcmV?d00001 From 9f783473b21733074416e5a7419d770596bd3e0d Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 11:44:27 +0200 Subject: [PATCH 0224/1315] Result: fix ECI designator for ALPHA content in utf8Protocol --- core/src/Content.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index a7bdd2ec0e..4ad4ec373f 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -48,9 +48,7 @@ std::wstring Content::text() const std::wstring wstr; ForEachECIBlock([&](ECI eci, int begin, int end) { - CharacterSet cs = ToCharacterSet(eci); - if (cs == CharacterSet::Unknown) - cs = fallbackCS; + CharacterSet cs = eci == ECI::Unknown ? fallbackCS : ToCharacterSet(eci); TextDecoder::Append(wstr, binary.data() + begin, end - begin, cs); }); @@ -64,17 +62,19 @@ std::string Content::utf8Protocol() const std::wstring res; ECI lastECI = ECI::Unknown; + auto fallbackCS = guessEncoding(); ForEachECIBlock([&](ECI eci, int begin, int end) { - if (!hasECI) - eci = ToECI(guessEncoding()); - CharacterSet cs = ToCharacterSet(eci); - if (cs == CharacterSet::Unknown) - cs = CharacterSet::BINARY; - if (eci == ECI::Unknown) - eci = ECI::Binary; - else if (IsText(eci)) + // first determine how to decode the content (choose character set) + // * eci == ECI::Unknown implies !hasECI and we guess + // * if !IsText(eci) the ToCharcterSet(eci) will return Unknown and we decode as binary + CharacterSet cs = eci == ECI::Unknown ? fallbackCS : ToCharacterSet(eci); + + // then find the eci to report back in the ECI designator + if (IsText(ToECI(cs))) // everything decoded as text is reported as utf8 eci = ECI::UTF8; + else if (eci == ECI::Unknown) // implies !hasECI and fallbackCS is Unknown or Binary + eci = ECI::Binary; if (lastECI != eci) TextDecoder::AppendLatin1(res, ToString(eci)); From 7693e4d7b85b2ee3066e3f5538b859a46ffa2c58 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 11:47:29 +0200 Subject: [PATCH 0225/1315] Content: minor improvement of binary.empty() check --- core/src/Content.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 4ad4ec373f..c17a4d12ca 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -19,7 +19,8 @@ void Content::ForEachECIBlock(FUNC func) const auto [eci, start] = encodings[i]; int end = i + 1 == Size(encodings) ? Size(binary) : encodings[i + 1].pos; - func(eci, start, end); + if (start != end) + func(eci, start, end); } } @@ -57,9 +58,6 @@ std::wstring Content::text() const std::string Content::utf8Protocol() const { - if (binary.empty()) - return {}; - std::wstring res; ECI lastECI = ECI::Unknown; auto fallbackCS = guessEncoding(); From 80ee48ba4da83af397d7d5ee88f41686dfcdc43a Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 12:23:37 +0200 Subject: [PATCH 0226/1315] TextDecoder: improve binary auto-detection Treat all ANSI control characters as binary, except EOT, LF, CR, GS and RS (see ISO/IEC 15434). See also the discussion in https://github.com/nu-book/zxing-cpp/issues/334#issuecomment-1133554551 --- core/src/TextDecoder.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/TextDecoder.cpp b/core/src/TextDecoder.cpp index 4df8a65f14..98677d63a4 100644 --- a/core/src/TextDecoder.cpp +++ b/core/src/TextDecoder.cpp @@ -402,6 +402,10 @@ TextDecoder::GuessEncoding(const uint8_t* bytes, size_t length, CharacterSet fal if (value > 0x7F && value < 0xA0) { canBeISO88591 = false; } + // treat all ANSI control characters as binary, except EOT, LF, CR, GS and RS (see ISO/IEC 15434) + else if (value < 0x20 && value != 0x04 && value != 0x0a && value != 0x0d && value != 0x1d && value != 0x1e) { + canBeISO88591 = false; + } else if (value > 0x9F) { if (value < 0xC0 || value == 0xD7 || value == 0xF7) { isoHighOther++; From 665f1a102b1715bb5a577e2e41ff0afd89e8c097 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 12:59:45 +0200 Subject: [PATCH 0227/1315] test: remove unnecessary explicit std::wstring and std::string construction --- test/unit/CharacterSetECITest.cpp | 10 ++++---- test/unit/TextDecoderTest.cpp | 38 ++++++++++++++-------------- test/unit/TextUtfEncodingTest.cpp | 42 +++++++++++++++---------------- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index d83c208741..5e695e7c68 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -57,7 +57,7 @@ TEST(CharacterSetECITest, OnChangeAppendReset) auto result = OnChangeAppendReset(3, encoded, data, CharacterSet::Unknown); EXPECT_EQ(result, CharacterSet::ISO8859_1); EXPECT_TRUE(data.empty()); - EXPECT_EQ(encoded, std::wstring(L"A\u00E9Z")); + EXPECT_EQ(encoded, L"A\u00E9Z"); } { @@ -68,7 +68,7 @@ TEST(CharacterSetECITest, OnChangeAppendReset) // Encoding same auto result = OnChangeAppendReset(3, encoded, data, CharacterSet::ISO8859_1); EXPECT_EQ(result, CharacterSet::ISO8859_1); - EXPECT_EQ(data, std::string("A\xE9Z")); + EXPECT_EQ(data, "A\xE9Z"); EXPECT_TRUE(encoded.empty()); } @@ -82,7 +82,7 @@ TEST(CharacterSetECITest, OnChangeAppendReset) result = OnChangeAppendReset(20, encoded, data, CharacterSet::ISO8859_5); EXPECT_EQ(result, CharacterSet::Shift_JIS); EXPECT_TRUE(data.empty()); - EXPECT_EQ(encoded, std::wstring(L"A\u00E9ZA\u0449Z")); + EXPECT_EQ(encoded, L"A\u00E9ZA\u0449Z"); static const uint8_t bytes2[] = { 'A', 0x83, 0x65, 'Z' }; std::string data2(reinterpret_cast(&bytes2), sizeof(bytes2)); @@ -91,12 +91,12 @@ TEST(CharacterSetECITest, OnChangeAppendReset) result = OnChangeAppendReset(20, encoded, data2, result); EXPECT_EQ(result, CharacterSet::Shift_JIS); EXPECT_THAT(data2, ElementsAreArray(bytes2, sizeof(bytes2))); - EXPECT_EQ(encoded, std::wstring(L"A\u00E9ZA\u0449Z")); + EXPECT_EQ(encoded, L"A\u00E9ZA\u0449Z"); // Encoding change result = OnChangeAppendReset(4, encoded, data2, result); EXPECT_EQ(result, CharacterSet::ISO8859_2); EXPECT_TRUE(data2.empty()); - EXPECT_EQ(encoded, std::wstring(L"A\u00E9ZA\u0449ZA\u30C6Z")); + EXPECT_EQ(encoded, L"A\u00E9ZA\u0449ZA\u30C6Z"); } } diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index 6d3ec55d09..5276c4e7f5 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -90,7 +90,7 @@ TEST(TextDecoderTest, AppendShift_JIS) static const uint8_t data[] = { 0x5C }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); - EXPECT_EQ(str, std::wstring(L"\u005C")); // Would normally be "\u00A5" + EXPECT_EQ(str, L"\u005C"); // Would normally be "\u00A5" EXPECT_EQ(ToUtf8(str), "\\"); // "¥" ditto } @@ -99,7 +99,7 @@ TEST(TextDecoderTest, AppendShift_JIS) static const uint8_t data[] = { 0x81, 0x5F }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); - EXPECT_EQ(str, std::wstring(L"\uFF3C")); + EXPECT_EQ(str, L"\uFF3C"); EXPECT_EQ(ToUtf8(str), "\"); } @@ -108,7 +108,7 @@ TEST(TextDecoderTest, AppendShift_JIS) static const uint8_t data[] = { 0xA5 }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); - EXPECT_EQ(str, std::wstring(L"\uFF65")); + EXPECT_EQ(str, L"\uFF65"); EXPECT_EQ(ToUtf8(str), "・"); } @@ -117,7 +117,7 @@ TEST(TextDecoderTest, AppendShift_JIS) static const uint8_t data[] = { 0x7E }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); - EXPECT_EQ(str, std::wstring(L"~")); // Would normally be "\u203E" + EXPECT_EQ(str, L"~"); // Would normally be "\u203E" EXPECT_EQ(ToUtf8(str), "~"); // "‾" ditto } @@ -126,7 +126,7 @@ TEST(TextDecoderTest, AppendShift_JIS) 0xE4, 0xAA, 0x83, 0x65 }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); - EXPECT_EQ(str, std::wstring(L"a\u03B2c\u0416\uFF65\uFF7F\uFF3C\u70B9\u8317\u30C6")); + EXPECT_EQ(str, L"a\u03B2c\u0416\uFF65\uFF7F\uFF3C\u70B9\u8317\u30C6"); EXPECT_EQ(ToUtf8(str), "aβcЖ・ソ\点茗テ"); } } @@ -137,7 +137,7 @@ TEST(TextDecoderTest, AppendBig5) static const uint8_t data[] = { 0xA1, 0x5A }; // Drawings box light left in Big5-2003; not in original Big5 std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Big5); - EXPECT_EQ(str, std::wstring(L"\u2574")); + EXPECT_EQ(str, L"\u2574"); EXPECT_EQ(ToUtf8(str), "╴"); } @@ -145,7 +145,7 @@ TEST(TextDecoderTest, AppendBig5) static const uint8_t data[] = { 0xA1, 0x56 }; // En dash U+2013 in Big5, horizontal bar U+2015 in Big5-2003 std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Big5); - EXPECT_EQ(str, std::wstring(L"\u2013")); + EXPECT_EQ(str, L"\u2013"); EXPECT_EQ(ToUtf8(str), "–"); } @@ -153,7 +153,7 @@ TEST(TextDecoderTest, AppendBig5) static const uint8_t data[] = { 0x1, ' ', 0xA1, 0x71, '@', 0xC0, 0x40, 0xF9, 0xD5, 0x7F }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Big5); - EXPECT_EQ(str, std::wstring(L"\u0001 \u3008@\u9310\u9F98\u007F")); + EXPECT_EQ(str, L"\u0001 \u3008@\u9310\u9F98\u007F"); EXPECT_EQ(ToUtf8(str), "\x01 〈@錐龘\x7F"); } } @@ -164,7 +164,7 @@ TEST(TextDecoderTest, AppendGB2312) static const uint8_t data[] = { 'a', 0xA6, 0xC2, 'c', 0xA1, 0xA4, 0xA1, 0xAA, 0xA8, 0xA6, 'Z' }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::GB2312); - EXPECT_EQ(str, std::wstring(L"a\u03B2c\u00B7\u2014\u00E9Z")); + EXPECT_EQ(str, L"a\u03B2c\u00B7\u2014\u00E9Z"); EXPECT_EQ(ToUtf8(str), "aβc·—éZ"); } } @@ -176,8 +176,8 @@ TEST(TextDecoderTest, AppendGB18030) 0xA8, 0xA6, 'Z' }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::GB18030); - EXPECT_EQ(str, std::wstring(L"a\u03B2c\u30FB\u00B7\u2014\u00E9Z")); - EXPECT_EQ(ToUtf8(str), std::string("aβc・·—éZ")); + EXPECT_EQ(str, L"a\u03B2c\u30FB\u00B7\u2014\u00E9Z"); + EXPECT_EQ(ToUtf8(str), "aβc・·—éZ"); } } @@ -187,16 +187,16 @@ TEST(TextDecoderTest, AppendEUC_KR) static const uint8_t data[] = { 0xA2, 0xE6 }; // Euro sign U+20AC added KS X 1001:1998, not supported std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::EUC_KR); - EXPECT_EQ(str, std::wstring(L"\uFFFD")); - EXPECT_EQ(ToUtf8(str), std::string("\xEF\xBF\xBD")); + EXPECT_EQ(str, L"\uFFFD"); + EXPECT_EQ(ToUtf8(str), "\xEF\xBF\xBD"); } { static const uint8_t data[] = { 'a', 0xA4, 0xA1, 'Z' }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::EUC_KR); - EXPECT_EQ(str, std::wstring(L"a\u3131Z")); - EXPECT_EQ(ToUtf8(str), std::string("aㄱZ")); + EXPECT_EQ(str, L"a\u3131Z"); + EXPECT_EQ(ToUtf8(str), "aㄱZ"); } } @@ -207,15 +207,15 @@ TEST(TextDecoderTest, AppendUnicodeBig) static const uint8_t data[] = { 0x00, 0x01, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x01, 0xFF, 0x10, 0xFF, 0xFF, 0xFD }; TextDecoder::Append(str, data, sizeof(data), CharacterSet::UnicodeBig); - EXPECT_EQ(str, std::wstring(L"\u0001\u007F\u0080\u00FF\u01FF\u10FF\uFFFD")); - EXPECT_EQ(ToUtf8(str), std::string("\x01\x7F\xC2\x80ÿǿჿ\xEF\xBF\xBD")); + EXPECT_EQ(str, L"\u0001\u007F\u0080\u00FF\u01FF\u10FF\uFFFD"); + EXPECT_EQ(ToUtf8(str), "\x01\x7F\xC2\x80ÿǿჿ\xEF\xBF\xBD"); } { std::wstring str; static const uint8_t data[] = { 0xD8, 0x00, 0xDC, 0x00 }; // Surrogate pair U+10000 TextDecoder::Append(str, data, sizeof(data), CharacterSet::UnicodeBig); - EXPECT_EQ(str, std::wstring(L"\U00010000")); - EXPECT_EQ(ToUtf8(str), std::string("𐀀")); + EXPECT_EQ(str, L"\U00010000"); + EXPECT_EQ(ToUtf8(str), "𐀀"); } } diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index 2c6c0773a5..f37e1bfb65 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -19,11 +19,11 @@ TEST(TextUtfEncodingTest, ToUtf8AngleEscape) EXPECT_EQ(ctype_locale, std::string("C")); #ifndef _WIN32 - EXPECT_EQ(ToUtf8(std::wstring(L"\u00B6\u0416"), angleEscape), std::string("")); + EXPECT_EQ(ToUtf8(L"\u00B6\u0416", angleEscape), ""); #else - EXPECT_EQ(ToUtf8(std::wstring(L"\u00B6\u0416"), angleEscape), std::string("¶Ж")); + EXPECT_EQ(ToUtf8(L"\u00B6\u0416", angleEscape), "¶Ж"); #endif - EXPECT_EQ(ToUtf8(std::wstring(L"\u2602"), angleEscape), std::string("")); + EXPECT_EQ(ToUtf8(L"\u2602", angleEscape), ""); #ifndef _WIN32 std::setlocale(LC_CTYPE, "en_US.UTF-8"); @@ -33,33 +33,33 @@ TEST(TextUtfEncodingTest, ToUtf8AngleEscape) EXPECT_TRUE(std::string(std::setlocale(LC_CTYPE, NULL)).find("utf8") != std::string::npos); #endif - EXPECT_EQ(ToUtf8(std::wstring(L"\u00B6\u0416"), angleEscape), std::string("¶Ж")); + EXPECT_EQ(ToUtf8(L"\u00B6\u0416", angleEscape), "¶Ж"); #ifndef _WIN32 - EXPECT_EQ(ToUtf8(std::wstring(L"\u2602"), angleEscape), std::string("☂")); + EXPECT_EQ(ToUtf8(L"\u2602", angleEscape), "☂"); #else - EXPECT_EQ(ToUtf8(std::wstring(L"\u2602"), angleEscape), std::string("")); + EXPECT_EQ(ToUtf8(L"\u2602", angleEscape), ""); #endif - EXPECT_EQ(ToUtf8(std::wstring(L"\x01\x1F\x7F"), angleEscape), std::string("")); - EXPECT_EQ(ToUtf8(std::wstring(L"\x80\x9F"), angleEscape), std::string("")); - EXPECT_EQ(ToUtf8(std::wstring(L"\xA0"), angleEscape), std::string("")); // NO-BREAK space (nbsp) - EXPECT_EQ(ToUtf8(std::wstring(L"\x2007"), angleEscape), std::string("")); // NO-BREAK space (numsp) - EXPECT_EQ(ToUtf8(std::wstring(L"\xFFEF"), angleEscape), std::string("")); // Was NO-BREAK space but now isn't (BOM) - EXPECT_EQ(ToUtf8(std::wstring(L"\u0100"), angleEscape), std::string("Ā")); - EXPECT_EQ(ToUtf8(std::wstring(L"\u1000"), angleEscape), std::string("က")); - EXPECT_EQ(ToUtf8(std::wstring(L"\u2000"), angleEscape), std::string("")); // Space char (nqsp) + EXPECT_EQ(ToUtf8(L"\x01\x1F\x7F", angleEscape), ""); + EXPECT_EQ(ToUtf8(L"\x80\x9F", angleEscape), ""); + EXPECT_EQ(ToUtf8(L"\xA0", angleEscape), ""); // NO-BREAK space (nbsp) + EXPECT_EQ(ToUtf8(L"\x2007", angleEscape), ""); // NO-BREAK space (numsp) + EXPECT_EQ(ToUtf8(L"\xFFEF", angleEscape), ""); // Was NO-BREAK space but now isn't (BOM) + EXPECT_EQ(ToUtf8(L"\u0100", angleEscape), "Ā"); + EXPECT_EQ(ToUtf8(L"\u1000", angleEscape), "က"); + EXPECT_EQ(ToUtf8(L"\u2000", angleEscape), ""); // Space char (nqsp) #ifndef _WIN32 - EXPECT_EQ(ToUtf8(std::wstring(L"\uFFFD"), angleEscape), std::string("�")); + EXPECT_EQ(ToUtf8(L"\uFFFD", angleEscape), "�"); #else - EXPECT_EQ(ToUtf8(std::wstring(L"\uFFFD"), angleEscape), std::string("")); + EXPECT_EQ(ToUtf8(L"\uFFFD", angleEscape), ""); #endif - EXPECT_EQ(ToUtf8(std::wstring(L"\uFFFF"), angleEscape), std::string("")); + EXPECT_EQ(ToUtf8(L"\uFFFF", angleEscape), ""); #ifndef __APPLE__ - EXPECT_EQ(ToUtf8(std::wstring(L"\U00010000"), angleEscape), std::string("𐀀")); + EXPECT_EQ(ToUtf8(L"\U00010000", angleEscape), "𐀀"); #else - EXPECT_EQ(ToUtf8(std::wstring(L"\U00010000"), angleEscape), std::string("")); + EXPECT_EQ(ToUtf8(L"\U00010000", angleEscape), ""); #endif - EXPECT_EQ(ToUtf8(std::wstring(L"\xD800Z"), angleEscape), std::string("Z")); // Unpaired high surrogate - EXPECT_EQ(ToUtf8(std::wstring(L"A\xDC00"), angleEscape), std::string("A")); // Unpaired low surrogate + EXPECT_EQ(ToUtf8(L"\xD800Z", angleEscape), "Z"); // Unpaired high surrogate + EXPECT_EQ(ToUtf8(L"A\xDC00", angleEscape), "A"); // Unpaired low surrogate std::setlocale(LC_CTYPE, ctype_locale.c_str()); } From 984c64b614246b0617a90f340b5ad594048c11b5 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 13:00:50 +0200 Subject: [PATCH 0228/1315] android: fix potential issue with ISO8859 std::string to JString conversion --- wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp index e552c912d8..6ae1333f12 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp @@ -4,6 +4,8 @@ // SPDX-License-Identifier: Apache-2.0 #include "JNIUtils.h" +#include "TextDecoder.h" + #include #include @@ -53,7 +55,7 @@ jstring C2JString(JNIEnv* env, const std::wstring& str) jstring C2JString(JNIEnv* env, const std::string& str) { - return C2JString(env, std::wstring(str.begin(), str.end())); + return C2JString(env, ZXing::TextDecoder::FromLatin1(str)); } std::string J2CString(JNIEnv* env, jstring str) From 966ddfab66770404c4caa57e0468dda7c3c6d077 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 13:17:06 +0200 Subject: [PATCH 0229/1315] DecoderResult: switch internal representation of ecLevel to std::string --- core/src/DecoderResult.h | 4 ++-- core/src/Result.cpp | 2 +- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 2 +- core/src/qrcode/QRErrorCorrectionLevel.cpp | 4 ++-- core/src/qrcode/QRErrorCorrectionLevel.h | 2 +- test/unit/qrcode/QRErrorCorrectionLevelTest.cpp | 10 ++++++---- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index c239d07e03..6f768cc8ec 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -34,7 +34,7 @@ class DecoderResult Content _content; int _numBits = 0; std::wstring _text; - std::wstring _ecLevel; + std::string _ecLevel; int _errorsCorrected = -1; int _erasures = -1; int _lineCount = 0; @@ -90,7 +90,7 @@ class DecoderResult DecoderResult&& SETTER(TYPE&& v) && { _##GETTER = std::move(v); return std::move(*this); } ZX_PROPERTY(int, numBits, setNumBits) - ZX_PROPERTY(std::wstring, ecLevel, setEcLevel) + ZX_PROPERTY(std::string, ecLevel, setEcLevel) ZX_PROPERTY(int, errorsCorrected, setErrorsCorrected) ZX_PROPERTY(int, erasures, setErasures) ZX_PROPERTY(int, lineCount, setLineCount) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index f397219f9b..13ae8f663d 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -36,7 +36,7 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), - _ecLevel(decodeResult.ecLevel()), + _ecLevel(TextDecoder::FromLatin1(decodeResult.ecLevel())), _symbologyIdentifier(decodeResult.symbologyIdentifier()), _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 5bbeba0e95..9a499f9399 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -307,7 +307,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& chara // No identifier defined for mode 6 return DecoderResult(std::move(bytes), std::move(result)) - .setEcLevel(std::to_wstring(mode)) + .setEcLevel(std::to_string(mode)) .setSymbologyIdentifier(std::move(symbologyIdentifier)) .setStructuredAppend(sai) .setReaderInit(mode == 6); diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 1d0620ce23..e616790f4f 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -845,7 +845,7 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c content.append(result); return DecoderResult(ByteArray(), std::move(resultEncoded), std::move(content)) - .setEcLevel(std::to_wstring(ecLevel)) + .setEcLevel(std::to_string(ecLevel)) // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using modifier // that indicates ECI protocol (ISO/IEC 15438:2015 Annex L Table L.1) .setSymbologyIdentifier("]L2") diff --git a/core/src/qrcode/QRErrorCorrectionLevel.cpp b/core/src/qrcode/QRErrorCorrectionLevel.cpp index 6194e5c7b5..0c66b2263c 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.cpp +++ b/core/src/qrcode/QRErrorCorrectionLevel.cpp @@ -10,10 +10,10 @@ namespace ZXing::QRCode { -const wchar_t* ToString(ErrorCorrectionLevel l) +const char* ToString(ErrorCorrectionLevel l) { assert(l != ErrorCorrectionLevel::Invalid); - static const wchar_t* const LEVEL_STR[] = {L"L", L"M", L"Q", L"H", nullptr}; + static const char* const LEVEL_STR[] = {"L", "M", "Q", "H", nullptr}; return LEVEL_STR[static_cast(l)]; } diff --git a/core/src/qrcode/QRErrorCorrectionLevel.h b/core/src/qrcode/QRErrorCorrectionLevel.h index 58d689240f..704fc86939 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.h +++ b/core/src/qrcode/QRErrorCorrectionLevel.h @@ -24,7 +24,7 @@ enum class ErrorCorrectionLevel Invalid, // denotes in invalid/unknown value }; -const wchar_t* ToString(ErrorCorrectionLevel l); +const char* ToString(ErrorCorrectionLevel l); ErrorCorrectionLevel ECLevelFromString(const char* str); ErrorCorrectionLevel ECLevelFromBits(int bits, const bool isMicro = false); int BitsFromECLevel(ErrorCorrectionLevel l); diff --git a/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp b/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp index f3870b4bbe..77c103023e 100644 --- a/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp +++ b/test/unit/qrcode/QRErrorCorrectionLevelTest.cpp @@ -36,8 +36,10 @@ TEST(QRErrorCorrectionLevelTest, ForMicroBits) TEST(QRErrorCorrectionLevelTest, ToString) { - EXPECT_EQ(L"L", std::wstring(ToString(ErrorCorrectionLevel::Low))); - EXPECT_EQ(L"M", std::wstring(ToString(ErrorCorrectionLevel::Medium))); - EXPECT_EQ(L"Q", std::wstring(ToString(ErrorCorrectionLevel::Quality))); - EXPECT_EQ(L"H", std::wstring(ToString(ErrorCorrectionLevel::High))); + using namespace std::literals; + + EXPECT_EQ("L"s, ToString(ErrorCorrectionLevel::Low)); + EXPECT_EQ("M"s, ToString(ErrorCorrectionLevel::Medium)); + EXPECT_EQ("Q"s, ToString(ErrorCorrectionLevel::Quality)); + EXPECT_EQ("H"s, ToString(ErrorCorrectionLevel::High)); } From a7944233365ef15d84fba496144f051fd5edffd0 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 13:26:07 +0200 Subject: [PATCH 0230/1315] cleanup: cut back on explicit std::string construction --- core/src/GTIN.cpp | 6 +++--- .../oned/rss/ODRSSExpandedBinaryDecoder.cpp | 18 +++++++++--------- test/unit/BarcodeFormatTest.cpp | 8 +++++--- test/unit/CharacterSetECITest.cpp | 16 ++++++++-------- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/core/src/GTIN.cpp b/core/src/GTIN.cpp index 8d498206a8..4231597aa8 100644 --- a/core/src/GTIN.cpp +++ b/core/src/GTIN.cpp @@ -165,7 +165,7 @@ std::string LookupCountryIdentifier(const std::string& GTIN, const BarcodeFormat const std::string::size_type size = space != std::string::npos ? space : GTIN.size(); if (size != 14 && size != 13 && size != 12 && size != 8) - return std::string(); + return {}; // GTIN-14 leading packaging level indicator const int first = size == 14 ? 1 : 0; @@ -176,7 +176,7 @@ std::string LookupCountryIdentifier(const std::string& GTIN, const BarcodeFormat // 0000000 Restricted Circulation Numbers; 0000001-0000099 unused to avoid collision with GTIN-8 int prefix = std::stoi(GTIN.substr(first, 7 - implicitZero)); if (prefix >= 0 && prefix <= 99) - return std::string(); + return {}; // 00001-00009 US prefix = std::stoi(GTIN.substr(first, 5 - implicitZero)); @@ -193,7 +193,7 @@ std::string LookupCountryIdentifier(const std::string& GTIN, const BarcodeFormat // Special case EAN-8 for prefix < 100 (GS1 General Specifications Figure 1.4.3-1) if (size == 8 && format == BarcodeFormat::EAN8 && prefix <= 99) // Restricted Circulation Numbers - return std::string(); + return {}; const auto it = std::lower_bound(std::begin(COUNTRIES), std::end(COUNTRIES), CountryId{0, prefix, nullptr}); diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp index 3a669a049f..444ecf4982 100644 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp +++ b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp @@ -117,7 +117,7 @@ static std::string DecodeAnyAI(const BitArray& bits) if (StatusIsOK(DecodeAppIdAllCodes(bits, HEADER_SIZE, -1, buffer))) { return buffer; } - return std::string(); + return {}; } static std::string DecodeAI013103(const BitArray& bits) @@ -126,7 +126,7 @@ static std::string DecodeAI013103(const BitArray& bits) static const int WEIGHT_SIZE = 15; if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) { - return std::string(); + return {}; } std::string buffer; @@ -146,7 +146,7 @@ static std::string DecodeAI01320x(const BitArray& bits) static const int WEIGHT_SIZE = 15; if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) { - return std::string(); + return {}; } std::string buffer; @@ -167,7 +167,7 @@ static std::string DecodeAI01392x(const BitArray& bits) static const int LAST_DIGIT_SIZE = 2; if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) { - return std::string(); + return {}; } std::string buffer; @@ -184,7 +184,7 @@ static std::string DecodeAI01392x(const BitArray& bits) && StatusIsOK(DecodeAppIdAllCodes(bits, pos, remainingValue, buffer))) { return buffer; } - return std::string(); + return {}; } static std::string DecodeAI01393x(const BitArray& bits) @@ -194,7 +194,7 @@ static std::string DecodeAI01393x(const BitArray& bits) static const int FIRST_THREE_DIGITS_SIZE = 10; if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) { - return std::string(); + return {}; } std::string buffer; @@ -221,7 +221,7 @@ static std::string DecodeAI01393x(const BitArray& bits) && StatusIsOK(DecodeAppIdAllCodes(bits, pos, remainingValue, buffer))) { return buffer; } - return std::string(); + return {}; } static std::string DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdigits, const char* dateCode) @@ -231,7 +231,7 @@ static std::string DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdig static const int DATE_SIZE = 16; if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE) { - return std::string(); + return {}; } std::string buffer; @@ -313,7 +313,7 @@ std::string DecodeExpandedBits(const BitArray& bits) case 63: return DecodeAI013x0x1x(bits, "320", "17"); } - return std::string(); + return {}; //throw new IllegalStateException("unknown decoder: " + information); } diff --git a/test/unit/BarcodeFormatTest.cpp b/test/unit/BarcodeFormatTest.cpp index 7dfcbf3ab8..9413314067 100644 --- a/test/unit/BarcodeFormatTest.cpp +++ b/test/unit/BarcodeFormatTest.cpp @@ -13,9 +13,11 @@ using namespace ZXing; TEST(BarcodeFormatTest, BarcodeFormat) { - EXPECT_EQ(ToString(BarcodeFormat::QRCode), std::string("QRCode")); - EXPECT_EQ(ToString(BarcodeFormat::None), std::string("None")); - EXPECT_EQ(ToString(BarcodeFormat::DataMatrix | BarcodeFormat::EAN13), std::string("DataMatrix|EAN-13")); + using namespace std::literals; + + EXPECT_EQ(ToString(BarcodeFormat::QRCode), "QRCode"s); + EXPECT_EQ(ToString(BarcodeFormat::None), "None"s); + EXPECT_EQ(ToString(BarcodeFormat::DataMatrix | BarcodeFormat::EAN13), "DataMatrix|EAN-13"); EXPECT_EQ(BarcodeFormat::EAN8, BarcodeFormatFromString("EAN_8")); EXPECT_EQ(BarcodeFormat::EAN8, BarcodeFormatFromString("EAN-8")); diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index 5e695e7c68..3495bc3b7e 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -25,14 +25,14 @@ TEST(CharacterSetECITest, Charset2ECI) TEST(CharacterSetECITest, InitEncoding) { - EXPECT_EQ(InitEncoding(std::string()), CharacterSet::ISO8859_1); - EXPECT_EQ(InitEncoding(std::string(), CharacterSet::ISO8859_2), CharacterSet::ISO8859_2); - EXPECT_EQ(InitEncoding(std::string("asdfasdf")), CharacterSet::ISO8859_1); - EXPECT_EQ(InitEncoding(std::string("asdfasdf"), CharacterSet::ISO8859_2), CharacterSet::ISO8859_2); - EXPECT_EQ(InitEncoding(std::string("ISO-8859-1")), CharacterSet::ISO8859_1); - EXPECT_EQ(InitEncoding(std::string("ISO-8859-2")), CharacterSet::ISO8859_2); - EXPECT_EQ(InitEncoding(std::string("UTF-16BE")), CharacterSet::UnicodeBig); - EXPECT_EQ(InitEncoding(std::string(), CharacterSet::Unknown), CharacterSet::Unknown); + EXPECT_EQ(InitEncoding(""), CharacterSet::ISO8859_1); + EXPECT_EQ(InitEncoding("", CharacterSet::ISO8859_2), CharacterSet::ISO8859_2); + EXPECT_EQ(InitEncoding("asdfasdf"), CharacterSet::ISO8859_1); + EXPECT_EQ(InitEncoding("asdfasdf", CharacterSet::ISO8859_2), CharacterSet::ISO8859_2); + EXPECT_EQ(InitEncoding("ISO-8859-1"), CharacterSet::ISO8859_1); + EXPECT_EQ(InitEncoding("ISO-8859-2"), CharacterSet::ISO8859_2); + EXPECT_EQ(InitEncoding("UTF-16BE"), CharacterSet::UnicodeBig); + EXPECT_EQ(InitEncoding("", CharacterSet::Unknown), CharacterSet::Unknown); } TEST(CharacterSetECITest, OnChangeAppendReset) From d47ddec0745d71df7cc7abb58df1843febdf0a33 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 25 May 2022 13:35:24 +0200 Subject: [PATCH 0231/1315] ECI: replace all non-ECI entries on first ECI entry with default ECI This implements the spec in line 'd' in the table in https://github.com/zxing/zxing/pull/1498#issuecomment-1134578616 --- core/src/Content.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index c17a4d12ca..c38e9c8b1e 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -26,7 +26,9 @@ void Content::ForEachECIBlock(FUNC func) const void Content::switchEncoding(ECI eci, bool isECI) { - // TODO: replace non-ECI entries on first ECI entry with default ECI + // replace all non-ECI entries on first ECI entry with default ECI + if (isECI && !hasECI) + encodings = {{ECI::ISO8859_1, 0}}; if (isECI || !hasECI) { if (encodings.back().pos == Size(binary)) encodings.back().eci = eci; // no point in recording 0 length segments From 24deab4ff17ca58e109f58bc818429697f85284a Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 27 May 2022 08:51:49 +0200 Subject: [PATCH 0232/1315] example: use std::ios::boolalpha --- example/ZXingReader.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index f4ca2d427f..576152408d 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -135,6 +135,8 @@ int main(int argc, char* argv[]) if (angleEscape) std::setlocale(LC_CTYPE, "en_US.UTF-8"); // Needed so `std::iswgraph()` in `ToUtf8(angleEscape)` does not 'swallow' all printable non-ascii utf8 chars + std::cout.setf(std::ios::boolalpha); + for (const auto& filePath : filePaths) { int width, height, channels; std::unique_ptr buffer(stbi_load(filePath.c_str(), &width, &height, &channels, 3), stbi_image_free); @@ -187,7 +189,7 @@ int main(int argc, char* argv[]) << "Identifier: " << result.symbologyIdentifier() << "\n" << "Position: " << result.position() << "\n" << "Rotation: " << result.orientation() << " deg\n" - << "IsMirrored: " << (result.isMirrored() ? "true" : "false") << "\n" + << "IsMirrored: " << result.isMirrored() << "\n" << "Error: " << ToString(result.status()) << "\n"; auto printOptional = [](const char* key, const std::string& v) { From a56ade3d3630da558771fb55a9aac1342ded7749 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 27 May 2022 08:55:55 +0200 Subject: [PATCH 0233/1315] Result: move ECI encoding specification for 1D codes to Content --- core/src/Content.h | 2 +- core/src/Result.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/Content.h b/core/src/Content.h index 7b7dce5af1..cc671025c2 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -34,7 +34,7 @@ class Content std::string applicationIndicator; Content() = default; - Content(ByteArray&& binary, ECI defaultECI) : binary(binary), encodings{{defaultECI, 0}} {} + Content(ByteArray&& binary) : binary(std::move(binary)), encodings{{ECI::ISO8859_1, 0}} {} void switchEncoding(ECI eci) { switchEncoding(eci, true); } void switchEncoding(CharacterSet cs); diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 13ae8f663d..10b4a52731 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -18,7 +18,7 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor std::string&& symbologyIdentifier, ByteArray&& rawBytes, const bool readerInit) : _format(format), - _content({ByteArray(text), ECI::ISO8859_1}), + _content({ByteArray(text)}), _text(TextDecoder::FromLatin1(text)), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), From 096f44a47ecb920239bdb8b00f7c25e95e1b9ae3 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 27 May 2022 09:27:46 +0200 Subject: [PATCH 0234/1315] ECI: new SymbologyIdentifier class to support ECI protocol modifiers Not yet implemented for PDF417, Aztec and Maxicode --- core/src/Content.cpp | 8 +++++++- core/src/Content.h | 17 +++++++++++++++-- core/src/DecoderResult.h | 2 ++ core/src/Result.cpp | 4 ++-- core/src/Result.h | 2 +- core/src/datamatrix/DMDecoder.cpp | 11 ++++------- core/src/oned/ODCodabarReader.cpp | 4 ++-- core/src/oned/ODCode128Reader.cpp | 8 ++++---- core/src/oned/ODCode39Reader.cpp | 8 +++----- core/src/oned/ODCode93Reader.cpp | 4 ++-- core/src/oned/ODITFReader.cpp | 6 +++--- core/src/oned/ODMultiUPCEANReader.cpp | 6 +++--- core/src/qrcode/QRDecoder.cpp | 9 +++------ 13 files changed, 51 insertions(+), 38 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index c38e9c8b1e..f4c3a20f10 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -12,6 +12,12 @@ namespace ZXing { +std::string ToString(ContentType type) +{ + const char* t2s[] = {"Text", "Binary", "Mixed"}; + return t2s[static_cast(type)]; +} + template void Content::ForEachECIBlock(FUNC func) const { @@ -60,7 +66,7 @@ std::wstring Content::text() const std::string Content::utf8Protocol() const { - std::wstring res; + std::wstring res = TextDecoder::FromLatin1(symbology.toString(true)); ECI lastECI = ECI::Unknown; auto fallbackCS = guessEncoding(); diff --git a/core/src/Content.h b/core/src/Content.h index cc671025c2..5e48f35406 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -12,10 +12,21 @@ namespace ZXing { enum class ContentType { Text, Binary, Mixed }; -class Content +std::string ToString(ContentType type); + +struct SymbologyIdentifier { - bool hasECI = false; + char code, modifier; + int eciModifierOffset = 0; + std::string toString(bool hasECI = false) const + { + return ']' + std::string(1, code) + static_cast(modifier + eciModifierOffset * hasECI); + } +}; + +class Content +{ template void ForEachECIBlock(FUNC f) const; @@ -32,6 +43,8 @@ class Content std::vector encodings = {{ECI::Unknown, 0}}; std::string hintedCharset; std::string applicationIndicator; + SymbologyIdentifier symbology; + bool hasECI = false; Content() = default; Content(ByteArray&& binary) : binary(std::move(binary)), encodings{{ECI::ISO8859_1, 0}} {} diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 6f768cc8ec..8714396f29 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -58,6 +58,8 @@ class DecoderResult // provide some best guess fallback for barcodes not, yet supporting the content info if (_content.empty() && std::all_of(_text.begin(), _text.end(), [](auto c) { return c < 256; })) std::for_each(_text.begin(), _text.end(), [this](wchar_t c) { _content += static_cast(c); }); + if (_content.symbology.code != 0) + _symbologyIdentifier = _content.symbology.toString(); } DecoderResult() = default; diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 10b4a52731..9d3c417868 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -15,7 +15,7 @@ namespace ZXing { Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, - std::string&& symbologyIdentifier, ByteArray&& rawBytes, const bool readerInit) + SymbologyIdentifier si, ByteArray&& rawBytes, const bool readerInit) : _format(format), _content({ByteArray(text)}), @@ -23,7 +23,7 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), _numBits(Size(_rawBytes) * 8), - _symbologyIdentifier(std::move(symbologyIdentifier)), + _symbologyIdentifier(si.toString()), _readerInit(readerInit), _lineCount(0) {} diff --git a/core/src/Result.h b/core/src/Result.h index c869e188c9..bdf767e30b 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -35,7 +35,7 @@ class Result // 1D convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, - std::string&& symbologyIdentifier = "", ByteArray&& rawBytes = {}, const bool readerInit = false); + SymbologyIdentifier si, ByteArray&& rawBytes = {}, const bool readerInit = false); Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index af58169cbf..87286c8300 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -277,10 +277,10 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b { BitSource bits(bytes); Content result; + result.symbology = {'d', '1', 3}; // ECC 200 (ISO 16022:2006 Annex N Table N.1) result.hintedCharset = characterSet; std::string resultTrailer; - int symbologyIdModifier = 1; // ECC 200 (ISO 16022:2006 Annex N Table N.1) struct StructuredAppendInfo sai; bool readerInit = false; bool firstCodeword = true; @@ -298,16 +298,13 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b case 230: DecodeC40OrTextSegment(bits, result, Mode::C40); break; case 231: DecodeBase256Segment(bits, result); break; case 232: // FNC1 - // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using - // modifiers that indicate ECI protocol (ISO 16022:2006 Annex N Table N.1, ISO 21471:2020 Annex G Table G.1) - // Only recognizing an FNC1 as first/second by codeword position (aka symbol character position), not // by decoded character position, i.e. not recognizing a C40/Text encoded FNC1 (which requires a latch // and a shift) if (bits.byteOffset() == firstFNC1Position) - symbologyIdModifier = 2; // GS1 + result.symbology.modifier = '2'; // GS1 else if (bits.byteOffset() == firstFNC1Position + 1) - symbologyIdModifier = 3; // AIM, note no AIM Application Indicator format defined, ISO 16022:2006 11.2 + result.symbology.modifier = '3'; // AIM, note no AIM Application Indicator format defined, ISO 16022:2006 11.2 else result.push_back((char)29); // translate as ASCII 29 break; @@ -360,9 +357,9 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b } result.append(resultTrailer); + result.symbology.modifier += isDMRE * 6; return DecoderResult(std::move(bytes), {}, std::move(result)) - .setSymbologyIdentifier("]d" + std::to_string(symbologyIdModifier + (isDMRE ? 6 : 0))) .setStructuredAppend(sai) .setReaderInit(readerInit); } diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index 53d8dec94b..0ebec78088 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -94,10 +94,10 @@ CodabarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr= 'a' && txt[0] <= 'z')))) { // ISO/IEC 15417:2007 Annex B.2 // FNC1 in second position following Code Set C "00-99" or Code Set A/B "A-Za-z" - AIM - _symbologyIdentifier = "]C2"; + _symbologyIdentifier.modifier = '2'; } else { // ISO/IEC 15417:2007 Annex B.3. Otherwise FNC1 is returned as ASCII 29 (GS) @@ -153,7 +153,7 @@ class Raw2TxtDecoder return txt.substr(0, lastTxtSize); } - std::string symbologyIdentifier() const { return _symbologyIdentifier; } + SymbologyIdentifier symbologyIdentifier() const { return _symbologyIdentifier; } bool readerInit() const { return _readerInit; } }; diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index 3952025a4f..caf4d76f18 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -133,13 +133,11 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique return Result(DecodeStatus::FormatError); // Symbology identifier modifiers ISO/IEC 16388:2007 Annex C Table C.1 - static const int symbologyModifiers[4] = { 0, 3 /*checksum*/, 4 /*extended*/, 7 /*checksum,extended*/ }; - int symbologyIdModifier = symbologyModifiers[(int)_extendedMode * 2 + (int)_validateCheckSum]; - - std::string symbologyIdentifier("]A" + std::to_string(symbologyIdModifier)); + constexpr const char symbologyModifiers[4] = { '0', '3' /*checksum*/, '4' /*extended*/, '7' /*checksum,extended*/ }; + SymbologyIdentifier symbologyIdentifier = {'A', symbologyModifiers[(int)_extendedMode * 2 + (int)_validateCheckSum]}; int xStop = next.pixelsTillEnd(); - return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::Code39, std::move(symbologyIdentifier)); + return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::Code39, symbologyIdentifier); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index 484308aafc..7b3552d519 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -124,10 +124,10 @@ Result Code93Reader::decodePattern(int rowNumber, PatternView& next, std::unique return Result(DecodeStatus::FormatError); // Symbology identifier ISO/IEC 15424:2008 4.4.10 no modifiers - std::string symbologyIdentifier("]G0"); + SymbologyIdentifier symbologyIdentifier = {'G', '0'}; int xStop = next.pixelsTillEnd(); - return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::Code93, std::move(symbologyIdentifier)); + return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::Code93, symbologyIdentifier); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 704cc7bfaa..3de5d5206c 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -81,13 +81,13 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt // Symbology identifier ISO/IEC 16390:2007 Annex C Table C.1 // See also GS1 General Specifications 5.1.3 Figure 5.1.3-2 - std::string symbologyIdentifier("]I0"); // No check character validation + SymbologyIdentifier symbologyIdentifier = {'I', '0'}; // No check character validation if (_validateCheckSum || (txt.size() == 14 && GTIN::IsCheckDigitValid(txt))) // If no hint test if valid ITF-14 - symbologyIdentifier = "]I1"; // Modulo 10 symbol check character validated and transmitted + symbologyIdentifier.modifier = '1'; // Modulo 10 symbol check character validated and transmitted int xStop = next.pixelsTillEnd(); - return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::ITF, std::move(symbologyIdentifier)); + return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::ITF, symbologyIdentifier); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index cfa806ea17..92b59d379a 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -289,7 +289,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u // Symbology identifier modifiers ISO/IEC 15420:2009 Annex B Table B.1 // ISO/IEC 15420:2009 (& GS1 General Specifications 5.1.3) states that the content for "]E0" should be 13 digits, // i.e. converted to EAN-13 if UPC-A/E, but not doing this here to maintain backward compatibility - std::string symbologyIdentifier(res.format == BarcodeFormat::EAN8 ? "]E4" : "]E0"); + SymbologyIdentifier symbologyIdentifier = {'E', res.format == BarcodeFormat::EAN8 ? '4' : '0'}; auto ext = res.end; PartialResult addOnRes; @@ -301,7 +301,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u res.txt += " " + addOnRes.txt; if (res.format != BarcodeFormat::EAN8) // Keeping EAN-8 with add-on as "]E4" - symbologyIdentifier = "]E3"; // Combined packet, EAN-13, UPC-A, UPC-E, with add-on + symbologyIdentifier.modifier = '3'; // Combined packet, EAN-13, UPC-A, UPC-E, with add-on } next = res.end; @@ -309,7 +309,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u if (_hints.eanAddOnSymbol() == EanAddOnSymbol::Require && !addOnRes.isValid()) return Result(DecodeStatus::NotFound); - return {res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, std::move(symbologyIdentifier)}; + return {res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, symbologyIdentifier}; } } // namespace ZXing::OneD diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index ad0b2b27fb..a5b2c579dd 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -259,8 +259,8 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo { BitSource bits(bytes); Content result; + result.symbology = {'Q', '1', 1}; result.hintedCharset = hintedCharset.empty() ? "Auto" : hintedCharset; - int symbologyIdModifier = 1; // ISO/IEC 18004:2015 Annex F Table F.1 StructuredAppendInfo structuredAppend; const int modeBitLength = CodecModeBitsLength(version); @@ -277,15 +277,13 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo case CodecMode::FNC1_FIRST_POSITION: // if (!result.empty()) // uncomment to enforce specification // throw std::runtime_error("GS1 Indicator (FNC1 in first position) at illegal position"); - // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using - // modifiers that indicate ECI protocol (ISO/IEC 18004:2015 Annex F Table F.1) - symbologyIdModifier = 3; + result.symbology.modifier = '3'; result.applicationIndicator = "GS1"; // In Alphanumeric mode undouble doubled percents and treat single percent as break; case CodecMode::FNC1_SECOND_POSITION: if (!result.empty()) throw std::runtime_error("AIM Application Indicator (FNC1 in second position) at illegal position"); - symbologyIdModifier = 5; // As above + result.symbology.modifier = '5'; // As above // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position), "00-99" or "A-Za-z" if (int appInd = bits.readBits(8); appInd < 10) // "00-09" result += '0' + std::to_string(appInd); @@ -343,7 +341,6 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo return DecoderResult(std::move(bytes), {}, std::move(result)) .setEcLevel(ToString(ecLevel)) - .setSymbologyIdentifier("]Q" + std::to_string(symbologyIdModifier)) .setStructuredAppend(structuredAppend); } From 2c01b06015bb9c2ef0cac5483f70d3b5e909f8d9 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 27 May 2022 09:38:39 +0200 Subject: [PATCH 0235/1315] ECI: remove dead code --- core/src/oned/ODDataBarExpandedReader.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 95832f52de..42fed5a6fa 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -373,13 +373,10 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, RemovePairs(allPairs, pairs); - // Symbology identifier ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - std::string symbologyIdentifier("]e0"); - // TODO: EstimatePosition misses part of the symbol in the stacked case where the last row contains less pairs than // the first return {DecoderResult({}, TextDecoder::FromLatin1(txt)) - .setSymbologyIdentifier("]e0") + .setSymbologyIdentifier("]e0") // ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 .setLineCount(EstimateLineCount(pairs.front(), pairs.back())), EstimatePosition(pairs.front(), pairs.back()), BarcodeFormat::DataBarExpanded}; } From f7cfbbb4a5e420f3a4b5c2d523a49d098809182d Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 27 May 2022 09:40:01 +0200 Subject: [PATCH 0236/1315] Result: add contentType and hasECI properties (experimental) --- core/src/Result.h | 5 ++++- example/ZXingReader.cpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/Result.h b/core/src/Result.h index bdf767e30b..ffa319a9c7 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -50,7 +50,10 @@ class Result // WARNING: this is an experimental API and may change/disappear const ByteArray& binary() const { return _content.binary; } const std::string utf8Protocol() const { return _content.utf8Protocol(); } - const std::string applicationIndicator() const { return _content.applicationIndicator; } + const std::string& applicationIndicator() const { return _content.applicationIndicator; } + ContentType contentType() const { return _content.type(); } + bool hasECI() const { return _content.hasECI; } + // END WARNING const Position& position() const { return _position; } void setPosition(Position pos) { _position = pos; } diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 576152408d..a368169e40 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -187,6 +187,8 @@ int main(int argc, char* argv[]) << "ECI-Proto: \"" << result.utf8Protocol() << "\"\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" + << "Content: " << ToString(result.contentType()) << "\n" + << "HasECI: " << result.hasECI() << "\n" << "Position: " << result.position() << "\n" << "Rotation: " << result.orientation() << " deg\n" << "IsMirrored: " << result.isMirrored() << "\n" From cd09da36f299f143415aaafa68bb9aca69122fb0 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 27 May 2022 12:39:45 +0200 Subject: [PATCH 0237/1315] ECI: tune ContentType deduction --- core/src/Content.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index f4c3a20f10..771459b6b8 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -117,15 +117,15 @@ ContentType Content::type() const { auto isBinary = [](Encoding e) { return !IsText(e.eci); }; - if (hasECI) { - if (std::none_of(encodings.begin(), encodings.end(), isBinary)) - return ContentType::Text; - if (std::all_of(encodings.begin(), encodings.end(), isBinary)) - return ContentType::Binary; - } else { - if (std::none_of(encodings.begin(), encodings.end(), isBinary)) - return ContentType::Text; + if (std::none_of(encodings.begin(), encodings.end(), isBinary)) + return ContentType::Text; + if (std::all_of(encodings.begin(), encodings.end(), isBinary)) + return ContentType::Binary; + + if (!hasECI) { auto cs = guessEncoding(); + if (IsText(ToECI(cs))) + return ContentType::Text; if (cs == CharacterSet::BINARY) return ContentType::Binary; } From 14cb929a4cb2bcb9e1aa0c3507d7184d1ce5782a Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 28 May 2022 17:32:58 +0200 Subject: [PATCH 0238/1315] ECI: add `binaryECI` channel to `Result` Still a WIP. See https://github.com/nu-book/zxing-cpp/issues/334#issuecomment-1140271102 --- core/src/Content.cpp | 19 +++++++++++++++++++ core/src/Content.h | 1 + core/src/Result.h | 1 + example/ZXingReader.cpp | 3 ++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 771459b6b8..1a505dfa7e 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -98,6 +98,25 @@ std::string Content::utf8Protocol() const return TextUtfEncoding::ToUtf8(res); } +ByteArray Content::binaryECI() const +{ + std::string res = symbology.toString(true); + + ForEachECIBlock([&](ECI eci, int begin, int end) { + if (hasECI) + res += ToString(eci); + + for (int i = begin; i != end; ++i) { + char c = static_cast(binary[i]); + res += c; + if (c == '\\') // in the ECI protocol a '\' has to be doubled + res += c; + } + }); + + return ByteArray(res); +} + CharacterSet Content::guessEncoding() const { // assemble all blocks with unknown encoding diff --git a/core/src/Content.h b/core/src/Content.h index 5e48f35406..abb8bc873b 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -65,6 +65,7 @@ class Content std::wstring text() const; std::string utf8Protocol() const; + ByteArray binaryECI() const; CharacterSet guessEncoding() const; ContentType type() const; }; diff --git a/core/src/Result.h b/core/src/Result.h index ffa319a9c7..f13afcc233 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -49,6 +49,7 @@ class Result // WARNING: this is an experimental API and may change/disappear const ByteArray& binary() const { return _content.binary; } + const ByteArray binaryECI() const { return _content.binaryECI(); } const std::string utf8Protocol() const { return _content.utf8Protocol(); } const std::string& applicationIndicator() const { return _content.applicationIndicator; } ContentType contentType() const { return _content.type(); } diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index a368169e40..9baf5961f8 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -184,7 +184,8 @@ int main(int argc, char* argv[]) } std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" << "Binary: \"" << ToHex(result.binary()) << "\"\n" - << "ECI-Proto: \"" << result.utf8Protocol() << "\"\n" + << "TextECI: \"" << result.utf8Protocol() << "\"\n" + << "BinaryECI: \"" << ToHex(result.binaryECI()) << "\"\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" << "Content: " << ToString(result.contentType()) << "\n" From e339392e8c759272d7aa9e19d14cab920cf52916 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 29 May 2022 05:20:12 +0200 Subject: [PATCH 0239/1315] AZDecoder: fail on illegally truncated message and simplify bounds checks --- core/src/BitArray.h | 6 ++++- core/src/aztec/AZDecoder.cpp | 43 ++++++++++++++---------------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/core/src/BitArray.h b/core/src/BitArray.h index b2164da1cb..91d60a8b5e 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -365,8 +366,11 @@ int ToInt(const ARRAY& a) inline int ReadBits(BitArray::Range& bits, int n) { + assert(n <= 32); + if (n > bits.size()) + throw std::out_of_range("ReadBits(BitArray::Range&) out of range."); int res = 0; - for (; n > 0 && bits.size(); --n, bits.begin++) + for (; n > 0; --n, bits.begin++) AppendBit(res, *bits.begin); return res; } diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 9027a677e1..fa549e3be4 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -286,30 +286,17 @@ AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet) bool haveFNC1 = false; auto remBits = bits.range(); - while (remBits) { + while (remBits.size() >= (shiftTable == Table::DIGIT ? 4 : 5)) { // see ISO/IEC 24778:2008 7.3.1.2 regarding padding bits if (shiftTable == Table::BINARY) { - if (remBits.size() < 5) - break; int length = ReadBits(remBits, 5); - if (length == 0) { - if (remBits.size() < 11) - break; + if (length == 0) length = ReadBits(remBits, 11) + 31; - } - for (int charCount = 0; charCount < length; charCount++) { - if (remBits.size() < 8) { - remBits.begin = remBits.end; // Force outer loop to exit - break; - } - int code = ReadBits(remBits, 8); - text.push_back((char)code); - } + for (int i = 0; i < length; i++) + text.push_back(static_cast(ReadBits(remBits, 8))); // Go back to whatever mode we had been in shiftTable = latchTable; } else { int size = shiftTable == Table::DIGIT ? 4 : 5; - if (remBits.size() < size) - break; int code = ReadBits(remBits, size); const char* str = GetCharacter(shiftTable, code); if (std::strncmp(str, "CTRL_", 5) == 0) { @@ -322,8 +309,6 @@ AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet) if (str[6] == 'L') latchTable = shiftTable; } else if (std::strcmp(str, "FLGN") == 0) { - if (remBits.size() < 3) - break; int flg = ReadBits(remBits, 3); if (flg == 0) { // FNC1 haveFNC1 = true; // Will process first/second FNC1 at end after any Structured Append @@ -382,15 +367,19 @@ DecoderResult Decode(const DetectorResult& detectorResult, const std::string& ch if (!bits.size()) return DecodeStatus::FormatError; - auto data = GetEncodedData(bits, characterSet); - if (data.text.empty()) + try { + auto data = GetEncodedData(bits, characterSet); + if (data.text.empty()) + return DecodeStatus::FormatError; + + return DecoderResult(bits.toBytes(), std::move(data.text)) + .setNumBits(Size(bits)) + .setSymbologyIdentifier(std::move(data.symbologyIdentifier)) + .setStructuredAppend(data.sai) + .setReaderInit(detectorResult.readerInit()); + } catch (const std::out_of_range&) { // see ReadBits() return DecodeStatus::FormatError; - - return DecoderResult(bits.toBytes(), std::move(data.text)) - .setNumBits(Size(bits)) - .setSymbologyIdentifier(std::move(data.symbologyIdentifier)) - .setStructuredAppend(data.sai) - .setReaderInit(detectorResult.readerInit()); + } } } // namespace ZXing::Aztec From 6312ca9e62b29e3a54623e723f9b239180dfd285 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 30 May 2022 10:14:34 +0200 Subject: [PATCH 0240/1315] style: trivial whitespace fix --- core/src/Content.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 1a505dfa7e..fb3a81424b 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -46,7 +46,7 @@ void Content::switchEncoding(ECI eci, bool isECI) void Content::switchEncoding(CharacterSet cs) { - switchEncoding(ToECI(cs), false); + switchEncoding(ToECI(cs), false); } std::wstring Content::text() const From a7f4722fd7dbb503156246ce2eb73535459b3f44 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 30 May 2022 10:18:58 +0200 Subject: [PATCH 0241/1315] ECI: transformative ECIs are not supported -> return empty `text` see https://github.com/nu-book/zxing-cpp/commit/d8587545434d533c4e568181e1c12ef04a8e42d9#r74864359 Switch 2 test samples from text to binary. --- core/src/Content.cpp | 11 +++++++++++ core/src/Content.h | 1 + core/src/ECI.h | 6 ++++++ test/samples/aztec-1/mixed-ecis-41x41.bin | Bin 0 -> 29 bytes test/samples/aztec-1/mixed-ecis-41x41.txt | 1 - test/samples/datamatrix-1/eci-mixed.bin | 1 + test/samples/datamatrix-1/eci-mixed.txt | 1 - 7 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 test/samples/aztec-1/mixed-ecis-41x41.bin delete mode 100644 test/samples/aztec-1/mixed-ecis-41x41.txt create mode 100644 test/samples/datamatrix-1/eci-mixed.bin delete mode 100644 test/samples/datamatrix-1/eci-mixed.txt diff --git a/core/src/Content.cpp b/core/src/Content.cpp index fb3a81424b..96f12e491d 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -49,8 +49,16 @@ void Content::switchEncoding(CharacterSet cs) switchEncoding(ToECI(cs), false); } +bool Content::canProcess() const +{ + return std::all_of(encodings.begin(), encodings.end(), [](Encoding e) { return CanProcess(e.eci); }); +} + std::wstring Content::text() const { + if (!canProcess()) + return {}; + auto fallbackCS = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); if (!hasECI && fallbackCS == CharacterSet::Unknown) fallbackCS = guessEncoding(); @@ -66,6 +74,9 @@ std::wstring Content::text() const std::string Content::utf8Protocol() const { + if (!canProcess()) + return {}; + std::wstring res = TextDecoder::FromLatin1(symbology.toString(true)); ECI lastECI = ECI::Unknown; auto fallbackCS = guessEncoding(); diff --git a/core/src/Content.h b/core/src/Content.h index abb8bc873b..e856393ba8 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -62,6 +62,7 @@ class Content void operator+=(const std::string& str) { append(str); } bool empty() const { return binary.empty(); } + bool canProcess() const; std::wstring text() const; std::string utf8Protocol() const; diff --git a/core/src/ECI.h b/core/src/ECI.h index ac2f65dfb8..bb780324b0 100644 --- a/core/src/ECI.h +++ b/core/src/ECI.h @@ -53,6 +53,12 @@ inline constexpr bool IsText(ECI eci) return ToInt(eci) >= 0 && ToInt(eci) <= 32; } +inline constexpr bool CanProcess(ECI eci) +{ + // see https://github.com/nu-book/zxing-cpp/commit/d8587545434d533c4e568181e1c12ef04a8e42d9#r74864359 + return ToInt(eci) <= 899; +} + /** * @brief ToString converts the numerical ECI value to a 7 character string as used in the ECI protocol * @return e.g. "\000020" diff --git a/test/samples/aztec-1/mixed-ecis-41x41.bin b/test/samples/aztec-1/mixed-ecis-41x41.bin new file mode 100644 index 0000000000000000000000000000000000000000..a51ee9f519ddaff94183407aa032013c7c33fb28 GIT binary patch literal 29 kcmaF35Coc2C&x1^{4k+s+s~^%7rxxEaKobS{}wI+026%^Z~y=R literal 0 HcmV?d00001 diff --git a/test/samples/aztec-1/mixed-ecis-41x41.txt b/test/samples/aztec-1/mixed-ecis-41x41.txt deleted file mode 100644 index 6c534d58d7..0000000000 --- a/test/samples/aztec-1/mixed-ecis-41x41.txt +++ /dev/null @@ -1 +0,0 @@ -á¡ĦЁ‘Ąテ点¡𐌶龘龤é가각齄،¢ \ No newline at end of file diff --git a/test/samples/datamatrix-1/eci-mixed.bin b/test/samples/datamatrix-1/eci-mixed.bin new file mode 100644 index 0000000000..7f4b77e09b --- /dev/null +++ b/test/samples/datamatrix-1/eci-mixed.bin @@ -0,0 +1 @@ +ᡡͱ𐌶@@@@@@@@@@_ \ No newline at end of file diff --git a/test/samples/datamatrix-1/eci-mixed.txt b/test/samples/datamatrix-1/eci-mixed.txt deleted file mode 100644 index 18e1efa017..0000000000 --- a/test/samples/datamatrix-1/eci-mixed.txt +++ /dev/null @@ -1 +0,0 @@ -á¡¡ĦĦͱ𐌶@@@@@@@@@@_ \ No newline at end of file From a9f5f078bd93e4c64acb84ae3e684444306852ea Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 30 May 2022 11:47:13 +0200 Subject: [PATCH 0242/1315] ECI: switch AZDecoder to new Content class There are a couple open questions/ToDos regarding the handling of symbology identifier, structured append and AIM data. --- core/src/Content.cpp | 8 ++ core/src/Content.h | 2 + core/src/aztec/AZDecoder.cpp | 146 +++++++++------------ test/unit/aztec/AZDecoderTest.cpp | 105 +++++++-------- test/unit/aztec/AZEncodeDecodeTest.cpp | 5 +- test/unit/aztec/AZHighLevelEncoderTest.cpp | 16 +-- 6 files changed, 127 insertions(+), 155 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 96f12e491d..12e560cf1d 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -49,6 +49,14 @@ void Content::switchEncoding(CharacterSet cs) switchEncoding(ToECI(cs), false); } +void Content::erase(int pos, int n) +{ + binary.erase(binary.begin() + pos, binary.begin() + pos + n); + for (auto& e : encodings) + if (e.pos > pos) + pos -= n; +} + bool Content::canProcess() const { return std::all_of(encodings.begin(), encodings.end(), [](Encoding e) { return CanProcess(e.eci); }); diff --git a/core/src/Content.h b/core/src/Content.h index e856393ba8..33e7991ba2 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -61,6 +61,8 @@ class Content void operator+=(char val) { push_back(val); } void operator+=(const std::string& str) { append(str); } + void erase(int pos, int n); + bool empty() const { return binary.empty(); } bool canProcess() const; diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index fa549e3be4..6c295a6593 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -1,6 +1,7 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 @@ -9,21 +10,17 @@ #include "AZDetectorResult.h" #include "BitArray.h" #include "BitMatrix.h" -#include "CharacterSetECI.h" +#include "CharacterSet.h" #include "DecodeStatus.h" #include "DecoderResult.h" #include "GenericGF.h" #include "ReedSolomonDecoder.h" -#include "TextDecoder.h" -#include "TextUtfEncoding.h" #include "ZXTestSupport.h" -#include -#include -#include #include #include #include +#include #include namespace ZXing::Aztec { @@ -215,20 +212,21 @@ static const char* GetCharacter(Table table, int code) /** * See ISO/IEC 24778:2008 Section 10.1 */ -static int ParseECIValue(BitArray::Range& bits, const int flg) +static ECI ParseECIValue(BitArray::Range& bits, const int flg) { int eci = 0; - for (int i = 0; i < flg && bits.size() >= 4; i++) + for (int i = 0; i < flg; i++) eci = 10 * eci + ReadBits(bits, 4) - 2; - return eci; + return ECI(eci); } /** * See ISO/IEC 24778:2008 Section 8 */ -static StructuredAppendInfo ParseStructuredAppend(std::wstring& text) +static StructuredAppendInfo ParseStructuredAppend(ByteArray& binary) { - std::wstring id; + std::string text(binary.begin(), binary.end()); + StructuredAppendInfo sai; std::string::size_type i = 0; if (text[0] == ' ') { // Space-delimited id @@ -236,54 +234,29 @@ static StructuredAppendInfo ParseStructuredAppend(std::wstring& text) if (sp == std::string::npos) return {}; - id = text.substr(1, sp - 1); // Strip space delimiters + sai.id = text.substr(1, sp - 1); // Strip space delimiters i = sp + 1; } if (i + 1 >= text.size() || !std::isupper(text[i]) || !std::isupper(text[i + 1])) return {}; - StructuredAppendInfo sai; sai.index = text[i] - 'A'; sai.count = text[i + 1] - 'A' + 1; if (sai.count == 1 || sai.count <= sai.index) // If info doesn't make sense sai.count = 0; // Choose to mark count as unknown - if (!id.empty()) - TextUtfEncoding::ToUtf8(id, sai.id); - text.erase(0, i + 2); // Remove + binary = ByteArray(text); return sai; } -struct AztecData -{ - std::wstring text; - std::string symbologyIdentifier; - StructuredAppendInfo sai; -}; - -/** -* Gets the string encoded in the aztec code bits -* -* @return the decoded string -*/ -ZXING_EXPORT_TEST_ONLY -AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet) +static void DecodeContent(const BitArray& bits, Content& res) { - AztecData res; Table latchTable = Table::UPPER; // table most recently latched to Table shiftTable = Table::UPPER; // table to use for the next read - std::string text; - text.reserve(20); - int symbologyIdModifier = 0; - CharacterSet encoding = CharacterSetECI::InitEncoding(characterSet); - // Check for Structured Append - need 4 5-bit words, beginning with ML UL, ending with index and count - bool haveStructuredAppend = Size(bits) > 20 && ToInt(bits, 0, 5) == 29 // latch to MIXED (from UPPER) - && ToInt(bits, 5, 5) == 29; // latch back to UPPER (from MIXED) - bool haveFNC1 = false; auto remBits = bits.range(); while (remBits.size() >= (shiftTable == Table::DIGIT ? 4 : 5)) { // see ISO/IEC 24778:2008 7.3.1.2 regarding padding bits @@ -292,7 +265,7 @@ AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet) if (length == 0) length = ReadBits(remBits, 11) + 31; for (int i = 0; i < length; i++) - text.push_back(static_cast(ReadBits(remBits, 8))); + res.push_back(ReadBits(remBits, 8)); // Go back to whatever mode we had been in shiftTable = latchTable; } else { @@ -311,53 +284,70 @@ AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet) } else if (std::strcmp(str, "FLGN") == 0) { int flg = ReadBits(remBits, 3); if (flg == 0) { // FNC1 - haveFNC1 = true; // Will process first/second FNC1 at end after any Structured Append - text.push_back((char)29); // May be removed at end if first/second FNC1 + res.push_back(29); // May be removed at end if first/second FNC1 } else if (flg <= 6) { // FLG(1) to FLG(6) ECI - encoding = - CharacterSetECI::OnChangeAppendReset(ParseECIValue(remBits, flg), res.text, text, encoding); + res.switchEncoding(ParseECIValue(remBits, flg)); } else { // FLG(7) is invalid } shiftTable = latchTable; } else { - text.append(str); + res.append(str); // Go back to whatever mode we had been in shiftTable = latchTable; } } } +} - TextDecoder::Append(res.text, reinterpret_cast(text.data()), text.size(), encoding); - - if (!res.text.empty()) { - if (haveStructuredAppend) - res.sai = ParseStructuredAppend(res.text); - if (haveFNC1) { - // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using - // modifiers that indicate ECI protocol (ISO/IEC 24778:2008 Annex F Table F.1) - if (res.text.front() == 29) { - symbologyIdModifier = 1; // GS1 - res.text.erase(0, 1); // Remove FNC1 - } else if (res.text.size() > 2 && std::isupper(res.text[0]) && res.text[1] == 29) { - // FNC1 following single uppercase letter (the AIM Application Indicator) - symbologyIdModifier = 2; // AIM - res.text.erase(1, 1); // Remove FNC1 - // The AIM Application Indicator character "A"-"Z" is left in the stream (ISO/IEC 24778:2008 16.2) - } else if (res.text.size() > 3 && std::isdigit(res.text[0]) && std::isdigit(res.text[1]) && - res.text[2] == 29) { - // FNC1 following 2 digits (the AIM Application Indicator) - symbologyIdModifier = 2; // AIM - res.text.erase(2, 1); // Remove FNC1 - // The AIM Application Indicator characters "00"-"99" are left in the stream (ISO/IEC 24778:2008 16.2) - } - } +ZXING_EXPORT_TEST_ONLY +DecoderResult Decode(const BitArray& bits, const std::string& characterSet) +{ + Content res; + res.symbology = {'z', '0', 3}; + res.hintedCharset = characterSet; + + try { + DecodeContent(bits, res); + } catch (const std::out_of_range&) { // see ReadBits() + return DecodeStatus::FormatError; } - res.symbologyIdentifier = "]z" + std::to_string(symbologyIdModifier + (res.sai.index > -1 ? 6 : 0)); + if (res.binary.empty()) + return DecodeStatus::FormatError; - return res; + // Check for Structured Append - need 4 5-bit words, beginning with ML UL, ending with index and count + bool haveStructuredAppend = Size(bits) > 20 && ToInt(bits, 0, 5) == 29 // latch to MIXED (from UPPER) + && ToInt(bits, 5, 5) == 29; // latch back to UPPER (from MIXED) + + StructuredAppendInfo sai = haveStructuredAppend ? ParseStructuredAppend(res.binary) : StructuredAppendInfo(); + + // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using + // modifiers that indicate ECI protocol (ISO/IEC 24778:2008 Annex F Table F.1) + if (res.binary[0] == 29) { + res.symbology.modifier = '1'; // GS1 + res.applicationIndicator = "GS1"; + res.erase(0, 1); // Remove FNC1 + } else if (res.binary.size() > 2 && std::isupper(res.binary[0]) && res.binary[1] == 29) { + // FNC1 following single uppercase letter (the AIM Application Indicator) + res.symbology.modifier = '2'; // AIM + // TODO: remove the AI from the content? + res.applicationIndicator = std::string(reinterpret_cast(res.binary.data()), 1); + res.erase(1, 1); // Remove FNC1, + // The AIM Application Indicator character "A"-"Z" is left in the stream (ISO/IEC 24778:2008 16.2) + } else if (res.binary.size() > 3 && std::isdigit(res.binary[0]) && std::isdigit(res.binary[1]) && res.binary[2] == 29) { + // FNC1 following 2 digits (the AIM Application Indicator) + res.symbology.modifier = '2'; // AIM + res.applicationIndicator = std::string(reinterpret_cast(res.binary.data()), 2); + res.erase(2, 1); // Remove FNC1 + // The AIM Application Indicator characters "00"-"99" are left in the stream (ISO/IEC 24778:2008 16.2) + } + + if (sai.index != -1) + res.symbology.modifier += 6; // TODO: this is wrong as long as we remove the sai info from the content in ParseStructuredAppend + + return DecoderResult(bits.toBytes(), {}, std::move(res)).setNumBits(Size(bits)).setStructuredAppend(sai); } DecoderResult Decode(const DetectorResult& detectorResult, const std::string& characterSet) @@ -367,19 +357,7 @@ DecoderResult Decode(const DetectorResult& detectorResult, const std::string& ch if (!bits.size()) return DecodeStatus::FormatError; - try { - auto data = GetEncodedData(bits, characterSet); - if (data.text.empty()) - return DecodeStatus::FormatError; - - return DecoderResult(bits.toBytes(), std::move(data.text)) - .setNumBits(Size(bits)) - .setSymbologyIdentifier(std::move(data.symbologyIdentifier)) - .setStructuredAppend(data.sai) - .setReaderInit(detectorResult.readerInit()); - } catch (const std::out_of_range&) { // see ReadBits() - return DecodeStatus::FormatError; - } + return Decode(bits, characterSet).setReaderInit(detectorResult.readerInit()); } } // namespace ZXing::Aztec diff --git a/test/unit/aztec/AZDecoderTest.cpp b/test/unit/aztec/AZDecoderTest.cpp index 56c323a6a6..523bb8b920 100644 --- a/test/unit/aztec/AZDecoderTest.cpp +++ b/test/unit/aztec/AZDecoderTest.cpp @@ -17,14 +17,7 @@ namespace ZXing::Aztec { -struct AztecData -{ - std::wstring text; - std::string symbologyIdentifier; - StructuredAppendInfo sai; -}; - -AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet = ""); +DecoderResult Decode(const BitArray& bits, const std::string& characterSet = ""); } @@ -148,14 +141,14 @@ TEST(AZDecoderTest, DecodeTooManyErrors2) } // Helper taking bit string to call GetEncodedData() -static Aztec::AztecData getData(std::string_view bitStr) +static DecoderResult getData(std::string_view bitStr) { BitArray bits; for (auto b : bitStr) bits.appendBit(b == '1'); - return Aztec::GetEncodedData(bits); + return Aztec::Decode(bits); } TEST(AZDecoderTest, SymbologyIdentifier) @@ -163,101 +156,101 @@ TEST(AZDecoderTest, SymbologyIdentifier) { // Plain auto data = getData("00010"); - EXPECT_EQ(data.symbologyIdentifier, "]z0"); - EXPECT_EQ(data.text, L"A"); + EXPECT_EQ(data.symbologyIdentifier(), "]z0"); + EXPECT_EQ(data.text(), L"A"); } { // GS1 ("PS FLGN(0) DL (20)01") auto data = getData("0000000000000111100100001000100011"); - EXPECT_EQ(data.symbologyIdentifier, "]z1"); - EXPECT_EQ(data.text, L"2001"); + EXPECT_EQ(data.symbologyIdentifier(), "]z1"); + EXPECT_EQ(data.text(), L"2001"); } { // AIM ("A PS FLGN(0) B") auto data = getData("00010000000000000000011"); - EXPECT_EQ(data.symbologyIdentifier, "]z2"); - EXPECT_EQ(data.text, L"AB"); + EXPECT_EQ(data.symbologyIdentifier(), "]z2"); + EXPECT_EQ(data.text(), L"AB"); } { // AIM ("DL 99 UL PS FLGN(0) B") auto data = getData("11110101110111110000000000000000011"); - EXPECT_EQ(data.symbologyIdentifier, "]z2"); - EXPECT_EQ(data.text, L"99B"); + EXPECT_EQ(data.symbologyIdentifier(), "]z2"); + EXPECT_EQ(data.text(), L"99B"); } { // Structured Append ("UL ML A D A") auto data = getData("1110111101000100010100010"); - EXPECT_EQ(data.symbologyIdentifier, "]z6"); - EXPECT_EQ(data.text, L"A"); - EXPECT_EQ(data.sai.index, 0); - EXPECT_EQ(data.sai.count, 4); + EXPECT_EQ(data.symbologyIdentifier(), "]z6"); + EXPECT_EQ(data.text(), L"A"); + EXPECT_EQ(data.structuredAppend().index, 0); + EXPECT_EQ(data.structuredAppend().count, 4); } { // Structured Append with GS1 ("UL ML A D PS FLGN(0) DL (20)01") auto data = getData("111011110100010001010000000000000111100100001000100011"); - EXPECT_EQ(data.symbologyIdentifier, "]z7"); - EXPECT_EQ(data.text, L"2001"); - EXPECT_EQ(data.sai.index, 0); - EXPECT_EQ(data.sai.count, 4); + EXPECT_EQ(data.symbologyIdentifier(), "]z7"); + EXPECT_EQ(data.text(), L"2001"); + EXPECT_EQ(data.structuredAppend().index, 0); + EXPECT_EQ(data.structuredAppend().count, 4); } { // Structured Append with AIM ("UL ML A D A PS FLGN(0) B") auto data = getData("1110111101000100010100010000000000000000011"); - EXPECT_EQ(data.symbologyIdentifier, "]z8"); - EXPECT_EQ(data.text, L"AB"); - EXPECT_EQ(data.sai.index, 0); - EXPECT_EQ(data.sai.count, 4); + EXPECT_EQ(data.symbologyIdentifier(), "]z8"); + EXPECT_EQ(data.text(), L"AB"); + EXPECT_EQ(data.structuredAppend().index, 0); + EXPECT_EQ(data.structuredAppend().count, 4); } { // Plain with FNC1 not in first/second position ("A B PS FLGN(0) C") auto data = getData("0001000011000000000000000100"); - EXPECT_EQ(data.symbologyIdentifier, "]z0"); - EXPECT_EQ(data.text, L"AB\u001DC"); // "ABC" + EXPECT_EQ(data.symbologyIdentifier(), "]z0"); + EXPECT_EQ(data.text(), L"AB\u001DC"); // "ABC" } { // Plain with FNC1 not in first/second position ("A B C PS FLGN(0) D") auto data = getData("000100001100100000000000000000101"); - EXPECT_EQ(data.symbologyIdentifier, "]z0"); - EXPECT_EQ(data.text, L"ABC\u001DD"); // "ABCD" + EXPECT_EQ(data.symbologyIdentifier(), "]z0"); + EXPECT_EQ(data.text(), L"ABC\u001DD"); // "ABCD" } { // Plain with FNC1 not in first/second position ("DL 1 UL PS FLGN(0) A") auto data = getData("1111000111110000000000000000010"); - EXPECT_EQ(data.symbologyIdentifier, "]z0"); - EXPECT_EQ(data.text, L"1\u001DA"); // "1D" + EXPECT_EQ(data.symbologyIdentifier(), "]z0"); + EXPECT_EQ(data.text(), L"1\u001DA"); // "1D" } } // Helper taking 5-bit word array to call GetEncodedData() -static Aztec::AztecData getData(const ByteArray& bytes) +static DecoderResult getData(const ByteArray& bytes) { BitArray bits; // 5-bit words (assuming no digits/binary) for (auto b : bytes) bits.appendBits(b, 5); - return Aztec::GetEncodedData(bits); + return Aztec::Decode(bits); } // Shorthand to return Structured Append given 5-bit word array static StructuredAppendInfo sai(const ByteArray& bytes) { - return getData(bytes).sai; + return getData(bytes).structuredAppend(); } // Shorthand to return string result given 5-bit word array static std::wstring text(const ByteArray& bytes) { - return getData(bytes).text; + return getData(bytes).text(); } TEST(AZDecoderTest, StructuredAppend) @@ -335,30 +328,30 @@ TEST(AZDecoderTest, StructuredAppend) // Invalid Ids { auto data = getData({29, 29, 1, 10, 5, 2, 5, 2}); // No terminating space - EXPECT_TRUE(data.sai.id.empty()); - EXPECT_EQ(data.sai.index, -1); // Not recognized as sequence - EXPECT_EQ(data.sai.count, -1); - EXPECT_EQ(data.text, L" IDADA"); // Bad ID and sequencing left in result + EXPECT_TRUE(data.structuredAppend().id.empty()); + EXPECT_EQ(data.structuredAppend().index, -1); // Not recognized as sequence + EXPECT_EQ(data.structuredAppend().count, -1); + EXPECT_EQ(data.text(), L" IDADA"); // Bad ID and sequencing left in result } { auto data = getData({29, 29, 1, 1, 2, 5, 2}); // Blank - EXPECT_TRUE(data.sai.id.empty()); - EXPECT_EQ(data.sai.index, 0); // Recognized as sequence - EXPECT_EQ(data.sai.count, 4); - EXPECT_EQ(data.text, L"A"); + EXPECT_TRUE(data.structuredAppend().id.empty()); + EXPECT_EQ(data.structuredAppend().index, 0); // Recognized as sequence + EXPECT_EQ(data.structuredAppend().count, 4); + EXPECT_EQ(data.text(), L"A"); } { auto data = getData({29, 29, 1, 10, 1, 5, 1, 2, 5, 2}); // Space in "I D" - EXPECT_TRUE(data.sai.id.empty()); - EXPECT_EQ(data.sai.index, -1); // Not recognized as sequence as sequence count invalid (space) - EXPECT_EQ(data.sai.count, -1); - EXPECT_EQ(data.text, L" I D ADA"); // Bad ID and sequencing left in result + EXPECT_TRUE(data.structuredAppend().id.empty()); + EXPECT_EQ(data.structuredAppend().index, -1); // Not recognized as sequence as sequence count invalid (space) + EXPECT_EQ(data.structuredAppend().count, -1); + EXPECT_EQ(data.text(), L" I D ADA"); // Bad ID and sequencing left in result } { auto data = getData({29, 29, 1, 10, 1, 2, 5, 1, 2, 5, 2}); // "I AD" (happens to have valid sequencing at end) - EXPECT_EQ(data.sai.id, "I"); - EXPECT_EQ(data.sai.index, 0); - EXPECT_EQ(data.sai.count, 4); - EXPECT_EQ(data.text, L" ADA"); // Trailing space and "real" sequencing left in result + EXPECT_EQ(data.structuredAppend().id, "I"); + EXPECT_EQ(data.structuredAppend().index, 0); + EXPECT_EQ(data.structuredAppend().count, 4); + EXPECT_EQ(data.text(), L" ADA"); // Trailing space and "real" sequencing left in result } } diff --git a/test/unit/aztec/AZEncodeDecodeTest.cpp b/test/unit/aztec/AZEncodeDecodeTest.cpp index d968371719..54c7d2fe7f 100644 --- a/test/unit/aztec/AZEncodeDecodeTest.cpp +++ b/test/unit/aztec/AZEncodeDecodeTest.cpp @@ -86,10 +86,9 @@ namespace { EXPECT_EQ(aztec.matrix, matrix); - std::wstring expectedData = TextDecoder::ToUnicode(textBytes, CharacterSet::ISO8859_1); DecoderResult res = parse(matrix.copy(), aztec.compact, aztec.codeWords, aztec.layers); EXPECT_EQ(res.isValid(), true); - EXPECT_EQ(res.text(), expectedData); + EXPECT_EQ(res.content().binary, ByteArray(textBytes)); // Check error correction by introducing up to eccPercent/2 errors int ecWords = aztec.codeWords * eccPercent / 100 / 2; @@ -106,7 +105,7 @@ namespace { } res = parse(std::move(matrix), aztec.compact, aztec.codeWords, aztec.layers); EXPECT_EQ(res.isValid(), true); - EXPECT_EQ(res.text(), expectedData); + EXPECT_EQ(res.content().binary, ByteArray(textBytes)); } } diff --git a/test/unit/aztec/AZHighLevelEncoderTest.cpp b/test/unit/aztec/AZHighLevelEncoderTest.cpp index 7643f1e9b9..7e80feb770 100644 --- a/test/unit/aztec/AZHighLevelEncoderTest.cpp +++ b/test/unit/aztec/AZHighLevelEncoderTest.cpp @@ -7,6 +7,7 @@ #include "aztec/AZHighLevelEncoder.h" #include "BitArray.h" #include "BitArrayUtility.h" +#include "DecoderResult.h" #include "StructuredAppend.h" #include "TextDecoder.h" @@ -15,14 +16,7 @@ namespace ZXing::Aztec { -struct AztecData -{ - std::wstring text; - std::string symbologyIdentifier; - StructuredAppendInfo sai; -}; - -AztecData GetEncodedData(const BitArray& bits, const std::string& characterSet = ""); +DecoderResult Decode(const BitArray& bits, const std::string& characterSet = ""); } @@ -37,16 +31,14 @@ namespace { void TestHighLevelEncodeString(const std::string& s, const std::string& expectedBits) { BitArray bits = Aztec::HighLevelEncoder::Encode(s); EXPECT_EQ(Utility::ToString(bits), StripSpaces(expectedBits)) << "highLevelEncode() failed for input string: " + s; - EXPECT_EQ(TextDecoder::FromLatin1(s), Aztec::GetEncodedData(bits).text); + EXPECT_EQ(TextDecoder::FromLatin1(s), Aztec::Decode(bits).text()); } void TestHighLevelEncodeString(const std::string& s, int expectedReceivedBits) { BitArray bits = Aztec::HighLevelEncoder::Encode(s); int receivedBitCount = Size(Utility::ToString(bits)); EXPECT_EQ(receivedBitCount, expectedReceivedBits) << "highLevelEncode() failed for input string: " + s; - std::string symbologyIdentifier; - StructuredAppendInfo sai; - EXPECT_EQ(TextDecoder::FromLatin1(s), Aztec::GetEncodedData(bits).text); + EXPECT_EQ(ByteArray(s), Aztec::Decode(bits).content().binary); } } From becb24448e5147e7c9a2338adb45b8ba22499642 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 30 May 2022 11:48:17 +0200 Subject: [PATCH 0243/1315] ECI: tune Content::type() (again...) --- core/src/Content.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 12e560cf1d..a0ec9951fa 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -154,20 +154,17 @@ CharacterSet Content::guessEncoding() const ContentType Content::type() const { auto isBinary = [](Encoding e) { return !IsText(e.eci); }; + auto es = encodings; - if (std::none_of(encodings.begin(), encodings.end(), isBinary)) + for (auto& e : es) + if (e.eci == ECI::Unknown) + e.eci = ToECI(guessEncoding()); + + if (std::none_of(es.begin(), es.end(), isBinary)) return ContentType::Text; - if (std::all_of(encodings.begin(), encodings.end(), isBinary)) + if (std::all_of(es.begin(), es.end(), isBinary)) return ContentType::Binary; - if (!hasECI) { - auto cs = guessEncoding(); - if (IsText(ToECI(cs))) - return ContentType::Text; - if (cs == CharacterSet::BINARY) - return ContentType::Binary; - } - return ContentType::Mixed; } From 2ec23cb1d2d3cdc5efc3b8f7797782296e99d51c Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 30 May 2022 18:37:34 +0200 Subject: [PATCH 0244/1315] PDF417: add trivial IsECI() helper function to raise abstraction --- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index e616790f4f..0a760140f6 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -66,6 +66,11 @@ static const char* MIXED_CHARS = "0123456789&\r\t,:#-.$/+%*=^"; static const int NUMBER_OF_SEQUENCE_CODEWORDS = 2; +inline bool IsECI(int code) +{ + return code >= ECI_USER_DEFINED && code <= ECI_CHARSET; +} + /** * Whether a codeword terminates a Compaction mode. * @@ -91,7 +96,7 @@ static bool TerminatesCompaction(int code) static int ProcessECI(const std::vector& codewords, int codeIndex, const int length, const int code, std::wstring& resultEncoded, std::string& result, CharacterSet& encoding) { - if (codeIndex < length && code >= ECI_USER_DEFINED && code <= ECI_CHARSET) { + if (codeIndex < length && IsECI(code)) { if (code == ECI_CHARSET) { encoding = CharacterSetECI::OnChangeAppendReset(codewords[codeIndex++], resultEncoded, result, encoding); } @@ -134,13 +139,13 @@ static void DecodeTextCompaction(const std::vector& textCompactionData, int int subModeCh = textCompactionData[i]; // Note only have ECI and MODE_SHIFT_TO_BYTE_COMPACTION_MODE function codewords in text compaction array - if (subModeCh >= ECI_USER_DEFINED && subModeCh <= ECI_CHARSET) { + if (IsECI(subModeCh)) { i = ProcessECI(textCompactionData, i + 1, length, subModeCh, resultEncoded, result, encoding); continue; } if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { i++; - while (i < length && textCompactionData[i] >= ECI_USER_DEFINED && textCompactionData[i] <= ECI_CHARSET) { + while (i < length && IsECI(textCompactionData[i])) { i = ProcessECI(textCompactionData, i + 1, length, textCompactionData[i], resultEncoded, result, encoding); } @@ -303,8 +308,7 @@ static int TextCompaction(DecodeStatus& status, const std::vector& codeword // in Text Compaction mode; its use is described in 5.4.2.4. textCompactionData[index++] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE; // 5.5.3.1 allows ECIs anywhere in Text Compaction, including after a Shift to Byte - while (codeIndex < codewords[0] && codewords[codeIndex] >= ECI_USER_DEFINED - && codewords[codeIndex] <= ECI_CHARSET) { + while (codeIndex < codewords[0] && IsECI(codewords[codeIndex])) { codeIndex = ProcessTextECI(textCompactionData, index, codewords, codeIndex + 1, codewords[codeIndex]); } @@ -349,7 +353,7 @@ static int CountByteBatches(DecodeStatus& status, int mode, const std::vector= ECI_USER_DEFINED && code <= ECI_CHARSET) { + if (IsECI(code)) { codeIndex += code == ECI_GENERAL_PURPOSE ? 2 : 1; continue; } @@ -395,7 +399,7 @@ static int ProcessByteECIs(const std::vector& codewords, int codeIndex, while (codeIndex < codewords[0] && codewords[codeIndex] >= TEXT_COMPACTION_MODE_LATCH && !TerminatesCompaction(codewords[codeIndex])) { int code = codewords[codeIndex++]; - if (code >= ECI_USER_DEFINED && code <= ECI_CHARSET) { + if (IsECI(code)) { codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, resultEncoded, result, encoding); } } @@ -543,7 +547,7 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew while (codeIndex < codewords[0] && !end) { int code = codewords[codeIndex++]; if (code >= TEXT_COMPACTION_MODE_LATCH) { - if (code >= ECI_USER_DEFINED && code <= ECI_CHARSET) { + if (IsECI(code)) { // As operating in Basic Channel Mode (i.e. not embedding backslashed ECIs and doubling backslashes) // allow ECIs anywhere in Numeric Compaction (i.e. ISO/IEC 15438:2015 5.5.3.4 doesn't apply). if (count > 0) { From e1c70bf87b5aae96ff2e81a77bd4eda28df24d53 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 31 May 2022 11:35:19 +0200 Subject: [PATCH 0245/1315] PDF417: clang-format fixes --- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 172 +++++++----------- 1 file changed, 67 insertions(+), 105 deletions(-) diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 0a760140f6..425016674a 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -24,7 +24,8 @@ namespace ZXing::Pdf417 { -enum class Mode { +enum class Mode +{ ALPHA, LOWER, MIXED, @@ -97,13 +98,10 @@ static int ProcessECI(const std::vector& codewords, int codeIndex, const in std::wstring& resultEncoded, std::string& result, CharacterSet& encoding) { if (codeIndex < length && IsECI(code)) { - if (code == ECI_CHARSET) { + if (code == ECI_CHARSET) encoding = CharacterSetECI::OnChangeAppendReset(codewords[codeIndex++], resultEncoded, result, encoding); - } - else { - // Don't currently handle non-character set ECIs so just ignore - codeIndex += code == ECI_GENERAL_PURPOSE ? 2 : 1; - } + else + codeIndex += code == ECI_GENERAL_PURPOSE ? 2 : 1; // Don't currently handle non-character set ECIs so just ignore } return codeIndex; @@ -145,14 +143,12 @@ static void DecodeTextCompaction(const std::vector& textCompactionData, int } if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { i++; - while (i < length && IsECI(textCompactionData[i])) { - i = ProcessECI(textCompactionData, i + 1, length, textCompactionData[i], resultEncoded, result, - encoding); - } - if (i < length) { - result.push_back((uint8_t)textCompactionData[i]); - i++; - } + while (i < length && IsECI(textCompactionData[i])) + i = ProcessECI(textCompactionData, i + 1, length, textCompactionData[i], resultEncoded, result, encoding); + + if (i < length) + result.push_back((uint8_t)textCompactionData[i++]); + continue; } @@ -164,19 +160,15 @@ static void DecodeTextCompaction(const std::vector& textCompactionData, int if (subModeCh < 26) { // Upper/lowercase character ch = (char)((subMode == Mode::ALPHA ? 'A' : 'a') + subModeCh); - } - else if (subModeCh == 26) { // Space + } else if (subModeCh == 26) { // Space ch = ' '; - } - else if (subModeCh == 27 && subMode == Mode::ALPHA) { // LL + } else if (subModeCh == 27 && subMode == Mode::ALPHA) { // LL subMode = Mode::LOWER; - } - else if (subModeCh == 27 && subMode == Mode::LOWER) { // AS + } else if (subModeCh == 27 && subMode == Mode::LOWER) { // AS // Shift to alpha priorToShiftMode = subMode; subMode = Mode::ALPHA_SHIFT; - } - else if (subModeCh == 28) { // ML + } else if (subModeCh == 28) { // ML subMode = Mode::MIXED; } // 29 PS - ignore if last or followed by Shift to Byte, 5.4.2.4 (b) (1) @@ -191,17 +183,13 @@ static void DecodeTextCompaction(const std::vector& textCompactionData, int // Mixed (numeric and some punctuation) if (subModeCh < 25) { ch = MIXED_CHARS[subModeCh]; - } - else if (subModeCh == 25) { // PL + } else if (subModeCh == 25) { // PL subMode = Mode::PUNCT; - } - else if (subModeCh == 26) { // Space + } else if (subModeCh == 26) { // Space ch = ' '; - } - else if (subModeCh == 27) { // LL + } else if (subModeCh == 27) { // LL subMode = Mode::LOWER; - } - else if (subModeCh == 28) { // AL + } else if (subModeCh == 28) { // AL subMode = Mode::ALPHA; } // 29 PS - ignore if last or followed by Shift to Byte, 5.4.2.4 (b) (1) @@ -214,41 +202,33 @@ static void DecodeTextCompaction(const std::vector& textCompactionData, int case Mode::PUNCT: // Punctuation - if (subModeCh < 29) { + if (subModeCh < 29) ch = PUNCT_CHARS[subModeCh]; - } - else { // 29 AL - note not ignored if followed by Shift to Byte, 5.4.2.4 (b) (2) + else // 29 AL - note not ignored if followed by Shift to Byte, 5.4.2.4 (b) (2) subMode = Mode::ALPHA; - } break; case Mode::ALPHA_SHIFT: // Restore sub-mode subMode = priorToShiftMode; - if (subModeCh < 26) { + if (subModeCh < 26) ch = (char)('A' + subModeCh); - } - else if (subModeCh == 26) { // Space + else if (subModeCh == 26) // Space ch = ' '; - } // 27 LL, 28 ML, 29 PS used as padding break; case Mode::PUNCT_SHIFT: // Restore sub-mode subMode = priorToShiftMode; - if (subModeCh < 29) { + if (subModeCh < 29) ch = PUNCT_CHARS[subModeCh]; - } - else { // 29 AL + else // 29 AL subMode = Mode::ALPHA; - } break; } - if (ch != 0) { - // Append decoded character to result - result.push_back(ch); - } + if (ch != 0) + result.push_back(ch); // Append decoded character to result i++; } } @@ -256,8 +236,9 @@ static void DecodeTextCompaction(const std::vector& textCompactionData, int /* * Helper to put ECI codewords into Text Compaction array. */ -static int ProcessTextECI(std::vector& textCompactionData, int& index, - const std::vector& codewords, int codeIndex, const int code) { +static int ProcessTextECI(std::vector& textCompactionData, int& index, const std::vector& codewords, int codeIndex, + const int code) +{ textCompactionData[index++] = code; if (codeIndex < codewords[0]) { textCompactionData[index++] = codewords[codeIndex++]; @@ -296,8 +277,7 @@ static int TextCompaction(DecodeStatus& status, const std::vector& codeword textCompactionData[index] = code / 30; textCompactionData[index + 1] = code % 30; index += 2; - } - else { + } else { switch (code) { case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: // The Mode Shift codeword 913 shall cause a temporary @@ -309,12 +289,10 @@ static int TextCompaction(DecodeStatus& status, const std::vector& codeword textCompactionData[index++] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE; // 5.5.3.1 allows ECIs anywhere in Text Compaction, including after a Shift to Byte while (codeIndex < codewords[0] && IsECI(codewords[codeIndex])) { - codeIndex = ProcessTextECI(textCompactionData, index, codewords, codeIndex + 1, - codewords[codeIndex]); + codeIndex = ProcessTextECI(textCompactionData, index, codewords, codeIndex + 1, codewords[codeIndex]); } - if (codeIndex < codewords[0]) { + if (codeIndex < codewords[0]) textCompactionData[index++] = codewords[codeIndex++]; // Byte to shift - } break; case ECI_CHARSET: case ECI_GENERAL_PURPOSE: @@ -340,8 +318,7 @@ static int TextCompaction(DecodeStatus& status, const std::vector& codeword * Helper for Byte Compaction to look ahead and count 5-codeword batches and trailing bytes, with some checking of * format errors. */ -static int CountByteBatches(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, - int& trailingCount) +static int CountByteBatches(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, int& trailingCount) { int count = 0; trailingCount = 0; @@ -369,9 +346,8 @@ static int CountByteBatches(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, while (codeIndex < codewords[0] && codewords[codeIndex] >= TEXT_COMPACTION_MODE_LATCH && !TerminatesCompaction(codewords[codeIndex])) { int code = codewords[codeIndex++]; - if (IsECI(code)) { + if (IsECI(code)) codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, resultEncoded, result, encoding); - } } return codeIndex; @@ -428,21 +402,20 @@ static int ByteCompaction(DecodeStatus& status, int mode, const std::vector int trailingCount; int batches = CountByteBatches(status, mode, codewords, codeIndex, trailingCount); - if (StatusIsError(status)) { + if (StatusIsError(status)) return codeIndex; - } // Deal with initial ECIs codeIndex = ProcessByteECIs(codewords, codeIndex, resultEncoded, result, encoding); for (int batch = 0; batch < batches; batch++) { int64_t value = 0; - for (int count = 0; count < 5; count++) { + for (int count = 0; count < 5; count++) value = 900 * value + codewords[codeIndex++]; - } - for (int j = 0; j < 6; ++j) { + + for (int j = 0; j < 6; ++j) result.push_back((uint8_t)(value >> (8 * (5 - j)))); - } + // Deal with inter-batch ECIs codeIndex = ProcessByteECIs(codewords, codeIndex, resultEncoded, result, encoding); } @@ -505,18 +478,17 @@ static DecodeStatus DecodeBase900toBase10(const std::vector& codewords, int // Table containing values for the exponent of 900. static const auto EXP900 = []() { std::array table = {1, 900}; - for (size_t i = 2; i < table.size(); ++i) { + for (size_t i = 2; i < table.size(); ++i) table[i] = table[i - 1] * 900; - } return table; }(); assert(count <= 16); BigInteger result; - for (int i = 0; i < count; i++) { + for (int i = 0; i < count; i++) result += EXP900[count - i - 1] * codewords[i]; - } + resultString = result.toString(); if (!resultString.empty() && resultString.front() == '1') { resultString = resultString.substr(1); @@ -553,9 +525,9 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew if (count > 0) { std::string tmp; status = DecodeBase900toBase10(numericCodewords, count, tmp); - if (StatusIsError(status)) { + if (StatusIsError(status)) return codeIndex; - } + result += tmp; count = 0; } @@ -584,9 +556,9 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew if (count > 0) { std::string tmp; status = DecodeBase900toBase10(numericCodewords, count, tmp); - if (StatusIsError(status)) { + if (StatusIsError(status)) return codeIndex; - } + result += tmp; count = 0; } @@ -640,20 +612,19 @@ ZXING_EXPORT_TEST_ONLY DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderResultExtra& resultMetadata, int& next) { - if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) { - // we must have at least two bytes left for the segment index + // we must have at least two bytes left for the segment index + if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) return DecodeStatus::FormatError; - } + std::vector segmentIndexArray(NUMBER_OF_SEQUENCE_CODEWORDS); - for (int i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) { + for (int i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) segmentIndexArray[i] = codewords[codeIndex]; - } std::string strBuf; DecodeStatus status = DecodeBase900toBase10(segmentIndexArray, NUMBER_OF_SEQUENCE_CODEWORDS, strBuf); - if (StatusIsError(status)) { + if (StatusIsError(status)) return status; - } + resultMetadata.setSegmentIndex(std::stoi(strBuf)); // Decoding the fileId codewords as 0-899 numbers, each 0-filled to width 3. This follows the spec @@ -661,25 +632,23 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, // the fileId using text compaction, so in those cases the fileId will appear mangled. std::ostringstream fileId; fileId.fill('0'); - for (; codeIndex < codewords[0] && codewords[codeIndex] != MACRO_PDF417_TERMINATOR && - codewords[codeIndex] != BEGIN_MACRO_PDF417_OPTIONAL_FIELD; + for (; codeIndex < codewords[0] && codewords[codeIndex] != MACRO_PDF417_TERMINATOR + && codewords[codeIndex] != BEGIN_MACRO_PDF417_OPTIONAL_FIELD; codeIndex++) { fileId << std::setw(3) << codewords[codeIndex]; } resultMetadata.setFileId(fileId.str()); int optionalFieldsStart = -1; - if (codeIndex < codewords[0] && codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) { + if (codeIndex < codewords[0] && codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) optionalFieldsStart = codeIndex + 1; - } while (codeIndex < codewords[0]) { switch (codewords[codeIndex]) { case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: { codeIndex++; - if (codeIndex >= codewords[0]) { + if (codeIndex >= codewords[0]) break; - } switch (codewords[codeIndex]) { case MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: { std::string fileName; @@ -742,10 +711,9 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, // copy optional fields to additional options if (optionalFieldsStart != -1) { int optionalFieldsLength = codeIndex - optionalFieldsStart; - if (resultMetadata.isLastSegment()) { - // do not include terminator - optionalFieldsLength--; - } + if (resultMetadata.isLastSegment()) + optionalFieldsLength--; // do not include terminator + resultMetadata.setOptionalData(std::vector(codewords.begin() + optionalFieldsStart, codewords.begin() + optionalFieldsStart + optionalFieldsLength)); } @@ -797,20 +765,15 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c status = DecodeStatus::FormatError; break; case READER_INIT: - if (codeIndex != 2) { // Must be first codeword after symbol length (ISO/IEC 15438:2015 5.4.1.4) + if (codeIndex != 2) // Must be first codeword after symbol length (ISO/IEC 15438:2015 5.4.1.4) status = DecodeStatus::FormatError; - } - else { + else readerInit = true; - } break; case LINKAGE_EANUCC: - if (codeIndex != 2) { // Must be first codeword after symbol length (GS1 Composite ISO/IEC 24723:2010 4.3) + if (codeIndex != 2) // Must be first codeword after symbol length (GS1 Composite ISO/IEC 24723:2010 4.3) status = DecodeStatus::FormatError; - } - else { - // TODO: handle - } + // TODO: handle else case break; case LINKAGE_OTHER: // Allowed to treat as invalid by ISO/IEC 24723:2010 5.4.1.5 and 5.4.6.1 when in Basic Channel Mode @@ -820,8 +783,7 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c if (code >= TEXT_COMPACTION_MODE_LATCH) { // Reserved codewords (all others in switch) // Allowed to treat as invalid by ISO/IEC 24723:2010 5.4.6.1 when in Basic Channel Mode status = DecodeStatus::FormatError; // TODO: add NotSupported error - } - else { + } else { // Default mode is Text Compaction mode Alpha sub-mode (ISO/IEC 15438:2015 5.4.2.1) codeIndex = TextCompaction(status, codewords, codeIndex - 1, resultEncoded, result, encoding); } From 89a0d2b15113fa04e8105e75d13f58fa9a0bc351 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 31 May 2022 12:33:42 +0200 Subject: [PATCH 0246/1315] ECI: update PDF417 decoder to use new Content class --- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 102 +++++++----------- test/unit/pdf417/PDF417DecoderTest.cpp | 3 +- 2 files changed, 42 insertions(+), 63 deletions(-) diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 425016674a..e3ebc2a8ff 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -94,12 +94,11 @@ static bool TerminatesCompaction(int code) /** * Helper to process ECIs. **/ -static int ProcessECI(const std::vector& codewords, int codeIndex, const int length, const int code, - std::wstring& resultEncoded, std::string& result, CharacterSet& encoding) +static int ProcessECI(const std::vector& codewords, int codeIndex, const int length, const int code, Content& result) { if (codeIndex < length && IsECI(code)) { if (code == ECI_CHARSET) - encoding = CharacterSetECI::OnChangeAppendReset(codewords[codeIndex++], resultEncoded, result, encoding); + result.switchEncoding(ECI(codewords[codeIndex++])); else codeIndex += code == ECI_GENERAL_PURPOSE ? 2 : 1; // Don't currently handle non-character set ECIs so just ignore } @@ -119,12 +118,9 @@ static int ProcessECI(const std::vector& codewords, int codeIndex, const in * * @param textCompactionData The text compaction data. * @param length The size of the text compaction data. -* @param resultEncoded The Unicode-encoded data. * @param result The data in the character set encoding. -* @param encoding Currently active character encoding. */ -static void DecodeTextCompaction(const std::vector& textCompactionData, int length, std::wstring& resultEncoded, - std::string& result, CharacterSet& encoding) +static void DecodeTextCompaction(const std::vector& textCompactionData, int length, Content& result) { // Beginning from an initial state of the Alpha sub-mode // The default compaction mode for PDF417 in effect at the start of each symbol shall always be Text @@ -138,13 +134,13 @@ static void DecodeTextCompaction(const std::vector& textCompactionData, int // Note only have ECI and MODE_SHIFT_TO_BYTE_COMPACTION_MODE function codewords in text compaction array if (IsECI(subModeCh)) { - i = ProcessECI(textCompactionData, i + 1, length, subModeCh, resultEncoded, result, encoding); + i = ProcessECI(textCompactionData, i + 1, length, subModeCh, result); continue; } if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { i++; while (i < length && IsECI(textCompactionData[i])) - i = ProcessECI(textCompactionData, i + 1, length, textCompactionData[i], resultEncoded, result, encoding); + i = ProcessECI(textCompactionData, i + 1, length, textCompactionData[i], result); if (i < length) result.push_back((uint8_t)textCompactionData[i++]); @@ -257,13 +253,10 @@ static int ProcessTextECI(std::vector& textCompactionData, int& index, cons * * @param codewords The array of codewords (data + error) * @param codeIndex The current index into the codeword array. -* @param resultEncoded The Unicode-encoded data. * @param result The data in the character set encoding. -* @param encoding Currently active character encoding. * @return The next index into the codeword array. */ -static int TextCompaction(DecodeStatus& status, const std::vector& codewords, int codeIndex, - std::wstring& resultEncoded, std::string& result, CharacterSet& encoding) +static int TextCompaction(DecodeStatus& status, const std::vector& codewords, int codeIndex, Content& result) { // 2 characters per codeword std::vector textCompactionData((codewords[0] - codeIndex) * 2, 0); @@ -310,7 +303,7 @@ static int TextCompaction(DecodeStatus& status, const std::vector& codeword } } } - DecodeTextCompaction(textCompactionData, index, resultEncoded, result, encoding); + DecodeTextCompaction(textCompactionData, index, result); return codeIndex; } @@ -368,14 +361,13 @@ static int CountByteBatches(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, - std::wstring& resultEncoded, std::string& result, CharacterSet& encoding) +static int ProcessByteECIs(const std::vector& codewords, int codeIndex, Content& result) { while (codeIndex < codewords[0] && codewords[codeIndex] >= TEXT_COMPACTION_MODE_LATCH && !TerminatesCompaction(codewords[codeIndex])) { int code = codewords[codeIndex++]; if (IsECI(code)) - codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, resultEncoded, result, encoding); + codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, result); } return codeIndex; @@ -390,13 +382,11 @@ static int ProcessByteECIs(const std::vector& codewords, int codeIndex, * @param mode The byte compaction mode i.e. 901 or 924 * @param codewords The array of codewords (data + error) * @param codeIndex The current index into the codeword array. -* @param resultEncoded The Unicode-encoded data. * @param result The data in the character set encoding. -* @param encoding Currently active character encoding. * @return The next index into the codeword array. */ static int ByteCompaction(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, - std::wstring& resultEncoded, std::string& result, CharacterSet& encoding) + Content& result) { // Count number of 5-codeword batches and trailing bytes int trailingCount; @@ -406,7 +396,7 @@ static int ByteCompaction(DecodeStatus& status, int mode, const std::vector return codeIndex; // Deal with initial ECIs - codeIndex = ProcessByteECIs(codewords, codeIndex, resultEncoded, result, encoding); + codeIndex = ProcessByteECIs(codewords, codeIndex, result); for (int batch = 0; batch < batches; batch++) { int64_t value = 0; @@ -417,13 +407,13 @@ static int ByteCompaction(DecodeStatus& status, int mode, const std::vector result.push_back((uint8_t)(value >> (8 * (5 - j)))); // Deal with inter-batch ECIs - codeIndex = ProcessByteECIs(codewords, codeIndex, resultEncoded, result, encoding); + codeIndex = ProcessByteECIs(codewords, codeIndex, result); } for (int i = 0; i < trailingCount; i++) { result.push_back((uint8_t)codewords[codeIndex++]); // Deal with inter-byte ECIs - codeIndex = ProcessByteECIs(codewords, codeIndex, resultEncoded, result, encoding); + codeIndex = ProcessByteECIs(codewords, codeIndex, result); } return codeIndex; @@ -508,8 +498,7 @@ static DecodeStatus DecodeBase900toBase10(const std::vector& codewords, int * @param encoding Currently active character encoding. * @return The next index into the codeword array. */ -static int NumericCompaction(DecodeStatus& status, const std::vector& codewords, int codeIndex, - std::wstring& resultEncoded, std::string& result, CharacterSet& encoding) +static int NumericCompaction(DecodeStatus& status, const std::vector& codewords, int codeIndex, Content& result) { int count = 0; bool end = false; @@ -531,7 +520,7 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew result += tmp; count = 0; } - codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, resultEncoded, result, encoding); + codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, result); continue; } if (!TerminatesCompaction(code)) { @@ -570,20 +559,17 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew /* * Helper to deal with optional text fields in Macros. */ -static int DecodeMacroOptionalTextField(DecodeStatus& status, const std::vector& codewords, int codeIndex, - std::string& field) +static int DecodeMacroOptionalTextField(DecodeStatus& status, const std::vector& codewords, int codeIndex, std::string& field) { - std::wstring resultEncoded; - std::string result; + Content result; // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 // for non-ASCII (128-255). Text optional fields can contain ECIs. - CharacterSet encoding = CharacterSet::Cp437; + result.hintedCharset = "Cp437"; - codeIndex = TextCompaction(status, codewords, codeIndex, resultEncoded, result, encoding); - TextDecoder::Append(resultEncoded, reinterpret_cast(result.data()), result.size(), encoding); + codeIndex = TextCompaction(status, codewords, codeIndex, result); // Converting to UTF-8 (backward-incompatible change for non-ASCII chars) - TextUtfEncoding::ToUtf8(resultEncoded, field); + TextUtfEncoding::ToUtf8(result.text(), field); return codeIndex; } @@ -594,16 +580,14 @@ static int DecodeMacroOptionalTextField(DecodeStatus& status, const std::vector< static int DecodeMacroOptionalNumericField(DecodeStatus& status, const std::vector& codewords, int codeIndex, uint64_t& field) { - std::wstring resultEncoded; - std::string result; - // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). - // Numeric optional fields should not contain ECIs, but processed anyway. - CharacterSet encoding = CharacterSet::Cp437; + Content result; + // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 + // for non-ASCII (128-255). Text optional fields can contain ECIs. + result.hintedCharset = "Cp437"; - codeIndex = NumericCompaction(status, codewords, codeIndex, resultEncoded, result, encoding); - TextDecoder::Append(resultEncoded, reinterpret_cast(result.data()), result.size(), encoding); + codeIndex = NumericCompaction(status, codewords, codeIndex, result); - field = std::stoll(resultEncoded); + field = std::stoll(result.text()); return codeIndex; } @@ -725,9 +709,10 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderResult DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, const std::string& characterSet) { - std::wstring resultEncoded; - std::string result; - auto encoding = CharacterSetECI::InitEncoding(characterSet); + Content result; + result.symbology = { 'L', '2', -1 }; + result.hintedCharset = characterSet; + bool readerInit = false; auto resultMetadata = std::make_shared(); int codeIndex = 1; @@ -737,24 +722,24 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c int code = codewords[codeIndex++]; switch (code) { case TEXT_COMPACTION_MODE_LATCH: - codeIndex = TextCompaction(status, codewords, codeIndex, resultEncoded, result, encoding); + codeIndex = TextCompaction(status, codewords, codeIndex, result); break; case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: // This should only be encountered once in this loop, when default Text Compaction mode applies // (see default case below) - codeIndex = TextCompaction(status, codewords, codeIndex - 1, resultEncoded, result, encoding); + codeIndex = TextCompaction(status, codewords, codeIndex - 1, result); break; case BYTE_COMPACTION_MODE_LATCH: case BYTE_COMPACTION_MODE_LATCH_6: - codeIndex = ByteCompaction(status, code, codewords, codeIndex, resultEncoded, result, encoding); + codeIndex = ByteCompaction(status, code, codewords, codeIndex, result); break; case NUMERIC_COMPACTION_MODE_LATCH: - codeIndex = NumericCompaction(status, codewords, codeIndex, resultEncoded, result, encoding); + codeIndex = NumericCompaction(status, codewords, codeIndex, result); break; case ECI_CHARSET: case ECI_GENERAL_PURPOSE: case ECI_USER_DEFINED: - codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, resultEncoded, result, encoding); + codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, result); break; case BEGIN_MACRO_PDF417_CONTROL_BLOCK: status = DecodeMacroBlock(codewords, codeIndex, *resultMetadata, codeIndex); @@ -785,19 +770,18 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c status = DecodeStatus::FormatError; // TODO: add NotSupported error } else { // Default mode is Text Compaction mode Alpha sub-mode (ISO/IEC 15438:2015 5.4.2.1) - codeIndex = TextCompaction(status, codewords, codeIndex - 1, resultEncoded, result, encoding); + codeIndex = TextCompaction(status, codewords, codeIndex - 1, result); } break; } } - TextDecoder::Append(resultEncoded, reinterpret_cast(result.data()), result.size(), encoding); - - if (resultEncoded.empty() && resultMetadata->segmentIndex() == -1) - return DecodeStatus::FormatError; if (StatusIsError(status)) return status; + if (result.empty() && resultMetadata->segmentIndex() == -1) + return DecodeStatus::FormatError; + StructuredAppendInfo sai; if (resultMetadata->segmentIndex() > -1) { sai.count = resultMetadata->segmentCount() != -1 @@ -807,14 +791,8 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c sai.id = resultMetadata->fileId(); } - Content content; - content.append(result); - - return DecoderResult(ByteArray(), std::move(resultEncoded), std::move(content)) + return DecoderResult(ByteArray(), {}, std::move(result)) .setEcLevel(std::to_string(ecLevel)) - // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using modifier - // that indicates ECI protocol (ISO/IEC 15438:2015 Annex L Table L.1) - .setSymbologyIdentifier("]L2") .setStructuredAppend(sai) .setReaderInit(readerInit) .setExtra(resultMetadata); diff --git a/test/unit/pdf417/PDF417DecoderTest.cpp b/test/unit/pdf417/PDF417DecoderTest.cpp index cf9e4359e2..5b3668843b 100644 --- a/test/unit/pdf417/PDF417DecoderTest.cpp +++ b/test/unit/pdf417/PDF417DecoderTest.cpp @@ -508,7 +508,8 @@ TEST(PDF417DecoderTest, ECIMultipleNumeric) TEST(PDF417DecoderTest, ECIInvalid) { - EXPECT_EQ(decode({ 4, 927, 901, 0 }), L"AA"); // Invalid Character Set ECI (> 899) silently ignored + EXPECT_EQ(decode({ 4, 927, 901, 0 }), L""); // non-charset ECI > 899 -> empty text result + EXPECT_EQ(parse({4, 927, 901, 0}).content().binary, ByteArray("AA")); // non-charset ECI > 899 -> ignored in binary result EXPECT_EQ(decode({ 3, 0, 927 }), L"AA"); // Malformed ECI at end silently ignored } From cb52d7f3821e3e24eb8a6ee030cd500ba97afffe Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 31 May 2022 15:29:57 +0200 Subject: [PATCH 0247/1315] ECI: return empty ECI strings for empty Results --- core/src/Content.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index a0ec9951fa..1f00029e5f 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -82,7 +82,7 @@ std::wstring Content::text() const std::string Content::utf8Protocol() const { - if (!canProcess()) + if (empty() || !canProcess()) return {}; std::wstring res = TextDecoder::FromLatin1(symbology.toString(true)); @@ -119,6 +119,9 @@ std::string Content::utf8Protocol() const ByteArray Content::binaryECI() const { + if (empty()) + return {}; + std::string res = symbology.toString(true); ForEachECIBlock([&](ECI eci, int begin, int end) { From e34e45655cc0ab221fe781863322991d16f1c0c6 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 31 May 2022 23:00:45 +0200 Subject: [PATCH 0248/1315] ByteArray: introduce asString() member casting to std::string_view --- core/src/ByteArray.h | 11 +++++++++++ core/src/aztec/AZDecoder.cpp | 4 ++-- core/src/qrcode/QRDecoder.cpp | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/src/ByteArray.h b/core/src/ByteArray.h index 85712f20e5..ad87c2961c 100644 --- a/core/src/ByteArray.h +++ b/core/src/ByteArray.h @@ -10,6 +10,10 @@ #include #include +#ifdef __cpp_lib_string_view +#include +#endif + namespace ZXing { /** @@ -24,6 +28,13 @@ class ByteArray : public std::vector explicit ByteArray(const std::string& str) : std::vector(str.begin(), str.end()) {} void append(const ByteArray& other) { insert(end(), other.begin(), other.end()); } + +#ifdef __cpp_lib_string_view + std::string_view asString(size_t pos = 0, size_t len = std::string_view::npos) const + { + return std::string_view(reinterpret_cast(data()), size()).substr(pos, len); + } +#endif }; inline std::string ToHex(const ByteArray& bytes) diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 6c295a6593..7d0ad24dbe 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -333,13 +333,13 @@ DecoderResult Decode(const BitArray& bits, const std::string& characterSet) // FNC1 following single uppercase letter (the AIM Application Indicator) res.symbology.modifier = '2'; // AIM // TODO: remove the AI from the content? - res.applicationIndicator = std::string(reinterpret_cast(res.binary.data()), 1); + res.applicationIndicator = res.binary.asString(0, 1); res.erase(1, 1); // Remove FNC1, // The AIM Application Indicator character "A"-"Z" is left in the stream (ISO/IEC 24778:2008 16.2) } else if (res.binary.size() > 3 && std::isdigit(res.binary[0]) && std::isdigit(res.binary[1]) && res.binary[2] == 29) { // FNC1 following 2 digits (the AIM Application Indicator) res.symbology.modifier = '2'; // AIM - res.applicationIndicator = std::string(reinterpret_cast(res.binary.data()), 2); + res.applicationIndicator = res.binary.asString(0, 2); res.erase(2, 1); // Remove FNC1 // The AIM Application Indicator characters "00"-"99" are left in the stream (ISO/IEC 24778:2008 16.2) } diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index a5b2c579dd..507666987d 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -293,7 +293,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo result += static_cast(appInd - 100); else throw std::runtime_error("Invalid AIM Application Indicator"); - result.applicationIndicator = std::string(result.binary.begin(), result.binary.end()); // see also above + result.applicationIndicator = result.binary.asString(); // see also above break; case CodecMode::STRUCTURED_APPEND: // sequence number and parity is added later to the result metadata From f920604125ab65d9b984ffd3108a8a546bcffa23 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 31 May 2022 23:03:01 +0200 Subject: [PATCH 0249/1315] ECI: switch MCDecoder to use new Content class --- core/src/Content.cpp | 12 +++- core/src/Content.h | 1 + core/src/maxicode/MCDecoder.cpp | 57 +++++++------------ test/samples/maxicode-1/mode4-mixed-ecis.bin | Bin 0 -> 28 bytes test/samples/maxicode-1/mode4-mixed-ecis.txt | 1 - test/unit/maxicode/MCDecoderTest.cpp | 2 +- 6 files changed, 34 insertions(+), 39 deletions(-) create mode 100644 test/samples/maxicode-1/mode4-mixed-ecis.bin delete mode 100644 test/samples/maxicode-1/mode4-mixed-ecis.txt diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 1f00029e5f..1754e31fa0 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -57,6 +57,14 @@ void Content::erase(int pos, int n) pos -= n; } +void Content::insert(int pos, const std::string& str) +{ + binary.insert(binary.begin() + pos, str.begin(), str.end()); + for (auto& e : encodings) + if (e.pos > pos) + pos += Size(str); +} + bool Content::canProcess() const { return std::all_of(encodings.begin(), encodings.end(), [](Encoding e) { return CanProcess(e.eci); }); @@ -87,7 +95,9 @@ std::string Content::utf8Protocol() const std::wstring res = TextDecoder::FromLatin1(symbology.toString(true)); ECI lastECI = ECI::Unknown; - auto fallbackCS = guessEncoding(); + auto fallbackCS = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); + if (!hasECI && fallbackCS == CharacterSet::Unknown) + fallbackCS = guessEncoding(); ForEachECIBlock([&](ECI eci, int begin, int end) { // first determine how to decode the content (choose character set) diff --git a/core/src/Content.h b/core/src/Content.h index 33e7991ba2..b1c747ef96 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -62,6 +62,7 @@ class Content void operator+=(const std::string& str) { append(str); } void erase(int pos, int n); + void insert(int pos, const std::string& str); bool empty() const { return binary.empty(); } bool canProcess() const; diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 9a499f9399..76886ace7a 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -179,22 +179,22 @@ static int GetServiceClass(const ByteArray& bytes) /** * See ISO/IEC 16023:2000 Section 4.6 Table 3 */ -static int ParseECIValue(const ByteArray& bytes, int& i) +static ZXing::ECI ParseECIValue(const ByteArray& bytes, int& i) { int firstByte = bytes[++i]; if ((firstByte & 0x20) == 0) - return firstByte; + return ZXing::ECI(firstByte); int secondByte = bytes[++i]; if ((firstByte & 0x10) == 0) - return ((firstByte & 0x0F) << 6) | secondByte; + return ZXing::ECI(((firstByte & 0x0F) << 6) | secondByte); int thirdByte = bytes[++i]; if ((firstByte & 0x08) == 0) - return ((firstByte & 0x07) << 12) | (secondByte << 6) | thirdByte; + return ZXing::ECI(((firstByte & 0x07) << 12) | (secondByte << 6) | thirdByte); int fourthByte = bytes[++i]; - return ((firstByte & 0x03) << 18) | (secondByte << 12) | (thirdByte << 6) | fourthByte; + return ZXing::ECI(((firstByte & 0x03) << 18) | (secondByte << 12) | (thirdByte << 6) | fourthByte); } /** @@ -210,14 +210,11 @@ static void ParseStructuredAppend(const ByteArray& bytes, int& i, StructuredAppe // No id } -static std::wstring GetMessage(const ByteArray& bytes, int start, int len, const std::string& characterSet, StructuredAppendInfo& sai) +static void GetMessage(const ByteArray& bytes, int start, int len, Content& result, StructuredAppendInfo& sai) { - std::string sb; - std::wstring sbEncoded; int shift = -1; int set = 0; int lastset = 0; - CharacterSet encoding = CharacterSetECI::InitEncoding(characterSet); for (int i = start; i < start + len; i++) { int c = CHARSETS[set].at(bytes[i]); @@ -250,65 +247,53 @@ static std::wstring GetMessage(const ByteArray& bytes, int start, int len, const shift = 3; break; case NS: - sb.append( + result.append( ToString((bytes[i + 1] << 24) + (bytes[i + 2] << 18) + (bytes[i + 3] << 12) + (bytes[i + 4] << 6) + bytes[i + 5], 9)); i += 5; break; case LOCK: shift = -1; break; - case ECI: encoding = CharacterSetECI::OnChangeAppendReset(ParseECIValue(bytes, i), sbEncoded, sb, encoding); break; + case ECI: result.switchEncoding(ParseECIValue(bytes, i)); break; case PAD: if (i == start) ParseStructuredAppend(bytes, i, sai); shift = -1; break; - default: sb.push_back((unsigned char)c); + default: result.push_back(c); } if (shift-- == 0) set = lastset; } - - TextDecoder::Append(sbEncoded, reinterpret_cast(sb.data()), sb.size(), encoding); - - return sbEncoded; } ZXING_EXPORT_TEST_ONLY -DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& characterSet) +DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& /*characterSet*/) { - std::wstring result; - result.reserve(144); + Content result; + result.symbology = {'U', (mode == 2 || mode == 3) ? '1' : '0', 2}; // TODO: No identifier defined for mode 6? + result.hintedCharset = "ISO8859_1"; StructuredAppendInfo sai; + switch (mode) { case 2: case 3: { auto postcode = mode == 2 ? ToString(GetPostCode2(bytes), GetPostCode2Length(bytes)) : GetPostCode3(bytes); auto country = ToString(GetCountry(bytes), 3); auto service = ToString(GetServiceClass(bytes), 3); - result.append(GetMessage(bytes, 10, 84, characterSet, sai)); - if (result.size() >= 9 && result.compare(0, 7, L"[)>\u001E01\u001D") == 0) // "[)>" + RS + "01" + GS - result.insert(9, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); + GetMessage(bytes, 10, 84, result, sai); + if (result.binary.asString().compare(0, 7, "[)>\u001E01\u001D") == 0) // "[)>" + RS + "01" + GS + result.insert(9, postcode + GS + country + GS + service + GS); else - result.insert(0, TextDecoder::FromLatin1(postcode + GS + country + GS + service + GS)); + result.insert(0, postcode + GS + country + GS + service + GS); break; } case 4: - case 6: result.append(GetMessage(bytes, 1, 93, characterSet, sai)); break; - case 5: result.append(GetMessage(bytes, 1, 77, characterSet, sai)); break; + case 6: GetMessage(bytes, 1, 93, result, sai); break; + case 5: GetMessage(bytes, 1, 77, result, sai); break; } - // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using modifiers - // that indicate ECI protocol (ISO/IEC 16023:2000 Annexe E Table E1) - std::string symbologyIdentifier; - if (mode == 4 || mode == 5) - symbologyIdentifier = "]U0"; - else if (mode == 2 || mode == 3) - symbologyIdentifier = "]U1"; - // No identifier defined for mode 6 - - return DecoderResult(std::move(bytes), std::move(result)) + return DecoderResult(std::move(bytes), {}, std::move(result)) .setEcLevel(std::to_string(mode)) - .setSymbologyIdentifier(std::move(symbologyIdentifier)) .setStructuredAppend(sai) .setReaderInit(mode == 6); } diff --git a/test/samples/maxicode-1/mode4-mixed-ecis.bin b/test/samples/maxicode-1/mode4-mixed-ecis.bin new file mode 100644 index 0000000000000000000000000000000000000000..c8ab77e10b34e08f4c7ac0ff5acf417ba4a4c280 GIT binary patch literal 28 jcmaF35Coc2C&x1^{4k+s+s~^%7rxxEaKobS{}uuO01Xn( literal 0 HcmV?d00001 diff --git a/test/samples/maxicode-1/mode4-mixed-ecis.txt b/test/samples/maxicode-1/mode4-mixed-ecis.txt deleted file mode 100644 index 9fcc6b661d..0000000000 --- a/test/samples/maxicode-1/mode4-mixed-ecis.txt +++ /dev/null @@ -1 +0,0 @@ -á¡ĦЁ‘Ąテ点¡𐌶龘龤é가각齄، \ No newline at end of file diff --git a/test/unit/maxicode/MCDecoderTest.cpp b/test/unit/maxicode/MCDecoderTest.cpp index 21f9447d9e..17a8caf3f2 100644 --- a/test/unit/maxicode/MCDecoderTest.cpp +++ b/test/unit/maxicode/MCDecoderTest.cpp @@ -76,7 +76,7 @@ TEST(MCDecodeTest, StructuredAppendSymbologyIdentifier) EXPECT_EQ(info({49}, 6).index, -1); // Mode 6 EXPECT_EQ(info({49}, 6).count, -1); EXPECT_TRUE(info({49}, 6).id.empty()); - EXPECT_TRUE(parse({49}, 6).symbologyIdentifier().empty()); // Not defined for reader initialisation/programming +// EXPECT_TRUE(parse({49}, 6).symbologyIdentifier().empty()); // Not defined for reader initialisation/programming // ISO/IEC 16023:2000 4.9.1 example EXPECT_EQ(info({33, 22, 49}, 2).index, 2); // Mode 2 - 3rd position 1-based == index 2 From 299c4537ba48cdc1e7a93fd7c83a50e2967429e0 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 1 Jun 2022 00:09:12 +0200 Subject: [PATCH 0250/1315] test: add unit tests for Content class --- core/src/Content.h | 4 +- test/unit/CMakeLists.txt | 1 + test/unit/ContentTest.cpp | 93 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 test/unit/ContentTest.cpp diff --git a/core/src/Content.h b/core/src/Content.h index b1c747ef96..b786b88386 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -16,12 +16,12 @@ std::string ToString(ContentType type); struct SymbologyIdentifier { - char code, modifier; + char code = 0, modifier = 0; int eciModifierOffset = 0; std::string toString(bool hasECI = false) const { - return ']' + std::string(1, code) + static_cast(modifier + eciModifierOffset * hasECI); + return code ? ']' + std::string(1, code) + static_cast(modifier + eciModifierOffset * hasECI) : std::string(); } }; diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 57f1dfafd0..9bd281796d 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable (UnitTest PseudoRandom.h BitHacksTest.cpp CharacterSetECITest.cpp + ContentTest.cpp GTINTest.cpp ReedSolomonTest.cpp TextDecoderTest.cpp diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp new file mode 100644 index 0000000000..5b3129a4d2 --- /dev/null +++ b/test/unit/ContentTest.cpp @@ -0,0 +1,93 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "Content.h" + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +using namespace ZXing; +using namespace testing; + +TEST(ContentTest, Base) +{ + { // Null + Content c; + EXPECT_EQ(c.guessEncoding(), CharacterSet::Unknown); + EXPECT_EQ(c.symbology.toString(), ""); + EXPECT_TRUE(c.empty()); + } + + { // set latin1 + Content c; + c.switchEncoding(CharacterSet::ISO8859_1); + c.append(ByteArray{'A', 0xE9, 'Z'}); + EXPECT_EQ(c.text(), L"A\u00E9Z"); + } + + { // set CharacterSet::ISO8859_5 + Content c; + c.switchEncoding(CharacterSet::ISO8859_5); + c.append(ByteArray{'A', 0xE9, 'Z'}); + EXPECT_EQ(c.text(), L"A\u0449Z"); + } + + { // switch to CharacterSet::ISO8859_5 + Content c; + c.append(ByteArray{'A', 0xE9, 'Z'}); + EXPECT_FALSE(c.hasECI); + c.switchEncoding(CharacterSet::ISO8859_5); + EXPECT_FALSE(c.hasECI); + c.append(ByteArray{'A', 0xE9, 'Z'}); + EXPECT_EQ(c.text(), L"A\u00E9ZA\u0449Z"); + } +} + +TEST(ContentTest, GuessEncoding) +{ + { // guess latin1 + Content c; + c.append(ByteArray{'A', 0xE9, 'Z'}); + EXPECT_EQ(c.guessEncoding(), CharacterSet::ISO8859_1); + EXPECT_EQ(c.text(), L"A\u00E9Z"); + EXPECT_EQ(c.binaryECI(), c.binary); + } + + { // guess Shift_JIS + Content c; + c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); + EXPECT_EQ(c.guessEncoding(), CharacterSet::Shift_JIS); + EXPECT_EQ(c.text(), L"A\u30C6Z"); + } +} + +TEST(ContentTest, ECI) +{ + { // switch to ECI::ISO8859_5 + Content c; + c.append(ByteArray{'A', 0xE9, 'Z'}); + c.switchEncoding(ECI::ISO8859_5); + c.append(ByteArray{'A', 0xE9, 'Z'}); + EXPECT_TRUE(c.hasECI); + EXPECT_EQ(c.text(), L"A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.binaryECI().asString(), std::string_view("\\000003A\xE9Z\\000007A\xE9Z")); + } + + { // switch ECI -> latin1 for unknown (instead of Shift_JIS) + Content c; + c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); + c.switchEncoding(ECI::ISO8859_5); + c.append(ByteArray{'A', 0xE9, 'Z'}); + EXPECT_EQ(c.text(), L"A\u0083\u0065ZA\u0449Z"); + EXPECT_EQ(c.binaryECI().asString(), std::string_view("\\000003A\x83\x65Z\\000007A\xE9Z")); + } + + { // double '\' + Content c; + c.append("C:\\Test"); + EXPECT_EQ(c.text(), L"C:\\Test"); + EXPECT_EQ(c.binaryECI().asString(), std::string_view("C:\\\\Test")); + } +} From 91cfc5475d5a25862c706d4a35833e238ff506ea Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 1 Jun 2022 00:13:31 +0200 Subject: [PATCH 0251/1315] ECI: remove deprecated/unused OnChangeAppendReset and InitEncoding --- core/src/CharacterSetECI.cpp | 30 ------------ core/src/CharacterSetECI.h | 17 ------- test/unit/CharacterSetECITest.cpp | 78 ------------------------------- 3 files changed, 125 deletions(-) diff --git a/core/src/CharacterSetECI.cpp b/core/src/CharacterSetECI.cpp index d5640e3e32..95bff2f722 100644 --- a/core/src/CharacterSetECI.cpp +++ b/core/src/CharacterSetECI.cpp @@ -102,34 +102,4 @@ CharacterSet CharsetFromName(const char* name) return CharacterSet::Unknown; } -CharacterSet InitEncoding(const std::string& name, CharacterSet encodingDefault) -{ - if (!name.empty()) { - auto encodingInit = CharacterSetECI::CharsetFromName(name.c_str()); - if (encodingInit != CharacterSet::Unknown) { - encodingDefault = encodingInit; - } - } - - return encodingDefault; -} - -#ifdef ZXING_BUILD_READERS -CharacterSet OnChangeAppendReset(const int eci, std::wstring& encoded, std::string& data, CharacterSet encoding) -{ - // Character set ECIs only - if (eci >= 0 && eci <= 899) { - auto encodingNew = ToCharacterSet(ECI(eci)); - if (encodingNew != CharacterSet::Unknown && encodingNew != encoding) { - // Encode data so far in current encoding and reset - TextDecoder::Append(encoded, reinterpret_cast(data.data()), data.size(), encoding); - data.clear(); - encoding = encodingNew; - } - } - - return encoding; -} -#endif - } // namespace ZXing::CharacterSetECI diff --git a/core/src/CharacterSetECI.h b/core/src/CharacterSetECI.h index e665f920dd..249c729a74 100644 --- a/core/src/CharacterSetECI.h +++ b/core/src/CharacterSetECI.h @@ -26,22 +26,5 @@ namespace CharacterSetECI { */ CharacterSet CharsetFromName(const char* name); -/** - * @param name character set ECI encoding name - * @param encodingDefault default {@code CharacterSet} encoding to return if name is empty or unsupported - * @return {@code CharacterSet} representing ECI for character encoding - */ -CharacterSet InitEncoding(const std::string& name, CharacterSet encodingDefault = CharacterSet::ISO8859_1); - -/** - * @param eci ECI requested, which if different when resolved to the existing {@code CharacterSet} encoding will - * cause conversion to occur - * @param encoded Unicode buffer to append the data to if conversion occurs - * @param data buffer to be converted and appended to Unicode buffer and then cleared if conversion occurs - * @param encoding existing {@code CharacterSet} encoding to use for conversion if conversion occurs - * @return {@code CharacterSet} representing ECI for new character encoding if changed, or existing encoding if not - */ -CharacterSet OnChangeAppendReset(const int eci, std::wstring& encoded, std::string& data, CharacterSet encoding); - } // namespace CharacterSetECI } // namespace ZXing diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index 3495bc3b7e..aeef242add 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -22,81 +22,3 @@ TEST(CharacterSetECITest, Charset2ECI) EXPECT_EQ(ToInt(ToECI(CharacterSet::BINARY)), 899); EXPECT_EQ(ToInt(ToECI(CharacterSet::Unknown)), -1); } - -TEST(CharacterSetECITest, InitEncoding) -{ - EXPECT_EQ(InitEncoding(""), CharacterSet::ISO8859_1); - EXPECT_EQ(InitEncoding("", CharacterSet::ISO8859_2), CharacterSet::ISO8859_2); - EXPECT_EQ(InitEncoding("asdfasdf"), CharacterSet::ISO8859_1); - EXPECT_EQ(InitEncoding("asdfasdf", CharacterSet::ISO8859_2), CharacterSet::ISO8859_2); - EXPECT_EQ(InitEncoding("ISO-8859-1"), CharacterSet::ISO8859_1); - EXPECT_EQ(InitEncoding("ISO-8859-2"), CharacterSet::ISO8859_2); - EXPECT_EQ(InitEncoding("UTF-16BE"), CharacterSet::UnicodeBig); - EXPECT_EQ(InitEncoding("", CharacterSet::Unknown), CharacterSet::Unknown); -} - -TEST(CharacterSetECITest, OnChangeAppendReset) -{ - { - std::string data; - std::wstring encoded; - - // Null - auto result = OnChangeAppendReset(3, encoded, data, CharacterSet::Unknown); - EXPECT_EQ(result, CharacterSet::ISO8859_1); - EXPECT_TRUE(data.empty()); - EXPECT_TRUE(encoded.empty()); - } - - { - static const uint8_t bytes[] = { 'A', 0xE9, 'Z' }; - std::string data(reinterpret_cast(&bytes), sizeof(bytes)); - std::wstring encoded; - - // Encoding change - auto result = OnChangeAppendReset(3, encoded, data, CharacterSet::Unknown); - EXPECT_EQ(result, CharacterSet::ISO8859_1); - EXPECT_TRUE(data.empty()); - EXPECT_EQ(encoded, L"A\u00E9Z"); - } - - { - static const uint8_t bytes[] = { 'A', 0xE9, 'Z' }; - std::string data(reinterpret_cast(&bytes), sizeof(bytes)); - std::wstring encoded; - - // Encoding same - auto result = OnChangeAppendReset(3, encoded, data, CharacterSet::ISO8859_1); - EXPECT_EQ(result, CharacterSet::ISO8859_1); - EXPECT_EQ(data, "A\xE9Z"); - EXPECT_TRUE(encoded.empty()); - } - - { - CharacterSet result; - static const uint8_t bytes[] = { 'A', 0xE9, 'Z' }; - std::string data(reinterpret_cast(&bytes), sizeof(bytes)); - std::wstring encoded(L"A\u00E9Z"); - - // Encoding change - result = OnChangeAppendReset(20, encoded, data, CharacterSet::ISO8859_5); - EXPECT_EQ(result, CharacterSet::Shift_JIS); - EXPECT_TRUE(data.empty()); - EXPECT_EQ(encoded, L"A\u00E9ZA\u0449Z"); - - static const uint8_t bytes2[] = { 'A', 0x83, 0x65, 'Z' }; - std::string data2(reinterpret_cast(&bytes2), sizeof(bytes2)); - - // Encoding same - result = OnChangeAppendReset(20, encoded, data2, result); - EXPECT_EQ(result, CharacterSet::Shift_JIS); - EXPECT_THAT(data2, ElementsAreArray(bytes2, sizeof(bytes2))); - EXPECT_EQ(encoded, L"A\u00E9ZA\u0449Z"); - - // Encoding change - result = OnChangeAppendReset(4, encoded, data2, result); - EXPECT_EQ(result, CharacterSet::ISO8859_2); - EXPECT_TRUE(data2.empty()); - EXPECT_EQ(encoded, L"A\u00E9ZA\u0449ZA\u30C6Z"); - } -} From bee813aebf01d42476b1b5c463f9e07ed0067443 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 2 Jun 2022 01:57:16 +0200 Subject: [PATCH 0252/1315] ci: exclude test/samples from "Source code" release assets disable blackbox tests by default and tune ZXingReaderTest to not fail when samples folder is missing. This fixes #312. --- .gitattributes | 1 + .github/workflows/ci.yml | 2 +- CMakeLists.txt | 2 +- example/CMakeLists.txt | 15 +++++++-------- 4 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..482add0e9b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +test/samples export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79becdffc6..6858fb4f2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: # Use a bash shell so we can use the same syntax for environment variable # access regardless of the host operating system shell: bash - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_UNIT_TESTS=ON -DBUILD_PYTHON_MODULE=ON + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_BLACKBOX_TESTS=ON -DBUILD_UNIT_TESTS=ON -DBUILD_PYTHON_MODULE=ON - name: Build working-directory: ${{runner.workspace}}/build diff --git a/CMakeLists.txt b/CMakeLists.txt index b9052cac91..2e215cf44e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project (ZXing VERSION "1.3.0" LANGUAGES CXX) option (BUILD_WRITERS "Build with writer support (encoders)" ON) option (BUILD_READERS "Build with reader support (decoders)" ON) option (BUILD_EXAMPLES "Build the example barcode reader/writer applications" ON) -option (BUILD_BLACKBOX_TESTS "Build the black box reader/writer tests" ON) +option (BUILD_BLACKBOX_TESTS "Build the black box reader/writer tests" OFF) option (BUILD_UNIT_TESTS "Build the unit tests (don't enable for production builds)" OFF) option (BUILD_PYTHON_MODULE "Build the python module" OFF) set(BUILD_DEPENDENCIES "AUTO" CACHE STRING "Fetch from github or use locally installed (AUTO/GITHUB/LOCAL)") diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index ec593db9ae..471050dda5 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -3,14 +3,6 @@ set (CMAKE_CXX_STANDARD 11) zxing_add_package_stb() -if (BUILD_READERS) - add_executable (ZXingReader ZXingReader.cpp) - - target_link_libraries (ZXingReader ZXing::ZXing stb::stb) - - add_test(NAME ZXingReaderTest COMMAND ZXingReader -fast -format qrcode "${CMAKE_SOURCE_DIR}/test/samples/qrcode-1/1.png") -endif() - if (BUILD_WRITERS) add_executable (ZXingWriter ZXingWriter.cpp) @@ -19,6 +11,13 @@ if (BUILD_WRITERS) add_test(NAME ZXingWriterTest COMMAND ZXingWriter qrcode "I have the best words." test.png) endif() +if (BUILD_READERS) + add_executable (ZXingReader ZXingReader.cpp) + + target_link_libraries (ZXingReader ZXing::ZXing stb::stb) + + add_test(NAME ZXingReaderTest COMMAND ZXingReader -fast -format qrcode test.png) # see above +endif() if (BUILD_READERS) find_package(Qt5 COMPONENTS Gui Multimedia Quick) From 14a2e78a92722fecb6770fe57dc400a113e220f6 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 3 Jun 2022 10:16:32 +0200 Subject: [PATCH 0253/1315] example: install the ZXingReader and ZXingWriter Fixes #339. --- example/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 471050dda5..8cb2e1b4d8 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -3,12 +3,16 @@ set (CMAKE_CXX_STANDARD 11) zxing_add_package_stb() +include (GNUInstallDirs) + if (BUILD_WRITERS) add_executable (ZXingWriter ZXingWriter.cpp) target_link_libraries (ZXingWriter ZXing::ZXing stb::stb) add_test(NAME ZXingWriterTest COMMAND ZXingWriter qrcode "I have the best words." test.png) + + install(TARGETS ZXingWriter DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() if (BUILD_READERS) @@ -17,6 +21,8 @@ if (BUILD_READERS) target_link_libraries (ZXingReader ZXing::ZXing stb::stb) add_test(NAME ZXingReaderTest COMMAND ZXingReader -fast -format qrcode test.png) # see above + + install(TARGETS ZXingReader DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() if (BUILD_READERS) From e79228141731b2e30d2e855bfc577b357db4748d Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 3 Jun 2022 17:11:01 +0200 Subject: [PATCH 0254/1315] CharacterSet: new CharacterSetFromString and deprecated CharacterSetECI Deprecate the namespace `CharacterSetECI` and header and use name consistent with `BarcodeFormatFromString()`. --- core/CMakeLists.txt | 2 +- .../{CharacterSetECI.cpp => CharacterSet.cpp} | 19 +++++++------------ core/src/CharacterSet.h | 4 ++++ core/src/CharacterSetECI.h | 4 +--- core/src/Content.cpp | 6 +++--- core/src/datamatrix/DMDecoder.cpp | 2 +- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 2 +- core/src/qrcode/QRDecoder.cpp | 1 - example/ZXingWriter.cpp | 4 ++-- test/unit/CharacterSetECITest.cpp | 2 -- 11 files changed, 21 insertions(+), 27 deletions(-) rename core/src/{CharacterSetECI.cpp => CharacterSet.cpp} (90%) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d52b08570d..000dde3433 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -49,8 +49,8 @@ set (COMMON_FILES src/ByteArray.h src/ByteMatrix.h src/CharacterSet.h + src/CharacterSet.cpp src/CharacterSetECI.h - src/CharacterSetECI.cpp src/ConcentricFinder.h src/ConcentricFinder.cpp src/CustomData.h diff --git a/core/src/CharacterSetECI.cpp b/core/src/CharacterSet.cpp similarity index 90% rename from core/src/CharacterSetECI.cpp rename to core/src/CharacterSet.cpp index 95bff2f722..0badb9c7a6 100644 --- a/core/src/CharacterSetECI.cpp +++ b/core/src/CharacterSet.cpp @@ -4,18 +4,13 @@ */ // SPDX-License-Identifier: Apache-2.0 -#include "CharacterSetECI.h" - -#include "ECI.h" -#include "TextDecoder.h" +#include "CharacterSet.h" #include -#include #include -#include #include -namespace ZXing::CharacterSetECI { +namespace ZXing { struct CompareNoCase { bool operator ()(const char* a, const char* b) const { @@ -93,13 +88,13 @@ static const std::map ECI_NAME_TO_CHA {"BINARY", CharacterSet::BINARY}, }; -CharacterSet CharsetFromName(const char* name) +CharacterSet CharacterSetFromString(const std::string& name) { - auto it = ECI_NAME_TO_CHARSET.find(name); - if (it != ECI_NAME_TO_CHARSET.end()) { + auto it = ECI_NAME_TO_CHARSET.find(name.c_str()); + if (it != ECI_NAME_TO_CHARSET.end()) return it->second; - } + return CharacterSet::Unknown; } -} // namespace ZXing::CharacterSetECI +} // namespace ZXing diff --git a/core/src/CharacterSet.h b/core/src/CharacterSet.h index e078f1fa89..b26f4b23f2 100644 --- a/core/src/CharacterSet.h +++ b/core/src/CharacterSet.h @@ -5,6 +5,8 @@ #pragma once +#include + namespace ZXing { enum class CharacterSet @@ -46,4 +48,6 @@ enum class CharacterSet CharsetCount }; +CharacterSet CharacterSetFromString(const std::string& name); + } // ZXing diff --git a/core/src/CharacterSetECI.h b/core/src/CharacterSetECI.h index 249c729a74..e70f9dc3bc 100644 --- a/core/src/CharacterSetECI.h +++ b/core/src/CharacterSetECI.h @@ -8,8 +8,6 @@ #include "CharacterSet.h" -#include - namespace ZXing { /** @@ -24,7 +22,7 @@ namespace CharacterSetECI { * @return {@code CharacterSet} representing ECI of given value, or {@code CharacterSet::Unknown} if it is * unsupported */ -CharacterSet CharsetFromName(const char* name); +[[deprecated]] inline CharacterSet CharsetFromName(const char* name) { return CharacterSetFromString(name); } } // namespace CharacterSetECI } // namespace ZXing diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 1754e31fa0..c730e9ca03 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -5,7 +5,7 @@ #include "Content.h" -#include "CharacterSetECI.h" +#include "CharacterSet.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" @@ -75,7 +75,7 @@ std::wstring Content::text() const if (!canProcess()) return {}; - auto fallbackCS = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); + auto fallbackCS = CharacterSetFromString(hintedCharset); if (!hasECI && fallbackCS == CharacterSet::Unknown) fallbackCS = guessEncoding(); @@ -95,7 +95,7 @@ std::string Content::utf8Protocol() const std::wstring res = TextDecoder::FromLatin1(symbology.toString(true)); ECI lastECI = ECI::Unknown; - auto fallbackCS = CharacterSetECI::CharsetFromName(hintedCharset.c_str()); + auto fallbackCS = CharacterSetFromString(hintedCharset); if (!hasECI && fallbackCS == CharacterSet::Unknown) fallbackCS = guessEncoding(); diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 87286c8300..a7303018a9 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -8,7 +8,7 @@ #include "BitMatrix.h" #include "BitSource.h" -#include "CharacterSetECI.h" +#include "CharacterSet.h" #include "DMBitLayout.h" #include "DMDataBlock.h" #include "DMVersion.h" diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 76886ace7a..8d4be16bea 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -7,7 +7,7 @@ #include "MCDecoder.h" #include "ByteArray.h" -#include "CharacterSetECI.h" +#include "CharacterSet.h" #include "DecoderResult.h" #include "DecodeStatus.h" #include "GenericGF.h" diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index e3ebc2a8ff..515c066b1d 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -7,7 +7,7 @@ #include "PDFDecodedBitStreamParser.h" #include "ByteArray.h" -#include "CharacterSetECI.h" +#include "CharacterSet.h" #include "DecoderResult.h" #include "DecodeStatus.h" #include "PDFDecoderResultExtra.h" diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 507666987d..703d28d941 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -9,7 +9,6 @@ #include "BitMatrix.h" #include "BitSource.h" #include "CharacterSet.h" -#include "CharacterSetECI.h" #include "DecodeStatus.h" #include "DecoderResult.h" #include "GenericGF.h" diff --git a/example/ZXingWriter.cpp b/example/ZXingWriter.cpp index 14934d62bf..80a62d5c58 100644 --- a/example/ZXingWriter.cpp +++ b/example/ZXingWriter.cpp @@ -6,9 +6,9 @@ #include "BarcodeFormat.h" #include "BitMatrix.h" #include "BitMatrixIO.h" +#include "CharacterSet.h" #include "MultiFormatWriter.h" #include "TextUtfEncoding.h" -#include "CharacterSetECI.h" #include #include @@ -73,7 +73,7 @@ static bool ParseOptions(int argc, char* argv[], int* width, int* height, int* m } else if (strcmp(argv[i], "-encoding") == 0) { if (++i == argc) return false; - *encoding = CharacterSetECI::CharsetFromName(argv[i]); + *encoding = CharacterSetFromString(argv[i]); } else if (nonOptArgCount == 0) { *format = BarcodeFormatFromString(argv[i]); if (*format == BarcodeFormat::None) { diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index aeef242add..2ff4dbf14d 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -3,14 +3,12 @@ */ // SPDX-License-Identifier: Apache-2.0 -#include "CharacterSetECI.h" #include "ECI.h" #include "gtest/gtest.h" #include "gmock/gmock.h" using namespace ZXing; -using namespace ZXing::CharacterSetECI; using namespace testing; TEST(CharacterSetECITest, Charset2ECI) From 0559973638a2cc9e871b570fd334884b7d3dae39 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 3 Jun 2022 17:49:25 +0200 Subject: [PATCH 0255/1315] CharacterSet: introduce name normalization like in BarcodeFormatFromString --- core/src/CharacterSet.cpp | 58 +++++++++---------------------- test/unit/CharacterSetECITest.cpp | 10 ++++++ 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/core/src/CharacterSet.cpp b/core/src/CharacterSet.cpp index 0badb9c7a6..57ee86eb01 100644 --- a/core/src/CharacterSet.cpp +++ b/core/src/CharacterSet.cpp @@ -6,59 +6,34 @@ #include "CharacterSet.h" -#include -#include -#include +#include "ZXContainerAlgorithms.h" + +#include namespace ZXing { -struct CompareNoCase { - bool operator ()(const char* a, const char* b) const { - while (*a != '\0' && *b != '\0') { - auto ca = std::tolower(*a++); - auto cb = std::tolower(*b++); - if (ca < cb) { - return true; - } - else if (ca > cb) { - return false; - } - } - return *a == '\0' && *b != '\0'; - } +struct CharacterSetName +{ + const char* name; + CharacterSet cs; }; -static const std::map ECI_NAME_TO_CHARSET = { +static CharacterSetName NAME_TO_CHARSET[] = { {"Cp437", CharacterSet::Cp437}, - {"ISO8859_1", CharacterSet::ISO8859_1}, {"ISO-8859-1", CharacterSet::ISO8859_1}, - {"ISO8859_2", CharacterSet::ISO8859_2}, {"ISO-8859-2", CharacterSet::ISO8859_2}, - {"ISO8859_3", CharacterSet::ISO8859_3}, {"ISO-8859-3", CharacterSet::ISO8859_3}, - {"ISO8859_4", CharacterSet::ISO8859_4}, {"ISO-8859-4", CharacterSet::ISO8859_4}, - {"ISO8859_5", CharacterSet::ISO8859_5}, {"ISO-8859-5", CharacterSet::ISO8859_5}, - {"ISO8859_6", CharacterSet::ISO8859_6}, {"ISO-8859-6", CharacterSet::ISO8859_6}, - {"ISO8859_7", CharacterSet::ISO8859_7}, {"ISO-8859-7", CharacterSet::ISO8859_7}, - {"ISO8859_8", CharacterSet::ISO8859_8}, {"ISO-8859-8", CharacterSet::ISO8859_8}, - {"ISO8859_9", CharacterSet::ISO8859_9}, {"ISO-8859-9", CharacterSet::ISO8859_9}, - {"ISO8859_10", CharacterSet::ISO8859_10}, {"ISO-8859-10", CharacterSet::ISO8859_10}, - {"ISO8859_11", CharacterSet::ISO8859_11}, {"ISO-8859-11", CharacterSet::ISO8859_11}, - {"ISO8859_13", CharacterSet::ISO8859_13}, {"ISO-8859-13", CharacterSet::ISO8859_13}, - {"ISO8859_14", CharacterSet::ISO8859_14}, {"ISO-8859-14", CharacterSet::ISO8859_14}, - {"ISO8859_15", CharacterSet::ISO8859_15}, {"ISO-8859-15", CharacterSet::ISO8859_15}, - {"ISO8859_16", CharacterSet::ISO8859_16}, {"ISO-8859-16", CharacterSet::ISO8859_16}, {"SJIS", CharacterSet::Shift_JIS}, {"Shift_JIS", CharacterSet::Shift_JIS}, @@ -73,28 +48,29 @@ static const std::map ECI_NAME_TO_CHA {"UnicodeBigUnmarked", CharacterSet::UnicodeBig}, {"UTF-16BE", CharacterSet::UnicodeBig}, {"UnicodeBig", CharacterSet::UnicodeBig}, - {"UTF8", CharacterSet::UTF8}, {"UTF-8", CharacterSet::UTF8}, {"ASCII", CharacterSet::ASCII}, {"US-ASCII", CharacterSet::ASCII}, {"Big5", CharacterSet::Big5}, {"GB2312", CharacterSet::GB2312}, {"GB18030", CharacterSet::GB18030}, - {"EUC_CN", CharacterSet::GB18030}, {"EUC-CN", CharacterSet::GB18030}, {"GBK", CharacterSet::GB18030}, - {"EUC_KR", CharacterSet::EUC_KR}, {"EUC-KR", CharacterSet::EUC_KR}, {"BINARY", CharacterSet::BINARY}, }; -CharacterSet CharacterSetFromString(const std::string& name) +static std::string NormalizeName(std::string str) { - auto it = ECI_NAME_TO_CHARSET.find(name.c_str()); - if (it != ECI_NAME_TO_CHARSET.end()) - return it->second; + std::transform(str.begin(), str.end(), str.begin(), [](char c) { return (char)std::tolower(c); }); + str.erase(std::remove_if(str.begin(), str.end(), [](char c) { return Contains("_-[] ", c); }), str.end()); + return str; +} - return CharacterSet::Unknown; +CharacterSet CharacterSetFromString(const std::string& name) +{ + auto i = FindIf(NAME_TO_CHARSET, [str = NormalizeName(name)](auto& v) { return NormalizeName(v.name) == str; }); + return i == std::end(NAME_TO_CHARSET) ? CharacterSet::Unknown : i->cs; } } // namespace ZXing diff --git a/test/unit/CharacterSetECITest.cpp b/test/unit/CharacterSetECITest.cpp index 2ff4dbf14d..e34dd9640f 100644 --- a/test/unit/CharacterSetECITest.cpp +++ b/test/unit/CharacterSetECITest.cpp @@ -3,6 +3,7 @@ */ // SPDX-License-Identifier: Apache-2.0 +#include "CharacterSet.h" #include "ECI.h" #include "gtest/gtest.h" @@ -20,3 +21,12 @@ TEST(CharacterSetECITest, Charset2ECI) EXPECT_EQ(ToInt(ToECI(CharacterSet::BINARY)), 899); EXPECT_EQ(ToInt(ToECI(CharacterSet::Unknown)), -1); } + +TEST(CharacterSetECITest, CharacterSetFromString) +{ + EXPECT_EQ(CharacterSet::ISO8859_1, CharacterSetFromString("ISO-8859-1")); + EXPECT_EQ(CharacterSet::ISO8859_1, CharacterSetFromString("ISO8859_1")); + EXPECT_EQ(CharacterSet::ISO8859_1, CharacterSetFromString("ISO 8859-1")); + EXPECT_EQ(CharacterSet::ISO8859_1, CharacterSetFromString("iso88591")); + EXPECT_EQ(CharacterSet::Unknown, CharacterSetFromString("invalid-name")); +} From 6e21219ac5a6f9108db239ed072576d0596cd57a Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 3 Jun 2022 18:45:53 +0200 Subject: [PATCH 0256/1315] ECI: remove the need to publish ECI.h (via Content.h -> Result.h) --- core/src/Content.cpp | 5 +++++ core/src/Content.h | 10 ++++++---- test/unit/ContentTest.cpp | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index c730e9ca03..e89c86a534 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -6,6 +6,7 @@ #include "Content.h" #include "CharacterSet.h" +#include "ECI.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" @@ -44,6 +45,10 @@ void Content::switchEncoding(ECI eci, bool isECI) hasECI |= isECI; } +Content::Content() : encodings({{ECI::Unknown, 0}}) {} + +Content::Content(ByteArray&& binary) : binary(std::move(binary)), encodings{{ECI::ISO8859_1, 0}} {} + void Content::switchEncoding(CharacterSet cs) { switchEncoding(ToECI(cs), false); diff --git a/core/src/Content.h b/core/src/Content.h index b786b88386..6b3e874545 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -6,10 +6,12 @@ #pragma once #include "ByteArray.h" -#include "ECI.h" namespace ZXing { +enum class ECI : int; +enum class CharacterSet; + enum class ContentType { Text, Binary, Mixed }; std::string ToString(ContentType type); @@ -40,14 +42,14 @@ class Content }; ByteArray binary; - std::vector encodings = {{ECI::Unknown, 0}}; + std::vector encodings; std::string hintedCharset; std::string applicationIndicator; SymbologyIdentifier symbology; bool hasECI = false; - Content() = default; - Content(ByteArray&& binary) : binary(std::move(binary)), encodings{{ECI::ISO8859_1, 0}} {} + Content(); + Content(ByteArray&& binary); void switchEncoding(ECI eci) { switchEncoding(eci, true); } void switchEncoding(CharacterSet cs); diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp index 5b3129a4d2..b200f51530 100644 --- a/test/unit/ContentTest.cpp +++ b/test/unit/ContentTest.cpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "Content.h" +#include "ECI.h" #include "gtest/gtest.h" #include "gmock/gmock.h" From f86c4b69ca40dd9cbbc556bdf092b8d7832bd036 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 3 Jun 2022 18:51:45 +0200 Subject: [PATCH 0257/1315] cmake: only install minimal set of header files Fixes #168. This has been tested to work with the example applications. This is a pretty sharp "deprecation" of a whole lot of internal API and reduces the published interface to merely `ReadBarcode` and `MultiFormatWriter`. It is obviously somewhat risky but I see no other practical way of moving forward with limiting the API. --- CMakeLists.txt | 16 --------------- core/CMakeLists.txt | 49 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e215cf44e..50e2702c03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,22 +87,6 @@ install ( DESTINATION ${CMAKECONFIG_INSTALL_DIR} NAMESPACE ZXing:: ) -install ( - DIRECTORY core/src/ - DESTINATION include/ZXing - FILES_MATCHING PATTERN "*.h" -) - -configure_file ( - core/ZXVersion.h.in - ZXVersion.h -) - -install ( - FILES "${CMAKE_CURRENT_BINARY_DIR}/ZXVersion.h" - DESTINATION include/ZXing -) - # PC file generation. if (NOT DEFINED INSTALLDIR) set (INSTALLDIR ${CMAKE_INSTALL_PREFIX}) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 000dde3433..7b34509510 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -133,6 +133,41 @@ if (BUILD_WRITERS) ) endif() +# define subset of public headers that get distributed with the binaries +set (PUBLIC_HEADERS + src/BarcodeFormat.h + src/BitHacks.h + src/ByteArray.h + src/CharacterSet.h + src/CharacterSetECI.h # deprecated + src/Flags.h + src/GTIN.h + src/TextUtfEncoding.h + src/ZXConfig.h + src/ZXContainerAlgorithms.h +) +if (BUILD_READERS) + set (PUBLIC_HEADERS ${PUBLIC_HEADERS} + src/Content.h + src/DecodeHints.h + src/DecodeStatus.h + src/ImageView.h + src/Point.h + src/Quadrilateral.h + src/ReadBarcode.h + src/Result.h + src/StructuredAppend.h + ) +endif() +if (BUILD_WRITERS) + set (PUBLIC_HEADERS ${PUBLIC_HEADERS} + src/BitMatrix.h + src/BitMatrixIO.h + src/Matrix.h + src/MultiFormatWriter.h + ) +endif() +# end of public header set set (AZTEC_FILES ) @@ -426,7 +461,7 @@ add_library (ZXing target_include_directories (ZXing PUBLIC "$" - INTERFACE "$" + INTERFACE "$" ) target_compile_options (ZXing @@ -462,6 +497,8 @@ if (PROJECT_VERSION) set_target_properties(ZXing PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) endif() +set_target_properties(ZXing PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADERS}") + include (GNUInstallDirs) install ( @@ -469,7 +506,15 @@ install ( LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - INCLUDES DESTINATION include +# INCLUDES DESTINATION include + PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ZXing" +) + +configure_file (ZXVersion.h.in ZXVersion.h) + +install ( + FILES "${CMAKE_CURRENT_BINARY_DIR}/ZXVersion.h" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ZXing" ) if(MSVC) From f502cb6fc6e9ec5e857dbe1c098980ab56489d6d Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 3 Jun 2022 22:45:59 +0200 Subject: [PATCH 0258/1315] CharacterSet: replace deprecated CharsetFromName in WASM wrapper --- wrappers/wasm/BarcodeWriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/wasm/BarcodeWriter.cpp b/wrappers/wasm/BarcodeWriter.cpp index 209fec1a89..ed2a2b1663 100644 --- a/wrappers/wasm/BarcodeWriter.cpp +++ b/wrappers/wasm/BarcodeWriter.cpp @@ -6,7 +6,7 @@ #include "BarcodeFormat.h" #include "MultiFormatWriter.h" #include "BitMatrix.h" -#include "CharacterSetECI.h" +#include "CharacterSet.h" #include #include @@ -59,7 +59,7 @@ WriteResult generateBarcode(std::wstring text, std::string format, std::string e if (margin >= 0) writer.setMargin(margin); - CharacterSet charset = CharacterSetECI::CharsetFromName(encoding.c_str()); + CharacterSet charset = CharacterSetFromString(encoding); if (charset != CharacterSet::Unknown) writer.setEncoding(charset); From 24c50536ad68aecfb48ccbe31b150c9b05033026 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 6 Jun 2022 13:18:16 +0200 Subject: [PATCH 0259/1315] DMDecoder: set missing Result::applicationIndicator --- core/src/datamatrix/DMDecoder.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index a7303018a9..efd6f1bea7 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -320,11 +320,11 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b readerInit = true; break; case 235: upperShift.set = true; break; // Upper Shift (shift to Extended ASCII) - case 236: // 05 Macro + case 236: // ISO 15434 format "05" Macro result.append("[)>\x1E" "05\x1D"); resultTrailer.insert(0, "\x1E\x04"); break; - case 237: // 06 Macro + case 237: // ISO 15434 format "06" Macro result.append("[)>\x1E" "06\x1D"); resultTrailer.insert(0, "\x1E\x04"); break; @@ -357,6 +357,7 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b } result.append(resultTrailer); + result.applicationIndicator = result.symbology.modifier == '2' ? "GS1" : ""; result.symbology.modifier += isDMRE * 6; return DecoderResult(std::move(bytes), {}, std::move(result)) From 79b0f438fc5065481a055c10df208285a9e33c58 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 6 Jun 2022 13:27:07 +0200 Subject: [PATCH 0260/1315] Result: add GS1, ISO15434 and UnknownECI ContentTypes Also tuned binary detection to possibly return true even if a 'text' ECI like latin1 was used (see https://github.com/nu-book/zxing-cpp/issues/334#issuecomment-1146083723) --- core/src/Content.cpp | 32 +++++++++++++++++++++++--------- core/src/Content.h | 2 +- core/src/TextDecoder.cpp | 4 ---- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index e89c86a534..c9482336e0 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -15,7 +15,7 @@ namespace ZXing { std::string ToString(ContentType type) { - const char* t2s[] = {"Text", "Binary", "Mixed"}; + const char* t2s[] = {"Text", "Binary", "Mixed", "GS1", "ISO15434", "UnknownECI"}; return t2s[static_cast(type)]; } @@ -166,21 +166,35 @@ CharacterSet Content::guessEncoding() const if (input.empty()) return CharacterSet::Unknown; - return TextDecoder::GuessEncoding(input.data(), input.size(), CharacterSet::BINARY); + return TextDecoder::GuessEncoding(input.data(), input.size(), CharacterSet::ISO8859_1); } ContentType Content::type() const { - auto isBinary = [](Encoding e) { return !IsText(e.eci); }; - auto es = encodings; + if (!canProcess()) + return ContentType::UnknownECI; + + if (applicationIndicator == "GS1") + return ContentType::GS1; + + // check for the absolut minimum of a ISO 15434 conforming message ("[)>" + RS + digit + digit) + if (binary.size() > 6 && binary.asString(0, 4) == "[)>\x1E" && std::isdigit(binary[4]) && std::isdigit(binary[5])) + return ContentType::ISO15434; - for (auto& e : es) - if (e.eci == ECI::Unknown) - e.eci = ToECI(guessEncoding()); + ECI fallback = ToECI(guessEncoding()); + std::vector binaryECIs; + ForEachECIBlock([&](ECI eci, int begin, int end) { + if (eci == ECI::Unknown) + eci = fallback; + binaryECIs.push_back((!IsText(eci) + || (ToInt(eci) > 0 && ToInt(eci) < 28 && ToInt(eci) != 25 + && std::any_of(binary.begin() + begin, binary.begin() + end, + [](auto c) { return c < 0x20 && c != 0xa && c != 0xd; })))); + }); - if (std::none_of(es.begin(), es.end(), isBinary)) + if (!Contains(binaryECIs, true)) return ContentType::Text; - if (std::all_of(es.begin(), es.end(), isBinary)) + if (!Contains(binaryECIs, false)) return ContentType::Binary; return ContentType::Mixed; diff --git a/core/src/Content.h b/core/src/Content.h index 6b3e874545..34aa6b92d7 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -12,7 +12,7 @@ namespace ZXing { enum class ECI : int; enum class CharacterSet; -enum class ContentType { Text, Binary, Mixed }; +enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; std::string ToString(ContentType type); diff --git a/core/src/TextDecoder.cpp b/core/src/TextDecoder.cpp index 98677d63a4..4df8a65f14 100644 --- a/core/src/TextDecoder.cpp +++ b/core/src/TextDecoder.cpp @@ -402,10 +402,6 @@ TextDecoder::GuessEncoding(const uint8_t* bytes, size_t length, CharacterSet fal if (value > 0x7F && value < 0xA0) { canBeISO88591 = false; } - // treat all ANSI control characters as binary, except EOT, LF, CR, GS and RS (see ISO/IEC 15434) - else if (value < 0x20 && value != 0x04 && value != 0x0a && value != 0x0d && value != 0x1d && value != 0x1e) { - canBeISO88591 = false; - } else if (value > 0x9F) { if (value < 0xC0 || value == 0xD7 || value == 0xF7) { isoHighOther++; From 3dad01926d2371603ae5b162d685be0d81d07a27 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 6 Jun 2022 17:41:39 +0200 Subject: [PATCH 0261/1315] Result: deprecate rawBytes and numBits --- core/src/Result.h | 12 +++++------- example/ZXingQtReader.h | 9 ++++----- test/blackbox/BlackboxTestRunner.cpp | 2 -- test/unit/aztec/AZDecoderTest.cpp | 5 ----- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/core/src/Result.h b/core/src/Result.h index f13afcc233..6f196fb198 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -24,10 +24,8 @@ class DecoderResult; using Position = QuadrilateralI; /** -*

Encapsulates the result of decoding a barcode within an image.

-* -* @author Sean Owen -*/ + * @brief The Result class encapsulates the result of decoding a barcode within an image. + */ class Result { public: @@ -66,9 +64,9 @@ class Result */ bool isMirrored() const { return _isMirrored; } - const ByteArray& rawBytes() const { return _rawBytes; } - - int numBits() const { return _numBits; } + /// see binary() above for a proper replacement of rawByes + [[deprecated]] const ByteArray& rawBytes() const { return _rawBytes; } + [[deprecated]] int numBits() const { return _numBits; } const std::wstring& ecLevel() const { return _ecLevel; } diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 2a05bbf5d8..9db4a7c528 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -97,13 +97,13 @@ class Result : private ZXing::Result Q_PROPERTY(BarcodeFormat format READ format) Q_PROPERTY(QString formatName READ formatName) Q_PROPERTY(QString text READ text) - Q_PROPERTY(QByteArray rawBytes READ rawBytes) + Q_PROPERTY(QByteArray binary READ binary) Q_PROPERTY(bool isValid READ isValid) Q_PROPERTY(DecodeStatus status READ status) Q_PROPERTY(Position position READ position) QString _text; - QByteArray _rawBytes; + QByteArray _binary; Position _position; public: @@ -111,8 +111,7 @@ class Result : private ZXing::Result explicit Result(ZXing::Result&& r) : ZXing::Result(std::move(r)) { _text = QString::fromWCharArray(ZXing::Result::text().c_str()); - _rawBytes = QByteArray(reinterpret_cast(ZXing::Result::rawBytes().data()), - Size(ZXing::Result::rawBytes())); + _binary = QByteArray(reinterpret_cast(ZXing::Result::binary().data()), Size(ZXing::Result::binary())); auto& pos = ZXing::Result::position(); auto qp = [&pos](int i) { return QPoint(pos[i].x, pos[i].y); }; _position = {qp(0), qp(1), qp(2), qp(3)}; @@ -124,7 +123,7 @@ class Result : private ZXing::Result DecodeStatus status() const { return static_cast(ZXing::Result::status()); } QString formatName() const { return QString::fromStdString(ZXing::ToString(ZXing::Result::format())); } const QString& text() const { return _text; } - const QByteArray& rawBytes() const { return _rawBytes; } + const QByteArray& binary() const { return _binary; } const Position& position() const { return _position; } // For debugging/development diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 9f16fa2aa3..8864d224a8 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -68,8 +68,6 @@ static std::string getResultValue(const Result& result, const std::string& key) return TextUtfEncoding::ToUtf8(result.ecLevel()); if (key == "orientation") return std::to_string(result.orientation()); - if (key == "numBits") - return std::to_string(result.numBits()); if (key == "symbologyIdentifier") return result.symbologyIdentifier(); if (key == "sequenceSize") diff --git a/test/unit/aztec/AZDecoderTest.cpp b/test/unit/aztec/AZDecoderTest.cpp index 523bb8b920..62d70977ff 100644 --- a/test/unit/aztec/AZDecoderTest.cpp +++ b/test/unit/aztec/AZDecoderTest.cpp @@ -60,11 +60,6 @@ TEST(AZDecoderTest, AztecResult) DecoderResult result = parse(std::move(bits), false, 30, 2); EXPECT_EQ(result.isValid(), true); EXPECT_EQ(result.text(), L"88888TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"); - EXPECT_EQ(result.rawBytes(), ByteArray({ - 0xf5, 0x55, 0x55, 0x75, 0x6b, 0x5a, 0xd6, 0xb5, 0xad, 0x6b, - 0x5a, 0xd6, 0xb5, 0xad, 0x6b, 0x5a, 0xd6, 0xb5, 0xad, 0x6b, - 0x5a, 0xd6, 0xb0 })); - EXPECT_EQ(result.numBits(), 180); EXPECT_EQ(result.symbologyIdentifier(), "]z0"); } From 26c117c4a196e6a5ec7caf5d1cc6db22bd0641d8 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 7 Jun 2022 12:24:40 +0200 Subject: [PATCH 0262/1315] Result: rename `binary` to `bytes` Originally the `binary` property was envisioned to contain only the binary parts (if present) of a barcode content. During the discussion, this has changed. Hence the name became misleading and should be changed before releasing it. Reasons for the choice `bytes`: * does not somehow imply that the content is 'binary' in nature * is closer to `rawBytes` which was there before with a similar intention * is used in Python as the name of the type this data would be stored in --- core/src/Content.cpp | 26 +++++++++++----------- core/src/Content.h | 16 ++++++------- core/src/Result.h | 6 ++--- core/src/aztec/AZDecoder.cpp | 20 ++++++++--------- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/qrcode/QRDecoder.cpp | 2 +- example/ZXingQtReader.h | 8 +++---- example/ZXingReader.cpp | 6 ++--- test/blackbox/BlackboxTestRunner.cpp | 6 ++--- test/unit/ContentTest.cpp | 8 +++---- test/unit/aztec/AZEncodeDecodeTest.cpp | 4 ++-- test/unit/aztec/AZHighLevelEncoderTest.cpp | 2 +- test/unit/pdf417/PDF417DecoderTest.cpp | 2 +- 13 files changed, 54 insertions(+), 54 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index c9482336e0..90dd68d9f8 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -24,7 +24,7 @@ void Content::ForEachECIBlock(FUNC func) const { for (int i = 0; i < Size(encodings); ++i) { auto [eci, start] = encodings[i]; - int end = i + 1 == Size(encodings) ? Size(binary) : encodings[i + 1].pos; + int end = i + 1 == Size(encodings) ? Size(bytes) : encodings[i + 1].pos; if (start != end) func(eci, start, end); @@ -37,17 +37,17 @@ void Content::switchEncoding(ECI eci, bool isECI) if (isECI && !hasECI) encodings = {{ECI::ISO8859_1, 0}}; if (isECI || !hasECI) { - if (encodings.back().pos == Size(binary)) + if (encodings.back().pos == Size(bytes)) encodings.back().eci = eci; // no point in recording 0 length segments else - encodings.push_back({eci, Size(binary)}); + encodings.push_back({eci, Size(bytes)}); } hasECI |= isECI; } Content::Content() : encodings({{ECI::Unknown, 0}}) {} -Content::Content(ByteArray&& binary) : binary(std::move(binary)), encodings{{ECI::ISO8859_1, 0}} {} +Content::Content(ByteArray&& bytes) : bytes(std::move(bytes)), encodings{{ECI::ISO8859_1, 0}} {} void Content::switchEncoding(CharacterSet cs) { @@ -56,7 +56,7 @@ void Content::switchEncoding(CharacterSet cs) void Content::erase(int pos, int n) { - binary.erase(binary.begin() + pos, binary.begin() + pos + n); + bytes.erase(bytes.begin() + pos, bytes.begin() + pos + n); for (auto& e : encodings) if (e.pos > pos) pos -= n; @@ -64,7 +64,7 @@ void Content::erase(int pos, int n) void Content::insert(int pos, const std::string& str) { - binary.insert(binary.begin() + pos, str.begin(), str.end()); + bytes.insert(bytes.begin() + pos, str.begin(), str.end()); for (auto& e : encodings) if (e.pos > pos) pos += Size(str); @@ -88,7 +88,7 @@ std::wstring Content::text() const ForEachECIBlock([&](ECI eci, int begin, int end) { CharacterSet cs = eci == ECI::Unknown ? fallbackCS : ToCharacterSet(eci); - TextDecoder::Append(wstr, binary.data() + begin, end - begin, cs); + TextDecoder::Append(wstr, bytes.data() + begin, end - begin, cs); }); return wstr; } @@ -121,7 +121,7 @@ std::string Content::utf8Protocol() const lastECI = eci; std::wstring tmp; - TextDecoder::Append(tmp, binary.data() + begin, end - begin, cs); + TextDecoder::Append(tmp, bytes.data() + begin, end - begin, cs); for (auto c : tmp) { res += c; if (c == L'\\') // in the ECI protocol a '\' has to be doubled @@ -132,7 +132,7 @@ std::string Content::utf8Protocol() const return TextUtfEncoding::ToUtf8(res); } -ByteArray Content::binaryECI() const +ByteArray Content::bytesECI() const { if (empty()) return {}; @@ -144,7 +144,7 @@ ByteArray Content::binaryECI() const res += ToString(eci); for (int i = begin; i != end; ++i) { - char c = static_cast(binary[i]); + char c = static_cast(bytes[i]); res += c; if (c == '\\') // in the ECI protocol a '\' has to be doubled res += c; @@ -160,7 +160,7 @@ CharacterSet Content::guessEncoding() const ByteArray input; ForEachECIBlock([&](ECI eci, int begin, int end) { if (eci == ECI::Unknown) - input.insert(input.end(), binary.begin() + begin, binary.begin() + end); + input.insert(input.end(), bytes.begin() + begin, bytes.begin() + end); }); if (input.empty()) @@ -178,7 +178,7 @@ ContentType Content::type() const return ContentType::GS1; // check for the absolut minimum of a ISO 15434 conforming message ("[)>" + RS + digit + digit) - if (binary.size() > 6 && binary.asString(0, 4) == "[)>\x1E" && std::isdigit(binary[4]) && std::isdigit(binary[5])) + if (bytes.size() > 6 && bytes.asString(0, 4) == "[)>\x1E" && std::isdigit(bytes[4]) && std::isdigit(bytes[5])) return ContentType::ISO15434; ECI fallback = ToECI(guessEncoding()); @@ -188,7 +188,7 @@ ContentType Content::type() const eci = fallback; binaryECIs.push_back((!IsText(eci) || (ToInt(eci) > 0 && ToInt(eci) < 28 && ToInt(eci) != 25 - && std::any_of(binary.begin() + begin, binary.begin() + end, + && std::any_of(bytes.begin() + begin, bytes.begin() + end, [](auto c) { return c < 0x20 && c != 0xa && c != 0xd; })))); }); diff --git a/core/src/Content.h b/core/src/Content.h index 34aa6b92d7..a96113300e 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -41,7 +41,7 @@ class Content int pos; }; - ByteArray binary; + ByteArray bytes; std::vector encodings; std::string hintedCharset; std::string applicationIndicator; @@ -49,16 +49,16 @@ class Content bool hasECI = false; Content(); - Content(ByteArray&& binary); + Content(ByteArray&& bytes); void switchEncoding(ECI eci) { switchEncoding(eci, true); } void switchEncoding(CharacterSet cs); - void reserve(int count) { binary.reserve(binary.size() + count); } + void reserve(int count) { bytes.reserve(bytes.size() + count); } - void push_back(uint8_t val) { binary.push_back(val); } - void append(const std::string& str) { binary.insert(binary.end(), str.begin(), str.end()); } - void append(const ByteArray& bytes) { binary.insert(binary.end(), bytes.begin(), bytes.end()); } + void push_back(uint8_t val) { bytes.push_back(val); } + void append(const std::string& str) { bytes.insert(bytes.end(), str.begin(), str.end()); } + void append(const ByteArray& ba) { bytes.insert(bytes.end(), ba.begin(), ba.end()); } void operator+=(char val) { push_back(val); } void operator+=(const std::string& str) { append(str); } @@ -66,12 +66,12 @@ class Content void erase(int pos, int n); void insert(int pos, const std::string& str); - bool empty() const { return binary.empty(); } + bool empty() const { return bytes.empty(); } bool canProcess() const; std::wstring text() const; std::string utf8Protocol() const; - ByteArray binaryECI() const; + ByteArray bytesECI() const; CharacterSet guessEncoding() const; ContentType type() const; }; diff --git a/core/src/Result.h b/core/src/Result.h index 6f196fb198..17d969d5b3 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -46,8 +46,8 @@ class Result const std::wstring& text() const { return _text; } // WARNING: this is an experimental API and may change/disappear - const ByteArray& binary() const { return _content.binary; } - const ByteArray binaryECI() const { return _content.binaryECI(); } + const ByteArray& bytes() const { return _content.bytes; } + const ByteArray bytesECI() const { return _content.bytesECI(); } const std::string utf8Protocol() const { return _content.utf8Protocol(); } const std::string& applicationIndicator() const { return _content.applicationIndicator; } ContentType contentType() const { return _content.type(); } @@ -64,7 +64,7 @@ class Result */ bool isMirrored() const { return _isMirrored; } - /// see binary() above for a proper replacement of rawByes + /// see bytes() above for a proper replacement of rawByes [[deprecated]] const ByteArray& rawBytes() const { return _rawBytes; } [[deprecated]] int numBits() const { return _numBits; } diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 7d0ad24dbe..b099e7434a 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -223,9 +223,9 @@ static ECI ParseECIValue(BitArray::Range& bits, const int flg) /** * See ISO/IEC 24778:2008 Section 8 */ -static StructuredAppendInfo ParseStructuredAppend(ByteArray& binary) +static StructuredAppendInfo ParseStructuredAppend(ByteArray& bytes) { - std::string text(binary.begin(), binary.end()); + std::string text(bytes.begin(), bytes.end()); StructuredAppendInfo sai; std::string::size_type i = 0; @@ -247,7 +247,7 @@ static StructuredAppendInfo ParseStructuredAppend(ByteArray& binary) sai.count = 0; // Choose to mark count as unknown text.erase(0, i + 2); // Remove - binary = ByteArray(text); + bytes = ByteArray(text); return sai; } @@ -314,32 +314,32 @@ DecoderResult Decode(const BitArray& bits, const std::string& characterSet) return DecodeStatus::FormatError; } - if (res.binary.empty()) + if (res.bytes.empty()) return DecodeStatus::FormatError; // Check for Structured Append - need 4 5-bit words, beginning with ML UL, ending with index and count bool haveStructuredAppend = Size(bits) > 20 && ToInt(bits, 0, 5) == 29 // latch to MIXED (from UPPER) && ToInt(bits, 5, 5) == 29; // latch back to UPPER (from MIXED) - StructuredAppendInfo sai = haveStructuredAppend ? ParseStructuredAppend(res.binary) : StructuredAppendInfo(); + StructuredAppendInfo sai = haveStructuredAppend ? ParseStructuredAppend(res.bytes) : StructuredAppendInfo(); // As converting character set ECIs ourselves and ignoring/skipping non-character ECIs, not using // modifiers that indicate ECI protocol (ISO/IEC 24778:2008 Annex F Table F.1) - if (res.binary[0] == 29) { + if (res.bytes[0] == 29) { res.symbology.modifier = '1'; // GS1 res.applicationIndicator = "GS1"; res.erase(0, 1); // Remove FNC1 - } else if (res.binary.size() > 2 && std::isupper(res.binary[0]) && res.binary[1] == 29) { + } else if (res.bytes.size() > 2 && std::isupper(res.bytes[0]) && res.bytes[1] == 29) { // FNC1 following single uppercase letter (the AIM Application Indicator) res.symbology.modifier = '2'; // AIM // TODO: remove the AI from the content? - res.applicationIndicator = res.binary.asString(0, 1); + res.applicationIndicator = res.bytes.asString(0, 1); res.erase(1, 1); // Remove FNC1, // The AIM Application Indicator character "A"-"Z" is left in the stream (ISO/IEC 24778:2008 16.2) - } else if (res.binary.size() > 3 && std::isdigit(res.binary[0]) && std::isdigit(res.binary[1]) && res.binary[2] == 29) { + } else if (res.bytes.size() > 3 && std::isdigit(res.bytes[0]) && std::isdigit(res.bytes[1]) && res.bytes[2] == 29) { // FNC1 following 2 digits (the AIM Application Indicator) res.symbology.modifier = '2'; // AIM - res.applicationIndicator = res.binary.asString(0, 2); + res.applicationIndicator = res.bytes.asString(0, 2); res.erase(2, 1); // Remove FNC1 // The AIM Application Indicator characters "00"-"99" are left in the stream (ISO/IEC 24778:2008 16.2) } diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 8d4be16bea..16292730ae 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -281,7 +281,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& /*cha auto country = ToString(GetCountry(bytes), 3); auto service = ToString(GetServiceClass(bytes), 3); GetMessage(bytes, 10, 84, result, sai); - if (result.binary.asString().compare(0, 7, "[)>\u001E01\u001D") == 0) // "[)>" + RS + "01" + GS + if (result.bytes.asString().compare(0, 7, "[)>\u001E01\u001D") == 0) // "[)>" + RS + "01" + GS result.insert(9, postcode + GS + country + GS + service + GS); else result.insert(0, postcode + GS + country + GS + service + GS); diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 703d28d941..e4ebed8192 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -292,7 +292,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo result += static_cast(appInd - 100); else throw std::runtime_error("Invalid AIM Application Indicator"); - result.applicationIndicator = result.binary.asString(); // see also above + result.applicationIndicator = result.bytes.asString(); // see also above break; case CodecMode::STRUCTURED_APPEND: // sequence number and parity is added later to the result metadata diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 9db4a7c528..7435e56c85 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -97,13 +97,13 @@ class Result : private ZXing::Result Q_PROPERTY(BarcodeFormat format READ format) Q_PROPERTY(QString formatName READ formatName) Q_PROPERTY(QString text READ text) - Q_PROPERTY(QByteArray binary READ binary) + Q_PROPERTY(QByteArray bytes READ bytes) Q_PROPERTY(bool isValid READ isValid) Q_PROPERTY(DecodeStatus status READ status) Q_PROPERTY(Position position READ position) QString _text; - QByteArray _binary; + QByteArray _bytes; Position _position; public: @@ -111,7 +111,7 @@ class Result : private ZXing::Result explicit Result(ZXing::Result&& r) : ZXing::Result(std::move(r)) { _text = QString::fromWCharArray(ZXing::Result::text().c_str()); - _binary = QByteArray(reinterpret_cast(ZXing::Result::binary().data()), Size(ZXing::Result::binary())); + _bytes = QByteArray(reinterpret_cast(ZXing::Result::bytes().data()), Size(ZXing::Result::bytes())); auto& pos = ZXing::Result::position(); auto qp = [&pos](int i) { return QPoint(pos[i].x, pos[i].y); }; _position = {qp(0), qp(1), qp(2), qp(3)}; @@ -123,7 +123,7 @@ class Result : private ZXing::Result DecodeStatus status() const { return static_cast(ZXing::Result::status()); } QString formatName() const { return QString::fromStdString(ZXing::ToString(ZXing::Result::format())); } const QString& text() const { return _text; } - const QByteArray& binary() const { return _binary; } + const QByteArray& bytes() const { return _bytes; } const Position& position() const { return _position; } // For debugging/development diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 9baf5961f8..937da9077a 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -160,7 +160,7 @@ int main(int argc, char* argv[]) ret |= static_cast(result.status()); if (binaryOutput) { - std::cout.write(reinterpret_cast(result.binary().data()), result.binary().size()); + std::cout.write(reinterpret_cast(result.bytes().data()), result.bytes().size()); continue; } @@ -183,9 +183,9 @@ int main(int argc, char* argv[]) firstFile = false; } std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" - << "Binary: \"" << ToHex(result.binary()) << "\"\n" + << "Bytes: \"" << ToHex(result.bytes()) << "\"\n" << "TextECI: \"" << result.utf8Protocol() << "\"\n" - << "BinaryECI: \"" << ToHex(result.binaryECI()) << "\"\n" + << "BytesECI: \"" << ToHex(result.bytesECI()) << "\"\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" << "Content: " << ToString(result.contentType()) << "\n" diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 8864d224a8..108e91f9b8 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -141,8 +141,8 @@ static std::string checkResult(const fs::path& imgPath, std::string_view expecte if (auto expected = readFile(".bin")) { ByteArray binaryExpected(*expected); - return result.binary() != binaryExpected - ? fmt::format("Content mismatch: expected '{}' but got '{}'", ToHex(binaryExpected), ToHex(result.binary())) + return result.bytes() != binaryExpected + ? fmt::format("Content mismatch: expected '{}' but got '{}'", ToHex(binaryExpected), ToHex(result.bytes())) : ""; } @@ -266,7 +266,7 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi Content content; for (const auto& r : allResults) { text.append(r.text()); - content.append(r.binary()); + content.append(r.bytes()); } const auto& first = allResults.front(); diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp index b200f51530..19c3a5f8b1 100644 --- a/test/unit/ContentTest.cpp +++ b/test/unit/ContentTest.cpp @@ -53,7 +53,7 @@ TEST(ContentTest, GuessEncoding) c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::ISO8859_1); EXPECT_EQ(c.text(), L"A\u00E9Z"); - EXPECT_EQ(c.binaryECI(), c.binary); + EXPECT_EQ(c.bytesECI(), c.bytes); } { // guess Shift_JIS @@ -73,7 +73,7 @@ TEST(ContentTest, ECI) c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_TRUE(c.hasECI); EXPECT_EQ(c.text(), L"A\u00E9ZA\u0449Z"); - EXPECT_EQ(c.binaryECI().asString(), std::string_view("\\000003A\xE9Z\\000007A\xE9Z")); + EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\xE9Z\\000007A\xE9Z")); } { // switch ECI -> latin1 for unknown (instead of Shift_JIS) @@ -82,13 +82,13 @@ TEST(ContentTest, ECI) c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_EQ(c.text(), L"A\u0083\u0065ZA\u0449Z"); - EXPECT_EQ(c.binaryECI().asString(), std::string_view("\\000003A\x83\x65Z\\000007A\xE9Z")); + EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\x83\x65Z\\000007A\xE9Z")); } { // double '\' Content c; c.append("C:\\Test"); EXPECT_EQ(c.text(), L"C:\\Test"); - EXPECT_EQ(c.binaryECI().asString(), std::string_view("C:\\\\Test")); + EXPECT_EQ(c.bytesECI().asString(), std::string_view("C:\\\\Test")); } } diff --git a/test/unit/aztec/AZEncodeDecodeTest.cpp b/test/unit/aztec/AZEncodeDecodeTest.cpp index 54c7d2fe7f..b28b9135e3 100644 --- a/test/unit/aztec/AZEncodeDecodeTest.cpp +++ b/test/unit/aztec/AZEncodeDecodeTest.cpp @@ -88,7 +88,7 @@ namespace { DecoderResult res = parse(matrix.copy(), aztec.compact, aztec.codeWords, aztec.layers); EXPECT_EQ(res.isValid(), true); - EXPECT_EQ(res.content().binary, ByteArray(textBytes)); + EXPECT_EQ(res.content().bytes, ByteArray(textBytes)); // Check error correction by introducing up to eccPercent/2 errors int ecWords = aztec.codeWords * eccPercent / 100 / 2; @@ -105,7 +105,7 @@ namespace { } res = parse(std::move(matrix), aztec.compact, aztec.codeWords, aztec.layers); EXPECT_EQ(res.isValid(), true); - EXPECT_EQ(res.content().binary, ByteArray(textBytes)); + EXPECT_EQ(res.content().bytes, ByteArray(textBytes)); } } diff --git a/test/unit/aztec/AZHighLevelEncoderTest.cpp b/test/unit/aztec/AZHighLevelEncoderTest.cpp index 7e80feb770..5f82f99d4a 100644 --- a/test/unit/aztec/AZHighLevelEncoderTest.cpp +++ b/test/unit/aztec/AZHighLevelEncoderTest.cpp @@ -38,7 +38,7 @@ namespace { BitArray bits = Aztec::HighLevelEncoder::Encode(s); int receivedBitCount = Size(Utility::ToString(bits)); EXPECT_EQ(receivedBitCount, expectedReceivedBits) << "highLevelEncode() failed for input string: " + s; - EXPECT_EQ(ByteArray(s), Aztec::Decode(bits).content().binary); + EXPECT_EQ(ByteArray(s), Aztec::Decode(bits).content().bytes); } } diff --git a/test/unit/pdf417/PDF417DecoderTest.cpp b/test/unit/pdf417/PDF417DecoderTest.cpp index 5b3668843b..2df84c85db 100644 --- a/test/unit/pdf417/PDF417DecoderTest.cpp +++ b/test/unit/pdf417/PDF417DecoderTest.cpp @@ -509,7 +509,7 @@ TEST(PDF417DecoderTest, ECIMultipleNumeric) TEST(PDF417DecoderTest, ECIInvalid) { EXPECT_EQ(decode({ 4, 927, 901, 0 }), L""); // non-charset ECI > 899 -> empty text result - EXPECT_EQ(parse({4, 927, 901, 0}).content().binary, ByteArray("AA")); // non-charset ECI > 899 -> ignored in binary result + EXPECT_EQ(parse({4, 927, 901, 0}).content().bytes, ByteArray("AA")); // non-charset ECI > 899 -> ignored in binary result EXPECT_EQ(decode({ 3, 0, 927 }), L"AA"); // Malformed ECI at end silently ignored } From a8629e04bc0a5369227f035613dc960ae9298984 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 7 Jun 2022 12:29:29 +0200 Subject: [PATCH 0263/1315] python: add the `bytes` property to the Result struct --- wrappers/python/test.py | 1 + wrappers/python/zxing.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/wrappers/python/test.py b/wrappers/python/test.py index 350d08cd0e..8f37dbce59 100644 --- a/wrappers/python/test.py +++ b/wrappers/python/test.py @@ -23,6 +23,7 @@ def check_res(self, res, format, text): self.assertTrue(res.valid) self.assertEqual(res.format, format) self.assertEqual(res.text, text) + self.assertEqual(res.bytes, bytes(text, 'utf-8')) self.assertEqual(res.orientation, 0) def test_write_read_cycle(self): diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 60db5387a2..72336d5c0c 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -205,6 +205,9 @@ PYBIND11_MODULE(zxingcpp, m) .def_property_readonly("text", &Result::text, ":return: text of the decoded symbol\n" ":rtype: str") + .def_property_readonly("bytes", [](const Result& res) { return py::bytes(res.bytes().asString()); }, + ":return: uninterpreted bytes of the decoded symbol\n" + ":rtype: bytes") .def_property_readonly("format", &Result::format, ":return: decoded symbol format\n" ":rtype: zxing.BarcodeFormat") From 5d37ef8d90d3001efddba3cf691abd3f1d1f0bdb Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 8 Jun 2022 10:27:29 +0200 Subject: [PATCH 0264/1315] Result: add MergeStructuredAppendResults() --- core/src/Content.cpp | 7 +++++++ core/src/Content.h | 1 + core/src/Result.cpp | 23 +++++++++++++++++++++++ core/src/Result.h | 7 +++++++ test/blackbox/BlackboxTestRunner.cpp | 27 ++------------------------- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 90dd68d9f8..15ad8787d5 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -54,6 +54,13 @@ void Content::switchEncoding(CharacterSet cs) switchEncoding(ToECI(cs), false); } +void Content::append(const Content& other) +{ + for (auto& e : other.encodings) + encodings.push_back({e.eci, Size(bytes) + e.pos}); + append(other.bytes); +} + void Content::erase(int pos, int n) { bytes.erase(bytes.begin() + pos, bytes.begin() + pos + n); diff --git a/core/src/Content.h b/core/src/Content.h index a96113300e..f429286d9f 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -59,6 +59,7 @@ class Content void push_back(uint8_t val) { bytes.push_back(val); } void append(const std::string& str) { bytes.insert(bytes.end(), str.begin(), str.end()); } void append(const ByteArray& ba) { bytes.insert(bytes.end(), ba.begin(), ba.end()); } + void append(const Content& other); void operator+=(char val) { push_back(val); } void operator+=(const std::string& str) { append(str); } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 9d3c417868..6850dd167e 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -10,6 +10,7 @@ #include "TextDecoder.h" #include +#include #include namespace ZXing { @@ -69,4 +70,26 @@ bool Result::operator==(const Result& o) const return std::min(dTop, dBot) < length / 2; } +Result MergeStructuredAppendResults(const Results& results) +{ + if (results.empty()) + return Result(DecodeStatus::NotFound); + + std::list allResults(results.begin(), results.end()); + allResults.sort([](const Result& r1, const Result& r2) { return r1.sequenceIndex() < r2.sequenceIndex(); }); + + if (allResults.back().sequenceSize() != Size(allResults) || + !std::all_of(allResults.begin(), allResults.end(), + [&](Result& it) { return it.sequenceId() == allResults.front().sequenceId(); })) + return Result(DecodeStatus::FormatError); + + Result res = allResults.front(); + for (auto i = std::next(allResults.begin()); i != allResults.end(); ++i) + res._content.append(i->_content); + + res._text = res._content.text(); + + return res; +} + } // ZXing diff --git a/core/src/Result.h b/core/src/Result.h index 17d969d5b3..13ce7f2bb8 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -114,6 +114,8 @@ class Result bool operator==(const Result& o) const; + friend Result MergeStructuredAppendResults(const std::vector& results); + private: DecodeStatus _status = DecodeStatus::NoError; BarcodeFormat _format = BarcodeFormat::None; @@ -132,4 +134,9 @@ class Result using Results = std::vector; +/** + * @brief Merge a list of Results from one Structured Append set to a single result + */ +Result MergeStructuredAppendResults(const Results& results); + } // ZXing diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 108e91f9b8..4fff96eb5d 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -245,37 +245,14 @@ static void doRunTests(const fs::path& directory, std::string_view format, int t static Result readMultiple(const std::vector& imgPaths, std::string_view format) { - std::list allResults; + Results allResults; for (const auto& imgPath : imgPaths) { auto results = ReadBarcodes(ImageLoader::load(imgPath), DecodeHints().setFormats(BarcodeFormatFromString(format.data())).setTryDownscale(false)); allResults.insert(allResults.end(), results.begin(), results.end()); } - if (allResults.empty()) - return Result(DecodeStatus::NotFound); - - allResults.sort([](const Result& r1, const Result& r2) { return r1.sequenceIndex() < r2.sequenceIndex(); }); - - if (allResults.back().sequenceSize() != Size(allResults) || - !std::all_of(allResults.begin(), allResults.end(), - [&](Result& it) { return it.sequenceId() == allResults.front().sequenceId(); })) - return Result(DecodeStatus::FormatError); - - std::wstring text; - Content content; - for (const auto& r : allResults) { - text.append(r.text()); - content.append(r.bytes()); - } - - const auto& first = allResults.front(); - return {DecoderResult({}, std::move(text), std::move(content)) - .setStructuredAppend({first.sequenceIndex(), first.sequenceSize(), first.sequenceId()}) - .setSymbologyIdentifier(first.symbologyIdentifier()) - .setReaderInit(first.readerInit()), - {}, - first.format()}; + return MergeStructuredAppendResults(allResults); } static void doRunStructuredAppendTest(const fs::path& directory, std::string_view format, int totalTests, From 4d7ea2a603d2ad770d259f436b0078b500a13f21 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 8 Jun 2022 10:59:36 +0200 Subject: [PATCH 0265/1315] DecoderResult: remove `text` and `symbologyIdentifier` member variables This further consolidates the internal structure with respect to the new `Content` class and its application. --- core/src/Content.cpp | 4 ++- core/src/Content.h | 2 +- core/src/DecoderResult.h | 26 ++++--------------- core/src/Result.cpp | 6 ++--- core/src/aztec/AZDecoder.cpp | 2 +- core/src/datamatrix/DMDecoder.cpp | 2 +- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/oned/ODDataBarExpandedReader.cpp | 5 ++-- core/src/oned/ODDataBarReader.cpp | 3 +-- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 2 +- core/src/qrcode/QRDecoder.cpp | 2 +- 11 files changed, 20 insertions(+), 36 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 15ad8787d5..14fddaad2d 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -47,7 +47,9 @@ void Content::switchEncoding(ECI eci, bool isECI) Content::Content() : encodings({{ECI::Unknown, 0}}) {} -Content::Content(ByteArray&& bytes) : bytes(std::move(bytes)), encodings{{ECI::ISO8859_1, 0}} {} +Content::Content(ByteArray&& bytes, SymbologyIdentifier si) + : bytes(std::move(bytes)), encodings{{ECI::ISO8859_1, 0}}, symbology(si) +{} void Content::switchEncoding(CharacterSet cs) { diff --git a/core/src/Content.h b/core/src/Content.h index f429286d9f..5d1f982069 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -49,7 +49,7 @@ class Content bool hasECI = false; Content(); - Content(ByteArray&& bytes); + Content(ByteArray&& bytes, SymbologyIdentifier si); void switchEncoding(ECI eci) { switchEncoding(eci, true); } void switchEncoding(CharacterSet cs); diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 8714396f29..a6ce5e6ab3 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -20,25 +20,16 @@ namespace ZXing { class CustomData; -/** -*

Encapsulates the result of decoding a matrix of bits. This typically -* applies to 2D barcode formats. For now it contains the raw bytes obtained, -* as well as a string interpretation of those bytes, if applicable.

-* -* @author Sean Owen -*/ class DecoderResult { DecodeStatus _status = DecodeStatus::NoError; ByteArray _rawBytes; Content _content; int _numBits = 0; - std::wstring _text; std::string _ecLevel; int _errorsCorrected = -1; int _erasures = -1; int _lineCount = 0; - std::string _symbologyIdentifier; StructuredAppendInfo _structuredAppend; bool _isMirrored = false; bool _readerInit = false; @@ -49,17 +40,9 @@ class DecoderResult public: DecoderResult(DecodeStatus status) : _status(status) {} - DecoderResult(ByteArray&& rawBytes, std::wstring&& text, Content&& binary = {}) - : _rawBytes(std::move(rawBytes)), _content(std::move(binary)), _text(std::move(text)) + DecoderResult(ByteArray&& rawBytes, Content&& bytes = {}) : _rawBytes(std::move(rawBytes)), _content(std::move(bytes)) { _numBits = 8 * Size(_rawBytes); - if (_text.empty()) - _text = _content.text(); - // provide some best guess fallback for barcodes not, yet supporting the content info - if (_content.empty() && std::all_of(_text.begin(), _text.end(), [](auto c) { return c < 256; })) - std::for_each(_text.begin(), _text.end(), [this](wchar_t c) { _content += static_cast(c); }); - if (_content.symbology.code != 0) - _symbologyIdentifier = _content.symbology.toString(); } DecoderResult() = default; @@ -71,11 +54,13 @@ class DecoderResult const ByteArray& rawBytes() const & { return _rawBytes; } ByteArray&& rawBytes() && { return std::move(_rawBytes); } - const std::wstring& text() const & { return _text; } - std::wstring&& text() && { return std::move(_text); } const Content& content() const & { return _content; } Content&& content() && { return std::move(_content); } + // to keep the unit tests happy for now: + std::wstring text() const { return _content.text(); } + std::string symbologyIdentifier() const { return _content.symbology.toString(false); } + // Simple macro to set up getter/setter methods that save lots of boilerplate. // It sets up a standard 'const & () const', 2 setters for setting lvalues via // copy and 2 for setting rvalues via move. They are provided each to work @@ -96,7 +81,6 @@ class DecoderResult ZX_PROPERTY(int, errorsCorrected, setErrorsCorrected) ZX_PROPERTY(int, erasures, setErasures) ZX_PROPERTY(int, lineCount, setLineCount) - ZX_PROPERTY(std::string, symbologyIdentifier, setSymbologyIdentifier) ZX_PROPERTY(StructuredAppendInfo, structuredAppend, setStructuredAppend) ZX_PROPERTY(bool, isMirrored, setIsMirrored) ZX_PROPERTY(bool, readerInit, setReaderInit) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 6850dd167e..b4948f3721 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -19,7 +19,7 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor SymbologyIdentifier si, ByteArray&& rawBytes, const bool readerInit) : _format(format), - _content({ByteArray(text)}), + _content({ByteArray(text)}, si), _text(TextDecoder::FromLatin1(text)), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), @@ -33,12 +33,12 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat : _status(decodeResult.errorCode()), _format(format), _content(std::move(decodeResult).content()), - _text(std::move(decodeResult).text()), + _text(_content.text()), _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), _ecLevel(TextDecoder::FromLatin1(decodeResult.ecLevel())), - _symbologyIdentifier(decodeResult.symbologyIdentifier()), + _symbologyIdentifier(_content.symbology.toString(false)), _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), _readerInit(decodeResult.readerInit()), diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index b099e7434a..86b802c532 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -347,7 +347,7 @@ DecoderResult Decode(const BitArray& bits, const std::string& characterSet) if (sai.index != -1) res.symbology.modifier += 6; // TODO: this is wrong as long as we remove the sai info from the content in ParseStructuredAppend - return DecoderResult(bits.toBytes(), {}, std::move(res)).setNumBits(Size(bits)).setStructuredAppend(sai); + return DecoderResult(bits.toBytes(), std::move(res)).setNumBits(Size(bits)).setStructuredAppend(sai); } DecoderResult Decode(const DetectorResult& detectorResult, const std::string& characterSet) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index efd6f1bea7..1b1f5a785d 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -360,7 +360,7 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b result.applicationIndicator = result.symbology.modifier == '2' ? "GS1" : ""; result.symbology.modifier += isDMRE * 6; - return DecoderResult(std::move(bytes), {}, std::move(result)) + return DecoderResult(std::move(bytes), std::move(result)) .setStructuredAppend(sai) .setReaderInit(readerInit); } diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 16292730ae..e3a781f2bb 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -292,7 +292,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& /*cha case 5: GetMessage(bytes, 1, 77, result, sai); break; } - return DecoderResult(std::move(bytes), {}, std::move(result)) + return DecoderResult(std::move(bytes), std::move(result)) .setEcLevel(std::to_string(mode)) .setStructuredAppend(sai) .setReaderInit(mode == 6); diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 42fed5a6fa..2260931761 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -375,9 +375,8 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, // TODO: EstimatePosition misses part of the symbol in the stacked case where the last row contains less pairs than // the first - return {DecoderResult({}, TextDecoder::FromLatin1(txt)) - .setSymbologyIdentifier("]e0") // ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - .setLineCount(EstimateLineCount(pairs.front(), pairs.back())), + // Symbology identifier: ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 + return {DecoderResult({}, Content(ByteArray(txt), {'e', '0'})).setLineCount(EstimateLineCount(pairs.front(), pairs.back())), EstimatePosition(pairs.front(), pairs.back()), BarcodeFormat::DataBarExpanded}; } diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index b9f4fa9601..a39ec9f741 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -198,8 +198,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, for (const auto& rightPair : prevState->rightPairs) if (ChecksumIsValid(leftPair, rightPair)) { // Symbology identifier ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - Result res{DecoderResult({}, TextDecoder::FromLatin1(ConstructText(leftPair, rightPair))) - .setSymbologyIdentifier("]e0") + Result res{DecoderResult({}, Content(ByteArray(ConstructText(leftPair, rightPair)), {'e', '0'})) .setLineCount(EstimateLineCount(leftPair, rightPair)), EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar}; diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 515c066b1d..6f7a835309 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -791,7 +791,7 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, c sai.id = resultMetadata->fileId(); } - return DecoderResult(ByteArray(), {}, std::move(result)) + return DecoderResult({}, std::move(result)) .setEcLevel(std::to_string(ecLevel)) .setStructuredAppend(sai) .setReaderInit(readerInit) diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index e4ebed8192..29d35f0ac3 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -338,7 +338,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo return DecodeStatus::FormatError; } - return DecoderResult(std::move(bytes), {}, std::move(result)) + return DecoderResult(std::move(bytes), std::move(result)) .setEcLevel(ToString(ecLevel)) .setStructuredAppend(structuredAppend); } From fbbe4c4f0d1beb36d5eee9ab7a8491b95a4e730d Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 8 Jun 2022 11:50:33 +0200 Subject: [PATCH 0266/1315] TextDecoder: non-printable ASCII control chars -> probably not Shift_JIS This fixes a regression with some Aztec binary symbols reported by @vkrause. --- core/src/TextDecoder.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/TextDecoder.cpp b/core/src/TextDecoder.cpp index 4df8a65f14..b9835c77ad 100644 --- a/core/src/TextDecoder.cpp +++ b/core/src/TextDecoder.cpp @@ -426,6 +426,9 @@ TextDecoder::GuessEncoding(const uint8_t* bytes, size_t length, CharacterSet fal else if (value == 0x80 || value == 0xA0 || value > 0xEF) { canBeShiftJIS = false; } + else if (value < 0x20 && value != 0xa && value != 0xd) { + canBeShiftJIS = false; // use non-printable ASCII as indication for binary content + } else if (value > 0xA0 && value < 0xE0) { sjisKatakanaChars++; sjisCurDoubleBytesWordLength = 0; From 364007b662004261b01435600e61aa072aed94e1 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 9 Jun 2022 12:53:47 +0200 Subject: [PATCH 0267/1315] ECI: change handling of pseudo-ECIs to fix MergeStructuredAppendResults This fixes the cross symbol ECI sample discussed in https://github.com/nu-book/zxing-cpp/issues/334#issuecomment-1150297982 --- core/src/Content.cpp | 34 ++++++++++++++++----------- test/blackbox/BlackboxTestRunner.cpp | 4 ++-- test/samples/pdf417-4/03-01.png | Bin 0 -> 583 bytes test/samples/pdf417-4/03.txt | 1 + 4 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 test/samples/pdf417-4/03-01.png create mode 100644 test/samples/pdf417-4/03.txt diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 14fddaad2d..21fde3c976 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -22,6 +22,12 @@ std::string ToString(ContentType type) template void Content::ForEachECIBlock(FUNC func) const { + ECI defaultECI = hasECI ? ECI::ISO8859_1 : ECI::Unknown; + if (encodings.empty()) + func(defaultECI, 0, Size(bytes)); + else if (encodings.front().pos != 0) + func(defaultECI, 0, encodings.front().pos); + for (int i = 0; i < Size(encodings); ++i) { auto [eci, start] = encodings[i]; int end = i + 1 == Size(encodings) ? Size(bytes) : encodings[i + 1].pos; @@ -33,23 +39,18 @@ void Content::ForEachECIBlock(FUNC func) const void Content::switchEncoding(ECI eci, bool isECI) { - // replace all non-ECI entries on first ECI entry with default ECI + // remove all non-ECI entries on first ECI entry if (isECI && !hasECI) - encodings = {{ECI::ISO8859_1, 0}}; - if (isECI || !hasECI) { - if (encodings.back().pos == Size(bytes)) - encodings.back().eci = eci; // no point in recording 0 length segments - else - encodings.push_back({eci, Size(bytes)}); - } + encodings.clear(); + if (isECI || !hasECI) + encodings.push_back({eci, Size(bytes)}); + hasECI |= isECI; } -Content::Content() : encodings({{ECI::Unknown, 0}}) {} +Content::Content() {} -Content::Content(ByteArray&& bytes, SymbologyIdentifier si) - : bytes(std::move(bytes)), encodings{{ECI::ISO8859_1, 0}}, symbology(si) -{} +Content::Content(ByteArray&& bytes, SymbologyIdentifier si) : bytes(std::move(bytes)), symbology(si) {} void Content::switchEncoding(CharacterSet cs) { @@ -58,9 +59,14 @@ void Content::switchEncoding(CharacterSet cs) void Content::append(const Content& other) { - for (auto& e : other.encodings) - encodings.push_back({e.eci, Size(bytes) + e.pos}); + if (!hasECI && other.hasECI) + encodings.clear(); + if (other.hasECI || !hasECI) + for (auto& e : other.encodings) + encodings.push_back({e.eci, Size(bytes) + e.pos}); append(other.bytes); + + hasECI |= other.hasECI; } void Content::erase(int pos, int n) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 4fff96eb5d..2d7fe005dd 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -615,8 +615,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 7, 0, pure }, }); - runStructuredAppendTest("pdf417-4", "PDF417", 2, { - { 2, 2, 0 }, + runStructuredAppendTest("pdf417-4", "PDF417", 3, { + { 3, 3, 0 }, }); runTests("falsepositives-1", "None", 26, { diff --git a/test/samples/pdf417-4/03-01.png b/test/samples/pdf417-4/03-01.png new file mode 100644 index 0000000000000000000000000000000000000000..3e54a6e9e2b882192aa8601545b77df60e4d388d GIT binary patch literal 583 zcmV-N0=WH&P)Px#22e~?MF0Q*|NsA`*`M7200G}gL_t(o!|m6xswOcA z1z^Ee@Kpp`!B-d327DDEt&q)s*=n1u7S_w1YA|0DGEB~a`?sfI7->Lt)VNE8iYNEuj}jBVf%#~nhIgCc5eK>;hcb9J0l^)@r=1O5n8IK*p|~DiOMzAw zoJG-hGy#RRe8X`Lq74okdoRpCh5~pGHp}^sU>g;Sh*NPe{ zbrp^#T6e9?R<7&=#c#k<$@fb^Kja^i0M%0CRt)#kopQNQ!GJn#DuLaEo-VL`UC~EY zPbNphJ2Tui-U!9|{N6?rK`^`a@>}>SXW1B|Nh!9W)cqV|B(B<=J({49z3`SCY|*dI zDd=c&jDN>9-yHh7s>YuuJ&P3Drz9i;ZGQQ!WrNHnZ`B~irtPyBWq3^(@Rov~Ci- zB(HWylbvwO0^jQLPxjbZJen-wmz Date: Thu, 9 Jun 2022 12:55:00 +0200 Subject: [PATCH 0268/1315] Result: clear position and structuredAppendIndex in merged result --- core/src/Result.cpp | 2 ++ core/src/Result.h | 2 +- test/samples/qrcode-7/01.result.txt | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index b4948f3721..a516f9087b 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -88,6 +88,8 @@ Result MergeStructuredAppendResults(const Results& results) res._content.append(i->_content); res._text = res._content.text(); + res._position = {}; + res._sai.index = -1; return res; } diff --git a/core/src/Result.h b/core/src/Result.h index 13ce7f2bb8..f52d41e0b6 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -99,7 +99,7 @@ class Result const std::string& sequenceId() const { return _sai.id; } bool isLastInSequence() const { return sequenceSize() == sequenceIndex() + 1; } - bool isPartOfSequence() const { return sequenceSize() > -1; } + bool isPartOfSequence() const { return sequenceSize() > -1 && sequenceIndex() > -1; } /** * @brief readerInit Set if Reader Initialisation/Programming symbol. diff --git a/test/samples/qrcode-7/01.result.txt b/test/samples/qrcode-7/01.result.txt index 7867b23fec..0631ce5a33 100644 --- a/test/samples/qrcode-7/01.result.txt +++ b/test/samples/qrcode-7/01.result.txt @@ -1,6 +1,6 @@ symbologyIdentifier=]Q1 # ecLevel not set when "runStructuredAppendTest" sequenceSize=4 -# sequenceIndex set to first when "runStructuredAppendTest" -sequenceIndex=0 +# sequenceIndex set to -1 in MergeStructuredAppendResults +sequenceIndex=-1 sequenceId=95 From 856903310d157fc1fee482efef53899ff6f46ecf Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 9 Jun 2022 13:43:38 +0200 Subject: [PATCH 0269/1315] Result: add MergeStructuredAppendSequences for automatically merging Add some automatic structured append sequence merging to ZXingReader. All merged sequences are reported under the last file name (for now). --- core/src/Result.cpp | 21 ++++++++++++++++++++- core/src/Result.h | 11 ++++++++--- example/ZXingReader.cpp | 11 +++++++++++ test/blackbox/BlackboxTestRunner.cpp | 2 +- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index a516f9087b..b077830286 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -11,6 +11,7 @@ #include #include +#include #include namespace ZXing { @@ -70,7 +71,7 @@ bool Result::operator==(const Result& o) const return std::min(dTop, dBot) < length / 2; } -Result MergeStructuredAppendResults(const Results& results) +Result MergeStructuredAppendSequence(const Results& results) { if (results.empty()) return Result(DecodeStatus::NotFound); @@ -94,4 +95,22 @@ Result MergeStructuredAppendResults(const Results& results) return res; } +Results MergeStructuredAppendSequences(const Results& results) +{ + std::map sas; + for (auto& res : results) { + if (res.isPartOfSequence()) + sas[res.sequenceId()].push_back(res); + } + + Results saiResults; + for (auto& [id, seq] : sas) { + auto res = MergeStructuredAppendSequence(seq); + if (res.isValid()) + saiResults.push_back(std::move(res)); + } + + return saiResults; +} + } // ZXing diff --git a/core/src/Result.h b/core/src/Result.h index f52d41e0b6..8a07381e1c 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -114,7 +114,7 @@ class Result bool operator==(const Result& o) const; - friend Result MergeStructuredAppendResults(const std::vector& results); + friend Result MergeStructuredAppendSequence(const std::vector& results); private: DecodeStatus _status = DecodeStatus::NoError; @@ -135,8 +135,13 @@ class Result using Results = std::vector; /** - * @brief Merge a list of Results from one Structured Append set to a single result + * @brief Merge a list of Results from one Structured Append sequence to a single result */ -Result MergeStructuredAppendResults(const Results& results); +Result MergeStructuredAppendSequence(const Results& results); + +/** + * @brief Automatically merge all structured append sequences found in the given results + */ +Results MergeStructuredAppendSequences(const Results& results); } // ZXing diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 937da9077a..578e7714c6 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -115,6 +115,7 @@ int main(int argc, char* argv[]) { DecodeHints hints; std::vector filePaths; + Results allResults; std::string outPath; bool oneLine = false; bool angleEscape = false; @@ -152,6 +153,13 @@ int main(int argc, char* argv[]) if (results.empty()) results.emplace_back(DecodeStatus::NotFound); + allResults.insert(allResults.end(), results.begin(), results.end()); + if (filePath == filePaths.back()) { + auto merged = MergeStructuredAppendSequences(allResults); + // report all merged sequences as part of the last file to make the logic not overly complicated here + results.insert(results.end(), merged.begin(), merged.end()); + } + for (auto&& result : results) { if (!outPath.empty()) @@ -219,6 +227,9 @@ int main(int argc, char* argv[]) if (result.isPartOfSequence()) std::cout << "Structured Append: symbol " << result.sequenceIndex() + 1 << " of " << result.sequenceSize() << " (parity/id: '" << result.sequenceId() << "')\n"; + else if (result.sequenceSize() > 0) + std::cout << "Structured Append: merged result from " << result.sequenceSize() << " symbols (parity/id: '" + << result.sequenceId() << "')\n"; if (result.readerInit()) std::cout << "Reader Initialisation/Programming\n"; diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 2d7fe005dd..085bb41d95 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -252,7 +252,7 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi allResults.insert(allResults.end(), results.begin(), results.end()); } - return MergeStructuredAppendResults(allResults); + return MergeStructuredAppendSequence(allResults); } static void doRunStructuredAppendTest(const fs::path& directory, std::string_view format, int totalTests, From 7da0d436842ce1026591202eccad1429f661e2bb Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 13 Jun 2022 18:37:49 +0200 Subject: [PATCH 0270/1315] example: port ZXingQtReader to Qt6 Note: to compile it with qt6, increase c++ standard to 17 and replace `find_package(Qt5 ...` with `ind_package(Qt6 ...`. The overlay drawing feature is missing due to a removed `videoOutput.mapPointToItem()` function. The default video resolution is different and the `Q_ENUM_NS` macros don't work correct (int value instead of string in GUI). --- example/CMakeLists.txt | 8 +- ...gQtCamReader.qml => ZXingQt5CamReader.qml} | 22 +-- example/ZXingQt6CamReader.qml | 148 ++++++++++++++++++ example/ZXingQtCamReader.cpp | 8 +- example/ZXingQtCamReader.qrc | 3 +- example/ZXingQtReader.h | 138 +++++++++++----- 6 files changed, 265 insertions(+), 62 deletions(-) rename example/{ZXingQtCamReader.qml => ZXingQt5CamReader.qml} (87%) create mode 100644 example/ZXingQt6CamReader.qml diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 8cb2e1b4d8..36d663a67f 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -30,14 +30,14 @@ if (BUILD_READERS) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) - if (TARGET Qt5::Gui) + if (TARGET Qt::Gui) add_executable (ZXingQtReader ZXingQtReader.cpp ZXingQtReader.h) - target_link_libraries(ZXingQtReader ZXing::ZXing Qt5::Gui) + target_link_libraries(ZXingQtReader ZXing::ZXing Qt::Gui) endif() - if (TARGET Qt5::Multimedia) + if (TARGET Qt::Multimedia AND TARGET Qt::Quick) add_executable(ZXingQtCamReader ZXingQtCamReader.cpp ZXingQtCamReader.qrc ZXingQtReader.h) - target_link_libraries(ZXingQtCamReader ZXing::ZXing Qt5::Gui Qt5::Multimedia Qt5::Quick) + target_link_libraries(ZXingQtCamReader ZXing::ZXing Qt::Gui Qt::Multimedia Qt::Quick) endif() find_package(OpenCV) diff --git a/example/ZXingQtCamReader.qml b/example/ZXingQt5CamReader.qml similarity index 87% rename from example/ZXingQtCamReader.qml rename to example/ZXingQt5CamReader.qml index 9a90cf20d6..bf3f8d3ed2 100644 --- a/example/ZXingQtCamReader.qml +++ b/example/ZXingQt5CamReader.qml @@ -1,18 +1,7 @@ /* * Copyright 2020 Axel Waggershauser - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 import QtQuick 2.12 import QtQuick.Window 2.12 @@ -36,12 +25,13 @@ Window { interval: 2000 } - VideoFilter { - id: zxingFilter + BarcodeReader { + id: barcodeReader formats: (oneDSwitch.checked ? (ZXing.OneDCodes) : ZXing.None) | (twoDSwitch.checked ? (ZXing.TwoDCodes) : ZXing.None) tryRotate: tryRotateSwitch.checked tryHarder: tryHarderSwitch.checked + tryDownscale: tryDownscaleSwitch.checked // callback with parameter 'result', called for every successfully processed frame // onFoundBarcode: {} @@ -100,7 +90,7 @@ Window { id: videoOutput Layout.fillHeight: true Layout.fillWidth: true - filters: [zxingFilter] + filters: [barcodeReader] source: camera autoOrientation: true @@ -144,9 +134,11 @@ Window { ColumnLayout { anchors.right: parent.right + anchors.bottom: parent.bottom Switch {id: tryRotateSwitch; text: qsTr("Try Rotate"); checked: true } Switch {id: tryHarderSwitch; text: qsTr("Try Harder"); checked: true } + Switch {id: tryDownscaleSwitch; text: qsTr("Try Downscale"); checked: true } Switch {id: oneDSwitch; text: qsTr("1D Codes"); checked: true } Switch {id: twoDSwitch; text: qsTr("2D Codes"); checked: true } } diff --git a/example/ZXingQt6CamReader.qml b/example/ZXingQt6CamReader.qml new file mode 100644 index 0000000000..7c80e77855 --- /dev/null +++ b/example/ZXingQt6CamReader.qml @@ -0,0 +1,148 @@ +/* + * Copyright 2022 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Shapes +import QtMultimedia +import ZXing + +Window { + visible: true + width: 640 + height: 480 + title: Qt.application.name + + property var nullPoints: [Qt.point(0,0), Qt.point(0,0), Qt.point(0,0), Qt.point(0,0)] + property var points: nullPoints + + Timer { + id: resetInfo + interval: 2000 + } + + BarcodeReader { + id: barcodeReader + videoSink: videoOutput.videoSink + + formats: (oneDSwitch.checked ? (ZXing.OneDCodes) : ZXing.None) | (twoDSwitch.checked ? (ZXing.TwoDCodes) : ZXing.None) + tryRotate: tryRotateSwitch.checked + tryHarder: tryHarderSwitch.checked + tryDownscale: tryDownscaleSwitch.checked + + // callback with parameter 'result', called for every successfully processed frame + // onFoundBarcode: {} + + // callback with parameter 'result', called for every processed frame + onNewResult: { + points = result.isValid + ? [result.position.topLeft, result.position.topRight, result.position.bottomRight, result.position.bottomLeft] + : nullPoints + + if (result.isValid) + resetInfo.restart() + + if (result.isValid || !resetInfo.running) + info.text = qsTr("Format: \t %1 \nText: \t %2 \nError: \t %3 \nTime: \t %4 ms").arg(result.formatName).arg(result.text).arg(result.status).arg(result.runTime) + +// console.log(result) + } + } + + MediaDevices { + id: devices + } + + Camera { + id: camera + cameraDevice: devices.videoInputs[camerasComboBox.currentIndex] ? devices.videoInputs[camerasComboBox.currentIndex] : devices.defaultVideoInput + focusMode: Camera.FocusModeAutoNear + onErrorOccurred: console.log("camera error:" + errorString) + } + + CaptureSession { + id: captureSession + camera: camera + videoOutput: videoOutput + } + + ColumnLayout { + anchors.fill: parent + + RowLayout { + Layout.fillWidth: true + Layout.fillHeight: false + visible: devices.videoInputs.length > 1 + Label { + text: qsTr("Camera: ") + Layout.fillWidth: false + } + ComboBox { + id: camerasComboBox + Layout.fillWidth: true + model: devices.videoInputs + textRole: "displayName" + currentIndex: 0 + } + } + + VideoOutput { + id: videoOutput + Layout.fillHeight: true + Layout.fillWidth: true + +// Shape { +// id: polygon +// anchors.fill: parent +// visible: points.length == 4 +// ShapePath { +// strokeWidth: 3 +// strokeColor: "red" +// strokeStyle: ShapePath.SolidLine +// fillColor: "transparent" +// //TODO: really? I don't know qml... +// startX: videoOutput.mapPointToItem(points[3]).x +// startY: videoOutput.mapPointToItem(points[3]).y +// PathLine { +// x: videoOutput.mapPointToItem(points[0]).x +// y: videoOutput.mapPointToItem(points[0]).y +// } +// PathLine { +// x: videoOutput.mapPointToItem(points[1]).x +// y: videoOutput.mapPointToItem(points[1]).y +// } +// PathLine { +// x: videoOutput.mapPointToItem(points[2]).x +// y: videoOutput.mapPointToItem(points[2]).y +// } +// PathLine { +// x: videoOutput.mapPointToItem(points[3]).x +// y: videoOutput.mapPointToItem(points[3]).y +// } +// } +// } + + Label { + id: info + color: "white" + padding: 10 + background: Rectangle { color: "#80808080" } + } + + ColumnLayout { + anchors.right: parent.right + anchors.bottom: parent.bottom + + Switch {id: tryRotateSwitch; text: qsTr("Try Rotate"); checked: true } + Switch {id: tryHarderSwitch; text: qsTr("Try Harder"); checked: true } + Switch {id: tryDownscaleSwitch; text: qsTr("Try Downscale"); checked: true } + Switch {id: oneDSwitch; text: qsTr("1D Codes"); checked: true } + Switch {id: twoDSwitch; text: qsTr("2D Codes"); checked: true } + } + } + } +} diff --git a/example/ZXingQtCamReader.cpp b/example/ZXingQtCamReader.cpp index 102312e0e6..3815bfe43b 100644 --- a/example/ZXingQtCamReader.cpp +++ b/example/ZXingQtCamReader.cpp @@ -10,14 +10,20 @@ int main(int argc, char *argv[]) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif ZXingQt::registerQmlAndMetaTypes(); QGuiApplication app(argc, argv); app.setApplicationName("ZXingQtCamReader"); QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/ZXingQtCamReader.qml"))); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + engine.load(QUrl(QStringLiteral("qrc:/ZXingQt5CamReader.qml"))); +#else + engine.load(QUrl(QStringLiteral("qrc:/ZXingQt6CamReader.qml"))); +#endif if (engine.rootObjects().isEmpty()) return -1; diff --git a/example/ZXingQtCamReader.qrc b/example/ZXingQtCamReader.qrc index 967e6ec7d1..b6b772c75c 100644 --- a/example/ZXingQtCamReader.qrc +++ b/example/ZXingQtCamReader.qrc @@ -1,5 +1,6 @@ - ZXingQtCamReader.qml + ZXingQt5CamReader.qml + ZXingQt6CamReader.qml diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 7435e56c85..07effc10d0 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -12,7 +12,12 @@ #include #ifdef QT_MULTIMEDIA_LIB +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include +#else +#include +#include +#endif #include #endif @@ -154,7 +159,7 @@ inline Result ReadBarcode(const QImage& img, const DecodeHints& hints = {}) auto exec = [&](const QImage& img) { return Result(ZXing::ReadBarcode( - {img.bits(), img.width(), img.height(), ImgFmtFromQImg(img), img.bytesPerLine()}, hints)); + {img.bits(), img.width(), img.height(), ImgFmtFromQImg(img), static_cast(img.bytesPerLine())}, hints)); }; return ImgFmtFromQImg(img) == ImageFormat::None ? exec(img.convertToFormat(QImage::Format_Grayscale8)) : exec(img); @@ -166,7 +171,11 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { using namespace ZXing; auto img = frame; // shallow copy just get access to non-const map() function +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (!frame.isValid() || !img.map(QAbstractVideoBuffer::ReadOnly)){ +#else + if (!frame.isValid() || !img.map(QVideoFrame::ReadOnly)){ +#endif qWarning() << "invalid QVideoFrame: could not map memory"; return {}; } @@ -176,10 +185,18 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { int pixStride = 0; int pixOffset = 0; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#define FORMAT(F5, F6) QVideoFrame::Format_##F5 +#define FIRST_PLANE +#else +#define FORMAT(F5, F6) QVideoFrameFormat::Format_##F6 +#define FIRST_PLANE 0 +#endif + switch (img.pixelFormat()) { - case QVideoFrame::Format_ARGB32: - case QVideoFrame::Format_ARGB32_Premultiplied: - case QVideoFrame::Format_RGB32: + case FORMAT(ARGB32, ARGB8888): + case FORMAT(ARGB32_Premultiplied, ARGB8888_Premultiplied): + case FORMAT(RGB32, RGBX8888): #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN fmt = ImageFormat::BGRX; #else @@ -187,11 +204,9 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { #endif break; - case QVideoFrame::Format_RGB24: fmt = ImageFormat::RGB; break; - - case QVideoFrame::Format_BGRA32: - case QVideoFrame::Format_BGRA32_Premultiplied: - case QVideoFrame::Format_BGR32: + case FORMAT(BGRA32, BGRA8888): + case FORMAT(BGRA32_Premultiplied, BGRA8888_Premultiplied): + case FORMAT(BGR32, BGRX8888): #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN fmt = ImageFormat::RGBX; #else @@ -199,10 +214,17 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { #endif break; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + case QVideoFrame::Format_RGB24: fmt = ImageFormat::RGB; break; case QVideoFrame::Format_BGR24: fmt = ImageFormat::BGR; break; + case QVideoFrame::Format_YUV444: fmt = ImageFormat::Lum, pixStride = 3; break; +#else + case QVideoFrameFormat::Format_P010: + case QVideoFrameFormat::Format_P016: fmt = ImageFormat::Lum, pixStride = 1; break; +#endif - case QVideoFrame::Format_AYUV444: - case QVideoFrame::Format_AYUV444_Premultiplied: + case FORMAT(AYUV444, AYUV): + case FORMAT(AYUV444_Premultiplied, AYUV_Premultiplied): #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN fmt = ImageFormat::Lum, pixStride = 4, pixOffset = 3; #else @@ -210,23 +232,22 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { #endif break; - case QVideoFrame::Format_YUV444: fmt = ImageFormat::Lum, pixStride = 3; break; - case QVideoFrame::Format_YUV420P: - case QVideoFrame::Format_NV12: - case QVideoFrame::Format_NV21: - case QVideoFrame::Format_IMC1: - case QVideoFrame::Format_IMC2: - case QVideoFrame::Format_IMC3: - case QVideoFrame::Format_IMC4: - case QVideoFrame::Format_YV12: fmt = ImageFormat::Lum; break; - case QVideoFrame::Format_UYVY: fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break; - case QVideoFrame::Format_YUYV: fmt = ImageFormat::Lum, pixStride = 2; break; - - case QVideoFrame::Format_Y8: fmt = ImageFormat::Lum; break; - case QVideoFrame::Format_Y16: fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break; + case FORMAT(YUV420P, YUV420P): + case FORMAT(NV12, NV12): + case FORMAT(NV21, NV21): + case FORMAT(IMC1, IMC1): + case FORMAT(IMC2, IMC2): + case FORMAT(IMC3, IMC3): + case FORMAT(IMC4, IMC4): + case FORMAT(YV12, YV12): fmt = ImageFormat::Lum; break; + case FORMAT(UYVY, UYVY): fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break; + case FORMAT(YUYV, YUYV): fmt = ImageFormat::Lum, pixStride = 2; break; + + case FORMAT(Y8, Y8): fmt = ImageFormat::Lum; break; + case FORMAT(Y16, Y16): fmt = ImageFormat::Lum, pixStride = 2, pixOffset = 1; break; #if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)) - case QVideoFrame::Format_ABGR32: + case FORMAT(ABGR32, ABGR8888): #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN fmt = ImageFormat::RGBX; #else @@ -235,19 +256,22 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { break; #endif #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - case QVideoFrame::Format_YUV422P: fmt = ImageFormat::Lum; break; + case FORMAT(YUV422P, YUV422P): fmt = ImageFormat::Lum; break; #endif default: break; } Result res; if (fmt != ImageFormat::None) { - res = Result( - ZXing::ReadBarcode({img.bits() + pixOffset, img.width(), img.height(), fmt, img.bytesPerLine(), pixStride}, - hints)); + res = Result(ZXing::ReadBarcode( + {img.bits(FIRST_PLANE) + pixOffset, img.width(), img.height(), fmt, img.bytesPerLine(FIRST_PLANE), pixStride}, hints)); } else { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (QVideoFrame::imageFormatFromPixelFormat(img.pixelFormat()) != QImage::Format_Invalid) res = ReadBarcode(img.image(), hints); +#else + res = ReadBarcode(img.toImage(), hints); +#endif } img.unmap(); @@ -268,14 +292,21 @@ public: \ } \ Q_SIGNAL void name##Changed(); -class VideoFilter : public QAbstractVideoFilter, private DecodeHints + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +class BarcodeReader : public QAbstractVideoFilter, private DecodeHints +#else +class BarcodeReader : public QObject, private DecodeHints +#endif { Q_OBJECT public: - VideoFilter(QObject* parent = nullptr) : QAbstractVideoFilter(parent) {} - - QVideoFilterRunnable* createFilterRunnable() override; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + BarcodeReader(QObject* parent = nullptr) : QAbstractVideoFilter(parent) {} +#else + BarcodeReader(QObject* parent = nullptr) : QObject(parent) {} +#endif // TODO: find out how to properly expose QFlags to QML // simply using ZQ_PROPERTY(BarcodeFormats, formats, setFormats) @@ -298,9 +329,10 @@ class VideoFilter : public QAbstractVideoFilter, private DecodeHints ZQ_PROPERTY(bool, tryRotate, setTryRotate) ZQ_PROPERTY(bool, tryHarder, setTryHarder) + ZQ_PROPERTY(bool, tryDownscale, setTryDownscale) public slots: - Result process(const QVideoFrame& image) + ZXingQt::Result process(const QVideoFrame& image) { QElapsedTimer t; t.start(); @@ -316,18 +348,41 @@ public slots: } signals: - void newResult(Result result); - void foundBarcode(Result result); + void newResult(ZXingQt::Result result); + void foundBarcode(ZXingQt::Result result); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +public: + QVideoFilterRunnable *createFilterRunnable() override; +#else +private: + QVideoSink *_sink = nullptr; + +public: + void setVideoSink(QVideoSink* sink) { + if (_sink == sink) + return; + + if (_sink) + disconnect(_sink, nullptr, this, nullptr); + + _sink = sink; + connect(_sink, &QVideoSink::videoFrameChanged, this, &BarcodeReader::process); + } + Q_PROPERTY(QVideoSink* videoSink WRITE setVideoSink) +#endif + }; #undef ZX_PROPERTY +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) class VideoFilterRunnable : public QVideoFilterRunnable { - VideoFilter* _filter = nullptr; + BarcodeReader* _filter = nullptr; public: - explicit VideoFilterRunnable(VideoFilter* filter) : _filter(filter) {} + explicit VideoFilterRunnable(BarcodeReader* filter) : _filter(filter) {} QVideoFrame run(QVideoFrame* input, const QVideoSurfaceFormat& /*surfaceFormat*/, RunFlags /*flags*/) override { @@ -336,10 +391,11 @@ class VideoFilterRunnable : public QVideoFilterRunnable } }; -inline QVideoFilterRunnable* VideoFilter::createFilterRunnable() +inline QVideoFilterRunnable* BarcodeReader::createFilterRunnable() { return new VideoFilterRunnable(this); } +#endif #endif // QT_MULTIMEDIA_LIB @@ -367,7 +423,7 @@ inline void registerQmlAndMetaTypes() qmlRegisterUncreatableMetaObject( ZXingQt::staticMetaObject, "ZXing", 1, 0, "ZXing", "Access to enums & flags only"); - qmlRegisterType("ZXing", 1, 0, "VideoFilter"); + qmlRegisterType("ZXing", 1, 0, "BarcodeReader"); } } // namespace ZXingQt From 86d28521300d58cb1f8848946729d0cc6ca60ea7 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 13 Jun 2022 19:03:41 +0200 Subject: [PATCH 0271/1315] cmake: revert breaking change of `INTERFACE "$"` The change was deliberate but ill advised. Need a different solution to make the examples compile with the installed includes. --- core/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 7b34509510..e6c4d1a07f 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -461,7 +461,7 @@ add_library (ZXing target_include_directories (ZXing PUBLIC "$" - INTERFACE "$" + INTERFACE "$" ) target_compile_options (ZXing From a555eb01e13eb2768ffbe340526409edf14a6074 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 14 Jun 2022 13:29:25 +0200 Subject: [PATCH 0272/1315] API: improve a few comments for public symbols --- core/src/DecodeHints.h | 8 ++------ core/src/ReadBarcode.h | 8 +++++++- core/src/Result.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 68ffe031b9..26813d387e 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -109,7 +109,7 @@ class DecodeHints /// The maximum number of symbols (barcodes) to detect / look for in the image with ReadBarcodes ZX_PROPERTY(uint8_t, maxNumberOfSymbols, setMaxNumberOfSymbols) - /// Specifies what character encoding to use when decoding, where applicable. + /// Specifies fallback character set to use instead of auto-detecting it (when applicable) ZX_PROPERTY(std::string, characterSet, setCharacterSet) /// Allowed lengths of encoded data -- reject anything else.. @@ -124,11 +124,7 @@ class DecodeHints /// Assume ITF codes employ a GS1 check digit and validate it. ZX_PROPERTY(bool, validateITFCheckSum, setValidateITFCheckSum) - /** - * If true, return the start and end digits in a Codabar barcode instead of stripping them. They - * are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them - * to not be. - */ + /// If true, return the start and end chars in a Codabar barcode instead of stripping them. ZX_PROPERTY(bool, returnCodabarStartEnd, setReturnCodabarStartEnd) /// Specify whether to ignore, read or require EAN-2/5 add-on symbols while scanning EAN/UPC codes diff --git a/core/src/ReadBarcode.h b/core/src/ReadBarcode.h index a76d60c31b..5b73d16913 100644 --- a/core/src/ReadBarcode.h +++ b/core/src/ReadBarcode.h @@ -20,7 +20,13 @@ namespace ZXing { */ Result ReadBarcode(const ImageView& buffer, const DecodeHints& hints = {}); -// WARNING: this API is experimental and may change/disappear +/** + * Read barcodes from an ImageView + * + * @param buffer view of the image data including layout and format + * @param hints optional DecodeHints to parameterize / speed up decoding + * @return #Results list of results found, may be empty + */ Results ReadBarcodes(const ImageView& buffer, const DecodeHints& hints = {}); } // ZXing diff --git a/core/src/Result.h b/core/src/Result.h index 8a07381e1c..c0a27513d7 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -140,7 +140,7 @@ using Results = std::vector; Result MergeStructuredAppendSequence(const Results& results); /** - * @brief Automatically merge all structured append sequences found in the given results + * @brief Automatically merge all Structured Append sequences found in the given results */ Results MergeStructuredAppendSequences(const Results& results); From 5b461cb5cd1cf3ba0ff0049b43ed03ade429874c Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 14 Jun 2022 13:31:34 +0200 Subject: [PATCH 0273/1315] Result: remove applicationIndicator property (for now) --- core/src/Result.h | 1 - example/ZXingReader.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/core/src/Result.h b/core/src/Result.h index c0a27513d7..7f6db93e59 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -49,7 +49,6 @@ class Result const ByteArray& bytes() const { return _content.bytes; } const ByteArray bytesECI() const { return _content.bytesECI(); } const std::string utf8Protocol() const { return _content.utf8Protocol(); } - const std::string& applicationIndicator() const { return _content.applicationIndicator; } ContentType contentType() const { return _content.type(); } bool hasECI() const { return _content.hasECI; } // END WARNING diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 578e7714c6..56f6759491 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -209,7 +209,6 @@ int main(int argc, char* argv[]) }; printOptional("EC Level: ", ToUtf8(result.ecLevel())); - printOptional("App-Ind.: ", result.applicationIndicator()); if (result.lineCount()) std::cout << "Lines: " << result.lineCount() << "\n"; From e6be0662da80be5a4c923e0880457b26221380fc Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 14 Jun 2022 13:46:44 +0200 Subject: [PATCH 0274/1315] Result: increase API resilience against future ABI breakages (de-inlining) --- core/src/Result.cpp | 55 ++++++++++++++++++++++++++++++++++++++++----- core/src/Result.h | 24 ++++++++++---------- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index b077830286..72c995e0f5 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -21,11 +21,9 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor : _format(format), _content({ByteArray(text)}, si), - _text(TextDecoder::FromLatin1(text)), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), _numBits(Size(_rawBytes) * 8), - _symbologyIdentifier(si.toString()), _readerInit(readerInit), _lineCount(0) {} @@ -34,12 +32,10 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat : _status(decodeResult.errorCode()), _format(format), _content(std::move(decodeResult).content()), - _text(_content.text()), _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), _ecLevel(TextDecoder::FromLatin1(decodeResult.ecLevel())), - _symbologyIdentifier(_content.symbology.toString(false)), _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), _readerInit(decodeResult.readerInit()), @@ -48,12 +44,62 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } +std::wstring Result::text() const +{ + return _content.text(); +} + +const ByteArray& Result::bytes() const +{ + return _content.bytes; +} + +ByteArray Result::bytesECI() const +{ + return _content.bytesECI(); +} + +std::string Result::utf8Protocol() const +{ + return _content.utf8Protocol(); +} + +ContentType Result::contentType() const +{ + return _content.type(); +} + +bool Result::hasECI() const +{ + return _content.hasECI; +} + int Result::orientation() const { constexpr auto std_numbers_pi_v = 3.14159265358979323846; // TODO: c++20 return std::lround(_position.orientation() * 180 / std_numbers_pi_v); } +std::string Result::symbologyIdentifier() const +{ + return _content.symbology.toString(); +} + +int Result::sequenceSize() const +{ + return _sai.count; +} + +int Result::sequenceIndex() const +{ + return _sai.index; +} + +std::string Result::sequenceId() const +{ + return _sai.id; +} + bool Result::operator==(const Result& o) const { if (format() != o.format() || text() != o.text()) @@ -88,7 +134,6 @@ Result MergeStructuredAppendSequence(const Results& results) for (auto i = std::next(allResults.begin()); i != allResults.end(); ++i) res._content.append(i->_content); - res._text = res._content.text(); res._position = {}; res._sai.index = -1; diff --git a/core/src/Result.h b/core/src/Result.h index 7f6db93e59..6a8ae00000 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -43,14 +43,14 @@ class Result BarcodeFormat format() const { return _format; } - const std::wstring& text() const { return _text; } + std::wstring text() const; // WARNING: this is an experimental API and may change/disappear - const ByteArray& bytes() const { return _content.bytes; } - const ByteArray bytesECI() const { return _content.bytesECI(); } - const std::string utf8Protocol() const { return _content.utf8Protocol(); } - ContentType contentType() const { return _content.type(); } - bool hasECI() const { return _content.hasECI; } + const ByteArray& bytes() const; + ByteArray bytesECI() const; + std::string utf8Protocol() const; + ContentType contentType() const; + bool hasECI() const; // END WARNING const Position& position() const { return _position; } @@ -72,7 +72,7 @@ class Result /** * @brief symbologyIdentifier Symbology identifier "]cm" where "c" is symbology code character, "m" the modifier. */ - const std::string& symbologyIdentifier() const { return _symbologyIdentifier; } + std::string symbologyIdentifier() const; /** * @brief sequenceSize number of symbols in a structured append sequence. @@ -81,12 +81,12 @@ class Result * If it is a structured append symbol but the total number of symbols is unknown, the * returned value is 0 (see PDF417 if optional "Segment Count" not given). */ - int sequenceSize() const { return _sai.count; } + int sequenceSize() const; /** * @brief sequenceIndex the 0-based index of this symbol in a structured append sequence. */ - int sequenceIndex() const { return _sai.index; } + int sequenceIndex() const; /** * @brief sequenceId id to check if a set of symbols belongs to the same structured append sequence. @@ -95,7 +95,7 @@ class Result * For QR Code, this is the parity integer converted to a string. * For PDF417 and DataMatrix, this is the "fileId". */ - const std::string& sequenceId() const { return _sai.id; } + std::string sequenceId() const; bool isLastInSequence() const { return sequenceSize() == sequenceIndex() + 1; } bool isPartOfSequence() const { return sequenceSize() > -1 && sequenceIndex() > -1; } @@ -109,6 +109,8 @@ class Result * @brief How many lines have been detected with this code (applies only to 1D symbologies) */ int lineCount() const { return _lineCount; } + + // only for internal use void incrementLineCount() { ++_lineCount; } bool operator==(const Result& o) const; @@ -119,12 +121,10 @@ class Result DecodeStatus _status = DecodeStatus::NoError; BarcodeFormat _format = BarcodeFormat::None; Content _content; - std::wstring _text; Position _position; ByteArray _rawBytes; int _numBits = 0; std::wstring _ecLevel; - std::string _symbologyIdentifier; StructuredAppendInfo _sai; bool _isMirrored = false; bool _readerInit = false; From 2d712ea4874f00bbe8f63e7afd9d964f315b5e92 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 18 Jun 2022 15:42:50 +0200 Subject: [PATCH 0275/1315] GridSampler: support multi-symbol debugging --- core/src/GridSampler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/GridSampler.cpp b/core/src/GridSampler.cpp index b612f3a5ef..9bc3490212 100644 --- a/core/src/GridSampler.cpp +++ b/core/src/GridSampler.cpp @@ -22,7 +22,8 @@ DetectorResult SampleGrid(const BitMatrix& image, int width, int height, const P { #ifdef PRINT_DEBUG LogMatrix log; - LogMatrixWriter lmw(log, image, 5, "grid.pnm"); + static int i = 0; + LogMatrixWriter lmw(log, image, 5, "grid" + std::to_string(i++) + ".pnm"); #endif if (width <= 0 || height <= 0 || !mod2Pix.isValid()) return {}; From 5a839fea00cb0acb1d3aad6f62f89ee6c896bf62 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 18 Jun 2022 15:47:18 +0200 Subject: [PATCH 0276/1315] QRCode: detect mirrored symbols directly from FormatInfo bits Also prepares MicroQRCode improvement based on hamming distance info in FormatInfo --- core/src/qrcode/QRBitMatrixParser.cpp | 41 +++++++------- core/src/qrcode/QRBitMatrixParser.h | 4 +- core/src/qrcode/QRDecoder.cpp | 21 +++----- core/src/qrcode/QRDetector.cpp | 2 +- core/src/qrcode/QRFormatInformation.cpp | 56 +++++++++----------- core/src/qrcode/QRFormatInformation.h | 34 ++++-------- test/unit/qrcode/QRBitMatrixParserTest.cpp | 8 +-- test/unit/qrcode/QRFormatInformationTest.cpp | 8 +-- 8 files changed, 73 insertions(+), 101 deletions(-) diff --git a/core/src/qrcode/QRBitMatrixParser.cpp b/core/src/qrcode/QRBitMatrixParser.cpp index ed614fe9a3..7cdb3e7529 100644 --- a/core/src/qrcode/QRBitMatrixParser.cpp +++ b/core/src/qrcode/QRBitMatrixParser.cpp @@ -17,7 +17,7 @@ namespace ZXing::QRCode { -static bool getBit(const BitMatrix& bitMatrix, int x, int y, bool mirrored) +static bool getBit(const BitMatrix& bitMatrix, int x, int y, bool mirrored = false) { return mirrored ? bitMatrix.get(y, x) : bitMatrix.get(x, y); } @@ -60,7 +60,7 @@ const Version* ReadVersion(const BitMatrix& bitMatrix) return nullptr; } -FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrored, bool isMicro) +FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool isMicro) { if (!hasValidDimension(bitMatrix, isMicro)) return {}; @@ -69,9 +69,9 @@ FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrore // Read top-left format info bits int formatInfoBits = 0; for (int x = 1; x < 9; x++) - AppendBit(formatInfoBits, getBit(bitMatrix, x, 8, mirrored)); + AppendBit(formatInfoBits, getBit(bitMatrix, x, 8)); for (int y = 7; y >= 1; y--) - AppendBit(formatInfoBits, getBit(bitMatrix, 8, y, mirrored)); + AppendBit(formatInfoBits, getBit(bitMatrix, 8, y)); return FormatInformation::DecodeMQR(formatInfoBits); } @@ -79,27 +79,27 @@ FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrore // Read top-left format info bits int formatInfoBits1 = 0; for (int x = 0; x < 6; x++) - AppendBit(formatInfoBits1, getBit(bitMatrix, x, 8, mirrored)); + AppendBit(formatInfoBits1, getBit(bitMatrix, x, 8)); // .. and skip a bit in the timing pattern ... - AppendBit(formatInfoBits1, getBit(bitMatrix, 7, 8, mirrored)); - AppendBit(formatInfoBits1, getBit(bitMatrix, 8, 8, mirrored)); - AppendBit(formatInfoBits1, getBit(bitMatrix, 8, 7, mirrored)); + AppendBit(formatInfoBits1, getBit(bitMatrix, 7, 8)); + AppendBit(formatInfoBits1, getBit(bitMatrix, 8, 8)); + AppendBit(formatInfoBits1, getBit(bitMatrix, 8, 7)); // .. and skip a bit in the timing pattern ... for (int y = 5; y >= 0; y--) - AppendBit(formatInfoBits1, getBit(bitMatrix, 8, y, mirrored)); + AppendBit(formatInfoBits1, getBit(bitMatrix, 8, y)); // Read the top-right/bottom-left pattern too int dimension = bitMatrix.height(); int formatInfoBits2 = 0; for (int y = dimension - 1; y >= dimension - 7; y--) - AppendBit(formatInfoBits2, getBit(bitMatrix, 8, y, mirrored)); + AppendBit(formatInfoBits2, getBit(bitMatrix, 8, y)); for (int x = dimension - 8; x < dimension; x++) - AppendBit(formatInfoBits2, getBit(bitMatrix, x, 8, mirrored)); + AppendBit(formatInfoBits2, getBit(bitMatrix, x, 8)); return FormatInformation::DecodeQR(formatInfoBits1, formatInfoBits2); } -static ByteArray ReadQRCodewords(const BitMatrix& bitMatrix, const Version& version, int maskIndex, bool mirrored) +static ByteArray ReadQRCodewords(const BitMatrix& bitMatrix, const Version& version, const FormatInformation& formatInfo) { BitMatrix functionPattern = version.buildFunctionPattern(); @@ -122,7 +122,8 @@ static ByteArray ReadQRCodewords(const BitMatrix& bitMatrix, const Version& vers // Ignore bits covered by the function pattern if (!functionPattern.get(xx, y)) { // Read a bit - AppendBit(currentByte, GetDataMaskBit(maskIndex, xx, y) != getBit(bitMatrix, xx, y, mirrored)); + AppendBit(currentByte, + GetDataMaskBit(formatInfo.dataMask, xx, y) != getBit(bitMatrix, xx, y, formatInfo.isMirrored)); // If we've made a whole byte, save it off if (++bitsRead % 8 == 0) result.push_back(std::exchange(currentByte, 0)); @@ -137,8 +138,7 @@ static ByteArray ReadQRCodewords(const BitMatrix& bitMatrix, const Version& vers return result; } -static ByteArray ReadMQRCodewords(const BitMatrix& bitMatrix, const QRCode::Version& version, - const FormatInformation& formatInformation, bool mirrored) +static ByteArray ReadMQRCodewords(const BitMatrix& bitMatrix, const QRCode::Version& version, const FormatInformation& formatInfo) { BitMatrix functionPattern = version.buildFunctionPattern(); @@ -147,7 +147,7 @@ static ByteArray ReadMQRCodewords(const BitMatrix& bitMatrix, const QRCode::Vers // See ISO 18004:2006 6.7.3. bool hasD4mBlock = version.versionNumber() % 2 == 1; int d4mBlockIndex = - version.versionNumber() == 1 ? 3 : (formatInformation.errorCorrectionLevel() == QRCode::ErrorCorrectionLevel::Low ? 11 : 9); + version.versionNumber() == 1 ? 3 : (formatInfo.ecLevel == QRCode::ErrorCorrectionLevel::Low ? 11 : 9); ByteArray result; result.reserve(version.totalCodewords()); @@ -166,7 +166,7 @@ static ByteArray ReadMQRCodewords(const BitMatrix& bitMatrix, const QRCode::Vers if (!functionPattern.get(xx, y)) { // Read a bit AppendBit(currentByte, - GetDataMaskBit(formatInformation.dataMask(), xx, y, true) != getBit(bitMatrix, xx, y, mirrored)); + GetDataMaskBit(formatInfo.dataMask, xx, y, true) != getBit(bitMatrix, xx, y, formatInfo.isMirrored)); ++bitsRead; // If we've made a whole byte, save it off; save early if 2x2 data block. if (bitsRead == 8 || (bitsRead == 4 && hasD4mBlock && Size(result) == d4mBlockIndex - 1)) { @@ -184,14 +184,13 @@ static ByteArray ReadMQRCodewords(const BitMatrix& bitMatrix, const QRCode::Vers return result; } -ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, const FormatInformation& formatInformation, - bool mirrored) +ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, const FormatInformation& formatInfo) { if (!hasValidDimension(bitMatrix, version.isMicroQRCode())) return {}; - return version.isMicroQRCode() ? ReadMQRCodewords(bitMatrix, version, formatInformation, mirrored) - : ReadQRCodewords(bitMatrix, version, formatInformation.dataMask(), mirrored); + return version.isMicroQRCode() ? ReadMQRCodewords(bitMatrix, version, formatInfo) + : ReadQRCodewords(bitMatrix, version, formatInfo); } } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRBitMatrixParser.h b/core/src/qrcode/QRBitMatrixParser.h index cabb260210..0f070c8403 100644 --- a/core/src/qrcode/QRBitMatrixParser.h +++ b/core/src/qrcode/QRBitMatrixParser.h @@ -27,13 +27,13 @@ const Version* ReadVersion(const BitMatrix& bitMatrix); * @return {@link FormatInformation} encapsulating the QR Code's format info, result is invalid if both format * information locations cannot be parsed as the valid encoding of format information */ -FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool mirrored, bool isMicro); +FormatInformation ReadFormatInformation(const BitMatrix& bitMatrix, bool isMicro); /** * @brief Reads the codewords from the BitMatrix. * @return bytes encoded within the QR Code or empty array if the exact number of bytes expected is not read */ -ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, const FormatInformation& formatInformation, bool mirrored); +ByteArray ReadCodewords(const BitMatrix& bitMatrix, const Version& version, const FormatInformation& formatInfo); } // QRCode } // ZXing diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 29d35f0ac3..f454b012fc 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -343,19 +343,19 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo .setStructuredAppend(structuredAppend); } -static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, const std::string& hintedCharset, bool mirrored) +static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, const std::string& hintedCharset) { - auto formatInfo = ReadFormatInformation(bits, mirrored, version.isMicroQRCode()); + auto formatInfo = ReadFormatInformation(bits, version.isMicroQRCode()); if (!formatInfo.isValid()) return DecodeStatus::FormatError; // Read codewords - ByteArray codewords = ReadCodewords(bits, version, formatInfo, mirrored); + ByteArray codewords = ReadCodewords(bits, version, formatInfo); if (codewords.empty()) return DecodeStatus::FormatError; // Separate into data blocks - std::vector dataBlocks = DataBlock::GetDataBlocks(codewords, version, formatInfo.errorCorrectionLevel()); + std::vector dataBlocks = DataBlock::GetDataBlocks(codewords, version, formatInfo.ecLevel); if (dataBlocks.empty()) return DecodeStatus::FormatError; @@ -378,7 +378,7 @@ static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, con } // Decode the contents of that stream of bytes - return DecodeBitStream(std::move(resultBytes), version, formatInfo.errorCorrectionLevel(), hintedCharset); + return DecodeBitStream(std::move(resultBytes), version, formatInfo.ecLevel, hintedCharset).setIsMirrored(formatInfo.isMirrored); } DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) @@ -387,16 +387,7 @@ DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) if (!version) return DecodeStatus::FormatError; - auto res = DoDecode(bits, *version, hintedCharset, false); - if (res.isValid()) - return res; - - if (auto resMirrored = DoDecode(bits, *version, hintedCharset, true); resMirrored.isValid()) { - resMirrored.setIsMirrored(true); - return resMirrored; - } - - return res; + return DoDecode(bits, *version, hintedCharset); } } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 3b0ea99766..1fdaa431ce 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -432,7 +432,7 @@ DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp) if (!fi.isValid()) continue; - const int dim = Version::DimensionOfVersion(fi.microVersion(), true); + const int dim = Version::DimensionOfVersion(fi.microVersion, true); // check that we are in fact not looking at a corner of a non-micro QRCode symbol // we accept at most 1/3rd black pixels in the quite zone (in a QRCode symbol we expect about 1/2). diff --git a/core/src/qrcode/QRFormatInformation.cpp b/core/src/qrcode/QRFormatInformation.cpp index 44db397c06..7f4cba4aa8 100644 --- a/core/src/qrcode/QRFormatInformation.cpp +++ b/core/src/qrcode/QRFormatInformation.cpp @@ -87,64 +87,60 @@ static const std::array, 32> FORMAT_INFO_DECODE_LOOKUP_MICRO {0x3BBA, 0x1F}, }}; -static int FindBestFormatInfo(int mask, const std::array, 32> lookup, const std::vector& bits) +static FormatInformation FindBestFormatInfo(int mask, const std::array, 32> lookup, + const std::vector& bits) { - // Find the int in lookup with fewest bits differing - int bestDifference = 32; - int bestFormatInfo = -1; + FormatInformation fi; // Some QR codes apparently do not apply the XOR mask. Try without and with additional masking. - // TODO: test for mirrored format for (auto mask : {0, mask}) for (uint32_t bits : bits) - for (const auto& [pattern, decodedInfo] : lookup) - if (int bitsDifference = BitHacks::CountBitsSet((bits ^ mask) ^ pattern); bitsDifference < bestDifference) { - bestFormatInfo = decodedInfo; - bestDifference = bitsDifference; + for (bool mirror : {false, true}) + for (const auto& [pattern, index] : lookup) { + if (mirror) + bits = BitHacks::Reverse(bits) >> 17; + // Find the int in lookup with fewest bits differing + if (int hammingDist = BitHacks::CountBitsSet((bits ^ mask) ^ pattern); hammingDist < fi.hammingDistance) { + fi.index = index; + fi.hammingDistance = hammingDist; + fi.isMirrored = mirror; + } } - // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits - // differing means we found a match - if (bestDifference <= 3) - return bestFormatInfo; - - return -1; + return fi; } /** * @param formatInfoBits1 format info indicator, with mask still applied -* @param formatInfoBits2 second copy of same info; both are checked at the same time -* to establish best match -* @return information about the format it specifies, or {@code null} -* if doesn't seem to match any known pattern +* @param formatInfoBits2 second copy of same info; both are checked at the same time to establish best match */ FormatInformation FormatInformation::DecodeQR(uint32_t formatInfoBits1, uint32_t formatInfoBits2) { - int bestFormatInfo = FindBestFormatInfo(FORMAT_INFO_MASK_QR, FORMAT_INFO_DECODE_LOOKUP, {formatInfoBits1, formatInfoBits2}); - if (bestFormatInfo < 0) - return {}; + auto fi = FindBestFormatInfo(FORMAT_INFO_MASK_QR, FORMAT_INFO_DECODE_LOOKUP, {formatInfoBits1, formatInfoBits2}); // Use bits 3/4 for error correction, and 0-2 for mask. - return {ECLevelFromBits((bestFormatInfo >> 3) & 0x03), static_cast(bestFormatInfo & 0x07)}; + fi.ecLevel = ECLevelFromBits((fi.index >> 3) & 0x03); + fi.dataMask = static_cast(fi.index & 0x07); + + return fi; } /** * @param formatInfoBits format info indicator, with mask still applied - * @return information about the format it specifies, or {@code null} - * if doesn't seem to match any known pattern */ FormatInformation FormatInformation::DecodeMQR(uint32_t formatInfoBits) { // We don't use the additional masking (with 0x4445) to work around potentially non complying MircoQRCode encoders - int bestFormatInfo = FindBestFormatInfo(0, FORMAT_INFO_DECODE_LOOKUP_MICRO, {formatInfoBits}); - if (bestFormatInfo < 0) - return {}; + auto fi = FindBestFormatInfo(0, FORMAT_INFO_DECODE_LOOKUP_MICRO, {formatInfoBits}); constexpr uint8_t BITS_TO_VERSION[] = {1, 2, 2, 3, 3, 4, 4, 4}; // Bits 2/3/4 contain both error correction level and version, 0/1 contain mask. - return {ECLevelFromBits((bestFormatInfo >> 2) & 0x07, true), static_cast(bestFormatInfo & 0x03), - BITS_TO_VERSION[(bestFormatInfo >> 2) & 0x07]}; + fi.ecLevel = ECLevelFromBits((fi.index >> 2) & 0x07, true); + fi.dataMask = static_cast(fi.index & 0x03); + fi.microVersion = BITS_TO_VERSION[(fi.index >> 2) & 0x07]; + + return fi; } } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRFormatInformation.h b/core/src/qrcode/QRFormatInformation.h index e83775b0fc..d7d59a2d9d 100644 --- a/core/src/qrcode/QRFormatInformation.h +++ b/core/src/qrcode/QRFormatInformation.h @@ -13,42 +13,28 @@ namespace ZXing { namespace QRCode { -/** -*

Encapsulates a QR Code's format information, including the data mask used and -* error correction level.

-* -* @author Sean Owen -* @see DataMask -* @see ErrorCorrectionLevel -*/ class FormatInformation { public: + uint8_t index = 255; + uint8_t hammingDistance = 255; + bool isMirrored = false; + uint8_t dataMask = 0; + uint8_t microVersion = 0; + ErrorCorrectionLevel ecLevel = ErrorCorrectionLevel::Invalid; + FormatInformation() = default; static FormatInformation DecodeQR(uint32_t formatInfoBits1, uint32_t formatInfoBits2); static FormatInformation DecodeMQR(uint32_t formatInfoBits); - ErrorCorrectionLevel errorCorrectionLevel() const { return _errorCorrectionLevel; } - - uint8_t dataMask() const { return _dataMask; } - uint8_t microVersion() const { return _microVersion; } - - bool isValid() const { return _errorCorrectionLevel != ErrorCorrectionLevel::Invalid; } + // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match + bool isValid() const { return hammingDistance <= 3; } bool operator==(const FormatInformation& other) const { - return _dataMask == other._dataMask && _errorCorrectionLevel == other._errorCorrectionLevel; + return dataMask == other.dataMask && ecLevel == other.ecLevel; } - -private: - ErrorCorrectionLevel _errorCorrectionLevel = ErrorCorrectionLevel::Invalid; - uint8_t _dataMask = 0; - uint8_t _microVersion = 0; - - FormatInformation(const ErrorCorrectionLevel& errorCorrectionLevel, uint8_t dataMask, uint8_t microVersion = 0) - : _errorCorrectionLevel(errorCorrectionLevel), _dataMask(dataMask), _microVersion(microVersion) - {} }; } // QRCode diff --git a/test/unit/qrcode/QRBitMatrixParserTest.cpp b/test/unit/qrcode/QRBitMatrixParserTest.cpp index 2cd7a9c5cf..f8c5a93a0d 100644 --- a/test/unit/qrcode/QRBitMatrixParserTest.cpp +++ b/test/unit/qrcode/QRBitMatrixParserTest.cpp @@ -37,8 +37,8 @@ TEST(QRBitMatrixParserTest, MQRCodeM3L) const auto version = ReadVersion(bitMatrix); EXPECT_EQ(3, version->versionNumber()); - const auto format = ReadFormatInformation(bitMatrix, false, true); - const auto codewords = ReadCodewords(bitMatrix, *version, format, false); + const auto format = ReadFormatInformation(bitMatrix, true); + const auto codewords = ReadCodewords(bitMatrix, *version, format); EXPECT_EQ(17, codewords.size()); EXPECT_EQ(0x0, codewords[10]); EXPECT_EQ(0xd1, codewords[11]); @@ -65,8 +65,8 @@ TEST(QRBitMatrixParserTest, MQRCodeM3M) const auto version = ReadVersion(bitMatrix); EXPECT_EQ(3, version->versionNumber()); - const auto format = ReadFormatInformation(bitMatrix, false, true); - const auto codewords = ReadCodewords(bitMatrix, *version, format, false); + const auto format = ReadFormatInformation(bitMatrix, true); + const auto codewords = ReadCodewords(bitMatrix, *version, format); EXPECT_EQ(17, codewords.size()); EXPECT_EQ(0x0, codewords[8]); EXPECT_EQ(0x89, codewords[9]); diff --git a/test/unit/qrcode/QRFormatInformationTest.cpp b/test/unit/qrcode/QRFormatInformationTest.cpp index 959f5ae42e..0dffa5ea27 100644 --- a/test/unit/qrcode/QRFormatInformationTest.cpp +++ b/test/unit/qrcode/QRFormatInformationTest.cpp @@ -20,8 +20,8 @@ static void DoFormatInformationTest(const int formatInfo, const uint8_t expected { FormatInformation parsedFormat = FormatInformation::DecodeMQR(formatInfo); EXPECT_TRUE(parsedFormat.isValid()); - EXPECT_EQ(expectedMask, parsedFormat.dataMask()); - EXPECT_EQ(expectedECL, parsedFormat.errorCorrectionLevel()); + EXPECT_EQ(expectedMask, parsedFormat.dataMask); + EXPECT_EQ(expectedECL, parsedFormat.ecLevel); } TEST(QRFormatInformationTest, Decode) @@ -29,8 +29,8 @@ TEST(QRFormatInformationTest, Decode) // Normal case FormatInformation expected = FormatInformation::DecodeQR(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO); EXPECT_TRUE(expected.isValid()); - EXPECT_EQ(0x07, expected.dataMask()); - EXPECT_EQ(ErrorCorrectionLevel::Quality, expected.errorCorrectionLevel()); + EXPECT_EQ(0x07, expected.dataMask); + EXPECT_EQ(ErrorCorrectionLevel::Quality, expected.ecLevel); // where the code forgot the mask! EXPECT_EQ(expected, FormatInformation::DecodeQR(UNMASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO)); } From dd14a3b5ee725492de9f779829952dc5757f0e9f Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 18 Jun 2022 16:01:52 +0200 Subject: [PATCH 0277/1315] MicoQRCode: choose orientation with the lowest hamming distance FormatInfo This fixes #344. --- core/src/PerspectiveTransform.h | 1 + core/src/qrcode/QRDetector.cpp | 36 +++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/core/src/PerspectiveTransform.h b/core/src/PerspectiveTransform.h index 0e99c3c101..c2f5043e18 100644 --- a/core/src/PerspectiveTransform.h +++ b/core/src/PerspectiveTransform.h @@ -34,6 +34,7 @@ class PerspectiveTransform static PerspectiveTransform UnitSquareTo(const QuadrilateralF& q); public: + PerspectiveTransform() = default; PerspectiveTransform(const QuadrilateralF& src, const QuadrilateralF& dst); /// Project from the destination space (grid of modules) into the image space (bit matrix) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 1fdaa431ce..5fdad20b89 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -412,6 +412,9 @@ DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp) constexpr PointI FORMAT_INFO_COORDS[] = {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {8, 7}, {8, 6}, {8, 5}, {8, 4}, {8, 3}, {8, 2}, {8, 1}, {8, 0}}; + FormatInformation bestFI; + PerspectiveTransform bestPT; + for (int i = 0; i < 4; ++i) { auto mod2Pix = PerspectiveTransform(srcQuad, RotatedCorners(*fpQuad, i)); @@ -429,26 +432,29 @@ DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp) AppendBit(formatInfoBits, image.get(mod2Pix(centered(FORMAT_INFO_COORDS[i])))); auto fi = FormatInformation::DecodeMQR(formatInfoBits); - if (!fi.isValid()) - continue; + if (fi.hammingDistance < bestFI.hammingDistance) { + bestFI = fi; + bestPT = mod2Pix; + } + } - const int dim = Version::DimensionOfVersion(fi.microVersion, true); + if (!bestFI.isValid()) + return {}; - // check that we are in fact not looking at a corner of a non-micro QRCode symbol - // we accept at most 1/3rd black pixels in the quite zone (in a QRCode symbol we expect about 1/2). - int blackPixels = 0; - for (int i = 0; i < dim; ++i) { - auto px = mod2Pix(centered(PointI{i, dim})); - auto py = mod2Pix(centered(PointI{dim, i})); - blackPixels += (image.isIn(px) && image.get(px)) + (image.isIn(py) && image.get(py)); - } - if (blackPixels > 2 * dim / 3) - continue; + const int dim = Version::DimensionOfVersion(bestFI.microVersion, true); - return SampleGrid(image, dim, dim, mod2Pix); + // check that we are in fact not looking at a corner of a non-micro QRCode symbol + // we accept at most 1/3rd black pixels in the quite zone (in a QRCode symbol we expect about 1/2). + int blackPixels = 0; + for (int i = 0; i < dim; ++i) { + auto px = bestPT(centered(PointI{i, dim})); + auto py = bestPT(centered(PointI{dim, i})); + blackPixels += (image.isIn(px) && image.get(px)) + (image.isIn(py) && image.get(py)); } + if (blackPixels > 2 * dim / 3) + return {}; - return {}; + return SampleGrid(image, dim, dim, bestPT); } } // namespace ZXing::QRCode From 3093ee5bff1f4523a38ced56049f6952b1978de8 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 19 Jun 2022 01:08:54 +0200 Subject: [PATCH 0278/1315] Result: compare bytes instead of text in opoerator== (performance) --- core/src/Result.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 72c995e0f5..3e0f62e38a 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -102,7 +102,7 @@ std::string Result::sequenceId() const bool Result::operator==(const Result& o) const { - if (format() != o.format() || text() != o.text()) + if (format() != o.format() || bytes() != o.bytes()) return false; if (BarcodeFormats(BarcodeFormat::TwoDCodes).testFlag(format())) From 18cd69a628bd58962091fa0e6d5d842dbb663955 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 19 Jun 2022 01:14:32 +0200 Subject: [PATCH 0279/1315] Result: rename utf8Protocol -> utf8ECI --- core/src/Content.cpp | 2 +- core/src/Content.h | 2 +- core/src/Result.cpp | 4 ++-- core/src/Result.h | 2 +- example/ZXingReader.cpp | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 21fde3c976..f5b4e1a852 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -108,7 +108,7 @@ std::wstring Content::text() const return wstr; } -std::string Content::utf8Protocol() const +std::string Content::utf8ECI() const { if (empty() || !canProcess()) return {}; diff --git a/core/src/Content.h b/core/src/Content.h index 5d1f982069..756d8b72fe 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -71,7 +71,7 @@ class Content bool canProcess() const; std::wstring text() const; - std::string utf8Protocol() const; + std::string utf8ECI() const; ByteArray bytesECI() const; CharacterSet guessEncoding() const; ContentType type() const; diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 3e0f62e38a..15399dea0a 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -59,9 +59,9 @@ ByteArray Result::bytesECI() const return _content.bytesECI(); } -std::string Result::utf8Protocol() const +std::string Result::utf8ECI() const { - return _content.utf8Protocol(); + return _content.utf8ECI(); } ContentType Result::contentType() const diff --git a/core/src/Result.h b/core/src/Result.h index 6a8ae00000..0bad7c7f03 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -48,7 +48,7 @@ class Result // WARNING: this is an experimental API and may change/disappear const ByteArray& bytes() const; ByteArray bytesECI() const; - std::string utf8Protocol() const; + std::string utf8ECI() const; ContentType contentType() const; bool hasECI() const; // END WARNING diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 56f6759491..d8bf8fbd99 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -192,7 +192,7 @@ int main(int argc, char* argv[]) } std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" << "Bytes: \"" << ToHex(result.bytes()) << "\"\n" - << "TextECI: \"" << result.utf8Protocol() << "\"\n" + << "TextECI: \"" << result.utf8ECI() << "\"\n" << "BytesECI: \"" << ToHex(result.bytesECI()) << "\"\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" From 1f7d12b6fd5c7ad61ee1252c12d6ab96c1580f22 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 19 Jun 2022 23:14:21 +0200 Subject: [PATCH 0280/1315] GTIN: parse the `bytes()` instead of `text()` in `EanAddOn()` --- core/src/GTIN.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/GTIN.cpp b/core/src/GTIN.cpp index 4231597aa8..252393dcbb 100644 --- a/core/src/GTIN.cpp +++ b/core/src/GTIN.cpp @@ -205,9 +205,9 @@ std::string EanAddOn(const Result& result) if (!(BarcodeFormat::EAN13 | BarcodeFormat::UPCA | BarcodeFormat::UPCE | BarcodeFormat::EAN8) .testFlag(result.format())) return {}; - auto txt = result.text(); - auto pos = txt.find(L' '); - return pos != std::wstring::npos ? TextUtfEncoding::ToUtf8(txt.substr(pos + 1)) : std::string(); + auto txt = result.bytes().asString(); + auto pos = txt.find(' '); + return pos != std::string::npos ? std::string(txt.substr(pos + 1)) : std::string(); } std::string IssueNr(const std::string& ean2AddOn) From 4b0a575e4d4ae71b5771c9214785b9f43f3afb41 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 19 Jun 2022 23:27:52 +0200 Subject: [PATCH 0281/1315] example: don't double quote the `bytes` result in ZXingReader output --- example/ZXingReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index d8bf8fbd99..206c400bcb 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -191,9 +191,9 @@ int main(int argc, char* argv[]) firstFile = false; } std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" - << "Bytes: \"" << ToHex(result.bytes()) << "\"\n" + << "Bytes: " << ToHex(result.bytes()) << "\n" << "TextECI: \"" << result.utf8ECI() << "\"\n" - << "BytesECI: \"" << ToHex(result.bytesECI()) << "\"\n" + << "BytesECI: " << ToHex(result.bytesECI()) << "\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" << "Content: " << ToString(result.contentType()) << "\n" From e37b857aa37b667931a0aa0297eafdddb5f84e29 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 20 Jun 2022 09:04:11 +0200 Subject: [PATCH 0282/1315] example: use new Result::utf8() --- example/ZXingReader.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 206c400bcb..64f91e1701 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -111,6 +111,11 @@ void drawRect(const ImageView& image, const Position& pos) drawLine(image, pos[i], pos[(i + 1) % 4]); } +std::string escapeNonGraphical(const std::string& str) +{ + return ToUtf8(FromUtf8(str), true); +} + int main(int argc, char* argv[]) { DecodeHints hints; @@ -130,9 +135,6 @@ int main(int argc, char* argv[]) hints.setEanAddOnSymbol(EanAddOnSymbol::Read); - if (oneLine) - angleEscape = true; - if (angleEscape) std::setlocale(LC_CTYPE, "en_US.UTF-8"); // Needed so `std::iswgraph()` in `ToUtf8(angleEscape)` does not 'swallow' all printable non-ascii utf8 chars @@ -175,7 +177,7 @@ int main(int argc, char* argv[]) if (oneLine) { std::cout << filePath << " " << ToString(result.format()); if (result.isValid()) - std::cout << " \"" << ToUtf8(result.text(), angleEscape) << "\""; + std::cout << " \"" << escapeNonGraphical(result.utf8()) << "\""; else if (result.format() != BarcodeFormat::None) std::cout << " " << ToString(result.status()); std::cout << "\n"; @@ -190,9 +192,9 @@ int main(int argc, char* argv[]) std::cout << "File: " << filePath << "\n"; firstFile = false; } - std::cout << "Text: \"" << ToUtf8(result.text(), angleEscape) << "\"\n" - << "Bytes: " << ToHex(result.bytes()) << "\n" + std::cout << "Text: \"" << (angleEscape ? escapeNonGraphical(result.utf8()) : result.utf8()) << "\"\n" << "TextECI: \"" << result.utf8ECI() << "\"\n" + << "Bytes: " << ToHex(result.bytes()) << "\n" << "BytesECI: " << ToHex(result.bytesECI()) << "\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" From 95d6a540ed95ca07c0a19ef2906d210785d46210 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 20 Jun 2022 09:06:37 +0200 Subject: [PATCH 0283/1315] Result: add new `utf8` property (forgot in last commit) --- core/src/Result.cpp | 6 ++++++ core/src/Result.h | 1 + 2 files changed, 7 insertions(+) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 15399dea0a..fc1a86656a 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -8,6 +8,7 @@ #include "DecoderResult.h" #include "TextDecoder.h" +#include "TextUtfEncoding.h" #include #include @@ -59,6 +60,11 @@ ByteArray Result::bytesECI() const return _content.bytesECI(); } +std::string Result::utf8() const +{ + return TextUtfEncoding::ToUtf8(_content.text()); +} + std::string Result::utf8ECI() const { return _content.utf8ECI(); diff --git a/core/src/Result.h b/core/src/Result.h index 0bad7c7f03..24238bcee8 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -48,6 +48,7 @@ class Result // WARNING: this is an experimental API and may change/disappear const ByteArray& bytes() const; ByteArray bytesECI() const; + std::string utf8() const; std::string utf8ECI() const; ContentType contentType() const; bool hasECI() const; From 1c5af714b3c36cc1f05184a5b03bed80e8260b68 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 20 Jun 2022 10:00:04 +0200 Subject: [PATCH 0284/1315] Writers: add utf8 overload for `encode()` functions To prevent a blatant inconsistency between writing and reading with regards to utf8 vs utf16 input/output... --- core/src/MultiFormatWriter.cpp | 6 ++++++ core/src/MultiFormatWriter.h | 1 + core/src/aztec/AZWriter.cpp | 6 ++++++ core/src/aztec/AZWriter.h | 1 + core/src/datamatrix/DMWriter.cpp | 6 ++++++ core/src/datamatrix/DMWriter.h | 1 + core/src/oned/ODCodabarWriter.cpp | 6 ++++++ core/src/oned/ODCodabarWriter.h | 1 + core/src/oned/ODCode128Writer.cpp | 6 ++++++ core/src/oned/ODCode128Writer.h | 1 + core/src/oned/ODCode39Writer.cpp | 6 ++++++ core/src/oned/ODCode39Writer.h | 1 + core/src/oned/ODCode93Writer.cpp | 6 ++++++ core/src/oned/ODCode93Writer.h | 1 + core/src/oned/ODEAN13Writer.cpp | 6 ++++++ core/src/oned/ODEAN13Writer.h | 1 + core/src/oned/ODEAN8Writer.cpp | 6 ++++++ core/src/oned/ODEAN8Writer.h | 1 + core/src/oned/ODITFWriter.cpp | 6 ++++++ core/src/oned/ODITFWriter.h | 1 + core/src/oned/ODUPCAWriter.cpp | 6 ++++++ core/src/oned/ODUPCAWriter.h | 1 + core/src/oned/ODUPCEWriter.cpp | 6 ++++++ core/src/oned/ODUPCEWriter.h | 1 + core/src/pdf417/PDFWriter.cpp | 6 ++++++ core/src/pdf417/PDFWriter.h | 1 + core/src/qrcode/QRWriter.cpp | 6 ++++++ core/src/qrcode/QRWriter.h | 1 + test/blackbox/TestWriterMain.cpp | 4 ++-- test/unit/oned/ODCodaBarWriterTest.cpp | 17 +++++++++-------- test/unit/oned/ODCode128WriterTest.cpp | 16 ++++++++-------- test/unit/oned/ODCode39ExtendedModeTest.cpp | 12 ++++++------ test/unit/oned/ODEAN13WriterTest.cpp | 8 ++++---- test/unit/oned/ODEAN8WriterTest.cpp | 8 ++++---- test/unit/oned/ODUPCAWriterTest.cpp | 6 +++--- test/unit/oned/ODUPCEWriterTest.cpp | 10 +++++----- 36 files changed, 139 insertions(+), 40 deletions(-) diff --git a/core/src/MultiFormatWriter.cpp b/core/src/MultiFormatWriter.cpp index 464dbc8054..5a03a6a4b3 100644 --- a/core/src/MultiFormatWriter.cpp +++ b/core/src/MultiFormatWriter.cpp @@ -20,6 +20,7 @@ #include "pdf417/PDFWriter.h" #include "qrcode/QRErrorCorrectionLevel.h" #include "qrcode/QRWriter.h" +#include "TextUtfEncoding.h" #include @@ -66,4 +67,9 @@ MultiFormatWriter::encode(const std::wstring& contents, int width, int height) c } } +BitMatrix MultiFormatWriter::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // ZXing diff --git a/core/src/MultiFormatWriter.h b/core/src/MultiFormatWriter.h index 88b1c61591..f63ca03edb 100644 --- a/core/src/MultiFormatWriter.h +++ b/core/src/MultiFormatWriter.h @@ -50,6 +50,7 @@ class MultiFormatWriter } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: BarcodeFormat _format; diff --git a/core/src/aztec/AZWriter.cpp b/core/src/aztec/AZWriter.cpp index b41a15a62a..6e6b0ad0d7 100644 --- a/core/src/aztec/AZWriter.cpp +++ b/core/src/aztec/AZWriter.cpp @@ -9,6 +9,7 @@ #include "AZEncoder.h" #include "CharacterSet.h" #include "TextEncoder.h" +#include "TextUtfEncoding.h" #include @@ -29,4 +30,9 @@ Writer::encode(const std::wstring& contents, int width, int height) const return Inflate(std::move(aztec.matrix), width, height, _margin); } +BitMatrix Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::Aztec diff --git a/core/src/aztec/AZWriter.h b/core/src/aztec/AZWriter.h index 1a41f6267e..aa80d46a30 100644 --- a/core/src/aztec/AZWriter.h +++ b/core/src/aztec/AZWriter.h @@ -41,6 +41,7 @@ class Writer } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: CharacterSet _encoding; diff --git a/core/src/datamatrix/DMWriter.cpp b/core/src/datamatrix/DMWriter.cpp index a95f5ad8a2..8c8f7bd3d3 100644 --- a/core/src/datamatrix/DMWriter.cpp +++ b/core/src/datamatrix/DMWriter.cpp @@ -13,6 +13,7 @@ #include "DMHighLevelEncoder.h" #include "DMSymbolInfo.h" #include "DMSymbolShape.h" +#include "TextUtfEncoding.h" #include #include @@ -110,4 +111,9 @@ Writer::encode(const std::wstring& contents, int width, int height) const return Inflate(std::move(result), width, height, _quietZone); } +BitMatrix Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMWriter.h b/core/src/datamatrix/DMWriter.h index 61b0caba2a..f126e6eb35 100644 --- a/core/src/datamatrix/DMWriter.h +++ b/core/src/datamatrix/DMWriter.h @@ -44,6 +44,7 @@ class Writer } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: SymbolShape _shapeHint; diff --git a/core/src/oned/ODCodabarWriter.cpp b/core/src/oned/ODCodabarWriter.cpp index 1d74711299..25c42edbfc 100644 --- a/core/src/oned/ODCodabarWriter.cpp +++ b/core/src/oned/ODCodabarWriter.cpp @@ -7,6 +7,7 @@ #include "ODCodabarWriter.h" #include "ODWriterHelper.h" +#include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" #include @@ -126,4 +127,9 @@ CodabarWriter::encode(const std::wstring& contents_, int width, int height) cons return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 10); } +BitMatrix CodabarWriter::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODCodabarWriter.h b/core/src/oned/ODCodabarWriter.h index 7304d49efc..10914313a7 100644 --- a/core/src/oned/ODCodabarWriter.h +++ b/core/src/oned/ODCodabarWriter.h @@ -24,6 +24,7 @@ class CodabarWriter public: CodabarWriter& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODCode128Writer.cpp b/core/src/oned/ODCode128Writer.cpp index 2325376d5e..b737af2fca 100644 --- a/core/src/oned/ODCode128Writer.cpp +++ b/core/src/oned/ODCode128Writer.cpp @@ -8,6 +8,7 @@ #include "ODCode128Patterns.h" #include "ODWriterHelper.h" +#include "TextUtfEncoding.h" #include #include @@ -252,4 +253,9 @@ Code128Writer::encode(const std::wstring& contents, int width, int height) const return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 10); } +BitMatrix Code128Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode128Writer.h b/core/src/oned/ODCode128Writer.h index 5e517a66a6..386bf5cefc 100644 --- a/core/src/oned/ODCode128Writer.h +++ b/core/src/oned/ODCode128Writer.h @@ -24,6 +24,7 @@ class Code128Writer public: Code128Writer& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODCode39Writer.cpp b/core/src/oned/ODCode39Writer.cpp index e05faa661f..d6732cd801 100644 --- a/core/src/oned/ODCode39Writer.cpp +++ b/core/src/oned/ODCode39Writer.cpp @@ -9,6 +9,7 @@ #include "CharacterSet.h" #include "ODWriterHelper.h" #include "TextEncoder.h" +#include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" #include @@ -167,4 +168,9 @@ Code39Writer::encode(const std::wstring& contents, int width, int height) const return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 10); } +BitMatrix Code39Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode39Writer.h b/core/src/oned/ODCode39Writer.h index 3342490301..20194b572f 100644 --- a/core/src/oned/ODCode39Writer.h +++ b/core/src/oned/ODCode39Writer.h @@ -24,6 +24,7 @@ class Code39Writer public: Code39Writer& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODCode93Writer.cpp b/core/src/oned/ODCode93Writer.cpp index f84693ffce..fb2c26157c 100644 --- a/core/src/oned/ODCode93Writer.cpp +++ b/core/src/oned/ODCode93Writer.cpp @@ -7,6 +7,7 @@ #include "ODCode93Writer.h" #include "ODWriterHelper.h" +#include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" #include "ZXTestSupport.h" @@ -183,4 +184,9 @@ Code93Writer::encode(const std::wstring& contents_, int width, int height) const return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 10); } +BitMatrix Code93Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode93Writer.h b/core/src/oned/ODCode93Writer.h index e33f4f512b..40654c8ccf 100644 --- a/core/src/oned/ODCode93Writer.h +++ b/core/src/oned/ODCode93Writer.h @@ -22,6 +22,7 @@ class Code93Writer public: Code93Writer& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODEAN13Writer.cpp b/core/src/oned/ODEAN13Writer.cpp index 156ac51999..cf99be12cc 100644 --- a/core/src/oned/ODEAN13Writer.cpp +++ b/core/src/oned/ODEAN13Writer.cpp @@ -8,6 +8,7 @@ #include "ODUPCEANCommon.h" #include "ODWriterHelper.h" +#include "TextUtfEncoding.h" #include #include @@ -53,4 +54,9 @@ EAN13Writer::encode(const std::wstring& contents, int width, int height) const return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 9); } +BitMatrix EAN13Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODEAN13Writer.h b/core/src/oned/ODEAN13Writer.h index bfed737bc1..c9086941d6 100644 --- a/core/src/oned/ODEAN13Writer.h +++ b/core/src/oned/ODEAN13Writer.h @@ -24,6 +24,7 @@ class EAN13Writer public: EAN13Writer& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODEAN8Writer.cpp b/core/src/oned/ODEAN8Writer.cpp index f659a1cb18..652c26f719 100644 --- a/core/src/oned/ODEAN8Writer.cpp +++ b/core/src/oned/ODEAN8Writer.cpp @@ -8,6 +8,7 @@ #include "ODUPCEANCommon.h" #include "ODWriterHelper.h" +#include "TextUtfEncoding.h" #include @@ -42,4 +43,9 @@ EAN8Writer::encode(const std::wstring& contents, int width, int height) const return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 9); } +BitMatrix EAN8Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODEAN8Writer.h b/core/src/oned/ODEAN8Writer.h index 2bbabd265a..8c42ea969c 100644 --- a/core/src/oned/ODEAN8Writer.h +++ b/core/src/oned/ODEAN8Writer.h @@ -24,6 +24,7 @@ class EAN8Writer public: EAN8Writer& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODITFWriter.cpp b/core/src/oned/ODITFWriter.cpp index 27b8f58e58..1f3e6f611d 100644 --- a/core/src/oned/ODITFWriter.cpp +++ b/core/src/oned/ODITFWriter.cpp @@ -7,6 +7,7 @@ #include "ODITFWriter.h" #include "ODWriterHelper.h" +#include "TextUtfEncoding.h" #include #include @@ -69,4 +70,9 @@ ITFWriter::encode(const std::wstring& contents, int width, int height) const return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 10); } +BitMatrix ITFWriter::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODITFWriter.h b/core/src/oned/ODITFWriter.h index de837dd3a5..f4cab9bb39 100644 --- a/core/src/oned/ODITFWriter.h +++ b/core/src/oned/ODITFWriter.h @@ -24,6 +24,7 @@ class ITFWriter public: ITFWriter& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODUPCAWriter.cpp b/core/src/oned/ODUPCAWriter.cpp index 0a789b6e95..16574022fb 100644 --- a/core/src/oned/ODUPCAWriter.cpp +++ b/core/src/oned/ODUPCAWriter.cpp @@ -8,6 +8,7 @@ #include "BitMatrix.h" #include "ODEAN13Writer.h" +#include "TextUtfEncoding.h" #include @@ -24,4 +25,9 @@ UPCAWriter::encode(const std::wstring& contents, int width, int height) const return EAN13Writer().setMargin(_sidesMargin).encode(L'0' + contents, width, height); } +BitMatrix UPCAWriter::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODUPCAWriter.h b/core/src/oned/ODUPCAWriter.h index 467fbf0682..22dacdac20 100644 --- a/core/src/oned/ODUPCAWriter.h +++ b/core/src/oned/ODUPCAWriter.h @@ -24,6 +24,7 @@ class UPCAWriter public: UPCAWriter& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/oned/ODUPCEWriter.cpp b/core/src/oned/ODUPCEWriter.cpp index 5adf99cc4f..ea23e32290 100644 --- a/core/src/oned/ODUPCEWriter.cpp +++ b/core/src/oned/ODUPCEWriter.cpp @@ -8,6 +8,7 @@ #include "ODUPCEANCommon.h" #include "ODWriterHelper.h" +#include "TextUtfEncoding.h" #include #include @@ -47,4 +48,9 @@ UPCEWriter::encode(const std::wstring& contents, int width, int height) const return WriterHelper::RenderResult(result, width, height, _sidesMargin >= 0 ? _sidesMargin : 9); } +BitMatrix UPCEWriter::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::OneD diff --git a/core/src/oned/ODUPCEWriter.h b/core/src/oned/ODUPCEWriter.h index 6e48975970..90fd7b0b8c 100644 --- a/core/src/oned/ODUPCEWriter.h +++ b/core/src/oned/ODUPCEWriter.h @@ -24,6 +24,7 @@ class UPCEWriter public: UPCEWriter& setMargin(int sidesMargin) { _sidesMargin = sidesMargin; return *this; } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _sidesMargin = -1; diff --git a/core/src/pdf417/PDFWriter.cpp b/core/src/pdf417/PDFWriter.cpp index 19543119d6..400208eb50 100644 --- a/core/src/pdf417/PDFWriter.cpp +++ b/core/src/pdf417/PDFWriter.cpp @@ -7,6 +7,7 @@ #include "PDFWriter.h" #include "PDFEncoder.h" #include "BitMatrix.h" +#include "TextUtfEncoding.h" #include @@ -111,6 +112,11 @@ Writer::encode(const std::wstring& contents, int width, int height) const } } +BitMatrix Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + Writer::Writer() { _encoder.reset(new Encoder); diff --git a/core/src/pdf417/PDFWriter.h b/core/src/pdf417/PDFWriter.h index a9e01c943b..b9bf3c3606 100644 --- a/core/src/pdf417/PDFWriter.h +++ b/core/src/pdf417/PDFWriter.h @@ -60,6 +60,7 @@ class Writer BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _margin = -1; diff --git a/core/src/qrcode/QRWriter.cpp b/core/src/qrcode/QRWriter.cpp index 63a161150e..8f0597cab3 100644 --- a/core/src/qrcode/QRWriter.cpp +++ b/core/src/qrcode/QRWriter.cpp @@ -11,6 +11,7 @@ #include "QREncodeResult.h" #include "QREncoder.h" #include "QRErrorCorrectionLevel.h" +#include "TextUtfEncoding.h" #include #include @@ -42,4 +43,9 @@ BitMatrix Writer::encode(const std::wstring& contents, int width, int height) co return Inflate(std::move(code.matrix), width, height, _margin); } +BitMatrix Writer::encode(const std::string& contents, int width, int height) const +{ + return encode(TextUtfEncoding::FromUtf8(contents), width, height); +} + } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRWriter.h b/core/src/qrcode/QRWriter.h index 5aef3b70b8..d088c8bc20 100644 --- a/core/src/qrcode/QRWriter.h +++ b/core/src/qrcode/QRWriter.h @@ -58,6 +58,7 @@ class Writer } BitMatrix encode(const std::wstring& contents, int width, int height) const; + BitMatrix encode(const std::string& contents, int width, int height) const; private: int _margin; diff --git a/test/blackbox/TestWriterMain.cpp b/test/blackbox/TestWriterMain.cpp index cb8e728198..420f0bf6ca 100644 --- a/test/blackbox/TestWriterMain.cpp +++ b/test/blackbox/TestWriterMain.cpp @@ -23,7 +23,7 @@ void savePng(const BitMatrix& matrix, BarcodeFormat format) int main() { - std::wstring text = L"http://www.google.com/"; + std::string text = "http://www.google.com/"; for (auto format : { BarcodeFormat::Aztec, BarcodeFormat::DataMatrix, @@ -33,7 +33,7 @@ int main() savePng(MultiFormatWriter(format).encode(text, 200, 200), format); } - text = L"012345678901234567890123456789"; + text = "012345678901234567890123456789"; using FormatSpecs = std::vector>; for (const auto& [format, length] : FormatSpecs({ {BarcodeFormat::Codabar, 0}, diff --git a/test/unit/oned/ODCodaBarWriterTest.cpp b/test/unit/oned/ODCodaBarWriterTest.cpp index f4071c33b7..f8662491fa 100644 --- a/test/unit/oned/ODCodaBarWriterTest.cpp +++ b/test/unit/oned/ODCodaBarWriterTest.cpp @@ -10,6 +10,7 @@ #include "DecodeHints.h" #include "Result.h" #include "oned/ODCodabarReader.h" +#include "TextUtfEncoding.h" #include "gtest/gtest.h" #include @@ -18,7 +19,7 @@ using namespace ZXing; using namespace ZXing::OneD; namespace { - std::string Encode(const std::wstring& input) + std::string Encode(const std::string& input) { auto result = ToString(CodabarWriter().encode(input, 0, 0), '1', '0', false); return result.substr(0, result.size() - 1); // remove the \n at the end @@ -27,7 +28,7 @@ namespace { TEST(ODCodaBarWriterTest, Encode) { - EXPECT_EQ(Encode(L"B515-3/B"), + EXPECT_EQ(Encode("B515-3/B"), "00000" "1001001011" "0110101001" "0101011001" "0110101001" "0101001101" "0110010101" "01101101011" "01001001011" @@ -36,7 +37,7 @@ TEST(ODCodaBarWriterTest, Encode) TEST(ODCodaBarWriterTest, Encode2) { - EXPECT_EQ(Encode(L"T123T"), + EXPECT_EQ(Encode("T123T"), "00000" "1011001001" "0101011001" "0101001011" "0110010101" "01011001001" "00000"); @@ -44,20 +45,20 @@ TEST(ODCodaBarWriterTest, Encode2) TEST(ODCodaBarWriterTest, AltStartEnd) { - EXPECT_EQ(Encode(L"T123456789-$T"), Encode(L"A123456789-$A")); + EXPECT_EQ(Encode("T123456789-$T"), Encode("A123456789-$A")); } TEST(ODCodaBarWriterTest, FullCircle) { - std::wstring text = L"A0123456789-$:/.+A"; + std::string text = "A0123456789-$:/.+A"; BitArray row; CodabarWriter().encode(text, 0, 0).getRow(0, row); Result res = CodabarReader(DecodeHints().setReturnCodabarStartEnd(true)).decodeSingleRow(0, row); - EXPECT_EQ(text, res.text()); + EXPECT_EQ(text, res.utf8()); } TEST(ODCodaBarWriterTest, InvalidChars) { - EXPECT_THROW({Encode(L"AxA");}, std::invalid_argument ); - EXPECT_THROW({Encode(L"a0a");}, std::invalid_argument ); + EXPECT_THROW({Encode("AxA");}, std::invalid_argument ); + EXPECT_THROW({Encode("a0a");}, std::invalid_argument ); } diff --git a/test/unit/oned/ODCode128WriterTest.cpp b/test/unit/oned/ODCode128WriterTest.cpp index 010854357f..0d25f605d4 100644 --- a/test/unit/oned/ODCode128WriterTest.cpp +++ b/test/unit/oned/ODCode128WriterTest.cpp @@ -92,11 +92,11 @@ TEST(ODCode128Writer, EncodeWithFncsAndNumberInCodesetA) TEST(ODCode128Writer, RoundtripGS1) { auto toEncode = L"\xf1" "10958" "\xf1" "17160526"; - auto expected = L"10958\u001D17160526"; + auto expected = "10958\u001D17160526"; auto encResult = Code128Writer().encode(toEncode, 0, 0); auto decResult = Decode(encResult); - auto actual = decResult.text(); + auto actual = decResult.utf8(); EXPECT_EQ(actual, expected); EXPECT_EQ(decResult.symbologyIdentifier(), "]C1"); } @@ -104,11 +104,11 @@ TEST(ODCode128Writer, RoundtripGS1) TEST(ODCode128Writer, RoundtripFNC1) { auto toEncode = L"1\xf1" "0958" "\xf1" "17160526"; - auto expected = L"1\u001D0958\u001D17160526"; + auto expected = "1\u001D0958\u001D17160526"; auto encResult = Code128Writer().encode(toEncode, 0, 0); auto decResult = Decode(encResult); - auto actual = decResult.text(); + auto actual = decResult.utf8(); EXPECT_EQ(actual, expected); EXPECT_EQ(decResult.symbologyIdentifier(), "]C0"); } @@ -116,7 +116,7 @@ TEST(ODCode128Writer, RoundtripFNC1) TEST(ODCode128Writer, EncodeSwitchCodesetFromAToB) { // start with A switch to B and back to A - auto toEncode = std::wstring(L"\0ABab\u0010", 6); + auto toEncode = std::string("\0ABab\u0010", 6); // "\0" "A" "B" Switch to B "a" "b" Switch to A "\u0010" check digit auto expected = QUIET_SPACE + START_CODE_A + "10100001100" + "10100011000" + "10001011000" + SWITCH_CODE_B + "10010110000" + "10010000110" + SWITCH_CODE_A + "10100111100" + "11001110100" + STOP + QUIET_SPACE; @@ -124,14 +124,14 @@ TEST(ODCode128Writer, EncodeSwitchCodesetFromAToB) auto actual = LineMatrixToString(encoded); EXPECT_EQ(actual, expected); - auto actualRoundTrip = Decode(encoded).text(); + auto actualRoundTrip = Decode(encoded).utf8(); EXPECT_EQ(actualRoundTrip, toEncode); } TEST(ODCode128Writer, EncodeSwitchCodesetFromBToA) { // start with B switch to A and back to B - auto toEncode = std::wstring(L"ab\0ab", 5); + auto toEncode = std::string("ab\0ab", 5); // "a" "b" Switch to A "\0 "Switch to B" "a" "b" check digit auto expected = QUIET_SPACE + START_CODE_B + "10010110000" + "10010000110" + SWITCH_CODE_A + "10100001100" + SWITCH_CODE_B + "10010110000" + "10010000110" + "11010001110" + STOP + QUIET_SPACE; @@ -139,6 +139,6 @@ TEST(ODCode128Writer, EncodeSwitchCodesetFromBToA) auto actual = LineMatrixToString(encoded); EXPECT_EQ(actual, expected); - auto actualRoundTrip = Decode(encoded).text(); + auto actualRoundTrip = Decode(encoded).utf8(); EXPECT_EQ(actualRoundTrip, toEncode); } diff --git a/test/unit/oned/ODCode39ExtendedModeTest.cpp b/test/unit/oned/ODCode39ExtendedModeTest.cpp index 0c256971a4..ca172b4ec1 100644 --- a/test/unit/oned/ODCode39ExtendedModeTest.cpp +++ b/test/unit/oned/ODCode39ExtendedModeTest.cpp @@ -15,12 +15,12 @@ using namespace ZXing; using namespace ZXing::OneD; -static std::wstring Decode(std::string_view encoded) +static std::string Decode(std::string_view encoded) { Code39Reader sut(DecodeHints().setTryCode39ExtendedMode(true)); BitArray row = Utility::ParseBitArray(encoded, '1'); Result result = sut.decodeSingleRow(0, row); - return result.text(); + return result.utf8(); } TEST(ODCode39ExtendedModeTest, Decode) @@ -37,7 +37,7 @@ TEST(ODCode39ExtendedModeTest, Decode) "10100100100101010010110101101001001001010110010110101010010010010101001101101010" "10100100100101101010010110101001001001010110100101101010010010010110110100101010" "1001001001010101100101101010010010010110101100101010010110110100000"), - std::wstring(L"\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 0x20)); + std::string("\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 0x20)); EXPECT_EQ(Decode( "00000100101101101010011010110101001001010010110101001011010010010100101011010010" @@ -49,7 +49,7 @@ TEST(ODCode39ExtendedModeTest, Decode) "10101010100101101101101001011010101100101101010010010100101001101101010101001001" "00101011011001010101001001001010101001101101010010010010110101001101010100100100" "1010110100110101010010010010101011001101010010110110100000"), - L" !\"#$%&'()*+,-./0123456789:;<=>?"); + " !\"#$%&'()*+,-./0123456789:;<=>?"); EXPECT_EQ(Decode( "00001001011011010101001001001010011010101101101010010110101101001011011011010010" @@ -59,7 +59,7 @@ TEST(ODCode39ExtendedModeTest, Decode) "10101011011001101010101001011010110110010110101010011011010101010010010010110101" "01001101010010010010101101010011010100100100101101101010010101001001001010101101" "001101010010010010110101101001010010110110100000"), - L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"); + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"); EXPECT_EQ(Decode( "00000100101101101010100100100101100110101010100101001001011010100101101001010010" @@ -73,5 +73,5 @@ TEST(ODCode39ExtendedModeTest, Decode) "10100101001001010010110101101001010010010110010110101010010100100101001101101010" "10100100100101011011010010101001001001010101011001101010010010010110101011001010" "1001001001010110101100101010010010010101011011001010010110110100000"), - L"`abcdefghijklmnopqrstuvwxyz{|}~"); + "`abcdefghijklmnopqrstuvwxyz{|}~"); } diff --git a/test/unit/oned/ODEAN13WriterTest.cpp b/test/unit/oned/ODEAN13WriterTest.cpp index 22cfd92da9..c1bd1deee4 100644 --- a/test/unit/oned/ODEAN13WriterTest.cpp +++ b/test/unit/oned/ODEAN13WriterTest.cpp @@ -14,7 +14,7 @@ using namespace ZXing; using namespace ZXing::OneD; namespace { - std::string Encode(const std::wstring& input) + std::string Encode(const std::string& input) { auto result = ToString(EAN13Writer().encode(input, 0, 0), '1', '0', false); return result.substr(0, result.size() - 1); // remove the \n at the end @@ -23,19 +23,19 @@ namespace { TEST(ODEAN13WriterTest, Encode1) { - std::wstring toEncode = L"5901234123457"; + std::string toEncode = "5901234123457"; std::string expected = "00001010001011010011101100110010011011110100111010101011001101101100100001010111001001110100010010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODEAN13WriterTest, AddChecksumAndEncode) { - std::wstring toEncode = L"590123412345"; + std::string toEncode = "590123412345"; std::string expected = "00001010001011010011101100110010011011110100111010101011001101101100100001010111001001110100010010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODEAN13WriterTest, EncodeIllegalCharacters) { - EXPECT_THROW({ Encode(L"5901234123abc"); }, std::invalid_argument); + EXPECT_THROW({ Encode("5901234123abc"); }, std::invalid_argument); } diff --git a/test/unit/oned/ODEAN8WriterTest.cpp b/test/unit/oned/ODEAN8WriterTest.cpp index c2bebf5d54..6df37af6c9 100644 --- a/test/unit/oned/ODEAN8WriterTest.cpp +++ b/test/unit/oned/ODEAN8WriterTest.cpp @@ -13,7 +13,7 @@ using namespace ZXing; using namespace ZXing::OneD; namespace { - std::string Encode(const std::wstring& input) + std::string Encode(const std::string& input) { auto result = ToString(EAN8Writer().encode(input, 0, 0), '1', '0', false); return result.substr(0, result.size() - 1); // remove the \n at the end @@ -22,19 +22,19 @@ namespace { TEST(ODEAN8WriterTest, Encode1) { - std::wstring toEncode = L"96385074"; + std::string toEncode = "96385074"; std::string expected = "0000101000101101011110111101011011101010100111011100101000100101110010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODEAN8WriterTest, AddChecksumAndEncode) { - std::wstring toEncode = L"9638507"; + std::string toEncode = "9638507"; std::string expected = "0000101000101101011110111101011011101010100111011100101000100101110010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODEAN8WriterTest, EncodeIllegalCharacters) { - EXPECT_THROW({ Encode(L"96385abc"); }, std::invalid_argument); + EXPECT_THROW({ Encode("96385abc"); }, std::invalid_argument); } diff --git a/test/unit/oned/ODUPCAWriterTest.cpp b/test/unit/oned/ODUPCAWriterTest.cpp index f015c6cfbc..66e02f3f78 100644 --- a/test/unit/oned/ODUPCAWriterTest.cpp +++ b/test/unit/oned/ODUPCAWriterTest.cpp @@ -13,7 +13,7 @@ using namespace ZXing; using namespace ZXing::OneD; namespace { - std::string Encode(const std::wstring& input) + std::string Encode(const std::string& input) { auto result = ToString(UPCAWriter().encode(input, 0, 0), '1', '0', false); return result.substr(0, result.size() - 1); // remove the \n at the end @@ -22,14 +22,14 @@ namespace { TEST(ODUPCAWriterTest, Encode1) { - std::wstring toEncode = L"485963095124"; + std::string toEncode = "485963095124"; std::string expected = "00001010100011011011101100010001011010111101111010101011100101110100100111011001101101100101110010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODUPCAWriterTest, AddChecksumAndEncode) { - std::wstring toEncode = L"12345678901"; + std::string toEncode = "12345678901"; std::string expected = "00001010011001001001101111010100011011000101011110101010001001001000111010011100101100110110110010100000"; EXPECT_EQ(Encode(toEncode), expected); } diff --git a/test/unit/oned/ODUPCEWriterTest.cpp b/test/unit/oned/ODUPCEWriterTest.cpp index 9db92ee6cd..271a817ced 100644 --- a/test/unit/oned/ODUPCEWriterTest.cpp +++ b/test/unit/oned/ODUPCEWriterTest.cpp @@ -14,7 +14,7 @@ using namespace ZXing; using namespace ZXing::OneD; namespace { - std::string Encode(const std::wstring& input) + std::string Encode(const std::string& input) { auto result = ToString(UPCEWriter().encode(input, 0, 0), '1', '0', false); return result.substr(0, result.size() - 1); // remove the \n at the end @@ -23,26 +23,26 @@ namespace { TEST(ODUPCEWriterTest, Encode1) { - std::wstring toEncode = L"05096893"; + std::string toEncode = "05096893"; std::string expected = "000010101110010100111000101101011110110111001011101010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODUPCEWriterTest, EncodeSystem1) { - std::wstring toEncode = L"12345670"; + std::string toEncode = "12345670"; std::string expected = "000010100100110111101010001101110010000101001000101010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODUPCEWriterTest, AddChecksumAndEncode) { - std::wstring toEncode = L"0509689"; + std::string toEncode = "0509689"; std::string expected = "000010101110010100111000101101011110110111001011101010100000"; EXPECT_EQ(Encode(toEncode), expected); } TEST(ODUPCEWriterTest, EncodeIllegalCharacters) { - EXPECT_THROW(Encode(L"05096abc"), std::invalid_argument); + EXPECT_THROW(Encode("05096abc"), std::invalid_argument); } From cce9f9dfdb7e60aa91339df6035a9c2863eec320 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 00:18:27 +0200 Subject: [PATCH 0285/1315] Content: cleanup text/utf8/utf16 situation and remove code duplication --- core/src/Content.cpp | 71 ++++++++++--------- core/src/Content.h | 4 +- core/src/DecoderResult.h | 2 +- core/src/Result.cpp | 2 +- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 4 +- test/unit/ContentTest.cpp | 16 ++--- 6 files changed, 52 insertions(+), 47 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index f5b4e1a852..c7fe98a619 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -90,30 +90,14 @@ bool Content::canProcess() const return std::all_of(encodings.begin(), encodings.end(), [](Encoding e) { return CanProcess(e.eci); }); } -std::wstring Content::text() const -{ - if (!canProcess()) - return {}; - - auto fallbackCS = CharacterSetFromString(hintedCharset); - if (!hasECI && fallbackCS == CharacterSet::Unknown) - fallbackCS = guessEncoding(); - - std::wstring wstr; - ForEachECIBlock([&](ECI eci, int begin, int end) { - CharacterSet cs = eci == ECI::Unknown ? fallbackCS : ToCharacterSet(eci); - - TextDecoder::Append(wstr, bytes.data() + begin, end - begin, cs); - }); - return wstr; -} - -std::string Content::utf8ECI() const +std::wstring Content::render(bool withECI) const { if (empty() || !canProcess()) return {}; - std::wstring res = TextDecoder::FromLatin1(symbology.toString(true)); + std::wstring res; + if (withECI) + res = TextDecoder::FromLatin1(symbology.toString(true)); ECI lastECI = ECI::Unknown; auto fallbackCS = CharacterSetFromString(hintedCharset); if (!hasECI && fallbackCS == CharacterSet::Unknown) @@ -125,26 +109,45 @@ std::string Content::utf8ECI() const // * if !IsText(eci) the ToCharcterSet(eci) will return Unknown and we decode as binary CharacterSet cs = eci == ECI::Unknown ? fallbackCS : ToCharacterSet(eci); - // then find the eci to report back in the ECI designator - if (IsText(ToECI(cs))) // everything decoded as text is reported as utf8 - eci = ECI::UTF8; - else if (eci == ECI::Unknown) // implies !hasECI and fallbackCS is Unknown or Binary - eci = ECI::Binary; + if (withECI) { + // then find the eci to report back in the ECI designator + if (IsText(ToECI(cs))) // everything decoded as text is reported as utf8 + eci = ECI::UTF8; + else if (eci == ECI::Unknown) // implies !hasECI and fallbackCS is Unknown or Binary + eci = ECI::Binary; - if (lastECI != eci) - TextDecoder::AppendLatin1(res, ToString(eci)); - lastECI = eci; + if (lastECI != eci) + TextDecoder::AppendLatin1(res, ToString(eci)); + lastECI = eci; - std::wstring tmp; - TextDecoder::Append(tmp, bytes.data() + begin, end - begin, cs); - for (auto c : tmp) { - res += c; - if (c == L'\\') // in the ECI protocol a '\' has to be doubled + std::wstring tmp; + TextDecoder::Append(tmp, bytes.data() + begin, end - begin, cs); + for (auto c : tmp) { res += c; + if (c == L'\\') // in the ECI protocol a '\' has to be doubled + res += c; + } + } else { + TextDecoder::Append(res, bytes.data() + begin, end - begin, cs); } }); - return TextUtfEncoding::ToUtf8(res); + return res; +} + +std::wstring Content::utf16() const +{ + return render(false); +} + +std::string Content::utf8() const +{ + return TextUtfEncoding::ToUtf8(render(false)); +} + +std::string Content::utf8ECI() const +{ + return TextUtfEncoding::ToUtf8(render(true)); } ByteArray Content::bytesECI() const diff --git a/core/src/Content.h b/core/src/Content.h index 756d8b72fe..022cdc9569 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -33,6 +33,7 @@ class Content void ForEachECIBlock(FUNC f) const; void switchEncoding(ECI eci, bool isECI); + std::wstring render(bool withECI) const; public: struct Encoding @@ -70,7 +71,8 @@ class Content bool empty() const { return bytes.empty(); } bool canProcess() const; - std::wstring text() const; + std::wstring utf16() const; + std::string utf8() const; std::string utf8ECI() const; ByteArray bytesECI() const; CharacterSet guessEncoding() const; diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index a6ce5e6ab3..9908d1121c 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -58,7 +58,7 @@ class DecoderResult Content&& content() && { return std::move(_content); } // to keep the unit tests happy for now: - std::wstring text() const { return _content.text(); } + std::wstring text() const { return _content.utf16(); } std::string symbologyIdentifier() const { return _content.symbology.toString(false); } // Simple macro to set up getter/setter methods that save lots of boilerplate. diff --git a/core/src/Result.cpp b/core/src/Result.cpp index fc1a86656a..1e6a7e8bcb 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -62,7 +62,7 @@ ByteArray Result::bytesECI() const std::string Result::utf8() const { - return TextUtfEncoding::ToUtf8(_content.text()); + return _content.utf8(); } std::string Result::utf8ECI() const diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 6f7a835309..3a5cc5eef8 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -569,7 +569,7 @@ static int DecodeMacroOptionalTextField(DecodeStatus& status, const std::vector< codeIndex = TextCompaction(status, codewords, codeIndex, result); // Converting to UTF-8 (backward-incompatible change for non-ASCII chars) - TextUtfEncoding::ToUtf8(result.text(), field); + field = result.utf8(); return codeIndex; } @@ -587,7 +587,7 @@ static int DecodeMacroOptionalNumericField(DecodeStatus& status, const std::vect codeIndex = NumericCompaction(status, codewords, codeIndex, result); - field = std::stoll(result.text()); + field = std::stoll(result.utf8()); return codeIndex; } diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp index 19c3a5f8b1..39fa72ba25 100644 --- a/test/unit/ContentTest.cpp +++ b/test/unit/ContentTest.cpp @@ -25,14 +25,14 @@ TEST(ContentTest, Base) Content c; c.switchEncoding(CharacterSet::ISO8859_1); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.text(), L"A\u00E9Z"); + EXPECT_EQ(c.utf16(), L"A\u00E9Z"); } { // set CharacterSet::ISO8859_5 Content c; c.switchEncoding(CharacterSet::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.text(), L"A\u0449Z"); + EXPECT_EQ(c.utf16(), L"A\u0449Z"); } { // switch to CharacterSet::ISO8859_5 @@ -42,7 +42,7 @@ TEST(ContentTest, Base) c.switchEncoding(CharacterSet::ISO8859_5); EXPECT_FALSE(c.hasECI); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.text(), L"A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf16(), L"A\u00E9ZA\u0449Z"); } } @@ -52,7 +52,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::ISO8859_1); - EXPECT_EQ(c.text(), L"A\u00E9Z"); + EXPECT_EQ(c.utf16(), L"A\u00E9Z"); EXPECT_EQ(c.bytesECI(), c.bytes); } @@ -60,7 +60,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::Shift_JIS); - EXPECT_EQ(c.text(), L"A\u30C6Z"); + EXPECT_EQ(c.utf16(), L"A\u30C6Z"); } } @@ -72,7 +72,7 @@ TEST(ContentTest, ECI) c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_TRUE(c.hasECI); - EXPECT_EQ(c.text(), L"A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf16(), L"A\u00E9ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\xE9Z\\000007A\xE9Z")); } @@ -81,14 +81,14 @@ TEST(ContentTest, ECI) c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.text(), L"A\u0083\u0065ZA\u0449Z"); + EXPECT_EQ(c.utf16(), L"A\u0083\u0065ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\x83\x65Z\\000007A\xE9Z")); } { // double '\' Content c; c.append("C:\\Test"); - EXPECT_EQ(c.text(), L"C:\\Test"); + EXPECT_EQ(c.utf16(), L"C:\\Test"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("C:\\\\Test")); } } From 34b54060590485a0b0bef6cdb3b5baa70123918a Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 01:18:29 +0200 Subject: [PATCH 0286/1315] Result: #define ZX_USE_UTF8 to transition from std::wstring to std::string See https://github.com/nu-book/zxing-cpp/issues/338 for more information * Change the return type of `text()` and `ecLevel()` based on ZX_USE_UTF8. * Introduce `utf16()` as a (temporary?) backend for `text()`. * Add documentation. * Update examples, wrappers and testing code to use ZX_USE_UTF8. --- core/CMakeLists.txt | 1 + core/src/Result.cpp | 12 ++--- core/src/Result.h | 50 ++++++++++++++++--- example/ZXingOpenCV.h | 6 +-- example/ZXingQtReader.h | 4 +- example/ZXingReader.cpp | 17 ++++--- test/blackbox/BlackboxTestRunner.cpp | 5 +- test/blackbox/CMakeLists.txt | 1 + test/blackbox/TestReaderMain.cpp | 5 +- test/unit/CMakeLists.txt | 1 + test/unit/ThresholdBinarizerTest.cpp | 2 +- test/unit/oned/ODCode128ReaderTest.cpp | 18 +++---- test/unit/oned/ODCode39ReaderTest.cpp | 14 +++--- test/unit/oned/ODCode93ReaderTest.cpp | 6 +-- .../zxingcpp/src/main/cpp/CMakeLists.txt | 1 + .../zxingcpp/src/main/cpp/JNIUtils.cpp | 4 +- wrappers/python/zxing.cpp | 2 + wrappers/wasm/BarcodeReader.cpp | 16 +++--- wrappers/winrt/BarcodeReader.cpp | 4 +- 19 files changed, 107 insertions(+), 62 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index e6c4d1a07f..655d569305 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -19,6 +19,7 @@ set (ZXING_CORE_LOCAL_DEFINES $<$:-DZXING_BUILD_READERS> $<$:-DZXING_BUILD_WRITERS> $<$:-DZXING_BUILD_FOR_TEST> + -DZX_USE_UTF8 # silence deprecation warning in Result.h ) if (MSVC) set (ZXING_CORE_LOCAL_DEFINES ${ZXING_CORE_LOCAL_DEFINES} diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 1e6a7e8bcb..9539e273fc 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -36,7 +36,7 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), - _ecLevel(TextDecoder::FromLatin1(decodeResult.ecLevel())), + _ecLevel(decodeResult.ecLevel()), _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), _readerInit(decodeResult.readerInit()), @@ -45,11 +45,6 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } -std::wstring Result::text() const -{ - return _content.text(); -} - const ByteArray& Result::bytes() const { return _content.bytes; @@ -65,6 +60,11 @@ std::string Result::utf8() const return _content.utf8(); } +std::wstring Result::utf16() const +{ + return _content.utf16(); +} + std::string Result::utf8ECI() const { return _content.utf8ECI(); diff --git a/core/src/Result.h b/core/src/Result.h index 24238bcee8..74dcb5f411 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -43,21 +43,57 @@ class Result BarcodeFormat format() const { return _format; } - std::wstring text() const; - - // WARNING: this is an experimental API and may change/disappear + /** + * @brief bytes is the raw / standard content without any modifications like character set conversions + */ const ByteArray& bytes() const; + + /** + * @brief bytesECI is the raw / standard content following the ECI protocol + */ ByteArray bytesECI() const; + + /** + * @brief utf8/utf16 is the bytes() content converted to utf8/16 based on ECI or guessed character set information + * + * Note: these two properties might only be available while transitioning text() from std::wstring to std::string. time will tell. + * see https://github.com/nu-book/zxing-cpp/issues/338 for a background discussion on the issue. + */ std::string utf8() const; + std::wstring utf16() const; + +#ifdef ZX_USE_UTF8 + std::string text() const { return utf8(); } + std::string ecLevel() const { return _ecLevel; } +#else +#pragma message( \ + "Warning: the return type of text() and ecLevel() will change to std::string. Please #define ZX_USE_UTF8 to transition before the next release.") + std::wstring text() const { return utf16(); } + std::wstring ecLevel() const { return {_ecLevel.begin(), _ecLevel.end()}; } +#endif + + /** + * @brief utf8ECI is the standard content following the ECI protocol with every character set ECI segment transcoded to utf8 + */ std::string utf8ECI() const; + + /** + * @brief contentType gives a hint to the type of content found (Text/Binary/GS1/etc.) + */ ContentType contentType() const; + + /** + * @brief hasECI specifies wheter or not an ECI tag was found + */ bool hasECI() const; - // END WARNING const Position& position() const { return _position; } void setPosition(Position pos) { _position = pos; } - int orientation() const; //< orientation of barcode in degree, see also Position::orientation() + /** + * @brief orientation of barcode in degree, see also Position::orientation() + */ + int orientation() const; /** * @brief isMirrored is the symbol mirrored (currently only supported by QRCode and DataMatrix) @@ -68,8 +104,6 @@ class Result [[deprecated]] const ByteArray& rawBytes() const { return _rawBytes; } [[deprecated]] int numBits() const { return _numBits; } - const std::wstring& ecLevel() const { return _ecLevel; } - /** * @brief symbologyIdentifier Symbology identifier "]cm" where "c" is symbology code character, "m" the modifier. */ @@ -125,7 +159,7 @@ class Result Position _position; ByteArray _rawBytes; int _numBits = 0; - std::wstring _ecLevel; + std::string _ecLevel; StructuredAppendInfo _sai; bool _isMirrored = false; bool _readerInit = false; diff --git a/example/ZXingOpenCV.h b/example/ZXingOpenCV.h index bf9cca06e7..8dbfb2545d 100644 --- a/example/ZXingOpenCV.h +++ b/example/ZXingOpenCV.h @@ -5,8 +5,9 @@ #pragma once +#define ZX_USE_UTF8 1 // see Result.h + #include "ReadBarcode.h" -#include "TextUtfEncoding.h" #include @@ -41,6 +42,5 @@ inline void DrawResult(cv::Mat& img, ZXing::Result res) int npts = contour.size(); cv::polylines(img, &pts, &npts, 1, true, CV_RGB(0, 255, 0)); - cv::putText(img, ZXing::TextUtfEncoding::ToUtf8(res.text()), cv::Point(10, 20), cv::FONT_HERSHEY_DUPLEX, 0.5, - CV_RGB(0, 255, 0)); + cv::putText(img, res.text(), cv::Point(10, 20), cv::FONT_HERSHEY_DUPLEX, 0.5, CV_RGB(0, 255, 0)); } diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 07effc10d0..675b2d0205 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -5,6 +5,8 @@ #pragma once +#define ZX_USE_UTF8 1 // see Result.h + #include "ReadBarcode.h" #include @@ -115,7 +117,7 @@ class Result : private ZXing::Result Result() : ZXing::Result(ZXing::DecodeStatus::NotFound) {} // required for qmetatype machinery explicit Result(ZXing::Result&& r) : ZXing::Result(std::move(r)) { - _text = QString::fromWCharArray(ZXing::Result::text().c_str()); + _text = QString::fromStdString(ZXing::Result::text()); _bytes = QByteArray(reinterpret_cast(ZXing::Result::bytes().data()), Size(ZXing::Result::bytes())); auto& pos = ZXing::Result::position(); auto qp = [&pos](int i) { return QPoint(pos[i].x, pos[i].y); }; diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 64f91e1701..db7ac9239f 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -4,6 +4,8 @@ */ // SPDX-License-Identifier: Apache-2.0 +#define ZX_USE_UTF8 1 // see Result.h + #include "ReadBarcode.h" #include "TextUtfEncoding.h" #include "GTIN.h" @@ -23,7 +25,6 @@ #include using namespace ZXing; -using namespace TextUtfEncoding; static void PrintUsage(const char* exePath) { @@ -113,7 +114,7 @@ void drawRect(const ImageView& image, const Position& pos) std::string escapeNonGraphical(const std::string& str) { - return ToUtf8(FromUtf8(str), true); + return TextUtfEncoding::ToUtf8(TextUtfEncoding::FromUtf8(str), true); } int main(int argc, char* argv[]) @@ -177,7 +178,7 @@ int main(int argc, char* argv[]) if (oneLine) { std::cout << filePath << " " << ToString(result.format()); if (result.isValid()) - std::cout << " \"" << escapeNonGraphical(result.utf8()) << "\""; + std::cout << " \"" << escapeNonGraphical(result.text()) << "\""; else if (result.format() != BarcodeFormat::None) std::cout << " " << ToString(result.status()); std::cout << "\n"; @@ -192,7 +193,7 @@ int main(int argc, char* argv[]) std::cout << "File: " << filePath << "\n"; firstFile = false; } - std::cout << "Text: \"" << (angleEscape ? escapeNonGraphical(result.utf8()) : result.utf8()) << "\"\n" + std::cout << "Text: \"" << (angleEscape ? escapeNonGraphical(result.text()) : result.text()) << "\"\n" << "TextECI: \"" << result.utf8ECI() << "\"\n" << "Bytes: " << ToHex(result.bytes()) << "\n" << "BytesECI: " << ToHex(result.bytesECI()) << "\n" @@ -210,19 +211,19 @@ int main(int argc, char* argv[]) std::cout << key << v << "\n"; }; - printOptional("EC Level: ", ToUtf8(result.ecLevel())); + printOptional("EC Level: ", result.ecLevel()); if (result.lineCount()) std::cout << "Lines: " << result.lineCount() << "\n"; if ((BarcodeFormat::EAN13 | BarcodeFormat::EAN8 | BarcodeFormat::UPCA | BarcodeFormat::UPCE) .testFlag(result.format())) { - printOptional("Country: ", GTIN::LookupCountryIdentifier(ToUtf8(result.text()), result.format())); + printOptional("Country: ", GTIN::LookupCountryIdentifier(result.text(), result.format())); printOptional("Add-On: ", GTIN::EanAddOn(result)); printOptional("Price: ", GTIN::Price(GTIN::EanAddOn(result))); printOptional("Issue #: ", GTIN::IssueNr(GTIN::EanAddOn(result))); - } else if (result.format() == BarcodeFormat::ITF && result.text().length() == 14) { - printOptional("Country: ", GTIN::LookupCountryIdentifier(ToUtf8(result.text()), result.format())); + } else if (result.format() == BarcodeFormat::ITF && Size(result.bytes()) == 14) { + printOptional("Country: ", GTIN::LookupCountryIdentifier(result.text(), result.format())); } if (result.isPartOfSequence()) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 085bb41d95..e28f3a1e02 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -9,7 +9,6 @@ #include "DecoderResult.h" #include "ImageLoader.h" #include "ReadBarcode.h" -#include "TextUtfEncoding.h" #include "ThresholdBinarizer.h" #include "ZXContainerAlgorithms.h" #include "pdf417/PDFReader.h" @@ -65,7 +64,7 @@ namespace { static std::string getResultValue(const Result& result, const std::string& key) { if (key == "ecLevel") - return TextUtfEncoding::ToUtf8(result.ecLevel()); + return result.ecLevel(); if (key == "orientation") return std::to_string(result.orientation()); if (key == "symbologyIdentifier") @@ -135,7 +134,7 @@ static std::string checkResult(const fs::path& imgPath, std::string_view expecte } if (auto expected = readFile(".txt")) { - auto utf8Result = TextUtfEncoding::ToUtf8(result.text()); + auto utf8Result = result.utf8(); return utf8Result != *expected ? fmt::format("Content mismatch: expected '{}' but got '{}'", *expected, utf8Result) : ""; } diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index f20f4127c7..2d7d9e3036 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -15,6 +15,7 @@ if (BUILD_READERS) ZXing::ZXing fmt::fmt stb::stb $<$,$,9.0>>:stdc++fs> ) + target_compile_definitions(ReaderTest PRIVATE ZX_USE_UTF8) add_test(NAME ReaderTest COMMAND ReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/../samples) endif() diff --git a/test/blackbox/TestReaderMain.cpp b/test/blackbox/TestReaderMain.cpp index 4aad4905cc..ebc4ed972e 100644 --- a/test/blackbox/TestReaderMain.cpp +++ b/test/blackbox/TestReaderMain.cpp @@ -6,7 +6,6 @@ #include "BlackboxTestRunner.h" #include "ImageLoader.h" -#include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" #include "ZXFilesystem.h" @@ -44,12 +43,12 @@ int main(int argc, char** argv) Result result = ReadBarcode(ImageLoader::load(argv[i]).rotated(rotation), hints); std::cout << argv[i] << ": "; if (result.isValid()) - std::cout << ToString(result.format()) << ": " << TextUtfEncoding::ToUtf8(result.text()) << "\n"; + std::cout << ToString(result.format()) << ": " << result.text() << "\n"; else std::cout << "FAILED\n"; if (result.isValid() && getenv("WRITE_TEXT")) { std::ofstream f(fs::path(argv[i]).replace_extension(".txt")); - f << TextUtfEncoding::ToUtf8(result.text()); + f << result.text(); } } return 0; diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 9bd281796d..96ddb9b60e 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -65,5 +65,6 @@ add_executable (UnitTest target_include_directories (UnitTest PRIVATE .) target_link_libraries (UnitTest ZXing::ZXing GTest::gtest_main GTest::gmock) +target_compile_definitions(UnitTest PRIVATE ZX_USE_UTF8) add_test(NAME UnitTest COMMAND UnitTest) diff --git a/test/unit/ThresholdBinarizerTest.cpp b/test/unit/ThresholdBinarizerTest.cpp index ae6449f8dd..aee132bdcc 100644 --- a/test/unit/ThresholdBinarizerTest.cpp +++ b/test/unit/ThresholdBinarizerTest.cpp @@ -100,5 +100,5 @@ TEST(ThresholdBinarizerTest, PatternRowClear) result = reader.decode(ThresholdBinarizer(getImageView(buf, bits), 0x7F)); EXPECT_TRUE(result.isValid()); - EXPECT_EQ(result.text(), L"(91)12345678901234567890123456789012345678901234567890123456789012345678"); + EXPECT_EQ(result.text(), "(91)12345678901234567890123456789012345678901234567890123456789012345678"); } diff --git a/test/unit/oned/ODCode128ReaderTest.cpp b/test/unit/oned/ODCode128ReaderTest.cpp index ed37bcf79c..c22f655333 100644 --- a/test/unit/oned/ODCode128ReaderTest.cpp +++ b/test/unit/oned/ODCode128ReaderTest.cpp @@ -37,7 +37,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 2, 1, 2, 3, 1, 2, 2, 2, 1, 2, 2, 3, 1, 1, 2, 2, 2 }); auto result = parse('C', row); EXPECT_EQ(result.symbologyIdentifier(), "]C0"); - EXPECT_EQ(result.text(), L"2001"); + EXPECT_EQ(result.utf8(), "2001"); } { @@ -45,7 +45,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 4, 1, 1, 1, 3, 1, 2, 2, 1, 2, 3, 1, 2, 2, 2, 1, 2, 2, 1, 3, 2, 1, 3, 1 }); auto result = parse('C', row); EXPECT_EQ(result.symbologyIdentifier(), "]C1"); - EXPECT_EQ(result.text(), L"2001"); + EXPECT_EQ(result.utf8(), "2001"); } { @@ -53,7 +53,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 1, 1, 1, 3, 2, 3, 4, 1, 1, 1, 3, 1, 1, 3, 1, 1, 2, 3, 2, 1, 2, 3, 2, 1 }); auto result = parse('B', row); EXPECT_EQ(result.symbologyIdentifier(), "]C2"); - EXPECT_EQ(result.text(), L"AB"); + EXPECT_EQ(result.utf8(), "AB"); } { @@ -61,7 +61,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 1, 4, 1, 2, 1, 4, 1, 1, 1, 3, 1, 1, 3, 1, 1, 2, 3, 4, 2, 1, 2, 1, 1 }); auto result = parse('B', row); EXPECT_EQ(result.symbologyIdentifier(), "]C2"); - EXPECT_EQ(result.text(), L"zB"); + EXPECT_EQ(result.utf8(), "zB"); } { @@ -69,7 +69,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 1, 1, 3, 1, 4, 1, 4, 1, 1, 1, 3, 1, 1, 1, 4, 1, 3, 1, 1, 1, 1, 3, 2, 3, 1, 2, 3, 1, 2, 2 }); auto result = parse('C', row); EXPECT_EQ(result.symbologyIdentifier(), "]C2"); - EXPECT_EQ(result.text(), L"99A"); + EXPECT_EQ(result.utf8(), "99A"); } { @@ -77,7 +77,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 1, 2, 3, 2, 1, 4, 1, 1, 1, 3, 1, 1, 3, 1, 1, 2, 3, 3, 2, 2, 2, 1, 1 }); auto result = parse('B', row); EXPECT_EQ(result.symbologyIdentifier(), "]C0"); // Just ignoring, not giving FormatError - EXPECT_EQ(result.text(), L"?\u001DB"); + EXPECT_EQ(result.utf8(), "?\u001DB"); } } @@ -88,7 +88,7 @@ TEST(ODCode128ReaderTest, ReaderInit) PatternRow row({ 1, 1, 1, 1, 4, 3, 1, 3, 1, 1, 4, 1 }); auto result = parse('C', row); EXPECT_FALSE(result.readerInit()); - EXPECT_EQ(result.text(), L"92"); + EXPECT_EQ(result.utf8(), "92"); } { @@ -96,7 +96,7 @@ TEST(ODCode128ReaderTest, ReaderInit) PatternRow row({ 1, 1, 4, 3, 1, 1, 1, 1, 3, 1, 4, 1, 1, 1, 1, 1, 4, 3, 3, 3, 1, 1, 2, 1 }); auto result = parse('B', row); EXPECT_TRUE(result.readerInit()); - EXPECT_EQ(result.text(), L"92"); + EXPECT_EQ(result.utf8(), "92"); } { @@ -104,6 +104,6 @@ TEST(ODCode128ReaderTest, ReaderInit) PatternRow row({ 3, 2, 1, 1, 2, 2, 1, 1, 4, 3, 1, 1, 2, 2, 3, 2, 1, 1, 1, 2, 1, 4, 2, 1 }); auto result = parse('B', row); EXPECT_TRUE(result.readerInit()); - EXPECT_EQ(result.text(), L"92"); + EXPECT_EQ(result.utf8(), "92"); } } diff --git a/test/unit/oned/ODCode39ReaderTest.cpp b/test/unit/oned/ODCode39ReaderTest.cpp index 42da6c6ce0..893c2a008c 100644 --- a/test/unit/oned/ODCode39ReaderTest.cpp +++ b/test/unit/oned/ODCode39ReaderTest.cpp @@ -33,39 +33,39 @@ TEST(ODCode39ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 1, 1, 1, 1, 2, 1, 1, 2 }); auto result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.text(), L"A"); + EXPECT_EQ(result.utf8(), "A"); } { // "A" with checksum PatternRow row({ 2, 1, 1, 1, 1, 2, 1, 1, 2, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2 }); auto result = parse(row, DecodeHints().setValidateCode39CheckSum(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A3"); - EXPECT_EQ(result.text(), L"A"); + EXPECT_EQ(result.utf8(), "A"); result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.text(), L"AA"); + EXPECT_EQ(result.utf8(), "AA"); } { // Extended "a" PatternRow row({ 1, 2, 1, 1, 1, 2, 1, 2, 1, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2 }); auto result = parse(row, DecodeHints().setTryCode39ExtendedMode(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A4"); - EXPECT_EQ(result.text(), L"a"); + EXPECT_EQ(result.utf8(), "a"); result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.text(), L"+A"); + EXPECT_EQ(result.utf8(), "+A"); } { // Extended "a" with checksum PatternRow row({ 1, 2, 1, 1, 1, 2, 1, 2, 1, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2, 0, 2, 1, 1, 2, 1, 1, 2, 1, 1 }); auto result = parse(row, DecodeHints().setTryCode39ExtendedMode(true).setValidateCode39CheckSum(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A7"); - EXPECT_EQ(result.text(), L"a"); + EXPECT_EQ(result.utf8(), "a"); result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.text(), L"+A8"); + EXPECT_EQ(result.utf8(), "+A8"); } } diff --git a/test/unit/oned/ODCode93ReaderTest.cpp b/test/unit/oned/ODCode93ReaderTest.cpp index 221d37d957..b037f1acbc 100644 --- a/test/unit/oned/ODCode93ReaderTest.cpp +++ b/test/unit/oned/ODCode93ReaderTest.cpp @@ -14,17 +14,17 @@ using namespace ZXing; using namespace ZXing::OneD; -static std::wstring Decode(std::string_view input) +static std::string Decode(std::string_view input) { Code93Reader sut; auto row = Utility::ParseBitArray(input, '1'); auto result = sut.decodeSingleRow(0, row); - return result.text(); + return result.utf8(); } TEST(ODCode93ReaderTest, Decode) { - auto expected = std::wstring(L"Code93!\n$%/+ :\x1b;[{\x7f\x00@`\x7f\x7f\x7f", 25); + auto expected = std::string("Code93!\n$%/+ :\x1b;[{\x7f\x00@`\x7f\x7f\x7f", 25); auto decoded = Decode( "00000010101111011010001010011001010010110010011001011001010010011001011001001010" "00010101010000101110101101101010001001001101001101001110010101101011101011011101" diff --git a/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt b/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt index e49d0b61e5..8d28b221a2 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt +++ b/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt @@ -12,5 +12,6 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../core ZXing EXCLUD add_library(zxing_android SHARED BarcodeReader.cpp JNIUtils.cpp) +target_compile_definitions(zxing_android PRIVATE -DZX_USE_UTF8) target_link_libraries(zxing_android PRIVATE ZXing::ZXing log jnigraphics) diff --git a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp index 6ae1333f12..85d1717f92 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "JNIUtils.h" -#include "TextDecoder.h" +#include "TextUtfEncoding.h" #include #include @@ -55,7 +55,7 @@ jstring C2JString(JNIEnv* env, const std::wstring& str) jstring C2JString(JNIEnv* env, const std::string& str) { - return C2JString(env, ZXing::TextDecoder::FromLatin1(str)); + return C2JString(env, ZXing::TextUtfEncoding::FromUtf8(str)); } std::string J2CString(JNIEnv* env, jstring str) diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 72336d5c0c..17c79e80df 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -7,6 +7,8 @@ #include "BarcodeFormat.h" +#define ZX_USE_UTF8 1 // see Result.h + // Reader #include "ReadBarcode.h" diff --git a/wrappers/wasm/BarcodeReader.cpp b/wrappers/wasm/BarcodeReader.cpp index eb6e437b5a..7efee44486 100644 --- a/wrappers/wasm/BarcodeReader.cpp +++ b/wrappers/wasm/BarcodeReader.cpp @@ -3,6 +3,8 @@ */ // SPDX-License-Identifier: Apache-2.0 +#define ZX_USE_UTF8 1 // see Result.h + #include "ReadBarcode.h" #include @@ -16,7 +18,7 @@ struct ReadResult { std::string format; - std::wstring text; + std::string text; std::string error; ZXing::Position position; }; @@ -37,7 +39,7 @@ ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, &channels, 4), stbi_image_free); if (buffer == nullptr) { - return { "", L"", "Error loading image" }; + return { "", "", "Error loading image" }; } auto result = ReadBarcode({buffer.get(), width, height, ImageFormat::RGBX}, hints); @@ -46,10 +48,10 @@ ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, } } catch (const std::exception& e) { - return { "", L"", e.what() }; + return { "", "", e.what() }; } catch (...) { - return { "", L"", "Unknown error" }; + return { "", "", "Unknown error" }; } return {}; } @@ -72,10 +74,10 @@ ReadResult readBarcodeFromPixmap(int bufferPtr, int imgWidth, int imgHeight, boo } } catch (const std::exception& e) { - return { "", L"", e.what() }; + return { "", "", e.what() }; } catch (...) { - return { "", L"", "Unknown error" }; + return { "", "", "Unknown error" }; } return {}; } @@ -106,7 +108,7 @@ EMSCRIPTEN_BINDINGS(BarcodeReader) function("readBarcodeFromImage", &readBarcodeFromImage); function("readBarcodeFromPixmap", &readBarcodeFromPixmap); - // obsoletes + // obsoletes [[deprecated]] function("readBarcode", &readBarcodeFromImage); function("readBarcodeFromPng", &readBarcodeFromImage); } diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index 9695d26400..7080be6241 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -21,6 +21,8 @@ #include "BarcodeReader.h" +#define ZX_USE_UTF8 1 // silence deprecation warning in Result.h + #include "BarcodeFormat.h" #include "DecodeHints.h" #include "ReadBarcode.h" @@ -202,7 +204,7 @@ BarcodeReader::Read(SoftwareBitmap^ bitmap, int cropWidth, int cropHeight) auto result = ReadBarcode(img, *m_hints); if (result.isValid()) { - return ref new ReadResult(ToPlatformString(ZXing::ToString(result.format())), ToPlatformString(result.text()), ConvertNativeToRuntime(result.format())); + return ref new ReadResult(ToPlatformString(ZXing::ToString(result.format())), ToPlatformString(result.utf16()), ConvertNativeToRuntime(result.format())); } } else { throw std::runtime_error("Failed to read bitmap's data"); From 907b735a5ded24e8fb3376175f0465495247ecb0 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 01:21:55 +0200 Subject: [PATCH 0287/1315] License: add overlooked SPDX-License-Identifier in 2 files --- core/ZXVersion.h.in | 16 +++------------- wrappers/winrt/BarcodeReader.cpp | 13 +------------ 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/core/ZXVersion.h.in b/core/ZXVersion.h.in index 8e2151f629..78fde4106a 100644 --- a/core/ZXVersion.h.in +++ b/core/ZXVersion.h.in @@ -1,19 +1,9 @@ -#pragma once /* * Copyright 2019 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once // Version numbering #define ZXING_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index 7080be6241..5d3360985e 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -1,18 +1,7 @@ /* * Copyright 2016 Nu-book Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. */ +// SPDX-License-Identifier: Apache-2.0 #if (_MSC_VER >= 1915) #define no_init_all deprecated From 728b5a99a74132251933685299f880bfa300761c Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 12:32:35 +0200 Subject: [PATCH 0288/1315] android: add `bytes` and `contentType` members to `Result` Use in demo app to show hex coded binary content. --- .../com/example/zxingcppdemo/MainActivity.kt | 4 ++- .../zxingcpp/src/main/cpp/BarcodeReader.cpp | 29 +++++++++++++++++++ .../main/java/com/zxingcpp/BarcodeReader.kt | 5 ++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt index d023a70676..82cf02fd9e 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt @@ -166,7 +166,9 @@ class MainActivity : AppCompatActivity() { p.toPointF() } } - (result?.let { "${it.format}: ${it.text}" } ?: "") + (result?.let { "${it.format} (${it.contentType}):" + + "${if (it.contentType != BarcodeReader.ContentType.BINARY) it.text else it.bytes!!.joinToString(separator = "") { v -> "%02x".format(v) }}" } + ?: "") } catch (e: Throwable) { e.message ?: "Error" } diff --git a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp index ce37a1ecde..571434cff1 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp @@ -39,6 +39,20 @@ static const char* JavaBarcodeFormatName(BarcodeFormat format) } } +static const char* JavaContentTypeName(ContentType contentType) +{ + // These have to be the names of the enum constants in the kotlin code. + switch (contentType) { + case ContentType::Text: return "TEXT"; + case ContentType::Binary: return "BINARY"; + case ContentType::Mixed: return "MIXED"; + case ContentType::GS1: return "GS1"; + case ContentType::ISO15434: return "ISO15434"; + case ContentType::UnknownECI: return "UNKNOWN_ECI"; + default: throw std::invalid_argument("Invalid contentType"); + } +} + static jstring ThrowJavaException(JNIEnv* env, const char* message) { // if (env->ExceptionCheck()) @@ -48,6 +62,13 @@ static jstring ThrowJavaException(JNIEnv* env, const char* message) return nullptr; } +static jobject CreateContentType(JNIEnv* env, ContentType contentType) +{ + jclass cls = env->FindClass("com/zxingcpp/BarcodeReader$ContentType"); + jfieldID fidCT = env->GetStaticFieldID(cls , JavaContentTypeName(contentType), "Lcom/zxingcpp/BarcodeReader$ContentType;"); + return env->GetStaticObjectField(cls, fidCT); +} + static jobject CreateAndroidPoint(JNIEnv* env, const PointT& point) { jclass cls = env->FindClass("android/graphics/Point"); @@ -99,9 +120,17 @@ jstring Read(JNIEnv *env, ImageView image, jstring formats, jboolean tryHarder, env->SetObjectField(result, fidTime, C2JString(env, time)); if (res.isValid()) { + jbyteArray jByteArray = env->NewByteArray(res.bytes().size()); + env->SetByteArrayRegion(jByteArray, 0, res.bytes().size(), (jbyte*)res.bytes().data()); + jfieldID fidBytes = env->GetFieldID(clResult, "bytes", "[B"); + env->SetObjectField(result, fidBytes, jByteArray); + jfieldID fidText = env->GetFieldID(clResult, "text", "Ljava/lang/String;"); env->SetObjectField(result, fidText, C2JString(env, res.text())); + jfieldID fidContentType = env->GetFieldID(clResult , "contentType", "Lcom/zxingcpp/BarcodeReader$ContentType;"); + env->SetObjectField(result, fidContentType, CreateContentType(env, res.contentType())); + jfieldID fidPosition = env->GetFieldID(clResult, "position", "Lcom/zxingcpp/BarcodeReader$Position;"); env->SetObjectField(result, fidPosition, CreatePosition(env, res.position())); diff --git a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt index 6dbddecdac..8f5745976d 100644 --- a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt +++ b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt @@ -32,6 +32,9 @@ class BarcodeReader { NONE, AZTEC, CODABAR, CODE_39, CODE_93, CODE_128, DATA_BAR, DATA_BAR_EXPANDED, DATA_MATRIX, EAN_8, EAN_13, ITF, MAXICODE, PDF_417, QR_CODE, MICRO_QR_CODE, UPC_A, UPC_E } + enum class ContentType { + TEXT, BINARY, MIXED, GS1, ISO15434, UNKNOWN_ECI + } data class Options( val formats: Set = setOf(), @@ -50,8 +53,10 @@ class BarcodeReader { data class Result( val format: Format = Format.NONE, + val bytes: ByteArray? = null, val text: String? = null, val time: String? = null, // for development/debug purposes only + val contentType: ContentType = ContentType.TEXT, val position: Position? = null, val orientation: Int = 0, val ecLevel: String? = null, From 5a0cb4569843818710fc546a8421a4277a07c6e3 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 12:33:28 +0200 Subject: [PATCH 0289/1315] python: add `content_type` property in Result --- wrappers/python/zxing.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 17c79e80df..59be2d6e24 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -175,6 +175,14 @@ PYBIND11_MODULE(zxingcpp, m) .value("Read", EanAddOnSymbol::Read) .value("Require", EanAddOnSymbol::Require) .export_values(); + py::enum_(m, "ContentType", "Enumeration of content types") + .value("Text", ContentType::Text) + .value("Binary", ContentType::Binary) + .value("Mixed", ContentType::Mixed) + .value("GS1", ContentType::GS1) + .value("ISO15434", ContentType::ISO15434) + .value("UnknownECI", ContentType::UnknownECI) + .export_values(); py::class_(m, "Point", "Represents the coordinates of a point in an image") .def_readonly("x", &PointI::x, ":return: horizontal coordinate of the point\n" @@ -216,6 +224,9 @@ PYBIND11_MODULE(zxingcpp, m) .def_property_readonly("symbology_identifier", &Result::symbologyIdentifier, ":return: decoded symbology idendifier\n" ":rtype: str") + .def_property_readonly("content_type", &Result::contentType, + ":return: content type of symbol\n" + ":rtype: zxing.ContentType") .def_property_readonly("position", &Result::position, ":return: position of the decoded symbol\n" ":rtype: zxing.Position") From ce08cb337be8322740714683d8ac4e0299c7a0a3 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 13:33:19 +0200 Subject: [PATCH 0290/1315] Code128: properly report contentType GS1 --- core/src/Content.cpp | 4 +++- core/src/Content.h | 2 +- core/src/Result.cpp | 4 ++-- core/src/Result.h | 4 ++-- core/src/oned/ODCode128Reader.cpp | 9 ++++++--- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index c7fe98a619..16f290044d 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -50,7 +50,9 @@ void Content::switchEncoding(ECI eci, bool isECI) Content::Content() {} -Content::Content(ByteArray&& bytes, SymbologyIdentifier si) : bytes(std::move(bytes)), symbology(si) {} +Content::Content(ByteArray&& bytes, SymbologyIdentifier si, std::string ai) + : bytes(std::move(bytes)), applicationIndicator(std::move(ai)), symbology(si) +{} void Content::switchEncoding(CharacterSet cs) { diff --git a/core/src/Content.h b/core/src/Content.h index 022cdc9569..13e5e7c365 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -50,7 +50,7 @@ class Content bool hasECI = false; Content(); - Content(ByteArray&& bytes, SymbologyIdentifier si); + Content(ByteArray&& bytes, SymbologyIdentifier si, std::string ai = {}); void switchEncoding(ECI eci) { switchEncoding(eci, true); } void switchEncoding(CharacterSet cs); diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 9539e273fc..8e3ed62867 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -18,10 +18,10 @@ namespace ZXing { Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, - SymbologyIdentifier si, ByteArray&& rawBytes, const bool readerInit) + SymbologyIdentifier si, ByteArray&& rawBytes, bool readerInit, const std::string& ai) : _format(format), - _content({ByteArray(text)}, si), + _content({ByteArray(text)}, si, ai), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), _numBits(Size(_rawBytes) * 8), diff --git a/core/src/Result.h b/core/src/Result.h index 74dcb5f411..735f2f2d23 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -32,8 +32,8 @@ class Result explicit Result(DecodeStatus status) : _status(status) {} // 1D convenience constructor - Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, - SymbologyIdentifier si, ByteArray&& rawBytes = {}, const bool readerInit = false); + Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, + ByteArray&& rawBytes = {}, bool readerInit = false, const std::string& ai = {}); Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index a9e55b7f5d..be000e4f7b 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -43,6 +43,7 @@ class Raw2TxtDecoder int codeSet = 0; SymbologyIdentifier _symbologyIdentifier = {'C', '0'}; // ISO/IEC 15417:2007 Annex C Table C.1 bool _readerInit = false; + std::string _applicationIndicator; std::string txt; size_t lastTxtSize = 0; @@ -59,6 +60,7 @@ class Raw2TxtDecoder // GS1 General Specifications Section 5.4.6.4 // "Transmitted data ... is prefixed by the symbology identifier ]C1, if used." // Choosing not to use symbology identifier, i.e. to not prefix to data. + _applicationIndicator = "GS1"; } else if ((isCodeSetC && txt.size() == 2 && txt[0] >= '0' && txt[0] <= '9' && txt[1] >= '0' && txt[1] <= '9') || (!isCodeSetC && txt.size() == 1 && ((txt[0] >= 'A' && txt[0] <= 'Z') @@ -66,6 +68,7 @@ class Raw2TxtDecoder // ISO/IEC 15417:2007 Annex B.2 // FNC1 in second position following Code Set C "00-99" or Code Set A/B "A-Za-z" - AIM _symbologyIdentifier.modifier = '2'; + _applicationIndicator = txt; } else { // ISO/IEC 15417:2007 Annex B.3. Otherwise FNC1 is returned as ASCII 29 (GS) @@ -154,7 +157,7 @@ class Raw2TxtDecoder } SymbologyIdentifier symbologyIdentifier() const { return _symbologyIdentifier; } - + std::string applicationIndicator() const { return _applicationIndicator; } bool readerInit() const { return _readerInit; } }; @@ -268,13 +271,13 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu int checksum = rawCodes.front(); for (int i = 1; i < Size(rawCodes) - 1; ++i) checksum += i * rawCodes[i]; - // the second last code is the checksum (last one is the stop code): + // the last code is the checksum: if (checksum % 103 != rawCodes.back()) return Result(DecodeStatus::ChecksumError); int xStop = next.pixelsTillEnd(); return Result(raw2txt.text(), rowNumber, xStart, xStop, BarcodeFormat::Code128, raw2txt.symbologyIdentifier(), - std::move(rawCodes), raw2txt.readerInit()); + std::move(rawCodes), raw2txt.readerInit(), raw2txt.applicationIndicator()); } } // namespace ZXing::OneD From 3df848f1a788a429a2e9f21ef00ea965ca3e8726 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 13:34:16 +0200 Subject: [PATCH 0291/1315] Result: report (empty) NotFound results as ContentType::Text --- core/src/Content.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 16f290044d..280c3e41ee 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -191,6 +191,9 @@ CharacterSet Content::guessEncoding() const ContentType Content::type() const { + if (empty()) + return ContentType::Text; + if (!canProcess()) return ContentType::UnknownECI; From 02b6999ee28f6b48b4a025a1a947e26da41b52b7 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 13:35:22 +0200 Subject: [PATCH 0292/1315] test: add a few checks for contentType to black box tests --- test/blackbox/BlackboxTestRunner.cpp | 2 ++ test/samples/code128-1/1.result.txt | 1 + test/samples/datamatrix-1/eci-mixed.result.txt | 2 ++ test/samples/datamatrix-1/gs1-figure-4.15.1-2-32x32.result.txt | 1 + test/samples/datamatrix-3/dm-c.result.txt | 1 + 5 files changed, 7 insertions(+) create mode 100644 test/samples/datamatrix-1/eci-mixed.result.txt create mode 100644 test/samples/datamatrix-3/dm-c.result.txt diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index e28f3a1e02..7f9a1d7ab9 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -63,6 +63,8 @@ namespace { // Helper for `compareResult()` - map `key` to Result property, converting value to std::string static std::string getResultValue(const Result& result, const std::string& key) { + if (key == "contentType") + return ToString(result.contentType()); if (key == "ecLevel") return result.ecLevel(); if (key == "orientation") diff --git a/test/samples/code128-1/1.result.txt b/test/samples/code128-1/1.result.txt index 90af6c5d09..ec5103cdec 100644 --- a/test/samples/code128-1/1.result.txt +++ b/test/samples/code128-1/1.result.txt @@ -1 +1,2 @@ symbologyIdentifier=]C1 +contentType=GS1 diff --git a/test/samples/datamatrix-1/eci-mixed.result.txt b/test/samples/datamatrix-1/eci-mixed.result.txt new file mode 100644 index 0000000000..352fff3edf --- /dev/null +++ b/test/samples/datamatrix-1/eci-mixed.result.txt @@ -0,0 +1,2 @@ +symbologyIdentifier=]d1 +contentType=UnknownECI diff --git a/test/samples/datamatrix-1/gs1-figure-4.15.1-2-32x32.result.txt b/test/samples/datamatrix-1/gs1-figure-4.15.1-2-32x32.result.txt index c31c096dbb..1edb45e39f 100644 --- a/test/samples/datamatrix-1/gs1-figure-4.15.1-2-32x32.result.txt +++ b/test/samples/datamatrix-1/gs1-figure-4.15.1-2-32x32.result.txt @@ -1 +1,2 @@ symbologyIdentifier=]d2 +contentType=GS1 diff --git a/test/samples/datamatrix-3/dm-c.result.txt b/test/samples/datamatrix-3/dm-c.result.txt new file mode 100644 index 0000000000..d0aaba1474 --- /dev/null +++ b/test/samples/datamatrix-3/dm-c.result.txt @@ -0,0 +1 @@ +contentType=Binary From 6527a7cea4f1f8e702abc93021ff7011731dfff9 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 15:47:47 +0200 Subject: [PATCH 0293/1315] example: add contentType support to Qt wrapper --- example/ZXingQtReader.cpp | 1 + example/ZXingQtReader.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/example/ZXingQtReader.cpp b/example/ZXingQtReader.cpp index 2fa90d1a8e..7d35d9553a 100644 --- a/example/ZXingQtReader.cpp +++ b/example/ZXingQtReader.cpp @@ -34,6 +34,7 @@ int main(int argc, char* argv[]) qDebug() << "Text: " << result.text(); qDebug() << "Format: " << result.format(); + qDebug() << "Content:" << result.contentType(); qDebug() << "Error: " << result.status(); return result.isValid() ? 0 : 1; diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 675b2d0205..0756fa661c 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -57,6 +57,8 @@ enum class BarcodeFormat TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, }; +enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; + enum class DecodeStatus { NoError = 0, @@ -66,6 +68,7 @@ enum class DecodeStatus }; #else using ZXing::BarcodeFormat; +using ZXing::ContentType; using ZXing::DecodeStatus; #endif @@ -74,6 +77,7 @@ using ZXing::Binarizer; using ZXing::BarcodeFormats; Q_ENUM_NS(BarcodeFormat) +Q_ENUM_NS(ContentType) Q_ENUM_NS(DecodeStatus) template @@ -107,6 +111,7 @@ class Result : private ZXing::Result Q_PROPERTY(QByteArray bytes READ bytes) Q_PROPERTY(bool isValid READ isValid) Q_PROPERTY(DecodeStatus status READ status) + Q_PROPERTY(ContentType contentType READ contentType) Q_PROPERTY(Position position READ position) QString _text; @@ -128,6 +133,7 @@ class Result : private ZXing::Result BarcodeFormat format() const { return static_cast(ZXing::Result::format()); } DecodeStatus status() const { return static_cast(ZXing::Result::status()); } + ContentType contentType() const { return static_cast(ZXing::Result::contentType()); } QString formatName() const { return QString::fromStdString(ZXing::ToString(ZXing::Result::format())); } const QString& text() const { return _text; } const QByteArray& bytes() const { return _bytes; } From dee1d41f3ec899751fc46c7fbea5c36419ed6462 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 16:57:33 +0200 Subject: [PATCH 0294/1315] example: add basic multi-symbol support to Qt wrapper --- example/ZXingQtReader.cpp | 19 +++++++++++-------- example/ZXingQtReader.h | 40 ++++++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/example/ZXingQtReader.cpp b/example/ZXingQtReader.cpp index 7d35d9553a..c07544b08f 100644 --- a/example/ZXingQtReader.cpp +++ b/example/ZXingQtReader.cpp @@ -26,16 +26,19 @@ int main(int argc, char* argv[]) } auto hints = DecodeHints() - .setFormats(BarcodeFormat::QRCode) + .setFormats(BarcodeFormat::Any) .setTryRotate(false) - .setBinarizer(Binarizer::FixedThreshold); + .setMaxNumberOfSymbols(10); - auto result = ReadBarcode(fileImage, hints); + auto results = ReadBarcodes(fileImage, hints); - qDebug() << "Text: " << result.text(); - qDebug() << "Format: " << result.format(); - qDebug() << "Content:" << result.contentType(); - qDebug() << "Error: " << result.status(); + for (auto& result : results) { + qDebug() << "Text: " << result.text(); + qDebug() << "Format: " << result.format(); + qDebug() << "Content:" << result.contentType(); + qDebug() << "Error: " << result.status(); + qDebug() << ""; + } - return result.isValid() ? 0 : 1; + return results.isEmpty() ? 1 : 0; } diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 0756fa661c..d97d634d9a 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef QT_MULTIMEDIA_LIB #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) @@ -144,7 +145,15 @@ class Result : private ZXing::Result Q_PROPERTY(int runTime MEMBER runTime) }; -inline Result ReadBarcode(const QImage& img, const DecodeHints& hints = {}) +inline QList QListResults(ZXing::Results&& zxres) +{ + QList res; + for (auto&& r : zxres) + res.push_back(Result(std::move(r))); + return res; +} + +inline QList ReadBarcodes(const QImage& img, const DecodeHints& hints = {}) { using namespace ZXing; @@ -166,15 +175,21 @@ inline Result ReadBarcode(const QImage& img, const DecodeHints& hints = {}) }; auto exec = [&](const QImage& img) { - return Result(ZXing::ReadBarcode( + return QListResults(ZXing::ReadBarcodes( {img.bits(), img.width(), img.height(), ImgFmtFromQImg(img), static_cast(img.bytesPerLine())}, hints)); }; return ImgFmtFromQImg(img) == ImageFormat::None ? exec(img.convertToFormat(QImage::Format_Grayscale8)) : exec(img); } +inline Result ReadBarcode(const QImage& img, const DecodeHints& hints = {}) +{ + auto res = ReadBarcodes(img, DecodeHints(hints).setMaxNumberOfSymbols(1)); + return !res.isEmpty() ? res.takeFirst() : Result(); +} + #ifdef QT_MULTIMEDIA_LIB -inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = {}) +inline QList ReadBarcodes(const QVideoFrame& frame, const DecodeHints& hints = {}) { using namespace ZXing; @@ -187,7 +202,7 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { qWarning() << "invalid QVideoFrame: could not map memory"; return {}; } - //TODO c++17: SCOPE_EXIT([&] { img.unmap(); }); + auto unmap = qScopeGuard([&] { img.unmap(); }); ImageFormat fmt = ImageFormat::None; int pixStride = 0; @@ -269,22 +284,25 @@ inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = { default: break; } - Result res; if (fmt != ImageFormat::None) { - res = Result(ZXing::ReadBarcode( + return QListResults(ZXing::ReadBarcodes( {img.bits(FIRST_PLANE) + pixOffset, img.width(), img.height(), fmt, img.bytesPerLine(FIRST_PLANE), pixStride}, hints)); } else { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (QVideoFrame::imageFormatFromPixelFormat(img.pixelFormat()) != QImage::Format_Invalid) - res = ReadBarcode(img.image(), hints); + return ReadBarcodes(img.image(), hints); + qWarning() << "unsupported QVideoFrame::pixelFormat"; + return {}; #else - res = ReadBarcode(img.toImage(), hints); + return ReadBarcodes(img.toImage(), hints); #endif } +} - img.unmap(); - - return res; +inline Result ReadBarcode(const QVideoFrame& frame, const DecodeHints& hints = {}) +{ + auto res = ReadBarcodes(frame, DecodeHints(hints).setMaxNumberOfSymbols(1)); + return !res.isEmpty() ? res.takeFirst() : Result(); } #define ZQ_PROPERTY(Type, name, setter) \ From f70f64ca2eee582c5688945ed852a49837b33c48 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 18:18:20 +0200 Subject: [PATCH 0295/1315] example: update "TextECI" -> "Utf8ECI" in console output --- example/ZXingReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index db7ac9239f..32cd7c7674 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -194,7 +194,7 @@ int main(int argc, char* argv[]) firstFile = false; } std::cout << "Text: \"" << (angleEscape ? escapeNonGraphical(result.text()) : result.text()) << "\"\n" - << "TextECI: \"" << result.utf8ECI() << "\"\n" + << "Utf8ECI: \"" << result.utf8ECI() << "\"\n" << "Bytes: " << ToHex(result.bytes()) << "\n" << "BytesECI: " << ToHex(result.bytesECI()) << "\n" << "Format: " << ToString(result.format()) << "\n" From 74bbc150ff81c73c086c5199bbc0c0eb14537795 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 21 Jun 2022 23:27:10 +0200 Subject: [PATCH 0296/1315] DecoderResult: remove unused error correction related properties --- core/src/DecoderResult.h | 4 ---- core/src/pdf417/PDFScanningDecoder.cpp | 7 +------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 9908d1121c..0071bfae27 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -27,8 +27,6 @@ class DecoderResult Content _content; int _numBits = 0; std::string _ecLevel; - int _errorsCorrected = -1; - int _erasures = -1; int _lineCount = 0; StructuredAppendInfo _structuredAppend; bool _isMirrored = false; @@ -78,8 +76,6 @@ class DecoderResult ZX_PROPERTY(int, numBits, setNumBits) ZX_PROPERTY(std::string, ecLevel, setEcLevel) - ZX_PROPERTY(int, errorsCorrected, setErrorsCorrected) - ZX_PROPERTY(int, erasures, setErasures) ZX_PROPERTY(int, lineCount, setLineCount) ZX_PROPERTY(StructuredAppendInfo, structuredAppend, setStructuredAppend) ZX_PROPERTY(bool, isMirrored, setIsMirrored) diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index 4d4217f31a..5191dffd5e 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -585,12 +585,7 @@ DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const st return DecodeStatus::FormatError; // Decode the codewords - auto result = DecodedBitStreamParser::Decode(codewords, ecLevel, characterSet); - if (result.isValid()) { - result.setErrorsCorrected(correctedErrorsCount); - result.setErasures(Size(erasures)); - } - return result; + return DecodedBitStreamParser::Decode(codewords, ecLevel, characterSet); } From 1db3ff0a7604f9715a9260d8b18d93d950a5d7b7 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 22 Jun 2022 20:47:01 +0200 Subject: [PATCH 0297/1315] documentation: randomly remove/fix outdated/unhelpful/verbose comments --- core/src/BarcodeFormat.h | 2 +- core/src/BitArray.h | 1 - core/src/BitSource.h | 4 +-- core/src/GenericGFPoly.h | 3 -- core/src/Reader.h | 28 ------------------- core/src/WhiteRectDetector.cpp | 14 ---------- core/src/WhiteRectDetector.h | 2 +- core/src/aztec/AZDecoder.cpp | 5 +--- core/src/aztec/AZDecoder.h | 3 -- core/src/aztec/AZDetector.cpp | 4 +-- core/src/aztec/AZDetector.h | 2 -- core/src/aztec/AZReader.h | 5 ---- core/src/datamatrix/DMDecoder.cpp | 2 +- core/src/datamatrix/DMDecoder.h | 10 ------- core/src/datamatrix/DMDetector.h | 3 -- core/src/datamatrix/DMReader.cpp | 11 +------- core/src/datamatrix/DMReader.h | 5 ---- core/src/maxicode/MCDecoder.h | 6 ---- core/src/oned/ODCodabarReader.h | 6 ---- core/src/oned/ODCode128Reader.h | 5 ---- core/src/oned/ODCode39Reader.h | 11 -------- core/src/oned/ODCode93Reader.h | 6 ---- core/src/oned/ODITFReader.h | 4 +-- core/src/oned/ODMultiUPCEANReader.h | 6 +--- core/src/oned/ODReader.h | 4 --- .../oned/rss/ODRSSExpandedBinaryDecoder.cpp | 1 - core/src/pdf417/PDFDetector.cpp | 3 -- core/src/pdf417/PDFScanningDecoder.cpp | 5 ++-- core/src/qrcode/QRCodecMode.h | 2 +- core/src/qrcode/QRDecoder.cpp | 2 +- core/src/qrcode/QRDecoder.h | 3 -- core/src/qrcode/QRReader.h | 5 ---- 32 files changed, 14 insertions(+), 159 deletions(-) diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index 2d82784525..186e52eee6 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -80,7 +80,7 @@ BarcodeFormat BarcodeFormatFromString(const std::string& str); * Separators can be (any combination of) '|', ',' or ' '. * Underscores are optional and input can be lower case. * e.g. "EAN-8 qrcode, Itf" would be parsed into [EAN8, QRCode, ITF]. - * @throws std::invalid_parameter Throws if the string can not be fully parsed. + * @throws std::invalid_parameter if the string can not be fully parsed. */ BarcodeFormats BarcodeFormatsFromString(const std::string& str); diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 91d60a8b5e..355c76eea3 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -257,7 +257,6 @@ class BitArray * @param end end of range, exclusive * @param value if true, checks that bits in range are set, otherwise checks that they are not set * @return true iff all bits are set or not set in range, according to value argument - * @throws IllegalArgumentException if end is less than or equal to start */ #ifdef ZX_FAST_BIT_STORAGE bool isRange(int start, int end, bool value) const diff --git a/core/src/BitSource.h b/core/src/BitSource.h index 1db7c9eeb8..9e9bbe977f 100644 --- a/core/src/BitSource.h +++ b/core/src/BitSource.h @@ -52,9 +52,7 @@ class BitSource /** * @param numBits number of bits to read - * @return int representing the bits read. The bits will appear as the least-significant - * bits of the int - * @throws IllegalArgumentException if numBits isn't in [1,32] or more than is available + * @return int representing the bits read. The bits will appear as the least-significant bits of the int */ int readBits(int numBits); diff --git a/core/src/GenericGFPoly.h b/core/src/GenericGFPoly.h index 7aa56b927d..11b03a70d6 100644 --- a/core/src/GenericGFPoly.h +++ b/core/src/GenericGFPoly.h @@ -59,9 +59,6 @@ class GenericGFPoly * to perform computations * @param coefficients coefficients as ints representing elements of GF(size), arranged * from most significant (highest-power term) coefficient to least significant - * @throws IllegalArgumentException if argument is null or empty, - * or if leading coefficient is 0 and this is not a - * constant polynomial (that is, it is not the monomial "0"). */ GenericGFPoly(const GenericGF& field, std::vector&& coefficients) : _field(&field) { diff --git a/core/src/Reader.h b/core/src/Reader.h index 99ea56d3ff..4e8a2721d8 100644 --- a/core/src/Reader.h +++ b/core/src/Reader.h @@ -12,39 +12,11 @@ namespace ZXing { class BinaryBitmap; -/** -* Implementations of this interface can decode an image of a barcode in some format into -* the string it encodes. For example, {@link com.google.zxing.qrcode.QRCodeReader} can -* decode a QR code. The decoder may optionally receive hints from the caller which may help -* it decode more quickly or accurately. -* -* See {@link MultiFormatReader}, which attempts to determine what barcode -* format is present within the image as well, and then decodes it accordingly. -* -* All readers are thread-safe with no temporary state left behind after decode(). -* -* @author Sean Owen -* @author dswitkin@google.com (Daniel Switkin) -*/ class Reader { public: virtual ~Reader() = default; - /** - * Locates and decodes a barcode in some format within an image. This method also accepts - * hints, each possibly associated to some data, which may help the implementation decode. - * - * @param image image of barcode to decode - * @param hints passed as a {@link java.util.Map} from {@link DecodeHintType} - * to arbitrary data. The - * meaning of the data depends upon the hint type. The implementation may or may not do - * anything with these hints. - * @return string which the barcode encodes - * @throws NotFoundException if no potential barcode is found - * @throws ChecksumException if a potential barcode is found but does not pass its checksum - * @throws FormatException if a potential barcode is found but format is invalid - */ virtual Result decode(const BinaryBitmap& image) const = 0; // WARNING: this API is experimental and may change/disappear diff --git a/core/src/WhiteRectDetector.cpp b/core/src/WhiteRectDetector.cpp index 5148e9cfdd..87cfca924e 100644 --- a/core/src/WhiteRectDetector.cpp +++ b/core/src/WhiteRectDetector.cpp @@ -118,20 +118,6 @@ static void CenterEdges(const ResultPoint& y, const ResultPoint& z, const Result } } -/** -*

-* Detects a candidate barcode-like rectangular region within an image. It -* starts around the center of the image, increases the size of the candidate -* region until it finds a white rectangular region. -*

-* -* @return {@link ResultPoint}[] describing the corners of the rectangular -* region. The first and last points are opposed on the diagonal, as -* are the second and third. The first point will be the topmost -* point and the last, the bottommost. The second point will be -* leftmost and the third, the rightmost -* @throws NotFoundException if no Data Matrix Code can be found -*/ bool DetectWhiteRect(const BitMatrix& image, int initSize, int x, int y, ResultPoint& p0, ResultPoint& p1, ResultPoint& p2, ResultPoint& p3) { diff --git a/core/src/WhiteRectDetector.h b/core/src/WhiteRectDetector.h index 834d5a6db6..db4d11f0c5 100644 --- a/core/src/WhiteRectDetector.h +++ b/core/src/WhiteRectDetector.h @@ -27,7 +27,7 @@ class ResultPoint; * are the second and third. The first point will be the topmost * point and the last, the bottommost. The second point will be * leftmost and the third, the rightmost - * @throws NotFoundException if no Data Matrix Code can be found + * @return true iff white rect was found */ bool DetectWhiteRect(const BitMatrix& image, int initSize, int x, int y, ResultPoint& p0, ResultPoint& p1, ResultPoint& p2, ResultPoint& p3); diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 86b802c532..d322157139 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -117,10 +117,7 @@ static BitArray ExtractBits(const DetectorResult& ddata) } /** -*

Performs RS error correction on an array of bits.

-* -* @return the corrected array -* @throws FormatException if the input contains too many errors +* @brief Performs RS error correction on an array of bits. */ static BitArray CorrectBits(const DetectorResult& ddata, const BitArray& rawbits) { diff --git a/core/src/aztec/AZDecoder.h b/core/src/aztec/AZDecoder.h index 9db9f80a3e..81b8ca0d9b 100644 --- a/core/src/aztec/AZDecoder.h +++ b/core/src/aztec/AZDecoder.h @@ -16,9 +16,6 @@ namespace Aztec { class DetectorResult; -/** - * @brief Decode Aztec Code after locating and extracting from an image. - */ DecoderResult Decode(const DetectorResult& detectorResult, const std::string& characterSet = ""); } // Aztec diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index edfcff0295..453509b29c 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -143,7 +143,7 @@ static bool GetCorrectedParameterData(int64_t parameterData, bool compact, int& * Extracts the number of data layers and data blocks from the layer around the bull's eye. * * @param bullsEyeCorners the array of bull's eye corners -* @throws NotFoundException in case of too many errors or invalid parameters +* @return false in case of too many errors or invalid parameters */ static bool ExtractParameters(const BitMatrix& image, const std::array& bullsEyeCorners, bool compact, int nbCenterLayers, int& nbLayers, int& nbDataBlocks, bool& readerInit, int& shift) @@ -354,7 +354,7 @@ static void ExpandSquare(std::array& cornerPoints, float oldSide * * @param pCenter Center point * @return The corners of the bull-eye -* @throws NotFoundException If no valid bull-eye can be found +* @return false If no valid bull-eye can be found */ static bool GetBullsEyeCorners(const BitMatrix& image, const PointI& pCenter, std::array& result, bool& compact, int& nbCenterLayers) { diff --git a/core/src/aztec/AZDetector.h b/core/src/aztec/AZDetector.h index 08a1edda7e..25927e2f3f 100644 --- a/core/src/aztec/AZDetector.h +++ b/core/src/aztec/AZDetector.h @@ -18,8 +18,6 @@ class DetectorResult; * Detects an Aztec Code in an image. * * @param isMirror if true, image is a mirror-image of original - * @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code - * @throws NotFoundException if no Aztec Code can be found */ DetectorResult Detect(const BitMatrix& image, bool isMirror, bool isPure); diff --git a/core/src/aztec/AZReader.h b/core/src/aztec/AZReader.h index 6997b57ad5..3d3b1cb392 100644 --- a/core/src/aztec/AZReader.h +++ b/core/src/aztec/AZReader.h @@ -16,11 +16,6 @@ class DecodeHints; namespace Aztec { -/** -* This implementation can detect and decode Aztec codes in an image. -* -* @author David Olivier -*/ class Reader : public ZXing::Reader { public: diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 1b1f5a785d..6f2748323d 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -373,7 +373,7 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b * * @param codewordBytes data and error correction codewords * @param numDataCodewords number of codewords that are data bytes -* @throws ChecksumException if error correction fails +* @return false if error correction fails */ static bool CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) diff --git a/core/src/datamatrix/DMDecoder.h b/core/src/datamatrix/DMDecoder.h index b91fa0b47e..165b97a642 100644 --- a/core/src/datamatrix/DMDecoder.h +++ b/core/src/datamatrix/DMDecoder.h @@ -15,16 +15,6 @@ class BitMatrix; namespace DataMatrix { -/** - * @brief Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken - * to mean a black module. - * - * @param bits booleans representing white/black Data Matrix Code modules - * @param characterSet initial character encoding to use as a {@link CharacterSetECI} name string - * @return text and bytes encoded within the Data Matrix Code - * @throws FormatException if the Data Matrix Code cannot be decoded - * @throws ChecksumException if error correction fails - */ DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet = ""); } // DataMatrix diff --git a/core/src/datamatrix/DMDetector.h b/core/src/datamatrix/DMDetector.h index e632b08681..4ec5d7e135 100644 --- a/core/src/datamatrix/DMDetector.h +++ b/core/src/datamatrix/DMDetector.h @@ -13,9 +13,6 @@ class DetectorResult; namespace DataMatrix { -/** - * @brief Detects a Data Matrix symbol in an image. - */ DetectorResult Detect(const BitMatrix& image, bool tryHarder, bool tryRotate, bool isPure); } // DataMatrix diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index a2ac999a84..988cd71d6a 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -25,16 +25,7 @@ Reader::Reader(const DecodeHints& hints) _characterSet(hints.characterSet()) {} -/** -* Locates and decodes a Data Matrix code in an image. -* -* @return a string representing the content encoded by the Data Matrix code -* @throws NotFoundException if a Data Matrix code cannot be found -* @throws FormatException if a Data Matrix code cannot be decoded -* @throws ChecksumException if error correction fails -*/ -Result -Reader::decode(const BinaryBitmap& image) const +Result Reader::decode(const BinaryBitmap& image) const { auto binImg = image.getBitMatrix(); if (binImg == nullptr) diff --git a/core/src/datamatrix/DMReader.h b/core/src/datamatrix/DMReader.h index 571a9c0e46..54fdb74b48 100644 --- a/core/src/datamatrix/DMReader.h +++ b/core/src/datamatrix/DMReader.h @@ -15,11 +15,6 @@ class DecodeHints; namespace DataMatrix { -/** -* This implementation can detect and decode Data Matrix codes in an image. -* -* @author bbrown@google.com (Brian Brown) -*/ class Reader : public ZXing::Reader { bool _tryRotate, _tryHarder, _isPure; diff --git a/core/src/maxicode/MCDecoder.h b/core/src/maxicode/MCDecoder.h index 7a112c64ac..d7098cd9e3 100644 --- a/core/src/maxicode/MCDecoder.h +++ b/core/src/maxicode/MCDecoder.h @@ -15,12 +15,6 @@ class BitMatrix; namespace MaxiCode { -/** -*

The main class which implements MaxiCode decoding -- as opposed to locating and extracting -* the MaxiCode from an image.

-* -* @author Manuel Kasten -*/ class Decoder { public: diff --git a/core/src/oned/ODCodabarReader.h b/core/src/oned/ODCodabarReader.h index 52e9c7a8f8..82c539f1ff 100644 --- a/core/src/oned/ODCodabarReader.h +++ b/core/src/oned/ODCodabarReader.h @@ -14,12 +14,6 @@ class DecodeHints; namespace OneD { -/** -*

Decodes Codabar barcodes.

-* -* @author Bas Vijfwinkel -* @author David Walker -*/ class CodabarReader : public RowReader { public: diff --git a/core/src/oned/ODCode128Reader.h b/core/src/oned/ODCode128Reader.h index 1a2a8db4d1..e555afa93e 100644 --- a/core/src/oned/ODCode128Reader.h +++ b/core/src/oned/ODCode128Reader.h @@ -14,11 +14,6 @@ class DecodeHints; namespace OneD { -/** -*

Decodes Code 128 barcodes.

-* -* @author Sean Owen -*/ class Code128Reader : public RowReader { public: diff --git a/core/src/oned/ODCode39Reader.h b/core/src/oned/ODCode39Reader.h index 58b4de493a..4bda353dc0 100644 --- a/core/src/oned/ODCode39Reader.h +++ b/core/src/oned/ODCode39Reader.h @@ -14,12 +14,6 @@ class DecodeHints; namespace OneD { -/** -*

Decodes Code 39 barcodes. Supports "Full ASCII Code 39" if extendedMode is true.

-* -* @author Sean Owen -* @see Code93Reader -*/ class Code39Reader : public RowReader { public: @@ -27,11 +21,6 @@ class Code39Reader : public RowReader * Creates a reader that can be configured to check the last character as a check digit, * or optionally attempt to decode "extended Code 39" sequences that are used to encode * the full ASCII character set. - * - * @param usingCheckDigit if true, treat the last data character as a check digit, not - * data, and verify that the checksum passes. - * @param extendedMode if true, will attempt to decode extended Code 39 sequences in the - * text. */ explicit Code39Reader(const DecodeHints& hints); diff --git a/core/src/oned/ODCode93Reader.h b/core/src/oned/ODCode93Reader.h index 86ea8ac593..c0733533e3 100644 --- a/core/src/oned/ODCode93Reader.h +++ b/core/src/oned/ODCode93Reader.h @@ -11,12 +11,6 @@ namespace ZXing { namespace OneD { -/** -*

Decodes Code 93 barcodes.

-* -* @author Sean Owen -* @see Code39Reader -*/ class Code93Reader : public RowReader { public: diff --git a/core/src/oned/ODITFReader.h b/core/src/oned/ODITFReader.h index 7f494d76bf..0277c52a7d 100644 --- a/core/src/oned/ODITFReader.h +++ b/core/src/oned/ODITFReader.h @@ -24,12 +24,10 @@ namespace OneD { * lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of * required checksum function.

* -*

The checksum is optional and is only applied by this Reader if the assumeITFCheckDigit hint is given.

+*

The checksum is optional and is only applied by this Reader if the validateITFCheckSum hint is given.

* *
-* -* @author kevin.osullivan@sita.aero, SITA Lab. */ class ITFReader : public RowReader { diff --git a/core/src/oned/ODMultiUPCEANReader.h b/core/src/oned/ODMultiUPCEANReader.h index 999c542290..e4537ca287 100644 --- a/core/src/oned/ODMultiUPCEANReader.h +++ b/core/src/oned/ODMultiUPCEANReader.h @@ -14,11 +14,7 @@ namespace ZXing { namespace OneD { /** -*

A reader that can read all available UPC/EAN formats. If a caller wants to try to -* read all such formats, it is most efficient to use this implementation rather than invoke -* individual readers.

-* -* @author Sean Owen +* @brief A reader that can read all available UPC/EAN formats. */ class MultiUPCEANReader : public RowReader { diff --git a/core/src/oned/ODReader.h b/core/src/oned/ODReader.h index bccd417c2e..c2f5336a2e 100644 --- a/core/src/oned/ODReader.h +++ b/core/src/oned/ODReader.h @@ -19,10 +19,6 @@ namespace OneD { class RowReader; -/** -* @author dswitkin@google.com (Daniel Switkin) -* @author Sean Owen -*/ class Reader : public ZXing::Reader { public: diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp index 444ecf4982..1ebe6237f9 100644 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp +++ b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp @@ -314,7 +314,6 @@ std::string DecodeExpandedBits(const BitArray& bits) } return {}; - //throw new IllegalStateException("unknown decoder: " + information); } } // namespace ZXing::OneD::DataBar diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 3d29fc59fb..72bf872cff 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -329,11 +329,8 @@ bool HasStartPattern(const BitMatrix& m) *

Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.

* * @param image barcode image to decode -* @param hints optional hints to detector * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will * be found and returned -* @return {@link PDF417DetectorResult} encapsulating results of detecting a PDF417 code -* @throws NotFoundException if no PDF417 Code can be found */ DecodeStatus Detector::Detect(const BinaryBitmap& image, bool multiple, Result& result) diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index 5191dffd5e..b36d55a1b5 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -458,8 +458,7 @@ static std::vector FindErrorMagnitudes(const ModulusPoly& errorEvaluator, c * @param received received codewords * @param numECCodewords number of those codewords used for EC * @param erasures location of erasures -* @return number of errors -* @throws ChecksumException if errors cannot be corrected, maybe because of too many errors +* @return false if errors cannot be corrected, maybe because of too many errors */ ZXING_EXPORT_TEST_ONLY bool DecodeErrorCorrection(std::vector& received, int numECCodewords, const std::vector& erasures, int& nbErrors) @@ -527,7 +526,7 @@ bool DecodeErrorCorrection(std::vector& received, int numECCodewords, const * @param codewords data and error correction codewords * @param erasures positions of any known erasures * @param numECCodewords number of error correction codewords that are available in codewords -* @throws ChecksumException if error correction fails +* @return false if error correction fails */ static bool CorrectErrors(std::vector& codewords, const std::vector& erasures, int numECCodewords, int& errorCount) { diff --git a/core/src/qrcode/QRCodecMode.h b/core/src/qrcode/QRCodecMode.h index f55bc677f6..830b2f897a 100644 --- a/core/src/qrcode/QRCodecMode.h +++ b/core/src/qrcode/QRCodecMode.h @@ -33,7 +33,7 @@ enum class CodecMode * @param bits variable number of bits encoding a QR Code data mode * @param isMicro is this a MicroQRCode * @return Mode encoded by these bits - * @throws IllegalArgumentException if bits do not correspond to a known mode + * @throws std::invalid_argument if bits do not correspond to a known mode */ CodecMode CodecModeForBits(int bits, bool isMirco = false); diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index f454b012fc..994f044bb4 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -36,7 +36,7 @@ namespace ZXing::QRCode { * * @param codewordBytes data and error correction codewords * @param numDataCodewords number of codewords that are data bytes -* @throws ChecksumException if error correction fails +* @return false if error correction fails */ static bool CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) { diff --git a/core/src/qrcode/QRDecoder.h b/core/src/qrcode/QRDecoder.h index 32194d8899..e4ab05d5c7 100644 --- a/core/src/qrcode/QRDecoder.h +++ b/core/src/qrcode/QRDecoder.h @@ -15,9 +15,6 @@ class BitMatrix; namespace QRCode { -/** - * @brief Decodes a QR Code from the BitMatrix and the hinted charset. - */ DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset = {}); } // QRCode diff --git a/core/src/qrcode/QRReader.h b/core/src/qrcode/QRReader.h index d7e96f935f..f8fe736a2f 100644 --- a/core/src/qrcode/QRReader.h +++ b/core/src/qrcode/QRReader.h @@ -16,11 +16,6 @@ class DecodeHints; namespace QRCode { -/** -* This implementation can detect and decode QR Codes in an image. -* -* @author Sean Owen -*/ class Reader : public ZXing::Reader { public: From 77aa450a8edb253f3b32bb2b28e60b4bb125e2f9 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 22 Jun 2022 22:28:25 +0200 Subject: [PATCH 0298/1315] MCDecoder: make Decoder::Decode a simple function --- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/maxicode/MCDecoder.h | 6 +----- core/src/maxicode/MCReader.cpp | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index e3a781f2bb..90f6bee8db 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -300,7 +300,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& /*cha } // DecodedBitStreamParser -DecoderResult Decoder::Decode(const BitMatrix& bits, const std::string& characterSet) +DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet) { ByteArray codewords = BitMatrixParser::ReadCodewords(bits); diff --git a/core/src/maxicode/MCDecoder.h b/core/src/maxicode/MCDecoder.h index d7098cd9e3..1ed0c80eb8 100644 --- a/core/src/maxicode/MCDecoder.h +++ b/core/src/maxicode/MCDecoder.h @@ -15,11 +15,7 @@ class BitMatrix; namespace MaxiCode { -class Decoder -{ -public: - static DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet); -}; +DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet); } // MaxiCode } // ZXing diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index dd6f7cc0f3..9131b1200f 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -59,7 +59,7 @@ Reader::decode(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); } - return Result(Decoder::Decode(bits, _characterSet), {}, BarcodeFormat::MaxiCode); + return Result(Decode(bits, _characterSet), {}, BarcodeFormat::MaxiCode); } } // namespace ZXing::MaxiCode From aee37e7486ac5c2bc448bb5ff528376296e79718 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 23 Jun 2022 13:14:02 +0200 Subject: [PATCH 0299/1315] Errors: harmonize internal error reporting in QR and DM decoders --- core/src/datamatrix/DMDecoder.cpp | 8 ++++---- core/src/qrcode/QRDecoder.cpp | 20 ++++++++------------ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 6f2748323d..38a2f1aa0c 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -293,7 +293,7 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b while (!done && bits.available() >= 8) { int oneByte = bits.readBits(8); switch (oneByte) { - case 0: return DecodeStatus::FormatError; + case 0: throw std::runtime_error("invalid 0 code word"); case 129: done = true; break; // Pad -> we are done, ignore the rest of the bits case 230: DecodeC40OrTextSegment(bits, result, Mode::C40); break; case 231: DecodeBase256Segment(bits, result); break; @@ -310,13 +310,13 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b break; case 233: // Structured Append if (!firstCodeword) // Must be first ISO 16022:2006 5.6.1 - return DecodeStatus::FormatError; + throw std::runtime_error("structured append tag must be first code word"); ParseStructuredAppend(bits, sai); firstFNC1Position = 5; break; case 234: // Reader Programming if (!firstCodeword) // Must be first ISO 16022:2006 5.2.4.9 - return DecodeStatus::FormatError; + throw std::runtime_error("reader programming tag must be first code word"); readerInit = true; break; case 235: upperShift.set = true; break; // Upper Shift (shift to Extended ASCII) @@ -344,7 +344,7 @@ DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const b // work around encoders that use unlatch to ASCII as last code word (ask upstream) if (oneByte == 254 && bits.available() == 0) break; - return DecodeStatus::FormatError; + throw std::runtime_error("invalid code word"); } } firstCodeword = false; diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 994f044bb4..f56876e1f7 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -309,7 +309,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo // First handle Hanzi mode which does not start with character count // chinese mode contains a sub set indicator right after mode indicator if (int subset = bits.readBits(4); subset != 1) // GB2312_SUBSET is the only supported one right now - return DecodeStatus::FormatError; + throw std::runtime_error("Unsupported HANZI subset"); int count = bits.readBits(CharacterCountBits(mode, version)); DecodeHanziSegment(bits, count, result); break; @@ -323,7 +323,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo case CodecMode::ALPHANUMERIC: DecodeAlphanumericSegment(bits, count, result); break; case CodecMode::BYTE: DecodeByteSegment(bits, count, result); break; case CodecMode::KANJI: DecodeKanjiSegment(bits, count, result); break; - default: return DecodeStatus::FormatError; + default: throw std::runtime_error("Invalid CodecMode"); } break; } @@ -343,8 +343,13 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo .setStructuredAppend(structuredAppend); } -static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, const std::string& hintedCharset) +DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) { + const Version* pversion = ReadVersion(bits); + if (!pversion) + return DecodeStatus::FormatError; + const Version& version = *pversion; + auto formatInfo = ReadFormatInformation(bits, version.isMicroQRCode()); if (!formatInfo.isValid()) return DecodeStatus::FormatError; @@ -381,13 +386,4 @@ static DecoderResult DoDecode(const BitMatrix& bits, const Version& version, con return DecodeBitStream(std::move(resultBytes), version, formatInfo.ecLevel, hintedCharset).setIsMirrored(formatInfo.isMirrored); } -DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) -{ - const Version* version = ReadVersion(bits); - if (!version) - return DecodeStatus::FormatError; - - return DoDecode(bits, *version, hintedCharset); -} - } // namespace ZXing::QRCode From ccbf2bee9380f29b341dfb780c094405cc8d01fc Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 23 Jun 2022 13:52:19 +0200 Subject: [PATCH 0300/1315] ECI: remove the whole charset business from the decoder call tree Don't pass that string down to the inner most decoder functions, just to set the Content::defaultCharset member, which is only evaluated once the result is passed to the user code anyway. --- core/src/Content.cpp | 2 +- core/src/Content.h | 2 +- core/src/ReadBarcode.cpp | 5 +++- core/src/Result.cpp | 7 +++++ core/src/Result.h | 1 + core/src/aztec/AZDecoder.cpp | 7 +++-- core/src/aztec/AZDecoder.h | 2 +- core/src/aztec/AZReader.cpp | 6 ++--- core/src/aztec/AZReader.h | 1 - core/src/datamatrix/DMDecoder.cpp | 13 +++++----- core/src/datamatrix/DMDecoder.h | 2 +- core/src/datamatrix/DMReader.cpp | 5 ++-- core/src/datamatrix/DMReader.h | 2 +- core/src/maxicode/MCDecoder.cpp | 8 +++--- core/src/maxicode/MCDecoder.h | 2 +- core/src/maxicode/MCReader.cpp | 4 +-- core/src/maxicode/MCReader.h | 1 - core/src/pdf417/PDFDecodedBitStreamParser.cpp | 7 +++-- core/src/pdf417/PDFDecodedBitStreamParser.h | 2 +- core/src/pdf417/PDFReader.cpp | 22 +++++++--------- core/src/pdf417/PDFReader.h | 1 - core/src/pdf417/PDFScanningDecoder.cpp | 17 ++++++------ core/src/pdf417/PDFScanningDecoder.h | 2 +- core/src/qrcode/QRDecoder.cpp | 8 +++--- core/src/qrcode/QRDecoder.h | 2 +- core/src/qrcode/QRReader.cpp | 9 +++---- core/src/qrcode/QRReader.h | 1 - test/fuzz/fuzzDMDecoder.cpp | 4 +-- test/unit/aztec/AZDecoderTest.cpp | 2 +- test/unit/aztec/AZHighLevelEncoderTest.cpp | 2 +- .../DMDecodedBitStreamParserTest.cpp | 4 +-- test/unit/maxicode/MCDecoderTest.cpp | 4 +-- test/unit/pdf417/PDF417DecoderTest.cpp | 4 +-- .../qrcode/QRDecodedBitStreamParserTest.cpp | 26 +++++++++---------- 34 files changed, 92 insertions(+), 95 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 280c3e41ee..ae0ac9157b 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -101,7 +101,7 @@ std::wstring Content::render(bool withECI) const if (withECI) res = TextDecoder::FromLatin1(symbology.toString(true)); ECI lastECI = ECI::Unknown; - auto fallbackCS = CharacterSetFromString(hintedCharset); + auto fallbackCS = CharacterSetFromString(defaultCharset); if (!hasECI && fallbackCS == CharacterSet::Unknown) fallbackCS = guessEncoding(); diff --git a/core/src/Content.h b/core/src/Content.h index 13e5e7c365..cce0b541d2 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -44,7 +44,7 @@ class Content ByteArray bytes; std::vector encodings; - std::string hintedCharset; + std::string defaultCharset; std::string applicationIndicator; SymbologyIdentifier symbology; bool hasECI = false; diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 4ffc2e8aab..9f95eb4688 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -127,7 +127,7 @@ Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) LumImage lum; ImageView iv = SetupLumImageView(_iv, lum, hints); - return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)); + return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)).setCharacterSet(hints.characterSet()); } } @@ -159,6 +159,9 @@ Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) break; } + for (auto& res : results) + res.setCharacterSet(hints.characterSet()); + return results; } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 8e3ed62867..4bd0d320f0 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -106,6 +106,13 @@ std::string Result::sequenceId() const return _sai.id; } +Result& Result::setCharacterSet(const std::string& defaultCS) +{ + if (!defaultCS.empty()) + _content.defaultCharset = defaultCS; + return *this; +} + bool Result::operator==(const Result& o) const { if (format() != o.format() || bytes() != o.bytes()) diff --git a/core/src/Result.h b/core/src/Result.h index 735f2f2d23..c76f4abffd 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -147,6 +147,7 @@ class Result // only for internal use void incrementLineCount() { ++_lineCount; } + Result& setCharacterSet(const std::string& defaultCS); bool operator==(const Result& o) const; diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index d322157139..ebb7c6c083 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -299,11 +299,10 @@ static void DecodeContent(const BitArray& bits, Content& res) } ZXING_EXPORT_TEST_ONLY -DecoderResult Decode(const BitArray& bits, const std::string& characterSet) +DecoderResult Decode(const BitArray& bits) { Content res; res.symbology = {'z', '0', 3}; - res.hintedCharset = characterSet; try { DecodeContent(bits, res); @@ -347,14 +346,14 @@ DecoderResult Decode(const BitArray& bits, const std::string& characterSet) return DecoderResult(bits.toBytes(), std::move(res)).setNumBits(Size(bits)).setStructuredAppend(sai); } -DecoderResult Decode(const DetectorResult& detectorResult, const std::string& characterSet) +DecoderResult Decode(const DetectorResult& detectorResult) { BitArray bits = CorrectBits(detectorResult, ExtractBits(detectorResult)); if (!bits.size()) return DecodeStatus::FormatError; - return Decode(bits, characterSet).setReaderInit(detectorResult.readerInit()); + return Decode(bits).setReaderInit(detectorResult.readerInit()); } } // namespace ZXing::Aztec diff --git a/core/src/aztec/AZDecoder.h b/core/src/aztec/AZDecoder.h index 81b8ca0d9b..2054c2fd92 100644 --- a/core/src/aztec/AZDecoder.h +++ b/core/src/aztec/AZDecoder.h @@ -16,7 +16,7 @@ namespace Aztec { class DetectorResult; -DecoderResult Decode(const DetectorResult& detectorResult, const std::string& characterSet = ""); +DecoderResult Decode(const DetectorResult& detectorResult); } // Aztec } // ZXing diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 0f6547ae4d..4ca316c416 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -20,7 +20,7 @@ namespace ZXing::Aztec { Reader::Reader(const DecodeHints& hints) - : _isPure(hints.isPure()), _characterSet(hints.characterSet()) + : _isPure(hints.isPure()) { } @@ -35,14 +35,14 @@ Reader::decode(const BinaryBitmap& image) const DetectorResult detectResult = Detect(*binImg, false, _isPure); DecoderResult decodeResult = DecodeStatus::NotFound; if (detectResult.isValid()) { - decodeResult = Decode(detectResult, _characterSet); + decodeResult = Decode(detectResult); } //TODO: don't start detection all over again, just to swap 2 corner points if (!decodeResult.isValid()) { detectResult = Detect(*binImg, true, _isPure); if (detectResult.isValid()) { - decodeResult = Decode(detectResult, _characterSet); + decodeResult = Decode(detectResult); } } diff --git a/core/src/aztec/AZReader.h b/core/src/aztec/AZReader.h index 3d3b1cb392..df5a837507 100644 --- a/core/src/aztec/AZReader.h +++ b/core/src/aztec/AZReader.h @@ -24,7 +24,6 @@ class Reader : public ZXing::Reader private: bool _isPure; - std::string _characterSet; }; } // Aztec diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 38a2f1aa0c..8284833b17 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -273,12 +273,11 @@ static void DecodeBase256Segment(BitSource& bits, Content& result) } ZXING_EXPORT_TEST_ONLY -DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const bool isDMRE) +DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) { BitSource bits(bytes); Content result; result.symbology = {'d', '1', 3}; // ECC 200 (ISO 16022:2006 Annex N Table N.1) - result.hintedCharset = characterSet; std::string resultTrailer; struct StructuredAppendInfo sai; @@ -392,7 +391,7 @@ CorrectErrors(ByteArray& codewordBytes, int numDataCodewords) return true; } -static DecoderResult DoDecode(const BitMatrix& bits, const std::string& characterSet) +static DecoderResult DoDecode(const BitMatrix& bits) { // Construct a parser and read version, error-correction level const Version* version = VersionForDimensionsOf(bits); @@ -428,7 +427,7 @@ static DecoderResult DoDecode(const BitMatrix& bits, const std::string& characte } // Decode the contents of that stream of bytes - return DecodedBitStreamParser::Decode(std::move(resultBytes), characterSet, version->isDMRE()); + return DecodedBitStreamParser::Decode(std::move(resultBytes), version->isDMRE()); } static BitMatrix FlippedL(const BitMatrix& bits) @@ -440,16 +439,16 @@ static BitMatrix FlippedL(const BitMatrix& bits) return res; } -DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet) +DecoderResult Decode(const BitMatrix& bits) { - auto res = DoDecode(bits, characterSet); + auto res = DoDecode(bits); if (res.isValid()) return res; //TODO: // * unify bit mirroring helper code with QRReader? // * rectangular symbols with the a size of 8 x Y are not supported a.t.m. - if (auto mirroredRes = DoDecode(FlippedL(bits), characterSet); mirroredRes.isValid()) { + if (auto mirroredRes = DoDecode(FlippedL(bits)); mirroredRes.isValid()) { mirroredRes.setIsMirrored(true); return mirroredRes; } diff --git a/core/src/datamatrix/DMDecoder.h b/core/src/datamatrix/DMDecoder.h index 165b97a642..e8aac914f6 100644 --- a/core/src/datamatrix/DMDecoder.h +++ b/core/src/datamatrix/DMDecoder.h @@ -15,7 +15,7 @@ class BitMatrix; namespace DataMatrix { -DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet = ""); +DecoderResult Decode(const BitMatrix& bits); } // DataMatrix } // ZXing diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index 988cd71d6a..fc4c1bdec6 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -21,8 +21,7 @@ namespace ZXing::DataMatrix { Reader::Reader(const DecodeHints& hints) : _tryRotate(hints.tryRotate()), _tryHarder(hints.tryHarder()), - _isPure(hints.isPure()), - _characterSet(hints.characterSet()) + _isPure(hints.isPure()) {} Result Reader::decode(const BinaryBitmap& image) const @@ -35,7 +34,7 @@ Result Reader::decode(const BinaryBitmap& image) const if (!detectorResult.isValid()) return Result(DecodeStatus::NotFound); - return Result(Decode(detectorResult.bits(), _characterSet), std::move(detectorResult).position(), BarcodeFormat::DataMatrix); + return Result(Decode(detectorResult.bits()), std::move(detectorResult).position(), BarcodeFormat::DataMatrix); } } // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMReader.h b/core/src/datamatrix/DMReader.h index 54fdb74b48..a0c728ae41 100644 --- a/core/src/datamatrix/DMReader.h +++ b/core/src/datamatrix/DMReader.h @@ -18,7 +18,7 @@ namespace DataMatrix { class Reader : public ZXing::Reader { bool _tryRotate, _tryHarder, _isPure; - std::string _characterSet; + public: explicit Reader(const DecodeHints& hints); Result decode(const BinaryBitmap& image) const override; diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 90f6bee8db..30a6b87913 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -267,11 +267,11 @@ static void GetMessage(const ByteArray& bytes, int start, int len, Content& resu } ZXING_EXPORT_TEST_ONLY -DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& /*characterSet*/) +DecoderResult Decode(ByteArray&& bytes, const int mode) { Content result; result.symbology = {'U', (mode == 2 || mode == 3) ? '1' : '0', 2}; // TODO: No identifier defined for mode 6? - result.hintedCharset = "ISO8859_1"; + result.defaultCharset = "ISO8859_1"; StructuredAppendInfo sai; switch (mode) { @@ -300,7 +300,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& /*cha } // DecodedBitStreamParser -DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet) +DecoderResult Decode(const BitMatrix& bits) { ByteArray codewords = BitMatrixParser::ReadCodewords(bits); @@ -331,7 +331,7 @@ DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet) std::copy_n(codewords.begin(), 10, datawords.begin()); std::copy_n(codewords.begin() + 20, datawords.size() - 10, datawords.begin() + 10); - return DecodedBitStreamParser::Decode(std::move(datawords), mode, characterSet); + return DecodedBitStreamParser::Decode(std::move(datawords), mode); } } // namespace ZXing::MaxiCode diff --git a/core/src/maxicode/MCDecoder.h b/core/src/maxicode/MCDecoder.h index 1ed0c80eb8..e53f533766 100644 --- a/core/src/maxicode/MCDecoder.h +++ b/core/src/maxicode/MCDecoder.h @@ -15,7 +15,7 @@ class BitMatrix; namespace MaxiCode { -DecoderResult Decode(const BitMatrix& bits, const std::string& characterSet); +DecoderResult Decode(const BitMatrix& bits); } // MaxiCode } // ZXing diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index 9131b1200f..ce3c9a9125 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -43,7 +43,7 @@ static BitMatrix ExtractPureBits(const BitMatrix& image) return result; } -Reader::Reader(const DecodeHints& hints) : _isPure(hints.isPure()), _characterSet(hints.characterSet()) {} +Reader::Reader(const DecodeHints& hints) : _isPure(hints.isPure()) {} Result Reader::decode(const BinaryBitmap& image) const @@ -59,7 +59,7 @@ Reader::decode(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); } - return Result(Decode(bits, _characterSet), {}, BarcodeFormat::MaxiCode); + return Result(Decode(bits), {}, BarcodeFormat::MaxiCode); } } // namespace ZXing::MaxiCode diff --git a/core/src/maxicode/MCReader.h b/core/src/maxicode/MCReader.h index 3dacd59f9c..9b907d0f37 100644 --- a/core/src/maxicode/MCReader.h +++ b/core/src/maxicode/MCReader.h @@ -19,7 +19,6 @@ namespace MaxiCode { class Reader : public ZXing::Reader { bool _isPure; - std::string _characterSet; public: explicit Reader(const DecodeHints& hints); diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 3a5cc5eef8..b481549f29 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -564,7 +564,7 @@ static int DecodeMacroOptionalTextField(DecodeStatus& status, const std::vector< Content result; // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 // for non-ASCII (128-255). Text optional fields can contain ECIs. - result.hintedCharset = "Cp437"; + result.defaultCharset = "Cp437"; codeIndex = TextCompaction(status, codewords, codeIndex, result); @@ -583,7 +583,7 @@ static int DecodeMacroOptionalNumericField(DecodeStatus& status, const std::vect Content result; // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 // for non-ASCII (128-255). Text optional fields can contain ECIs. - result.hintedCharset = "Cp437"; + result.defaultCharset = "Cp437"; codeIndex = NumericCompaction(status, codewords, codeIndex, result); @@ -707,11 +707,10 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, } DecoderResult -DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel, const std::string& characterSet) +DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel) { Content result; result.symbology = { 'L', '2', -1 }; - result.hintedCharset = characterSet; bool readerInit = false; auto resultMetadata = std::make_shared(); diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.h b/core/src/pdf417/PDFDecodedBitStreamParser.h index 39b03fed41..103db7c5b0 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.h +++ b/core/src/pdf417/PDFDecodedBitStreamParser.h @@ -24,7 +24,7 @@ namespace Pdf417 { class DecodedBitStreamParser { public: - static DecoderResult Decode(const std::vector& codewords, int ecLevel, const std::string& characterSet); + static DecoderResult Decode(const std::vector& codewords, int ecLevel); }; } // Pdf417 diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 7d179b37a7..130a06d3a7 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -66,8 +66,7 @@ static int GetMaxCodewordWidth(const std::array, 8>& p) std::max(GetMaxWidth(p[1], p[5]), GetMaxWidth(p[7], p[3]) * CodewordDecoder::MODULES_IN_CODEWORD / MODULES_IN_STOP_PATTERN)); } -DecodeStatus DoDecode(const BinaryBitmap& image, bool multiple, std::list& results, - const std::string& characterSet) +DecodeStatus DoDecode(const BinaryBitmap& image, bool multiple, std::list& results) { Detector::Result detectorResult; DecodeStatus status = Detector::Detect(image, multiple, detectorResult); @@ -78,7 +77,7 @@ DecodeStatus DoDecode(const BinaryBitmap& image, bool multiple, std::list ReadCodeWords(BitMatrixCursor topCur, SymbolInfo info) } // forward declaration from PDFScanningDecoder.cpp -DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const std::vector& erasures, - const std::string& characterSet); +DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const std::vector& erasures); -static Result DecodePure(const BinaryBitmap& image_, const std::string& characterSet) +static Result DecodePure(const BinaryBitmap& image_) { auto pimage = image_.getBitMatrix(); if (!pimage) @@ -301,18 +299,18 @@ static Result DecodePure(const BinaryBitmap& image_, const std::string& characte erasures.push_back(i); } - auto res = DecodeCodewords(codeWords, info.ecLevel, erasures, characterSet); + auto res = DecodeCodewords(codeWords, info.ecLevel, erasures); return Result(std::move(res), {{left, top}, {right, top}, {right, bottom}, {left, bottom}}, BarcodeFormat::PDF417); } -Reader::Reader(const DecodeHints& hints) : _isPure(hints.isPure()), _characterSet(hints.characterSet()) {} +Reader::Reader(const DecodeHints& hints) : _isPure(hints.isPure()) {} Result Reader::decode(const BinaryBitmap& image) const { if (_isPure) { - auto res = DecodePure(image, _characterSet); + auto res = DecodePure(image); if (res.status() != DecodeStatus::ChecksumError) return res; // This falls through and tries the non-pure code path if we have a checksum error. This approach is @@ -320,7 +318,7 @@ Reader::decode(const BinaryBitmap& image) const } std::list results; - DecodeStatus status = DoDecode(image, false, results, _characterSet); + DecodeStatus status = DoDecode(image, false, results); if (StatusIsOK(status)) { return results.front(); } @@ -330,7 +328,7 @@ Reader::decode(const BinaryBitmap& image) const Results Reader::decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const { std::list results; - DoDecode(image, true, results, _characterSet); + DoDecode(image, true, results); return Results(results.begin(), results.end()); } @@ -338,7 +336,7 @@ std::list Reader::decodeMultiple(const BinaryBitmap& image) const { std::list results; - DoDecode(image, true, results, _characterSet); + DoDecode(image, true, results); return results; } diff --git a/core/src/pdf417/PDFReader.h b/core/src/pdf417/PDFReader.h index 435a50f252..b3cd81779a 100644 --- a/core/src/pdf417/PDFReader.h +++ b/core/src/pdf417/PDFReader.h @@ -25,7 +25,6 @@ namespace Pdf417 { class Reader : public ZXing::Reader { bool _isPure; - std::string _characterSet; public: explicit Reader(const DecodeHints& hints); diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index b36d55a1b5..d946fa0a16 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -568,8 +568,7 @@ static bool VerifyCodewordCount(std::vector& codewords, int numECCodewords) return true; } -DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const std::vector& erasures, - const std::string& characterSet) +DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const std::vector& erasures) { if (codewords.empty()) { return DecodeStatus::FormatError; @@ -584,7 +583,7 @@ DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const st return DecodeStatus::FormatError; // Decode the codewords - return DecodedBitStreamParser::Decode(codewords, ecLevel, characterSet); + return DecodedBitStreamParser::Decode(codewords, ecLevel); } @@ -603,7 +602,7 @@ DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const st */ static DecoderResult CreateDecoderResultFromAmbiguousValues(int ecLevel, std::vector& codewords, const std::vector& erasureArray, const std::vector& ambiguousIndexes, - const std::vector>& ambiguousIndexValues, const std::string& characterSet) + const std::vector>& ambiguousIndexValues) { std::vector ambiguousIndexCount(ambiguousIndexes.size(), 0); @@ -612,7 +611,7 @@ static DecoderResult CreateDecoderResultFromAmbiguousValues(int ecLevel, std::ve for (size_t i = 0; i < ambiguousIndexCount.size(); i++) { codewords[ambiguousIndexes[i]] = ambiguousIndexValues[i][ambiguousIndexCount[i]]; } - auto result = DecodeCodewords(codewords, ecLevel, erasureArray, characterSet); + auto result = DecodeCodewords(codewords, ecLevel, erasureArray); if (result.errorCode() != DecodeStatus::ChecksumError) { return result; } @@ -637,7 +636,7 @@ static DecoderResult CreateDecoderResultFromAmbiguousValues(int ecLevel, std::ve } -static DecoderResult CreateDecoderResult(DetectionResult& detectionResult, const std::string& characterSet) +static DecoderResult CreateDecoderResult(DetectionResult& detectionResult) { auto barcodeMatrix = CreateBarcodeMatrix(detectionResult); if (!AdjustCodewordCount(detectionResult, barcodeMatrix)) { @@ -664,7 +663,7 @@ static DecoderResult CreateDecoderResult(DetectionResult& detectionResult, const } } return CreateDecoderResultFromAmbiguousValues(detectionResult.barcodeECLevel(), codewords, erasures, - ambiguousIndexesList, ambiguousIndexValues, characterSet); + ambiguousIndexesList, ambiguousIndexValues); } @@ -675,7 +674,7 @@ static DecoderResult CreateDecoderResult(DetectionResult& detectionResult, const DecoderResult ScanningDecoder::Decode(const BitMatrix& image, const Nullable& imageTopLeft, const Nullable& imageBottomLeft, const Nullable& imageTopRight, const Nullable& imageBottomRight, - int minCodewordWidth, int maxCodewordWidth, const std::string& characterSet) + int minCodewordWidth, int maxCodewordWidth) { BoundingBox boundingBox; if (!BoundingBox::Create(image.width(), image.height(), imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight, boundingBox)) { @@ -736,7 +735,7 @@ ScanningDecoder::Decode(const BitMatrix& image, const Nullable& ima } } } - return CreateDecoderResult(detectionResult, characterSet); + return CreateDecoderResult(detectionResult); } } // Pdf417 diff --git a/core/src/pdf417/PDFScanningDecoder.h b/core/src/pdf417/PDFScanningDecoder.h index 08d795649c..2c34aea07c 100644 --- a/core/src/pdf417/PDFScanningDecoder.h +++ b/core/src/pdf417/PDFScanningDecoder.h @@ -26,7 +26,7 @@ class ScanningDecoder static DecoderResult Decode(const BitMatrix& image, const Nullable& imageTopLeft, const Nullable& imageBottomLeft, const Nullable& imageTopRight, const Nullable& imageBottomRight, - int minCodewordWidth, int maxCodewordWidth, const std::string& characterSet); + int minCodewordWidth, int maxCodewordWidth); }; } // Pdf417 diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index f56876e1f7..90d80b2723 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -253,13 +253,11 @@ bool IsEndOfStream(const BitSource& bits, const Version& version) *

See ISO 18004:2006, 6.4.3 - 6.4.7

*/ ZXING_EXPORT_TEST_ONLY -DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel, - const std::string& hintedCharset) +DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel) { BitSource bits(bytes); Content result; result.symbology = {'Q', '1', 1}; - result.hintedCharset = hintedCharset.empty() ? "Auto" : hintedCharset; StructuredAppendInfo structuredAppend; const int modeBitLength = CodecModeBitsLength(version); @@ -343,7 +341,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo .setStructuredAppend(structuredAppend); } -DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) +DecoderResult Decode(const BitMatrix& bits) { const Version* pversion = ReadVersion(bits); if (!pversion) @@ -383,7 +381,7 @@ DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset) } // Decode the contents of that stream of bytes - return DecodeBitStream(std::move(resultBytes), version, formatInfo.ecLevel, hintedCharset).setIsMirrored(formatInfo.isMirrored); + return DecodeBitStream(std::move(resultBytes), version, formatInfo.ecLevel).setIsMirrored(formatInfo.isMirrored); } } // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRDecoder.h b/core/src/qrcode/QRDecoder.h index e4ab05d5c7..ecfdc92be1 100644 --- a/core/src/qrcode/QRDecoder.h +++ b/core/src/qrcode/QRDecoder.h @@ -15,7 +15,7 @@ class BitMatrix; namespace QRCode { -DecoderResult Decode(const BitMatrix& bits, const std::string& hintedCharset = {}); +DecoderResult Decode(const BitMatrix& bits); } // QRCode } // ZXing diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 60007c87a4..869373415f 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -25,8 +25,7 @@ Reader::Reader(const DecodeHints& hints) : _tryHarder(hints.tryHarder()), _isPure(hints.isPure()), _testQR(hints.hasFormat(BarcodeFormat::QRCode)), - _testMQR(hints.hasFormat(BarcodeFormat::MicroQRCode)), - _charset(hints.characterSet()) + _testMQR(hints.hasFormat(BarcodeFormat::MicroQRCode)) {} Result Reader::decode(const BinaryBitmap& image) const @@ -52,7 +51,7 @@ Result Reader::decode(const BinaryBitmap& image) const if (!detectorResult.isValid()) return Result(DecodeStatus::NotFound); - auto decoderResult = Decode(detectorResult.bits(), _charset); + auto decoderResult = Decode(detectorResult.bits()); auto position = detectorResult.position(); return Result(std::move(decoderResult), std::move(position), @@ -82,7 +81,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const auto detectorResult = SampleQR(*binImg, fpSet); if (detectorResult.isValid()) { - auto decoderResult = Decode(detectorResult.bits(), _charset); + auto decoderResult = Decode(detectorResult.bits()); auto position = detectorResult.position(); if (decoderResult.isValid()) { usedFPs.push_back(fpSet.bl); @@ -103,7 +102,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const auto detectorResult = SampleMQR(*binImg, fp); if (detectorResult.isValid()) { - auto decoderResult = Decode(detectorResult.bits(), _charset); + auto decoderResult = Decode(detectorResult.bits()); auto position = detectorResult.position(); if (decoderResult.isValid()) { results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MicroQRCode); diff --git a/core/src/qrcode/QRReader.h b/core/src/qrcode/QRReader.h index f8fe736a2f..4f8454e18d 100644 --- a/core/src/qrcode/QRReader.h +++ b/core/src/qrcode/QRReader.h @@ -26,7 +26,6 @@ class Reader : public ZXing::Reader private: bool _tryHarder, _isPure, _testQR, _testMQR; - std::string _charset; }; } // QRCode diff --git a/test/fuzz/fuzzDMDecoder.cpp b/test/fuzz/fuzzDMDecoder.cpp index d0c07f070c..6b4500d8c7 100644 --- a/test/fuzz/fuzzDMDecoder.cpp +++ b/test/fuzz/fuzzDMDecoder.cpp @@ -12,7 +12,7 @@ using namespace ZXing; namespace ZXing::DataMatrix::DecodedBitStreamParser { -DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const bool isDMRE); +DecoderResult Decode(ByteArray&& bytes, const bool isDMRE); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) @@ -23,7 +23,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ByteArray ba; ba.insert(ba.begin(), data, data + size); try { - DataMatrix::DecodedBitStreamParser::Decode(std::move(ba), "", false); + DataMatrix::DecodedBitStreamParser::Decode(std::move(ba), false); } catch (...) { } diff --git a/test/unit/aztec/AZDecoderTest.cpp b/test/unit/aztec/AZDecoderTest.cpp index 62d70977ff..175b041405 100644 --- a/test/unit/aztec/AZDecoderTest.cpp +++ b/test/unit/aztec/AZDecoderTest.cpp @@ -17,7 +17,7 @@ namespace ZXing::Aztec { -DecoderResult Decode(const BitArray& bits, const std::string& characterSet = ""); +DecoderResult Decode(const BitArray& bits); } diff --git a/test/unit/aztec/AZHighLevelEncoderTest.cpp b/test/unit/aztec/AZHighLevelEncoderTest.cpp index 5f82f99d4a..0869921bdf 100644 --- a/test/unit/aztec/AZHighLevelEncoderTest.cpp +++ b/test/unit/aztec/AZHighLevelEncoderTest.cpp @@ -16,7 +16,7 @@ namespace ZXing::Aztec { -DecoderResult Decode(const BitArray& bits, const std::string& characterSet = ""); +DecoderResult Decode(const BitArray& bits); } diff --git a/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp b/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp index 13d7f99cd0..c6b6e8de64 100644 --- a/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp +++ b/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp @@ -12,7 +12,7 @@ namespace ZXing::DataMatrix::DecodedBitStreamParser { -DecoderResult Decode(ByteArray&& bytes, const std::string& characterSet, const bool isDMRE); +DecoderResult Decode(ByteArray&& bytes, const bool isDMRE); } @@ -21,7 +21,7 @@ using namespace ZXing; // Helper to call Decode() static DecoderResult parse(ByteArray bytes, const bool isDMRE = false) { - return DataMatrix::DecodedBitStreamParser::Decode(std::move(bytes), "", isDMRE); + return DataMatrix::DecodedBitStreamParser::Decode(std::move(bytes), isDMRE); } // Shorthand to return text diff --git a/test/unit/maxicode/MCDecoderTest.cpp b/test/unit/maxicode/MCDecoderTest.cpp index 17a8caf3f2..e811107c0f 100644 --- a/test/unit/maxicode/MCDecoderTest.cpp +++ b/test/unit/maxicode/MCDecoderTest.cpp @@ -11,7 +11,7 @@ namespace ZXing::MaxiCode::DecodedBitStreamParser { -DecoderResult Decode(ByteArray&& bytes, const int mode, const std::string& characterSet); +DecoderResult Decode(ByteArray&& bytes, const int mode); } @@ -41,7 +41,7 @@ static DecoderResult parse(ByteArray bytes, const int mode) } padded.insert(padded.end(), bytes.begin(), bytes.end()); pad(padded); - return MaxiCode::DecodedBitStreamParser::Decode(std::move(padded), mode, ""); + return MaxiCode::DecodedBitStreamParser::Decode(std::move(padded), mode); } // Helper to return Structured Append diff --git a/test/unit/pdf417/PDF417DecoderTest.cpp b/test/unit/pdf417/PDF417DecoderTest.cpp index 2df84c85db..55b902cd3f 100644 --- a/test/unit/pdf417/PDF417DecoderTest.cpp +++ b/test/unit/pdf417/PDF417DecoderTest.cpp @@ -19,9 +19,9 @@ using namespace ZXing; using namespace ZXing::Pdf417; // Shorthand for Decode() -static DecoderResult parse(const std::vector& codewords, int ecLevel = 0, const std::string& characterSet = "") +static DecoderResult parse(const std::vector& codewords, int ecLevel = 0) { - return DecodedBitStreamParser::Decode(codewords, ecLevel, characterSet); + return DecodedBitStreamParser::Decode(codewords, ecLevel); } /** diff --git a/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp b/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp index 81d5f97c9b..0d8c1b0def 100644 --- a/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp +++ b/test/unit/qrcode/QRDecodedBitStreamParserTest.cpp @@ -16,7 +16,7 @@ namespace ZXing { namespace QRCode { - DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel, const std::string& hintedCharset); + DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCorrectionLevel ecLevel); } } @@ -31,7 +31,7 @@ TEST(QRDecodedBitStreamParserTest, SimpleByteMode) ba.appendBits(0xF1, 8); ba.appendBits(0xF2, 8); ba.appendBits(0xF3, 8); - auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium, "").text(); + auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium).text(); EXPECT_EQ(L"\xF1\xF2\xF3", result); } @@ -44,7 +44,7 @@ TEST(QRDecodedBitStreamParserTest, SimpleSJIS) ba.appendBits(0xA2, 8); ba.appendBits(0xA3, 8); ba.appendBits(0xD0, 8); - auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium, "").text(); + auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium).text(); EXPECT_EQ(L"\uff61\uff62\uff63\uff90", result); } @@ -58,7 +58,7 @@ TEST(QRDecodedBitStreamParserTest, ECI) ba.appendBits(0xA1, 8); ba.appendBits(0xA2, 8); ba.appendBits(0xA3, 8); - auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium, "").text(); + auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium).text(); EXPECT_EQ(L"\xED\xF3\xFA", result); } @@ -69,7 +69,7 @@ TEST(QRDecodedBitStreamParserTest, Hanzi) ba.appendBits(0x01, 4); // Subset 1 = GB2312 encoding ba.appendBits(0x01, 8); // 1 characters ba.appendBits(0x03C1, 13); - auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium, "").text(); + auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium).text(); EXPECT_EQ(L"\u963f", result); } @@ -82,7 +82,7 @@ TEST(QRDecodedBitStreamParserTest, HanziLevel1) // A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181 ba.appendBits(0x0181, 13); - auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium, "").text(); + auto result = DecodeBitStream(ba.toBytes(), *Version::VersionForNumber(1), ErrorCorrectionLevel::Medium).text(); EXPECT_EQ(L"\u30a2", result); } @@ -93,22 +93,22 @@ TEST(QRDecodedBitStreamParserTest, SymbologyIdentifier) DecoderResult result; // Plain "ANUM(1) A" - result = DecodeBitStream({0x20, 0x09, 0x40}, version, ecLevel, ""); + result = DecodeBitStream({0x20, 0x09, 0x40}, version, ecLevel); EXPECT_EQ(result.symbologyIdentifier(), "]Q1"); EXPECT_EQ(result.text(), L"A"); // GS1 "FNC1(1st) NUM(4) 2001" - result = DecodeBitStream({0x51, 0x01, 0x0C, 0x81, 0x00}, version, ecLevel, ""); + result = DecodeBitStream({0x51, 0x01, 0x0C, 0x81, 0x00}, version, ecLevel); EXPECT_EQ(result.symbologyIdentifier(), "]Q3"); EXPECT_EQ(result.text(), L"2001"); // "(20)01" // GS1 "NUM(4) 2001 FNC1(1st) 301" - FNC1(1st) can occur anywhere (this actually violates the specification) - result = DecodeBitStream({0x10, 0x10, 0xC8, 0x15, 0x10, 0x0D, 0x2D, 0x00}, version, ecLevel, ""); + result = DecodeBitStream({0x10, 0x10, 0xC8, 0x15, 0x10, 0x0D, 0x2D, 0x00}, version, ecLevel); EXPECT_EQ(result.symbologyIdentifier(), "]Q3"); EXPECT_EQ(result.text(), L"2001301"); // "(20)01(30)1" // AIM "FNC1(2nd) 99 (0x63) ANUM(1) A" - result = DecodeBitStream({0x96, 0x32, 0x00, 0x94, 0x00}, version, ecLevel, ""); + result = DecodeBitStream({0x96, 0x32, 0x00, 0x94, 0x00}, version, ecLevel); EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); EXPECT_EQ(result.text(), L"99A"); @@ -119,16 +119,16 @@ TEST(QRDecodedBitStreamParserTest, SymbologyIdentifier) // EXPECT_EQ(result.text(), L"99AB"); // Application Indicator prefixed to data // AIM "FNC1(2nd) A (100 + 61 = 0xA5) ANUM(1) B" - result = DecodeBitStream({0x9A, 0x52, 0x00, 0x96, 0x00}, version, ecLevel, ""); + result = DecodeBitStream({0x9A, 0x52, 0x00, 0x96, 0x00}, version, ecLevel); EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); EXPECT_EQ(result.text(), L"AB"); // AIM "FNC1(2nd) a (100 + 97 = 0xC5) ANUM(1) B" - result = DecodeBitStream({0x9C, 0x52, 0x00, 0x96, 0x00}, version, ecLevel, ""); + result = DecodeBitStream({0x9C, 0x52, 0x00, 0x96, 0x00}, version, ecLevel); EXPECT_EQ(result.symbologyIdentifier(), "]Q5"); EXPECT_EQ(result.text(), L"aB"); // Bad AIM Application Indicator "FNC1(2nd) @ (0xA4) ANUM(1) B" - result = DecodeBitStream({0x9A, 0x42, 0x00, 0x96, 0x00}, version, ecLevel, ""); + result = DecodeBitStream({0x9A, 0x42, 0x00, 0x96, 0x00}, version, ecLevel); EXPECT_FALSE(result.isValid()); } From d5c5286dedf65019be468b09ca963800bf72e9b2 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 23 Jun 2022 16:30:18 +0200 Subject: [PATCH 0301/1315] LogMatrix: remove non-scenical template specialization (g++ complained) --- core/src/LogMatrix.h | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/LogMatrix.h b/core/src/LogMatrix.h index 1d366b9ca1..4633a3ef7d 100644 --- a/core/src/LogMatrix.h +++ b/core/src/LogMatrix.h @@ -68,7 +68,6 @@ class LogMatrix _log.set(static_cast(p.x * _scale), static_cast(p.y * _scale), color); } - template <> void operator()(const PointT& p, int color) { operator()(centered(p), color); From d6dc409ef15ff7171c7f9130dff7266a7c65f053 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 24 Jun 2022 01:27:10 +0200 Subject: [PATCH 0302/1315] c++20: coroutine based multi-symbol detection support for DataMatrix To enable this, compile with `CMAKE_CXX_STANDARD 20` (see top-level CMakeLists.txt). This has been discussed in #344. --- core/src/Generator.h | 109 +++++++++++++++++++++++++++++ core/src/datamatrix/DMDetector.cpp | 26 ++++++- core/src/datamatrix/DMDetector.h | 13 +++- core/src/datamatrix/DMReader.cpp | 22 ++++++ core/src/datamatrix/DMReader.h | 3 + 5 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 core/src/Generator.h diff --git a/core/src/Generator.h b/core/src/Generator.h new file mode 100644 index 0000000000..922af66d85 --- /dev/null +++ b/core/src/Generator.h @@ -0,0 +1,109 @@ +/* + * Copyright 2022 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#ifdef __cpp_impl_coroutine +#include +#include + +// this code is based on https://en.cppreference.com/w/cpp/coroutine/coroutine_handle#Example +// but modified trying to prevent accidental copying of generated objects + +template +class Generator +{ +public: + struct promise_type + { + Generator get_return_object() { return Generator{Handle::from_promise(*this)}; } + static std::suspend_always initial_suspend() noexcept { return {}; } + static std::suspend_always final_suspend() noexcept { return {}; } + std::suspend_always yield_value(T&& value) noexcept + { + current_value = std::move(value); + return {}; + } +// void return_value(T&& value) noexcept { current_value = std::move(value); } + // Disallow co_await in generator coroutines. + void await_transform() = delete; + [[noreturn]] static void unhandled_exception() { throw; } + + std::optional current_value; + }; + + using Handle = std::coroutine_handle; + + explicit Generator(const Handle coroutine) : _coroutine{coroutine} {} + + Generator() = default; + ~Generator() + { + if (_coroutine) + _coroutine.destroy(); + } + + Generator(const Generator&) = delete; + Generator& operator=(const Generator&) = delete; + + Generator(Generator&& other) noexcept : _coroutine{other._coroutine} { other._coroutine = {}; } +// Generator& operator=(Generator&& other) noexcept +// { +// if (this != &other) { +// if (_coroutine) +// _coroutine.destroy(); + +// _coroutine = other._coroutine; +// other._coroutine = {}; +// } +// return *this; +// } + + // Range-based for loop support. + class Iter + { + public: + void operator++() { _coroutine.resume(); } + T&& operator*() const { return std::move(*_coroutine.promise().current_value); } + bool operator==(std::default_sentinel_t) const { return !_coroutine || _coroutine.done(); } + + explicit Iter(const Handle coroutine) : _coroutine{coroutine} {} + + private: + Handle _coroutine; + }; + + Iter begin() + { + if (_coroutine) + _coroutine.resume(); + + return Iter{_coroutine}; + } + std::default_sentinel_t end() { return {}; } + +private: + Handle _coroutine; +}; + +#endif + +/* +usage example: + +template +Generator range(T first, const T last) +{ + while (first < last) + co_yield first++; +} + +int main() +{ + for (const char i : range(65, 91)) + std::cout << i << ' '; + std::cout << '\n'; +} +*/ diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 4a9b6eb57d..e2b88b8853 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -775,7 +775,7 @@ static DetectorResult Scan(EdgeTracer startTracer, std::array +#include +#endif + namespace ZXing { class BitMatrix; @@ -13,7 +18,13 @@ class DetectorResult; namespace DataMatrix { -DetectorResult Detect(const BitMatrix& image, bool tryHarder, bool tryRotate, bool isPure); +#ifdef __cpp_impl_coroutine +using DetectorResults = Generator; +#else +using DetectorResults = DetectorResult; +#endif + +DetectorResults Detect(const BitMatrix& image, bool tryHarder, bool tryRotate, bool isPure); } // DataMatrix } // ZXing diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index fc4c1bdec6..a6736d85fa 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -26,6 +26,10 @@ Reader::Reader(const DecodeHints& hints) Result Reader::decode(const BinaryBitmap& image) const { +#ifdef __cpp_impl_coroutine + auto results = decode(image, 1); + return results.empty() ? Result(DecodeStatus::NotFound) : results.front(); +#else auto binImg = image.getBitMatrix(); if (binImg == nullptr) return Result(DecodeStatus::NotFound); @@ -35,6 +39,24 @@ Result Reader::decode(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); return Result(Decode(detectorResult.bits()), std::move(detectorResult).position(), BarcodeFormat::DataMatrix); +#endif } +#ifdef __cpp_impl_coroutine +Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const +{ + auto binImg = image.getBitMatrix(); + if (binImg == nullptr) + return {}; + + Results results; + for (auto&& res : Detect(*binImg, maxSymbols > 1, _tryRotate, _isPure)) { + results.push_back(Result(Decode(res.bits()), std::move(res).position(), BarcodeFormat::DataMatrix)); + if (maxSymbols > 0 && Size(results) >= maxSymbols) + break; + } + + return results; +} +#endif } // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMReader.h b/core/src/datamatrix/DMReader.h index a0c728ae41..dd472b6096 100644 --- a/core/src/datamatrix/DMReader.h +++ b/core/src/datamatrix/DMReader.h @@ -22,6 +22,9 @@ class Reader : public ZXing::Reader public: explicit Reader(const DecodeHints& hints); Result decode(const BinaryBitmap& image) const override; +#ifdef __cpp_impl_coroutine + Results decode(const BinaryBitmap& image, int maxSymbols) const override; +#endif }; } // DataMatrix From 3bf38b255c11955218f52f544ed44c54c39fffbb Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 24 Jun 2022 11:45:25 +0200 Subject: [PATCH 0303/1315] Result: deprecated `status()` and introduced `Error Result::error()` This is a preview/WIP as discussed in #345. The 'msg' functionality of the new Error class is not used inside the library, yet. --- core/CMakeLists.txt | 3 +++ core/src/Error.h | 50 +++++++++++++++++++++++++++++++++++ core/src/Result.cpp | 26 ++++++++++++++++-- core/src/Result.h | 11 +++++--- core/src/oned/ODReader.cpp | 2 +- core/src/pdf417/PDFReader.cpp | 2 +- example/ZXingQtReader.cpp | 1 - example/ZXingQtReader.h | 13 +-------- example/ZXingReader.cpp | 16 +++++++---- 9 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 core/src/Error.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 655d569305..d59ed2d818 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -58,6 +58,7 @@ set (COMMON_FILES src/ECI.h src/ECI.cpp src/Flags.h + src/Generator.h src/GenericGF.h src/GenericGF.cpp src/GenericGFPoly.h @@ -95,6 +96,7 @@ if (BUILD_READERS) src/DecodeStatus.cpp src/DecoderResult.h src/DetectorResult.h + src/Error.h src/GlobalHistogramBinarizer.h src/GlobalHistogramBinarizer.cpp src/GridSampler.h @@ -152,6 +154,7 @@ if (BUILD_READERS) src/Content.h src/DecodeHints.h src/DecodeStatus.h + src/Error.h src/ImageView.h src/Point.h src/Quadrilateral.h diff --git a/core/src/Error.h b/core/src/Error.h new file mode 100644 index 0000000000..6cbee9f95e --- /dev/null +++ b/core/src/Error.h @@ -0,0 +1,50 @@ +/* + * Copyright 2022 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +namespace ZXing { + +class Error +{ +public: + enum Type { None, Format, Checksum, Unsupported }; + Type type() const noexcept { return _type; } + const std::string& msg() const noexcept { return _msg; } + operator bool() const noexcept { return _type != None; } + + Error() = default; + +protected: + Type _type = None; + std::string _msg; + + Error(Type type, std::string msg) : _type(type), _msg(std::move(msg)) {} +}; + +class FormatError : public Error +{ +public: + FormatError(std::string msg = {}) : Error(Format, std::move(msg)) {} +}; + +class ChecksumError : public Error +{ +public: + ChecksumError(std::string msg = {}) : Error(Checksum, std::move(msg)) {} +}; + +inline std::string ToString(const Error& e) +{ + const char* name[] = {"", "FormatError", "ChecksumError", "Unsupported"}; + std::string ret = name[static_cast(e.type())]; + if (!e.msg().empty()) + ret += " (" + e.msg() + ")"; + return ret; +} + +} diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 4bd0d320f0..ef6f9a1214 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -17,6 +17,17 @@ namespace ZXing { +static Error Status2Error(DecodeStatus s) +{ + switch (s) { + case DecodeStatus::FormatError: return FormatError(); + case DecodeStatus::ChecksumError: return ChecksumError(); + default: return {}; + } +} + +Result::Result(DecodeStatus status) : _error(Status2Error(status)) {} + Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, ByteArray&& rawBytes, bool readerInit, const std::string& ai) : @@ -30,9 +41,9 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor {} Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format) - : _status(decodeResult.errorCode()), - _format(format), + : _format(decodeResult.errorCode() == DecodeStatus::NotFound ? BarcodeFormat::None : format), _content(std::move(decodeResult).content()), + _error(Status2Error(decodeResult.errorCode())), _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), @@ -45,6 +56,17 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } +DecodeStatus Result::status() const +{ + switch(_error.type()) { + case Error::Format : return DecodeStatus::FormatError; + case Error::Checksum : return DecodeStatus::ChecksumError; + default: ; + } + + return format() == BarcodeFormat::None ? DecodeStatus::NotFound : DecodeStatus::NoError; +} + const ByteArray& Result::bytes() const { return _content.bytes; diff --git a/core/src/Result.h b/core/src/Result.h index c76f4abffd..41adcda416 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -11,6 +11,7 @@ #include "ByteArray.h" #include "Content.h" #include "DecodeStatus.h" +#include "Error.h" #include "Quadrilateral.h" #include "StructuredAppend.h" @@ -29,7 +30,7 @@ using Position = QuadrilateralI; class Result { public: - explicit Result(DecodeStatus status) : _status(status) {} + explicit Result(DecodeStatus status); // 1D convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, @@ -37,9 +38,11 @@ class Result Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); - bool isValid() const { return StatusIsOK(_status); } + bool isValid() const { return format() != BarcodeFormat::None && !error(); } - DecodeStatus status() const { return _status; } + const Error& error() const { return _error; } + + [[deprecated]] DecodeStatus status() const; BarcodeFormat format() const { return _format; } @@ -154,9 +157,9 @@ class Result friend Result MergeStructuredAppendSequence(const std::vector& results); private: - DecodeStatus _status = DecodeStatus::NoError; BarcodeFormat _format = BarcodeFormat::None; Content _content; + Error _error; Position _position; ByteArray _rawBytes; int _numBits = 0; diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 59d61ad4e1..8b8abc1574 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -216,7 +216,7 @@ static Results DoDecode(const std::vector>& readers, *(a->lineCount() < b->lineCount() ? a : b) = Result(DecodeStatus::NotFound); //TODO: C++20 res.erase_if() - it = std::remove_if(res.begin(), res.end(), [](auto&& r) { return r.status() == DecodeStatus::NotFound; }); + it = std::remove_if(res.begin(), res.end(), [](auto&& r) { return r.format() == BarcodeFormat::None; }); res.erase(it, res.end()); return res; diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 130a06d3a7..3673a73211 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -311,7 +311,7 @@ Reader::decode(const BinaryBitmap& image) const { if (_isPure) { auto res = DecodePure(image); - if (res.status() != DecodeStatus::ChecksumError) + if (res.error().type() != Error::Checksum) return res; // This falls through and tries the non-pure code path if we have a checksum error. This approach is // currently the best option to deal with 'aliased' input like e.g. 03-aliased.png diff --git a/example/ZXingQtReader.cpp b/example/ZXingQtReader.cpp index c07544b08f..757cabd87c 100644 --- a/example/ZXingQtReader.cpp +++ b/example/ZXingQtReader.cpp @@ -36,7 +36,6 @@ int main(int argc, char* argv[]) qDebug() << "Text: " << result.text(); qDebug() << "Format: " << result.format(); qDebug() << "Content:" << result.contentType(); - qDebug() << "Error: " << result.status(); qDebug() << ""; } diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index d97d634d9a..58998c20c8 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -60,17 +60,9 @@ enum class BarcodeFormat enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; -enum class DecodeStatus -{ - NoError = 0, - NotFound, - FormatError, - ChecksumError, -}; #else using ZXing::BarcodeFormat; using ZXing::ContentType; -using ZXing::DecodeStatus; #endif using ZXing::DecodeHints; @@ -79,7 +71,6 @@ using ZXing::BarcodeFormats; Q_ENUM_NS(BarcodeFormat) Q_ENUM_NS(ContentType) -Q_ENUM_NS(DecodeStatus) template QDebug operator<<(QDebug dbg, const T& v) @@ -111,7 +102,6 @@ class Result : private ZXing::Result Q_PROPERTY(QString text READ text) Q_PROPERTY(QByteArray bytes READ bytes) Q_PROPERTY(bool isValid READ isValid) - Q_PROPERTY(DecodeStatus status READ status) Q_PROPERTY(ContentType contentType READ contentType) Q_PROPERTY(Position position READ position) @@ -133,7 +123,6 @@ class Result : private ZXing::Result using ZXing::Result::isValid; BarcodeFormat format() const { return static_cast(ZXing::Result::format()); } - DecodeStatus status() const { return static_cast(ZXing::Result::status()); } ContentType contentType() const { return static_cast(ZXing::Result::contentType()); } QString formatName() const { return QString::fromStdString(ZXing::ToString(ZXing::Result::format())); } const QString& text() const { return _text; } @@ -440,7 +429,7 @@ namespace ZXingQt { inline void registerQmlAndMetaTypes() { qRegisterMetaType("BarcodeFormat"); - qRegisterMetaType("DecodeStatus"); + qRegisterMetaType("ContentType"); // supposedly the Q_DECLARE_METATYPE should be used with the overload without a custom name // but then the qml side complains about "unregistered type" diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 32cd7c7674..21087efb24 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -168,7 +168,7 @@ int main(int argc, char* argv[]) if (!outPath.empty()) drawRect(image, result.position()); - ret |= static_cast(result.status()); + ret |= static_cast(result.error().type()); if (binaryOutput) { std::cout.write(reinterpret_cast(result.bytes().data()), result.bytes().size()); @@ -179,8 +179,8 @@ int main(int argc, char* argv[]) std::cout << filePath << " " << ToString(result.format()); if (result.isValid()) std::cout << " \"" << escapeNonGraphical(result.text()) << "\""; - else if (result.format() != BarcodeFormat::None) - std::cout << " " << ToString(result.status()); + else if (result.error()) + std::cout << " " << ToString(result.error()); std::cout << "\n"; continue; } @@ -193,6 +193,12 @@ int main(int argc, char* argv[]) std::cout << "File: " << filePath << "\n"; firstFile = false; } + + if (result.format() == BarcodeFormat::None) { + std::cout << "No barcode found\n"; + continue; + } + std::cout << "Text: \"" << (angleEscape ? escapeNonGraphical(result.text()) : result.text()) << "\"\n" << "Utf8ECI: \"" << result.utf8ECI() << "\"\n" << "Bytes: " << ToHex(result.bytes()) << "\n" @@ -203,8 +209,7 @@ int main(int argc, char* argv[]) << "HasECI: " << result.hasECI() << "\n" << "Position: " << result.position() << "\n" << "Rotation: " << result.orientation() << " deg\n" - << "IsMirrored: " << result.isMirrored() << "\n" - << "Error: " << ToString(result.status()) << "\n"; + << "IsMirrored: " << result.isMirrored() << "\n"; auto printOptional = [](const char* key, const std::string& v) { if (!v.empty()) @@ -212,6 +217,7 @@ int main(int argc, char* argv[]) }; printOptional("EC Level: ", result.ecLevel()); + printOptional("Error: ", ToString(result.error())); if (result.lineCount()) std::cout << "Lines: " << result.lineCount() << "\n"; From 20cd93ae70b96b959cf3e9c7803cc193a685b9b0 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 28 Jun 2022 23:58:56 +0200 Subject: [PATCH 0304/1315] python: add content_type output to demo_reader.py --- wrappers/python/demo_reader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/demo_reader.py b/wrappers/python/demo_reader.py index d8e95cb9ef..c2a3ad9468 100644 --- a/wrappers/python/demo_reader.py +++ b/wrappers/python/demo_reader.py @@ -4,7 +4,7 @@ img = Image.open(sys.argv[1]) results = zxingcpp.read_barcodes(img) for result in results: - print("Found barcode:\n Text: '{}'\n Format: {}\n Position: {}" - .format(result.text, result.format, result.position)) + print("Found barcode:\n Text: '{}'\n Format: {}\n Content: {}\n Position: {}" + .format(result.text, result.format, result.content_type, result.position)) if len(results) == 0: print("Could not find any barcode.") From 5f13f87b429fd49f2b18d925b639247901a51a6d Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 28 Jun 2022 23:59:20 +0200 Subject: [PATCH 0305/1315] DecodeHints: remove dead code --- core/src/DecodeHints.h | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 26813d387e..1c1e9129aa 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -131,7 +131,6 @@ class DecodeHints ZX_PROPERTY(EanAddOnSymbol, eanAddOnSymbol, setEanAddOnSymbol) #undef ZX_PROPERTY -#undef ZX_PROPERTY_DEPRECATED /// NOTE: used to affect FNC1 handling for Code 128 (aka GS1-128) but behavior now based on position of FNC1. [[deprecated]] bool assumeGS1() const noexcept { return true; } From e322b4d6052d2c4cc7a0343b6870ae3ad0faccb1 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 29 Jun 2022 01:24:06 +0200 Subject: [PATCH 0306/1315] QRCode: minor performance improvement of MQR-only use case Save like 10% by not calculating the unused FinderPatternSets in the MQR case. Also fix wrong reference type in `GenerateFinderPatternSets`. --- core/src/qrcode/QRDetector.cpp | 2 +- core/src/qrcode/QRDetector.h | 2 +- core/src/qrcode/QRReader.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 5fdad20b89..9c93a13e9e 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -82,7 +82,7 @@ std::vector FindFinderPatterns(const BitMatrix& image, bool t * @param patterns list of ConcentricPattern objects, i.e. found finder pattern squares * @return list of plausible finder pattern sets, sorted by decreasing plausibility */ -FinderPatternSets GenerateFinderPatternSets(FinderPatterns&& patterns) +FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) { std::sort(patterns.begin(), patterns.end(), [](const auto& a, const auto& b) { return a.size < b.size; }); diff --git a/core/src/qrcode/QRDetector.h b/core/src/qrcode/QRDetector.h index 77b5914615..4173d59a7a 100644 --- a/core/src/qrcode/QRDetector.h +++ b/core/src/qrcode/QRDetector.h @@ -28,7 +28,7 @@ using FinderPatterns = std::vector; using FinderPatternSets = std::vector; FinderPatterns FindFinderPatterns(const BitMatrix& image, bool tryHarder); -FinderPatternSets GenerateFinderPatternSets(FinderPatterns&& patterns); +FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns); DetectorResult SampleQR(const BitMatrix& image, const FinderPatternSet& fp); DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp); diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 869373415f..d87161d381 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -69,12 +69,12 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const #endif auto allFPs = FindFinderPatterns(*binImg, _tryHarder); - auto allFPSets = GenerateFinderPatternSets(std::move(allFPs)); std::vector usedFPs; Results results; if (_testQR) { + auto allFPSets = GenerateFinderPatternSets(allFPs); for (auto& fpSet : allFPSets) { if (Contains(usedFPs, fpSet.bl) || Contains(usedFPs, fpSet.tl) || Contains(usedFPs, fpSet.tr)) continue; From c33f5f910f81a5f3d4e4f4ec8a3fbdeb543f6062 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 29 Jun 2022 10:54:53 +0200 Subject: [PATCH 0307/1315] DataMatrix: fix spurious detection with FormatError in new c++20 code See https://github.com/nu-book/zxing-cpp/issues/344#issuecomment-1169662905 --- core/src/datamatrix/DMDetector.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index e2b88b8853..5760e52114 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -884,8 +884,11 @@ DetectorResults Detect(const BitMatrix& image, bool tryHarder, bool tryRotate, b found = true; co_yield std::move(r); } - if (!found) - co_yield DetectOld(image); + if (!found) { + auto r = DetectOld(image); + if (r.isValid()) + co_yield std::move(r); + } } #else if (isPure) From 022a0cf9fac1704176c9ed7dc029ef22830ec8a8 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 29 Jun 2022 13:20:18 +0200 Subject: [PATCH 0308/1315] example: clean up ZXingReader help text --- example/ZXingReader.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 21087efb24..da8a3a3e8d 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -28,16 +28,18 @@ using namespace ZXing; static void PrintUsage(const char* exePath) { - std::cout << "Usage: " << exePath << " [-fast] [-norotate] [-format ] [-pngout ] [-ispure] [-1] ...\n" + std::cout << "Usage: " << exePath << " [options] ...\n" << " -fast Skip some lines/pixels during detection (faster)\n" << " -norotate Don't try rotated image during detection (faster)\n" << " -noscale Don't try downscaled images during detection (faster)\n" - << " -format Only detect given format(s) (faster)\n" + << " -format \n" + << " Only detect given format(s) (faster)\n" << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" - << " -1 Print only file name, text and status on one line per file/barcode\n" - << " -escape Escape non-graphical characters in angle brackets (implicit for -1 option, which always escapes)\n" + << " -1 Print only file name, content/error on one line per file/barcode (implies '-escape')\n" + << " -escape Escape non-graphical characters in angle brackets\n" << " -binary Write (only) the binary content of the symbol(s) to stdout\n" - << " -pngout Write a copy of the input image with barcodes outlined by a green line\n" + << " -pngout \n" + << " Write a copy of the input image with barcodes outlined by a green line\n" << "\n" << "Supported formats are:\n"; for (auto f : BarcodeFormats::all()) { From 7f306d287a03bf1b2a389a5f1e46c5f2f49bb349 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 29 Jun 2022 23:52:07 +0200 Subject: [PATCH 0309/1315] QRCode: simply variable renaming (preparing next change) --- core/src/qrcode/QRDetector.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 9c93a13e9e..f40419da53 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -110,20 +110,23 @@ FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) // Orders the three points in an order [A,B,C] such that AB is less than AC // and BC is less than AC, and the angle between BC and BA is less than 180 degrees. - auto distAB = squaredDistance(a, b); - auto distBC = squaredDistance(b, c); - auto distAC = squaredDistance(a, c); + auto distAB2 = squaredDistance(a, b); + auto distBC2 = squaredDistance(b, c); + auto distAC2 = squaredDistance(a, c); - if (distBC >= distAB && distBC >= distAC) { + if (distBC2 >= distAB2 && distBC2 >= distAC2) { std::swap(a, b); - std::swap(distBC, distAC); - } else if (distAB >= distAC && distAB >= distBC) { + std::swap(distBC2, distAC2); + } else if (distAB2 >= distAC2 && distAB2 >= distBC2) { std::swap(b, c); - std::swap(distAB, distAC); + std::swap(distAB2, distAC2); } + auto distAB = std::sqrt(distAB2); + auto distBC = std::sqrt(distBC2); + // Estimate the module count and ignore this set if it can not result in a valid decoding - if (auto moduleCount = (std::sqrt(distAB) + std::sqrt(distBC)) / (2 * (a->size + b->size + c->size) / (3 * 7.f)) + 7; + if (auto moduleCount = (distAB + distBC) / (2 * (a->size + b->size + c->size) / (3 * 7.f)) + 7; moduleCount < 21 * 0.9 || moduleCount > 177 * 1.05) continue; @@ -132,7 +135,7 @@ FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) // we need to check both two equal sides separately. // The value of |c^2 - 2 * b^2| + |c^2 - 2 * a^2| increases as dissimilarity // from isosceles right triangle. - double d = std::abs(distAC - 2 * distAB) + std::abs(distAC - 2 * distBC); + double d = (std::abs(distAC2 - 2 * distAB2) + std::abs(distAC2 - 2 * distBC2)) / distAC2; // Use cross product to figure out whether A and C are correct or flipped. // This asks whether BC x BA has a positive z component, which is the arrangement From c97736f147542ed5f48076f10e9b11f0c64a9565 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 30 Jun 2022 00:25:10 +0200 Subject: [PATCH 0310/1315] Reader: store a reference to DecodeHints vs. copies of members thereof --- core/src/Reader.h | 5 +++++ core/src/aztec/AZReader.cpp | 9 ++------- core/src/aztec/AZReader.h | 6 ++---- core/src/datamatrix/DMReader.cpp | 10 ++-------- core/src/datamatrix/DMReader.h | 5 ++--- core/src/maxicode/MCReader.cpp | 2 -- core/src/maxicode/MCReader.h | 5 ++--- core/src/oned/ODReader.cpp | 19 ++++++++----------- core/src/oned/ODReader.h | 4 ---- core/src/pdf417/PDFReader.cpp | 4 +--- core/src/pdf417/PDFReader.h | 4 +--- core/src/qrcode/QRReader.cpp | 23 +++++++++-------------- core/src/qrcode/QRReader.h | 7 ++----- 13 files changed, 36 insertions(+), 67 deletions(-) diff --git a/core/src/Reader.h b/core/src/Reader.h index 4e8a2721d8..bdc8cd0b1e 100644 --- a/core/src/Reader.h +++ b/core/src/Reader.h @@ -11,10 +11,15 @@ namespace ZXing { class BinaryBitmap; +class DecodeHints; class Reader { +protected: + const DecodeHints& _hints; + public: + explicit Reader(const DecodeHints& hints) : _hints(hints) {} virtual ~Reader() = default; virtual Result decode(const BinaryBitmap& image) const = 0; diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 4ca316c416..de452c6a6e 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -19,11 +19,6 @@ namespace ZXing::Aztec { -Reader::Reader(const DecodeHints& hints) - : _isPure(hints.isPure()) -{ -} - Result Reader::decode(const BinaryBitmap& image) const { @@ -32,7 +27,7 @@ Reader::decode(const BinaryBitmap& image) const return Result(DecodeStatus::NotFound); } - DetectorResult detectResult = Detect(*binImg, false, _isPure); + DetectorResult detectResult = Detect(*binImg, false, _hints.isPure()); DecoderResult decodeResult = DecodeStatus::NotFound; if (detectResult.isValid()) { decodeResult = Decode(detectResult); @@ -40,7 +35,7 @@ Reader::decode(const BinaryBitmap& image) const //TODO: don't start detection all over again, just to swap 2 corner points if (!decodeResult.isValid()) { - detectResult = Detect(*binImg, true, _isPure); + detectResult = Detect(*binImg, true, _hints.isPure()); if (detectResult.isValid()) { decodeResult = Decode(detectResult); } diff --git a/core/src/aztec/AZReader.h b/core/src/aztec/AZReader.h index df5a837507..c0bab4fea4 100644 --- a/core/src/aztec/AZReader.h +++ b/core/src/aztec/AZReader.h @@ -19,11 +19,9 @@ namespace Aztec { class Reader : public ZXing::Reader { public: - explicit Reader(const DecodeHints& hints); - Result decode(const BinaryBitmap& image) const override; + using ZXing::Reader::Reader; -private: - bool _isPure; + Result decode(const BinaryBitmap& image) const override; }; } // Aztec diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index a6736d85fa..ed3b93979c 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -18,12 +18,6 @@ namespace ZXing::DataMatrix { -Reader::Reader(const DecodeHints& hints) - : _tryRotate(hints.tryRotate()), - _tryHarder(hints.tryHarder()), - _isPure(hints.isPure()) -{} - Result Reader::decode(const BinaryBitmap& image) const { #ifdef __cpp_impl_coroutine @@ -34,7 +28,7 @@ Result Reader::decode(const BinaryBitmap& image) const if (binImg == nullptr) return Result(DecodeStatus::NotFound); - auto detectorResult = Detect(*binImg, _tryHarder, _tryRotate, _isPure); + auto detectorResult = Detect(*binImg, _hints.tryHarder(), _hints.tryRotate(), _hints.isPure()); if (!detectorResult.isValid()) return Result(DecodeStatus::NotFound); @@ -50,7 +44,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const return {}; Results results; - for (auto&& res : Detect(*binImg, maxSymbols > 1, _tryRotate, _isPure)) { + for (auto&& res : Detect(*binImg, maxSymbols > 1, _hints.tryRotate(), _hints.isPure())) { results.push_back(Result(Decode(res.bits()), std::move(res).position(), BarcodeFormat::DataMatrix)); if (maxSymbols > 0 && Size(results) >= maxSymbols) break; diff --git a/core/src/datamatrix/DMReader.h b/core/src/datamatrix/DMReader.h index dd472b6096..1d6706072c 100644 --- a/core/src/datamatrix/DMReader.h +++ b/core/src/datamatrix/DMReader.h @@ -17,10 +17,9 @@ namespace DataMatrix { class Reader : public ZXing::Reader { - bool _tryRotate, _tryHarder, _isPure; - public: - explicit Reader(const DecodeHints& hints); + using ZXing::Reader::Reader; + Result decode(const BinaryBitmap& image) const override; #ifdef __cpp_impl_coroutine Results decode(const BinaryBitmap& image, int maxSymbols) const override; diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index ce3c9a9125..441bb529bd 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -43,8 +43,6 @@ static BitMatrix ExtractPureBits(const BitMatrix& image) return result; } -Reader::Reader(const DecodeHints& hints) : _isPure(hints.isPure()) {} - Result Reader::decode(const BinaryBitmap& image) const { diff --git a/core/src/maxicode/MCReader.h b/core/src/maxicode/MCReader.h index 9b907d0f37..8f209c0ff7 100644 --- a/core/src/maxicode/MCReader.h +++ b/core/src/maxicode/MCReader.h @@ -18,10 +18,9 @@ namespace MaxiCode { class Reader : public ZXing::Reader { - bool _isPure; - public: - explicit Reader(const DecodeHints& hints); + using ZXing::Reader::Reader; + Result decode(const BinaryBitmap& image) const override; }; diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 8b8abc1574..823432f260 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -24,11 +24,7 @@ namespace ZXing::OneD { -Reader::Reader(const DecodeHints& hints) : - _tryHarder(hints.tryHarder()), - _tryRotate(hints.tryRotate()), - _isPure(hints.isPure()), - _minLineCount(hints.minLineCount()) +Reader::Reader(const DecodeHints& hints) : ZXing::Reader(hints) { _readers.reserve(8); @@ -225,19 +221,20 @@ static Results DoDecode(const std::vector>& readers, Result Reader::decode(const BinaryBitmap& image) const { - auto result = DoDecode(_readers, image, _tryHarder, false, _isPure, 1, _minLineCount); + auto result = DoDecode(_readers, image, _hints.tryHarder(), false, _hints.isPure(), 1, _hints.minLineCount()); - if (result.empty() && _tryRotate) - result = DoDecode(_readers, image, _tryHarder, true, _isPure, 1, _minLineCount); + if (result.empty() && _hints.tryRotate()) + result = DoDecode(_readers, image, _hints.tryHarder(), true, _hints.isPure(), 1, _hints.minLineCount()); return result.empty() ? Result(DecodeStatus::NotFound) : result.front(); } Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const { - auto resH = DoDecode(_readers, image, _tryHarder, false, _isPure, maxSymbols, _minLineCount); - if ((!maxSymbols || Size(resH) < maxSymbols) && _tryRotate) { - auto resV = DoDecode(_readers, image, _tryHarder, true, _isPure, maxSymbols - Size(resH), _minLineCount); + auto resH = DoDecode(_readers, image, _hints.tryHarder(), false, _hints.isPure(), maxSymbols, _hints.minLineCount()); + if ((!maxSymbols || Size(resH) < maxSymbols) && _hints.tryRotate()) { + auto resV = DoDecode(_readers, image, _hints.tryHarder(), true, _hints.isPure(), maxSymbols - Size(resH), + _hints.minLineCount()); resH.insert(resH.end(), resV.begin(), resV.end()); } return resH; diff --git a/core/src/oned/ODReader.h b/core/src/oned/ODReader.h index c2f5336a2e..5ccf2b43a0 100644 --- a/core/src/oned/ODReader.h +++ b/core/src/oned/ODReader.h @@ -30,10 +30,6 @@ class Reader : public ZXing::Reader private: std::vector> _readers; - bool _tryHarder; - bool _tryRotate; - bool _isPure; - int _minLineCount; }; } // OneD diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 3673a73211..7f015553ac 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -304,12 +304,10 @@ static Result DecodePure(const BinaryBitmap& image_) return Result(std::move(res), {{left, top}, {right, top}, {right, bottom}, {left, bottom}}, BarcodeFormat::PDF417); } -Reader::Reader(const DecodeHints& hints) : _isPure(hints.isPure()) {} - Result Reader::decode(const BinaryBitmap& image) const { - if (_isPure) { + if (_hints.isPure()) { auto res = DecodePure(image); if (res.error().type() != Error::Checksum) return res; diff --git a/core/src/pdf417/PDFReader.h b/core/src/pdf417/PDFReader.h index b3cd81779a..9d8be24824 100644 --- a/core/src/pdf417/PDFReader.h +++ b/core/src/pdf417/PDFReader.h @@ -24,10 +24,8 @@ namespace Pdf417 { */ class Reader : public ZXing::Reader { - bool _isPure; - public: - explicit Reader(const DecodeHints& hints); + using ZXing::Reader::Reader; Result decode(const BinaryBitmap& image) const override; Results decode(const BinaryBitmap& image, int maxSymbols) const override; diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index d87161d381..a7f2676509 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -21,17 +21,10 @@ namespace ZXing::QRCode { -Reader::Reader(const DecodeHints& hints) - : _tryHarder(hints.tryHarder()), - _isPure(hints.isPure()), - _testQR(hints.hasFormat(BarcodeFormat::QRCode)), - _testMQR(hints.hasFormat(BarcodeFormat::MicroQRCode)) -{} - Result Reader::decode(const BinaryBitmap& image) const { #if 1 - if (!_isPure) { + if (!_hints.isPure()) { auto res = decode(image, 1); return res.empty() ? Result(DecodeStatus::NotFound) : res.front(); } @@ -43,9 +36,9 @@ Result Reader::decode(const BinaryBitmap& image) const } DetectorResult detectorResult; - if (_testQR) + if (_hints.hasFormat(BarcodeFormat::QRCode)) detectorResult = DetectPureQR(*binImg); - if (_testMQR && !detectorResult.isValid()) + if (_hints.hasFormat(BarcodeFormat::MicroQRCode) && !detectorResult.isValid()) detectorResult = DetectPureMQR(*binImg); if (!detectorResult.isValid()) @@ -68,12 +61,12 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const LogMatrixWriter lmw(log, *binImg, 5, "qr-log.pnm"); #endif - auto allFPs = FindFinderPatterns(*binImg, _tryHarder); + auto allFPs = FindFinderPatterns(*binImg, _hints.tryHarder()); std::vector usedFPs; Results results; - if (_testQR) { + if (_hints.hasFormat(BarcodeFormat::QRCode)) { auto allFPSets = GenerateFinderPatternSets(allFPs); for (auto& fpSet : allFPSets) { if (Contains(usedFPs, fpSet.bl) || Contains(usedFPs, fpSet.tl) || Contains(usedFPs, fpSet.tr)) @@ -87,6 +80,8 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const usedFPs.push_back(fpSet.bl); usedFPs.push_back(fpSet.tl); usedFPs.push_back(fpSet.tr); + } + if (decoderResult.isValid(_hints.returnErrors())) { results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); if (maxSymbols && Size(results) == maxSymbols) break; @@ -95,7 +90,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const } } - if (_testMQR && !(maxSymbols && Size(results) == maxSymbols)) { + if (_hints.hasFormat(BarcodeFormat::MicroQRCode) && !(maxSymbols && Size(results) == maxSymbols)) { for (auto fp : allFPs) { if (Contains(usedFPs, fp)) continue; @@ -104,7 +99,7 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const if (detectorResult.isValid()) { auto decoderResult = Decode(detectorResult.bits()); auto position = detectorResult.position(); - if (decoderResult.isValid()) { + if (decoderResult.isValid(_hints.returnErrors())) { results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MicroQRCode); if (maxSymbols && Size(results) == maxSymbols) break; diff --git a/core/src/qrcode/QRReader.h b/core/src/qrcode/QRReader.h index 4f8454e18d..5b86edf751 100644 --- a/core/src/qrcode/QRReader.h +++ b/core/src/qrcode/QRReader.h @@ -19,13 +19,10 @@ namespace QRCode { class Reader : public ZXing::Reader { public: - explicit Reader(const DecodeHints& hints); - Result decode(const BinaryBitmap& image) const override; + using ZXing::Reader::Reader; + Result decode(const BinaryBitmap& image) const override; Results decode(const BinaryBitmap& image, int maxSymbols) const override; - -private: - bool _tryHarder, _isPure, _testQR, _testMQR; }; } // QRCode From 7f2240f9f9acf9763b461fb38931b524c906d7a9 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 30 Jun 2022 00:35:21 +0200 Subject: [PATCH 0311/1315] DecodeHints: add returnErrors property Add property to specify whether or not `ReadBarcodes` shall return symbols with errors (like ChecksumError) or only valid symbols. Add `-error` command line parameter to ZXingReader example. --- core/src/DecodeHints.h | 7 ++++++- core/src/DecoderResult.h | 5 ++++- core/src/MultiFormatReader.cpp | 23 +++++++++++------------ core/src/MultiFormatReader.h | 1 + core/src/Result.cpp | 3 ++- core/src/oned/ODReader.cpp | 16 +++++++++------- example/ZXingReader.cpp | 16 ++++++++++------ 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 1c1e9129aa..558dfc57be 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -47,6 +47,7 @@ class DecodeHints bool _validateCode39CheckSum : 1; bool _validateITFCheckSum : 1; bool _returnCodabarStartEnd : 1; + bool _returnErrors : 1; Binarizer _binarizer : 2; EanAddOnSymbol _eanAddOnSymbol : 2; @@ -59,7 +60,7 @@ class DecodeHints uint8_t _maxNumberOfSymbols = 0xff; public: - // bitfields don't get default initialized to 0. + // bitfields don't get default initialized to 0 before c++20 DecodeHints() : _tryHarder(1), _tryRotate(1), @@ -69,6 +70,7 @@ class DecodeHints _validateCode39CheckSum(0), _validateITFCheckSum(0), _returnCodabarStartEnd(0), + _returnErrors(0), _binarizer(Binarizer::LocalAverage), _eanAddOnSymbol(EanAddOnSymbol::Ignore) {} @@ -127,6 +129,9 @@ class DecodeHints /// If true, return the start and end chars in a Codabar barcode instead of stripping them. ZX_PROPERTY(bool, returnCodabarStartEnd, setReturnCodabarStartEnd) + /// If true, return the barcodes with errors as well (e.g. checksum errors, see @Result::error()) + ZX_PROPERTY(bool, returnErrors, setReturnErrors) + /// Specify whether to ignore, read or require EAN-2/5 add-on symbols while scanning EAN/UPC codes ZX_PROPERTY(EanAddOnSymbol, eanAddOnSymbol, setEanAddOnSymbol) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 0071bfae27..0175db24d4 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -47,7 +47,10 @@ class DecoderResult DecoderResult(DecoderResult&&) noexcept = default; DecoderResult& operator=(DecoderResult&&) = default; - bool isValid() const { return StatusIsOK(_status); } + bool isValid(bool includeErrors = false) const + { + return StatusIsOK(_status) || (includeErrors && _status != DecodeStatus::NotFound); + } DecodeStatus errorCode() const { return _status; } const ByteArray& rawBytes() const & { return _rawBytes; } diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 563c0397a1..38cdaf1c20 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -19,13 +19,12 @@ namespace ZXing { -MultiFormatReader::MultiFormatReader(const DecodeHints& hints) +MultiFormatReader::MultiFormatReader(const DecodeHints& hints) : _hints(hints) { - bool tryHarder = hints.tryHarder(); auto formats = hints.formats().empty() ? BarcodeFormat::Any : hints.formats(); // Put 1D readers upfront in "normal" mode - if (formats.testFlags(BarcodeFormat::OneDCodes) && !tryHarder) + if (formats.testFlags(BarcodeFormat::OneDCodes) && !hints.tryHarder()) _readers.emplace_back(new OneD::Reader(hints)); if (formats.testFlags(BarcodeFormat::QRCode | BarcodeFormat::MicroQRCode)) @@ -40,9 +39,8 @@ MultiFormatReader::MultiFormatReader(const DecodeHints& hints) _readers.emplace_back(new MaxiCode::Reader(hints)); // At end in "try harder" mode - if (formats.testFlags(BarcodeFormat::OneDCodes) && tryHarder) { + if (formats.testFlags(BarcodeFormat::OneDCodes) && hints.tryHarder()) _readers.emplace_back(new OneD::Reader(hints)); - } } MultiFormatReader::~MultiFormatReader() = default; @@ -50,17 +48,13 @@ MultiFormatReader::~MultiFormatReader() = default; Result MultiFormatReader::read(const BinaryBitmap& image) const { - // If we have only one reader in our list, just return whatever that decoded. - // This preserves information (e.g. ChecksumError) instead of just returning 'NotFound'. - if (_readers.size() == 1) - return _readers.front()->decode(image); - + Result r(DecodeStatus::NotFound); for (const auto& reader : _readers) { - Result r = reader->decode(image); + r = reader->decode(image); if (r.isValid()) return r; } - return Result(DecodeStatus::NotFound); + return _hints.returnErrors() ? r : Result(DecodeStatus::NotFound); } Results MultiFormatReader::readMultiple(const BinaryBitmap& image, int maxSymbols) const @@ -69,6 +63,11 @@ Results MultiFormatReader::readMultiple(const BinaryBitmap& image, int maxSymbol for (const auto& reader : _readers) { auto r = reader->decode(image, maxSymbols); + if (!_hints.returnErrors()) { + //TODO: C++20 res.erase_if() + auto it = std::remove_if(res.begin(), res.end(), [](auto&& r) { return !r.isValid(); }); + res.erase(it, res.end()); + } maxSymbols -= r.size(); res.insert(res.end(), std::move_iterator(r.begin()), std::move_iterator(r.end())); if (maxSymbols <= 0) diff --git a/core/src/MultiFormatReader.h b/core/src/MultiFormatReader.h index f418f229e7..a9022f246c 100644 --- a/core/src/MultiFormatReader.h +++ b/core/src/MultiFormatReader.h @@ -39,6 +39,7 @@ class MultiFormatReader private: std::vector> _readers; + const DecodeHints& _hints; }; } // ZXing diff --git a/core/src/Result.cpp b/core/src/Result.cpp index ef6f9a1214..5588cf9cb1 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -137,7 +137,8 @@ Result& Result::setCharacterSet(const std::string& defaultCS) bool Result::operator==(const Result& o) const { - if (format() != o.format() || bytes() != o.bytes()) + // two symbols may be considered the same if at least one of them has an error + if (!(format() == o.format() && (bytes() == o.bytes() || error() || o.error()))) return false; if (BarcodeFormats(BarcodeFormat::TwoDCodes).testFlag(format())) diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 823432f260..a09858a192 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -61,7 +61,7 @@ Reader::~Reader() = default; * image if "trying harder". */ static Results DoDecode(const std::vector>& readers, const BinaryBitmap& image, - bool tryHarder, bool rotate, bool isPure, int maxSymbols, int minLineCount) + bool tryHarder, bool rotate, bool isPure, int maxSymbols, int minLineCount, bool returnErrors) { Results res; @@ -134,7 +134,7 @@ static Results DoDecode(const std::vector>& readers, PatternView next(bars); do { Result result = readers[r]->decodePattern(rowNumber, next, decodingState[r]); - if (result.isValid()) { + if (result.isValid() || (returnErrors && result.error())) { result.incrementLineCount(); if (upsideDown) { // update position (flip horizontally). @@ -175,7 +175,7 @@ static Results DoDecode(const std::vector>& readers, } } - if (result.isValid()) + if (result.format() != BarcodeFormat::None) res.push_back(std::move(result)); if (maxSymbols && Reduce(res, 0, [&](int s, const Result& r) { @@ -221,20 +221,22 @@ static Results DoDecode(const std::vector>& readers, Result Reader::decode(const BinaryBitmap& image) const { - auto result = DoDecode(_readers, image, _hints.tryHarder(), false, _hints.isPure(), 1, _hints.minLineCount()); + auto result = + DoDecode(_readers, image, _hints.tryHarder(), false, _hints.isPure(), 1, _hints.minLineCount(), _hints.returnErrors()); if (result.empty() && _hints.tryRotate()) - result = DoDecode(_readers, image, _hints.tryHarder(), true, _hints.isPure(), 1, _hints.minLineCount()); + result = DoDecode(_readers, image, _hints.tryHarder(), true, _hints.isPure(), 1, _hints.minLineCount(), _hints.returnErrors()); return result.empty() ? Result(DecodeStatus::NotFound) : result.front(); } Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const { - auto resH = DoDecode(_readers, image, _hints.tryHarder(), false, _hints.isPure(), maxSymbols, _hints.minLineCount()); + auto resH = DoDecode(_readers, image, _hints.tryHarder(), false, _hints.isPure(), maxSymbols, _hints.minLineCount(), + _hints.returnErrors()); if ((!maxSymbols || Size(resH) < maxSymbols) && _hints.tryRotate()) { auto resV = DoDecode(_readers, image, _hints.tryHarder(), true, _hints.isPure(), maxSymbols - Size(resH), - _hints.minLineCount()); + _hints.minLineCount(), _hints.returnErrors()); resH.insert(resH.end(), resV.begin(), resV.end()); } return resH; diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index da8a3a3e8d..42dda3837e 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -35,6 +35,7 @@ static void PrintUsage(const char* exePath) << " -format \n" << " Only detect given format(s) (faster)\n" << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" + << " -errors Include results with errors (like checksum error)\n" << " -1 Print only file name, content/error on one line per file/barcode (implies '-escape')\n" << " -escape Escape non-graphical characters in angle brackets\n" << " -binary Write (only) the binary content of the symbol(s) to stdout\n" @@ -61,6 +62,8 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi } else if (strcmp(argv[i], "-ispure") == 0) { hints.setIsPure(true); hints.setBinarizer(Binarizer::FixedThreshold); + } else if (strcmp(argv[i], "-errors") == 0) { + hints.setReturnErrors(true); } else if (strcmp(argv[i], "-format") == 0) { if (++i == argc) return false; @@ -95,7 +98,7 @@ std::ostream& operator<<(std::ostream& os, const Position& points) return os; } -void drawLine(const ImageView& iv, PointI a, PointI b) +void drawLine(const ImageView& iv, PointI a, PointI b, bool error) { int steps = maxAbsComponent(b - a); PointF dir = bresenhamDirection(PointF(b - a)); @@ -103,15 +106,16 @@ void drawLine(const ImageView& iv, PointI a, PointI b) for (int i = 0; i < steps; ++i) { auto p = PointI(centered(a + i * dir)); auto* dst = const_cast(iv.data(p.x, p.y)); - dst[R] = dst[B] = 0; - dst[G] = 0xff; + dst[R] = error ? 0xff : 0; + dst[G] = error ? 0 : 0xff; + dst[B] = 0; } } -void drawRect(const ImageView& image, const Position& pos) +void drawRect(const ImageView& image, const Position& pos, bool error) { for (int i = 0; i < 4; ++i) - drawLine(image, pos[i], pos[(i + 1) % 4]); + drawLine(image, pos[i], pos[(i + 1) % 4], error); } std::string escapeNonGraphical(const std::string& str) @@ -168,7 +172,7 @@ int main(int argc, char* argv[]) for (auto&& result : results) { if (!outPath.empty()) - drawRect(image, result.position()); + drawRect(image, result.position(), result.error()); ret |= static_cast(result.error().type()); From 53a5d670202750d717fae846f5e01dd464bbcba8 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 30 Jun 2022 00:38:57 +0200 Subject: [PATCH 0312/1315] Error: tune QR and DM detectors to detect less obviously bogous errors --- core/src/ConcentricFinder.cpp | 4 ++++ core/src/datamatrix/DMDetector.cpp | 4 ++++ core/src/qrcode/QRDetector.cpp | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/core/src/ConcentricFinder.cpp b/core/src/ConcentricFinder.cpp index 57b94f4704..494971de51 100644 --- a/core/src/ConcentricFinder.cpp +++ b/core/src/ConcentricFinder.cpp @@ -86,6 +86,10 @@ std::optional CenterOfRings(const BitMatrix& image, PointI center, int r std::optional FinetuneConcentricPatternCenter(const BitMatrix& image, PointF center, int range, int finderPatternSize) { + // make sure we have at least one path of white around the center + if (!CenterOfRing(image, PointI(center), range, 1)) + return {}; + auto res = CenterOfRings(image, PointI(center), range, finderPatternSize / 2); if (!res || !image.get(*res)) res = CenterOfDoubleCross(image, PointI(center), range, finderPatternSize / 2 + 1); diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 5760e52114..7eb9dc20c6 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -270,6 +270,10 @@ static DetectorResult DetectOld(const BitMatrix& image) const auto& lSideOne = transitions[0]; const auto& lSideTwo = transitions[1]; + // We accept at most 4 transisions inside the L pattern (i.e. 2 corruptions) to reduce false positive FormatErrors + if (lSideTwo.transitions > 2) + return {}; + // Figure out which point is their intersection by tallying up the number of times we see the // endpoints in the four endpoints. One will show up twice. std::map pointCount; diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index f40419da53..2eb0e04c1a 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -130,6 +130,12 @@ FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) moduleCount < 21 * 0.9 || moduleCount > 177 * 1.05) continue; + // Make sure the angle between AB and BC does not deviate from 90° by more than 45° + auto alpha = std::acos((distAB2 + distBC2 - distAC2) / (2 * distAB * distBC)) / 3.1415 * 180; +// printf("alpha: %.1f\n", alpha); + if (std::isnan(alpha) || std::abs(90 - alpha) > 45) + continue; + // a^2 + b^2 = c^2 (Pythagorean theorem), and a = b (isosceles triangle). // Since any right triangle satisfies the formula c^2 - b^2 - a^2 = 0, // we need to check both two equal sides separately. From 9a3017b4f36a96ce4afc12ab55f3caffc02eed0d Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 30 Jun 2022 10:49:17 +0200 Subject: [PATCH 0313/1315] python: make `read_barcode` return `None` if no barcode is found See also https://github.com/nu-book/zxing-cpp/issues/345#issue-1279720947 --- wrappers/python/test.py | 4 +--- wrappers/python/zxing.cpp | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/wrappers/python/test.py b/wrappers/python/test.py index 8f37dbce59..ea979f9ee7 100644 --- a/wrappers/python/test.py +++ b/wrappers/python/test.py @@ -66,9 +66,7 @@ def test_failed_read(self): np.zeros((100, 100), np.uint8), formats=BF.EAN8 | BF.Aztec, binarizer=zxingcpp.Binarizer.BoolCast ) - self.assertFalse(res.valid) - self.assertEqual(res.format, BF.NONE) - self.assertEqual(res.text, '') + self.assertEqual(res, None) @unittest.skipIf(not has_pil, "need PIL for read/write tests") def test_write_read_cycle_pil(self): diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 59be2d6e24..862d024947 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -43,10 +44,8 @@ std::ostream& operator<<(std::ostream& os, const Position& points) { return os; } -template -auto read_barcode_impl(FUNC func, py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, - Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol, - uint8_t max_number_of_symbols = 0xff) +auto read_barcodes_impl(py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, Binarizer binarizer, + bool is_pure, EanAddOnSymbol ean_add_on_symbol, uint8_t max_number_of_symbols = 0xff) { const auto hints = DecodeHints() .setFormats(formats) @@ -93,21 +92,20 @@ auto read_barcode_impl(FUNC func, py::object _image, const BarcodeFormats& forma } const auto bytes = image.data(); - return func({bytes, width, height, imgfmt, width * channels, channels}, hints); + return ReadBarcodes({bytes, width, height, imgfmt, width * channels, channels}, hints); } -Result read_barcode(py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, - Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol) +std::optional read_barcode(py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, + Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol) { - return read_barcode_impl(ReadBarcode, _image, formats, try_rotate, try_downscale, binarizer, is_pure, - ean_add_on_symbol, 1); + auto res = read_barcodes_impl(_image, formats, try_rotate, try_downscale, binarizer, is_pure, ean_add_on_symbol, 1); + return res.empty() ? std::nullopt : std::optional(res.front()); } Results read_barcodes(py::object _image, const BarcodeFormats& formats, bool try_rotate, bool try_downscale, Binarizer binarizer, bool is_pure, EanAddOnSymbol ean_add_on_symbol) { - return read_barcode_impl(ReadBarcodes, _image, formats, try_rotate, try_downscale, binarizer, is_pure, - ean_add_on_symbol); + return read_barcodes_impl(_image, formats, try_rotate, try_downscale, binarizer, is_pure, ean_add_on_symbol); } Image write_barcode(BarcodeFormat format, std::string text, int width, int height, int quiet_zone, int ec_level) @@ -278,7 +276,7 @@ PYBIND11_MODULE(zxingcpp, m) ":param ean_add_on_symbol: Specify whether to Ignore, Read or Require EAN-2/5 add-on symbols while scanning \n" " EAN/UPC codes. Default is ``Ignore``.\n" ":rtype: zxing.Result\n" - ":return: a zxing result containing decoded symbol if found." + ":return: a zxing result containing decoded symbol if found, None otherwise" ); m.def("read_barcodes", &read_barcodes, py::arg("image"), From a057c14f50ee205389bd227837095650057ed034 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 30 Jun 2022 19:18:47 +0200 Subject: [PATCH 0314/1315] PDF417: implement new DecodingHints::returnErrors feature --- core/src/pdf417/PDFDetector.cpp | 19 ++++++++-------- core/src/pdf417/PDFDetector.h | 2 +- core/src/pdf417/PDFReader.cpp | 40 ++++++++++++--------------------- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 72bf872cff..003b4b4654 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -332,19 +332,17 @@ bool HasStartPattern(const BitMatrix& m) * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will * be found and returned */ -DecodeStatus -Detector::Detect(const BinaryBitmap& image, bool multiple, Result& result) +Detector::Result Detector::Detect(const BinaryBitmap& image, bool multiple) { // construct a 'dummy' shared pointer, just be able to pass it up the call chain in DecodeStatus // TODO: reimplement PDF Detector auto binImg = std::shared_ptr(image.getBitMatrix(), [](const BitMatrix*){}); - if (!binImg) { - return DecodeStatus::NotFound; - } + if (!binImg) + return {}; #if defined(ZX_FAST_BIT_STORAGE) if (!HasStartPattern(*binImg)) - return DecodeStatus::NotFound; + return {}; #endif auto barcodeCoordinates = DetectBarcode(*binImg, multiple); @@ -354,12 +352,13 @@ Detector::Detect(const BinaryBitmap& image, bool multiple, Result& result) binImg = newBits; barcodeCoordinates = DetectBarcode(*binImg, multiple); } - if (barcodeCoordinates.empty()) { - return DecodeStatus::NotFound; - } + if (barcodeCoordinates.empty()) + return {}; + + Result result; result.points = barcodeCoordinates; result.bits = binImg; - return DecodeStatus::NoError; + return result; } } // Pdf417 diff --git a/core/src/pdf417/PDFDetector.h b/core/src/pdf417/PDFDetector.h index e129d6d2c0..ab375ff1c1 100644 --- a/core/src/pdf417/PDFDetector.h +++ b/core/src/pdf417/PDFDetector.h @@ -38,7 +38,7 @@ class Detector std::list, 8>> points; }; - static DecodeStatus Detect(const BinaryBitmap& image, bool multiple, Result& result); + static Result Detect(const BinaryBitmap& image, bool multiple); }; } // Pdf417 diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 7f015553ac..c773f34a2a 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -66,31 +66,26 @@ static int GetMaxCodewordWidth(const std::array, 8>& p) std::max(GetMaxWidth(p[1], p[5]), GetMaxWidth(p[7], p[3]) * CodewordDecoder::MODULES_IN_CODEWORD / MODULES_IN_STOP_PATTERN)); } -DecodeStatus DoDecode(const BinaryBitmap& image, bool multiple, std::list& results) +static Results DoDecode(const BinaryBitmap& image, bool multiple, bool returnErrors) { - Detector::Result detectorResult; - DecodeStatus status = Detector::Detect(image, multiple, detectorResult); - if (StatusIsError(status)) { - return status; - } + Detector::Result detectorResult = Detector::Detect(image, multiple); + if (detectorResult.points.empty()) + return {}; + Results results; for (const auto& points : detectorResult.points) { DecoderResult decoderResult = ScanningDecoder::Decode(*detectorResult.bits, points[4], points[5], points[6], points[7], GetMinCodewordWidth(points), GetMaxCodewordWidth(points)); - if (decoderResult.isValid()) { + if (decoderResult.isValid(returnErrors)) { auto point = [&](int i) { return points[i].value(); }; Result result(std::move(decoderResult), {point(0), point(2), point(3), point(1)}, BarcodeFormat::PDF417); results.push_back(result); - if (!multiple) { - return DecodeStatus::NoError; - } - } - else if (!multiple) { - return decoderResult.errorCode(); + if (!multiple) + return results; } } - return results.empty() ? DecodeStatus::NotFound : DecodeStatus::NoError; + return results; } // new implementation (only for isPure use case atm.) @@ -315,27 +310,20 @@ Reader::decode(const BinaryBitmap& image) const // currently the best option to deal with 'aliased' input like e.g. 03-aliased.png } - std::list results; - DecodeStatus status = DoDecode(image, false, results); - if (StatusIsOK(status)) { - return results.front(); - } - return Result(status); + Results results = DoDecode(image, false, _hints.returnErrors()); + return results.empty() ? Result(DecodeStatus::NotFound) : results.front(); } Results Reader::decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const { - std::list results; - DoDecode(image, true, results); - return Results(results.begin(), results.end()); + return DoDecode(image, true, _hints.returnErrors()); } std::list Reader::decodeMultiple(const BinaryBitmap& image) const { - std::list results; - DoDecode(image, true, results); - return results; + Results results = DoDecode(image, true, _hints.returnErrors()); + return std::list(results.begin(), results.end()); } } // Pdf417 From 0da93e0983eea30dcfefdcfbf5832acab6de5d94 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 00:43:14 +0200 Subject: [PATCH 0315/1315] Error: implement typesafe comparison between Error and Error::Type Prevent a comparison of `Error` and `Error::Type` (via `operator bool()`) by changing `enum Type` to `enum class Type`. --- core/src/Error.h | 15 ++++++++++++--- core/src/pdf417/PDFReader.cpp | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index 6cbee9f95e..fc4d690467 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -12,20 +12,29 @@ namespace ZXing { class Error { public: - enum Type { None, Format, Checksum, Unsupported }; + enum class Type { None, Format, Checksum, Unsupported }; Type type() const noexcept { return _type; } const std::string& msg() const noexcept { return _msg; } - operator bool() const noexcept { return _type != None; } + operator bool() const noexcept { return _type != Type::None; } Error() = default; + static constexpr auto Format = Type::Format; + static constexpr auto Checksum = Type::Checksum; + static constexpr auto Unsupported = Type::Unsupported; + protected: - Type _type = None; + Type _type = Type::None; std::string _msg; Error(Type type, std::string msg) : _type(type), _msg(std::move(msg)) {} }; +inline bool operator==(const Error& e, Error::Type t) noexcept { return e.type() == t; } +inline bool operator!=(const Error& e, Error::Type t) noexcept { return !(e == t); } +inline bool operator==(Error::Type t, const Error& e) noexcept { return e.type() == t; } +inline bool operator!=(Error::Type t, const Error& e) noexcept { return !(t == e); } + class FormatError : public Error { public: diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index c773f34a2a..e731760916 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -304,7 +304,7 @@ Reader::decode(const BinaryBitmap& image) const { if (_hints.isPure()) { auto res = DecodePure(image); - if (res.error().type() != Error::Checksum) + if (res.error() != Error::Checksum) return res; // This falls through and tries the non-pure code path if we have a checksum error. This approach is // currently the best option to deal with 'aliased' input like e.g. 03-aliased.png From 0386fe9f0e74e621fe11503f33423aa59f79aa78 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 00:45:22 +0200 Subject: [PATCH 0316/1315] Error: Prepare phasing out `DecodeStatus` usage in `DecoderResult` * introduce `DecoderResult::error()` * remove `DecoderResult::errorCode()` --- core/src/DecoderResult.h | 10 ++++++---- core/src/Error.h | 12 ++++++++++++ core/src/Result.cpp | 13 ++----------- core/src/pdf417/PDFScanningDecoder.cpp | 2 +- test/unit/aztec/AZDecoderTest.cpp | 4 ++-- .../datamatrix/DMDecodedBitStreamParserTest.cpp | 6 +++--- test/unit/qrcode/MQRDecoderTest.cpp | 10 +++++----- 7 files changed, 31 insertions(+), 26 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 0175db24d4..e6682df153 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -9,6 +9,7 @@ #include "ByteArray.h" #include "Content.h" #include "DecodeStatus.h" +#include "Error.h" #include "StructuredAppend.h" #include "ZXContainerAlgorithms.h" @@ -22,7 +23,6 @@ class CustomData; class DecoderResult { - DecodeStatus _status = DecodeStatus::NoError; ByteArray _rawBytes; Content _content; int _numBits = 0; @@ -31,13 +31,15 @@ class DecoderResult StructuredAppendInfo _structuredAppend; bool _isMirrored = false; bool _readerInit = false; + Error _error; std::shared_ptr _extra; DecoderResult(const DecoderResult &) = delete; DecoderResult& operator=(const DecoderResult &) = delete; public: - DecoderResult(DecodeStatus status) : _status(status) {} + DecoderResult(DecodeStatus status) : _error(Status2Error(status)) {} + DecoderResult(Error error) : _error(error) {} DecoderResult(ByteArray&& rawBytes, Content&& bytes = {}) : _rawBytes(std::move(rawBytes)), _content(std::move(bytes)) { _numBits = 8 * Size(_rawBytes); @@ -49,9 +51,8 @@ class DecoderResult bool isValid(bool includeErrors = false) const { - return StatusIsOK(_status) || (includeErrors && _status != DecodeStatus::NotFound); + return _content.symbology.code != 0 && (!_error || includeErrors); } - DecodeStatus errorCode() const { return _status; } const ByteArray& rawBytes() const & { return _rawBytes; } ByteArray&& rawBytes() && { return std::move(_rawBytes); } @@ -81,6 +82,7 @@ class DecoderResult ZX_PROPERTY(std::string, ecLevel, setEcLevel) ZX_PROPERTY(int, lineCount, setLineCount) ZX_PROPERTY(StructuredAppendInfo, structuredAppend, setStructuredAppend) + ZX_PROPERTY(Error, error, setError) ZX_PROPERTY(bool, isMirrored, setIsMirrored) ZX_PROPERTY(bool, readerInit, setReaderInit) ZX_PROPERTY(std::shared_ptr, extra, setExtra) diff --git a/core/src/Error.h b/core/src/Error.h index fc4d690467..4b63dd8952 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -5,6 +5,8 @@ #pragma once +#include "DecodeStatus.h" + #include namespace ZXing { @@ -56,4 +58,14 @@ inline std::string ToString(const Error& e) return ret; } +// transitional helper function +inline Error Status2Error(DecodeStatus s) +{ + switch (s) { + case DecodeStatus::FormatError: return FormatError(); + case DecodeStatus::ChecksumError: return ChecksumError(); + default: return {}; + } +} + } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 5588cf9cb1..b993a13bc7 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -17,15 +17,6 @@ namespace ZXing { -static Error Status2Error(DecodeStatus s) -{ - switch (s) { - case DecodeStatus::FormatError: return FormatError(); - case DecodeStatus::ChecksumError: return ChecksumError(); - default: return {}; - } -} - Result::Result(DecodeStatus status) : _error(Status2Error(status)) {} Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, @@ -41,9 +32,9 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor {} Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format) - : _format(decodeResult.errorCode() == DecodeStatus::NotFound ? BarcodeFormat::None : format), + : _format(decodeResult.content().symbology.code == 0 ? BarcodeFormat::None : format), _content(std::move(decodeResult).content()), - _error(Status2Error(decodeResult.errorCode())), + _error(std::move(decodeResult).error()), _position(std::move(position)), _rawBytes(std::move(decodeResult).rawBytes()), _numBits(decodeResult.numBits()), diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index d946fa0a16..c73ab8e3fa 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -612,7 +612,7 @@ static DecoderResult CreateDecoderResultFromAmbiguousValues(int ecLevel, std::ve codewords[ambiguousIndexes[i]] = ambiguousIndexValues[i][ambiguousIndexCount[i]]; } auto result = DecodeCodewords(codewords, ecLevel, erasureArray); - if (result.errorCode() != DecodeStatus::ChecksumError) { + if (result.error() != Error::Checksum) { return result; } diff --git a/test/unit/aztec/AZDecoderTest.cpp b/test/unit/aztec/AZDecoderTest.cpp index 175b041405..b1b7c5cc24 100644 --- a/test/unit/aztec/AZDecoderTest.cpp +++ b/test/unit/aztec/AZDecoderTest.cpp @@ -96,7 +96,7 @@ TEST(AZDecoderTest, DecodeTooManyErrors) , 'X', true); DecoderResult result = parse(std::move(bits), true, 16, 4); - EXPECT_EQ(result.errorCode(), DecodeStatus::FormatError); + EXPECT_EQ(result.error(), Error::Format); } TEST(AZDecoderTest, DecodeTooManyErrors2) @@ -132,7 +132,7 @@ TEST(AZDecoderTest, DecodeTooManyErrors2) , 'X', true); DecoderResult result = parse(std::move(bits), true, 16, 4); - EXPECT_EQ(result.errorCode(), DecodeStatus::FormatError); + EXPECT_EQ(result.error(), Error::Format); } // Helper taking bit string to call GetEncodedData() diff --git a/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp b/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp index c6b6e8de64..1e03a453dd 100644 --- a/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp +++ b/test/unit/datamatrix/DMDecodedBitStreamParserTest.cpp @@ -54,13 +54,13 @@ TEST(DMDecodeTest, Ascii) TEST(DMDecodeTest, AsciiError) { // ASCII err on invalid code word - EXPECT_EQ(parse({66, 250, 68}).errorCode(), DecodeStatus::FormatError); + EXPECT_EQ(parse({66, 250, 68}).error(), Error::Format); // ASCII err on invalid code word at end (currently failing) - EXPECT_EQ(parse({66, 67, 68, 250}).errorCode(), DecodeStatus::FormatError); + EXPECT_EQ(parse({66, 67, 68, 250}).error(), Error::Format); // ASCII accept extra (illegal) unlatch at end - EXPECT_EQ(parse({66, 67, 68, 254}).errorCode(), DecodeStatus::NoError); + EXPECT_FALSE(parse({66, 67, 68, 254}).error()); } // Most of the following examples are taken from the DMHighLevelEncodeTest.cpp tests. diff --git a/test/unit/qrcode/MQRDecoderTest.cpp b/test/unit/qrcode/MQRDecoderTest.cpp index 34bf5add5e..25e7f700de 100644 --- a/test/unit/qrcode/MQRDecoderTest.cpp +++ b/test/unit/qrcode/MQRDecoderTest.cpp @@ -35,7 +35,7 @@ TEST(MQRDecoderTest, MQRCodeM3L) 88, false); const auto result = Decode(bitMatrix); - EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); + EXPECT_TRUE(result.isValid()); } TEST(MQRDecoderTest, MQRCodeM3M) @@ -58,7 +58,7 @@ TEST(MQRDecoderTest, MQRCodeM3M) 88, false); const auto result = Decode(bitMatrix); - EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); + EXPECT_TRUE(result.isValid()); } TEST(MQRDecoderTest, MQRCodeM1) @@ -76,7 +76,7 @@ TEST(MQRDecoderTest, MQRCodeM1) "X XXXXXX X\n", 88, false); const auto result = Decode(bitMatrix); - EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); + EXPECT_TRUE(result.isValid()); EXPECT_EQ(L"123", result.text()); } @@ -95,7 +95,7 @@ TEST(MQRDecoderTest, MQRCodeM1Error4Bits) "X XXXXXXX \n", 88, false); const auto result = Decode(bitMatrix); - EXPECT_EQ(DecodeStatus::ChecksumError, result.errorCode()); + EXPECT_EQ(Error::Checksum, result.error()); EXPECT_TRUE(result.text().empty()); } @@ -120,5 +120,5 @@ TEST(MQRDecoderTest, MQRCodeM4) "X XXXXXXX X X X\n", 88, false); const auto result = Decode(bitMatrix); - EXPECT_EQ(DecodeStatus::NoError, result.errorCode()); + EXPECT_TRUE(result.isValid()); } From af45a12e4f1d7aeed9339e24a54e7792f8e665aa Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 01:27:24 +0200 Subject: [PATCH 0317/1315] Result: introduce default constructor for "empty" / "not-found" result --- core/src/MultiFormatReader.cpp | 4 ++-- core/src/ReadBarcode.cpp | 2 +- core/src/Result.cpp | 2 +- core/src/Result.h | 1 + core/src/aztec/AZReader.cpp | 2 +- core/src/datamatrix/DMReader.cpp | 4 ++-- core/src/maxicode/MCReader.cpp | 4 ++-- core/src/oned/ODCodabarReader.cpp | 10 +++++----- core/src/oned/ODCode128Reader.cpp | 12 ++++++------ core/src/oned/ODCode39Reader.cpp | 10 +++++----- core/src/oned/ODCode93Reader.cpp | 10 +++++----- core/src/oned/ODDataBarExpandedReader.cpp | 6 +++--- core/src/oned/ODDataBarReader.cpp | 2 +- core/src/oned/ODITFReader.cpp | 6 +++--- core/src/oned/ODMultiUPCEANReader.cpp | 6 +++--- core/src/oned/ODReader.cpp | 6 +++--- core/src/pdf417/PDFReader.cpp | 8 ++++---- core/src/qrcode/QRReader.cpp | 6 +++--- example/ZXingQtReader.h | 2 +- example/ZXingReader.cpp | 2 +- test/unit/ThresholdBinarizerTest.cpp | 3 +-- 21 files changed, 54 insertions(+), 54 deletions(-) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 38cdaf1c20..d52e91d2af 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -48,13 +48,13 @@ MultiFormatReader::~MultiFormatReader() = default; Result MultiFormatReader::read(const BinaryBitmap& image) const { - Result r(DecodeStatus::NotFound); + Result r; for (const auto& reader : _readers) { r = reader->decode(image); if (r.isValid()) return r; } - return _hints.returnErrors() ? r : Result(DecodeStatus::NotFound); + return _hints.returnErrors() ? r : Result(); } Results MultiFormatReader::readMultiple(const BinaryBitmap& image, int maxSymbols) const diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 9f95eb4688..39e3ee768a 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -122,7 +122,7 @@ Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) // HACK: use the maxNumberOfSymbols value as a switch to ReadBarcodes to enable the downscaling // see python and android wrapper auto ress = ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1)); - return ress.empty() ? Result(DecodeStatus::NotFound) : ress.front(); + return ress.empty() ? Result() : ress.front(); } else { LumImage lum; ImageView iv = SetupLumImageView(_iv, lum, hints); diff --git a/core/src/Result.cpp b/core/src/Result.cpp index b993a13bc7..ae166486ae 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -147,7 +147,7 @@ bool Result::operator==(const Result& o) const Result MergeStructuredAppendSequence(const Results& results) { if (results.empty()) - return Result(DecodeStatus::NotFound); + return {}; std::list allResults(results.begin(), results.end()); allResults.sort([](const Result& r1, const Result& r2) { return r1.sequenceIndex() < r2.sequenceIndex(); }); diff --git a/core/src/Result.h b/core/src/Result.h index 41adcda416..273216799c 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -30,6 +30,7 @@ using Position = QuadrilateralI; class Result { public: + Result() noexcept = default; explicit Result(DecodeStatus status); // 1D convenience constructor diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index de452c6a6e..236ff4761f 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -24,7 +24,7 @@ Reader::decode(const BinaryBitmap& image) const { auto binImg = image.getBitMatrix(); if (binImg == nullptr) { - return Result(DecodeStatus::NotFound); + return {}; } DetectorResult detectResult = Detect(*binImg, false, _hints.isPure()); diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index ed3b93979c..c34ea646c8 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -26,11 +26,11 @@ Result Reader::decode(const BinaryBitmap& image) const #else auto binImg = image.getBitMatrix(); if (binImg == nullptr) - return Result(DecodeStatus::NotFound); + return {}; auto detectorResult = Detect(*binImg, _hints.tryHarder(), _hints.tryRotate(), _hints.isPure()); if (!detectorResult.isValid()) - return Result(DecodeStatus::NotFound); + return {}; return Result(Decode(detectorResult.bits()), std::move(detectorResult).position(), BarcodeFormat::DataMatrix); #endif diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index 441bb529bd..fc0834efb6 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -48,13 +48,13 @@ Reader::decode(const BinaryBitmap& image) const { auto binImg = image.getBitMatrix(); if (binImg == nullptr) { - return Result(DecodeStatus::NotFound); + return {}; } //TODO: this only works with effectively 'pure' barcodes. Needs proper detector. BitMatrix bits = ExtractPureBits(*binImg); if (bits.empty()) { - return Result(DecodeStatus::NotFound); + return {}; } return Result(Decode(bits), {}, BarcodeFormat::MaxiCode); diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index 0ebec78088..119911d1a9 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -61,7 +61,7 @@ CodabarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr(next, minCharCount * CHAR_LEN, IsLeftGuard); if (!next.isValid()) - return Result(DecodeStatus::NotFound); + return {}; int xStart = next.pixelsInFront(); int maxInterCharacterSpace = next.sum() / 2; // spec actually says 1 narrow space, width/2 is about 4 @@ -71,22 +71,22 @@ CodabarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr= CODE_START_A) @@ -260,13 +260,13 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu } if (Size(rawCodes) < minCharCount - 1) // stop code is missing in rawCodes - return Result(DecodeStatus::NotFound); + return {}; // check termination bar (is present and not wider than about 2 modules) and quiet zone (next is now 13 modules // wide, require at least 8) next = next.subView(0, CHAR_LEN + 1); if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuietZoneAfter(QUIET_ZONE/13)) - return Result(DecodeStatus::NotFound); + return {}; int checksum = rawCodes.front(); for (int i = 1; i < Size(rawCodes) - 1; ++i) diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index caf4d76f18..469b61628c 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -94,10 +94,10 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique next = FindLeftGuard(next, minCharCount * CHAR_LEN, START_PATTERN, QUIET_ZONE_SCALE * 12); if (!next.isValid()) - return Result(DecodeStatus::NotFound); + return {}; if (!isStartOrStopSymbol(DecodeNarrowWidePattern(next, CHARACTER_ENCODINGS, ALPHABET))) // read off the start pattern - return Result(DecodeStatus::NotFound); + return {}; int xStart = next.pixelsInFront(); int maxInterCharacterSpace = next.sum() / 2; // spec actually says 1 narrow space, width/2 is about 4 @@ -108,18 +108,18 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique do { // check remaining input width and inter-character space if (!next.skipSymbol() || !next.skipSingle(maxInterCharacterSpace)) - return Result(DecodeStatus::NotFound); + return {}; txt += DecodeNarrowWidePattern(next, CHARACTER_ENCODINGS, ALPHABET); if (txt.back() == 0) - return Result(DecodeStatus::NotFound); + return {}; } while (!isStartOrStopSymbol(txt.back())); txt.pop_back(); // remove asterisk // check txt length and whitespace after the last char. See also FindStartPattern. if (Size(txt) < minCharCount - 2 || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) - return Result(DecodeStatus::NotFound); + return {}; if (_validateCheckSum) { auto checkDigit = txt.back(); diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index 7b3552d519..4cc499205d 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -87,7 +87,7 @@ Result Code93Reader::decodePattern(int rowNumber, PatternView& next, std::unique next = FindLeftGuard(next, minCharCount * CHAR_LEN, IsStartGuard); if (!next.isValid()) - return Result(DecodeStatus::NotFound); + return {}; int xStart = next.pixelsInFront(); @@ -97,22 +97,22 @@ Result Code93Reader::decodePattern(int rowNumber, PatternView& next, std::unique do { // check remaining input width if (!next.skipSymbol()) - return Result(DecodeStatus::NotFound); + return {}; txt += LookupBitPattern(OneToFourBitPattern(next), CHARACTER_ENCODINGS, ALPHABET); if (txt.back() == 0) - return Result(DecodeStatus::NotFound); + return {}; } while (txt.back() != '*'); txt.pop_back(); // remove asterisk if (Size(txt) < minCharCount - 2) - return Result(DecodeStatus::NotFound); + return {}; // check termination bar (is present and not wider than about 2 modules) and quiet zone next = next.subView(0, CHAR_LEN + 1); if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) - return Result(DecodeStatus::NotFound); + return {}; if (!CheckChecksums(txt)) return Result(DecodeStatus::ChecksumError); diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 2260931761..6e8d59e92f 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -360,16 +360,16 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, // L R L R | r | l if (!Insert(allPairs, ReadRowOfPairs(view, rowNumber))) - return Result(DecodeStatus::NotFound); + return {}; auto pairs = FindValidSequence(allPairs); if (pairs.empty()) - return Result(DecodeStatus::NotFound); + return {}; #endif auto txt = DecodeExpandedBits(BuildBitArray(pairs)); if (txt.empty()) - return Result(DecodeStatus::NotFound); + return {}; RemovePairs(allPairs, pairs); diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index a39ec9f741..88865b6e3d 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -211,7 +211,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, // guaratee progress (see loop in ODReader.cpp) next = {}; - return Result(DecodeStatus::NotFound); + return {}; } } // namespace ZXing::OneD diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 3de5d5206c..2e4db3f3f3 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -37,7 +37,7 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt next = FindLeftGuard(next, 4 + minCharCount/2 + 3, START_PATTERN_, minQuietZone); if (!next.isValid()) - return Result(DecodeStatus::NotFound); + return {}; std::string txt; txt.reserve(20); @@ -71,10 +71,10 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt next = next.subView(0, 3); if (Size(txt) < minCharCount || !next.isValid()) - return Result(DecodeStatus::NotFound); + return {}; if (!IsRightGuard(next, STOP_PATTERN_1, minQuietZone) && !IsRightGuard(next, STOP_PATTERN_2, minQuietZone)) - return Result(DecodeStatus::NotFound); + return {}; if (_validateCheckSum && !GTIN::IsCheckDigitValid(txt)) return Result(DecodeStatus::ChecksumError); diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 92b59d379a..22da7ad2cf 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -265,7 +265,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u next = FindLeftGuard(next, minSize, END_PATTERN, QUIET_ZONE_LEFT); if (!next.isValid()) - return Result(DecodeStatus::NotFound); + return {}; PartialResult res; auto begin = next; @@ -273,7 +273,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u if (!(((_hints.hasFormat(BarcodeFormat::EAN13 | BarcodeFormat::UPCA)) && EAN13(res, begin)) || (_hints.hasFormat(BarcodeFormat::EAN8) && EAN8(res, begin)) || (_hints.hasFormat(BarcodeFormat::UPCE) && UPCE(res, begin)))) - return Result(DecodeStatus::NotFound); + return {}; if (!GTIN::IsCheckDigitValid(res.format == BarcodeFormat::UPCE ? UPCEANCommon::ConvertUPCEtoUPCA(res.txt) : res.txt)) return Result(DecodeStatus::ChecksumError); @@ -307,7 +307,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u next = res.end; if (_hints.eanAddOnSymbol() == EanAddOnSymbol::Require && !addOnRes.isValid()) - return Result(DecodeStatus::NotFound); + return {}; return {res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, symbologyIdentifier}; } diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index a09858a192..c6877f3e24 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -170,7 +170,7 @@ static Results DoDecode(const std::vector>& readers, other.setPosition(points); other.incrementLineCount(); // clear the result, so we don't insert it again below - result = Result(DecodeStatus::NotFound); + result = Result(); break; } } @@ -209,7 +209,7 @@ static Results DoDecode(const std::vector>& readers, for (auto a = res.begin(); a != res.end(); ++a) for (auto b = std::next(a); b != res.end(); ++b) if (HaveIntersectingBoundingBoxes(a->position(), b->position())) - *(a->lineCount() < b->lineCount() ? a : b) = Result(DecodeStatus::NotFound); + *(a->lineCount() < b->lineCount() ? a : b) = Result(); //TODO: C++20 res.erase_if() it = std::remove_if(res.begin(), res.end(), [](auto&& r) { return r.format() == BarcodeFormat::None; }); @@ -227,7 +227,7 @@ Reader::decode(const BinaryBitmap& image) const if (result.empty() && _hints.tryRotate()) result = DoDecode(_readers, image, _hints.tryHarder(), true, _hints.isPure(), 1, _hints.minLineCount(), _hints.returnErrors()); - return result.empty() ? Result(DecodeStatus::NotFound) : result.front(); + return result.empty() ? Result() : result.front(); } Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index e731760916..9a54180ff2 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -255,7 +255,7 @@ static Result DecodePure(const BinaryBitmap& image_) { auto pimage = image_.getBitMatrix(); if (!pimage) - return Result(DecodeStatus::NotFound); + return {}; auto& image = *pimage; #ifdef PRINT_DEBUG @@ -264,7 +264,7 @@ static Result DecodePure(const BinaryBitmap& image_) int left, top, width, height; if (!image.findBoundingBox(left, top, width, height, 9) || (width < 3 * 17 && height < 3 * 17)) - return Result(DecodeStatus::NotFound); + return {}; int right = left + width - 1; int bottom = top + height - 1; @@ -283,7 +283,7 @@ static Result DecodePure(const BinaryBitmap& image_) } if (!info) - return Result(DecodeStatus::NotFound); + return {}; auto codeWords = ReadCodeWords(cur, info); @@ -311,7 +311,7 @@ Reader::decode(const BinaryBitmap& image) const } Results results = DoDecode(image, false, _hints.returnErrors()); - return results.empty() ? Result(DecodeStatus::NotFound) : results.front(); + return results.empty() ? Result() : results.front(); } Results Reader::decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index a7f2676509..ba5c6d7478 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -26,13 +26,13 @@ Result Reader::decode(const BinaryBitmap& image) const #if 1 if (!_hints.isPure()) { auto res = decode(image, 1); - return res.empty() ? Result(DecodeStatus::NotFound) : res.front(); + return res.empty() ? Result() : res.front(); } #endif auto binImg = image.getBitMatrix(); if (binImg == nullptr) { - return Result(DecodeStatus::NotFound); + return {}; } DetectorResult detectorResult; @@ -42,7 +42,7 @@ Result Reader::decode(const BinaryBitmap& image) const detectorResult = DetectPureMQR(*binImg); if (!detectorResult.isValid()) - return Result(DecodeStatus::NotFound); + return {}; auto decoderResult = Decode(detectorResult.bits()); auto position = detectorResult.position(); diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index 58998c20c8..c2155dff9e 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -110,7 +110,7 @@ class Result : private ZXing::Result Position _position; public: - Result() : ZXing::Result(ZXing::DecodeStatus::NotFound) {} // required for qmetatype machinery + Result() = default; // required for qmetatype machinery explicit Result(ZXing::Result&& r) : ZXing::Result(std::move(r)) { _text = QString::fromStdString(ZXing::Result::text()); diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 42dda3837e..f134809807 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -160,7 +160,7 @@ int main(int argc, char* argv[]) // if we did not find anything, insert a dummy to produce some output for each file if (results.empty()) - results.emplace_back(DecodeStatus::NotFound); + results.emplace_back(); allResults.insert(allResults.end(), results.begin(), results.end()); if (filePath == filePaths.back()) { diff --git a/test/unit/ThresholdBinarizerTest.cpp b/test/unit/ThresholdBinarizerTest.cpp index aee132bdcc..d6695ba404 100644 --- a/test/unit/ThresholdBinarizerTest.cpp +++ b/test/unit/ThresholdBinarizerTest.cpp @@ -46,7 +46,6 @@ TEST(ThresholdBinarizerTest, PatternRowClear) BitMatrix bits; DecodeHints hints; std::vector buf; - Result result(DecodeStatus::NotFound); // Test that ThresholdBinarizer::getPatternRow() clears row first (same as GlobalHistogramBinarizer) // Following was failing due to OneD::DoDecode() accumulating bars in loop when using ThresholdBinarizer @@ -98,7 +97,7 @@ TEST(ThresholdBinarizerTest, PatternRowClear) hints.setFormats(BarcodeFormat::DataBarExpanded); OneD::Reader reader(hints); - result = reader.decode(ThresholdBinarizer(getImageView(buf, bits), 0x7F)); + Result result = reader.decode(ThresholdBinarizer(getImageView(buf, bits), 0x7F)); EXPECT_TRUE(result.isValid()); EXPECT_EQ(result.text(), "(91)12345678901234567890123456789012345678901234567890123456789012345678"); } From 55dd6b6db6328d706a4c64da3cbfdc378b9eb955 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 01:45:20 +0200 Subject: [PATCH 0318/1315] Result: introduce FirstOrDefault helper for `Results` to `Result` conv --- core/src/ReadBarcode.cpp | 3 +-- core/src/Result.h | 6 ++++++ core/src/oned/ODReader.cpp | 2 +- core/src/pdf417/PDFReader.cpp | 3 +-- core/src/qrcode/QRReader.cpp | 3 +-- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 39e3ee768a..5b62ff0d87 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -121,8 +121,7 @@ Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) if (hints.maxNumberOfSymbols() == 1) { // HACK: use the maxNumberOfSymbols value as a switch to ReadBarcodes to enable the downscaling // see python and android wrapper - auto ress = ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1)); - return ress.empty() ? Result() : ress.front(); + return FirstOrDefault(ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1))); } else { LumImage lum; ImageView iv = SetupLumImageView(_iv, lum, hints); diff --git a/core/src/Result.h b/core/src/Result.h index 273216799c..49485de189 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -173,6 +173,12 @@ class Result using Results = std::vector; +// Consider this an internal function that can change/disappear anytime without notice +inline Result FirstOrDefault(Results&& results) +{ + return results.empty() ? Result() : std::move(results.front()); +} + /** * @brief Merge a list of Results from one Structured Append sequence to a single result */ diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index c6877f3e24..afbd698485 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -227,7 +227,7 @@ Reader::decode(const BinaryBitmap& image) const if (result.empty() && _hints.tryRotate()) result = DoDecode(_readers, image, _hints.tryHarder(), true, _hints.isPure(), 1, _hints.minLineCount(), _hints.returnErrors()); - return result.empty() ? Result() : result.front(); + return FirstOrDefault(std::move(result)); } Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 9a54180ff2..3cdab9aa2b 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -310,8 +310,7 @@ Reader::decode(const BinaryBitmap& image) const // currently the best option to deal with 'aliased' input like e.g. 03-aliased.png } - Results results = DoDecode(image, false, _hints.returnErrors()); - return results.empty() ? Result() : results.front(); + return FirstOrDefault(DoDecode(image, false, _hints.returnErrors())); } Results Reader::decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index ba5c6d7478..7b681e9f2e 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -25,8 +25,7 @@ Result Reader::decode(const BinaryBitmap& image) const { #if 1 if (!_hints.isPure()) { - auto res = decode(image, 1); - return res.empty() ? Result() : res.front(); + return FirstOrDefault(decode(image, 1)); } #endif From 610e53c39c3cf5254de5c2a2cedfca694efb521b Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 01:53:42 +0200 Subject: [PATCH 0319/1315] c++: code style improvements (remove braces around single line if blocks) --- core/src/aztec/AZDetector.cpp | 10 ++-- core/src/aztec/AZReader.cpp | 9 ++-- core/src/datamatrix/DMDetector.cpp | 6 +-- core/src/maxicode/MCReader.cpp | 9 ++-- .../oned/rss/ODRSSExpandedBinaryDecoder.cpp | 50 ++++++++----------- core/src/qrcode/QRReader.cpp | 6 +-- 6 files changed, 35 insertions(+), 55 deletions(-) diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index 453509b29c..7c56af7829 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -496,23 +496,19 @@ DetectorResult Detect(const BitMatrix& image, bool isMirror, bool isPure) std::array bullsEyeCorners; bool compact = false; int nbCenterLayers = 0; - if (!GetBullsEyeCorners(image, pCenter, bullsEyeCorners, compact, nbCenterLayers)) { + if (!GetBullsEyeCorners(image, pCenter, bullsEyeCorners, compact, nbCenterLayers)) return {}; - } - if (isMirror) { + if (isMirror) std::swap(bullsEyeCorners[0], bullsEyeCorners[2]); - } // 3. Get the size of the matrix and other parameters from the bull's eye int nbLayers = 0; int nbDataBlocks = 0; bool readerInit = false; int shift = 0; - if (!ExtractParameters(image, bullsEyeCorners, compact, nbCenterLayers, nbLayers, nbDataBlocks, readerInit, - shift)) { + if (!ExtractParameters(image, bullsEyeCorners, compact, nbCenterLayers, nbLayers, nbDataBlocks, readerInit, shift)) return {}; - } // 4. Sample the grid return {SampleGrid(image, bullsEyeCorners[(shift + 0) % 4], bullsEyeCorners[(shift + 1) % 4], diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 236ff4761f..95e43ad8d8 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -23,22 +23,19 @@ Result Reader::decode(const BinaryBitmap& image) const { auto binImg = image.getBitMatrix(); - if (binImg == nullptr) { + if (binImg == nullptr) return {}; - } DetectorResult detectResult = Detect(*binImg, false, _hints.isPure()); DecoderResult decodeResult = DecodeStatus::NotFound; - if (detectResult.isValid()) { + if (detectResult.isValid()) decodeResult = Decode(detectResult); - } //TODO: don't start detection all over again, just to swap 2 corner points if (!decodeResult.isValid()) { detectResult = Detect(*binImg, true, _hints.isPure()); - if (detectResult.isValid()) { + if (detectResult.isValid()) decodeResult = Decode(detectResult); - } } return Result(std::move(decodeResult), std::move(detectResult).position(), BarcodeFormat::Aztec); diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 7eb9dc20c6..47078d6986 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -249,9 +249,8 @@ static void OrderByBestPatterns(const ResultPoint*& p0, const ResultPoint*& p1, static DetectorResult DetectOld(const BitMatrix& image) { ResultPoint pointA, pointB, pointC, pointD; - if (!DetectWhiteRect(image, pointA, pointB, pointC, pointD)) { + if (!DetectWhiteRect(image, pointA, pointB, pointC, pointD)) return {}; - } // Point A and D are across the diagonal from one another, // as are B and C. Figure out which are the solid black lines @@ -300,9 +299,8 @@ static DetectorResult DetectOld(const BitMatrix& image) } } - if (bottomRight == nullptr || bottomLeft == nullptr || topLeft == nullptr) { + if (bottomRight == nullptr || bottomLeft == nullptr || topLeft == nullptr) return {}; - } // Bottom left is correct but top left and bottom right might be switched // Use the dot product trick to sort them out diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index fc0834efb6..a03e8c76de 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -25,9 +25,8 @@ namespace ZXing::MaxiCode { static BitMatrix ExtractPureBits(const BitMatrix& image) { int left, top, width, height; - if (!image.findBoundingBox(left, top, width, height, BitMatrixParser::MATRIX_WIDTH)) { + if (!image.findBoundingBox(left, top, width, height, BitMatrixParser::MATRIX_WIDTH)) return {}; - } // Now just read off the bits BitMatrix result(BitMatrixParser::MATRIX_WIDTH, BitMatrixParser::MATRIX_HEIGHT); @@ -47,15 +46,13 @@ Result Reader::decode(const BinaryBitmap& image) const { auto binImg = image.getBitMatrix(); - if (binImg == nullptr) { + if (binImg == nullptr) return {}; - } //TODO: this only works with effectively 'pure' barcodes. Needs proper detector. BitMatrix bits = ExtractPureBits(*binImg); - if (bits.empty()) { + if (bits.empty()) return {}; - } return Result(Decode(bits), {}, BarcodeFormat::MaxiCode); } diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp index 1ebe6237f9..5c513c2cd6 100644 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp +++ b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp @@ -104,9 +104,9 @@ static std::string DecodeAI01AndOtherAIs(const BitArray& bits) buffer.append(std::to_string(firstGtinDigit)); AI01EncodeCompressedGtinWithoutAI(buffer, bits, HEADER_SIZE + 4, initialGtinPosition); - if (StatusIsOK(DecodeAppIdAllCodes(bits, HEADER_SIZE + 44, -1, buffer))) { + if (StatusIsOK(DecodeAppIdAllCodes(bits, HEADER_SIZE + 44, -1, buffer))) return buffer; - } + return {}; } @@ -114,9 +114,9 @@ static std::string DecodeAnyAI(const BitArray& bits) { static const int HEADER_SIZE = 2 + 1 + 2; std::string buffer; - if (StatusIsOK(DecodeAppIdAllCodes(bits, HEADER_SIZE, -1, buffer))) { + if (StatusIsOK(DecodeAppIdAllCodes(bits, HEADER_SIZE, -1, buffer))) return buffer; - } + return {}; } @@ -125,9 +125,8 @@ static std::string DecodeAI013103(const BitArray& bits) static const int HEADER_SIZE = 4 + 1; static const int WEIGHT_SIZE = 15; - if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) { + if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) return {}; - } std::string buffer; AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); @@ -145,9 +144,8 @@ static std::string DecodeAI01320x(const BitArray& bits) static const int HEADER_SIZE = 4 + 1; static const int WEIGHT_SIZE = 15; - if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) { + if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) return {}; - } std::string buffer; AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); @@ -166,9 +164,8 @@ static std::string DecodeAI01392x(const BitArray& bits) static const int HEADER_SIZE = 5 + 1 + 2; static const int LAST_DIGIT_SIZE = 2; - if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) { + if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) return {}; - } std::string buffer; AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); @@ -193,9 +190,8 @@ static std::string DecodeAI01393x(const BitArray& bits) static const int LAST_DIGIT_SIZE = 2; static const int FIRST_THREE_DIGITS_SIZE = 10; - if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) { + if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) return {}; - } std::string buffer; AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); @@ -207,12 +203,12 @@ static std::string DecodeAI01393x(const BitArray& bits) buffer.push_back(')'); int firstThreeDigits = ToInt(bits, HEADER_SIZE + AI01_GTIN_SIZE + LAST_DIGIT_SIZE, FIRST_THREE_DIGITS_SIZE); - if (firstThreeDigits / 100 == 0) { + if (firstThreeDigits / 100 == 0) buffer.push_back('0'); - } - if (firstThreeDigits / 10 == 0) { + + if (firstThreeDigits / 10 == 0) buffer.push_back('0'); - } + buffer.append(std::to_string(firstThreeDigits)); int pos = HEADER_SIZE + AI01_GTIN_SIZE + LAST_DIGIT_SIZE + FIRST_THREE_DIGITS_SIZE; @@ -230,9 +226,8 @@ static std::string DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdig static const int WEIGHT_SIZE = 20; static const int DATE_SIZE = 16; - if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE) { + if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE) return {}; - } std::string buffer; AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); @@ -262,17 +257,17 @@ static std::string DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdig numericDate /= 12; int year = numericDate; - if (year / 10 == 0) { + if (year / 10 == 0) buffer.push_back('0'); - } + buffer.append(std::to_string(year)); - if (month / 10 == 0) { + if (month / 10 == 0) buffer.push_back('0'); - } + buffer.append(std::to_string(month)); - if (day / 10 == 0) { + if (day / 10 == 0) buffer.push_back('0'); - } + buffer.append(std::to_string(day)); } @@ -281,12 +276,11 @@ static std::string DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdig std::string DecodeExpandedBits(const BitArray& bits) { - if (bits.get(1)) { + if (bits.get(1)) return DecodeAI01AndOtherAIs(bits); - } - if (!bits.get(2)) { + + if (!bits.get(2)) return DecodeAnyAI(bits); - } int fourBitEncodationMethod = ToInt(bits, 1, 4); diff --git a/core/src/qrcode/QRReader.cpp b/core/src/qrcode/QRReader.cpp index 7b681e9f2e..7d825f7f82 100644 --- a/core/src/qrcode/QRReader.cpp +++ b/core/src/qrcode/QRReader.cpp @@ -24,15 +24,13 @@ namespace ZXing::QRCode { Result Reader::decode(const BinaryBitmap& image) const { #if 1 - if (!_hints.isPure()) { + if (!_hints.isPure()) return FirstOrDefault(decode(image, 1)); - } #endif auto binImg = image.getBitMatrix(); - if (binImg == nullptr) { + if (binImg == nullptr) return {}; - } DetectorResult detectorResult; if (_hints.hasFormat(BarcodeFormat::QRCode)) From 0be27beb2318d41642308994851f492f63d4f7dc Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 02:01:33 +0200 Subject: [PATCH 0320/1315] Result: fix gcc build regression (noexcept default constructor) --- core/src/Result.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/Result.h b/core/src/Result.h index 49485de189..befd92e3b8 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -30,7 +30,7 @@ using Position = QuadrilateralI; class Result { public: - Result() noexcept = default; + Result() = default; explicit Result(DecodeStatus status); // 1D convenience constructor From 94a4c443999f0bc705061fc5cb41a75bc396d821 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 09:39:11 +0200 Subject: [PATCH 0321/1315] Error: switch PDFDecodedBitStreamParser to exception based error handling Format errors in ReedSolomon corrected bits are very exceptional. See also other matrix decoders. --- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 154 +++++++----------- test/unit/pdf417/PDF417DecoderTest.cpp | 40 ++--- 2 files changed, 74 insertions(+), 120 deletions(-) diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index b481549f29..f7f493d300 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -256,7 +256,7 @@ static int ProcessTextECI(std::vector& textCompactionData, int& index, cons * @param result The data in the character set encoding. * @return The next index into the codeword array. */ -static int TextCompaction(DecodeStatus& status, const std::vector& codewords, int codeIndex, Content& result) +static int TextCompaction(const std::vector& codewords, int codeIndex, Content& result) { // 2 characters per codeword std::vector textCompactionData((codewords[0] - codeIndex) * 2, 0); @@ -293,10 +293,9 @@ static int TextCompaction(DecodeStatus& status, const std::vector& codeword codeIndex = ProcessTextECI(textCompactionData, index, codewords, codeIndex, code); break; default: - if (!TerminatesCompaction(code)) { - status = DecodeStatus::FormatError; - return codeIndex; - } + if (!TerminatesCompaction(code)) + throw FormatError(); + codeIndex--; end = true; break; @@ -311,7 +310,7 @@ static int TextCompaction(DecodeStatus& status, const std::vector& codeword * Helper for Byte Compaction to look ahead and count 5-codeword batches and trailing bytes, with some checking of * format errors. */ -static int CountByteBatches(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, int& trailingCount) +static int CountByteBatches(int mode, const std::vector& codewords, int codeIndex, int& trailingCount) { int count = 0; trailingCount = 0; @@ -319,26 +318,22 @@ static int CountByteBatches(DecodeStatus& status, int mode, const std::vector= TEXT_COMPACTION_MODE_LATCH) { - if (mode == BYTE_COMPACTION_MODE_LATCH_6 && count && count % 5) { - status = DecodeStatus::FormatError; - return 0; - } + if (mode == BYTE_COMPACTION_MODE_LATCH_6 && count && count % 5) + throw FormatError(); + if (IsECI(code)) { codeIndex += code == ECI_GENERAL_PURPOSE ? 2 : 1; continue; } - if (!TerminatesCompaction(code)) { - status = DecodeStatus::FormatError; - return 0; - } + if (!TerminatesCompaction(code)) + throw FormatError(); break; } count++; } - if (codeIndex > codewords[0]) { - status = DecodeStatus::FormatError; - return 0; - } + if (codeIndex > codewords[0]) + throw FormatError(); + if (count == 0) return 0; @@ -349,10 +344,8 @@ static int CountByteBatches(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, Con * @param result The data in the character set encoding. * @return The next index into the codeword array. */ -static int ByteCompaction(DecodeStatus& status, int mode, const std::vector& codewords, int codeIndex, - Content& result) +static int ByteCompaction(int mode, const std::vector& codewords, int codeIndex, Content& result) { // Count number of 5-codeword batches and trailing bytes int trailingCount; - int batches = CountByteBatches(status, mode, codewords, codeIndex, trailingCount); - - if (StatusIsError(status)) - return codeIndex; + int batches = CountByteBatches(mode, codewords, codeIndex, trailingCount); // Deal with initial ECIs codeIndex = ProcessByteECIs(codewords, codeIndex, result); @@ -463,7 +452,7 @@ Decode the above codewords involves Remove leading 1 => Result is 000213298174000 */ -static DecodeStatus DecodeBase900toBase10(const std::vector& codewords, int count, std::string& resultString) +static std::string DecodeBase900toBase10(const std::vector& codewords, int count) { // Table containing values for the exponent of 900. static const auto EXP900 = []() { @@ -479,12 +468,11 @@ static DecodeStatus DecodeBase900toBase10(const std::vector& codewords, int for (int i = 0; i < count; i++) result += EXP900[count - i - 1] * codewords[i]; - resultString = result.toString(); - if (!resultString.empty() && resultString.front() == '1') { - resultString = resultString.substr(1); - return DecodeStatus::NoError; - } - return DecodeStatus::FormatError; + std::string resultString = result.toString(); + if (!resultString.empty() && resultString.front() == '1') + return resultString.substr(1); + + throw FormatError(); } @@ -498,7 +486,7 @@ static DecodeStatus DecodeBase900toBase10(const std::vector& codewords, int * @param encoding Currently active character encoding. * @return The next index into the codeword array. */ -static int NumericCompaction(DecodeStatus& status, const std::vector& codewords, int codeIndex, Content& result) +static int NumericCompaction(const std::vector& codewords, int codeIndex, Content& result) { int count = 0; bool end = false; @@ -512,21 +500,15 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew // As operating in Basic Channel Mode (i.e. not embedding backslashed ECIs and doubling backslashes) // allow ECIs anywhere in Numeric Compaction (i.e. ISO/IEC 15438:2015 5.5.3.4 doesn't apply). if (count > 0) { - std::string tmp; - status = DecodeBase900toBase10(numericCodewords, count, tmp); - if (StatusIsError(status)) - return codeIndex; - - result += tmp; + result += DecodeBase900toBase10(numericCodewords, count); count = 0; } codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, result); continue; } - if (!TerminatesCompaction(code)) { - status = DecodeStatus::FormatError; - return codeIndex; - } + if (!TerminatesCompaction(code)) + throw FormatError(); + codeIndex--; end = true; } @@ -543,12 +525,7 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew // current Numeric Compaction mode grouping as described in 5.4.4.2, // and then to start a new one grouping. if (count > 0) { - std::string tmp; - status = DecodeBase900toBase10(numericCodewords, count, tmp); - if (StatusIsError(status)) - return codeIndex; - - result += tmp; + result += DecodeBase900toBase10(numericCodewords, count); count = 0; } } @@ -559,14 +536,14 @@ static int NumericCompaction(DecodeStatus& status, const std::vector& codew /* * Helper to deal with optional text fields in Macros. */ -static int DecodeMacroOptionalTextField(DecodeStatus& status, const std::vector& codewords, int codeIndex, std::string& field) +static int DecodeMacroOptionalTextField(const std::vector& codewords, int codeIndex, std::string& field) { Content result; // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 // for non-ASCII (128-255). Text optional fields can contain ECIs. result.defaultCharset = "Cp437"; - codeIndex = TextCompaction(status, codewords, codeIndex, result); + codeIndex = TextCompaction(codewords, codeIndex, result); // Converting to UTF-8 (backward-incompatible change for non-ASCII chars) field = result.utf8(); @@ -577,15 +554,14 @@ static int DecodeMacroOptionalTextField(DecodeStatus& status, const std::vector< /* * Helper to deal with optional numeric fields in Macros. */ -static int DecodeMacroOptionalNumericField(DecodeStatus& status, const std::vector& codewords, int codeIndex, - uint64_t& field) +static int DecodeMacroOptionalNumericField(const std::vector& codewords, int codeIndex, uint64_t& field) { Content result; // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 // for non-ASCII (128-255). Text optional fields can contain ECIs. result.defaultCharset = "Cp437"; - codeIndex = NumericCompaction(status, codewords, codeIndex, result); + codeIndex = NumericCompaction(codewords, codeIndex, result); field = std::stoll(result.utf8()); @@ -593,21 +569,17 @@ static int DecodeMacroOptionalNumericField(DecodeStatus& status, const std::vect } ZXING_EXPORT_TEST_ONLY -DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderResultExtra& resultMetadata, - int& next) +int DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderResultExtra& resultMetadata) { // we must have at least two bytes left for the segment index if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) - return DecodeStatus::FormatError; + throw FormatError(); std::vector segmentIndexArray(NUMBER_OF_SEQUENCE_CODEWORDS); for (int i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) segmentIndexArray[i] = codewords[codeIndex]; - std::string strBuf; - DecodeStatus status = DecodeBase900toBase10(segmentIndexArray, NUMBER_OF_SEQUENCE_CODEWORDS, strBuf); - if (StatusIsError(status)) - return status; + std::string strBuf = DecodeBase900toBase10(segmentIndexArray, NUMBER_OF_SEQUENCE_CODEWORDS); resultMetadata.setSegmentIndex(std::stoi(strBuf)); @@ -636,47 +608,47 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, switch (codewords[codeIndex]) { case MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: { std::string fileName; - codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, fileName); + codeIndex = DecodeMacroOptionalTextField(codewords, codeIndex + 1, fileName); resultMetadata.setFileName(fileName); break; } case MACRO_PDF417_OPTIONAL_FIELD_SENDER: { std::string sender; - codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, sender); + codeIndex = DecodeMacroOptionalTextField(codewords, codeIndex + 1, sender); resultMetadata.setSender(sender); break; } case MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE: { std::string addressee; - codeIndex = DecodeMacroOptionalTextField(status, codewords, codeIndex + 1, addressee); + codeIndex = DecodeMacroOptionalTextField(codewords, codeIndex + 1, addressee); resultMetadata.setAddressee(addressee); break; } case MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: { uint64_t segmentCount; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, segmentCount); + codeIndex = DecodeMacroOptionalNumericField(codewords, codeIndex + 1, segmentCount); resultMetadata.setSegmentCount(static_cast(segmentCount)); break; } case MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: { uint64_t timestamp; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, timestamp); + codeIndex = DecodeMacroOptionalNumericField(codewords, codeIndex + 1, timestamp); resultMetadata.setTimestamp(timestamp); break; } case MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: { uint64_t checksum; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, checksum); + codeIndex = DecodeMacroOptionalNumericField(codewords, codeIndex + 1, checksum); resultMetadata.setChecksum(static_cast(checksum)); break; } case MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: { uint64_t fileSize; - codeIndex = DecodeMacroOptionalNumericField(status, codewords, codeIndex + 1, fileSize); + codeIndex = DecodeMacroOptionalNumericField(codewords, codeIndex + 1, fileSize); resultMetadata.setFileSize(fileSize); break; } - default: status = DecodeStatus::FormatError; break; + default: throw FormatError(); } break; } @@ -685,10 +657,7 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, resultMetadata.setLastSegment(true); break; } - default: status = DecodeStatus::FormatError; break; - } - if (StatusIsError(status)) { - return status; + default: throw FormatError(); } } @@ -702,8 +671,7 @@ DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, codewords.begin() + optionalFieldsStart + optionalFieldsLength)); } - next = codeIndex; - return DecodeStatus::NoError; + return codeIndex; } DecoderResult @@ -715,25 +683,24 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel) bool readerInit = false; auto resultMetadata = std::make_shared(); int codeIndex = 1; - DecodeStatus status = DecodeStatus::NoError; - while (codeIndex < codewords[0] && status == DecodeStatus::NoError) { + while (codeIndex < codewords[0]) { int code = codewords[codeIndex++]; switch (code) { case TEXT_COMPACTION_MODE_LATCH: - codeIndex = TextCompaction(status, codewords, codeIndex, result); + codeIndex = TextCompaction(codewords, codeIndex, result); break; case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: // This should only be encountered once in this loop, when default Text Compaction mode applies // (see default case below) - codeIndex = TextCompaction(status, codewords, codeIndex - 1, result); + codeIndex = TextCompaction(codewords, codeIndex - 1, result); break; case BYTE_COMPACTION_MODE_LATCH: case BYTE_COMPACTION_MODE_LATCH_6: - codeIndex = ByteCompaction(status, code, codewords, codeIndex, result); + codeIndex = ByteCompaction(code, codewords, codeIndex, result); break; case NUMERIC_COMPACTION_MODE_LATCH: - codeIndex = NumericCompaction(status, codewords, codeIndex, result); + codeIndex = NumericCompaction(codewords, codeIndex, result); break; case ECI_CHARSET: case ECI_GENERAL_PURPOSE: @@ -741,45 +708,42 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel) codeIndex = ProcessECI(codewords, codeIndex, codewords[0], code, result); break; case BEGIN_MACRO_PDF417_CONTROL_BLOCK: - status = DecodeMacroBlock(codewords, codeIndex, *resultMetadata, codeIndex); + codeIndex = DecodeMacroBlock(codewords, codeIndex, *resultMetadata); break; case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: case MACRO_PDF417_TERMINATOR: // Should not see these outside a macro block - status = DecodeStatus::FormatError; + throw FormatError(); break; case READER_INIT: if (codeIndex != 2) // Must be first codeword after symbol length (ISO/IEC 15438:2015 5.4.1.4) - status = DecodeStatus::FormatError; + throw FormatError(); else readerInit = true; break; case LINKAGE_EANUCC: if (codeIndex != 2) // Must be first codeword after symbol length (GS1 Composite ISO/IEC 24723:2010 4.3) - status = DecodeStatus::FormatError; + throw FormatError(); // TODO: handle else case break; case LINKAGE_OTHER: // Allowed to treat as invalid by ISO/IEC 24723:2010 5.4.1.5 and 5.4.6.1 when in Basic Channel Mode - status = DecodeStatus::FormatError; // TODO: add NotSupported error + throw FormatError(); // TODO: add NotSupported error break; default: if (code >= TEXT_COMPACTION_MODE_LATCH) { // Reserved codewords (all others in switch) // Allowed to treat as invalid by ISO/IEC 24723:2010 5.4.6.1 when in Basic Channel Mode - status = DecodeStatus::FormatError; // TODO: add NotSupported error + throw FormatError(); // TODO: add NotSupported error } else { // Default mode is Text Compaction mode Alpha sub-mode (ISO/IEC 15438:2015 5.4.2.1) - codeIndex = TextCompaction(status, codewords, codeIndex - 1, result); + codeIndex = TextCompaction(codewords, codeIndex - 1, result); } break; } } - if (StatusIsError(status)) - return status; - if (result.empty() && resultMetadata->segmentIndex() == -1) - return DecodeStatus::FormatError; + return FormatError(); StructuredAppendInfo sai; if (resultMetadata->segmentIndex() > -1) { diff --git a/test/unit/pdf417/PDF417DecoderTest.cpp b/test/unit/pdf417/PDF417DecoderTest.cpp index 55b902cd3f..c08f83ab0a 100644 --- a/test/unit/pdf417/PDF417DecoderTest.cpp +++ b/test/unit/pdf417/PDF417DecoderTest.cpp @@ -11,9 +11,9 @@ #include "gtest/gtest.h" -namespace ZXing { namespace Pdf417 { - DecodeStatus DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderResultExtra& resultMetadata, int& next); -}} +namespace ZXing::Pdf417 { +int DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderResultExtra& resultMetadata); +} using namespace ZXing; using namespace ZXing::Pdf417; @@ -21,7 +21,11 @@ using namespace ZXing::Pdf417; // Shorthand for Decode() static DecoderResult parse(const std::vector& codewords, int ecLevel = 0) { - return DecodedBitStreamParser::Decode(codewords, ecLevel); + try { + return DecodedBitStreamParser::Decode(codewords, ecLevel); + } catch (Error e) { + return e; + } } /** @@ -33,10 +37,8 @@ TEST(PDF417DecoderTest, StandardSample1) // we should never reach these 1000, 1000, 1000 }; - int next = 0; DecoderResultExtra resultMetadata; - auto status = DecodeMacroBlock(sampleCodes, 2, resultMetadata, next); - EXPECT_EQ(status, DecodeStatus::NoError); + DecodeMacroBlock(sampleCodes, 2, resultMetadata); EXPECT_EQ(0, resultMetadata.segmentIndex()); EXPECT_EQ("017053", resultMetadata.fileId()); @@ -65,10 +67,8 @@ TEST(PDF417DecoderTest, StandardSample2) // we should never reach these 1000, 1000, 1000 }; - int next = 0; DecoderResultExtra resultMetadata; - auto status = DecodeMacroBlock(sampleCodes, 2, resultMetadata, next); - EXPECT_EQ(status, DecodeStatus::NoError); + DecodeMacroBlock(sampleCodes, 2, resultMetadata); EXPECT_EQ(3, resultMetadata.segmentIndex()); EXPECT_EQ("017053", resultMetadata.fileId()); @@ -95,10 +95,8 @@ TEST(PDF417DecoderTest, StandardSample3) { std::vector sampleCodes = { 7, 928, 111, 100, 100, 200, 300 }; - int next = 0; DecoderResultExtra resultMetadata; - auto status = DecodeMacroBlock(sampleCodes, 2, resultMetadata, next); - EXPECT_EQ(status, DecodeStatus::NoError); + DecodeMacroBlock(sampleCodes, 2, resultMetadata); EXPECT_EQ(0, resultMetadata.segmentIndex()); EXPECT_EQ("100200300", resultMetadata.fileId()); @@ -117,10 +115,8 @@ TEST(PDF417DecoderTest, SampleWithFilename) 599, 923, 1, 111, 102, 98, 311, 355, 522, 920, 779, 40, 628, 33, 749, 267, 506, 213, 928, 465, 248, 493, 72, 780, 699, 780, 493, 755, 84, 198, 628, 368, 156, 198, 809, 19, 113 }; - int next = 0; DecoderResultExtra resultMetadata; - auto status = DecodeMacroBlock(sampleCodes, 3, resultMetadata, next); - EXPECT_EQ(status, DecodeStatus::NoError); + DecodeMacroBlock(sampleCodes, 3, resultMetadata); EXPECT_EQ(0, resultMetadata.segmentIndex()); EXPECT_EQ("000252021086", resultMetadata.fileId()); @@ -142,10 +138,8 @@ TEST(PDF417DecoderTest, SampleWithNumericValues) std::vector sampleCodes = { 25, 477, 928, 111, 100, 0, 252, 21, 86, 923, 2, 2, 0, 1, 0, 0, 0, 923, 5, 130, 923, 6, 1, 500, 13 }; - int next = 0; DecoderResultExtra resultMetadata; - auto status = DecodeMacroBlock(sampleCodes, 3, resultMetadata, next); - EXPECT_EQ(status, DecodeStatus::NoError); + DecodeMacroBlock(sampleCodes, 3, resultMetadata); EXPECT_EQ(0, resultMetadata.segmentIndex()); EXPECT_EQ("000252021086", resultMetadata.fileId()); @@ -167,10 +161,8 @@ TEST(PDF417DecoderTest, SampleWithMacroTerminatorOnly) { std::vector sampleCodes = { 7, 477, 928, 222, 198, 0, 922 }; - int next = 0; DecoderResultExtra resultMetadata; - auto status = DecodeMacroBlock(sampleCodes, 3, resultMetadata, next); - EXPECT_EQ(status, DecodeStatus::NoError); + DecodeMacroBlock(sampleCodes, 3, resultMetadata); EXPECT_EQ(99998, resultMetadata.segmentIndex()); EXPECT_EQ("000", resultMetadata.fileId()); @@ -522,10 +514,8 @@ TEST(PDF417DecoderTest, ECIMacroOptionalNumeric) std::vector sampleCodes = { 19, 477, 928, 111, 100, 0, 252, 21, 86, 923, 5, 15, 369, 753, 190, 927, 25, 124, 745 }; - int next = 0; DecoderResultExtra resultMetadata; - auto status = DecodeMacroBlock(sampleCodes, 3, resultMetadata, next); - EXPECT_EQ(status, DecodeStatus::NoError); + DecodeMacroBlock(sampleCodes, 3, resultMetadata); EXPECT_EQ(0, resultMetadata.segmentIndex()); EXPECT_EQ("000252021086", resultMetadata.fileId()); From 4186c76257e595748ec2bd11f70d06760265a416 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 09:43:29 +0200 Subject: [PATCH 0322/1315] Error: switch to `DecoderResult(Error)` constructor from `DecodeStatus` --- core/src/DecoderResult.h | 4 +--- core/src/aztec/AZDecoder.cpp | 6 +++--- core/src/aztec/AZReader.cpp | 2 +- core/src/datamatrix/DMDecoder.cpp | 10 +++++----- core/src/maxicode/MCDecoder.cpp | 8 ++++---- core/src/pdf417/PDFScanningDecoder.cpp | 27 ++++++++++++++------------ core/src/qrcode/QRDecoder.cpp | 12 ++++++------ 7 files changed, 35 insertions(+), 34 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index e6682df153..7c54337f55 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -8,7 +8,6 @@ #include "ByteArray.h" #include "Content.h" -#include "DecodeStatus.h" #include "Error.h" #include "StructuredAppend.h" #include "ZXContainerAlgorithms.h" @@ -38,14 +37,13 @@ class DecoderResult DecoderResult& operator=(const DecoderResult &) = delete; public: - DecoderResult(DecodeStatus status) : _error(Status2Error(status)) {} + DecoderResult() = default; DecoderResult(Error error) : _error(error) {} DecoderResult(ByteArray&& rawBytes, Content&& bytes = {}) : _rawBytes(std::move(rawBytes)), _content(std::move(bytes)) { _numBits = 8 * Size(_rawBytes); } - DecoderResult() = default; DecoderResult(DecoderResult&&) noexcept = default; DecoderResult& operator=(DecoderResult&&) = default; diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index ebb7c6c083..1fb152515f 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -307,11 +307,11 @@ DecoderResult Decode(const BitArray& bits) try { DecodeContent(bits, res); } catch (const std::out_of_range&) { // see ReadBits() - return DecodeStatus::FormatError; + return FormatError(); } if (res.bytes.empty()) - return DecodeStatus::FormatError; + return FormatError(); // Check for Structured Append - need 4 5-bit words, beginning with ML UL, ending with index and count bool haveStructuredAppend = Size(bits) > 20 && ToInt(bits, 0, 5) == 29 // latch to MIXED (from UPPER) @@ -351,7 +351,7 @@ DecoderResult Decode(const DetectorResult& detectorResult) BitArray bits = CorrectBits(detectorResult, ExtractBits(detectorResult)); if (!bits.size()) - return DecodeStatus::FormatError; + return FormatError(); return Decode(bits).setReaderInit(detectorResult.readerInit()); } diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 95e43ad8d8..56f45040e7 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -27,7 +27,7 @@ Reader::decode(const BinaryBitmap& image) const return {}; DetectorResult detectResult = Detect(*binImg, false, _hints.isPure()); - DecoderResult decodeResult = DecodeStatus::NotFound; + DecoderResult decodeResult; if (detectResult.isValid()) decodeResult = Decode(detectResult); diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 8284833b17..186d291ca8 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -352,7 +352,7 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) #ifndef NDEBUG printf("DMDecoder error: %s\n", e.what()); #endif - return DecodeStatus::FormatError; + return FormatError(); } result.append(resultTrailer); @@ -396,17 +396,17 @@ static DecoderResult DoDecode(const BitMatrix& bits) // Construct a parser and read version, error-correction level const Version* version = VersionForDimensionsOf(bits); if (version == nullptr) - return DecodeStatus::FormatError; + return FormatError(); // Read codewords ByteArray codewords = CodewordsFromBitMatrix(bits); if (codewords.empty()) - return DecodeStatus::FormatError; + return FormatError(); // Separate into data blocks std::vector dataBlocks = GetDataBlocks(codewords, *version); if (dataBlocks.empty()) - return DecodeStatus::FormatError; + return FormatError(); // Count total number of data bytes ByteArray resultBytes(TransformReduce(dataBlocks, 0, [](const auto& db) { return db.numDataCodewords; })); @@ -418,7 +418,7 @@ static DecoderResult DoDecode(const BitMatrix& bits) ByteArray& codewordBytes = dataBlock.codewords; int numDataCodewords = dataBlock.numDataCodewords; if (!CorrectErrors(codewordBytes, numDataCodewords)) - return DecodeStatus::ChecksumError; + return ChecksumError(); for (int i = 0; i < numDataCodewords; i++) { // De-interlace data blocks. diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 30a6b87913..cbf875ac71 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -305,7 +305,7 @@ DecoderResult Decode(const BitMatrix& bits) ByteArray codewords = BitMatrixParser::ReadCodewords(bits); if (!CorrectErrors(codewords, 0, 10, 10, ALL)) - return DecodeStatus::ChecksumError; + return ChecksumError(); int mode = codewords[0] & 0x0F; ByteArray datawords; @@ -317,15 +317,15 @@ DecoderResult Decode(const BitMatrix& bits) if (CorrectErrors(codewords, 20, 84, 40, EVEN) && CorrectErrors(codewords, 20, 84, 40, ODD)) datawords.resize(94, 0); else - return DecodeStatus::ChecksumError; + return ChecksumError(); break; case 5: // Full ECC if (CorrectErrors(codewords, 20, 68, 56, EVEN) && CorrectErrors(codewords, 20, 68, 56, ODD)) datawords.resize(78, 0); else - return DecodeStatus::ChecksumError; + return ChecksumError(); break; - default: return DecodeStatus::FormatError; + default: return FormatError(); } std::copy_n(codewords.begin(), 10, datawords.begin()); diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index c73ab8e3fa..895404ca1b 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -570,20 +570,23 @@ static bool VerifyCodewordCount(std::vector& codewords, int numECCodewords) DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const std::vector& erasures) { - if (codewords.empty()) { - return DecodeStatus::FormatError; - } + if (codewords.empty()) + return FormatError(); int numECCodewords = 1 << (ecLevel + 1); int correctedErrorsCount = 0; if (!CorrectErrors(codewords, erasures, numECCodewords, correctedErrorsCount)) - return DecodeStatus::ChecksumError; + return ChecksumError(); if (!VerifyCodewordCount(codewords, numECCodewords)) - return DecodeStatus::FormatError; + return FormatError(); // Decode the codewords - return DecodedBitStreamParser::Decode(codewords, ecLevel); + try { + return DecodedBitStreamParser::Decode(codewords, ecLevel); + } catch (Error e) { + return e; + } } @@ -617,7 +620,7 @@ static DecoderResult CreateDecoderResultFromAmbiguousValues(int ecLevel, std::ve } if (ambiguousIndexCount.empty()) { - return DecodeStatus::ChecksumError; + return ChecksumError(); } for (size_t i = 0; i < ambiguousIndexCount.size(); i++) { if (ambiguousIndexCount[i] < Size(ambiguousIndexValues[i]) - 1) { @@ -627,12 +630,12 @@ static DecoderResult CreateDecoderResultFromAmbiguousValues(int ecLevel, std::ve else { ambiguousIndexCount[i] = 0; if (i == ambiguousIndexCount.size() - 1) { - return DecodeStatus::ChecksumError; + return ChecksumError(); } } } } - return DecodeStatus::ChecksumError; + return ChecksumError(); } @@ -640,7 +643,7 @@ static DecoderResult CreateDecoderResult(DetectionResult& detectionResult) { auto barcodeMatrix = CreateBarcodeMatrix(detectionResult); if (!AdjustCodewordCount(detectionResult, barcodeMatrix)) { - return DecodeStatus::NotFound; + return {}; } std::vector erasures; std::vector codewords(detectionResult.barcodeRowCount() * detectionResult.barcodeColumnCount(), 0); @@ -678,7 +681,7 @@ ScanningDecoder::Decode(const BitMatrix& image, const Nullable& ima { BoundingBox boundingBox; if (!BoundingBox::Create(image.width(), image.height(), imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight, boundingBox)) { - return DecodeStatus::NotFound; + return {}; } Nullable leftRowIndicatorColumn, rightRowIndicatorColumn; @@ -691,7 +694,7 @@ ScanningDecoder::Decode(const BitMatrix& image, const Nullable& ima rightRowIndicatorColumn = GetRowIndicatorColumn(image, boundingBox, imageTopRight, false, minCodewordWidth, maxCodewordWidth); } if (!Merge(leftRowIndicatorColumn, rightRowIndicatorColumn, detectionResult)) { - return DecodeStatus::NotFound; + return {}; } if (i == 0 && detectionResult.getBoundingBox() != nullptr && (detectionResult.getBoundingBox().value().minY() < boundingBox.minY() || detectionResult.getBoundingBox().value().maxY() > boundingBox.maxY())) { boundingBox = detectionResult.getBoundingBox(); diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 90d80b2723..1af47dd5dc 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -333,7 +333,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo #ifndef NDEBUG printf("QRDecoder error: %s\n", e.what()); #endif - return DecodeStatus::FormatError; + return FormatError(); } return DecoderResult(std::move(bytes), std::move(result)) @@ -345,22 +345,22 @@ DecoderResult Decode(const BitMatrix& bits) { const Version* pversion = ReadVersion(bits); if (!pversion) - return DecodeStatus::FormatError; + return FormatError(); const Version& version = *pversion; auto formatInfo = ReadFormatInformation(bits, version.isMicroQRCode()); if (!formatInfo.isValid()) - return DecodeStatus::FormatError; + return FormatError(); // Read codewords ByteArray codewords = ReadCodewords(bits, version, formatInfo); if (codewords.empty()) - return DecodeStatus::FormatError; + return FormatError(); // Separate into data blocks std::vector dataBlocks = DataBlock::GetDataBlocks(codewords, version, formatInfo.ecLevel); if (dataBlocks.empty()) - return DecodeStatus::FormatError; + return FormatError(); // Count total number of data bytes const auto op = [](auto totalBytes, const auto& dataBlock){ return totalBytes + dataBlock.numDataCodewords();}; @@ -375,7 +375,7 @@ DecoderResult Decode(const BitMatrix& bits) int numDataCodewords = dataBlock.numDataCodewords(); if (!CorrectErrors(codewordBytes, numDataCodewords)) - return DecodeStatus::ChecksumError; + return ChecksumError(); resultIterator = std::copy_n(codewordBytes.begin(), numDataCodewords, resultIterator); } From 24b737365358bdb0e404e65cb70d0071362159f7 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 1 Jul 2022 16:17:16 +0200 Subject: [PATCH 0323/1315] GS1: introduce general purpose `HRIFromGS1` function This a cleaned up and generalized (handle `` delimiters) version of what was formerly implemented as part of the DataBar decoder. --- core/CMakeLists.txt | 4 +- .../rss/ODRSSFieldParser.cpp => GS1.cpp} | 96 ++-- core/src/GS1.h | 14 + core/src/oned/rss/ODRSSFieldParser.h | 20 - .../src/oned/rss/ODRSSGenericAppIdDecoder.cpp | 18 +- test/unit/CMakeLists.txt | 2 +- test/unit/GS1Test.cpp | 346 +++++++++++++++ test/unit/oned/rss/ODRSSFieldParserTest.cpp | 420 ------------------ 8 files changed, 421 insertions(+), 499 deletions(-) rename core/src/{oned/rss/ODRSSFieldParser.cpp => GS1.cpp} (65%) create mode 100644 core/src/GS1.h delete mode 100644 core/src/oned/rss/ODRSSFieldParser.h create mode 100644 test/unit/GS1Test.cpp delete mode 100644 test/unit/oned/rss/ODRSSFieldParserTest.cpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d59ed2d818..fa5df9058d 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -101,6 +101,8 @@ if (BUILD_READERS) src/GlobalHistogramBinarizer.cpp src/GridSampler.h src/GridSampler.cpp + src/GS1.h + src/GS1.cpp src/HybridBinarizer.h src/HybridBinarizer.cpp src/ImageView.h @@ -313,8 +315,6 @@ if (BUILD_READERS) set (ONED_RSS_FILES ${ONED_RSS_FILES} src/oned/rss/ODRSSExpandedBinaryDecoder.h src/oned/rss/ODRSSExpandedBinaryDecoder.cpp - src/oned/rss/ODRSSFieldParser.h - src/oned/rss/ODRSSFieldParser.cpp src/oned/rss/ODRSSGenericAppIdDecoder.h src/oned/rss/ODRSSGenericAppIdDecoder.cpp ) diff --git a/core/src/oned/rss/ODRSSFieldParser.cpp b/core/src/GS1.cpp similarity index 65% rename from core/src/oned/rss/ODRSSFieldParser.cpp rename to core/src/GS1.cpp index 6551cf1acf..ab0ab598bc 100644 --- a/core/src/oned/rss/ODRSSFieldParser.cpp +++ b/core/src/GS1.cpp @@ -1,27 +1,30 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 -#include "ODRSSFieldParser.h" +#include "GS1.h" -#include "DecodeStatus.h" #include "ZXContainerAlgorithms.h" -#include -#include -#include -#include - -namespace ZXing::OneD::DataBar { - - //private static final Object VARIABLE_LENGTH = new Object(); +namespace ZXing { struct AiInfo { - const char* aiPrefix; - int fieldSize; // if negative, the length is variable and abs(length) give the max size + std::string_view aiPrefix; + int _fieldSize; // if negative, the length is variable and abs(length) give the max size + + bool isVariableLength() const noexcept { return _fieldSize < 0; } + int fieldSize() const noexcept { return std::abs(_fieldSize); } + int aiSize() const + { + if ((aiPrefix[0] == '3' && Contains("1234569", aiPrefix[1])) || aiPrefix == "703" || aiPrefix == "723") + return 4; + else + return Size(aiPrefix); + } }; // GS1 General Specifications Release 22.0 (Jan 22, 2022) @@ -230,48 +233,49 @@ static const AiInfo aiInfos[] = { { "8200", -70 }, }; -static size_t -AiSize(const char* aiPrefix) +std::string HRIFromGS1(const std::string& gs1) { - if ((aiPrefix[0] == '3' && Contains("1234569", aiPrefix[1])) || std::string(aiPrefix) == "703" - || std::string(aiPrefix) == "723") - return 4; - else - return strlen(aiPrefix); -} + //TODO: c++20 + auto starts_with = [](std::string_view str, std::string_view pre) { return str.substr(0, pre.size()) == pre; }; + constexpr char GS = 29; // GS character (29 / 0x1D) + std::string_view rem = gs1; + std::string res; -DecodeStatus -ParseFieldsInGeneralPurpose(const std::string &rawInfo, std::string& result) -{ - if (rawInfo.empty()) { - return DecodeStatus::NoError; - } + while (rem.size()) { + const AiInfo* i = FindIf(aiInfos, [&](const AiInfo& i) { return starts_with(rem, i.aiPrefix); }); + if (i == std::end(aiInfos)) + return {}; - auto starts_with = - [](const std::string& str, const char* pre) { return strncmp(pre, str.data(), strlen(pre)) == 0; }; + int aiSize = i->aiSize(); + if (Size(rem) < aiSize) + return {}; - const AiInfo* aiInfo = FindIf(aiInfos, [&](const AiInfo& i) { return starts_with(rawInfo, i.aiPrefix); }); - if (aiInfo == std::end(aiInfos)) - return DecodeStatus::NotFound; + res += '('; + res += rem.substr(0, aiSize); + res += ')'; + rem.remove_prefix(aiSize); - size_t aiSize = AiSize(aiInfo->aiPrefix); + int fieldSize = i->fieldSize(); + if (i->isVariableLength()) { + auto gsPos = rem.find(GS); + fieldSize = std::min(gsPos == std::string_view::npos ? Size(rem) : static_cast(gsPos), fieldSize); + } + if (fieldSize == 0 || Size(rem) < fieldSize) + return {}; - // require at least one character in the variable field size case - if (rawInfo.length() < aiSize + std::max(1, aiInfo->fieldSize)) - return DecodeStatus::NotFound; + res += rem.substr(0, fieldSize); + rem.remove_prefix(fieldSize); - size_t fieldSize = aiInfo->fieldSize >= 0 - ? size_t(aiInfo->fieldSize) // fixed - : std::min(rawInfo.length() - aiSize, size_t(-aiInfo->fieldSize)); // variable + if (Size(rem) && rem.front() == GS) { + if (i->isVariableLength()) + rem.remove_prefix(1); + else + return {}; + } + } - auto ai = rawInfo.substr(0, aiSize); - auto field = rawInfo.substr(aiSize, fieldSize); - auto remaining = rawInfo.substr(aiSize + fieldSize); - std::string parsedRemaining; - auto status = ParseFieldsInGeneralPurpose(remaining, parsedRemaining); - result = '(' + ai + ')' + field + parsedRemaining; - return status; + return res; } -} // namespace ZXing::OneD::DataBar +} // namespace ZXing diff --git a/core/src/GS1.h b/core/src/GS1.h new file mode 100644 index 0000000000..50b579a8a9 --- /dev/null +++ b/core/src/GS1.h @@ -0,0 +1,14 @@ +/* + * Copyright 2022 Axel Waggershauser + */ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +namespace ZXing { + +std::string HRIFromGS1(const std::string& gs1); + +} // namespace ZXing diff --git a/core/src/oned/rss/ODRSSFieldParser.h b/core/src/oned/rss/ODRSSFieldParser.h deleted file mode 100644 index 0d24839429..0000000000 --- a/core/src/oned/rss/ODRSSFieldParser.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -*/ -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -namespace ZXing { - -enum class DecodeStatus; - -namespace OneD::DataBar { - -DecodeStatus ParseFieldsInGeneralPurpose(const std::string &rawInfo, std::string& result); - -} // namespace OneD::DataBar -} // namespace ZXing diff --git a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp b/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp index 5064abfd71..eee7c9e4e7 100644 --- a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp +++ b/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp @@ -8,7 +8,7 @@ #include "BitArray.h" #include "DecodeStatus.h" -#include "ODRSSFieldParser.h" +#include "GS1.h" #include #include @@ -409,7 +409,6 @@ ParseBlocks(const BitArray& bits, ParsingState& state, std::string& buffer) ParseAlphaBlock(bits, state, buffer) : (state.encoding == ParsingState::ISO_IEC_646 ? ParseIsoIec646Block(bits, state, buffer) : - // else ParseNumericBlock(bits, state, buffer)); if (result.isValid() || initialPosition == state.position) { @@ -460,14 +459,16 @@ DecodeAppIdAllCodes(const BitArray& bits, int pos, int remainingValue, std::stri while (true) { state.position = pos; DecodedInformation info = DoDecodeGeneralPurposeField(state, bits, remaining); - std::string parsedFields; - auto status = ParseFieldsInGeneralPurpose(info.newString, parsedFields); - if (StatusIsError(status)) { - if (result.empty() && remaining.empty()){ + if (pos == info.newPosition || info.newString.empty()) // No step forward! + break; + + std::string parsedFields = HRIFromGS1(info.newString); + if (parsedFields.empty()) { + if (result.empty() && remaining.empty()) { result = info.newString; return DecodeStatus::NoError; } else - return status; + return DecodeStatus::FormatError; } result += parsedFields; if (info.isRemaining()) { @@ -477,9 +478,6 @@ DecodeAppIdAllCodes(const BitArray& bits, int pos, int remainingValue, std::stri remaining.clear(); } - if (pos == info.newPosition) {// No step forward! - break; - } pos = info.newPosition; }; return DecodeStatus::NoError; diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 96ddb9b60e..45f609c1f5 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable (UnitTest CharacterSetECITest.cpp ContentTest.cpp GTINTest.cpp + GS1Test.cpp ReedSolomonTest.cpp TextDecoderTest.cpp TextUtfEncodingTest.cpp @@ -45,7 +46,6 @@ add_executable (UnitTest oned/ODUPCAWriterTest.cpp oned/ODUPCEWriterTest.cpp oned/rss/ODRSSExpandedBinaryDecoderTest.cpp - oned/rss/ODRSSFieldParserTest.cpp qrcode/MQRDecoderTest.cpp qrcode/QRBitMatrixParserTest.cpp qrcode/QRDataMaskTest.cpp diff --git a/test/unit/GS1Test.cpp b/test/unit/GS1Test.cpp new file mode 100644 index 0000000000..122e09228a --- /dev/null +++ b/test/unit/GS1Test.cpp @@ -0,0 +1,346 @@ +/* + * Copyright 2022 gitlost + */ +// SPDX-License-Identifier: Apache-2.0 + +#include "GS1.h" + +#include "gtest/gtest.h" + +using namespace ZXing; + +TEST(HRIFromGS1, Single) +{ + // 2-digit AIs + + // Fixed length + EXPECT_EQ(HRIFromGS1("00123456789012345678"), "(00)123456789012345678"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("0012345678901234567"), ""); + EXPECT_EQ(HRIFromGS1("001234567890123456789"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("16123456"), "(16)123456"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("1612345"), ""); + EXPECT_EQ(HRIFromGS1("161234567"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("2212345678901234567890"), "(22)12345678901234567890"); + EXPECT_EQ(HRIFromGS1("221234567890123456789"), "(22)1234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("22123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("91123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"), + "(91)123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("9112345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"), + "(91)12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("911234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("99123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"), + "(99)123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("9912345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"), + "(99)12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("991234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901"), ""); + + // 3-digit AIs + + EXPECT_EQ(HRIFromGS1("310"), ""); // incomplete prefix + + // Max length + EXPECT_EQ(HRIFromGS1("2351234567890123456789012345678"), "(235)1234567890123456789012345678"); + EXPECT_EQ(HRIFromGS1("235123456789012345678901234567"), "(235)123456789012345678901234567"); + // Too long + EXPECT_EQ(HRIFromGS1("23512345678901234567890123456789"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("24312345678901234567890"), "(243)12345678901234567890"); + EXPECT_EQ(HRIFromGS1("2431234567890123456789"), "(243)1234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("243123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("253123456789012345678901234567890"), "(253)123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("25312345678901234567890123456789"), "(253)12345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("2531234567890123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("2551234567890123456789012345"), "(255)1234567890123456789012345"); + EXPECT_EQ(HRIFromGS1("255123456789012345678901234"), "(255)123456789012345678901234"); + // Too long + EXPECT_EQ(HRIFromGS1("25512345678901234567890123456"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("4151234567890123"), "(415)1234567890123"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("415123456789012"), ""); + EXPECT_EQ(HRIFromGS1("41512345678901234"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("4171234567890123"), "(417)1234567890123"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("417123456789012"), ""); + EXPECT_EQ(HRIFromGS1("41712345678901234"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("421123456789012"), "(421)123456789012"); + EXPECT_EQ(HRIFromGS1("42112345678901"), "(421)12345678901"); + // Too long + EXPECT_EQ(HRIFromGS1("4211234567890123"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("425123456789012345"), "(425)123456789012345"); + EXPECT_EQ(HRIFromGS1("42512345678901234"), "(425)12345678901234"); + // Too long + EXPECT_EQ(HRIFromGS1("4251234567890123456"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("427123"), "(427)123"); + EXPECT_EQ(HRIFromGS1("42712"), "(427)12"); + // Too long + EXPECT_EQ(HRIFromGS1("4271234"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("71012345678901234567890"), "(710)12345678901234567890"); + EXPECT_EQ(HRIFromGS1("7101234567890123456789"), "(710)1234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("710123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("71512345678901234567890"), "(715)12345678901234567890"); + EXPECT_EQ(HRIFromGS1("7151234567890123456789"), "(715)1234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("715123456789012345678901"), ""); + + // 4-digit variable 4th + + // Fixed length + EXPECT_EQ(HRIFromGS1("3370123456"), "(3370)123456"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("337012345"), ""); + EXPECT_EQ(HRIFromGS1("33701234567"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("3375123456"), "(3375)123456"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("33751234567"), ""); + EXPECT_EQ(HRIFromGS1("337512345"), ""); + + // EXPECT_EQ(ParseFieldsInGeneralPurpose("3376123456"), // Allow although > max 3375 + + // Fixed length + EXPECT_EQ(HRIFromGS1("39401234"), "(3940)1234"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("394012345"), ""); + EXPECT_EQ(HRIFromGS1("3940123"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("39431234"), "(3943)1234"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("394312345"), ""); + EXPECT_EQ(HRIFromGS1("3943123"), ""); + + // EXPECT_EQ(ParseFieldsInGeneralPurpose("39441234"), // Allow although > max 3943 + + // Fixed length + EXPECT_EQ(HRIFromGS1("3950123456"), "(3950)123456"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("39501234567"), ""); + EXPECT_EQ(HRIFromGS1("395012345"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("3955123456"), "(3955)123456"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("39551234567"), ""); + EXPECT_EQ(HRIFromGS1("395512345"), ""); + + // EXPECT_EQ(ParseFieldsInGeneralPurpose("3956123456"), // Allow although > max 3955 + + // Max length + EXPECT_EQ(HRIFromGS1("7230123456789012345678901234567890"), "(7230)123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("723012345678901234567890123456789"), "(7230)12345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("72301234567890123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("7239123456789012345678901234567890"), "(7239)123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("723912345678901234567890123456789"), "(7239)12345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("72391234567890123456789012345678901"), ""); + + // 4-digit AIs + + // Max length + EXPECT_EQ(HRIFromGS1("430012345678901234567890123456789012345"), "(4300)12345678901234567890123456789012345"); + EXPECT_EQ(HRIFromGS1("43001234567890123456789012345678901234"), "(4300)1234567890123456789012345678901234"); + // Too long + EXPECT_EQ(HRIFromGS1("4300123456789012345678901234567890123456"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("430712"), "(4307)12"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("4307123"), ""); + EXPECT_EQ(HRIFromGS1("43071"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("4308123456789012345678901234567890"), "(4308)123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("430812345678901234567890123456789"), "(4308)12345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("43081234567890123456789012345678901"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("431712"), "(4317)12"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("4317123"), ""); + EXPECT_EQ(HRIFromGS1("43171"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("431812345678901234567890"), "(4318)12345678901234567890"); + EXPECT_EQ(HRIFromGS1("43181234567890123456789"), "(4318)1234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("4318123456789012345678901"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("43211"), "(4321)1"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("432112"), ""); + EXPECT_EQ(HRIFromGS1("4321"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("4326123456"), "(4326)123456"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("43261234567"), ""); + EXPECT_EQ(HRIFromGS1("432612345"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("70041234"), "(7004)1234"); + EXPECT_EQ(HRIFromGS1("7004123"), "(7004)123"); + // Too long + EXPECT_EQ(HRIFromGS1("700412345"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("7006123456"), "(7006)123456"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("70061234567"), ""); + EXPECT_EQ(HRIFromGS1("700612345"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("701012"), "(7010)12"); + EXPECT_EQ(HRIFromGS1("70101"), "(7010)1"); + // Too long + EXPECT_EQ(HRIFromGS1("7010123"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("702012345678901234567890"), "(7020)12345678901234567890"); + EXPECT_EQ(HRIFromGS1("70201234567890123456789"), "(7020)1234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("7020123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("7023123456789012345678901234567890"), "(7023)123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("702312345678901234567890123456789"), "(7023)12345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("70231234567890123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("70401234"), "(7040)1234"); + EXPECT_EQ(HRIFromGS1("704012345"), ""); + // Too long + EXPECT_EQ(HRIFromGS1("7040123"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("724012345678901234567890"), "(7240)12345678901234567890"); + EXPECT_EQ(HRIFromGS1("72401234567890123456789"), "(7240)1234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("7240123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("80071234567890123456789012345678901234"), "(8007)1234567890123456789012345678901234"); + EXPECT_EQ(HRIFromGS1("8007123456789012345678901234567890123"), "(8007)123456789012345678901234567890123"); + // Too long + EXPECT_EQ(HRIFromGS1("800712345678901234567890123456789012345"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("800912345678901234567890123456789012345678901234567890"), + + "(8009)12345678901234567890123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("80091234567890123456789012345678901234567890123456789"), + + "(8009)1234567890123456789012345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("8009123456789012345678901234567890123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("80131234567890123456789012345"), "(8013)1234567890123456789012345"); + EXPECT_EQ(HRIFromGS1("8013123456789012345678901234"), "(8013)123456789012345678901234"); + // Too long + EXPECT_EQ(HRIFromGS1("801312345678901234567890123456"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("8017123456789012345678"), "(8017)123456789012345678"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("80171234567890123456789"), ""); + EXPECT_EQ(HRIFromGS1("801712345678901234567"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("80191234567890"), "(8019)1234567890"); + EXPECT_EQ(HRIFromGS1("8019123456789"), "(8019)123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("801912345678901"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("8026123456789012345678"), "(8026)123456789012345678"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("80261234567890123456789"), ""); + EXPECT_EQ(HRIFromGS1("802612345678901234567"), ""); + + // Non-existing + EXPECT_EQ(HRIFromGS1("8100123456"), ""); + EXPECT_EQ(HRIFromGS1("81011234567890"), ""); + EXPECT_EQ(HRIFromGS1("810212"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("81101234567890123456789012345678901234567890123456789012345678901234567890"), + "(8110)1234567890123456789012345678901234567890123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("8110123456789012345678901234567890123456789012345678901234567890123456789"), + "(8110)123456789012345678901234567890123456789012345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("811012345678901234567890123456789012345678901234567890123456789012345678901"), ""); + + // Fixed length + EXPECT_EQ(HRIFromGS1("81111234"), "(8111)1234"); + // Incorrect lengths + EXPECT_EQ(HRIFromGS1("811112345"), ""); + EXPECT_EQ(HRIFromGS1("8111123"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("81121234567890123456789012345678901234567890123456789012345678901234567890"), + "(8112)1234567890123456789012345678901234567890123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("8112123456789012345678901234567890123456789012345678901234567890123456789"), + "(8112)123456789012345678901234567890123456789012345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("811212345678901234567890123456789012345678901234567890123456789012345678901"), ""); + + // Max length + EXPECT_EQ(HRIFromGS1("82001234567890123456789012345678901234567890123456789012345678901234567890"), + "(8200)1234567890123456789012345678901234567890123456789012345678901234567890"); + EXPECT_EQ(HRIFromGS1("8200123456789012345678901234567890123456789012345678901234567890123456789"), + "(8200)123456789012345678901234567890123456789012345678901234567890123456789"); + // Too long + EXPECT_EQ(HRIFromGS1("820012345678901234567890123456789012345678901234567890123456789012345678901"), ""); +} + +TEST(HRIFromGS1, MultiFixed) +{ + EXPECT_EQ(HRIFromGS1("81111234430712"), "(8111)1234(4307)12"); +} + +TEST(HRIFromGS1, MultiVariable) +{ + EXPECT_EQ(HRIFromGS1("70041234\x1d""81111234"), "(7004)1234(8111)1234"); +} diff --git a/test/unit/oned/rss/ODRSSFieldParserTest.cpp b/test/unit/oned/rss/ODRSSFieldParserTest.cpp deleted file mode 100644 index a6cf3ffd79..0000000000 --- a/test/unit/oned/rss/ODRSSFieldParserTest.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* -* Copyright 2022 gitlost -*/ -// SPDX-License-Identifier: Apache-2.0 - -#include "oned/rss/ODRSSFieldParser.h" - -#include "DecodeStatus.h" - -#include "gtest/gtest.h" - -using namespace ZXing; -using namespace ZXing::OneD::DataBar; - -TEST(ODRSSFieldParserTest, ParseFieldsInGeneralPurpose) -{ - std::string result; - - // 2-digit AIs - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("00123456789012345678", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(00)123456789012345678"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("0012345678901234567", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("001234567890123456789", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("16123456", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(16)123456"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("1612345", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("161234567", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("2212345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(22)12345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("221234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(22)1234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("22123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("9112345678901234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(91)123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("9112345678901234567890123456789012345678901234567890" - "123456789012345678901234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(91)12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("9112345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("9912345678901234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(99)123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("9912345678901234567890123456789012345678901234567890" - "123456789012345678901234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(99)12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("9912345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901", result), DecodeStatus::NotFound); - - // 3-digit AIs - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("2351234567890123456789012345678", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(235)1234567890123456789012345678"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("235123456789012345678901234567", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(235)123456789012345678901234567"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("23512345678901234567890123456789", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("24312345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(243)12345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("2431234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(243)1234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("243123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("253123456789012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(253)123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("25312345678901234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(253)12345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("2531234567890123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("2551234567890123456789012345", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(255)1234567890123456789012345"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("255123456789012345678901234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(255)123456789012345678901234"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("25512345678901234567890123456", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("4151234567890123", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(415)1234567890123"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("415123456789012", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("41512345678901234", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("4171234567890123", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(417)1234567890123"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("417123456789012", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("41712345678901234", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("421123456789012", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(421)123456789012"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("42112345678901", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(421)12345678901"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("4211234567890123", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("425123456789012345", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(425)123456789012345"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("42512345678901234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(425)12345678901234"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("4251234567890123456", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("427123", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(427)123"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("42712", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(427)12"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("4271234", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("71012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(710)12345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("7101234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(710)1234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("710123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("71512345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(715)12345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("7151234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(715)1234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("715123456789012345678901", result), DecodeStatus::NotFound); - - // 4-digit variable 4th - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("3370123456", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(3370)123456"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("337012345", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("33701234567", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("3375123456", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(3375)123456"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("33751234567", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("337512345", result), DecodeStatus::NotFound); - - EXPECT_EQ(ParseFieldsInGeneralPurpose("3376123456", result), DecodeStatus::NoError); // Allow although > max 3375 - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("39401234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(3940)1234"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("394012345", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("3940123", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("39431234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(3943)1234"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("394312345", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("3943123", result), DecodeStatus::NotFound); - - EXPECT_EQ(ParseFieldsInGeneralPurpose("39441234", result), DecodeStatus::NoError); // Allow although > max 3943 - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("3950123456", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(3950)123456"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("39501234567", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("395012345", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("3955123456", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(3955)123456"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("39551234567", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("395512345", result), DecodeStatus::NotFound); - - EXPECT_EQ(ParseFieldsInGeneralPurpose("3956123456", result), DecodeStatus::NoError); // Allow although > max 3955 - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("7230123456789012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7230)123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("723012345678901234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7230)12345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("72301234567890123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("7239123456789012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7239)123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("723912345678901234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7239)12345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("72391234567890123456789012345678901", result), DecodeStatus::NotFound); - - // 4-digit AIs - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("430012345678901234567890123456789012345", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4300)12345678901234567890123456789012345"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("43001234567890123456789012345678901234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4300)1234567890123456789012345678901234"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("4300123456789012345678901234567890123456", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("430712", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4307)12"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("4307123", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("43071", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("4308123456789012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4308)123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("430812345678901234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4308)12345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("43081234567890123456789012345678901", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("431712", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4317)12"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("4317123", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("43171", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("431812345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4318)12345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("43181234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4318)1234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("4318123456789012345678901", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("43211", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4321)1"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("432112", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("4321", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("4326123456", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(4326)123456"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("43261234567", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("432612345", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("70041234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7004)1234"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("7004123", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7004)123"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("700412345", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("7006123456", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7006)123456"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("70061234567", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("700612345", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("701012", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7010)12"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("70101", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7010)1"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("7010123", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("702012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7020)12345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("70201234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7020)1234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("7020123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("7023123456789012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7023)123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("702312345678901234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7023)12345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("70231234567890123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("70401234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7040)1234"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("704012345", result), DecodeStatus::NotFound); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("7040123", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("724012345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7240)12345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("72401234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(7240)1234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("7240123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("80071234567890123456789012345678901234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8007)1234567890123456789012345678901234"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("8007123456789012345678901234567890123", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8007)123456789012345678901234567890123"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("800712345678901234567890123456789012345", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("800912345678901234567890123456789012345678901234567890", result), - DecodeStatus::NoError); - EXPECT_EQ(result, "(8009)12345678901234567890123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("80091234567890123456789012345678901234567890123456789", result), - DecodeStatus::NoError); - EXPECT_EQ(result, "(8009)1234567890123456789012345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("8009123456789012345678901234567890123456789012345678901", result), - DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("80131234567890123456789012345", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8013)1234567890123456789012345"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("8013123456789012345678901234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8013)123456789012345678901234"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("801312345678901234567890123456", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("8017123456789012345678", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8017)123456789012345678"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("80171234567890123456789", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("801712345678901234567", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("80191234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8019)1234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("8019123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8019)123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("801912345678901", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("8026123456789012345678", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8026)123456789012345678"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("80261234567890123456789", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("802612345678901234567", result), DecodeStatus::NotFound); - - // Non-existing - EXPECT_EQ(ParseFieldsInGeneralPurpose("8100123456", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("81011234567890", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("810212", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("811012345678901234567890123456789012345678901234567890" - "12345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8110)1234567890123456789012345678901234567890123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("811012345678901234567890123456789012345678901234567890" - "1234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8110)123456789012345678901234567890123456789012345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("811012345678901234567890123456789012345678901234567890" - "123456789012345678901", result), DecodeStatus::NotFound); - - // Fixed length - EXPECT_EQ(ParseFieldsInGeneralPurpose("81111234", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8111)1234"); - // Incorrect lengths - EXPECT_EQ(ParseFieldsInGeneralPurpose("811112345", result), DecodeStatus::NotFound); - EXPECT_EQ(ParseFieldsInGeneralPurpose("8111123", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("811212345678901234567890123456789012345678901234567890" - "12345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8112)1234567890123456789012345678901234567890123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("811212345678901234567890123456789012345678901234567890" - "1234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8112)123456789012345678901234567890123456789012345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("811212345678901234567890123456789012345678901234567890" - "123456789012345678901", result), DecodeStatus::NotFound); - - // Max length - EXPECT_EQ(ParseFieldsInGeneralPurpose("820012345678901234567890123456789012345678901234567890" - "12345678901234567890", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8200)1234567890123456789012345678901234567890123456789012345678901234567890"); - EXPECT_EQ(ParseFieldsInGeneralPurpose("820012345678901234567890123456789012345678901234567890" - "1234567890123456789", result), DecodeStatus::NoError); - EXPECT_EQ(result, "(8200)123456789012345678901234567890123456789012345678901234567890123456789"); - // Too long - EXPECT_EQ(ParseFieldsInGeneralPurpose("820012345678901234567890123456789012345678901234567890" - "123456789012345678901", result), DecodeStatus::NotFound); -} From e69f1be2ea9a91cbc4b69fd1a69dad428c2eb79c Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 2 Jul 2022 21:50:28 +0200 Subject: [PATCH 0324/1315] BitArrayView: is to BitArray what BitSource is to ByteArray --- core/src/BitArray.h | 53 ++++++++++++++++++++++++++++-------- core/src/aztec/AZDecoder.cpp | 16 +++++------ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 355c76eea3..b531389f4d 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -363,17 +363,6 @@ int ToInt(const ARRAY& a) return pattern; } -inline int ReadBits(BitArray::Range& bits, int n) -{ - assert(n <= 32); - if (n > bits.size()) - throw std::out_of_range("ReadBits(BitArray::Range&) out of range."); - int res = 0; - for (; n > 0; --n, bits.begin++) - AppendBit(res, *bits.begin); - return res; -} - template >> T ToInt(const BitArray& bits, int pos = 0, int count = 8 * sizeof(T)) { @@ -402,4 +391,46 @@ std::vector ToInts(const BitArray& bits, int wordSize, int totalWords, int of return res; } +class BitArrayView +{ + const BitArray& bits; + BitArray::Iterator cur; + +public: + BitArrayView(const BitArray& bits) : bits(bits), cur(bits.begin()) {} + + BitArrayView& skipBits(int n) + { + if (n > bits.size()) + throw std::out_of_range("BitArrayView::skipBits() out of range."); + cur += n; + return *this; + } + + int peakBits(int n) const + { + assert(n <= 32); + if (n > bits.size()) + throw std::out_of_range("BitArrayView::peakBits() out of range."); + int res = 0; + for (auto i = cur; n > 0; --n, i++) + AppendBit(res, *i); + return res; + } + + int readBits(int n) + { + int res = peakBits(n); + cur += n; + return res; + } + + int size() const + { + return bits.end() - cur; + } + + explicit operator bool() const { return size(); } +}; + } // ZXing diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 1fb152515f..e5c5d34c78 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -209,11 +209,11 @@ static const char* GetCharacter(Table table, int code) /** * See ISO/IEC 24778:2008 Section 10.1 */ -static ECI ParseECIValue(BitArray::Range& bits, const int flg) +static ECI ParseECIValue(BitArrayView& bits, const int flg) { int eci = 0; for (int i = 0; i < flg; i++) - eci = 10 * eci + ReadBits(bits, 4) - 2; + eci = 10 * eci + bits.readBits(4) - 2; return ECI(eci); } @@ -254,20 +254,20 @@ static void DecodeContent(const BitArray& bits, Content& res) Table latchTable = Table::UPPER; // table most recently latched to Table shiftTable = Table::UPPER; // table to use for the next read - auto remBits = bits.range(); + auto remBits = BitArrayView(bits); while (remBits.size() >= (shiftTable == Table::DIGIT ? 4 : 5)) { // see ISO/IEC 24778:2008 7.3.1.2 regarding padding bits if (shiftTable == Table::BINARY) { - int length = ReadBits(remBits, 5); + int length = remBits.readBits(5); if (length == 0) - length = ReadBits(remBits, 11) + 31; + length = remBits.readBits(11) + 31; for (int i = 0; i < length; i++) - res.push_back(ReadBits(remBits, 8)); + res.push_back(remBits.readBits(8)); // Go back to whatever mode we had been in shiftTable = latchTable; } else { int size = shiftTable == Table::DIGIT ? 4 : 5; - int code = ReadBits(remBits, size); + int code = remBits.readBits(size); const char* str = GetCharacter(shiftTable, code); if (std::strncmp(str, "CTRL_", 5) == 0) { // Table changes @@ -279,7 +279,7 @@ static void DecodeContent(const BitArray& bits, Content& res) if (str[6] == 'L') latchTable = shiftTable; } else if (std::strcmp(str, "FLGN") == 0) { - int flg = ReadBits(remBits, 3); + int flg = remBits.readBits(3); if (flg == 0) { // FNC1 res.push_back(29); // May be removed at end if first/second FNC1 } else if (flg <= 6) { From e52ef0e98e2be446edc57c41819faa175fe3c71b Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 2 Jul 2022 23:10:02 +0200 Subject: [PATCH 0325/1315] DataBar: reimplement `DecodeExpandedBits` * separate HRI generation from bit stream decoding * remove `DecodeStatus` usage * drop remaining reference to RSS --- core/CMakeLists.txt | 16 +- core/src/GS1.cpp | 8 +- core/src/oned/ODDataBarExpandedBitDecoder.cpp | 262 ++++++++++ ...ecoder.h => ODDataBarExpandedBitDecoder.h} | 3 +- core/src/oned/ODDataBarExpandedReader.cpp | 5 +- .../oned/rss/ODRSSExpandedBinaryDecoder.cpp | 313 ----------- .../src/oned/rss/ODRSSGenericAppIdDecoder.cpp | 491 ------------------ core/src/oned/rss/ODRSSGenericAppIdDecoder.h | 22 - test/blackbox/BlackboxTestRunner.cpp | 12 +- test/unit/CMakeLists.txt | 2 +- ...pp => ODDataBarExpandedBitDecoderTest.cpp} | 11 +- 11 files changed, 290 insertions(+), 855 deletions(-) create mode 100644 core/src/oned/ODDataBarExpandedBitDecoder.cpp rename core/src/oned/{rss/ODRSSExpandedBinaryDecoder.h => ODDataBarExpandedBitDecoder.h} (80%) delete mode 100644 core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp delete mode 100644 core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp delete mode 100644 core/src/oned/rss/ODRSSGenericAppIdDecoder.h rename test/unit/oned/{rss/ODRSSExpandedBinaryDecoderTest.cpp => ODDataBarExpandedBitDecoderTest.cpp} (88%) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index fa5df9058d..4088c65288 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -271,6 +271,8 @@ if (BUILD_READERS) src/oned/ODDataBarCommon.cpp src/oned/ODDataBarReader.h src/oned/ODDataBarReader.cpp + src/oned/ODDataBarExpandedBitDecoder.h + src/oned/ODDataBarExpandedBitDecoder.cpp src/oned/ODDataBarExpandedReader.h src/oned/ODDataBarExpandedReader.cpp src/oned/ODITFReader.h @@ -309,18 +311,6 @@ if (BUILD_WRITERS) endif() -set (ONED_RSS_FILES -) -if (BUILD_READERS) - set (ONED_RSS_FILES ${ONED_RSS_FILES} - src/oned/rss/ODRSSExpandedBinaryDecoder.h - src/oned/rss/ODRSSExpandedBinaryDecoder.cpp - src/oned/rss/ODRSSGenericAppIdDecoder.h - src/oned/rss/ODRSSGenericAppIdDecoder.cpp - ) -endif() - - set (PDF417_FILES ) if (BUILD_READERS) @@ -442,7 +432,6 @@ source_group (Sources\\aztec FILES ${AZTEC_FILES}) source_group (Sources\\datamatrix FILES ${DATAMATRIX_FILES}) source_group (Sources\\maxicode FILES ${MAXICODE_FILES}) source_group (Sources\\oned FILES ${ONED_FILES}) -source_group (Sources\\oned\\rss FILES ${ONED_RSS_FILES}) source_group (Sources\\pdf417 FILES ${PDF417_FILES}) source_group (Sources\\qrcode FILES ${QRCODE_FILES}) source_group (Sources\\textcodec FILES ${TEXT_CODEC_FILES}) @@ -457,7 +446,6 @@ add_library (ZXing ${DATAMATRIX_FILES} ${MAXICODE_FILES} ${ONED_FILES} - ${ONED_RSS_FILES} ${PDF417_FILES} ${QRCODE_FILES} ${TEXT_CODEC_FILES} diff --git a/core/src/GS1.cpp b/core/src/GS1.cpp index ab0ab598bc..ab6b94d5d4 100644 --- a/core/src/GS1.cpp +++ b/core/src/GS1.cpp @@ -259,7 +259,12 @@ std::string HRIFromGS1(const std::string& gs1) int fieldSize = i->fieldSize(); if (i->isVariableLength()) { auto gsPos = rem.find(GS); +#if 1 fieldSize = std::min(gsPos == std::string_view::npos ? Size(rem) : static_cast(gsPos), fieldSize); +#else + // TODO: ignore the 'max field size' part for now as it breaks rssexpanded-3/13.png? + fieldSize = gsPos == std::string_view::npos ? Size(rem) : static_cast(gsPos); +#endif } if (fieldSize == 0 || Size(rem) < fieldSize) return {}; @@ -268,7 +273,8 @@ std::string HRIFromGS1(const std::string& gs1) rem.remove_prefix(fieldSize); if (Size(rem) && rem.front() == GS) { - if (i->isVariableLength()) + // TODO: we have DataBar samples where the fixed-length 422 ends with a GS, sigh... + if (i->isVariableLength() || i->aiPrefix == "422") rem.remove_prefix(1); else return {}; diff --git a/core/src/oned/ODDataBarExpandedBitDecoder.cpp b/core/src/oned/ODDataBarExpandedBitDecoder.cpp new file mode 100644 index 0000000000..c31e7f681f --- /dev/null +++ b/core/src/oned/ODDataBarExpandedBitDecoder.cpp @@ -0,0 +1,262 @@ +/* +* Copyright 2016 Nu-book Inc. +* Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "ODDataBarExpandedBitDecoder.h" + +#include "BitArray.h" +#include "Error.h" +#include "GTIN.h" + +#include + +namespace ZXing::OneD::DataBar { + +constexpr char GS = 29; // FNC1 + +static std::string DecodeGeneralPurposeBits(BitArrayView& bits) +{ + enum State { NUMERIC, ALPHA, ISO_IEC_646 }; + State state = NUMERIC; + std::string res; + + auto decode5Bits = [](State& state, std::string& res, BitArrayView& bits) { + int v = bits.readBits(5); + if (v == 4) { + state = state == ALPHA ? ISO_IEC_646 : ALPHA; + } else if (v == 15) { // FNC1 + latch to Numeric + res.push_back(GS); + state = NUMERIC; + // Allow for some generators incorrectly placing a numeric latch "000" after an FNC1 + if (bits.size() >= 7 && bits.peakBits(7) < 8) + bits.skipBits(3); + } else { + res.push_back(v + 43); + } + }; + + auto isPadding = [](State state, BitArrayView& bits) { + bool res = (state == NUMERIC) ? bits.size() < 4 + : bits.size() < 5 && (0b00100 >> (5 - bits.size()) == bits.peakBits(bits.size())); + if (res) + bits.skipBits(bits.size()); + return res; + }; + + while(bits.size() >= 3) { + switch(state) { + case NUMERIC: + if (isPadding(state, bits)) + break; + if (bits.size() < 7) { + int v = bits.readBits(4); + if (v > 0) + res.push_back('0' + v - 1); + } else if (bits.peakBits(4) == 0) { + bits.skipBits(4); + state = ALPHA; + } else { + int v = bits.readBits(7); + for (int digit : {(v - 8) / 11, (v - 8) % 11}) + res.push_back(digit == 10 ? GS : '0' + digit); + } + break; + case ALPHA: + if (isPadding(state, bits)) + break; + if (bits.peakBits(1) == 1) { + constexpr char const* lut58to62 = R"(*,-./)"; + int v = bits.readBits(6); + if (v < 58) + res.push_back(v + 33); + else if (v < 63) + res.push_back(lut58to62[v - 58]); + else + throw FormatError(); + } else if (bits.peakBits(3) == 0) { + bits.skipBits(3); + state = NUMERIC; + } else { + decode5Bits(state, res, bits); + } + break; + case ISO_IEC_646: + if (isPadding(state, bits)) + break; + if (bits.peakBits(3) == 0) { + bits.skipBits(3); + state = NUMERIC; + } else { + int v = bits.peakBits(5); + if (v < 16) { + decode5Bits(state, res, bits); + } else if (v < 29) { + v = bits.readBits(7); + res.push_back(v < 90 ? v + 1 : v + 7); + } else { + constexpr char const* lut232to252 = R"(!"%&'()*+,-./:;<=>?_ )"; + v = bits.readBits(8); + if (v < 232 || 252 < v) + throw FormatError(); + res.push_back(lut232to252[v - 232]); + } + } + break; + } + } + + // in NUMERIC encodation there might be a trailing FNC1 that needs to be ignored + if (res.size() && res.back() == GS) + res.pop_back(); + + return res; +} + +static void AppendNDigits(std::string& s, int v, int n) +{ + int div = std::pow(10, n-1); + while (v / div == 0 && div > 1) { + s.push_back('0'); + div /= 10; + } + s.append(std::to_string(v)); +} + +static std::string DecodeCompressedGTIN(std::string prefix, BitArrayView& bits) +{ + for (int i = 0; i < 4; ++i) + AppendNDigits(prefix, bits.readBits(10), 3); + + prefix.push_back(GTIN::ComputeCheckDigit(prefix.substr(2))); + + return prefix; +} + +static std::string DecodeAI01GTIN(BitArrayView& bits) +{ + return DecodeCompressedGTIN("019", bits); +} + +static std::string DecodeAI01AndOtherAIs(BitArrayView& bits) +{ + bits.skipBits(2); // Variable length symbol bit field + + auto header = DecodeCompressedGTIN("01" + std::to_string(bits.readBits(4)), bits); + auto trailer = DecodeGeneralPurposeBits(bits); + if (trailer.empty()) + return {}; + + return header + trailer; +} + +static std::string DecodeAnyAI(BitArrayView& bits) +{ + bits.skipBits(2); // Variable length symbol bit field + + return DecodeGeneralPurposeBits(bits); +} + +static std::string DecodeAI013103(BitArrayView& bits) +{ + std::string buffer = DecodeAI01GTIN(bits); + buffer.append("3103"); + AppendNDigits(buffer, bits.readBits(15), 6); + + return buffer; +} + +static std::string DecodeAI01320x(BitArrayView& bits) +{ + std::string buffer = DecodeAI01GTIN(bits); + int weight = bits.readBits(15); + buffer.append(weight < 10000 ? "3202" : "3203"); + AppendNDigits(buffer, weight < 10000 ? weight : weight - 10000, 6); + + return buffer; +} + +static std::string DecodeAI0139yx(BitArrayView& bits, char y) +{ + bits.skipBits(2); // Variable length symbol bit field + + std::string buffer = DecodeAI01GTIN(bits); + buffer.append("39"); + buffer.push_back(y); + buffer.append(std::to_string(bits.readBits(2))); + + if (y == '3') + AppendNDigits(buffer, bits.readBits(10), 3); + + auto trailer = DecodeGeneralPurposeBits(bits); + if (trailer.empty()) + return {}; + + return buffer + trailer; +} + +static std::string DecodeAI013x0x1x(BitArrayView& bits, const char* aiPrefix, const char* dateCode) +{ + std::string buffer = DecodeAI01GTIN(bits); + buffer.append(aiPrefix); + + int weight = bits.readBits(20); + buffer.append(std::to_string(weight / 100000)); + AppendNDigits(buffer, weight % 100000, 6); + + int date = bits.readBits(16); + if (date != 38400) { + buffer.append(dateCode); + + int day = date % 32; + date /= 32; + int month = date % 12 + 1; + date /= 12; + int year = date; + + AppendNDigits(buffer, year, 2); + AppendNDigits(buffer, month, 2); + AppendNDigits(buffer, day, 2); + } + + return buffer; +} + +std::string DecodeExpandedBits(const BitArray& _bits) +{ + auto bits = BitArrayView(_bits); + bits.readBits(1); // skip linkage bit + + if (bits.peakBits(1) == 1) + return DecodeAI01AndOtherAIs(bits.skipBits(1)); + + if (bits.peakBits(2) == 0) + return DecodeAnyAI(bits.skipBits(2)); + + switch (bits.peakBits(4)) { + case 4: return DecodeAI013103(bits.skipBits(4)); + case 5: return DecodeAI01320x(bits.skipBits(4)); + } + + switch (bits.peakBits(5)) { + case 12: return DecodeAI0139yx(bits.skipBits(5), '2'); + case 13: return DecodeAI0139yx(bits.skipBits(5), '3'); + } + + switch (bits.readBits(7)) { + case 56: return DecodeAI013x0x1x(bits, "310", "11"); + case 57: return DecodeAI013x0x1x(bits, "320", "11"); + case 58: return DecodeAI013x0x1x(bits, "310", "13"); + case 59: return DecodeAI013x0x1x(bits, "320", "13"); + case 60: return DecodeAI013x0x1x(bits, "310", "15"); + case 61: return DecodeAI013x0x1x(bits, "320", "15"); + case 62: return DecodeAI013x0x1x(bits, "310", "17"); + case 63: return DecodeAI013x0x1x(bits, "320", "17"); + } + + return {}; +} + +} // namespace ZXing::OneD::DataBar diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.h b/core/src/oned/ODDataBarExpandedBitDecoder.h similarity index 80% rename from core/src/oned/rss/ODRSSExpandedBinaryDecoder.h rename to core/src/oned/ODDataBarExpandedBitDecoder.h index 2c708b4354..71653a6659 100644 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.h +++ b/core/src/oned/ODDataBarExpandedBitDecoder.h @@ -1,6 +1,5 @@ /* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 6e8d59e92f..be1c1247c1 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -9,10 +9,11 @@ #include "BarcodeFormat.h" #include "DecoderResult.h" +#include "GS1.h" #include "ODDataBarCommon.h" +#include "ODDataBarExpandedBitDecoder.h" #include "Result.h" #include "TextDecoder.h" -#include "rss/ODRSSExpandedBinaryDecoder.h" #include #include @@ -368,6 +369,8 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, #endif auto txt = DecodeExpandedBits(BuildBitArray(pairs)); + // TODO: remove this to make it return standard conform content -> needs lots of blackbox test fixes + txt = HRIFromGS1(txt); if (txt.empty()) return {}; diff --git a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp b/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp deleted file mode 100644 index 5c513c2cd6..0000000000 --- a/core/src/oned/rss/ODRSSExpandedBinaryDecoder.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -*/ -// SPDX-License-Identifier: Apache-2.0 - -/* -* These authors would like to acknowledge the Spanish Ministry of Industry, -* Tourism and Trade, for the support in the project TSI020301-2008-2 -* "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled -* Mobile Dynamic Environments", led by Treelogic -* ( http://www.treelogic.com/ ): -* -* http://www.piramidepse.com/ -*/ - -#include "ODRSSExpandedBinaryDecoder.h" - -#include "BitArray.h" -#include "DecodeStatus.h" -#include "ODRSSGenericAppIdDecoder.h" - -#include - -namespace ZXing::OneD::DataBar { - -static const int AI01_GTIN_SIZE = 40; - -static void AI01AppendCheckDigit(std::string& buffer, int currentPos) -{ - int checkDigit = 0; - for (int i = 0; i < 13; i++) { - int digit = buffer[i + currentPos] - '0'; - checkDigit += (i & 0x01) == 0 ? 3 * digit : digit; - } - - checkDigit = 10 - (checkDigit % 10); - if (checkDigit == 10) { - checkDigit = 0; - } - buffer.append(std::to_string(checkDigit)); -} - -static void AI01EncodeCompressedGtinWithoutAI(std::string& buffer, const BitArray& bits, int currentPos, int initialBufferPosition) -{ - for (int i = 0; i < 4; ++i) { - int currentBlock = ToInt(bits, currentPos + 10 * i, 10); - if (currentBlock / 100 == 0) { - buffer.push_back('0'); - } - if (currentBlock / 10 == 0) { - buffer.push_back('0'); - } - buffer.append(std::to_string(currentBlock)); - } - AI01AppendCheckDigit(buffer, initialBufferPosition); -} - -static void AI01EncodeCompressedGtin(std::string& buffer, const BitArray& bits, int currentPos) -{ - buffer.append("(01)"); - int initialPosition = Size(buffer); - buffer.push_back('9'); - AI01EncodeCompressedGtinWithoutAI(buffer, bits, currentPos, initialPosition); -} - -using AddWeightCodeFunc = const std::function; -using CheckWeightFunc = const std::function; - -static void AI01EncodeCompressedWeight(std::string& buffer, const BitArray& bits, int currentPos, int weightSize, - const AddWeightCodeFunc& addWeightCode, const CheckWeightFunc& checkWeight) -{ - int originalWeightNumeric = ToInt(bits, currentPos, weightSize); - addWeightCode(buffer, originalWeightNumeric); - - int weightNumeric = checkWeight(originalWeightNumeric); - - int currentDivisor = 100000; - for (int i = 0; i < 5; ++i) { - if (weightNumeric / currentDivisor == 0) { - buffer.push_back('0'); - } - currentDivisor /= 10; - } - buffer.append(std::to_string(weightNumeric)); -} - -/** -* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) -* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) -*/ -static std::string DecodeAI01AndOtherAIs(const BitArray& bits) -{ - static const int HEADER_SIZE = 1 + 1 + 2; // first bit encodes the linkage flag, the second one is the encodation - // method, and the other two are for the variable length - - if (bits.size() < HEADER_SIZE + 44) - return {}; - - std::string buffer; - buffer.append("(01)"); - int initialGtinPosition = Size(buffer); - int firstGtinDigit = ToInt(bits, HEADER_SIZE, 4); - buffer.append(std::to_string(firstGtinDigit)); - - AI01EncodeCompressedGtinWithoutAI(buffer, bits, HEADER_SIZE + 4, initialGtinPosition); - if (StatusIsOK(DecodeAppIdAllCodes(bits, HEADER_SIZE + 44, -1, buffer))) - return buffer; - - return {}; -} - -static std::string DecodeAnyAI(const BitArray& bits) -{ - static const int HEADER_SIZE = 2 + 1 + 2; - std::string buffer; - if (StatusIsOK(DecodeAppIdAllCodes(bits, HEADER_SIZE, -1, buffer))) - return buffer; - - return {}; -} - -static std::string DecodeAI013103(const BitArray& bits) -{ - static const int HEADER_SIZE = 4 + 1; - static const int WEIGHT_SIZE = 15; - - if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) - return {}; - - std::string buffer; - AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); - AI01EncodeCompressedWeight(buffer, bits, HEADER_SIZE + AI01_GTIN_SIZE, WEIGHT_SIZE, - // addWeightCode - [](std::string& buf, int) { buf.append("(3103)"); }, - // checkWeight - [](int weight) { return weight; }); - - return buffer; -} - -static std::string DecodeAI01320x(const BitArray& bits) -{ - static const int HEADER_SIZE = 4 + 1; - static const int WEIGHT_SIZE = 15; - - if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE) - return {}; - - std::string buffer; - AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); - AI01EncodeCompressedWeight( - buffer, bits, HEADER_SIZE + AI01_GTIN_SIZE, WEIGHT_SIZE, - // addWeightCode - [](std::string& buf, int weight) { buf.append(weight < 10000 ? "(3202)" : "(3203)"); }, - // checkWeight - [](int weight) { return weight < 10000 ? weight : weight - 10000; }); - - return buffer; -} - -static std::string DecodeAI01392x(const BitArray& bits) -{ - static const int HEADER_SIZE = 5 + 1 + 2; - static const int LAST_DIGIT_SIZE = 2; - - if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) - return {}; - - std::string buffer; - AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); - - int lastAIdigit = ToInt(bits, HEADER_SIZE + AI01_GTIN_SIZE, LAST_DIGIT_SIZE); - buffer.append("(392"); - buffer.append(std::to_string(lastAIdigit)); - buffer.push_back(')'); - - int pos = HEADER_SIZE + AI01_GTIN_SIZE + LAST_DIGIT_SIZE; - int remainingValue = -1; - if (StatusIsOK(DecodeAppIdGeneralPurposeField(bits, pos, remainingValue, buffer)) - && StatusIsOK(DecodeAppIdAllCodes(bits, pos, remainingValue, buffer))) { - return buffer; - } - return {}; -} - -static std::string DecodeAI01393x(const BitArray& bits) -{ - static const int HEADER_SIZE = 5 + 1 + 2; - static const int LAST_DIGIT_SIZE = 2; - static const int FIRST_THREE_DIGITS_SIZE = 10; - - if (bits.size() < HEADER_SIZE + AI01_GTIN_SIZE) - return {}; - - std::string buffer; - AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); - - int lastAIdigit = ToInt(bits, HEADER_SIZE + AI01_GTIN_SIZE, LAST_DIGIT_SIZE); - - buffer.append("(393"); - buffer.append(std::to_string(lastAIdigit)); - buffer.push_back(')'); - - int firstThreeDigits = ToInt(bits, HEADER_SIZE + AI01_GTIN_SIZE + LAST_DIGIT_SIZE, FIRST_THREE_DIGITS_SIZE); - if (firstThreeDigits / 100 == 0) - buffer.push_back('0'); - - if (firstThreeDigits / 10 == 0) - buffer.push_back('0'); - - buffer.append(std::to_string(firstThreeDigits)); - - int pos = HEADER_SIZE + AI01_GTIN_SIZE + LAST_DIGIT_SIZE + FIRST_THREE_DIGITS_SIZE; - int remainingValue = -1; - if (StatusIsOK(DecodeAppIdGeneralPurposeField(bits, pos, remainingValue, buffer)) - && StatusIsOK(DecodeAppIdAllCodes(bits, pos, remainingValue, buffer))) { - return buffer; - } - return {}; -} - -static std::string DecodeAI013x0x1x(const BitArray& bits, const char* firstAIdigits, const char* dateCode) -{ - static const int HEADER_SIZE = 7 + 1; - static const int WEIGHT_SIZE = 20; - static const int DATE_SIZE = 16; - - if (bits.size() != HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE) - return {}; - - std::string buffer; - AI01EncodeCompressedGtin(buffer, bits, HEADER_SIZE); - AI01EncodeCompressedWeight(buffer, bits, HEADER_SIZE + AI01_GTIN_SIZE, WEIGHT_SIZE, - // addWeightCode - [firstAIdigits](std::string& buf, int weight) { - buf.push_back('('); - buf.append(firstAIdigits); - buf.append(std::to_string(weight / 100000)); - buf.push_back(')'); - }, - // checkWeight - [](int weight) { - return weight % 100000; - }); - - // encode compressed date - int numericDate = ToInt(bits, HEADER_SIZE + AI01_GTIN_SIZE + WEIGHT_SIZE, DATE_SIZE); - if (numericDate != 38400) { - buffer.push_back('('); - buffer.append(dateCode); - buffer.push_back(')'); - - int day = numericDate % 32; - numericDate /= 32; - int month = numericDate % 12 + 1; - numericDate /= 12; - int year = numericDate; - - if (year / 10 == 0) - buffer.push_back('0'); - - buffer.append(std::to_string(year)); - if (month / 10 == 0) - buffer.push_back('0'); - - buffer.append(std::to_string(month)); - if (day / 10 == 0) - buffer.push_back('0'); - - buffer.append(std::to_string(day)); - } - - return buffer; -} - -std::string DecodeExpandedBits(const BitArray& bits) -{ - if (bits.get(1)) - return DecodeAI01AndOtherAIs(bits); - - if (!bits.get(2)) - return DecodeAnyAI(bits); - - int fourBitEncodationMethod = ToInt(bits, 1, 4); - - switch (fourBitEncodationMethod) { - case 4: return DecodeAI013103(bits); - case 5: return DecodeAI01320x(bits); - } - - int fiveBitEncodationMethod = ToInt(bits, 1, 5); - switch (fiveBitEncodationMethod) { - case 12: return DecodeAI01392x(bits); - case 13: return DecodeAI01393x(bits); - } - - int sevenBitEncodationMethod = ToInt(bits, 1, 7); - switch (sevenBitEncodationMethod) { - case 56: return DecodeAI013x0x1x(bits, "310", "11"); - case 57: return DecodeAI013x0x1x(bits, "320", "11"); - case 58: return DecodeAI013x0x1x(bits, "310", "13"); - case 59: return DecodeAI013x0x1x(bits, "320", "13"); - case 60: return DecodeAI013x0x1x(bits, "310", "15"); - case 61: return DecodeAI013x0x1x(bits, "320", "15"); - case 62: return DecodeAI013x0x1x(bits, "310", "17"); - case 63: return DecodeAI013x0x1x(bits, "320", "17"); - } - - return {}; -} - -} // namespace ZXing::OneD::DataBar diff --git a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp b/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp deleted file mode 100644 index eee7c9e4e7..0000000000 --- a/core/src/oned/rss/ODRSSGenericAppIdDecoder.cpp +++ /dev/null @@ -1,491 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -*/ -// SPDX-License-Identifier: Apache-2.0 - -#include "ODRSSGenericAppIdDecoder.h" - -#include "BitArray.h" -#include "DecodeStatus.h" -#include "GS1.h" - -#include -#include -#include - -namespace ZXing::OneD::DataBar { - -struct DecodedValue -{ - int newPosition = std::numeric_limits::max(); - - DecodedValue() = default; - explicit DecodedValue(int np) : newPosition(np) {} - bool isValid() const { return newPosition != std::numeric_limits::max(); } -}; - -/** -* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) -* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) -*/ -struct DecodedChar : public DecodedValue -{ - static const char FNC1 = '$'; // It's not in Alphanumeric neither in ISO/IEC 646 charset - - char value = '\0'; - - DecodedChar() = default; - DecodedChar(int np, char c) : DecodedValue(np), value(c) {} - - bool isFNC1() const { return value == FNC1; } -}; - -/** -* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) -* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) -*/ -struct DecodedInformation : public DecodedValue -{ - std::string newString; - int remainingValue = -1; - - DecodedInformation() = default; - DecodedInformation(int np, std::string s) : DecodedValue(np), newString(std::move(s)) {} - DecodedInformation(int np, std::string s, int r) : DecodedValue(np), newString(std::move(s)), remainingValue(r) {} - - bool isRemaining() const { return remainingValue >= 0; } -}; - -/** -* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) -* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) -*/ -struct DecodedNumeric : public DecodedValue -{ - static const int FNC1 = 10; - - int firstDigit = 0; - int secondDigit = 0; - - DecodedNumeric() = default; - DecodedNumeric(int newPosition, int first, int second) : DecodedValue(newPosition), firstDigit(first), secondDigit(second) { - if (firstDigit < 0 || firstDigit > 10 || secondDigit < 0 || secondDigit > 10) { - *this = DecodedNumeric(); - } - } - - int value() const { - return firstDigit * 10 + secondDigit; - } - - bool isFirstDigitFNC1() const { - return firstDigit == FNC1; - } - - bool isSecondDigitFNC1() const { - return secondDigit == FNC1; - } - - bool isAnyFNC1() const { - return firstDigit == FNC1 || secondDigit == FNC1; - } - -private: -}; - -struct ParsingState -{ - enum State { NUMERIC, ALPHA, ISO_IEC_646 }; - - int position = 0; - State encoding = NUMERIC; -}; - -static bool -IsStillAlpha(const BitArray& bits, int pos) -{ - if (pos + 5 > bits.size()) { - return false; - } - - // We now check if it's a valid 5-bit value (0..9 and FNC1) - int fiveBitValue = ToInt(bits, pos, 5); - if (fiveBitValue >= 5 && fiveBitValue < 16) { - return true; - } - - if (pos + 6 > bits.size()) { - return false; - } - - int sixBitValue = ToInt(bits, pos, 6); - return sixBitValue >= 16 && sixBitValue < 63; // 63 not included -} - -static bool -IsStillIsoIec646(const BitArray& bits, int pos) -{ - if (pos + 5 > bits.size()) { - return false; - } - - int fiveBitValue = ToInt(bits, pos, 5); - if (fiveBitValue >= 5 && fiveBitValue < 16) { - return true; - } - - if (pos + 7 > bits.size()) { - return false; - } - - int sevenBitValue = ToInt(bits, pos, 7); - if (sevenBitValue >= 64 && sevenBitValue < 116) { - return true; - } - - if (pos + 8 > bits.size()) { - return false; - } - - int eightBitValue = ToInt(bits, pos, 8); - return eightBitValue >= 232 && eightBitValue < 253; -} - -static bool -IsStillNumeric(const BitArray& bits, int pos) -{ - // It's numeric if it still has 7 positions - // and one of the first 4 bits is "1". - if (pos + 7 > bits.size()) { - return pos + 4 <= bits.size(); - } - auto bitIter = bits.iterAt(pos); - for (int i = 0; i < 4; ++i, ++bitIter) { - if (*bitIter) { - return true; - } - } - return false; -} - -static DecodedChar -DecodeAlphanumeric(const BitArray& bits, int pos) -{ - int fiveBitValue = ToInt(bits, pos, 5); - if (fiveBitValue == 15) { - return DecodedChar(pos + 5, DecodedChar::FNC1); - } - - if (fiveBitValue >= 5 && fiveBitValue < 15) { - return DecodedChar(pos + 5, (char)('0' + fiveBitValue - 5)); - } - - int sixBitValue = ToInt(bits, pos, 6); - - if (sixBitValue >= 32 && sixBitValue < 58) { - return DecodedChar(pos + 6, (char)(sixBitValue + 33)); - } - - if (sixBitValue < 58 || sixBitValue > 62) - throw std::runtime_error("Decoding invalid alphanumeric value"); - - constexpr char const* lut58to62 = R"(*,-./)"; - char c = lut58to62[sixBitValue - 58]; - - return DecodedChar(pos + 6, c); -} - -static bool -IsAlphaTo646ToAlphaLatch(const BitArray& bits, int pos) -{ - if (pos + 1 > bits.size()) { - return false; - } - for (int i = 0; i < 5 && i + pos < bits.size(); ++i) { - if (i == 2) { - if (!bits.get(pos + 2)) { - return false; - } - } - else if (bits.get(pos + i)) { - return false; - } - } - return true; -} - -static bool -IsAlphaOr646ToNumericLatch(const BitArray& bits, int pos) -{ - // Next is alphanumeric if there are 3 positions and they are all zeros - if (pos + 3 > bits.size()) { - return false; - } - auto bitIter = bits.iterAt(pos); - for (int i = 0; i < 3; ++i, ++bitIter) { - if (*bitIter) { - return false; - } - } - return true; -} - -static bool -IsNumericToAlphaNumericLatch(const BitArray& bits, int pos) -{ - // Next is alphanumeric if there are 4 positions and they are all zeros, or - // if there is a subset of this just before the end of the symbol - if (pos + 1 > bits.size()) { - return false; - } - - auto bitIter = bits.iterAt(pos); - for (int i = 0; i < 4 && i + pos < bits.size(); ++i, ++bitIter) { - if (*bitIter) { - return false; - } - } - return true; -} - -static DecodedInformation -ParseAlphaBlock(const BitArray& bits, ParsingState& state, std::string& buffer) -{ - while (IsStillAlpha(bits, state.position)) { - DecodedChar alpha = DecodeAlphanumeric(bits, state.position); - state.position = alpha.newPosition; - - if (alpha.isFNC1()) { - // Allow for some generators incorrectly placing a numeric latch "000" after an FNC1 - if (state.position + 7 < bits.size() && ToInt(bits, state.position, 7) < 8) { - state.position += 3; - } - state.encoding = ParsingState::NUMERIC; // FNC1 latches to numeric encodation - return DecodedInformation(state.position, buffer); //end of the char block - } - buffer.push_back(alpha.value); - } - - if (IsAlphaOr646ToNumericLatch(bits, state.position)) { - state.position += 3; - state.encoding = ParsingState::NUMERIC; - } - else if (IsAlphaTo646ToAlphaLatch(bits, state.position)) { - if (state.position + 5 < bits.size()) { - state.position += 5; - } - else { - state.position = bits.size(); - } - state.encoding = ParsingState::ISO_IEC_646; - } - return DecodedInformation(); -} - -static DecodedChar -DecodeIsoIec646(const BitArray& bits, int pos) -{ - int fiveBitValue = ToInt(bits,pos, 5); - if (fiveBitValue == 15) { - return DecodedChar(pos + 5, DecodedChar::FNC1); - } - - if (fiveBitValue >= 5 && fiveBitValue < 15) { - return DecodedChar(pos + 5, (char)('0' + fiveBitValue - 5)); - } - - int sevenBitValue = ToInt(bits, pos, 7); - - if (sevenBitValue >= 64 && sevenBitValue < 90) { - return DecodedChar(pos + 7, (char)(sevenBitValue + 1)); - } - - if (sevenBitValue >= 90 && sevenBitValue < 116) { - return DecodedChar(pos + 7, (char)(sevenBitValue + 7)); - } - - int eightBitValue = ToInt(bits, pos, 8); - if (eightBitValue < 232 || eightBitValue > 252) - throw std::runtime_error("Decoding invalid ISO-IEC-646 value"); - - constexpr char const* lut232to252 = R"(!"%&'()*+,-./:;<=>?_ )"; - char c = lut232to252[eightBitValue - 232]; - - return DecodedChar(pos + 8, c); -} - -static DecodedInformation -ParseIsoIec646Block(const BitArray& bits, ParsingState& state, std::string& buffer) -{ - while (IsStillIsoIec646(bits, state.position)) { - DecodedChar iso = DecodeIsoIec646(bits, state.position); - state.position = iso.newPosition; - if (iso.isFNC1()) { - // Allow for some generators incorrectly placing a numeric latch "000" after an FNC1 - if (state.position + 7 < bits.size() && ToInt(bits, state.position, 7) < 8) { - state.position += 3; - } - state.encoding = ParsingState::NUMERIC; // FNC1 latches to numeric encodation - return DecodedInformation(state.position, buffer); - } - buffer.push_back(iso.value); - } - - if (IsAlphaOr646ToNumericLatch(bits, state.position)) { - state.position += 3;; - state.encoding = ParsingState::NUMERIC; - } - else if (IsAlphaTo646ToAlphaLatch(bits, state.position)) { - if (state.position + 5 < bits.size()) { - state.position += 5; - } - else { - state.position = bits.size(); - } - state.encoding = ParsingState::ALPHA; - } - return DecodedInformation(); -} - -static DecodedNumeric -DecodeNumeric(const BitArray& bits, int pos) -{ - if (pos + 7 > bits.size()) { - int numeric = ToInt(bits, pos, 4); - if (numeric == 0) { - return DecodedNumeric(bits.size(), DecodedNumeric::FNC1, DecodedNumeric::FNC1); - } - return DecodedNumeric(bits.size(), numeric - 1, DecodedNumeric::FNC1); - } - int numeric = ToInt(bits, pos, 7); - int digit1 = (numeric - 8) / 11; - int digit2 = (numeric - 8) % 11; - - return DecodedNumeric(pos + 7, digit1, digit2); -} - -static DecodedInformation -ParseNumericBlock(const BitArray& bits, ParsingState& state, std::string& buffer) -{ - while (IsStillNumeric(bits, state.position)) { - DecodedNumeric numeric = DecodeNumeric(bits, state.position); - if (!numeric.isValid()) - break; - state.position = numeric.newPosition; - - if (numeric.isFirstDigitFNC1()) { - DecodedInformation information; - if (numeric.isSecondDigitFNC1()) { - return DecodedInformation(state.position, buffer); - } - else { - return DecodedInformation(state.position, buffer, numeric.secondDigit); - } - } - - buffer.append(std::to_string(numeric.firstDigit)); - if (numeric.isSecondDigitFNC1()) { - return DecodedInformation(state.position, buffer); - } - buffer.append(std::to_string(numeric.secondDigit)); - } - - if (IsNumericToAlphaNumericLatch(bits, state.position)) { - state.encoding = ParsingState::ALPHA; - state.position += 4; - } - return DecodedInformation(); -} - - -static DecodedInformation -ParseBlocks(const BitArray& bits, ParsingState& state, std::string& buffer) -{ - while (true) { - int initialPosition = state.position; - auto result = - state.encoding == ParsingState::ALPHA ? - ParseAlphaBlock(bits, state, buffer) : - (state.encoding == ParsingState::ISO_IEC_646 ? - ParseIsoIec646Block(bits, state, buffer) : - ParseNumericBlock(bits, state, buffer)); - if (result.isValid() || initialPosition == state.position) - { - return result; - } - } -} - -static DecodedInformation -DoDecodeGeneralPurposeField(ParsingState& state, const BitArray& bits, std::string prefix) -{ - DecodedInformation lastDecoded = ParseBlocks(bits, state, prefix); - if (lastDecoded.isValid() && lastDecoded.isRemaining()) { - return DecodedInformation(state.position, prefix, lastDecoded.remainingValue); - } - return DecodedInformation(state.position, prefix); -} - -DecodeStatus -DecodeAppIdGeneralPurposeField(const BitArray& bits, int& pos, int& remainingValue, std::string& result) -{ - try - { - ParsingState state; - state.position = pos; - DecodedInformation info = DoDecodeGeneralPurposeField(state, bits, std::string()); - result += info.newString; - pos = state.position; - remainingValue = info.remainingValue; - return DecodeStatus::NoError; - } - catch (const std::exception &) - { - } - return DecodeStatus::FormatError; -} - -DecodeStatus -DecodeAppIdAllCodes(const BitArray& bits, int pos, int remainingValue, std::string& result) -{ - try - { - ParsingState state; - std::string remaining; - if (remainingValue != -1) { - remaining = std::to_string(remainingValue); - } - while (true) { - state.position = pos; - DecodedInformation info = DoDecodeGeneralPurposeField(state, bits, remaining); - if (pos == info.newPosition || info.newString.empty()) // No step forward! - break; - - std::string parsedFields = HRIFromGS1(info.newString); - if (parsedFields.empty()) { - if (result.empty() && remaining.empty()) { - result = info.newString; - return DecodeStatus::NoError; - } else - return DecodeStatus::FormatError; - } - result += parsedFields; - if (info.isRemaining()) { - remaining = std::to_string(info.remainingValue); - } - else { - remaining.clear(); - } - - pos = info.newPosition; - }; - return DecodeStatus::NoError; - } - catch (const std::exception &) - { - } - return DecodeStatus::FormatError; -} - -} // namespace ZXing::OneD::DataBar diff --git a/core/src/oned/rss/ODRSSGenericAppIdDecoder.h b/core/src/oned/rss/ODRSSGenericAppIdDecoder.h deleted file mode 100644 index b6fe69485c..0000000000 --- a/core/src/oned/rss/ODRSSGenericAppIdDecoder.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -*/ -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -namespace ZXing { - -class BitArray; -enum class DecodeStatus; - -namespace OneD::DataBar { - -DecodeStatus DecodeAppIdGeneralPurposeField(const BitArray& bits, int& pos, int& remainingValue, std::string& result); -DecodeStatus DecodeAppIdAllCodes(const BitArray& bits, int pos, const int remainingValue, std::string& result); - -} // namespace OneD::DataBar -} // namespace ZXing diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 7f9a1d7ab9..bd12204987 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -525,14 +525,16 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("rssexpanded-3", "DataBarExpanded", 118, { - { 118, 118, 0 }, - { 118, 118, 180 }, - { 118, 0, pure }, + // TODO: See HRIFromGS1. 13.png and 66.png are seemingly invalid symbols + { 116, 116, 0 }, + { 116, 116, 180 }, + { 116, 0, pure }, }); runTests("rssexpandedstacked-1", "DataBarExpanded", 65, { - { 60, 65, 0 }, - { 60, 65, 180 }, + // TODO: See HRIFromGS1. 13.png is seemingly invalid symbol + { 60, 64, 0 }, + { 60, 64, 180 }, { 60, 0, pure }, }); diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 45f609c1f5..82503c0c90 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -45,7 +45,7 @@ add_executable (UnitTest oned/ODITFWriterTest.cpp oned/ODUPCAWriterTest.cpp oned/ODUPCEWriterTest.cpp - oned/rss/ODRSSExpandedBinaryDecoderTest.cpp + oned/ODDataBarExpandedBitDecoderTest.cpp qrcode/MQRDecoderTest.cpp qrcode/QRBitMatrixParserTest.cpp qrcode/QRDataMaskTest.cpp diff --git a/test/unit/oned/rss/ODRSSExpandedBinaryDecoderTest.cpp b/test/unit/oned/ODDataBarExpandedBitDecoderTest.cpp similarity index 88% rename from test/unit/oned/rss/ODRSSExpandedBinaryDecoderTest.cpp rename to test/unit/oned/ODDataBarExpandedBitDecoderTest.cpp index c11b7528ef..27e6902a63 100644 --- a/test/unit/oned/rss/ODRSSExpandedBinaryDecoderTest.cpp +++ b/test/unit/oned/ODDataBarExpandedBitDecoderTest.cpp @@ -5,7 +5,8 @@ #include "BitArray.h" #include "BitArrayUtility.h" -#include "oned/rss/ODRSSExpandedBinaryDecoder.h" +#include "GS1.h" +#include "oned/ODDataBarExpandedBitDecoder.h" #include "gtest/gtest.h" @@ -13,10 +14,10 @@ using namespace ZXing; static std::string parse(std::string bitStr) { - return OneD::DataBar::DecodeExpandedBits(Utility::ParseBitArray(bitStr, '1')); + return HRIFromGS1(OneD::DataBar::DecodeExpandedBits(Utility::ParseBitArray(bitStr, '1'))); } -TEST(ODRSSExpandedBinaryDecoderTest, FNC1NumericLatch) +TEST(ODDataBarExpandedBitDecoderTest, FNC1NumericLatch) { std::string result; @@ -37,7 +38,7 @@ TEST(ODRSSExpandedBinaryDecoderTest, FNC1NumericLatch) EXPECT_EQ(result, "(10)12((422)123"); } -TEST(ODRSSExpandedBinaryDecoderTest, DecodeAI01392x) +TEST(ODDataBarExpandedBitDecoderTest, DecodeAI01392x) { std::string result; @@ -53,7 +54,7 @@ TEST(ODRSSExpandedBinaryDecoderTest, DecodeAI01392x) EXPECT_EQ(result, "(01)90012345678908(3929)12345678901234(20)01"); } -TEST(ODRSSExpandedBinaryDecoderTest, DecodeAI01393x) +TEST(ODDataBarExpandedBitDecoderTest, DecodeAI01393x) { std::string result; From 18797e2c09fc3ac0d51d032e4a75c280425f25f7 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 2 Jul 2022 23:10:47 +0200 Subject: [PATCH 0326/1315] test: remove duplicated blackbox test files from rssexpandedstacked --- test/blackbox/BlackboxTestRunner.cpp | 6 +++--- test/samples/rssexpandedstacked-2/13.png | Bin 334 -> 0 bytes test/samples/rssexpandedstacked-2/13.txt | 1 - test/samples/rssexpandedstacked-2/19.png | Bin 258 -> 0 bytes test/samples/rssexpandedstacked-2/19.txt | 1 - test/samples/rssexpandedstacked-2/20.png | Bin 249 -> 0 bytes test/samples/rssexpandedstacked-2/20.txt | 1 - test/samples/rssexpandedstacked-2/22.png | Bin 330 -> 0 bytes test/samples/rssexpandedstacked-2/22.txt | 1 - test/samples/rssexpandedstacked-2/23.png | Bin 301 -> 0 bytes test/samples/rssexpandedstacked-2/23.txt | 1 - 11 files changed, 3 insertions(+), 8 deletions(-) delete mode 100644 test/samples/rssexpandedstacked-2/13.png delete mode 100644 test/samples/rssexpandedstacked-2/13.txt delete mode 100644 test/samples/rssexpandedstacked-2/19.png delete mode 100644 test/samples/rssexpandedstacked-2/19.txt delete mode 100644 test/samples/rssexpandedstacked-2/20.png delete mode 100644 test/samples/rssexpandedstacked-2/20.txt delete mode 100644 test/samples/rssexpandedstacked-2/22.png delete mode 100644 test/samples/rssexpandedstacked-2/22.txt delete mode 100644 test/samples/rssexpandedstacked-2/23.png delete mode 100644 test/samples/rssexpandedstacked-2/23.txt diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index bd12204987..fdda8ff254 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -538,9 +538,9 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 60, 0, pure }, }); - runTests("rssexpandedstacked-2", "DataBarExpanded", 7, { - { 2, 7, 0 }, - { 2, 7, 180 }, + runTests("rssexpandedstacked-2", "DataBarExpanded", 2, { + { 2, 2, 0 }, + { 2, 2, 180 }, }); runTests("qrcode-1", "QRCode", 16, { diff --git a/test/samples/rssexpandedstacked-2/13.png b/test/samples/rssexpandedstacked-2/13.png deleted file mode 100644 index 21dc744571328db490eb75af6570d58a5032b906..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^XBZe5w=n`44ARp>e1IHLPZ!6K3dXnBcb`f%&7jN`K}v8=R{sUQ~Cby`d^!Ci(bV!ooi}DOVp%p9T0xy=Ox7J2{ z{w--4Ri5E{G4r_lq;K9*-;L8I&bCtG7gqqFC!D@|2x~d=5>XU@yuD} ze=Cl8TZ!!z-yRow_4an5_bR<82JV~nT;j3PwZ7-Gz?=6#He+j;Iz S|66ea6i}Y7elF{r5}E*5K$EEe diff --git a/test/samples/rssexpandedstacked-2/13.txt b/test/samples/rssexpandedstacked-2/13.txt deleted file mode 100644 index 0429d93c29..0000000000 --- a/test/samples/rssexpandedstacked-2/13.txt +++ /dev/null @@ -1 +0,0 @@ -(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-2/19.png b/test/samples/rssexpandedstacked-2/19.png deleted file mode 100644 index f21183e01b4f5edd2879569c9ea68e1ec0b1d227..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^XBZe5l^B5xhPeq0l0fRDr;B4q1>@VRwpnhD9Bzq; zx483MXM`2JZhG4gEx1hd%yg^&EAL;n%8v1M+yQQEKH5}GOzTV zdlTaxp6PjSZH)i5?Im{a*-w4Bo4#%LHt(6w-n>b@KdIx!!-dIWrzhEVM};kKZ~$qn zx@gb;`~2+SFO$okr}leaFD{$>`g@7nbzQm2Q(tBtZ%ONIwE!9Kut5Cp=MDe&?9A_* zH*wOd7hAtPDZBV{+7UlZVO4eg*t?cjryXPhDpL@6;hO((Z_Cl*C>DE==R95gT-G@y GGywn&B5?cw diff --git a/test/samples/rssexpandedstacked-2/19.txt b/test/samples/rssexpandedstacked-2/19.txt deleted file mode 100644 index 8f0841f935..0000000000 --- a/test/samples/rssexpandedstacked-2/19.txt +++ /dev/null @@ -1 +0,0 @@ -(01)12345678901231(10)UNIVERSITY-OF-DEUSTO \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-2/20.png b/test/samples/rssexpandedstacked-2/20.png deleted file mode 100644 index 7f5d8326efaef78decb6f99829514503b2702cf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^XBZe5l^B5xhPeq0l0fQ!r;B4q1>@VRmaA9|INTmK zJe9uFl^}iM8uPZMXu(Tdc6nc)SzrC1xu128;9;-h8NE}I9t&i7+ih}G5a3{8id|7X zseCmz`%|CJPmgMP_jvs)zrHf^#;WL!$gZa)3zwRB#xd${i1nyEEvx0hWDesXGW%7onbolpy2>^y8&{ne1IH5PZ!6K3dXlrtxshr^0+>1 zSo zbxoA3D!y^uTzu>7)aYv~UubsjnsnHHN$;JvJQB}d#Boi%xIn$hMQNgk$|dJ~zTdx| zeF#jw@S#rmVe#_Zm-3T6=e!HQw0PEPmq#(qJ12R7OsslwH!=R6jgHm3b8lCtnt9%l zF8ipsG=F_YKzC)Re#os)cU8dZlx)Ae+n}Fc*KcON`DJJP?+L4V_psm4F0lZ5WunIt a`xorF^ID!>=E%?i1(K($pUXO@geCy@VR)~9q7c#eK_ zh&s5I;EI;nY`yhC)K8!C3j!C_sV$X?=x{Cd#3)ZIJWFg zds~A8NMqH7*hKwoyV@w3-fM>~ce`X-o&7lR+J=X_r_a%yw#RwJjjS`AK*JRTUO1Mw z?p;&4y7 Date: Sat, 2 Jul 2022 23:17:45 +0200 Subject: [PATCH 0327/1315] GS1: accept GS after every field according to spec See also https://github.com/nu-book/zxing-cpp/issues/338#issuecomment-1172957337 --- core/src/GS1.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/core/src/GS1.cpp b/core/src/GS1.cpp index ab6b94d5d4..50c25debd7 100644 --- a/core/src/GS1.cpp +++ b/core/src/GS1.cpp @@ -272,13 +272,10 @@ std::string HRIFromGS1(const std::string& gs1) res += rem.substr(0, fieldSize); rem.remove_prefix(fieldSize); - if (Size(rem) && rem.front() == GS) { - // TODO: we have DataBar samples where the fixed-length 422 ends with a GS, sigh... - if (i->isVariableLength() || i->aiPrefix == "422") - rem.remove_prefix(1); - else - return {}; - } + // See General Specification v22.0 Section 7.8.6.3: "...the processing routine SHALL tolerate a single separator character + // immediately following any element string, whether necessary or not..." + if (Size(rem) && rem.front() == GS) + rem.remove_prefix(1); } return res; From 747f8d97c965172e8ca0d21ce2ff1d2b80937795 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 3 Jul 2022 00:47:14 +0200 Subject: [PATCH 0328/1315] Error: remove all remaining internal use of `DecodeStatus` Checksum and Format errors are now passed with fully decoded and located 1D symbols. For the 2D symbols, this is still a TODO. deprecate `DecodeStatus` related helper functions. --- core/src/DecodeStatus.h | 6 +++--- core/src/DecoderResult.h | 2 +- core/src/Result.cpp | 18 +++++++++--------- core/src/Result.h | 2 +- core/src/oned/ODCode128Reader.cpp | 9 +++++---- core/src/oned/ODCode39Reader.cpp | 10 ++++++---- core/src/oned/ODCode93Reader.cpp | 9 +++++---- core/src/oned/ODDataBarExpandedReader.cpp | 2 +- core/src/oned/ODITFReader.cpp | 5 +++-- core/src/oned/ODMultiUPCEANReader.cpp | 5 +++-- core/src/pdf417/PDFDetector.h | 1 - 11 files changed, 37 insertions(+), 32 deletions(-) diff --git a/core/src/DecodeStatus.h b/core/src/DecodeStatus.h index 5c8fba4a47..80a52ba3c3 100644 --- a/core/src/DecodeStatus.h +++ b/core/src/DecodeStatus.h @@ -15,17 +15,17 @@ enum class DecodeStatus ChecksumError, }; -inline bool StatusIsOK(DecodeStatus status) +[[deprecated]] inline bool StatusIsOK(DecodeStatus status) { return status == DecodeStatus::NoError; } -inline bool StatusIsError(DecodeStatus status) +[[deprecated]] inline bool StatusIsError(DecodeStatus status) { return status != DecodeStatus::NoError; } -inline const char* ToString(DecodeStatus status) +[[deprecated]] inline const char* ToString(DecodeStatus status) { constexpr const char* names[] = {"NoError", "NotFound", "FormatError", "ChecksumError"}; return names[static_cast(status)]; diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 7c54337f55..9340da4182 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -39,7 +39,7 @@ class DecoderResult public: DecoderResult() = default; DecoderResult(Error error) : _error(error) {} - DecoderResult(ByteArray&& rawBytes, Content&& bytes = {}) : _rawBytes(std::move(rawBytes)), _content(std::move(bytes)) + DecoderResult(ByteArray&& rawBytes, Content&& bytes) : _rawBytes(std::move(rawBytes)), _content(std::move(bytes)) { _numBits = 8 * Size(_rawBytes); } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index ae166486ae..4a1daa6ab7 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -19,11 +19,11 @@ namespace ZXing { Result::Result(DecodeStatus status) : _error(Status2Error(status)) {} -Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, - SymbologyIdentifier si, ByteArray&& rawBytes, bool readerInit, const std::string& ai) - : - _format(format), +Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, + ByteArray&& rawBytes, bool readerInit, const std::string& ai) + : _format(format), _content({ByteArray(text)}, si, ai), + _error(error), _position(Line(y, xStart, xStop)), _rawBytes(std::move(rawBytes)), _numBits(Size(_rawBytes) * 8), @@ -152,11 +152,6 @@ Result MergeStructuredAppendSequence(const Results& results) std::list allResults(results.begin(), results.end()); allResults.sort([](const Result& r1, const Result& r2) { return r1.sequenceIndex() < r2.sequenceIndex(); }); - if (allResults.back().sequenceSize() != Size(allResults) || - !std::all_of(allResults.begin(), allResults.end(), - [&](Result& it) { return it.sequenceId() == allResults.front().sequenceId(); })) - return Result(DecodeStatus::FormatError); - Result res = allResults.front(); for (auto i = std::next(allResults.begin()); i != allResults.end(); ++i) res._content.append(i->_content); @@ -164,6 +159,11 @@ Result MergeStructuredAppendSequence(const Results& results) res._position = {}; res._sai.index = -1; + if (allResults.back().sequenceSize() != Size(allResults) || + !std::all_of(allResults.begin(), allResults.end(), + [&](Result& it) { return it.sequenceId() == allResults.front().sequenceId(); })) + res._error = FormatError("sequenceIDs not matching during structured append sequence merging"); + return res; } diff --git a/core/src/Result.h b/core/src/Result.h index befd92e3b8..6c7ed47da1 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -34,7 +34,7 @@ class Result explicit Result(DecodeStatus status); // 1D convenience constructor - Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, + Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error = {}, ByteArray&& rawBytes = {}, bool readerInit = false, const std::string& ai = {}); Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index bb7ab97964..42fa421b79 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -252,9 +252,9 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu if (code == CODE_STOP) break; if (code >= CODE_START_A) - return Result(DecodeStatus::FormatError); + return {}; if (!raw2txt.decode(code)) - return Result(DecodeStatus::FormatError); + return {}; rawCodes.push_back(static_cast(code)); } @@ -268,15 +268,16 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuietZoneAfter(QUIET_ZONE/13)) return {}; + Error error; int checksum = rawCodes.front(); for (int i = 1; i < Size(rawCodes) - 1; ++i) checksum += i * rawCodes[i]; // the last code is the checksum: if (checksum % 103 != rawCodes.back()) - return Result(DecodeStatus::ChecksumError); + error = ChecksumError(); int xStop = next.pixelsTillEnd(); - return Result(raw2txt.text(), rowNumber, xStart, xStop, BarcodeFormat::Code128, raw2txt.symbologyIdentifier(), + return Result(raw2txt.text(), rowNumber, xStart, xStop, BarcodeFormat::Code128, raw2txt.symbologyIdentifier(), error, std::move(rawCodes), raw2txt.readerInit(), raw2txt.applicationIndicator()); } diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index 469b61628c..cadaf784a2 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -7,6 +7,7 @@ #include "ODCode39Reader.h" #include "DecodeHints.h" +#include "DecoderResult.h" #include "Result.h" #include "ZXContainerAlgorithms.h" @@ -121,23 +122,24 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique if (Size(txt) < minCharCount - 2 || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) return {}; + Error error; if (_validateCheckSum) { auto checkDigit = txt.back(); txt.pop_back(); int checksum = TransformReduce(txt, 0, [](char c) { return IndexOf(ALPHABET, c); }); if (checkDigit != ALPHABET[checksum % 43]) - return Result(DecodeStatus::ChecksumError); + error = ChecksumError(); } - if (_extendedMode && !DecodeExtendedCode39AndCode93(txt, "$%/+")) - return Result(DecodeStatus::FormatError); + if (!error && _extendedMode && !DecodeExtendedCode39AndCode93(txt, "$%/+")) + error = FormatError("Decoding extended Code39/Code93 failed"); // Symbology identifier modifiers ISO/IEC 16388:2007 Annex C Table C.1 constexpr const char symbologyModifiers[4] = { '0', '3' /*checksum*/, '4' /*extended*/, '7' /*checksum,extended*/ }; SymbologyIdentifier symbologyIdentifier = {'A', symbologyModifiers[(int)_extendedMode * 2 + (int)_validateCheckSum]}; int xStop = next.pixelsTillEnd(); - return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::Code39, symbologyIdentifier); + return Result(std::move(txt), rowNumber, xStart, xStop, BarcodeFormat::Code39, symbologyIdentifier, error); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index 4cc499205d..a2668f9af6 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -114,20 +114,21 @@ Result Code93Reader::decodePattern(int rowNumber, PatternView& next, std::unique if (!next.isValid() || next[CHAR_LEN] > next.sum(CHAR_LEN) / 4 || !next.hasQuietZoneAfter(QUIET_ZONE_SCALE)) return {}; + Error error; if (!CheckChecksums(txt)) - return Result(DecodeStatus::ChecksumError); + error = ChecksumError(); // Remove checksum digits txt.resize(txt.size() - 2); - if (!DecodeExtendedCode39AndCode93(txt, "abcd")) - return Result(DecodeStatus::FormatError); + if (!error && !DecodeExtendedCode39AndCode93(txt, "abcd")) + error = FormatError("Decoding extended Code39/Code93 failed"); // Symbology identifier ISO/IEC 15424:2008 4.4.10 no modifiers SymbologyIdentifier symbologyIdentifier = {'G', '0'}; int xStop = next.pixelsTillEnd(); - return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::Code93, symbologyIdentifier); + return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::Code93, symbologyIdentifier, error); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index be1c1247c1..fb89a596ef 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -341,7 +341,7 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, auto pairs = ReadRowOfPairs(view, rowNumber); if (pairs.empty() || !ChecksumIsValid(pairs)) - return Result(DecodeStatus::NotFound); + return {}; #else if (!state) state.reset(new DBERState); diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 2e4db3f3f3..a251d65fe7 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -76,8 +76,9 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt if (!IsRightGuard(next, STOP_PATTERN_1, minQuietZone) && !IsRightGuard(next, STOP_PATTERN_2, minQuietZone)) return {}; + Error error; if (_validateCheckSum && !GTIN::IsCheckDigitValid(txt)) - return Result(DecodeStatus::ChecksumError); + error = ChecksumError(); // Symbology identifier ISO/IEC 16390:2007 Annex C Table C.1 // See also GS1 General Specifications 5.1.3 Figure 5.1.3-2 @@ -87,7 +88,7 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt symbologyIdentifier.modifier = '1'; // Modulo 10 symbol check character validated and transmitted int xStop = next.pixelsTillEnd(); - return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::ITF, symbologyIdentifier); + return Result(txt, rowNumber, xStart, xStop, BarcodeFormat::ITF, symbologyIdentifier, error); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 22da7ad2cf..c1aa0e4104 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -275,8 +275,9 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u (_hints.hasFormat(BarcodeFormat::UPCE) && UPCE(res, begin)))) return {}; + Error error; if (!GTIN::IsCheckDigitValid(res.format == BarcodeFormat::UPCE ? UPCEANCommon::ConvertUPCEtoUPCA(res.txt) : res.txt)) - return Result(DecodeStatus::ChecksumError); + error = ChecksumError(); // If UPC-A was a requested format and we detected a EAN-13 code with a leading '0', then we drop the '0' and call it // a UPC-A code. @@ -309,7 +310,7 @@ Result MultiUPCEANReader::decodePattern(int rowNumber, PatternView& next, std::u if (_hints.eanAddOnSymbol() == EanAddOnSymbol::Require && !addOnRes.isValid()) return {}; - return {res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, symbologyIdentifier}; + return Result(res.txt, rowNumber, begin.pixelsInFront(), res.end.pixelsTillEnd(), res.format, symbologyIdentifier, error); } } // namespace ZXing::OneD diff --git a/core/src/pdf417/PDFDetector.h b/core/src/pdf417/PDFDetector.h index ab375ff1c1..d3cc9bdf79 100644 --- a/core/src/pdf417/PDFDetector.h +++ b/core/src/pdf417/PDFDetector.h @@ -17,7 +17,6 @@ namespace ZXing { class BitMatrix; class BinaryBitmap; -enum class DecodeStatus; namespace Pdf417 { From 61063aad85afb8f7ef610e48aa17d64344e228af Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 01:20:03 +0200 Subject: [PATCH 0329/1315] DecodeHints: deprecate unused `hasNoFormat` --- core/src/DecodeHints.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 558dfc57be..d8c76c16e5 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -146,7 +146,7 @@ class DecodeHints [[deprecated]] DecodeHints& setAssumeCode39CheckDigit(bool v) { return setValidateCode39CheckSum(v); } bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f) || _formats.empty(); } - bool hasNoFormat() const noexcept { return _formats.empty(); } + [[deprecated]] bool hasNoFormat() const noexcept { return _formats.empty(); } }; } // ZXing From 233a04a6d3ee72cd417469da10257600b057d553 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 01:21:37 +0200 Subject: [PATCH 0330/1315] Error: fix `returnErrors` behavior for DataMatrix --- core/src/Reader.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/Reader.h b/core/src/Reader.h index bdc8cd0b1e..716d26b94d 100644 --- a/core/src/Reader.h +++ b/core/src/Reader.h @@ -6,6 +6,7 @@ #pragma once +#include "DecodeHints.h" #include "Result.h" namespace ZXing { @@ -27,7 +28,7 @@ class Reader // WARNING: this API is experimental and may change/disappear virtual Results decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const { auto res = decode(image); - return res.isValid() ? Results{std::move(res)} : Results{}; + return res.isValid() || (_hints.returnErrors() && res.format() != BarcodeFormat::None) ? Results{std::move(res)} : Results{}; } }; From bd6d69b5b3859fc12b2d5e5f6230bf42b8f44aa8 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 01:24:00 +0200 Subject: [PATCH 0331/1315] DataMatrix: pass already parsed version to `CodewordsFromBitMatrix` --- core/src/datamatrix/DMBitLayout.cpp | 10 +++------- core/src/datamatrix/DMBitLayout.h | 4 +++- core/src/datamatrix/DMDecoder.cpp | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/core/src/datamatrix/DMBitLayout.cpp b/core/src/datamatrix/DMBitLayout.cpp index 1acffdb662..c0b0cddc7c 100644 --- a/core/src/datamatrix/DMBitLayout.cpp +++ b/core/src/datamatrix/DMBitLayout.cpp @@ -170,15 +170,11 @@ static BitMatrix ExtractDataBits(const Version& version, const BitMatrix& bits) * * @return bytes encoded within the Data Matrix Code */ -ByteArray CodewordsFromBitMatrix(const BitMatrix& bits) +ByteArray CodewordsFromBitMatrix(const BitMatrix& bits, const Version& version) { - const Version* version = VersionForDimensionsOf(bits); - if (version == nullptr) - return {}; - - BitMatrix dataBits = ExtractDataBits(*version, bits); + BitMatrix dataBits = ExtractDataBits(version, bits); - ByteArray result(version->totalCodewords()); + ByteArray result(version.totalCodewords()); auto codeword = result.begin(); VisitMatrix(dataBits.height(), dataBits.width(), [&codeword, &dataBits](const BitPosArray& bitPos) { diff --git a/core/src/datamatrix/DMBitLayout.h b/core/src/datamatrix/DMBitLayout.h index 395ba23ffd..92f8e291f3 100644 --- a/core/src/datamatrix/DMBitLayout.h +++ b/core/src/datamatrix/DMBitLayout.h @@ -12,8 +12,10 @@ class ByteArray; namespace DataMatrix { +class Version; + BitMatrix BitMatrixFromCodewords(const ByteArray& codewords, int width, int height); -ByteArray CodewordsFromBitMatrix(const BitMatrix& bits); +ByteArray CodewordsFromBitMatrix(const BitMatrix& bits, const Version& version); } // namespace DataMatrix } // namespace ZXing diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 186d291ca8..75da4309ae 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -399,7 +399,7 @@ static DecoderResult DoDecode(const BitMatrix& bits) return FormatError(); // Read codewords - ByteArray codewords = CodewordsFromBitMatrix(bits); + ByteArray codewords = CodewordsFromBitMatrix(bits, *version); if (codewords.empty()) return FormatError(); From d2dc44b6facae5d6f9a5ac6fae2b978ebe860f34 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 01:26:05 +0200 Subject: [PATCH 0332/1315] Error: replace Error subclasses with macros, implementing tracing support Use `__FILE__` and `__LINE__` to report location of error. --- core/src/Error.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index 4b63dd8952..6eeeb0f001 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -18,8 +18,16 @@ class Error Type type() const noexcept { return _type; } const std::string& msg() const noexcept { return _msg; } operator bool() const noexcept { return _type != Type::None; } + std::string location() const noexcept + { + return _file.empty() ? "" : _file.substr(_file.find_last_of("/\\") + 1) + ":" + std::to_string(_line); + } Error() = default; + Error(Type type, std::string msg = {}) : _type(type), _msg(std::move(msg)) {} + Error(std::string file, int line, Type type, std::string msg = {}) + : _type(type), _msg(std::move(msg)), _file(std::move(file)), _line(line) + {} static constexpr auto Format = Type::Format; static constexpr auto Checksum = Type::Checksum; @@ -28,8 +36,8 @@ class Error protected: Type _type = Type::None; std::string _msg; - - Error(Type type, std::string msg) : _type(type), _msg(std::move(msg)) {} + std::string _file; + int _line = -1; }; inline bool operator==(const Error& e, Error::Type t) noexcept { return e.type() == t; } @@ -37,17 +45,9 @@ inline bool operator!=(const Error& e, Error::Type t) noexcept { return !(e == t inline bool operator==(Error::Type t, const Error& e) noexcept { return e.type() == t; } inline bool operator!=(Error::Type t, const Error& e) noexcept { return !(t == e); } -class FormatError : public Error -{ -public: - FormatError(std::string msg = {}) : Error(Format, std::move(msg)) {} -}; - -class ChecksumError : public Error -{ -public: - ChecksumError(std::string msg = {}) : Error(Checksum, std::move(msg)) {} -}; +#define FormatError(...) Error(__FILE__, __LINE__, Error::Format, ##__VA_ARGS__) +#define ChecksumError(...) Error(__FILE__, __LINE__, Error::Checksum, ##__VA_ARGS__) +#define UnsupportedError(...) Error(__FILE__, __LINE__, Error::Unsupported, ##__VA_ARGS__) inline std::string ToString(const Error& e) { @@ -55,6 +55,8 @@ inline std::string ToString(const Error& e) std::string ret = name[static_cast(e.type())]; if (!e.msg().empty()) ret += " (" + e.msg() + ")"; + if (!e.location().empty()) + ret += " @ " + e.location(); return ret; } @@ -62,8 +64,8 @@ inline std::string ToString(const Error& e) inline Error Status2Error(DecodeStatus s) { switch (s) { - case DecodeStatus::FormatError: return FormatError(); - case DecodeStatus::ChecksumError: return ChecksumError(); + case DecodeStatus::FormatError: return Error(Error::Format); + case DecodeStatus::ChecksumError: return Error(Error::Checksum); default: return {}; } } From f2e9e5e73006759662deb9c2e5b3b1ddcb91fd8e Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 09:46:06 +0200 Subject: [PATCH 0333/1315] Error: add some `FormatError` messages and use `UnsupportedError` --- core/src/DecoderResult.h | 2 +- core/src/aztec/AZDecoder.cpp | 20 ++++----- core/src/datamatrix/DMDecoder.cpp | 41 +++++++++---------- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 4 +- core/src/qrcode/QRDecoder.cpp | 37 ++++++++--------- test/unit/aztec/AZDecoderTest.cpp | 4 +- 7 files changed, 53 insertions(+), 57 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 9340da4182..34822a7791 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -38,7 +38,7 @@ class DecoderResult public: DecoderResult() = default; - DecoderResult(Error error) : _error(error) {} + DecoderResult(Error error) : _error(std::move(error)) {} DecoderResult(ByteArray&& rawBytes, Content&& bytes) : _rawBytes(std::move(rawBytes)), _content(std::move(bytes)) { _numBits = 8 * Size(_rawBytes); diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index e5c5d34c78..1a71e0022f 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -143,12 +143,12 @@ static BitArray CorrectBits(const DetectorResult& ddata, const BitArray& rawbits int numECCodewords = numCodewords - numDataCodewords; if (numCodewords < numDataCodewords) - return {}; + throw FormatError("Invalid number of code words"); auto dataWords = ToInts(rawbits, codewordSize, numCodewords, Size(rawbits) % codewordSize); if (!ReedSolomonDecode(*gf, dataWords, numECCodewords)) - return {}; + throw ChecksumError(); // drop the ECCodewords from the dataWords array dataWords.resize(numDataCodewords); @@ -306,12 +306,12 @@ DecoderResult Decode(const BitArray& bits) try { DecodeContent(bits, res); - } catch (const std::out_of_range&) { // see ReadBits() + } catch (const std::exception&) { // see BitArrayView::readBits return FormatError(); } if (res.bytes.empty()) - return FormatError(); + return FormatError("Empty symbol content"); // Check for Structured Append - need 4 5-bit words, beginning with ML UL, ending with index and count bool haveStructuredAppend = Size(bits) > 20 && ToInt(bits, 0, 5) == 29 // latch to MIXED (from UPPER) @@ -348,12 +348,12 @@ DecoderResult Decode(const BitArray& bits) DecoderResult Decode(const DetectorResult& detectorResult) { - BitArray bits = CorrectBits(detectorResult, ExtractBits(detectorResult)); - - if (!bits.size()) - return FormatError(); - - return Decode(bits).setReaderInit(detectorResult.readerInit()); + try { + auto bits = CorrectBits(detectorResult, ExtractBits(detectorResult)); + return Decode(bits).setReaderInit(detectorResult.readerInit()); + } catch (Error e) { + return e; + } } } // namespace ZXing::Aztec diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 75da4309ae..a82440c5be 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -161,7 +161,7 @@ static void DecodeC40OrTextSegment(BitSource& bits, Content& result, Mode mode) else if (cValue < 40) // Size(BASIC_SET_CHARS) result.push_back(upperShift(BASIC_SET_CHARS[cValue])); else - throw std::runtime_error("invalid value in C40 or Text segment"); + throw FormatError("invalid value in C40 or Text segment"); break; case 1: result.push_back(upperShift(cValue)); break; case 2: @@ -170,7 +170,7 @@ static void DecodeC40OrTextSegment(BitSource& bits, Content& result, Mode mode) else if (cValue == 30) // Upper Shift upperShift.set = true; else - throw std::runtime_error("invalid value in C40 or Text segment"); + throw FormatError("invalid value in C40 or Text segment"); break; case 3: if (mode == Mode::C40) @@ -178,9 +178,9 @@ static void DecodeC40OrTextSegment(BitSource& bits, Content& result, Mode mode) else if (cValue < Size(TEXT_SHIFT3_SET_CHARS)) result.push_back(upperShift(TEXT_SHIFT3_SET_CHARS[cValue])); else - throw std::runtime_error("invalid value in C40 or Text segment"); + throw FormatError("invalid value in C40 or Text segment"); break; - default: throw std::runtime_error("invalid value in C40 or Text segment"); ; + default: throw FormatError("invalid value in C40 or Text segment"); ; } } } @@ -196,7 +196,7 @@ static void DecodeAnsiX12Segment(BitSource& bits, Content& result) // X12 segment terminator , separator *, sub-element separator >, space static const char segChars[4] = {'\r', '*', '>', ' '}; if (cValue < 0) - throw std::runtime_error("invalid value in AnsiX12 segment"); + throw FormatError("invalid value in AnsiX12 segment"); else if (cValue < 4) result.push_back(segChars[cValue]); else if (cValue < 14) // 0 - 9 @@ -204,7 +204,7 @@ static void DecodeAnsiX12Segment(BitSource& bits, Content& result) else if (cValue < 40) // A - Z result.push_back((char)(cValue + 51)); else - throw std::runtime_error("invalid value in AnsiX12 segment"); + throw FormatError("invalid value in AnsiX12 segment"); } } } @@ -262,7 +262,7 @@ static void DecodeBase256Segment(BitSource& bits, Content& result) // We're seeing NegativeArraySizeException errors from users. if (count < 0) - throw std::runtime_error("invalid count in Base256 segment"); + throw FormatError("invalid count in Base256 segment"); result.reserve(count); for (int i = 0; i < count; i++) { @@ -277,6 +277,7 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) { BitSource bits(bytes); Content result; + Error error; result.symbology = {'d', '1', 3}; // ECC 200 (ISO 16022:2006 Annex N Table N.1) std::string resultTrailer; @@ -292,7 +293,7 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) while (!done && bits.available() >= 8) { int oneByte = bits.readBits(8); switch (oneByte) { - case 0: throw std::runtime_error("invalid 0 code word"); + case 0: throw FormatError("invalid 0 code word"); case 129: done = true; break; // Pad -> we are done, ignore the rest of the bits case 230: DecodeC40OrTextSegment(bits, result, Mode::C40); break; case 231: DecodeBase256Segment(bits, result); break; @@ -309,13 +310,13 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) break; case 233: // Structured Append if (!firstCodeword) // Must be first ISO 16022:2006 5.6.1 - throw std::runtime_error("structured append tag must be first code word"); + throw FormatError("structured append tag must be first code word"); ParseStructuredAppend(bits, sai); firstFNC1Position = 5; break; case 234: // Reader Programming if (!firstCodeword) // Must be first ISO 16022:2006 5.2.4.9 - throw std::runtime_error("reader programming tag must be first code word"); + throw FormatError("reader programming tag must be first code word"); readerInit = true; break; case 235: upperShift.set = true; break; // Upper Shift (shift to Extended ASCII) @@ -343,16 +344,13 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) // work around encoders that use unlatch to ASCII as last code word (ask upstream) if (oneByte == 254 && bits.available() == 0) break; - throw std::runtime_error("invalid code word"); + throw FormatError("invalid code word"); } } firstCodeword = false; } - } catch (const std::exception& e) { -#ifndef NDEBUG - printf("DMDecoder error: %s\n", e.what()); -#endif - return FormatError(); + } catch (Error e) { + error = std::move(e); } result.append(resultTrailer); @@ -360,8 +358,9 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) result.symbology.modifier += isDMRE * 6; return DecoderResult(std::move(bytes), std::move(result)) - .setStructuredAppend(sai) - .setReaderInit(readerInit); + .setError(std::move(error)) + .setStructuredAppend(sai) + .setReaderInit(readerInit); } } // namespace DecodedBitStreamParser @@ -396,17 +395,17 @@ static DecoderResult DoDecode(const BitMatrix& bits) // Construct a parser and read version, error-correction level const Version* version = VersionForDimensionsOf(bits); if (version == nullptr) - return FormatError(); + return FormatError("Invalid matrix dimension"); // Read codewords ByteArray codewords = CodewordsFromBitMatrix(bits, *version); if (codewords.empty()) - return FormatError(); + return FormatError("Invalid number of code words"); // Separate into data blocks std::vector dataBlocks = GetDataBlocks(codewords, *version); if (dataBlocks.empty()) - return FormatError(); + return FormatError("Invalid number of data blocks"); // Count total number of data bytes ByteArray resultBytes(TransformReduce(dataBlocks, 0, [](const auto& db) { return db.numDataCodewords; })); diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index cbf875ac71..058527cf19 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -325,7 +325,7 @@ DecoderResult Decode(const BitMatrix& bits) else return ChecksumError(); break; - default: return FormatError(); + default: return FormatError("Invalid mode"); } std::copy_n(codewords.begin(), 10, datawords.begin()); diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index f7f493d300..631af0b07d 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -728,12 +728,12 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel) break; case LINKAGE_OTHER: // Allowed to treat as invalid by ISO/IEC 24723:2010 5.4.1.5 and 5.4.6.1 when in Basic Channel Mode - throw FormatError(); // TODO: add NotSupported error + throw UnsupportedError("LINKAGE_OTHER, see ISO/IEC 24723:2010 5.4.1.5"); break; default: if (code >= TEXT_COMPACTION_MODE_LATCH) { // Reserved codewords (all others in switch) // Allowed to treat as invalid by ISO/IEC 24723:2010 5.4.6.1 when in Basic Channel Mode - throw FormatError(); // TODO: add NotSupported error + throw UnsupportedError("TEXT_COMPACTION_MODE_LATCH, see ISO/IEC 24723:2010 5.4.6.1"); } else { // Default mode is Text Compaction mode Alpha sub-mode (ISO/IEC 15438:2015 5.4.2.1) codeIndex = TextCompaction(codewords, codeIndex - 1, result); diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 1af47dd5dc..cfb94a774e 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -176,7 +176,7 @@ static void DecodeNumericSegment(BitSource& bits, int count, Content& result) // Each 10 bits encodes three digits int threeDigitsBits = bits.readBits(10); if (threeDigitsBits >= 1000) - throw std::runtime_error("Invalid value in numeric segment"); + throw FormatError("Invalid value in numeric segment"); result += ToAlphaNumericChar(threeDigitsBits / 100); result += ToAlphaNumericChar((threeDigitsBits / 10) % 10); @@ -188,7 +188,7 @@ static void DecodeNumericSegment(BitSource& bits, int count, Content& result) // Two digits left over to read, encoded in 7 bits int twoDigitsBits = bits.readBits(7); if (twoDigitsBits >= 100) - throw std::runtime_error("Invalid value in numeric segment"); + throw FormatError("Invalid value in numeric segment"); result += ToAlphaNumericChar(twoDigitsBits / 10); result += ToAlphaNumericChar(twoDigitsBits % 10); @@ -196,7 +196,7 @@ static void DecodeNumericSegment(BitSource& bits, int count, Content& result) // One digit left over to read int digitBits = bits.readBits(4); if (digitBits >= 10) - throw std::runtime_error("Invalid value in numeric segment"); + throw FormatError("Invalid value in numeric segment"); result += ToAlphaNumericChar(digitBits); } @@ -219,7 +219,7 @@ static ECI ParseECIValue(BitSource& bits) int secondThirdBytes = bits.readBits(16); return ECI(((firstByte & 0x1F) << 16) | secondThirdBytes); } - throw std::runtime_error("ParseECIValue: invalid value"); + throw FormatError("ParseECIValue: invalid value"); } /** @@ -257,6 +257,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo { BitSource bits(bytes); Content result; + Error error; result.symbology = {'Q', '1', 1}; StructuredAppendInfo structuredAppend; const int modeBitLength = CodecModeBitsLength(version); @@ -273,13 +274,13 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo switch (mode) { case CodecMode::FNC1_FIRST_POSITION: // if (!result.empty()) // uncomment to enforce specification -// throw std::runtime_error("GS1 Indicator (FNC1 in first position) at illegal position"); +// throw FormatError("GS1 Indicator (FNC1 in first position) at illegal position"); result.symbology.modifier = '3'; result.applicationIndicator = "GS1"; // In Alphanumeric mode undouble doubled percents and treat single percent as break; case CodecMode::FNC1_SECOND_POSITION: if (!result.empty()) - throw std::runtime_error("AIM Application Indicator (FNC1 in second position) at illegal position"); + throw FormatError("AIM Application Indicator (FNC1 in second position) at illegal position"); result.symbology.modifier = '5'; // As above // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position), "00-99" or "A-Za-z" if (int appInd = bits.readBits(8); appInd < 10) // "00-09" @@ -289,7 +290,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo else if ((appInd >= 165 && appInd <= 190) || (appInd >= 197 && appInd <= 222)) // "A-Za-z" result += static_cast(appInd - 100); else - throw std::runtime_error("Invalid AIM Application Indicator"); + throw FormatError("Invalid AIM Application Indicator"); result.applicationIndicator = result.bytes.asString(); // see also above break; case CodecMode::STRUCTURED_APPEND: @@ -307,7 +308,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo // First handle Hanzi mode which does not start with character count // chinese mode contains a sub set indicator right after mode indicator if (int subset = bits.readBits(4); subset != 1) // GB2312_SUBSET is the only supported one right now - throw std::runtime_error("Unsupported HANZI subset"); + throw FormatError("Unsupported HANZI subset"); int count = bits.readBits(CharacterCountBits(mode, version)); DecodeHanziSegment(bits, count, result); break; @@ -321,22 +322,18 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo case CodecMode::ALPHANUMERIC: DecodeAlphanumericSegment(bits, count, result); break; case CodecMode::BYTE: DecodeByteSegment(bits, count, result); break; case CodecMode::KANJI: DecodeKanjiSegment(bits, count, result); break; - default: throw std::runtime_error("Invalid CodecMode"); + default: throw FormatError("Invalid CodecMode"); } break; } } } - } - catch (const std::exception& e) - { -#ifndef NDEBUG - printf("QRDecoder error: %s\n", e.what()); -#endif - return FormatError(); + } catch (Error e) { + error = std::move(e); } return DecoderResult(std::move(bytes), std::move(result)) + .setError(std::move(error)) .setEcLevel(ToString(ecLevel)) .setStructuredAppend(structuredAppend); } @@ -345,22 +342,22 @@ DecoderResult Decode(const BitMatrix& bits) { const Version* pversion = ReadVersion(bits); if (!pversion) - return FormatError(); + return FormatError("Invalid version"); const Version& version = *pversion; auto formatInfo = ReadFormatInformation(bits, version.isMicroQRCode()); if (!formatInfo.isValid()) - return FormatError(); + return FormatError("Invalid format informatino"); // Read codewords ByteArray codewords = ReadCodewords(bits, version, formatInfo); if (codewords.empty()) - return FormatError(); + return FormatError("Failed to read codewords"); // Separate into data blocks std::vector dataBlocks = DataBlock::GetDataBlocks(codewords, version, formatInfo.ecLevel); if (dataBlocks.empty()) - return FormatError(); + return FormatError("Failed to get data blocks"); // Count total number of data bytes const auto op = [](auto totalBytes, const auto& dataBlock){ return totalBytes + dataBlock.numDataCodewords();}; diff --git a/test/unit/aztec/AZDecoderTest.cpp b/test/unit/aztec/AZDecoderTest.cpp index b1b7c5cc24..43f39c4872 100644 --- a/test/unit/aztec/AZDecoderTest.cpp +++ b/test/unit/aztec/AZDecoderTest.cpp @@ -96,7 +96,7 @@ TEST(AZDecoderTest, DecodeTooManyErrors) , 'X', true); DecoderResult result = parse(std::move(bits), true, 16, 4); - EXPECT_EQ(result.error(), Error::Format); + EXPECT_EQ(result.error(), Error::Checksum); } TEST(AZDecoderTest, DecodeTooManyErrors2) @@ -132,7 +132,7 @@ TEST(AZDecoderTest, DecodeTooManyErrors2) , 'X', true); DecoderResult result = parse(std::move(bits), true, 16, 4); - EXPECT_EQ(result.error(), Error::Format); + EXPECT_EQ(result.error(), Error::Checksum); } // Helper taking bit string to call GetEncodedData() From 5abaacf334f8944942a4740bffb6d917988ffe08 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 09:47:05 +0200 Subject: [PATCH 0334/1315] Error: make bool case explicit for now --- core/src/Error.h | 2 +- example/ZXingReader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index 6eeeb0f001..43ff156bf2 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -17,7 +17,7 @@ class Error enum class Type { None, Format, Checksum, Unsupported }; Type type() const noexcept { return _type; } const std::string& msg() const noexcept { return _msg; } - operator bool() const noexcept { return _type != Type::None; } + explicit operator bool() const noexcept { return _type != Type::None; } std::string location() const noexcept { return _file.empty() ? "" : _file.substr(_file.find_last_of("/\\") + 1) + ":" + std::to_string(_line); diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index f134809807..3532fb3280 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -172,7 +172,7 @@ int main(int argc, char* argv[]) for (auto&& result : results) { if (!outPath.empty()) - drawRect(image, result.position(), result.error()); + drawRect(image, result.position(), bool(result.error())); ret |= static_cast(result.error().type()); From a29c3174dcb02e1e46df334c4a303d5784672d58 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 09:47:36 +0200 Subject: [PATCH 0335/1315] Error: add unit tests --- test/unit/CMakeLists.txt | 1 + test/unit/ErrorTest.cpp | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 test/unit/ErrorTest.cpp diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 82503c0c90..871bac6f76 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable (UnitTest BitHacksTest.cpp CharacterSetECITest.cpp ContentTest.cpp + ErrorTest.cpp GTINTest.cpp GS1Test.cpp ReedSolomonTest.cpp diff --git a/test/unit/ErrorTest.cpp b/test/unit/ErrorTest.cpp new file mode 100644 index 0000000000..66eb6ac611 --- /dev/null +++ b/test/unit/ErrorTest.cpp @@ -0,0 +1,43 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "Error.h" + +#include "gtest/gtest.h" + +using namespace ZXing; + +TEST(ErrorTest, Default) +{ + Error e; + + EXPECT_FALSE(e); + EXPECT_EQ(e.type(), Error::Type::None); + EXPECT_EQ(e.msg().empty(), true); + EXPECT_EQ(e.location().empty(), true); +} + +TEST(ErrorTest, Empty) +{ + Error e = ChecksumError(); + + EXPECT_TRUE(e); + EXPECT_EQ(e.type(), Error::Type::Checksum); + EXPECT_EQ(e.type(), Error::Checksum); + EXPECT_EQ(e, Error::Checksum); + EXPECT_EQ(Error::Checksum, e); + EXPECT_EQ(e.msg().empty(), true); + EXPECT_EQ(e.location().empty(), false); +} + +TEST(ErrorTest, WithMsg) +{ + Error e = FormatError("something is wrong"); int line = __LINE__; + + EXPECT_TRUE(e); + EXPECT_EQ(e, Error::Format); + EXPECT_EQ(e.msg(), "something is wrong"); + EXPECT_EQ(e.location(), "ErrorTest.cpp:" + std::to_string(line)); +} From 430880c046fcf856c010c2017e5be46f2bacdc6f Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 10:13:21 +0200 Subject: [PATCH 0336/1315] ODReader: fix #350 (failed 1d symbol merging) --- core/src/Result.cpp | 3 +++ core/src/oned/ODReader.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 4a1daa6ab7..e7f102e663 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -135,6 +135,9 @@ bool Result::operator==(const Result& o) const if (BarcodeFormats(BarcodeFormat::TwoDCodes).testFlag(format())) return IsInside(Center(o.position()), position()); + // 1D comparisons only implemented for this->lineCount == 1 + assert(lineCount() == 1); + // if one line is less than half the length of the other away from the // latter, we consider it to belong to the same symbol auto dTop = maxAbsComponent(o.position().topLeft() - position().topLeft()); diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index afbd698485..4d5f2f374e 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -154,7 +154,7 @@ static Results DoDecode(const std::vector>& readers, // check if we know this code already for (auto& other : res) { - if (other == result) { + if (result == other) { // merge the position information auto dTop = maxAbsComponent(other.position().topLeft() - result.position().topLeft()); auto dBot = maxAbsComponent(other.position().bottomLeft() - result.position().topLeft()); From be97c41a479c0100fe1be799b2521ce9b7fe7c57 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 11:02:22 +0200 Subject: [PATCH 0337/1315] Error: fix compile regression on gcc-9 (##__VA_ARGS_ -> __VA_OPT__) --- core/src/Error.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index 43ff156bf2..a405eb8fe9 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -45,9 +45,10 @@ inline bool operator!=(const Error& e, Error::Type t) noexcept { return !(e == t inline bool operator==(Error::Type t, const Error& e) noexcept { return e.type() == t; } inline bool operator!=(Error::Type t, const Error& e) noexcept { return !(t == e); } -#define FormatError(...) Error(__FILE__, __LINE__, Error::Format, ##__VA_ARGS__) -#define ChecksumError(...) Error(__FILE__, __LINE__, Error::Checksum, ##__VA_ARGS__) -#define UnsupportedError(...) Error(__FILE__, __LINE__, Error::Unsupported, ##__VA_ARGS__) +// see https://en.wikipedia.org/wiki/Variadic_macro_in_the_C_preprocessor#Support regarding __VA_OPT__ +#define FormatError(...) Error(__FILE__, __LINE__, Error::Format __VA_OPT__(,) __VA_ARGS__) +#define ChecksumError(...) Error(__FILE__, __LINE__, Error::Checksum __VA_OPT__(,) __VA_ARGS__) +#define UnsupportedError(...) Error(__FILE__, __LINE__, Error::Unsupported __VA_OPT__(,) __VA_ARGS__) inline std::string ToString(const Error& e) { From 53da58625dcd519b7c10e2349a83c9bd10105cf7 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 4 Jul 2022 10:19:37 +0200 Subject: [PATCH 0338/1315] gcc13: add missing header file Include Fixes: #348 --- core/src/textcodec/JPTextEncoder.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/textcodec/JPTextEncoder.cpp b/core/src/textcodec/JPTextEncoder.cpp index 26cf744d8f..d909ad666f 100644 --- a/core/src/textcodec/JPTextEncoder.cpp +++ b/core/src/textcodec/JPTextEncoder.cpp @@ -37,6 +37,8 @@ #include "JPTextEncoder.h" +#include + /* * This data is derived from Unicode 1.1, * JIS X 0208 (1990) to Unicode mapping table version 0.9 . From 991cbbd0ab26c02f192879846e597d4847477bee Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 11:23:01 +0200 Subject: [PATCH 0339/1315] Error: fix compile regression (2nd attempt, since wikipedia was wrong...) --- core/src/Error.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index a405eb8fe9..0b7ee85351 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -45,10 +45,9 @@ inline bool operator!=(const Error& e, Error::Type t) noexcept { return !(e == t inline bool operator==(Error::Type t, const Error& e) noexcept { return e.type() == t; } inline bool operator!=(Error::Type t, const Error& e) noexcept { return !(t == e); } -// see https://en.wikipedia.org/wiki/Variadic_macro_in_the_C_preprocessor#Support regarding __VA_OPT__ -#define FormatError(...) Error(__FILE__, __LINE__, Error::Format __VA_OPT__(,) __VA_ARGS__) -#define ChecksumError(...) Error(__FILE__, __LINE__, Error::Checksum __VA_OPT__(,) __VA_ARGS__) -#define UnsupportedError(...) Error(__FILE__, __LINE__, Error::Unsupported __VA_OPT__(,) __VA_ARGS__) +#define FormatError(...) Error(__FILE__, __LINE__, Error::Format, std::string(__VA_ARGS__)) +#define ChecksumError(...) Error(__FILE__, __LINE__, Error::Checksum, std::string(__VA_ARGS__)) +#define UnsupportedError(...) Error(__FILE__, __LINE__, Error::Unsupported, std::string(__VA_ARGS__)) inline std::string ToString(const Error& e) { From ee75cdece23beeb983e5b1f9bc42641f65e53c1b Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 16:23:35 +0200 Subject: [PATCH 0340/1315] example: move OpenCV example from `ReadBarcode` to `ReadBarcodes` --- example/ZXingOpenCV.cpp | 6 +++--- example/ZXingOpenCV.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/example/ZXingOpenCV.cpp b/example/ZXingOpenCV.cpp index d4c3e4c06f..21411cf779 100644 --- a/example/ZXingOpenCV.cpp +++ b/example/ZXingOpenCV.cpp @@ -21,9 +21,9 @@ int main() else while (waitKey(25) != 27) { cap >> image; - auto res = ReadBarcode(image); - if (res.isValid()) - DrawResult(image, res); + auto results = ReadBarcodes(image); + for (auto& r : results) + DrawResult(image, r); imshow("Display window", image); } diff --git a/example/ZXingOpenCV.h b/example/ZXingOpenCV.h index 8dbfb2545d..3987458b43 100644 --- a/example/ZXingOpenCV.h +++ b/example/ZXingOpenCV.h @@ -28,9 +28,9 @@ inline ZXing::ImageView ImageViewFromMat(const cv::Mat& image) return {image.data, image.cols, image.rows, fmt}; } -inline ZXing::Result ReadBarcode(const cv::Mat& image, const ZXing::DecodeHints& hints = {}) +inline ZXing::Results ReadBarcodes(const cv::Mat& image, const ZXing::DecodeHints& hints = {}) { - return ZXing::ReadBarcode(ImageViewFromMat(image), hints); + return ZXing::ReadBarcodes(ImageViewFromMat(image), hints); } inline void DrawResult(cv::Mat& img, ZXing::Result res) @@ -42,5 +42,5 @@ inline void DrawResult(cv::Mat& img, ZXing::Result res) int npts = contour.size(); cv::polylines(img, &pts, &npts, 1, true, CV_RGB(0, 255, 0)); - cv::putText(img, res.text(), cv::Point(10, 20), cv::FONT_HERSHEY_DUPLEX, 0.5, CV_RGB(0, 255, 0)); + cv::putText(img, res.text(), zx2cv(pos[3]) + cv::Point(0, 20), cv::FONT_HERSHEY_DUPLEX, 0.5, CV_RGB(0, 255, 0)); } From 080dd4a4bdac0121ff70dd5da2d844c467aee4bd Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 17:13:51 +0200 Subject: [PATCH 0341/1315] ImageView: include `ImageView.h` instead of `ReadBarcode.h` --- core/src/BinaryBitmap.h | 2 +- test/blackbox/ImageLoader.cpp | 2 +- test/blackbox/ImageLoader.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/BinaryBitmap.h b/core/src/BinaryBitmap.h index 0337d24abd..433e510aed 100644 --- a/core/src/BinaryBitmap.h +++ b/core/src/BinaryBitmap.h @@ -7,7 +7,7 @@ #pragma once -#include "ReadBarcode.h" +#include "ImageView.h" #include #include diff --git a/test/blackbox/ImageLoader.cpp b/test/blackbox/ImageLoader.cpp index 69d1d7c303..1f1f073421 100644 --- a/test/blackbox/ImageLoader.cpp +++ b/test/blackbox/ImageLoader.cpp @@ -7,7 +7,7 @@ #include "ImageLoader.h" #include "BinaryBitmap.h" -#include "ReadBarcode.h" +#include "ImageView.h" #include #include diff --git a/test/blackbox/ImageLoader.h b/test/blackbox/ImageLoader.h index 29469ce989..1d96e71c3d 100644 --- a/test/blackbox/ImageLoader.h +++ b/test/blackbox/ImageLoader.h @@ -5,7 +5,7 @@ #pragma once -#include "ReadBarcode.h" +#include "ImageView.h" #include "ZXFilesystem.h" namespace ZXing::Test::ImageLoader { From 244147c08ff1c1f1b7310652ce4403f85144dfe9 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 17:15:35 +0200 Subject: [PATCH 0342/1315] WASM: use `ReadBarcodes` internally (actually using `tryDownscale`) --- wrappers/wasm/BarcodeReader.cpp | 52 +++++++++++++-------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/wrappers/wasm/BarcodeReader.cpp b/wrappers/wasm/BarcodeReader.cpp index 7efee44486..2b9c0b46a0 100644 --- a/wrappers/wasm/BarcodeReader.cpp +++ b/wrappers/wasm/BarcodeReader.cpp @@ -23,7 +23,7 @@ struct ReadResult ZXing::Position position; }; -ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, std::string format) +ReadResult readBarcodeFromImageView(ZXing::ImageView iv, bool tryHarder, const std::string& format) { using namespace ZXing; try { @@ -32,18 +32,11 @@ ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, hints.setTryRotate(tryHarder); hints.setTryDownscale(tryHarder); hints.setFormats(BarcodeFormatsFromString(format)); + hints.setMaxNumberOfSymbols(1); - int width, height, channels; - std::unique_ptr buffer( - stbi_load_from_memory(reinterpret_cast(bufferPtr), bufferLength, &width, &height, - &channels, 4), - stbi_image_free); - if (buffer == nullptr) { - return { "", "", "Error loading image" }; - } - - auto result = ReadBarcode({buffer.get(), width, height, ImageFormat::RGBX}, hints); - if (result.isValid()) { + auto results = ReadBarcodes(iv, hints); + if (!results.empty()) { + auto& result = results.front(); return { ToString(result.format()), result.text(), "", result.position() }; } } @@ -56,30 +49,25 @@ ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, return {}; } -ReadResult readBarcodeFromPixmap(int bufferPtr, int imgWidth, int imgHeight, bool tryHarder, std::string format) +ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, std::string format) { using namespace ZXing; - try { - DecodeHints hints; - hints.setTryHarder(tryHarder); - hints.setTryRotate(tryHarder); - hints.setTryDownscale(tryHarder); - hints.setFormats(BarcodeFormatsFromString(format)); - auto result = - ReadBarcode({reinterpret_cast(bufferPtr), imgWidth, imgHeight, ImageFormat::RGBX}, hints); - - if (result.isValid()) { - return { ToString(result.format()), result.text(), "", result.position() }; - } + int width, height, channels; + std::unique_ptr buffer( + stbi_load_from_memory(reinterpret_cast(bufferPtr), bufferLength, &width, &height, &channels, 4), + stbi_image_free); + if (buffer == nullptr) { + return {"", "", "Error loading image"}; } - catch (const std::exception& e) { - return { "", "", e.what() }; - } - catch (...) { - return { "", "", "Unknown error" }; - } - return {}; + + return readBarcodeFromImageView({buffer.get(), width, height, ImageFormat::RGBX}, tryHarder, format); +} + +ReadResult readBarcodeFromPixmap(int bufferPtr, int imgWidth, int imgHeight, bool tryHarder, std::string format) +{ + using namespace ZXing; + return readBarcodeFromImageView({reinterpret_cast(bufferPtr), imgWidth, imgHeight, ImageFormat::RGBX}, tryHarder, format); } EMSCRIPTEN_BINDINGS(BarcodeReader) From e64432ca17e594fb806ec4233555db07dd7e3b23 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 17:40:18 +0200 Subject: [PATCH 0343/1315] fix build regression: missing include ( I'm getting sloppy :-( ) --- test/blackbox/TestReaderMain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/blackbox/TestReaderMain.cpp b/test/blackbox/TestReaderMain.cpp index ebc4ed972e..22691a6864 100644 --- a/test/blackbox/TestReaderMain.cpp +++ b/test/blackbox/TestReaderMain.cpp @@ -6,6 +6,7 @@ #include "BlackboxTestRunner.h" #include "ImageLoader.h" +#include "ReadBarcode.h" #include "ZXContainerAlgorithms.h" #include "ZXFilesystem.h" From db1cc6129ddab042ab1417e5d53074691f6dcf58 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 17:55:28 +0200 Subject: [PATCH 0344/1315] android: use `ReadBarcodes` and remove Result::status() usage --- .../android/zxingcpp/src/main/cpp/BarcodeReader.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp index 571434cff1..8afd7a3d51 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/BarcodeReader.cpp @@ -104,12 +104,10 @@ jstring Read(JNIEnv *env, ImageView image, jstring formats, jboolean tryHarder, .setTryHarder(tryHarder) .setTryRotate( tryRotate ) .setTryDownscale(tryDownscale) - .setMaxNumberOfSymbols(1); // see ReadBarcode implementation - -// return C2JString(env, ToString(DecodeStatus::NotFound)); + .setMaxNumberOfSymbols(1); auto startTime = std::chrono::high_resolution_clock::now(); - auto res = ReadBarcode(image, hints); + auto results = ReadBarcodes(image, hints); auto duration = std::chrono::high_resolution_clock::now() - startTime; // LOGD("time: %4d ms\n", (int)std::chrono::duration_cast(duration).count()); @@ -119,7 +117,8 @@ jstring Read(JNIEnv *env, ImageView image, jstring formats, jboolean tryHarder, auto time = std::to_wstring(std::chrono::duration_cast(duration).count()); env->SetObjectField(result, fidTime, C2JString(env, time)); - if (res.isValid()) { + if (!results.empty()) { + auto& res = results.front(); jbyteArray jByteArray = env->NewByteArray(res.bytes().size()); env->SetByteArrayRegion(jByteArray, 0, res.bytes().size(), (jbyte*)res.bytes().data()); jfieldID fidBytes = env->GetFieldID(clResult, "bytes", "[B"); @@ -145,7 +144,7 @@ jstring Read(JNIEnv *env, ImageView image, jstring formats, jboolean tryHarder, return C2JString(env, JavaBarcodeFormatName(res.format())); } else - return C2JString(env, ToString(res.status())); + return C2JString(env, "NotFound"); } catch (const std::exception& e) { return ThrowJavaException(env, e.what()); } catch (...) { From 544fa75175dc82f79a48724d3f2a30834f88ad8a Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 18:39:44 +0200 Subject: [PATCH 0345/1315] BarcodeFormat: deprecate `OneDCodes` and `TwoDCodes` The ISO specifications use the terms 'linear symbology' and 'matrix symbology'. So we are using the new names `LinearCodes` and `MatrixCodes`, which are also nicer to read than the old. --- core/src/BarcodeFormat.cpp | 4 ++-- core/src/BarcodeFormat.h | 8 +++++--- core/src/MultiFormatReader.cpp | 4 ++-- core/src/Result.cpp | 2 +- example/ZXingQt5CamReader.qml | 6 +++--- example/ZXingQt6CamReader.qml | 6 +++--- example/ZXingQtReader.h | 4 ++-- wrappers/python/zxing.cpp | 6 ++++-- 8 files changed, 22 insertions(+), 18 deletions(-) diff --git a/core/src/BarcodeFormat.cpp b/core/src/BarcodeFormat.cpp index 232bcb854f..0bc05be826 100644 --- a/core/src/BarcodeFormat.cpp +++ b/core/src/BarcodeFormat.cpp @@ -42,8 +42,8 @@ static BarcodeFormatName NAMES[] = { {BarcodeFormat::QRCode, "QRCode"}, {BarcodeFormat::UPCA, "UPC-A"}, {BarcodeFormat::UPCE, "UPC-E"}, - {BarcodeFormat::OneDCodes, "1D-Codes"}, - {BarcodeFormat::TwoDCodes, "2D-Codes"}, + {BarcodeFormat::LinearCodes, "Linear-Codes"}, + {BarcodeFormat::MatrixCodes, "Matrix-Codes"}, }; const char* ToString(BarcodeFormat format) diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index 186e52eee6..b12e332a77 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -39,9 +39,9 @@ enum class BarcodeFormat UPCE = (1 << 15), ///< UPC-E (1D) MicroQRCode = (1 << 16), ///< Micro QR Code (2D) - OneDCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, - TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, - Any = OneDCodes | TwoDCodes, + LinearCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, + MatrixCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, + Any = LinearCodes | MatrixCodes, // Deprecated names, kept for compatibility at the moment NONE [[deprecated]] = None, @@ -60,6 +60,8 @@ enum class BarcodeFormat RSS_EXPANDED [[deprecated]] = DataBarExpanded, UPC_A [[deprecated]] = UPCA, UPC_E [[deprecated]] = UPCE, + OneDCodes [[deprecated]] = LinearCodes, + TwoDCodes [[deprecated]] = MatrixCodes, _max = MicroQRCode, ///> implementation detail, don't use }; diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index d52e91d2af..442dd64488 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -24,7 +24,7 @@ MultiFormatReader::MultiFormatReader(const DecodeHints& hints) : _hints(hints) auto formats = hints.formats().empty() ? BarcodeFormat::Any : hints.formats(); // Put 1D readers upfront in "normal" mode - if (formats.testFlags(BarcodeFormat::OneDCodes) && !hints.tryHarder()) + if (formats.testFlags(BarcodeFormat::LinearCodes) && !hints.tryHarder()) _readers.emplace_back(new OneD::Reader(hints)); if (formats.testFlags(BarcodeFormat::QRCode | BarcodeFormat::MicroQRCode)) @@ -39,7 +39,7 @@ MultiFormatReader::MultiFormatReader(const DecodeHints& hints) : _hints(hints) _readers.emplace_back(new MaxiCode::Reader(hints)); // At end in "try harder" mode - if (formats.testFlags(BarcodeFormat::OneDCodes) && hints.tryHarder()) + if (formats.testFlags(BarcodeFormat::LinearCodes) && hints.tryHarder()) _readers.emplace_back(new OneD::Reader(hints)); } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index e7f102e663..74c177cbc9 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -132,7 +132,7 @@ bool Result::operator==(const Result& o) const if (!(format() == o.format() && (bytes() == o.bytes() || error() || o.error()))) return false; - if (BarcodeFormats(BarcodeFormat::TwoDCodes).testFlag(format())) + if (BarcodeFormats(BarcodeFormat::MatrixCodes).testFlag(format())) return IsInside(Center(o.position()), position()); // 1D comparisons only implemented for this->lineCount == 1 diff --git a/example/ZXingQt5CamReader.qml b/example/ZXingQt5CamReader.qml index bf3f8d3ed2..467bb18a63 100644 --- a/example/ZXingQt5CamReader.qml +++ b/example/ZXingQt5CamReader.qml @@ -28,7 +28,7 @@ Window { BarcodeReader { id: barcodeReader - formats: (oneDSwitch.checked ? (ZXing.OneDCodes) : ZXing.None) | (twoDSwitch.checked ? (ZXing.TwoDCodes) : ZXing.None) + formats: (linearSwitch.checked ? (ZXing.LinearCodes) : ZXing.None) | (matrixSwitch.checked ? (ZXing.MatrixCodes) : ZXing.None) tryRotate: tryRotateSwitch.checked tryHarder: tryHarderSwitch.checked tryDownscale: tryDownscaleSwitch.checked @@ -139,8 +139,8 @@ Window { Switch {id: tryRotateSwitch; text: qsTr("Try Rotate"); checked: true } Switch {id: tryHarderSwitch; text: qsTr("Try Harder"); checked: true } Switch {id: tryDownscaleSwitch; text: qsTr("Try Downscale"); checked: true } - Switch {id: oneDSwitch; text: qsTr("1D Codes"); checked: true } - Switch {id: twoDSwitch; text: qsTr("2D Codes"); checked: true } + Switch {id: linearSwitch; text: qsTr("Linear Codes"); checked: true } + Switch {id: matrixSwitch; text: qsTr("Matrix Codes"); checked: true } } } } diff --git a/example/ZXingQt6CamReader.qml b/example/ZXingQt6CamReader.qml index 7c80e77855..9234ae1882 100644 --- a/example/ZXingQt6CamReader.qml +++ b/example/ZXingQt6CamReader.qml @@ -29,7 +29,7 @@ Window { id: barcodeReader videoSink: videoOutput.videoSink - formats: (oneDSwitch.checked ? (ZXing.OneDCodes) : ZXing.None) | (twoDSwitch.checked ? (ZXing.TwoDCodes) : ZXing.None) + formats: (linearSwitch.checked ? (ZXing.LinearCodes) : ZXing.None) | (matrixSwitch.checked ? (ZXing.MatrixCodes) : ZXing.None) tryRotate: tryRotateSwitch.checked tryHarder: tryHarderSwitch.checked tryDownscale: tryDownscaleSwitch.checked @@ -140,8 +140,8 @@ Window { Switch {id: tryRotateSwitch; text: qsTr("Try Rotate"); checked: true } Switch {id: tryHarderSwitch; text: qsTr("Try Harder"); checked: true } Switch {id: tryDownscaleSwitch; text: qsTr("Try Downscale"); checked: true } - Switch {id: oneDSwitch; text: qsTr("1D Codes"); checked: true } - Switch {id: twoDSwitch; text: qsTr("2D Codes"); checked: true } + Switch {id: linearSwitch; text: qsTr("Linear Codes"); checked: true } + Switch {id: matrixSwitch; text: qsTr("Matrix Codes"); checked: true } } } } diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index c2155dff9e..a43453c9aa 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -54,8 +54,8 @@ enum class BarcodeFormat UPCE = (1 << 15), ///< UPC-E (1D) MicroQRCode = (1 << 16), ///< Micro QR Code (2D) - OneDCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, - TwoDCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, + LinearCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, + MatrixCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, }; enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 862d024947..b00c47d2bb 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -150,8 +150,10 @@ PYBIND11_MODULE(zxingcpp, m) .value("UPCE", BarcodeFormat::UPCE) // use upper case 'NONE' because 'None' is a reserved identifier in python .value("NONE", BarcodeFormat::None) - .value("OneDCodes", BarcodeFormat::OneDCodes) - .value("TwoDCodes", BarcodeFormat::TwoDCodes) + .value("OneDCodes", BarcodeFormat::LinearCodes) // deprecated, will be removed + .value("TwoDCodes", BarcodeFormat::MatrixCodes) // deprecated, will be removed + .value("LinearCodes", BarcodeFormat::LinearCodes) + .value("MatrixCodes", BarcodeFormat::MatrixCodes) .export_values() // see https://github.com/pybind/pybind11/issues/2221 .def("__or__", [](BarcodeFormat f1, BarcodeFormat f2){ return f1 | f2; }); From 725047ebeb3e2286b233bc473586d1a24885c6f0 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 4 Jul 2022 19:13:59 +0200 Subject: [PATCH 0346/1315] README: refer to `ReadBarcodes` and use new "Linear"/"Matrix" terminolgy --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ddaf4a862d..0508b63cac 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # ZXing-C++ -ZXing-C++ ("zebra crossing") is an open-source, multi-format 1D/2D barcode image processing library implemented in C++. +ZXing-C++ ("zebra crossing") is an open-source, multi-format linear/matrix barcode image processing library implemented in C++. It was originally ported from the Java [ZXing Library](https://github.com/zxing/zxing) but has been developed further and now includes many improvements in terms of quality and performance. It can both read and write barcodes in a number of formats. @@ -18,14 +18,14 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ ## Supported Formats -| 1D product | 1D industrial | 2D -| ---------- | ----------------- | -------------- -| UPC-A | Code 39 | QR Code -| UPC-E | Code 93 | Micro QR Code -| EAN-8 | Code 128 | Aztec -| EAN-13 | Codabar | DataMatrix -| DataBar | ITF | PDF417 -| | DataBar Expanded | MaxiCode (beta) +| Linear product | Linear industrial | Matrix | +|----------------|-------------------|--------------------| +| UPC-A | Code 39 | QR Code | +| UPC-E | Code 93 | Micro QR Code | +| EAN-8 | Code 128 | Aztec | +| EAN-13 | Codabar | DataMatrix | +| DataBar | DataBar Exanded | PDF417 | +| | ITF | MaxiCode (partial) | Note: DataBar used to be called RSS. DataBar is not supported for writing. @@ -34,7 +34,7 @@ Note: DataBar used to be called RSS. DataBar is not supported for writing. ### To read barcodes: As an example, have a look at [`ZXingReader.cpp`](example/ZXingReader.cpp). 1. Load your image into memory (3rd-party library required). -2. Call `ReadBarcode()` from [`ReadBarcode.h`](core/src/ReadBarcode.h), the simplest API to get a `Result`. +2. Call `ReadBarcodes()` from [`ReadBarcode.h`](core/src/ReadBarcode.h), the simplest API to get a list of `Result` objects. ### To write barcodes: As an example, have a look at [`ZXingWriter.cpp`](example/ZXingWriter.cpp). From e0592197f7dae0a0c9755a925d04f355abb4c634 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 00:55:19 +0200 Subject: [PATCH 0347/1315] BarcodeFormat: replace or remove 1D/2D terms in comments --- core/src/BarcodeFormat.h | 30 +++++++++++++++--------------- core/src/DecodeHints.h | 6 +++--- core/src/MultiFormatReader.cpp | 2 +- core/src/Result.cpp | 2 +- core/src/Result.h | 4 ++-- example/ZXingQtReader.h | 30 +++++++++++++++--------------- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index b12e332a77..01263c375a 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -21,23 +21,23 @@ enum class BarcodeFormat // would not have been necessary to explicitly set the values to single bit constants. This has been done to ease // the interoperability with C-like interfaces, the python and the Qt wrapper. None = 0, ///< Used as a return value if no valid barcode has been detected - Aztec = (1 << 0), ///< Aztec (2D) - Codabar = (1 << 1), ///< Codabar (1D) - Code39 = (1 << 2), ///< Code39 (1D) - Code93 = (1 << 3), ///< Code93 (1D) - Code128 = (1 << 4), ///< Code128 (1D) + Aztec = (1 << 0), ///< Aztec + Codabar = (1 << 1), ///< Codabar + Code39 = (1 << 2), ///< Code39 + Code93 = (1 << 3), ///< Code93 + Code128 = (1 << 4), ///< Code128 DataBar = (1 << 5), ///< GS1 DataBar, formerly known as RSS 14 DataBarExpanded = (1 << 6), ///< GS1 DataBar Expanded, formerly known as RSS EXPANDED - DataMatrix = (1 << 7), ///< DataMatrix (2D) - EAN8 = (1 << 8), ///< EAN-8 (1D) - EAN13 = (1 << 9), ///< EAN-13 (1D) - ITF = (1 << 10), ///< ITF (Interleaved Two of Five) (1D) - MaxiCode = (1 << 11), ///< MaxiCode (2D) - PDF417 = (1 << 12), ///< PDF417 (1D) or (2D) - QRCode = (1 << 13), ///< QR Code (2D) - UPCA = (1 << 14), ///< UPC-A (1D) - UPCE = (1 << 15), ///< UPC-E (1D) - MicroQRCode = (1 << 16), ///< Micro QR Code (2D) + DataMatrix = (1 << 7), ///< DataMatrix + EAN8 = (1 << 8), ///< EAN-8 + EAN13 = (1 << 9), ///< EAN-13 + ITF = (1 << 10), ///< ITF (Interleaved Two of Five) + MaxiCode = (1 << 11), ///< MaxiCode + PDF417 = (1 << 12), ///< PDF417 + QRCode = (1 << 13), ///< QR Code + UPCA = (1 << 14), ///< UPC-A + UPCE = (1 << 15), ///< UPC-E + MicroQRCode = (1 << 16), ///< Micro QR Code LinearCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, MatrixCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index d8c76c16e5..05d051cd96 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -24,8 +24,8 @@ namespace ZXing { */ enum class Binarizer : unsigned char // needs to unsigned for the bitfield below to work, uint8_t fails as well { - LocalAverage, ///< T = average of neighboring pixels for 2D and GlobalHistogram for 1D (HybridBinarizer) - GlobalHistogram, ///< T = valley between the 2 largest peaks in the histogram (per line in 1D case) + LocalAverage, ///< T = average of neighboring pixels for matrix and GlobalHistogram for linear (HybridBinarizer) + GlobalHistogram, ///< T = valley between the 2 largest peaks in the histogram (per line in linear case) FixedThreshold, ///< T = 127 BoolCast, ///< T = 0, fastest possible }; @@ -105,7 +105,7 @@ class DecodeHints // WARNING: this API is experimental and may change/disappear ZX_PROPERTY(uint8_t, downscaleFactor, setDownscaleFactor) - /// The number of scan lines in a 1D barcode that have to be equal to accept the result, default is 2 + /// The number of scan lines in a linear barcode that have to be equal to accept the result, default is 2 ZX_PROPERTY(uint8_t, minLineCount, setMinLineCount) /// The maximum number of symbols (barcodes) to detect / look for in the image with ReadBarcodes diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index 442dd64488..f445232a47 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -23,7 +23,7 @@ MultiFormatReader::MultiFormatReader(const DecodeHints& hints) : _hints(hints) { auto formats = hints.formats().empty() ? BarcodeFormat::Any : hints.formats(); - // Put 1D readers upfront in "normal" mode + // Put linear readers upfront in "normal" mode if (formats.testFlags(BarcodeFormat::LinearCodes) && !hints.tryHarder()) _readers.emplace_back(new OneD::Reader(hints)); diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 74c177cbc9..d406f975b3 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -135,7 +135,7 @@ bool Result::operator==(const Result& o) const if (BarcodeFormats(BarcodeFormat::MatrixCodes).testFlag(format())) return IsInside(Center(o.position()), position()); - // 1D comparisons only implemented for this->lineCount == 1 + // linear symbology comparisons only implemented for this->lineCount == 1 assert(lineCount() == 1); // if one line is less than half the length of the other away from the diff --git a/core/src/Result.h b/core/src/Result.h index 6c7ed47da1..cd6397944d 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -33,7 +33,7 @@ class Result Result() = default; explicit Result(DecodeStatus status); - // 1D convenience constructor + // linear symbology convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error = {}, ByteArray&& rawBytes = {}, bool readerInit = false, const std::string& ai = {}); @@ -145,7 +145,7 @@ class Result bool readerInit() const { return _readerInit; } /** - * @brief How many lines have been detected with this code (applies only to 1D symbologies) + * @brief How many lines have been detected with this code (applies only to linear symbologies) */ int lineCount() const { return _lineCount; } diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index a43453c9aa..a181a4b1a3 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -36,23 +36,23 @@ Q_NAMESPACE enum class BarcodeFormat { None = 0, ///< Used as a return value if no valid barcode has been detected - Aztec = (1 << 0), ///< Aztec (2D) - Codabar = (1 << 1), ///< Codabar (1D) - Code39 = (1 << 2), ///< Code39 (1D) - Code93 = (1 << 3), ///< Code93 (1D) - Code128 = (1 << 4), ///< Code128 (1D) + Aztec = (1 << 0), ///< Aztec + Codabar = (1 << 1), ///< Codabar + Code39 = (1 << 2), ///< Code39 + Code93 = (1 << 3), ///< Code93 + Code128 = (1 << 4), ///< Code128 DataBar = (1 << 5), ///< GS1 DataBar, formerly known as RSS 14 DataBarExpanded = (1 << 6), ///< GS1 DataBar Expanded, formerly known as RSS EXPANDED - DataMatrix = (1 << 7), ///< DataMatrix (2D) - EAN8 = (1 << 8), ///< EAN-8 (1D) - EAN13 = (1 << 9), ///< EAN-13 (1D) - ITF = (1 << 10), ///< ITF (Interleaved Two of Five) (1D) - MaxiCode = (1 << 11), ///< MaxiCode (2D) - PDF417 = (1 << 12), ///< PDF417 (1D) or (2D) - QRCode = (1 << 13), ///< QR Code (2D) - UPCA = (1 << 14), ///< UPC-A (1D) - UPCE = (1 << 15), ///< UPC-E (1D) - MicroQRCode = (1 << 16), ///< Micro QR Code (2D) + DataMatrix = (1 << 7), ///< DataMatrix + EAN8 = (1 << 8), ///< EAN-8 + EAN13 = (1 << 9), ///< EAN-13 + ITF = (1 << 10), ///< ITF (Interleaved Two of Five) + MaxiCode = (1 << 11), ///< MaxiCode + PDF417 = (1 << 12), ///< PDF417 or + QRCode = (1 << 13), ///< QR Code + UPCA = (1 << 14), ///< UPC-A + UPCE = (1 << 15), ///< UPC-E + MicroQRCode = (1 << 16), ///< Micro QR Code LinearCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | UPCA | UPCE, MatrixCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, From c8c5d1853d96a365bec26f68c689f8057c84d3e8 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 00:56:41 +0200 Subject: [PATCH 0348/1315] DecodeHints: deprecate unused `allowedLengths` property --- core/src/DecodeHints.h | 8 ++++---- core/src/oned/ODITFReader.cpp | 11 +---------- core/src/oned/ODITFReader.h | 8 +++----- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 05d051cd96..6f0343edab 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -52,7 +52,6 @@ class DecodeHints EanAddOnSymbol _eanAddOnSymbol : 2; std::string _characterSet; - std::vector _allowedLengths; BarcodeFormats _formats = BarcodeFormat::None; uint16_t _downscaleThreshold = 500; uint8_t _downscaleFactor = 3; @@ -114,9 +113,6 @@ class DecodeHints /// Specifies fallback character set to use instead of auto-detecting it (when applicable) ZX_PROPERTY(std::string, characterSet, setCharacterSet) - /// Allowed lengths of encoded data -- reject anything else.. - ZX_PROPERTY(std::vector, allowedLengths, setAllowedLengths) - /// If true, the Code-39 reader will try to read extended mode. ZX_PROPERTY(bool, tryCode39ExtendedMode, setTryCode39ExtendedMode) @@ -141,6 +137,10 @@ class DecodeHints [[deprecated]] bool assumeGS1() const noexcept { return true; } [[deprecated]] DecodeHints& setAssumeGS1(bool v [[maybe_unused]]) { return *this; } + /// NOTE: has not been in effect since at least 1.2 and no one noticed. + [[deprecated]] std::vector allowedLengths() const noexcept { return {}; } + [[deprecated]] DecodeHints& setAllowedLengths(const std::vector v [[maybe_unused]]) { return *this; } + /// NOTE: use validateCode39CheckSum [[deprecated]] bool assumeCode39CheckDigit() const noexcept { return validateCode39CheckSum(); } [[deprecated]] DecodeHints& setAssumeCode39CheckDigit(bool v) { return setValidateCode39CheckSum(v); } diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index a251d65fe7..f7c1805815 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -15,16 +15,7 @@ namespace ZXing::OneD { -/** Valid ITF lengths. Anything longer than the largest value is also allowed. */ -constexpr auto DEFAULT_ALLOWED_LENGTHS = { 6, 8, 10, 12, 14 }; - -ITFReader::ITFReader(const DecodeHints& hints) : - _allowedLengths(hints.allowedLengths()), - _validateCheckSum(hints.validateITFCheckSum()) -{ - if (_allowedLengths.empty()) - _allowedLengths.assign(DEFAULT_ALLOWED_LENGTHS.begin(), DEFAULT_ALLOWED_LENGTHS.end()); -} +ITFReader::ITFReader(const DecodeHints& hints) : _validateCheckSum(hints.validateITFCheckSum()) {} constexpr auto START_PATTERN_ = FixedPattern<4, 4>{1, 1, 1, 1}; constexpr auto STOP_PATTERN_1 = FixedPattern<3, 4>{2, 1, 1}; diff --git a/core/src/oned/ODITFReader.h b/core/src/oned/ODITFReader.h index 0277c52a7d..c3bf45fba8 100644 --- a/core/src/oned/ODITFReader.h +++ b/core/src/oned/ODITFReader.h @@ -20,11 +20,10 @@ namespace OneD { *

Implements decoding of the ITF format, or Interleaved Two of Five.

* *

This Reader will scan ITF barcodes of certain lengths only. -* At the moment it reads length 6, 8, 10, 12, 14, 16, 18, 20, 24, and 44 as these have appeared "in the wild". Not all -* lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of -* required checksum function.

+* At the moment it reads length >= 6. Not all lengths are scanned, especially shorter ones, to avoid false positives. +* This in turn is due to a lack of required checksum function.

* -*

The checksum is optional and is only applied by this Reader if the validateITFCheckSum hint is given.

+*

The checksum is optional and is only checked if the validateITFCheckSum hint is given.

* *

http://en.wikipedia.org/wiki/Interleaved_2_of_5 * is a great reference for Interleaved 2 of 5 information.

@@ -36,7 +35,6 @@ class ITFReader : public RowReader Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; private: - std::vector _allowedLengths; bool _validateCheckSum; }; From 51217a10d5d379ec284e96be376ef9f16044d61e Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 01:20:41 +0200 Subject: [PATCH 0349/1315] DecodeHints: optimize struct layout to reduce size --- core/src/DecodeHints.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 6f0343edab..841bb24255 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -48,15 +48,15 @@ class DecodeHints bool _validateITFCheckSum : 1; bool _returnCodabarStartEnd : 1; bool _returnErrors : 1; - Binarizer _binarizer : 2; EanAddOnSymbol _eanAddOnSymbol : 2; + Binarizer _binarizer : 2; - std::string _characterSet; - BarcodeFormats _formats = BarcodeFormat::None; - uint16_t _downscaleThreshold = 500; - uint8_t _downscaleFactor = 3; uint8_t _minLineCount = 2; uint8_t _maxNumberOfSymbols = 0xff; + uint8_t _downscaleFactor = 3; + uint16_t _downscaleThreshold = 500; + BarcodeFormats _formats = BarcodeFormat::None; + std::string _characterSet; public: // bitfields don't get default initialized to 0 before c++20 @@ -70,8 +70,8 @@ class DecodeHints _validateITFCheckSum(0), _returnCodabarStartEnd(0), _returnErrors(0), - _binarizer(Binarizer::LocalAverage), - _eanAddOnSymbol(EanAddOnSymbol::Ignore) + _eanAddOnSymbol(EanAddOnSymbol::Ignore), + _binarizer(Binarizer::LocalAverage) {} #define ZX_PROPERTY(TYPE, GETTER, SETTER) \ From 4afba9ba0def489437874f8a5cf7e4d0140041db Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 01:28:20 +0200 Subject: [PATCH 0350/1315] DecodeHints: cleanup matrix reader headers --- core/src/aztec/AZReader.h | 11 ++--------- core/src/datamatrix/DMReader.h | 10 ++-------- core/src/maxicode/MCReader.h | 11 ++--------- core/src/pdf417/PDFReader.h | 10 ++-------- core/src/qrcode/QRReader.h | 11 ++--------- 5 files changed, 10 insertions(+), 43 deletions(-) diff --git a/core/src/aztec/AZReader.h b/core/src/aztec/AZReader.h index c0bab4fea4..0b8c2a6a29 100644 --- a/core/src/aztec/AZReader.h +++ b/core/src/aztec/AZReader.h @@ -8,13 +8,7 @@ #include "Reader.h" -#include - -namespace ZXing { - -class DecodeHints; - -namespace Aztec { +namespace ZXing::Aztec { class Reader : public ZXing::Reader { @@ -24,5 +18,4 @@ class Reader : public ZXing::Reader Result decode(const BinaryBitmap& image) const override; }; -} // Aztec -} // ZXing +} // namespace ZXing::Aztec diff --git a/core/src/datamatrix/DMReader.h b/core/src/datamatrix/DMReader.h index 1d6706072c..62f67142e1 100644 --- a/core/src/datamatrix/DMReader.h +++ b/core/src/datamatrix/DMReader.h @@ -7,13 +7,8 @@ #pragma once #include "Reader.h" -#include -namespace ZXing { - -class DecodeHints; - -namespace DataMatrix { +namespace ZXing::DataMatrix { class Reader : public ZXing::Reader { @@ -26,5 +21,4 @@ class Reader : public ZXing::Reader #endif }; -} // DataMatrix -} // ZXing +} // namespace ZXing::DataMatrix diff --git a/core/src/maxicode/MCReader.h b/core/src/maxicode/MCReader.h index 8f209c0ff7..f3cfd75a57 100644 --- a/core/src/maxicode/MCReader.h +++ b/core/src/maxicode/MCReader.h @@ -8,13 +8,7 @@ #include "Reader.h" -#include - -namespace ZXing { - -class DecodeHints; - -namespace MaxiCode { +namespace ZXing::MaxiCode { class Reader : public ZXing::Reader { @@ -24,5 +18,4 @@ class Reader : public ZXing::Reader Result decode(const BinaryBitmap& image) const override; }; -} // MaxiCode -} // ZXing +} // namespace ZXing::MaxiCode diff --git a/core/src/pdf417/PDFReader.h b/core/src/pdf417/PDFReader.h index 9d8be24824..c4d3272ee6 100644 --- a/core/src/pdf417/PDFReader.h +++ b/core/src/pdf417/PDFReader.h @@ -9,13 +9,8 @@ #include "Reader.h" #include -#include -namespace ZXing { - -class DecodeHints; - -namespace Pdf417 { +namespace ZXing::Pdf417 { /** * This implementation can detect and decode PDF417 codes in an image. @@ -33,5 +28,4 @@ class Reader : public ZXing::Reader [[deprecated]] std::list decodeMultiple(const BinaryBitmap& image) const; }; -} // Pdf417 -} // ZXing +} // namespace ZXing::Pdf417 diff --git a/core/src/qrcode/QRReader.h b/core/src/qrcode/QRReader.h index 5b86edf751..22d514e254 100644 --- a/core/src/qrcode/QRReader.h +++ b/core/src/qrcode/QRReader.h @@ -8,13 +8,7 @@ #include "Reader.h" -#include - -namespace ZXing { - -class DecodeHints; - -namespace QRCode { +namespace ZXing::QRCode { class Reader : public ZXing::Reader { @@ -25,5 +19,4 @@ class Reader : public ZXing::Reader Results decode(const BinaryBitmap& image, int maxSymbols) const override; }; -} // QRCode -} // ZXing +} // namespace ZXing::QRCode From 7c4bd7af454a555fbfedcb2c8bcdaf6ce6f593f6 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 02:30:58 +0200 Subject: [PATCH 0351/1315] DecodeHints: prevent to store reference to temporary in `Reader` --- core/src/DecodeHints.h | 5 +++-- core/src/Reader.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 841bb24255..9668a09848 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -76,7 +76,8 @@ class DecodeHints #define ZX_PROPERTY(TYPE, GETTER, SETTER) \ TYPE GETTER() const noexcept { return _##GETTER; } \ - DecodeHints& SETTER(TYPE v) { return _##GETTER = std::move(v), *this; } + DecodeHints& SETTER(TYPE v)& { return _##GETTER = std::move(v), *this; } \ + DecodeHints&& SETTER(TYPE v)&& { return _##GETTER = std::move(v), std::move(*this); } /// Specify a set of BarcodeFormats that should be searched for, the default is all supported formats. ZX_PROPERTY(BarcodeFormats, formats, setFormats) @@ -143,7 +144,7 @@ class DecodeHints /// NOTE: use validateCode39CheckSum [[deprecated]] bool assumeCode39CheckDigit() const noexcept { return validateCode39CheckSum(); } - [[deprecated]] DecodeHints& setAssumeCode39CheckDigit(bool v) { return setValidateCode39CheckSum(v); } + [[deprecated]] DecodeHints& setAssumeCode39CheckDigit(bool v) & { return setValidateCode39CheckSum(v); } bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f) || _formats.empty(); } [[deprecated]] bool hasNoFormat() const noexcept { return _formats.empty(); } diff --git a/core/src/Reader.h b/core/src/Reader.h index 716d26b94d..70f34e1d29 100644 --- a/core/src/Reader.h +++ b/core/src/Reader.h @@ -21,6 +21,7 @@ class Reader public: explicit Reader(const DecodeHints& hints) : _hints(hints) {} + explicit Reader(DecodeHints&& hints) = delete; virtual ~Reader() = default; virtual Result decode(const BinaryBitmap& image) const = 0; From 4eeaff2b85f0821da8d249187bb6b8f2c83f0288 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 02:32:37 +0200 Subject: [PATCH 0352/1315] DecodeHints: store reference in RowReader base class and use everywhere --- core/src/oned/ODCodabarReader.cpp | 7 +------ core/src/oned/ODCodabarReader.h | 15 ++++----------- core/src/oned/ODCode128Reader.h | 11 ++++------- core/src/oned/ODCode39Reader.cpp | 15 ++++----------- core/src/oned/ODCode39Reader.h | 17 ++++------------- core/src/oned/ODCode93Reader.h | 8 ++++---- core/src/oned/ODDataBarExpandedReader.cpp | 3 --- core/src/oned/ODDataBarExpandedReader.h | 11 +++-------- core/src/oned/ODDataBarReader.cpp | 3 --- core/src/oned/ODDataBarReader.h | 11 +++-------- core/src/oned/ODITFReader.cpp | 6 ++---- core/src/oned/ODITFReader.h | 17 ++++------------- core/src/oned/ODMultiUPCEANReader.cpp | 4 ---- core/src/oned/ODMultiUPCEANReader.h | 14 +++----------- core/src/oned/ODReader.cpp | 4 ++-- core/src/oned/ODRowReader.h | 7 ++++++- test/unit/oned/ODCodaBarWriterTest.cpp | 3 ++- test/unit/oned/ODCode128ReaderTest.cpp | 4 +++- test/unit/oned/ODCode128WriterTest.cpp | 4 +++- test/unit/oned/ODCode39ExtendedModeTest.cpp | 3 ++- test/unit/oned/ODCode93ReaderTest.cpp | 4 +++- 21 files changed, 57 insertions(+), 114 deletions(-) diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index 119911d1a9..b3fd40b0c3 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -30,11 +30,6 @@ static_assert(Size(ALPHABET) - 1 == Size(CHARACTER_ENCODINGS), "table size misma // some industries use a checksum standard but this is not part of the original codabar standard // for more information see : http://www.mecsw.com/specs/codabar.html -CodabarReader::CodabarReader(const DecodeHints& hints) -{ - _returnStartEnd = hints.returnCodabarStartEnd(); -} - // each character has 4 bars and 3 spaces constexpr int CHAR_LEN = 7; // quiet zone is half the width of a character symbol @@ -89,7 +84,7 @@ CodabarReader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const override; + using RowReader::RowReader; -private: - bool _returnStartEnd; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const override; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODCode128Reader.h b/core/src/oned/ODCode128Reader.h index e555afa93e..60526fa469 100644 --- a/core/src/oned/ODCode128Reader.h +++ b/core/src/oned/ODCode128Reader.h @@ -8,17 +8,14 @@ #include "ODRowReader.h" -namespace ZXing { - -class DecodeHints; - -namespace OneD { +namespace ZXing::OneD { class Code128Reader : public RowReader { public: + using RowReader::RowReader; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index cadaf784a2..5eb916d6d2 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -75,17 +75,10 @@ DecodeExtendedCode39AndCode93(std::string& encoded, const char ctrl[4]) return true; } - -Code39Reader::Code39Reader(const DecodeHints& hints) : - _extendedMode(hints.tryCode39ExtendedMode()), - _validateCheckSum(hints.validateCode39CheckSum()) -{ -} - Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const { // minimal number of characters that must be present (including start, stop and checksum characters) - int minCharCount = _validateCheckSum ? 4 : 3; + int minCharCount = _hints.validateCode39CheckSum() ? 4 : 3; auto isStartOrStopSymbol = [](char c) { return c == '*'; }; // provide the indices with the narrow bars/spaces which have to be equally wide @@ -123,7 +116,7 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique return {}; Error error; - if (_validateCheckSum) { + if (_hints.validateCode39CheckSum()) { auto checkDigit = txt.back(); txt.pop_back(); int checksum = TransformReduce(txt, 0, [](char c) { return IndexOf(ALPHABET, c); }); @@ -131,12 +124,12 @@ Result Code39Reader::decodePattern(int rowNumber, PatternView& next, std::unique error = ChecksumError(); } - if (!error && _extendedMode && !DecodeExtendedCode39AndCode93(txt, "$%/+")) + if (!error && _hints.tryCode39ExtendedMode() && !DecodeExtendedCode39AndCode93(txt, "$%/+")) error = FormatError("Decoding extended Code39/Code93 failed"); // Symbology identifier modifiers ISO/IEC 16388:2007 Annex C Table C.1 constexpr const char symbologyModifiers[4] = { '0', '3' /*checksum*/, '4' /*extended*/, '7' /*checksum,extended*/ }; - SymbologyIdentifier symbologyIdentifier = {'A', symbologyModifiers[(int)_extendedMode * 2 + (int)_validateCheckSum]}; + SymbologyIdentifier symbologyIdentifier = {'A', symbologyModifiers[(int)_hints.tryCode39ExtendedMode() * 2 + (int)_hints.validateCode39CheckSum()]}; int xStop = next.pixelsTillEnd(); return Result(std::move(txt), rowNumber, xStart, xStop, BarcodeFormat::Code39, symbologyIdentifier, error); diff --git a/core/src/oned/ODCode39Reader.h b/core/src/oned/ODCode39Reader.h index 4bda353dc0..51b7139fe8 100644 --- a/core/src/oned/ODCode39Reader.h +++ b/core/src/oned/ODCode39Reader.h @@ -8,11 +8,7 @@ #include "ODRowReader.h" -namespace ZXing { - -class DecodeHints; - -namespace OneD { +namespace ZXing::OneD { class Code39Reader : public RowReader { @@ -22,14 +18,9 @@ class Code39Reader : public RowReader * or optionally attempt to decode "extended Code 39" sequences that are used to encode * the full ASCII character set. */ - explicit Code39Reader(const DecodeHints& hints); - - Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; + using RowReader::RowReader; -private: - bool _extendedMode; - bool _validateCheckSum; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODCode93Reader.h b/core/src/oned/ODCode93Reader.h index c0733533e3..b8ea6125d0 100644 --- a/core/src/oned/ODCode93Reader.h +++ b/core/src/oned/ODCode93Reader.h @@ -8,14 +8,14 @@ #include "ODRowReader.h" -namespace ZXing { -namespace OneD { +namespace ZXing::OneD { class Code93Reader : public RowReader { public: + using RowReader::RowReader; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index fb89a596ef..7565e50388 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -22,9 +22,6 @@ namespace ZXing::OneD { using namespace DataBar; -DataBarExpandedReader::DataBarExpandedReader(const DecodeHints&) {} -DataBarExpandedReader::~DataBarExpandedReader() = default; - static bool IsFinderPattern(int a, int b, int c, int d, int e) { return IsFinder(a, b, c, d, e) && (c > 3 * e); diff --git a/core/src/oned/ODDataBarExpandedReader.h b/core/src/oned/ODDataBarExpandedReader.h index 290482470a..65c523636c 100644 --- a/core/src/oned/ODDataBarExpandedReader.h +++ b/core/src/oned/ODDataBarExpandedReader.h @@ -7,24 +7,19 @@ #pragma once -#include "DecodeHints.h" #include "ODRowReader.h" -namespace ZXing { -namespace OneD { +namespace ZXing::OneD { /** * Decodes DataBarExpandedReader (formerly known as RSS) sybmols, including truncated and stacked variants. See ISO/IEC 24724:2006. */ class DataBarExpandedReader : public RowReader { - public: - explicit DataBarExpandedReader(const DecodeHints& hints); - ~DataBarExpandedReader() override; + using RowReader::RowReader; Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const override; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index 88865b6e3d..aa647ffb67 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -22,9 +22,6 @@ namespace ZXing::OneD { using namespace DataBar; -DataBarReader::DataBarReader(const DecodeHints&) {} -DataBarReader::~DataBarReader() = default; - static bool IsCharacterPair(PatternView v, int modsLeft, int modsRight) { float modSizeRef = ModSizeFinder(v); diff --git a/core/src/oned/ODDataBarReader.h b/core/src/oned/ODDataBarReader.h index 0e10cebc1d..0e64bb2f9a 100644 --- a/core/src/oned/ODDataBarReader.h +++ b/core/src/oned/ODDataBarReader.h @@ -7,24 +7,19 @@ #pragma once -#include "DecodeHints.h" #include "ODRowReader.h" -namespace ZXing { -namespace OneD { +namespace ZXing::OneD { /** * Decodes DataBar (formerly known as RSS) sybmols, including truncated and stacked variants. See ISO/IEC 24724:2006. */ class DataBarReader : public RowReader { - public: - explicit DataBarReader(const DecodeHints& hints); - ~DataBarReader() override; + using RowReader::RowReader; Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const override; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index f7c1805815..27145e29c5 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -15,8 +15,6 @@ namespace ZXing::OneD { -ITFReader::ITFReader(const DecodeHints& hints) : _validateCheckSum(hints.validateITFCheckSum()) {} - constexpr auto START_PATTERN_ = FixedPattern<4, 4>{1, 1, 1, 1}; constexpr auto STOP_PATTERN_1 = FixedPattern<3, 4>{2, 1, 1}; constexpr auto STOP_PATTERN_2 = FixedPattern<3, 5>{3, 1, 1}; @@ -68,14 +66,14 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt return {}; Error error; - if (_validateCheckSum && !GTIN::IsCheckDigitValid(txt)) + if (_hints.validateITFCheckSum() && !GTIN::IsCheckDigitValid(txt)) error = ChecksumError(); // Symbology identifier ISO/IEC 16390:2007 Annex C Table C.1 // See also GS1 General Specifications 5.1.3 Figure 5.1.3-2 SymbologyIdentifier symbologyIdentifier = {'I', '0'}; // No check character validation - if (_validateCheckSum || (txt.size() == 14 && GTIN::IsCheckDigitValid(txt))) // If no hint test if valid ITF-14 + if (_hints.validateITFCheckSum() || (txt.size() == 14 && GTIN::IsCheckDigitValid(txt))) // If no hint test if valid ITF-14 symbologyIdentifier.modifier = '1'; // Modulo 10 symbol check character validated and transmitted int xStop = next.pixelsTillEnd(); diff --git a/core/src/oned/ODITFReader.h b/core/src/oned/ODITFReader.h index c3bf45fba8..e71d0ea25e 100644 --- a/core/src/oned/ODITFReader.h +++ b/core/src/oned/ODITFReader.h @@ -8,13 +8,7 @@ #include "ODRowReader.h" -#include - -namespace ZXing { - -class DecodeHints; - -namespace OneD { +namespace ZXing::OneD { /** *

Implements decoding of the ITF format, or Interleaved Two of Five.

@@ -31,12 +25,9 @@ namespace OneD { class ITFReader : public RowReader { public: - explicit ITFReader(const DecodeHints& hints); - Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; + using RowReader::RowReader; -private: - bool _validateCheckSum; + Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index c1aa0e4104..bba83cdc23 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -16,10 +16,6 @@ namespace ZXing::OneD { -MultiUPCEANReader::MultiUPCEANReader(const DecodeHints& hints) : _hints(hints) {} - -MultiUPCEANReader::~MultiUPCEANReader() = default; - constexpr int CHAR_LEN = 4; constexpr auto END_PATTERN = FixedPattern<3, 3>{1, 1, 1}; diff --git a/core/src/oned/ODMultiUPCEANReader.h b/core/src/oned/ODMultiUPCEANReader.h index e4537ca287..9ec795d51c 100644 --- a/core/src/oned/ODMultiUPCEANReader.h +++ b/core/src/oned/ODMultiUPCEANReader.h @@ -6,12 +6,9 @@ #pragma once -#include "BarcodeFormat.h" -#include "DecodeHints.h" #include "ODRowReader.h" -namespace ZXing { -namespace OneD { +namespace ZXing::OneD { /** * @brief A reader that can read all available UPC/EAN formats. @@ -19,14 +16,9 @@ namespace OneD { class MultiUPCEANReader : public RowReader { public: - explicit MultiUPCEANReader(const DecodeHints& hints); - ~MultiUPCEANReader() override; + using RowReader::RowReader; Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr&) const override; - -private: - DecodeHints _hints; }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index 4d5f2f374e..a616029413 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -36,9 +36,9 @@ Reader::Reader(const DecodeHints& hints) : ZXing::Reader(hints) if (formats.testFlag(BarcodeFormat::Code39)) _readers.emplace_back(new Code39Reader(hints)); if (formats.testFlag(BarcodeFormat::Code93)) - _readers.emplace_back(new Code93Reader()); + _readers.emplace_back(new Code93Reader(hints)); if (formats.testFlag(BarcodeFormat::Code128)) - _readers.emplace_back(new Code128Reader()); + _readers.emplace_back(new Code128Reader(hints)); if (formats.testFlag(BarcodeFormat::ITF)) _readers.emplace_back(new ITFReader(hints)); if (formats.testFlag(BarcodeFormat::Codabar)) diff --git a/core/src/oned/ODRowReader.h b/core/src/oned/ODRowReader.h index 9bf55fc9d2..98e61a22d7 100644 --- a/core/src/oned/ODRowReader.h +++ b/core/src/oned/ODRowReader.h @@ -8,7 +8,6 @@ #pragma once #include "BitArray.h" -#include "DecodeStatus.h" #include "Pattern.h" #include @@ -38,6 +37,7 @@ RSSExp.: v?-74d/?-41c namespace ZXing { +class DecodeHints; class Result; namespace OneD { @@ -48,7 +48,12 @@ namespace OneD { */ class RowReader { +protected: + const DecodeHints& _hints; + public: + explicit RowReader(const DecodeHints& hints) : _hints(hints) {} + explicit RowReader(DecodeHints&& hints) = delete; struct DecodingState { diff --git a/test/unit/oned/ODCodaBarWriterTest.cpp b/test/unit/oned/ODCodaBarWriterTest.cpp index f8662491fa..7294b5a942 100644 --- a/test/unit/oned/ODCodaBarWriterTest.cpp +++ b/test/unit/oned/ODCodaBarWriterTest.cpp @@ -53,7 +53,8 @@ TEST(ODCodaBarWriterTest, FullCircle) std::string text = "A0123456789-$:/.+A"; BitArray row; CodabarWriter().encode(text, 0, 0).getRow(0, row); - Result res = CodabarReader(DecodeHints().setReturnCodabarStartEnd(true)).decodeSingleRow(0, row); + auto hints = DecodeHints().setReturnCodabarStartEnd(true); + Result res = CodabarReader(hints).decodeSingleRow(0, row); EXPECT_EQ(text, res.utf8()); } diff --git a/test/unit/oned/ODCode128ReaderTest.cpp b/test/unit/oned/ODCode128ReaderTest.cpp index c22f655333..530da630b7 100644 --- a/test/unit/oned/ODCode128ReaderTest.cpp +++ b/test/unit/oned/ODCode128ReaderTest.cpp @@ -5,6 +5,7 @@ #include "oned/ODCode128Reader.h" +#include "DecodeHints.h" #include "Result.h" #include "gtest/gtest.h" @@ -25,7 +26,8 @@ static Result parse(const int startPattern, PatternRow row) row.insert(row.end(), { 2, 3, 3, 1, 1, 1, 2, 0 }); // Stop pattern std::unique_ptr state; - Code128Reader reader; + DecodeHints hints; + Code128Reader reader(hints); PatternView next(row); return reader.decodePattern(0, next, state); } diff --git a/test/unit/oned/ODCode128WriterTest.cpp b/test/unit/oned/ODCode128WriterTest.cpp index 0d25f605d4..a524164a5a 100644 --- a/test/unit/oned/ODCode128WriterTest.cpp +++ b/test/unit/oned/ODCode128WriterTest.cpp @@ -6,6 +6,7 @@ #include "oned/ODCode128Writer.h" #include "BitMatrixIO.h" +#include "DecodeHints.h" #include "Result.h" #include "oned/ODCode128Reader.h" @@ -38,7 +39,8 @@ static ZXing::Result Decode(const BitMatrix &matrix) { BitArray row; matrix.getRow(0, row); - return Code128Reader().decodeSingleRow(0, row); + DecodeHints hints; + return Code128Reader(hints).decodeSingleRow(0, row); } TEST(ODCode128Writer, EncodeWithFunc1) diff --git a/test/unit/oned/ODCode39ExtendedModeTest.cpp b/test/unit/oned/ODCode39ExtendedModeTest.cpp index ca172b4ec1..cbf307d3ba 100644 --- a/test/unit/oned/ODCode39ExtendedModeTest.cpp +++ b/test/unit/oned/ODCode39ExtendedModeTest.cpp @@ -17,7 +17,8 @@ using namespace ZXing::OneD; static std::string Decode(std::string_view encoded) { - Code39Reader sut(DecodeHints().setTryCode39ExtendedMode(true)); + auto hints = DecodeHints().setTryCode39ExtendedMode(true); + Code39Reader sut(hints); BitArray row = Utility::ParseBitArray(encoded, '1'); Result result = sut.decodeSingleRow(0, row); return result.utf8(); diff --git a/test/unit/oned/ODCode93ReaderTest.cpp b/test/unit/oned/ODCode93ReaderTest.cpp index b037f1acbc..f11a70ec79 100644 --- a/test/unit/oned/ODCode93ReaderTest.cpp +++ b/test/unit/oned/ODCode93ReaderTest.cpp @@ -7,6 +7,7 @@ #include "oned/ODCode93Reader.h" #include "BitArray.h" #include "BitArrayUtility.h" +#include "DecodeHints.h" #include "Result.h" #include "gtest/gtest.h" @@ -16,7 +17,8 @@ using namespace ZXing::OneD; static std::string Decode(std::string_view input) { - Code93Reader sut; + DecodeHints hints; + Code93Reader sut(hints); auto row = Utility::ParseBitArray(input, '1'); auto result = sut.decodeSingleRow(0, row); return result.utf8(); From 838ff6cc52de0d6ccaf365dcee8716283eb59c04 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 02:34:04 +0200 Subject: [PATCH 0353/1315] ByteArray: add copyright line --- core/src/ByteArray.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/ByteArray.h b/core/src/ByteArray.h index ad87c2961c..a31f42c1ed 100644 --- a/core/src/ByteArray.h +++ b/core/src/ByteArray.h @@ -1,5 +1,6 @@ /* * Copyright 2016 Nu-book Inc. +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 From 2dfb65ac8ac77135b9e7ff2174f7da2a71d9fe60 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 02:34:26 +0200 Subject: [PATCH 0354/1315] Content: add missing includes (IWYU) --- core/src/Content.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/Content.h b/core/src/Content.h index cce0b541d2..0acd6c2761 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -7,6 +7,9 @@ #include "ByteArray.h" +#include +#include + namespace ZXing { enum class ECI : int; From caab6edcf6c99a0146e33d1c1dbbfa3b792312e2 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 10:22:02 +0200 Subject: [PATCH 0355/1315] Content: introduce `text(TextMode)` See https://github.com/nu-book/zxing-cpp/issues/338#issuecomment-1174741554 --- core/src/Content.cpp | 27 ++++++++++++++++----------- core/src/Content.h | 8 +++++--- core/src/Result.cpp | 2 +- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index ae0ac9157b..3829abe140 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -7,6 +7,7 @@ #include "CharacterSet.h" #include "ECI.h" +#include "GS1.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" #include "ZXContainerAlgorithms.h" @@ -137,19 +138,23 @@ std::wstring Content::render(bool withECI) const return res; } -std::wstring Content::utf16() const +std::string Content::text(TextMode mode) const { - return render(false); -} - -std::string Content::utf8() const -{ - return TextUtfEncoding::ToUtf8(render(false)); -} + switch(mode) { + case TextMode::Utf8: return TextUtfEncoding::ToUtf8(render(false)); + case TextMode::Utf8ECI: return TextUtfEncoding::ToUtf8(render(true)); + case TextMode::HRI: + if (applicationIndicator == "GS1") + return HRIFromGS1(text(TextMode::Utf8)); + else if (type() == ContentType::Text) + return text(TextMode::Utf8); + else + return text(TextMode::Escaped); + case TextMode::Hex: return ToHex(bytes); + case TextMode::Escaped: return TextUtfEncoding::ToUtf8(render(false), true); + } -std::string Content::utf8ECI() const -{ - return TextUtfEncoding::ToUtf8(render(true)); + return {}; // silence compiler warning } ByteArray Content::bytesECI() const diff --git a/core/src/Content.h b/core/src/Content.h index 0acd6c2761..d330ca1312 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -16,6 +16,7 @@ enum class ECI : int; enum class CharacterSet; enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; +enum class TextMode { Utf8, Utf8ECI, HRI, Hex, Escaped }; std::string ToString(ContentType type); @@ -74,9 +75,10 @@ class Content bool empty() const { return bytes.empty(); } bool canProcess() const; - std::wstring utf16() const; - std::string utf8() const; - std::string utf8ECI() const; + std::string text(TextMode mode) const; + std::wstring utf16() const { return render(false); } + std::string utf8() const { return text(TextMode::Utf8); } + ByteArray bytesECI() const; CharacterSet guessEncoding() const; ContentType type() const; diff --git a/core/src/Result.cpp b/core/src/Result.cpp index d406f975b3..0b1e2ddf50 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -80,7 +80,7 @@ std::wstring Result::utf16() const std::string Result::utf8ECI() const { - return _content.utf8ECI(); + return _content.text(TextMode::Utf8ECI); } ContentType Result::contentType() const From 776a2b4f29cbc6c4410aa992080e391c63477a69 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 10:27:52 +0200 Subject: [PATCH 0356/1315] example: use the term 'bytes' instead of 'binary' in output option --- example/ZXingReader.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 3532fb3280..9ef814f7f9 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -38,7 +38,7 @@ static void PrintUsage(const char* exePath) << " -errors Include results with errors (like checksum error)\n" << " -1 Print only file name, content/error on one line per file/barcode (implies '-escape')\n" << " -escape Escape non-graphical characters in angle brackets\n" - << " -binary Write (only) the binary content of the symbol(s) to stdout\n" + << " -bytes Write (only) the bytes content of the symbol(s) to stdout\n" << " -pngout \n" << " Write a copy of the input image with barcodes outlined by a green line\n" << "\n" @@ -49,7 +49,7 @@ static void PrintUsage(const char* exePath) std::cout << "Formats can be lowercase, with or without '-', separated by ',' and/or '|'\n"; } -static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& angleEscape, bool& binaryOutput, +static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& angleEscape, bool& bytesOnly, std::vector& filePaths, std::string& outPath) { for (int i = 1; i < argc; ++i) { @@ -77,8 +77,8 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi oneLine = true; } else if (strcmp(argv[i], "-escape") == 0) { angleEscape = true; - } else if (strcmp(argv[i], "-binary") == 0) { - binaryOutput = true; + } else if (strcmp(argv[i], "-bytes") == 0) { + bytesOnly = true; } else if (strcmp(argv[i], "-pngout") == 0) { if (++i == argc) return false; @@ -131,11 +131,11 @@ int main(int argc, char* argv[]) std::string outPath; bool oneLine = false; bool angleEscape = false; - bool binaryOutput = false; + bool bytesOnly = false; int ret = 0; - if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, binaryOutput, filePaths, outPath)) { + if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, bytesOnly, filePaths, outPath)) { PrintUsage(argv[0]); return -1; } @@ -176,7 +176,7 @@ int main(int argc, char* argv[]) ret |= static_cast(result.error().type()); - if (binaryOutput) { + if (bytesOnly) { std::cout.write(reinterpret_cast(result.bytes().data()), result.bytes().size()); continue; } From 7a597ff0c9c0e8af6dca4c41dd0fcff4090f8d41 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 22:57:28 +0200 Subject: [PATCH 0357/1315] Result: remove now unused `Result(DecodeStatus)` constructor --- core/src/Error.h | 12 ------------ core/src/Result.cpp | 2 -- core/src/Result.h | 1 - 3 files changed, 15 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index 0b7ee85351..207caf3d5d 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -5,8 +5,6 @@ #pragma once -#include "DecodeStatus.h" - #include namespace ZXing { @@ -60,14 +58,4 @@ inline std::string ToString(const Error& e) return ret; } -// transitional helper function -inline Error Status2Error(DecodeStatus s) -{ - switch (s) { - case DecodeStatus::FormatError: return Error(Error::Format); - case DecodeStatus::ChecksumError: return Error(Error::Checksum); - default: return {}; - } -} - } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 0b1e2ddf50..c4a489c610 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -17,8 +17,6 @@ namespace ZXing { -Result::Result(DecodeStatus status) : _error(Status2Error(status)) {} - Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, ByteArray&& rawBytes, bool readerInit, const std::string& ai) : _format(format), diff --git a/core/src/Result.h b/core/src/Result.h index cd6397944d..5469a0370f 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -31,7 +31,6 @@ class Result { public: Result() = default; - explicit Result(DecodeStatus status); // linear symbology convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error = {}, From 5a700741eef8546ad265283b14b49571c2368767 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 23:52:30 +0200 Subject: [PATCH 0358/1315] DMReader: fix compile regression in c++20 --- core/src/datamatrix/DMReader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index c34ea646c8..06d21a9cce 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -21,8 +21,7 @@ namespace ZXing::DataMatrix { Result Reader::decode(const BinaryBitmap& image) const { #ifdef __cpp_impl_coroutine - auto results = decode(image, 1); - return results.empty() ? Result(DecodeStatus::NotFound) : results.front(); + return FirstOrDefault(decode(image, 1)); #else auto binImg = image.getBitMatrix(); if (binImg == nullptr) From b3e94b8ca5f5697929dc5d9e57fd1dc4ba777d85 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 5 Jul 2022 23:53:51 +0200 Subject: [PATCH 0359/1315] ReadBarcode: code cosmetic and TODO comment --- core/src/ReadBarcode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 5b62ff0d87..6b1e22df97 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -121,7 +121,7 @@ Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) if (hints.maxNumberOfSymbols() == 1) { // HACK: use the maxNumberOfSymbols value as a switch to ReadBarcodes to enable the downscaling // see python and android wrapper - return FirstOrDefault(ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1))); + return FirstOrDefault(ReadBarcodes(_iv, hints)); } else { LumImage lum; ImageView iv = SetupLumImageView(_iv, lum, hints); @@ -150,7 +150,7 @@ Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) if (iv.width() != _iv.width()) r.setPosition(Scale(r.position(), _iv.width() / iv.width())); if (!Contains(results, r)) { - results.push_back(std::move(r)); + results.push_back(std::move(r)); // TODO: keep the one with no error instead of the first found --maxSymbols; } } From d3f18b8316e3eef33c81c91e068ef0e4b37256c2 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 6 Jul 2022 10:43:44 +0200 Subject: [PATCH 0360/1315] PDF417: support `tryRotate` (fix #349) This comes at the cost of about 2% performance decrease in the falsepositive use case. --- core/src/BitMatrix.cpp | 18 ++++++++---- core/src/BitMatrix.h | 15 +++++++++- core/src/pdf417/PDFDetector.cpp | 41 ++++++++++++++++++---------- core/src/pdf417/PDFDetector.h | 3 +- core/src/pdf417/PDFReader.cpp | 21 ++++++++++---- test/blackbox/BlackboxTestRunner.cpp | 12 +++++--- 6 files changed, 78 insertions(+), 32 deletions(-) diff --git a/core/src/BitMatrix.cpp b/core/src/BitMatrix.cpp index d9449cfbe3..d0497ff394 100644 --- a/core/src/BitMatrix.cpp +++ b/core/src/BitMatrix.cpp @@ -196,9 +196,9 @@ BitMatrix::getBottomRightOnBit(int& right, int& bottom) const constexpr BitMatrix::data_t BitMatrix::SET_V; constexpr BitMatrix::data_t BitMatrix::UNSET_V; -void BitMatrix::getPatternRow(int r, PatternRow& p_row) const +template +void GetPatternRow(BitMatrix::Row b_row, int row_size, PatternRow& p_row) { - auto b_row = row(r); #if 0 p_row.reserve(64); p_row.clear(); @@ -216,11 +216,11 @@ void BitMatrix::getPatternRow(int r, PatternRow& p_row) const if (BitMatrix::isSet(*lastPos)) p_row.push_back(0); // last value is number of white pixels, here 0 #else - p_row.resize(width() + 2); + p_row.resize(row_size + 2); std::fill(p_row.begin(), p_row.end(), 0); - auto* bitPos = b_row.begin(); - auto* intPos = p_row.data(); + auto bitPos = b_row.begin(); + auto intPos = p_row.data(); intPos += BitMatrix::isSet(*bitPos); // first value is number of white pixels, here 0 @@ -236,6 +236,14 @@ void BitMatrix::getPatternRow(int r, PatternRow& p_row) const p_row.resize(intPos - p_row.data() + 1); #endif } + +void BitMatrix::getPatternRow(int r, PatternRow& p_row, bool transpose) const +{ + if (transpose) + GetPatternRow(col(r), height(), p_row); + else + GetPatternRow(row(r), width(), p_row); +} #endif BitMatrix Inflate(BitMatrix&& input, int width, int height, int quietZone) diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index a01f20a4f4..13c34fd875 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -104,6 +104,19 @@ class BitMatrix }; Row row(int y) { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } Row row(int y) const { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } + + struct ColIter + { + const data_t* pos; + int stride; + + data_t operator*() const { return *pos; } + data_t operator[](int i) const { return *(pos + i * stride); } + ColIter& operator++() { return pos += stride, *this; } + bool operator<(const ColIter& rhs) const { return pos < rhs.pos; } + }; + Row col(int x) const { return {{_bits.data() + x, _width}, {_bits.data() + x + _height * _width, _width}}; } + #endif /** @@ -232,7 +245,7 @@ class BitMatrix bool getBottomRightOnBit(int &right, int& bottom) const; #ifdef ZX_FAST_BIT_STORAGE - void getPatternRow(int r, std::vector& p_row) const; + void getPatternRow(int r, std::vector& p_row, bool transpose = false) const; #endif /** diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 003b4b4654..97835f13c5 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -304,15 +304,16 @@ static std::list, 8>> DetectBarcode(const BitMa } #ifdef ZX_FAST_BIT_STORAGE -bool HasStartPattern(const BitMatrix& m) +bool HasStartPattern(const BitMatrix& m, bool rotate90) { constexpr FixedPattern<8, 17> START_PATTERN = { 8, 1, 1, 1, 1, 1, 1, 3 }; constexpr int minSymbolWidth = 3*8+1; // compact symbol PatternRow row; + int end = rotate90 ? m.width() : m.height(); - for (int r = ROW_STEP; r < m.height(); r += ROW_STEP) { - m.getPatternRow(r, row); + for (int r = ROW_STEP; r < end; r += ROW_STEP) { + m.getPatternRow(r, row, rotate90); if (FindLeftGuard(row, minSymbolWidth, START_PATTERN, 2).isValid()) return true; @@ -332,7 +333,7 @@ bool HasStartPattern(const BitMatrix& m) * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will * be found and returned */ -Detector::Result Detector::Detect(const BinaryBitmap& image, bool multiple) +Detector::Result Detector::Detect(const BinaryBitmap& image, bool multiple, bool tryRotate) { // construct a 'dummy' shared pointer, just be able to pass it up the call chain in DecodeStatus // TODO: reimplement PDF Detector @@ -340,23 +341,33 @@ Detector::Result Detector::Detect(const BinaryBitmap& image, bool multiple) if (!binImg) return {}; + Result result; + + for (int rotate90 = false; rotate90 <= tryRotate && result.points.empty(); ++rotate90) { #if defined(ZX_FAST_BIT_STORAGE) - if (!HasStartPattern(*binImg)) - return {}; + if (!HasStartPattern(*binImg, rotate90)) + continue; #endif + result.rotation = 90 * rotate90; + if (rotate90) { + auto newBits = std::make_shared(binImg->copy()); + newBits->rotate90(); + binImg = newBits; + } - auto barcodeCoordinates = DetectBarcode(*binImg, multiple); - if (barcodeCoordinates.empty()) { - auto newBits = std::make_shared(binImg->copy()); - newBits->rotate180(); - binImg = newBits; - barcodeCoordinates = DetectBarcode(*binImg, multiple); + result.points = DetectBarcode(*binImg, multiple); + if (result.points.empty()) { + auto newBits = std::make_shared(binImg->copy()); + newBits->rotate180(); + binImg = newBits; + result.points = DetectBarcode(*binImg, multiple); + result.rotation += 180; + } } - if (barcodeCoordinates.empty()) + + if (result.points.empty()) return {}; - Result result; - result.points = barcodeCoordinates; result.bits = binImg; return result; } diff --git a/core/src/pdf417/PDFDetector.h b/core/src/pdf417/PDFDetector.h index d3cc9bdf79..1316c0a52c 100644 --- a/core/src/pdf417/PDFDetector.h +++ b/core/src/pdf417/PDFDetector.h @@ -35,9 +35,10 @@ class Detector { std::shared_ptr bits; std::list, 8>> points; + int rotation; }; - static Result Detect(const BinaryBitmap& image, bool multiple); + static Result Detect(const BinaryBitmap& image, bool multiple, bool tryRotate); }; } // Pdf417 diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 3cdab9aa2b..947b21e95c 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -66,19 +66,28 @@ static int GetMaxCodewordWidth(const std::array, 8>& p) std::max(GetMaxWidth(p[1], p[5]), GetMaxWidth(p[7], p[3]) * CodewordDecoder::MODULES_IN_CODEWORD / MODULES_IN_STOP_PATTERN)); } -static Results DoDecode(const BinaryBitmap& image, bool multiple, bool returnErrors) +static Results DoDecode(const BinaryBitmap& image, bool multiple, bool tryRotate, bool returnErrors) { - Detector::Result detectorResult = Detector::Detect(image, multiple); + Detector::Result detectorResult = Detector::Detect(image, multiple, tryRotate); if (detectorResult.points.empty()) return {}; + auto rotate = [res = detectorResult](PointI p) { + switch(res.rotation) { + case 90: return PointI(res.bits->height() - p.y - 1, p.x); + case 180: return PointI(res.bits->width() - p.x - 1, res.bits->height() - p.y - 1); + case 270: return PointI(p.y, res.bits->width() - p.x - 1); + } + return p; + }; + Results results; for (const auto& points : detectorResult.points) { DecoderResult decoderResult = ScanningDecoder::Decode(*detectorResult.bits, points[4], points[5], points[6], points[7], GetMinCodewordWidth(points), GetMaxCodewordWidth(points)); if (decoderResult.isValid(returnErrors)) { - auto point = [&](int i) { return points[i].value(); }; + auto point = [&](int i) { return rotate(PointI(points[i].value())); }; Result result(std::move(decoderResult), {point(0), point(2), point(3), point(1)}, BarcodeFormat::PDF417); results.push_back(result); if (!multiple) @@ -310,18 +319,18 @@ Reader::decode(const BinaryBitmap& image) const // currently the best option to deal with 'aliased' input like e.g. 03-aliased.png } - return FirstOrDefault(DoDecode(image, false, _hints.returnErrors())); + return FirstOrDefault(DoDecode(image, false, _hints.tryRotate(), _hints.returnErrors())); } Results Reader::decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbols) const { - return DoDecode(image, true, _hints.returnErrors()); + return DoDecode(image, true, _hints.tryRotate(), _hints.returnErrors()); } std::list Reader::decodeMultiple(const BinaryBitmap& image) const { - Results results = DoDecode(image, true, _hints.returnErrors()); + Results results = DoDecode(image, true, _hints.tryRotate(), _hints.returnErrors()); return std::list(results.begin(), results.end()); } diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index fdda8ff254..52038adcc7 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -600,21 +600,25 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("pdf417-1", "PDF417", 17, { - { 16, 16, 0 }, - { 1, 1, 90 }, - { 16, 16, 180 }, - { 1, 1, 270 }, + { 16, 17, 0 }, + { 1, 17, 90 }, + { 16, 17, 180 }, + { 1, 17, 270 }, { 17, 0, pure }, }); runTests("pdf417-2", "PDF417", 25, { { 25, 25, 0 }, + { 0, 25, 90 }, { 25, 25, 180 }, + { 0, 25, 270 }, }); runTests("pdf417-3", "PDF417", 16, { { 16, 16, 0 }, + { 0, 16, 90 }, { 16, 16, 180 }, + { 0, 16, 270 }, { 7, 0, pure }, }); From 0e863f16df743f0de82340e8b641d5f413fe6e82 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 02:02:57 +0200 Subject: [PATCH 0361/1315] ZXAlgorithms: introduce narrow_cast from gsl -> fix a few warnings --- core/src/BitArray.h | 8 +++---- core/src/BitMatrixIO.cpp | 4 ++-- core/src/GS1.cpp | 4 ++-- core/src/GlobalHistogramBinarizer.cpp | 6 ++--- core/src/Pattern.h | 4 ++-- core/src/Result.cpp | 3 ++- core/src/ThresholdBinarizer.h | 4 ++-- core/src/ZXContainerAlgorithms.h | 13 +++++++---- core/src/aztec/AZDetector.cpp | 3 ++- core/src/datamatrix/DMDecoder.cpp | 2 +- core/src/datamatrix/DMEncoderContext.h | 2 +- core/src/datamatrix/DMHighLevelEncoder.cpp | 22 +++++++++---------- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/oned/ODCode128Reader.cpp | 4 ++-- core/src/oned/ODRowReader.cpp | 4 ++-- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 4 ++-- core/src/qrcode/QRDecoder.cpp | 12 +++++----- core/src/qrcode/QRDetector.cpp | 2 +- core/src/qrcode/QREncoder.cpp | 2 +- core/src/qrcode/QRMaskUtil.cpp | 2 +- test/blackbox/BlackboxTestRunner.cpp | 2 +- test/unit/ThresholdBinarizerTest.cpp | 2 +- wrappers/python/zxing.cpp | 15 +++++-------- 23 files changed, 64 insertions(+), 62 deletions(-) diff --git a/core/src/BitArray.h b/core/src/BitArray.h index b531389f4d..6f4829aee8 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -31,7 +31,7 @@ struct Range { Iterator begin, end; explicit operator bool() const { return begin < end; } - int size() const { return static_cast(end - begin); } + int size() const { return narrow_cast(end - begin); } }; /** @@ -89,7 +89,7 @@ class BitArray int operator-(const Iterator& rhs) const { - return static_cast(_value - rhs._value) * 32 + (_mask >= rhs._mask + return narrow_cast(_value - rhs._value) * 32 + (_mask >= rhs._mask ? +BitHacks::CountBitsSet(_mask - rhs._mask) : -BitHacks::CountBitsSet(rhs._mask - _mask)); } @@ -272,7 +272,7 @@ class BitArray // Set allowClippedZone to false if clipping the zone at the image border is not acceptable. bool hasQuietZone(Iterator i, int signedZoneSize, bool allowClippedZone = true) const { - int index = static_cast(i - begin()); + int index = narrow_cast(i - begin()); if (signedZoneSize > 0) { if (!allowClippedZone && index + signedZoneSize >= size()) return false; @@ -427,7 +427,7 @@ class BitArrayView int size() const { - return bits.end() - cur; + return narrow_cast(bits.end() - cur); } explicit operator bool() const { return size(); } diff --git a/core/src/BitMatrixIO.cpp b/core/src/BitMatrixIO.cpp index 10a7c86306..0d4e54325d 100644 --- a/core/src/BitMatrixIO.cpp +++ b/core/src/BitMatrixIO.cpp @@ -64,8 +64,8 @@ BitMatrix ParseBitMatrix(const std::string& str, char one, bool expectSpace) return {}; int strStride = expectSpace ? 2 : 1; - int height = static_cast(str.length() / (lineLength + 1)); - int width = static_cast(lineLength / strStride); + int height = narrow_cast(str.length() / (lineLength + 1)); + int width = narrow_cast(lineLength / strStride); BitMatrix mat(width, height); for (int y = 0; y < height; ++y) { size_t offset = y * (lineLength + 1); diff --git a/core/src/GS1.cpp b/core/src/GS1.cpp index 50c25debd7..d083d8af0e 100644 --- a/core/src/GS1.cpp +++ b/core/src/GS1.cpp @@ -260,10 +260,10 @@ std::string HRIFromGS1(const std::string& gs1) if (i->isVariableLength()) { auto gsPos = rem.find(GS); #if 1 - fieldSize = std::min(gsPos == std::string_view::npos ? Size(rem) : static_cast(gsPos), fieldSize); + fieldSize = std::min(gsPos == std::string_view::npos ? Size(rem) : narrow_cast(gsPos), fieldSize); #else // TODO: ignore the 'max field size' part for now as it breaks rssexpanded-3/13.png? - fieldSize = gsPos == std::string_view::npos ? Size(rem) : static_cast(gsPos); + fieldSize = gsPos == std::string_view::npos ? Size(rem) : narrow_cast(gsPos); #endif } if (fieldSize == 0 || Size(rem) < fieldSize) diff --git a/core/src/GlobalHistogramBinarizer.cpp b/core/src/GlobalHistogramBinarizer.cpp index 000bbe9182..f09d040d22 100644 --- a/core/src/GlobalHistogramBinarizer.cpp +++ b/core/src/GlobalHistogramBinarizer.cpp @@ -30,7 +30,7 @@ static int EstimateBlackPoint(const std::array& buckets) { // Find the tallest peak in the histogram. auto firstPeakPos = std::max_element(buckets.begin(), buckets.end()); - int firstPeak = static_cast(firstPeakPos - buckets.begin()); + int firstPeak = narrow_cast(firstPeakPos - buckets.begin()); int firstPeakSize = *firstPeakPos; int maxBucketCount = firstPeakSize; @@ -99,7 +99,7 @@ bool GlobalHistogramBinarizer::getPatternRow(int row, int rotation, PatternRow& auto process = [&](bool val, const uint8_t* p) { if (val != lastVal) { - res.push_back(static_cast((p - lastPos) / pixStride)); + res.push_back(narrow_cast((p - lastPos) / pixStride)); lastVal = val; lastPos = p; } @@ -112,7 +112,7 @@ bool GlobalHistogramBinarizer::getPatternRow(int row, int rotation, PatternRow& bool backVal = *backPos < blackPoint; process(backVal, backPos); - res.push_back(static_cast((backPos - lastPos) / pixStride + 1)); + res.push_back(narrow_cast((backPos - lastPos) / pixStride + 1)); if (backVal) res.push_back(0); // last value is number of white pixels, here 0 diff --git a/core/src/Pattern.h b/core/src/Pattern.h index 2226169d15..1b2a112c9b 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -59,7 +59,7 @@ class PatternView int size() const { return _size; } // index is the number of bars and spaces from the first bar to the current position - int index() const { return static_cast(_data - (_base + 1)); } + int index() const { return narrow_cast(_data - (_base + 1)); } int pixelsInFront() const { return std::accumulate(_base, _data, 0); } int pixelsTillEnd() const { return std::accumulate(_base, _data + _size, 0) - 1; } bool isAtFirstBar() const { return _data == _base + 1; } @@ -114,7 +114,7 @@ class PatternView void extend() { - _size = std::max(0, static_cast(_end - _data)); + _size = std::max(0, narrow_cast(_end - _data)); } }; diff --git a/core/src/Result.cpp b/core/src/Result.cpp index c4a489c610..da29225cd1 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -9,6 +9,7 @@ #include "DecoderResult.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" +#include "ZXContainerAlgorithms.h" #include #include @@ -94,7 +95,7 @@ bool Result::hasECI() const int Result::orientation() const { constexpr auto std_numbers_pi_v = 3.14159265358979323846; // TODO: c++20 - return std::lround(_position.orientation() * 180 / std_numbers_pi_v); + return narrow_cast(std::lround(_position.orientation() * 180 / std_numbers_pi_v)); } std::string Result::symbologyIdentifier() const diff --git a/core/src/ThresholdBinarizer.h b/core/src/ThresholdBinarizer.h index 620886a536..92cb1ffb56 100644 --- a/core/src/ThresholdBinarizer.h +++ b/core/src/ThresholdBinarizer.h @@ -35,13 +35,13 @@ class ThresholdBinarizer : public BinaryBitmap for (const uint8_t* p = begin; p < end; p += stride) { bool val = *p <= _threshold; if (val != lastVal) { - res.push_back(static_cast(p - lastPos) / stride); + res.push_back(narrow_cast(p - lastPos) / stride); lastVal = val; lastPos = p; } } - res.push_back(static_cast(end - lastPos) / stride); + res.push_back(narrow_cast(end - lastPos) / stride); if (*(end - stride) <= _threshold) res.push_back(0); // last value is number of white pixels, here 0 diff --git a/core/src/ZXContainerAlgorithms.h b/core/src/ZXContainerAlgorithms.h index 28a9b89a19..f04191f10d 100644 --- a/core/src/ZXContainerAlgorithms.h +++ b/core/src/ZXContainerAlgorithms.h @@ -14,6 +14,11 @@ namespace ZXing { +template +constexpr T narrow_cast(U&& u) noexcept { + return static_cast(std::forward(u)); +} + template auto Find(Container& c, const Value& v) -> decltype(std::begin(c)) { return std::find(std::begin(c), std::end(c), v); @@ -46,23 +51,23 @@ Value Reduce(const Container& c, Value v = Value{}, Op op = {}) { // see C++20 ssize template constexpr auto Size(const Container& c) -> decltype(c.size(), int()) { - return static_cast(c.size()); + return narrow_cast(c.size()); } template constexpr int Size(const T (&)[N]) noexcept { - return static_cast(N); + return narrow_cast(N); } template int IndexOf(const Container& c, const Value& v) { auto i = Find(c, v); - return i == std::end(c) ? -1 : static_cast(std::distance(std::begin(c), i)); + return i == std::end(c) ? -1 : narrow_cast(std::distance(std::begin(c), i)); } inline int IndexOf(const char* str, char c) { auto s = strchr(str, c); - return s != nullptr ? static_cast(s - str) : -1; + return s != nullptr ? narrow_cast(s - str) : -1; } template diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index 7c56af7829..d309ea6c7a 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -14,6 +14,7 @@ #include "ReedSolomonDecoder.h" #include "ResultPoint.h" #include "WhiteRectDetector.h" +#include "ZXContainerAlgorithms.h" #include #include @@ -23,7 +24,7 @@ namespace ZXing::Aztec { template ::value>::type> static int RoundToNearest(T x) { - return static_cast(std::lround(x)); + return narrow_cast(std::lround(x)); } static const int EXPECTED_CORNER_BITS[] = { diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index a82440c5be..69c5067208 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -268,7 +268,7 @@ static void DecodeBase256Segment(BitSource& bits, Content& result) for (int i = 0; i < count; i++) { // readBits(8) may fail, have seen this particular error in the wild, such as at // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2 - result += static_cast(Unrandomize255State(bits.readBits(8), codewordPosition++)); + result += narrow_cast(Unrandomize255State(bits.readBits(8), codewordPosition++)); } } diff --git a/core/src/datamatrix/DMEncoderContext.h b/core/src/datamatrix/DMEncoderContext.h index ac5a81555f..dabcf0aef6 100644 --- a/core/src/datamatrix/DMEncoderContext.h +++ b/core/src/datamatrix/DMEncoderContext.h @@ -103,7 +103,7 @@ class EncoderContext } int totalMessageCharCount() const { - return static_cast(_msg.length() - _skipAtEnd); + return narrow_cast(_msg.length() - _skipAtEnd); } int remainingCharacters() const { diff --git a/core/src/datamatrix/DMHighLevelEncoder.cpp b/core/src/datamatrix/DMHighLevelEncoder.cpp index d030aa05be..0ace173816 100644 --- a/core/src/datamatrix/DMHighLevelEncoder.cpp +++ b/core/src/datamatrix/DMHighLevelEncoder.cpp @@ -116,7 +116,7 @@ static uint8_t Randomize253State(uint8_t ch, int codewordPosition) { int pseudoRandom = ((149 * codewordPosition) % 253) + 1; int tempVariable = ch + pseudoRandom; - return static_cast(tempVariable <= 254 ? tempVariable : (tempVariable - 254)); + return narrow_cast(tempVariable <= 254 ? tempVariable : (tempVariable - 254)); } static int FindMinimums(const std::array& intCharCounts, int min, std::array& mins) @@ -322,7 +322,7 @@ namespace ASCIIEncoder { static int DetermineConsecutiveDigitCount(const std::string& msg, int startpos) { auto begin = msg.begin() + startpos; - return static_cast(std::find_if_not(begin, msg.end(), IsDigit) - begin); + return narrow_cast(std::find_if_not(begin, msg.end(), IsDigit) - begin); } static uint8_t EncodeASCIIDigits(int digit1, int digit2) @@ -428,8 +428,8 @@ namespace C40Encoder { int c2 = sb.at(startPos + 1); int c3 = sb.at(startPos + 2); int v = (1600 * c1) + (40 * c2) + c3 + 1; - context.addCodeword(static_cast(v / 256)); - context.addCodeword(static_cast(v % 256)); + context.addCodeword(narrow_cast(v / 256)); + context.addCodeword(narrow_cast(v % 256)); } static void WriteNextTriplet(EncoderContext& context, std::string& buffer) @@ -494,7 +494,7 @@ namespace C40Encoder { int c = context.currentChar(); context.setCurrentPos(context.currentPos() + 1); int lastCharSize = encodeChar(c, buffer); - int unwritten = static_cast(buffer.length() / 3) * 2; + int unwritten = narrow_cast(buffer.length() / 3) * 2; int curCodewordCount = context.codewordCount() + unwritten; auto symbolInfo = context.updateSymbolInfo(curCodewordCount); int available = symbolInfo->dataCapacity() - curCodewordCount; @@ -682,17 +682,17 @@ namespace EdifactEncoder { int c4 = len >= 4 ? sb.at(startPos + 3) : 0; int v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4; - int cw1 = (v >> 16) & 255; - int cw2 = (v >> 8) & 255; - int cw3 = v & 255; + uint8_t cw1 = (v >> 16) & 255; + uint8_t cw2 = (v >> 8) & 255; + uint8_t cw3 = v & 255; ByteArray res; res.reserve(3); - res.push_back(static_cast(cw1)); + res.push_back(cw1); if (len >= 2) { - res.push_back(static_cast(cw2)); + res.push_back(cw2); } if (len >= 3) { - res.push_back(static_cast(cw3)); + res.push_back(cw3); } return res; } diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 058527cf19..794409da26 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -52,7 +52,7 @@ static bool CorrectErrors(ByteArray& codewordBytes, int start, int dataCodewords // We don't care about errors in the error-correction codewords for (int i = 0; i < dataCodewords; i++) { if ((mode == ALL) || (i % 2 == (mode - 1))) - codewordBytes[i + start] = static_cast(codewordsInts[i / divisor]); + codewordBytes[i + start] = narrow_cast(codewordsInts[i / divisor]); } return true; diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index 42fa421b79..a90228de8f 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -237,7 +237,7 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu int xStart = next.pixelsInFront(); ByteArray rawCodes; rawCodes.reserve(20); - rawCodes.push_back(static_cast(startCode)); + rawCodes.push_back(narrow_cast(startCode)); Raw2TxtDecoder raw2txt(startCode); @@ -256,7 +256,7 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu if (!raw2txt.decode(code)) return {}; - rawCodes.push_back(static_cast(code)); + rawCodes.push_back(narrow_cast(code)); } if (Size(rawCodes) < minCharCount - 1) // stop code is missing in rawCodes diff --git a/core/src/oned/ODRowReader.cpp b/core/src/oned/ODRowReader.cpp index ef5bb3458f..339ec0d56d 100644 --- a/core/src/oned/ODRowReader.cpp +++ b/core/src/oned/ODRowReader.cpp @@ -21,10 +21,10 @@ Result RowReader::decodeSingleRow(int rowNumber, const BitArray& row) const if (*i) res.push_back(0); while ((i = row.getNextSetTo(i, !*i)) != row.end()) { - res.push_back(static_cast(i - li)); + res.push_back(narrow_cast(i - li)); li = i; } - res.push_back(static_cast(i - li)); + res.push_back(narrow_cast(i - li)); if (*(i-1)) res.push_back(0); diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 631af0b07d..72f8989505 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -627,7 +627,7 @@ int DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderRe case MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: { uint64_t segmentCount; codeIndex = DecodeMacroOptionalNumericField(codewords, codeIndex + 1, segmentCount); - resultMetadata.setSegmentCount(static_cast(segmentCount)); + resultMetadata.setSegmentCount(narrow_cast(segmentCount)); break; } case MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: { @@ -639,7 +639,7 @@ int DecodeMacroBlock(const std::vector& codewords, int codeIndex, DecoderRe case MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: { uint64_t checksum; codeIndex = DecodeMacroOptionalNumericField(codewords, codeIndex + 1, checksum); - resultMetadata.setChecksum(static_cast(checksum)); + resultMetadata.setChecksum(narrow_cast(checksum)); break; } case MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: { diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index cfb94a774e..7465577c79 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -75,8 +75,8 @@ static void DecodeHanziSegment(BitSource& bits, int count, Content& result) // In the 0xB0A1 to 0xFAFE range assembledTwoBytes += 0x0A6A1; } - result += static_cast((assembledTwoBytes >> 8) & 0xFF); - result += static_cast(assembledTwoBytes & 0xFF); + result += narrow_cast((assembledTwoBytes >> 8) & 0xFF); + result += narrow_cast(assembledTwoBytes & 0xFF); count--; } } @@ -99,8 +99,8 @@ static void DecodeKanjiSegment(BitSource& bits, int count, Content& result) // In the 0xE040 to 0xEBBF range assembledTwoBytes += 0x0C140; } - result += static_cast(assembledTwoBytes >> 8); - result += static_cast(assembledTwoBytes); + result += narrow_cast(assembledTwoBytes >> 8); + result += narrow_cast(assembledTwoBytes); count--; } } @@ -111,7 +111,7 @@ static void DecodeByteSegment(BitSource& bits, int count, Content& result) result.reserve(count); for (int i = 0; i < count; i++) - result += static_cast(bits.readBits(8)); + result += narrow_cast(bits.readBits(8)); } static char ToAlphaNumericChar(int value) @@ -288,7 +288,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo else if (appInd < 100) // "10-99" result += std::to_string(appInd); else if ((appInd >= 165 && appInd <= 190) || (appInd >= 197 && appInd <= 222)) // "A-Za-z" - result += static_cast(appInd - 100); + result += narrow_cast(appInd - 100); else throw FormatError("Invalid AIM Application Indicator"); result.applicationIndicator = result.bytes.asString(); // see also above diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 2eb0e04c1a..0070718858 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -202,7 +202,7 @@ static DimensionEstimate EstimateDimension(const BitMatrix& image, PointF a, Poi auto moduleSize = (ms_a + ms_b) / 2; - int dimension = std::lround(distance(a, b) / moduleSize) + 7; + int dimension = narrow_cast(std::lround(distance(a, b) / moduleSize) + 7); int error = 1 - (dimension % 4); return {dimension + error, moduleSize, std::abs(error)}; diff --git a/core/src/qrcode/QREncoder.cpp b/core/src/qrcode/QREncoder.cpp index 2ce915fd0d..206e4cd70a 100644 --- a/core/src/qrcode/QREncoder.cpp +++ b/core/src/qrcode/QREncoder.cpp @@ -376,7 +376,7 @@ void GenerateECBytes(const ByteArray& dataBytes, int numEcBytes, ByteArray& ecBy ReedSolomonEncode(GenericGF::QRCodeField256(), message, numEcBytes); ecBytes.resize(numEcBytes); - std::transform(message.end() - numEcBytes, message.end(), ecBytes.begin(), [](auto c) { return static_cast(c); }); + std::transform(message.end() - numEcBytes, message.end(), ecBytes.begin(), [](auto c) { return narrow_cast(c); }); } diff --git a/core/src/qrcode/QRMaskUtil.cpp b/core/src/qrcode/QRMaskUtil.cpp index 0213730b2d..53c9b3ac58 100644 --- a/core/src/qrcode/QRMaskUtil.cpp +++ b/core/src/qrcode/QRMaskUtil.cpp @@ -138,7 +138,7 @@ static int ApplyMaskPenaltyRule4(const TritMatrix& matrix) auto numDarkCells = std::count_if(matrix.begin(), matrix.end(), [](Trit cell) { return cell; }); auto numTotalCells = matrix.size(); auto fivePercentVariances = std::abs(numDarkCells * 2 - numTotalCells) * 10 / numTotalCells; - return static_cast(fivePercentVariances * N4); + return narrow_cast(fivePercentVariances * N4); } // The mask penalty calculation is complicated. See Table 21 of JISX0510:2004 (p.45) for details. diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 52038adcc7..dc657ab667 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -156,7 +156,7 @@ static int totalImageLoadTime = 0; int timeSince(std::chrono::steady_clock::time_point startTime) { auto duration = std::chrono::steady_clock::now() - startTime; - return static_cast(std::chrono::duration_cast(duration).count()); + return narrow_cast(std::chrono::duration_cast(duration).count()); } // pre-load images into cache, so the disc io time does not end up in the timing measurement diff --git a/test/unit/ThresholdBinarizerTest.cpp b/test/unit/ThresholdBinarizerTest.cpp index d6695ba404..bcf8ab6839 100644 --- a/test/unit/ThresholdBinarizerTest.cpp +++ b/test/unit/ThresholdBinarizerTest.cpp @@ -13,7 +13,7 @@ using namespace ZXing; // Helper to parse a 0/1 string into a BitMatrix static BitMatrix ParseBitMatrix(const std::string& str, const int width) { - const int height = static_cast(str.length() / width); + const int height = narrow_cast(str.length() / width); BitMatrix mat(width, height); for (int y = 0; y < height; ++y) { diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index b00c47d2bb..e4997020c3 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -11,6 +11,7 @@ // Reader #include "ReadBarcode.h" +#include "ZXContainerAlgorithms.h" // Writer #include "BitMatrix.h" @@ -30,12 +31,6 @@ namespace py = pybind11; // Numpy array wrapper class for images (either BGR or GRAYSCALE) using Image = py::array_t; -template -OUT narrow(IN in) -{ - return static_cast(in); -} - std::ostream& operator<<(std::ostream& os, const Position& points) { for (const auto& p : points) os << p.x << "x" << p.y << " "; @@ -63,9 +58,9 @@ auto read_barcodes_impl(py::object _image, const BarcodeFormats& formats, bool t catch(...) { throw py::type_error("Unsupported type " + _type + ". Expect a PIL Image or numpy array"); } - const auto height = narrow(image.shape(0)); - const auto width = narrow(image.shape(1)); - auto channels = image.ndim() == 2 ? 1 : narrow(image.shape(2)); + const auto height = narrow_cast(image.shape(0)); + const auto width = narrow_cast(image.shape(1)); + auto channels = image.ndim() == 2 ? 1 : narrow_cast(image.shape(2)); ImageFormat imgfmt; if (_type.find("PIL.") != std::string::npos) { const auto mode = _image.attr("mode").cast(); @@ -117,7 +112,7 @@ Image write_barcode(BarcodeFormat format, std::string text, int width, int heigh auto r = result.mutable_unchecked<2>(); for (py::ssize_t y = 0; y < r.shape(0); y++) for (py::ssize_t x = 0; x < r.shape(1); x++) - r(y, x) = bitmap.get(narrow(x), narrow(y)) ? 0 : 255; + r(y, x) = bitmap.get(narrow_cast(x), narrow_cast(y)) ? 0 : 255; return result; } From 60944309c034395a228a61ec577ce89f2bf4baff Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 02:10:20 +0200 Subject: [PATCH 0362/1315] ZXAlgorithms: rename `ZXContainerAlgoriths.h` to `ZXAlgorithms.h` --- core/CMakeLists.txt | 4 ++-- core/src/BarcodeFormat.cpp | 2 +- core/src/BitArray.h | 2 +- core/src/BitSource.cpp | 2 +- core/src/CharacterSet.cpp | 2 +- core/src/ConcentricFinder.h | 2 +- core/src/Content.cpp | 2 +- core/src/DecoderResult.h | 2 +- core/src/GS1.cpp | 2 +- core/src/GTIN.h | 2 +- core/src/GenericGFPoly.cpp | 2 +- core/src/GenericGFPoly.h | 2 +- core/src/HybridBinarizer.cpp | 2 +- core/src/Matrix.h | 2 +- core/src/Pattern.h | 2 +- core/src/Quadrilateral.h | 2 +- core/src/Result.cpp | 2 +- core/src/TextEncoder.cpp | 2 +- core/src/{ZXContainerAlgorithms.h => ZXAlgorithms.h} | 0 core/src/aztec/AZDetector.cpp | 2 +- core/src/aztec/AZHighLevelEncoder.cpp | 2 +- core/src/datamatrix/DMDataBlock.cpp | 2 +- core/src/datamatrix/DMDecoder.cpp | 2 +- core/src/datamatrix/DMEncoderContext.h | 2 +- core/src/datamatrix/DMHighLevelEncoder.cpp | 2 +- core/src/datamatrix/DMSymbolInfo.cpp | 2 +- core/src/oned/ODCodabarReader.cpp | 2 +- core/src/oned/ODCodabarWriter.cpp | 2 +- core/src/oned/ODCode128Reader.cpp | 2 +- core/src/oned/ODCode39Reader.cpp | 2 +- core/src/oned/ODCode39Writer.cpp | 2 +- core/src/oned/ODCode93Reader.cpp | 2 +- core/src/oned/ODCode93Writer.cpp | 2 +- core/src/oned/ODITFReader.cpp | 2 +- core/src/pdf417/PDFCodewordDecoder.cpp | 2 +- core/src/pdf417/PDFDetectionResult.cpp | 2 +- core/src/pdf417/PDFDetectionResultColumn.cpp | 2 +- core/src/pdf417/PDFEncoder.h | 2 +- core/src/pdf417/PDFHighLevelEncoder.cpp | 2 +- core/src/pdf417/PDFModulusPoly.h | 2 +- core/src/qrcode/QRCodecMode.cpp | 2 +- core/src/qrcode/QRDataBlock.cpp | 2 +- core/src/qrcode/QRDecoder.cpp | 2 +- test/blackbox/BlackboxTestRunner.cpp | 2 +- test/blackbox/TestReaderMain.cpp | 2 +- test/unit/datamatrix/DMHighLevelEncodeTest.cpp | 2 +- test/unit/pdf417/PDF417ErrorCorrectionTest.cpp | 2 +- wrappers/python/zxing.cpp | 2 +- 48 files changed, 48 insertions(+), 48 deletions(-) rename core/src/{ZXContainerAlgorithms.h => ZXAlgorithms.h} (100%) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 4088c65288..7382bcae71 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -75,11 +75,11 @@ set (COMMON_FILES src/TextUtfEncoding.h src/TextUtfEncoding.cpp src/TritMatrix.h + src/ZXAlgorithms.h src/ZXBigInteger.h src/ZXBigInteger.cpp src/ZXConfig.h src/ZXNullable.h - src/ZXContainerAlgorithms.h src/ZXTestSupport.h ) if (BUILD_READERS) @@ -148,8 +148,8 @@ set (PUBLIC_HEADERS src/Flags.h src/GTIN.h src/TextUtfEncoding.h + src/ZXAlgorithms.h src/ZXConfig.h - src/ZXContainerAlgorithms.h ) if (BUILD_READERS) set (PUBLIC_HEADERS ${PUBLIC_HEADERS} diff --git a/core/src/BarcodeFormat.cpp b/core/src/BarcodeFormat.cpp index 0bc05be826..e188f2908a 100644 --- a/core/src/BarcodeFormat.cpp +++ b/core/src/BarcodeFormat.cpp @@ -6,7 +6,7 @@ #include "BarcodeFormat.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 6f4829aee8..4c840262e6 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -8,7 +8,7 @@ #pragma once #include "ZXConfig.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #ifndef ZX_FAST_BIT_STORAGE #include "BitHacks.h" #endif diff --git a/core/src/BitSource.cpp b/core/src/BitSource.cpp index bc2771a932..3693e52607 100644 --- a/core/src/BitSource.cpp +++ b/core/src/BitSource.cpp @@ -7,7 +7,7 @@ #include "BitSource.h" #include "ByteArray.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include diff --git a/core/src/CharacterSet.cpp b/core/src/CharacterSet.cpp index 57ee86eb01..4c0c17bb16 100644 --- a/core/src/CharacterSet.cpp +++ b/core/src/CharacterSet.cpp @@ -6,7 +6,7 @@ #include "CharacterSet.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include diff --git a/core/src/ConcentricFinder.h b/core/src/ConcentricFinder.h index 8fe07d2945..ab86da8a1f 100644 --- a/core/src/ConcentricFinder.h +++ b/core/src/ConcentricFinder.h @@ -8,7 +8,7 @@ #include "BitMatrixCursor.h" #include "Pattern.h" #include "Quadrilateral.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 3829abe140..00ea9b3217 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -10,7 +10,7 @@ #include "GS1.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" namespace ZXing { diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 34822a7791..2b916d0249 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -10,7 +10,7 @@ #include "Content.h" #include "Error.h" #include "StructuredAppend.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/GS1.cpp b/core/src/GS1.cpp index d083d8af0e..1b5994abfb 100644 --- a/core/src/GS1.cpp +++ b/core/src/GS1.cpp @@ -7,7 +7,7 @@ #include "GS1.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" namespace ZXing { diff --git a/core/src/GTIN.h b/core/src/GTIN.h index 9637be44ec..df9405c720 100644 --- a/core/src/GTIN.h +++ b/core/src/GTIN.h @@ -8,7 +8,7 @@ #pragma once #include "BarcodeFormat.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include diff --git a/core/src/GenericGFPoly.cpp b/core/src/GenericGFPoly.cpp index 8abe394e93..a2634f82d1 100644 --- a/core/src/GenericGFPoly.cpp +++ b/core/src/GenericGFPoly.cpp @@ -9,7 +9,7 @@ #include "GenericGF.h" #include "ZXConfig.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/GenericGFPoly.h b/core/src/GenericGFPoly.h index 11b03a70d6..70ce6f1a70 100644 --- a/core/src/GenericGFPoly.h +++ b/core/src/GenericGFPoly.h @@ -6,7 +6,7 @@ #pragma once -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/HybridBinarizer.cpp b/core/src/HybridBinarizer.cpp index bf14d51d6a..598bd2a860 100644 --- a/core/src/HybridBinarizer.cpp +++ b/core/src/HybridBinarizer.cpp @@ -10,7 +10,7 @@ #include "BitMatrixIO.h" #include "ByteArray.h" #include "Matrix.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/Matrix.h b/core/src/Matrix.h index a85ccf42c1..7b350ec735 100644 --- a/core/src/Matrix.h +++ b/core/src/Matrix.h @@ -7,7 +7,7 @@ #pragma once #include "Point.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/Pattern.h b/core/src/Pattern.h index 1b2a112c9b..f75bc7dbb0 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -5,7 +5,7 @@ #pragma once -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/Quadrilateral.h b/core/src/Quadrilateral.h index 9d3cea0201..a2620715a8 100644 --- a/core/src/Quadrilateral.h +++ b/core/src/Quadrilateral.h @@ -6,7 +6,7 @@ #pragma once #include "Point.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/Result.cpp b/core/src/Result.cpp index da29225cd1..00d70ae6aa 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -9,7 +9,7 @@ #include "DecoderResult.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/TextEncoder.cpp b/core/src/TextEncoder.cpp index 21af9ee744..5ddde516bf 100644 --- a/core/src/TextEncoder.cpp +++ b/core/src/TextEncoder.cpp @@ -7,7 +7,7 @@ #include "CharacterSet.h" #include "TextUtfEncoding.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "textcodec/Big5TextEncoder.h" #include "textcodec/GBTextEncoder.h" #include "textcodec/JPTextEncoder.h" diff --git a/core/src/ZXContainerAlgorithms.h b/core/src/ZXAlgorithms.h similarity index 100% rename from core/src/ZXContainerAlgorithms.h rename to core/src/ZXAlgorithms.h diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index d309ea6c7a..8f14fe07f6 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -14,7 +14,7 @@ #include "ReedSolomonDecoder.h" #include "ResultPoint.h" #include "WhiteRectDetector.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/aztec/AZHighLevelEncoder.cpp b/core/src/aztec/AZHighLevelEncoder.cpp index 0060050cd6..f17b5df637 100644 --- a/core/src/aztec/AZHighLevelEncoder.cpp +++ b/core/src/aztec/AZHighLevelEncoder.cpp @@ -9,7 +9,7 @@ #include "AZEncodingState.h" #include "AZToken.h" #include "BitArray.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/datamatrix/DMDataBlock.cpp b/core/src/datamatrix/DMDataBlock.cpp index 241a160ac5..710e67d087 100644 --- a/core/src/datamatrix/DMDataBlock.cpp +++ b/core/src/datamatrix/DMDataBlock.cpp @@ -7,7 +7,7 @@ #include "DMDataBlock.h" #include "DMVersion.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 69c5067208..6c30613221 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -17,7 +17,7 @@ #include "GenericGF.h" #include "ReedSolomonDecoder.h" #include "TextDecoder.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "ZXTestSupport.h" #include diff --git a/core/src/datamatrix/DMEncoderContext.h b/core/src/datamatrix/DMEncoderContext.h index dabcf0aef6..ecd9b0b032 100644 --- a/core/src/datamatrix/DMEncoderContext.h +++ b/core/src/datamatrix/DMEncoderContext.h @@ -9,7 +9,7 @@ #include "ByteArray.h" #include "DMSymbolInfo.h" #include "DMSymbolShape.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/datamatrix/DMHighLevelEncoder.cpp b/core/src/datamatrix/DMHighLevelEncoder.cpp index 0ace173816..9741de5473 100644 --- a/core/src/datamatrix/DMHighLevelEncoder.cpp +++ b/core/src/datamatrix/DMHighLevelEncoder.cpp @@ -10,7 +10,7 @@ #include "CharacterSet.h" #include "DMEncoderContext.h" #include "TextEncoder.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/datamatrix/DMSymbolInfo.cpp b/core/src/datamatrix/DMSymbolInfo.cpp index 0a3c0ce848..f3505a69a5 100644 --- a/core/src/datamatrix/DMSymbolInfo.cpp +++ b/core/src/datamatrix/DMSymbolInfo.cpp @@ -7,7 +7,7 @@ #include "DMSymbolInfo.h" #include "DMSymbolShape.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "ZXTestSupport.h" #include diff --git a/core/src/oned/ODCodabarReader.cpp b/core/src/oned/ODCodabarReader.cpp index b3fd40b0c3..f72b6ad44c 100644 --- a/core/src/oned/ODCodabarReader.cpp +++ b/core/src/oned/ODCodabarReader.cpp @@ -9,7 +9,7 @@ #include "DecodeHints.h" #include "Result.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/oned/ODCodabarWriter.cpp b/core/src/oned/ODCodabarWriter.cpp index 25c42edbfc..46a50569f9 100644 --- a/core/src/oned/ODCodabarWriter.cpp +++ b/core/src/oned/ODCodabarWriter.cpp @@ -8,7 +8,7 @@ #include "ODWriterHelper.h" #include "TextUtfEncoding.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index a90228de8f..9f9f788e2f 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -8,7 +8,7 @@ #include "ODCode128Patterns.h" #include "Result.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/oned/ODCode39Reader.cpp b/core/src/oned/ODCode39Reader.cpp index 5eb916d6d2..6824075fe0 100644 --- a/core/src/oned/ODCode39Reader.cpp +++ b/core/src/oned/ODCode39Reader.cpp @@ -9,7 +9,7 @@ #include "DecodeHints.h" #include "DecoderResult.h" #include "Result.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include diff --git a/core/src/oned/ODCode39Writer.cpp b/core/src/oned/ODCode39Writer.cpp index d6732cd801..49347f3964 100644 --- a/core/src/oned/ODCode39Writer.cpp +++ b/core/src/oned/ODCode39Writer.cpp @@ -10,7 +10,7 @@ #include "ODWriterHelper.h" #include "TextEncoder.h" #include "TextUtfEncoding.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/oned/ODCode93Reader.cpp b/core/src/oned/ODCode93Reader.cpp index a2668f9af6..cfeaa0db3f 100644 --- a/core/src/oned/ODCode93Reader.cpp +++ b/core/src/oned/ODCode93Reader.cpp @@ -8,7 +8,7 @@ #include "ODCode93Reader.h" #include "Result.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/oned/ODCode93Writer.cpp b/core/src/oned/ODCode93Writer.cpp index fb2c26157c..9cca0771db 100644 --- a/core/src/oned/ODCode93Writer.cpp +++ b/core/src/oned/ODCode93Writer.cpp @@ -8,7 +8,7 @@ #include "ODWriterHelper.h" #include "TextUtfEncoding.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "ZXTestSupport.h" #include diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index 27145e29c5..f2e8078196 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -9,7 +9,7 @@ #include "DecodeHints.h" #include "GTIN.h" #include "Result.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include diff --git a/core/src/pdf417/PDFCodewordDecoder.cpp b/core/src/pdf417/PDFCodewordDecoder.cpp index 9318156ad2..4b9d8c1094 100644 --- a/core/src/pdf417/PDFCodewordDecoder.cpp +++ b/core/src/pdf417/PDFCodewordDecoder.cpp @@ -6,7 +6,7 @@ #include "PDFCodewordDecoder.h" #include "BitArray.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/pdf417/PDFDetectionResult.cpp b/core/src/pdf417/PDFDetectionResult.cpp index c145a1be2e..b9f97b305a 100644 --- a/core/src/pdf417/PDFDetectionResult.cpp +++ b/core/src/pdf417/PDFDetectionResult.cpp @@ -6,7 +6,7 @@ #include "PDFDetectionResult.h" #include "PDFCodewordDecoder.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/pdf417/PDFDetectionResultColumn.cpp b/core/src/pdf417/PDFDetectionResultColumn.cpp index 8c85065889..4386746fda 100644 --- a/core/src/pdf417/PDFDetectionResultColumn.cpp +++ b/core/src/pdf417/PDFDetectionResultColumn.cpp @@ -7,7 +7,7 @@ #include "PDFDetectionResultColumn.h" #include "PDFBarcodeMetadata.h" #include "PDFBarcodeValue.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/pdf417/PDFEncoder.h b/core/src/pdf417/PDFEncoder.h index f58d1279ef..3f086dfd0d 100644 --- a/core/src/pdf417/PDFEncoder.h +++ b/core/src/pdf417/PDFEncoder.h @@ -7,7 +7,7 @@ #pragma once #include "CharacterSet.h" #include "PDFCompaction.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/pdf417/PDFHighLevelEncoder.cpp b/core/src/pdf417/PDFHighLevelEncoder.cpp index ea394d11c2..07f08b4421 100644 --- a/core/src/pdf417/PDFHighLevelEncoder.cpp +++ b/core/src/pdf417/PDFHighLevelEncoder.cpp @@ -11,7 +11,7 @@ #include "ECI.h" #include "TextEncoder.h" #include "ZXBigInteger.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/pdf417/PDFModulusPoly.h b/core/src/pdf417/PDFModulusPoly.h index ed44abe7d3..0de1c9132a 100644 --- a/core/src/pdf417/PDFModulusPoly.h +++ b/core/src/pdf417/PDFModulusPoly.h @@ -6,7 +6,7 @@ #pragma once -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/qrcode/QRCodecMode.cpp b/core/src/qrcode/QRCodecMode.cpp index 4937b1c858..9d018d64bd 100644 --- a/core/src/qrcode/QRCodecMode.cpp +++ b/core/src/qrcode/QRCodecMode.cpp @@ -7,7 +7,7 @@ #include "QRCodecMode.h" #include "QRVersion.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include #include diff --git a/core/src/qrcode/QRDataBlock.cpp b/core/src/qrcode/QRDataBlock.cpp index 0c63a52ef5..cedd8a303a 100644 --- a/core/src/qrcode/QRDataBlock.cpp +++ b/core/src/qrcode/QRDataBlock.cpp @@ -8,7 +8,7 @@ #include "QRErrorCorrectionLevel.h" #include "QRVersion.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" namespace ZXing::QRCode { diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 7465577c79..abe44ba8c5 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -20,7 +20,7 @@ #include "ReedSolomonDecoder.h" #include "StructuredAppend.h" #include "TextDecoder.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "ZXTestSupport.h" #include diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index dc657ab667..be71b2f809 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -10,7 +10,7 @@ #include "ImageLoader.h" #include "ReadBarcode.h" #include "ThresholdBinarizer.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "pdf417/PDFReader.h" #include "qrcode/QRReader.h" diff --git a/test/blackbox/TestReaderMain.cpp b/test/blackbox/TestReaderMain.cpp index 22691a6864..31f9063092 100644 --- a/test/blackbox/TestReaderMain.cpp +++ b/test/blackbox/TestReaderMain.cpp @@ -7,7 +7,7 @@ #include "BlackboxTestRunner.h" #include "ImageLoader.h" #include "ReadBarcode.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "ZXFilesystem.h" #include diff --git a/test/unit/datamatrix/DMHighLevelEncodeTest.cpp b/test/unit/datamatrix/DMHighLevelEncodeTest.cpp index 3c0d437e53..5a8a57ef6e 100644 --- a/test/unit/datamatrix/DMHighLevelEncodeTest.cpp +++ b/test/unit/datamatrix/DMHighLevelEncodeTest.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "ByteArray.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "datamatrix/DMHighLevelEncoder.h" #include "datamatrix/DMSymbolInfo.h" #include "datamatrix/DMSymbolShape.h" diff --git a/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp b/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp index 763d9e4dbf..b7def50056 100644 --- a/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp +++ b/test/unit/pdf417/PDF417ErrorCorrectionTest.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "PseudoRandom.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" #include "gtest/gtest.h" diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index e4997020c3..1685777336 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -11,7 +11,7 @@ // Reader #include "ReadBarcode.h" -#include "ZXContainerAlgorithms.h" +#include "ZXAlgorithms.h" // Writer #include "BitMatrix.h" From 76828972cb7bef59c2bc3a5060fdac7ff0554dc4 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 09:41:21 +0200 Subject: [PATCH 0363/1315] Result: minimize additions of new text related API Don't add new API until the debate in https://github.com/nu-book/zxing-cpp/issues/338#issuecomment-1174741554 has settled. --- core/src/Result.cpp | 2 ++ core/src/Result.h | 20 +++++++++++--------- example/ZXingReader.cpp | 1 - test/blackbox/BlackboxTestRunner.cpp | 2 +- test/unit/oned/ODCodaBarWriterTest.cpp | 2 +- test/unit/oned/ODCode128ReaderTest.cpp | 18 +++++++++--------- test/unit/oned/ODCode128WriterTest.cpp | 8 ++++---- test/unit/oned/ODCode39ExtendedModeTest.cpp | 2 +- test/unit/oned/ODCode39ReaderTest.cpp | 14 +++++++------- test/unit/oned/ODCode93ReaderTest.cpp | 2 +- wrappers/winrt/BarcodeReader.cpp | 11 +++-------- 11 files changed, 40 insertions(+), 42 deletions(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 00d70ae6aa..3ce1d103c7 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -77,10 +77,12 @@ std::wstring Result::utf16() const return _content.utf16(); } +#if 0 std::string Result::utf8ECI() const { return _content.text(TextMode::Utf8ECI); } +#endif ContentType Result::contentType() const { diff --git a/core/src/Result.h b/core/src/Result.h index 5469a0370f..1d60013f50 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -29,6 +29,15 @@ using Position = QuadrilateralI; */ class Result { + /** + * @brief utf8/utf16 is the bytes() content converted to utf8/16 based on ECI or guessed character set information + * + * Note: these two properties might only be available while transitioning text() from std::wstring to std::string. time will tell. + * see https://github.com/nu-book/zxing-cpp/issues/338 for a background discussion on the issue. + */ + std::string utf8() const; + std::wstring utf16() const; + public: Result() = default; @@ -56,15 +65,6 @@ class Result */ ByteArray bytesECI() const; - /** - * @brief utf8/utf16 is the bytes() content converted to utf8/16 based on ECI or guessed character set information - * - * Note: these two properties might only be available while transitioning text() from std::wstring to std::string. time will tell. - * see https://github.com/nu-book/zxing-cpp/issues/338 for a background discussion on the issue. - */ - std::string utf8() const; - std::wstring utf16() const; - #ifdef ZX_USE_UTF8 std::string text() const { return utf8(); } std::string ecLevel() const { return _ecLevel; } @@ -75,10 +75,12 @@ class Result std::wstring ecLevel() const { return {_ecLevel.begin(), _ecLevel.end()}; } #endif +#if 0 // disabled until final API decission is made /** * @brief utf8ECI is the standard content following the ECI protocol with every character set ECI segment transcoded to utf8 */ std::string utf8ECI() const; +#endif /** * @brief contentType gives a hint to the type of content found (Text/Binary/GS1/etc.) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 9ef814f7f9..163cf39858 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -206,7 +206,6 @@ int main(int argc, char* argv[]) } std::cout << "Text: \"" << (angleEscape ? escapeNonGraphical(result.text()) : result.text()) << "\"\n" - << "Utf8ECI: \"" << result.utf8ECI() << "\"\n" << "Bytes: " << ToHex(result.bytes()) << "\n" << "BytesECI: " << ToHex(result.bytesECI()) << "\n" << "Format: " << ToString(result.format()) << "\n" diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index be71b2f809..aec499faa4 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -136,7 +136,7 @@ static std::string checkResult(const fs::path& imgPath, std::string_view expecte } if (auto expected = readFile(".txt")) { - auto utf8Result = result.utf8(); + auto utf8Result = result.text(); return utf8Result != *expected ? fmt::format("Content mismatch: expected '{}' but got '{}'", *expected, utf8Result) : ""; } diff --git a/test/unit/oned/ODCodaBarWriterTest.cpp b/test/unit/oned/ODCodaBarWriterTest.cpp index 7294b5a942..9ae038db5e 100644 --- a/test/unit/oned/ODCodaBarWriterTest.cpp +++ b/test/unit/oned/ODCodaBarWriterTest.cpp @@ -55,7 +55,7 @@ TEST(ODCodaBarWriterTest, FullCircle) CodabarWriter().encode(text, 0, 0).getRow(0, row); auto hints = DecodeHints().setReturnCodabarStartEnd(true); Result res = CodabarReader(hints).decodeSingleRow(0, row); - EXPECT_EQ(text, res.utf8()); + EXPECT_EQ(text, res.text()); } TEST(ODCodaBarWriterTest, InvalidChars) diff --git a/test/unit/oned/ODCode128ReaderTest.cpp b/test/unit/oned/ODCode128ReaderTest.cpp index 530da630b7..7f3ad3e30d 100644 --- a/test/unit/oned/ODCode128ReaderTest.cpp +++ b/test/unit/oned/ODCode128ReaderTest.cpp @@ -39,7 +39,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 2, 1, 2, 3, 1, 2, 2, 2, 1, 2, 2, 3, 1, 1, 2, 2, 2 }); auto result = parse('C', row); EXPECT_EQ(result.symbologyIdentifier(), "]C0"); - EXPECT_EQ(result.utf8(), "2001"); + EXPECT_EQ(result.text(), "2001"); } { @@ -47,7 +47,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 4, 1, 1, 1, 3, 1, 2, 2, 1, 2, 3, 1, 2, 2, 2, 1, 2, 2, 1, 3, 2, 1, 3, 1 }); auto result = parse('C', row); EXPECT_EQ(result.symbologyIdentifier(), "]C1"); - EXPECT_EQ(result.utf8(), "2001"); + EXPECT_EQ(result.text(), "2001"); } { @@ -55,7 +55,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 1, 1, 1, 3, 2, 3, 4, 1, 1, 1, 3, 1, 1, 3, 1, 1, 2, 3, 2, 1, 2, 3, 2, 1 }); auto result = parse('B', row); EXPECT_EQ(result.symbologyIdentifier(), "]C2"); - EXPECT_EQ(result.utf8(), "AB"); + EXPECT_EQ(result.text(), "AB"); } { @@ -63,7 +63,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 1, 4, 1, 2, 1, 4, 1, 1, 1, 3, 1, 1, 3, 1, 1, 2, 3, 4, 2, 1, 2, 1, 1 }); auto result = parse('B', row); EXPECT_EQ(result.symbologyIdentifier(), "]C2"); - EXPECT_EQ(result.utf8(), "zB"); + EXPECT_EQ(result.text(), "zB"); } { @@ -71,7 +71,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 1, 1, 3, 1, 4, 1, 4, 1, 1, 1, 3, 1, 1, 1, 4, 1, 3, 1, 1, 1, 1, 3, 2, 3, 1, 2, 3, 1, 2, 2 }); auto result = parse('C', row); EXPECT_EQ(result.symbologyIdentifier(), "]C2"); - EXPECT_EQ(result.utf8(), "99A"); + EXPECT_EQ(result.text(), "99A"); } { @@ -79,7 +79,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 1, 2, 3, 2, 1, 4, 1, 1, 1, 3, 1, 1, 3, 1, 1, 2, 3, 3, 2, 2, 2, 1, 1 }); auto result = parse('B', row); EXPECT_EQ(result.symbologyIdentifier(), "]C0"); // Just ignoring, not giving FormatError - EXPECT_EQ(result.utf8(), "?\u001DB"); + EXPECT_EQ(result.text(), "?\u001DB"); } } @@ -90,7 +90,7 @@ TEST(ODCode128ReaderTest, ReaderInit) PatternRow row({ 1, 1, 1, 1, 4, 3, 1, 3, 1, 1, 4, 1 }); auto result = parse('C', row); EXPECT_FALSE(result.readerInit()); - EXPECT_EQ(result.utf8(), "92"); + EXPECT_EQ(result.text(), "92"); } { @@ -98,7 +98,7 @@ TEST(ODCode128ReaderTest, ReaderInit) PatternRow row({ 1, 1, 4, 3, 1, 1, 1, 1, 3, 1, 4, 1, 1, 1, 1, 1, 4, 3, 3, 3, 1, 1, 2, 1 }); auto result = parse('B', row); EXPECT_TRUE(result.readerInit()); - EXPECT_EQ(result.utf8(), "92"); + EXPECT_EQ(result.text(), "92"); } { @@ -106,6 +106,6 @@ TEST(ODCode128ReaderTest, ReaderInit) PatternRow row({ 3, 2, 1, 1, 2, 2, 1, 1, 4, 3, 1, 1, 2, 2, 3, 2, 1, 1, 1, 2, 1, 4, 2, 1 }); auto result = parse('B', row); EXPECT_TRUE(result.readerInit()); - EXPECT_EQ(result.utf8(), "92"); + EXPECT_EQ(result.text(), "92"); } } diff --git a/test/unit/oned/ODCode128WriterTest.cpp b/test/unit/oned/ODCode128WriterTest.cpp index a524164a5a..bc9db158be 100644 --- a/test/unit/oned/ODCode128WriterTest.cpp +++ b/test/unit/oned/ODCode128WriterTest.cpp @@ -98,7 +98,7 @@ TEST(ODCode128Writer, RoundtripGS1) auto encResult = Code128Writer().encode(toEncode, 0, 0); auto decResult = Decode(encResult); - auto actual = decResult.utf8(); + auto actual = decResult.text(); EXPECT_EQ(actual, expected); EXPECT_EQ(decResult.symbologyIdentifier(), "]C1"); } @@ -110,7 +110,7 @@ TEST(ODCode128Writer, RoundtripFNC1) auto encResult = Code128Writer().encode(toEncode, 0, 0); auto decResult = Decode(encResult); - auto actual = decResult.utf8(); + auto actual = decResult.text(); EXPECT_EQ(actual, expected); EXPECT_EQ(decResult.symbologyIdentifier(), "]C0"); } @@ -126,7 +126,7 @@ TEST(ODCode128Writer, EncodeSwitchCodesetFromAToB) auto actual = LineMatrixToString(encoded); EXPECT_EQ(actual, expected); - auto actualRoundTrip = Decode(encoded).utf8(); + auto actualRoundTrip = Decode(encoded).text(); EXPECT_EQ(actualRoundTrip, toEncode); } @@ -141,6 +141,6 @@ TEST(ODCode128Writer, EncodeSwitchCodesetFromBToA) auto actual = LineMatrixToString(encoded); EXPECT_EQ(actual, expected); - auto actualRoundTrip = Decode(encoded).utf8(); + auto actualRoundTrip = Decode(encoded).text(); EXPECT_EQ(actualRoundTrip, toEncode); } diff --git a/test/unit/oned/ODCode39ExtendedModeTest.cpp b/test/unit/oned/ODCode39ExtendedModeTest.cpp index cbf307d3ba..d25d7a6205 100644 --- a/test/unit/oned/ODCode39ExtendedModeTest.cpp +++ b/test/unit/oned/ODCode39ExtendedModeTest.cpp @@ -21,7 +21,7 @@ static std::string Decode(std::string_view encoded) Code39Reader sut(hints); BitArray row = Utility::ParseBitArray(encoded, '1'); Result result = sut.decodeSingleRow(0, row); - return result.utf8(); + return result.text(); } TEST(ODCode39ExtendedModeTest, Decode) diff --git a/test/unit/oned/ODCode39ReaderTest.cpp b/test/unit/oned/ODCode39ReaderTest.cpp index 893c2a008c..e33f587a0c 100644 --- a/test/unit/oned/ODCode39ReaderTest.cpp +++ b/test/unit/oned/ODCode39ReaderTest.cpp @@ -33,39 +33,39 @@ TEST(ODCode39ReaderTest, SymbologyIdentifier) PatternRow row({ 2, 1, 1, 1, 1, 2, 1, 1, 2 }); auto result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.utf8(), "A"); + EXPECT_EQ(result.text(), "A"); } { // "A" with checksum PatternRow row({ 2, 1, 1, 1, 1, 2, 1, 1, 2, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2 }); auto result = parse(row, DecodeHints().setValidateCode39CheckSum(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A3"); - EXPECT_EQ(result.utf8(), "A"); + EXPECT_EQ(result.text(), "A"); result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.utf8(), "AA"); + EXPECT_EQ(result.text(), "AA"); } { // Extended "a" PatternRow row({ 1, 2, 1, 1, 1, 2, 1, 2, 1, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2 }); auto result = parse(row, DecodeHints().setTryCode39ExtendedMode(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A4"); - EXPECT_EQ(result.utf8(), "a"); + EXPECT_EQ(result.text(), "a"); result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.utf8(), "+A"); + EXPECT_EQ(result.text(), "+A"); } { // Extended "a" with checksum PatternRow row({ 1, 2, 1, 1, 1, 2, 1, 2, 1, 0, 2, 1, 1, 1, 1, 2, 1, 1, 2, 0, 2, 1, 1, 2, 1, 1, 2, 1, 1 }); auto result = parse(row, DecodeHints().setTryCode39ExtendedMode(true).setValidateCode39CheckSum(true)); EXPECT_EQ(result.symbologyIdentifier(), "]A7"); - EXPECT_EQ(result.utf8(), "a"); + EXPECT_EQ(result.text(), "a"); result = parse(row); EXPECT_EQ(result.symbologyIdentifier(), "]A0"); - EXPECT_EQ(result.utf8(), "+A8"); + EXPECT_EQ(result.text(), "+A8"); } } diff --git a/test/unit/oned/ODCode93ReaderTest.cpp b/test/unit/oned/ODCode93ReaderTest.cpp index f11a70ec79..93d7557e3b 100644 --- a/test/unit/oned/ODCode93ReaderTest.cpp +++ b/test/unit/oned/ODCode93ReaderTest.cpp @@ -21,7 +21,7 @@ static std::string Decode(std::string_view input) Code93Reader sut(hints); auto row = Utility::ParseBitArray(input, '1'); auto result = sut.decodeSingleRow(0, row); - return result.utf8(); + return result.text(); } TEST(ODCode93ReaderTest, Decode) diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index 5d3360985e..7855bcd10f 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -149,15 +149,10 @@ BarcodeType BarcodeReader::ConvertNativeToRuntime(BarcodeFormat format) } } -static Platform::String^ ToPlatformString(const std::wstring& str) -{ - return ref new Platform::String(str.c_str(), (unsigned)str.length()); -} - static Platform::String^ ToPlatformString(const std::string& str) { - auto ptr = (const uint8_t*)str.data(); - return ToPlatformString(std::wstring(ptr, ptr + str.length())); + std::wstring wstr = TextUtfEncoding::FromUtf8(str); + return ref new Platform::String(wstr.c_str(), (unsigned)wstr.length()); } ReadResult^ @@ -193,7 +188,7 @@ BarcodeReader::Read(SoftwareBitmap^ bitmap, int cropWidth, int cropHeight) auto result = ReadBarcode(img, *m_hints); if (result.isValid()) { - return ref new ReadResult(ToPlatformString(ZXing::ToString(result.format())), ToPlatformString(result.utf16()), ConvertNativeToRuntime(result.format())); + return ref new ReadResult(ToPlatformString(ZXing::ToString(result.format())), ToPlatformString(result.text()), ConvertNativeToRuntime(result.format())); } } else { throw std::runtime_error("Failed to read bitmap's data"); From 4fe52f2f791c7f81c43f8eb0b1ca11c9d70772d6 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 09:51:14 +0200 Subject: [PATCH 0364/1315] WINRT: replace usage of deprecated BarcodeFormat enum names --- wrappers/winrt/BarcodeReader.cpp | 60 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index 7855bcd10f..84303c6a64 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -68,39 +68,39 @@ BarcodeFormat BarcodeReader::ConvertRuntimeToNative(BarcodeType type) { switch (type) { case BarcodeType::AZTEC: - return BarcodeFormat::AZTEC; + return BarcodeFormat::Aztec; case BarcodeType::CODABAR: - return BarcodeFormat::CODABAR; + return BarcodeFormat::Codabar; case BarcodeType::CODE_128: - return BarcodeFormat::CODE_128; + return BarcodeFormat::Code128; case BarcodeType::CODE_39: - return BarcodeFormat::CODE_39; + return BarcodeFormat::Code39; case BarcodeType::CODE_93: - return BarcodeFormat::CODE_93; + return BarcodeFormat::Code93; case BarcodeType::DATA_MATRIX: - return BarcodeFormat::DATA_MATRIX; + return BarcodeFormat::DataMatrix; case BarcodeType::EAN_13: - return BarcodeFormat::EAN_13; + return BarcodeFormat::EAN13; case BarcodeType::EAN_8: - return BarcodeFormat::EAN_8; + return BarcodeFormat::EAN8; case BarcodeType::ITF: return BarcodeFormat::ITF; case BarcodeType::MAXICODE: - return BarcodeFormat::MAXICODE; + return BarcodeFormat::MaxiCode; case BarcodeType::PDF_417: - return BarcodeFormat::PDF_417; + return BarcodeFormat::PDF417; case BarcodeType::QR_CODE: - return BarcodeFormat::QR_CODE; + return BarcodeFormat::QRCode; case BarcodeType::MICRO_QR_CODE: return BarcodeFormat::MicroQRCode; case BarcodeType::RSS_14: - return BarcodeFormat::RSS_14; + return BarcodeFormat::DataBar; case BarcodeType::RSS_EXPANDED: - return BarcodeFormat::RSS_EXPANDED; + return BarcodeFormat::DataBarExpanded; case BarcodeType::UPC_A: - return BarcodeFormat::UPC_A; + return BarcodeFormat::UPCA; case BarcodeType::UPC_E: - return BarcodeFormat::UPC_E; + return BarcodeFormat::UPCE; default: std::wstring typeAsString = type.ToString()->Begin(); throw std::invalid_argument("Unknown Barcode Type: " + TextUtfEncoding::ToUtf8(typeAsString)); @@ -110,39 +110,39 @@ BarcodeFormat BarcodeReader::ConvertRuntimeToNative(BarcodeType type) BarcodeType BarcodeReader::ConvertNativeToRuntime(BarcodeFormat format) { switch (format) { - case BarcodeFormat::AZTEC: + case BarcodeFormat::Aztec: return BarcodeType::AZTEC; - case BarcodeFormat::CODABAR: + case BarcodeFormat::Codabar: return BarcodeType::CODABAR; - case BarcodeFormat::CODE_128: + case BarcodeFormat::Code128: return BarcodeType::CODE_128; - case BarcodeFormat::CODE_39: + case BarcodeFormat::Code39: return BarcodeType::CODE_39; - case BarcodeFormat::CODE_93: + case BarcodeFormat::Code93: return BarcodeType::CODE_93; - case BarcodeFormat::DATA_MATRIX: + case BarcodeFormat::DataMatrix: return BarcodeType::DATA_MATRIX; - case BarcodeFormat::EAN_13: + case BarcodeFormat::EAN13: return BarcodeType::EAN_13; - case BarcodeFormat::EAN_8: + case BarcodeFormat::EAN8: return BarcodeType::EAN_8; case BarcodeFormat::ITF: return BarcodeType::ITF; - case BarcodeFormat::MAXICODE: + case BarcodeFormat::MaxiCode: return BarcodeType::MAXICODE; - case BarcodeFormat::PDF_417: + case BarcodeFormat::PDF417: return BarcodeType::PDF_417; - case BarcodeFormat::QR_CODE: + case BarcodeFormat::QRCode: return BarcodeType::QR_CODE; case BarcodeFormat::MicroQRCode: return BarcodeType::MICRO_QR_CODE; - case BarcodeFormat::RSS_14: + case BarcodeFormat::DataBar: return BarcodeType::RSS_14; - case BarcodeFormat::RSS_EXPANDED: + case BarcodeFormat::DataBarExpanded: return BarcodeType::RSS_EXPANDED; - case BarcodeFormat::UPC_A: + case BarcodeFormat::UPCA: return BarcodeType::UPC_A; - case BarcodeFormat::UPC_E: + case BarcodeFormat::UPCE: return BarcodeType::UPC_E; default: throw std::invalid_argument("Unknown Barcode Format "); From f89db69e34543c508f80e807535dab3012eea7ad Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 10:59:58 +0200 Subject: [PATCH 0365/1315] release: bump version number from 1.3.0 to 1.4.0 --- CMakeLists.txt | 2 +- wrappers/python/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50e2702c03..e947ce8dbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.14) -project (ZXing VERSION "1.3.0" LANGUAGES CXX) +project (ZXing VERSION "1.4.0" LANGUAGES CXX) option (BUILD_WRITERS "Build with writer support (encoders)" ON) option (BUILD_READERS "Build with reader support (decoders)" ON) diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index 873767a51d..eb47198d46 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -59,7 +59,7 @@ def build_extension(self, ext): # "local_scheme": "no-local-version", # "tag_regex": "v?([0-9]+.[0-9]+.[0-9]+)", # }, - version='1.3.0', + version='1.4.0', description='Python bindings for the zxing-cpp barcode library', long_description=long_description, long_description_content_type="text/markdown", From d81d016f1ea8f305b17a0060a08a4bd0ce12b0fa Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 13:34:06 +0200 Subject: [PATCH 0366/1315] LogMatrix: don't crash when using uninitialized log --- core/src/LogMatrix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/LogMatrix.h b/core/src/LogMatrix.h index 4633a3ef7d..a1e5728d94 100644 --- a/core/src/LogMatrix.h +++ b/core/src/LogMatrix.h @@ -64,7 +64,7 @@ class LogMatrix template void operator()(const PointT& p, int color = 1) { - if (_image->isIn(p)) + if (_image && _image->isIn(p)) _log.set(static_cast(p.x * _scale), static_cast(p.y * _scale), color); } From 8de4b9d280adbe2c3205b74a99dfe0eed83bc60d Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 13:49:38 +0200 Subject: [PATCH 0367/1315] DataMatrix: fix remaining issue in new c++20 multi-symbol detection Need to keep scanning in the same line after yielding a found symbol. --- core/src/datamatrix/DMDetector.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 47078d6986..1a5d2e6b16 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -630,7 +630,7 @@ class EdgeTracer : public BitMatrixCursorF } }; -static DetectorResult Scan(EdgeTracer startTracer, std::array& lines) +static DetectorResult Scan(EdgeTracer& startTracer, std::array& lines) { while (startTracer.step()) { log(startTracer.p); @@ -803,22 +803,23 @@ static DetectorResults DetectNew(const BitMatrix& image, bool tryHarder, bool tr auto center = PointF(image.width() / 2, image.height() / 2); auto startPos = centered(center - center * dir + minSymbolSize / 2 * dir); - EdgeTracer tracer(image, startPos, dir); - if (tryHarder) { - tracer.history = &history; - history.clear(); - } + history.clear(); for (int i = 1;; ++i) { - tracer.p = startPos + i / 2 * minSymbolSize * (i & 1 ? -1 : 1) * tracer.right(); + EdgeTracer tracer(image, startPos, dir); + tracer.p += i / 2 * minSymbolSize * (i & 1 ? -1 : 1) * tracer.right(); + if (tryHarder) + tracer.history = &history; if (!tracer.isIn()) break; - if (auto res = Scan(tracer, lines); res.isValid()) #ifdef __cpp_impl_coroutine + DetectorResult res; + while (res = Scan(tracer, lines), res.isValid()) co_yield std::move(res); #else + if (auto res = Scan(tracer, lines); res.isValid()) return res; #endif From 70346d0e9d2ae118e7ecfe6d136c29d2b2b33ab8 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 15:13:46 +0200 Subject: [PATCH 0368/1315] [[deprecated]]: remove all deprecated API and code --- core/CMakeLists.txt | 5 --- core/src/BarcodeFormat.h | 22 +----------- core/src/CharacterSetECI.h | 28 --------------- core/src/DecodeHints.h | 13 ------- core/src/DecodeStatus.cpp | 11 ------ core/src/DecodeStatus.h | 34 ------------------- core/src/DecoderResult.h | 10 +----- core/src/Result.cpp | 18 +--------- core/src/Result.h | 10 +----- core/src/aztec/AZDecoder.cpp | 3 +- core/src/datamatrix/DMDecoder.cpp | 3 +- core/src/maxicode/MCDecoder.cpp | 3 +- core/src/oned/ODCode128Reader.cpp | 2 +- core/src/oned/ODDataBarExpandedReader.cpp | 2 +- core/src/oned/ODDataBarReader.cpp | 2 +- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 3 +- core/src/pdf417/PDFDetector.cpp | 3 +- core/src/pdf417/PDFReader.cpp | 8 ----- core/src/pdf417/PDFReader.h | 2 -- core/src/pdf417/PDFScanningDecoder.cpp | 1 - core/src/qrcode/QRDecoder.cpp | 3 +- test/unit/aztec/AZDecoderTest.cpp | 1 - test/unit/pdf417/PDF417DecoderTest.cpp | 1 - wrappers/python/zxing.cpp | 2 -- wrappers/wasm/BarcodeReader.cpp | 4 --- 25 files changed, 13 insertions(+), 181 deletions(-) delete mode 100644 core/src/CharacterSetECI.h delete mode 100644 core/src/DecodeStatus.cpp delete mode 100644 core/src/DecodeStatus.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 7382bcae71..3093c1bba4 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -51,7 +51,6 @@ set (COMMON_FILES src/ByteMatrix.h src/CharacterSet.h src/CharacterSet.cpp - src/CharacterSetECI.h src/ConcentricFinder.h src/ConcentricFinder.cpp src/CustomData.h @@ -92,8 +91,6 @@ if (BUILD_READERS) src/Content.cpp src/DecodeHints.h src/DecodeHints.cpp - src/DecodeStatus.h - src/DecodeStatus.cpp src/DecoderResult.h src/DetectorResult.h src/Error.h @@ -144,7 +141,6 @@ set (PUBLIC_HEADERS src/BitHacks.h src/ByteArray.h src/CharacterSet.h - src/CharacterSetECI.h # deprecated src/Flags.h src/GTIN.h src/TextUtfEncoding.h @@ -155,7 +151,6 @@ if (BUILD_READERS) set (PUBLIC_HEADERS ${PUBLIC_HEADERS} src/Content.h src/DecodeHints.h - src/DecodeStatus.h src/Error.h src/ImageView.h src/Point.h diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index 01263c375a..1b973569a1 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -43,27 +43,7 @@ enum class BarcodeFormat MatrixCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode, Any = LinearCodes | MatrixCodes, - // Deprecated names, kept for compatibility at the moment - NONE [[deprecated]] = None, - AZTEC [[deprecated]] = Aztec, - CODABAR [[deprecated]] = Codabar, - CODE_39 [[deprecated]] = Code39, - CODE_93 [[deprecated]] = Code93, - CODE_128 [[deprecated]] = Code128, - DATA_MATRIX [[deprecated]] = DataMatrix, - EAN_8 [[deprecated]] = EAN8, - EAN_13 [[deprecated]] = EAN13, - MAXICODE [[deprecated]] = MaxiCode, - PDF_417 [[deprecated]] = PDF417, - QR_CODE [[deprecated]] = QRCode, - RSS_14 [[deprecated]] = DataBar, - RSS_EXPANDED [[deprecated]] = DataBarExpanded, - UPC_A [[deprecated]] = UPCA, - UPC_E [[deprecated]] = UPCE, - OneDCodes [[deprecated]] = LinearCodes, - TwoDCodes [[deprecated]] = MatrixCodes, - - _max = MicroQRCode, ///> implementation detail, don't use + _max = MicroQRCode, ///> implementation detail, don't use }; ZX_DECLARE_FLAGS(BarcodeFormats, BarcodeFormat) diff --git a/core/src/CharacterSetECI.h b/core/src/CharacterSetECI.h deleted file mode 100644 index e70f9dc3bc..0000000000 --- a/core/src/CharacterSetECI.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -* Copyright 2016 ZXing authors -*/ -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "CharacterSet.h" - -namespace ZXing { - -/** -* Encapsulates a Character Set ECI, according to AIM ITS/04-023:2004 Extended Channel Interpretations Part 3: Register -* -* @author Sean Owen -*/ -namespace CharacterSetECI { - -/** - * @param name character set ECI encoding name - * @return {@code CharacterSet} representing ECI of given value, or {@code CharacterSet::Unknown} if it is - * unsupported - */ -[[deprecated]] inline CharacterSet CharsetFromName(const char* name) { return CharacterSetFromString(name); } - -} // namespace CharacterSetECI -} // namespace ZXing diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 9668a09848..c791ae74aa 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -134,20 +134,7 @@ class DecodeHints #undef ZX_PROPERTY - /// NOTE: used to affect FNC1 handling for Code 128 (aka GS1-128) but behavior now based on position of FNC1. - [[deprecated]] bool assumeGS1() const noexcept { return true; } - [[deprecated]] DecodeHints& setAssumeGS1(bool v [[maybe_unused]]) { return *this; } - - /// NOTE: has not been in effect since at least 1.2 and no one noticed. - [[deprecated]] std::vector allowedLengths() const noexcept { return {}; } - [[deprecated]] DecodeHints& setAllowedLengths(const std::vector v [[maybe_unused]]) { return *this; } - - /// NOTE: use validateCode39CheckSum - [[deprecated]] bool assumeCode39CheckDigit() const noexcept { return validateCode39CheckSum(); } - [[deprecated]] DecodeHints& setAssumeCode39CheckDigit(bool v) & { return setValidateCode39CheckSum(v); } - bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f) || _formats.empty(); } - [[deprecated]] bool hasNoFormat() const noexcept { return _formats.empty(); } }; } // ZXing diff --git a/core/src/DecodeStatus.cpp b/core/src/DecodeStatus.cpp deleted file mode 100644 index 8abff86b2d..0000000000 --- a/core/src/DecodeStatus.cpp +++ /dev/null @@ -1,11 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -*/ -// SPDX-License-Identifier: Apache-2.0 - -#include "DecodeStatus.h" - -namespace ZXing { - - -} // ZXing diff --git a/core/src/DecodeStatus.h b/core/src/DecodeStatus.h deleted file mode 100644 index 80a52ba3c3..0000000000 --- a/core/src/DecodeStatus.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* Copyright 2016 Nu-book Inc. -*/ -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -namespace ZXing { - -enum class DecodeStatus -{ - NoError = 0, - NotFound, - FormatError, - ChecksumError, -}; - -[[deprecated]] inline bool StatusIsOK(DecodeStatus status) -{ - return status == DecodeStatus::NoError; -} - -[[deprecated]] inline bool StatusIsError(DecodeStatus status) -{ - return status != DecodeStatus::NoError; -} - -[[deprecated]] inline const char* ToString(DecodeStatus status) -{ - constexpr const char* names[] = {"NoError", "NotFound", "FormatError", "ChecksumError"}; - return names[static_cast(status)]; -} - -} // ZXing diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 2b916d0249..e701d266bc 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -22,9 +22,7 @@ class CustomData; class DecoderResult { - ByteArray _rawBytes; Content _content; - int _numBits = 0; std::string _ecLevel; int _lineCount = 0; StructuredAppendInfo _structuredAppend; @@ -39,10 +37,7 @@ class DecoderResult public: DecoderResult() = default; DecoderResult(Error error) : _error(std::move(error)) {} - DecoderResult(ByteArray&& rawBytes, Content&& bytes) : _rawBytes(std::move(rawBytes)), _content(std::move(bytes)) - { - _numBits = 8 * Size(_rawBytes); - } + DecoderResult(Content&& bytes) : _content(std::move(bytes)) {} DecoderResult(DecoderResult&&) noexcept = default; DecoderResult& operator=(DecoderResult&&) = default; @@ -52,8 +47,6 @@ class DecoderResult return _content.symbology.code != 0 && (!_error || includeErrors); } - const ByteArray& rawBytes() const & { return _rawBytes; } - ByteArray&& rawBytes() && { return std::move(_rawBytes); } const Content& content() const & { return _content; } Content&& content() && { return std::move(_content); } @@ -76,7 +69,6 @@ class DecoderResult DecoderResult&& SETTER(const TYPE& v) && { _##GETTER = v; return std::move(*this); } \ DecoderResult&& SETTER(TYPE&& v) && { _##GETTER = std::move(v); return std::move(*this); } - ZX_PROPERTY(int, numBits, setNumBits) ZX_PROPERTY(std::string, ecLevel, setEcLevel) ZX_PROPERTY(int, lineCount, setLineCount) ZX_PROPERTY(StructuredAppendInfo, structuredAppend, setStructuredAppend) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 3ce1d103c7..ae06bbf5c4 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -18,14 +18,11 @@ namespace ZXing { -Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, - ByteArray&& rawBytes, bool readerInit, const std::string& ai) +Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, bool readerInit, const std::string& ai) : _format(format), _content({ByteArray(text)}, si, ai), _error(error), _position(Line(y, xStart, xStop)), - _rawBytes(std::move(rawBytes)), - _numBits(Size(_rawBytes) * 8), _readerInit(readerInit), _lineCount(0) {} @@ -35,8 +32,6 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat _content(std::move(decodeResult).content()), _error(std::move(decodeResult).error()), _position(std::move(position)), - _rawBytes(std::move(decodeResult).rawBytes()), - _numBits(decodeResult.numBits()), _ecLevel(decodeResult.ecLevel()), _sai(decodeResult.structuredAppend()), _isMirrored(decodeResult.isMirrored()), @@ -46,17 +41,6 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } -DecodeStatus Result::status() const -{ - switch(_error.type()) { - case Error::Format : return DecodeStatus::FormatError; - case Error::Checksum : return DecodeStatus::ChecksumError; - default: ; - } - - return format() == BarcodeFormat::None ? DecodeStatus::NotFound : DecodeStatus::NoError; -} - const ByteArray& Result::bytes() const { return _content.bytes; diff --git a/core/src/Result.h b/core/src/Result.h index 1d60013f50..5d0cf306eb 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -10,7 +10,6 @@ #include "BarcodeFormat.h" #include "ByteArray.h" #include "Content.h" -#include "DecodeStatus.h" #include "Error.h" #include "Quadrilateral.h" #include "StructuredAppend.h" @@ -43,7 +42,7 @@ class Result // linear symbology convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error = {}, - ByteArray&& rawBytes = {}, bool readerInit = false, const std::string& ai = {}); + bool readerInit = false, const std::string& ai = {}); Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); @@ -51,8 +50,6 @@ class Result const Error& error() const { return _error; } - [[deprecated]] DecodeStatus status() const; - BarcodeFormat format() const { return _format; } /** @@ -105,10 +102,6 @@ class Result */ bool isMirrored() const { return _isMirrored; } - /// see bytes() above for a proper replacement of rawByes - [[deprecated]] const ByteArray& rawBytes() const { return _rawBytes; } - [[deprecated]] int numBits() const { return _numBits; } - /** * @brief symbologyIdentifier Symbology identifier "]cm" where "c" is symbology code character, "m" the modifier. */ @@ -164,7 +157,6 @@ class Result Error _error; Position _position; ByteArray _rawBytes; - int _numBits = 0; std::string _ecLevel; StructuredAppendInfo _sai; bool _isMirrored = false; diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 1a71e0022f..04dc0d6c83 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -11,7 +11,6 @@ #include "BitArray.h" #include "BitMatrix.h" #include "CharacterSet.h" -#include "DecodeStatus.h" #include "DecoderResult.h" #include "GenericGF.h" #include "ReedSolomonDecoder.h" @@ -343,7 +342,7 @@ DecoderResult Decode(const BitArray& bits) if (sai.index != -1) res.symbology.modifier += 6; // TODO: this is wrong as long as we remove the sai info from the content in ParseStructuredAppend - return DecoderResult(bits.toBytes(), std::move(res)).setNumBits(Size(bits)).setStructuredAppend(sai); + return DecoderResult(std::move(res)).setStructuredAppend(sai); } DecoderResult Decode(const DetectorResult& detectorResult) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 6c30613221..5b8cbf105d 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -12,7 +12,6 @@ #include "DMBitLayout.h" #include "DMDataBlock.h" #include "DMVersion.h" -#include "DecodeStatus.h" #include "DecoderResult.h" #include "GenericGF.h" #include "ReedSolomonDecoder.h" @@ -357,7 +356,7 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) result.applicationIndicator = result.symbology.modifier == '2' ? "GS1" : ""; result.symbology.modifier += isDMRE * 6; - return DecoderResult(std::move(bytes), std::move(result)) + return DecoderResult(std::move(result)) .setError(std::move(error)) .setStructuredAppend(sai) .setReaderInit(readerInit); diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 794409da26..2a983ca040 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -9,7 +9,6 @@ #include "ByteArray.h" #include "CharacterSet.h" #include "DecoderResult.h" -#include "DecodeStatus.h" #include "GenericGF.h" #include "MCBitMatrixParser.h" #include "ReedSolomonDecoder.h" @@ -292,7 +291,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode) case 5: GetMessage(bytes, 1, 77, result, sai); break; } - return DecoderResult(std::move(bytes), std::move(result)) + return DecoderResult(std::move(result)) .setEcLevel(std::to_string(mode)) .setStructuredAppend(sai) .setReaderInit(mode == 6); diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index 9f9f788e2f..2c2ad1c3d4 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -278,7 +278,7 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu int xStop = next.pixelsTillEnd(); return Result(raw2txt.text(), rowNumber, xStart, xStop, BarcodeFormat::Code128, raw2txt.symbologyIdentifier(), error, - std::move(rawCodes), raw2txt.readerInit(), raw2txt.applicationIndicator()); + raw2txt.readerInit(), raw2txt.applicationIndicator()); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 7565e50388..0c48723bb3 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -376,7 +376,7 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, // TODO: EstimatePosition misses part of the symbol in the stacked case where the last row contains less pairs than // the first // Symbology identifier: ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - return {DecoderResult({}, Content(ByteArray(txt), {'e', '0'})).setLineCount(EstimateLineCount(pairs.front(), pairs.back())), + return {DecoderResult(Content(ByteArray(txt), {'e', '0'})).setLineCount(EstimateLineCount(pairs.front(), pairs.back())), EstimatePosition(pairs.front(), pairs.back()), BarcodeFormat::DataBarExpanded}; } diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index aa647ffb67..5ed08e04b8 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -195,7 +195,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, for (const auto& rightPair : prevState->rightPairs) if (ChecksumIsValid(leftPair, rightPair)) { // Symbology identifier ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - Result res{DecoderResult({}, Content(ByteArray(ConstructText(leftPair, rightPair)), {'e', '0'})) + Result res{DecoderResult(Content(ByteArray(ConstructText(leftPair, rightPair)), {'e', '0'})) .setLineCount(EstimateLineCount(leftPair, rightPair)), EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar}; diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 72f8989505..4d1d68c4d7 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -9,7 +9,6 @@ #include "ByteArray.h" #include "CharacterSet.h" #include "DecoderResult.h" -#include "DecodeStatus.h" #include "PDFDecoderResultExtra.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" @@ -754,7 +753,7 @@ DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel) sai.id = resultMetadata->fileId(); } - return DecoderResult({}, std::move(result)) + return DecoderResult(std::move(result)) .setEcLevel(std::to_string(ecLevel)) .setStructuredAppend(sai) .setReaderInit(readerInit) diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 97835f13c5..78d9526e3e 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -6,7 +6,6 @@ #include "PDFDetector.h" #include "BinaryBitmap.h" -#include "DecodeStatus.h" #include "BitMatrix.h" #include "ZXNullable.h" #include "Pattern.h" @@ -335,7 +334,7 @@ bool HasStartPattern(const BitMatrix& m, bool rotate90) */ Detector::Result Detector::Detect(const BinaryBitmap& image, bool multiple, bool tryRotate) { - // construct a 'dummy' shared pointer, just be able to pass it up the call chain in DecodeStatus + // construct a 'dummy' shared pointer, just be able to pass it up the call chain in DetectorResult // TODO: reimplement PDF Detector auto binImg = std::shared_ptr(image.getBitMatrix(), [](const BitMatrix*){}); if (!binImg) diff --git a/core/src/pdf417/PDFReader.cpp b/core/src/pdf417/PDFReader.cpp index 947b21e95c..d901ce0631 100644 --- a/core/src/pdf417/PDFReader.cpp +++ b/core/src/pdf417/PDFReader.cpp @@ -16,7 +16,6 @@ #include "BitMatrixCursor.h" #include "BinaryBitmap.h" #include "BitArray.h" -#include "DecodeStatus.h" #include "Pattern.h" #include @@ -327,12 +326,5 @@ Results Reader::decode(const BinaryBitmap& image, [[maybe_unused]] int maxSymbol return DoDecode(image, true, _hints.tryRotate(), _hints.returnErrors()); } -std::list -Reader::decodeMultiple(const BinaryBitmap& image) const -{ - Results results = DoDecode(image, true, _hints.tryRotate(), _hints.returnErrors()); - return std::list(results.begin(), results.end()); -} - } // Pdf417 } // ZXing diff --git a/core/src/pdf417/PDFReader.h b/core/src/pdf417/PDFReader.h index c4d3272ee6..2a05012350 100644 --- a/core/src/pdf417/PDFReader.h +++ b/core/src/pdf417/PDFReader.h @@ -24,8 +24,6 @@ class Reader : public ZXing::Reader Result decode(const BinaryBitmap& image) const override; Results decode(const BinaryBitmap& image, int maxSymbols) const override; - - [[deprecated]] std::list decodeMultiple(const BinaryBitmap& image) const; }; } // namespace ZXing::Pdf417 diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index 895404ca1b..df0708ad07 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -16,7 +16,6 @@ #include "ResultPoint.h" #include "ZXNullable.h" #include "BitMatrix.h" -#include "DecodeStatus.h" #include "DecoderResult.h" #include "ZXTestSupport.h" diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index abe44ba8c5..d7f990c770 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -9,7 +9,6 @@ #include "BitMatrix.h" #include "BitSource.h" #include "CharacterSet.h" -#include "DecodeStatus.h" #include "DecoderResult.h" #include "GenericGF.h" #include "QRBitMatrixParser.h" @@ -332,7 +331,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo error = std::move(e); } - return DecoderResult(std::move(bytes), std::move(result)) + return DecoderResult(std::move(result)) .setError(std::move(error)) .setEcLevel(ToString(ecLevel)) .setStructuredAppend(structuredAppend); diff --git a/test/unit/aztec/AZDecoderTest.cpp b/test/unit/aztec/AZDecoderTest.cpp index 43f39c4872..c76b4cf99c 100644 --- a/test/unit/aztec/AZDecoderTest.cpp +++ b/test/unit/aztec/AZDecoderTest.cpp @@ -7,7 +7,6 @@ #include "aztec/AZDecoder.h" #include "BitArray.h" #include "BitMatrixIO.h" -#include "DecodeStatus.h" #include "DecoderResult.h" #include "aztec/AZDetectorResult.h" diff --git a/test/unit/pdf417/PDF417DecoderTest.cpp b/test/unit/pdf417/PDF417DecoderTest.cpp index c08f83ab0a..2ec267c14b 100644 --- a/test/unit/pdf417/PDF417DecoderTest.cpp +++ b/test/unit/pdf417/PDF417DecoderTest.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 #include "DecoderResult.h" -#include "DecodeStatus.h" #include "pdf417/PDFDecodedBitStreamParser.h" #include "pdf417/PDFDecoderResultExtra.h" diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 1685777336..c0c9ebaf55 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -145,8 +145,6 @@ PYBIND11_MODULE(zxingcpp, m) .value("UPCE", BarcodeFormat::UPCE) // use upper case 'NONE' because 'None' is a reserved identifier in python .value("NONE", BarcodeFormat::None) - .value("OneDCodes", BarcodeFormat::LinearCodes) // deprecated, will be removed - .value("TwoDCodes", BarcodeFormat::MatrixCodes) // deprecated, will be removed .value("LinearCodes", BarcodeFormat::LinearCodes) .value("MatrixCodes", BarcodeFormat::MatrixCodes) .export_values() diff --git a/wrappers/wasm/BarcodeReader.cpp b/wrappers/wasm/BarcodeReader.cpp index 2b9c0b46a0..6b3e8ad0af 100644 --- a/wrappers/wasm/BarcodeReader.cpp +++ b/wrappers/wasm/BarcodeReader.cpp @@ -95,8 +95,4 @@ EMSCRIPTEN_BINDINGS(BarcodeReader) function("readBarcodeFromImage", &readBarcodeFromImage); function("readBarcodeFromPixmap", &readBarcodeFromPixmap); - - // obsoletes [[deprecated]] - function("readBarcode", &readBarcodeFromImage); - function("readBarcodeFromPng", &readBarcodeFromImage); } From 65da307787a66a62985731169dc796bf5aa7d98a Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 15:23:31 +0200 Subject: [PATCH 0369/1315] fuzzer: fix the usual unnoticed compile regressions --- test/fuzz/fuzzDBEDecoder.cpp | 2 +- test/fuzz/fuzzODDecoders.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/fuzz/fuzzDBEDecoder.cpp b/test/fuzz/fuzzDBEDecoder.cpp index 292a7b9ce7..6270fff552 100644 --- a/test/fuzz/fuzzDBEDecoder.cpp +++ b/test/fuzz/fuzzDBEDecoder.cpp @@ -7,7 +7,7 @@ #include #include "BitArray.h" -#include "oned/rss/ODRSSExpandedBinaryDecoder.h" +#include "oned/ODDataBarExpandedBitDecoder.h" using namespace ZXing; diff --git a/test/fuzz/fuzzODDecoders.cpp b/test/fuzz/fuzzODDecoders.cpp index 2ffd01392d..a3d44ec84d 100644 --- a/test/fuzz/fuzzODDecoders.cpp +++ b/test/fuzz/fuzzODDecoders.cpp @@ -14,6 +14,7 @@ #include "oned/ODDataBarExpandedReader.h" #include "oned/ODITFReader.h" #include "oned/ODCodabarReader.h" +#include "DecodeHints.h" #include "Result.h" using namespace ZXing; @@ -26,8 +27,8 @@ bool init() DecodeHints hints; readers.emplace_back(new MultiUPCEANReader(hints)); readers.emplace_back(new Code39Reader(hints)); - readers.emplace_back(new Code93Reader()); - readers.emplace_back(new Code128Reader()); + readers.emplace_back(new Code93Reader(hints)); + readers.emplace_back(new Code128Reader(hints)); readers.emplace_back(new ITFReader(hints)); readers.emplace_back(new CodabarReader(hints)); readers.emplace_back(new DataBarReader(hints)); From 27a84d42f44f76cd543b85ee2332d4596694ebe4 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 15:25:31 +0200 Subject: [PATCH 0370/1315] Result: use utf8 by default (replace ZX_USE_UTF8 with ZX_USE_UTF16) Note: this ZX_USE_UTF16 might not be around in 2.0 anymore. --- core/CMakeLists.txt | 1 - core/src/Result.h | 4 +--- example/ZXingOpenCV.h | 2 -- example/ZXingQtReader.h | 2 -- example/ZXingReader.cpp | 2 -- test/blackbox/CMakeLists.txt | 1 - test/unit/CMakeLists.txt | 1 - wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt | 1 - wrappers/python/zxing.cpp | 2 -- wrappers/wasm/BarcodeReader.cpp | 2 -- wrappers/winrt/BarcodeReader.cpp | 2 -- 11 files changed, 1 insertion(+), 19 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 3093c1bba4..719c400be9 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -19,7 +19,6 @@ set (ZXING_CORE_LOCAL_DEFINES $<$:-DZXING_BUILD_READERS> $<$:-DZXING_BUILD_WRITERS> $<$:-DZXING_BUILD_FOR_TEST> - -DZX_USE_UTF8 # silence deprecation warning in Result.h ) if (MSVC) set (ZXING_CORE_LOCAL_DEFINES ${ZXING_CORE_LOCAL_DEFINES} diff --git a/core/src/Result.h b/core/src/Result.h index 5d0cf306eb..a547bdd233 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -62,12 +62,10 @@ class Result */ ByteArray bytesECI() const; -#ifdef ZX_USE_UTF8 +#ifndef ZX_USE_UTF16 std::string text() const { return utf8(); } std::string ecLevel() const { return _ecLevel; } #else -#pragma message( \ - "Warning: the return type of text() and ecLevel() will change to std::string. Please #define ZX_USE_UTF8 to transition before the next release.") std::wstring text() const { return utf16(); } std::wstring ecLevel() const { return {_ecLevel.begin(), _ecLevel.end()}; } #endif diff --git a/example/ZXingOpenCV.h b/example/ZXingOpenCV.h index 3987458b43..c81d0e598c 100644 --- a/example/ZXingOpenCV.h +++ b/example/ZXingOpenCV.h @@ -5,8 +5,6 @@ #pragma once -#define ZX_USE_UTF8 1 // see Result.h - #include "ReadBarcode.h" #include diff --git a/example/ZXingQtReader.h b/example/ZXingQtReader.h index a181a4b1a3..46ad47eb44 100644 --- a/example/ZXingQtReader.h +++ b/example/ZXingQtReader.h @@ -5,8 +5,6 @@ #pragma once -#define ZX_USE_UTF8 1 // see Result.h - #include "ReadBarcode.h" #include diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 163cf39858..0c82caffcb 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -4,8 +4,6 @@ */ // SPDX-License-Identifier: Apache-2.0 -#define ZX_USE_UTF8 1 // see Result.h - #include "ReadBarcode.h" #include "TextUtfEncoding.h" #include "GTIN.h" diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index 2d7d9e3036..f20f4127c7 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -15,7 +15,6 @@ if (BUILD_READERS) ZXing::ZXing fmt::fmt stb::stb $<$,$,9.0>>:stdc++fs> ) - target_compile_definitions(ReaderTest PRIVATE ZX_USE_UTF8) add_test(NAME ReaderTest COMMAND ReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/../samples) endif() diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 871bac6f76..9d3e38a4bd 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -66,6 +66,5 @@ add_executable (UnitTest target_include_directories (UnitTest PRIVATE .) target_link_libraries (UnitTest ZXing::ZXing GTest::gtest_main GTest::gmock) -target_compile_definitions(UnitTest PRIVATE ZX_USE_UTF8) add_test(NAME UnitTest COMMAND UnitTest) diff --git a/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt b/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt index 8d28b221a2..e49d0b61e5 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt +++ b/wrappers/android/zxingcpp/src/main/cpp/CMakeLists.txt @@ -12,6 +12,5 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../core ZXing EXCLUD add_library(zxing_android SHARED BarcodeReader.cpp JNIUtils.cpp) -target_compile_definitions(zxing_android PRIVATE -DZX_USE_UTF8) target_link_libraries(zxing_android PRIVATE ZXing::ZXing log jnigraphics) diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index c0c9ebaf55..cd204cde2b 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -7,8 +7,6 @@ #include "BarcodeFormat.h" -#define ZX_USE_UTF8 1 // see Result.h - // Reader #include "ReadBarcode.h" #include "ZXAlgorithms.h" diff --git a/wrappers/wasm/BarcodeReader.cpp b/wrappers/wasm/BarcodeReader.cpp index 6b3e8ad0af..c44cfca224 100644 --- a/wrappers/wasm/BarcodeReader.cpp +++ b/wrappers/wasm/BarcodeReader.cpp @@ -3,8 +3,6 @@ */ // SPDX-License-Identifier: Apache-2.0 -#define ZX_USE_UTF8 1 // see Result.h - #include "ReadBarcode.h" #include diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index 84303c6a64..0baa93d069 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -10,8 +10,6 @@ #include "BarcodeReader.h" -#define ZX_USE_UTF8 1 // silence deprecation warning in Result.h - #include "BarcodeFormat.h" #include "DecodeHints.h" #include "ReadBarcode.h" From fbc30e96e83962a029efb4f5d4846e07096257cb Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 23:09:14 +0200 Subject: [PATCH 0371/1315] Content: model GS1/AIM Application Indicator as flag instead of string --- core/src/Content.cpp | 8 +++----- core/src/Content.h | 8 ++++---- core/src/Result.cpp | 4 ++-- core/src/Result.h | 2 +- core/src/aztec/AZDecoder.cpp | 7 +++---- core/src/datamatrix/DMDecoder.cpp | 2 +- core/src/oned/ODCode128Reader.cpp | 8 +++----- core/src/qrcode/QRDecoder.cpp | 6 +++--- 8 files changed, 20 insertions(+), 25 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 00ea9b3217..68f6310423 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -51,9 +51,7 @@ void Content::switchEncoding(ECI eci, bool isECI) Content::Content() {} -Content::Content(ByteArray&& bytes, SymbologyIdentifier si, std::string ai) - : bytes(std::move(bytes)), applicationIndicator(std::move(ai)), symbology(si) -{} +Content::Content(ByteArray&& bytes, SymbologyIdentifier si) : bytes(std::move(bytes)), symbology(si) {} void Content::switchEncoding(CharacterSet cs) { @@ -144,7 +142,7 @@ std::string Content::text(TextMode mode) const case TextMode::Utf8: return TextUtfEncoding::ToUtf8(render(false)); case TextMode::Utf8ECI: return TextUtfEncoding::ToUtf8(render(true)); case TextMode::HRI: - if (applicationIndicator == "GS1") + if (symbology.aiFlag == AIFlag::GS1) return HRIFromGS1(text(TextMode::Utf8)); else if (type() == ContentType::Text) return text(TextMode::Utf8); @@ -202,7 +200,7 @@ ContentType Content::type() const if (!canProcess()) return ContentType::UnknownECI; - if (applicationIndicator == "GS1") + if (symbology.aiFlag == AIFlag::GS1) return ContentType::GS1; // check for the absolut minimum of a ISO 15434 conforming message ("[)>" + RS + digit + digit) diff --git a/core/src/Content.h b/core/src/Content.h index d330ca1312..6bdda3dc78 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -17,13 +17,14 @@ enum class CharacterSet; enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; enum class TextMode { Utf8, Utf8ECI, HRI, Hex, Escaped }; +enum class AIFlag : char { None, GS1, AIM }; std::string ToString(ContentType type); struct SymbologyIdentifier { - char code = 0, modifier = 0; - int eciModifierOffset = 0; + char code = 0, modifier = 0, eciModifierOffset = 0; + AIFlag aiFlag = AIFlag::None; std::string toString(bool hasECI = false) const { @@ -49,12 +50,11 @@ class Content ByteArray bytes; std::vector encodings; std::string defaultCharset; - std::string applicationIndicator; SymbologyIdentifier symbology; bool hasECI = false; Content(); - Content(ByteArray&& bytes, SymbologyIdentifier si, std::string ai = {}); + Content(ByteArray&& bytes, SymbologyIdentifier si); void switchEncoding(ECI eci) { switchEncoding(eci, true); } void switchEncoding(CharacterSet cs); diff --git a/core/src/Result.cpp b/core/src/Result.cpp index ae06bbf5c4..9e097db2b5 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -18,9 +18,9 @@ namespace ZXing { -Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, bool readerInit, const std::string& ai) +Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, bool readerInit) : _format(format), - _content({ByteArray(text)}, si, ai), + _content({ByteArray(text)}, si), _error(error), _position(Line(y, xStart, xStop)), _readerInit(readerInit), diff --git a/core/src/Result.h b/core/src/Result.h index a547bdd233..77247f65f4 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -42,7 +42,7 @@ class Result // linear symbology convenience constructor Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error = {}, - bool readerInit = false, const std::string& ai = {}); + bool readerInit = false); Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index 04dc0d6c83..d96e01bd95 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -322,19 +322,18 @@ DecoderResult Decode(const BitArray& bits) // modifiers that indicate ECI protocol (ISO/IEC 24778:2008 Annex F Table F.1) if (res.bytes[0] == 29) { res.symbology.modifier = '1'; // GS1 - res.applicationIndicator = "GS1"; + res.symbology.aiFlag = AIFlag::GS1; res.erase(0, 1); // Remove FNC1 } else if (res.bytes.size() > 2 && std::isupper(res.bytes[0]) && res.bytes[1] == 29) { // FNC1 following single uppercase letter (the AIM Application Indicator) res.symbology.modifier = '2'; // AIM - // TODO: remove the AI from the content? - res.applicationIndicator = res.bytes.asString(0, 1); + res.symbology.aiFlag = AIFlag::AIM; res.erase(1, 1); // Remove FNC1, // The AIM Application Indicator character "A"-"Z" is left in the stream (ISO/IEC 24778:2008 16.2) } else if (res.bytes.size() > 3 && std::isdigit(res.bytes[0]) && std::isdigit(res.bytes[1]) && res.bytes[2] == 29) { // FNC1 following 2 digits (the AIM Application Indicator) res.symbology.modifier = '2'; // AIM - res.applicationIndicator = res.bytes.asString(0, 2); + res.symbology.aiFlag = AIFlag::AIM; res.erase(2, 1); // Remove FNC1 // The AIM Application Indicator characters "00"-"99" are left in the stream (ISO/IEC 24778:2008 16.2) } diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 5b8cbf105d..be879b54f1 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -353,7 +353,7 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) } result.append(resultTrailer); - result.applicationIndicator = result.symbology.modifier == '2' ? "GS1" : ""; + result.symbology.aiFlag = result.symbology.modifier == '2' ? AIFlag::GS1 : AIFlag::None; result.symbology.modifier += isDMRE * 6; return DecoderResult(std::move(result)) diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index 2c2ad1c3d4..e29703e3b2 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -43,7 +43,6 @@ class Raw2TxtDecoder int codeSet = 0; SymbologyIdentifier _symbologyIdentifier = {'C', '0'}; // ISO/IEC 15417:2007 Annex C Table C.1 bool _readerInit = false; - std::string _applicationIndicator; std::string txt; size_t lastTxtSize = 0; @@ -60,7 +59,7 @@ class Raw2TxtDecoder // GS1 General Specifications Section 5.4.6.4 // "Transmitted data ... is prefixed by the symbology identifier ]C1, if used." // Choosing not to use symbology identifier, i.e. to not prefix to data. - _applicationIndicator = "GS1"; + _symbologyIdentifier.aiFlag = AIFlag::GS1; } else if ((isCodeSetC && txt.size() == 2 && txt[0] >= '0' && txt[0] <= '9' && txt[1] >= '0' && txt[1] <= '9') || (!isCodeSetC && txt.size() == 1 && ((txt[0] >= 'A' && txt[0] <= 'Z') @@ -68,7 +67,7 @@ class Raw2TxtDecoder // ISO/IEC 15417:2007 Annex B.2 // FNC1 in second position following Code Set C "00-99" or Code Set A/B "A-Za-z" - AIM _symbologyIdentifier.modifier = '2'; - _applicationIndicator = txt; + _symbologyIdentifier.aiFlag = AIFlag::AIM; } else { // ISO/IEC 15417:2007 Annex B.3. Otherwise FNC1 is returned as ASCII 29 (GS) @@ -157,7 +156,6 @@ class Raw2TxtDecoder } SymbologyIdentifier symbologyIdentifier() const { return _symbologyIdentifier; } - std::string applicationIndicator() const { return _applicationIndicator; } bool readerInit() const { return _readerInit; } }; @@ -278,7 +276,7 @@ Result Code128Reader::decodePattern(int rowNumber, PatternView& next, std::uniqu int xStop = next.pixelsTillEnd(); return Result(raw2txt.text(), rowNumber, xStart, xStop, BarcodeFormat::Code128, raw2txt.symbologyIdentifier(), error, - raw2txt.readerInit(), raw2txt.applicationIndicator()); + raw2txt.readerInit()); } } // namespace ZXing::OneD diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index d7f990c770..214583be5b 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -146,7 +146,7 @@ static void DecodeAlphanumericSegment(BitSource& bits, int count, Content& resul buffer += ToAlphaNumericChar(bits.readBits(6)); } // See section 6.4.8.1, 6.4.8.2 - if (!result.applicationIndicator.empty()) { + if (result.symbology.aiFlag != AIFlag::None) { // We need to massage the result a bit if in an FNC1 mode: for (size_t i = 0; i < buffer.length(); i++) { if (buffer[i] == '%') { @@ -275,7 +275,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo // if (!result.empty()) // uncomment to enforce specification // throw FormatError("GS1 Indicator (FNC1 in first position) at illegal position"); result.symbology.modifier = '3'; - result.applicationIndicator = "GS1"; // In Alphanumeric mode undouble doubled percents and treat single percent as + result.symbology.aiFlag = AIFlag::GS1; // In Alphanumeric mode undouble doubled '%' and treat single '%' as break; case CodecMode::FNC1_SECOND_POSITION: if (!result.empty()) @@ -290,7 +290,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo result += narrow_cast(appInd - 100); else throw FormatError("Invalid AIM Application Indicator"); - result.applicationIndicator = result.bytes.asString(); // see also above + result.symbology.aiFlag = AIFlag::AIM; // see also above break; case CodecMode::STRUCTURED_APPEND: // sequence number and parity is added later to the result metadata From c219d9e57a2ab93af1897394c1ad4038cb771251 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 23:20:32 +0200 Subject: [PATCH 0372/1315] example: compile with mandatory c++17 mode, prepare std::string_view usage --- example/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 36d663a67f..dbd96f7d90 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,6 +1,3 @@ -#show that it is possible to use the library (in its simples form) with a c++-11 compiler -set (CMAKE_CXX_STANDARD 11) - zxing_add_package_stb() include (GNUInstallDirs) From 28ce7fd5c6d114baa892448850b2c3b82df9e3ca Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 23:27:06 +0200 Subject: [PATCH 0373/1315] DecodeHints: store `characterSet` as enum instead of string Reduces size from 32 to 4 bytes for this info. Add convenience/compatibility `setCharacterSet(std::string_view)` setter. --- core/src/CharacterSet.cpp | 13 ++++++++++--- core/src/CharacterSet.h | 5 +++-- core/src/Content.cpp | 2 +- core/src/Content.h | 4 ++-- core/src/DecodeHints.h | 13 ++++++++----- core/src/Result.cpp | 4 ++-- core/src/Result.h | 2 +- core/src/maxicode/MCDecoder.cpp | 2 +- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 4 ++-- 9 files changed, 30 insertions(+), 19 deletions(-) diff --git a/core/src/CharacterSet.cpp b/core/src/CharacterSet.cpp index 4c0c17bb16..7d985204c2 100644 --- a/core/src/CharacterSet.cpp +++ b/core/src/CharacterSet.cpp @@ -14,7 +14,7 @@ namespace ZXing { struct CharacterSetName { - const char* name; + std::string_view name; CharacterSet cs; }; @@ -60,17 +60,24 @@ static CharacterSetName NAME_TO_CHARSET[] = { {"BINARY", CharacterSet::BINARY}, }; -static std::string NormalizeName(std::string str) +static std::string NormalizeName(std::string_view sv) { + std::string str(sv); std::transform(str.begin(), str.end(), str.begin(), [](char c) { return (char)std::tolower(c); }); str.erase(std::remove_if(str.begin(), str.end(), [](char c) { return Contains("_-[] ", c); }), str.end()); return str; } -CharacterSet CharacterSetFromString(const std::string& name) +CharacterSet CharacterSetFromString(std::string_view name) { auto i = FindIf(NAME_TO_CHARSET, [str = NormalizeName(name)](auto& v) { return NormalizeName(v.name) == str; }); return i == std::end(NAME_TO_CHARSET) ? CharacterSet::Unknown : i->cs; } +std::string_view ToString(CharacterSet cs) +{ + auto i = FindIf(NAME_TO_CHARSET, [cs](auto& v) { return v.cs == cs; }); + return i == std::end(NAME_TO_CHARSET) ? "" : i->name; +} + } // namespace ZXing diff --git a/core/src/CharacterSet.h b/core/src/CharacterSet.h index b26f4b23f2..acd41fc9b4 100644 --- a/core/src/CharacterSet.h +++ b/core/src/CharacterSet.h @@ -5,7 +5,7 @@ #pragma once -#include +#include namespace ZXing { @@ -48,6 +48,7 @@ enum class CharacterSet CharsetCount }; -CharacterSet CharacterSetFromString(const std::string& name); +CharacterSet CharacterSetFromString(std::string_view name); +std::string_view ToString(CharacterSet cs); } // ZXing diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 68f6310423..d8917de79c 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -100,7 +100,7 @@ std::wstring Content::render(bool withECI) const if (withECI) res = TextDecoder::FromLatin1(symbology.toString(true)); ECI lastECI = ECI::Unknown; - auto fallbackCS = CharacterSetFromString(defaultCharset); + auto fallbackCS = defaultCharset; if (!hasECI && fallbackCS == CharacterSet::Unknown) fallbackCS = guessEncoding(); diff --git a/core/src/Content.h b/core/src/Content.h index 6bdda3dc78..6146eda3c3 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -6,6 +6,7 @@ #pragma once #include "ByteArray.h" +#include "CharacterSet.h" #include #include @@ -13,7 +14,6 @@ namespace ZXing { enum class ECI : int; -enum class CharacterSet; enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; enum class TextMode { Utf8, Utf8ECI, HRI, Hex, Escaped }; @@ -49,8 +49,8 @@ class Content ByteArray bytes; std::vector encodings; - std::string defaultCharset; SymbologyIdentifier symbology; + CharacterSet defaultCharset = CharacterSet::Unknown; bool hasECI = false; Content(); diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index c791ae74aa..0cd73a1771 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -8,8 +8,9 @@ #pragma once #include "BarcodeFormat.h" +#include "CharacterSet.h" -#include +#include #include #include @@ -51,12 +52,12 @@ class DecodeHints EanAddOnSymbol _eanAddOnSymbol : 2; Binarizer _binarizer : 2; + CharacterSet _characterSet = CharacterSet::Unknown; uint8_t _minLineCount = 2; uint8_t _maxNumberOfSymbols = 0xff; uint8_t _downscaleFactor = 3; uint16_t _downscaleThreshold = 500; BarcodeFormats _formats = BarcodeFormat::None; - std::string _characterSet; public: // bitfields don't get default initialized to 0 before c++20 @@ -111,9 +112,6 @@ class DecodeHints /// The maximum number of symbols (barcodes) to detect / look for in the image with ReadBarcodes ZX_PROPERTY(uint8_t, maxNumberOfSymbols, setMaxNumberOfSymbols) - /// Specifies fallback character set to use instead of auto-detecting it (when applicable) - ZX_PROPERTY(std::string, characterSet, setCharacterSet) - /// If true, the Code-39 reader will try to read extended mode. ZX_PROPERTY(bool, tryCode39ExtendedMode, setTryCode39ExtendedMode) @@ -132,6 +130,11 @@ class DecodeHints /// Specify whether to ignore, read or require EAN-2/5 add-on symbols while scanning EAN/UPC codes ZX_PROPERTY(EanAddOnSymbol, eanAddOnSymbol, setEanAddOnSymbol) + /// Specifies fallback character set to use instead of auto-detecting it (when applicable) + ZX_PROPERTY(CharacterSet, characterSet, setCharacterSet) + DecodeHints& setCharacterSet(std::string_view v)& { return _characterSet = CharacterSetFromString(v), *this; } + DecodeHints&& setCharacterSet(std::string_view v) && { return _characterSet = CharacterSetFromString(v), std::move(*this); } + #undef ZX_PROPERTY bool hasFormat(BarcodeFormats f) const noexcept { return _formats.testFlags(f) || _formats.empty(); } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 9e097db2b5..6dd053cbc0 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -104,9 +104,9 @@ std::string Result::sequenceId() const return _sai.id; } -Result& Result::setCharacterSet(const std::string& defaultCS) +Result& Result::setCharacterSet(CharacterSet defaultCS) { - if (!defaultCS.empty()) + if (defaultCS != CharacterSet::Unknown) _content.defaultCharset = defaultCS; return *this; } diff --git a/core/src/Result.h b/core/src/Result.h index 77247f65f4..a4043eb41c 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -143,7 +143,7 @@ class Result // only for internal use void incrementLineCount() { ++_lineCount; } - Result& setCharacterSet(const std::string& defaultCS); + Result& setCharacterSet(CharacterSet defaultCS); bool operator==(const Result& o) const; diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 2a983ca040..3022ba10bd 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -270,7 +270,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode) { Content result; result.symbology = {'U', (mode == 2 || mode == 3) ? '1' : '0', 2}; // TODO: No identifier defined for mode 6? - result.defaultCharset = "ISO8859_1"; + result.defaultCharset = CharacterSet::ISO8859_1; StructuredAppendInfo sai; switch (mode) { diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 4d1d68c4d7..a843cebbad 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -540,7 +540,7 @@ static int DecodeMacroOptionalTextField(const std::vector& codewords, int c Content result; // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 // for non-ASCII (128-255). Text optional fields can contain ECIs. - result.defaultCharset = "Cp437"; + result.defaultCharset = CharacterSet::Cp437; codeIndex = TextCompaction(codewords, codeIndex, result); @@ -558,7 +558,7 @@ static int DecodeMacroOptionalNumericField(const std::vector& codewords, in Content result; // Each optional field begins with an implied reset to ECI 2 (Annex H.2.3). ECI 2 is ASCII for 0-127, and Cp437 // for non-ASCII (128-255). Text optional fields can contain ECIs. - result.defaultCharset = "Cp437"; + result.defaultCharset = CharacterSet::Cp437; codeIndex = NumericCompaction(codewords, codeIndex, result); From 00f9e8d0e287b1fb5864fdd7051153bc7611ca99 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 23:31:21 +0200 Subject: [PATCH 0374/1315] Error: store location info as std::string instead of string+int --- core/src/Error.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index 207caf3d5d..9d21a80ffc 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -15,16 +15,13 @@ class Error enum class Type { None, Format, Checksum, Unsupported }; Type type() const noexcept { return _type; } const std::string& msg() const noexcept { return _msg; } + const std::string& location() const noexcept { return _location; } explicit operator bool() const noexcept { return _type != Type::None; } - std::string location() const noexcept - { - return _file.empty() ? "" : _file.substr(_file.find_last_of("/\\") + 1) + ":" + std::to_string(_line); - } Error() = default; Error(Type type, std::string msg = {}) : _type(type), _msg(std::move(msg)) {} Error(std::string file, int line, Type type, std::string msg = {}) - : _type(type), _msg(std::move(msg)), _file(std::move(file)), _line(line) + : _type(type), _msg(std::move(msg)), _location(file.substr(file.find_last_of("/\\") + 1) + ":" + std::to_string(line)) {} static constexpr auto Format = Type::Format; @@ -34,8 +31,7 @@ class Error protected: Type _type = Type::None; std::string _msg; - std::string _file; - int _line = -1; + std::string _location; }; inline bool operator==(const Error& e, Error::Type t) noexcept { return e.type() == t; } From 1236fe3e0387f75d6dbc170650f3a1908ed96ffa Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 7 Jul 2022 23:33:53 +0200 Subject: [PATCH 0375/1315] CharacterSet: use 1 instead of 4 bytes storage Replace all forward declarations with simple #includes. --- core/src/CharacterSet.h | 2 +- core/src/TextDecoder.h | 5 ++--- core/src/TextEncoder.h | 4 ++-- core/src/aztec/AZWriter.h | 3 ++- core/src/pdf417/PDFHighLevelEncoder.h | 5 +++-- core/src/pdf417/PDFWriter.h | 4 +++- core/src/qrcode/QREncoder.h | 5 ++--- core/src/qrcode/QRWriter.h | 3 ++- 8 files changed, 17 insertions(+), 14 deletions(-) diff --git a/core/src/CharacterSet.h b/core/src/CharacterSet.h index acd41fc9b4..b347e787a3 100644 --- a/core/src/CharacterSet.h +++ b/core/src/CharacterSet.h @@ -9,7 +9,7 @@ namespace ZXing { -enum class CharacterSet +enum class CharacterSet : unsigned char { Unknown, ASCII, diff --git a/core/src/TextDecoder.h b/core/src/TextDecoder.h index ee35251867..a587a100bd 100644 --- a/core/src/TextDecoder.h +++ b/core/src/TextDecoder.h @@ -5,14 +5,14 @@ #pragma once +#include "CharacterSet.h" + #include #include #include namespace ZXing { -enum class CharacterSet; - class TextDecoder { public: @@ -36,7 +36,6 @@ class TextDecoder Append(r, (const uint8_t*)str.data(), str.length(), charset); return r; } - }; } // ZXing diff --git a/core/src/TextEncoder.h b/core/src/TextEncoder.h index d16972f104..df91a3ff58 100644 --- a/core/src/TextEncoder.h +++ b/core/src/TextEncoder.h @@ -5,12 +5,12 @@ #pragma once +#include "CharacterSet.h" + #include namespace ZXing { -enum class CharacterSet; - class TextEncoder { static void GetBytes(const std::wstring& str, CharacterSet charset, std::string& bytes); diff --git a/core/src/aztec/AZWriter.h b/core/src/aztec/AZWriter.h index aa80d46a30..13e5c67c04 100644 --- a/core/src/aztec/AZWriter.h +++ b/core/src/aztec/AZWriter.h @@ -6,11 +6,12 @@ #pragma once +#include "CharacterSet.h" + #include namespace ZXing { -enum class CharacterSet; class BitMatrix; namespace Aztec { diff --git a/core/src/pdf417/PDFHighLevelEncoder.h b/core/src/pdf417/PDFHighLevelEncoder.h index e0bbe89d28..83ee69e268 100644 --- a/core/src/pdf417/PDFHighLevelEncoder.h +++ b/core/src/pdf417/PDFHighLevelEncoder.h @@ -6,13 +6,14 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once + +#include "CharacterSet.h" + #include #include namespace ZXing { -enum class CharacterSet; - namespace Pdf417 { enum class Compaction; diff --git a/core/src/pdf417/PDFWriter.h b/core/src/pdf417/PDFWriter.h index b9bf3c3606..a352002bdd 100644 --- a/core/src/pdf417/PDFWriter.h +++ b/core/src/pdf417/PDFWriter.h @@ -5,13 +5,15 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once + +#include "CharacterSet.h" + #include #include namespace ZXing { class BitMatrix; -enum class CharacterSet; namespace Pdf417 { diff --git a/core/src/qrcode/QREncoder.h b/core/src/qrcode/QREncoder.h index b8e364806a..acf49b451f 100644 --- a/core/src/qrcode/QREncoder.h +++ b/core/src/qrcode/QREncoder.h @@ -6,12 +6,11 @@ #pragma once +#include "CharacterSet.h" + #include namespace ZXing { - -enum class CharacterSet; - namespace QRCode { enum class ErrorCorrectionLevel; diff --git a/core/src/qrcode/QRWriter.h b/core/src/qrcode/QRWriter.h index d088c8bc20..2f1759a949 100644 --- a/core/src/qrcode/QRWriter.h +++ b/core/src/qrcode/QRWriter.h @@ -6,12 +6,13 @@ #pragma once +#include "CharacterSet.h" + #include namespace ZXing { class BitMatrix; -enum class CharacterSet; namespace QRCode { From 315354be06ef9dd1f49242d22e09f2f17423a6ca Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 8 Jul 2022 00:17:39 +0200 Subject: [PATCH 0376/1315] To/From-String: consistently take std::string_view and return std::string --- core/src/BarcodeFormat.cpp | 16 ++++++++-------- core/src/BarcodeFormat.h | 7 ++++--- core/src/CharacterSet.cpp | 6 +++--- core/src/CharacterSet.h | 3 ++- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/core/src/BarcodeFormat.cpp b/core/src/BarcodeFormat.cpp index e188f2908a..58db3decce 100644 --- a/core/src/BarcodeFormat.cpp +++ b/core/src/BarcodeFormat.cpp @@ -13,14 +13,13 @@ #include #include #include -#include namespace ZXing { struct BarcodeFormatName { BarcodeFormat format; - const char* name; + std::string_view name; }; static BarcodeFormatName NAMES[] = { @@ -46,10 +45,10 @@ static BarcodeFormatName NAMES[] = { {BarcodeFormat::MatrixCodes, "Matrix-Codes"}, }; -const char* ToString(BarcodeFormat format) +std::string ToString(BarcodeFormat format) { auto i = FindIf(NAMES, [format](auto& v) { return v.format == format; }); - return i == std::end(NAMES) ? nullptr : i->name; + return i == std::end(NAMES) ? std::string() : std::string(i->name); } std::string ToString(BarcodeFormats formats) @@ -58,12 +57,13 @@ std::string ToString(BarcodeFormats formats) return ToString(BarcodeFormat::None); std::string res; for (auto f : formats) - res += ToString(f) + std::string("|"); + res += ToString(f) + "|"; return res.substr(0, res.size() - 1); } -static std::string NormalizeFormatString(std::string str) +static std::string NormalizeFormatString(std::string_view sv) { + std::string str(sv); std::transform(str.begin(), str.end(), str.begin(), [](char c) { return (char)std::tolower(c); }); str.erase(std::remove_if(str.begin(), str.end(), [](char c) { return Contains("_-[]", c); }), str.end()); return str; @@ -75,12 +75,12 @@ static BarcodeFormat ParseFormatString(const std::string& str) return i == std::end(NAMES) ? BarcodeFormat::None : i->format; } -BarcodeFormat BarcodeFormatFromString(const std::string& str) +BarcodeFormat BarcodeFormatFromString(std::string_view str) { return ParseFormatString(NormalizeFormatString(str)); } -BarcodeFormats BarcodeFormatsFromString(const std::string& str) +BarcodeFormats BarcodeFormatsFromString(std::string_view str) { auto normalized = NormalizeFormatString(str); std::replace_if( diff --git a/core/src/BarcodeFormat.h b/core/src/BarcodeFormat.h index 1b973569a1..3d3a4c326e 100644 --- a/core/src/BarcodeFormat.h +++ b/core/src/BarcodeFormat.h @@ -9,6 +9,7 @@ #include "Flags.h" #include +#include namespace ZXing { @@ -48,14 +49,14 @@ enum class BarcodeFormat ZX_DECLARE_FLAGS(BarcodeFormats, BarcodeFormat) -const char* ToString(BarcodeFormat format); +std::string ToString(BarcodeFormat format); std::string ToString(BarcodeFormats formats); /** * @brief Parse a string into a BarcodeFormat. '-' and '_' are optional. * @return None if str can not be parsed as a valid enum value */ -BarcodeFormat BarcodeFormatFromString(const std::string& str); +BarcodeFormat BarcodeFormatFromString(std::string_view str); /** * @brief Parse a string into a set of BarcodeFormats. @@ -64,6 +65,6 @@ BarcodeFormat BarcodeFormatFromString(const std::string& str); * e.g. "EAN-8 qrcode, Itf" would be parsed into [EAN8, QRCode, ITF]. * @throws std::invalid_parameter if the string can not be fully parsed. */ -BarcodeFormats BarcodeFormatsFromString(const std::string& str); +BarcodeFormats BarcodeFormatsFromString(std::string_view str); } // ZXing diff --git a/core/src/CharacterSet.cpp b/core/src/CharacterSet.cpp index 7d985204c2..dafefc12de 100644 --- a/core/src/CharacterSet.cpp +++ b/core/src/CharacterSet.cpp @@ -45,8 +45,8 @@ static CharacterSetName NAME_TO_CHARSET[] = { {"windows-1252",CharacterSet::Cp1252}, {"Cp1256", CharacterSet::Cp1256}, {"windows-1256",CharacterSet::Cp1256}, - {"UnicodeBigUnmarked", CharacterSet::UnicodeBig}, {"UTF-16BE", CharacterSet::UnicodeBig}, + {"UnicodeBigUnmarked", CharacterSet::UnicodeBig}, {"UnicodeBig", CharacterSet::UnicodeBig}, {"UTF-8", CharacterSet::UTF8}, {"ASCII", CharacterSet::ASCII}, @@ -74,10 +74,10 @@ CharacterSet CharacterSetFromString(std::string_view name) return i == std::end(NAME_TO_CHARSET) ? CharacterSet::Unknown : i->cs; } -std::string_view ToString(CharacterSet cs) +std::string ToString(CharacterSet cs) { auto i = FindIf(NAME_TO_CHARSET, [cs](auto& v) { return v.cs == cs; }); - return i == std::end(NAME_TO_CHARSET) ? "" : i->name; + return i == std::end(NAME_TO_CHARSET) ? "" : std::string(i->name); } } // namespace ZXing diff --git a/core/src/CharacterSet.h b/core/src/CharacterSet.h index b347e787a3..19c2838e49 100644 --- a/core/src/CharacterSet.h +++ b/core/src/CharacterSet.h @@ -5,6 +5,7 @@ #pragma once +#include #include namespace ZXing { @@ -49,6 +50,6 @@ enum class CharacterSet : unsigned char }; CharacterSet CharacterSetFromString(std::string_view name); -std::string_view ToString(CharacterSet cs); +std::string ToString(CharacterSet cs); } // ZXing From 44d015da522c0a5bec65f904838c1e21a8cf9f36 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 8 Jul 2022 00:27:12 +0200 Subject: [PATCH 0377/1315] Error: save even more space by replacing std::string with char* + int From originally std::string+int (36) down to char*+short (10) bytes for the location info. --- core/src/Error.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/core/src/Error.h b/core/src/Error.h index 9d21a80ffc..a7daaa4eb6 100644 --- a/core/src/Error.h +++ b/core/src/Error.h @@ -6,32 +6,39 @@ #pragma once #include +#include namespace ZXing { class Error { public: - enum class Type { None, Format, Checksum, Unsupported }; + enum class Type : uint8_t { None, Format, Checksum, Unsupported }; Type type() const noexcept { return _type; } const std::string& msg() const noexcept { return _msg; } - const std::string& location() const noexcept { return _location; } explicit operator bool() const noexcept { return _type != Type::None; } + std::string location() const + { + if (!_file) + return {}; + std::string file(_file); + return file.substr(file.find_last_of("/\\") + 1) + ":" + std::to_string(_line); + } + Error() = default; - Error(Type type, std::string msg = {}) : _type(type), _msg(std::move(msg)) {} - Error(std::string file, int line, Type type, std::string msg = {}) - : _type(type), _msg(std::move(msg)), _location(file.substr(file.find_last_of("/\\") + 1) + ":" + std::to_string(line)) - {} + Error(Type type, std::string msg = {}) : _msg(std::move(msg)), _type(type) {} + Error(const char* file, short line, Type type, std::string msg = {}) : _msg(std::move(msg)), _file(file), _line(line), _type(type) {} static constexpr auto Format = Type::Format; static constexpr auto Checksum = Type::Checksum; static constexpr auto Unsupported = Type::Unsupported; protected: - Type _type = Type::None; std::string _msg; - std::string _location; + const char* _file = nullptr; + short _line = -1; + Type _type = Type::None; }; inline bool operator==(const Error& e, Error::Type t) noexcept { return e.type() == t; } @@ -49,7 +56,7 @@ inline std::string ToString(const Error& e) std::string ret = name[static_cast(e.type())]; if (!e.msg().empty()) ret += " (" + e.msg() + ")"; - if (!e.location().empty()) + if (auto location = e.location(); !location.empty()) ret += " @ " + e.location(); return ret; } From d829aa337ecc28fcfd2375da081947a678d22e5a Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 8 Jul 2022 00:27:35 +0200 Subject: [PATCH 0378/1315] ZXAlgorithm: fix includes --- core/src/ZXAlgorithms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/ZXAlgorithms.h b/core/src/ZXAlgorithms.h index f04191f10d..7256119f2d 100644 --- a/core/src/ZXAlgorithms.h +++ b/core/src/ZXAlgorithms.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace ZXing { From 5882f0764000a12a49bdf574965622b22bb80b68 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 8 Jul 2022 00:30:11 +0200 Subject: [PATCH 0379/1315] Result: struct packing by member reordering Including earlier optimizations this saved a total of > 100 bytes (30%). --- core/src/Result.cpp | 16 ++++++++-------- core/src/Result.h | 5 ++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 6dd053cbc0..9f697d26a8 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -19,24 +19,24 @@ namespace ZXing { Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFormat format, SymbologyIdentifier si, Error error, bool readerInit) - : _format(format), - _content({ByteArray(text)}, si), + : _content({ByteArray(text)}, si), _error(error), _position(Line(y, xStart, xStop)), - _readerInit(readerInit), - _lineCount(0) + _format(format), + _lineCount(0), + _readerInit(readerInit) {} Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format) - : _format(decodeResult.content().symbology.code == 0 ? BarcodeFormat::None : format), - _content(std::move(decodeResult).content()), + : _content(std::move(decodeResult).content()), _error(std::move(decodeResult).error()), _position(std::move(position)), _ecLevel(decodeResult.ecLevel()), _sai(decodeResult.structuredAppend()), + _format(decodeResult.content().symbology.code == 0 ? BarcodeFormat::None : format), + _lineCount(decodeResult.lineCount()), _isMirrored(decodeResult.isMirrored()), - _readerInit(decodeResult.readerInit()), - _lineCount(decodeResult.lineCount()) + _readerInit(decodeResult.readerInit()) { // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } diff --git a/core/src/Result.h b/core/src/Result.h index a4043eb41c..7c2b63adf0 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -150,16 +150,15 @@ class Result friend Result MergeStructuredAppendSequence(const std::vector& results); private: - BarcodeFormat _format = BarcodeFormat::None; Content _content; Error _error; Position _position; - ByteArray _rawBytes; std::string _ecLevel; StructuredAppendInfo _sai; + BarcodeFormat _format = BarcodeFormat::None; + int _lineCount = 0; bool _isMirrored = false; bool _readerInit = false; - int _lineCount = 0; }; using Results = std::vector; From 0a7e92c87666063c11f2c3320d00a7b3901fc2ae Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 8 Jul 2022 00:45:16 +0200 Subject: [PATCH 0380/1315] c++: fix compile regression on (only) android (-1 can't be a char?!?) --- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index a843cebbad..c6d9738c1f 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -677,7 +677,7 @@ DecoderResult DecodedBitStreamParser::Decode(const std::vector& codewords, int ecLevel) { Content result; - result.symbology = { 'L', '2', -1 }; + result.symbology = { 'L', '2', char(-1) }; bool readerInit = false; auto resultMetadata = std::make_shared(); From be0e481218e27eebe82aba5b0a5dc0293ed4f918 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 8 Jul 2022 12:03:17 +0200 Subject: [PATCH 0381/1315] cmake: request c++17 also on client side cmake projects This should accidentally fix #355. --- core/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 719c400be9..33a7d35933 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -464,8 +464,7 @@ if (COMPILER_NEEDS_FLOAT_STORE) ) endif() -# the lib needs a c++-17 compiler but can be used with a c++-11 compiler (see examples) -target_compile_features(ZXing PRIVATE cxx_std_17 INTERFACE cxx_std_11) +target_compile_features(ZXing PUBLIC cxx_std_17) target_link_libraries (ZXing PRIVATE Threads::Threads) From 8e0ca7cc6deff3612926fc02ad7c1a6d9e0670bf Mon Sep 17 00:00:00 2001 From: Khoren Markosyan Date: Fri, 8 Jul 2022 16:12:41 +0400 Subject: [PATCH 0382/1315] README: add link to external Flutter wrapper (#356) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0508b63cac..b16bad4ba1 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ * Android * WebAssembly * [Python](wrappers/python/README.md) + * [Flutter](https://pub.dev/packages/flutter_zxing) (external project) ## Supported Formats From 7ebada5c61f0d253a6df0c99d2bba4ef8c64bcce Mon Sep 17 00:00:00 2001 From: Hendrik Date: Wed, 13 Jul 2022 10:17:16 +0200 Subject: [PATCH 0383/1315] Adding a wrapper for iOS (#337) Co-authored-by: @parallaxe Co-authored-by: Christian Braun braun.christian.bamberg@gmail.com This pull request adds a wrapper of ZXing for iOS. It offers one class for reading and one for writing. ZXing itself will be compiled to an universal framework, xcframework, that contains the binaries and headers for the iOS-simulator and for iOS-devices. The wrapper-code is written in Objective-C++, whereas the public part of the wrapper is Objective-C only. By this, it can also be used in Swift. To build the xcframework, I had to add a section to the CMakeLists.txt. This enables building frameworks for Apple platforms. Those frameworks are only either for the simulator, or for real devices. But they can be combined to a single xcframework. This process is automated by the build-release.sh-script. The section in the CMakeLists.txt should not change the behaviour on other platforms (tested on Linux so far). To use the wrapper, you first have to build the xcframework by calling the build-script and then adding the Package.swift-file to your project. A demoproject is included, where also the usage is demonstrated. --- .github/workflows/ci.yml | 23 + core/CMakeLists.txt | 19 + wrappers/ios/.gitignore | 5 + wrappers/ios/Info.plist | Bin 0 -> 723 bytes wrappers/ios/Package.swift | 31 ++ wrappers/ios/README.md | 14 + .../Sources/Wrapper/Reader/ZXIBarcodeReader.h | 21 + .../Wrapper/Reader/ZXIBarcodeReader.mm | 127 ++++++ .../Sources/Wrapper/Reader/ZXIDecodeHints.h | 24 ++ .../Sources/Wrapper/Reader/ZXIDecodeHints.mm | 23 + .../ios/Sources/Wrapper/Reader/ZXIPoint.h | 17 + .../ios/Sources/Wrapper/Reader/ZXIPoint.m | 16 + .../Wrapper/Reader/ZXIPosition+Helper.h | 15 + .../Wrapper/Reader/ZXIPosition+Helper.mm | 17 + .../ios/Sources/Wrapper/Reader/ZXIPosition.h | 23 + .../ios/Sources/Wrapper/Reader/ZXIPosition.m | 20 + .../ios/Sources/Wrapper/Reader/ZXIResult.h | 23 + .../ios/Sources/Wrapper/Reader/ZXIResult.mm | 19 + wrappers/ios/Sources/Wrapper/UmbrellaHeader.h | 17 + .../Sources/Wrapper/Writer/ZXIBarcodeWriter.h | 19 + .../Wrapper/Writer/ZXIBarcodeWriter.mm | 93 ++++ wrappers/ios/Sources/Wrapper/ZXIErrors.h | 15 + wrappers/ios/Sources/Wrapper/ZXIFormat.h | 15 + .../ios/Sources/Wrapper/ZXIFormatHelper.h | 13 + .../ios/Sources/Wrapper/ZXIFormatHelper.mm | 103 +++++ wrappers/ios/Sources/Wrapper/module.modulemap | 6 + wrappers/ios/build-release.sh | 36 ++ wrappers/ios/demo/README.md | 5 + .../ios/demo/demo.xcodeproj/project.pbxproj | 405 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/demo.xcscheme | 90 ++++ wrappers/ios/demo/demo/AppDelegate.swift | 35 ++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 93 ++++ .../demo/demo/Assets.xcassets/Contents.json | 6 + .../demo/Base.lproj/LaunchScreen.storyboard | 25 ++ .../ios/demo/demo/Base.lproj/Main.storyboard | 101 +++++ wrappers/ios/demo/demo/Info.plist | 25 ++ wrappers/ios/demo/demo/SceneDelegate.swift | 47 ++ wrappers/ios/demo/demo/ViewController.swift | 71 +++ .../ios/demo/demo/WriteViewController.swift | 25 ++ 42 files changed, 1708 insertions(+) create mode 100644 wrappers/ios/.gitignore create mode 100644 wrappers/ios/Info.plist create mode 100644 wrappers/ios/Package.swift create mode 100644 wrappers/ios/README.md create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.h create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.h create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.mm create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.h create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.m create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.h create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.mm create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.h create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.m create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIResult.h create mode 100644 wrappers/ios/Sources/Wrapper/Reader/ZXIResult.mm create mode 100644 wrappers/ios/Sources/Wrapper/UmbrellaHeader.h create mode 100644 wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.h create mode 100644 wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.mm create mode 100644 wrappers/ios/Sources/Wrapper/ZXIErrors.h create mode 100644 wrappers/ios/Sources/Wrapper/ZXIFormat.h create mode 100644 wrappers/ios/Sources/Wrapper/ZXIFormatHelper.h create mode 100644 wrappers/ios/Sources/Wrapper/ZXIFormatHelper.mm create mode 100644 wrappers/ios/Sources/Wrapper/module.modulemap create mode 100755 wrappers/ios/build-release.sh create mode 100644 wrappers/ios/demo/README.md create mode 100644 wrappers/ios/demo/demo.xcodeproj/project.pbxproj create mode 100644 wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 wrappers/ios/demo/demo.xcodeproj/xcshareddata/xcschemes/demo.xcscheme create mode 100644 wrappers/ios/demo/demo/AppDelegate.swift create mode 100644 wrappers/ios/demo/demo/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 wrappers/ios/demo/demo/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 wrappers/ios/demo/demo/Assets.xcassets/Contents.json create mode 100644 wrappers/ios/demo/demo/Base.lproj/LaunchScreen.storyboard create mode 100644 wrappers/ios/demo/demo/Base.lproj/Main.storyboard create mode 100644 wrappers/ios/demo/demo/Info.plist create mode 100644 wrappers/ios/demo/demo/SceneDelegate.swift create mode 100644 wrappers/ios/demo/demo/ViewController.swift create mode 100644 wrappers/ios/demo/demo/WriteViewController.swift diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6858fb4f2e..23bf7aec08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,29 @@ jobs: # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest -V -C $BUILD_TYPE + + build-ios: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{github.ref}} + + - name: Build the ZXingCpp.xcframework + shell: sh + working-directory: ${{runner.workspace}}/${{github.event.repository.name}}/wrappers/ios + run: ./build-release.sh + + - name: Upload .xcframework + uses: actions/upload-artifact@v3 + with: + name: ios-artifacts + path: ${{runner.workspace}}/${{github.event.repository.name}}/wrappers/ios/ZXingCpp.xcframework + + - name: Build the demo app + shell: sh + working-directory: ${{runner.workspace}}/${{github.event.repository.name}}/wrappers/ios/demo + run: xcodebuild build -scheme demo -sdk "iphonesimulator" build-android: runs-on: ubuntu-latest diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 33a7d35933..54a053838e 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -115,6 +115,7 @@ if (BUILD_READERS) src/Result.cpp src/ResultPoint.h src/ResultPoint.cpp + src/StructuredAppend.h src/TextDecoder.h src/TextDecoder.cpp src/ThresholdBinarizer.h @@ -484,6 +485,23 @@ endif() set_target_properties(ZXing PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADERS}") +if (APPLE) + set_target_properties(ZXing PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION "C" + XCODE_ATTRIBUTE_DEFINES_MODULE YES + XCODE_ATTRIBUTE_BUILD_LIBRARY_FOR_DISTRIBUTION YES + XCODE_ATTRIBUTE_MODULEMAP_FILE "wrappers/ios/Sources/Wrapper/module.modulemap" + XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES + MACOSX_FRAMEWORK_IDENTIFIER "com.zxing_cpp.ios" + CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH NO + #MACOSX_FRAMEWORK_INFO_PLIST Info.plist + PUBLIC_HEADER "${PUBLIC_HEADERS}" + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer" + XCODE_ATTRIBUTE_ENABLE_BITCODE "YES" + ) +endif() + include (GNUInstallDirs) install ( @@ -491,6 +509,7 @@ install ( LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} # INCLUDES DESTINATION include PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ZXing" ) diff --git a/wrappers/ios/.gitignore b/wrappers/ios/.gitignore new file mode 100644 index 0000000000..be5558caa1 --- /dev/null +++ b/wrappers/ios/.gitignore @@ -0,0 +1,5 @@ +.swiftpm +_builds +.build +xcuserdata +ZXingCpp.xcframework diff --git a/wrappers/ios/Info.plist b/wrappers/ios/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..0433f478b49fa21f43f38dbba7b6bc0a62542df1 GIT binary patch literal 723 zcmYjOyKWOf6x}<#5+2DWPJo02On3x{Sb4pPrO+VRYa=VNW4!Cwi9%N6-LXB&?1Ozo zc7B0^p3YxDO+|&M_y8(IK|_ORD4=0>V-u#i_ndpqoqK269-~2+$$Sy#0G&B|?)-&` z$%~gRUzwT~XJ%7#^H;B3Us$}cbn{mF_DcHB-Fx>}9~xpRA5msiu-T&y+13(dhzo^M zK5{HZRB}X^>)FH!>!eFv#}H@7wPK%`QHa}&{7058E~Onxd_!CwE6YyDRjCd-9coARwl*>!G|K$ts7XrLrfgt{OO0}!yo{(%tdl|kd$>&*4Jip4Sy|0xn?Yf-1mM>1VoI_~rQvFUjdbptIYW%N>|xurklXSm#=wVoUQ+N2?_#A?1cBNES& zwF8N^VcDj;mWOn4uVpiE~Q7?A6fi7=I>-%FA16@`WE>nuKtkh*?_&|i=qXzcv z+`2F!C_-5v!m;pLcq@DmJ`2BK3Kn1uo +#import +#import "ZXIResult.h" +#import "ZXIDecodeHints.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ZXIBarcodeReader : NSObject +@property(nonatomic, strong) ZXIDecodeHints *hints; + +- (instancetype)initWithHints:(ZXIDecodeHints*)options; +- (NSArray *)readCIImage:(nonnull CIImage *)image; +- (NSArray *)readCGImage:(nonnull CGImageRef)image; +- (NSArray *)readCVPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer; +@end + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm b/wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm new file mode 100644 index 0000000000..abee63aabc --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm @@ -0,0 +1,127 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import "ZXIBarcodeReader.h" +#import "ZXing/ReadBarcode.h" +#import "ZXing/ImageView.h" +#import "ZXing/Result.h" +#import "ZXIFormatHelper.h" +#import "ZXIPosition+Helper.h" + +using namespace ZXing; + +@interface ZXIBarcodeReader() +@property (nonatomic, strong) CIContext* ciContext; +@end + +@implementation ZXIBarcodeReader + +- (instancetype)init { + return [self initWithHints: [[ZXIDecodeHints alloc]initWithTryHarder:NO tryRotate:NO tryDownscale:NO maxNumberOfSymbols:1 formats:@[]]]; +} + +- (instancetype)initWithHints:(ZXIDecodeHints*)hints{ + self = [super init]; + self.ciContext = [CIContext new]; + self.hints = hints; + return self; +} + +- (NSArray *)readCVPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer { + OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer); + + // We tried to work with all luminance based formats listed in kCVPixelFormatType + // but only the following ones seem to be supported on iOS. + switch (pixelFormat) { + case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: + case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: + NSInteger cols = CVPixelBufferGetWidth(pixelBuffer); + NSInteger rows = CVPixelBufferGetHeight(pixelBuffer); + NSInteger bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); + CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); + const uint8_t * bytes = static_cast(CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0)); + ImageView imageView = ImageView( + static_cast(bytes), + static_cast(cols), + static_cast(rows), + ImageFormat::Lum, + static_cast(bytesPerRow), + 0); + NSArray* results = [self readImageView:imageView]; + CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); + return results; + } + + // If given pixel format is not a supported type with a luminance channel we just use the + // default method + return [self readCIImage:[[CIImage alloc] initWithCVImageBuffer:pixelBuffer]]; +} + +- (NSArray *)readCIImage:(nonnull CIImage *)image { + CGImageRef cgImage = [self.ciContext createCGImage:image fromRect:image.extent]; + auto results = [self readCGImage:cgImage]; + CGImageRelease(cgImage); + return results; +} + +- (NSArray *)readCGImage: (nonnull CGImageRef)image { + CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); + CGFloat cols = CGImageGetWidth(image); + CGFloat rows = CGImageGetHeight(image); + NSMutableData *data = [NSMutableData dataWithLength: cols * rows]; + + + CGContextRef contextRef = CGBitmapContextCreate( + data.mutableBytes,// Pointer to backing data + cols, // Width of bitmap + rows, // Height of bitmap + 8, // Bits per component + cols, // Bytes per row + colorSpace, // Colorspace + kCGBitmapByteOrderDefault); // Bitmap info flags + CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image); + CGContextRelease(contextRef); + + ImageView imageView = ImageView( + static_cast(data.bytes), + static_cast(cols), + static_cast(rows), + ImageFormat::Lum); + return [self readImageView:imageView]; +} + ++ (DecodeHints)DecodeHintsFromZXIOptions:(ZXIDecodeHints*)hints { + BarcodeFormats formats; + for(NSNumber* flag in hints.formats) { + formats.setFlag(BarcodeFormatFromZXIFormat((ZXIFormat)flag.integerValue)); + } + DecodeHints resultingHints = DecodeHints() + .setTryRotate(hints.tryRotate) + .setTryHarder(hints.tryHarder) + .setTryDownscale(hints.tryDownscale) + .setFormats(formats) + .setMaxNumberOfSymbols(hints.maxNumberOfSymbols); + return resultingHints; +} + +- (NSArray *)readImageView: (ImageView)imageView { + Results results = ReadBarcodes(imageView, [ZXIBarcodeReader DecodeHintsFromZXIOptions:self.hints]); + + NSMutableArray* zxiResults = [NSMutableArray array]; + for (auto result: results) { + auto resultText = result.text(); + NSString *text = [[NSString alloc]initWithBytes:resultText.data() length:resultText.size() encoding:NSUTF8StringEncoding]; + + NSData *bytes = [[NSData alloc] initWithBytes:result.bytes().data() length:result.bytes().size()]; + [zxiResults addObject: + [[ZXIResult alloc] init:text + format:ZXIFormatFromBarcodeFormat(result.format()) + bytes:bytes + position:[[ZXIPosition alloc]initWithPosition: result.position()] + ]]; + } + return zxiResults; +} + +@end diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.h b/wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.h new file mode 100644 index 0000000000..6a113f94e5 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.h @@ -0,0 +1,24 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ZXIDecodeHints : NSObject +@property(nonatomic) BOOL tryHarder; +@property(nonatomic) BOOL tryRotate; +@property(nonatomic) BOOL tryDownscale; +@property(nonatomic) NSInteger maxNumberOfSymbols; +/// An array of ZXIFormat +@property(nonatomic, strong) NSArray *formats; + +- (instancetype)initWithTryHarder:(BOOL)tryHarder + tryRotate:(BOOL)tryRotate + tryDownscale:(BOOL)tryDownscale + maxNumberOfSymbols:(NSInteger)maxNumberOfSymbol + formats:(NSArray*)formats; +@end + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.mm b/wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.mm new file mode 100644 index 0000000000..cd28dc40f8 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIDecodeHints.mm @@ -0,0 +1,23 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import "ZXIDecodeHints.h" + +@implementation ZXIDecodeHints + +- (instancetype)initWithTryHarder:(BOOL)tryHarder + tryRotate:(BOOL)tryRotate + tryDownscale:(BOOL)tryDownscale + maxNumberOfSymbols:(NSInteger)maxNumberOfSymbols + formats:(NSArray*)formats { + self = [super init]; + self.tryHarder = tryHarder; + self.tryRotate = tryRotate; + self.tryDownscale = tryDownscale; + self.maxNumberOfSymbols = maxNumberOfSymbols; + self.formats = formats; + return self; +} + +@end diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.h b/wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.h new file mode 100644 index 0000000000..5ce37c125b --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.h @@ -0,0 +1,17 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ZXIPoint : NSObject +@property(nonatomic) NSInteger x; +@property(nonatomic) NSInteger y; + +- (instancetype)initWithX:(NSInteger)x y:(NSInteger)y; +@end + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.m b/wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.m new file mode 100644 index 0000000000..3a303c3bae --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIPoint.m @@ -0,0 +1,16 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + + +#import "ZXIPoint.h" + +@implementation ZXIPoint + +- (instancetype)initWithX:(NSInteger)x y:(NSInteger)y { + self = [super init]; + self.x = x; + self.y = y; + return self; +} +@end diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.h b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.h new file mode 100644 index 0000000000..5224ea8d9c --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.h @@ -0,0 +1,15 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import +#import "ZXIPosition.h" +#import "ZXing/Result.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ZXIPosition(Helper) +- (instancetype)initWithPosition:(ZXing::Position)position; +@end + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.mm b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.mm new file mode 100644 index 0000000000..94404b5136 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition+Helper.mm @@ -0,0 +1,17 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + + +#import "ZXIPosition+Helper.h" +#import "ZXIPoint.h" + +@implementation ZXIPosition(Helper) +-(instancetype)initWithPosition:(ZXing::Position)position { + return [self initWithTopLeft:[[ZXIPoint alloc] initWithX:position.topLeft().x y:position.topLeft().y] + topRight:[[ZXIPoint alloc] initWithX:position.topRight().x y:position.topRight().y] + bottomRight:[[ZXIPoint alloc] initWithX:position.bottomRight().x y:position.bottomRight().y] + bottomLeft:[[ZXIPoint alloc] initWithX:position.bottomLeft().x y:position.bottomLeft().y]]; +} + +@end diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.h b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.h new file mode 100644 index 0000000000..1aa44dd56b --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.h @@ -0,0 +1,23 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + + +#import +#import "ZXIPoint.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ZXIPosition : NSObject +@property(nonatomic, nonnull)ZXIPoint *topLeft; +@property(nonatomic, nonnull)ZXIPoint *topRight; +@property(nonatomic, nonnull)ZXIPoint *bottomRight; +@property(nonatomic, nonnull)ZXIPoint *bottomLeft; + +- (instancetype)initWithTopLeft:(ZXIPoint *)topLeft + topRight:(ZXIPoint *)topRight + bottomRight:(ZXIPoint *)bottomRight + bottomLeft:(ZXIPoint *)bottomLeft; +@end + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.m b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.m new file mode 100644 index 0000000000..17432026c5 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIPosition.m @@ -0,0 +1,20 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + + +#import "ZXIPosition.h" + +@implementation ZXIPosition +- (instancetype)initWithTopLeft:(ZXIPoint *)topLeft + topRight:(ZXIPoint *)topRight + bottomRight:(ZXIPoint *)bottomRight + bottomLeft:(ZXIPoint *)bottomLeft { + self = [super init]; + self.topLeft = topLeft; + self.topRight = topRight; + self.bottomRight = bottomRight; + self.bottomLeft = bottomLeft; + return self; +} +@end diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIResult.h b/wrappers/ios/Sources/Wrapper/Reader/ZXIResult.h new file mode 100644 index 0000000000..83d8a4cffc --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIResult.h @@ -0,0 +1,23 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import +#import "ZXIFormat.h" +#import "ZXIPosition.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ZXIResult : NSObject +@property(nonatomic, strong) NSString *text; +@property(nonatomic, strong) NSData *bytes; +@property(nonatomic, strong) ZXIPosition *position; +@property(nonatomic) ZXIFormat format; + +- (instancetype)init:(NSString *)text + format:(ZXIFormat)format + bytes:(NSData *)bytes + position:(ZXIPosition *)position; +@end + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIResult.mm b/wrappers/ios/Sources/Wrapper/Reader/ZXIResult.mm new file mode 100644 index 0000000000..b84267d2a0 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIResult.mm @@ -0,0 +1,19 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import "ZXIResult.h" + +@implementation ZXIResult +- (instancetype)init:(NSString *)text + format:(ZXIFormat)format + bytes:(NSData *)bytes + position:(ZXIPosition *)position { + self = [super init]; + self.text = text; + self.format = format; + self.bytes = bytes; + self.position = position; + return self; +} +@end diff --git a/wrappers/ios/Sources/Wrapper/UmbrellaHeader.h b/wrappers/ios/Sources/Wrapper/UmbrellaHeader.h new file mode 100644 index 0000000000..951357f673 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/UmbrellaHeader.h @@ -0,0 +1,17 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef UmbrellaHeader_h +#define UmbrellaHeader_h + +#import "Reader/ZXIBarcodeReader.h" +#import "Reader/ZXIResult.h" +#import "Reader/ZXIPosition.h" +#import "Reader/ZXIPoint.h" +#import "Reader/ZXIDecodeHints.h" +#import "Writer/ZXIBarcodeWriter.h" +#import "ZXIErrors.h" +#import "ZXIFormat.h" + +#endif diff --git a/wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.h b/wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.h new file mode 100644 index 0000000000..664ff3dd84 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.h @@ -0,0 +1,19 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import +#import "ZXIFormat.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ZXIBarcodeWriter : NSObject + +-(nullable CGImageRef)write:(NSString *)contents + width:(int)width + height:(int)height + format:(ZXIFormat)format + error:(NSError **)error; +@end + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.mm b/wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.mm new file mode 100644 index 0000000000..430fed9995 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/Writer/ZXIBarcodeWriter.mm @@ -0,0 +1,93 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import +#import "ZXIBarcodeWriter.h" +#import "ZXing/MultiFormatWriter.h" +#import "ZXing/BitMatrix.h" +#import "ZXIFormatHelper.h" +#import "ZXIErrors.h" +#import + +using namespace ZXing; + +std::wstring NSStringToStringW(NSString* str) { + NSData* asData = [str dataUsingEncoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE)]; + return std::wstring((wchar_t*)[asData bytes], [asData length] / + sizeof(wchar_t)); +} + +#ifdef DEBUG +std::string ToString(const BitMatrix& matrix, char one, char zero, bool addSpace, bool printAsCString) +{ + std::string result; + result.reserve((addSpace ? 2 : 1) * (matrix.width() * matrix.height()) + matrix.height()); + for (int y = 0; y < matrix.height(); ++y) { + for (int x = 0; x < matrix.width(); ++x) { + result += matrix.get(x, y) ? one : zero; + if (addSpace) + result += ' '; + } + if (printAsCString) + result += "\\n\""; + result += '\n'; + } + return result; +} +#endif + +@implementation ZXIBarcodeWriter + +-(CGImageRef)write:(NSString *)contents + width:(int)width + height:(int)height + format:(ZXIFormat)format + error:(NSError *__autoreleasing _Nullable *)error { + MultiFormatWriter writer { BarcodeFormatFromZXIFormat(format) }; + // Catch exception for invalid formats + try { + BitMatrix result = writer.encode(NSStringToStringW(contents), width, height); + int realWidth = result.width(); + int realHeight = result.height(); + +#ifdef DEBUG +// std::cout << ToString(result, 'X', ' ', false, false); +#endif + + NSMutableData *resultAsNSData = [[NSMutableData alloc] initWithLength:realWidth * realHeight]; + size_t index = 0; + uint8_t *bytes = (uint8_t*)resultAsNSData.mutableBytes; + for (int y = 0; y < realHeight; ++y) { + for (int x = 0; x < realWidth; ++x) { + bytes[index] = result.get(x, y) ? 0 : 255; + ++index; + } + } + + CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); + + CGImageRef cgimage = CGImageCreate(realWidth, + realHeight, + 8, + 8, + realWidth, + colorSpace, + kCGBitmapByteOrderDefault, + CGDataProviderCreateWithCFData((CFDataRef)resultAsNSData), + NULL, + YES, + kCGRenderingIntentDefault); + return cgimage; + } catch(std::exception &e) { + if(error != nil) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: [[NSString alloc] initWithUTF8String:e.what()] + }; + *error = [[NSError alloc] initWithDomain:ZXIErrorDomain code:ZXIWriterError userInfo:userInfo]; + } + return nil; + } +} + +@end diff --git a/wrappers/ios/Sources/Wrapper/ZXIErrors.h b/wrappers/ios/Sources/Wrapper/ZXIErrors.h new file mode 100644 index 0000000000..7f1ebb6e26 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/ZXIErrors.h @@ -0,0 +1,15 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import + +NS_ASSUME_NONNULL_BEGIN + +#define ZXIErrorDomain @"ZXIErrorDomain" + +typedef NS_ENUM(NSInteger, ZXIBarcodeWriterError) { + ZXIWriterError, +}; + +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/ZXIFormat.h b/wrappers/ios/Sources/Wrapper/ZXIFormat.h new file mode 100644 index 0000000000..157ac227cf --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/ZXIFormat.h @@ -0,0 +1,15 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import +#ifndef ZXIFormat_h +#define ZXIFormat_h + +typedef NS_ENUM(NSInteger, ZXIFormat) { + NONE, AZTEC, CODABAR, CODE_39, CODE_93, CODE_128, DATA_BAR, DATA_BAR_EXPANDED, + DATA_MATRIX, EAN_8, EAN_13, ITF, MAXICODE, PDF_417, QR_CODE, MICRO_QR_CODE, UPC_A, UPC_E, + LINEAR_CODES, MATRIX_CODES, ANY +}; + +#endif diff --git a/wrappers/ios/Sources/Wrapper/ZXIFormatHelper.h b/wrappers/ios/Sources/Wrapper/ZXIFormatHelper.h new file mode 100644 index 0000000000..29f90a03bf --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/ZXIFormatHelper.h @@ -0,0 +1,13 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import +#import "ZXing/BarcodeFormat.h" +#import "ZXIFormat.h" + +NS_ASSUME_NONNULL_BEGIN + +ZXing::BarcodeFormat BarcodeFormatFromZXIFormat(ZXIFormat format); +ZXIFormat ZXIFormatFromBarcodeFormat(ZXing::BarcodeFormat format); +NS_ASSUME_NONNULL_END diff --git a/wrappers/ios/Sources/Wrapper/ZXIFormatHelper.mm b/wrappers/ios/Sources/Wrapper/ZXIFormatHelper.mm new file mode 100644 index 0000000000..457c6e551f --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/ZXIFormatHelper.mm @@ -0,0 +1,103 @@ +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +#import "ZXIFormatHelper.h" + +ZXing::BarcodeFormat BarcodeFormatFromZXIFormat(ZXIFormat format) { + switch (format) { + case ZXIFormat::ANY: + return ZXing::BarcodeFormat::Any; + case ZXIFormat::MATRIX_CODES: + return ZXing::BarcodeFormat::MatrixCodes; + case ZXIFormat::LINEAR_CODES: + return ZXing::BarcodeFormat::LinearCodes; + case ZXIFormat::UPC_E: + return ZXing::BarcodeFormat::UPCE; + case ZXIFormat::UPC_A: + return ZXing::BarcodeFormat::UPCA; + case ZXIFormat::QR_CODE: + return ZXing::BarcodeFormat::QRCode; + case ZXIFormat::PDF_417: + return ZXing::BarcodeFormat::PDF417; + case ZXIFormat::MAXICODE: + return ZXing::BarcodeFormat::MaxiCode; + case ZXIFormat::ITF: + return ZXing::BarcodeFormat::ITF; + case ZXIFormat::EAN_13: + return ZXing::BarcodeFormat::EAN13; + case ZXIFormat::EAN_8: + return ZXing::BarcodeFormat::EAN8; + case ZXIFormat::DATA_MATRIX: + return ZXing::BarcodeFormat::DataMatrix; + case ZXIFormat::DATA_BAR_EXPANDED: + return ZXing::BarcodeFormat::DataBarExpanded; + case ZXIFormat::DATA_BAR: + return ZXing::BarcodeFormat::DataBar; + case ZXIFormat::CODE_128: + return ZXing::BarcodeFormat::Code128; + case ZXIFormat::CODE_93: + return ZXing::BarcodeFormat::Code93; + case ZXIFormat::CODE_39: + return ZXing::BarcodeFormat::Code39; + case ZXIFormat::CODABAR: + return ZXing::BarcodeFormat::Codabar; + case ZXIFormat::AZTEC: + return ZXing::BarcodeFormat::Aztec; + case ZXIFormat::MICRO_QR_CODE: + return ZXing::BarcodeFormat::MicroQRCode; + case ZXIFormat::NONE: + return ZXing::BarcodeFormat::None; + } + NSLog(@"ZXIWrapper: Received invalid ZXIFormat, returning format: None"); + return ZXing::BarcodeFormat::None; +} + +ZXIFormat ZXIFormatFromBarcodeFormat(ZXing::BarcodeFormat format) { + switch (format) { + case ZXing::BarcodeFormat::None: + return ZXIFormat::NONE; + case ZXing::BarcodeFormat::Aztec: + return ZXIFormat::AZTEC; + case ZXing::BarcodeFormat::Codabar: + return ZXIFormat::CODABAR; + case ZXing::BarcodeFormat::Code39: + return ZXIFormat::CODE_39; + case ZXing::BarcodeFormat::Code93: + return ZXIFormat::CODE_93; + case ZXing::BarcodeFormat::Code128: + return ZXIFormat::CODE_128; + case ZXing::BarcodeFormat::DataBar: + return ZXIFormat::DATA_BAR; + case ZXing::BarcodeFormat::DataBarExpanded: + return ZXIFormat::DATA_BAR_EXPANDED; + case ZXing::BarcodeFormat::DataMatrix: + return ZXIFormat::DATA_MATRIX; + case ZXing::BarcodeFormat::EAN8: + return ZXIFormat::EAN_8; + case ZXing::BarcodeFormat::EAN13: + return ZXIFormat::EAN_13; + case ZXing::BarcodeFormat::ITF: + return ZXIFormat::ITF; + case ZXing::BarcodeFormat::MaxiCode: + return ZXIFormat::MAXICODE; + case ZXing::BarcodeFormat::PDF417: + return ZXIFormat::PDF_417; + case ZXing::BarcodeFormat::QRCode: + return ZXIFormat::QR_CODE; + case ZXing::BarcodeFormat::UPCA: + return ZXIFormat::UPC_A; + case ZXing::BarcodeFormat::UPCE: + return ZXIFormat::UPC_E; + case ZXing::BarcodeFormat::LinearCodes: + return ZXIFormat::LINEAR_CODES; + case ZXing::BarcodeFormat::MatrixCodes: + return ZXIFormat::MATRIX_CODES; + case ZXing::BarcodeFormat::MicroQRCode: + return ZXIFormat::MICRO_QR_CODE; + case ZXing::BarcodeFormat::Any: + return ZXIFormat::ANY; + } + NSLog(@"ZXIWrapper: Received invalid BarcodeFormat, returning format: None"); + return ZXIFormat::NONE; +} diff --git a/wrappers/ios/Sources/Wrapper/module.modulemap b/wrappers/ios/Sources/Wrapper/module.modulemap new file mode 100644 index 0000000000..f613294fc1 --- /dev/null +++ b/wrappers/ios/Sources/Wrapper/module.modulemap @@ -0,0 +1,6 @@ +module ZXingCppWrapper { + umbrella header "UmbrellaHeader.h" + export * + module * { export * } +} + diff --git a/wrappers/ios/build-release.sh b/wrappers/ios/build-release.sh new file mode 100755 index 0000000000..e8180c3d08 --- /dev/null +++ b/wrappers/ios/build-release.sh @@ -0,0 +1,36 @@ +echo ========= Remove previous builds +rm -rf _builds +rm -rf ZXingCpp.xcframework + +echo ========= Create project structure +cmake -S../../ -B_builds -GXcode \ + -DCMAKE_SYSTEM_NAME=iOS \ + "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 \ + -DCMAKE_INSTALL_PREFIX=`pwd`/_install \ + -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO \ + -DBUILD_UNIT_TESTS=NO \ + -DBUILD_BLACKBOX_TESTS=NO \ + -DBUILD_EXAMPLES=NO + +echo ========= Build the sdk for simulators +xcodebuild -project _builds/ZXing.xcodeproj build \ + -target ZXing \ + -parallelizeTargets \ + -configuration Release \ + -hideShellScriptEnvironment \ + -sdk iphonesimulator + +echo ========= Build the sdk for iOS +xcodebuild -project _builds/ZXing.xcodeproj build \ + -target ZXing \ + -parallelizeTargets \ + -configuration Release \ + -hideShellScriptEnvironment \ + -sdk iphoneos + +echo ========= Create the xcframework +xcodebuild -create-xcframework \ + -framework ./_builds/core/Release-iphonesimulator/ZXing.framework \ + -framework ./_builds/core/Release-iphoneos/ZXing.framework \ + -output ZXingCpp.xcframework diff --git a/wrappers/ios/demo/README.md b/wrappers/ios/demo/README.md new file mode 100644 index 0000000000..6d8a8ed41e --- /dev/null +++ b/wrappers/ios/demo/README.md @@ -0,0 +1,5 @@ +# ZXingWrapper Demo Project + +This demo-project sets up a basic `AVCaptureSession` and uses ZXing on the incoming frames. +You have to build the `ZXing.xcframework` before, by performing the `build-release.sh` script +in the parent-directory. diff --git a/wrappers/ios/demo/demo.xcodeproj/project.pbxproj b/wrappers/ios/demo/demo.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..204cd12fe1 --- /dev/null +++ b/wrappers/ios/demo/demo.xcodeproj/project.pbxproj @@ -0,0 +1,405 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 388BF029283CC49D005CE271 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 388BF028283CC49D005CE271 /* AppDelegate.swift */; }; + 388BF02B283CC49D005CE271 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 388BF02A283CC49D005CE271 /* SceneDelegate.swift */; }; + 388BF02D283CC49D005CE271 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 388BF02C283CC49D005CE271 /* ViewController.swift */; }; + 388BF030283CC49D005CE271 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 388BF02E283CC49D005CE271 /* Main.storyboard */; }; + 388BF032283CC49E005CE271 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 388BF031283CC49E005CE271 /* Assets.xcassets */; }; + 388BF035283CC49E005CE271 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 388BF033283CC49E005CE271 /* LaunchScreen.storyboard */; }; + 9507445028609C0500E02D06 /* ZXingCppWrapper in Frameworks */ = {isa = PBXBuildFile; productRef = 9507444F28609C0500E02D06 /* ZXingCppWrapper */; }; + 950744522860A3A300E02D06 /* WriteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950744512860A3A300E02D06 /* WriteViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 388BF025283CC49D005CE271 /* demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 388BF028283CC49D005CE271 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 388BF02A283CC49D005CE271 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 388BF02C283CC49D005CE271 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 388BF02F283CC49D005CE271 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 388BF031283CC49E005CE271 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 388BF034283CC49E005CE271 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 388BF036283CC49E005CE271 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 388BF043283CE0AC005CE271 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 950744512860A3A300E02D06 /* WriteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteViewController.swift; sourceTree = ""; }; + 9550105328609B7900ED103F /* ios */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = ios; path = ..; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 388BF022283CC49D005CE271 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9507445028609C0500E02D06 /* ZXingCppWrapper in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 388BF01C283CC49D005CE271 = { + isa = PBXGroup; + children = ( + 388BF043283CE0AC005CE271 /* README.md */, + 388BF03E283CD6C5005CE271 /* Packages */, + 388BF027283CC49D005CE271 /* demo */, + 388BF026283CC49D005CE271 /* Products */, + 388BF040283CD908005CE271 /* Frameworks */, + ); + sourceTree = ""; + }; + 388BF026283CC49D005CE271 /* Products */ = { + isa = PBXGroup; + children = ( + 388BF025283CC49D005CE271 /* demo.app */, + ); + name = Products; + sourceTree = ""; + }; + 388BF027283CC49D005CE271 /* demo */ = { + isa = PBXGroup; + children = ( + 388BF028283CC49D005CE271 /* AppDelegate.swift */, + 388BF02A283CC49D005CE271 /* SceneDelegate.swift */, + 388BF02C283CC49D005CE271 /* ViewController.swift */, + 950744512860A3A300E02D06 /* WriteViewController.swift */, + 388BF02E283CC49D005CE271 /* Main.storyboard */, + 388BF031283CC49E005CE271 /* Assets.xcassets */, + 388BF033283CC49E005CE271 /* LaunchScreen.storyboard */, + 388BF036283CC49E005CE271 /* Info.plist */, + ); + path = demo; + sourceTree = ""; + }; + 388BF03E283CD6C5005CE271 /* Packages */ = { + isa = PBXGroup; + children = ( + 9550105328609B7900ED103F /* ios */, + ); + name = Packages; + sourceTree = ""; + }; + 388BF040283CD908005CE271 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 388BF024283CC49D005CE271 /* demo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 388BF039283CC49E005CE271 /* Build configuration list for PBXNativeTarget "demo" */; + buildPhases = ( + 388BF021283CC49D005CE271 /* Sources */, + 388BF022283CC49D005CE271 /* Frameworks */, + 388BF023283CC49D005CE271 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = demo; + packageProductDependencies = ( + 9507444F28609C0500E02D06 /* ZXingCppWrapper */, + ); + productName = demo; + productReference = 388BF025283CC49D005CE271 /* demo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 388BF01D283CC49D005CE271 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1340; + LastUpgradeCheck = 1340; + TargetAttributes = { + 388BF024283CC49D005CE271 = { + CreatedOnToolsVersion = 13.4; + }; + }; + }; + buildConfigurationList = 388BF020283CC49D005CE271 /* Build configuration list for PBXProject "demo" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 388BF01C283CC49D005CE271; + productRefGroup = 388BF026283CC49D005CE271 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 388BF024283CC49D005CE271 /* demo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 388BF023283CC49D005CE271 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 388BF035283CC49E005CE271 /* LaunchScreen.storyboard in Resources */, + 388BF032283CC49E005CE271 /* Assets.xcassets in Resources */, + 388BF030283CC49D005CE271 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 388BF021283CC49D005CE271 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 388BF02D283CC49D005CE271 /* ViewController.swift in Sources */, + 388BF029283CC49D005CE271 /* AppDelegate.swift in Sources */, + 950744522860A3A300E02D06 /* WriteViewController.swift in Sources */, + 388BF02B283CC49D005CE271 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 388BF02E283CC49D005CE271 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 388BF02F283CC49D005CE271 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 388BF033283CC49E005CE271 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 388BF034283CC49E005CE271 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 388BF037283CC49E005CE271 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 388BF038283CC49E005CE271 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 388BF03A283CC49E005CE271 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = demo/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "Test ZXing"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.zxing-cpp.ios.demo-${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 388BF03B283CC49E005CE271 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = demo/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "Test ZXing"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.zxing-cpp.ios.demo-${SAMPLE_CODE_DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 388BF020283CC49D005CE271 /* Build configuration list for PBXProject "demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 388BF037283CC49E005CE271 /* Debug */, + 388BF038283CC49E005CE271 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 388BF039283CC49E005CE271 /* Build configuration list for PBXNativeTarget "demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 388BF03A283CC49E005CE271 /* Debug */, + 388BF03B283CC49E005CE271 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + 9507444F28609C0500E02D06 /* ZXingCppWrapper */ = { + isa = XCSwiftPackageProductDependency; + productName = ZXingCppWrapper; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 388BF01D283CC49D005CE271 /* Project object */; +} diff --git a/wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..919434a625 --- /dev/null +++ b/wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/wrappers/ios/demo/demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/wrappers/ios/demo/demo.xcodeproj/xcshareddata/xcschemes/demo.xcscheme b/wrappers/ios/demo/demo.xcodeproj/xcshareddata/xcschemes/demo.xcscheme new file mode 100644 index 0000000000..45b72fe64f --- /dev/null +++ b/wrappers/ios/demo/demo.xcodeproj/xcshareddata/xcschemes/demo.xcscheme @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/ios/demo/demo/AppDelegate.swift b/wrappers/ios/demo/demo/AppDelegate.swift new file mode 100644 index 0000000000..1b46e39eae --- /dev/null +++ b/wrappers/ios/demo/demo/AppDelegate.swift @@ -0,0 +1,35 @@ +// demo +// +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/wrappers/ios/demo/demo/Assets.xcassets/AccentColor.colorset/Contents.json b/wrappers/ios/demo/demo/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000000..eb87897008 --- /dev/null +++ b/wrappers/ios/demo/demo/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/wrappers/ios/demo/demo/Assets.xcassets/AppIcon.appiconset/Contents.json b/wrappers/ios/demo/demo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..5a3257a7d0 --- /dev/null +++ b/wrappers/ios/demo/demo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/wrappers/ios/demo/demo/Assets.xcassets/Contents.json b/wrappers/ios/demo/demo/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/wrappers/ios/demo/demo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/wrappers/ios/demo/demo/Base.lproj/LaunchScreen.storyboard b/wrappers/ios/demo/demo/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..865e9329f3 --- /dev/null +++ b/wrappers/ios/demo/demo/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/ios/demo/demo/Base.lproj/Main.storyboard b/wrappers/ios/demo/demo/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..68bbd506cf --- /dev/null +++ b/wrappers/ios/demo/demo/Base.lproj/Main.storyboard @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/ios/demo/demo/Info.plist b/wrappers/ios/demo/demo/Info.plist new file mode 100644 index 0000000000..dd3c9afdae --- /dev/null +++ b/wrappers/ios/demo/demo/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/wrappers/ios/demo/demo/SceneDelegate.swift b/wrappers/ios/demo/demo/SceneDelegate.swift new file mode 100644 index 0000000000..717ca0b219 --- /dev/null +++ b/wrappers/ios/demo/demo/SceneDelegate.swift @@ -0,0 +1,47 @@ +// demo +// +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } +} diff --git a/wrappers/ios/demo/demo/ViewController.swift b/wrappers/ios/demo/demo/ViewController.swift new file mode 100644 index 0000000000..4b4dd1e245 --- /dev/null +++ b/wrappers/ios/demo/demo/ViewController.swift @@ -0,0 +1,71 @@ +// demo +// +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +import UIKit +import AVFoundation +import ZXingCppWrapper + +class ViewController: UIViewController { + let captureSession = AVCaptureSession() + lazy var preview = AVCaptureVideoPreviewLayer(session: captureSession) + let queue = DispatchQueue(label: "com.zxing_cpp.ios.demo") + let reader = ZXIBarcodeReader() + let zxingLock = DispatchSemaphore(value: 1) + + override func viewDidLoad() { + super.viewDidLoad() + + self.preview.videoGravity = AVLayerVideoGravity.resizeAspectFill + self.preview.frame = self.view.layer.bounds + self.view.layer.addSublayer(self.preview) + + // setup camera session + self.requestAccess { + let discoverySession = AVCaptureDevice.DiscoverySession( + deviceTypes: [.builtInWideAngleCamera], + mediaType: AVMediaType.video, + position: .back) + + let device = discoverySession.devices.first! + let cameraInput = try! AVCaptureDeviceInput(device: device) + self.captureSession.beginConfiguration() + self.captureSession.addInput(cameraInput) + let videoDataOutput = AVCaptureVideoDataOutput() + videoDataOutput.setSampleBufferDelegate(self, queue: self.queue) + videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)] + videoDataOutput.alwaysDiscardsLateVideoFrames = true + self.captureSession.addOutput(videoDataOutput) + self.captureSession.commitConfiguration() + self.captureSession.startRunning() + } + } +} + +extension ViewController { + func requestAccess(_ completion: @escaping () -> Void) { + if AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == .notDetermined { + AVCaptureDevice.requestAccess(for: .video) { _ in + completion() + } + } else { + completion() + } + } +} + +extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate { + func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { + guard self.zxingLock.wait(timeout: DispatchTime.now()) == .success else { + // The previous image is still processed, drop the new one to prevent too much pressure + return + } + let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! + if let result = reader.read(imageBuffer).first { + print("Found barcode of format", result.format.rawValue, "with text", result.text) + } + self.zxingLock.signal() + } +} diff --git a/wrappers/ios/demo/demo/WriteViewController.swift b/wrappers/ios/demo/demo/WriteViewController.swift new file mode 100644 index 0000000000..8f1e1f28e8 --- /dev/null +++ b/wrappers/ios/demo/demo/WriteViewController.swift @@ -0,0 +1,25 @@ +// +// demo +// +// Copyright 2022 KURZ Digital Solutions GmbH +// +// SPDX-License-Identifier: Apache-2.0 + +import UIKit +import ZXingCppWrapper + +class WriteViewController: UIViewController { + @IBOutlet fileprivate var imageView: UIImageView! + + // MARK: - Actions + + @IBAction func textFieldChanged(_ sender: UITextField) { + guard let text = sender.text, + let image = try? ZXIBarcodeWriter().write(text, width: 200, height: 200, format: .QR_CODE) + else { + return + } + + imageView.image = UIImage(cgImage: image.takeRetainedValue()) + } +} From 987cc7e4623db236417a58bbcf9122c8ab0ae8be Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 8 Jul 2022 15:34:01 +0200 Subject: [PATCH 0384/1315] ZXAlgorithm: new general purpose ToString(int, len) helper --- core/src/ECI.cpp | 8 +++--- core/src/ZXAlgorithms.h | 11 ++++++++ core/src/maxicode/MCDecoder.cpp | 9 ------- core/src/oned/ODCode128Reader.cpp | 4 +-- core/src/oned/ODDataBarExpandedBitDecoder.cpp | 26 ++++++------------- core/src/oned/ODDataBarReader.cpp | 8 ++---- core/src/qrcode/QRDecoder.cpp | 6 ++--- wrappers/python/zxing.cpp | 4 +-- 8 files changed, 29 insertions(+), 47 deletions(-) diff --git a/core/src/ECI.cpp b/core/src/ECI.cpp index a8ee347009..f0ff259a66 100644 --- a/core/src/ECI.cpp +++ b/core/src/ECI.cpp @@ -5,9 +5,9 @@ #include "ECI.h" -#include +#include "ZXAlgorithms.h" + #include -#include namespace ZXing { @@ -47,9 +47,7 @@ static const std::map ECI_TO_CHARSET = { std::string ToString(ECI eci) { - std::ostringstream oss; - oss << '\\' << std::setw(6) << std::setfill('0') << ToInt(eci); - return oss.str(); + return '\\' + ToString(ToInt(eci), 6); } CharacterSet ToCharacterSet(ECI eci) diff --git a/core/src/ZXAlgorithms.h b/core/src/ZXAlgorithms.h index 7256119f2d..f5f61770cb 100644 --- a/core/src/ZXAlgorithms.h +++ b/core/src/ZXAlgorithms.h @@ -77,4 +77,15 @@ Value TransformReduce(const Container& c, Value s, UnaryOp op) { return s; } +template>> +std::string ToString(T n, int len) +{ + std::string result(len--, '0'); + for (T val = (n < 0) ? -n : n; len >= 0 && val != 0; --len, val /= 10) + result[len] = '0' + val % 10; + if (len >= 0 && n < 0) + result[0] = '-'; + return result; +} + } // ZXing diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 3022ba10bd..f0f26c68ca 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include @@ -158,13 +156,6 @@ static std::string GetPostCode3(const ByteArray& bytes) }; } -static std::string ToString(int x, int width) -{ - std::stringstream buf; - buf << std::setw(width) << std::setfill('0') << x; - return buf.str(); -} - static int GetCountry(const ByteArray& bytes) { return GetInt(bytes, {53, 54, 43, 44, 45, 46, 47, 48, 37, 38}); diff --git a/core/src/oned/ODCode128Reader.cpp b/core/src/oned/ODCode128Reader.cpp index e29703e3b2..d2614c29fc 100644 --- a/core/src/oned/ODCode128Reader.cpp +++ b/core/src/oned/ODCode128Reader.cpp @@ -87,9 +87,7 @@ class Raw2TxtDecoder if (codeSet == CODE_CODE_C) { if (code < 100) { - if (code < 10) - txt.push_back('0'); - txt.append(std::to_string(code)); + txt.append(ToString(code, 2)); } else if (code == CODE_FNC_1) { fnc1(true /*isCodeSetC*/); } else { diff --git a/core/src/oned/ODDataBarExpandedBitDecoder.cpp b/core/src/oned/ODDataBarExpandedBitDecoder.cpp index c31e7f681f..72fa11bef0 100644 --- a/core/src/oned/ODDataBarExpandedBitDecoder.cpp +++ b/core/src/oned/ODDataBarExpandedBitDecoder.cpp @@ -115,20 +115,10 @@ static std::string DecodeGeneralPurposeBits(BitArrayView& bits) return res; } -static void AppendNDigits(std::string& s, int v, int n) -{ - int div = std::pow(10, n-1); - while (v / div == 0 && div > 1) { - s.push_back('0'); - div /= 10; - } - s.append(std::to_string(v)); -} - static std::string DecodeCompressedGTIN(std::string prefix, BitArrayView& bits) { for (int i = 0; i < 4; ++i) - AppendNDigits(prefix, bits.readBits(10), 3); + prefix.append(ToString(bits.readBits(10), 3)); prefix.push_back(GTIN::ComputeCheckDigit(prefix.substr(2))); @@ -163,7 +153,7 @@ static std::string DecodeAI013103(BitArrayView& bits) { std::string buffer = DecodeAI01GTIN(bits); buffer.append("3103"); - AppendNDigits(buffer, bits.readBits(15), 6); + buffer.append(ToString(bits.readBits(15), 6)); return buffer; } @@ -173,7 +163,7 @@ static std::string DecodeAI01320x(BitArrayView& bits) std::string buffer = DecodeAI01GTIN(bits); int weight = bits.readBits(15); buffer.append(weight < 10000 ? "3202" : "3203"); - AppendNDigits(buffer, weight < 10000 ? weight : weight - 10000, 6); + buffer.append(ToString(weight < 10000 ? weight : weight - 10000, 6)); return buffer; } @@ -188,7 +178,7 @@ static std::string DecodeAI0139yx(BitArrayView& bits, char y) buffer.append(std::to_string(bits.readBits(2))); if (y == '3') - AppendNDigits(buffer, bits.readBits(10), 3); + buffer.append(ToString(bits.readBits(10), 3)); auto trailer = DecodeGeneralPurposeBits(bits); if (trailer.empty()) @@ -204,7 +194,7 @@ static std::string DecodeAI013x0x1x(BitArrayView& bits, const char* aiPrefix, co int weight = bits.readBits(20); buffer.append(std::to_string(weight / 100000)); - AppendNDigits(buffer, weight % 100000, 6); + buffer.append(ToString(weight % 100000, 6)); int date = bits.readBits(16); if (date != 38400) { @@ -216,9 +206,9 @@ static std::string DecodeAI013x0x1x(BitArrayView& bits, const char* aiPrefix, co date /= 12; int year = date; - AppendNDigits(buffer, year, 2); - AppendNDigits(buffer, month, 2); - AppendNDigits(buffer, day, 2); + buffer.append(ToString(year, 2)); + buffer.append(ToString(month, 2)); + buffer.append(ToString(day, 2)); } return buffer; diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index 5ed08e04b8..3945241dc6 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -14,8 +14,6 @@ #include "Result.h" #include "TextDecoder.h" -#include -#include #include namespace ZXing::OneD { @@ -138,10 +136,8 @@ static std::string ConstructText(Pair leftPair, Pair rightPair) { auto value = [](Pair p) { return 1597 * p.left.value + p.right.value; }; auto res = 4537077LL * value(leftPair) + value(rightPair); - std::ostringstream txt; - txt << std::setw(13) << std::setfill('0') << res; - txt << GTIN::ComputeCheckDigit(txt.str()); - return txt.str(); + auto txt = ToString(res, 13); + return txt + GTIN::ComputeCheckDigit(txt); } struct State : public RowReader::DecodingState diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 214583be5b..457bebac71 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -282,10 +282,8 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo throw FormatError("AIM Application Indicator (FNC1 in second position) at illegal position"); result.symbology.modifier = '5'; // As above // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position), "00-99" or "A-Za-z" - if (int appInd = bits.readBits(8); appInd < 10) // "00-09" - result += '0' + std::to_string(appInd); - else if (appInd < 100) // "10-99" - result += std::to_string(appInd); + if (int appInd = bits.readBits(8); appInd < 100) // "00-09" + result += ZXing::ToString(appInd, 2); else if ((appInd >= 165 && appInd <= 190) || (appInd >= 197 && appInd <= 222)) // "A-Za-z" result += narrow_cast(appInd - 100); else diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index cd204cde2b..f89ea0c4e7 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -149,8 +149,8 @@ PYBIND11_MODULE(zxingcpp, m) // see https://github.com/pybind/pybind11/issues/2221 .def("__or__", [](BarcodeFormat f1, BarcodeFormat f2){ return f1 | f2; }); pyBarcodeFormats - .def("__repr__", py::overload_cast(&ToString)) - .def("__str__", py::overload_cast(&ToString)) + .def("__repr__", py::overload_cast(static_cast(ToString))) + .def("__str__", py::overload_cast(static_cast(ToString))) .def("__eq__", [](BarcodeFormats f1, BarcodeFormats f2){ return f1 == f2; }) .def("__or__", [](BarcodeFormats fs, BarcodeFormat f){ return fs | f; }) .def(py::init()); From f3777a659ca28537a1cc07dc30a4914bae2ee770 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 13 Jul 2022 10:37:18 +0200 Subject: [PATCH 0385/1315] README: add link to new iOS wrapper --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b16bad4ba1..dfaf996082 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ * Android * WebAssembly * [Python](wrappers/python/README.md) + * [iOS](wrappers/ios/README.md) * [Flutter](https://pub.dev/packages/flutter_zxing) (external project) ## Supported Formats From 6b958aad91fc792ff778bf00d72cb7c87c09e287 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 13 Jul 2022 10:48:43 +0200 Subject: [PATCH 0386/1315] ZXAlgorithm: add missing include (fix build regression) --- core/src/ZXAlgorithms.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/ZXAlgorithms.h b/core/src/ZXAlgorithms.h index f5f61770cb..5b52f22e1a 100644 --- a/core/src/ZXAlgorithms.h +++ b/core/src/ZXAlgorithms.h @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace ZXing { From 69a43b6bb2d87aaa20b199fc4f3183d2aeea2758 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Jul 2022 02:32:45 +0200 Subject: [PATCH 0387/1315] README: put wrapper infos in separate REAME files --- README.md | 39 +++++--------------------------------- wrappers/android/README.md | 9 ++++++--- wrappers/wasm/README.md | 11 +++++++++++ wrappers/winrt/README.md | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 37 deletions(-) create mode 100644 wrappers/wasm/README.md create mode 100644 wrappers/winrt/README.md diff --git a/README.md b/README.md index dfaf996082..5d1e598e7b 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ * In pure C++17, no third-party dependencies (for the library) * Stateless, thread-safe readers/scanners and writers/generators * Wrapper/Bindings for: - * WinRT - * Android - * WebAssembly - * [Python](wrappers/python/README.md) + * [Android](wrappers/android/README.md) * [iOS](wrappers/ios/README.md) + * [Python](wrappers/python/README.md) + * [WebAssembly](wrappers/wasm/README.md) + * [WinRT](wrappers/winrt/README.md) * [Flutter](https://pub.dev/packages/flutter_zxing) (external project) ## Supported Formats @@ -49,37 +49,8 @@ As an example, have a look at [`ZXingWriter.cpp`](example/ZXingWriter.cpp). - [Write barcodes](https://nu-book.github.io/zxing-cpp/demo_writer.html) - [Scan with camera](https://nu-book.github.io/zxing-cpp/zxing_viddemo.html) -## WinRT Package -A nuget package is available for WinRT: [huycn.zxingcpp.winrt](https://www.nuget.org/packages/huycn.zxingcpp.winrt). -To install it, run the following command in the Package Manager Console -```sh -PM> Install-Package huycn.zxingcpp.winrt -``` - -## Build Instructions - -### Standard setup on Windows/macOS/Linux +## Build Instructions (for Windows/macOS/Linux) 1. Make sure [CMake](https://cmake.org) version 3.14 or newer is installed. 2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8 / gcc 7 / clang 5). 3. See the cmake `BUILD_...` options to enable the testing code, python wrapper, etc. -### Windows Universal Platform -1. Make sure [CMake](https://cmake.org) version 3.4 or newer is installed. -2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8). -3. Edit the file [`wrappers/winrt/BuildWinCom.bat`](wrappers/winrt/BuildWinCom.bat) to adjust the path to your CMake installation. -4. Double-click on the batch script to run it. -5. If the build succeeds, it will put the results in the folder UAP which is ready-to-use SDK extension. - -### Android -1. Install AndroidStudio including NDK and CMake (see 'SDK Tools'). -2. Open the project in folder [wrappers/android](wrappers/android). -3. The project contains 2 modules: `zxingcpp` is the wrapper library, `app` is the demo app using `zxingcpp`. - -### WebAssembly -1. [Install Emscripten](https://kripken.github.io/emscripten-site/docs/getting_started/) if not done already. -2. In an empty build folder, invoke `emcmake cmake `. -3. Invoke `cmake --build .` to create `zxing.js` and `zxing.wasm` (and `_reader`/`_writer` versions). -4. To see how to include these into a working HTML page, have a look at the [reader](wrappers/wasm/demo_reader.html) and [writer](wrappers/wasm/demo_writer.html) demos. -5. To quickly test your build, copy those demo files into your build directory and run e.g. `emrun --serve_after_close demo_reader.html`. - -You can also download the latest build output from the continuous integration system from the [Actions](https://github.com/nu-book/zxing-cpp/actions) tab. Look for 'wasm-artifacts'. Also check out the [live demos](https://nu-book.github.io/zxing-cpp/). diff --git a/wrappers/android/README.md b/wrappers/android/README.md index e6e67373ca..fd6e00d134 100644 --- a/wrappers/android/README.md +++ b/wrappers/android/README.md @@ -4,13 +4,16 @@ To use the Android (wrapper) library in other apps, it is easiest to build the library project and include the resulting AAR (Android Archive) file in your app. -## How to build and use +## Build -To build the AAR (Android Archive): +1. Install AndroidStudio including NDK and CMake (see 'SDK Tools'). +2. Open the project in folder [wrappers/android](wrappers/android). +3. The project contains 2 modules: `zxingcpp` is the wrapper library, `app` is the demo app using `zxingcpp`. + +To build the AAR (Android Archive) from the command line: $ ./gradlew :zxingcpp:assembleRelease Then copy `zxingcpp/build/outputs/aar/zxingcpp-release.aar` into `app/libs` of your app. -Check the included sample app on how to use `com.zxingcpp.BarcodeReader`. diff --git a/wrappers/wasm/README.md b/wrappers/wasm/README.md new file mode 100644 index 0000000000..a618a0503c --- /dev/null +++ b/wrappers/wasm/README.md @@ -0,0 +1,11 @@ +# WebAssembly/WASM Wrapper/Library + +## Build + +1. [Install Emscripten](https://kripken.github.io/emscripten-site/docs/getting_started/) if not done already. +2. In an empty build folder, invoke `emcmake cmake `. +3. Invoke `cmake --build .` to create `zxing.js` and `zxing.wasm` (and `_reader`/`_writer` versions). +4. To see how to include these into a working HTML page, have a look at the [reader](wrappers/wasm/demo_reader.html) and [writer](wrappers/wasm/demo_writer.html) demos. +5. To quickly test your build, copy those demo files into your build directory and run e.g. `emrun --serve_after_close demo_reader.html`. + +You can also download the latest build output from the continuous integration system from the [Actions](https://github.com/nu-book/zxing-cpp/actions) tab. Look for 'wasm-artifacts'. Also check out the [live demos](https://nu-book.github.io/zxing-cpp/). diff --git a/wrappers/winrt/README.md b/wrappers/winrt/README.md new file mode 100644 index 0000000000..0ca8abcaac --- /dev/null +++ b/wrappers/winrt/README.md @@ -0,0 +1,18 @@ +# WinRT Package/Wrapper + +## Install + +A nuget package is available for WinRT: [huycn.zxingcpp.winrt](https://www.nuget.org/packages/huycn.zxingcpp.winrt). +To install it, run the following command in the Package Manager Console +```sh +PM> Install-Package huycn.zxingcpp.winrt +``` + +## Build + +1. Make sure [CMake](https://cmake.org) version 3.4 or newer is installed. +2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8). +3. Edit the file [`BuildWinCom.bat`](wrappers/winrt/BuildWinCom.bat) to adjust the path to your CMake installation. +4. Double-click on the batch script to run it. +5. If the build succeeds, it will put the results in the folder UAP which is ready-to-use SDK extension. + From 549974f6e063dab69227e92e42378c84e921a2c9 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Jul 2022 02:39:23 +0200 Subject: [PATCH 0388/1315] README: fix links to local files --- wrappers/android/README.md | 5 ++--- wrappers/wasm/README.md | 2 +- wrappers/winrt/README.md | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/wrappers/android/README.md b/wrappers/android/README.md index fd6e00d134..448f53e871 100644 --- a/wrappers/android/README.md +++ b/wrappers/android/README.md @@ -7,13 +7,12 @@ Archive) file in your app. ## Build 1. Install AndroidStudio including NDK and CMake (see 'SDK Tools'). -2. Open the project in folder [wrappers/android](wrappers/android). +2. Open the project in folder containing this README. 3. The project contains 2 modules: `zxingcpp` is the wrapper library, `app` is the demo app using `zxingcpp`. To build the AAR (Android Archive) from the command line: $ ./gradlew :zxingcpp:assembleRelease -Then copy `zxingcpp/build/outputs/aar/zxingcpp-release.aar` into -`app/libs` of your app. +Then copy `zxingcpp/build/outputs/aar/zxingcpp-release.aar` into `app/libs` of your app. diff --git a/wrappers/wasm/README.md b/wrappers/wasm/README.md index a618a0503c..117c38dc6e 100644 --- a/wrappers/wasm/README.md +++ b/wrappers/wasm/README.md @@ -5,7 +5,7 @@ 1. [Install Emscripten](https://kripken.github.io/emscripten-site/docs/getting_started/) if not done already. 2. In an empty build folder, invoke `emcmake cmake `. 3. Invoke `cmake --build .` to create `zxing.js` and `zxing.wasm` (and `_reader`/`_writer` versions). -4. To see how to include these into a working HTML page, have a look at the [reader](wrappers/wasm/demo_reader.html) and [writer](wrappers/wasm/demo_writer.html) demos. +4. To see how to include these into a working HTML page, have a look at the [reader](demo_reader.html) and [writer](demo_writer.html) demos. 5. To quickly test your build, copy those demo files into your build directory and run e.g. `emrun --serve_after_close demo_reader.html`. You can also download the latest build output from the continuous integration system from the [Actions](https://github.com/nu-book/zxing-cpp/actions) tab. Look for 'wasm-artifacts'. Also check out the [live demos](https://nu-book.github.io/zxing-cpp/). diff --git a/wrappers/winrt/README.md b/wrappers/winrt/README.md index 0ca8abcaac..ff16da34c1 100644 --- a/wrappers/winrt/README.md +++ b/wrappers/winrt/README.md @@ -12,7 +12,7 @@ PM> Install-Package huycn.zxingcpp.winrt 1. Make sure [CMake](https://cmake.org) version 3.4 or newer is installed. 2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8). -3. Edit the file [`BuildWinCom.bat`](wrappers/winrt/BuildWinCom.bat) to adjust the path to your CMake installation. +3. Edit the file [`BuildWinCom.bat`](BuildWinCom.bat) to adjust the path to your CMake installation. 4. Double-click on the batch script to run it. 5. If the build succeeds, it will put the results in the folder UAP which is ready-to-use SDK extension. From 79885f19bed32c6d6d70373426627a32e2052c2a Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Jul 2022 11:58:34 +0200 Subject: [PATCH 0389/1315] DataBarExpanded: return standard conforming text instead of HRI This is a breaking change. It fixes the problem that the DataBarExpanded reader would implicitly return the "human readable interpretation" of the content instead of the spec conforming string (see the section "4. Scanned GS1 barcode data" in https://www.linkedin.com/pulse/gs1-application-identifier-syntax-dictionary-terry-burton/ A later change will allow to somehow specify that the HRI shall be returned as text. You may use the existing function `HRIFromGS1()` from `GS1.h` in the meantime. --- core/src/oned/ODDataBarExpandedReader.cpp | 5 ++--- test/blackbox/BlackboxTestRunner.cpp | 5 ++--- test/samples/rssexpanded-1/1.txt | 2 +- test/samples/rssexpanded-1/10-corrected.txt | 2 +- test/samples/rssexpanded-1/10.txt | 2 +- test/samples/rssexpanded-1/11.txt | 2 +- test/samples/rssexpanded-1/12.txt | 2 +- test/samples/rssexpanded-1/13.txt | 2 +- test/samples/rssexpanded-1/14.txt | 2 +- test/samples/rssexpanded-1/15.txt | 2 +- test/samples/rssexpanded-1/16.txt | 2 +- test/samples/rssexpanded-1/17.txt | 2 +- test/samples/rssexpanded-1/18.txt | 2 +- test/samples/rssexpanded-1/19.txt | 2 +- test/samples/rssexpanded-1/2.txt | 2 +- test/samples/rssexpanded-1/20.txt | 2 +- test/samples/rssexpanded-1/21.txt | 2 +- test/samples/rssexpanded-1/22.txt | 2 +- test/samples/rssexpanded-1/23.txt | 2 +- test/samples/rssexpanded-1/24.txt | 2 +- test/samples/rssexpanded-1/25.txt | 2 +- test/samples/rssexpanded-1/26.txt | 2 +- test/samples/rssexpanded-1/27.txt | 2 +- test/samples/rssexpanded-1/28.txt | 2 +- test/samples/rssexpanded-1/29.txt | 2 +- test/samples/rssexpanded-1/3.txt | 2 +- test/samples/rssexpanded-1/30.txt | 2 +- test/samples/rssexpanded-1/31.txt | 2 +- test/samples/rssexpanded-1/32.txt | 2 +- test/samples/rssexpanded-1/4.txt | 2 +- test/samples/rssexpanded-1/5.txt | 2 +- test/samples/rssexpanded-1/6.txt | 2 +- test/samples/rssexpanded-1/7.txt | 2 +- test/samples/rssexpanded-1/8.txt | 2 +- test/samples/rssexpanded-1/9.txt | 2 +- test/samples/rssexpanded-2/12.txt | 2 +- test/samples/rssexpanded-2/16.txt | 2 +- test/samples/rssexpanded-2/17.txt | 2 +- test/samples/rssexpanded-2/18.txt | 2 +- test/samples/rssexpanded-2/3_01.txt | 2 +- test/samples/rssexpanded-2/3_02.txt | 2 +- test/samples/rssexpanded-2/3_05.txt | 2 +- test/samples/rssexpanded-2/3_06.txt | 2 +- test/samples/rssexpanded-2/3_07.txt | 2 +- test/samples/rssexpanded-2/3_09.txt | 2 +- test/samples/rssexpanded-2/4_00.txt | 2 +- test/samples/rssexpanded-2/4_02.txt | 2 +- test/samples/rssexpanded-2/4_03.txt | 2 +- test/samples/rssexpanded-2/4_04.txt | 2 +- test/samples/rssexpanded-2/5.txt | 2 +- test/samples/rssexpanded-3/1.txt | 2 +- test/samples/rssexpanded-3/10.txt | 2 +- test/samples/rssexpanded-3/100.txt | 2 +- test/samples/rssexpanded-3/101.txt | 2 +- test/samples/rssexpanded-3/102.txt | 2 +- test/samples/rssexpanded-3/103.txt | 2 +- test/samples/rssexpanded-3/104.txt | 2 +- test/samples/rssexpanded-3/105.txt | 2 +- test/samples/rssexpanded-3/106.txt | 2 +- test/samples/rssexpanded-3/107.txt | 2 +- test/samples/rssexpanded-3/108-corrected.txt | 2 +- test/samples/rssexpanded-3/108.txt | 2 +- test/samples/rssexpanded-3/109.txt | 2 +- test/samples/rssexpanded-3/11.txt | 2 +- test/samples/rssexpanded-3/110.txt | 2 +- test/samples/rssexpanded-3/111.txt | 2 +- test/samples/rssexpanded-3/112.txt | 2 +- test/samples/rssexpanded-3/113.txt | 2 +- test/samples/rssexpanded-3/114.txt | 2 +- test/samples/rssexpanded-3/115.txt | 2 +- test/samples/rssexpanded-3/116.txt | 2 +- test/samples/rssexpanded-3/117.txt | 2 +- test/samples/rssexpanded-3/12.txt | 2 +- test/samples/rssexpanded-3/13.txt | 2 +- test/samples/rssexpanded-3/14.txt | 2 +- test/samples/rssexpanded-3/15.txt | 2 +- test/samples/rssexpanded-3/16.txt | 2 +- test/samples/rssexpanded-3/17.txt | 2 +- test/samples/rssexpanded-3/18.txt | 2 +- test/samples/rssexpanded-3/19.txt | 2 +- test/samples/rssexpanded-3/2.txt | 2 +- test/samples/rssexpanded-3/20.txt | 2 +- test/samples/rssexpanded-3/21.txt | 2 +- test/samples/rssexpanded-3/22.txt | 2 +- test/samples/rssexpanded-3/23.txt | 2 +- test/samples/rssexpanded-3/24.txt | 2 +- test/samples/rssexpanded-3/25.txt | 2 +- test/samples/rssexpanded-3/26.txt | 2 +- test/samples/rssexpanded-3/27.txt | 2 +- test/samples/rssexpanded-3/28.txt | 2 +- test/samples/rssexpanded-3/29.txt | 2 +- test/samples/rssexpanded-3/3.txt | 2 +- test/samples/rssexpanded-3/30.txt | 2 +- test/samples/rssexpanded-3/31.txt | 2 +- test/samples/rssexpanded-3/32.txt | 2 +- test/samples/rssexpanded-3/33.txt | 2 +- test/samples/rssexpanded-3/34.txt | 2 +- test/samples/rssexpanded-3/35.txt | 2 +- test/samples/rssexpanded-3/36.txt | 2 +- test/samples/rssexpanded-3/37.txt | 2 +- test/samples/rssexpanded-3/38.txt | 2 +- test/samples/rssexpanded-3/39.txt | 2 +- test/samples/rssexpanded-3/4.txt | 2 +- test/samples/rssexpanded-3/40.txt | 2 +- test/samples/rssexpanded-3/41.txt | 2 +- test/samples/rssexpanded-3/42.txt | 2 +- test/samples/rssexpanded-3/43.txt | 2 +- test/samples/rssexpanded-3/44.txt | 2 +- test/samples/rssexpanded-3/45.txt | 2 +- test/samples/rssexpanded-3/46.txt | 2 +- test/samples/rssexpanded-3/47.txt | 2 +- test/samples/rssexpanded-3/48.txt | 2 +- test/samples/rssexpanded-3/49.txt | 2 +- test/samples/rssexpanded-3/5.txt | 2 +- test/samples/rssexpanded-3/50.txt | 2 +- test/samples/rssexpanded-3/51.txt | 2 +- test/samples/rssexpanded-3/52.txt | 2 +- test/samples/rssexpanded-3/53.txt | 2 +- test/samples/rssexpanded-3/54.txt | 2 +- test/samples/rssexpanded-3/55.txt | 2 +- test/samples/rssexpanded-3/56.txt | 2 +- test/samples/rssexpanded-3/57.txt | 2 +- test/samples/rssexpanded-3/58.txt | 2 +- test/samples/rssexpanded-3/59.txt | 2 +- test/samples/rssexpanded-3/6.txt | 2 +- test/samples/rssexpanded-3/60.txt | 2 +- test/samples/rssexpanded-3/61.txt | 2 +- test/samples/rssexpanded-3/62.txt | 2 +- test/samples/rssexpanded-3/63.txt | 2 +- test/samples/rssexpanded-3/64.txt | 2 +- test/samples/rssexpanded-3/65.txt | 2 +- test/samples/rssexpanded-3/66.txt | 2 +- test/samples/rssexpanded-3/67.txt | 2 +- test/samples/rssexpanded-3/68.txt | 2 +- test/samples/rssexpanded-3/69.txt | 2 +- test/samples/rssexpanded-3/7.txt | 2 +- test/samples/rssexpanded-3/70.txt | 2 +- test/samples/rssexpanded-3/71.txt | 2 +- test/samples/rssexpanded-3/72.txt | 2 +- test/samples/rssexpanded-3/73.txt | 2 +- test/samples/rssexpanded-3/74.txt | 2 +- test/samples/rssexpanded-3/75.txt | 2 +- test/samples/rssexpanded-3/76.txt | 2 +- test/samples/rssexpanded-3/77.txt | 2 +- test/samples/rssexpanded-3/78.txt | 2 +- test/samples/rssexpanded-3/79.txt | 2 +- test/samples/rssexpanded-3/8.txt | 2 +- test/samples/rssexpanded-3/80.txt | 2 +- test/samples/rssexpanded-3/81.txt | 2 +- test/samples/rssexpanded-3/82.txt | 2 +- test/samples/rssexpanded-3/83.txt | 2 +- test/samples/rssexpanded-3/84.txt | 2 +- test/samples/rssexpanded-3/85.txt | 2 +- test/samples/rssexpanded-3/86.txt | 2 +- test/samples/rssexpanded-3/87.txt | 2 +- test/samples/rssexpanded-3/88.txt | 2 +- test/samples/rssexpanded-3/89.txt | 2 +- test/samples/rssexpanded-3/9.txt | 2 +- test/samples/rssexpanded-3/90.txt | 2 +- test/samples/rssexpanded-3/91.txt | 2 +- test/samples/rssexpanded-3/92.txt | 2 +- test/samples/rssexpanded-3/93.txt | 2 +- test/samples/rssexpanded-3/94.txt | 2 +- test/samples/rssexpanded-3/95.txt | 2 +- test/samples/rssexpanded-3/96.txt | 2 +- test/samples/rssexpanded-3/97.txt | 2 +- test/samples/rssexpanded-3/98.txt | 2 +- test/samples/rssexpanded-3/99.txt | 2 +- test/samples/rssexpandedstacked-1/1.txt | 2 +- test/samples/rssexpandedstacked-1/10.txt | 2 +- test/samples/rssexpandedstacked-1/11.txt | 2 +- test/samples/rssexpandedstacked-1/12.txt | 2 +- test/samples/rssexpandedstacked-1/13.txt | 2 +- test/samples/rssexpandedstacked-1/14.txt | 2 +- test/samples/rssexpandedstacked-1/15.txt | 2 +- test/samples/rssexpandedstacked-1/16.txt | 2 +- test/samples/rssexpandedstacked-1/17.txt | 2 +- test/samples/rssexpandedstacked-1/18.txt | 2 +- test/samples/rssexpandedstacked-1/19.txt | 2 +- test/samples/rssexpandedstacked-1/2.txt | 2 +- test/samples/rssexpandedstacked-1/20.txt | 2 +- test/samples/rssexpandedstacked-1/21.txt | 2 +- test/samples/rssexpandedstacked-1/22.txt | 2 +- test/samples/rssexpandedstacked-1/23.txt | 2 +- test/samples/rssexpandedstacked-1/24.txt | 2 +- test/samples/rssexpandedstacked-1/25.txt | 2 +- test/samples/rssexpandedstacked-1/26.txt | 2 +- test/samples/rssexpandedstacked-1/27.txt | 2 +- test/samples/rssexpandedstacked-1/28.txt | 2 +- test/samples/rssexpandedstacked-1/29.txt | 2 +- test/samples/rssexpandedstacked-1/3.txt | 2 +- test/samples/rssexpandedstacked-1/30.txt | 2 +- test/samples/rssexpandedstacked-1/31.txt | 2 +- test/samples/rssexpandedstacked-1/32.txt | 2 +- test/samples/rssexpandedstacked-1/33.txt | 2 +- test/samples/rssexpandedstacked-1/34.txt | 2 +- test/samples/rssexpandedstacked-1/35.txt | 2 +- test/samples/rssexpandedstacked-1/36.txt | 2 +- test/samples/rssexpandedstacked-1/37.txt | 2 +- test/samples/rssexpandedstacked-1/38.txt | 2 +- test/samples/rssexpandedstacked-1/39.txt | 2 +- test/samples/rssexpandedstacked-1/4.txt | 2 +- test/samples/rssexpandedstacked-1/40.txt | 2 +- test/samples/rssexpandedstacked-1/41.txt | 2 +- test/samples/rssexpandedstacked-1/42.txt | 2 +- test/samples/rssexpandedstacked-1/43.txt | 2 +- test/samples/rssexpandedstacked-1/44.txt | 2 +- test/samples/rssexpandedstacked-1/45.txt | 2 +- test/samples/rssexpandedstacked-1/46.txt | 2 +- test/samples/rssexpandedstacked-1/47.txt | 2 +- test/samples/rssexpandedstacked-1/48.txt | 2 +- test/samples/rssexpandedstacked-1/49.txt | 2 +- test/samples/rssexpandedstacked-1/5.txt | 2 +- test/samples/rssexpandedstacked-1/50.txt | 2 +- test/samples/rssexpandedstacked-1/51.txt | 2 +- test/samples/rssexpandedstacked-1/52.txt | 2 +- test/samples/rssexpandedstacked-1/53.txt | 2 +- test/samples/rssexpandedstacked-1/54.txt | 2 +- test/samples/rssexpandedstacked-1/55-corrected.txt | 2 +- test/samples/rssexpandedstacked-1/55.txt | 2 +- test/samples/rssexpandedstacked-1/56.txt | 2 +- test/samples/rssexpandedstacked-1/57.txt | 2 +- test/samples/rssexpandedstacked-1/58.txt | 2 +- test/samples/rssexpandedstacked-1/59.txt | 2 +- test/samples/rssexpandedstacked-1/6.txt | 2 +- test/samples/rssexpandedstacked-1/60.txt | 2 +- test/samples/rssexpandedstacked-1/61.txt | 2 +- test/samples/rssexpandedstacked-1/62.txt | 2 +- test/samples/rssexpandedstacked-1/63.txt | 2 +- test/samples/rssexpandedstacked-1/64.txt | 2 +- test/samples/rssexpandedstacked-1/7.txt | 2 +- test/samples/rssexpandedstacked-1/8.txt | 2 +- test/samples/rssexpandedstacked-1/9.txt | 2 +- test/samples/rssexpandedstacked-2/1.txt | 2 +- test/samples/rssexpandedstacked-2/1000.txt | 2 +- test/unit/ThresholdBinarizerTest.cpp | 2 +- 236 files changed, 238 insertions(+), 240 deletions(-) diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 0c48723bb3..02aec2a3ad 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -366,8 +366,6 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, #endif auto txt = DecodeExpandedBits(BuildBitArray(pairs)); - // TODO: remove this to make it return standard conform content -> needs lots of blackbox test fixes - txt = HRIFromGS1(txt); if (txt.empty()) return {}; @@ -376,7 +374,8 @@ Result DataBarExpandedReader::decodePattern(int rowNumber, PatternView& view, // TODO: EstimatePosition misses part of the symbol in the stacked case where the last row contains less pairs than // the first // Symbology identifier: ISO/IEC 24724:2011 Section 9 and GS1 General Specifications 5.1.3 Figure 5.1.3-2 - return {DecoderResult(Content(ByteArray(txt), {'e', '0'})).setLineCount(EstimateLineCount(pairs.front(), pairs.back())), + return {DecoderResult(Content(ByteArray(txt), {'e', '0', 0, AIFlag::GS1})) + .setLineCount(EstimateLineCount(pairs.front(), pairs.back())), EstimatePosition(pairs.front(), pairs.back()), BarcodeFormat::DataBarExpanded}; } diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index aec499faa4..c42a0217a9 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -532,9 +532,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("rssexpandedstacked-1", "DataBarExpanded", 65, { - // TODO: See HRIFromGS1. 13.png is seemingly invalid symbol - { 60, 64, 0 }, - { 60, 64, 180 }, + { 60, 65, 0 }, + { 60, 65, 180 }, { 60, 0, pure }, }); diff --git a/test/samples/rssexpanded-1/1.txt b/test/samples/rssexpanded-1/1.txt index 8b369b3072..199a948919 100644 --- a/test/samples/rssexpanded-1/1.txt +++ b/test/samples/rssexpanded-1/1.txt @@ -1 +1 @@ -(11)100224(17)110224(3102)000100 \ No newline at end of file +11100224171102243102000100 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/10-corrected.txt b/test/samples/rssexpanded-1/10-corrected.txt index 09d4208414..b0885acaa8 100644 --- a/test/samples/rssexpanded-1/10-corrected.txt +++ b/test/samples/rssexpanded-1/10-corrected.txt @@ -1 +1 @@ -(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901 \ No newline at end of file +01988987654321061599123131030017501012A42212321123456423012345678901 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/10.txt b/test/samples/rssexpanded-1/10.txt index 09d4208414..b0885acaa8 100644 --- a/test/samples/rssexpanded-1/10.txt +++ b/test/samples/rssexpanded-1/10.txt @@ -1 +1 @@ -(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901 \ No newline at end of file +01988987654321061599123131030017501012A42212321123456423012345678901 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/11.txt b/test/samples/rssexpanded-1/11.txt index abe2a8162c..ea688c19b9 100644 --- a/test/samples/rssexpanded-1/11.txt +++ b/test/samples/rssexpanded-1/11.txt @@ -1 +1 @@ -(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456 \ No newline at end of file +01988987654321061599123131030017501012A42212321123456 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/12.txt b/test/samples/rssexpanded-1/12.txt index 32ad2dae6b..9b255f97f0 100644 --- a/test/samples/rssexpanded-1/12.txt +++ b/test/samples/rssexpanded-1/12.txt @@ -1 +1 @@ -(01)98898765432106(3103)001750 \ No newline at end of file +01988987654321063103001750 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/13.txt b/test/samples/rssexpanded-1/13.txt index dd36aabdc1..1d29f26188 100644 --- a/test/samples/rssexpanded-1/13.txt +++ b/test/samples/rssexpanded-1/13.txt @@ -1 +1 @@ -(01)90012345678908(3922)795 \ No newline at end of file +01900123456789083922795 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/14.txt b/test/samples/rssexpanded-1/14.txt index fb00e311f8..1be59ac1f7 100644 --- a/test/samples/rssexpanded-1/14.txt +++ b/test/samples/rssexpanded-1/14.txt @@ -1 +1 @@ -(01)90012345678908(3932)0401234 \ No newline at end of file +019001234567890839320401234 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/15.txt b/test/samples/rssexpanded-1/15.txt index f2bfc4b94a..4d6883fbfa 100644 --- a/test/samples/rssexpanded-1/15.txt +++ b/test/samples/rssexpanded-1/15.txt @@ -1 +1 @@ -(01)90012345678908(3102)001750(11)100312 \ No newline at end of file +0190012345678908310200175011100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/16.txt b/test/samples/rssexpanded-1/16.txt index c9f248d08f..082bbe5436 100644 --- a/test/samples/rssexpanded-1/16.txt +++ b/test/samples/rssexpanded-1/16.txt @@ -1 +1 @@ -(01)90012345678908(3202)001750(11)100312 \ No newline at end of file +0190012345678908320200175011100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/17.txt b/test/samples/rssexpanded-1/17.txt index 9b4fc495ed..8df804363c 100644 --- a/test/samples/rssexpanded-1/17.txt +++ b/test/samples/rssexpanded-1/17.txt @@ -1 +1 @@ -(01)90012345678908(3102)001750(13)100312 \ No newline at end of file +0190012345678908310200175013100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/18.txt b/test/samples/rssexpanded-1/18.txt index cd15aa06cf..fd734e7794 100644 --- a/test/samples/rssexpanded-1/18.txt +++ b/test/samples/rssexpanded-1/18.txt @@ -1 +1 @@ -(01)90012345678908(3202)001750(13)100312 \ No newline at end of file +0190012345678908320200175013100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/19.txt b/test/samples/rssexpanded-1/19.txt index dcd156138f..b973bbdcdd 100644 --- a/test/samples/rssexpanded-1/19.txt +++ b/test/samples/rssexpanded-1/19.txt @@ -1 +1 @@ -(01)90012345678908(3102)001750(15)100312 \ No newline at end of file +0190012345678908310200175015100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/2.txt b/test/samples/rssexpanded-1/2.txt index b4113ac56d..aee1d62673 100644 --- a/test/samples/rssexpanded-1/2.txt +++ b/test/samples/rssexpanded-1/2.txt @@ -1 +1 @@ -(01)90012345678908(3103)001750 \ No newline at end of file +01900123456789083103001750 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/20.txt b/test/samples/rssexpanded-1/20.txt index 830845fe76..28f915983d 100644 --- a/test/samples/rssexpanded-1/20.txt +++ b/test/samples/rssexpanded-1/20.txt @@ -1 +1 @@ -(01)90012345678908(3202)001750(15)100312 \ No newline at end of file +0190012345678908320200175015100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/21.txt b/test/samples/rssexpanded-1/21.txt index 506b17bcd1..b7dfdd3d78 100644 --- a/test/samples/rssexpanded-1/21.txt +++ b/test/samples/rssexpanded-1/21.txt @@ -1 +1 @@ -(01)90012345678908(3102)001750(17)100312 \ No newline at end of file +0190012345678908310200175017100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/22.txt b/test/samples/rssexpanded-1/22.txt index ca6045a645..32c140cc28 100644 --- a/test/samples/rssexpanded-1/22.txt +++ b/test/samples/rssexpanded-1/22.txt @@ -1 +1 @@ -(01)90012345678908(3202)001750(17)100312 \ No newline at end of file +0190012345678908320200175017100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/23.txt b/test/samples/rssexpanded-1/23.txt index a6f7e240e9..8f58a2c719 100644 --- a/test/samples/rssexpanded-1/23.txt +++ b/test/samples/rssexpanded-1/23.txt @@ -1 +1 @@ -(10)56789(11)010101 \ No newline at end of file +105678911010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/24.txt b/test/samples/rssexpanded-1/24.txt index a7b34974c6..b236cb3daf 100644 --- a/test/samples/rssexpanded-1/24.txt +++ b/test/samples/rssexpanded-1/24.txt @@ -1 +1 @@ -(10)567890(11)010101 \ No newline at end of file +1056789011010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/25.txt b/test/samples/rssexpanded-1/25.txt index 62c17f167c..3bbd5e5122 100644 --- a/test/samples/rssexpanded-1/25.txt +++ b/test/samples/rssexpanded-1/25.txt @@ -1 +1 @@ -(10)123 \ No newline at end of file +10123 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/26.txt b/test/samples/rssexpanded-1/26.txt index 17966ee8b2..efff0d4aee 100644 --- a/test/samples/rssexpanded-1/26.txt +++ b/test/samples/rssexpanded-1/26.txt @@ -1 +1 @@ -(10)5678(11)010101 \ No newline at end of file +10567811010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/27.txt b/test/samples/rssexpanded-1/27.txt index 5263f7fc5a..a6113cbe0a 100644 --- a/test/samples/rssexpanded-1/27.txt +++ b/test/samples/rssexpanded-1/27.txt @@ -1 +1 @@ -(10)1098-1234 \ No newline at end of file +101098-1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/28.txt b/test/samples/rssexpanded-1/28.txt index 9208d92acb..4921a3252a 100644 --- a/test/samples/rssexpanded-1/28.txt +++ b/test/samples/rssexpanded-1/28.txt @@ -1 +1 @@ -(10)1098/1234 \ No newline at end of file +101098/1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/29.txt b/test/samples/rssexpanded-1/29.txt index b78623a34f..37d26ab8ed 100644 --- a/test/samples/rssexpanded-1/29.txt +++ b/test/samples/rssexpanded-1/29.txt @@ -1 +1 @@ -(10)1098.1234 \ No newline at end of file +101098.1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/3.txt b/test/samples/rssexpanded-1/3.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-1/3.txt +++ b/test/samples/rssexpanded-1/3.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-1/30.txt b/test/samples/rssexpanded-1/30.txt index 82bfa6ae93..9bb5c079c3 100644 --- a/test/samples/rssexpanded-1/30.txt +++ b/test/samples/rssexpanded-1/30.txt @@ -1 +1 @@ -(10)1098*1234 \ No newline at end of file +101098*1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/31.txt b/test/samples/rssexpanded-1/31.txt index f6413d5df5..203ccbb336 100644 --- a/test/samples/rssexpanded-1/31.txt +++ b/test/samples/rssexpanded-1/31.txt @@ -1 +1 @@ -(10)1098,1234 \ No newline at end of file +101098,1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/32.txt b/test/samples/rssexpanded-1/32.txt index 5e76631589..8f35538c43 100644 --- a/test/samples/rssexpanded-1/32.txt +++ b/test/samples/rssexpanded-1/32.txt @@ -1 +1 @@ -(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012 \ No newline at end of file +1599123131030017501012A422123211234564230123456789012 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/4.txt b/test/samples/rssexpanded-1/4.txt index 4e8655ca59..395fb680dc 100644 --- a/test/samples/rssexpanded-1/4.txt +++ b/test/samples/rssexpanded-1/4.txt @@ -1 +1 @@ -(01)98898765432106(3202)012345(15)991231 \ No newline at end of file +0198898765432106320201234515991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/5.txt b/test/samples/rssexpanded-1/5.txt index 4a708608fb..cc3ec9d4ff 100644 --- a/test/samples/rssexpanded-1/5.txt +++ b/test/samples/rssexpanded-1/5.txt @@ -1 +1 @@ -(01)90614141000015(3202)000150 \ No newline at end of file +01906141410000153202000150 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/6.txt b/test/samples/rssexpanded-1/6.txt index 84f8807633..a0bb85e2ca 100644 --- a/test/samples/rssexpanded-1/6.txt +++ b/test/samples/rssexpanded-1/6.txt @@ -1 +1 @@ -(10)567(01)90012345678908(11)010101 \ No newline at end of file +10567019001234567890811010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/7.txt b/test/samples/rssexpanded-1/7.txt index e8c72688f3..258e2f0334 100644 --- a/test/samples/rssexpanded-1/7.txt +++ b/test/samples/rssexpanded-1/7.txt @@ -1 +1 @@ -(10)567(11)010101 \ No newline at end of file +1056711010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/8.txt b/test/samples/rssexpanded-1/8.txt index 56981cdffc..aeec179cc2 100644 --- a/test/samples/rssexpanded-1/8.txt +++ b/test/samples/rssexpanded-1/8.txt @@ -1 +1 @@ -(10)567(11)010101(13)010101 \ No newline at end of file +105671101010113010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-1/9.txt b/test/samples/rssexpanded-1/9.txt index 84cf63cb89..0aa62050c9 100644 --- a/test/samples/rssexpanded-1/9.txt +++ b/test/samples/rssexpanded-1/9.txt @@ -1 +1 @@ -(10)567(3102)123456 \ No newline at end of file +105673102123456 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/12.txt b/test/samples/rssexpanded-2/12.txt index 32ad2dae6b..9b255f97f0 100644 --- a/test/samples/rssexpanded-2/12.txt +++ b/test/samples/rssexpanded-2/12.txt @@ -1 +1 @@ -(01)98898765432106(3103)001750 \ No newline at end of file +01988987654321063103001750 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/16.txt b/test/samples/rssexpanded-2/16.txt index c9f248d08f..082bbe5436 100644 --- a/test/samples/rssexpanded-2/16.txt +++ b/test/samples/rssexpanded-2/16.txt @@ -1 +1 @@ -(01)90012345678908(3202)001750(11)100312 \ No newline at end of file +0190012345678908320200175011100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/17.txt b/test/samples/rssexpanded-2/17.txt index 9b4fc495ed..8df804363c 100644 --- a/test/samples/rssexpanded-2/17.txt +++ b/test/samples/rssexpanded-2/17.txt @@ -1 +1 @@ -(01)90012345678908(3102)001750(13)100312 \ No newline at end of file +0190012345678908310200175013100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/18.txt b/test/samples/rssexpanded-2/18.txt index cd15aa06cf..fd734e7794 100644 --- a/test/samples/rssexpanded-2/18.txt +++ b/test/samples/rssexpanded-2/18.txt @@ -1 +1 @@ -(01)90012345678908(3202)001750(13)100312 \ No newline at end of file +0190012345678908320200175013100312 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/3_01.txt b/test/samples/rssexpanded-2/3_01.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-2/3_01.txt +++ b/test/samples/rssexpanded-2/3_01.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-2/3_02.txt b/test/samples/rssexpanded-2/3_02.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-2/3_02.txt +++ b/test/samples/rssexpanded-2/3_02.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-2/3_05.txt b/test/samples/rssexpanded-2/3_05.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-2/3_05.txt +++ b/test/samples/rssexpanded-2/3_05.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-2/3_06.txt b/test/samples/rssexpanded-2/3_06.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-2/3_06.txt +++ b/test/samples/rssexpanded-2/3_06.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-2/3_07.txt b/test/samples/rssexpanded-2/3_07.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-2/3_07.txt +++ b/test/samples/rssexpanded-2/3_07.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-2/3_09.txt b/test/samples/rssexpanded-2/3_09.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-2/3_09.txt +++ b/test/samples/rssexpanded-2/3_09.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-2/4_00.txt b/test/samples/rssexpanded-2/4_00.txt index 4e8655ca59..395fb680dc 100644 --- a/test/samples/rssexpanded-2/4_00.txt +++ b/test/samples/rssexpanded-2/4_00.txt @@ -1 +1 @@ -(01)98898765432106(3202)012345(15)991231 \ No newline at end of file +0198898765432106320201234515991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/4_02.txt b/test/samples/rssexpanded-2/4_02.txt index 4e8655ca59..395fb680dc 100644 --- a/test/samples/rssexpanded-2/4_02.txt +++ b/test/samples/rssexpanded-2/4_02.txt @@ -1 +1 @@ -(01)98898765432106(3202)012345(15)991231 \ No newline at end of file +0198898765432106320201234515991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/4_03.txt b/test/samples/rssexpanded-2/4_03.txt index 4e8655ca59..395fb680dc 100644 --- a/test/samples/rssexpanded-2/4_03.txt +++ b/test/samples/rssexpanded-2/4_03.txt @@ -1 +1 @@ -(01)98898765432106(3202)012345(15)991231 \ No newline at end of file +0198898765432106320201234515991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/4_04.txt b/test/samples/rssexpanded-2/4_04.txt index 4e8655ca59..395fb680dc 100644 --- a/test/samples/rssexpanded-2/4_04.txt +++ b/test/samples/rssexpanded-2/4_04.txt @@ -1 +1 @@ -(01)98898765432106(3202)012345(15)991231 \ No newline at end of file +0198898765432106320201234515991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-2/5.txt b/test/samples/rssexpanded-2/5.txt index 4a708608fb..cc3ec9d4ff 100644 --- a/test/samples/rssexpanded-2/5.txt +++ b/test/samples/rssexpanded-2/5.txt @@ -1 +1 @@ -(01)90614141000015(3202)000150 \ No newline at end of file +01906141410000153202000150 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/1.txt b/test/samples/rssexpanded-3/1.txt index ed31c4d92a..4a607fa610 100644 --- a/test/samples/rssexpanded-3/1.txt +++ b/test/samples/rssexpanded-3/1.txt @@ -1 +1 @@ -(01)90012345678908(3103)012233(15)991231 \ No newline at end of file +0190012345678908310301223315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/10.txt b/test/samples/rssexpanded-3/10.txt index e8f98fef35..410a24bc6c 100644 --- a/test/samples/rssexpanded-3/10.txt +++ b/test/samples/rssexpanded-3/10.txt @@ -1 +1 @@ -(01)90012345678908(3203)010000 \ No newline at end of file +01900123456789083203010000 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/100.txt b/test/samples/rssexpanded-3/100.txt index 4339de91be..07d4b42372 100644 --- a/test/samples/rssexpanded-3/100.txt +++ b/test/samples/rssexpanded-3/100.txt @@ -1 +1 @@ -(10)1098 1234 \ No newline at end of file +101098 1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/101.txt b/test/samples/rssexpanded-3/101.txt index 6f63fb0d8e..8dda74e6cd 100644 --- a/test/samples/rssexpanded-3/101.txt +++ b/test/samples/rssexpanded-3/101.txt @@ -1 +1 @@ -(10)123456A \ No newline at end of file +10123456A \ No newline at end of file diff --git a/test/samples/rssexpanded-3/102.txt b/test/samples/rssexpanded-3/102.txt index 5c1b912a9b..9638dbe444 100644 --- a/test/samples/rssexpanded-3/102.txt +++ b/test/samples/rssexpanded-3/102.txt @@ -1 +1 @@ -(10)123456A1 \ No newline at end of file +10123456A1 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/103.txt b/test/samples/rssexpanded-3/103.txt index d77a4769e3..90e67659dc 100644 --- a/test/samples/rssexpanded-3/103.txt +++ b/test/samples/rssexpanded-3/103.txt @@ -1 +1 @@ -(10)123456A123 \ No newline at end of file +10123456A123 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/104.txt b/test/samples/rssexpanded-3/104.txt index 2e2ec43d09..c894b12b79 100644 --- a/test/samples/rssexpanded-3/104.txt +++ b/test/samples/rssexpanded-3/104.txt @@ -1 +1 @@ -(10)123456A1234 \ No newline at end of file +10123456A1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/105.txt b/test/samples/rssexpanded-3/105.txt index b607d14301..0019761597 100644 --- a/test/samples/rssexpanded-3/105.txt +++ b/test/samples/rssexpanded-3/105.txt @@ -1 +1 @@ -(10)123456A1234A \ No newline at end of file +10123456A1234A \ No newline at end of file diff --git a/test/samples/rssexpanded-3/106.txt b/test/samples/rssexpanded-3/106.txt index 389adcaf73..fc70522c01 100644 --- a/test/samples/rssexpanded-3/106.txt +++ b/test/samples/rssexpanded-3/106.txt @@ -1 +1 @@ -(10)123456A123456 \ No newline at end of file +10123456A123456 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/107.txt b/test/samples/rssexpanded-3/107.txt index fffde5d07d..b1a0a8909c 100644 --- a/test/samples/rssexpanded-3/107.txt +++ b/test/samples/rssexpanded-3/107.txt @@ -1 +1 @@ -(10)123456A12345678 \ No newline at end of file +10123456A12345678 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/108-corrected.txt b/test/samples/rssexpanded-3/108-corrected.txt index 1ad0fbd888..b7ca18f986 100644 --- a/test/samples/rssexpanded-3/108-corrected.txt +++ b/test/samples/rssexpanded-3/108-corrected.txt @@ -1 +1 @@ -(10)123456A1234A(15)991231 \ No newline at end of file +10123456A1234A15991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/108.txt b/test/samples/rssexpanded-3/108.txt index 1ad0fbd888..b7ca18f986 100644 --- a/test/samples/rssexpanded-3/108.txt +++ b/test/samples/rssexpanded-3/108.txt @@ -1 +1 @@ -(10)123456A1234A(15)991231 \ No newline at end of file +10123456A1234A15991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/109.txt b/test/samples/rssexpanded-3/109.txt index ac7961799b..c9063887c8 100644 --- a/test/samples/rssexpanded-3/109.txt +++ b/test/samples/rssexpanded-3/109.txt @@ -1 +1 @@ -(10)1ABCDEF;:/1234567 \ No newline at end of file +101ABCDEF;:/1234567 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/11.txt b/test/samples/rssexpanded-3/11.txt index 9895a675fd..868c296567 100644 --- a/test/samples/rssexpanded-3/11.txt +++ b/test/samples/rssexpanded-3/11.txt @@ -1 +1 @@ -(01)90012345678908(3203)032767 \ No newline at end of file +01900123456789083203032767 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/110.txt b/test/samples/rssexpanded-3/110.txt index 163b64b566..a8e72e07cc 100644 --- a/test/samples/rssexpanded-3/110.txt +++ b/test/samples/rssexpanded-3/110.txt @@ -1 +1 @@ -(10)1ABCDEF;:/ABCDEFG \ No newline at end of file +101ABCDEF;:/ABCDEFG \ No newline at end of file diff --git a/test/samples/rssexpanded-3/111.txt b/test/samples/rssexpanded-3/111.txt index d359328c90..5e59f66082 100644 --- a/test/samples/rssexpanded-3/111.txt +++ b/test/samples/rssexpanded-3/111.txt @@ -1 +1 @@ -(10)1;:/ABCDEFGHIJKLM \ No newline at end of file +101;:/ABCDEFGHIJKLM \ No newline at end of file diff --git a/test/samples/rssexpanded-3/112.txt b/test/samples/rssexpanded-3/112.txt index c25e84f78f..41d6022acc 100644 --- a/test/samples/rssexpanded-3/112.txt +++ b/test/samples/rssexpanded-3/112.txt @@ -1 +1 @@ -(10)1;:/0123456789012 \ No newline at end of file +101;:/0123456789012 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/113.txt b/test/samples/rssexpanded-3/113.txt index 2914766cb8..1778e170dd 100644 --- a/test/samples/rssexpanded-3/113.txt +++ b/test/samples/rssexpanded-3/113.txt @@ -1 +1 @@ -(10)1;:/0123 \ No newline at end of file +101;:/0123 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/114.txt b/test/samples/rssexpanded-3/114.txt index c8be9f3bc1..21abbac01b 100644 --- a/test/samples/rssexpanded-3/114.txt +++ b/test/samples/rssexpanded-3/114.txt @@ -1 +1 @@ -(10)1;:/0123(15)991231 \ No newline at end of file +101;:/012315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/115.txt b/test/samples/rssexpanded-3/115.txt index 9a1581d3e4..97a55e1d74 100644 --- a/test/samples/rssexpanded-3/115.txt +++ b/test/samples/rssexpanded-3/115.txt @@ -1 +1 @@ -(10)1 \ No newline at end of file +101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/116.txt b/test/samples/rssexpanded-3/116.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpanded-3/116.txt +++ b/test/samples/rssexpanded-3/116.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpanded-3/117.txt b/test/samples/rssexpanded-3/117.txt index 62c17f167c..3bbd5e5122 100644 --- a/test/samples/rssexpanded-3/117.txt +++ b/test/samples/rssexpanded-3/117.txt @@ -1 +1 @@ -(10)123 \ No newline at end of file +10123 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/12.txt b/test/samples/rssexpanded-3/12.txt index dd36aabdc1..1d29f26188 100644 --- a/test/samples/rssexpanded-3/12.txt +++ b/test/samples/rssexpanded-3/12.txt @@ -1 +1 @@ -(01)90012345678908(3922)795 \ No newline at end of file +01900123456789083922795 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/13.txt b/test/samples/rssexpanded-3/13.txt index 0429d93c29..ac550ef17e 100644 --- a/test/samples/rssexpanded-3/13.txt +++ b/test/samples/rssexpanded-3/13.txt @@ -1 +1 @@ -(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888 \ No newline at end of file +01900123456789083922795888888888888888888888888888888888888888888888888888 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/14.txt b/test/samples/rssexpanded-3/14.txt index fb00e311f8..1be59ac1f7 100644 --- a/test/samples/rssexpanded-3/14.txt +++ b/test/samples/rssexpanded-3/14.txt @@ -1 +1 @@ -(01)90012345678908(3932)0401234 \ No newline at end of file +019001234567890839320401234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/15.txt b/test/samples/rssexpanded-3/15.txt index 9066194a66..d2e6b8f052 100644 --- a/test/samples/rssexpanded-3/15.txt +++ b/test/samples/rssexpanded-3/15.txt @@ -1 +1 @@ -(01)00012345678905(10)ABC123 \ No newline at end of file +010001234567890510ABC123 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/16.txt b/test/samples/rssexpanded-3/16.txt index 8f0841f935..8fce00bd76 100644 --- a/test/samples/rssexpanded-3/16.txt +++ b/test/samples/rssexpanded-3/16.txt @@ -1 +1 @@ -(01)12345678901231(10)UNIVERSITY-OF-DEUSTO \ No newline at end of file +011234567890123110UNIVERSITY-OF-DEUSTO \ No newline at end of file diff --git a/test/samples/rssexpanded-3/17.txt b/test/samples/rssexpanded-3/17.txt index 89fda98695..f639b985f0 100644 --- a/test/samples/rssexpanded-3/17.txt +++ b/test/samples/rssexpanded-3/17.txt @@ -1 +1 @@ -(01)12345678901231(10)PIRAMIDE-PROJECT \ No newline at end of file +011234567890123110PIRAMIDE-PROJECT \ No newline at end of file diff --git a/test/samples/rssexpanded-3/18.txt b/test/samples/rssexpanded-3/18.txt index b120324e08..41a8e0f023 100644 --- a/test/samples/rssexpanded-3/18.txt +++ b/test/samples/rssexpanded-3/18.txt @@ -1 +1 @@ -(01)12345678901231(10)TREELOGIC \ No newline at end of file +011234567890123110TREELOGIC \ No newline at end of file diff --git a/test/samples/rssexpanded-3/19.txt b/test/samples/rssexpanded-3/19.txt index 17966ee8b2..efff0d4aee 100644 --- a/test/samples/rssexpanded-3/19.txt +++ b/test/samples/rssexpanded-3/19.txt @@ -1 +1 @@ -(10)5678(11)010101 \ No newline at end of file +10567811010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/2.txt b/test/samples/rssexpanded-3/2.txt index d7f0a6a199..6a2bd9c8c1 100644 --- a/test/samples/rssexpanded-3/2.txt +++ b/test/samples/rssexpanded-3/2.txt @@ -1 +1 @@ -(01)91234567980129(3103)012233(15)991231 \ No newline at end of file +0191234567980129310301223315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/20.txt b/test/samples/rssexpanded-3/20.txt index b948648964..1fe9058cf0 100644 --- a/test/samples/rssexpanded-3/20.txt +++ b/test/samples/rssexpanded-3/20.txt @@ -1 +1 @@ -(10)5678(11)001010 \ No newline at end of file +10567811001010 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/21.txt b/test/samples/rssexpanded-3/21.txt index a7b34974c6..b236cb3daf 100644 --- a/test/samples/rssexpanded-3/21.txt +++ b/test/samples/rssexpanded-3/21.txt @@ -1 +1 @@ -(10)567890(11)010101 \ No newline at end of file +1056789011010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/22.txt b/test/samples/rssexpanded-3/22.txt index e8c72688f3..258e2f0334 100644 --- a/test/samples/rssexpanded-3/22.txt +++ b/test/samples/rssexpanded-3/22.txt @@ -1 +1 @@ -(10)567(11)010101 \ No newline at end of file +1056711010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/23.txt b/test/samples/rssexpanded-3/23.txt index 5263f7fc5a..a6113cbe0a 100644 --- a/test/samples/rssexpanded-3/23.txt +++ b/test/samples/rssexpanded-3/23.txt @@ -1 +1 @@ -(10)1098-1234 \ No newline at end of file +101098-1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/24.txt b/test/samples/rssexpanded-3/24.txt index f6413d5df5..203ccbb336 100644 --- a/test/samples/rssexpanded-3/24.txt +++ b/test/samples/rssexpanded-3/24.txt @@ -1 +1 @@ -(10)1098,1234 \ No newline at end of file +101098,1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/25.txt b/test/samples/rssexpanded-3/25.txt index 9208d92acb..4921a3252a 100644 --- a/test/samples/rssexpanded-3/25.txt +++ b/test/samples/rssexpanded-3/25.txt @@ -1 +1 @@ -(10)1098/1234 \ No newline at end of file +101098/1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/26.txt b/test/samples/rssexpanded-3/26.txt index b78623a34f..37d26ab8ed 100644 --- a/test/samples/rssexpanded-3/26.txt +++ b/test/samples/rssexpanded-3/26.txt @@ -1 +1 @@ -(10)1098.1234 \ No newline at end of file +101098.1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/27.txt b/test/samples/rssexpanded-3/27.txt index 82bfa6ae93..9bb5c079c3 100644 --- a/test/samples/rssexpanded-3/27.txt +++ b/test/samples/rssexpanded-3/27.txt @@ -1 +1 @@ -(10)1098*1234 \ No newline at end of file +101098*1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/28.txt b/test/samples/rssexpanded-3/28.txt index 6263d994ea..f5c98f2873 100644 --- a/test/samples/rssexpanded-3/28.txt +++ b/test/samples/rssexpanded-3/28.txt @@ -1 +1 @@ -(10)1098a1234 \ No newline at end of file +101098a1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/29.txt b/test/samples/rssexpanded-3/29.txt index 35fc529eee..33a6725991 100644 --- a/test/samples/rssexpanded-3/29.txt +++ b/test/samples/rssexpanded-3/29.txt @@ -1 +1 @@ -(10)1098!1234 \ No newline at end of file +101098!1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/3.txt b/test/samples/rssexpanded-3/3.txt index ab93c9775a..b25c4162fc 100644 --- a/test/samples/rssexpanded-3/3.txt +++ b/test/samples/rssexpanded-3/3.txt @@ -1 +1 @@ -(01)91234567980129(3102)012233(15)991231 \ No newline at end of file +0191234567980129310201223315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/30.txt b/test/samples/rssexpanded-3/30.txt index d0d95d09b1..afff5844f4 100644 --- a/test/samples/rssexpanded-3/30.txt +++ b/test/samples/rssexpanded-3/30.txt @@ -1 +1 @@ -(10)1098"1234 \ No newline at end of file +101098"1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/31.txt b/test/samples/rssexpanded-3/31.txt index 53bf7814fe..df57c75c1b 100644 --- a/test/samples/rssexpanded-3/31.txt +++ b/test/samples/rssexpanded-3/31.txt @@ -1 +1 @@ -(10)1098%1234 \ No newline at end of file +101098%1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/32.txt b/test/samples/rssexpanded-3/32.txt index 5d1d3514d4..6a2dc09970 100644 --- a/test/samples/rssexpanded-3/32.txt +++ b/test/samples/rssexpanded-3/32.txt @@ -1 +1 @@ -(10)1098&1234 \ No newline at end of file +101098&1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/33.txt b/test/samples/rssexpanded-3/33.txt index f00c6bb1fa..8b2cc6b704 100644 --- a/test/samples/rssexpanded-3/33.txt +++ b/test/samples/rssexpanded-3/33.txt @@ -1 +1 @@ -(10)1098'1234 \ No newline at end of file +101098'1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/34.txt b/test/samples/rssexpanded-3/34.txt index 18b90ec777..3feae80189 100644 --- a/test/samples/rssexpanded-3/34.txt +++ b/test/samples/rssexpanded-3/34.txt @@ -1 +1 @@ -(10)1098+1234 \ No newline at end of file +101098+1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/35.txt b/test/samples/rssexpanded-3/35.txt index 96f90494bd..43ec78faf5 100644 --- a/test/samples/rssexpanded-3/35.txt +++ b/test/samples/rssexpanded-3/35.txt @@ -1 +1 @@ -(10)1098:1234 \ No newline at end of file +101098:1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/36.txt b/test/samples/rssexpanded-3/36.txt index 2dd84d5e6b..4b0a48386a 100644 --- a/test/samples/rssexpanded-3/36.txt +++ b/test/samples/rssexpanded-3/36.txt @@ -1 +1 @@ -(10)1098;1234 \ No newline at end of file +101098;1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/37.txt b/test/samples/rssexpanded-3/37.txt index a64a6db2a8..bac6e34f0c 100644 --- a/test/samples/rssexpanded-3/37.txt +++ b/test/samples/rssexpanded-3/37.txt @@ -1 +1 @@ -(10)1098<1234 \ No newline at end of file +101098<1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/38.txt b/test/samples/rssexpanded-3/38.txt index c7cc6061b7..1678854264 100644 --- a/test/samples/rssexpanded-3/38.txt +++ b/test/samples/rssexpanded-3/38.txt @@ -1 +1 @@ -(10)1098=1234 \ No newline at end of file +101098=1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/39.txt b/test/samples/rssexpanded-3/39.txt index 7345e4ec31..967d803057 100644 --- a/test/samples/rssexpanded-3/39.txt +++ b/test/samples/rssexpanded-3/39.txt @@ -1 +1 @@ -(10)1098>1234 \ No newline at end of file +101098>1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/4.txt b/test/samples/rssexpanded-3/4.txt index fca726b060..bf3d1e612c 100644 --- a/test/samples/rssexpanded-3/4.txt +++ b/test/samples/rssexpanded-3/4.txt @@ -1 +1 @@ -(01)91234567980129(3102)012233(15)000101 \ No newline at end of file +0191234567980129310201223315000101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/40.txt b/test/samples/rssexpanded-3/40.txt index 5e152de159..91293e57f9 100644 --- a/test/samples/rssexpanded-3/40.txt +++ b/test/samples/rssexpanded-3/40.txt @@ -1 +1 @@ -(10)1098?1234 \ No newline at end of file +101098?1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/41.txt b/test/samples/rssexpanded-3/41.txt index aad1b28524..d892771714 100644 --- a/test/samples/rssexpanded-3/41.txt +++ b/test/samples/rssexpanded-3/41.txt @@ -1 +1 @@ -(10)1098_1234 \ No newline at end of file +101098_1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/42.txt b/test/samples/rssexpanded-3/42.txt index 4339de91be..07d4b42372 100644 --- a/test/samples/rssexpanded-3/42.txt +++ b/test/samples/rssexpanded-3/42.txt @@ -1 +1 @@ -(10)1098 1234 \ No newline at end of file +101098 1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/43.txt b/test/samples/rssexpanded-3/43.txt index 6f63fb0d8e..8dda74e6cd 100644 --- a/test/samples/rssexpanded-3/43.txt +++ b/test/samples/rssexpanded-3/43.txt @@ -1 +1 @@ -(10)123456A \ No newline at end of file +10123456A \ No newline at end of file diff --git a/test/samples/rssexpanded-3/44.txt b/test/samples/rssexpanded-3/44.txt index 2e2ec43d09..c894b12b79 100644 --- a/test/samples/rssexpanded-3/44.txt +++ b/test/samples/rssexpanded-3/44.txt @@ -1 +1 @@ -(10)123456A1234 \ No newline at end of file +10123456A1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/45.txt b/test/samples/rssexpanded-3/45.txt index b607d14301..0019761597 100644 --- a/test/samples/rssexpanded-3/45.txt +++ b/test/samples/rssexpanded-3/45.txt @@ -1 +1 @@ -(10)123456A1234A \ No newline at end of file +10123456A1234A \ No newline at end of file diff --git a/test/samples/rssexpanded-3/46.txt b/test/samples/rssexpanded-3/46.txt index 389adcaf73..fc70522c01 100644 --- a/test/samples/rssexpanded-3/46.txt +++ b/test/samples/rssexpanded-3/46.txt @@ -1 +1 @@ -(10)123456A123456 \ No newline at end of file +10123456A123456 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/47.txt b/test/samples/rssexpanded-3/47.txt index fffde5d07d..b1a0a8909c 100644 --- a/test/samples/rssexpanded-3/47.txt +++ b/test/samples/rssexpanded-3/47.txt @@ -1 +1 @@ -(10)123456A12345678 \ No newline at end of file +10123456A12345678 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/48.txt b/test/samples/rssexpanded-3/48.txt index ac7961799b..c9063887c8 100644 --- a/test/samples/rssexpanded-3/48.txt +++ b/test/samples/rssexpanded-3/48.txt @@ -1 +1 @@ -(10)1ABCDEF;:/1234567 \ No newline at end of file +101ABCDEF;:/1234567 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/49.txt b/test/samples/rssexpanded-3/49.txt index 163b64b566..a8e72e07cc 100644 --- a/test/samples/rssexpanded-3/49.txt +++ b/test/samples/rssexpanded-3/49.txt @@ -1 +1 @@ -(10)1ABCDEF;:/ABCDEFG \ No newline at end of file +101ABCDEF;:/ABCDEFG \ No newline at end of file diff --git a/test/samples/rssexpanded-3/5.txt b/test/samples/rssexpanded-3/5.txt index b4113ac56d..aee1d62673 100644 --- a/test/samples/rssexpanded-3/5.txt +++ b/test/samples/rssexpanded-3/5.txt @@ -1 +1 @@ -(01)90012345678908(3103)001750 \ No newline at end of file +01900123456789083103001750 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/50.txt b/test/samples/rssexpanded-3/50.txt index d359328c90..5e59f66082 100644 --- a/test/samples/rssexpanded-3/50.txt +++ b/test/samples/rssexpanded-3/50.txt @@ -1 +1 @@ -(10)1;:/ABCDEFGHIJKLM \ No newline at end of file +101;:/ABCDEFGHIJKLM \ No newline at end of file diff --git a/test/samples/rssexpanded-3/51.txt b/test/samples/rssexpanded-3/51.txt index c25e84f78f..41d6022acc 100644 --- a/test/samples/rssexpanded-3/51.txt +++ b/test/samples/rssexpanded-3/51.txt @@ -1 +1 @@ -(10)1;:/0123456789012 \ No newline at end of file +101;:/0123456789012 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/52.txt b/test/samples/rssexpanded-3/52.txt index 2914766cb8..1778e170dd 100644 --- a/test/samples/rssexpanded-3/52.txt +++ b/test/samples/rssexpanded-3/52.txt @@ -1 +1 @@ -(10)1;:/0123 \ No newline at end of file +101;:/0123 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/53.txt b/test/samples/rssexpanded-3/53.txt index c8be9f3bc1..21abbac01b 100644 --- a/test/samples/rssexpanded-3/53.txt +++ b/test/samples/rssexpanded-3/53.txt @@ -1 +1 @@ -(10)1;:/0123(15)991231 \ No newline at end of file +101;:/012315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/54.txt b/test/samples/rssexpanded-3/54.txt index ed31c4d92a..4a607fa610 100644 --- a/test/samples/rssexpanded-3/54.txt +++ b/test/samples/rssexpanded-3/54.txt @@ -1 +1 @@ -(01)90012345678908(3103)012233(15)991231 \ No newline at end of file +0190012345678908310301223315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/55.txt b/test/samples/rssexpanded-3/55.txt index d7f0a6a199..6a2bd9c8c1 100644 --- a/test/samples/rssexpanded-3/55.txt +++ b/test/samples/rssexpanded-3/55.txt @@ -1 +1 @@ -(01)91234567980129(3103)012233(15)991231 \ No newline at end of file +0191234567980129310301223315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/56.txt b/test/samples/rssexpanded-3/56.txt index ab93c9775a..b25c4162fc 100644 --- a/test/samples/rssexpanded-3/56.txt +++ b/test/samples/rssexpanded-3/56.txt @@ -1 +1 @@ -(01)91234567980129(3102)012233(15)991231 \ No newline at end of file +0191234567980129310201223315991231 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/57.txt b/test/samples/rssexpanded-3/57.txt index fca726b060..bf3d1e612c 100644 --- a/test/samples/rssexpanded-3/57.txt +++ b/test/samples/rssexpanded-3/57.txt @@ -1 +1 @@ -(01)91234567980129(3102)012233(15)000101 \ No newline at end of file +0191234567980129310201223315000101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/58.txt b/test/samples/rssexpanded-3/58.txt index b4113ac56d..aee1d62673 100644 --- a/test/samples/rssexpanded-3/58.txt +++ b/test/samples/rssexpanded-3/58.txt @@ -1 +1 @@ -(01)90012345678908(3103)001750 \ No newline at end of file +01900123456789083103001750 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/59.txt b/test/samples/rssexpanded-3/59.txt index 57a2c644e1..2838c85fd5 100644 --- a/test/samples/rssexpanded-3/59.txt +++ b/test/samples/rssexpanded-3/59.txt @@ -1 +1 @@ -(01)92109876543213(3103)032767 \ No newline at end of file +01921098765432133103032767 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/6.txt b/test/samples/rssexpanded-3/6.txt index 57a2c644e1..2838c85fd5 100644 --- a/test/samples/rssexpanded-3/6.txt +++ b/test/samples/rssexpanded-3/6.txt @@ -1 +1 @@ -(01)92109876543213(3103)032767 \ No newline at end of file +01921098765432133103032767 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/60.txt b/test/samples/rssexpanded-3/60.txt index bfa41779e7..d091ce7bf9 100644 --- a/test/samples/rssexpanded-3/60.txt +++ b/test/samples/rssexpanded-3/60.txt @@ -1 +1 @@ -(01)92109876543213(3103)000000 \ No newline at end of file +01921098765432133103000000 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/61.txt b/test/samples/rssexpanded-3/61.txt index e0da7fa314..6e64d025ce 100644 --- a/test/samples/rssexpanded-3/61.txt +++ b/test/samples/rssexpanded-3/61.txt @@ -1 +1 @@ -(01)90012345678908(3202)000156 \ No newline at end of file +01900123456789083202000156 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/62.txt b/test/samples/rssexpanded-3/62.txt index 01af485cc6..5218dfc1c0 100644 --- a/test/samples/rssexpanded-3/62.txt +++ b/test/samples/rssexpanded-3/62.txt @@ -1 +1 @@ -(01)90012345678908(3202)009999 \ No newline at end of file +01900123456789083202009999 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/63.txt b/test/samples/rssexpanded-3/63.txt index e8f98fef35..410a24bc6c 100644 --- a/test/samples/rssexpanded-3/63.txt +++ b/test/samples/rssexpanded-3/63.txt @@ -1 +1 @@ -(01)90012345678908(3203)010000 \ No newline at end of file +01900123456789083203010000 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/64.txt b/test/samples/rssexpanded-3/64.txt index 9895a675fd..868c296567 100644 --- a/test/samples/rssexpanded-3/64.txt +++ b/test/samples/rssexpanded-3/64.txt @@ -1 +1 @@ -(01)90012345678908(3203)032767 \ No newline at end of file +01900123456789083203032767 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/65.txt b/test/samples/rssexpanded-3/65.txt index dd36aabdc1..1d29f26188 100644 --- a/test/samples/rssexpanded-3/65.txt +++ b/test/samples/rssexpanded-3/65.txt @@ -1 +1 @@ -(01)90012345678908(3922)795 \ No newline at end of file +01900123456789083922795 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/66.txt b/test/samples/rssexpanded-3/66.txt index 0429d93c29..ac550ef17e 100644 --- a/test/samples/rssexpanded-3/66.txt +++ b/test/samples/rssexpanded-3/66.txt @@ -1 +1 @@ -(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888 \ No newline at end of file +01900123456789083922795888888888888888888888888888888888888888888888888888 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/67.txt b/test/samples/rssexpanded-3/67.txt index fb00e311f8..1be59ac1f7 100644 --- a/test/samples/rssexpanded-3/67.txt +++ b/test/samples/rssexpanded-3/67.txt @@ -1 +1 @@ -(01)90012345678908(3932)0401234 \ No newline at end of file +019001234567890839320401234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/68.txt b/test/samples/rssexpanded-3/68.txt index b5f3fe92d8..383b584f6c 100644 --- a/test/samples/rssexpanded-3/68.txt +++ b/test/samples/rssexpanded-3/68.txt @@ -1 +1 @@ -(01)90012345678908(3932)040EUR \ No newline at end of file +01900123456789083932040EUR \ No newline at end of file diff --git a/test/samples/rssexpanded-3/69.txt b/test/samples/rssexpanded-3/69.txt index e95bc8d7b5..f9a5e0b509 100644 --- a/test/samples/rssexpanded-3/69.txt +++ b/test/samples/rssexpanded-3/69.txt @@ -1 +1 @@ -(01)90012345678908(3932)04055GBP \ No newline at end of file +0190012345678908393204055GBP \ No newline at end of file diff --git a/test/samples/rssexpanded-3/7.txt b/test/samples/rssexpanded-3/7.txt index bfa41779e7..d091ce7bf9 100644 --- a/test/samples/rssexpanded-3/7.txt +++ b/test/samples/rssexpanded-3/7.txt @@ -1 +1 @@ -(01)92109876543213(3103)000000 \ No newline at end of file +01921098765432133103000000 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/70.txt b/test/samples/rssexpanded-3/70.txt index 37c6cb3946..9702210661 100644 --- a/test/samples/rssexpanded-3/70.txt +++ b/test/samples/rssexpanded-3/70.txt @@ -1 +1 @@ -(01)90012345678908(3932)04066USD778899 \ No newline at end of file +0190012345678908393204066USD778899 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/71.txt b/test/samples/rssexpanded-3/71.txt index 9066194a66..d2e6b8f052 100644 --- a/test/samples/rssexpanded-3/71.txt +++ b/test/samples/rssexpanded-3/71.txt @@ -1 +1 @@ -(01)00012345678905(10)ABC123 \ No newline at end of file +010001234567890510ABC123 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/72.txt b/test/samples/rssexpanded-3/72.txt index 8f0841f935..8fce00bd76 100644 --- a/test/samples/rssexpanded-3/72.txt +++ b/test/samples/rssexpanded-3/72.txt @@ -1 +1 @@ -(01)12345678901231(10)UNIVERSITY-OF-DEUSTO \ No newline at end of file +011234567890123110UNIVERSITY-OF-DEUSTO \ No newline at end of file diff --git a/test/samples/rssexpanded-3/73.txt b/test/samples/rssexpanded-3/73.txt index 89fda98695..f639b985f0 100644 --- a/test/samples/rssexpanded-3/73.txt +++ b/test/samples/rssexpanded-3/73.txt @@ -1 +1 @@ -(01)12345678901231(10)PIRAMIDE-PROJECT \ No newline at end of file +011234567890123110PIRAMIDE-PROJECT \ No newline at end of file diff --git a/test/samples/rssexpanded-3/74.txt b/test/samples/rssexpanded-3/74.txt index b120324e08..41a8e0f023 100644 --- a/test/samples/rssexpanded-3/74.txt +++ b/test/samples/rssexpanded-3/74.txt @@ -1 +1 @@ -(01)12345678901231(10)TREELOGIC \ No newline at end of file +011234567890123110TREELOGIC \ No newline at end of file diff --git a/test/samples/rssexpanded-3/75.txt b/test/samples/rssexpanded-3/75.txt index 09d4208414..b0885acaa8 100644 --- a/test/samples/rssexpanded-3/75.txt +++ b/test/samples/rssexpanded-3/75.txt @@ -1 +1 @@ -(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901 \ No newline at end of file +01988987654321061599123131030017501012A42212321123456423012345678901 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/76.txt b/test/samples/rssexpanded-3/76.txt index 5e76631589..8f35538c43 100644 --- a/test/samples/rssexpanded-3/76.txt +++ b/test/samples/rssexpanded-3/76.txt @@ -1 +1 @@ -(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012 \ No newline at end of file +1599123131030017501012A422123211234564230123456789012 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/77.txt b/test/samples/rssexpanded-3/77.txt index 17966ee8b2..efff0d4aee 100644 --- a/test/samples/rssexpanded-3/77.txt +++ b/test/samples/rssexpanded-3/77.txt @@ -1 +1 @@ -(10)5678(11)010101 \ No newline at end of file +10567811010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/78.txt b/test/samples/rssexpanded-3/78.txt index b948648964..1fe9058cf0 100644 --- a/test/samples/rssexpanded-3/78.txt +++ b/test/samples/rssexpanded-3/78.txt @@ -1 +1 @@ -(10)5678(11)001010 \ No newline at end of file +10567811001010 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/79.txt b/test/samples/rssexpanded-3/79.txt index a7b34974c6..b236cb3daf 100644 --- a/test/samples/rssexpanded-3/79.txt +++ b/test/samples/rssexpanded-3/79.txt @@ -1 +1 @@ -(10)567890(11)010101 \ No newline at end of file +1056789011010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/8.txt b/test/samples/rssexpanded-3/8.txt index e0da7fa314..6e64d025ce 100644 --- a/test/samples/rssexpanded-3/8.txt +++ b/test/samples/rssexpanded-3/8.txt @@ -1 +1 @@ -(01)90012345678908(3202)000156 \ No newline at end of file +01900123456789083202000156 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/80.txt b/test/samples/rssexpanded-3/80.txt index e8c72688f3..258e2f0334 100644 --- a/test/samples/rssexpanded-3/80.txt +++ b/test/samples/rssexpanded-3/80.txt @@ -1 +1 @@ -(10)567(11)010101 \ No newline at end of file +1056711010101 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/81.txt b/test/samples/rssexpanded-3/81.txt index 5263f7fc5a..a6113cbe0a 100644 --- a/test/samples/rssexpanded-3/81.txt +++ b/test/samples/rssexpanded-3/81.txt @@ -1 +1 @@ -(10)1098-1234 \ No newline at end of file +101098-1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/82.txt b/test/samples/rssexpanded-3/82.txt index f6413d5df5..203ccbb336 100644 --- a/test/samples/rssexpanded-3/82.txt +++ b/test/samples/rssexpanded-3/82.txt @@ -1 +1 @@ -(10)1098,1234 \ No newline at end of file +101098,1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/83.txt b/test/samples/rssexpanded-3/83.txt index 9208d92acb..4921a3252a 100644 --- a/test/samples/rssexpanded-3/83.txt +++ b/test/samples/rssexpanded-3/83.txt @@ -1 +1 @@ -(10)1098/1234 \ No newline at end of file +101098/1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/84.txt b/test/samples/rssexpanded-3/84.txt index b78623a34f..37d26ab8ed 100644 --- a/test/samples/rssexpanded-3/84.txt +++ b/test/samples/rssexpanded-3/84.txt @@ -1 +1 @@ -(10)1098.1234 \ No newline at end of file +101098.1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/85.txt b/test/samples/rssexpanded-3/85.txt index 82bfa6ae93..9bb5c079c3 100644 --- a/test/samples/rssexpanded-3/85.txt +++ b/test/samples/rssexpanded-3/85.txt @@ -1 +1 @@ -(10)1098*1234 \ No newline at end of file +101098*1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/86.txt b/test/samples/rssexpanded-3/86.txt index 6263d994ea..f5c98f2873 100644 --- a/test/samples/rssexpanded-3/86.txt +++ b/test/samples/rssexpanded-3/86.txt @@ -1 +1 @@ -(10)1098a1234 \ No newline at end of file +101098a1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/87.txt b/test/samples/rssexpanded-3/87.txt index 35fc529eee..33a6725991 100644 --- a/test/samples/rssexpanded-3/87.txt +++ b/test/samples/rssexpanded-3/87.txt @@ -1 +1 @@ -(10)1098!1234 \ No newline at end of file +101098!1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/88.txt b/test/samples/rssexpanded-3/88.txt index d0d95d09b1..afff5844f4 100644 --- a/test/samples/rssexpanded-3/88.txt +++ b/test/samples/rssexpanded-3/88.txt @@ -1 +1 @@ -(10)1098"1234 \ No newline at end of file +101098"1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/89.txt b/test/samples/rssexpanded-3/89.txt index 53bf7814fe..df57c75c1b 100644 --- a/test/samples/rssexpanded-3/89.txt +++ b/test/samples/rssexpanded-3/89.txt @@ -1 +1 @@ -(10)1098%1234 \ No newline at end of file +101098%1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/9.txt b/test/samples/rssexpanded-3/9.txt index 01af485cc6..5218dfc1c0 100644 --- a/test/samples/rssexpanded-3/9.txt +++ b/test/samples/rssexpanded-3/9.txt @@ -1 +1 @@ -(01)90012345678908(3202)009999 \ No newline at end of file +01900123456789083202009999 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/90.txt b/test/samples/rssexpanded-3/90.txt index 5d1d3514d4..6a2dc09970 100644 --- a/test/samples/rssexpanded-3/90.txt +++ b/test/samples/rssexpanded-3/90.txt @@ -1 +1 @@ -(10)1098&1234 \ No newline at end of file +101098&1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/91.txt b/test/samples/rssexpanded-3/91.txt index f00c6bb1fa..8b2cc6b704 100644 --- a/test/samples/rssexpanded-3/91.txt +++ b/test/samples/rssexpanded-3/91.txt @@ -1 +1 @@ -(10)1098'1234 \ No newline at end of file +101098'1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/92.txt b/test/samples/rssexpanded-3/92.txt index 18b90ec777..3feae80189 100644 --- a/test/samples/rssexpanded-3/92.txt +++ b/test/samples/rssexpanded-3/92.txt @@ -1 +1 @@ -(10)1098+1234 \ No newline at end of file +101098+1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/93.txt b/test/samples/rssexpanded-3/93.txt index 96f90494bd..43ec78faf5 100644 --- a/test/samples/rssexpanded-3/93.txt +++ b/test/samples/rssexpanded-3/93.txt @@ -1 +1 @@ -(10)1098:1234 \ No newline at end of file +101098:1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/94.txt b/test/samples/rssexpanded-3/94.txt index 2dd84d5e6b..4b0a48386a 100644 --- a/test/samples/rssexpanded-3/94.txt +++ b/test/samples/rssexpanded-3/94.txt @@ -1 +1 @@ -(10)1098;1234 \ No newline at end of file +101098;1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/95.txt b/test/samples/rssexpanded-3/95.txt index a64a6db2a8..bac6e34f0c 100644 --- a/test/samples/rssexpanded-3/95.txt +++ b/test/samples/rssexpanded-3/95.txt @@ -1 +1 @@ -(10)1098<1234 \ No newline at end of file +101098<1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/96.txt b/test/samples/rssexpanded-3/96.txt index c7cc6061b7..1678854264 100644 --- a/test/samples/rssexpanded-3/96.txt +++ b/test/samples/rssexpanded-3/96.txt @@ -1 +1 @@ -(10)1098=1234 \ No newline at end of file +101098=1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/97.txt b/test/samples/rssexpanded-3/97.txt index 7345e4ec31..967d803057 100644 --- a/test/samples/rssexpanded-3/97.txt +++ b/test/samples/rssexpanded-3/97.txt @@ -1 +1 @@ -(10)1098>1234 \ No newline at end of file +101098>1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/98.txt b/test/samples/rssexpanded-3/98.txt index 5e152de159..91293e57f9 100644 --- a/test/samples/rssexpanded-3/98.txt +++ b/test/samples/rssexpanded-3/98.txt @@ -1 +1 @@ -(10)1098?1234 \ No newline at end of file +101098?1234 \ No newline at end of file diff --git a/test/samples/rssexpanded-3/99.txt b/test/samples/rssexpanded-3/99.txt index aad1b28524..d892771714 100644 --- a/test/samples/rssexpanded-3/99.txt +++ b/test/samples/rssexpanded-3/99.txt @@ -1 +1 @@ -(10)1098_1234 \ No newline at end of file +101098_1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/1.txt b/test/samples/rssexpandedstacked-1/1.txt index ed31c4d92a..4a607fa610 100644 --- a/test/samples/rssexpandedstacked-1/1.txt +++ b/test/samples/rssexpandedstacked-1/1.txt @@ -1 +1 @@ -(01)90012345678908(3103)012233(15)991231 \ No newline at end of file +0190012345678908310301223315991231 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/10.txt b/test/samples/rssexpandedstacked-1/10.txt index e8f98fef35..410a24bc6c 100644 --- a/test/samples/rssexpandedstacked-1/10.txt +++ b/test/samples/rssexpandedstacked-1/10.txt @@ -1 +1 @@ -(01)90012345678908(3203)010000 \ No newline at end of file +01900123456789083203010000 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/11.txt b/test/samples/rssexpandedstacked-1/11.txt index 9895a675fd..868c296567 100644 --- a/test/samples/rssexpandedstacked-1/11.txt +++ b/test/samples/rssexpandedstacked-1/11.txt @@ -1 +1 @@ -(01)90012345678908(3203)032767 \ No newline at end of file +01900123456789083203032767 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/12.txt b/test/samples/rssexpandedstacked-1/12.txt index dd36aabdc1..1d29f26188 100644 --- a/test/samples/rssexpandedstacked-1/12.txt +++ b/test/samples/rssexpandedstacked-1/12.txt @@ -1 +1 @@ -(01)90012345678908(3922)795 \ No newline at end of file +01900123456789083922795 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/13.txt b/test/samples/rssexpandedstacked-1/13.txt index 0429d93c29..ac550ef17e 100644 --- a/test/samples/rssexpandedstacked-1/13.txt +++ b/test/samples/rssexpandedstacked-1/13.txt @@ -1 +1 @@ -(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888 \ No newline at end of file +01900123456789083922795888888888888888888888888888888888888888888888888888 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/14.txt b/test/samples/rssexpandedstacked-1/14.txt index fb00e311f8..1be59ac1f7 100644 --- a/test/samples/rssexpandedstacked-1/14.txt +++ b/test/samples/rssexpandedstacked-1/14.txt @@ -1 +1 @@ -(01)90012345678908(3932)0401234 \ No newline at end of file +019001234567890839320401234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/15.txt b/test/samples/rssexpandedstacked-1/15.txt index b5f3fe92d8..383b584f6c 100644 --- a/test/samples/rssexpandedstacked-1/15.txt +++ b/test/samples/rssexpandedstacked-1/15.txt @@ -1 +1 @@ -(01)90012345678908(3932)040EUR \ No newline at end of file +01900123456789083932040EUR \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/16.txt b/test/samples/rssexpandedstacked-1/16.txt index e95bc8d7b5..f9a5e0b509 100644 --- a/test/samples/rssexpandedstacked-1/16.txt +++ b/test/samples/rssexpandedstacked-1/16.txt @@ -1 +1 @@ -(01)90012345678908(3932)04055GBP \ No newline at end of file +0190012345678908393204055GBP \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/17.txt b/test/samples/rssexpandedstacked-1/17.txt index 37c6cb3946..9702210661 100644 --- a/test/samples/rssexpandedstacked-1/17.txt +++ b/test/samples/rssexpandedstacked-1/17.txt @@ -1 +1 @@ -(01)90012345678908(3932)04066USD778899 \ No newline at end of file +0190012345678908393204066USD778899 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/18.txt b/test/samples/rssexpandedstacked-1/18.txt index 9066194a66..d2e6b8f052 100644 --- a/test/samples/rssexpandedstacked-1/18.txt +++ b/test/samples/rssexpandedstacked-1/18.txt @@ -1 +1 @@ -(01)00012345678905(10)ABC123 \ No newline at end of file +010001234567890510ABC123 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/19.txt b/test/samples/rssexpandedstacked-1/19.txt index 8f0841f935..8fce00bd76 100644 --- a/test/samples/rssexpandedstacked-1/19.txt +++ b/test/samples/rssexpandedstacked-1/19.txt @@ -1 +1 @@ -(01)12345678901231(10)UNIVERSITY-OF-DEUSTO \ No newline at end of file +011234567890123110UNIVERSITY-OF-DEUSTO \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/2.txt b/test/samples/rssexpandedstacked-1/2.txt index d7f0a6a199..6a2bd9c8c1 100644 --- a/test/samples/rssexpandedstacked-1/2.txt +++ b/test/samples/rssexpandedstacked-1/2.txt @@ -1 +1 @@ -(01)91234567980129(3103)012233(15)991231 \ No newline at end of file +0191234567980129310301223315991231 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/20.txt b/test/samples/rssexpandedstacked-1/20.txt index 89fda98695..f639b985f0 100644 --- a/test/samples/rssexpandedstacked-1/20.txt +++ b/test/samples/rssexpandedstacked-1/20.txt @@ -1 +1 @@ -(01)12345678901231(10)PIRAMIDE-PROJECT \ No newline at end of file +011234567890123110PIRAMIDE-PROJECT \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/21.txt b/test/samples/rssexpandedstacked-1/21.txt index b120324e08..41a8e0f023 100644 --- a/test/samples/rssexpandedstacked-1/21.txt +++ b/test/samples/rssexpandedstacked-1/21.txt @@ -1 +1 @@ -(01)12345678901231(10)TREELOGIC \ No newline at end of file +011234567890123110TREELOGIC \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/22.txt b/test/samples/rssexpandedstacked-1/22.txt index 09d4208414..b0885acaa8 100644 --- a/test/samples/rssexpandedstacked-1/22.txt +++ b/test/samples/rssexpandedstacked-1/22.txt @@ -1 +1 @@ -(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901 \ No newline at end of file +01988987654321061599123131030017501012A42212321123456423012345678901 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/23.txt b/test/samples/rssexpandedstacked-1/23.txt index 5e76631589..8f35538c43 100644 --- a/test/samples/rssexpandedstacked-1/23.txt +++ b/test/samples/rssexpandedstacked-1/23.txt @@ -1 +1 @@ -(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012 \ No newline at end of file +1599123131030017501012A422123211234564230123456789012 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/24.txt b/test/samples/rssexpandedstacked-1/24.txt index 17966ee8b2..efff0d4aee 100644 --- a/test/samples/rssexpandedstacked-1/24.txt +++ b/test/samples/rssexpandedstacked-1/24.txt @@ -1 +1 @@ -(10)5678(11)010101 \ No newline at end of file +10567811010101 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/25.txt b/test/samples/rssexpandedstacked-1/25.txt index b948648964..1fe9058cf0 100644 --- a/test/samples/rssexpandedstacked-1/25.txt +++ b/test/samples/rssexpandedstacked-1/25.txt @@ -1 +1 @@ -(10)5678(11)001010 \ No newline at end of file +10567811001010 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/26.txt b/test/samples/rssexpandedstacked-1/26.txt index a7b34974c6..b236cb3daf 100644 --- a/test/samples/rssexpandedstacked-1/26.txt +++ b/test/samples/rssexpandedstacked-1/26.txt @@ -1 +1 @@ -(10)567890(11)010101 \ No newline at end of file +1056789011010101 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/27.txt b/test/samples/rssexpandedstacked-1/27.txt index e8c72688f3..258e2f0334 100644 --- a/test/samples/rssexpandedstacked-1/27.txt +++ b/test/samples/rssexpandedstacked-1/27.txt @@ -1 +1 @@ -(10)567(11)010101 \ No newline at end of file +1056711010101 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/28.txt b/test/samples/rssexpandedstacked-1/28.txt index 5263f7fc5a..a6113cbe0a 100644 --- a/test/samples/rssexpandedstacked-1/28.txt +++ b/test/samples/rssexpandedstacked-1/28.txt @@ -1 +1 @@ -(10)1098-1234 \ No newline at end of file +101098-1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/29.txt b/test/samples/rssexpandedstacked-1/29.txt index f6413d5df5..203ccbb336 100644 --- a/test/samples/rssexpandedstacked-1/29.txt +++ b/test/samples/rssexpandedstacked-1/29.txt @@ -1 +1 @@ -(10)1098,1234 \ No newline at end of file +101098,1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/3.txt b/test/samples/rssexpandedstacked-1/3.txt index ab93c9775a..b25c4162fc 100644 --- a/test/samples/rssexpandedstacked-1/3.txt +++ b/test/samples/rssexpandedstacked-1/3.txt @@ -1 +1 @@ -(01)91234567980129(3102)012233(15)991231 \ No newline at end of file +0191234567980129310201223315991231 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/30.txt b/test/samples/rssexpandedstacked-1/30.txt index 9208d92acb..4921a3252a 100644 --- a/test/samples/rssexpandedstacked-1/30.txt +++ b/test/samples/rssexpandedstacked-1/30.txt @@ -1 +1 @@ -(10)1098/1234 \ No newline at end of file +101098/1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/31.txt b/test/samples/rssexpandedstacked-1/31.txt index b78623a34f..37d26ab8ed 100644 --- a/test/samples/rssexpandedstacked-1/31.txt +++ b/test/samples/rssexpandedstacked-1/31.txt @@ -1 +1 @@ -(10)1098.1234 \ No newline at end of file +101098.1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/32.txt b/test/samples/rssexpandedstacked-1/32.txt index 82bfa6ae93..9bb5c079c3 100644 --- a/test/samples/rssexpandedstacked-1/32.txt +++ b/test/samples/rssexpandedstacked-1/32.txt @@ -1 +1 @@ -(10)1098*1234 \ No newline at end of file +101098*1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/33.txt b/test/samples/rssexpandedstacked-1/33.txt index 6263d994ea..f5c98f2873 100644 --- a/test/samples/rssexpandedstacked-1/33.txt +++ b/test/samples/rssexpandedstacked-1/33.txt @@ -1 +1 @@ -(10)1098a1234 \ No newline at end of file +101098a1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/34.txt b/test/samples/rssexpandedstacked-1/34.txt index 35fc529eee..33a6725991 100644 --- a/test/samples/rssexpandedstacked-1/34.txt +++ b/test/samples/rssexpandedstacked-1/34.txt @@ -1 +1 @@ -(10)1098!1234 \ No newline at end of file +101098!1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/35.txt b/test/samples/rssexpandedstacked-1/35.txt index d0d95d09b1..afff5844f4 100644 --- a/test/samples/rssexpandedstacked-1/35.txt +++ b/test/samples/rssexpandedstacked-1/35.txt @@ -1 +1 @@ -(10)1098"1234 \ No newline at end of file +101098"1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/36.txt b/test/samples/rssexpandedstacked-1/36.txt index 53bf7814fe..df57c75c1b 100644 --- a/test/samples/rssexpandedstacked-1/36.txt +++ b/test/samples/rssexpandedstacked-1/36.txt @@ -1 +1 @@ -(10)1098%1234 \ No newline at end of file +101098%1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/37.txt b/test/samples/rssexpandedstacked-1/37.txt index 5d1d3514d4..6a2dc09970 100644 --- a/test/samples/rssexpandedstacked-1/37.txt +++ b/test/samples/rssexpandedstacked-1/37.txt @@ -1 +1 @@ -(10)1098&1234 \ No newline at end of file +101098&1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/38.txt b/test/samples/rssexpandedstacked-1/38.txt index f00c6bb1fa..8b2cc6b704 100644 --- a/test/samples/rssexpandedstacked-1/38.txt +++ b/test/samples/rssexpandedstacked-1/38.txt @@ -1 +1 @@ -(10)1098'1234 \ No newline at end of file +101098'1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/39.txt b/test/samples/rssexpandedstacked-1/39.txt index 18b90ec777..3feae80189 100644 --- a/test/samples/rssexpandedstacked-1/39.txt +++ b/test/samples/rssexpandedstacked-1/39.txt @@ -1 +1 @@ -(10)1098+1234 \ No newline at end of file +101098+1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/4.txt b/test/samples/rssexpandedstacked-1/4.txt index fca726b060..bf3d1e612c 100644 --- a/test/samples/rssexpandedstacked-1/4.txt +++ b/test/samples/rssexpandedstacked-1/4.txt @@ -1 +1 @@ -(01)91234567980129(3102)012233(15)000101 \ No newline at end of file +0191234567980129310201223315000101 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/40.txt b/test/samples/rssexpandedstacked-1/40.txt index 96f90494bd..43ec78faf5 100644 --- a/test/samples/rssexpandedstacked-1/40.txt +++ b/test/samples/rssexpandedstacked-1/40.txt @@ -1 +1 @@ -(10)1098:1234 \ No newline at end of file +101098:1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/41.txt b/test/samples/rssexpandedstacked-1/41.txt index 2dd84d5e6b..4b0a48386a 100644 --- a/test/samples/rssexpandedstacked-1/41.txt +++ b/test/samples/rssexpandedstacked-1/41.txt @@ -1 +1 @@ -(10)1098;1234 \ No newline at end of file +101098;1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/42.txt b/test/samples/rssexpandedstacked-1/42.txt index a64a6db2a8..bac6e34f0c 100644 --- a/test/samples/rssexpandedstacked-1/42.txt +++ b/test/samples/rssexpandedstacked-1/42.txt @@ -1 +1 @@ -(10)1098<1234 \ No newline at end of file +101098<1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/43.txt b/test/samples/rssexpandedstacked-1/43.txt index c7cc6061b7..1678854264 100644 --- a/test/samples/rssexpandedstacked-1/43.txt +++ b/test/samples/rssexpandedstacked-1/43.txt @@ -1 +1 @@ -(10)1098=1234 \ No newline at end of file +101098=1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/44.txt b/test/samples/rssexpandedstacked-1/44.txt index 7345e4ec31..967d803057 100644 --- a/test/samples/rssexpandedstacked-1/44.txt +++ b/test/samples/rssexpandedstacked-1/44.txt @@ -1 +1 @@ -(10)1098>1234 \ No newline at end of file +101098>1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/45.txt b/test/samples/rssexpandedstacked-1/45.txt index 5e152de159..91293e57f9 100644 --- a/test/samples/rssexpandedstacked-1/45.txt +++ b/test/samples/rssexpandedstacked-1/45.txt @@ -1 +1 @@ -(10)1098?1234 \ No newline at end of file +101098?1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/46.txt b/test/samples/rssexpandedstacked-1/46.txt index aad1b28524..d892771714 100644 --- a/test/samples/rssexpandedstacked-1/46.txt +++ b/test/samples/rssexpandedstacked-1/46.txt @@ -1 +1 @@ -(10)1098_1234 \ No newline at end of file +101098_1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/47.txt b/test/samples/rssexpandedstacked-1/47.txt index 4339de91be..07d4b42372 100644 --- a/test/samples/rssexpandedstacked-1/47.txt +++ b/test/samples/rssexpandedstacked-1/47.txt @@ -1 +1 @@ -(10)1098 1234 \ No newline at end of file +101098 1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/48.txt b/test/samples/rssexpandedstacked-1/48.txt index 6f63fb0d8e..8dda74e6cd 100644 --- a/test/samples/rssexpandedstacked-1/48.txt +++ b/test/samples/rssexpandedstacked-1/48.txt @@ -1 +1 @@ -(10)123456A \ No newline at end of file +10123456A \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/49.txt b/test/samples/rssexpandedstacked-1/49.txt index 5c1b912a9b..9638dbe444 100644 --- a/test/samples/rssexpandedstacked-1/49.txt +++ b/test/samples/rssexpandedstacked-1/49.txt @@ -1 +1 @@ -(10)123456A1 \ No newline at end of file +10123456A1 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/5.txt b/test/samples/rssexpandedstacked-1/5.txt index b4113ac56d..aee1d62673 100644 --- a/test/samples/rssexpandedstacked-1/5.txt +++ b/test/samples/rssexpandedstacked-1/5.txt @@ -1 +1 @@ -(01)90012345678908(3103)001750 \ No newline at end of file +01900123456789083103001750 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/50.txt b/test/samples/rssexpandedstacked-1/50.txt index d77a4769e3..90e67659dc 100644 --- a/test/samples/rssexpandedstacked-1/50.txt +++ b/test/samples/rssexpandedstacked-1/50.txt @@ -1 +1 @@ -(10)123456A123 \ No newline at end of file +10123456A123 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/51.txt b/test/samples/rssexpandedstacked-1/51.txt index 2e2ec43d09..c894b12b79 100644 --- a/test/samples/rssexpandedstacked-1/51.txt +++ b/test/samples/rssexpandedstacked-1/51.txt @@ -1 +1 @@ -(10)123456A1234 \ No newline at end of file +10123456A1234 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/52.txt b/test/samples/rssexpandedstacked-1/52.txt index b607d14301..0019761597 100644 --- a/test/samples/rssexpandedstacked-1/52.txt +++ b/test/samples/rssexpandedstacked-1/52.txt @@ -1 +1 @@ -(10)123456A1234A \ No newline at end of file +10123456A1234A \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/53.txt b/test/samples/rssexpandedstacked-1/53.txt index 389adcaf73..fc70522c01 100644 --- a/test/samples/rssexpandedstacked-1/53.txt +++ b/test/samples/rssexpandedstacked-1/53.txt @@ -1 +1 @@ -(10)123456A123456 \ No newline at end of file +10123456A123456 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/54.txt b/test/samples/rssexpandedstacked-1/54.txt index fffde5d07d..b1a0a8909c 100644 --- a/test/samples/rssexpandedstacked-1/54.txt +++ b/test/samples/rssexpandedstacked-1/54.txt @@ -1 +1 @@ -(10)123456A12345678 \ No newline at end of file +10123456A12345678 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/55-corrected.txt b/test/samples/rssexpandedstacked-1/55-corrected.txt index 1ad0fbd888..b7ca18f986 100644 --- a/test/samples/rssexpandedstacked-1/55-corrected.txt +++ b/test/samples/rssexpandedstacked-1/55-corrected.txt @@ -1 +1 @@ -(10)123456A1234A(15)991231 \ No newline at end of file +10123456A1234A15991231 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/55.txt b/test/samples/rssexpandedstacked-1/55.txt index 1ad0fbd888..b7ca18f986 100644 --- a/test/samples/rssexpandedstacked-1/55.txt +++ b/test/samples/rssexpandedstacked-1/55.txt @@ -1 +1 @@ -(10)123456A1234A(15)991231 \ No newline at end of file +10123456A1234A15991231 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/56.txt b/test/samples/rssexpandedstacked-1/56.txt index ac7961799b..c9063887c8 100644 --- a/test/samples/rssexpandedstacked-1/56.txt +++ b/test/samples/rssexpandedstacked-1/56.txt @@ -1 +1 @@ -(10)1ABCDEF;:/1234567 \ No newline at end of file +101ABCDEF;:/1234567 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/57.txt b/test/samples/rssexpandedstacked-1/57.txt index 163b64b566..a8e72e07cc 100644 --- a/test/samples/rssexpandedstacked-1/57.txt +++ b/test/samples/rssexpandedstacked-1/57.txt @@ -1 +1 @@ -(10)1ABCDEF;:/ABCDEFG \ No newline at end of file +101ABCDEF;:/ABCDEFG \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/58.txt b/test/samples/rssexpandedstacked-1/58.txt index d359328c90..5e59f66082 100644 --- a/test/samples/rssexpandedstacked-1/58.txt +++ b/test/samples/rssexpandedstacked-1/58.txt @@ -1 +1 @@ -(10)1;:/ABCDEFGHIJKLM \ No newline at end of file +101;:/ABCDEFGHIJKLM \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/59.txt b/test/samples/rssexpandedstacked-1/59.txt index c25e84f78f..41d6022acc 100644 --- a/test/samples/rssexpandedstacked-1/59.txt +++ b/test/samples/rssexpandedstacked-1/59.txt @@ -1 +1 @@ -(10)1;:/0123456789012 \ No newline at end of file +101;:/0123456789012 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/6.txt b/test/samples/rssexpandedstacked-1/6.txt index 57a2c644e1..2838c85fd5 100644 --- a/test/samples/rssexpandedstacked-1/6.txt +++ b/test/samples/rssexpandedstacked-1/6.txt @@ -1 +1 @@ -(01)92109876543213(3103)032767 \ No newline at end of file +01921098765432133103032767 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/60.txt b/test/samples/rssexpandedstacked-1/60.txt index 2914766cb8..1778e170dd 100644 --- a/test/samples/rssexpandedstacked-1/60.txt +++ b/test/samples/rssexpandedstacked-1/60.txt @@ -1 +1 @@ -(10)1;:/0123 \ No newline at end of file +101;:/0123 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/61.txt b/test/samples/rssexpandedstacked-1/61.txt index c8be9f3bc1..21abbac01b 100644 --- a/test/samples/rssexpandedstacked-1/61.txt +++ b/test/samples/rssexpandedstacked-1/61.txt @@ -1 +1 @@ -(10)1;:/0123(15)991231 \ No newline at end of file +101;:/012315991231 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/62.txt b/test/samples/rssexpandedstacked-1/62.txt index 9a1581d3e4..97a55e1d74 100644 --- a/test/samples/rssexpandedstacked-1/62.txt +++ b/test/samples/rssexpandedstacked-1/62.txt @@ -1 +1 @@ -(10)1 \ No newline at end of file +101 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/63.txt b/test/samples/rssexpandedstacked-1/63.txt index 4c3769ffc5..9a7b90a321 100644 --- a/test/samples/rssexpandedstacked-1/63.txt +++ b/test/samples/rssexpandedstacked-1/63.txt @@ -1 +1 @@ -(10)12A \ No newline at end of file +1012A \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/64.txt b/test/samples/rssexpandedstacked-1/64.txt index 62c17f167c..3bbd5e5122 100644 --- a/test/samples/rssexpandedstacked-1/64.txt +++ b/test/samples/rssexpandedstacked-1/64.txt @@ -1 +1 @@ -(10)123 \ No newline at end of file +10123 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/7.txt b/test/samples/rssexpandedstacked-1/7.txt index bfa41779e7..d091ce7bf9 100644 --- a/test/samples/rssexpandedstacked-1/7.txt +++ b/test/samples/rssexpandedstacked-1/7.txt @@ -1 +1 @@ -(01)92109876543213(3103)000000 \ No newline at end of file +01921098765432133103000000 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/8.txt b/test/samples/rssexpandedstacked-1/8.txt index e0da7fa314..6e64d025ce 100644 --- a/test/samples/rssexpandedstacked-1/8.txt +++ b/test/samples/rssexpandedstacked-1/8.txt @@ -1 +1 @@ -(01)90012345678908(3202)000156 \ No newline at end of file +01900123456789083202000156 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-1/9.txt b/test/samples/rssexpandedstacked-1/9.txt index 01af485cc6..5218dfc1c0 100644 --- a/test/samples/rssexpandedstacked-1/9.txt +++ b/test/samples/rssexpandedstacked-1/9.txt @@ -1 +1 @@ -(01)90012345678908(3202)009999 \ No newline at end of file +01900123456789083202009999 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-2/1.txt b/test/samples/rssexpandedstacked-2/1.txt index 963f111ec5..ef7c5515ad 100644 --- a/test/samples/rssexpandedstacked-2/1.txt +++ b/test/samples/rssexpandedstacked-2/1.txt @@ -1 +1 @@ -(8110)10014141012345290110100 \ No newline at end of file +811010014141012345290110100 \ No newline at end of file diff --git a/test/samples/rssexpandedstacked-2/1000.txt b/test/samples/rssexpandedstacked-2/1000.txt index 4e8655ca59..395fb680dc 100644 --- a/test/samples/rssexpandedstacked-2/1000.txt +++ b/test/samples/rssexpandedstacked-2/1000.txt @@ -1 +1 @@ -(01)98898765432106(3202)012345(15)991231 \ No newline at end of file +0198898765432106320201234515991231 \ No newline at end of file diff --git a/test/unit/ThresholdBinarizerTest.cpp b/test/unit/ThresholdBinarizerTest.cpp index bcf8ab6839..8b34bfd4b8 100644 --- a/test/unit/ThresholdBinarizerTest.cpp +++ b/test/unit/ThresholdBinarizerTest.cpp @@ -99,5 +99,5 @@ TEST(ThresholdBinarizerTest, PatternRowClear) Result result = reader.decode(ThresholdBinarizer(getImageView(buf, bits), 0x7F)); EXPECT_TRUE(result.isValid()); - EXPECT_EQ(result.text(), "(91)12345678901234567890123456789012345678901234567890123456789012345678"); + EXPECT_EQ(result.text(), "9112345678901234567890123456789012345678901234567890123456789012345678"); } From 4937d3317d6936e2b8d136758035022b59940762 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Jul 2022 22:41:26 +0200 Subject: [PATCH 0390/1315] c++17: use nested namespaces and other c++17 features in public API --- core/src/BitHacks.h | 6 ++---- core/src/ByteArray.h | 7 +------ core/src/ZXBigInteger.h | 4 ++-- core/src/aztec/AZDetector.cpp | 2 +- core/src/aztec/AZDetectorResult.h | 6 ++---- core/src/aztec/AZEncoder.h | 6 ++---- core/src/aztec/AZEncodingState.h | 6 ++---- core/src/datamatrix/DMEncoderContext.h | 9 ++------- core/src/datamatrix/DMSymbolInfo.cpp | 1 - core/src/datamatrix/DMSymbolInfo.h | 8 +++----- core/src/datamatrix/DMSymbolShape.h | 6 ++---- core/src/datamatrix/DMWriter.cpp | 1 - core/src/datamatrix/DMWriter.h | 4 ++-- core/src/oned/ODCode128Patterns.h | 8 ++------ core/src/oned/ODUPCEANCommon.h | 8 ++------ core/src/oned/ODWriterHelper.h | 6 ++---- core/src/qrcode/QRCodecMode.h | 6 ++---- core/src/qrcode/QRDataBlock.h | 6 ++---- core/src/qrcode/QRDataMask.h | 6 ++---- core/src/qrcode/QRECB.h | 7 ++----- core/src/qrcode/QREncodeResult.h | 6 ++---- core/src/qrcode/QREncoder.h | 6 ++---- core/src/qrcode/QRErrorCorrectionLevel.h | 6 ++---- core/src/qrcode/QRFormatInformation.h | 6 ++---- core/src/qrcode/QRMaskUtil.h | 8 ++------ test/unit/datamatrix/DMEncodeDecodeTest.cpp | 1 - test/unit/datamatrix/DMHighLevelEncodeTest.cpp | 1 - test/unit/datamatrix/DMSymbolInfoTest.cpp | 1 - test/unit/datamatrix/DMWriterTest.cpp | 1 - 29 files changed, 45 insertions(+), 104 deletions(-) diff --git a/core/src/BitHacks.h b/core/src/BitHacks.h index 482b181a8b..f21a15460e 100644 --- a/core/src/BitHacks.h +++ b/core/src/BitHacks.h @@ -14,8 +14,7 @@ #define ZX_HAS_GCC_BUILTINS #endif -namespace ZXing { -namespace BitHacks { +namespace ZXing::BitHacks { /** * The code below is taken from https://graphics.stanford.edu/~seander/bithacks.html @@ -135,5 +134,4 @@ void Reverse(std::vector& bits, std::size_t padding) ShiftRight(bits, padding); } -} // BitHacks -} // ZXing +} // namespace ZXing::BitHacks diff --git a/core/src/ByteArray.h b/core/src/ByteArray.h index a31f42c1ed..a68a38090e 100644 --- a/core/src/ByteArray.h +++ b/core/src/ByteArray.h @@ -9,11 +9,8 @@ #include #include #include -#include - -#ifdef __cpp_lib_string_view #include -#endif +#include namespace ZXing { @@ -30,12 +27,10 @@ class ByteArray : public std::vector void append(const ByteArray& other) { insert(end(), other.begin(), other.end()); } -#ifdef __cpp_lib_string_view std::string_view asString(size_t pos = 0, size_t len = std::string_view::npos) const { return std::string_view(reinterpret_cast(data()), size()).substr(pos, len); } -#endif }; inline std::string ToHex(const ByteArray& bytes) diff --git a/core/src/ZXBigInteger.h b/core/src/ZXBigInteger.h index 92aa21b0f6..9bda684e43 100644 --- a/core/src/ZXBigInteger.h +++ b/core/src/ZXBigInteger.h @@ -28,10 +28,10 @@ class BigInteger BigInteger() = default; template - BigInteger(T x, typename std::enable_if::value && std::is_unsigned::value>::type* = nullptr) : mag(1, x) {} + BigInteger(T x, typename std::enable_if_t && std::is_unsigned_v>* = nullptr) : mag(1, x) {} template - BigInteger(T x, typename std::enable_if::value && std::is_signed::value>::type* = nullptr) : negative(x < 0), mag(1, std::abs(x)) {} + BigInteger(T x, typename std::enable_if_t && std::is_signed_v>* = nullptr) : negative(x < 0), mag(1, std::abs(x)) {} static bool TryParse(const std::string& str, BigInteger& result); static bool TryParse(const std::wstring& str, BigInteger& result); diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index 8f14fe07f6..099864ee57 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -21,7 +21,7 @@ namespace ZXing::Aztec { -template ::value>::type> +template >> static int RoundToNearest(T x) { return narrow_cast(std::lround(x)); diff --git a/core/src/aztec/AZDetectorResult.h b/core/src/aztec/AZDetectorResult.h index 54c6c5524e..193e6ef768 100644 --- a/core/src/aztec/AZDetectorResult.h +++ b/core/src/aztec/AZDetectorResult.h @@ -10,8 +10,7 @@ #include -namespace ZXing { -namespace Aztec { +namespace ZXing::Aztec { class DetectorResult : public ZXing::DetectorResult { @@ -39,5 +38,4 @@ class DetectorResult : public ZXing::DetectorResult bool readerInit() const { return _readerInit; } }; -} // Aztec -} // ZXing +} // namespace ZXing::Aztec diff --git a/core/src/aztec/AZEncoder.h b/core/src/aztec/AZEncoder.h index 3c8d5351a3..47311c0c90 100644 --- a/core/src/aztec/AZEncoder.h +++ b/core/src/aztec/AZEncoder.h @@ -10,8 +10,7 @@ #include -namespace ZXing { -namespace Aztec { +namespace ZXing::Aztec { /** * Aztec 2D code representation @@ -41,5 +40,4 @@ class Encoder static EncodeResult Encode(const std::string& data, int minECCPercent, int userSpecifiedLayers); }; -} // Aztec -} // ZXing +} // namespace ZXing::Aztec diff --git a/core/src/aztec/AZEncodingState.h b/core/src/aztec/AZEncodingState.h index 71ee8d3292..039a9d791a 100644 --- a/core/src/aztec/AZEncodingState.h +++ b/core/src/aztec/AZEncodingState.h @@ -10,8 +10,7 @@ #include -namespace ZXing { -namespace Aztec { +namespace ZXing::Aztec { class Token; @@ -38,5 +37,4 @@ class EncodingState int bitCount = 0; }; -} // Aztec -} // ZXing +} // namespace ZXing::Aztec diff --git a/core/src/datamatrix/DMEncoderContext.h b/core/src/datamatrix/DMEncoderContext.h index ecd9b0b032..fa1b0f9fc5 100644 --- a/core/src/datamatrix/DMEncoderContext.h +++ b/core/src/datamatrix/DMEncoderContext.h @@ -8,17 +8,13 @@ #include "ByteArray.h" #include "DMSymbolInfo.h" -#include "DMSymbolShape.h" #include "ZXAlgorithms.h" #include #include #include -namespace ZXing { -namespace DataMatrix { - -class SymbolInfo; +namespace ZXing::DataMatrix { class EncoderContext { @@ -129,5 +125,4 @@ class EncoderContext } }; -} // DataMatrix -} // ZXing +} // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMSymbolInfo.cpp b/core/src/datamatrix/DMSymbolInfo.cpp index f3505a69a5..9247dd2609 100644 --- a/core/src/datamatrix/DMSymbolInfo.cpp +++ b/core/src/datamatrix/DMSymbolInfo.cpp @@ -6,7 +6,6 @@ #include "DMSymbolInfo.h" -#include "DMSymbolShape.h" #include "ZXAlgorithms.h" #include "ZXTestSupport.h" diff --git a/core/src/datamatrix/DMSymbolInfo.h b/core/src/datamatrix/DMSymbolInfo.h index fa366da4a1..2936785237 100644 --- a/core/src/datamatrix/DMSymbolInfo.h +++ b/core/src/datamatrix/DMSymbolInfo.h @@ -6,10 +6,9 @@ #pragma once -namespace ZXing { -namespace DataMatrix { +#include "DMSymbolShape.h" -enum class SymbolShape; +namespace ZXing::DataMatrix { class SymbolInfo { @@ -76,5 +75,4 @@ class SymbolInfo int errorLengthForInterleavedBlock() const { return _rsBlockError; } }; -} // DataMatrix -} // ZXing +} // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMSymbolShape.h b/core/src/datamatrix/DMSymbolShape.h index 3c15f5d156..4192e83887 100644 --- a/core/src/datamatrix/DMSymbolShape.h +++ b/core/src/datamatrix/DMSymbolShape.h @@ -6,8 +6,7 @@ #pragma once -namespace ZXing { -namespace DataMatrix { +namespace ZXing::DataMatrix { enum class SymbolShape { NONE, @@ -15,5 +14,4 @@ enum class SymbolShape { RECTANGLE, }; -} // DataMatrix -} // ZXing +} // namespace ZXing::DataMatrix diff --git a/core/src/datamatrix/DMWriter.cpp b/core/src/datamatrix/DMWriter.cpp index 8c8f7bd3d3..f2b61c5682 100644 --- a/core/src/datamatrix/DMWriter.cpp +++ b/core/src/datamatrix/DMWriter.cpp @@ -12,7 +12,6 @@ #include "DMECEncoder.h" #include "DMHighLevelEncoder.h" #include "DMSymbolInfo.h" -#include "DMSymbolShape.h" #include "TextUtfEncoding.h" #include diff --git a/core/src/datamatrix/DMWriter.h b/core/src/datamatrix/DMWriter.h index f126e6eb35..c0e3a43ee4 100644 --- a/core/src/datamatrix/DMWriter.h +++ b/core/src/datamatrix/DMWriter.h @@ -6,6 +6,8 @@ #pragma once +#include "DMSymbolShape.h" + #include namespace ZXing { @@ -14,8 +16,6 @@ class BitMatrix; namespace DataMatrix { -enum class SymbolShape; - class Writer { public: diff --git a/core/src/oned/ODCode128Patterns.h b/core/src/oned/ODCode128Patterns.h index 391e9be30d..09099a9f4a 100644 --- a/core/src/oned/ODCode128Patterns.h +++ b/core/src/oned/ODCode128Patterns.h @@ -8,12 +8,8 @@ #include -namespace ZXing { -namespace OneD { -namespace Code128 { +namespace ZXing::OneD::Code128 { extern const std::array, 107> CODE_PATTERNS; -} // Code128 -} // OneD -} // ZXing +} // namespace ZXing::OneD::Code128 diff --git a/core/src/oned/ODUPCEANCommon.h b/core/src/oned/ODUPCEANCommon.h index 3c0eb59ac3..52369435d9 100644 --- a/core/src/oned/ODUPCEANCommon.h +++ b/core/src/oned/ODUPCEANCommon.h @@ -13,9 +13,7 @@ #include #include -namespace ZXing { -namespace OneD { -namespace UPCEANCommon { +namespace ZXing::OneD::UPCEANCommon { using Digit = std::array; @@ -128,6 +126,4 @@ StringT ConvertUPCEtoUPCA(const StringT& upce) return result; } -} // namespace UPCEANCommon -} // namespace OneD -} // namespace ZXing +} // namespace ZXing::OneD::UPCEANCommon diff --git a/core/src/oned/ODWriterHelper.h b/core/src/oned/ODWriterHelper.h index f50f644df1..e6b20e02bb 100644 --- a/core/src/oned/ODWriterHelper.h +++ b/core/src/oned/ODWriterHelper.h @@ -11,8 +11,7 @@ #include #include -namespace ZXing { -namespace OneD { +namespace ZXing::OneD { /** *

Encapsulates functionality and implementation that is common to one-dimensional barcodes.

@@ -41,5 +40,4 @@ class WriterHelper } }; -} // OneD -} // ZXing +} // namespace ZXing::OneD diff --git a/core/src/qrcode/QRCodecMode.h b/core/src/qrcode/QRCodecMode.h index 830b2f897a..54c5dbe622 100644 --- a/core/src/qrcode/QRCodecMode.h +++ b/core/src/qrcode/QRCodecMode.h @@ -6,8 +6,7 @@ #pragma once -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { class Version; @@ -56,5 +55,4 @@ int CodecModeBitsLength(const Version& version); */ int TerminatorBitsLength(const Version& version); -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRDataBlock.h b/core/src/qrcode/QRDataBlock.h index d5f9858785..1e7c8e9908 100644 --- a/core/src/qrcode/QRDataBlock.h +++ b/core/src/qrcode/QRDataBlock.h @@ -10,8 +10,7 @@ #include -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { class Version; enum class ErrorCorrectionLevel; @@ -50,5 +49,4 @@ class DataBlock ByteArray _codewords; }; -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRDataMask.h b/core/src/qrcode/QRDataMask.h index b735baf9ec..d8f057a897 100644 --- a/core/src/qrcode/QRDataMask.h +++ b/core/src/qrcode/QRDataMask.h @@ -11,8 +11,7 @@ #include #include -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { /** *

Encapsulates data masks for the data bits in a QR and micro QR code, per ISO 18004:2006 6.8.

@@ -48,5 +47,4 @@ inline bool GetMaskedBit(const BitMatrix& bits, int x, int y, int maskIndex, boo return GetDataMaskBit(maskIndex, x, y, isMicro) != bits.get(x, y); } -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRECB.h b/core/src/qrcode/QRECB.h index 37cefea6df..6829e695b2 100644 --- a/core/src/qrcode/QRECB.h +++ b/core/src/qrcode/QRECB.h @@ -8,8 +8,7 @@ #include -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { /** *

Encapsulates the parameters for one error-correction block in one symbol version. @@ -50,6 +49,4 @@ struct ECBlocks const std::array& blockArray() const { return blocks; } }; - -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QREncodeResult.h b/core/src/qrcode/QREncodeResult.h index 8898c04dc3..9163df102b 100644 --- a/core/src/qrcode/QREncodeResult.h +++ b/core/src/qrcode/QREncodeResult.h @@ -11,8 +11,7 @@ #include "QRCodecMode.h" #include "QRVersion.h" -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { /** * @author satorux@google.com (Satoru Takabayashi) - creator @@ -31,5 +30,4 @@ class EncodeResult BitMatrix matrix; }; -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QREncoder.h b/core/src/qrcode/QREncoder.h index acf49b451f..26352e54c3 100644 --- a/core/src/qrcode/QREncoder.h +++ b/core/src/qrcode/QREncoder.h @@ -10,8 +10,7 @@ #include -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { enum class ErrorCorrectionLevel; class EncodeResult; @@ -19,5 +18,4 @@ class EncodeResult; EncodeResult Encode(const std::wstring& content, ErrorCorrectionLevel ecLevel, CharacterSet encoding, int versionNumber, bool useGs1Format, int maskPattern = -1); -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRErrorCorrectionLevel.h b/core/src/qrcode/QRErrorCorrectionLevel.h index 704fc86939..38bd9ac307 100644 --- a/core/src/qrcode/QRErrorCorrectionLevel.h +++ b/core/src/qrcode/QRErrorCorrectionLevel.h @@ -6,8 +6,7 @@ #pragma once -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { /** *

See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels @@ -29,5 +28,4 @@ ErrorCorrectionLevel ECLevelFromString(const char* str); ErrorCorrectionLevel ECLevelFromBits(int bits, const bool isMicro = false); int BitsFromECLevel(ErrorCorrectionLevel l); -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRFormatInformation.h b/core/src/qrcode/QRFormatInformation.h index d7d59a2d9d..da15d940bc 100644 --- a/core/src/qrcode/QRFormatInformation.h +++ b/core/src/qrcode/QRFormatInformation.h @@ -10,8 +10,7 @@ #include -namespace ZXing { -namespace QRCode { +namespace ZXing::QRCode { class FormatInformation { @@ -37,5 +36,4 @@ class FormatInformation } }; -} // QRCode -} // ZXing +} // namespace ZXing::QRCode diff --git a/core/src/qrcode/QRMaskUtil.h b/core/src/qrcode/QRMaskUtil.h index f7a0c06ddd..440247bb53 100644 --- a/core/src/qrcode/QRMaskUtil.h +++ b/core/src/qrcode/QRMaskUtil.h @@ -8,12 +8,8 @@ #include "TritMatrix.h" -namespace ZXing { -namespace QRCode { -namespace MaskUtil { +namespace ZXing::QRCode::MaskUtil { int CalculateMaskPenalty(const TritMatrix& matrix); -} // namespace MaskUtil -} // namespace QRCode -} // namespace ZXing +} // namespace ZXing::QRCode::MaskUtil diff --git a/test/unit/datamatrix/DMEncodeDecodeTest.cpp b/test/unit/datamatrix/DMEncodeDecodeTest.cpp index 10a4f7b98d..da64b8c415 100644 --- a/test/unit/datamatrix/DMEncodeDecodeTest.cpp +++ b/test/unit/datamatrix/DMEncodeDecodeTest.cpp @@ -7,7 +7,6 @@ #include "BitMatrixIO.h" #include "DecoderResult.h" #include "datamatrix/DMDecoder.h" -#include "datamatrix/DMSymbolShape.h" #include "datamatrix/DMWriter.h" #include diff --git a/test/unit/datamatrix/DMHighLevelEncodeTest.cpp b/test/unit/datamatrix/DMHighLevelEncodeTest.cpp index 5a8a57ef6e..75eebe3d0b 100644 --- a/test/unit/datamatrix/DMHighLevelEncodeTest.cpp +++ b/test/unit/datamatrix/DMHighLevelEncodeTest.cpp @@ -8,7 +8,6 @@ #include "ZXAlgorithms.h" #include "datamatrix/DMHighLevelEncoder.h" #include "datamatrix/DMSymbolInfo.h" -#include "datamatrix/DMSymbolShape.h" #include "gtest/gtest.h" diff --git a/test/unit/datamatrix/DMSymbolInfoTest.cpp b/test/unit/datamatrix/DMSymbolInfoTest.cpp index bae53e8542..1d9268f135 100644 --- a/test/unit/datamatrix/DMSymbolInfoTest.cpp +++ b/test/unit/datamatrix/DMSymbolInfoTest.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 #include "datamatrix/DMSymbolInfo.h" -#include "datamatrix/DMSymbolShape.h" #include "gtest/gtest.h" diff --git a/test/unit/datamatrix/DMWriterTest.cpp b/test/unit/datamatrix/DMWriterTest.cpp index 4aa0738e51..a47f2b743b 100644 --- a/test/unit/datamatrix/DMWriterTest.cpp +++ b/test/unit/datamatrix/DMWriterTest.cpp @@ -6,7 +6,6 @@ #include "datamatrix/DMWriter.h" #include "BitMatrixIO.h" -#include "datamatrix/DMSymbolShape.h" #include "gtest/gtest.h" From e31e031e0d1fe51f3ad6cc081df7ff69ac66aef1 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 14 Jul 2022 22:42:04 +0200 Subject: [PATCH 0391/1315] IWUY: remove unused includes --- core/src/aztec/AZDecoder.h | 2 -- core/src/datamatrix/DMDecoder.h | 2 -- core/src/maxicode/MCDecoder.h | 2 -- core/src/qrcode/QRDecoder.h | 2 -- 4 files changed, 8 deletions(-) diff --git a/core/src/aztec/AZDecoder.h b/core/src/aztec/AZDecoder.h index 2054c2fd92..d8580a40a7 100644 --- a/core/src/aztec/AZDecoder.h +++ b/core/src/aztec/AZDecoder.h @@ -6,8 +6,6 @@ #pragma once -#include - namespace ZXing { class DecoderResult; diff --git a/core/src/datamatrix/DMDecoder.h b/core/src/datamatrix/DMDecoder.h index e8aac914f6..c2a1a28606 100644 --- a/core/src/datamatrix/DMDecoder.h +++ b/core/src/datamatrix/DMDecoder.h @@ -6,8 +6,6 @@ #pragma once -#include - namespace ZXing { class DecoderResult; diff --git a/core/src/maxicode/MCDecoder.h b/core/src/maxicode/MCDecoder.h index e53f533766..066c332e3d 100644 --- a/core/src/maxicode/MCDecoder.h +++ b/core/src/maxicode/MCDecoder.h @@ -6,8 +6,6 @@ #pragma once -#include - namespace ZXing { class DecoderResult; diff --git a/core/src/qrcode/QRDecoder.h b/core/src/qrcode/QRDecoder.h index ecfdc92be1..2b724fc172 100644 --- a/core/src/qrcode/QRDecoder.h +++ b/core/src/qrcode/QRDecoder.h @@ -6,8 +6,6 @@ #pragma once -#include - namespace ZXing { class DecoderResult; From cba613d523d3be3116542f2f86c3e5f4cd2bbddd Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Jul 2022 01:40:18 +0200 Subject: [PATCH 0392/1315] ZXAlgorithms: Make ToString(val, len) perform a bounds check on the input --- core/src/ZXAlgorithms.h | 12 ++++++++---- test/unit/CMakeLists.txt | 1 + test/unit/ZXAlgorithmsTest.cpp | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 test/unit/ZXAlgorithmsTest.cpp diff --git a/core/src/ZXAlgorithms.h b/core/src/ZXAlgorithms.h index 5b52f22e1a..dc1859afb3 100644 --- a/core/src/ZXAlgorithms.h +++ b/core/src/ZXAlgorithms.h @@ -5,6 +5,8 @@ #pragma once +#include "Error.h" + #include #include #include @@ -79,13 +81,15 @@ Value TransformReduce(const Container& c, Value s, UnaryOp op) { } template>> -std::string ToString(T n, int len) +std::string ToString(T val, int len) { std::string result(len--, '0'); - for (T val = (n < 0) ? -n : n; len >= 0 && val != 0; --len, val /= 10) + if (val < 0) + throw FormatError("Invalid value"); + for (; len >= 0 && val != 0; --len, val /= 10) result[len] = '0' + val % 10; - if (len >= 0 && n < 0) - result[0] = '-'; + if (val) + throw FormatError("Invalid value"); return result; } diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 9d3e38a4bd..6edfcc2bc2 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable (UnitTest TextDecoderTest.cpp TextUtfEncodingTest.cpp ThresholdBinarizerTest.cpp + ZXAlgorithmsTest.cpp aztec/AZDetectorTest.cpp aztec/AZDecoderTest.cpp aztec/AZEncoderTest.cpp diff --git a/test/unit/ZXAlgorithmsTest.cpp b/test/unit/ZXAlgorithmsTest.cpp new file mode 100644 index 0000000000..29f522fd26 --- /dev/null +++ b/test/unit/ZXAlgorithmsTest.cpp @@ -0,0 +1,21 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "ZXAlgorithms.h" + +#include "gtest/gtest.h" + +using namespace ZXing; + +TEST(ZXAlgorithmsTest, ToString) +{ + EXPECT_EQ(ToString(0, 1), "0"); + EXPECT_EQ(ToString(0, 2), "00"); + EXPECT_EQ(ToString(1, 3), "001"); + EXPECT_EQ(ToString(99, 2), "99"); + + EXPECT_THROW(ToString(-1, 2), Error); + EXPECT_THROW(ToString(111, 2), Error); +} From 2d55b5a4f1d40ce9e10def1f14521949343cff8e Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Jul 2022 01:41:07 +0200 Subject: [PATCH 0393/1315] ZXAlgorithms: use ToString(val, len) in 2 more places --- core/src/datamatrix/DMDecoder.cpp | 5 +---- core/src/qrcode/QRDecoder.cpp | 33 +++++-------------------------- 2 files changed, 6 insertions(+), 32 deletions(-) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index be879b54f1..96115f9772 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -335,10 +335,7 @@ DecoderResult Decode(ByteArray&& bytes, const bool isDMRE) if (oneByte <= 128) { // ASCII data (ASCII value + 1) result.push_back(upperShift(oneByte) - 1); } else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130) - int value = oneByte - 130; - if (value < 10) // pad with '0' for single digit values - result.push_back('0'); - result.append(std::to_string(value)); + result.append(ToString(oneByte - 130, 2)); } else if (oneByte >= 242) { // Not to be used in ASCII encodation // work around encoders that use unlatch to ASCII as last code word (ask upstream) if (oneByte == 254 && bits.available() == 0) diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 457bebac71..21720d1996 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -170,34 +170,11 @@ static void DecodeNumericSegment(BitSource& bits, int count, Content& result) result.switchEncoding(CharacterSet::ISO8859_1); result.reserve(count); - // Read three digits at a time - while (count >= 3) { - // Each 10 bits encodes three digits - int threeDigitsBits = bits.readBits(10); - if (threeDigitsBits >= 1000) - throw FormatError("Invalid value in numeric segment"); - - result += ToAlphaNumericChar(threeDigitsBits / 100); - result += ToAlphaNumericChar((threeDigitsBits / 10) % 10); - result += ToAlphaNumericChar(threeDigitsBits % 10); - count -= 3; - } - - if (count == 2) { - // Two digits left over to read, encoded in 7 bits - int twoDigitsBits = bits.readBits(7); - if (twoDigitsBits >= 100) - throw FormatError("Invalid value in numeric segment"); - - result += ToAlphaNumericChar(twoDigitsBits / 10); - result += ToAlphaNumericChar(twoDigitsBits % 10); - } else if (count == 1) { - // One digit left over to read - int digitBits = bits.readBits(4); - if (digitBits >= 10) - throw FormatError("Invalid value in numeric segment"); - - result += ToAlphaNumericChar(digitBits); + while (count) { + int n = std::min(count, 3); + int nDigits = bits.readBits(1 + 3 * n); // read 4, 7 or 10 bits into 1, 2 or 3 digits + result.append(ZXing::ToString(nDigits, n)); + count -= n; } } From 8f4677345e71c638af576480066732522c328516 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Jul 2022 02:13:50 +0200 Subject: [PATCH 0394/1315] ZXAlgorithms: Introduce new `char ToDigit(int)` helper with bounds check --- core/src/GTIN.h | 2 +- core/src/ZXAlgorithms.h | 8 ++++++++ core/src/ZXBigInteger.cpp | 3 ++- core/src/oned/ODDataBarExpandedBitDecoder.cpp | 4 ++-- core/src/oned/ODITFReader.cpp | 2 +- core/src/oned/ODMultiUPCEANReader.cpp | 20 +++++++++++-------- test/unit/ZXAlgorithmsTest.cpp | 9 +++++++++ 7 files changed, 35 insertions(+), 13 deletions(-) diff --git a/core/src/GTIN.h b/core/src/GTIN.h index df9405c720..d56b604e5f 100644 --- a/core/src/GTIN.h +++ b/core/src/GTIN.h @@ -27,7 +27,7 @@ T ComputeCheckDigit(const std::basic_string& digits, bool skipTail = false) sum *= 3; for (int i = N - 2; i >= 0; i -= 2) sum += digits[i] - '0'; - return ((10 - (sum % 10)) % 10) + '0'; + return ToDigit((10 - (sum % 10)) % 10); } template diff --git a/core/src/ZXAlgorithms.h b/core/src/ZXAlgorithms.h index dc1859afb3..e3df402ff0 100644 --- a/core/src/ZXAlgorithms.h +++ b/core/src/ZXAlgorithms.h @@ -80,6 +80,14 @@ Value TransformReduce(const Container& c, Value s, UnaryOp op) { return s; } +template +T ToDigit(int i) +{ + if (i < 0 || i > 9) + throw FormatError("Invalid digit value"); + return static_cast('0' + i); +} + template>> std::string ToString(T val, int len) { diff --git a/core/src/ZXBigInteger.cpp b/core/src/ZXBigInteger.cpp index 56e67300e9..2ce84ccbc6 100644 --- a/core/src/ZXBigInteger.cpp +++ b/core/src/ZXBigInteger.cpp @@ -6,6 +6,7 @@ #include "ZXBigInteger.h" #include "BitHacks.h" +#include "ZXAlgorithms.h" #include #include @@ -606,7 +607,7 @@ BigInteger::toString() const size_t offset = result.size(); result.resize(offset + buffer.size()); - std::transform(buffer.rbegin(), buffer.rend(), result.begin() + offset, [](uint8_t c) { return static_cast('0' + c); }); + std::transform(buffer.rbegin(), buffer.rend(), result.begin() + offset, ToDigit); return result; } diff --git a/core/src/oned/ODDataBarExpandedBitDecoder.cpp b/core/src/oned/ODDataBarExpandedBitDecoder.cpp index 72fa11bef0..6a4924ca71 100644 --- a/core/src/oned/ODDataBarExpandedBitDecoder.cpp +++ b/core/src/oned/ODDataBarExpandedBitDecoder.cpp @@ -54,14 +54,14 @@ static std::string DecodeGeneralPurposeBits(BitArrayView& bits) if (bits.size() < 7) { int v = bits.readBits(4); if (v > 0) - res.push_back('0' + v - 1); + res.push_back(ToDigit(v - 1)); } else if (bits.peakBits(4) == 0) { bits.skipBits(4); state = ALPHA; } else { int v = bits.readBits(7); for (int digit : {(v - 8) / 11, (v - 8) % 11}) - res.push_back(digit == 10 ? GS : '0' + digit); + res.push_back(digit == 10 ? GS : ToDigit(digit)); } break; case ALPHA: diff --git a/core/src/oned/ODITFReader.cpp b/core/src/oned/ODITFReader.cpp index f2e8078196..eec3cf3799 100644 --- a/core/src/oned/ODITFReader.cpp +++ b/core/src/oned/ODITFReader.cpp @@ -52,7 +52,7 @@ Result ITFReader::decodePattern(int rowNumber, PatternView& next, std::unique_pt break; for (int i = 0; i < 2; ++i) - txt.push_back((char)('0' + (digits[i] == 11 ? 0 : digits[i]))); + txt.push_back(ToDigit(digits[i] == 11 ? 0 : digits[i])); next.skipSymbol(); } diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index bba83cdc23..608d8807c4 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -50,11 +50,14 @@ static bool DecodeDigit(const PatternView& view, std::string& txt, int* lgPatter int bestMatch = lgPattern ? RowReader::DecodeDigit(view, UPCEANCommon::L_AND_G_PATTERNS, MAX_AVG_VARIANCE, MAX_INDIVIDUAL_VARIANCE, false) : RowReader::DecodeDigit(view, UPCEANCommon::L_PATTERNS, MAX_AVG_VARIANCE, MAX_INDIVIDUAL_VARIANCE, false); - txt += '0' + (bestMatch % 10); + if (bestMatch == -1) + return false; + + txt += ToDigit(bestMatch % 10); if (lgPattern) AppendBit(*lgPattern, bestMatch >= 10); - return bestMatch != -1; + return true; #else constexpr int CHAR_SUM = 7; auto pattern = RowReader::OneToFourBitPattern(view); @@ -80,7 +83,7 @@ static bool DecodeDigit(const PatternView& view, std::string& txt, int* lgPatter 8 11011 00100 00100 9 00101 01011 11010 */ - constexpr char I = -1; // invalid pattern + constexpr char I = 0xf0; // invalid pattern const char digit[] = {I, I, 0x16, I, 0x18, 0x09, 0x00, I, 0x17, 0x02, I, 0x19, 0x01, 0x12, 0x14, I, @@ -89,7 +92,7 @@ static bool DecodeDigit(const PatternView& view, std::string& txt, int* lgPatter // clang-format on char d = digit[pattern]; - txt += '0' + (d & 0xf); + txt += ToDigit(d & 0xf); if (lgPattern) AppendBit(*lgPattern, (d >> 4) & 1); @@ -138,8 +141,9 @@ static bool EAN13(PartialResult& res, PatternView begin) CHECK(DecodeDigits(6, next, res.txt)); - res.txt[0] = '0' + IndexOf(FIRST_DIGIT_ENCODINGS, lgPattern); - CHECK(res.txt[0] != '0' - 1); + int i = IndexOf(FIRST_DIGIT_ENCODINGS, lgPattern); + CHECK(i != -1); + res.txt[0] = ToDigit(i); res.end = end; res.format = BarcodeFormat::EAN13; @@ -202,8 +206,8 @@ static bool UPCE(PartialResult& res, PatternView begin) int i = IndexOf(UPCEANCommon::NUMSYS_AND_CHECK_DIGIT_PATTERNS, lgPattern); CHECK(i != -1); - res.txt[0] = '0' + i / 10; - res.txt += '0' + i % 10; + res.txt[0] = ToDigit(i / 10); + res.txt += ToDigit(i % 10); res.end = end; res.format = BarcodeFormat::UPCE; diff --git a/test/unit/ZXAlgorithmsTest.cpp b/test/unit/ZXAlgorithmsTest.cpp index 29f522fd26..3531e88b48 100644 --- a/test/unit/ZXAlgorithmsTest.cpp +++ b/test/unit/ZXAlgorithmsTest.cpp @@ -9,6 +9,15 @@ using namespace ZXing; +TEST(ZXAlgorithmsTest, ToDigit) +{ + EXPECT_EQ(ToDigit(0), '0'); + EXPECT_EQ(ToDigit(9), '9'); + + EXPECT_THROW(ToDigit(-1), Error); + EXPECT_THROW(ToDigit(11), Error); +} + TEST(ZXAlgorithmsTest, ToString) { EXPECT_EQ(ToString(0, 1), "0"); From d6ccd214284f5348526d5f0a8c164929ed37c993 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 15 Jul 2022 02:16:07 +0200 Subject: [PATCH 0395/1315] c++: remove random c-style cast --- core/src/oned/ODMultiUPCEANReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/oned/ODMultiUPCEANReader.cpp b/core/src/oned/ODMultiUPCEANReader.cpp index 608d8807c4..c8888547d4 100644 --- a/core/src/oned/ODMultiUPCEANReader.cpp +++ b/core/src/oned/ODMultiUPCEANReader.cpp @@ -218,10 +218,10 @@ static int Ean5Checksum(const std::string& s) { int sum = 0, N = Size(s); for (int i = N - 2; i >= 0; i -= 2) - sum += (int)s[i] - (int)'0'; + sum += s[i] - '0'; sum *= 3; for (int i = N - 1; i >= 0; i -= 2) - sum += (int)s[i] - (int)'0'; + sum += s[i] - '0'; sum *= 3; return sum % 10; } From b74bec857d4560cf575596bef3082f46cc9f98a5 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 18 Jul 2022 17:58:52 +0200 Subject: [PATCH 0396/1315] c++20: make VS be happy (unclear whether or not the standard requries this) --- core/src/Generator.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/Generator.h b/core/src/Generator.h index 922af66d85..2423ca569e 100644 --- a/core/src/Generator.h +++ b/core/src/Generator.h @@ -27,6 +27,7 @@ class Generator return {}; } // void return_value(T&& value) noexcept { current_value = std::move(value); } + static void return_void() {} // required to compile in VisualStudio, no idea why clang/gcc are happy without // Disallow co_await in generator coroutines. void await_transform() = delete; [[noreturn]] static void unhandled_exception() { throw; } From 8bd2373092a1e4ed5e33f6cf764863156927138d Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 18 Jul 2022 17:59:43 +0200 Subject: [PATCH 0397/1315] VS: fix a type conversion warning (bool -> int) --- core/src/pdf417/PDFDetector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 78d9526e3e..f5d13236d0 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -342,7 +342,7 @@ Detector::Result Detector::Detect(const BinaryBitmap& image, bool multiple, bool Result result; - for (int rotate90 = false; rotate90 <= tryRotate && result.points.empty(); ++rotate90) { + for (int rotate90 = 0; rotate90 <= static_cast(tryRotate) && result.points.empty(); ++rotate90) { #if defined(ZX_FAST_BIT_STORAGE) if (!HasStartPattern(*binImg, rotate90)) continue; From d9aa98a106468d0d5476334f4a0490fd052dbc87 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 18 Jul 2022 18:01:55 +0200 Subject: [PATCH 0398/1315] DataMatrix: tune multi-symbol mode * respect `DecodeHints::returnErrors` * respect `DecodeHints::tryHarder` --- core/src/datamatrix/DMReader.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/src/datamatrix/DMReader.cpp b/core/src/datamatrix/DMReader.cpp index 06d21a9cce..0754a8411f 100644 --- a/core/src/datamatrix/DMReader.cpp +++ b/core/src/datamatrix/DMReader.cpp @@ -43,10 +43,13 @@ Results Reader::decode(const BinaryBitmap& image, int maxSymbols) const return {}; Results results; - for (auto&& res : Detect(*binImg, maxSymbols > 1, _hints.tryRotate(), _hints.isPure())) { - results.push_back(Result(Decode(res.bits()), std::move(res).position(), BarcodeFormat::DataMatrix)); - if (maxSymbols > 0 && Size(results) >= maxSymbols) - break; + for (auto&& detRes : Detect(*binImg, _hints.tryHarder(), _hints.tryRotate(), _hints.isPure())) { + auto decRes = Decode(detRes.bits()); + if (decRes.isValid(_hints.returnErrors())) { + results.emplace_back(std::move(decRes), std::move(detRes).position(), BarcodeFormat::DataMatrix); + if (maxSymbols > 0 && Size(results) >= maxSymbols) + break; + } } return results; From 1175cce8844adda47a38d093bec7086855229b85 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 19 Jul 2022 09:11:02 +0200 Subject: [PATCH 0399/1315] MCDecoder: fix \n vs \r issue The problem has originated from the upstream source and was reported here: https://github.com/zxing/zxing/issues/1543 --- core/src/maxicode/MCDecoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index f0f26c68ca..7022feac98 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -85,7 +85,7 @@ static const char RS = 0x1E; // clang-format off const static std::array CHARSETS[] = { { // set 0 (A) - '\n', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + '\r', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ECI, FS, GS, RS, NS, ' ', PAD, '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', SHI1, SHI2, SHI3, SHI4, LCHB, From 28ce8da44d899f2e77d60294b695e452fa1960ac Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 19 Jul 2022 09:48:19 +0200 Subject: [PATCH 0400/1315] c++20: work around a bug in MSVC --- core/src/qrcode/QRDetector.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 0070718858..1b435728db 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -418,7 +418,12 @@ DetectorResult SampleMQR(const BitMatrix& image, const ConcentricPattern& fp) auto srcQuad = Rectangle(7, 7, 0.5); - constexpr PointI FORMAT_INFO_COORDS[] = {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, +#if defined(_MSVC_LANG) && _MSVC_LANG >= 202002L // TODO: see MSVC issue https://developercommunity.visualstudio.com/t/constexpr-object-is-unable-to-be-used-as/10035065 + static +#else + constexpr +#endif + const PointI FORMAT_INFO_COORDS[] = {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {8, 7}, {8, 6}, {8, 5}, {8, 4}, {8, 3}, {8, 2}, {8, 1}, {8, 0}}; FormatInformation bestFI; From 496ed0d62dfd33c5308835cd5dd5c9fd7325f0a5 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 19 Jul 2022 09:58:16 +0200 Subject: [PATCH 0401/1315] README: updated build instuctions, added links to binary sources --- README.md | 21 ++++++++++++++++++--- wrappers/python/README.md | 2 ++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5d1e598e7b..c6acecc4c9 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ * In pure C++17, no third-party dependencies (for the library) * Stateless, thread-safe readers/scanners and writers/generators -* Wrapper/Bindings for: +* Wrappers/Bindings for: * [Android](wrappers/android/README.md) * [iOS](wrappers/ios/README.md) * [Python](wrappers/python/README.md) @@ -29,7 +29,7 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ | DataBar | DataBar Exanded | PDF417 | | | ITF | MaxiCode (partial) | -Note: DataBar used to be called RSS. DataBar is not supported for writing. +[Note: DataBar used to be called RSS. DataBar is not supported for writing.] ## Getting Started @@ -49,8 +49,23 @@ As an example, have a look at [`ZXingWriter.cpp`](example/ZXingWriter.cpp). - [Write barcodes](https://nu-book.github.io/zxing-cpp/demo_writer.html) - [Scan with camera](https://nu-book.github.io/zxing-cpp/zxing_viddemo.html) -## Build Instructions (for Windows/macOS/Linux) +[Note: those live demos are not necessarily fully up-to-date at all times.] + +## Build Instructions +These are the generic instructions to build the library on Windows/macOS/Linux. For details on how to build the individual wrappers, follow the links above. + 1. Make sure [CMake](https://cmake.org) version 3.14 or newer is installed. 2. Make sure a C++17 compliant compiler is installed (minimum VS 2019 16.8 / gcc 7 / clang 5). 3. See the cmake `BUILD_...` options to enable the testing code, python wrapper, etc. +``` +git clone https://github.com/nu-book/zxing-cpp.git --single-branch --depth 1 +cmake -S zxing-cpp -B zxing-cpp.release -DCMAKE_BUILD_TYPE=Release +cmake --build zxing.release -j8 +``` + +[Note: binary packages are available for/as +[vcpkg](https://github.com/Microsoft/vcpkg/tree/master/ports/nu-book-zxing-cpp), +[conan](https://github.com/conan-io/conan-center-index/tree/master/recipes/zxing-cpp), +[mingw](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-zxing-cpp) and a bunch of +[linux distributions](https://repology.org/project/zxing-cpp-nu-book/versions).] diff --git a/wrappers/python/README.md b/wrappers/python/README.md index 00bd382893..0b7b3d737f 100644 --- a/wrappers/python/README.md +++ b/wrappers/python/README.md @@ -14,6 +14,8 @@ or python setup.py install ``` +Note: To install via `setup.py`, you need a suitable [build environment](https://github.com/nu-book/zxing-cpp#build-instructions-for-windowsmacoslinux) including a c++ compiler. + ## Usage ```python From 9ce2ab59a4445fca3a3c3680272a748327762535 Mon Sep 17 00:00:00 2001 From: Uri Shabi Date: Tue, 19 Jul 2022 15:08:48 +0300 Subject: [PATCH 0402/1315] Update README.md the name of the created folder has "-cpp" in the name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c6acecc4c9..147e86c33d 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ These are the generic instructions to build the library on Windows/macOS/Linux. ``` git clone https://github.com/nu-book/zxing-cpp.git --single-branch --depth 1 cmake -S zxing-cpp -B zxing-cpp.release -DCMAKE_BUILD_TYPE=Release -cmake --build zxing.release -j8 +cmake --build zxing-cpp.release -j8 ``` [Note: binary packages are available for/as From 20e9d344a154736329cb24f2f054b4bd83230153 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 19 Jul 2022 23:08:21 +0200 Subject: [PATCH 0403/1315] Error: fix issue with Errors not reported (e.g. from QRReader) --- core/src/DecoderResult.h | 2 +- core/src/Result.cpp | 7 ++++++- core/src/Result.h | 2 +- core/src/aztec/AZReader.cpp | 5 +++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index e701d266bc..128f3d1957 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -44,7 +44,7 @@ class DecoderResult bool isValid(bool includeErrors = false) const { - return _content.symbology.code != 0 && (!_error || includeErrors); + return includeErrors || (_content.symbology.code != 0 && !_error); } const Content& content() const & { return _content; } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 9f697d26a8..f843f89244 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -33,7 +33,7 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat _position(std::move(position)), _ecLevel(decodeResult.ecLevel()), _sai(decodeResult.structuredAppend()), - _format(decodeResult.content().symbology.code == 0 ? BarcodeFormat::None : format), + _format(format), _lineCount(decodeResult.lineCount()), _isMirrored(decodeResult.isMirrored()), _readerInit(decodeResult.readerInit()) @@ -41,6 +41,11 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat // TODO: add type opaque and code specific 'extra data'? (see DecoderResult::extra()) } +bool Result::isValid() const +{ + return format() != BarcodeFormat::None && _content.symbology.code != 0 && !error(); +} + const ByteArray& Result::bytes() const { return _content.bytes; diff --git a/core/src/Result.h b/core/src/Result.h index 7c2b63adf0..af8520ddfb 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -46,7 +46,7 @@ class Result Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat format); - bool isValid() const { return format() != BarcodeFormat::None && !error(); } + bool isValid() const; const Error& error() const { return _error; } diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 56f45040e7..2718b42e16 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -34,8 +34,9 @@ Reader::decode(const BinaryBitmap& image) const //TODO: don't start detection all over again, just to swap 2 corner points if (!decodeResult.isValid()) { detectResult = Detect(*binImg, true, _hints.isPure()); - if (detectResult.isValid()) - decodeResult = Decode(detectResult); + if (!detectResult.isValid()) + return {}; + decodeResult = Decode(detectResult); } return Result(std::move(decodeResult), std::move(detectResult).position(), BarcodeFormat::Aztec); From 166255d7714498b27717cbb9d6c1104d484d5478 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 19 Jul 2022 23:09:14 +0200 Subject: [PATCH 0404/1315] BitMatrix: Switch to binary output in SaveAsPBM --- core/src/BitMatrixIO.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/BitMatrixIO.cpp b/core/src/BitMatrixIO.cpp index 0d4e54325d..2036f34039 100644 --- a/core/src/BitMatrixIO.cpp +++ b/core/src/BitMatrixIO.cpp @@ -79,10 +79,10 @@ BitMatrix ParseBitMatrix(const std::string& str, char one, bool expectSpace) void SaveAsPBM(const BitMatrix& matrix, const std::string filename, int quietZone) { - auto out = Inflate(matrix.copy(), 0, 0, quietZone); + auto out = ToMatrix(Inflate(matrix.copy(), 0, 0, quietZone)); std::ofstream file(filename); - file << "P1\n" << out.width() << ' ' << out.height() << '\n'; - file << ToString(out, '1', '0', true); + file << "P5\n" << out.width() << ' ' << out.height() << "\n255\n"; + file.write(reinterpret_cast(out.data()), out.size()); } } // ZXing From f9b88893dd7fdcd054a8ff518659985fbffe16e8 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 20 Jul 2022 22:44:17 +0200 Subject: [PATCH 0405/1315] test: improve readability of blackbox test output Also add info about unexpectedly decoded samples. --- test/blackbox/BlackboxTestRunner.cpp | 31 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index c42a0217a9..ebc2d14f2b 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -151,6 +151,7 @@ static std::string checkResult(const fs::path& imgPath, std::string_view expecte } static int failed = 0; +static int extra = 0; static int totalImageLoadTime = 0; int timeSince(std::chrono::steady_clock::time_point startTime) @@ -169,26 +170,29 @@ void preloadImageCache(const std::vector& imgPaths) totalImageLoadTime += timeSince(startTime); } -static void printPositiveTestStats(int imageCount, const TestCase::TC& tc) +static std::string printPositiveTestStats(int imageCount, const TestCase::TC& tc) { int passCount = imageCount - Size(tc.misReadFiles) - Size(tc.notDetectedFiles); fmt::print(" | {}: {:3} of {:3}, misread {} of {}", tc.name, passCount, tc.minPassCount, Size(tc.misReadFiles), tc.maxMisreads); + std::string failures; if (passCount < tc.minPassCount && !tc.notDetectedFiles.empty()) { - fmt::print("\nFAILED: Not detected ({}):", tc.name); + failures += fmt::format(" Not detected ({}):", tc.name); for (const auto& f : tc.notDetectedFiles) - fmt::print(" {}", f.filename().string()); - fmt::print("\n"); - ++failed; + failures += fmt::format(" {}", f.filename().string()); + failures += "\n"; + failed += tc.minPassCount - passCount; } + extra += std::max(0, passCount - tc.minPassCount); if (Size(tc.misReadFiles) > tc.maxMisreads) { - fmt::print("\nFAILED: Read error ({}):", tc.name); + failures += fmt::format(" Read error ({}):", tc.name); for (const auto& [path, error] : tc.misReadFiles) - fmt::print(" {}: {}\n", path.filename().string(), error); - ++failed; + failures += fmt::format(" {}: {}\n", path.filename().string(), error); + failed += Size(tc.misReadFiles) - tc.maxMisreads; } + return failures; } static std::vector getImagesInDirectory(const fs::path& directory) @@ -217,6 +221,7 @@ static void doRunTests(const fs::path& directory, std::string_view format, int t for (auto& test : tests) { fmt::print("{:20} @ {:3}, {:3}", folderName.string(), test.rotation, Size(imgPaths)); std::vector times; + std::string failures; for (auto tc : test.tc) { if (tc.name.empty()) break; @@ -238,9 +243,11 @@ static void doRunTests(const fs::path& directory, std::string_view format, int t } times.push_back(timeSince(startTime)); - printPositiveTestStats(Size(imgPaths), tc); + failures += printPositiveTestStats(Size(imgPaths), tc); } fmt::print(" | time: {:3} vs {:3} ms\n", times.front(), times.back()); + if (!failures.empty()) + fmt::print("\n{}\n", failures); } } @@ -288,8 +295,10 @@ static void doRunStructuredAppendTest(const fs::path& directory, std::string_vie } } - printPositiveTestStats(Size(imageGroups), tc); + auto failures = printPositiveTestStats(Size(imageGroups), tc); fmt::print(" | time: {:3} ms\n", timeSince(startTime)); + if (!failures.empty()) + fmt::print("\n{}\n", failures); } } @@ -649,6 +658,8 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set fmt::print("total time: {} ms.\n", totalTime); if (failed) fmt::print("WARNING: {} tests failed.\n", failed); + if (extra) + fmt::print("INFO: {} tests succeded unexpecedly.\n", extra); return failed; } From 8bafa6d179782b27984a5065f77955c542ded37e Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 20 Jul 2022 22:44:45 +0200 Subject: [PATCH 0406/1315] test: add missing codabar-2/04.txt --- test/samples/codabar-2/04.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/samples/codabar-2/04.txt diff --git a/test/samples/codabar-2/04.txt b/test/samples/codabar-2/04.txt new file mode 100644 index 0000000000..9158bbd387 --- /dev/null +++ b/test/samples/codabar-2/04.txt @@ -0,0 +1 @@ +8030798962 \ No newline at end of file From 64fd28f07f2f526b17633a1687505a6fdf638904 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 20 Jul 2022 22:49:58 +0200 Subject: [PATCH 0407/1315] test: update overlooked rssexpanded test stats Should have been updated during the HRI -> standard GS1 transition. --- test/blackbox/BlackboxTestRunner.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index ebc2d14f2b..cd80553a63 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -534,10 +534,9 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set }); runTests("rssexpanded-3", "DataBarExpanded", 118, { - // TODO: See HRIFromGS1. 13.png and 66.png are seemingly invalid symbols - { 116, 116, 0 }, - { 116, 116, 180 }, - { 116, 0, pure }, + { 118, 118, 0 }, + { 118, 118, 180 }, + { 118, 0, pure }, }); runTests("rssexpandedstacked-1", "DataBarExpanded", 65, { From 11393a1efcd8edba7bfffa594306dd74d0e3463e Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 21 Jul 2022 00:00:11 +0200 Subject: [PATCH 0408/1315] Error: suppress Errors from MaxiCode reader as they are meaningless --- core/src/maxicode/MCReader.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/maxicode/MCReader.cpp b/core/src/maxicode/MCReader.cpp index a03e8c76de..6a41fc9b42 100644 --- a/core/src/maxicode/MCReader.cpp +++ b/core/src/maxicode/MCReader.cpp @@ -39,6 +39,8 @@ static BitMatrix ExtractPureBits(const BitMatrix& image) } } } + + //TODO: need to return position info return result; } @@ -54,7 +56,12 @@ Reader::decode(const BinaryBitmap& image) const if (bits.empty()) return {}; - return Result(Decode(bits), {}, BarcodeFormat::MaxiCode); + DecoderResult decRes = Decode(bits); + // TODO: before we can meaningfully return a ChecksumError result, we need to check the center for the presence of the finder pattern + if (!decRes.isValid()) + return {}; + + return Result(std::move(decRes), {}, BarcodeFormat::MaxiCode); } } // namespace ZXing::MaxiCode From 18f82e44381d4881fc18c7a365d9dd317cc0b6b8 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 21 Jul 2022 14:48:50 +0200 Subject: [PATCH 0409/1315] test: show unexpected detections in blackbox tests more prominently --- test/blackbox/BlackboxTestRunner.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index cd80553a63..bb32635c86 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -184,7 +184,10 @@ static std::string printPositiveTestStats(int imageCount, const TestCase::TC& tc failures += "\n"; failed += tc.minPassCount - passCount; } + extra += std::max(0, passCount - tc.minPassCount); + if (passCount > tc.minPassCount) + failures += fmt::format(" Unexpected detections ({}): {}\n", tc.name, passCount - tc.minPassCount); if (Size(tc.misReadFiles) > tc.maxMisreads) { failures += fmt::format(" Read error ({}):", tc.name); @@ -658,7 +661,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set if (failed) fmt::print("WARNING: {} tests failed.\n", failed); if (extra) - fmt::print("INFO: {} tests succeded unexpecedly.\n", extra); + fmt::print("INFO: {} tests succeeded unexpectedly.\n", extra); return failed; } From fbabd63fc8676c9ee97b29fc0853f7d6aa2bac28 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 21 Jul 2022 14:50:25 +0200 Subject: [PATCH 0410/1315] HybridBinarizer: ~10% performance gain in total matrix decoding time Who knew that replacing basically "2 ifs" with an "if else if" could have such a measurable overall effect? Downside: this reduces the bang of my not yet released SIMD improvements quite a bit ;-). And it might all be lost if my Otsu based experiments work out :-/. --- core/src/HybridBinarizer.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/src/HybridBinarizer.cpp b/core/src/HybridBinarizer.cpp index 598bd2a860..275d42352d 100644 --- a/core/src/HybridBinarizer.cpp +++ b/core/src/HybridBinarizer.cpp @@ -43,14 +43,16 @@ static Matrix CalculateBlackPoints(const uint8_t* luminances, int subWidth, for (int x = 0; x < subWidth; x++) { int xoffset = std::min(x * BLOCK_SIZE, width - BLOCK_SIZE); int sum = 0; - uint8_t min = 0xFF; - uint8_t max = 0; + uint8_t min = luminances[yoffset * rowStride + xoffset]; + uint8_t max = min; for (int yy = 0, offset = yoffset * rowStride + xoffset; yy < BLOCK_SIZE; yy++, offset += rowStride) { for (int xx = 0; xx < BLOCK_SIZE; xx++) { auto pixel = luminances[offset + xx]; sum += pixel; - min = min < pixel ? min : pixel; - max = max > pixel ? max : pixel; + if (pixel < min) + min = pixel; + else if (pixel > max) + max = pixel; } // short-circuit min/max tests once dynamic range is met if (max - min > MIN_DYNAMIC_RANGE) { From f87698251999d1e2ade84d29f74a6f42aafadb49 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 22 Jul 2022 22:36:20 +0200 Subject: [PATCH 0411/1315] Range: cleanup/consolidate getRow and getPatternRow related code Remove BitMatrix::getRow and BitMatrix::getPatternRow members and replace them with a new consistent `Range` based API. This prevents unnecessary copies and unifies separate implementations of the bits -> patterns functionality. --- core/CMakeLists.txt | 2 + core/src/BitArray.h | 9 +-- core/src/BitMatrix.cpp | 79 ++------------------- core/src/BitMatrix.h | 47 +++--------- core/src/BitMatrixIO.cpp | 4 +- core/src/Pattern.h | 43 +++++++++++ core/src/Range.h | 37 ++++++++++ core/src/oned/ODRowReader.cpp | 18 ----- core/src/oned/ODRowReader.h | 16 +++-- core/src/pdf417/PDFDetector.cpp | 2 +- core/src/qrcode/QRDetector.cpp | 2 +- test/unit/oned/ODCodaBarWriterTest.cpp | 6 +- test/unit/oned/ODCode128WriterTest.cpp | 4 +- test/unit/oned/ODCode39ExtendedModeTest.cpp | 3 +- test/unit/oned/ODCode93ReaderTest.cpp | 3 +- 15 files changed, 118 insertions(+), 157 deletions(-) create mode 100644 core/src/Range.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 54a053838e..c7fb9f7e61 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -68,6 +68,7 @@ set (COMMON_FILES src/Pattern.h src/Point.h src/Quadrilateral.h + src/Range.h src/RegressionLine.h src/Scope.h src/TextUtfEncoding.h @@ -166,6 +167,7 @@ if (BUILD_WRITERS) src/BitMatrixIO.h src/Matrix.h src/MultiFormatWriter.h + src/Range.h ) endif() # end of public header set diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 4c840262e6..75e706985e 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -7,6 +7,7 @@ #pragma once +#include "Range.h" #include "ZXConfig.h" #include "ZXAlgorithms.h" #ifndef ZX_FAST_BIT_STORAGE @@ -26,14 +27,6 @@ namespace ZXing { class ByteArray; -template -struct Range -{ - Iterator begin, end; - explicit operator bool() const { return begin < end; } - int size() const { return narrow_cast(end - begin); } -}; - /** * A simple, fast array of bits. */ diff --git a/core/src/BitMatrix.cpp b/core/src/BitMatrix.cpp index d0497ff394..036a5635ee 100644 --- a/core/src/BitMatrix.cpp +++ b/core/src/BitMatrix.cpp @@ -19,21 +19,6 @@ namespace ZXing { -void -BitMatrix::getRow(int y, BitArray& row) const -{ - if (y < 0 || y >= _height) { - throw std::out_of_range("Requested row is outside the matrix"); - } - if (row.size() != _width) - row = BitArray(_width); -#ifdef ZX_FAST_BIT_STORAGE - std::transform(_bits.begin() + y * _rowSize, _bits.begin() + (y + 1) * _rowSize, row._bits.begin(), isSet); -#else - std::copy_n(_bits.begin() + y * _rowSize, _rowSize, row._bits.begin()); -#endif -} - void BitMatrix::setRegion(int left, int top, int width, int height) { @@ -153,18 +138,12 @@ BitMatrix::findBoundingBox(int &left, int& top, int& width, int& height, int min return width >= minSize && height >= minSize; } -static auto isSet_ = [](auto v) { -#ifdef ZX_FAST_BIT_STORAGE - return BitMatrix::isSet(v); -#else - return v; -#endif -}; +static auto isSet = [](auto v) { return bool(v); }; bool BitMatrix::getTopLeftOnBit(int& left, int& top) const { - int bitsOffset = (int)std::distance(_bits.begin(), std::find_if(_bits.begin(), _bits.end(), isSet_)); + int bitsOffset = (int)std::distance(_bits.begin(), std::find_if(_bits.begin(), _bits.end(), isSet)); if (bitsOffset == Size(_bits)) { return false; } @@ -179,7 +158,7 @@ BitMatrix::getTopLeftOnBit(int& left, int& top) const bool BitMatrix::getBottomRightOnBit(int& right, int& bottom) const { - int bitsOffset = Size(_bits) - 1 - (int)std::distance(_bits.rbegin(), std::find_if(_bits.rbegin(), _bits.rend(), isSet_)); + int bitsOffset = Size(_bits) - 1 - (int)std::distance(_bits.rbegin(), std::find_if(_bits.rbegin(), _bits.rend(), isSet)); if (bitsOffset < 0) { return false; } @@ -192,59 +171,13 @@ BitMatrix::getBottomRightOnBit(int& right, int& bottom) const return true; } -#ifdef ZX_FAST_BIT_STORAGE -constexpr BitMatrix::data_t BitMatrix::SET_V; -constexpr BitMatrix::data_t BitMatrix::UNSET_V; - -template -void GetPatternRow(BitMatrix::Row b_row, int row_size, PatternRow& p_row) -{ -#if 0 - p_row.reserve(64); - p_row.clear(); - - auto* lastPos = b_row.begin(); - if (BitMatrix::isSet(*lastPos)) - p_row.push_back(0); // first value is number of white pixels, here 0 - - for (auto* p = b_row.begin() + 1; p < b_row.end(); ++p) - if (bool(*p) != bool(*lastPos)) - p_row.push_back(p - std::exchange(lastPos, p)); - - p_row.push_back(b_row.end() - lastPos); - - if (BitMatrix::isSet(*lastPos)) - p_row.push_back(0); // last value is number of white pixels, here 0 -#else - p_row.resize(row_size + 2); - std::fill(p_row.begin(), p_row.end(), 0); - - auto bitPos = b_row.begin(); - auto intPos = p_row.data(); - - intPos += BitMatrix::isSet(*bitPos); // first value is number of white pixels, here 0 - - while (++bitPos < b_row.end()) { - ++(*intPos); - intPos += bitPos[0] != bitPos[-1]; - } - ++(*intPos); - - if (BitMatrix::isSet(bitPos[-1])) - intPos++; - - p_row.resize(intPos - p_row.data() + 1); -#endif -} - -void BitMatrix::getPatternRow(int r, PatternRow& p_row, bool transpose) const +void GetPatternRow(const BitMatrix& matrix, int r, std::vector& pr, bool transpose) { if (transpose) - GetPatternRow(col(r), height(), p_row); + GetPatternRow(matrix.col(r), pr); else - GetPatternRow(row(r), width(), p_row); + GetPatternRow(matrix.row(r), pr); } -#endif BitMatrix Inflate(BitMatrix&& input, int width, int height, int quietZone) { diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index 13c34fd875..6cf56da017 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -8,6 +8,7 @@ #include "Matrix.h" #include "Point.h" +#include "Range.h" #include "ZXConfig.h" #include @@ -42,9 +43,9 @@ class BitMatrix int _rowSize = 0; #ifdef ZX_FAST_BIT_STORAGE using data_t = uint8_t; - //TODO: c++17 inline static constexpr data_t SET_V = 0xff; // allows playing with SIMD binarization static constexpr data_t UNSET_V = 0; + static_assert(bool(SET_V), "SET_V needs to evaluate to true, see iterator usage"); #else using data_t = uint32_t; #endif @@ -67,8 +68,6 @@ class BitMatrix public: BitMatrix() = default; #ifdef ZX_FAST_BIT_STORAGE - static bool isSet(data_t v) { return v != 0; } // see SET_V above - BitMatrix(int width, int height) : _width(width), _height(height), _rowSize(width), _bits(width * height, UNSET_V) {} #else BitMatrix(int width, int height) @@ -95,28 +94,10 @@ class BitMatrix #ifdef ZX_FAST_BIT_STORAGE // experimental iterator based access - template - struct Row - { - iterator _begin, _end; - iterator begin() noexcept { return _begin; } - iterator end() noexcept { return _end; } - }; - Row row(int y) { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } - Row row(int y) const { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } - - struct ColIter - { - const data_t* pos; - int stride; - - data_t operator*() const { return *pos; } - data_t operator[](int i) const { return *(pos + i * stride); } - ColIter& operator++() { return pos += stride, *this; } - bool operator<(const ColIter& rhs) const { return pos < rhs.pos; } - }; - Row col(int x) const { return {{_bits.data() + x, _width}, {_bits.data() + x + _height * _width, _width}}; } + Range row(int y) { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } + Range row(int y) const { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } + Range> col(int x) const { return {{_bits.data() + x, _width}, {_bits.data() + x + _height * _width, _width}}; } #endif /** @@ -129,7 +110,7 @@ class BitMatrix bool get(int x, int y) const { #ifdef ZX_FAST_BIT_STORAGE - return isSet(get(y * _width + x)); + return get(y * _width + x); #else return ((get(y * _rowSize + (x / 32)) >> (x & 0x1f)) & 1) != 0; #endif @@ -206,16 +187,6 @@ class BitMatrix */ void setRegion(int left, int top, int width, int height); - /** - * A fast method to retrieve one row of data from the matrix as a BitArray. - * - * @param y The row to retrieve - * @param row An optional caller-allocated BitArray, will be allocated if null or too small - * @return The resulting BitArray - this reference should always be used even when passing - * your own row - */ - void getRow(int y, BitArray& row) const; - /** * Modifies this {@code BitMatrix} to represent the same but rotated 90 degrees clockwise */ @@ -244,10 +215,6 @@ class BitMatrix bool getBottomRightOnBit(int &right, int& bottom) const; -#ifdef ZX_FAST_BIT_STORAGE - void getPatternRow(int r, std::vector& p_row, bool transpose = false) const; -#endif - /** * @return The width of the matrix */ @@ -282,6 +249,8 @@ class BitMatrix void set(PointF p, bool v = true) { set(PointI(p), v); } }; +void GetPatternRow(const BitMatrix& matrix, int r, std::vector& pr, bool transpose); + /** * @brief Inflate scales a BitMatrix up and adds a quiet Zone plus padding * @param matrix input to be expanded diff --git a/core/src/BitMatrixIO.cpp b/core/src/BitMatrixIO.cpp index 2036f34039..36d8d83eb4 100644 --- a/core/src/BitMatrixIO.cpp +++ b/core/src/BitMatrixIO.cpp @@ -18,11 +18,9 @@ std::string ToString(const BitMatrix& matrix, char one, char zero, bool addSpace std::string result; result.reserve((addSpace ? 2 : 1) * (matrix.width() * matrix.height()) + matrix.height()); for (int y = 0; y < matrix.height(); ++y) { - BitArray row; - matrix.getRow(y, row); if (printAsCString) result += '"'; - for (auto bit : row) { + for (auto bit : matrix.row(y)) { result += bit ? one : zero; if (addSpace) result += ' '; diff --git a/core/src/Pattern.h b/core/src/Pattern.h index f75bc7dbb0..22187195a7 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -5,6 +5,7 @@ #pragma once +#include "Range.h" #include "ZXAlgorithms.h" #include @@ -272,4 +273,46 @@ std::array NormalizedPattern(const PatternView& view) return is; } +template +void GetPatternRow(Range b_row, PatternRow& p_row) +{ +#if 0 + p_row.reserve(64); + p_row.clear(); + + auto lastPos = b_row.begin(); + if (*lastPos) + p_row.push_back(0); // first value is number of white pixels, here 0 + + for (auto p = b_row.begin() + 1; p < b_row.end(); ++p) + if (bool(*p) != bool(*lastPos)) + p_row.push_back(p - std::exchange(lastPos, p)); + + p_row.push_back(b_row.end() - lastPos); + + if (*lastPos) + p_row.push_back(0); // last value is number of white pixels, here 0 +#else + p_row.resize(b_row.size() + 2); + std::fill(p_row.begin(), p_row.end(), 0); + + auto bitPos = b_row.begin(); + auto intPos = p_row.data(); + + if (*bitPos) + intPos++; // first value is number of white pixels, here 0 + + while (++bitPos < b_row.end()) { + ++(*intPos); + intPos += bitPos[0] != bitPos[-1]; + } + ++(*intPos); + + if (bitPos[-1]) + intPos++; + + p_row.resize(intPos - p_row.data() + 1); +#endif +} + } // ZXing diff --git a/core/src/Range.h b/core/src/Range.h new file mode 100644 index 0000000000..21860384bf --- /dev/null +++ b/core/src/Range.h @@ -0,0 +1,37 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "ZXAlgorithms.h" + +namespace ZXing { + +template +struct StrideIter +{ + Iterator pos; + int stride; + + auto operator*() const { return *pos; } + auto operator[](int i) const { return *(pos + i * stride); } + StrideIter& operator++() { return pos += stride, *this; } + bool operator<(const StrideIter& rhs) const { return pos < rhs.pos; } + StrideIter operator+(int i) const { return {pos + i * stride, stride}; } + int operator-(const StrideIter& rhs) const { return (pos - rhs.pos) / stride; } +}; + +template +struct Range +{ + Iterator _begin, _end; + + Iterator begin() const noexcept { return _begin; } + Iterator end() const noexcept { return _end; } + explicit operator bool() const { return begin() < end(); } + int size() const { return narrow_cast(end() - begin()); } +}; + +} // namespace ZXing diff --git a/core/src/oned/ODRowReader.cpp b/core/src/oned/ODRowReader.cpp index 339ec0d56d..c8454dbf4b 100644 --- a/core/src/oned/ODRowReader.cpp +++ b/core/src/oned/ODRowReader.cpp @@ -12,24 +12,6 @@ namespace ZXing::OneD { -Result RowReader::decodeSingleRow(int rowNumber, const BitArray& row) const -{ - std::unique_ptr state; - PatternRow res; - auto li = row.begin(); - auto i = li; - if (*i) - res.push_back(0); - while ((i = row.getNextSetTo(i, !*i)) != row.end()) { - res.push_back(narrow_cast(i - li)); - li = i; - } - res.push_back(narrow_cast(i - li)); - if (*(i-1)) - res.push_back(0); - PatternView view(res); - return decodePattern(rowNumber, view, state); -} } // namespace ZXing::OneD diff --git a/core/src/oned/ODRowReader.h b/core/src/oned/ODRowReader.h index 98e61a22d7..bfa98d69cf 100644 --- a/core/src/oned/ODRowReader.h +++ b/core/src/oned/ODRowReader.h @@ -9,6 +9,7 @@ #include "BitArray.h" #include "Pattern.h" +#include "Result.h" #include #include @@ -38,7 +39,6 @@ RSSExp.: v?-74d/?-41c namespace ZXing { class DecodeHints; -class Result; namespace OneD { @@ -60,9 +60,6 @@ class RowReader virtual ~DecodingState() = default; }; - //TODO: this is only testing code -> move outside of this interface (and remove rowNumber parameter) - Result decodeSingleRow(int rowNumber, const BitArray& row) const; - virtual ~RowReader() {} virtual Result decodePattern(int rowNumber, PatternView& next, std::unique_ptr& state) const = 0; @@ -218,5 +215,16 @@ class RowReader } }; +template +Result DecodeSingleRow(const RowReader& reader, const Range& range) +{ + PatternRow row; + GetPatternRow(range, row); + PatternView view(row); + + std::unique_ptr state; + return reader.decodePattern(0, view, state); +} + } // OneD } // ZXing diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index f5d13236d0..57f91fb253 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -312,7 +312,7 @@ bool HasStartPattern(const BitMatrix& m, bool rotate90) int end = rotate90 ? m.width() : m.height(); for (int r = ROW_STEP; r < end; r += ROW_STEP) { - m.getPatternRow(r, row, rotate90); + GetPatternRow(m, r, row, rotate90); if (FindLeftGuard(row, minSymbolWidth, START_PATTERN, 2).isValid()) return true; diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 1b435728db..99d008f2e3 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -51,7 +51,7 @@ std::vector FindFinderPatterns(const BitMatrix& image, bool t for (int y = skip - 1; y < height; y += skip) { PatternRow row; - image.getPatternRow(y, row); + GetPatternRow(image, y, row, false); PatternView next = row; while (next = FindLeftGuard(next, 0, PATTERN, 0.5), next.isValid()) { diff --git a/test/unit/oned/ODCodaBarWriterTest.cpp b/test/unit/oned/ODCodaBarWriterTest.cpp index 9ae038db5e..15824775c4 100644 --- a/test/unit/oned/ODCodaBarWriterTest.cpp +++ b/test/unit/oned/ODCodaBarWriterTest.cpp @@ -51,10 +51,10 @@ TEST(ODCodaBarWriterTest, AltStartEnd) TEST(ODCodaBarWriterTest, FullCircle) { std::string text = "A0123456789-$:/.+A"; - BitArray row; - CodabarWriter().encode(text, 0, 0).getRow(0, row); + auto matrix = CodabarWriter().encode(text, 0, 0); auto hints = DecodeHints().setReturnCodabarStartEnd(true); - Result res = CodabarReader(hints).decodeSingleRow(0, row); + + Result res = OneD::DecodeSingleRow(CodabarReader(hints), matrix.row(0)); EXPECT_EQ(text, res.text()); } diff --git a/test/unit/oned/ODCode128WriterTest.cpp b/test/unit/oned/ODCode128WriterTest.cpp index bc9db158be..662c36db3b 100644 --- a/test/unit/oned/ODCode128WriterTest.cpp +++ b/test/unit/oned/ODCode128WriterTest.cpp @@ -37,10 +37,8 @@ static std::string LineMatrixToString(const BitMatrix& matrix) static ZXing::Result Decode(const BitMatrix &matrix) { - BitArray row; - matrix.getRow(0, row); DecodeHints hints; - return Code128Reader(hints).decodeSingleRow(0, row); + return DecodeSingleRow(Code128Reader(hints), matrix.row(0)); } TEST(ODCode128Writer, EncodeWithFunc1) diff --git a/test/unit/oned/ODCode39ExtendedModeTest.cpp b/test/unit/oned/ODCode39ExtendedModeTest.cpp index d25d7a6205..fb7a8599b4 100644 --- a/test/unit/oned/ODCode39ExtendedModeTest.cpp +++ b/test/unit/oned/ODCode39ExtendedModeTest.cpp @@ -18,9 +18,8 @@ using namespace ZXing::OneD; static std::string Decode(std::string_view encoded) { auto hints = DecodeHints().setTryCode39ExtendedMode(true); - Code39Reader sut(hints); BitArray row = Utility::ParseBitArray(encoded, '1'); - Result result = sut.decodeSingleRow(0, row); + Result result = DecodeSingleRow(Code39Reader(hints), row.range()); return result.text(); } diff --git a/test/unit/oned/ODCode93ReaderTest.cpp b/test/unit/oned/ODCode93ReaderTest.cpp index 93d7557e3b..7d29667c6c 100644 --- a/test/unit/oned/ODCode93ReaderTest.cpp +++ b/test/unit/oned/ODCode93ReaderTest.cpp @@ -18,9 +18,8 @@ using namespace ZXing::OneD; static std::string Decode(std::string_view input) { DecodeHints hints; - Code93Reader sut(hints); auto row = Utility::ParseBitArray(input, '1'); - auto result = sut.decodeSingleRow(0, row); + auto result = DecodeSingleRow(Code93Reader(hints), row.range()); return result.text(); } From f62b1f2e78dd8d0f87ba23541baf82c16904ed33 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 23 Jul 2022 13:25:08 +0200 Subject: [PATCH 0412/1315] BitArray/BitMatrix: remove stale/unused API Remove API that has not been in use since the introduction of the PatternRow concept to the 1D decoders. --- core/src/BitArray.cpp | 26 ------------- core/src/BitArray.h | 90 +------------------------------------------ core/src/BitMatrix.h | 67 +++++--------------------------- core/src/Pattern.h | 4 ++ 4 files changed, 14 insertions(+), 173 deletions(-) diff --git a/core/src/BitArray.cpp b/core/src/BitArray.cpp index 718d025bac..07bd240d15 100644 --- a/core/src/BitArray.cpp +++ b/core/src/BitArray.cpp @@ -20,32 +20,6 @@ namespace ZXing { #ifndef ZX_FAST_BIT_STORAGE -bool -BitArray::isRange(int start, int end, bool value) const -{ - if (end < start || start < 0 || end > _size) { - throw std::invalid_argument("BitArray::isRange(): Invalid range"); - } - if (end == start) { - return true; // empty range matches - } - end--; // will be easier to treat this as the last actually set bit -- inclusive - int firstInt = start / 32; - int lastInt = end / 32; - for (int i = firstInt; i <= lastInt; i++) { - int firstBit = i > firstInt ? 0 : start & 0x1F; - int lastBit = i < lastInt ? 31 : end & 0x1F; - // Ones from firstBit to lastBit, inclusive - uint32_t mask = (2UL << lastBit) - (1UL << firstBit); - // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is, - // equals the mask, or we're looking for 0s and the masked portion is not all 0s - if ((_bits[i] & mask) != (value ? mask : 0U)) { - return false; - } - } - return true; -} - void BitArray::appendBits(int value, int numBits) { diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 75e706985e..04f904b913 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -109,9 +109,6 @@ class BitArray }; #endif - using ReverseIterator = std::reverse_iterator; - using Range = ZXing::Range; - BitArray() = default; explicit BitArray(int size) @@ -173,54 +170,12 @@ class BitArray Iterator iterAt(int i) const noexcept { return {_bits.cbegin() + i}; } Iterator begin() const noexcept { return _bits.cbegin(); } Iterator end() const noexcept { return _bits.cend(); } - - template - static ITER getNextSetTo(ITER begin, ITER end, bool v) noexcept - { - while( begin != end && *begin != static_cast(v) ) - ++begin; - return begin; - } #else Iterator iterAt(int i) const noexcept { return {_bits.cbegin() + (i >> 5), 1U << (i & 0x1F)}; } Iterator begin() const noexcept { return iterAt(0); } Iterator end() const noexcept { return iterAt(_size); } - - static Iterator getNextSetTo(Iterator begin, Iterator end, bool v) - { - auto i = begin; - // reconstruct _bits.end() - auto bitsEnd = end._mask == 0x1 ? end._value : std::next(end._value); - if (i._value >= bitsEnd) - return end; - // mask off lesser bits first - auto currentBits = (v ? *i._value : ~*i._value) & ~(i._mask - 1); - while (currentBits == 0) { - if (++i._value == bitsEnd) { - return end; - } - currentBits = v ? *i._value : ~*i._value; - } - i._mask = 1 << BitHacks::NumberOfTrailingZeros(currentBits); - return i; - } - - static ReverseIterator getNextSetTo(ReverseIterator begin, ReverseIterator end, bool v) - { - while( begin != end && *begin != v ) - ++begin; - return begin; - } #endif - Iterator getNextSetTo(Iterator i, bool v) const { return getNextSetTo(i, end(), v); } - - Iterator getNextSet(Iterator i) const { return getNextSetTo(i, true); } - Iterator getNextUnset(Iterator i) const { return getNextSetTo(i, false); } - - ReverseIterator rbegin() const noexcept { return ReverseIterator(end()); } - ReverseIterator rend() const noexcept { return ReverseIterator(begin()); } - /** * Sets bit i. * @@ -238,50 +193,6 @@ class BitArray #endif } - /** - * Clears all bits (sets to false). - */ - void clearBits() { std::fill(_bits.begin(), _bits.end(), 0); } - - /** - * Efficient method to check if a range of bits is set, or not set. - * - * @param start start of range, inclusive. - * @param end end of range, exclusive - * @param value if true, checks that bits in range are set, otherwise checks that they are not set - * @return true iff all bits are set or not set in range, according to value argument - */ -#ifdef ZX_FAST_BIT_STORAGE - bool isRange(int start, int end, bool value) const - { - return std::all_of(std::begin(_bits) + start, std::begin(_bits) + end, [value](uint8_t v) { return v == static_cast(value); }); - } -#else - bool isRange(int start, int end, bool value) const; -#endif - - // Little helper method to make common isRange use case more readable. - // Pass positive zone size to look for quiet zone after i and negative for zone in front of i. - // Set allowClippedZone to false if clipping the zone at the image border is not acceptable. - bool hasQuietZone(Iterator i, int signedZoneSize, bool allowClippedZone = true) const - { - int index = narrow_cast(i - begin()); - if (signedZoneSize > 0) { - if (!allowClippedZone && index + signedZoneSize >= size()) - return false; - return isRange(index, std::min(size(), index + signedZoneSize), false); - } else { - if (!allowClippedZone && index + signedZoneSize < 0) - return false; - return isRange(std::max(0, index + signedZoneSize), index, false); - } - } - - bool hasQuietZone(ReverseIterator i, int signedZoneSize, bool allowClippedZone = true) const - { - return hasQuietZone(i.base(), -signedZoneSize, allowClippedZone); - } - /** * Appends the least-significant bits, from value, in order from most-significant to * least-significant. For example, appending 6 bits from 0x000001E will append the bits @@ -327,6 +238,7 @@ class BitArray */ ByteArray toBytes(int bitOffset = 0, int numBytes = -1) const; + using Range = ZXing::Range; Range range() const { return {begin(), end()}; } friend bool operator==(const BitArray& a, const BitArray& b) diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index 6cf56da017..4a6e824839 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -22,20 +22,10 @@ class BitArray; class ByteMatrix; /** -*

Represents a 2D matrix of bits. In function arguments below, and throughout the common -* module, x is the column position, and y is the row position. The ordering is always x, y. -* The origin is at the top-left.

-* -*

Internally the bits are represented in a 1-D array of 32-bit ints. However, each row begins -* with a new int. This is done intentionally so that we can copy out a row into a BitArray very -* efficiently.

-* -*

The ordering of bits is row-major. Within each int, the least significant bits are used first, -* meaning they represent lower x values. This is compatible with BitArray's implementation.

-* -* @author Sean Owen -* @author dswitkin@google.com (Daniel Switkin) -*/ + * @brief A simple, fast 2D array of bits. + * + * Note: the original bit-packed storage variant is currently unusuable. + */ class BitMatrix { int _width = 0; @@ -65,6 +55,9 @@ class BitMatrix data_t& get(int i) { return const_cast(static_cast(this)->get(i)); } + bool getTopLeftOnBit(int &left, int& top) const; + bool getBottomRightOnBit(int &right, int& bottom) const; + public: BitMatrix() = default; #ifdef ZX_FAST_BIT_STORAGE @@ -77,23 +70,12 @@ class BitMatrix explicit BitMatrix(int dimension) : BitMatrix(dimension, dimension) {} // Construct a square matrix. - BitMatrix(BitMatrix&& other) noexcept - : _width(other._width), _height(other._height), _rowSize(other._rowSize), _bits(std::move(other._bits)) - {} - - BitMatrix& operator=(BitMatrix&& other) noexcept - { - _width = other._width; - _height = other._height; - _rowSize = other._rowSize; - _bits = std::move(other._bits); - return *this; - } + BitMatrix(BitMatrix&& other) noexcept = default; + BitMatrix& operator=(BitMatrix&& other) noexcept = default; BitMatrix copy() const { return *this; } #ifdef ZX_FAST_BIT_STORAGE - // experimental iterator based access Range row(int y) { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } Range row(int y) const { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } @@ -172,11 +154,6 @@ class BitMatrix } } - /** - * Clears all bits (sets to false). - */ - void clear() { std::fill(_bits.begin(), _bits.end(), 0); } - /** *

Sets a square region of the bit matrix to true.

* @@ -187,14 +164,8 @@ class BitMatrix */ void setRegion(int left, int top, int width, int height); - /** - * Modifies this {@code BitMatrix} to represent the same but rotated 90 degrees clockwise - */ void rotate90(); - /** - * Modifies this {@code BitMatrix} to represent the same but rotated 180 degrees - */ void rotate180(); void mirror(); @@ -206,30 +177,10 @@ class BitMatrix */ bool findBoundingBox(int &left, int& top, int& width, int& height, int minSize = 1) const; - /** - * This is useful in detecting a corner of a 'pure' barcode. - * - * @return {@code x,y} coordinate of top-left-most 1 bit, or null if it is all white - */ - bool getTopLeftOnBit(int &left, int& top) const; - - bool getBottomRightOnBit(int &right, int& bottom) const; - - /** - * @return The width of the matrix - */ int width() const { return _width; } - /** - * @return The height of the matrix - */ int height() const { return _height; } - /** - * @return The row size of the matrix. That is the number of 32-bits blocks that one row takes. - */ - int rowSize() const { return _rowSize; } - bool empty() const { return _bits.empty(); } friend bool operator==(const BitMatrix& a, const BitMatrix& b) diff --git a/core/src/Pattern.h b/core/src/Pattern.h index 22187195a7..d1e830be1d 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -276,6 +276,10 @@ std::array NormalizedPattern(const PatternView& view) template void GetPatternRow(Range b_row, PatternRow& p_row) { + // TODO: if reactivating the bit-packed array (!ZX_FAST_BIT_STORAGE) should be of interest then the following code could be + // considerably speed up by using a specialized variant along the lines of the old BitArray::getNextSetTo() function that + // was removed between 1.4 and 2.0. + #if 0 p_row.reserve(64); p_row.clear(); From 3dfdc8cec9b752611f56c9b493f54c13fa888c32 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 23 Jul 2022 14:04:53 +0200 Subject: [PATCH 0413/1315] ZX_FAST_BIT_STORAGE: remove defunct packed bits variant of BitArray/Matrix The original bit-packed version of both BitArray and BitMatrix have not been even compiling for a long time now. The code has been kept around to not 'loose' the knowledge/work therein. If that should ever be of importance again (e.g. in special low memory embedded scenarios), the git history will have to be used to retrieve that information back. --- core/src/BitArray.cpp | 58 ----------- core/src/BitArray.h | 164 ++------------------------------ core/src/BitMatrix.cpp | 59 +----------- core/src/BitMatrix.h | 83 +++------------- core/src/HybridBinarizer.cpp | 11 --- core/src/ThresholdBinarizer.h | 9 +- core/src/ZXConfig.h | 7 -- core/src/pdf417/PDFDetector.cpp | 5 +- 8 files changed, 27 insertions(+), 369 deletions(-) diff --git a/core/src/BitArray.cpp b/core/src/BitArray.cpp index 07bd240d15..240bca5f09 100644 --- a/core/src/BitArray.cpp +++ b/core/src/BitArray.cpp @@ -11,66 +11,8 @@ #include #include -#ifndef ZX_FAST_BIT_STORAGE -#include "BitHacks.h" -#include -#endif - namespace ZXing { -#ifndef ZX_FAST_BIT_STORAGE - -void -BitArray::appendBits(int value, int numBits) -{ - if (numBits < 0 || numBits > 32) { - throw std::invalid_argument("BitArray::appendBits(): Num bits must be between 0 and 32"); - } - int i = _size; - _size += numBits; - _bits.resize((_size + 31) / 32, 0); - - for (--numBits; numBits >= 0; --numBits, ++i) { - _bits[i / 32] |= ((value >> numBits) & 1) << (i & 0x1F); - } -} - -void -BitArray::appendBit(bool bit) -{ - _bits.resize((_size + 1 + 31) / 32, 0); - if (bit) { - _bits[_size / 32] |= 1 << (_size & 0x1F); - } - _size++; -} - - -void -BitArray::appendBitArray(const BitArray& other) -{ - if (_bits.empty()) { - *this = other.copy(); - } - else if (other._size > 0) { - unsigned offset = static_cast(_bits.size()) * 32 - _size; - if (offset > 0) { - auto buffer = other._bits; - _bits.back() = (_bits.back() & (0xffffffff >> offset)) | (buffer.front() << (32 - offset)); - BitHacks::ShiftRight(buffer, offset); - size_t prevBlockSize = _bits.size(); - _size += other._size; - _bits.resize((_size + 31) / 32); - std::copy_n(buffer.begin(), _bits.size() - prevBlockSize, _bits.begin() + prevBlockSize); - } - else { - _size += other._size; - _bits.insert(_bits.end(), other._bits.begin(), other._bits.end()); - } - } -} -#endif - void BitArray::bitwiseXOR(const BitArray& other) { diff --git a/core/src/BitArray.h b/core/src/BitArray.h index 04f904b913..8e814b5a19 100644 --- a/core/src/BitArray.h +++ b/core/src/BitArray.h @@ -8,11 +8,7 @@ #pragma once #include "Range.h" -#include "ZXConfig.h" #include "ZXAlgorithms.h" -#ifndef ZX_FAST_BIT_STORAGE -#include "BitHacks.h" -#endif #include #include @@ -32,12 +28,7 @@ class ByteArray; */ class BitArray { -#ifdef ZX_FAST_BIT_STORAGE std::vector _bits; -#else - int _size = 0; - std::vector _bits; -#endif friend class BitMatrix; @@ -48,150 +39,31 @@ class BitArray public: -#ifdef ZX_FAST_BIT_STORAGE using Iterator = std::vector::const_iterator; -#else - class Iterator - { - public: - using iterator_category = std::bidirectional_iterator_tag; - using value_type = bool; - using difference_type = int; - using pointer = bool*; - using reference = bool; - - bool operator*() const { return (*_value & _mask) != 0; } - - Iterator& operator++() - { - if ((_mask <<= 1) == 0) { - _mask = 1; - ++_value; - } - return *this; - } - - Iterator& operator--() - { - if ((_mask >>= 1) == 0) { - _mask = 0x80000000; - --_value; - } - return *this; - } - - int operator-(const Iterator& rhs) const - { - return narrow_cast(_value - rhs._value) * 32 + (_mask >= rhs._mask - ? +BitHacks::CountBitsSet(_mask - rhs._mask) - : -BitHacks::CountBitsSet(rhs._mask - _mask)); - } - - bool operator==(const Iterator& rhs) const { return _mask == rhs._mask && _value == rhs._value; } - bool operator!=(const Iterator& rhs) const { return !(*this == rhs); } - - bool operator<(const Iterator& rhs) const - { - return _value < rhs._value || (_value == rhs._value && _mask < rhs._mask); - } - bool operator<=(const Iterator& rhs) const - { - return _value < rhs._value || (_value == rhs._value && _mask <= rhs._mask); - } - bool operator>(const Iterator& rhs) const { return !(*this <= rhs); } - bool operator>=(const Iterator& rhs) const { return !(*this < rhs); } - - private: - Iterator(std::vector::const_iterator p, uint32_t m) : _value(p), _mask(m) {} - std::vector::const_iterator _value; - uint32_t _mask; - friend class BitArray; - }; -#endif BitArray() = default; - explicit BitArray(int size) - : -#ifdef ZX_FAST_BIT_STORAGE - _bits(size, 0) {} -#else - _size(size), - _bits((size + 31) / 32, 0) {} -#endif - - BitArray(BitArray&& other) noexcept - : -#ifndef ZX_FAST_BIT_STORAGE - _size(other._size), -#endif - _bits(std::move(other._bits)) {} - - BitArray& operator=(BitArray&& other) noexcept - { -#ifndef ZX_FAST_BIT_STORAGE - _size = other._size; -#endif - _bits = std::move(other._bits); - return *this; - } + explicit BitArray(int size) : _bits(size, 0) {} + + BitArray(BitArray&& other) noexcept = default; + BitArray& operator=(BitArray&& other) noexcept = default; BitArray copy() const { return *this; } - int size() const noexcept - { -#ifdef ZX_FAST_BIT_STORAGE - return Size(_bits); -#else - return _size; -#endif - } + int size() const noexcept { return Size(_bits); } int sizeInBytes() const noexcept { return (size() + 7) / 8; } - /** - * @param i bit to get - * @return true iff bit i is set - */ - bool get(int i) const - { -#ifdef ZX_FAST_BIT_STORAGE - return _bits.at(i) != 0; -#else - return (_bits.at(i >> 5) & (1 << (i & 0x1F))) != 0; -#endif - } + bool get(int i) const { return _bits.at(i) != 0; } + void set(int i, bool val) { _bits.at(i) = val; } // If you know exactly how may bits you are going to iterate // and that you access bit in sequence, iterator is faster than get(). // However, be extremely careful since there is no check whatsoever. // (Performance is the reason for the iterator to exist in the first place.) -#ifdef ZX_FAST_BIT_STORAGE Iterator iterAt(int i) const noexcept { return {_bits.cbegin() + i}; } Iterator begin() const noexcept { return _bits.cbegin(); } Iterator end() const noexcept { return _bits.cend(); } -#else - Iterator iterAt(int i) const noexcept { return {_bits.cbegin() + (i >> 5), 1U << (i & 0x1F)}; } - Iterator begin() const noexcept { return iterAt(0); } - Iterator end() const noexcept { return iterAt(_size); } -#endif - - /** - * Sets bit i. - * - * @param i bit to set - */ - void set(int i, bool val) - { -#ifdef ZX_FAST_BIT_STORAGE - _bits.at(i) = val; -#else - if (val) - _bits.at(i >> 5) |= 1 << (i & 0x1F); - else - _bits.at(i >> 5) &= ~(1 << (i & 0x1F)); -#endif - } /** * Appends the least-significant bits, from value, in order from most-significant to @@ -201,7 +73,6 @@ class BitArray * @param value {@code int} containing bits to append * @param numBits bits from value to append */ -#ifdef ZX_FAST_BIT_STORAGE void appendBits(int value, int numBits) { for (; numBits; --numBits) @@ -216,18 +87,6 @@ class BitArray * Reverses all bits in the array. */ void reverse() { std::reverse(_bits.begin(), _bits.end()); } -#else - void appendBits(int value, int numBits); - - void appendBit(bool bit); - - void appendBitArray(const BitArray& other); - - /** - * Reverses all bits in the array. - */ - void reverse() { BitHacks::Reverse(_bits, _bits.size() * 32 - _size); } -#endif void bitwiseXOR(const BitArray& other); @@ -241,14 +100,7 @@ class BitArray using Range = ZXing::Range; Range range() const { return {begin(), end()}; } - friend bool operator==(const BitArray& a, const BitArray& b) - { - return -#ifndef ZX_FAST_BIT_STORAGE - a._size == b._size && -#endif - a._bits == b._bits; - } + friend bool operator==(const BitArray& a, const BitArray& b) { return a._bits == b._bits; } }; template>> diff --git a/core/src/BitMatrix.cpp b/core/src/BitMatrix.cpp index 036a5635ee..018bec31cc 100644 --- a/core/src/BitMatrix.cpp +++ b/core/src/BitMatrix.cpp @@ -9,10 +9,6 @@ #include "BitArray.h" #include "Pattern.h" -#ifndef ZX_FAST_BIT_STORAGE -#include "BitHacks.h" -#endif - #include #include #include @@ -34,13 +30,9 @@ BitMatrix::setRegion(int left, int top, int width, int height) throw std::invalid_argument("BitMatrix::setRegion(): The region must fit inside the matrix"); } for (int y = top; y < bottom; y++) { - size_t offset = y * _rowSize; + size_t offset = y * _width; for (int x = left; x < right; x++) { -#ifdef ZX_FAST_BIT_STORAGE _bits[offset + x] = SET_V; -#else - _bits[offset + (x / 32)] |= 1 << (x & 0x1f); -#endif } } } @@ -62,11 +54,7 @@ BitMatrix::rotate90() void BitMatrix::rotate180() { -#ifdef ZX_FAST_BIT_STORAGE std::reverse(_bits.begin(), _bits.end()); -#else - BitHacks::Reverse(_bits, _rowSize * 32 - _width); -#endif } void @@ -89,7 +77,6 @@ BitMatrix::findBoundingBox(int &left, int& top, int& width, int& height, int min if (!getTopLeftOnBit(left, top) || !getBottomRightOnBit(right, bottom) || bottom - top + 1 < minSize) return false; -#ifdef ZX_FAST_BIT_STORAGE for (int y = top; y <= bottom; y++ ) { for (int x = 0; x < left; ++x) if (get(x, y)) { @@ -102,36 +89,6 @@ BitMatrix::findBoundingBox(int &left, int& top, int& width, int& height, int min break; } } -#else - for (int y = top; y <= bottom; y++) - { - for (int x32 = 0; x32 < _rowSize; x32++) - { - uint32_t theBits = _bits[y * _rowSize + x32]; - if (theBits != 0) - { - if (x32 * 32 < left) { - int bit = 0; - while ((theBits << (31 - bit)) == 0) { - bit++; - } - if ((x32 * 32 + bit) < left) { - left = x32 * 32 + bit; - } - } - if (x32 * 32 + 31 > right) { - int bit = 31; - while ((theBits >> bit) == 0) { - bit--; - } - if ((x32 * 32 + bit) > right) { - right = x32 * 32 + bit; - } - } - } - } - } -#endif width = right - left + 1; height = bottom - top + 1; @@ -147,11 +104,8 @@ BitMatrix::getTopLeftOnBit(int& left, int& top) const if (bitsOffset == Size(_bits)) { return false; } - top = bitsOffset / _rowSize; - left = (bitsOffset % _rowSize); -#ifndef ZX_FAST_BIT_STORAGE - left = left * 32 + BitHacks::NumberOfTrailingZeros(_bits[bitsOffset]); -#endif + top = bitsOffset / _width; + left = (bitsOffset % _width); return true; } @@ -163,11 +117,8 @@ BitMatrix::getBottomRightOnBit(int& right, int& bottom) const return false; } - bottom = bitsOffset / _rowSize; - right = (bitsOffset % _rowSize); -#ifndef ZX_FAST_BIT_STORAGE - right = right * 32 + 31 - BitHacks::NumberOfLeadingZeros(_bits[bitsOffset]); -#endif + bottom = bitsOffset / _width; + right = (bitsOffset % _width); return true; } diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index 4a6e824839..a344beadbe 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -1,6 +1,7 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 @@ -9,7 +10,6 @@ #include "Matrix.h" #include "Point.h" #include "Range.h" -#include "ZXConfig.h" #include #include @@ -23,29 +23,24 @@ class ByteMatrix; /** * @brief A simple, fast 2D array of bits. - * - * Note: the original bit-packed storage variant is currently unusuable. */ class BitMatrix { int _width = 0; int _height = 0; - int _rowSize = 0; -#ifdef ZX_FAST_BIT_STORAGE using data_t = uint8_t; static constexpr data_t SET_V = 0xff; // allows playing with SIMD binarization static constexpr data_t UNSET_V = 0; static_assert(bool(SET_V), "SET_V needs to evaluate to true, see iterator usage"); -#else - using data_t = uint32_t; -#endif + std::vector _bits; // There is nothing wrong to support this but disable to make it explicit since we may copy something very big here. // Use copy() below. BitMatrix(const BitMatrix&) = default; BitMatrix& operator=(const BitMatrix&) = delete; - const data_t& get(int i) const { + const data_t& get(int i) const + { #if 1 return _bits.at(i); #else @@ -60,14 +55,7 @@ class BitMatrix public: BitMatrix() = default; -#ifdef ZX_FAST_BIT_STORAGE - BitMatrix(int width, int height) : _width(width), _height(height), _rowSize(width), _bits(width * height, UNSET_V) {} -#else - BitMatrix(int width, int height) - : _width(width), _height(height), _rowSize((width + 31) / 32), _bits(((width + 31) / 32) * _height, 0) - {} -#endif - + BitMatrix(int width, int height) : _width(width), _height(height), _bits(width * height, UNSET_V) {} explicit BitMatrix(int dimension) : BitMatrix(dimension, dimension) {} // Construct a square matrix. BitMatrix(BitMatrix&& other) noexcept = default; @@ -75,61 +63,16 @@ class BitMatrix BitMatrix copy() const { return *this; } -#ifdef ZX_FAST_BIT_STORAGE Range row(int y) { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } Range row(int y) const { return {_bits.data() + y * _width, _bits.data() + (y + 1) * _width}; } Range> col(int x) const { return {{_bits.data() + x, _width}, {_bits.data() + x + _height * _width, _width}}; } -#endif - - /** - *

Gets the requested bit, where true means black.

- * - * @param x The horizontal component (i.e. which column) - * @param y The vertical component (i.e. which row) - * @return value of given bit in matrix - */ - bool get(int x, int y) const - { -#ifdef ZX_FAST_BIT_STORAGE - return get(y * _width + x); -#else - return ((get(y * _rowSize + (x / 32)) >> (x & 0x1f)) & 1) != 0; -#endif - } - - /** - *

Sets the given bit to true.

- * - * @param x The horizontal component (i.e. which column) - * @param y The vertical component (i.e. which row) - */ - void set(int x, int y) - { -#ifdef ZX_FAST_BIT_STORAGE - get(y * _width + x) = SET_V; -#else - get(y * _rowSize + (x / 32)) |= 1 << (x & 0x1f); -#endif - } - void unset(int x, int y) - { -#ifdef ZX_FAST_BIT_STORAGE - get(y * _width + x) = UNSET_V; -#else - get(y * _rowSize + (x / 32)) &= ~(1 << (x & 0x1f)); -#endif - } + bool get(int x, int y) const { return get(y * _width + x); } + void set(int x, int y) { get(y * _width + x) = SET_V; } + void unset(int x, int y) { get(y * _width + x) = UNSET_V; } - void set(int x, int y, bool val) - { -#ifdef ZX_FAST_BIT_STORAGE - get(y * _width + x) = val ? SET_V : UNSET_V; -#else - val ? set(x, y) : unset(x, y); -#endif - } + void set(int x, int y, bool val) { get(y * _width + x) = val * SET_V; } /** *

Flips the given bit.

@@ -139,12 +82,8 @@ class BitMatrix */ void flip(int x, int y) { -#ifdef ZX_FAST_BIT_STORAGE - auto& v =get(y * _width + x); + auto& v = get(y * _width + x); v = !v; -#else - get(y * _rowSize + (x / 32)) ^= 1 << (x & 0x1f); -#endif } void flipAll() @@ -185,7 +124,7 @@ class BitMatrix friend bool operator==(const BitMatrix& a, const BitMatrix& b) { - return a._width == b._width && a._height == b._height && a._rowSize == b._rowSize && a._bits == b._bits; + return a._width == b._width && a._height == b._height && a._bits == b._bits; } template diff --git a/core/src/HybridBinarizer.cpp b/core/src/HybridBinarizer.cpp index 275d42352d..8ccc2aa800 100644 --- a/core/src/HybridBinarizer.cpp +++ b/core/src/HybridBinarizer.cpp @@ -103,23 +103,12 @@ static Matrix CalculateBlackPoints(const uint8_t* luminances, int subWidth, */ static void ThresholdBlock(const uint8_t* luminances, int xoffset, int yoffset, int threshold, int rowStride, BitMatrix& matrix) { -#ifdef ZX_FAST_BIT_STORAGE for (int y = yoffset; y < yoffset + BLOCK_SIZE; ++y) { auto* src = luminances + y * rowStride + xoffset; auto* const dstBegin = matrix.row(y).begin() + xoffset; for (auto* dst = dstBegin; dst < dstBegin + BLOCK_SIZE; ++dst, ++src) *dst = *src <= threshold; } -#else - for (int y = 0, offset = yoffset * rowStride + xoffset; y < BLOCK_SIZE; y++, offset += rowStride) { - for (int x = 0; x < BLOCK_SIZE; x++) { - // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0. - if (luminances[offset + x] <= threshold) { - matrix.set(xoffset + x, yoffset + y); - } - } - } -#endif } /** diff --git a/core/src/ThresholdBinarizer.h b/core/src/ThresholdBinarizer.h index 92cb1ffb56..66173c5868 100644 --- a/core/src/ThresholdBinarizer.h +++ b/core/src/ThresholdBinarizer.h @@ -52,7 +52,7 @@ class ThresholdBinarizer : public BinaryBitmap std::shared_ptr getBlackMatrix() const override { BitMatrix res(width(), height()); -#ifdef ZX_FAST_BIT_STORAGE + if (_buffer.pixStride() == 1 && _buffer.rowStride() == _buffer.width()) { // Specialize for a packed buffer with pixStride 1 to support auto vectorization (16x speedup on AVX2) auto dst = res.row(0).begin(); @@ -75,12 +75,7 @@ class ThresholdBinarizer : public BinaryBitmap } } } -#else - const int channel = GreenIndex(_buffer.format()); - for (int y = 0; y < res.height(); ++y) - for (int x = 0; x < res.width(); ++x) - res.set(x, y, _buffer.data(x, y)[channel] <= _threshold); -#endif + return std::make_shared(std::move(res)); } }; diff --git a/core/src/ZXConfig.h b/core/src/ZXConfig.h index 0a1e6a6ea1..c0d83452f0 100644 --- a/core/src/ZXConfig.h +++ b/core/src/ZXConfig.h @@ -13,13 +13,6 @@ // The alternative 'static' makes the code thread unsafe. #define ZX_THREAD_LOCAL // 'thread_local' or 'static' -// The two basic data structures for storing bits (BitArray and BitMatrix) can be operated by storing one bit -// of information either in one bit or one byte. Storing it in one byte is considerably faster, while obviously -// using more memory. The effect of the memory usage while running the TestRunner is virtually invisible. -// On embedded/mobile systems this might be of importance. Note: the BitMatrix in 'fast' mode still requires -// only 1/3 of the same image in RGB. -#define ZX_FAST_BIT_STORAGE // undef to disable - // The Galoir Field abstractions used in Reed-Solomon error correction code can use more memory to eliminate a modulo // operation. This improves performance but might not be the best option if RAM is scarce. The effect is a few kB big. #define ZX_REED_SOLOMON_USE_MORE_MEMORY_FOR_SPEED diff --git a/core/src/pdf417/PDFDetector.cpp b/core/src/pdf417/PDFDetector.cpp index 57f91fb253..99fcf76ac8 100644 --- a/core/src/pdf417/PDFDetector.cpp +++ b/core/src/pdf417/PDFDetector.cpp @@ -302,7 +302,6 @@ static std::list, 8>> DetectBarcode(const BitMa return barcodeCoordinates; } -#ifdef ZX_FAST_BIT_STORAGE bool HasStartPattern(const BitMatrix& m, bool rotate90) { constexpr FixedPattern<8, 17> START_PATTERN = { 8, 1, 1, 1, 1, 1, 1, 3 }; @@ -323,7 +322,6 @@ bool HasStartPattern(const BitMatrix& m, bool rotate90) return false; } -#endif /** *

Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.

@@ -343,10 +341,9 @@ Detector::Result Detector::Detect(const BinaryBitmap& image, bool multiple, bool Result result; for (int rotate90 = 0; rotate90 <= static_cast(tryRotate) && result.points.empty(); ++rotate90) { -#if defined(ZX_FAST_BIT_STORAGE) if (!HasStartPattern(*binImg, rotate90)) continue; -#endif + result.rotation = 90 * rotate90; if (rotate90) { auto newBits = std::make_shared(binImg->copy()); From 55dcb5e7d6d44c622d3a65b81f1843886848475b Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 23 Jul 2022 14:17:32 +0200 Subject: [PATCH 0414/1315] BitMatrix: remove unparameterized set/unset functions --- core/src/BitMatrix.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/core/src/BitMatrix.h b/core/src/BitMatrix.h index a344beadbe..1ae43a1110 100644 --- a/core/src/BitMatrix.h +++ b/core/src/BitMatrix.h @@ -31,7 +31,7 @@ class BitMatrix using data_t = uint8_t; static constexpr data_t SET_V = 0xff; // allows playing with SIMD binarization static constexpr data_t UNSET_V = 0; - static_assert(bool(SET_V), "SET_V needs to evaluate to true, see iterator usage"); + static_assert(bool(SET_V) && !bool(UNSET_V), "SET_V needs to evaluate to true, UNSET_V to false, see iterator usage"); std::vector _bits; // There is nothing wrong to support this but disable to make it explicit since we may copy something very big here. @@ -69,10 +69,7 @@ class BitMatrix Range> col(int x) const { return {{_bits.data() + x, _width}, {_bits.data() + x + _height * _width, _width}}; } bool get(int x, int y) const { return get(y * _width + x); } - void set(int x, int y) { get(y * _width + x) = SET_V; } - void unset(int x, int y) { get(y * _width + x) = UNSET_V; } - - void set(int x, int y, bool val) { get(y * _width + x) = val * SET_V; } + void set(int x, int y, bool val = true) { get(y * _width + x) = val * SET_V; } /** *

Flips the given bit.

@@ -88,9 +85,8 @@ class BitMatrix void flipAll() { - for (auto& i : _bits) { - i = ~i; - } + for (auto& i : _bits) + i = !i; } /** From 917ecec8735194b3b9bab1672b6bd6e7becdcc72 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 24 Jul 2022 18:07:03 +0200 Subject: [PATCH 0415/1315] example: add (hidden) performance measurement helper code in ZXingReader --- example/ZXingReader.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 0c82caffcb..d49d88a83a 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -249,6 +249,20 @@ int main(int argc, char* argv[]) if (Size(filePaths) == 1 && !outPath.empty()) stbi_write_png(outPath.c_str(), image.width(), image.height(), 3, image.data(0, 0), image.rowStride()); +#ifdef NDEBUG + if (getenv("MEASURE_PERF")) { + auto startTime = std::chrono::high_resolution_clock::now(); + auto duration = startTime - startTime; + int N = 0; + do { + for (int i = 0; i < 100; ++i) + ReadBarcodes(image, hints); + N += 100; + duration = std::chrono::high_resolution_clock::now() - startTime; + } while (duration < std::chrono::seconds(1)); + printf("time: %5.1f ms per frame\n", double(std::chrono::duration_cast(duration).count()) / N); + } +#endif } return ret; From 031cf183ab9fce5008b927eedad0b703978b8485 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Jul 2022 18:43:12 +0200 Subject: [PATCH 0416/1315] DataMatrix: improve detection rate in presence of noise * tolerate 2 pixel wide steps during finder pattern detection * tolerate more noise just outside the timing pattern * tolerate more noise at the timing pattern edges This has been coming up while experimenting with a new binarizer. --- core/src/RegressionLine.h | 10 ++++---- core/src/datamatrix/DMDetector.cpp | 34 +++++++++++++++------------ test/blackbox/BlackboxTestRunner.cpp | 10 ++++---- test/samples/datamatrix-3/dm-k.jpg | Bin 0 -> 3842 bytes test/samples/datamatrix-3/dm-k.txt | 1 + 5 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 test/samples/datamatrix-3/dm-k.jpg create mode 100644 test/samples/datamatrix-3/dm-k.txt diff --git a/core/src/RegressionLine.h b/core/src/RegressionLine.h index be3dd0a813..489e9d503f 100644 --- a/core/src/RegressionLine.h +++ b/core/src/RegressionLine.h @@ -104,10 +104,12 @@ class RegressionLine auto points = _points; while (true) { auto old_points_size = points.size(); - points.erase( - std::remove_if(points.begin(), points.end(), - [this, maxSignedDist](auto p) { return this->signedDistance(p) > maxSignedDist; }), - points.end()); + // remove points that are further 'inside' than maxSignedDist or further 'outside' than 2 x maxSignedDist + auto end = std::remove_if(points.begin(), points.end(), [this, maxSignedDist](auto p) { + auto sd = this->signedDistance(p); + return sd > maxSignedDist || sd < -2 * maxSignedDist; + }); + points.erase(end, points.end()); if (old_points_size == points.size()) break; #ifdef PRINT_DEBUG diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index 1a5d2e6b16..b50bbe9057 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -428,37 +428,41 @@ class DMRegressionLine : public RegressionLine // re-evaluate and filter out all points too far away. required for the gapSizes calculation. evaluate(1.0, true); - std::vector gapSizes; + std::vector gapSizes, modSizes; gapSizes.reserve(_points.size()); // calculate the distance between the points projected onto the regression line for (size_t i = 1; i < _points.size(); ++i) gapSizes.push_back(distance(project(_points[i]), project(_points[i - 1]))); - // calculate the (average) distance of two adjacent pixels - auto unitPixelDist = average(gapSizes, [](double dist){ return 0.75 < dist && dist < 1.5; }); + // calculate the (expected average) distance of two adjacent pixels + auto unitPixelDist = ZXing::length(bresenhamDirection(_points.back() - _points.front())); // calculate the width of 2 modules (first black pixel to first black pixel) - double sum = distance(beg, project(_points.front())) - unitPixelDist; - auto i = gapSizes.begin(); + double sumFront = distance(beg, project(_points.front())) - unitPixelDist; + double sumBack = 0; // (last black pixel to last black pixel) for (auto dist : gapSizes) { - sum += dist; if (dist > 1.9 * unitPixelDist) - *i++ = std::exchange(sum, 0.0); + modSizes.push_back(std::exchange(sumBack, 0.0)); + sumFront += dist; + sumBack += dist; + if (dist > 1.9 * unitPixelDist) + modSizes.push_back(std::exchange(sumFront, 0.0)); } - *i++ = sum + distance(end, project(_points.back())); - gapSizes.erase(i, gapSizes.end()); + modSizes.push_back(sumFront + distance(end, project(_points.back()))); + modSizes.front() = 0; // the first element is an invalid sumBack value, would be pop_front() if vector supported this auto lineLength = distance(beg, end) - unitPixelDist; - auto meanGapSize = lineLength / gapSizes.size(); + auto meanModSize = average(modSizes, [](double){ return true; }); #ifdef PRINT_DEBUG printf("unit pixel dist: %.1f\n", unitPixelDist); - printf("lineLength: %.1f, meanGapSize: %.1f, gaps: %lu\n", lineLength, meanGapSize, gapSizes.size()); + printf("lineLength: %.1f, meanModSize: %.1f, gaps: %lu\n", lineLength, meanModSize, modSizes.size()); #endif - meanGapSize = average(gapSizes, [&](double dist){ return std::abs(dist - meanGapSize) < meanGapSize/2; }); + for (int i = 0; i < 2; ++i) + meanModSize = average(modSizes, [=](double dist) { return std::abs(dist - meanModSize) < meanModSize / (2 + i); }); #ifdef PRINT_DEBUG - printf("lineLength: %.1f, meanGapSize: %.1f, gaps: %lu\n", lineLength, meanGapSize, gapSizes.size()); + printf("post filter meanModSize: %.1f\n", meanModSize); #endif - return lineLength / meanGapSize; + return lineLength / meanModSize; } }; @@ -469,7 +473,7 @@ class EdgeTracer : public BitMatrixCursorF StepResult traceStep(PointF dEdge, int maxStepSize, bool goodDirection) { dEdge = mainDirection(dEdge); - for (int breadth = 1; breadth <= (goodDirection ? 1 : (maxStepSize == 1 ? 2 : 3)); ++breadth) + for (int breadth = 1; breadth <= (maxStepSize == 1 ? 2 : (goodDirection ? 1 : 3)); ++breadth) for (int step = 1; step <= maxStepSize; ++step) for (int i = 0; i <= 2*(step/4+1) * breadth; ++i) { auto pEdge = p + step * d + (i&1 ? (i+1)/2 : -i/2) * dEdge; diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index bb32635c86..7e126a621c 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -360,11 +360,11 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 0, 13, 270 }, }); - runTests("datamatrix-3", "DataMatrix", 19, { - { 18, 19, 0 }, - { 0, 19, 90 }, - { 0, 19, 180 }, - { 0, 19, 270 }, + runTests("datamatrix-3", "DataMatrix", 20, { + { 19, 20, 0 }, + { 0, 20, 90 }, + { 0, 20, 180 }, + { 0, 20, 270 }, }); runTests("datamatrix-4", "DataMatrix", 21, { diff --git a/test/samples/datamatrix-3/dm-k.jpg b/test/samples/datamatrix-3/dm-k.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f43940c5a52dda8f2627599044fbf53a0ca6b738 GIT binary patch literal 3842 zcmb7GXH-*Lw>=37gwPUtCjk-zgc3wPsz@jbA|2@n5u}PV0hJ=1075{z2vP+uEr=B1 zaw!oh7CJ~#h)5L$QEVVzblm&ydq3YApYp^+f~Vgw$9 z2Y{n_Ko4MsK$)QsW@ace3kx$0j)22iS>e2#T`Wj4j9@}AUO$>}`cV?5mJ9ss z1^Wb467uVx8gLrFlWbn5z^-4imrt)F7+-8CdjBY@E2_VxPMF6v>%6W^W|KPnqoQ*} zWZ#PNrhVm;8DXKbmLF0cA>Rtx`P)|N zgJX5gwV`P`RyR4)e%3)>uQcXpvxIW4f2QSSo-w=yRfYCxXZr+f1@8|yueXrzR|+|_ zQCXP`uwL%u%lg!<785Sr5qq(@yrRg<7(}+Mp(x0N?`f0CarttME?b+0t6`ojq^3-v zTnn%sO+^s_V(_tFt%eY<|1#V{cP} za8d_*z3qRg^r(-=KkWIG&vY4;eX!{yJxr7=W1DF1?Cek+y7)6TP{&$X-rcC{$?c{? zuOI$%l_C9_)|pR4U9|#waa@ox2Okc~$P})L7Ku+XK|4cC%by$5WLVfPimue+l!sK? z$55fwBs;Iv>B0+j-FyDMyFo+)NMSXb72r*PU*Kj+vl)NLR%JyhjQMXq02sch*AOe_qr<)m((*}_wD%#}G62SRop zZlF{Q7wTf&X(+3%4MCmE#Ev?x`HP3AMFe;j`w6bXPC{qVm<#wbOg2!B_De^u`YNs*34dF$DcO2^6D(TriZ zU!BARVO-FEhJuh_ZnUHlK^I}+#&gOXWl0L8{@qK=I^ct1Bf>s^X=qxZ`^=x|f>TZ< zxQ@3%Vs$RL3&}oN(;tmbnkV zUdEZ%oCT9(Z>(3XEWo))Hhx2*Wx0QTB@e}Zeab)Cbf9tCDZn$SdF z+Qt6T9Pa!XlYm<$Z!Qy_M-p0gj0kTucP{R1MX!BY?CO5O;6ReW0n=}u|A%W35=}tp zTDS$qPXT^v0#fH}+4Qv(zfD6`^F`XI@R2d@-g! zom1pWx@YiEl}x%1HRK$Vnall?IAZH(pSm~uv)X8I=PHL7STaH7(j{(u&Aw_rif{V> zWM^J$X(=Ti|1;C$PK8U20u#5JcPZI=J;Bkdk=3_Z`mBI3I$W_TqviZxrB>2~netce z5u21LEq>(bsRuiUSog_e_aixN%!gYCqXlUNURe_CO@(rYJQPfr zH=TFig{>|%DiyLWgi)AEs&V zT5-s~NVYU@kAflY2I*UKYmSi2I1{qtQy?-FNRq|C(w{mHgazPVOW*A{YU_H(a+Y{m zOTos*MBMcp8dp4h9JG+6Bj8+jfD?g@jV|?Sl)_(rxSQtAt!Q%2kr<-Cr}K>@iV->j zbl#8LA&ps7``E$-*7MtoH8oem8J+ukj|F}i10r)McNuXJjCJ0sK?y!rB_CFAm2u#){4{Arh z==$4ne#zz^-(cK92qYRs&<*@8m|y;cNXg?naY9Hez`P(_a%Wx?1FMaT!o5)Y6n=$L zBO#fJplKq#IjcL2HTniz3Ww>pgfX06P6|#Kc7M5y-x!Po0%M|oK|lZ!fkG23+2jq2H^ zqP(9x=qB|K{?S~g@R9x|4x656`hvi~!yrHms=#0noglN6iWu8j?)?qS z*jIHBQcqxN)gsfP$$1M*PlsIZSUu!OJiG^3mQwjUiH<>_?O;%SOn-ahS3Hf{fe>L` zYE|Qw-}VqoEmTB8XLjvYZsvjL?5_j8je03xkS_$g`Wvh@xHyYE_%SO*{J4~SQWxIG_6m#YSkxVmt4Fujl<#GGk+{LB|{ z?tSn@SUwcxEhsq263Mo|3UhK~%fGK6|M9vT;Zw{iSJ_N{cyvc;wYA^N3>jlpG%1+R z*FK1=sOeKpvyk{a41cyHgS*_}(Eu)|Co!uE@$g-AHQB*YQ*uipb0ZCQrSStoG{qpt zIQ?)0@DiX2aU2r@b$j~K(L*%$Gc%s;7J%M4CthBljUJkc-+F4zreQd~bz1Y~{Rzo& z4(vknxe3!OydU1?^mr@%UHvY<)Az%thx5LU+vry}Jl@n?OMQGhmQIz#)QT_NlX;H% zexPmGJJB(2b9xCsIH>77;tnd^bg^rGt@mPF4fQ?jy+|)?|9i^Sh|K+nC*!5AN=4ns z8O8h{JoikkpBSODvXNFfr6zW7(`B(qBF6%{rJ!;yVz}5;mAj?#@R^Uf73(?Oz#{b; z+jt&urEFTWFmZ$~s~orADGQvKR5gD!aHx3!ka2nK=>6aXF0Tf`Q?6Y^0R2wYQmtnr1F| z@#2sr`3^-em|(c^N0QR)+>O>O2u#YCw{%WAX!yW*+Ie{XYF6LP>TYwMvt~VM)w-7I z8M}9`ZKN?PG8LR!elECOP-z_HdiP1cJ@MnK4_1!$;t&%7Kvsn3>2m4XW10cqSQFDS zy-b#@yJB_$0Tbc)3jrED8~h)yY5?b`LPHF)*q#qM=xg;z(wE#87hk?LMF*x*&8qCIqi)9(1*#J+UzN>t&`6FAdTisLmHP}c zTZfXPtDnXgVlh*9&sLx2?~Iotmf&l=PtJgW21K%0#BDCQL|Hj|tF~^`yHg8SwDr;S z2I+4d!G@D3RiUh6BYgGEF|x`db4{P~eqegfs%gf6PcAEQ2rX}YGkYR{uf#je17TV9t@i#d zq|7(BYwgovReE@&*)HD2!|Ll1KxOUs Date: Tue, 26 Jul 2022 22:29:48 +0200 Subject: [PATCH 0417/1315] ECI: remove unused `#include "TextDecoder.h" --- core/src/datamatrix/DMDecoder.cpp | 1 - core/src/maxicode/MCDecoder.cpp | 1 - core/src/oned/ODDataBarExpandedReader.cpp | 1 - core/src/oned/ODDataBarReader.cpp | 1 - core/src/pdf417/PDFDecodedBitStreamParser.cpp | 1 - core/src/qrcode/QRDecoder.cpp | 1 - test/unit/aztec/AZEncodeDecodeTest.cpp | 1 - test/unit/oned/ODCodaBarWriterTest.cpp | 1 - 8 files changed, 8 deletions(-) diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index 96115f9772..e12a9122f5 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -15,7 +15,6 @@ #include "DecoderResult.h" #include "GenericGF.h" #include "ReedSolomonDecoder.h" -#include "TextDecoder.h" #include "ZXAlgorithms.h" #include "ZXTestSupport.h" diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 7022feac98..3ddacbb8e9 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -12,7 +12,6 @@ #include "GenericGF.h" #include "MCBitMatrixParser.h" #include "ReedSolomonDecoder.h" -#include "TextDecoder.h" #include "ZXTestSupport.h" #include diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 02aec2a3ad..653d2f974d 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -13,7 +13,6 @@ #include "ODDataBarCommon.h" #include "ODDataBarExpandedBitDecoder.h" #include "Result.h" -#include "TextDecoder.h" #include #include diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index 3945241dc6..f75379e74f 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -12,7 +12,6 @@ #include "GTIN.h" #include "ODDataBarCommon.h" #include "Result.h" -#include "TextDecoder.h" #include diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index c6d9738c1f..914fed9c57 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -10,7 +10,6 @@ #include "CharacterSet.h" #include "DecoderResult.h" #include "PDFDecoderResultExtra.h" -#include "TextDecoder.h" #include "TextUtfEncoding.h" #include "ZXBigInteger.h" #include "ZXTestSupport.h" diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index 21720d1996..c4a42addbc 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -18,7 +18,6 @@ #include "QRVersion.h" #include "ReedSolomonDecoder.h" #include "StructuredAppend.h" -#include "TextDecoder.h" #include "ZXAlgorithms.h" #include "ZXTestSupport.h" diff --git a/test/unit/aztec/AZEncodeDecodeTest.cpp b/test/unit/aztec/AZEncodeDecodeTest.cpp index b28b9135e3..25d7981093 100644 --- a/test/unit/aztec/AZEncodeDecodeTest.cpp +++ b/test/unit/aztec/AZEncodeDecodeTest.cpp @@ -8,7 +8,6 @@ #include "CharacterSet.h" #include "DecoderResult.h" #include "PseudoRandom.h" -#include "TextDecoder.h" #include "TextEncoder.h" #include "aztec/AZDecoder.h" #include "aztec/AZDetectorResult.h" diff --git a/test/unit/oned/ODCodaBarWriterTest.cpp b/test/unit/oned/ODCodaBarWriterTest.cpp index 15824775c4..9023ffc787 100644 --- a/test/unit/oned/ODCodaBarWriterTest.cpp +++ b/test/unit/oned/ODCodaBarWriterTest.cpp @@ -10,7 +10,6 @@ #include "DecodeHints.h" #include "Result.h" #include "oned/ODCodabarReader.h" -#include "TextUtfEncoding.h" #include "gtest/gtest.h" #include From 1730eadf16f1437192ff9f39ac8374b8387520e8 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Jul 2022 22:30:58 +0200 Subject: [PATCH 0418/1315] python: use new utf8 based `MultiFormatWriter::encode()` overload --- wrappers/python/zxing.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index f89ea0c4e7..14555ba31b 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -14,7 +14,6 @@ // Writer #include "BitMatrix.h" #include "MultiFormatWriter.h" -#include "TextUtfEncoding.h" #include #include @@ -104,7 +103,7 @@ Results read_barcodes(py::object _image, const BarcodeFormats& formats, bool try Image write_barcode(BarcodeFormat format, std::string text, int width, int height, int quiet_zone, int ec_level) { auto writer = MultiFormatWriter(format).setMargin(quiet_zone).setEccLevel(ec_level); - auto bitmap = writer.encode(TextUtfEncoding::FromUtf8(text), width, height); + auto bitmap = writer.encode(text, width, height); auto result = Image({bitmap.height(), bitmap.width()}); auto r = result.mutable_unchecked<2>(); From 688f7fd41141ea7f678d2f53145bc2fc91481fca Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Jul 2022 22:31:47 +0200 Subject: [PATCH 0419/1315] python: use pybind11 v2.10.0 --- wrappers/python/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/CMakeLists.txt b/wrappers/python/CMakeLists.txt index eadfc045ff..465ec722a5 100644 --- a/wrappers/python/CMakeLists.txt +++ b/wrappers/python/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.14) project(ZXingPython) set (pybind11_git_repo https://github.com/pybind/pybind11.git) -set (pybind11_git_rev v2.9.1) +set (pybind11_git_rev v2.10.0) # check if we are called from the top-level ZXing project get_directory_property(hasParent PARENT_DIRECTORY) From 3872abbb33ebb8d6c891baff33778aae04f0c546 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Jul 2022 22:42:00 +0200 Subject: [PATCH 0420/1315] test: update to libfmt v9.0.0 --- test/blackbox/BlackboxTestRunner.cpp | 8 ++++---- test/blackbox/CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 7e126a621c..85c5b9d427 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -218,8 +218,7 @@ static void doRunTests(const fs::path& directory, std::string_view format, int t auto folderName = directory.stem(); if (Size(imgPaths) != totalTests) - fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName, totalTests, - imgPaths.size()); + fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName.string(), totalTests, imgPaths.size()); for (auto& test : tests) { fmt::print("{:20} @ {:3}, {:3}", folderName.string(), test.rotation, Size(imgPaths)); @@ -280,7 +279,8 @@ static void doRunStructuredAppendTest(const fs::path& directory, std::string_vie } if (Size(imageGroups) != totalTests) - fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName, totalTests, imageGroups.size()); + fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName.string(), totalTests, + imageGroups.size()); for (auto& test : tests) { fmt::print("{:20} @ {:3}, {:3}", folderName.string(), test.rotation, Size(imgPaths)); @@ -493,7 +493,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 17, 20, 0 }, { 18, 20, 180 }, }); - + runTests("upca-extension-1", "UPC-A", 6, { { 4, 4, 0 }, { 3, 4, 180 }, diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index f20f4127c7..2bb8cdd2fe 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -1,5 +1,5 @@ zxing_add_package_stb() -zxing_add_package(fmt fmtlib https://github.com/fmtlib/fmt.git 8.1.1) +zxing_add_package(fmt fmtlib https://github.com/fmtlib/fmt.git 9.0.0) if (BUILD_READERS) add_executable (ReaderTest From 0ca7e2a41e4907b95a1642aebb0c9bd7705dddc4 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 26 Jul 2022 23:15:56 +0200 Subject: [PATCH 0421/1315] c++: fix remaining MSVC compiler warnings --- core/src/MultiFormatReader.cpp | 2 +- core/src/Range.h | 2 +- core/src/qrcode/QRDetector.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index f445232a47..ecb6a3a02d 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -68,7 +68,7 @@ Results MultiFormatReader::readMultiple(const BinaryBitmap& image, int maxSymbol auto it = std::remove_if(res.begin(), res.end(), [](auto&& r) { return !r.isValid(); }); res.erase(it, res.end()); } - maxSymbols -= r.size(); + maxSymbols -= Size(r); res.insert(res.end(), std::move_iterator(r.begin()), std::move_iterator(r.end())); if (maxSymbols <= 0) break; diff --git a/core/src/Range.h b/core/src/Range.h index 21860384bf..d1d94faaaa 100644 --- a/core/src/Range.h +++ b/core/src/Range.h @@ -20,7 +20,7 @@ struct StrideIter StrideIter& operator++() { return pos += stride, *this; } bool operator<(const StrideIter& rhs) const { return pos < rhs.pos; } StrideIter operator+(int i) const { return {pos + i * stride, stride}; } - int operator-(const StrideIter& rhs) const { return (pos - rhs.pos) / stride; } + int operator-(const StrideIter& rhs) const { return narrow_cast((pos - rhs.pos) / stride); } }; template diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 99d008f2e3..3283feddb3 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -173,7 +173,7 @@ static double EstimateModuleSize(const BitMatrix& image, PointF a, PointF b) BitMatrixCursorF cur(image, a, b - a); assert(cur.isBlack()); - if (!cur.stepToEdge(3, distance(a, b) / 3, true)) + if (!cur.stepToEdge(3, static_cast(distance(a, b) / 3), true)) return -1; assert(cur.isBlack()); @@ -390,7 +390,7 @@ DetectorResult DetectPureMQR(const BitMatrix& image) auto fpWidth = Reduce(diagonal); float moduleSize = float(fpWidth) / 7; - auto dimension = width / moduleSize; + int dimension = narrow_cast(std::lround(width / moduleSize)); if (dimension < MIN_MODULES || dimension > MAX_MODULES || !image.isIn(PointF{left + moduleSize / 2 + (dimension - 1) * moduleSize, From 8131dc5ca823c776ba505cbafef4856c5b8bfa22 Mon Sep 17 00:00:00 2001 From: gitlost Date: Tue, 26 Jul 2022 23:31:04 +0100 Subject: [PATCH 0422/1315] PDFScanningDecoder::VerifyCodewordCount(): check codewords[0] exactly matches array size; add test --- core/src/pdf417/PDFScanningDecoder.cpp | 6 +- test/unit/CMakeLists.txt | 1 + .../unit/pdf417/PDF417ScanningDecoderTest.cpp | 56 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 test/unit/pdf417/PDF417ScanningDecoderTest.cpp diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index df0708ad07..ce7aa05200 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -555,8 +555,10 @@ static bool VerifyCodewordCount(std::vector& codewords, int numECCodewords) if (numberOfCodewords > Size(codewords)) { return false; } - if (numberOfCodewords == 0) { - // Reset to the length of the array - 8 (Allow for at least level 3 Error Correction (8 Error Codewords) + + assert(numECCodewords >= 2); + if (numberOfCodewords + numECCodewords != Size(codewords)) { + // Reset to the length of the array less number of Error Codewords if (numECCodewords < Size(codewords)) { codewords[0] = Size(codewords) - numECCodewords; } diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 6edfcc2bc2..facae254ed 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -61,6 +61,7 @@ add_executable (UnitTest pdf417/PDF417DecoderTest.cpp pdf417/PDF417ErrorCorrectionTest.cpp pdf417/PDF417HighLevelEncoderTest.cpp + pdf417/PDF417ScanningDecoderTest.cpp pdf417/PDF417WriterTest.cpp ) diff --git a/test/unit/pdf417/PDF417ScanningDecoderTest.cpp b/test/unit/pdf417/PDF417ScanningDecoderTest.cpp new file mode 100644 index 0000000000..cd7143a42f --- /dev/null +++ b/test/unit/pdf417/PDF417ScanningDecoderTest.cpp @@ -0,0 +1,56 @@ +/* +* Copyright 2022 gitlost +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "DecoderResult.h" +#include "pdf417/PDFScanningDecoder.h" + +#include "gtest/gtest.h" + +namespace ZXing::Pdf417 { + DecoderResult DecodeCodewords(std::vector& codewords, int ecLevel, const std::vector& erasures); +} + +using namespace ZXing; +using namespace ZXing::Pdf417; + +// Shorthand for DecodeCodewords() +static DecoderResult decode(std::vector& codewords, int ecLevel = 0) +{ + std::vector erasures; + auto result = DecodeCodewords(codewords, ecLevel, erasures); + + return result; +} + +TEST(PDF417ScanningDecoderTest, BadSymbolLengthDescriptor) +{ + { + std::vector codewords = { 4, 1, 449, 394 }; // 4 should be 2 + + auto result = decode(codewords); + + EXPECT_TRUE(result.isValid()); + EXPECT_EQ(result.text(), L"AB"); + EXPECT_EQ(codewords[0], 2); + } + { + std::vector codewords = { 1, 1, 800, 351 }; // 1 should be 2 + + auto result = decode(codewords); + + EXPECT_TRUE(result.isValid()); + EXPECT_EQ(result.text(), L"AB"); + EXPECT_EQ(codewords[0], 2); + } + { + std::vector codewords = { 0, 1, 917, 27 }; // 0 should be 2 + + auto result = decode(codewords); + + EXPECT_TRUE(result.isValid()); + EXPECT_EQ(result.text(), L"AB"); + EXPECT_EQ(codewords[0], 2); + } +} From ceb2d93c63c715d1ccf65089224ddb7f95a0c7ff Mon Sep 17 00:00:00 2001 From: gitlost Date: Tue, 26 Jul 2022 23:41:37 +0100 Subject: [PATCH 0423/1315] PDFScanningDecoder: remove some unnecessary includes, sort --- core/src/pdf417/PDFScanningDecoder.cpp | 17 +++++------------ core/src/pdf417/PDFScanningDecoder.h | 2 -- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/core/src/pdf417/PDFScanningDecoder.cpp b/core/src/pdf417/PDFScanningDecoder.cpp index ce7aa05200..4531228dc3 100644 --- a/core/src/pdf417/PDFScanningDecoder.cpp +++ b/core/src/pdf417/PDFScanningDecoder.cpp @@ -5,24 +5,17 @@ // SPDX-License-Identifier: Apache-2.0 #include "PDFScanningDecoder.h" -#include "PDFBoundingBox.h" -#include "PDFDetectionResultColumn.h" -#include "PDFCodewordDecoder.h" + +#include "BitMatrix.h" +#include "DecoderResult.h" #include "PDFBarcodeMetadata.h" -#include "PDFDetectionResult.h" #include "PDFBarcodeValue.h" +#include "PDFCodewordDecoder.h" +#include "PDFDetectionResult.h" #include "PDFDecodedBitStreamParser.h" #include "PDFModulusGF.h" -#include "ResultPoint.h" -#include "ZXNullable.h" -#include "BitMatrix.h" -#include "DecoderResult.h" #include "ZXTestSupport.h" -#include -#include -#include - namespace ZXing { namespace Pdf417 { diff --git a/core/src/pdf417/PDFScanningDecoder.h b/core/src/pdf417/PDFScanningDecoder.h index 2c34aea07c..8516699bf7 100644 --- a/core/src/pdf417/PDFScanningDecoder.h +++ b/core/src/pdf417/PDFScanningDecoder.h @@ -6,8 +6,6 @@ #pragma once -#include - namespace ZXing { class BitMatrix; From 8762c46b73db4ff40ff7e03dc7e5050894f1b008 Mon Sep 17 00:00:00 2001 From: gitlost Date: Wed, 27 Jul 2022 00:50:20 +0100 Subject: [PATCH 0424/1315] ODDatabarReader::ConstructText(): strip GS1 Composite 2D linkage flag from checksum if any (stops ToString() throwing an exception and at least allows the linear part of GS1 Composite symbols to be returned); add test --- core/src/oned/ODDataBarReader.cpp | 4 +++ test/unit/CMakeLists.txt | 3 +- test/unit/oned/ODDataBarReaderTest.cpp | 38 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test/unit/oned/ODDataBarReaderTest.cpp diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index f75379e74f..52b541c41a 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -135,6 +135,10 @@ static std::string ConstructText(Pair leftPair, Pair rightPair) { auto value = [](Pair p) { return 1597 * p.left.value + p.right.value; }; auto res = 4537077LL * value(leftPair) + value(rightPair); + if (res >= 10000000000000LL) { // Strip 2D linkage flag (GS1 Composite) if any (ISO/IEC 24724:2011 Section 5.2.3) + res -= 10000000000000LL; + assert(res <= 9999999999999LL); // 13 digits + } auto txt = ToString(res, 13); return txt + GTIN::ComputeCheckDigit(txt); } diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index facae254ed..7102f7e51d 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -42,12 +42,13 @@ add_executable (UnitTest oned/ODCode93WriterTest.cpp oned/ODCode128ReaderTest.cpp oned/ODCode128WriterTest.cpp + oned/ODDataBarReaderTest.cpp + oned/ODDataBarExpandedBitDecoderTest.cpp oned/ODEAN8WriterTest.cpp oned/ODEAN13WriterTest.cpp oned/ODITFWriterTest.cpp oned/ODUPCAWriterTest.cpp oned/ODUPCEWriterTest.cpp - oned/ODDataBarExpandedBitDecoderTest.cpp qrcode/MQRDecoderTest.cpp qrcode/QRBitMatrixParserTest.cpp qrcode/QRDataMaskTest.cpp diff --git a/test/unit/oned/ODDataBarReaderTest.cpp b/test/unit/oned/ODDataBarReaderTest.cpp new file mode 100644 index 0000000000..70cbfacbb8 --- /dev/null +++ b/test/unit/oned/ODDataBarReaderTest.cpp @@ -0,0 +1,38 @@ +/* +* Copyright 2022 gitlost +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "oned/ODDataBarReader.h" + +#include "DecodeHints.h" +#include "Result.h" + +#include "gtest/gtest.h" + +using namespace ZXing; +using namespace ZXing::OneD; + +// Helper to call decodePattern() +static Result parse(PatternRow row, DecodeHints hints = {}) +{ + DataBarReader reader(hints); + + row.insert(row.begin(), { 1, 1 }); // Left guard + row.insert(row.end(), { 1, 1 }); // Right guard + + std::unique_ptr state; + PatternView next(row); + return reader.decodePattern(0, next, state); +} + +TEST(ODDataBarReaderTest, Composite) +{ + { + // With 2D linkage flag (GS1 Composite) in checksum + PatternRow row = { 2, 3, 1, 2, 1, 2, 4, 1, 3, 3, 7, 1, 1, 3, 1, 2, 1, 1, 1, 4, 2, 4, 1, 1, 2, 3, 1, 1, 2, 1, 1, 2, 8, 3, 3, 2, 2, 1, 4, 1, 1, 2 }; + Result result = parse(row); + EXPECT_TRUE(result.isValid()); + EXPECT_EQ(result.text(), "01234567890128"); + } +} From 3ee0127044a10a27576332f596d11b9baf5c816e Mon Sep 17 00:00:00 2001 From: gitlost Date: Wed, 27 Jul 2022 00:53:38 +0100 Subject: [PATCH 0425/1315] ODDataBarReader: comment typo --- core/src/oned/ODDataBarReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/oned/ODDataBarReader.cpp b/core/src/oned/ODDataBarReader.cpp index 52b541c41a..a6477257fe 100644 --- a/core/src/oned/ODDataBarReader.cpp +++ b/core/src/oned/ODDataBarReader.cpp @@ -204,7 +204,7 @@ Result DataBarReader::decodePattern(int rowNumber, PatternView& next, } #endif - // guaratee progress (see loop in ODReader.cpp) + // guarantee progress (see loop in ODReader.cpp) next = {}; return {}; From 8629bda0ea4a5063b7aec9d11698518d574d35ed Mon Sep 17 00:00:00 2001 From: gitlost Date: Wed, 27 Jul 2022 11:35:48 +0100 Subject: [PATCH 0426/1315] MCDecode: allow for dodgy data in primary message, including postcode data/length mismatches and out-of-range postcode/country/class values. --- core/src/maxicode/MCDecoder.cpp | 30 +++++++----- test/unit/maxicode/MCDecoderTest.cpp | 71 +++++++++++++++++++++++++--- 2 files changed, 82 insertions(+), 19 deletions(-) diff --git a/core/src/maxicode/MCDecoder.cpp b/core/src/maxicode/MCDecoder.cpp index 3ddacbb8e9..dd154eed2b 100644 --- a/core/src/maxicode/MCDecoder.cpp +++ b/core/src/maxicode/MCDecoder.cpp @@ -122,25 +122,31 @@ static int GetBit(int bit, const ByteArray& bytes) return (bytes[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1; } -static int GetInt(const ByteArray& bytes, const ByteArray& x) +static unsigned int GetInt(const ByteArray& bytes, const ByteArray& x) { int len = Size(x); - int val = 0; + unsigned int val = 0; for (int i = 0; i < len; i++) val += GetBit(x[i], bytes) << (len - i - 1); return val; } -static int GetPostCode2(const ByteArray& bytes) +static unsigned int GetPostCode2Length(const ByteArray& bytes) { - return GetInt(bytes, - {33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2}); + return std::min(GetInt(bytes, {39, 40, 41, 42, 31, 32}), 9U); } -static int GetPostCode2Length(const ByteArray& bytes) +static std::string GetPostCode2(const ByteArray& bytes) { - return GetInt(bytes, {39, 40, 41, 42, 31, 32}); + unsigned int val = GetInt(bytes, + {33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2}); + unsigned int len = GetPostCode2Length(bytes); + // Pad or truncate to length + char buf[11]; // 30 bits 0x3FFFFFFF == 1073741823 (10 digits) + sprintf(buf, "%0*d", len, val); + buf[len] = '\0'; + return buf; } static std::string GetPostCode3(const ByteArray& bytes) @@ -155,14 +161,14 @@ static std::string GetPostCode3(const ByteArray& bytes) }; } -static int GetCountry(const ByteArray& bytes) +static unsigned int GetCountry(const ByteArray& bytes) { - return GetInt(bytes, {53, 54, 43, 44, 45, 46, 47, 48, 37, 38}); + return std::min(GetInt(bytes, {53, 54, 43, 44, 45, 46, 47, 48, 37, 38}), 999U); } -static int GetServiceClass(const ByteArray& bytes) +static unsigned int GetServiceClass(const ByteArray& bytes) { - return GetInt(bytes, {55, 56, 57, 58, 59, 60, 49, 50, 51, 52}); + return std::min(GetInt(bytes, {55, 56, 57, 58, 59, 60, 49, 50, 51, 52}), 999U); } /** @@ -266,7 +272,7 @@ DecoderResult Decode(ByteArray&& bytes, const int mode) switch (mode) { case 2: case 3: { - auto postcode = mode == 2 ? ToString(GetPostCode2(bytes), GetPostCode2Length(bytes)) : GetPostCode3(bytes); + auto postcode = mode == 2 ? GetPostCode2(bytes) : GetPostCode3(bytes); auto country = ToString(GetCountry(bytes), 3); auto service = ToString(GetServiceClass(bytes), 3); GetMessage(bytes, 10, 84, result, sai); diff --git a/test/unit/maxicode/MCDecoderTest.cpp b/test/unit/maxicode/MCDecoderTest.cpp index e811107c0f..b44af4d083 100644 --- a/test/unit/maxicode/MCDecoderTest.cpp +++ b/test/unit/maxicode/MCDecoderTest.cpp @@ -26,16 +26,24 @@ static void pad(ByteArray& padded) } // Helper to call Decode() -static DecoderResult parse(ByteArray bytes, const int mode) +static DecoderResult parse(ByteArray bytes, const int mode, ByteArray *mode2or3 = nullptr) { ByteArray padded; padded.reserve(93 + 1); // 93 + mode if (mode == 2) { - // Mode 2, Postcode 152382802, Country 840, Class 001 example from ISO/IEC 16023:2000 Annex B.2 - padded = {34, 20, 45, 20, 17, 18, 2, 18, 7, 0}; + if (mode2or3) { + padded = *mode2or3; + } else { + // Mode 2, Postcode 152382802, Country 840, Class 001 example from ISO/IEC 16023:2000 Annex B.2 + padded = {34, 20, 45, 20, 17, 18, 2, 18, 7, 0}; + } } else if (mode == 3) { - // Mode 3, Postcode B1050, Country 056, Class 999 example from ISO/IEC 16023:2000 Annex B.1 - padded = {3, 8, 28, 13, 28, 44, 0, 14, 28, 62}; + if (mode2or3) { + padded = *mode2or3; + } else { + // Mode 3, Postcode B1050, Country 056, Class 999 example from ISO/IEC 16023:2000 Annex B.1 + padded = {3, 8, 28, 13, 28, 44, 0, 14, 28, 62}; + } } else { padded.push_back(mode); } @@ -50,7 +58,7 @@ static StructuredAppendInfo info(ByteArray bytes, const int mode) return parse(bytes, mode).structuredAppend(); } -TEST(MCDecodeTest, StructuredAppendSymbologyIdentifier) +TEST(MCDecoderTest, StructuredAppendSymbologyIdentifier) { // Null EXPECT_EQ(info({49}, 2).index, -1); // Mode 2 @@ -137,7 +145,7 @@ TEST(MCDecodeTest, StructuredAppendSymbologyIdentifier) EXPECT_EQ(info({33, 032, 49}, 4).count, 0); } -TEST(MCDecodeTest, ReaderInit) +TEST(MCDecoderTest, ReaderInit) { // Null EXPECT_FALSE(parse({49}, 2).readerInit()); // Mode 2 @@ -147,3 +155,52 @@ TEST(MCDecodeTest, ReaderInit) EXPECT_TRUE(parse({49}, 6).readerInit()); // Mode 6 EXPECT_TRUE(parse({49}, 6).isValid()); } + +TEST(MCDecoderTest, Mode2) +{ + // Good data + { + // Postcode 1234, Postcode Length 4, Country 999, Class 999 + ByteArray mode2 = { 34, 52, 4, 0, 0, 0, 49, 57, 31, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "1234\035999\035999\0351"); + } + { + // Postcode 0123, Postcode Length 4, Country 999, Class 999 + ByteArray mode2 = { 50, 30, 0, 0, 0, 0, 49, 57, 31, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "0123\035999\035999\0351"); + } + + // Dodgy data (postcode length mismatch) + { + // Postcode 123456789, Postcode Length 4, Country 999, Class 999 + ByteArray mode2 = { 18, 5, 13, 47, 53, 1, 49, 57, 31, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "1234\035999\035999\0351"); // Postcode truncated + } + { + // Postcode 123, Postcode Length 4, Country 999, Class 999 + ByteArray mode2 = { 50, 30, 0, 0, 0, 0, 49, 57, 31, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "0123\035999\035999\0351"); // Postcode zero-filled to len 4 + } + + // Out-of-range data + { + // Postcode 1, Postcode Length 10, Country 999, Class 999 + ByteArray mode2 = { 18, 0, 0, 0, 0, 32, 50, 57, 31, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "000000001\035999\035999\0351"); // Postcode capped to len 9 & zero-filled + } + { + // Postcode 1073741823 (0x3FFFFFFF, 30-bit max), Postcode Length 10, Country 999, Class 999 + ByteArray mode2 = { 50, 63, 63, 63, 63, 47, 50, 57, 31, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "107374182\035999\035999\0351"); // Postcode truncated + } + { + // Postcode 12345, Postcode Length 5, Country 1023 (0x3FF, 10-bit max), Class 999 + ByteArray mode2 = { 18, 14, 48, 0, 0, 16, 49, 63, 31, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "12345\035999\035999\0351"); // Country capped to 999 + } + { + // Postcode 123456, Postcode Length 8, Country 999, Class 1000 (0x3E8) + ByteArray mode2 = { 2, 16, 34, 7, 0, 0, 50, 57, 35, 62 }; + EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "00123456\035999\035999\0351"); // Class capped to 999 + } +} From 5d9ac453735c48032053bbcfdb66ddc46359a0fa Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Jul 2022 18:03:19 +0200 Subject: [PATCH 0427/1315] TextUtfEncoding: drop dependence of angleEscape feature on system locale --- core/src/TextUtfEncoding.cpp | 7 ++++--- example/ZXingReader.cpp | 3 --- test/unit/TextUtfEncodingTest.cpp | 34 ------------------------------- 3 files changed, 4 insertions(+), 40 deletions(-) diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index 500a017975..b9267a818f 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -182,7 +182,6 @@ std::string ToUtf8(const std::wstring& str) } // Same as `ToUtf8()` above, except if angleEscape set, places non-graphical characters in angle brackets with text name -// Note `std::setlocale(LC_CTYPE, "en_US.UTF-8")` must be set beforehand for `std::iswraph()` to work std::string ToUtf8(const std::wstring& str, const bool angleEscape) { if (!angleEscape) { @@ -195,8 +194,10 @@ std::string ToUtf8(const std::wstring& str, const bool angleEscape) "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", "DEL", }; - std::wostringstream ws; + std::locale utf8Loc("en_US.UTF-8"); + + std::wostringstream ws; ws.fill(L'0'); for (unsigned int i = 0; i < str.length(); i++) { @@ -213,7 +214,7 @@ std::string ToUtf8(const std::wstring& str, const bool angleEscape) ws.write(str.c_str() + i++, 2); } else { // Exclude unpaired surrogates and NO-BREAK spaces NBSP and NUMSP - if ((wc < 0xd800 || wc >= 0xe000) && (std::iswgraph(wc) && wc != 0xA0 && wc != 0x2007)) { + if ((wc < 0xd800 || wc >= 0xe000) && (std::isgraph(wc, utf8Loc) && wc != 0xA0 && wc != 0x2007 && wc != 0xfffd)) { ws << wc; } else { // Non-graphical Unicode int width = wc < 256 ? 2 : 4; diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index d49d88a83a..0fdc819b62 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -140,9 +140,6 @@ int main(int argc, char* argv[]) hints.setEanAddOnSymbol(EanAddOnSymbol::Read); - if (angleEscape) - std::setlocale(LC_CTYPE, "en_US.UTF-8"); // Needed so `std::iswgraph()` in `ToUtf8(angleEscape)` does not 'swallow' all printable non-ascii utf8 chars - std::cout.setf(std::ios::boolalpha); for (const auto& filePath : filePaths) { diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index f37e1bfb65..dd87276521 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -15,30 +15,7 @@ TEST(TextUtfEncodingTest, ToUtf8AngleEscape) bool angleEscape = true; - std::string ctype_locale(std::setlocale(LC_CTYPE, NULL)); // Use std::string to avoid assert on Windows Debug - EXPECT_EQ(ctype_locale, std::string("C")); - -#ifndef _WIN32 - EXPECT_EQ(ToUtf8(L"\u00B6\u0416", angleEscape), ""); -#else EXPECT_EQ(ToUtf8(L"\u00B6\u0416", angleEscape), "¶Ж"); -#endif - EXPECT_EQ(ToUtf8(L"\u2602", angleEscape), ""); - -#ifndef _WIN32 - std::setlocale(LC_CTYPE, "en_US.UTF-8"); - EXPECT_STREQ(std::setlocale(LC_CTYPE, NULL), "en_US.UTF-8"); -#else - std::setlocale(LC_CTYPE, ".utf8"); - EXPECT_TRUE(std::string(std::setlocale(LC_CTYPE, NULL)).find("utf8") != std::string::npos); -#endif - - EXPECT_EQ(ToUtf8(L"\u00B6\u0416", angleEscape), "¶Ж"); -#ifndef _WIN32 - EXPECT_EQ(ToUtf8(L"\u2602", angleEscape), "☂"); -#else - EXPECT_EQ(ToUtf8(L"\u2602", angleEscape), ""); -#endif EXPECT_EQ(ToUtf8(L"\x01\x1F\x7F", angleEscape), ""); EXPECT_EQ(ToUtf8(L"\x80\x9F", angleEscape), ""); EXPECT_EQ(ToUtf8(L"\xA0", angleEscape), ""); // NO-BREAK space (nbsp) @@ -47,19 +24,8 @@ TEST(TextUtfEncodingTest, ToUtf8AngleEscape) EXPECT_EQ(ToUtf8(L"\u0100", angleEscape), "Ā"); EXPECT_EQ(ToUtf8(L"\u1000", angleEscape), "က"); EXPECT_EQ(ToUtf8(L"\u2000", angleEscape), ""); // Space char (nqsp) -#ifndef _WIN32 - EXPECT_EQ(ToUtf8(L"\uFFFD", angleEscape), "�"); -#else EXPECT_EQ(ToUtf8(L"\uFFFD", angleEscape), ""); -#endif EXPECT_EQ(ToUtf8(L"\uFFFF", angleEscape), ""); -#ifndef __APPLE__ - EXPECT_EQ(ToUtf8(L"\U00010000", angleEscape), "𐀀"); -#else - EXPECT_EQ(ToUtf8(L"\U00010000", angleEscape), ""); -#endif EXPECT_EQ(ToUtf8(L"\xD800Z", angleEscape), "Z"); // Unpaired high surrogate EXPECT_EQ(ToUtf8(L"A\xDC00", angleEscape), "A"); // Unpaired low surrogate - - std::setlocale(LC_CTYPE, ctype_locale.c_str()); } From e0b55812e8403d591339f89ddffbd16db40fcb3d Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 27 Jul 2022 18:16:12 +0200 Subject: [PATCH 0428/1315] TextUtfEncoding: attempted fix of build regression on win/macos --- core/src/TextUtfEncoding.cpp | 2 +- test/unit/TextUtfEncodingTest.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index b9267a818f..e3b6f88b94 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -5,7 +5,7 @@ #include "TextUtfEncoding.h" -#include +#include #include #include diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index dd87276521..83ad79641e 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -21,8 +21,6 @@ TEST(TextUtfEncodingTest, ToUtf8AngleEscape) EXPECT_EQ(ToUtf8(L"\xA0", angleEscape), ""); // NO-BREAK space (nbsp) EXPECT_EQ(ToUtf8(L"\x2007", angleEscape), ""); // NO-BREAK space (numsp) EXPECT_EQ(ToUtf8(L"\xFFEF", angleEscape), ""); // Was NO-BREAK space but now isn't (BOM) - EXPECT_EQ(ToUtf8(L"\u0100", angleEscape), "Ā"); - EXPECT_EQ(ToUtf8(L"\u1000", angleEscape), "က"); EXPECT_EQ(ToUtf8(L"\u2000", angleEscape), ""); // Space char (nqsp) EXPECT_EQ(ToUtf8(L"\uFFFD", angleEscape), ""); EXPECT_EQ(ToUtf8(L"\uFFFF", angleEscape), ""); From d97f4eaa6353edc8282b1fc16ea218da31acef45 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 2 Aug 2022 14:01:00 +0200 Subject: [PATCH 0429/1315] TextUtfEncoding: replace Utf8Decode with slightly improved version See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ --- core/src/TextUtfEncoding.cpp | 43 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index e3b6f88b94..b8259693fe 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -36,36 +36,37 @@ static size_t Utf8CountCodePoints(const uint8_t* utf8, size_t length) return count; } -static const uint32_t kAccepted = 0; +constexpr uint32_t kAccepted = 0; +constexpr uint32_t kRejected [[maybe_unused]] = 12; -/// -/// Copyright (c) 2008-2009 Bjoern Hoehrmann -/// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. -/// -static uint32_t Utf8Decode(uint8_t byte, uint32_t& state, uint32_t& codep) +inline uint32_t Utf8Decode(uint8_t byte, uint32_t& state, uint32_t& codep) { // Copyright (c) 2008-2009 Bjoern Hoehrmann // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. static const uint8_t kUtf8Data[] = { - 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,0, // 00..1f - 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,0, // 20..3f - 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,0, // 40..5f - 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,0, // 60..7f - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df - 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef - 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff - 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 - 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 - 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 - 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 + /* The first part of the table maps bytes to character classes that + * reduce the size of the transition table and create bitmasks. */ + 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,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,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,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,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + + /* The second part is a transition table that maps a combination + * of a state of the automaton and a character class to a state. */ + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, + 12,36,12,12,12,12,12,12,12,12,12,12, }; uint32_t type = kUtf8Data[byte]; codep = (state != kAccepted) ? (byte & 0x3fu) | (codep << 6) : (0xff >> type) & (byte); - state = kUtf8Data[256 + state * 16 + type]; + state = kUtf8Data[256 + state + type]; return state; } From bc26cd188faee6ab403f8d4f92643de8a531919c Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 4 Aug 2022 01:25:52 +0200 Subject: [PATCH 0430/1315] TextUtfEncoding: use narrow_cast (instead of static cast) --- core/src/TextUtfEncoding.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index b8259693fe..0d6bbb57b0 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "TextUtfEncoding.h" +#include "ZXAlgorithms.h" #include #include @@ -85,10 +86,11 @@ static void ConvertFromUtf8(const uint8_t* src, size_t length, std::wstring& buf continue; if (sizeof(wchar_t) == 2 && codePoint > 0xffff) { // surrogate pair - buffer.push_back(static_cast(0xd7c0 + (codePoint >> 10))); - buffer.push_back(static_cast(0xdc00 + (codePoint & 0x3ff))); - } else - buffer.push_back(static_cast(codePoint)); + buffer.push_back(narrow_cast(0xd7c0 + (codePoint >> 10))); + buffer.push_back(narrow_cast(0xdc00 + (codePoint & 0x3ff))); + } else { + buffer.push_back(narrow_cast(codePoint)); + } } } @@ -126,21 +128,21 @@ static int Utf8Encode(uint32_t utf32, char* out) return 1; } if (utf32 < 0x800) { - *out++ = static_cast((utf32 >> 6) | 0xc0); - *out++ = static_cast((utf32 & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 >> 6) | 0xc0); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); return 2; } if (utf32 < 0x10000) { - *out++ = static_cast((utf32 >> 12) | 0xe0); - *out++ = static_cast(((utf32 >> 6) & 0x3f) | 0x80); - *out++ = static_cast((utf32 & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 >> 12) | 0xe0); + *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); return 3; } - *out++ = static_cast((utf32 >> 18) | 0xf0); - *out++ = static_cast(((utf32 >> 12) & 0x3f) | 0x80); - *out++ = static_cast(((utf32 >> 6) & 0x3f) | 0x80); - *out++ = static_cast((utf32 & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 >> 18) | 0xf0); + *out++ = narrow_cast(((utf32 >> 12) & 0x3f) | 0x80); + *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); return 4; } From d742319f3428ac42704eab6b972ccf1f7cd97804 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 4 Aug 2022 20:10:30 +0200 Subject: [PATCH 0431/1315] ECI: replace Qt originated charset conversion code with libzueci Big thanks to @gitlost for providing libzueci especially for this project to be able to get rid of the questionable LGPL (with exception) code copied from Qt (which copied it from other BSD licensensed places). The libzueci code is fetched via cmake directly from its own git repo during configuration. We may decide to include the code in this repo later in case this fetch should be too much of a burden for package maintainsers. --- LGPL_EXCEPTION.Qt | 22 - LICENSE.Qt | 514 --- NOTICE | 29 - core/CMakeLists.txt | 40 +- core/src/Content.cpp | 23 +- core/src/Content.h | 6 +- core/src/ECI.cpp | 8 +- core/src/ECI.h | 7 +- core/src/TextDecoder.cpp | 331 +- core/src/TextDecoder.h | 10 +- core/src/TextEncoder.cpp | 247 +- core/src/TextEncoder.h | 6 + core/src/textcodec/Big5MapTable.cpp | 686 ---- core/src/textcodec/Big5MapTable.h | 47 - core/src/textcodec/Big5TextDecoder.cpp | 1794 -------- core/src/textcodec/Big5TextDecoder.h | 43 - core/src/textcodec/Big5TextEncoder.cpp | 4272 -------------------- core/src/textcodec/Big5TextEncoder.h | 41 - core/src/textcodec/GBTextDecoder.cpp | 3576 ---------------- core/src/textcodec/GBTextDecoder.h | 44 - core/src/textcodec/GBTextEncoder.cpp | 4061 ------------------- core/src/textcodec/GBTextEncoder.h | 42 - core/src/textcodec/JPTextDecoder.cpp | 2775 ------------- core/src/textcodec/JPTextDecoder.h | 73 - core/src/textcodec/JPTextEncoder.cpp | 2218 ---------- core/src/textcodec/JPTextEncoder.h | 71 - core/src/textcodec/KRHangulMapping.cpp | 189 - core/src/textcodec/KRHangulMapping.h | 38 - core/src/textcodec/KRTextDecoder.cpp | 1097 ----- core/src/textcodec/KRTextDecoder.h | 43 - core/src/textcodec/KRTextEncoder.cpp | 731 ---- core/src/textcodec/KRTextEncoder.h | 41 - test/unit/TextDecoderTest.cpp | 56 +- test/unit/TextUtfEncodingTest.cpp | 15 + test/unit/aztec/AZHighLevelEncoderTest.cpp | 3 +- test/unit/qrcode/QREncoderTest.cpp | 5 +- zxing.cmake | 7 +- 37 files changed, 145 insertions(+), 23066 deletions(-) delete mode 100644 LGPL_EXCEPTION.Qt delete mode 100644 LICENSE.Qt delete mode 100644 NOTICE delete mode 100644 core/src/textcodec/Big5MapTable.cpp delete mode 100644 core/src/textcodec/Big5MapTable.h delete mode 100644 core/src/textcodec/Big5TextDecoder.cpp delete mode 100644 core/src/textcodec/Big5TextDecoder.h delete mode 100644 core/src/textcodec/Big5TextEncoder.cpp delete mode 100644 core/src/textcodec/Big5TextEncoder.h delete mode 100644 core/src/textcodec/GBTextDecoder.cpp delete mode 100644 core/src/textcodec/GBTextDecoder.h delete mode 100644 core/src/textcodec/GBTextEncoder.cpp delete mode 100644 core/src/textcodec/GBTextEncoder.h delete mode 100644 core/src/textcodec/JPTextDecoder.cpp delete mode 100644 core/src/textcodec/JPTextDecoder.h delete mode 100644 core/src/textcodec/JPTextEncoder.cpp delete mode 100644 core/src/textcodec/JPTextEncoder.h delete mode 100644 core/src/textcodec/KRHangulMapping.cpp delete mode 100644 core/src/textcodec/KRHangulMapping.h delete mode 100644 core/src/textcodec/KRTextDecoder.cpp delete mode 100644 core/src/textcodec/KRTextDecoder.h delete mode 100644 core/src/textcodec/KRTextEncoder.cpp delete mode 100644 core/src/textcodec/KRTextEncoder.h diff --git a/LGPL_EXCEPTION.Qt b/LGPL_EXCEPTION.Qt deleted file mode 100644 index 5cdacb9a4e..0000000000 --- a/LGPL_EXCEPTION.Qt +++ /dev/null @@ -1,22 +0,0 @@ -The Qt Company Qt LGPL Exception version 1.1 - -As an additional permission to the GNU Lesser General Public License version -2.1, the object code form of a "work that uses the Library" may incorporate -material from a header file that is part of the Library. You may distribute -such object code under terms of your choice, provided that: - (i) the header files of the Library have not been modified; and - (ii) the incorporated material is limited to numerical parameters, data - structure layouts, accessors, macros, inline functions and - templates; and - (iii) you comply with the terms of Section 6 of the GNU Lesser General - Public License version 2.1. - -Moreover, you may apply this exception to a modified version of the Library, -provided that such modification does not involve copying material from the -Library into the modified Library's header files unless such material is -limited to (i) numerical parameters; (ii) data structure layouts; -(iii) accessors; and (iv) small macros, templates and inline functions of -five lines or less in length. - -Furthermore, you are not required to apply this additional permission to a -modified version of the Library. diff --git a/LICENSE.Qt b/LICENSE.Qt deleted file mode 100644 index 6e18461125..0000000000 --- a/LICENSE.Qt +++ /dev/null @@ -1,514 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - - The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. - Contact: http://www.qt.io/licensing/ - - You may use, distribute and copy the Qt GUI Toolkit under the terms of - GNU Lesser General Public License version 2.1, which is displayed below. - -------------------------------------------------------------------------- - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 067976dc1c..0000000000 --- a/NOTICE +++ /dev/null @@ -1,29 +0,0 @@ --------------------------------------------------------------------------------- -NOTICES FOR TextCodec --------------------------------------------------------------------------------- -Part of this software uses code source from Qt under LGPL license. -Copyright (C) 2015 The Qt Company Ltd. - --------------------------------------------------------------------------------- -NOTICES FOR ZXing --------------------------------------------------------------------------------- -Copyright 2016 ZXing authors. -https://github.com/zxing - --------------------------------------------------------------------------------- -NOTICES FOR BARCODE4J --------------------------------------------------------------------------------- - -Barcode4J -Copyright 2002-2010 Jeremias Märki -Copyright 2005-2006 Dietmar Bürkle - -Portions of this software were contributed under section 5 of the -Apache License. Contributors are listed under: -http://barcode4j.sourceforge.net/contributors.html - --------------------------------------------------------------------------------- -NOTICES FOR JCOMMANDER --------------------------------------------------------------------------------- - -Copyright 2010 Cedric Beust cedric@beust.com diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index c7fb9f7e61..4181b9af05 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required (VERSION 3.10) +include(../zxing.cmake) +zxing_add_package(zueci zueci https://git.code.sf.net/p/libzueci/code master) +set(ZUECI_STATIC ON CACHE INTERNAL "") + if (NOT DEFINED BUILD_WRITERS) set (BUILD_WRITERS OFF) endif() @@ -392,38 +396,6 @@ if (BUILD_WRITERS) ) endif() - -set (TEXT_CODEC_FILES - src/textcodec/Big5MapTable.h - src/textcodec/Big5MapTable.cpp - src/textcodec/KRHangulMapping.h - src/textcodec/KRHangulMapping.cpp -) -if (BUILD_READERS) - set (TEXT_CODEC_FILES ${TEXT_CODEC_FILES} - src/textcodec/Big5TextDecoder.h - src/textcodec/Big5TextDecoder.cpp - src/textcodec/GBTextDecoder.h - src/textcodec/GBTextDecoder.cpp - src/textcodec/JPTextDecoder.h - src/textcodec/JPTextDecoder.cpp - src/textcodec/KRTextDecoder.h - src/textcodec/KRTextDecoder.cpp - ) -endif() -if (BUILD_WRITERS) - set (TEXT_CODEC_FILES ${TEXT_CODEC_FILES} - src/textcodec/Big5TextEncoder.h - src/textcodec/Big5TextEncoder.cpp - src/textcodec/GBTextEncoder.h - src/textcodec/GBTextEncoder.cpp - src/textcodec/JPTextEncoder.h - src/textcodec/JPTextEncoder.cpp - src/textcodec/KRTextEncoder.h - src/textcodec/KRTextEncoder.cpp - ) -endif() - source_group (Sources FILES ${COMMON_FILES}) source_group (Sources\\aztec FILES ${AZTEC_FILES}) source_group (Sources\\datamatrix FILES ${DATAMATRIX_FILES}) @@ -431,7 +403,6 @@ source_group (Sources\\maxicode FILES ${MAXICODE_FILES}) source_group (Sources\\oned FILES ${ONED_FILES}) source_group (Sources\\pdf417 FILES ${PDF417_FILES}) source_group (Sources\\qrcode FILES ${QRCODE_FILES}) -source_group (Sources\\textcodec FILES ${TEXT_CODEC_FILES}) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) @@ -445,7 +416,6 @@ add_library (ZXing ${ONED_FILES} ${PDF417_FILES} ${QRCODE_FILES} - ${TEXT_CODEC_FILES} ) target_include_directories (ZXing @@ -469,7 +439,7 @@ endif() target_compile_features(ZXing PUBLIC cxx_std_17) -target_link_libraries (ZXing PRIVATE Threads::Threads) +target_link_libraries (ZXing PRIVATE Threads::Threads zueci-static) add_library(ZXing::ZXing ALIAS ZXing) # add the old alias as well, to keep old clients compiling diff --git a/core/src/Content.cpp b/core/src/Content.cpp index d8917de79c..eb34c3771f 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -91,14 +91,14 @@ bool Content::canProcess() const return std::all_of(encodings.begin(), encodings.end(), [](Encoding e) { return CanProcess(e.eci); }); } -std::wstring Content::render(bool withECI) const +std::string Content::render(bool withECI) const { if (empty() || !canProcess()) return {}; - std::wstring res; + std::string res; if (withECI) - res = TextDecoder::FromLatin1(symbology.toString(true)); + res = symbology.toString(true); ECI lastECI = ECI::Unknown; auto fallbackCS = defaultCharset; if (!hasECI && fallbackCS == CharacterSet::Unknown) @@ -118,14 +118,14 @@ std::wstring Content::render(bool withECI) const eci = ECI::Binary; if (lastECI != eci) - TextDecoder::AppendLatin1(res, ToString(eci)); + res += ToString(eci); lastECI = eci; - std::wstring tmp; + std::string tmp; TextDecoder::Append(tmp, bytes.data() + begin, end - begin, cs); for (auto c : tmp) { res += c; - if (c == L'\\') // in the ECI protocol a '\' has to be doubled + if (c == '\\') // in the ECI protocol a '\' has to be doubled res += c; } } else { @@ -139,8 +139,8 @@ std::wstring Content::render(bool withECI) const std::string Content::text(TextMode mode) const { switch(mode) { - case TextMode::Utf8: return TextUtfEncoding::ToUtf8(render(false)); - case TextMode::Utf8ECI: return TextUtfEncoding::ToUtf8(render(true)); + case TextMode::Utf8: return render(false); + case TextMode::Utf8ECI: return render(true); case TextMode::HRI: if (symbology.aiFlag == AIFlag::GS1) return HRIFromGS1(text(TextMode::Utf8)); @@ -149,12 +149,17 @@ std::string Content::text(TextMode mode) const else return text(TextMode::Escaped); case TextMode::Hex: return ToHex(bytes); - case TextMode::Escaped: return TextUtfEncoding::ToUtf8(render(false), true); + case TextMode::Escaped: return TextUtfEncoding::ToUtf8(TextUtfEncoding::FromUtf8(render(false)), true); } return {}; // silence compiler warning } +std::wstring Content::utf16() const +{ + return TextUtfEncoding::FromUtf8(render(false)); +} + ByteArray Content::bytesECI() const { if (empty()) diff --git a/core/src/Content.h b/core/src/Content.h index 6146eda3c3..d7a769ddc4 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -38,7 +38,7 @@ class Content void ForEachECIBlock(FUNC f) const; void switchEncoding(ECI eci, bool isECI); - std::wstring render(bool withECI) const; + std::string render(bool withECI) const; public: struct Encoding @@ -76,8 +76,8 @@ class Content bool canProcess() const; std::string text(TextMode mode) const; - std::wstring utf16() const { return render(false); } - std::string utf8() const { return text(TextMode::Utf8); } + std::wstring utf16() const; + std::string utf8() const { return render(false); } ByteArray bytesECI() const; CharacterSet guessEncoding() const; diff --git a/core/src/ECI.cpp b/core/src/ECI.cpp index f0ff259a66..e02fcb736d 100644 --- a/core/src/ECI.cpp +++ b/core/src/ECI.cpp @@ -14,7 +14,7 @@ namespace ZXing { static const std::map ECI_TO_CHARSET = { {ECI(0), CharacterSet::Cp437}, // Obsolete {ECI(1), CharacterSet::ISO8859_1}, // Obsolete - {ECI(2), CharacterSet::Cp437}, // Obsolete but still used by PDF417 Macro fields (ISO/IEC 15438:2015 Annex H.2.3) + {ECI::Cp437, CharacterSet::Cp437}, // Obsolete but still used by PDF417 Macro fields (ISO/IEC 15438:2015 Annex H.2.3) {ECI::ISO8859_1, CharacterSet::ISO8859_1}, {ECI::ISO8859_2, CharacterSet::ISO8859_2}, {ECI::ISO8859_3, CharacterSet::ISO8859_3}, @@ -40,8 +40,9 @@ static const std::map ECI_TO_CHARSET = { {ECI::ASCII, CharacterSet::ASCII}, {ECI::Big5, CharacterSet::Big5}, {ECI::GB18030, CharacterSet::GB18030}, + {ECI::GB2312, CharacterSet::GB2312}, {ECI::EUC_KR, CharacterSet::EUC_KR}, - {ECI(170), CharacterSet::ASCII}, + {ECI::ISO646_Inv, CharacterSet::ASCII}, {ECI::Binary, CharacterSet::BINARY}, }; @@ -63,6 +64,9 @@ ECI ToECI(CharacterSet cs) // Special case ISO8859_1 to avoid obsolete ECI 1 if (cs == CharacterSet::ISO8859_1) return ECI::ISO8859_1; + // Special case Cp437 to avoid obsolete ECI 0 for slightly less obsolete ECI 2 + if (cs == CharacterSet::Cp437) + return ECI::Cp437; for (auto& [key, value] : ECI_TO_CHARSET) if (value == cs) diff --git a/core/src/ECI.h b/core/src/ECI.h index bb780324b0..d7f6e122cb 100644 --- a/core/src/ECI.h +++ b/core/src/ECI.h @@ -14,6 +14,7 @@ namespace ZXing { enum class ECI : int { Unknown = -1, + Cp437 = 2, // obsolete ISO8859_1 = 3, ISO8859_2 = 4, ISO8859_3 = 5, @@ -38,8 +39,10 @@ enum class ECI : int UTF8 = 26, ASCII = 27, Big5 = 28, - GB18030 = 29, + GB2312 = 29, EUC_KR = 30, + GB18030 = 32, + ISO646_Inv = 170, Binary = 899 }; @@ -50,7 +53,7 @@ inline constexpr int ToInt(ECI eci) inline constexpr bool IsText(ECI eci) { - return ToInt(eci) >= 0 && ToInt(eci) <= 32; + return ToInt(eci) >= 0 && ToInt(eci) <= 170; } inline constexpr bool CanProcess(ECI eci) diff --git a/core/src/TextDecoder.cpp b/core/src/TextDecoder.cpp index b9835c77ad..5c75e04801 100644 --- a/core/src/TextDecoder.cpp +++ b/core/src/TextDecoder.cpp @@ -1,322 +1,53 @@ /* * Copyright 2016 Nu-book Inc. +* Copyright 2022 gitlost */ // SPDX-License-Identifier: Apache-2.0 #include "TextDecoder.h" #include "CharacterSet.h" +#include "ECI.h" #include "TextUtfEncoding.h" -#include "textcodec/Big5TextDecoder.h" -#include "textcodec/GBTextDecoder.h" -#include "textcodec/JPTextDecoder.h" -#include "textcodec/KRTextDecoder.h" +#include "ZXAlgorithms.h" +#include "zueci.h" -#include +#include namespace ZXing { -namespace Codecs { - -static const uint16_t SINGLE_BYTE_CODEPAGES[] = { - - // ISO-8859-2 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, - 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, - 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, - 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, - 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, - 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9, - - // ISO-8859-3 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFD, 0x0124, 0x00A7, 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFD, 0x017B, - 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFD, 0x017C, - 0x00C0, 0x00C1, 0x00C2, 0xFFFD, 0x00C4, 0x010A, 0x0108, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0xFFFD, 0x00E4, 0x010B, 0x0109, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9, - - // ISO-8859-4 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, - 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, - 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, - 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, - 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, - 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9, - - // ISO-8859-5 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, - 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, - 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, - 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, - 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F, - - // ISO-8859-6 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0xFFFD, 0xFFFD, 0xFFFD, 0x00A4, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x060C, 0x00AD, 0xFFFD, 0xFFFD, - 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x061B, 0xFFFD, 0xFFFD, 0xFFFD, 0x061F, - 0xFFFD, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, - 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, - 0x0650, 0x0651, 0x0652, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - - // ISO-8859-7 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x2018, 0x2019, 0x00A3, 0xFFFD, 0xFFFD, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0xFFFD, 0x2015, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, - 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, - 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD, - - // ISO-8859-8 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xFFFD, - 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2017, - 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, - 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - - // ISO-8859-9 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, - 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF, - - // ISO-8859-10 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, - 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B, - 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, - 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, - 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, - 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138, - - // ISO-8859-11 (extended with 9 CP874 codepoints in 0x80-9F range) - 0x20AC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2026, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0xFFFD, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, - 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, - 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, - 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F, - 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, - 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - - // ISO-8859-13 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, - 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, - 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, - 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, - 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019, - - // ISO-8859-14 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7, 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178, - 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56, 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61, - 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF, - - // ISO-8859-15 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF, - 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, - - // ISO-8859-16 - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B, - 0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7, 0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C, - 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A, 0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B, 0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF, - - // CP437 - 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, - 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, - 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, - 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, - 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, - 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, - - // CP1250 - 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021, 0xFFFD, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, - 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0xFFFD, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, - 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, - 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, - 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, - 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, - 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, - 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9, - - // CP1251 - 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, - 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0xFFFD, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, - 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, - 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, - 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, - 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, - 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, - - // CP1252 - 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD, - 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178, - 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, - 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, +void TextDecoder::Append(std::string& str, const uint8_t* bytes, size_t length, CharacterSet charset, bool sjisASCII) +{ + int eci = ToInt(ToECI(charset)); + const size_t str_len = str.length(); + const int bytes_len = narrow_cast(length); + constexpr unsigned int replacement = 0xFFFD; + const unsigned int flags = ZUECI_FLAG_SB_STRAIGHT_THRU | (sjisASCII ? ZUECI_FLAG_SJIS_STRAIGHT_THRU : 0); + int utf8_len; - // CP1256 - 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, - 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, - 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, - 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, - 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, - 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, - 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2, -}; + if (eci == -1) + eci = 899; // Binary + int error_number = zueci_dest_len_utf8(eci, bytes, bytes_len, replacement, flags, &utf8_len); + if (error_number >= ZUECI_ERROR) + throw std::runtime_error("zueci_dest_len_utf8 failed"); -} // Codecs + str.resize(str_len + utf8_len); // Precise length + unsigned char *utf8_buf = reinterpret_cast(str.data()) + str_len; + error_number = zueci_eci_to_utf8(eci, bytes, bytes_len, replacement, flags, utf8_buf, &utf8_len); + if (error_number >= ZUECI_ERROR) { + str.resize(str_len); + throw std::runtime_error("zueci_eci_to_utf8 failed"); + } + assert(str.length() == str_len + utf8_len); +} -void -TextDecoder::Append(std::wstring& str, const uint8_t* bytes, size_t length, CharacterSet charset) +void TextDecoder::Append(std::wstring& str, const uint8_t* bytes, size_t length, CharacterSet charset) { - switch (charset) - { - case CharacterSet::Unknown: - case CharacterSet::ISO8859_1: - case CharacterSet::ASCII: - case CharacterSet::BINARY: - { - str.append(bytes, bytes + length); - break; - } - case CharacterSet::ISO8859_2: - case CharacterSet::ISO8859_3: - case CharacterSet::ISO8859_4: - case CharacterSet::ISO8859_5: - case CharacterSet::ISO8859_6: - case CharacterSet::ISO8859_7: - case CharacterSet::ISO8859_8: - case CharacterSet::ISO8859_9: - case CharacterSet::ISO8859_10: - case CharacterSet::ISO8859_11: - case CharacterSet::ISO8859_13: - case CharacterSet::ISO8859_14: - case CharacterSet::ISO8859_15: - case CharacterSet::ISO8859_16: - case CharacterSet::Cp437: - case CharacterSet::Cp1250: - case CharacterSet::Cp1251: - case CharacterSet::Cp1252: - case CharacterSet::Cp1256: - { - str.reserve(str.length() + length); - for (size_t i = 0; i < length; ++i) { - uint8_t c = bytes[i]; - if (c < 128) - str.push_back(c); - else - str.push_back(Codecs::SINGLE_BYTE_CODEPAGES[((int)charset - (int)CharacterSet::ISO8859_2) * 128 + c - 128]); - } - break; - } - case CharacterSet::Shift_JIS: - { - std::vector buf; - JPTextDecoder::AppendShiftJIS(buf, bytes, length); - TextUtfEncoding::AppendUtf16(str, buf.data(), buf.size()); - break; - } - case CharacterSet::Big5: - { - std::vector buf; - Big5TextDecoder::AppendBig5(buf, bytes, length); - TextUtfEncoding::AppendUtf16(str, buf.data(), buf.size()); - break; - } - case CharacterSet::GB2312: - { - std::vector buf; - GBTextDecoder::AppendGB2312(buf, bytes, length); - TextUtfEncoding::AppendUtf16(str, buf.data(), buf.size()); - break; - } - case CharacterSet::GB18030: - { - std::vector buf; - GBTextDecoder::AppendGB18030(buf, bytes, length); - TextUtfEncoding::AppendUtf16(str, buf.data(), buf.size()); - break; - } - case CharacterSet::EUC_JP: - { - std::vector buf; - JPTextDecoder::AppendEUCJP(buf, bytes, length); - TextUtfEncoding::AppendUtf16(str, buf.data(), buf.size()); - break; - } - case CharacterSet::EUC_KR: - { - std::vector buf; - KRTextDecoder::AppendEucKr(buf, bytes, length); - TextUtfEncoding::AppendUtf16(str, buf.data(), buf.size()); - break; - } - case CharacterSet::UnicodeBig: - { - std::vector buf; - for (size_t i = 0; i + 1 < length; i += 2) { - buf.push_back((static_cast(bytes[i]) << 8) | bytes[i + 1]); - } - TextUtfEncoding::AppendUtf16(str, buf.data(), buf.size()); - break; - } - case CharacterSet::UTF8: - { - TextUtfEncoding::AppendUtf8(str, bytes, length); - break; - } - default: - break; - } + std::string u8str; + Append(u8str, bytes, length, charset); + str.append(TextUtfEncoding::FromUtf8(u8str)); } /** diff --git a/core/src/TextDecoder.h b/core/src/TextDecoder.h index a587a100bd..531614a779 100644 --- a/core/src/TextDecoder.h +++ b/core/src/TextDecoder.h @@ -19,6 +19,10 @@ class TextDecoder static CharacterSet DefaultEncoding(); static CharacterSet GuessEncoding(const uint8_t* bytes, size_t length, CharacterSet fallback = DefaultEncoding()); + // If `sjisASCII` set then for Shift_JIS maps ASCII directly (straight-thru), i.e. does not map ASCII backslash & tilde + // to Yen sign & overline resp. (JIS X 0201 Roman) + static void Append(std::string& str, const uint8_t* bytes, size_t length, CharacterSet charset, bool sjisASCII = true); + static void Append(std::wstring& str, const uint8_t* bytes, size_t length, CharacterSet charset); static void AppendLatin1(std::wstring& str, const std::string& latin1) { @@ -30,12 +34,6 @@ class TextDecoder auto ptr = (const uint8_t*)latin1.data(); return std::wstring(ptr, ptr + latin1.length()); } - - static std::wstring ToUnicode(const std::string& str, CharacterSet charset) { - std::wstring r; - Append(r, (const uint8_t*)str.data(), str.length(), charset); - return r; - } }; } // ZXing diff --git a/core/src/TextEncoder.cpp b/core/src/TextEncoder.cpp index 5ddde516bf..246b0a4a4b 100644 --- a/core/src/TextEncoder.cpp +++ b/core/src/TextEncoder.cpp @@ -6,250 +6,45 @@ #include "TextEncoder.h" #include "CharacterSet.h" +#include "ECI.h" #include "TextUtfEncoding.h" #include "ZXAlgorithms.h" -#include "textcodec/Big5TextEncoder.h" -#include "textcodec/GBTextEncoder.h" -#include "textcodec/JPTextEncoder.h" -#include "textcodec/KRTextEncoder.h" +#include "zueci.h" -#include -#include -#include #include namespace ZXing { -namespace { - -struct MapEntry +void TextEncoder::GetBytes(const std::string& str, CharacterSet charset, std::string& bytes) { - uint16_t unicode; - uint8_t count; - uint8_t charcode; -}; - -inline bool operator<(const uint16_t& val, const MapEntry& b) { return val < b.unicode; } - -static const MapEntry latin2Mapping[45] = { - {0x0080,33, 0}, {0x00a4, 1, 36}, {0x00a7, 2, 39}, {0x00ad, 1, 45}, {0x00b0, 1, 48}, {0x00b4, 1, 52}, {0x00b8, 1, 56}, {0x00c1, 2, 65}, - {0x00c4, 1, 68}, {0x00c7, 1, 71}, {0x00c9, 1, 73}, {0x00cb, 1, 75}, {0x00cd, 2, 77}, {0x00d3, 2, 83}, {0x00d6, 2, 86}, {0x00da, 1, 90}, - {0x00dc, 2, 92}, {0x00df, 1, 95}, {0x00e1, 2, 97}, {0x00e4, 1,100}, {0x00e7, 1,103}, {0x00e9, 1,105}, {0x00eb, 1,107}, {0x00ed, 2,109}, - {0x00f3, 2,115}, {0x00f6, 2,118}, {0x00fa, 1,122}, {0x00fc, 2,124}, {0x0102, 6, 67}, {0x010c, 6, 72}, {0x0118, 4, 74}, {0x0139, 2, 69}, - {0x013d, 2, 37}, {0x0141, 4, 35}, {0x0147, 2, 82}, {0x0150, 2, 85}, {0x0154, 2, 64}, {0x0158, 4, 88}, {0x015e, 8, 42}, {0x016e, 4, 89}, - {0x0179, 6, 44}, {0x02c7, 1, 55}, {0x02d8, 2, 34}, {0x02db, 1, 50}, {0x02dd, 1, 61}, -}; - -static const MapEntry latin3Mapping[30] = { - {0x0080,33, 0}, {0x00a3, 2, 35}, {0x00a7, 2, 39}, {0x00ad, 1, 45}, {0x00b0, 1, 48}, {0x00b2, 4, 50}, {0x00b7, 2, 55}, {0x00bd, 1, 61}, - {0x00c0, 3, 64}, {0x00c4, 1, 68}, {0x00c7, 9, 71}, {0x00d1, 4, 81}, {0x00d6, 2, 86}, {0x00d9, 4, 89}, {0x00df, 4, 95}, {0x00e4, 1,100}, - {0x00e7, 9,103}, {0x00f1, 4,113}, {0x00f6, 2,118}, {0x00f9, 4,121}, {0x0108, 4, 70}, {0x011c, 6, 88}, {0x0124, 4, 38}, {0x0130, 2, 41}, - {0x0134, 2, 44}, {0x015c, 4, 94}, {0x016c, 2, 93}, {0x017b, 2, 47}, {0x02d8, 2, 34}, {0xfffd, 1,112}, -}; - -static const MapEntry latin4Mapping[40] = { - {0x0080,33, 0}, {0x00a4, 1, 36}, {0x00a7, 2, 39}, {0x00ad, 1, 45}, {0x00af, 2, 47}, {0x00b4, 1, 52}, {0x00b8, 1, 56}, {0x00c1, 6, 65}, - {0x00c9, 1, 73}, {0x00cb, 1, 75}, {0x00cd, 2, 77}, {0x00d4, 5, 84}, {0x00da, 3, 90}, {0x00df, 1, 95}, {0x00e1, 6, 97}, {0x00e9, 1,105}, - {0x00eb, 1,107}, {0x00ed, 2,109}, {0x00f4, 5,116}, {0x00fa, 3,122}, {0x0100, 2, 64}, {0x0104, 2, 33}, {0x010c, 2, 72}, {0x0110, 4, 80}, - {0x0116, 4, 76}, {0x0122, 2, 43}, {0x0128, 4, 37}, {0x012e, 2, 71}, {0x0136, 3, 83}, {0x013b, 2, 38}, {0x0145, 2, 81}, {0x014a, 4, 61}, - {0x0156, 2, 35}, {0x0160, 2, 41}, {0x0166, 6, 44}, {0x0172, 2, 89}, {0x017d, 2, 46}, {0x02c7, 1, 55}, {0x02d9, 1,127}, {0x02db, 1, 50}, -}; - -static const MapEntry latin5Mapping[8] = { - {0x0080,33, 0}, {0x00a7, 1,125}, {0x00ad, 1, 45}, {0x0401,12, 33}, {0x040e,66, 46}, {0x0451,12,113}, {0x045e, 2,126}, {0x2116, 1,112}, -}; - -static const MapEntry latin6Mapping[9] = { - {0x0080,33, 0}, {0x00a4, 1, 36}, {0x00ad, 1, 45}, {0x060c, 1, 44}, {0x061b, 1, 59}, {0x061f, 1, 63}, {0x0621,26, 65}, {0x0640,19, 96}, - {0xfffd, 1,127}, -}; - -static const MapEntry latin7Mapping[16] = { - {0x0080,33, 0}, {0x00a3, 1, 35}, {0x00a6, 4, 38}, {0x00ab, 3, 43}, {0x00b0, 4, 48}, {0x00b7, 1, 55}, {0x00bb, 1, 59}, {0x00bd, 1, 61}, - {0x0384, 3, 52}, {0x0388, 3, 56}, {0x038c, 1, 60}, {0x038e,20, 62}, {0x03a3,44, 83}, {0x2015, 1, 47}, {0x2018, 2, 33}, {0xfffd, 1,127}, -}; - -static const MapEntry latin8Mapping[11] = { - {0x0080,33, 0}, {0x00a2, 8, 34}, {0x00ab, 4, 43}, {0x00b0,10, 48}, {0x00bb, 4, 59}, {0x00d7, 1, 42}, {0x00f7, 1, 58}, {0x05d0,27, 96}, - {0x2017, 1, 95}, {0x203e, 1, 47}, {0xfffd, 1,127}, -}; - -static const MapEntry latin9Mapping[8] = { - {0x0080,80, 0}, {0x00d1,12, 81}, {0x00df,17, 95}, {0x00f1,12,113}, {0x00ff, 1,127}, {0x011e, 2, 80}, {0x0130, 2, 93}, {0x015e, 2, 94}, -}; - -static const MapEntry latin10Mapping[36] = { - {0x0080,33, 0}, {0x00a7, 1, 39}, {0x00ad, 1, 45}, {0x00b0, 1, 48}, {0x00b7, 1, 55}, {0x00c1, 6, 65}, {0x00c9, 1, 73}, {0x00cb, 1, 75}, - {0x00cd, 4, 77}, {0x00d3, 4, 83}, {0x00d8, 1, 88}, {0x00da, 6, 90}, {0x00e1, 6, 97}, {0x00e9, 1,105}, {0x00eb, 1,107}, {0x00ed, 4,109}, - {0x00f3, 4,115}, {0x00f8, 1,120}, {0x00fa, 5,122}, {0x0100, 2, 64}, {0x0104, 2, 33}, {0x010c, 2, 72}, {0x0110, 4, 41}, {0x0116, 4, 76}, - {0x0122, 2, 35}, {0x0128, 4, 37}, {0x012e, 2, 71}, {0x0136, 3, 38}, {0x013b, 2, 40}, {0x0145, 2, 81}, {0x014a, 4, 47}, {0x0160, 2, 42}, - {0x0166, 6, 43}, {0x0172, 2, 89}, {0x017d, 2, 44}, {0x2015, 1, 61}, -}; - -static const MapEntry latin11Mapping[9] = { - {0x0e01,58, 33}, {0x0e3f,29, 95}, {0x2013, 2, 22}, {0x2018, 2, 17}, {0x201c, 2, 19}, {0x2022, 1, 21}, {0x2026, 1, 5}, {0x20ac, 1, 0}, - {0xfffd, 1,127}, -}; - -static const MapEntry latin13Mapping[40] = { - {0x0080,33, 0}, {0x00a2, 3, 34}, {0x00a6, 2, 38}, {0x00a9, 1, 41}, {0x00ab, 4, 43}, {0x00b0, 4, 48}, {0x00b5, 3, 53}, {0x00b9, 1, 57}, - {0x00bb, 4, 59}, {0x00c4, 3, 68}, {0x00c9, 1, 73}, {0x00d3, 1, 83}, {0x00d5, 4, 85}, {0x00dc, 1, 92}, {0x00df, 1, 95}, {0x00e4, 3,100}, - {0x00e9, 1,105}, {0x00f3, 1,115}, {0x00f5, 4,117}, {0x00fc, 1,124}, {0x0100, 2, 66}, {0x0104, 4, 64}, {0x010c, 2, 72}, {0x0112, 2, 71}, - {0x0116, 4, 75}, {0x0122, 2, 76}, {0x012a, 2, 78}, {0x012e, 2, 65}, {0x0136, 2, 77}, {0x013b, 2, 79}, {0x0141, 6, 89}, {0x014c, 2, 84}, - {0x0156, 2, 42}, {0x015a, 2, 90}, {0x0160, 2, 80}, {0x016a, 2, 91}, {0x0172, 2, 88}, {0x0179, 6, 74}, {0x2019, 1,127}, {0x201c, 3, 52}, -}; - -static const MapEntry latin14Mapping[25] = { - {0x0080,33, 0}, {0x00a3, 1, 35}, {0x00a7, 1, 39}, {0x00a9, 1, 41}, {0x00ad, 2, 45}, {0x00b6, 1, 54}, {0x00c0,16, 64}, {0x00d1, 6, 81}, - {0x00d8, 6, 88}, {0x00df,17, 95}, {0x00f1, 6,113}, {0x00f8, 6,120}, {0x00ff, 1,127}, {0x010a, 2, 36}, {0x0120, 2, 50}, {0x0174, 5, 80}, - {0x1e02, 2, 33}, {0x1e0a, 2, 38}, {0x1e1e, 2, 48}, {0x1e40, 2, 52}, {0x1e56, 2, 55}, {0x1e60, 2, 59}, {0x1e6a, 2, 87}, {0x1e80, 6, 40}, - {0x1ef2, 2, 44}, -}; + int eci = ToInt(ToECI(charset)); + const int str_len = narrow_cast(str.length()); + int eci_len; -static const MapEntry latin15Mapping[12] = { - {0x0080,36, 0}, {0x00a5, 1, 37}, {0x00a7, 1, 39}, {0x00a9,11, 41}, {0x00b5, 3, 53}, {0x00b9, 3, 57}, {0x00bf,65, 63}, {0x0152, 2, 60}, - {0x0160, 2, 38}, {0x0178, 1, 62}, {0x017d, 2, 52}, {0x20ac, 1, 36}, -}; + if (eci == -1) + eci = 899; // Binary -static const MapEntry latin16Mapping[34] = { - {0x0080,33, 0}, {0x00a7, 1, 39}, {0x00a9, 1, 41}, {0x00ab, 1, 43}, {0x00ad, 1, 45}, {0x00b0, 2, 48}, {0x00b6, 2, 54}, {0x00bb, 1, 59}, - {0x00c0, 3, 64}, {0x00c4, 1, 68}, {0x00c6,10, 70}, {0x00d2, 3, 82}, {0x00d6, 1, 86}, {0x00d9, 4, 89}, {0x00df, 4, 95}, {0x00e4, 1,100}, - {0x00e6,10,102}, {0x00f2, 3,114}, {0x00f6, 1,118}, {0x00f9, 4,121}, {0x00ff, 1,127}, {0x0102, 6, 67}, {0x010c, 2, 50}, {0x0110, 2, 80}, - {0x0118, 2, 93}, {0x0141, 4, 35}, {0x0150, 4, 85}, {0x015a, 2, 87}, {0x0160, 2, 38}, {0x0170, 2, 88}, {0x0178, 7, 62}, {0x0218, 4, 42}, - {0x201d, 2, 53}, {0x20ac, 1, 36}, -}; - -static const MapEntry cp437Mapping[58] = { - {0x00a0, 4,127}, {0x00a5, 1, 29}, {0x00aa, 3, 38}, {0x00b0, 3,120}, {0x00b5, 1,102}, {0x00b7, 1,122}, {0x00ba, 4, 39}, {0x00bf, 1, 40}, - {0x00c4, 4, 14}, {0x00c9, 1, 16}, {0x00d1, 1, 37}, {0x00d6, 1, 25}, {0x00dc, 1, 26}, {0x00df, 4, 97}, {0x00e4,12, 4}, {0x00f1, 4, 36}, - {0x00f6, 2, 20}, {0x00f9, 4, 23}, {0x00ff, 1, 24}, {0x0192, 1, 31}, {0x0393, 1, 98}, {0x0398, 1,105}, {0x03a3, 1,100}, {0x03a6, 1,104}, - {0x03a9, 1,106}, {0x03b1, 1, 96}, {0x03b4, 2,107}, {0x03c0, 1, 99}, {0x03c3, 2,101}, {0x03c6, 1,109}, {0x207f, 1,124}, {0x20a7, 1, 30}, - {0x2219, 2,121}, {0x221e, 1,108}, {0x2229, 1,111}, {0x2248, 1,119}, {0x2261, 1,112}, {0x2264, 2,115}, {0x2310, 1, 41}, {0x2320, 2,116}, - {0x2500, 1, 68}, {0x2502, 1, 51}, {0x250c, 1, 90}, {0x2510, 1, 63}, {0x2514, 1, 64}, {0x2518, 1, 89}, {0x251c, 1, 67}, {0x2524, 1, 52}, - {0x252c, 1, 66}, {0x2534, 1, 65}, {0x253c, 1, 69}, {0x2550,29, 77}, {0x2580, 1, 95}, {0x2584, 1, 92}, {0x2588, 1, 91}, {0x258c, 1, 93}, - {0x2590, 4, 94}, {0x25a0, 1,126}, -}; - -static const MapEntry cp1250Mapping[55] = { - {0x00a0, 1, 32}, {0x00a4, 1, 36}, {0x00a6, 4, 38}, {0x00ab, 4, 43}, {0x00b0, 2, 48}, {0x00b4, 5, 52}, {0x00bb, 1, 59}, {0x00c1, 2, 65}, - {0x00c4, 1, 68}, {0x00c7, 1, 71}, {0x00c9, 1, 73}, {0x00cb, 1, 75}, {0x00cd, 2, 77}, {0x00d3, 2, 83}, {0x00d6, 2, 86}, {0x00da, 1, 90}, - {0x00dc, 2, 92}, {0x00df, 1, 95}, {0x00e1, 2, 97}, {0x00e4, 1,100}, {0x00e7, 1,103}, {0x00e9, 1,105}, {0x00eb, 1,107}, {0x00ed, 2,109}, - {0x00f3, 2,115}, {0x00f6, 2,118}, {0x00fa, 1,122}, {0x00fc, 2,124}, {0x0102, 6, 67}, {0x010c, 6, 72}, {0x0118, 4, 74}, {0x0139, 2, 69}, - {0x013d, 2, 60}, {0x0141, 4, 35}, {0x0147, 2, 82}, {0x0150, 2, 85}, {0x0154, 2, 64}, {0x0158, 4, 88}, {0x015e, 8, 42}, {0x016e, 4, 89}, - {0x0179, 6, 15}, {0x02c7, 1, 33}, {0x02d8, 2, 34}, {0x02db, 1, 50}, {0x02dd, 1, 61}, {0x2013, 2, 22}, {0x2018, 3, 17}, {0x201c, 3, 19}, - {0x2020, 3, 6}, {0x2026, 1, 5}, {0x2030, 1, 9}, {0x2039, 2, 11}, {0x20ac, 1, 0}, {0x2122, 1, 25}, {0xfffd, 1, 24}, -}; - -static const MapEntry cp1251Mapping[24] = { - {0x00a0, 1, 32}, {0x00a4, 1, 36}, {0x00a6, 2, 38}, {0x00a9, 1, 41}, {0x00ab, 4, 43}, {0x00b0, 2, 48}, {0x00b5, 3, 53}, {0x00bb, 1, 59}, - {0x0401,12, 40}, {0x040e,66, 33}, {0x0451,12, 56}, {0x045e, 2, 34}, {0x0490, 2, 37}, {0x2013, 2, 22}, {0x2018, 3, 17}, {0x201c, 3, 19}, - {0x2020, 3, 6}, {0x2026, 1, 5}, {0x2030, 1, 9}, {0x2039, 2, 11}, {0x20ac, 1, 8}, {0x2116, 1, 57}, {0x2122, 1, 25}, {0xfffd, 1, 24}, -}; - -static const MapEntry cp1252Mapping[18] = { - {0x00a0,96, 32}, {0x0152, 2, 12}, {0x0160, 2, 10}, {0x0178, 1, 31}, {0x017d, 2, 14}, {0x0192, 1, 3}, {0x02c6, 1, 8}, {0x02dc, 1, 24}, - {0x2013, 2, 22}, {0x2018, 3, 17}, {0x201c, 3, 19}, {0x2020, 3, 6}, {0x2026, 1, 5}, {0x2030, 1, 9}, {0x2039, 2, 11}, {0x20ac, 1, 0}, - {0x2122, 1, 25}, {0xfffd, 1, 29}, -}; + bytes.clear(); -static const MapEntry cp1256Mapping[43] = { - {0x00a0, 1, 32}, {0x00a2, 8, 34}, {0x00ab,15, 43}, {0x00bb, 4, 59}, {0x00d7, 1, 87}, {0x00e0, 1, 96}, {0x00e2, 1, 98}, {0x00e7, 5,103}, - {0x00ee, 2,110}, {0x00f4, 1,116}, {0x00f7, 1,119}, {0x00f9, 1,121}, {0x00fb, 2,123}, {0x0152, 2, 12}, {0x0192, 1, 3}, {0x02c6, 1, 8}, - {0x060c, 1, 33}, {0x061b, 1, 58}, {0x061f, 1, 63}, {0x0621,26, 65}, {0x0640,19, 92}, {0x0679, 1, 10}, {0x067e, 1, 1}, {0x0686, 1, 13}, - {0x0688, 1, 15}, {0x0691, 1, 26}, {0x0698, 1, 14}, {0x06a9, 1, 24}, {0x06af, 1, 16}, {0x06ba, 1, 31}, {0x06be, 1, 42}, {0x06c1, 1, 64}, - {0x06d2, 1,127}, {0x200c, 4, 29}, {0x2013, 2, 22}, {0x2018, 3, 17}, {0x201c, 3, 19}, {0x2020, 3, 6}, {0x2026, 1, 5}, {0x2030, 1, 9}, - {0x2039, 2, 11}, {0x20ac, 1, 0}, {0x2122, 1, 25}, -}; + int error_number = zueci_dest_len_eci(eci, reinterpret_cast(str.data()), str_len, &eci_len); + if (error_number >= ZUECI_ERROR) // Shouldn't happen + throw std::logic_error("Internal error `zueci_dest_len_eci()`"); + bytes.resize(eci_len); // Sufficient but approximate length -static uint8_t unicodeToCharcode(uint16_t unicode, const MapEntry* entries, size_t entryCount) -{ - auto it = std::upper_bound(entries, entries + entryCount, unicode); - if (it != entries) - { - --it; - if (unicode < it->unicode + it->count) - { - return it->charcode + (unicode - it->unicode) + 128; - } + error_number = zueci_utf8_to_eci(eci, reinterpret_cast(str.data()), str_len, + reinterpret_cast(bytes.data()), &eci_len); + if (error_number >= ZUECI_ERROR) { + bytes.clear(); + throw std::invalid_argument("Unexpected charcode"); } - throw std::invalid_argument("Unexpected charcode"); -} -static void mapFromUnicode(const std::wstring& str, const MapEntry* entries, size_t entryCount, std::string& bytes) -{ - bytes.reserve(str.length()); - for (wchar_t c : str) { - if (c < 0x80) { - bytes.push_back(static_cast(c)); - } - else { - bytes.push_back(static_cast(unicodeToCharcode(c, entries, entryCount))); - } - } + bytes.resize(eci_len); // Actual length } -#define CONVERT_USING(table, str, bytes) mapFromUnicode(str, table, Size(table), bytes) - -} // anonymous - -void -TextEncoder::GetBytes(const std::wstring& str, CharacterSet charset, std::string& bytes) +void TextEncoder::GetBytes(const std::wstring& str, CharacterSet charset, std::string& bytes) { - bytes.clear(); - - switch (charset) - { - case CharacterSet::Unknown: - case CharacterSet::ISO8859_1: - case CharacterSet::BINARY: - bytes.reserve(str.length()); - for (wchar_t c : str) { - if (c <= 0xff) { - bytes.push_back(static_cast(c)); - } else { - throw std::invalid_argument("Unexpected charcode"); - } - } - break; - case CharacterSet::ASCII: - bytes.reserve(str.length()); - for (wchar_t c : str) { - if (c < 0x80) { - bytes.push_back(static_cast(c)); - } else { - throw std::invalid_argument("Unexpected charcode"); - } - } - break; - case CharacterSet::ISO8859_2: CONVERT_USING(latin2Mapping, str, bytes); break; - case CharacterSet::ISO8859_3: CONVERT_USING(latin3Mapping, str, bytes); break; - case CharacterSet::ISO8859_4: CONVERT_USING(latin4Mapping, str, bytes); break; - case CharacterSet::ISO8859_5: CONVERT_USING(latin5Mapping, str, bytes); break; - case CharacterSet::ISO8859_6: CONVERT_USING(latin6Mapping, str, bytes); break; - case CharacterSet::ISO8859_7: CONVERT_USING(latin7Mapping, str, bytes); break; - case CharacterSet::ISO8859_8: CONVERT_USING(latin8Mapping, str, bytes); break; - case CharacterSet::ISO8859_9: CONVERT_USING(latin9Mapping, str, bytes); break; - case CharacterSet::ISO8859_10: CONVERT_USING(latin10Mapping, str, bytes); break; - case CharacterSet::ISO8859_11: CONVERT_USING(latin11Mapping, str, bytes); break; - case CharacterSet::ISO8859_13: CONVERT_USING(latin13Mapping, str, bytes); break; - case CharacterSet::ISO8859_14: CONVERT_USING(latin14Mapping, str, bytes); break; - case CharacterSet::ISO8859_15: CONVERT_USING(latin15Mapping, str, bytes); break; - case CharacterSet::ISO8859_16: CONVERT_USING(latin16Mapping, str, bytes); break; - case CharacterSet::Cp437: CONVERT_USING(cp437Mapping, str, bytes); break; - case CharacterSet::Cp1250: CONVERT_USING(cp1250Mapping, str, bytes); break; - case CharacterSet::Cp1251: CONVERT_USING(cp1251Mapping, str, bytes); break; - case CharacterSet::Cp1252: CONVERT_USING(cp1252Mapping, str, bytes); break; - case CharacterSet::Cp1256: CONVERT_USING(cp1256Mapping, str, bytes); break; - case CharacterSet::Shift_JIS: JPTextEncoder::EncodeShiftJIS(str, bytes); break; - case CharacterSet::Big5: Big5TextEncoder::EncodeBig5(str, bytes); break; - case CharacterSet::GB2312: GBTextEncoder::EncodeGB2312(str, bytes); break; - case CharacterSet::GB18030: GBTextEncoder::EncodeGB18030(str, bytes); break; - case CharacterSet::EUC_JP: JPTextEncoder::EncodeEUCJP(str, bytes); break; - case CharacterSet::EUC_KR: KRTextEncoder::EncodeEucKr(str, bytes); break; - case CharacterSet::UTF8: TextUtfEncoding::ToUtf8(str, bytes); break; - default: break; - } + GetBytes(TextUtfEncoding::ToUtf8(str), charset, bytes); } } // ZXing diff --git a/core/src/TextEncoder.h b/core/src/TextEncoder.h index df91a3ff58..15c8567158 100644 --- a/core/src/TextEncoder.h +++ b/core/src/TextEncoder.h @@ -13,8 +13,14 @@ namespace ZXing { class TextEncoder { + static void GetBytes(const std::string& str, CharacterSet charset, std::string& bytes); static void GetBytes(const std::wstring& str, CharacterSet charset, std::string& bytes); public: + static std::string FromUnicode(const std::string& str, CharacterSet charset) { + std::string r; + GetBytes(str, charset, r); + return r; + } static std::string FromUnicode(const std::wstring& str, CharacterSet charset) { std::string r; GetBytes(str, charset, r); diff --git a/core/src/textcodec/Big5MapTable.cpp b/core/src/textcodec/Big5MapTable.cpp deleted file mode 100644 index ad80c85882..0000000000 --- a/core/src/textcodec/Big5MapTable.cpp +++ /dev/null @@ -1,686 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Big5MapTable.h" - -#include - -// Big 5 to Unicode mapping tables. -// Tables are in sorted order on X(all table together) & Y(individually) -static const B5Map b5_8140_to_uc_map[2041] = { - {0x8140,0xeeb8}, {0x8141,0xeeb9}, {0x8142,0xeeba}, {0x8143,0xeebb}, {0x8144,0xeebc}, {0x8145,0xeebd}, {0x8146,0xeebe}, {0x8147,0xeebf}, {0x8148,0xeec0}, {0x8149,0xeec1}, - {0x814a,0xeec2}, {0x814b,0xeec3}, {0x814c,0xeec4}, {0x814d,0xeec5}, {0x814e,0xeec6}, {0x814f,0xeec7}, {0x8150,0xeec8}, {0x8151,0xeec9}, {0x8152,0xeeca}, {0x8153,0xeecb}, - {0x8154,0xeecc}, {0x8155,0xeecd}, {0x8156,0xeece}, {0x8157,0xeecf}, {0x8158,0xeed0}, {0x8159,0xeed1}, {0x815a,0xeed2}, {0x815b,0xeed3}, {0x815c,0xeed4}, {0x815d,0xeed5}, - {0x815e,0xeed6}, {0x815f,0xeed7}, {0x8160,0xeed8}, {0x8161,0xeed9}, {0x8162,0xeeda}, {0x8163,0xeedb}, {0x8164,0xeedc}, {0x8165,0xeedd}, {0x8166,0xeede}, {0x8167,0xeedf}, - {0x8168,0xeee0}, {0x8169,0xeee1}, {0x816a,0xeee2}, {0x816b,0xeee3}, {0x816c,0xeee4}, {0x816d,0xeee5}, {0x816e,0xeee6}, {0x816f,0xeee7}, {0x8170,0xeee8}, {0x8171,0xeee9}, - {0x8172,0xeeea}, {0x8173,0xeeeb}, {0x8174,0xeeec}, {0x8175,0xeeed}, {0x8176,0xeeee}, {0x8177,0xeeef}, {0x8178,0xeef0}, {0x8179,0xeef1}, {0x817a,0xeef2}, {0x817b,0xeef3}, - {0x817c,0xeef4}, {0x817d,0xeef5}, {0x817e,0xeef6}, {0x81a1,0xeef7}, {0x81a2,0xeef8}, {0x81a3,0xeef9}, {0x81a4,0xeefa}, {0x81a5,0xeefb}, {0x81a6,0xeefc}, {0x81a7,0xeefd}, - {0x81a8,0xeefe}, {0x81a9,0xeeff}, {0x81aa,0xef00}, {0x81ab,0xef01}, {0x81ac,0xef02}, {0x81ad,0xef03}, {0x81ae,0xef04}, {0x81af,0xef05}, {0x81b0,0xef06}, {0x81b1,0xef07}, - {0x81b2,0xef08}, {0x81b3,0xef09}, {0x81b4,0xef0a}, {0x81b5,0xef0b}, {0x81b6,0xef0c}, {0x81b7,0xef0d}, {0x81b8,0xef0e}, {0x81b9,0xef0f}, {0x81ba,0xef10}, {0x81bb,0xef11}, - {0x81bc,0xef12}, {0x81bd,0xef13}, {0x81be,0xef14}, {0x81bf,0xef15}, {0x81c0,0xef16}, {0x81c1,0xef17}, {0x81c2,0xef18}, {0x81c3,0xef19}, {0x81c4,0xef1a}, {0x81c5,0xef1b}, - {0x81c6,0xef1c}, {0x81c7,0xef1d}, {0x81c8,0xef1e}, {0x81c9,0xef1f}, {0x81ca,0xef20}, {0x81cb,0xef21}, {0x81cc,0xef22}, {0x81cd,0xef23}, {0x81ce,0xef24}, {0x81cf,0xef25}, - {0x81d0,0xef26}, {0x81d1,0xef27}, {0x81d2,0xef28}, {0x81d3,0xef29}, {0x81d4,0xef2a}, {0x81d5,0xef2b}, {0x81d6,0xef2c}, {0x81d7,0xef2d}, {0x81d8,0xef2e}, {0x81d9,0xef2f}, - {0x81da,0xef30}, {0x81db,0xef31}, {0x81dc,0xef32}, {0x81dd,0xef33}, {0x81de,0xef34}, {0x81df,0xef35}, {0x81e0,0xef36}, {0x81e1,0xef37}, {0x81e2,0xef38}, {0x81e3,0xef39}, - {0x81e4,0xef3a}, {0x81e5,0xef3b}, {0x81e6,0xef3c}, {0x81e7,0xef3d}, {0x81e8,0xef3e}, {0x81e9,0xef3f}, {0x81ea,0xef40}, {0x81eb,0xef41}, {0x81ec,0xef42}, {0x81ed,0xef43}, - {0x81ee,0xef44}, {0x81ef,0xef45}, {0x81f0,0xef46}, {0x81f1,0xef47}, {0x81f2,0xef48}, {0x81f3,0xef49}, {0x81f4,0xef4a}, {0x81f5,0xef4b}, {0x81f6,0xef4c}, {0x81f7,0xef4d}, - {0x81f8,0xef4e}, {0x81f9,0xef4f}, {0x81fa,0xef50}, {0x81fb,0xef51}, {0x81fc,0xef52}, {0x81fd,0xef53}, {0x81fe,0xef54}, {0x8240,0xef55}, {0x8241,0xef56}, {0x8242,0xef57}, - {0x8243,0xef58}, {0x8244,0xef59}, {0x8245,0xef5a}, {0x8246,0xef5b}, {0x8247,0xef5c}, {0x8248,0xef5d}, {0x8249,0xef5e}, {0x824a,0xef5f}, {0x824b,0xef60}, {0x824c,0xef61}, - {0x824d,0xef62}, {0x824e,0xef63}, {0x824f,0xef64}, {0x8250,0xef65}, {0x8251,0xef66}, {0x8252,0xef67}, {0x8253,0xef68}, {0x8254,0xef69}, {0x8255,0xef6a}, {0x8256,0xef6b}, - {0x8257,0xef6c}, {0x8258,0xef6d}, {0x8259,0xef6e}, {0x825a,0xef6f}, {0x825b,0xef70}, {0x825c,0xef71}, {0x825d,0xef72}, {0x825e,0xef73}, {0x825f,0xef74}, {0x8260,0xef75}, - {0x8261,0xef76}, {0x8262,0xef77}, {0x8263,0xef78}, {0x8264,0xef79}, {0x8265,0xef7a}, {0x8266,0xef7b}, {0x8267,0xef7c}, {0x8268,0xef7d}, {0x8269,0xef7e}, {0x826a,0xef7f}, - {0x826b,0xef80}, {0x826c,0xef81}, {0x826d,0xef82}, {0x826e,0xef83}, {0x826f,0xef84}, {0x8270,0xef85}, {0x8271,0xef86}, {0x8272,0xef87}, {0x8273,0xef88}, {0x8274,0xef89}, - {0x8275,0xef8a}, {0x8276,0xef8b}, {0x8277,0xef8c}, {0x8278,0xef8d}, {0x8279,0xef8e}, {0x827a,0xef8f}, {0x827b,0xef90}, {0x827c,0xef91}, {0x827d,0xef92}, {0x827e,0xef93}, - {0x82a1,0xef94}, {0x82a2,0xef95}, {0x82a3,0xef96}, {0x82a4,0xef97}, {0x82a5,0xef98}, {0x82a6,0xef99}, {0x82a7,0xef9a}, {0x82a8,0xef9b}, {0x82a9,0xef9c}, {0x82aa,0xef9d}, - {0x82ab,0xef9e}, {0x82ac,0xef9f}, {0x82ad,0xefa0}, {0x82ae,0xefa1}, {0x82af,0xefa2}, {0x82b0,0xefa3}, {0x82b1,0xefa4}, {0x82b2,0xefa5}, {0x82b3,0xefa6}, {0x82b4,0xefa7}, - {0x82b5,0xefa8}, {0x82b6,0xefa9}, {0x82b7,0xefaa}, {0x82b8,0xefab}, {0x82b9,0xefac}, {0x82ba,0xefad}, {0x82bb,0xefae}, {0x82bc,0xefaf}, {0x82bd,0xefb0}, {0x82be,0xefb1}, - {0x82bf,0xefb2}, {0x82c0,0xefb3}, {0x82c1,0xefb4}, {0x82c2,0xefb5}, {0x82c3,0xefb6}, {0x82c4,0xefb7}, {0x82c5,0xefb8}, {0x82c6,0xefb9}, {0x82c7,0xefba}, {0x82c8,0xefbb}, - {0x82c9,0xefbc}, {0x82ca,0xefbd}, {0x82cb,0xefbe}, {0x82cc,0xefbf}, {0x82cd,0xefc0}, {0x82ce,0xefc1}, {0x82cf,0xefc2}, {0x82d0,0xefc3}, {0x82d1,0xefc4}, {0x82d2,0xefc5}, - {0x82d3,0xefc6}, {0x82d4,0xefc7}, {0x82d5,0xefc8}, {0x82d6,0xefc9}, {0x82d7,0xefca}, {0x82d8,0xefcb}, {0x82d9,0xefcc}, {0x82da,0xefcd}, {0x82db,0xefce}, {0x82dc,0xefcf}, - {0x82dd,0xefd0}, {0x82de,0xefd1}, {0x82df,0xefd2}, {0x82e0,0xefd3}, {0x82e1,0xefd4}, {0x82e2,0xefd5}, {0x82e3,0xefd6}, {0x82e4,0xefd7}, {0x82e5,0xefd8}, {0x82e6,0xefd9}, - {0x82e7,0xefda}, {0x82e8,0xefdb}, {0x82e9,0xefdc}, {0x82ea,0xefdd}, {0x82eb,0xefde}, {0x82ec,0xefdf}, {0x82ed,0xefe0}, {0x82ee,0xefe1}, {0x82ef,0xefe2}, {0x82f0,0xefe3}, - {0x82f1,0xefe4}, {0x82f2,0xefe5}, {0x82f3,0xefe6}, {0x82f4,0xefe7}, {0x82f5,0xefe8}, {0x82f6,0xefe9}, {0x82f7,0xefea}, {0x82f8,0xefeb}, {0x82f9,0xefec}, {0x82fa,0xefed}, - {0x82fb,0xefee}, {0x82fc,0xefef}, {0x82fd,0xeff0}, {0x82fe,0xeff1}, {0x8340,0xeff2}, {0x8341,0xeff3}, {0x8342,0xeff4}, {0x8343,0xeff5}, {0x8344,0xeff6}, {0x8345,0xeff7}, - {0x8346,0xeff8}, {0x8347,0xeff9}, {0x8348,0xeffa}, {0x8349,0xeffb}, {0x834a,0xeffc}, {0x834b,0xeffd}, {0x834c,0xeffe}, {0x834d,0xefff}, {0x834e,0xf000}, {0x834f,0xf001}, - {0x8350,0xf002}, {0x8351,0xf003}, {0x8352,0xf004}, {0x8353,0xf005}, {0x8354,0xf006}, {0x8355,0xf007}, {0x8356,0xf008}, {0x8357,0xf009}, {0x8358,0xf00a}, {0x8359,0xf00b}, - {0x835a,0xf00c}, {0x835b,0xf00d}, {0x835c,0xf00e}, {0x835d,0xf00f}, {0x835e,0xf010}, {0x835f,0xf011}, {0x8360,0xf012}, {0x8361,0xf013}, {0x8362,0xf014}, {0x8363,0xf015}, - {0x8364,0xf016}, {0x8365,0xf017}, {0x8366,0xf018}, {0x8367,0xf019}, {0x8368,0xf01a}, {0x8369,0xf01b}, {0x836a,0xf01c}, {0x836b,0xf01d}, {0x836c,0xf01e}, {0x836d,0xf01f}, - {0x836e,0xf020}, {0x836f,0xf021}, {0x8370,0xf022}, {0x8371,0xf023}, {0x8372,0xf024}, {0x8373,0xf025}, {0x8374,0xf026}, {0x8375,0xf027}, {0x8376,0xf028}, {0x8377,0xf029}, - {0x8378,0xf02a}, {0x8379,0xf02b}, {0x837a,0xf02c}, {0x837b,0xf02d}, {0x837c,0xf02e}, {0x837d,0xf02f}, {0x837e,0xf030}, {0x83a1,0xf031}, {0x83a2,0xf032}, {0x83a3,0xf033}, - {0x83a4,0xf034}, {0x83a5,0xf035}, {0x83a6,0xf036}, {0x83a7,0xf037}, {0x83a8,0xf038}, {0x83a9,0xf039}, {0x83aa,0xf03a}, {0x83ab,0xf03b}, {0x83ac,0xf03c}, {0x83ad,0xf03d}, - {0x83ae,0xf03e}, {0x83af,0xf03f}, {0x83b0,0xf040}, {0x83b1,0xf041}, {0x83b2,0xf042}, {0x83b3,0xf043}, {0x83b4,0xf044}, {0x83b5,0xf045}, {0x83b6,0xf046}, {0x83b7,0xf047}, - {0x83b8,0xf048}, {0x83b9,0xf049}, {0x83ba,0xf04a}, {0x83bb,0xf04b}, {0x83bc,0xf04c}, {0x83bd,0xf04d}, {0x83be,0xf04e}, {0x83bf,0xf04f}, {0x83c0,0xf050}, {0x83c1,0xf051}, - {0x83c2,0xf052}, {0x83c3,0xf053}, {0x83c4,0xf054}, {0x83c5,0xf055}, {0x83c6,0xf056}, {0x83c7,0xf057}, {0x83c8,0xf058}, {0x83c9,0xf059}, {0x83ca,0xf05a}, {0x83cb,0xf05b}, - {0x83cc,0xf05c}, {0x83cd,0xf05d}, {0x83ce,0xf05e}, {0x83cf,0xf05f}, {0x83d0,0xf060}, {0x83d1,0xf061}, {0x83d2,0xf062}, {0x83d3,0xf063}, {0x83d4,0xf064}, {0x83d5,0xf065}, - {0x83d6,0xf066}, {0x83d7,0xf067}, {0x83d8,0xf068}, {0x83d9,0xf069}, {0x83da,0xf06a}, {0x83db,0xf06b}, {0x83dc,0xf06c}, {0x83dd,0xf06d}, {0x83de,0xf06e}, {0x83df,0xf06f}, - {0x83e0,0xf070}, {0x83e1,0xf071}, {0x83e2,0xf072}, {0x83e3,0xf073}, {0x83e4,0xf074}, {0x83e5,0xf075}, {0x83e6,0xf076}, {0x83e7,0xf077}, {0x83e8,0xf078}, {0x83e9,0xf079}, - {0x83ea,0xf07a}, {0x83eb,0xf07b}, {0x83ec,0xf07c}, {0x83ed,0xf07d}, {0x83ee,0xf07e}, {0x83ef,0xf07f}, {0x83f0,0xf080}, {0x83f1,0xf081}, {0x83f2,0xf082}, {0x83f3,0xf083}, - {0x83f4,0xf084}, {0x83f5,0xf085}, {0x83f6,0xf086}, {0x83f7,0xf087}, {0x83f8,0xf088}, {0x83f9,0xf089}, {0x83fa,0xf08a}, {0x83fb,0xf08b}, {0x83fc,0xf08c}, {0x83fd,0xf08d}, - {0x83fe,0xf08e}, {0x8440,0xf08f}, {0x8441,0xf090}, {0x8442,0xf091}, {0x8443,0xf092}, {0x8444,0xf093}, {0x8445,0xf094}, {0x8446,0xf095}, {0x8447,0xf096}, {0x8448,0xf097}, - {0x8449,0xf098}, {0x844a,0xf099}, {0x844b,0xf09a}, {0x844c,0xf09b}, {0x844d,0xf09c}, {0x844e,0xf09d}, {0x844f,0xf09e}, {0x8450,0xf09f}, {0x8451,0xf0a0}, {0x8452,0xf0a1}, - {0x8453,0xf0a2}, {0x8454,0xf0a3}, {0x8455,0xf0a4}, {0x8456,0xf0a5}, {0x8457,0xf0a6}, {0x8458,0xf0a7}, {0x8459,0xf0a8}, {0x845a,0xf0a9}, {0x845b,0xf0aa}, {0x845c,0xf0ab}, - {0x845d,0xf0ac}, {0x845e,0xf0ad}, {0x845f,0xf0ae}, {0x8460,0xf0af}, {0x8461,0xf0b0}, {0x8462,0xf0b1}, {0x8463,0xf0b2}, {0x8464,0xf0b3}, {0x8465,0xf0b4}, {0x8466,0xf0b5}, - {0x8467,0xf0b6}, {0x8468,0xf0b7}, {0x8469,0xf0b8}, {0x846a,0xf0b9}, {0x846b,0xf0ba}, {0x846c,0xf0bb}, {0x846d,0xf0bc}, {0x846e,0xf0bd}, {0x846f,0xf0be}, {0x8470,0xf0bf}, - {0x8471,0xf0c0}, {0x8472,0xf0c1}, {0x8473,0xf0c2}, {0x8474,0xf0c3}, {0x8475,0xf0c4}, {0x8476,0xf0c5}, {0x8477,0xf0c6}, {0x8478,0xf0c7}, {0x8479,0xf0c8}, {0x847a,0xf0c9}, - {0x847b,0xf0ca}, {0x847c,0xf0cb}, {0x847d,0xf0cc}, {0x847e,0xf0cd}, {0x84a1,0xf0ce}, {0x84a2,0xf0cf}, {0x84a3,0xf0d0}, {0x84a4,0xf0d1}, {0x84a5,0xf0d2}, {0x84a6,0xf0d3}, - {0x84a7,0xf0d4}, {0x84a8,0xf0d5}, {0x84a9,0xf0d6}, {0x84aa,0xf0d7}, {0x84ab,0xf0d8}, {0x84ac,0xf0d9}, {0x84ad,0xf0da}, {0x84ae,0xf0db}, {0x84af,0xf0dc}, {0x84b0,0xf0dd}, - {0x84b1,0xf0de}, {0x84b2,0xf0df}, {0x84b3,0xf0e0}, {0x84b4,0xf0e1}, {0x84b5,0xf0e2}, {0x84b6,0xf0e3}, {0x84b7,0xf0e4}, {0x84b8,0xf0e5}, {0x84b9,0xf0e6}, {0x84ba,0xf0e7}, - {0x84bb,0xf0e8}, {0x84bc,0xf0e9}, {0x84bd,0xf0ea}, {0x84be,0xf0eb}, {0x84bf,0xf0ec}, {0x84c0,0xf0ed}, {0x84c1,0xf0ee}, {0x84c2,0xf0ef}, {0x84c3,0xf0f0}, {0x84c4,0xf0f1}, - {0x84c5,0xf0f2}, {0x84c6,0xf0f3}, {0x84c7,0xf0f4}, {0x84c8,0xf0f5}, {0x84c9,0xf0f6}, {0x84ca,0xf0f7}, {0x84cb,0xf0f8}, {0x84cc,0xf0f9}, {0x84cd,0xf0fa}, {0x84ce,0xf0fb}, - {0x84cf,0xf0fc}, {0x84d0,0xf0fd}, {0x84d1,0xf0fe}, {0x84d2,0xf0ff}, {0x84d3,0xf100}, {0x84d4,0xf101}, {0x84d5,0xf102}, {0x84d6,0xf103}, {0x84d7,0xf104}, {0x84d8,0xf105}, - {0x84d9,0xf106}, {0x84da,0xf107}, {0x84db,0xf108}, {0x84dc,0xf109}, {0x84dd,0xf10a}, {0x84de,0xf10b}, {0x84df,0xf10c}, {0x84e0,0xf10d}, {0x84e1,0xf10e}, {0x84e2,0xf10f}, - {0x84e3,0xf110}, {0x84e4,0xf111}, {0x84e5,0xf112}, {0x84e6,0xf113}, {0x84e7,0xf114}, {0x84e8,0xf115}, {0x84e9,0xf116}, {0x84ea,0xf117}, {0x84eb,0xf118}, {0x84ec,0xf119}, - {0x84ed,0xf11a}, {0x84ee,0xf11b}, {0x84ef,0xf11c}, {0x84f0,0xf11d}, {0x84f1,0xf11e}, {0x84f2,0xf11f}, {0x84f3,0xf120}, {0x84f4,0xf121}, {0x84f5,0xf122}, {0x84f6,0xf123}, - {0x84f7,0xf124}, {0x84f8,0xf125}, {0x84f9,0xf126}, {0x84fa,0xf127}, {0x84fb,0xf128}, {0x84fc,0xf129}, {0x84fd,0xf12a}, {0x84fe,0xf12b}, {0x8540,0xf12c}, {0x8541,0xf12d}, - {0x8542,0xf12e}, {0x8543,0xf12f}, {0x8544,0xf130}, {0x8545,0xf131}, {0x8546,0xf132}, {0x8547,0xf133}, {0x8548,0xf134}, {0x8549,0xf135}, {0x854a,0xf136}, {0x854b,0xf137}, - {0x854c,0xf138}, {0x854d,0xf139}, {0x854e,0xf13a}, {0x854f,0xf13b}, {0x8550,0xf13c}, {0x8551,0xf13d}, {0x8552,0xf13e}, {0x8553,0xf13f}, {0x8554,0xf140}, {0x8555,0xf141}, - {0x8556,0xf142}, {0x8557,0xf143}, {0x8558,0xf144}, {0x8559,0xf145}, {0x855a,0xf146}, {0x855b,0xf147}, {0x855c,0xf148}, {0x855d,0xf149}, {0x855e,0xf14a}, {0x855f,0xf14b}, - {0x8560,0xf14c}, {0x8561,0xf14d}, {0x8562,0xf14e}, {0x8563,0xf14f}, {0x8564,0xf150}, {0x8565,0xf151}, {0x8566,0xf152}, {0x8567,0xf153}, {0x8568,0xf154}, {0x8569,0xf155}, - {0x856a,0xf156}, {0x856b,0xf157}, {0x856c,0xf158}, {0x856d,0xf159}, {0x856e,0xf15a}, {0x856f,0xf15b}, {0x8570,0xf15c}, {0x8571,0xf15d}, {0x8572,0xf15e}, {0x8573,0xf15f}, - {0x8574,0xf160}, {0x8575,0xf161}, {0x8576,0xf162}, {0x8577,0xf163}, {0x8578,0xf164}, {0x8579,0xf165}, {0x857a,0xf166}, {0x857b,0xf167}, {0x857c,0xf168}, {0x857d,0xf169}, - {0x857e,0xf16a}, {0x85a1,0xf16b}, {0x85a2,0xf16c}, {0x85a3,0xf16d}, {0x85a4,0xf16e}, {0x85a5,0xf16f}, {0x85a6,0xf170}, {0x85a7,0xf171}, {0x85a8,0xf172}, {0x85a9,0xf173}, - {0x85aa,0xf174}, {0x85ab,0xf175}, {0x85ac,0xf176}, {0x85ad,0xf177}, {0x85ae,0xf178}, {0x85af,0xf179}, {0x85b0,0xf17a}, {0x85b1,0xf17b}, {0x85b2,0xf17c}, {0x85b3,0xf17d}, - {0x85b4,0xf17e}, {0x85b5,0xf17f}, {0x85b6,0xf180}, {0x85b7,0xf181}, {0x85b8,0xf182}, {0x85b9,0xf183}, {0x85ba,0xf184}, {0x85bb,0xf185}, {0x85bc,0xf186}, {0x85bd,0xf187}, - {0x85be,0xf188}, {0x85bf,0xf189}, {0x85c0,0xf18a}, {0x85c1,0xf18b}, {0x85c2,0xf18c}, {0x85c3,0xf18d}, {0x85c4,0xf18e}, {0x85c5,0xf18f}, {0x85c6,0xf190}, {0x85c7,0xf191}, - {0x85c8,0xf192}, {0x85c9,0xf193}, {0x85ca,0xf194}, {0x85cb,0xf195}, {0x85cc,0xf196}, {0x85cd,0xf197}, {0x85ce,0xf198}, {0x85cf,0xf199}, {0x85d0,0xf19a}, {0x85d1,0xf19b}, - {0x85d2,0xf19c}, {0x85d3,0xf19d}, {0x85d4,0xf19e}, {0x85d5,0xf19f}, {0x85d6,0xf1a0}, {0x85d7,0xf1a1}, {0x85d8,0xf1a2}, {0x85d9,0xf1a3}, {0x85da,0xf1a4}, {0x85db,0xf1a5}, - {0x85dc,0xf1a6}, {0x85dd,0xf1a7}, {0x85de,0xf1a8}, {0x85df,0xf1a9}, {0x85e0,0xf1aa}, {0x85e1,0xf1ab}, {0x85e2,0xf1ac}, {0x85e3,0xf1ad}, {0x85e4,0xf1ae}, {0x85e5,0xf1af}, - {0x85e6,0xf1b0}, {0x85e7,0xf1b1}, {0x85e8,0xf1b2}, {0x85e9,0xf1b3}, {0x85ea,0xf1b4}, {0x85eb,0xf1b5}, {0x85ec,0xf1b6}, {0x85ed,0xf1b7}, {0x85ee,0xf1b8}, {0x85ef,0xf1b9}, - {0x85f0,0xf1ba}, {0x85f1,0xf1bb}, {0x85f2,0xf1bc}, {0x85f3,0xf1bd}, {0x85f4,0xf1be}, {0x85f5,0xf1bf}, {0x85f6,0xf1c0}, {0x85f7,0xf1c1}, {0x85f8,0xf1c2}, {0x85f9,0xf1c3}, - {0x85fa,0xf1c4}, {0x85fb,0xf1c5}, {0x85fc,0xf1c6}, {0x85fd,0xf1c7}, {0x85fe,0xf1c8}, {0x8640,0xf1c9}, {0x8641,0xf1ca}, {0x8642,0xf1cb}, {0x8643,0xf1cc}, {0x8644,0xf1cd}, - {0x8645,0xf1ce}, {0x8646,0xf1cf}, {0x8647,0xf1d0}, {0x8648,0xf1d1}, {0x8649,0xf1d2}, {0x864a,0xf1d3}, {0x864b,0xf1d4}, {0x864c,0xf1d5}, {0x864d,0xf1d6}, {0x864e,0xf1d7}, - {0x864f,0xf1d8}, {0x8650,0xf1d9}, {0x8651,0xf1da}, {0x8652,0xf1db}, {0x8653,0xf1dc}, {0x8654,0xf1dd}, {0x8655,0xf1de}, {0x8656,0xf1df}, {0x8657,0xf1e0}, {0x8658,0xf1e1}, - {0x8659,0xf1e2}, {0x865a,0xf1e3}, {0x865b,0xf1e4}, {0x865c,0xf1e5}, {0x865d,0xf1e6}, {0x865e,0xf1e7}, {0x865f,0xf1e8}, {0x8660,0xf1e9}, {0x8661,0xf1ea}, {0x8662,0xf1eb}, - {0x8663,0xf1ec}, {0x8664,0xf1ed}, {0x8665,0xf1ee}, {0x8666,0xf1ef}, {0x8667,0xf1f0}, {0x8668,0xf1f1}, {0x8669,0xf1f2}, {0x866a,0xf1f3}, {0x866b,0xf1f4}, {0x866c,0xf1f5}, - {0x866d,0xf1f6}, {0x866e,0xf1f7}, {0x866f,0xf1f8}, {0x8670,0xf1f9}, {0x8671,0xf1fa}, {0x8672,0xf1fb}, {0x8673,0xf1fc}, {0x8674,0xf1fd}, {0x8675,0xf1fe}, {0x8676,0xf1ff}, - {0x8677,0xf200}, {0x8678,0xf201}, {0x8679,0xf202}, {0x867a,0xf203}, {0x867b,0xf204}, {0x867c,0xf205}, {0x867d,0xf206}, {0x867e,0xf207}, {0x86a1,0xf208}, {0x86a2,0xf209}, - {0x86a3,0xf20a}, {0x86a4,0xf20b}, {0x86a5,0xf20c}, {0x86a6,0xf20d}, {0x86a7,0xf20e}, {0x86a8,0xf20f}, {0x86a9,0xf210}, {0x86aa,0xf211}, {0x86ab,0xf212}, {0x86ac,0xf213}, - {0x86ad,0xf214}, {0x86ae,0xf215}, {0x86af,0xf216}, {0x86b0,0xf217}, {0x86b1,0xf218}, {0x86b2,0xf219}, {0x86b3,0xf21a}, {0x86b4,0xf21b}, {0x86b5,0xf21c}, {0x86b6,0xf21d}, - {0x86b7,0xf21e}, {0x86b8,0xf21f}, {0x86b9,0xf220}, {0x86ba,0xf221}, {0x86bb,0xf222}, {0x86bc,0xf223}, {0x86bd,0xf224}, {0x86be,0xf225}, {0x86bf,0xf226}, {0x86c0,0xf227}, - {0x86c1,0xf228}, {0x86c2,0xf229}, {0x86c3,0xf22a}, {0x86c4,0xf22b}, {0x86c5,0xf22c}, {0x86c6,0xf22d}, {0x86c7,0xf22e}, {0x86c8,0xf22f}, {0x86c9,0xf230}, {0x86ca,0xf231}, - {0x86cb,0xf232}, {0x86cc,0xf233}, {0x86cd,0xf234}, {0x86ce,0xf235}, {0x86cf,0xf236}, {0x86d0,0xf237}, {0x86d1,0xf238}, {0x86d2,0xf239}, {0x86d3,0xf23a}, {0x86d4,0xf23b}, - {0x86d5,0xf23c}, {0x86d6,0xf23d}, {0x86d7,0xf23e}, {0x86d8,0xf23f}, {0x86d9,0xf240}, {0x86da,0xf241}, {0x86db,0xf242}, {0x86dc,0xf243}, {0x86dd,0xf244}, {0x86de,0xf245}, - {0x86df,0xf246}, {0x86e0,0xf247}, {0x86e1,0xf248}, {0x86e2,0xf249}, {0x86e3,0xf24a}, {0x86e4,0xf24b}, {0x86e5,0xf24c}, {0x86e6,0xf24d}, {0x86e7,0xf24e}, {0x86e8,0xf24f}, - {0x86e9,0xf250}, {0x86ea,0xf251}, {0x86eb,0xf252}, {0x86ec,0xf253}, {0x86ed,0xf254}, {0x86ee,0xf255}, {0x86ef,0xf256}, {0x86f0,0xf257}, {0x86f1,0xf258}, {0x86f2,0xf259}, - {0x86f3,0xf25a}, {0x86f4,0xf25b}, {0x86f5,0xf25c}, {0x86f6,0xf25d}, {0x86f7,0xf25e}, {0x86f8,0xf25f}, {0x86f9,0xf260}, {0x86fa,0xf261}, {0x86fb,0xf262}, {0x86fc,0xf263}, - {0x86fd,0xf264}, {0x86fe,0xf265}, {0x8740,0xf266}, {0x8741,0xf267}, {0x8742,0xf268}, {0x8743,0xf269}, {0x8744,0xf26a}, {0x8745,0xf26b}, {0x8746,0xf26c}, {0x8747,0xf26d}, - {0x8748,0xf26e}, {0x8749,0xf26f}, {0x874a,0xf270}, {0x874b,0xf271}, {0x874c,0xf272}, {0x874d,0xf273}, {0x874e,0xf274}, {0x874f,0xf275}, {0x8750,0xf276}, {0x8751,0xf277}, - {0x8752,0xf278}, {0x8753,0xf279}, {0x8754,0xf27a}, {0x8755,0xf27b}, {0x8756,0xf27c}, {0x8757,0xf27d}, {0x8758,0xf27e}, {0x8759,0xf27f}, {0x875a,0xf280}, {0x875b,0xf281}, - {0x875c,0xf282}, {0x875d,0xf283}, {0x875e,0xf284}, {0x875f,0xf285}, {0x8760,0xf286}, {0x8761,0xf287}, {0x8762,0xf288}, {0x8763,0xf289}, {0x8764,0xf28a}, {0x8765,0xf28b}, - {0x8766,0xf28c}, {0x8767,0xf28d}, {0x8768,0xf28e}, {0x8769,0xf28f}, {0x876a,0xf290}, {0x876b,0xf291}, {0x876c,0xf292}, {0x876d,0xf293}, {0x876e,0xf294}, {0x876f,0xf295}, - {0x8770,0xf296}, {0x8771,0xf297}, {0x8772,0xf298}, {0x8773,0xf299}, {0x8774,0xf29a}, {0x8775,0xf29b}, {0x8776,0xf29c}, {0x8777,0xf29d}, {0x8778,0xf29e}, {0x8779,0xf29f}, - {0x877a,0xf2a0}, {0x877b,0xf2a1}, {0x877c,0xf2a2}, {0x877d,0xf2a3}, {0x877e,0xf2a4}, {0x87a1,0xf2a5}, {0x87a2,0xf2a6}, {0x87a3,0xf2a7}, {0x87a4,0xf2a8}, {0x87a5,0xf2a9}, - {0x87a6,0xf2aa}, {0x87a7,0xf2ab}, {0x87a8,0xf2ac}, {0x87a9,0xf2ad}, {0x87aa,0xf2ae}, {0x87ab,0xf2af}, {0x87ac,0xf2b0}, {0x87ad,0xf2b1}, {0x87ae,0xf2b2}, {0x87af,0xf2b3}, - {0x87b0,0xf2b4}, {0x87b1,0xf2b5}, {0x87b2,0xf2b6}, {0x87b3,0xf2b7}, {0x87b4,0xf2b8}, {0x87b5,0xf2b9}, {0x87b6,0xf2ba}, {0x87b7,0xf2bb}, {0x87b8,0xf2bc}, {0x87b9,0xf2bd}, - {0x87ba,0xf2be}, {0x87bb,0xf2bf}, {0x87bc,0xf2c0}, {0x87bd,0xf2c1}, {0x87be,0xf2c2}, {0x87bf,0xf2c3}, {0x87c0,0xf2c4}, {0x87c1,0xf2c5}, {0x87c2,0xf2c6}, {0x87c3,0xf2c7}, - {0x87c4,0xf2c8}, {0x87c5,0xf2c9}, {0x87c6,0xf2ca}, {0x87c7,0xf2cb}, {0x87c8,0xf2cc}, {0x87c9,0xf2cd}, {0x87ca,0xf2ce}, {0x87cb,0xf2cf}, {0x87cc,0xf2d0}, {0x87cd,0xf2d1}, - {0x87ce,0xf2d2}, {0x87cf,0xf2d3}, {0x87d0,0xf2d4}, {0x87d1,0xf2d5}, {0x87d2,0xf2d6}, {0x87d3,0xf2d7}, {0x87d4,0xf2d8}, {0x87d5,0xf2d9}, {0x87d6,0xf2da}, {0x87d7,0xf2db}, - {0x87d8,0xf2dc}, {0x87d9,0xf2dd}, {0x87da,0xf2de}, {0x87db,0xf2df}, {0x87dc,0xf2e0}, {0x87dd,0xf2e1}, {0x87de,0xf2e2}, {0x87df,0xf2e3}, {0x87e0,0xf2e4}, {0x87e1,0xf2e5}, - {0x87e2,0xf2e6}, {0x87e3,0xf2e7}, {0x87e4,0xf2e8}, {0x87e5,0xf2e9}, {0x87e6,0xf2ea}, {0x87e7,0xf2eb}, {0x87e8,0xf2ec}, {0x87e9,0xf2ed}, {0x87ea,0xf2ee}, {0x87eb,0xf2ef}, - {0x87ec,0xf2f0}, {0x87ed,0xf2f1}, {0x87ee,0xf2f2}, {0x87ef,0xf2f3}, {0x87f0,0xf2f4}, {0x87f1,0xf2f5}, {0x87f2,0xf2f6}, {0x87f3,0xf2f7}, {0x87f4,0xf2f8}, {0x87f5,0xf2f9}, - {0x87f6,0xf2fa}, {0x87f7,0xf2fb}, {0x87f8,0xf2fc}, {0x87f9,0xf2fd}, {0x87fa,0xf2fe}, {0x87fb,0xf2ff}, {0x87fc,0xf300}, {0x87fd,0xf301}, {0x87fe,0xf302}, {0x8840,0xf303}, - {0x8841,0xf304}, {0x8842,0xf305}, {0x8843,0xf306}, {0x8844,0xf307}, {0x8845,0xf308}, {0x8846,0xf309}, {0x8847,0xf30a}, {0x8848,0xf30b}, {0x8849,0xf30c}, {0x884a,0xf30d}, - {0x884b,0xf30e}, {0x884c,0xf30f}, {0x884d,0xf310}, {0x884e,0xf311}, {0x884f,0xf312}, {0x8850,0xf313}, {0x8851,0xf314}, {0x8852,0xf315}, {0x8853,0xf316}, {0x8854,0xf317}, - {0x8855,0xf318}, {0x8856,0xf319}, {0x8857,0xf31a}, {0x8858,0xf31b}, {0x8859,0xf31c}, {0x885a,0xf31d}, {0x885b,0xf31e}, {0x885c,0xf31f}, {0x885d,0xf320}, {0x885e,0xf321}, - {0x885f,0xf322}, {0x8860,0xf323}, {0x8861,0xf324}, {0x8862,0xf325}, {0x8863,0xf326}, {0x8864,0xf327}, {0x8865,0xf328}, {0x8866,0xf329}, {0x8867,0xf32a}, {0x8868,0xf32b}, - {0x8869,0xf32c}, {0x886a,0xf32d}, {0x886b,0xf32e}, {0x886c,0xf32f}, {0x886d,0xf330}, {0x886e,0xf331}, {0x886f,0xf332}, {0x8870,0xf333}, {0x8871,0xf334}, {0x8872,0xf335}, - {0x8873,0xf336}, {0x8874,0xf337}, {0x8875,0xf338}, {0x8876,0xf339}, {0x8877,0xf33a}, {0x8878,0xf33b}, {0x8879,0xf33c}, {0x887a,0xf33d}, {0x887b,0xf33e}, {0x887c,0xf33f}, - {0x887d,0xf340}, {0x887e,0xf341}, {0x88a1,0xf342}, {0x88a2,0xf343}, {0x88a3,0xf344}, {0x88a4,0xf345}, {0x88a5,0xf346}, {0x88a6,0xf347}, {0x88a7,0xf348}, {0x88a8,0xf349}, - {0x88a9,0xf34a}, {0x88aa,0xf34b}, {0x88ab,0xf34c}, {0x88ac,0xf34d}, {0x88ad,0xf34e}, {0x88ae,0xf34f}, {0x88af,0xf350}, {0x88b0,0xf351}, {0x88b1,0xf352}, {0x88b2,0xf353}, - {0x88b3,0xf354}, {0x88b4,0xf355}, {0x88b5,0xf356}, {0x88b6,0xf357}, {0x88b7,0xf358}, {0x88b8,0xf359}, {0x88b9,0xf35a}, {0x88ba,0xf35b}, {0x88bb,0xf35c}, {0x88bc,0xf35d}, - {0x88bd,0xf35e}, {0x88be,0xf35f}, {0x88bf,0xf360}, {0x88c0,0xf361}, {0x88c1,0xf362}, {0x88c2,0xf363}, {0x88c3,0xf364}, {0x88c4,0xf365}, {0x88c5,0xf366}, {0x88c6,0xf367}, - {0x88c7,0xf368}, {0x88c8,0xf369}, {0x88c9,0xf36a}, {0x88ca,0xf36b}, {0x88cb,0xf36c}, {0x88cc,0xf36d}, {0x88cd,0xf36e}, {0x88ce,0xf36f}, {0x88cf,0xf370}, {0x88d0,0xf371}, - {0x88d1,0xf372}, {0x88d2,0xf373}, {0x88d3,0xf374}, {0x88d4,0xf375}, {0x88d5,0xf376}, {0x88d6,0xf377}, {0x88d7,0xf378}, {0x88d8,0xf379}, {0x88d9,0xf37a}, {0x88da,0xf37b}, - {0x88db,0xf37c}, {0x88dc,0xf37d}, {0x88dd,0xf37e}, {0x88de,0xf37f}, {0x88df,0xf380}, {0x88e0,0xf381}, {0x88e1,0xf382}, {0x88e2,0xf383}, {0x88e3,0xf384}, {0x88e4,0xf385}, - {0x88e5,0xf386}, {0x88e6,0xf387}, {0x88e7,0xf388}, {0x88e8,0xf389}, {0x88e9,0xf38a}, {0x88ea,0xf38b}, {0x88eb,0xf38c}, {0x88ec,0xf38d}, {0x88ed,0xf38e}, {0x88ee,0xf38f}, - {0x88ef,0xf390}, {0x88f0,0xf391}, {0x88f1,0xf392}, {0x88f2,0xf393}, {0x88f3,0xf394}, {0x88f4,0xf395}, {0x88f5,0xf396}, {0x88f6,0xf397}, {0x88f7,0xf398}, {0x88f8,0xf399}, - {0x88f9,0xf39a}, {0x88fa,0xf39b}, {0x88fb,0xf39c}, {0x88fc,0xf39d}, {0x88fd,0xf39e}, {0x88fe,0xf39f}, {0x8940,0xf3a0}, {0x8941,0xf3a1}, {0x8942,0xf3a2}, {0x8943,0xf3a3}, - {0x8944,0xf3a4}, {0x8945,0xf3a5}, {0x8946,0xf3a6}, {0x8947,0xf3a7}, {0x8948,0xf3a8}, {0x8949,0xf3a9}, {0x894a,0xf3aa}, {0x894b,0xf3ab}, {0x894c,0xf3ac}, {0x894d,0xf3ad}, - {0x894e,0xf3ae}, {0x894f,0xf3af}, {0x8950,0xf3b0}, {0x8951,0xf3b1}, {0x8952,0xf3b2}, {0x8953,0xf3b3}, {0x8954,0xf3b4}, {0x8955,0xf3b5}, {0x8956,0xf3b6}, {0x8957,0xf3b7}, - {0x8958,0xf3b8}, {0x8959,0xf3b9}, {0x895a,0xf3ba}, {0x895b,0xf3bb}, {0x895c,0xf3bc}, {0x895d,0xf3bd}, {0x895e,0xf3be}, {0x895f,0xf3bf}, {0x8960,0xf3c0}, {0x8961,0xf3c1}, - {0x8962,0xf3c2}, {0x8963,0xf3c3}, {0x8964,0xf3c4}, {0x8965,0xf3c5}, {0x8966,0xf3c6}, {0x8967,0xf3c7}, {0x8968,0xf3c8}, {0x8969,0xf3c9}, {0x896a,0xf3ca}, {0x896b,0xf3cb}, - {0x896c,0xf3cc}, {0x896d,0xf3cd}, {0x896e,0xf3ce}, {0x896f,0xf3cf}, {0x8970,0xf3d0}, {0x8971,0xf3d1}, {0x8972,0xf3d2}, {0x8973,0xf3d3}, {0x8974,0xf3d4}, {0x8975,0xf3d5}, - {0x8976,0xf3d6}, {0x8977,0xf3d7}, {0x8978,0xf3d8}, {0x8979,0xf3d9}, {0x897a,0xf3da}, {0x897b,0xf3db}, {0x897c,0xf3dc}, {0x897d,0xf3dd}, {0x897e,0xf3de}, {0x89a1,0xf3df}, - {0x89a2,0xf3e0}, {0x89a3,0xf3e1}, {0x89a4,0xf3e2}, {0x89a5,0xf3e3}, {0x89a6,0xf3e4}, {0x89a7,0xf3e5}, {0x89a8,0xf3e6}, {0x89a9,0xf3e7}, {0x89aa,0xf3e8}, {0x89ab,0xf3e9}, - {0x89ac,0xf3ea}, {0x89ad,0xf3eb}, {0x89ae,0xf3ec}, {0x89af,0xf3ed}, {0x89b0,0xf3ee}, {0x89b1,0xf3ef}, {0x89b2,0xf3f0}, {0x89b3,0xf3f1}, {0x89b4,0xf3f2}, {0x89b5,0xf3f3}, - {0x89b6,0xf3f4}, {0x89b7,0xf3f5}, {0x89b8,0xf3f6}, {0x89b9,0xf3f7}, {0x89ba,0xf3f8}, {0x89bb,0xf3f9}, {0x89bc,0xf3fa}, {0x89bd,0xf3fb}, {0x89be,0xf3fc}, {0x89bf,0xf3fd}, - {0x89c0,0xf3fe}, {0x89c1,0xf3ff}, {0x89c2,0xf400}, {0x89c3,0xf401}, {0x89c4,0xf402}, {0x89c5,0xf403}, {0x89c6,0xf404}, {0x89c7,0xf405}, {0x89c8,0xf406}, {0x89c9,0xf407}, - {0x89ca,0xf408}, {0x89cb,0xf409}, {0x89cc,0xf40a}, {0x89cd,0xf40b}, {0x89ce,0xf40c}, {0x89cf,0xf40d}, {0x89d0,0xf40e}, {0x89d1,0xf40f}, {0x89d2,0xf410}, {0x89d3,0xf411}, - {0x89d4,0xf412}, {0x89d5,0xf413}, {0x89d6,0xf414}, {0x89d7,0xf415}, {0x89d8,0xf416}, {0x89d9,0xf417}, {0x89da,0xf418}, {0x89db,0xf419}, {0x89dc,0xf41a}, {0x89dd,0xf41b}, - {0x89de,0xf41c}, {0x89df,0xf41d}, {0x89e0,0xf41e}, {0x89e1,0xf41f}, {0x89e2,0xf420}, {0x89e3,0xf421}, {0x89e4,0xf422}, {0x89e5,0xf423}, {0x89e6,0xf424}, {0x89e7,0xf425}, - {0x89e8,0xf426}, {0x89e9,0xf427}, {0x89ea,0xf428}, {0x89eb,0xf429}, {0x89ec,0xf42a}, {0x89ed,0xf42b}, {0x89ee,0xf42c}, {0x89ef,0xf42d}, {0x89f0,0xf42e}, {0x89f1,0xf42f}, - {0x89f2,0xf430}, {0x89f3,0xf431}, {0x89f4,0xf432}, {0x89f5,0xf433}, {0x89f6,0xf434}, {0x89f7,0xf435}, {0x89f8,0xf436}, {0x89f9,0xf437}, {0x89fa,0xf438}, {0x89fb,0xf439}, - {0x89fc,0xf43a}, {0x89fd,0xf43b}, {0x89fe,0xf43c}, {0x8a40,0xf43d}, {0x8a41,0xf43e}, {0x8a42,0xf43f}, {0x8a43,0xf440}, {0x8a44,0xf441}, {0x8a45,0xf442}, {0x8a46,0xf443}, - {0x8a47,0xf444}, {0x8a48,0xf445}, {0x8a49,0xf446}, {0x8a4a,0xf447}, {0x8a4b,0xf448}, {0x8a4c,0xf449}, {0x8a4d,0xf44a}, {0x8a4e,0xf44b}, {0x8a4f,0xf44c}, {0x8a50,0xf44d}, - {0x8a51,0xf44e}, {0x8a52,0xf44f}, {0x8a53,0xf450}, {0x8a54,0xf451}, {0x8a55,0xf452}, {0x8a56,0xf453}, {0x8a57,0xf454}, {0x8a58,0xf455}, {0x8a59,0xf456}, {0x8a5a,0xf457}, - {0x8a5b,0xf458}, {0x8a5c,0xf459}, {0x8a5d,0xf45a}, {0x8a5e,0xf45b}, {0x8a5f,0xf45c}, {0x8a60,0xf45d}, {0x8a61,0xf45e}, {0x8a62,0xf45f}, {0x8a63,0xf460}, {0x8a64,0xf461}, - {0x8a65,0xf462}, {0x8a66,0xf463}, {0x8a67,0xf464}, {0x8a68,0xf465}, {0x8a69,0xf466}, {0x8a6a,0xf467}, {0x8a6b,0xf468}, {0x8a6c,0xf469}, {0x8a6d,0xf46a}, {0x8a6e,0xf46b}, - {0x8a6f,0xf46c}, {0x8a70,0xf46d}, {0x8a71,0xf46e}, {0x8a72,0xf46f}, {0x8a73,0xf470}, {0x8a74,0xf471}, {0x8a75,0xf472}, {0x8a76,0xf473}, {0x8a77,0xf474}, {0x8a78,0xf475}, - {0x8a79,0xf476}, {0x8a7a,0xf477}, {0x8a7b,0xf478}, {0x8a7c,0xf479}, {0x8a7d,0xf47a}, {0x8a7e,0xf47b}, {0x8aa1,0xf47c}, {0x8aa2,0xf47d}, {0x8aa3,0xf47e}, {0x8aa4,0xf47f}, - {0x8aa5,0xf480}, {0x8aa6,0xf481}, {0x8aa7,0xf482}, {0x8aa8,0xf483}, {0x8aa9,0xf484}, {0x8aaa,0xf485}, {0x8aab,0xf486}, {0x8aac,0xf487}, {0x8aad,0xf488}, {0x8aae,0xf489}, - {0x8aaf,0xf48a}, {0x8ab0,0xf48b}, {0x8ab1,0xf48c}, {0x8ab2,0xf48d}, {0x8ab3,0xf48e}, {0x8ab4,0xf48f}, {0x8ab5,0xf490}, {0x8ab6,0xf491}, {0x8ab7,0xf492}, {0x8ab8,0xf493}, - {0x8ab9,0xf494}, {0x8aba,0xf495}, {0x8abb,0xf496}, {0x8abc,0xf497}, {0x8abd,0xf498}, {0x8abe,0xf499}, {0x8abf,0xf49a}, {0x8ac0,0xf49b}, {0x8ac1,0xf49c}, {0x8ac2,0xf49d}, - {0x8ac3,0xf49e}, {0x8ac4,0xf49f}, {0x8ac5,0xf4a0}, {0x8ac6,0xf4a1}, {0x8ac7,0xf4a2}, {0x8ac8,0xf4a3}, {0x8ac9,0xf4a4}, {0x8aca,0xf4a5}, {0x8acb,0xf4a6}, {0x8acc,0xf4a7}, - {0x8acd,0xf4a8}, {0x8ace,0xf4a9}, {0x8acf,0xf4aa}, {0x8ad0,0xf4ab}, {0x8ad1,0xf4ac}, {0x8ad2,0xf4ad}, {0x8ad3,0xf4ae}, {0x8ad4,0xf4af}, {0x8ad5,0xf4b0}, {0x8ad6,0xf4b1}, - {0x8ad7,0xf4b2}, {0x8ad8,0xf4b3}, {0x8ad9,0xf4b4}, {0x8ada,0xf4b5}, {0x8adb,0xf4b6}, {0x8adc,0xf4b7}, {0x8add,0xf4b8}, {0x8ade,0xf4b9}, {0x8adf,0xf4ba}, {0x8ae0,0xf4bb}, - {0x8ae1,0xf4bc}, {0x8ae2,0xf4bd}, {0x8ae3,0xf4be}, {0x8ae4,0xf4bf}, {0x8ae5,0xf4c0}, {0x8ae6,0xf4c1}, {0x8ae7,0xf4c2}, {0x8ae8,0xf4c3}, {0x8ae9,0xf4c4}, {0x8aea,0xf4c5}, - {0x8aeb,0xf4c6}, {0x8aec,0xf4c7}, {0x8aed,0xf4c8}, {0x8aee,0xf4c9}, {0x8aef,0xf4ca}, {0x8af0,0xf4cb}, {0x8af1,0xf4cc}, {0x8af2,0xf4cd}, {0x8af3,0xf4ce}, {0x8af4,0xf4cf}, - {0x8af5,0xf4d0}, {0x8af6,0xf4d1}, {0x8af7,0xf4d2}, {0x8af8,0xf4d3}, {0x8af9,0xf4d4}, {0x8afa,0xf4d5}, {0x8afb,0xf4d6}, {0x8afc,0xf4d7}, {0x8afd,0xf4d8}, {0x8afe,0xf4d9}, - {0x8b40,0xf4da}, {0x8b41,0xf4db}, {0x8b42,0xf4dc}, {0x8b43,0xf4dd}, {0x8b44,0xf4de}, {0x8b45,0xf4df}, {0x8b46,0xf4e0}, {0x8b47,0xf4e1}, {0x8b48,0xf4e2}, {0x8b49,0xf4e3}, - {0x8b4a,0xf4e4}, {0x8b4b,0xf4e5}, {0x8b4c,0xf4e6}, {0x8b4d,0xf4e7}, {0x8b4e,0xf4e8}, {0x8b4f,0xf4e9}, {0x8b50,0xf4ea}, {0x8b51,0xf4eb}, {0x8b52,0xf4ec}, {0x8b53,0xf4ed}, - {0x8b54,0xf4ee}, {0x8b55,0xf4ef}, {0x8b56,0xf4f0}, {0x8b57,0xf4f1}, {0x8b58,0xf4f2}, {0x8b59,0xf4f3}, {0x8b5a,0xf4f4}, {0x8b5b,0xf4f5}, {0x8b5c,0xf4f6}, {0x8b5d,0xf4f7}, - {0x8b5e,0xf4f8}, {0x8b5f,0xf4f9}, {0x8b60,0xf4fa}, {0x8b61,0xf4fb}, {0x8b62,0xf4fc}, {0x8b63,0xf4fd}, {0x8b64,0xf4fe}, {0x8b65,0xf4ff}, {0x8b66,0xf500}, {0x8b67,0xf501}, - {0x8b68,0xf502}, {0x8b69,0xf503}, {0x8b6a,0xf504}, {0x8b6b,0xf505}, {0x8b6c,0xf506}, {0x8b6d,0xf507}, {0x8b6e,0xf508}, {0x8b6f,0xf509}, {0x8b70,0xf50a}, {0x8b71,0xf50b}, - {0x8b72,0xf50c}, {0x8b73,0xf50d}, {0x8b74,0xf50e}, {0x8b75,0xf50f}, {0x8b76,0xf510}, {0x8b77,0xf511}, {0x8b78,0xf512}, {0x8b79,0xf513}, {0x8b7a,0xf514}, {0x8b7b,0xf515}, - {0x8b7c,0xf516}, {0x8b7d,0xf517}, {0x8b7e,0xf518}, {0x8ba1,0xf519}, {0x8ba2,0xf51a}, {0x8ba3,0xf51b}, {0x8ba4,0xf51c}, {0x8ba5,0xf51d}, {0x8ba6,0xf51e}, {0x8ba7,0xf51f}, - {0x8ba8,0xf520}, {0x8ba9,0xf521}, {0x8baa,0xf522}, {0x8bab,0xf523}, {0x8bac,0xf524}, {0x8bad,0xf525}, {0x8bae,0xf526}, {0x8baf,0xf527}, {0x8bb0,0xf528}, {0x8bb1,0xf529}, - {0x8bb2,0xf52a}, {0x8bb3,0xf52b}, {0x8bb4,0xf52c}, {0x8bb5,0xf52d}, {0x8bb6,0xf52e}, {0x8bb7,0xf52f}, {0x8bb8,0xf530}, {0x8bb9,0xf531}, {0x8bba,0xf532}, {0x8bbb,0xf533}, - {0x8bbc,0xf534}, {0x8bbd,0xf535}, {0x8bbe,0xf536}, {0x8bbf,0xf537}, {0x8bc0,0xf538}, {0x8bc1,0xf539}, {0x8bc2,0xf53a}, {0x8bc3,0xf53b}, {0x8bc4,0xf53c}, {0x8bc5,0xf53d}, - {0x8bc6,0xf53e}, {0x8bc7,0xf53f}, {0x8bc8,0xf540}, {0x8bc9,0xf541}, {0x8bca,0xf542}, {0x8bcb,0xf543}, {0x8bcc,0xf544}, {0x8bcd,0xf545}, {0x8bce,0xf546}, {0x8bcf,0xf547}, - {0x8bd0,0xf548}, {0x8bd1,0xf549}, {0x8bd2,0xf54a}, {0x8bd3,0xf54b}, {0x8bd4,0xf54c}, {0x8bd5,0xf54d}, {0x8bd6,0xf54e}, {0x8bd7,0xf54f}, {0x8bd8,0xf550}, {0x8bd9,0xf551}, - {0x8bda,0xf552}, {0x8bdb,0xf553}, {0x8bdc,0xf554}, {0x8bdd,0xf555}, {0x8bde,0xf556}, {0x8bdf,0xf557}, {0x8be0,0xf558}, {0x8be1,0xf559}, {0x8be2,0xf55a}, {0x8be3,0xf55b}, - {0x8be4,0xf55c}, {0x8be5,0xf55d}, {0x8be6,0xf55e}, {0x8be7,0xf55f}, {0x8be8,0xf560}, {0x8be9,0xf561}, {0x8bea,0xf562}, {0x8beb,0xf563}, {0x8bec,0xf564}, {0x8bed,0xf565}, - {0x8bee,0xf566}, {0x8bef,0xf567}, {0x8bf0,0xf568}, {0x8bf1,0xf569}, {0x8bf2,0xf56a}, {0x8bf3,0xf56b}, {0x8bf4,0xf56c}, {0x8bf5,0xf56d}, {0x8bf6,0xf56e}, {0x8bf7,0xf56f}, - {0x8bf8,0xf570}, {0x8bf9,0xf571}, {0x8bfa,0xf572}, {0x8bfb,0xf573}, {0x8bfc,0xf574}, {0x8bfd,0xf575}, {0x8bfe,0xf576}, {0x8c40,0xf577}, {0x8c41,0xf578}, {0x8c42,0xf579}, - {0x8c43,0xf57a}, {0x8c44,0xf57b}, {0x8c45,0xf57c}, {0x8c46,0xf57d}, {0x8c47,0xf57e}, {0x8c48,0xf57f}, {0x8c49,0xf580}, {0x8c4a,0xf581}, {0x8c4b,0xf582}, {0x8c4c,0xf583}, - {0x8c4d,0xf584}, {0x8c4e,0xf585}, {0x8c4f,0xf586}, {0x8c50,0xf587}, {0x8c51,0xf588}, {0x8c52,0xf589}, {0x8c53,0xf58a}, {0x8c54,0xf58b}, {0x8c55,0xf58c}, {0x8c56,0xf58d}, - {0x8c57,0xf58e}, {0x8c58,0xf58f}, {0x8c59,0xf590}, {0x8c5a,0xf591}, {0x8c5b,0xf592}, {0x8c5c,0xf593}, {0x8c5d,0xf594}, {0x8c5e,0xf595}, {0x8c5f,0xf596}, {0x8c60,0xf597}, - {0x8c61,0xf598}, {0x8c62,0xf599}, {0x8c63,0xf59a}, {0x8c64,0xf59b}, {0x8c65,0xf59c}, {0x8c66,0xf59d}, {0x8c67,0xf59e}, {0x8c68,0xf59f}, {0x8c69,0xf5a0}, {0x8c6a,0xf5a1}, - {0x8c6b,0xf5a2}, {0x8c6c,0xf5a3}, {0x8c6d,0xf5a4}, {0x8c6e,0xf5a5}, {0x8c6f,0xf5a6}, {0x8c70,0xf5a7}, {0x8c71,0xf5a8}, {0x8c72,0xf5a9}, {0x8c73,0xf5aa}, {0x8c74,0xf5ab}, - {0x8c75,0xf5ac}, {0x8c76,0xf5ad}, {0x8c77,0xf5ae}, {0x8c78,0xf5af}, {0x8c79,0xf5b0}, {0x8c7a,0xf5b1}, {0x8c7b,0xf5b2}, {0x8c7c,0xf5b3}, {0x8c7d,0xf5b4}, {0x8c7e,0xf5b5}, - {0x8ca1,0xf5b6}, {0x8ca2,0xf5b7}, {0x8ca3,0xf5b8}, {0x8ca4,0xf5b9}, {0x8ca5,0xf5ba}, {0x8ca6,0xf5bb}, {0x8ca7,0xf5bc}, {0x8ca8,0xf5bd}, {0x8ca9,0xf5be}, {0x8caa,0xf5bf}, - {0x8cab,0xf5c0}, {0x8cac,0xf5c1}, {0x8cad,0xf5c2}, {0x8cae,0xf5c3}, {0x8caf,0xf5c4}, {0x8cb0,0xf5c5}, {0x8cb1,0xf5c6}, {0x8cb2,0xf5c7}, {0x8cb3,0xf5c8}, {0x8cb4,0xf5c9}, - {0x8cb5,0xf5ca}, {0x8cb6,0xf5cb}, {0x8cb7,0xf5cc}, {0x8cb8,0xf5cd}, {0x8cb9,0xf5ce}, {0x8cba,0xf5cf}, {0x8cbb,0xf5d0}, {0x8cbc,0xf5d1}, {0x8cbd,0xf5d2}, {0x8cbe,0xf5d3}, - {0x8cbf,0xf5d4}, {0x8cc0,0xf5d5}, {0x8cc1,0xf5d6}, {0x8cc2,0xf5d7}, {0x8cc3,0xf5d8}, {0x8cc4,0xf5d9}, {0x8cc5,0xf5da}, {0x8cc6,0xf5db}, {0x8cc7,0xf5dc}, {0x8cc8,0xf5dd}, - {0x8cc9,0xf5de}, {0x8cca,0xf5df}, {0x8ccb,0xf5e0}, {0x8ccc,0xf5e1}, {0x8ccd,0xf5e2}, {0x8cce,0xf5e3}, {0x8ccf,0xf5e4}, {0x8cd0,0xf5e5}, {0x8cd1,0xf5e6}, {0x8cd2,0xf5e7}, - {0x8cd3,0xf5e8}, {0x8cd4,0xf5e9}, {0x8cd5,0xf5ea}, {0x8cd6,0xf5eb}, {0x8cd7,0xf5ec}, {0x8cd8,0xf5ed}, {0x8cd9,0xf5ee}, {0x8cda,0xf5ef}, {0x8cdb,0xf5f0}, {0x8cdc,0xf5f1}, - {0x8cdd,0xf5f2}, {0x8cde,0xf5f3}, {0x8cdf,0xf5f4}, {0x8ce0,0xf5f5}, {0x8ce1,0xf5f6}, {0x8ce2,0xf5f7}, {0x8ce3,0xf5f8}, {0x8ce4,0xf5f9}, {0x8ce5,0xf5fa}, {0x8ce6,0xf5fb}, - {0x8ce7,0xf5fc}, {0x8ce8,0xf5fd}, {0x8ce9,0xf5fe}, {0x8cea,0xf5ff}, {0x8ceb,0xf600}, {0x8cec,0xf601}, {0x8ced,0xf602}, {0x8cee,0xf603}, {0x8cef,0xf604}, {0x8cf0,0xf605}, - {0x8cf1,0xf606}, {0x8cf2,0xf607}, {0x8cf3,0xf608}, {0x8cf4,0xf609}, {0x8cf5,0xf60a}, {0x8cf6,0xf60b}, {0x8cf7,0xf60c}, {0x8cf8,0xf60d}, {0x8cf9,0xf60e}, {0x8cfa,0xf60f}, - {0x8cfb,0xf610}, {0x8cfc,0xf611}, {0x8cfd,0xf612}, {0x8cfe,0xf613}, {0x8d40,0xf614}, {0x8d41,0xf615}, {0x8d42,0xf616}, {0x8d43,0xf617}, {0x8d44,0xf618}, {0x8d45,0xf619}, - {0x8d46,0xf61a}, {0x8d47,0xf61b}, {0x8d48,0xf61c}, {0x8d49,0xf61d}, {0x8d4a,0xf61e}, {0x8d4b,0xf61f}, {0x8d4c,0xf620}, {0x8d4d,0xf621}, {0x8d4e,0xf622}, {0x8d4f,0xf623}, - {0x8d50,0xf624}, {0x8d51,0xf625}, {0x8d52,0xf626}, {0x8d53,0xf627}, {0x8d54,0xf628}, {0x8d55,0xf629}, {0x8d56,0xf62a}, {0x8d57,0xf62b}, {0x8d58,0xf62c}, {0x8d59,0xf62d}, - {0x8d5a,0xf62e}, {0x8d5b,0xf62f}, {0x8d5c,0xf630}, {0x8d5d,0xf631}, {0x8d5e,0xf632}, {0x8d5f,0xf633}, {0x8d60,0xf634}, {0x8d61,0xf635}, {0x8d62,0xf636}, {0x8d63,0xf637}, - {0x8d64,0xf638}, {0x8d65,0xf639}, {0x8d66,0xf63a}, {0x8d67,0xf63b}, {0x8d68,0xf63c}, {0x8d69,0xf63d}, {0x8d6a,0xf63e}, {0x8d6b,0xf63f}, {0x8d6c,0xf640}, {0x8d6d,0xf641}, - {0x8d6e,0xf642}, {0x8d6f,0xf643}, {0x8d70,0xf644}, {0x8d71,0xf645}, {0x8d72,0xf646}, {0x8d73,0xf647}, {0x8d74,0xf648}, {0x8d75,0xf649}, {0x8d76,0xf64a}, {0x8d77,0xf64b}, - {0x8d78,0xf64c}, {0x8d79,0xf64d}, {0x8d7a,0xf64e}, {0x8d7b,0xf64f}, {0x8d7c,0xf650}, {0x8d7d,0xf651}, {0x8d7e,0xf652}, {0x8da1,0xf653}, {0x8da2,0xf654}, {0x8da3,0xf655}, - {0x8da4,0xf656}, {0x8da5,0xf657}, {0x8da6,0xf658}, {0x8da7,0xf659}, {0x8da8,0xf65a}, {0x8da9,0xf65b}, {0x8daa,0xf65c}, {0x8dab,0xf65d}, {0x8dac,0xf65e}, {0x8dad,0xf65f}, - {0x8dae,0xf660}, {0x8daf,0xf661}, {0x8db0,0xf662}, {0x8db1,0xf663}, {0x8db2,0xf664}, {0x8db3,0xf665}, {0x8db4,0xf666}, {0x8db5,0xf667}, {0x8db6,0xf668}, {0x8db7,0xf669}, - {0x8db8,0xf66a}, {0x8db9,0xf66b}, {0x8dba,0xf66c}, {0x8dbb,0xf66d}, {0x8dbc,0xf66e}, {0x8dbd,0xf66f}, {0x8dbe,0xf670}, {0x8dbf,0xf671}, {0x8dc0,0xf672}, {0x8dc1,0xf673}, - {0x8dc2,0xf674}, {0x8dc3,0xf675}, {0x8dc4,0xf676}, {0x8dc5,0xf677}, {0x8dc6,0xf678}, {0x8dc7,0xf679}, {0x8dc8,0xf67a}, {0x8dc9,0xf67b}, {0x8dca,0xf67c}, {0x8dcb,0xf67d}, - {0x8dcc,0xf67e}, {0x8dcd,0xf67f}, {0x8dce,0xf680}, {0x8dcf,0xf681}, {0x8dd0,0xf682}, {0x8dd1,0xf683}, {0x8dd2,0xf684}, {0x8dd3,0xf685}, {0x8dd4,0xf686}, {0x8dd5,0xf687}, - {0x8dd6,0xf688}, {0x8dd7,0xf689}, {0x8dd8,0xf68a}, {0x8dd9,0xf68b}, {0x8dda,0xf68c}, {0x8ddb,0xf68d}, {0x8ddc,0xf68e}, {0x8ddd,0xf68f}, {0x8dde,0xf690}, {0x8ddf,0xf691}, - {0x8de0,0xf692}, {0x8de1,0xf693}, {0x8de2,0xf694}, {0x8de3,0xf695}, {0x8de4,0xf696}, {0x8de5,0xf697}, {0x8de6,0xf698}, {0x8de7,0xf699}, {0x8de8,0xf69a}, {0x8de9,0xf69b}, - {0x8dea,0xf69c}, {0x8deb,0xf69d}, {0x8dec,0xf69e}, {0x8ded,0xf69f}, {0x8dee,0xf6a0}, {0x8def,0xf6a1}, {0x8df0,0xf6a2}, {0x8df1,0xf6a3}, {0x8df2,0xf6a4}, {0x8df3,0xf6a5}, - {0x8df4,0xf6a6}, {0x8df5,0xf6a7}, {0x8df6,0xf6a8}, {0x8df7,0xf6a9}, {0x8df8,0xf6aa}, {0x8df9,0xf6ab}, {0x8dfa,0xf6ac}, {0x8dfb,0xf6ad}, {0x8dfc,0xf6ae}, {0x8dfd,0xf6af}, - {0x8dfe,0xf6b0}, -}; - -static const B5Map b5_8E40_to_uc_map[2983] = { - {0x8e40,0xe311}, {0x8e41,0xe312}, {0x8e42,0xe313}, {0x8e43,0xe314}, {0x8e44,0xe315}, {0x8e45,0xe316}, {0x8e46,0xe317}, {0x8e47,0xe318}, {0x8e48,0xe319}, {0x8e49,0xe31a}, - {0x8e4a,0xe31b}, {0x8e4b,0xe31c}, {0x8e4c,0xe31d}, {0x8e4d,0xe31e}, {0x8e4e,0xe31f}, {0x8e4f,0xe320}, {0x8e50,0xe321}, {0x8e51,0xe322}, {0x8e52,0xe323}, {0x8e53,0xe324}, - {0x8e54,0xe325}, {0x8e55,0xe326}, {0x8e56,0xe327}, {0x8e57,0xe328}, {0x8e58,0xe329}, {0x8e59,0xe32a}, {0x8e5a,0xe32b}, {0x8e5b,0xe32c}, {0x8e5c,0xe32d}, {0x8e5d,0xe32e}, - {0x8e5e,0xe32f}, {0x8e5f,0xe330}, {0x8e60,0xe331}, {0x8e61,0xe332}, {0x8e62,0xe333}, {0x8e63,0xe334}, {0x8e64,0xe335}, {0x8e65,0xe336}, {0x8e66,0xe337}, {0x8e67,0xe338}, - {0x8e68,0xe339}, {0x8e69,0xe33a}, {0x8e6a,0xe33b}, {0x8e6b,0xe33c}, {0x8e6c,0xe33d}, {0x8e6d,0xe33e}, {0x8e6e,0xe33f}, {0x8e6f,0xe340}, {0x8e70,0xe341}, {0x8e71,0xe342}, - {0x8e72,0xe343}, {0x8e73,0xe344}, {0x8e74,0xe345}, {0x8e75,0xe346}, {0x8e76,0xe347}, {0x8e77,0xe348}, {0x8e78,0xe349}, {0x8e79,0xe34a}, {0x8e7a,0xe34b}, {0x8e7b,0xe34c}, - {0x8e7c,0xe34d}, {0x8e7d,0xe34e}, {0x8e7e,0xe34f}, {0x8ea1,0xe350}, {0x8ea2,0xe351}, {0x8ea3,0xe352}, {0x8ea4,0xe353}, {0x8ea5,0xe354}, {0x8ea6,0xe355}, {0x8ea7,0xe356}, - {0x8ea8,0xe357}, {0x8ea9,0xe358}, {0x8eaa,0xe359}, {0x8eab,0xe35a}, {0x8eac,0xe35b}, {0x8ead,0xe35c}, {0x8eae,0xe35d}, {0x8eaf,0xe35e}, {0x8eb0,0xe35f}, {0x8eb1,0xe360}, - {0x8eb2,0xe361}, {0x8eb3,0xe362}, {0x8eb4,0xe363}, {0x8eb5,0xe364}, {0x8eb6,0xe365}, {0x8eb7,0xe366}, {0x8eb8,0xe367}, {0x8eb9,0xe368}, {0x8eba,0xe369}, {0x8ebb,0xe36a}, - {0x8ebc,0xe36b}, {0x8ebd,0xe36c}, {0x8ebe,0xe36d}, {0x8ebf,0xe36e}, {0x8ec0,0xe36f}, {0x8ec1,0xe370}, {0x8ec2,0xe371}, {0x8ec3,0xe372}, {0x8ec4,0xe373}, {0x8ec5,0xe374}, - {0x8ec6,0xe375}, {0x8ec7,0xe376}, {0x8ec8,0xe377}, {0x8ec9,0xe378}, {0x8eca,0xe379}, {0x8ecb,0xe37a}, {0x8ecc,0xe37b}, {0x8ecd,0xe37c}, {0x8ece,0xe37d}, {0x8ecf,0xe37e}, - {0x8ed0,0xe37f}, {0x8ed1,0xe380}, {0x8ed2,0xe381}, {0x8ed3,0xe382}, {0x8ed4,0xe383}, {0x8ed5,0xe384}, {0x8ed6,0xe385}, {0x8ed7,0xe386}, {0x8ed8,0xe387}, {0x8ed9,0xe388}, - {0x8eda,0xe389}, {0x8edb,0xe38a}, {0x8edc,0xe38b}, {0x8edd,0xe38c}, {0x8ede,0xe38d}, {0x8edf,0xe38e}, {0x8ee0,0xe38f}, {0x8ee1,0xe390}, {0x8ee2,0xe391}, {0x8ee3,0xe392}, - {0x8ee4,0xe393}, {0x8ee5,0xe394}, {0x8ee6,0xe395}, {0x8ee7,0xe396}, {0x8ee8,0xe397}, {0x8ee9,0xe398}, {0x8eea,0xe399}, {0x8eeb,0xe39a}, {0x8eec,0xe39b}, {0x8eed,0xe39c}, - {0x8eee,0xe39d}, {0x8eef,0xe39e}, {0x8ef0,0xe39f}, {0x8ef1,0xe3a0}, {0x8ef2,0xe3a1}, {0x8ef3,0xe3a2}, {0x8ef4,0xe3a3}, {0x8ef5,0xe3a4}, {0x8ef6,0xe3a5}, {0x8ef7,0xe3a6}, - {0x8ef8,0xe3a7}, {0x8ef9,0xe3a8}, {0x8efa,0xe3a9}, {0x8efb,0xe3aa}, {0x8efc,0xe3ab}, {0x8efd,0xe3ac}, {0x8efe,0xe3ad}, {0x8f40,0xe3ae}, {0x8f41,0xe3af}, {0x8f42,0xe3b0}, - {0x8f43,0xe3b1}, {0x8f44,0xe3b2}, {0x8f45,0xe3b3}, {0x8f46,0xe3b4}, {0x8f47,0xe3b5}, {0x8f48,0xe3b6}, {0x8f49,0xe3b7}, {0x8f4a,0xe3b8}, {0x8f4b,0xe3b9}, {0x8f4c,0xe3ba}, - {0x8f4d,0xe3bb}, {0x8f4e,0xe3bc}, {0x8f4f,0xe3bd}, {0x8f50,0xe3be}, {0x8f51,0xe3bf}, {0x8f52,0xe3c0}, {0x8f53,0xe3c1}, {0x8f54,0xe3c2}, {0x8f55,0xe3c3}, {0x8f56,0xe3c4}, - {0x8f57,0xe3c5}, {0x8f58,0xe3c6}, {0x8f59,0xe3c7}, {0x8f5a,0xe3c8}, {0x8f5b,0xe3c9}, {0x8f5c,0xe3ca}, {0x8f5d,0xe3cb}, {0x8f5e,0xe3cc}, {0x8f5f,0xe3cd}, {0x8f60,0xe3ce}, - {0x8f61,0xe3cf}, {0x8f62,0xe3d0}, {0x8f63,0xe3d1}, {0x8f64,0xe3d2}, {0x8f65,0xe3d3}, {0x8f66,0xe3d4}, {0x8f67,0xe3d5}, {0x8f68,0xe3d6}, {0x8f69,0xe3d7}, {0x8f6a,0xe3d8}, - {0x8f6b,0xe3d9}, {0x8f6c,0xe3da}, {0x8f6d,0xe3db}, {0x8f6e,0xe3dc}, {0x8f6f,0xe3dd}, {0x8f70,0xe3de}, {0x8f71,0xe3df}, {0x8f72,0xe3e0}, {0x8f73,0xe3e1}, {0x8f74,0xe3e2}, - {0x8f75,0xe3e3}, {0x8f76,0xe3e4}, {0x8f77,0xe3e5}, {0x8f78,0xe3e6}, {0x8f79,0xe3e7}, {0x8f7a,0xe3e8}, {0x8f7b,0xe3e9}, {0x8f7c,0xe3ea}, {0x8f7d,0xe3eb}, {0x8f7e,0xe3ec}, - {0x8fa1,0xe3ed}, {0x8fa2,0xe3ee}, {0x8fa3,0xe3ef}, {0x8fa4,0xe3f0}, {0x8fa5,0xe3f1}, {0x8fa6,0xe3f2}, {0x8fa7,0xe3f3}, {0x8fa8,0xe3f4}, {0x8fa9,0xe3f5}, {0x8faa,0xe3f6}, - {0x8fab,0xe3f7}, {0x8fac,0xe3f8}, {0x8fad,0xe3f9}, {0x8fae,0xe3fa}, {0x8faf,0xe3fb}, {0x8fb0,0xe3fc}, {0x8fb1,0xe3fd}, {0x8fb2,0xe3fe}, {0x8fb3,0xe3ff}, {0x8fb4,0xe400}, - {0x8fb5,0xe401}, {0x8fb6,0xe402}, {0x8fb7,0xe403}, {0x8fb8,0xe404}, {0x8fb9,0xe405}, {0x8fba,0xe406}, {0x8fbb,0xe407}, {0x8fbc,0xe408}, {0x8fbd,0xe409}, {0x8fbe,0xe40a}, - {0x8fbf,0xe40b}, {0x8fc0,0xe40c}, {0x8fc1,0xe40d}, {0x8fc2,0xe40e}, {0x8fc3,0xe40f}, {0x8fc4,0xe410}, {0x8fc5,0xe411}, {0x8fc6,0xe412}, {0x8fc7,0xe413}, {0x8fc8,0xe414}, - {0x8fc9,0xe415}, {0x8fca,0xe416}, {0x8fcb,0xe417}, {0x8fcc,0xe418}, {0x8fcd,0xe419}, {0x8fce,0xe41a}, {0x8fcf,0xe41b}, {0x8fd0,0xe41c}, {0x8fd1,0xe41d}, {0x8fd2,0xe41e}, - {0x8fd3,0xe41f}, {0x8fd4,0xe420}, {0x8fd5,0xe421}, {0x8fd6,0xe422}, {0x8fd7,0xe423}, {0x8fd8,0xe424}, {0x8fd9,0xe425}, {0x8fda,0xe426}, {0x8fdb,0xe427}, {0x8fdc,0xe428}, - {0x8fdd,0xe429}, {0x8fde,0xe42a}, {0x8fdf,0xe42b}, {0x8fe0,0xe42c}, {0x8fe1,0xe42d}, {0x8fe2,0xe42e}, {0x8fe3,0xe42f}, {0x8fe4,0xe430}, {0x8fe5,0xe431}, {0x8fe6,0xe432}, - {0x8fe7,0xe433}, {0x8fe8,0xe434}, {0x8fe9,0xe435}, {0x8fea,0xe436}, {0x8feb,0xe437}, {0x8fec,0xe438}, {0x8fed,0xe439}, {0x8fee,0xe43a}, {0x8fef,0xe43b}, {0x8ff0,0xe43c}, - {0x8ff1,0xe43d}, {0x8ff2,0xe43e}, {0x8ff3,0xe43f}, {0x8ff4,0xe440}, {0x8ff5,0xe441}, {0x8ff6,0xe442}, {0x8ff7,0xe443}, {0x8ff8,0xe444}, {0x8ff9,0xe445}, {0x8ffa,0xe446}, - {0x8ffb,0xe447}, {0x8ffc,0xe448}, {0x8ffd,0xe449}, {0x8ffe,0xe44a}, {0x9040,0xe44b}, {0x9041,0xe44c}, {0x9042,0xe44d}, {0x9043,0xe44e}, {0x9044,0xe44f}, {0x9045,0xe450}, - {0x9046,0xe451}, {0x9047,0xe452}, {0x9048,0xe453}, {0x9049,0xe454}, {0x904a,0xe455}, {0x904b,0xe456}, {0x904c,0xe457}, {0x904d,0xe458}, {0x904e,0xe459}, {0x904f,0xe45a}, - {0x9050,0xe45b}, {0x9051,0xe45c}, {0x9052,0xe45d}, {0x9053,0xe45e}, {0x9054,0xe45f}, {0x9055,0xe460}, {0x9056,0xe461}, {0x9057,0xe462}, {0x9058,0xe463}, {0x9059,0xe464}, - {0x905a,0xe465}, {0x905b,0xe466}, {0x905c,0xe467}, {0x905d,0xe468}, {0x905e,0xe469}, {0x905f,0xe46a}, {0x9060,0xe46b}, {0x9061,0xe46c}, {0x9062,0xe46d}, {0x9063,0xe46e}, - {0x9064,0xe46f}, {0x9065,0xe470}, {0x9066,0xe471}, {0x9067,0xe472}, {0x9068,0xe473}, {0x9069,0xe474}, {0x906a,0xe475}, {0x906b,0xe476}, {0x906c,0xe477}, {0x906d,0xe478}, - {0x906e,0xe479}, {0x906f,0xe47a}, {0x9070,0xe47b}, {0x9071,0xe47c}, {0x9072,0xe47d}, {0x9073,0xe47e}, {0x9074,0xe47f}, {0x9075,0xe480}, {0x9076,0xe481}, {0x9077,0xe482}, - {0x9078,0xe483}, {0x9079,0xe484}, {0x907a,0xe485}, {0x907b,0xe486}, {0x907c,0xe487}, {0x907d,0xe488}, {0x907e,0xe489}, {0x90a1,0xe48a}, {0x90a2,0xe48b}, {0x90a3,0xe48c}, - {0x90a4,0xe48d}, {0x90a5,0xe48e}, {0x90a6,0xe48f}, {0x90a7,0xe490}, {0x90a8,0xe491}, {0x90a9,0xe492}, {0x90aa,0xe493}, {0x90ab,0xe494}, {0x90ac,0xe495}, {0x90ad,0xe496}, - {0x90ae,0xe497}, {0x90af,0xe498}, {0x90b0,0xe499}, {0x90b1,0xe49a}, {0x90b2,0xe49b}, {0x90b3,0xe49c}, {0x90b4,0xe49d}, {0x90b5,0xe49e}, {0x90b6,0xe49f}, {0x90b7,0xe4a0}, - {0x90b8,0xe4a1}, {0x90b9,0xe4a2}, {0x90ba,0xe4a3}, {0x90bb,0xe4a4}, {0x90bc,0xe4a5}, {0x90bd,0xe4a6}, {0x90be,0xe4a7}, {0x90bf,0xe4a8}, {0x90c0,0xe4a9}, {0x90c1,0xe4aa}, - {0x90c2,0xe4ab}, {0x90c3,0xe4ac}, {0x90c4,0xe4ad}, {0x90c5,0xe4ae}, {0x90c6,0xe4af}, {0x90c7,0xe4b0}, {0x90c8,0xe4b1}, {0x90c9,0xe4b2}, {0x90ca,0xe4b3}, {0x90cb,0xe4b4}, - {0x90cc,0xe4b5}, {0x90cd,0xe4b6}, {0x90ce,0xe4b7}, {0x90cf,0xe4b8}, {0x90d0,0xe4b9}, {0x90d1,0xe4ba}, {0x90d2,0xe4bb}, {0x90d3,0xe4bc}, {0x90d4,0xe4bd}, {0x90d5,0xe4be}, - {0x90d6,0xe4bf}, {0x90d7,0xe4c0}, {0x90d8,0xe4c1}, {0x90d9,0xe4c2}, {0x90da,0xe4c3}, {0x90db,0xe4c4}, {0x90dc,0xe4c5}, {0x90dd,0xe4c6}, {0x90de,0xe4c7}, {0x90df,0xe4c8}, - {0x90e0,0xe4c9}, {0x90e1,0xe4ca}, {0x90e2,0xe4cb}, {0x90e3,0xe4cc}, {0x90e4,0xe4cd}, {0x90e5,0xe4ce}, {0x90e6,0xe4cf}, {0x90e7,0xe4d0}, {0x90e8,0xe4d1}, {0x90e9,0xe4d2}, - {0x90ea,0xe4d3}, {0x90eb,0xe4d4}, {0x90ec,0xe4d5}, {0x90ed,0xe4d6}, {0x90ee,0xe4d7}, {0x90ef,0xe4d8}, {0x90f0,0xe4d9}, {0x90f1,0xe4da}, {0x90f2,0xe4db}, {0x90f3,0xe4dc}, - {0x90f4,0xe4dd}, {0x90f5,0xe4de}, {0x90f6,0xe4df}, {0x90f7,0xe4e0}, {0x90f8,0xe4e1}, {0x90f9,0xe4e2}, {0x90fa,0xe4e3}, {0x90fb,0xe4e4}, {0x90fc,0xe4e5}, {0x90fd,0xe4e6}, - {0x90fe,0xe4e7}, {0x9140,0xe4e8}, {0x9141,0xe4e9}, {0x9142,0xe4ea}, {0x9143,0xe4eb}, {0x9144,0xe4ec}, {0x9145,0xe4ed}, {0x9146,0xe4ee}, {0x9147,0xe4ef}, {0x9148,0xe4f0}, - {0x9149,0xe4f1}, {0x914a,0xe4f2}, {0x914b,0xe4f3}, {0x914c,0xe4f4}, {0x914d,0xe4f5}, {0x914e,0xe4f6}, {0x914f,0xe4f7}, {0x9150,0xe4f8}, {0x9151,0xe4f9}, {0x9152,0xe4fa}, - {0x9153,0xe4fb}, {0x9154,0xe4fc}, {0x9155,0xe4fd}, {0x9156,0xe4fe}, {0x9157,0xe4ff}, {0x9158,0xe500}, {0x9159,0xe501}, {0x915a,0xe502}, {0x915b,0xe503}, {0x915c,0xe504}, - {0x915d,0xe505}, {0x915e,0xe506}, {0x915f,0xe507}, {0x9160,0xe508}, {0x9161,0xe509}, {0x9162,0xe50a}, {0x9163,0xe50b}, {0x9164,0xe50c}, {0x9165,0xe50d}, {0x9166,0xe50e}, - {0x9167,0xe50f}, {0x9168,0xe510}, {0x9169,0xe511}, {0x916a,0xe512}, {0x916b,0xe513}, {0x916c,0xe514}, {0x916d,0xe515}, {0x916e,0xe516}, {0x916f,0xe517}, {0x9170,0xe518}, - {0x9171,0xe519}, {0x9172,0xe51a}, {0x9173,0xe51b}, {0x9174,0xe51c}, {0x9175,0xe51d}, {0x9176,0xe51e}, {0x9177,0xe51f}, {0x9178,0xe520}, {0x9179,0xe521}, {0x917a,0xe522}, - {0x917b,0xe523}, {0x917c,0xe524}, {0x917d,0xe525}, {0x917e,0xe526}, {0x91a1,0xe527}, {0x91a2,0xe528}, {0x91a3,0xe529}, {0x91a4,0xe52a}, {0x91a5,0xe52b}, {0x91a6,0xe52c}, - {0x91a7,0xe52d}, {0x91a8,0xe52e}, {0x91a9,0xe52f}, {0x91aa,0xe530}, {0x91ab,0xe531}, {0x91ac,0xe532}, {0x91ad,0xe533}, {0x91ae,0xe534}, {0x91af,0xe535}, {0x91b0,0xe536}, - {0x91b1,0xe537}, {0x91b2,0xe538}, {0x91b3,0xe539}, {0x91b4,0xe53a}, {0x91b5,0xe53b}, {0x91b6,0xe53c}, {0x91b7,0xe53d}, {0x91b8,0xe53e}, {0x91b9,0xe53f}, {0x91ba,0xe540}, - {0x91bb,0xe541}, {0x91bc,0xe542}, {0x91bd,0xe543}, {0x91be,0xe544}, {0x91bf,0xe545}, {0x91c0,0xe546}, {0x91c1,0xe547}, {0x91c2,0xe548}, {0x91c3,0xe549}, {0x91c4,0xe54a}, - {0x91c5,0xe54b}, {0x91c6,0xe54c}, {0x91c7,0xe54d}, {0x91c8,0xe54e}, {0x91c9,0xe54f}, {0x91ca,0xe550}, {0x91cb,0xe551}, {0x91cc,0xe552}, {0x91cd,0xe553}, {0x91ce,0xe554}, - {0x91cf,0xe555}, {0x91d0,0xe556}, {0x91d1,0xe557}, {0x91d2,0xe558}, {0x91d3,0xe559}, {0x91d4,0xe55a}, {0x91d5,0xe55b}, {0x91d6,0xe55c}, {0x91d7,0xe55d}, {0x91d8,0xe55e}, - {0x91d9,0xe55f}, {0x91da,0xe560}, {0x91db,0xe561}, {0x91dc,0xe562}, {0x91dd,0xe563}, {0x91de,0xe564}, {0x91df,0xe565}, {0x91e0,0xe566}, {0x91e1,0xe567}, {0x91e2,0xe568}, - {0x91e3,0xe569}, {0x91e4,0xe56a}, {0x91e5,0xe56b}, {0x91e6,0xe56c}, {0x91e7,0xe56d}, {0x91e8,0xe56e}, {0x91e9,0xe56f}, {0x91ea,0xe570}, {0x91eb,0xe571}, {0x91ec,0xe572}, - {0x91ed,0xe573}, {0x91ee,0xe574}, {0x91ef,0xe575}, {0x91f0,0xe576}, {0x91f1,0xe577}, {0x91f2,0xe578}, {0x91f3,0xe579}, {0x91f4,0xe57a}, {0x91f5,0xe57b}, {0x91f6,0xe57c}, - {0x91f7,0xe57d}, {0x91f8,0xe57e}, {0x91f9,0xe57f}, {0x91fa,0xe580}, {0x91fb,0xe581}, {0x91fc,0xe582}, {0x91fd,0xe583}, {0x91fe,0xe584}, {0x9240,0xe585}, {0x9241,0xe586}, - {0x9242,0xe587}, {0x9243,0xe588}, {0x9244,0xe589}, {0x9245,0xe58a}, {0x9246,0xe58b}, {0x9247,0xe58c}, {0x9248,0xe58d}, {0x9249,0xe58e}, {0x924a,0xe58f}, {0x924b,0xe590}, - {0x924c,0xe591}, {0x924d,0xe592}, {0x924e,0xe593}, {0x924f,0xe594}, {0x9250,0xe595}, {0x9251,0xe596}, {0x9252,0xe597}, {0x9253,0xe598}, {0x9254,0xe599}, {0x9255,0xe59a}, - {0x9256,0xe59b}, {0x9257,0xe59c}, {0x9258,0xe59d}, {0x9259,0xe59e}, {0x925a,0xe59f}, {0x925b,0xe5a0}, {0x925c,0xe5a1}, {0x925d,0xe5a2}, {0x925e,0xe5a3}, {0x925f,0xe5a4}, - {0x9260,0xe5a5}, {0x9261,0xe5a6}, {0x9262,0xe5a7}, {0x9263,0xe5a8}, {0x9264,0xe5a9}, {0x9265,0xe5aa}, {0x9266,0xe5ab}, {0x9267,0xe5ac}, {0x9268,0xe5ad}, {0x9269,0xe5ae}, - {0x926a,0xe5af}, {0x926b,0xe5b0}, {0x926c,0xe5b1}, {0x926d,0xe5b2}, {0x926e,0xe5b3}, {0x926f,0xe5b4}, {0x9270,0xe5b5}, {0x9271,0xe5b6}, {0x9272,0xe5b7}, {0x9273,0xe5b8}, - {0x9274,0xe5b9}, {0x9275,0xe5ba}, {0x9276,0xe5bb}, {0x9277,0xe5bc}, {0x9278,0xe5bd}, {0x9279,0xe5be}, {0x927a,0xe5bf}, {0x927b,0xe5c0}, {0x927c,0xe5c1}, {0x927d,0xe5c2}, - {0x927e,0xe5c3}, {0x92a1,0xe5c4}, {0x92a2,0xe5c5}, {0x92a3,0xe5c6}, {0x92a4,0xe5c7}, {0x92a5,0xe5c8}, {0x92a6,0xe5c9}, {0x92a7,0xe5ca}, {0x92a8,0xe5cb}, {0x92a9,0xe5cc}, - {0x92aa,0xe5cd}, {0x92ab,0xe5ce}, {0x92ac,0xe5cf}, {0x92ad,0xe5d0}, {0x92ae,0xe5d1}, {0x92af,0xe5d2}, {0x92b0,0xe5d3}, {0x92b1,0xe5d4}, {0x92b2,0xe5d5}, {0x92b3,0xe5d6}, - {0x92b4,0xe5d7}, {0x92b5,0xe5d8}, {0x92b6,0xe5d9}, {0x92b7,0xe5da}, {0x92b8,0xe5db}, {0x92b9,0xe5dc}, {0x92ba,0xe5dd}, {0x92bb,0xe5de}, {0x92bc,0xe5df}, {0x92bd,0xe5e0}, - {0x92be,0xe5e1}, {0x92bf,0xe5e2}, {0x92c0,0xe5e3}, {0x92c1,0xe5e4}, {0x92c2,0xe5e5}, {0x92c3,0xe5e6}, {0x92c4,0xe5e7}, {0x92c5,0xe5e8}, {0x92c6,0xe5e9}, {0x92c7,0xe5ea}, - {0x92c8,0xe5eb}, {0x92c9,0xe5ec}, {0x92ca,0xe5ed}, {0x92cb,0xe5ee}, {0x92cc,0xe5ef}, {0x92cd,0xe5f0}, {0x92ce,0xe5f1}, {0x92cf,0xe5f2}, {0x92d0,0xe5f3}, {0x92d1,0xe5f4}, - {0x92d2,0xe5f5}, {0x92d3,0xe5f6}, {0x92d4,0xe5f7}, {0x92d5,0xe5f8}, {0x92d6,0xe5f9}, {0x92d7,0xe5fa}, {0x92d8,0xe5fb}, {0x92d9,0xe5fc}, {0x92da,0xe5fd}, {0x92db,0xe5fe}, - {0x92dc,0xe5ff}, {0x92dd,0xe600}, {0x92de,0xe601}, {0x92df,0xe602}, {0x92e0,0xe603}, {0x92e1,0xe604}, {0x92e2,0xe605}, {0x92e3,0xe606}, {0x92e4,0xe607}, {0x92e5,0xe608}, - {0x92e6,0xe609}, {0x92e7,0xe60a}, {0x92e8,0xe60b}, {0x92e9,0xe60c}, {0x92ea,0xe60d}, {0x92eb,0xe60e}, {0x92ec,0xe60f}, {0x92ed,0xe610}, {0x92ee,0xe611}, {0x92ef,0xe612}, - {0x92f0,0xe613}, {0x92f1,0xe614}, {0x92f2,0xe615}, {0x92f3,0xe616}, {0x92f4,0xe617}, {0x92f5,0xe618}, {0x92f6,0xe619}, {0x92f7,0xe61a}, {0x92f8,0xe61b}, {0x92f9,0xe61c}, - {0x92fa,0xe61d}, {0x92fb,0xe61e}, {0x92fc,0xe61f}, {0x92fd,0xe620}, {0x92fe,0xe621}, {0x9340,0xe622}, {0x9341,0xe623}, {0x9342,0xe624}, {0x9343,0xe625}, {0x9344,0xe626}, - {0x9345,0xe627}, {0x9346,0xe628}, {0x9347,0xe629}, {0x9348,0xe62a}, {0x9349,0xe62b}, {0x934a,0xe62c}, {0x934b,0xe62d}, {0x934c,0xe62e}, {0x934d,0xe62f}, {0x934e,0xe630}, - {0x934f,0xe631}, {0x9350,0xe632}, {0x9351,0xe633}, {0x9352,0xe634}, {0x9353,0xe635}, {0x9354,0xe636}, {0x9355,0xe637}, {0x9356,0xe638}, {0x9357,0xe639}, {0x9358,0xe63a}, - {0x9359,0xe63b}, {0x935a,0xe63c}, {0x935b,0xe63d}, {0x935c,0xe63e}, {0x935d,0xe63f}, {0x935e,0xe640}, {0x935f,0xe641}, {0x9360,0xe642}, {0x9361,0xe643}, {0x9362,0xe644}, - {0x9363,0xe645}, {0x9364,0xe646}, {0x9365,0xe647}, {0x9366,0xe648}, {0x9367,0xe649}, {0x9368,0xe64a}, {0x9369,0xe64b}, {0x936a,0xe64c}, {0x936b,0xe64d}, {0x936c,0xe64e}, - {0x936d,0xe64f}, {0x936e,0xe650}, {0x936f,0xe651}, {0x9370,0xe652}, {0x9371,0xe653}, {0x9372,0xe654}, {0x9373,0xe655}, {0x9374,0xe656}, {0x9375,0xe657}, {0x9376,0xe658}, - {0x9377,0xe659}, {0x9378,0xe65a}, {0x9379,0xe65b}, {0x937a,0xe65c}, {0x937b,0xe65d}, {0x937c,0xe65e}, {0x937d,0xe65f}, {0x937e,0xe660}, {0x93a1,0xe661}, {0x93a2,0xe662}, - {0x93a3,0xe663}, {0x93a4,0xe664}, {0x93a5,0xe665}, {0x93a6,0xe666}, {0x93a7,0xe667}, {0x93a8,0xe668}, {0x93a9,0xe669}, {0x93aa,0xe66a}, {0x93ab,0xe66b}, {0x93ac,0xe66c}, - {0x93ad,0xe66d}, {0x93ae,0xe66e}, {0x93af,0xe66f}, {0x93b0,0xe670}, {0x93b1,0xe671}, {0x93b2,0xe672}, {0x93b3,0xe673}, {0x93b4,0xe674}, {0x93b5,0xe675}, {0x93b6,0xe676}, - {0x93b7,0xe677}, {0x93b8,0xe678}, {0x93b9,0xe679}, {0x93ba,0xe67a}, {0x93bb,0xe67b}, {0x93bc,0xe67c}, {0x93bd,0xe67d}, {0x93be,0xe67e}, {0x93bf,0xe67f}, {0x93c0,0xe680}, - {0x93c1,0xe681}, {0x93c2,0xe682}, {0x93c3,0xe683}, {0x93c4,0xe684}, {0x93c5,0xe685}, {0x93c6,0xe686}, {0x93c7,0xe687}, {0x93c8,0xe688}, {0x93c9,0xe689}, {0x93ca,0xe68a}, - {0x93cb,0xe68b}, {0x93cc,0xe68c}, {0x93cd,0xe68d}, {0x93ce,0xe68e}, {0x93cf,0xe68f}, {0x93d0,0xe690}, {0x93d1,0xe691}, {0x93d2,0xe692}, {0x93d3,0xe693}, {0x93d4,0xe694}, - {0x93d5,0xe695}, {0x93d6,0xe696}, {0x93d7,0xe697}, {0x93d8,0xe698}, {0x93d9,0xe699}, {0x93da,0xe69a}, {0x93db,0xe69b}, {0x93dc,0xe69c}, {0x93dd,0xe69d}, {0x93de,0xe69e}, - {0x93df,0xe69f}, {0x93e0,0xe6a0}, {0x93e1,0xe6a1}, {0x93e2,0xe6a2}, {0x93e3,0xe6a3}, {0x93e4,0xe6a4}, {0x93e5,0xe6a5}, {0x93e6,0xe6a6}, {0x93e7,0xe6a7}, {0x93e8,0xe6a8}, - {0x93e9,0xe6a9}, {0x93ea,0xe6aa}, {0x93eb,0xe6ab}, {0x93ec,0xe6ac}, {0x93ed,0xe6ad}, {0x93ee,0xe6ae}, {0x93ef,0xe6af}, {0x93f0,0xe6b0}, {0x93f1,0xe6b1}, {0x93f2,0xe6b2}, - {0x93f3,0xe6b3}, {0x93f4,0xe6b4}, {0x93f5,0xe6b5}, {0x93f6,0xe6b6}, {0x93f7,0xe6b7}, {0x93f8,0xe6b8}, {0x93f9,0xe6b9}, {0x93fa,0xe6ba}, {0x93fb,0xe6bb}, {0x93fc,0xe6bc}, - {0x93fd,0xe6bd}, {0x93fe,0xe6be}, {0x9440,0xe6bf}, {0x9441,0xe6c0}, {0x9442,0xe6c1}, {0x9443,0xe6c2}, {0x9444,0xe6c3}, {0x9445,0xe6c4}, {0x9446,0xe6c5}, {0x9447,0xe6c6}, - {0x9448,0xe6c7}, {0x9449,0xe6c8}, {0x944a,0xe6c9}, {0x944b,0xe6ca}, {0x944c,0xe6cb}, {0x944d,0xe6cc}, {0x944e,0xe6cd}, {0x944f,0xe6ce}, {0x9450,0xe6cf}, {0x9451,0xe6d0}, - {0x9452,0xe6d1}, {0x9453,0xe6d2}, {0x9454,0xe6d3}, {0x9455,0xe6d4}, {0x9456,0xe6d5}, {0x9457,0xe6d6}, {0x9458,0xe6d7}, {0x9459,0xe6d8}, {0x945a,0xe6d9}, {0x945b,0xe6da}, - {0x945c,0xe6db}, {0x945d,0xe6dc}, {0x945e,0xe6dd}, {0x945f,0xe6de}, {0x9460,0xe6df}, {0x9461,0xe6e0}, {0x9462,0xe6e1}, {0x9463,0xe6e2}, {0x9464,0xe6e3}, {0x9465,0xe6e4}, - {0x9466,0xe6e5}, {0x9467,0xe6e6}, {0x9468,0xe6e7}, {0x9469,0xe6e8}, {0x946a,0xe6e9}, {0x946b,0xe6ea}, {0x946c,0xe6eb}, {0x946d,0xe6ec}, {0x946e,0xe6ed}, {0x946f,0xe6ee}, - {0x9470,0xe6ef}, {0x9471,0xe6f0}, {0x9472,0xe6f1}, {0x9473,0xe6f2}, {0x9474,0xe6f3}, {0x9475,0xe6f4}, {0x9476,0xe6f5}, {0x9477,0xe6f6}, {0x9478,0xe6f7}, {0x9479,0xe6f8}, - {0x947a,0xe6f9}, {0x947b,0xe6fa}, {0x947c,0xe6fb}, {0x947d,0xe6fc}, {0x947e,0xe6fd}, {0x94a1,0xe6fe}, {0x94a2,0xe6ff}, {0x94a3,0xe700}, {0x94a4,0xe701}, {0x94a5,0xe702}, - {0x94a6,0xe703}, {0x94a7,0xe704}, {0x94a8,0xe705}, {0x94a9,0xe706}, {0x94aa,0xe707}, {0x94ab,0xe708}, {0x94ac,0xe709}, {0x94ad,0xe70a}, {0x94ae,0xe70b}, {0x94af,0xe70c}, - {0x94b0,0xe70d}, {0x94b1,0xe70e}, {0x94b2,0xe70f}, {0x94b3,0xe710}, {0x94b4,0xe711}, {0x94b5,0xe712}, {0x94b6,0xe713}, {0x94b7,0xe714}, {0x94b8,0xe715}, {0x94b9,0xe716}, - {0x94ba,0xe717}, {0x94bb,0xe718}, {0x94bc,0xe719}, {0x94bd,0xe71a}, {0x94be,0xe71b}, {0x94bf,0xe71c}, {0x94c0,0xe71d}, {0x94c1,0xe71e}, {0x94c2,0xe71f}, {0x94c3,0xe720}, - {0x94c4,0xe721}, {0x94c5,0xe722}, {0x94c6,0xe723}, {0x94c7,0xe724}, {0x94c8,0xe725}, {0x94c9,0xe726}, {0x94ca,0xe727}, {0x94cb,0xe728}, {0x94cc,0xe729}, {0x94cd,0xe72a}, - {0x94ce,0xe72b}, {0x94cf,0xe72c}, {0x94d0,0xe72d}, {0x94d1,0xe72e}, {0x94d2,0xe72f}, {0x94d3,0xe730}, {0x94d4,0xe731}, {0x94d5,0xe732}, {0x94d6,0xe733}, {0x94d7,0xe734}, - {0x94d8,0xe735}, {0x94d9,0xe736}, {0x94da,0xe737}, {0x94db,0xe738}, {0x94dc,0xe739}, {0x94dd,0xe73a}, {0x94de,0xe73b}, {0x94df,0xe73c}, {0x94e0,0xe73d}, {0x94e1,0xe73e}, - {0x94e2,0xe73f}, {0x94e3,0xe740}, {0x94e4,0xe741}, {0x94e5,0xe742}, {0x94e6,0xe743}, {0x94e7,0xe744}, {0x94e8,0xe745}, {0x94e9,0xe746}, {0x94ea,0xe747}, {0x94eb,0xe748}, - {0x94ec,0xe749}, {0x94ed,0xe74a}, {0x94ee,0xe74b}, {0x94ef,0xe74c}, {0x94f0,0xe74d}, {0x94f1,0xe74e}, {0x94f2,0xe74f}, {0x94f3,0xe750}, {0x94f4,0xe751}, {0x94f5,0xe752}, - {0x94f6,0xe753}, {0x94f7,0xe754}, {0x94f8,0xe755}, {0x94f9,0xe756}, {0x94fa,0xe757}, {0x94fb,0xe758}, {0x94fc,0xe759}, {0x94fd,0xe75a}, {0x94fe,0xe75b}, {0x9540,0xe75c}, - {0x9541,0xe75d}, {0x9542,0xe75e}, {0x9543,0xe75f}, {0x9544,0xe760}, {0x9545,0xe761}, {0x9546,0xe762}, {0x9547,0xe763}, {0x9548,0xe764}, {0x9549,0xe765}, {0x954a,0xe766}, - {0x954b,0xe767}, {0x954c,0xe768}, {0x954d,0xe769}, {0x954e,0xe76a}, {0x954f,0xe76b}, {0x9550,0xe76c}, {0x9551,0xe76d}, {0x9552,0xe76e}, {0x9553,0xe76f}, {0x9554,0xe770}, - {0x9555,0xe771}, {0x9556,0xe772}, {0x9557,0xe773}, {0x9558,0xe774}, {0x9559,0xe775}, {0x955a,0xe776}, {0x955b,0xe777}, {0x955c,0xe778}, {0x955d,0xe779}, {0x955e,0xe77a}, - {0x955f,0xe77b}, {0x9560,0xe77c}, {0x9561,0xe77d}, {0x9562,0xe77e}, {0x9563,0xe77f}, {0x9564,0xe780}, {0x9565,0xe781}, {0x9566,0xe782}, {0x9567,0xe783}, {0x9568,0xe784}, - {0x9569,0xe785}, {0x956a,0xe786}, {0x956b,0xe787}, {0x956c,0xe788}, {0x956d,0xe789}, {0x956e,0xe78a}, {0x956f,0xe78b}, {0x9570,0xe78c}, {0x9571,0xe78d}, {0x9572,0xe78e}, - {0x9573,0xe78f}, {0x9574,0xe790}, {0x9575,0xe791}, {0x9576,0xe792}, {0x9577,0xe793}, {0x9578,0xe794}, {0x9579,0xe795}, {0x957a,0xe796}, {0x957b,0xe797}, {0x957c,0xe798}, - {0x957d,0xe799}, {0x957e,0xe79a}, {0x95a1,0xe79b}, {0x95a2,0xe79c}, {0x95a3,0xe79d}, {0x95a4,0xe79e}, {0x95a5,0xe79f}, {0x95a6,0xe7a0}, {0x95a7,0xe7a1}, {0x95a8,0xe7a2}, - {0x95a9,0xe7a3}, {0x95aa,0xe7a4}, {0x95ab,0xe7a5}, {0x95ac,0xe7a6}, {0x95ad,0xe7a7}, {0x95ae,0xe7a8}, {0x95af,0xe7a9}, {0x95b0,0xe7aa}, {0x95b1,0xe7ab}, {0x95b2,0xe7ac}, - {0x95b3,0xe7ad}, {0x95b4,0xe7ae}, {0x95b5,0xe7af}, {0x95b6,0xe7b0}, {0x95b7,0xe7b1}, {0x95b8,0xe7b2}, {0x95b9,0xe7b3}, {0x95ba,0xe7b4}, {0x95bb,0xe7b5}, {0x95bc,0xe7b6}, - {0x95bd,0xe7b7}, {0x95be,0xe7b8}, {0x95bf,0xe7b9}, {0x95c0,0xe7ba}, {0x95c1,0xe7bb}, {0x95c2,0xe7bc}, {0x95c3,0xe7bd}, {0x95c4,0xe7be}, {0x95c5,0xe7bf}, {0x95c6,0xe7c0}, - {0x95c7,0xe7c1}, {0x95c8,0xe7c2}, {0x95c9,0xe7c3}, {0x95ca,0xe7c4}, {0x95cb,0xe7c5}, {0x95cc,0xe7c6}, {0x95cd,0xe7c7}, {0x95ce,0xe7c8}, {0x95cf,0xe7c9}, {0x95d0,0xe7ca}, - {0x95d1,0xe7cb}, {0x95d2,0xe7cc}, {0x95d3,0xe7cd}, {0x95d4,0xe7ce}, {0x95d5,0xe7cf}, {0x95d6,0xe7d0}, {0x95d7,0xe7d1}, {0x95d8,0xe7d2}, {0x95d9,0xe7d3}, {0x95da,0xe7d4}, - {0x95db,0xe7d5}, {0x95dc,0xe7d6}, {0x95dd,0xe7d7}, {0x95de,0xe7d8}, {0x95df,0xe7d9}, {0x95e0,0xe7da}, {0x95e1,0xe7db}, {0x95e2,0xe7dc}, {0x95e3,0xe7dd}, {0x95e4,0xe7de}, - {0x95e5,0xe7df}, {0x95e6,0xe7e0}, {0x95e7,0xe7e1}, {0x95e8,0xe7e2}, {0x95e9,0xe7e3}, {0x95ea,0xe7e4}, {0x95eb,0xe7e5}, {0x95ec,0xe7e6}, {0x95ed,0xe7e7}, {0x95ee,0xe7e8}, - {0x95ef,0xe7e9}, {0x95f0,0xe7ea}, {0x95f1,0xe7eb}, {0x95f2,0xe7ec}, {0x95f3,0xe7ed}, {0x95f4,0xe7ee}, {0x95f5,0xe7ef}, {0x95f6,0xe7f0}, {0x95f7,0xe7f1}, {0x95f8,0xe7f2}, - {0x95f9,0xe7f3}, {0x95fa,0xe7f4}, {0x95fb,0xe7f5}, {0x95fc,0xe7f6}, {0x95fd,0xe7f7}, {0x95fe,0xe7f8}, {0x9640,0xe7f9}, {0x9641,0xe7fa}, {0x9642,0xe7fb}, {0x9643,0xe7fc}, - {0x9644,0xe7fd}, {0x9645,0xe7fe}, {0x9646,0xe7ff}, {0x9647,0xe800}, {0x9648,0xe801}, {0x9649,0xe802}, {0x964a,0xe803}, {0x964b,0xe804}, {0x964c,0xe805}, {0x964d,0xe806}, - {0x964e,0xe807}, {0x964f,0xe808}, {0x9650,0xe809}, {0x9651,0xe80a}, {0x9652,0xe80b}, {0x9653,0xe80c}, {0x9654,0xe80d}, {0x9655,0xe80e}, {0x9656,0xe80f}, {0x9657,0xe810}, - {0x9658,0xe811}, {0x9659,0xe812}, {0x965a,0xe813}, {0x965b,0xe814}, {0x965c,0xe815}, {0x965d,0xe816}, {0x965e,0xe817}, {0x965f,0xe818}, {0x9660,0xe819}, {0x9661,0xe81a}, - {0x9662,0xe81b}, {0x9663,0xe81c}, {0x9664,0xe81d}, {0x9665,0xe81e}, {0x9666,0xe81f}, {0x9667,0xe820}, {0x9668,0xe821}, {0x9669,0xe822}, {0x966a,0xe823}, {0x966b,0xe824}, - {0x966c,0xe825}, {0x966d,0xe826}, {0x966e,0xe827}, {0x966f,0xe828}, {0x9670,0xe829}, {0x9671,0xe82a}, {0x9672,0xe82b}, {0x9673,0xe82c}, {0x9674,0xe82d}, {0x9675,0xe82e}, - {0x9676,0xe82f}, {0x9677,0xe830}, {0x9678,0xe831}, {0x9679,0xe832}, {0x967a,0xe833}, {0x967b,0xe834}, {0x967c,0xe835}, {0x967d,0xe836}, {0x967e,0xe837}, {0x96a1,0xe838}, - {0x96a2,0xe839}, {0x96a3,0xe83a}, {0x96a4,0xe83b}, {0x96a5,0xe83c}, {0x96a6,0xe83d}, {0x96a7,0xe83e}, {0x96a8,0xe83f}, {0x96a9,0xe840}, {0x96aa,0xe841}, {0x96ab,0xe842}, - {0x96ac,0xe843}, {0x96ad,0xe844}, {0x96ae,0xe845}, {0x96af,0xe846}, {0x96b0,0xe847}, {0x96b1,0xe848}, {0x96b2,0xe849}, {0x96b3,0xe84a}, {0x96b4,0xe84b}, {0x96b5,0xe84c}, - {0x96b6,0xe84d}, {0x96b7,0xe84e}, {0x96b8,0xe84f}, {0x96b9,0xe850}, {0x96ba,0xe851}, {0x96bb,0xe852}, {0x96bc,0xe853}, {0x96bd,0xe854}, {0x96be,0xe855}, {0x96bf,0xe856}, - {0x96c0,0xe857}, {0x96c1,0xe858}, {0x96c2,0xe859}, {0x96c3,0xe85a}, {0x96c4,0xe85b}, {0x96c5,0xe85c}, {0x96c6,0xe85d}, {0x96c7,0xe85e}, {0x96c8,0xe85f}, {0x96c9,0xe860}, - {0x96ca,0xe861}, {0x96cb,0xe862}, {0x96cc,0xe863}, {0x96cd,0xe864}, {0x96ce,0xe865}, {0x96cf,0xe866}, {0x96d0,0xe867}, {0x96d1,0xe868}, {0x96d2,0xe869}, {0x96d3,0xe86a}, - {0x96d4,0xe86b}, {0x96d5,0xe86c}, {0x96d6,0xe86d}, {0x96d7,0xe86e}, {0x96d8,0xe86f}, {0x96d9,0xe870}, {0x96da,0xe871}, {0x96db,0xe872}, {0x96dc,0xe873}, {0x96dd,0xe874}, - {0x96de,0xe875}, {0x96df,0xe876}, {0x96e0,0xe877}, {0x96e1,0xe878}, {0x96e2,0xe879}, {0x96e3,0xe87a}, {0x96e4,0xe87b}, {0x96e5,0xe87c}, {0x96e6,0xe87d}, {0x96e7,0xe87e}, - {0x96e8,0xe87f}, {0x96e9,0xe880}, {0x96ea,0xe881}, {0x96eb,0xe882}, {0x96ec,0xe883}, {0x96ed,0xe884}, {0x96ee,0xe885}, {0x96ef,0xe886}, {0x96f0,0xe887}, {0x96f1,0xe888}, - {0x96f2,0xe889}, {0x96f3,0xe88a}, {0x96f4,0xe88b}, {0x96f5,0xe88c}, {0x96f6,0xe88d}, {0x96f7,0xe88e}, {0x96f8,0xe88f}, {0x96f9,0xe890}, {0x96fa,0xe891}, {0x96fb,0xe892}, - {0x96fc,0xe893}, {0x96fd,0xe894}, {0x96fe,0xe895}, {0x9740,0xe896}, {0x9741,0xe897}, {0x9742,0xe898}, {0x9743,0xe899}, {0x9744,0xe89a}, {0x9745,0xe89b}, {0x9746,0xe89c}, - {0x9747,0xe89d}, {0x9748,0xe89e}, {0x9749,0xe89f}, {0x974a,0xe8a0}, {0x974b,0xe8a1}, {0x974c,0xe8a2}, {0x974d,0xe8a3}, {0x974e,0xe8a4}, {0x974f,0xe8a5}, {0x9750,0xe8a6}, - {0x9751,0xe8a7}, {0x9752,0xe8a8}, {0x9753,0xe8a9}, {0x9754,0xe8aa}, {0x9755,0xe8ab}, {0x9756,0xe8ac}, {0x9757,0xe8ad}, {0x9758,0xe8ae}, {0x9759,0xe8af}, {0x975a,0xe8b0}, - {0x975b,0xe8b1}, {0x975c,0xe8b2}, {0x975d,0xe8b3}, {0x975e,0xe8b4}, {0x975f,0xe8b5}, {0x9760,0xe8b6}, {0x9761,0xe8b7}, {0x9762,0xe8b8}, {0x9763,0xe8b9}, {0x9764,0xe8ba}, - {0x9765,0xe8bb}, {0x9766,0xe8bc}, {0x9767,0xe8bd}, {0x9768,0xe8be}, {0x9769,0xe8bf}, {0x976a,0xe8c0}, {0x976b,0xe8c1}, {0x976c,0xe8c2}, {0x976d,0xe8c3}, {0x976e,0xe8c4}, - {0x976f,0xe8c5}, {0x9770,0xe8c6}, {0x9771,0xe8c7}, {0x9772,0xe8c8}, {0x9773,0xe8c9}, {0x9774,0xe8ca}, {0x9775,0xe8cb}, {0x9776,0xe8cc}, {0x9777,0xe8cd}, {0x9778,0xe8ce}, - {0x9779,0xe8cf}, {0x977a,0xe8d0}, {0x977b,0xe8d1}, {0x977c,0xe8d2}, {0x977d,0xe8d3}, {0x977e,0xe8d4}, {0x97a1,0xe8d5}, {0x97a2,0xe8d6}, {0x97a3,0xe8d7}, {0x97a4,0xe8d8}, - {0x97a5,0xe8d9}, {0x97a6,0xe8da}, {0x97a7,0xe8db}, {0x97a8,0xe8dc}, {0x97a9,0xe8dd}, {0x97aa,0xe8de}, {0x97ab,0xe8df}, {0x97ac,0xe8e0}, {0x97ad,0xe8e1}, {0x97ae,0xe8e2}, - {0x97af,0xe8e3}, {0x97b0,0xe8e4}, {0x97b1,0xe8e5}, {0x97b2,0xe8e6}, {0x97b3,0xe8e7}, {0x97b4,0xe8e8}, {0x97b5,0xe8e9}, {0x97b6,0xe8ea}, {0x97b7,0xe8eb}, {0x97b8,0xe8ec}, - {0x97b9,0xe8ed}, {0x97ba,0xe8ee}, {0x97bb,0xe8ef}, {0x97bc,0xe8f0}, {0x97bd,0xe8f1}, {0x97be,0xe8f2}, {0x97bf,0xe8f3}, {0x97c0,0xe8f4}, {0x97c1,0xe8f5}, {0x97c2,0xe8f6}, - {0x97c3,0xe8f7}, {0x97c4,0xe8f8}, {0x97c5,0xe8f9}, {0x97c6,0xe8fa}, {0x97c7,0xe8fb}, {0x97c8,0xe8fc}, {0x97c9,0xe8fd}, {0x97ca,0xe8fe}, {0x97cb,0xe8ff}, {0x97cc,0xe900}, - {0x97cd,0xe901}, {0x97ce,0xe902}, {0x97cf,0xe903}, {0x97d0,0xe904}, {0x97d1,0xe905}, {0x97d2,0xe906}, {0x97d3,0xe907}, {0x97d4,0xe908}, {0x97d5,0xe909}, {0x97d6,0xe90a}, - {0x97d7,0xe90b}, {0x97d8,0xe90c}, {0x97d9,0xe90d}, {0x97da,0xe90e}, {0x97db,0xe90f}, {0x97dc,0xe910}, {0x97dd,0xe911}, {0x97de,0xe912}, {0x97df,0xe913}, {0x97e0,0xe914}, - {0x97e1,0xe915}, {0x97e2,0xe916}, {0x97e3,0xe917}, {0x97e4,0xe918}, {0x97e5,0xe919}, {0x97e6,0xe91a}, {0x97e7,0xe91b}, {0x97e8,0xe91c}, {0x97e9,0xe91d}, {0x97ea,0xe91e}, - {0x97eb,0xe91f}, {0x97ec,0xe920}, {0x97ed,0xe921}, {0x97ee,0xe922}, {0x97ef,0xe923}, {0x97f0,0xe924}, {0x97f1,0xe925}, {0x97f2,0xe926}, {0x97f3,0xe927}, {0x97f4,0xe928}, - {0x97f5,0xe929}, {0x97f6,0xe92a}, {0x97f7,0xe92b}, {0x97f8,0xe92c}, {0x97f9,0xe92d}, {0x97fa,0xe92e}, {0x97fb,0xe92f}, {0x97fc,0xe930}, {0x97fd,0xe931}, {0x97fe,0xe932}, - {0x9840,0xe933}, {0x9841,0xe934}, {0x9842,0xe935}, {0x9843,0xe936}, {0x9844,0xe937}, {0x9845,0xe938}, {0x9846,0xe939}, {0x9847,0xe93a}, {0x9848,0xe93b}, {0x9849,0xe93c}, - {0x984a,0xe93d}, {0x984b,0xe93e}, {0x984c,0xe93f}, {0x984d,0xe940}, {0x984e,0xe941}, {0x984f,0xe942}, {0x9850,0xe943}, {0x9851,0xe944}, {0x9852,0xe945}, {0x9853,0xe946}, - {0x9854,0xe947}, {0x9855,0xe948}, {0x9856,0xe949}, {0x9857,0xe94a}, {0x9858,0xe94b}, {0x9859,0xe94c}, {0x985a,0xe94d}, {0x985b,0xe94e}, {0x985c,0xe94f}, {0x985d,0xe950}, - {0x985e,0xe951}, {0x985f,0xe952}, {0x9860,0xe953}, {0x9861,0xe954}, {0x9862,0xe955}, {0x9863,0xe956}, {0x9864,0xe957}, {0x9865,0xe958}, {0x9866,0xe959}, {0x9867,0xe95a}, - {0x9868,0xe95b}, {0x9869,0xe95c}, {0x986a,0xe95d}, {0x986b,0xe95e}, {0x986c,0xe95f}, {0x986d,0xe960}, {0x986e,0xe961}, {0x986f,0xe962}, {0x9870,0xe963}, {0x9871,0xe964}, - {0x9872,0xe965}, {0x9873,0xe966}, {0x9874,0xe967}, {0x9875,0xe968}, {0x9876,0xe969}, {0x9877,0xe96a}, {0x9878,0xe96b}, {0x9879,0xe96c}, {0x987a,0xe96d}, {0x987b,0xe96e}, - {0x987c,0xe96f}, {0x987d,0xe970}, {0x987e,0xe971}, {0x98a1,0xe972}, {0x98a2,0xe973}, {0x98a3,0xe974}, {0x98a4,0xe975}, {0x98a5,0xe976}, {0x98a6,0xe977}, {0x98a7,0xe978}, - {0x98a8,0xe979}, {0x98a9,0xe97a}, {0x98aa,0xe97b}, {0x98ab,0xe97c}, {0x98ac,0xe97d}, {0x98ad,0xe97e}, {0x98ae,0xe97f}, {0x98af,0xe980}, {0x98b0,0xe981}, {0x98b1,0xe982}, - {0x98b2,0xe983}, {0x98b3,0xe984}, {0x98b4,0xe985}, {0x98b5,0xe986}, {0x98b6,0xe987}, {0x98b7,0xe988}, {0x98b8,0xe989}, {0x98b9,0xe98a}, {0x98ba,0xe98b}, {0x98bb,0xe98c}, - {0x98bc,0xe98d}, {0x98bd,0xe98e}, {0x98be,0xe98f}, {0x98bf,0xe990}, {0x98c0,0xe991}, {0x98c1,0xe992}, {0x98c2,0xe993}, {0x98c3,0xe994}, {0x98c4,0xe995}, {0x98c5,0xe996}, - {0x98c6,0xe997}, {0x98c7,0xe998}, {0x98c8,0xe999}, {0x98c9,0xe99a}, {0x98ca,0xe99b}, {0x98cb,0xe99c}, {0x98cc,0xe99d}, {0x98cd,0xe99e}, {0x98ce,0xe99f}, {0x98cf,0xe9a0}, - {0x98d0,0xe9a1}, {0x98d1,0xe9a2}, {0x98d2,0xe9a3}, {0x98d3,0xe9a4}, {0x98d4,0xe9a5}, {0x98d5,0xe9a6}, {0x98d6,0xe9a7}, {0x98d7,0xe9a8}, {0x98d8,0xe9a9}, {0x98d9,0xe9aa}, - {0x98da,0xe9ab}, {0x98db,0xe9ac}, {0x98dc,0xe9ad}, {0x98dd,0xe9ae}, {0x98de,0xe9af}, {0x98df,0xe9b0}, {0x98e0,0xe9b1}, {0x98e1,0xe9b2}, {0x98e2,0xe9b3}, {0x98e3,0xe9b4}, - {0x98e4,0xe9b5}, {0x98e5,0xe9b6}, {0x98e6,0xe9b7}, {0x98e7,0xe9b8}, {0x98e8,0xe9b9}, {0x98e9,0xe9ba}, {0x98ea,0xe9bb}, {0x98eb,0xe9bc}, {0x98ec,0xe9bd}, {0x98ed,0xe9be}, - {0x98ee,0xe9bf}, {0x98ef,0xe9c0}, {0x98f0,0xe9c1}, {0x98f1,0xe9c2}, {0x98f2,0xe9c3}, {0x98f3,0xe9c4}, {0x98f4,0xe9c5}, {0x98f5,0xe9c6}, {0x98f6,0xe9c7}, {0x98f7,0xe9c8}, - {0x98f8,0xe9c9}, {0x98f9,0xe9ca}, {0x98fa,0xe9cb}, {0x98fb,0xe9cc}, {0x98fc,0xe9cd}, {0x98fd,0xe9ce}, {0x98fe,0xe9cf}, {0x9940,0xe9d0}, {0x9941,0xe9d1}, {0x9942,0xe9d2}, - {0x9943,0xe9d3}, {0x9944,0xe9d4}, {0x9945,0xe9d5}, {0x9946,0xe9d6}, {0x9947,0xe9d7}, {0x9948,0xe9d8}, {0x9949,0xe9d9}, {0x994a,0xe9da}, {0x994b,0xe9db}, {0x994c,0xe9dc}, - {0x994d,0xe9dd}, {0x994e,0xe9de}, {0x994f,0xe9df}, {0x9950,0xe9e0}, {0x9951,0xe9e1}, {0x9952,0xe9e2}, {0x9953,0xe9e3}, {0x9954,0xe9e4}, {0x9955,0xe9e5}, {0x9956,0xe9e6}, - {0x9957,0xe9e7}, {0x9958,0xe9e8}, {0x9959,0xe9e9}, {0x995a,0xe9ea}, {0x995b,0xe9eb}, {0x995c,0xe9ec}, {0x995d,0xe9ed}, {0x995e,0xe9ee}, {0x995f,0xe9ef}, {0x9960,0xe9f0}, - {0x9961,0xe9f1}, {0x9962,0xe9f2}, {0x9963,0xe9f3}, {0x9964,0xe9f4}, {0x9965,0xe9f5}, {0x9966,0xe9f6}, {0x9967,0xe9f7}, {0x9968,0xe9f8}, {0x9969,0xe9f9}, {0x996a,0xe9fa}, - {0x996b,0xe9fb}, {0x996c,0xe9fc}, {0x996d,0xe9fd}, {0x996e,0xe9fe}, {0x996f,0xe9ff}, {0x9970,0xea00}, {0x9971,0xea01}, {0x9972,0xea02}, {0x9973,0xea03}, {0x9974,0xea04}, - {0x9975,0xea05}, {0x9976,0xea06}, {0x9977,0xea07}, {0x9978,0xea08}, {0x9979,0xea09}, {0x997a,0xea0a}, {0x997b,0xea0b}, {0x997c,0xea0c}, {0x997d,0xea0d}, {0x997e,0xea0e}, - {0x99a1,0xea0f}, {0x99a2,0xea10}, {0x99a3,0xea11}, {0x99a4,0xea12}, {0x99a5,0xea13}, {0x99a6,0xea14}, {0x99a7,0xea15}, {0x99a8,0xea16}, {0x99a9,0xea17}, {0x99aa,0xea18}, - {0x99ab,0xea19}, {0x99ac,0xea1a}, {0x99ad,0xea1b}, {0x99ae,0xea1c}, {0x99af,0xea1d}, {0x99b0,0xea1e}, {0x99b1,0xea1f}, {0x99b2,0xea20}, {0x99b3,0xea21}, {0x99b4,0xea22}, - {0x99b5,0xea23}, {0x99b6,0xea24}, {0x99b7,0xea25}, {0x99b8,0xea26}, {0x99b9,0xea27}, {0x99ba,0xea28}, {0x99bb,0xea29}, {0x99bc,0xea2a}, {0x99bd,0xea2b}, {0x99be,0xea2c}, - {0x99bf,0xea2d}, {0x99c0,0xea2e}, {0x99c1,0xea2f}, {0x99c2,0xea30}, {0x99c3,0xea31}, {0x99c4,0xea32}, {0x99c5,0xea33}, {0x99c6,0xea34}, {0x99c7,0xea35}, {0x99c8,0xea36}, - {0x99c9,0xea37}, {0x99ca,0xea38}, {0x99cb,0xea39}, {0x99cc,0xea3a}, {0x99cd,0xea3b}, {0x99ce,0xea3c}, {0x99cf,0xea3d}, {0x99d0,0xea3e}, {0x99d1,0xea3f}, {0x99d2,0xea40}, - {0x99d3,0xea41}, {0x99d4,0xea42}, {0x99d5,0xea43}, {0x99d6,0xea44}, {0x99d7,0xea45}, {0x99d8,0xea46}, {0x99d9,0xea47}, {0x99da,0xea48}, {0x99db,0xea49}, {0x99dc,0xea4a}, - {0x99dd,0xea4b}, {0x99de,0xea4c}, {0x99df,0xea4d}, {0x99e0,0xea4e}, {0x99e1,0xea4f}, {0x99e2,0xea50}, {0x99e3,0xea51}, {0x99e4,0xea52}, {0x99e5,0xea53}, {0x99e6,0xea54}, - {0x99e7,0xea55}, {0x99e8,0xea56}, {0x99e9,0xea57}, {0x99ea,0xea58}, {0x99eb,0xea59}, {0x99ec,0xea5a}, {0x99ed,0xea5b}, {0x99ee,0xea5c}, {0x99ef,0xea5d}, {0x99f0,0xea5e}, - {0x99f1,0xea5f}, {0x99f2,0xea60}, {0x99f3,0xea61}, {0x99f4,0xea62}, {0x99f5,0xea63}, {0x99f6,0xea64}, {0x99f7,0xea65}, {0x99f8,0xea66}, {0x99f9,0xea67}, {0x99fa,0xea68}, - {0x99fb,0xea69}, {0x99fc,0xea6a}, {0x99fd,0xea6b}, {0x99fe,0xea6c}, {0x9a40,0xea6d}, {0x9a41,0xea6e}, {0x9a42,0xea6f}, {0x9a43,0xea70}, {0x9a44,0xea71}, {0x9a45,0xea72}, - {0x9a46,0xea73}, {0x9a47,0xea74}, {0x9a48,0xea75}, {0x9a49,0xea76}, {0x9a4a,0xea77}, {0x9a4b,0xea78}, {0x9a4c,0xea79}, {0x9a4d,0xea7a}, {0x9a4e,0xea7b}, {0x9a4f,0xea7c}, - {0x9a50,0xea7d}, {0x9a51,0xea7e}, {0x9a52,0xea7f}, {0x9a53,0xea80}, {0x9a54,0xea81}, {0x9a55,0xea82}, {0x9a56,0xea83}, {0x9a57,0xea84}, {0x9a58,0xea85}, {0x9a59,0xea86}, - {0x9a5a,0xea87}, {0x9a5b,0xea88}, {0x9a5c,0xea89}, {0x9a5d,0xea8a}, {0x9a5e,0xea8b}, {0x9a5f,0xea8c}, {0x9a60,0xea8d}, {0x9a61,0xea8e}, {0x9a62,0xea8f}, {0x9a63,0xea90}, - {0x9a64,0xea91}, {0x9a65,0xea92}, {0x9a66,0xea93}, {0x9a67,0xea94}, {0x9a68,0xea95}, {0x9a69,0xea96}, {0x9a6a,0xea97}, {0x9a6b,0xea98}, {0x9a6c,0xea99}, {0x9a6d,0xea9a}, - {0x9a6e,0xea9b}, {0x9a6f,0xea9c}, {0x9a70,0xea9d}, {0x9a71,0xea9e}, {0x9a72,0xea9f}, {0x9a73,0xeaa0}, {0x9a74,0xeaa1}, {0x9a75,0xeaa2}, {0x9a76,0xeaa3}, {0x9a77,0xeaa4}, - {0x9a78,0xeaa5}, {0x9a79,0xeaa6}, {0x9a7a,0xeaa7}, {0x9a7b,0xeaa8}, {0x9a7c,0xeaa9}, {0x9a7d,0xeaaa}, {0x9a7e,0xeaab}, {0x9aa1,0xeaac}, {0x9aa2,0xeaad}, {0x9aa3,0xeaae}, - {0x9aa4,0xeaaf}, {0x9aa5,0xeab0}, {0x9aa6,0xeab1}, {0x9aa7,0xeab2}, {0x9aa8,0xeab3}, {0x9aa9,0xeab4}, {0x9aaa,0xeab5}, {0x9aab,0xeab6}, {0x9aac,0xeab7}, {0x9aad,0xeab8}, - {0x9aae,0xeab9}, {0x9aaf,0xeaba}, {0x9ab0,0xeabb}, {0x9ab1,0xeabc}, {0x9ab2,0xeabd}, {0x9ab3,0xeabe}, {0x9ab4,0xeabf}, {0x9ab5,0xeac0}, {0x9ab6,0xeac1}, {0x9ab7,0xeac2}, - {0x9ab8,0xeac3}, {0x9ab9,0xeac4}, {0x9aba,0xeac5}, {0x9abb,0xeac6}, {0x9abc,0xeac7}, {0x9abd,0xeac8}, {0x9abe,0xeac9}, {0x9abf,0xeaca}, {0x9ac0,0xeacb}, {0x9ac1,0xeacc}, - {0x9ac2,0xeacd}, {0x9ac3,0xeace}, {0x9ac4,0xeacf}, {0x9ac5,0xead0}, {0x9ac6,0xead1}, {0x9ac7,0xead2}, {0x9ac8,0xead3}, {0x9ac9,0xead4}, {0x9aca,0xead5}, {0x9acb,0xead6}, - {0x9acc,0xead7}, {0x9acd,0xead8}, {0x9ace,0xead9}, {0x9acf,0xeada}, {0x9ad0,0xeadb}, {0x9ad1,0xeadc}, {0x9ad2,0xeadd}, {0x9ad3,0xeade}, {0x9ad4,0xeadf}, {0x9ad5,0xeae0}, - {0x9ad6,0xeae1}, {0x9ad7,0xeae2}, {0x9ad8,0xeae3}, {0x9ad9,0xeae4}, {0x9ada,0xeae5}, {0x9adb,0xeae6}, {0x9adc,0xeae7}, {0x9add,0xeae8}, {0x9ade,0xeae9}, {0x9adf,0xeaea}, - {0x9ae0,0xeaeb}, {0x9ae1,0xeaec}, {0x9ae2,0xeaed}, {0x9ae3,0xeaee}, {0x9ae4,0xeaef}, {0x9ae5,0xeaf0}, {0x9ae6,0xeaf1}, {0x9ae7,0xeaf2}, {0x9ae8,0xeaf3}, {0x9ae9,0xeaf4}, - {0x9aea,0xeaf5}, {0x9aeb,0xeaf6}, {0x9aec,0xeaf7}, {0x9aed,0xeaf8}, {0x9aee,0xeaf9}, {0x9aef,0xeafa}, {0x9af0,0xeafb}, {0x9af1,0xeafc}, {0x9af2,0xeafd}, {0x9af3,0xeafe}, - {0x9af4,0xeaff}, {0x9af5,0xeb00}, {0x9af6,0xeb01}, {0x9af7,0xeb02}, {0x9af8,0xeb03}, {0x9af9,0xeb04}, {0x9afa,0xeb05}, {0x9afb,0xeb06}, {0x9afc,0xeb07}, {0x9afd,0xeb08}, - {0x9afe,0xeb09}, {0x9b40,0xeb0a}, {0x9b41,0xeb0b}, {0x9b42,0xeb0c}, {0x9b43,0xeb0d}, {0x9b44,0xeb0e}, {0x9b45,0xeb0f}, {0x9b46,0xeb10}, {0x9b47,0xeb11}, {0x9b48,0xeb12}, - {0x9b49,0xeb13}, {0x9b4a,0xeb14}, {0x9b4b,0xeb15}, {0x9b4c,0xeb16}, {0x9b4d,0xeb17}, {0x9b4e,0xeb18}, {0x9b4f,0xeb19}, {0x9b50,0xeb1a}, {0x9b51,0xeb1b}, {0x9b52,0xeb1c}, - {0x9b53,0xeb1d}, {0x9b54,0xeb1e}, {0x9b55,0xeb1f}, {0x9b56,0xeb20}, {0x9b57,0xeb21}, {0x9b58,0xeb22}, {0x9b59,0xeb23}, {0x9b5a,0xeb24}, {0x9b5b,0xeb25}, {0x9b5c,0xeb26}, - {0x9b5d,0xeb27}, {0x9b5e,0xeb28}, {0x9b5f,0xeb29}, {0x9b60,0xeb2a}, {0x9b61,0xeb2b}, {0x9b62,0xeb2c}, {0x9b63,0xeb2d}, {0x9b64,0xeb2e}, {0x9b65,0xeb2f}, {0x9b66,0xeb30}, - {0x9b67,0xeb31}, {0x9b68,0xeb32}, {0x9b69,0xeb33}, {0x9b6a,0xeb34}, {0x9b6b,0xeb35}, {0x9b6c,0xeb36}, {0x9b6d,0xeb37}, {0x9b6e,0xeb38}, {0x9b6f,0xeb39}, {0x9b70,0xeb3a}, - {0x9b71,0xeb3b}, {0x9b72,0xeb3c}, {0x9b73,0xeb3d}, {0x9b74,0xeb3e}, {0x9b75,0xeb3f}, {0x9b76,0xeb40}, {0x9b77,0xeb41}, {0x9b78,0xeb42}, {0x9b79,0xeb43}, {0x9b7a,0xeb44}, - {0x9b7b,0xeb45}, {0x9b7c,0xeb46}, {0x9b7d,0xeb47}, {0x9b7e,0xeb48}, {0x9ba1,0xeb49}, {0x9ba2,0xeb4a}, {0x9ba3,0xeb4b}, {0x9ba4,0xeb4c}, {0x9ba5,0xeb4d}, {0x9ba6,0xeb4e}, - {0x9ba7,0xeb4f}, {0x9ba8,0xeb50}, {0x9ba9,0xeb51}, {0x9baa,0xeb52}, {0x9bab,0xeb53}, {0x9bac,0xeb54}, {0x9bad,0xeb55}, {0x9bae,0xeb56}, {0x9baf,0xeb57}, {0x9bb0,0xeb58}, - {0x9bb1,0xeb59}, {0x9bb2,0xeb5a}, {0x9bb3,0xeb5b}, {0x9bb4,0xeb5c}, {0x9bb5,0xeb5d}, {0x9bb6,0xeb5e}, {0x9bb7,0xeb5f}, {0x9bb8,0xeb60}, {0x9bb9,0xeb61}, {0x9bba,0xeb62}, - {0x9bbb,0xeb63}, {0x9bbc,0xeb64}, {0x9bbd,0xeb65}, {0x9bbe,0xeb66}, {0x9bbf,0xeb67}, {0x9bc0,0xeb68}, {0x9bc1,0xeb69}, {0x9bc2,0xeb6a}, {0x9bc3,0xeb6b}, {0x9bc4,0xeb6c}, - {0x9bc5,0xeb6d}, {0x9bc6,0xeb6e}, {0x9bc7,0xeb6f}, {0x9bc8,0xeb70}, {0x9bc9,0xeb71}, {0x9bca,0xeb72}, {0x9bcb,0xeb73}, {0x9bcc,0xeb74}, {0x9bcd,0xeb75}, {0x9bce,0xeb76}, - {0x9bcf,0xeb77}, {0x9bd0,0xeb78}, {0x9bd1,0xeb79}, {0x9bd2,0xeb7a}, {0x9bd3,0xeb7b}, {0x9bd4,0xeb7c}, {0x9bd5,0xeb7d}, {0x9bd6,0xeb7e}, {0x9bd7,0xeb7f}, {0x9bd8,0xeb80}, - {0x9bd9,0xeb81}, {0x9bda,0xeb82}, {0x9bdb,0xeb83}, {0x9bdc,0xeb84}, {0x9bdd,0xeb85}, {0x9bde,0xeb86}, {0x9bdf,0xeb87}, {0x9be0,0xeb88}, {0x9be1,0xeb89}, {0x9be2,0xeb8a}, - {0x9be3,0xeb8b}, {0x9be4,0xeb8c}, {0x9be5,0xeb8d}, {0x9be6,0xeb8e}, {0x9be7,0xeb8f}, {0x9be8,0xeb90}, {0x9be9,0xeb91}, {0x9bea,0xeb92}, {0x9beb,0xeb93}, {0x9bec,0xeb94}, - {0x9bed,0xeb95}, {0x9bee,0xeb96}, {0x9bef,0xeb97}, {0x9bf0,0xeb98}, {0x9bf1,0xeb99}, {0x9bf2,0xeb9a}, {0x9bf3,0xeb9b}, {0x9bf4,0xeb9c}, {0x9bf5,0xeb9d}, {0x9bf6,0xeb9e}, - {0x9bf7,0xeb9f}, {0x9bf8,0xeba0}, {0x9bf9,0xeba1}, {0x9bfa,0xeba2}, {0x9bfb,0xeba3}, {0x9bfc,0xeba4}, {0x9bfd,0xeba5}, {0x9bfe,0xeba6}, {0x9c40,0xeba7}, {0x9c41,0xeba8}, - {0x9c42,0xeba9}, {0x9c43,0xebaa}, {0x9c44,0xebab}, {0x9c45,0xebac}, {0x9c46,0xebad}, {0x9c47,0xebae}, {0x9c48,0xebaf}, {0x9c49,0xebb0}, {0x9c4a,0xebb1}, {0x9c4b,0xebb2}, - {0x9c4c,0xebb3}, {0x9c4d,0xebb4}, {0x9c4e,0xebb5}, {0x9c4f,0xebb6}, {0x9c50,0xebb7}, {0x9c51,0xebb8}, {0x9c52,0xebb9}, {0x9c53,0xebba}, {0x9c54,0xebbb}, {0x9c55,0xebbc}, - {0x9c56,0xebbd}, {0x9c57,0xebbe}, {0x9c58,0xebbf}, {0x9c59,0xebc0}, {0x9c5a,0xebc1}, {0x9c5b,0xebc2}, {0x9c5c,0xebc3}, {0x9c5d,0xebc4}, {0x9c5e,0xebc5}, {0x9c5f,0xebc6}, - {0x9c60,0xebc7}, {0x9c61,0xebc8}, {0x9c62,0xebc9}, {0x9c63,0xebca}, {0x9c64,0xebcb}, {0x9c65,0xebcc}, {0x9c66,0xebcd}, {0x9c67,0xebce}, {0x9c68,0xebcf}, {0x9c69,0xebd0}, - {0x9c6a,0xebd1}, {0x9c6b,0xebd2}, {0x9c6c,0xebd3}, {0x9c6d,0xebd4}, {0x9c6e,0xebd5}, {0x9c6f,0xebd6}, {0x9c70,0xebd7}, {0x9c71,0xebd8}, {0x9c72,0xebd9}, {0x9c73,0xebda}, - {0x9c74,0xebdb}, {0x9c75,0xebdc}, {0x9c76,0xebdd}, {0x9c77,0xebde}, {0x9c78,0xebdf}, {0x9c79,0xebe0}, {0x9c7a,0xebe1}, {0x9c7b,0xebe2}, {0x9c7c,0xebe3}, {0x9c7d,0xebe4}, - {0x9c7e,0xebe5}, {0x9ca1,0xebe6}, {0x9ca2,0xebe7}, {0x9ca3,0xebe8}, {0x9ca4,0xebe9}, {0x9ca5,0xebea}, {0x9ca6,0xebeb}, {0x9ca7,0xebec}, {0x9ca8,0xebed}, {0x9ca9,0xebee}, - {0x9caa,0xebef}, {0x9cab,0xebf0}, {0x9cac,0xebf1}, {0x9cad,0xebf2}, {0x9cae,0xebf3}, {0x9caf,0xebf4}, {0x9cb0,0xebf5}, {0x9cb1,0xebf6}, {0x9cb2,0xebf7}, {0x9cb3,0xebf8}, - {0x9cb4,0xebf9}, {0x9cb5,0xebfa}, {0x9cb6,0xebfb}, {0x9cb7,0xebfc}, {0x9cb8,0xebfd}, {0x9cb9,0xebfe}, {0x9cba,0xebff}, {0x9cbb,0xec00}, {0x9cbc,0xec01}, {0x9cbd,0xec02}, - {0x9cbe,0xec03}, {0x9cbf,0xec04}, {0x9cc0,0xec05}, {0x9cc1,0xec06}, {0x9cc2,0xec07}, {0x9cc3,0xec08}, {0x9cc4,0xec09}, {0x9cc5,0xec0a}, {0x9cc6,0xec0b}, {0x9cc7,0xec0c}, - {0x9cc8,0xec0d}, {0x9cc9,0xec0e}, {0x9cca,0xec0f}, {0x9ccb,0xec10}, {0x9ccc,0xec11}, {0x9ccd,0xec12}, {0x9cce,0xec13}, {0x9ccf,0xec14}, {0x9cd0,0xec15}, {0x9cd1,0xec16}, - {0x9cd2,0xec17}, {0x9cd3,0xec18}, {0x9cd4,0xec19}, {0x9cd5,0xec1a}, {0x9cd6,0xec1b}, {0x9cd7,0xec1c}, {0x9cd8,0xec1d}, {0x9cd9,0xec1e}, {0x9cda,0xec1f}, {0x9cdb,0xec20}, - {0x9cdc,0xec21}, {0x9cdd,0xec22}, {0x9cde,0xec23}, {0x9cdf,0xec24}, {0x9ce0,0xec25}, {0x9ce1,0xec26}, {0x9ce2,0xec27}, {0x9ce3,0xec28}, {0x9ce4,0xec29}, {0x9ce5,0xec2a}, - {0x9ce6,0xec2b}, {0x9ce7,0xec2c}, {0x9ce8,0xec2d}, {0x9ce9,0xec2e}, {0x9cea,0xec2f}, {0x9ceb,0xec30}, {0x9cec,0xec31}, {0x9ced,0xec32}, {0x9cee,0xec33}, {0x9cef,0xec34}, - {0x9cf0,0xec35}, {0x9cf1,0xec36}, {0x9cf2,0xec37}, {0x9cf3,0xec38}, {0x9cf4,0xec39}, {0x9cf5,0xec3a}, {0x9cf6,0xec3b}, {0x9cf7,0xec3c}, {0x9cf8,0xec3d}, {0x9cf9,0xec3e}, - {0x9cfa,0xec3f}, {0x9cfb,0xec40}, {0x9cfc,0xec41}, {0x9cfd,0xec42}, {0x9cfe,0xec43}, {0x9d40,0xec44}, {0x9d41,0xec45}, {0x9d42,0xec46}, {0x9d43,0xec47}, {0x9d44,0xec48}, - {0x9d45,0xec49}, {0x9d46,0xec4a}, {0x9d47,0xec4b}, {0x9d48,0xec4c}, {0x9d49,0xec4d}, {0x9d4a,0xec4e}, {0x9d4b,0xec4f}, {0x9d4c,0xec50}, {0x9d4d,0xec51}, {0x9d4e,0xec52}, - {0x9d4f,0xec53}, {0x9d50,0xec54}, {0x9d51,0xec55}, {0x9d52,0xec56}, {0x9d53,0xec57}, {0x9d54,0xec58}, {0x9d55,0xec59}, {0x9d56,0xec5a}, {0x9d57,0xec5b}, {0x9d58,0xec5c}, - {0x9d59,0xec5d}, {0x9d5a,0xec5e}, {0x9d5b,0xec5f}, {0x9d5c,0xec60}, {0x9d5d,0xec61}, {0x9d5e,0xec62}, {0x9d5f,0xec63}, {0x9d60,0xec64}, {0x9d61,0xec65}, {0x9d62,0xec66}, - {0x9d63,0xec67}, {0x9d64,0xec68}, {0x9d65,0xec69}, {0x9d66,0xec6a}, {0x9d67,0xec6b}, {0x9d68,0xec6c}, {0x9d69,0xec6d}, {0x9d6a,0xec6e}, {0x9d6b,0xec6f}, {0x9d6c,0xec70}, - {0x9d6d,0xec71}, {0x9d6e,0xec72}, {0x9d6f,0xec73}, {0x9d70,0xec74}, {0x9d71,0xec75}, {0x9d72,0xec76}, {0x9d73,0xec77}, {0x9d74,0xec78}, {0x9d75,0xec79}, {0x9d76,0xec7a}, - {0x9d77,0xec7b}, {0x9d78,0xec7c}, {0x9d79,0xec7d}, {0x9d7a,0xec7e}, {0x9d7b,0xec7f}, {0x9d7c,0xec80}, {0x9d7d,0xec81}, {0x9d7e,0xec82}, {0x9da1,0xec83}, {0x9da2,0xec84}, - {0x9da3,0xec85}, {0x9da4,0xec86}, {0x9da5,0xec87}, {0x9da6,0xec88}, {0x9da7,0xec89}, {0x9da8,0xec8a}, {0x9da9,0xec8b}, {0x9daa,0xec8c}, {0x9dab,0xec8d}, {0x9dac,0xec8e}, - {0x9dad,0xec8f}, {0x9dae,0xec90}, {0x9daf,0xec91}, {0x9db0,0xec92}, {0x9db1,0xec93}, {0x9db2,0xec94}, {0x9db3,0xec95}, {0x9db4,0xec96}, {0x9db5,0xec97}, {0x9db6,0xec98}, - {0x9db7,0xec99}, {0x9db8,0xec9a}, {0x9db9,0xec9b}, {0x9dba,0xec9c}, {0x9dbb,0xec9d}, {0x9dbc,0xec9e}, {0x9dbd,0xec9f}, {0x9dbe,0xeca0}, {0x9dbf,0xeca1}, {0x9dc0,0xeca2}, - {0x9dc1,0xeca3}, {0x9dc2,0xeca4}, {0x9dc3,0xeca5}, {0x9dc4,0xeca6}, {0x9dc5,0xeca7}, {0x9dc6,0xeca8}, {0x9dc7,0xeca9}, {0x9dc8,0xecaa}, {0x9dc9,0xecab}, {0x9dca,0xecac}, - {0x9dcb,0xecad}, {0x9dcc,0xecae}, {0x9dcd,0xecaf}, {0x9dce,0xecb0}, {0x9dcf,0xecb1}, {0x9dd0,0xecb2}, {0x9dd1,0xecb3}, {0x9dd2,0xecb4}, {0x9dd3,0xecb5}, {0x9dd4,0xecb6}, - {0x9dd5,0xecb7}, {0x9dd6,0xecb8}, {0x9dd7,0xecb9}, {0x9dd8,0xecba}, {0x9dd9,0xecbb}, {0x9dda,0xecbc}, {0x9ddb,0xecbd}, {0x9ddc,0xecbe}, {0x9ddd,0xecbf}, {0x9dde,0xecc0}, - {0x9ddf,0xecc1}, {0x9de0,0xecc2}, {0x9de1,0xecc3}, {0x9de2,0xecc4}, {0x9de3,0xecc5}, {0x9de4,0xecc6}, {0x9de5,0xecc7}, {0x9de6,0xecc8}, {0x9de7,0xecc9}, {0x9de8,0xecca}, - {0x9de9,0xeccb}, {0x9dea,0xeccc}, {0x9deb,0xeccd}, {0x9dec,0xecce}, {0x9ded,0xeccf}, {0x9dee,0xecd0}, {0x9def,0xecd1}, {0x9df0,0xecd2}, {0x9df1,0xecd3}, {0x9df2,0xecd4}, - {0x9df3,0xecd5}, {0x9df4,0xecd6}, {0x9df5,0xecd7}, {0x9df6,0xecd8}, {0x9df7,0xecd9}, {0x9df8,0xecda}, {0x9df9,0xecdb}, {0x9dfa,0xecdc}, {0x9dfb,0xecdd}, {0x9dfc,0xecde}, - {0x9dfd,0xecdf}, {0x9dfe,0xece0}, {0x9e40,0xece1}, {0x9e41,0xece2}, {0x9e42,0xece3}, {0x9e43,0xece4}, {0x9e44,0xece5}, {0x9e45,0xece6}, {0x9e46,0xece7}, {0x9e47,0xece8}, - {0x9e48,0xece9}, {0x9e49,0xecea}, {0x9e4a,0xeceb}, {0x9e4b,0xecec}, {0x9e4c,0xeced}, {0x9e4d,0xecee}, {0x9e4e,0xecef}, {0x9e4f,0xecf0}, {0x9e50,0xecf1}, {0x9e51,0xecf2}, - {0x9e52,0xecf3}, {0x9e53,0xecf4}, {0x9e54,0xecf5}, {0x9e55,0xecf6}, {0x9e56,0xecf7}, {0x9e57,0xecf8}, {0x9e58,0xecf9}, {0x9e59,0xecfa}, {0x9e5a,0xecfb}, {0x9e5b,0xecfc}, - {0x9e5c,0xecfd}, {0x9e5d,0xecfe}, {0x9e5e,0xecff}, {0x9e5f,0xed00}, {0x9e60,0xed01}, {0x9e61,0xed02}, {0x9e62,0xed03}, {0x9e63,0xed04}, {0x9e64,0xed05}, {0x9e65,0xed06}, - {0x9e66,0xed07}, {0x9e67,0xed08}, {0x9e68,0xed09}, {0x9e69,0xed0a}, {0x9e6a,0xed0b}, {0x9e6b,0xed0c}, {0x9e6c,0xed0d}, {0x9e6d,0xed0e}, {0x9e6e,0xed0f}, {0x9e6f,0xed10}, - {0x9e70,0xed11}, {0x9e71,0xed12}, {0x9e72,0xed13}, {0x9e73,0xed14}, {0x9e74,0xed15}, {0x9e75,0xed16}, {0x9e76,0xed17}, {0x9e77,0xed18}, {0x9e78,0xed19}, {0x9e79,0xed1a}, - {0x9e7a,0xed1b}, {0x9e7b,0xed1c}, {0x9e7c,0xed1d}, {0x9e7d,0xed1e}, {0x9e7e,0xed1f}, {0x9ea1,0xed20}, {0x9ea2,0xed21}, {0x9ea3,0xed22}, {0x9ea4,0xed23}, {0x9ea5,0xed24}, - {0x9ea6,0xed25}, {0x9ea7,0xed26}, {0x9ea8,0xed27}, {0x9ea9,0xed28}, {0x9eaa,0xed29}, {0x9eab,0xed2a}, {0x9eac,0xed2b}, {0x9ead,0xed2c}, {0x9eae,0xed2d}, {0x9eaf,0xed2e}, - {0x9eb0,0xed2f}, {0x9eb1,0xed30}, {0x9eb2,0xed31}, {0x9eb3,0xed32}, {0x9eb4,0xed33}, {0x9eb5,0xed34}, {0x9eb6,0xed35}, {0x9eb7,0xed36}, {0x9eb8,0xed37}, {0x9eb9,0xed38}, - {0x9eba,0xed39}, {0x9ebb,0xed3a}, {0x9ebc,0xed3b}, {0x9ebd,0xed3c}, {0x9ebe,0xed3d}, {0x9ebf,0xed3e}, {0x9ec0,0xed3f}, {0x9ec1,0xed40}, {0x9ec2,0xed41}, {0x9ec3,0xed42}, - {0x9ec4,0xed43}, {0x9ec5,0xed44}, {0x9ec6,0xed45}, {0x9ec7,0xed46}, {0x9ec8,0xed47}, {0x9ec9,0xed48}, {0x9eca,0xed49}, {0x9ecb,0xed4a}, {0x9ecc,0xed4b}, {0x9ecd,0xed4c}, - {0x9ece,0xed4d}, {0x9ecf,0xed4e}, {0x9ed0,0xed4f}, {0x9ed1,0xed50}, {0x9ed2,0xed51}, {0x9ed3,0xed52}, {0x9ed4,0xed53}, {0x9ed5,0xed54}, {0x9ed6,0xed55}, {0x9ed7,0xed56}, - {0x9ed8,0xed57}, {0x9ed9,0xed58}, {0x9eda,0xed59}, {0x9edb,0xed5a}, {0x9edc,0xed5b}, {0x9edd,0xed5c}, {0x9ede,0xed5d}, {0x9edf,0xed5e}, {0x9ee0,0xed5f}, {0x9ee1,0xed60}, - {0x9ee2,0xed61}, {0x9ee3,0xed62}, {0x9ee4,0xed63}, {0x9ee5,0xed64}, {0x9ee6,0xed65}, {0x9ee7,0xed66}, {0x9ee8,0xed67}, {0x9ee9,0xed68}, {0x9eea,0xed69}, {0x9eeb,0xed6a}, - {0x9eec,0xed6b}, {0x9eed,0xed6c}, {0x9eee,0xed6d}, {0x9eef,0xed6e}, {0x9ef0,0xed6f}, {0x9ef1,0xed70}, {0x9ef2,0xed71}, {0x9ef3,0xed72}, {0x9ef4,0xed73}, {0x9ef5,0xed74}, - {0x9ef6,0xed75}, {0x9ef7,0xed76}, {0x9ef8,0xed77}, {0x9ef9,0xed78}, {0x9efa,0xed79}, {0x9efb,0xed7a}, {0x9efc,0xed7b}, {0x9efd,0xed7c}, {0x9efe,0xed7d}, {0x9f40,0xed7e}, - {0x9f41,0xed7f}, {0x9f42,0xed80}, {0x9f43,0xed81}, {0x9f44,0xed82}, {0x9f45,0xed83}, {0x9f46,0xed84}, {0x9f47,0xed85}, {0x9f48,0xed86}, {0x9f49,0xed87}, {0x9f4a,0xed88}, - {0x9f4b,0xed89}, {0x9f4c,0xed8a}, {0x9f4d,0xed8b}, {0x9f4e,0xed8c}, {0x9f4f,0xed8d}, {0x9f50,0xed8e}, {0x9f51,0xed8f}, {0x9f52,0xed90}, {0x9f53,0xed91}, {0x9f54,0xed92}, - {0x9f55,0xed93}, {0x9f56,0xed94}, {0x9f57,0xed95}, {0x9f58,0xed96}, {0x9f59,0xed97}, {0x9f5a,0xed98}, {0x9f5b,0xed99}, {0x9f5c,0xed9a}, {0x9f5d,0xed9b}, {0x9f5e,0xed9c}, - {0x9f5f,0xed9d}, {0x9f60,0xed9e}, {0x9f61,0xed9f}, {0x9f62,0xeda0}, {0x9f63,0xeda1}, {0x9f64,0xeda2}, {0x9f65,0xeda3}, {0x9f66,0xeda4}, {0x9f67,0xeda5}, {0x9f68,0xeda6}, - {0x9f69,0xeda7}, {0x9f6a,0xeda8}, {0x9f6b,0xeda9}, {0x9f6c,0xedaa}, {0x9f6d,0xedab}, {0x9f6e,0xedac}, {0x9f6f,0xedad}, {0x9f70,0xedae}, {0x9f71,0xedaf}, {0x9f72,0xedb0}, - {0x9f73,0xedb1}, {0x9f74,0xedb2}, {0x9f75,0xedb3}, {0x9f76,0xedb4}, {0x9f77,0xedb5}, {0x9f78,0xedb6}, {0x9f79,0xedb7}, {0x9f7a,0xedb8}, {0x9f7b,0xedb9}, {0x9f7c,0xedba}, - {0x9f7d,0xedbb}, {0x9f7e,0xedbc}, {0x9fa1,0xedbd}, {0x9fa2,0xedbe}, {0x9fa3,0xedbf}, {0x9fa4,0xedc0}, {0x9fa5,0xedc1}, {0x9fa6,0xedc2}, {0x9fa7,0xedc3}, {0x9fa8,0xedc4}, - {0x9fa9,0xedc5}, {0x9faa,0xedc6}, {0x9fab,0xedc7}, {0x9fac,0xedc8}, {0x9fad,0xedc9}, {0x9fae,0xedca}, {0x9faf,0xedcb}, {0x9fb0,0xedcc}, {0x9fb1,0xedcd}, {0x9fb2,0xedce}, - {0x9fb3,0xedcf}, {0x9fb4,0xedd0}, {0x9fb5,0xedd1}, {0x9fb6,0xedd2}, {0x9fb7,0xedd3}, {0x9fb8,0xedd4}, {0x9fb9,0xedd5}, {0x9fba,0xedd6}, {0x9fbb,0xedd7}, {0x9fbc,0xedd8}, - {0x9fbd,0xedd9}, {0x9fbe,0xedda}, {0x9fbf,0xeddb}, {0x9fc0,0xeddc}, {0x9fc1,0xeddd}, {0x9fc2,0xedde}, {0x9fc3,0xeddf}, {0x9fc4,0xede0}, {0x9fc5,0xede1}, {0x9fc6,0xede2}, - {0x9fc7,0xede3}, {0x9fc8,0xede4}, {0x9fc9,0xede5}, {0x9fca,0xede6}, {0x9fcb,0xede7}, {0x9fcc,0xede8}, {0x9fcd,0xede9}, {0x9fce,0xedea}, {0x9fcf,0xedeb}, {0x9fd0,0xedec}, - {0x9fd1,0xeded}, {0x9fd2,0xedee}, {0x9fd3,0xedef}, {0x9fd4,0xedf0}, {0x9fd5,0xedf1}, {0x9fd6,0xedf2}, {0x9fd7,0xedf3}, {0x9fd8,0xedf4}, {0x9fd9,0xedf5}, {0x9fda,0xedf6}, - {0x9fdb,0xedf7}, {0x9fdc,0xedf8}, {0x9fdd,0xedf9}, {0x9fde,0xedfa}, {0x9fdf,0xedfb}, {0x9fe0,0xedfc}, {0x9fe1,0xedfd}, {0x9fe2,0xedfe}, {0x9fe3,0xedff}, {0x9fe4,0xee00}, - {0x9fe5,0xee01}, {0x9fe6,0xee02}, {0x9fe7,0xee03}, {0x9fe8,0xee04}, {0x9fe9,0xee05}, {0x9fea,0xee06}, {0x9feb,0xee07}, {0x9fec,0xee08}, {0x9fed,0xee09}, {0x9fee,0xee0a}, - {0x9fef,0xee0b}, {0x9ff0,0xee0c}, {0x9ff1,0xee0d}, {0x9ff2,0xee0e}, {0x9ff3,0xee0f}, {0x9ff4,0xee10}, {0x9ff5,0xee11}, {0x9ff6,0xee12}, {0x9ff7,0xee13}, {0x9ff8,0xee14}, - {0x9ff9,0xee15}, {0x9ffa,0xee16}, {0x9ffb,0xee17}, {0x9ffc,0xee18}, {0x9ffd,0xee19}, {0x9ffe,0xee1a}, {0xa040,0xee1b}, {0xa041,0xee1c}, {0xa042,0xee1d}, {0xa043,0xee1e}, - {0xa044,0xee1f}, {0xa045,0xee20}, {0xa046,0xee21}, {0xa047,0xee22}, {0xa048,0xee23}, {0xa049,0xee24}, {0xa04a,0xee25}, {0xa04b,0xee26}, {0xa04c,0xee27}, {0xa04d,0xee28}, - {0xa04e,0xee29}, {0xa04f,0xee2a}, {0xa050,0xee2b}, {0xa051,0xee2c}, {0xa052,0xee2d}, {0xa053,0xee2e}, {0xa054,0xee2f}, {0xa055,0xee30}, {0xa056,0xee31}, {0xa057,0xee32}, - {0xa058,0xee33}, {0xa059,0xee34}, {0xa05a,0xee35}, {0xa05b,0xee36}, {0xa05c,0xee37}, {0xa05d,0xee38}, {0xa05e,0xee39}, {0xa05f,0xee3a}, {0xa060,0xee3b}, {0xa061,0xee3c}, - {0xa062,0xee3d}, {0xa063,0xee3e}, {0xa064,0xee3f}, {0xa065,0xee40}, {0xa066,0xee41}, {0xa067,0xee42}, {0xa068,0xee43}, {0xa069,0xee44}, {0xa06a,0xee45}, {0xa06b,0xee46}, - {0xa06c,0xee47}, {0xa06d,0xee48}, {0xa06e,0xee49}, {0xa06f,0xee4a}, {0xa070,0xee4b}, {0xa071,0xee4c}, {0xa072,0xee4d}, {0xa073,0xee4e}, {0xa074,0xee4f}, {0xa075,0xee50}, - {0xa076,0xee51}, {0xa077,0xee52}, {0xa078,0xee53}, {0xa079,0xee54}, {0xa07a,0xee55}, {0xa07b,0xee56}, {0xa07c,0xee57}, {0xa07d,0xee58}, {0xa07e,0xee59}, {0xa0a1,0xee5a}, - {0xa0a2,0xee5b}, {0xa0a3,0xee5c}, {0xa0a4,0xee5d}, {0xa0a5,0xee5e}, {0xa0a6,0xee5f}, {0xa0a7,0xee60}, {0xa0a8,0xee61}, {0xa0a9,0xee62}, {0xa0aa,0xee63}, {0xa0ab,0xee64}, - {0xa0ac,0xee65}, {0xa0ad,0xee66}, {0xa0ae,0xee67}, {0xa0af,0xee68}, {0xa0b0,0xee69}, {0xa0b1,0xee6a}, {0xa0b2,0xee6b}, {0xa0b3,0xee6c}, {0xa0b4,0xee6d}, {0xa0b5,0xee6e}, - {0xa0b6,0xee6f}, {0xa0b7,0xee70}, {0xa0b8,0xee71}, {0xa0b9,0xee72}, {0xa0ba,0xee73}, {0xa0bb,0xee74}, {0xa0bc,0xee75}, {0xa0bd,0xee76}, {0xa0be,0xee77}, {0xa0bf,0xee78}, - {0xa0c0,0xee79}, {0xa0c1,0xee7a}, {0xa0c2,0xee7b}, {0xa0c3,0xee7c}, {0xa0c4,0xee7d}, {0xa0c5,0xee7e}, {0xa0c6,0xee7f}, {0xa0c7,0xee80}, {0xa0c8,0xee81}, {0xa0c9,0xee82}, - {0xa0ca,0xee83}, {0xa0cb,0xee84}, {0xa0cc,0xee85}, {0xa0cd,0xee86}, {0xa0ce,0xee87}, {0xa0cf,0xee88}, {0xa0d0,0xee89}, {0xa0d1,0xee8a}, {0xa0d2,0xee8b}, {0xa0d3,0xee8c}, - {0xa0d4,0xee8d}, {0xa0d5,0xee8e}, {0xa0d6,0xee8f}, {0xa0d7,0xee90}, {0xa0d8,0xee91}, {0xa0d9,0xee92}, {0xa0da,0xee93}, {0xa0db,0xee94}, {0xa0dc,0xee95}, {0xa0dd,0xee96}, - {0xa0de,0xee97}, {0xa0df,0xee98}, {0xa0e0,0xee99}, {0xa0e1,0xee9a}, {0xa0e2,0xee9b}, {0xa0e3,0xee9c}, {0xa0e4,0xee9d}, {0xa0e5,0xee9e}, {0xa0e6,0xee9f}, {0xa0e7,0xeea0}, - {0xa0e8,0xeea1}, {0xa0e9,0xeea2}, {0xa0ea,0xeea3}, {0xa0eb,0xeea4}, {0xa0ec,0xeea5}, {0xa0ed,0xeea6}, {0xa0ee,0xeea7}, {0xa0ef,0xeea8}, {0xa0f0,0xeea9}, {0xa0f1,0xeeaa}, - {0xa0f2,0xeeab}, {0xa0f3,0xeeac}, {0xa0f4,0xeead}, {0xa0f5,0xeeae}, {0xa0f6,0xeeaf}, {0xa0f7,0xeeb0}, {0xa0f8,0xeeb1}, {0xa0f9,0xeeb2}, {0xa0fa,0xeeb3}, {0xa0fb,0xeeb4}, - {0xa0fc,0xeeb5}, {0xa0fd,0xeeb6}, {0xa0fe,0xeeb7}, -}; - -static const B5Map b5_C6A1_to_uc_map[408] = { - {0xc6a1,0xf6b1}, {0xc6a2,0xf6b2}, {0xc6a3,0xf6b3}, {0xc6a4,0xf6b4}, {0xc6a5,0xf6b5}, {0xc6a6,0xf6b6}, {0xc6a7,0xf6b7}, {0xc6a8,0xf6b8}, {0xc6a9,0xf6b9}, {0xc6aa,0xf6ba}, - {0xc6ab,0xf6bb}, {0xc6ac,0xf6bc}, {0xc6ad,0xf6bd}, {0xc6ae,0xf6be}, {0xc6af,0xf6bf}, {0xc6b0,0xf6c0}, {0xc6b1,0xf6c1}, {0xc6b2,0xf6c2}, {0xc6b3,0xf6c3}, {0xc6b4,0xf6c4}, - {0xc6b5,0xf6c5}, {0xc6b6,0xf6c6}, {0xc6b7,0xf6c7}, {0xc6b8,0xf6c8}, {0xc6b9,0xf6c9}, {0xc6ba,0xf6ca}, {0xc6bb,0xf6cb}, {0xc6bc,0xf6cc}, {0xc6bd,0xf6cd}, {0xc6be,0xf6ce}, - {0xc6bf,0xf6cf}, {0xc6c0,0xf6d0}, {0xc6c1,0xf6d1}, {0xc6c2,0xf6d2}, {0xc6c3,0xf6d3}, {0xc6c4,0xf6d4}, {0xc6c5,0xf6d5}, {0xc6c6,0xf6d6}, {0xc6c7,0xf6d7}, {0xc6c8,0xf6d8}, - {0xc6c9,0xf6d9}, {0xc6ca,0xf6da}, {0xc6cb,0xf6db}, {0xc6cc,0xf6dc}, {0xc6cd,0xf6dd}, {0xc6ce,0xf6de}, {0xc6cf,0xf6df}, {0xc6d0,0xf6e0}, {0xc6d1,0xf6e1}, {0xc6d2,0xf6e2}, - {0xc6d3,0xf6e3}, {0xc6d4,0xf6e4}, {0xc6d5,0xf6e5}, {0xc6d6,0xf6e6}, {0xc6d7,0xf6e7}, {0xc6d8,0xf6e8}, {0xc6d9,0xf6e9}, {0xc6da,0xf6ea}, {0xc6db,0xf6eb}, {0xc6dc,0xf6ec}, - {0xc6dd,0xf6ed}, {0xc6de,0xf6ee}, {0xc6df,0xf6ef}, {0xc6e0,0xf6f0}, {0xc6e1,0xf6f1}, {0xc6e2,0xf6f2}, {0xc6e3,0xf6f3}, {0xc6e4,0xf6f4}, {0xc6e5,0xf6f5}, {0xc6e6,0xf6f6}, - {0xc6e7,0xf6f7}, {0xc6e8,0xf6f8}, {0xc6e9,0xf6f9}, {0xc6ea,0xf6fa}, {0xc6eb,0xf6fb}, {0xc6ec,0xf6fc}, {0xc6ed,0xf6fd}, {0xc6ee,0xf6fe}, {0xc6ef,0xf6ff}, {0xc6f0,0xf700}, - {0xc6f1,0xf701}, {0xc6f2,0xf702}, {0xc6f3,0xf703}, {0xc6f4,0xf704}, {0xc6f5,0xf705}, {0xc6f6,0xf706}, {0xc6f7,0xf707}, {0xc6f8,0xf708}, {0xc6f9,0xf709}, {0xc6fa,0xf70a}, - {0xc6fb,0xf70b}, {0xc6fc,0xf70c}, {0xc6fd,0xf70d}, {0xc6fe,0xf70e}, {0xc740,0xf70f}, {0xc741,0xf710}, {0xc742,0xf711}, {0xc743,0xf712}, {0xc744,0xf713}, {0xc745,0xf714}, - {0xc746,0xf715}, {0xc747,0xf716}, {0xc748,0xf717}, {0xc749,0xf718}, {0xc74a,0xf719}, {0xc74b,0xf71a}, {0xc74c,0xf71b}, {0xc74d,0xf71c}, {0xc74e,0xf71d}, {0xc74f,0xf71e}, - {0xc750,0xf71f}, {0xc751,0xf720}, {0xc752,0xf721}, {0xc753,0xf722}, {0xc754,0xf723}, {0xc755,0xf724}, {0xc756,0xf725}, {0xc757,0xf726}, {0xc758,0xf727}, {0xc759,0xf728}, - {0xc75a,0xf729}, {0xc75b,0xf72a}, {0xc75c,0xf72b}, {0xc75d,0xf72c}, {0xc75e,0xf72d}, {0xc75f,0xf72e}, {0xc760,0xf72f}, {0xc761,0xf730}, {0xc762,0xf731}, {0xc763,0xf732}, - {0xc764,0xf733}, {0xc765,0xf734}, {0xc766,0xf735}, {0xc767,0xf736}, {0xc768,0xf737}, {0xc769,0xf738}, {0xc76a,0xf739}, {0xc76b,0xf73a}, {0xc76c,0xf73b}, {0xc76d,0xf73c}, - {0xc76e,0xf73d}, {0xc76f,0xf73e}, {0xc770,0xf73f}, {0xc771,0xf740}, {0xc772,0xf741}, {0xc773,0xf742}, {0xc774,0xf743}, {0xc775,0xf744}, {0xc776,0xf745}, {0xc777,0xf746}, - {0xc778,0xf747}, {0xc779,0xf748}, {0xc77a,0xf749}, {0xc77b,0xf74a}, {0xc77c,0xf74b}, {0xc77d,0xf74c}, {0xc77e,0xf74d}, {0xc7a1,0xf74e}, {0xc7a2,0xf74f}, {0xc7a3,0xf750}, - {0xc7a4,0xf751}, {0xc7a5,0xf752}, {0xc7a6,0xf753}, {0xc7a7,0xf754}, {0xc7a8,0xf755}, {0xc7a9,0xf756}, {0xc7aa,0xf757}, {0xc7ab,0xf758}, {0xc7ac,0xf759}, {0xc7ad,0xf75a}, - {0xc7ae,0xf75b}, {0xc7af,0xf75c}, {0xc7b0,0xf75d}, {0xc7b1,0xf75e}, {0xc7b2,0xf75f}, {0xc7b3,0xf760}, {0xc7b4,0xf761}, {0xc7b5,0xf762}, {0xc7b6,0xf763}, {0xc7b7,0xf764}, - {0xc7b8,0xf765}, {0xc7b9,0xf766}, {0xc7ba,0xf767}, {0xc7bb,0xf768}, {0xc7bc,0xf769}, {0xc7bd,0xf76a}, {0xc7be,0xf76b}, {0xc7bf,0xf76c}, {0xc7c0,0xf76d}, {0xc7c1,0xf76e}, - {0xc7c2,0xf76f}, {0xc7c3,0xf770}, {0xc7c4,0xf771}, {0xc7c5,0xf772}, {0xc7c6,0xf773}, {0xc7c7,0xf774}, {0xc7c8,0xf775}, {0xc7c9,0xf776}, {0xc7ca,0xf777}, {0xc7cb,0xf778}, - {0xc7cc,0xf779}, {0xc7cd,0xf77a}, {0xc7ce,0xf77b}, {0xc7cf,0xf77c}, {0xc7d0,0xf77d}, {0xc7d1,0xf77e}, {0xc7d2,0xf77f}, {0xc7d3,0xf780}, {0xc7d4,0xf781}, {0xc7d5,0xf782}, - {0xc7d6,0xf783}, {0xc7d7,0xf784}, {0xc7d8,0xf785}, {0xc7d9,0xf786}, {0xc7da,0xf787}, {0xc7db,0xf788}, {0xc7dc,0xf789}, {0xc7dd,0xf78a}, {0xc7de,0xf78b}, {0xc7df,0xf78c}, - {0xc7e0,0xf78d}, {0xc7e1,0xf78e}, {0xc7e2,0xf78f}, {0xc7e3,0xf790}, {0xc7e4,0xf791}, {0xc7e5,0xf792}, {0xc7e6,0xf793}, {0xc7e7,0xf794}, {0xc7e8,0xf795}, {0xc7e9,0xf796}, - {0xc7ea,0xf797}, {0xc7eb,0xf798}, {0xc7ec,0xf799}, {0xc7ed,0xf79a}, {0xc7ee,0xf79b}, {0xc7ef,0xf79c}, {0xc7f0,0xf79d}, {0xc7f1,0xf79e}, {0xc7f2,0xf79f}, {0xc7f3,0xf7a0}, - {0xc7f4,0xf7a1}, {0xc7f5,0xf7a2}, {0xc7f6,0xf7a3}, {0xc7f7,0xf7a4}, {0xc7f8,0xf7a5}, {0xc7f9,0xf7a6}, {0xc7fa,0xf7a7}, {0xc7fb,0xf7a8}, {0xc7fc,0xf7a9}, {0xc7fd,0xf7aa}, - {0xc7fe,0xf7ab}, {0xc840,0xf7ac}, {0xc841,0xf7ad}, {0xc842,0xf7ae}, {0xc843,0xf7af}, {0xc844,0xf7b0}, {0xc845,0xf7b1}, {0xc846,0xf7b2}, {0xc847,0xf7b3}, {0xc848,0xf7b4}, - {0xc849,0xf7b5}, {0xc84a,0xf7b6}, {0xc84b,0xf7b7}, {0xc84c,0xf7b8}, {0xc84d,0xf7b9}, {0xc84e,0xf7ba}, {0xc84f,0xf7bb}, {0xc850,0xf7bc}, {0xc851,0xf7bd}, {0xc852,0xf7be}, - {0xc853,0xf7bf}, {0xc854,0xf7c0}, {0xc855,0xf7c1}, {0xc856,0xf7c2}, {0xc857,0xf7c3}, {0xc858,0xf7c4}, {0xc859,0xf7c5}, {0xc85a,0xf7c6}, {0xc85b,0xf7c7}, {0xc85c,0xf7c8}, - {0xc85d,0xf7c9}, {0xc85e,0xf7ca}, {0xc85f,0xf7cb}, {0xc860,0xf7cc}, {0xc861,0xf7cd}, {0xc862,0xf7ce}, {0xc863,0xf7cf}, {0xc864,0xf7d0}, {0xc865,0xf7d1}, {0xc866,0xf7d2}, - {0xc867,0xf7d3}, {0xc868,0xf7d4}, {0xc869,0xf7d5}, {0xc86a,0xf7d6}, {0xc86b,0xf7d7}, {0xc86c,0xf7d8}, {0xc86d,0xf7d9}, {0xc86e,0xf7da}, {0xc86f,0xf7db}, {0xc870,0xf7dc}, - {0xc871,0xf7dd}, {0xc872,0xf7de}, {0xc873,0xf7df}, {0xc874,0xf7e0}, {0xc875,0xf7e1}, {0xc876,0xf7e2}, {0xc877,0xf7e3}, {0xc878,0xf7e4}, {0xc879,0xf7e5}, {0xc87a,0xf7e6}, - {0xc87b,0xf7e7}, {0xc87c,0xf7e8}, {0xc87d,0xf7e9}, {0xc87e,0xf7ea}, {0xc8a1,0xf7eb}, {0xc8a2,0xf7ec}, {0xc8a3,0xf7ed}, {0xc8a4,0xf7ee}, {0xc8a5,0xf7ef}, {0xc8a6,0xf7f0}, - {0xc8a7,0xf7f1}, {0xc8a8,0xf7f2}, {0xc8a9,0xf7f3}, {0xc8aa,0xf7f4}, {0xc8ab,0xf7f5}, {0xc8ac,0xf7f6}, {0xc8ad,0xf7f7}, {0xc8ae,0xf7f8}, {0xc8af,0xf7f9}, {0xc8b0,0xf7fa}, - {0xc8b1,0xf7fb}, {0xc8b2,0xf7fc}, {0xc8b3,0xf7fd}, {0xc8b4,0xf7fe}, {0xc8b5,0xf7ff}, {0xc8b6,0xf800}, {0xc8b7,0xf801}, {0xc8b8,0xf802}, {0xc8b9,0xf803}, {0xc8ba,0xf804}, - {0xc8bb,0xf805}, {0xc8bc,0xf806}, {0xc8bd,0xf807}, {0xc8be,0xf808}, {0xc8bf,0xf809}, {0xc8c0,0xf80a}, {0xc8c1,0xf80b}, {0xc8c2,0xf80c}, {0xc8c3,0xf80d}, {0xc8c4,0xf80e}, - {0xc8c5,0xf80f}, {0xc8c6,0xf810}, {0xc8c7,0xf811}, {0xc8c8,0xf812}, {0xc8c9,0xf813}, {0xc8ca,0xf814}, {0xc8cb,0xf815}, {0xc8cc,0xf816}, {0xc8cd,0xf817}, {0xc8ce,0xf818}, - {0xc8cf,0xf819}, {0xc8d0,0xf81a}, {0xc8d1,0xf81b}, {0xc8d2,0xf81c}, {0xc8d3,0xf81d}, {0xc8d4,0xf81e}, {0xc8d5,0xf81f}, {0xc8d6,0xf820}, {0xc8d7,0xf821}, {0xc8d8,0xf822}, - {0xc8d9,0xf823}, {0xc8da,0xf824}, {0xc8db,0xf825}, {0xc8dc,0xf826}, {0xc8dd,0xf827}, {0xc8de,0xf828}, {0xc8df,0xf829}, {0xc8e0,0xf82a}, {0xc8e1,0xf82b}, {0xc8e2,0xf82c}, - {0xc8e3,0xf82d}, {0xc8e4,0xf82e}, {0xc8e5,0xf82f}, {0xc8e6,0xf830}, {0xc8e7,0xf831}, {0xc8e8,0xf832}, {0xc8e9,0xf833}, {0xc8ea,0xf834}, {0xc8eb,0xf835}, {0xc8ec,0xf836}, - {0xc8ed,0xf837}, {0xc8ee,0xf838}, {0xc8ef,0xf839}, {0xc8f0,0xf83a}, {0xc8f1,0xf83b}, {0xc8f2,0xf83c}, {0xc8f3,0xf83d}, {0xc8f4,0xf83e}, {0xc8f5,0xf83f}, {0xc8f6,0xf840}, - {0xc8f7,0xf841}, {0xc8f8,0xf842}, {0xc8f9,0xf843}, {0xc8fa,0xf844}, {0xc8fb,0xf845}, {0xc8fc,0xf846}, {0xc8fd,0xf847}, {0xc8fe,0xf848}, -}; - -static const B5Map b5_FA40_to_uc_map[786] = { - {0xf9fe,0x2593}, {0xfa40,0xe000}, {0xfa41,0xe001}, {0xfa42,0xe002}, {0xfa43,0xe003}, {0xfa44,0xe004}, {0xfa45,0xe005}, {0xfa46,0xe006}, {0xfa47,0xe007}, {0xfa48,0xe008}, - {0xfa49,0xe009}, {0xfa4a,0xe00a}, {0xfa4b,0xe00b}, {0xfa4c,0xe00c}, {0xfa4d,0xe00d}, {0xfa4e,0xe00e}, {0xfa4f,0xe00f}, {0xfa50,0xe010}, {0xfa51,0xe011}, {0xfa52,0xe012}, - {0xfa53,0xe013}, {0xfa54,0xe014}, {0xfa55,0xe015}, {0xfa56,0xe016}, {0xfa57,0xe017}, {0xfa58,0xe018}, {0xfa59,0xe019}, {0xfa5a,0xe01a}, {0xfa5b,0xe01b}, {0xfa5c,0xe01c}, - {0xfa5d,0xe01d}, {0xfa5e,0xe01e}, {0xfa5f,0xe01f}, {0xfa60,0xe020}, {0xfa61,0xe021}, {0xfa62,0xe022}, {0xfa63,0xe023}, {0xfa64,0xe024}, {0xfa65,0xe025}, {0xfa66,0xe026}, - {0xfa67,0xe027}, {0xfa68,0xe028}, {0xfa69,0xe029}, {0xfa6a,0xe02a}, {0xfa6b,0xe02b}, {0xfa6c,0xe02c}, {0xfa6d,0xe02d}, {0xfa6e,0xe02e}, {0xfa6f,0xe02f}, {0xfa70,0xe030}, - {0xfa71,0xe031}, {0xfa72,0xe032}, {0xfa73,0xe033}, {0xfa74,0xe034}, {0xfa75,0xe035}, {0xfa76,0xe036}, {0xfa77,0xe037}, {0xfa78,0xe038}, {0xfa79,0xe039}, {0xfa7a,0xe03a}, - {0xfa7b,0xe03b}, {0xfa7c,0xe03c}, {0xfa7d,0xe03d}, {0xfa7e,0xe03e}, {0xfaa1,0xe03f}, {0xfaa2,0xe040}, {0xfaa3,0xe041}, {0xfaa4,0xe042}, {0xfaa5,0xe043}, {0xfaa6,0xe044}, - {0xfaa7,0xe045}, {0xfaa8,0xe046}, {0xfaa9,0xe047}, {0xfaaa,0xe048}, {0xfaab,0xe049}, {0xfaac,0xe04a}, {0xfaad,0xe04b}, {0xfaae,0xe04c}, {0xfaaf,0xe04d}, {0xfab0,0xe04e}, - {0xfab1,0xe04f}, {0xfab2,0xe050}, {0xfab3,0xe051}, {0xfab4,0xe052}, {0xfab5,0xe053}, {0xfab6,0xe054}, {0xfab7,0xe055}, {0xfab8,0xe056}, {0xfab9,0xe057}, {0xfaba,0xe058}, - {0xfabb,0xe059}, {0xfabc,0xe05a}, {0xfabd,0xe05b}, {0xfabe,0xe05c}, {0xfabf,0xe05d}, {0xfac0,0xe05e}, {0xfac1,0xe05f}, {0xfac2,0xe060}, {0xfac3,0xe061}, {0xfac4,0xe062}, - {0xfac5,0xe063}, {0xfac6,0xe064}, {0xfac7,0xe065}, {0xfac8,0xe066}, {0xfac9,0xe067}, {0xfaca,0xe068}, {0xfacb,0xe069}, {0xfacc,0xe06a}, {0xfacd,0xe06b}, {0xface,0xe06c}, - {0xfacf,0xe06d}, {0xfad0,0xe06e}, {0xfad1,0xe06f}, {0xfad2,0xe070}, {0xfad3,0xe071}, {0xfad4,0xe072}, {0xfad5,0xe073}, {0xfad6,0xe074}, {0xfad7,0xe075}, {0xfad8,0xe076}, - {0xfad9,0xe077}, {0xfada,0xe078}, {0xfadb,0xe079}, {0xfadc,0xe07a}, {0xfadd,0xe07b}, {0xfade,0xe07c}, {0xfadf,0xe07d}, {0xfae0,0xe07e}, {0xfae1,0xe07f}, {0xfae2,0xe080}, - {0xfae3,0xe081}, {0xfae4,0xe082}, {0xfae5,0xe083}, {0xfae6,0xe084}, {0xfae7,0xe085}, {0xfae8,0xe086}, {0xfae9,0xe087}, {0xfaea,0xe088}, {0xfaeb,0xe089}, {0xfaec,0xe08a}, - {0xfaed,0xe08b}, {0xfaee,0xe08c}, {0xfaef,0xe08d}, {0xfaf0,0xe08e}, {0xfaf1,0xe08f}, {0xfaf2,0xe090}, {0xfaf3,0xe091}, {0xfaf4,0xe092}, {0xfaf5,0xe093}, {0xfaf6,0xe094}, - {0xfaf7,0xe095}, {0xfaf8,0xe096}, {0xfaf9,0xe097}, {0xfafa,0xe098}, {0xfafb,0xe099}, {0xfafc,0xe09a}, {0xfafd,0xe09b}, {0xfafe,0xe09c}, {0xfb40,0xe09d}, {0xfb41,0xe09e}, - {0xfb42,0xe09f}, {0xfb43,0xe0a0}, {0xfb44,0xe0a1}, {0xfb45,0xe0a2}, {0xfb46,0xe0a3}, {0xfb47,0xe0a4}, {0xfb48,0xe0a5}, {0xfb49,0xe0a6}, {0xfb4a,0xe0a7}, {0xfb4b,0xe0a8}, - {0xfb4c,0xe0a9}, {0xfb4d,0xe0aa}, {0xfb4e,0xe0ab}, {0xfb4f,0xe0ac}, {0xfb50,0xe0ad}, {0xfb51,0xe0ae}, {0xfb52,0xe0af}, {0xfb53,0xe0b0}, {0xfb54,0xe0b1}, {0xfb55,0xe0b2}, - {0xfb56,0xe0b3}, {0xfb57,0xe0b4}, {0xfb58,0xe0b5}, {0xfb59,0xe0b6}, {0xfb5a,0xe0b7}, {0xfb5b,0xe0b8}, {0xfb5c,0xe0b9}, {0xfb5d,0xe0ba}, {0xfb5e,0xe0bb}, {0xfb5f,0xe0bc}, - {0xfb60,0xe0bd}, {0xfb61,0xe0be}, {0xfb62,0xe0bf}, {0xfb63,0xe0c0}, {0xfb64,0xe0c1}, {0xfb65,0xe0c2}, {0xfb66,0xe0c3}, {0xfb67,0xe0c4}, {0xfb68,0xe0c5}, {0xfb69,0xe0c6}, - {0xfb6a,0xe0c7}, {0xfb6b,0xe0c8}, {0xfb6c,0xe0c9}, {0xfb6d,0xe0ca}, {0xfb6e,0xe0cb}, {0xfb6f,0xe0cc}, {0xfb70,0xe0cd}, {0xfb71,0xe0ce}, {0xfb72,0xe0cf}, {0xfb73,0xe0d0}, - {0xfb74,0xe0d1}, {0xfb75,0xe0d2}, {0xfb76,0xe0d3}, {0xfb77,0xe0d4}, {0xfb78,0xe0d5}, {0xfb79,0xe0d6}, {0xfb7a,0xe0d7}, {0xfb7b,0xe0d8}, {0xfb7c,0xe0d9}, {0xfb7d,0xe0da}, - {0xfb7e,0xe0db}, {0xfba1,0xe0dc}, {0xfba2,0xe0dd}, {0xfba3,0xe0de}, {0xfba4,0xe0df}, {0xfba5,0xe0e0}, {0xfba6,0xe0e1}, {0xfba7,0xe0e2}, {0xfba8,0xe0e3}, {0xfba9,0xe0e4}, - {0xfbaa,0xe0e5}, {0xfbab,0xe0e6}, {0xfbac,0xe0e7}, {0xfbad,0xe0e8}, {0xfbae,0xe0e9}, {0xfbaf,0xe0ea}, {0xfbb0,0xe0eb}, {0xfbb1,0xe0ec}, {0xfbb2,0xe0ed}, {0xfbb3,0xe0ee}, - {0xfbb4,0xe0ef}, {0xfbb5,0xe0f0}, {0xfbb6,0xe0f1}, {0xfbb7,0xe0f2}, {0xfbb8,0xe0f3}, {0xfbb9,0xe0f4}, {0xfbba,0xe0f5}, {0xfbbb,0xe0f6}, {0xfbbc,0xe0f7}, {0xfbbd,0xe0f8}, - {0xfbbe,0xe0f9}, {0xfbbf,0xe0fa}, {0xfbc0,0xe0fb}, {0xfbc1,0xe0fc}, {0xfbc2,0xe0fd}, {0xfbc3,0xe0fe}, {0xfbc4,0xe0ff}, {0xfbc5,0xe100}, {0xfbc6,0xe101}, {0xfbc7,0xe102}, - {0xfbc8,0xe103}, {0xfbc9,0xe104}, {0xfbca,0xe105}, {0xfbcb,0xe106}, {0xfbcc,0xe107}, {0xfbcd,0xe108}, {0xfbce,0xe109}, {0xfbcf,0xe10a}, {0xfbd0,0xe10b}, {0xfbd1,0xe10c}, - {0xfbd2,0xe10d}, {0xfbd3,0xe10e}, {0xfbd4,0xe10f}, {0xfbd5,0xe110}, {0xfbd6,0xe111}, {0xfbd7,0xe112}, {0xfbd8,0xe113}, {0xfbd9,0xe114}, {0xfbda,0xe115}, {0xfbdb,0xe116}, - {0xfbdc,0xe117}, {0xfbdd,0xe118}, {0xfbde,0xe119}, {0xfbdf,0xe11a}, {0xfbe0,0xe11b}, {0xfbe1,0xe11c}, {0xfbe2,0xe11d}, {0xfbe3,0xe11e}, {0xfbe4,0xe11f}, {0xfbe5,0xe120}, - {0xfbe6,0xe121}, {0xfbe7,0xe122}, {0xfbe8,0xe123}, {0xfbe9,0xe124}, {0xfbea,0xe125}, {0xfbeb,0xe126}, {0xfbec,0xe127}, {0xfbed,0xe128}, {0xfbee,0xe129}, {0xfbef,0xe12a}, - {0xfbf0,0xe12b}, {0xfbf1,0xe12c}, {0xfbf2,0xe12d}, {0xfbf3,0xe12e}, {0xfbf4,0xe12f}, {0xfbf5,0xe130}, {0xfbf6,0xe131}, {0xfbf7,0xe132}, {0xfbf8,0xe133}, {0xfbf9,0xe134}, - {0xfbfa,0xe135}, {0xfbfb,0xe136}, {0xfbfc,0xe137}, {0xfbfd,0xe138}, {0xfbfe,0xe139}, {0xfc40,0xe13a}, {0xfc41,0xe13b}, {0xfc42,0xe13c}, {0xfc43,0xe13d}, {0xfc44,0xe13e}, - {0xfc45,0xe13f}, {0xfc46,0xe140}, {0xfc47,0xe141}, {0xfc48,0xe142}, {0xfc49,0xe143}, {0xfc4a,0xe144}, {0xfc4b,0xe145}, {0xfc4c,0xe146}, {0xfc4d,0xe147}, {0xfc4e,0xe148}, - {0xfc4f,0xe149}, {0xfc50,0xe14a}, {0xfc51,0xe14b}, {0xfc52,0xe14c}, {0xfc53,0xe14d}, {0xfc54,0xe14e}, {0xfc55,0xe14f}, {0xfc56,0xe150}, {0xfc57,0xe151}, {0xfc58,0xe152}, - {0xfc59,0xe153}, {0xfc5a,0xe154}, {0xfc5b,0xe155}, {0xfc5c,0xe156}, {0xfc5d,0xe157}, {0xfc5e,0xe158}, {0xfc5f,0xe159}, {0xfc60,0xe15a}, {0xfc61,0xe15b}, {0xfc62,0xe15c}, - {0xfc63,0xe15d}, {0xfc64,0xe15e}, {0xfc65,0xe15f}, {0xfc66,0xe160}, {0xfc67,0xe161}, {0xfc68,0xe162}, {0xfc69,0xe163}, {0xfc6a,0xe164}, {0xfc6b,0xe165}, {0xfc6c,0xe166}, - {0xfc6d,0xe167}, {0xfc6e,0xe168}, {0xfc6f,0xe169}, {0xfc70,0xe16a}, {0xfc71,0xe16b}, {0xfc72,0xe16c}, {0xfc73,0xe16d}, {0xfc74,0xe16e}, {0xfc75,0xe16f}, {0xfc76,0xe170}, - {0xfc77,0xe171}, {0xfc78,0xe172}, {0xfc79,0xe173}, {0xfc7a,0xe174}, {0xfc7b,0xe175}, {0xfc7c,0xe176}, {0xfc7d,0xe177}, {0xfc7e,0xe178}, {0xfca1,0xe179}, {0xfca2,0xe17a}, - {0xfca3,0xe17b}, {0xfca4,0xe17c}, {0xfca5,0xe17d}, {0xfca6,0xe17e}, {0xfca7,0xe17f}, {0xfca8,0xe180}, {0xfca9,0xe181}, {0xfcaa,0xe182}, {0xfcab,0xe183}, {0xfcac,0xe184}, - {0xfcad,0xe185}, {0xfcae,0xe186}, {0xfcaf,0xe187}, {0xfcb0,0xe188}, {0xfcb1,0xe189}, {0xfcb2,0xe18a}, {0xfcb3,0xe18b}, {0xfcb4,0xe18c}, {0xfcb5,0xe18d}, {0xfcb6,0xe18e}, - {0xfcb7,0xe18f}, {0xfcb8,0xe190}, {0xfcb9,0xe191}, {0xfcba,0xe192}, {0xfcbb,0xe193}, {0xfcbc,0xe194}, {0xfcbd,0xe195}, {0xfcbe,0xe196}, {0xfcbf,0xe197}, {0xfcc0,0xe198}, - {0xfcc1,0xe199}, {0xfcc2,0xe19a}, {0xfcc3,0xe19b}, {0xfcc4,0xe19c}, {0xfcc5,0xe19d}, {0xfcc6,0xe19e}, {0xfcc7,0xe19f}, {0xfcc8,0xe1a0}, {0xfcc9,0xe1a1}, {0xfcca,0xe1a2}, - {0xfccb,0xe1a3}, {0xfccc,0xe1a4}, {0xfccd,0xe1a5}, {0xfcce,0xe1a6}, {0xfccf,0xe1a7}, {0xfcd0,0xe1a8}, {0xfcd1,0xe1a9}, {0xfcd2,0xe1aa}, {0xfcd3,0xe1ab}, {0xfcd4,0xe1ac}, - {0xfcd5,0xe1ad}, {0xfcd6,0xe1ae}, {0xfcd7,0xe1af}, {0xfcd8,0xe1b0}, {0xfcd9,0xe1b1}, {0xfcda,0xe1b2}, {0xfcdb,0xe1b3}, {0xfcdc,0xe1b4}, {0xfcdd,0xe1b5}, {0xfcde,0xe1b6}, - {0xfcdf,0xe1b7}, {0xfce0,0xe1b8}, {0xfce1,0xe1b9}, {0xfce2,0xe1ba}, {0xfce3,0xe1bb}, {0xfce4,0xe1bc}, {0xfce5,0xe1bd}, {0xfce6,0xe1be}, {0xfce7,0xe1bf}, {0xfce8,0xe1c0}, - {0xfce9,0xe1c1}, {0xfcea,0xe1c2}, {0xfceb,0xe1c3}, {0xfcec,0xe1c4}, {0xfced,0xe1c5}, {0xfcee,0xe1c6}, {0xfcef,0xe1c7}, {0xfcf0,0xe1c8}, {0xfcf1,0xe1c9}, {0xfcf2,0xe1ca}, - {0xfcf3,0xe1cb}, {0xfcf4,0xe1cc}, {0xfcf5,0xe1cd}, {0xfcf6,0xe1ce}, {0xfcf7,0xe1cf}, {0xfcf8,0xe1d0}, {0xfcf9,0xe1d1}, {0xfcfa,0xe1d2}, {0xfcfb,0xe1d3}, {0xfcfc,0xe1d4}, - {0xfcfd,0xe1d5}, {0xfcfe,0xe1d6}, {0xfd40,0xe1d7}, {0xfd41,0xe1d8}, {0xfd42,0xe1d9}, {0xfd43,0xe1da}, {0xfd44,0xe1db}, {0xfd45,0xe1dc}, {0xfd46,0xe1dd}, {0xfd47,0xe1de}, - {0xfd48,0xe1df}, {0xfd49,0xe1e0}, {0xfd4a,0xe1e1}, {0xfd4b,0xe1e2}, {0xfd4c,0xe1e3}, {0xfd4d,0xe1e4}, {0xfd4e,0xe1e5}, {0xfd4f,0xe1e6}, {0xfd50,0xe1e7}, {0xfd51,0xe1e8}, - {0xfd52,0xe1e9}, {0xfd53,0xe1ea}, {0xfd54,0xe1eb}, {0xfd55,0xe1ec}, {0xfd56,0xe1ed}, {0xfd57,0xe1ee}, {0xfd58,0xe1ef}, {0xfd59,0xe1f0}, {0xfd5a,0xe1f1}, {0xfd5b,0xe1f2}, - {0xfd5c,0xe1f3}, {0xfd5d,0xe1f4}, {0xfd5e,0xe1f5}, {0xfd5f,0xe1f6}, {0xfd60,0xe1f7}, {0xfd61,0xe1f8}, {0xfd62,0xe1f9}, {0xfd63,0xe1fa}, {0xfd64,0xe1fb}, {0xfd65,0xe1fc}, - {0xfd66,0xe1fd}, {0xfd67,0xe1fe}, {0xfd68,0xe1ff}, {0xfd69,0xe200}, {0xfd6a,0xe201}, {0xfd6b,0xe202}, {0xfd6c,0xe203}, {0xfd6d,0xe204}, {0xfd6e,0xe205}, {0xfd6f,0xe206}, - {0xfd70,0xe207}, {0xfd71,0xe208}, {0xfd72,0xe209}, {0xfd73,0xe20a}, {0xfd74,0xe20b}, {0xfd75,0xe20c}, {0xfd76,0xe20d}, {0xfd77,0xe20e}, {0xfd78,0xe20f}, {0xfd79,0xe210}, - {0xfd7a,0xe211}, {0xfd7b,0xe212}, {0xfd7c,0xe213}, {0xfd7d,0xe214}, {0xfd7e,0xe215}, {0xfda1,0xe216}, {0xfda2,0xe217}, {0xfda3,0xe218}, {0xfda4,0xe219}, {0xfda5,0xe21a}, - {0xfda6,0xe21b}, {0xfda7,0xe21c}, {0xfda8,0xe21d}, {0xfda9,0xe21e}, {0xfdaa,0xe21f}, {0xfdab,0xe220}, {0xfdac,0xe221}, {0xfdad,0xe222}, {0xfdae,0xe223}, {0xfdaf,0xe224}, - {0xfdb0,0xe225}, {0xfdb1,0xe226}, {0xfdb2,0xe227}, {0xfdb3,0xe228}, {0xfdb4,0xe229}, {0xfdb5,0xe22a}, {0xfdb6,0xe22b}, {0xfdb7,0xe22c}, {0xfdb8,0xe22d}, {0xfdb9,0xe22e}, - {0xfdba,0xe22f}, {0xfdbb,0xe230}, {0xfdbc,0xe231}, {0xfdbd,0xe232}, {0xfdbe,0xe233}, {0xfdbf,0xe234}, {0xfdc0,0xe235}, {0xfdc1,0xe236}, {0xfdc2,0xe237}, {0xfdc3,0xe238}, - {0xfdc4,0xe239}, {0xfdc5,0xe23a}, {0xfdc6,0xe23b}, {0xfdc7,0xe23c}, {0xfdc8,0xe23d}, {0xfdc9,0xe23e}, {0xfdca,0xe23f}, {0xfdcb,0xe240}, {0xfdcc,0xe241}, {0xfdcd,0xe242}, - {0xfdce,0xe243}, {0xfdcf,0xe244}, {0xfdd0,0xe245}, {0xfdd1,0xe246}, {0xfdd2,0xe247}, {0xfdd3,0xe248}, {0xfdd4,0xe249}, {0xfdd5,0xe24a}, {0xfdd6,0xe24b}, {0xfdd7,0xe24c}, - {0xfdd8,0xe24d}, {0xfdd9,0xe24e}, {0xfdda,0xe24f}, {0xfddb,0xe250}, {0xfddc,0xe251}, {0xfddd,0xe252}, {0xfdde,0xe253}, {0xfddf,0xe254}, {0xfde0,0xe255}, {0xfde1,0xe256}, - {0xfde2,0xe257}, {0xfde3,0xe258}, {0xfde4,0xe259}, {0xfde5,0xe25a}, {0xfde6,0xe25b}, {0xfde7,0xe25c}, {0xfde8,0xe25d}, {0xfde9,0xe25e}, {0xfdea,0xe25f}, {0xfdeb,0xe260}, - {0xfdec,0xe261}, {0xfded,0xe262}, {0xfdee,0xe263}, {0xfdef,0xe264}, {0xfdf0,0xe265}, {0xfdf1,0xe266}, {0xfdf2,0xe267}, {0xfdf3,0xe268}, {0xfdf4,0xe269}, {0xfdf5,0xe26a}, - {0xfdf6,0xe26b}, {0xfdf7,0xe26c}, {0xfdf8,0xe26d}, {0xfdf9,0xe26e}, {0xfdfa,0xe26f}, {0xfdfb,0xe270}, {0xfdfc,0xe271}, {0xfdfd,0xe272}, {0xfdfe,0xe273}, {0xfe40,0xe274}, - {0xfe41,0xe275}, {0xfe42,0xe276}, {0xfe43,0xe277}, {0xfe44,0xe278}, {0xfe45,0xe279}, {0xfe46,0xe27a}, {0xfe47,0xe27b}, {0xfe48,0xe27c}, {0xfe49,0xe27d}, {0xfe4a,0xe27e}, - {0xfe4b,0xe27f}, {0xfe4c,0xe280}, {0xfe4d,0xe281}, {0xfe4e,0xe282}, {0xfe4f,0xe283}, {0xfe50,0xe284}, {0xfe51,0xe285}, {0xfe52,0xe286}, {0xfe53,0xe287}, {0xfe54,0xe288}, - {0xfe55,0xe289}, {0xfe56,0xe28a}, {0xfe57,0xe28b}, {0xfe58,0xe28c}, {0xfe59,0xe28d}, {0xfe5a,0xe28e}, {0xfe5b,0xe28f}, {0xfe5c,0xe290}, {0xfe5d,0xe291}, {0xfe5e,0xe292}, - {0xfe5f,0xe293}, {0xfe60,0xe294}, {0xfe61,0xe295}, {0xfe62,0xe296}, {0xfe63,0xe297}, {0xfe64,0xe298}, {0xfe65,0xe299}, {0xfe66,0xe29a}, {0xfe67,0xe29b}, {0xfe68,0xe29c}, - {0xfe69,0xe29d}, {0xfe6a,0xe29e}, {0xfe6b,0xe29f}, {0xfe6c,0xe2a0}, {0xfe6d,0xe2a1}, {0xfe6e,0xe2a2}, {0xfe6f,0xe2a3}, {0xfe70,0xe2a4}, {0xfe71,0xe2a5}, {0xfe72,0xe2a6}, - {0xfe73,0xe2a7}, {0xfe74,0xe2a8}, {0xfe75,0xe2a9}, {0xfe76,0xe2aa}, {0xfe77,0xe2ab}, {0xfe78,0xe2ac}, {0xfe79,0xe2ad}, {0xfe7a,0xe2ae}, {0xfe7b,0xe2af}, {0xfe7c,0xe2b0}, - {0xfe7d,0xe2b1}, {0xfe7e,0xe2b2}, {0xfea1,0xe2b3}, {0xfea2,0xe2b4}, {0xfea3,0xe2b5}, {0xfea4,0xe2b6}, {0xfea5,0xe2b7}, {0xfea6,0xe2b8}, {0xfea7,0xe2b9}, {0xfea8,0xe2ba}, - {0xfea9,0xe2bb}, {0xfeaa,0xe2bc}, {0xfeab,0xe2bd}, {0xfeac,0xe2be}, {0xfead,0xe2bf}, {0xfeae,0xe2c0}, {0xfeaf,0xe2c1}, {0xfeb0,0xe2c2}, {0xfeb1,0xe2c3}, {0xfeb2,0xe2c4}, - {0xfeb3,0xe2c5}, {0xfeb4,0xe2c6}, {0xfeb5,0xe2c7}, {0xfeb6,0xe2c8}, {0xfeb7,0xe2c9}, {0xfeb8,0xe2ca}, {0xfeb9,0xe2cb}, {0xfeba,0xe2cc}, {0xfebb,0xe2cd}, {0xfebc,0xe2ce}, - {0xfebd,0xe2cf}, {0xfebe,0xe2d0}, {0xfebf,0xe2d1}, {0xfec0,0xe2d2}, {0xfec1,0xe2d3}, {0xfec2,0xe2d4}, {0xfec3,0xe2d5}, {0xfec4,0xe2d6}, {0xfec5,0xe2d7}, {0xfec6,0xe2d8}, - {0xfec7,0xe2d9}, {0xfec8,0xe2da}, {0xfec9,0xe2db}, {0xfeca,0xe2dc}, {0xfecb,0xe2dd}, {0xfecc,0xe2de}, {0xfecd,0xe2df}, {0xfece,0xe2e0}, {0xfecf,0xe2e1}, {0xfed0,0xe2e2}, - {0xfed1,0xe2e3}, {0xfed2,0xe2e4}, {0xfed3,0xe2e5}, {0xfed4,0xe2e6}, {0xfed5,0xe2e7}, {0xfed6,0xe2e8}, {0xfed7,0xe2e9}, {0xfed8,0xe2ea}, {0xfed9,0xe2eb}, {0xfeda,0xe2ec}, - {0xfedb,0xe2ed}, {0xfedc,0xe2ee}, {0xfedd,0xe2ef}, {0xfede,0xe2f0}, {0xfedf,0xe2f1}, {0xfee0,0xe2f2}, {0xfee1,0xe2f3}, {0xfee2,0xe2f4}, {0xfee3,0xe2f5}, {0xfee4,0xe2f6}, - {0xfee5,0xe2f7}, {0xfee6,0xe2f8}, {0xfee7,0xe2f9}, {0xfee8,0xe2fa}, {0xfee9,0xe2fb}, {0xfeea,0xe2fc}, {0xfeeb,0xe2fd}, {0xfeec,0xe2fe}, {0xfeed,0xe2ff}, {0xfeee,0xe300}, - {0xfeef,0xe301}, {0xfef0,0xe302}, {0xfef1,0xe303}, {0xfef2,0xe304}, {0xfef3,0xe305}, {0xfef4,0xe306}, {0xfef5,0xe307}, {0xfef6,0xe308}, {0xfef7,0xe309}, {0xfef8,0xe30a}, - {0xfef9,0xe30b}, {0xfefa,0xe30c}, {0xfefb,0xe30d}, {0xfefc,0xe30e}, {0xfefd,0xe30f}, {0xfefe,0xe310}, -}; - -static const B5Map uc_to_b5_map[8] = { - {0xa2a4,0x2550}, {0xa2a5,0x255e}, {0xa2a7,0x2561}, {0xa2a6,0x256a}, {0xa27e,0x256d}, {0xa2a1,0x256e}, {0xa2a3,0x256f}, {0xa2a2,0x2570}, -}; - -//All the tables are sorted on both x and y, so can be used for binary search -const B5Index b5_map_table[5] = { - { b5_8140_to_uc_map , std::extent::value }, - { b5_8E40_to_uc_map , std::extent::value }, - { b5_C6A1_to_uc_map , std::extent::value }, - { b5_FA40_to_uc_map , std::extent::value }, - { uc_to_b5_map , std::extent::value }, -}; diff --git a/core/src/textcodec/Big5MapTable.h b/core/src/textcodec/Big5MapTable.h deleted file mode 100644 index 0d39c4c74a..0000000000 --- a/core/src/textcodec/Big5MapTable.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -struct B5Map { - uint16_t x; - uint16_t y; -}; - -struct B5Index { - const B5Map * table; - uint16_t tableSize; -}; - -extern const B5Index b5_map_table[5]; diff --git a/core/src/textcodec/Big5TextDecoder.cpp b/core/src/textcodec/Big5TextDecoder.cpp deleted file mode 100644 index 48ec9bdf16..0000000000 --- a/core/src/textcodec/Big5TextDecoder.cpp +++ /dev/null @@ -1,1794 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Big5TextDecoder.h" -#include "Big5MapTable.h" - -static const uint16_t big5hkscs_to_ucs[] = { - /* Big5-HKSCS 0x8140 .. 0x817E */ - 0xEEB8, 0xEEB9, 0xEEBA, 0xEEBB, 0xEEBC, 0xEEBD, 0xEEBE, 0xEEBF, 0xEEC0, 0xEEC1, 0xEEC2, 0xEEC3, 0xEEC4, 0xEEC5, 0xEEC6, 0xEEC7, - 0xEEC8, 0xEEC9, 0xEECA, 0xEECB, 0xEECC, 0xEECD, 0xEECE, 0xEECF, 0xEED0, 0xEED1, 0xEED2, 0xEED3, 0xEED4, 0xEED5, 0xEED6, 0xEED7, - 0xEED8, 0xEED9, 0xEEDA, 0xEEDB, 0xEEDC, 0xEEDD, 0xEEDE, 0xEEDF, 0xEEE0, 0xEEE1, 0xEEE2, 0xEEE3, 0xEEE4, 0xEEE5, 0xEEE6, 0xEEE7, - 0xEEE8, 0xEEE9, 0xEEEA, 0xEEEB, 0xEEEC, 0xEEED, 0xEEEE, 0xEEEF, 0xEEF0, 0xEEF1, 0xEEF2, 0xEEF3, 0xEEF4, 0xEEF5, 0xEEF6, - /* Big5-HKSCS 0x81A1 .. 0x81FE */ - 0xEEF7, 0xEEF8, 0xEEF9, 0xEEFA, 0xEEFB, 0xEEFC, 0xEEFD, - 0xEEFE, 0xEEFF, 0xEF00, 0xEF01, 0xEF02, 0xEF03, 0xEF04, 0xEF05, 0xEF06, 0xEF07, 0xEF08, 0xEF09, 0xEF0A, 0xEF0B, 0xEF0C, 0xEF0D, - 0xEF0E, 0xEF0F, 0xEF10, 0xEF11, 0xEF12, 0xEF13, 0xEF14, 0xEF15, 0xEF16, 0xEF17, 0xEF18, 0xEF19, 0xEF1A, 0xEF1B, 0xEF1C, 0xEF1D, - 0xEF1E, 0xEF1F, 0xEF20, 0xEF21, 0xEF22, 0xEF23, 0xEF24, 0xEF25, 0xEF26, 0xEF27, 0xEF28, 0xEF29, 0xEF2A, 0xEF2B, 0xEF2C, 0xEF2D, - 0xEF2E, 0xEF2F, 0xEF30, 0xEF31, 0xEF32, 0xEF33, 0xEF34, 0xEF35, 0xEF36, 0xEF37, 0xEF38, 0xEF39, 0xEF3A, 0xEF3B, 0xEF3C, 0xEF3D, - 0xEF3E, 0xEF3F, 0xEF40, 0xEF41, 0xEF42, 0xEF43, 0xEF44, 0xEF45, 0xEF46, 0xEF47, 0xEF48, 0xEF49, 0xEF4A, 0xEF4B, 0xEF4C, 0xEF4D, - 0xEF4E, 0xEF4F, 0xEF50, 0xEF51, 0xEF52, 0xEF53, 0xEF54, - /* Big5-HKSCS 0x8240 .. 0x827E */ - 0xEF55, 0xEF56, 0xEF57, 0xEF58, 0xEF59, 0xEF5A, 0xEF5B, 0xEF5C, 0xEF5D, 0xEF5E, 0xEF5F, 0xEF60, 0xEF61, 0xEF62, 0xEF63, 0xEF64, - 0xEF65, 0xEF66, 0xEF67, 0xEF68, 0xEF69, 0xEF6A, 0xEF6B, 0xEF6C, 0xEF6D, 0xEF6E, 0xEF6F, 0xEF70, 0xEF71, 0xEF72, 0xEF73, 0xEF74, - 0xEF75, 0xEF76, 0xEF77, 0xEF78, 0xEF79, 0xEF7A, 0xEF7B, 0xEF7C, 0xEF7D, 0xEF7E, 0xEF7F, 0xEF80, 0xEF81, 0xEF82, 0xEF83, 0xEF84, - 0xEF85, 0xEF86, 0xEF87, 0xEF88, 0xEF89, 0xEF8A, 0xEF8B, 0xEF8C, 0xEF8D, 0xEF8E, 0xEF8F, 0xEF90, 0xEF91, 0xEF92, 0xEF93, - /* Big5-HKSCS 0x82A1 .. 0x82FE */ - 0xEF94, 0xEF95, 0xEF96, 0xEF97, 0xEF98, 0xEF99, 0xEF9A, - 0xEF9B, 0xEF9C, 0xEF9D, 0xEF9E, 0xEF9F, 0xEFA0, 0xEFA1, 0xEFA2, 0xEFA3, 0xEFA4, 0xEFA5, 0xEFA6, 0xEFA7, 0xEFA8, 0xEFA9, 0xEFAA, - 0xEFAB, 0xEFAC, 0xEFAD, 0xEFAE, 0xEFAF, 0xEFB0, 0xEFB1, 0xEFB2, 0xEFB3, 0xEFB4, 0xEFB5, 0xEFB6, 0xEFB7, 0xEFB8, 0xEFB9, 0xEFBA, - 0xEFBB, 0xEFBC, 0xEFBD, 0xEFBE, 0xEFBF, 0xEFC0, 0xEFC1, 0xEFC2, 0xEFC3, 0xEFC4, 0xEFC5, 0xEFC6, 0xEFC7, 0xEFC8, 0xEFC9, 0xEFCA, - 0xEFCB, 0xEFCC, 0xEFCD, 0xEFCE, 0xEFCF, 0xEFD0, 0xEFD1, 0xEFD2, 0xEFD3, 0xEFD4, 0xEFD5, 0xEFD6, 0xEFD7, 0xEFD8, 0xEFD9, 0xEFDA, - 0xEFDB, 0xEFDC, 0xEFDD, 0xEFDE, 0xEFDF, 0xEFE0, 0xEFE1, 0xEFE2, 0xEFE3, 0xEFE4, 0xEFE5, 0xEFE6, 0xEFE7, 0xEFE8, 0xEFE9, 0xEFEA, - 0xEFEB, 0xEFEC, 0xEFED, 0xEFEE, 0xEFEF, 0xEFF0, 0xEFF1, - /* Big5-HKSCS 0x8340 .. 0x837E */ - 0xEFF2, 0xEFF3, 0xEFF4, 0xEFF5, 0xEFF6, 0xEFF7, 0xEFF8, 0xEFF9, 0xEFFA, 0xEFFB, 0xEFFC, 0xEFFD, 0xEFFE, 0xEFFF, 0xF000, 0xF001, - 0xF002, 0xF003, 0xF004, 0xF005, 0xF006, 0xF007, 0xF008, 0xF009, 0xF00A, 0xF00B, 0xF00C, 0xF00D, 0xF00E, 0xF00F, 0xF010, 0xF011, - 0xF012, 0xF013, 0xF014, 0xF015, 0xF016, 0xF017, 0xF018, 0xF019, 0xF01A, 0xF01B, 0xF01C, 0xF01D, 0xF01E, 0xF01F, 0xF020, 0xF021, - 0xF022, 0xF023, 0xF024, 0xF025, 0xF026, 0xF027, 0xF028, 0xF029, 0xF02A, 0xF02B, 0xF02C, 0xF02D, 0xF02E, 0xF02F, 0xF030, - /* Big5-HKSCS 0x83A1 .. 0x83FE */ - 0xF031, 0xF032, 0xF033, 0xF034, 0xF035, 0xF036, 0xF037, - 0xF038, 0xF039, 0xF03A, 0xF03B, 0xF03C, 0xF03D, 0xF03E, 0xF03F, 0xF040, 0xF041, 0xF042, 0xF043, 0xF044, 0xF045, 0xF046, 0xF047, - 0xF048, 0xF049, 0xF04A, 0xF04B, 0xF04C, 0xF04D, 0xF04E, 0xF04F, 0xF050, 0xF051, 0xF052, 0xF053, 0xF054, 0xF055, 0xF056, 0xF057, - 0xF058, 0xF059, 0xF05A, 0xF05B, 0xF05C, 0xF05D, 0xF05E, 0xF05F, 0xF060, 0xF061, 0xF062, 0xF063, 0xF064, 0xF065, 0xF066, 0xF067, - 0xF068, 0xF069, 0xF06A, 0xF06B, 0xF06C, 0xF06D, 0xF06E, 0xF06F, 0xF070, 0xF071, 0xF072, 0xF073, 0xF074, 0xF075, 0xF076, 0xF077, - 0xF078, 0xF079, 0xF07A, 0xF07B, 0xF07C, 0xF07D, 0xF07E, 0xF07F, 0xF080, 0xF081, 0xF082, 0xF083, 0xF084, 0xF085, 0xF086, 0xF087, - 0xF088, 0xF089, 0xF08A, 0xF08B, 0xF08C, 0xF08D, 0xF08E, - /* Big5-HKSCS 0x8440 .. 0x847E */ - 0xF08F, 0xF090, 0xF091, 0xF092, 0xF093, 0xF094, 0xF095, 0xF096, 0xF097, 0xF098, 0xF099, 0xF09A, 0xF09B, 0xF09C, 0xF09D, 0xF09E, - 0xF09F, 0xF0A0, 0xF0A1, 0xF0A2, 0xF0A3, 0xF0A4, 0xF0A5, 0xF0A6, 0xF0A7, 0xF0A8, 0xF0A9, 0xF0AA, 0xF0AB, 0xF0AC, 0xF0AD, 0xF0AE, - 0xF0AF, 0xF0B0, 0xF0B1, 0xF0B2, 0xF0B3, 0xF0B4, 0xF0B5, 0xF0B6, 0xF0B7, 0xF0B8, 0xF0B9, 0xF0BA, 0xF0BB, 0xF0BC, 0xF0BD, 0xF0BE, - 0xF0BF, 0xF0C0, 0xF0C1, 0xF0C2, 0xF0C3, 0xF0C4, 0xF0C5, 0xF0C6, 0xF0C7, 0xF0C8, 0xF0C9, 0xF0CA, 0xF0CB, 0xF0CC, 0xF0CD, - /* Big5-HKSCS 0x84A1 .. 0x84FE */ - 0xF0CE, 0xF0CF, 0xF0D0, 0xF0D1, 0xF0D2, 0xF0D3, 0xF0D4, - 0xF0D5, 0xF0D6, 0xF0D7, 0xF0D8, 0xF0D9, 0xF0DA, 0xF0DB, 0xF0DC, 0xF0DD, 0xF0DE, 0xF0DF, 0xF0E0, 0xF0E1, 0xF0E2, 0xF0E3, 0xF0E4, - 0xF0E5, 0xF0E6, 0xF0E7, 0xF0E8, 0xF0E9, 0xF0EA, 0xF0EB, 0xF0EC, 0xF0ED, 0xF0EE, 0xF0EF, 0xF0F0, 0xF0F1, 0xF0F2, 0xF0F3, 0xF0F4, - 0xF0F5, 0xF0F6, 0xF0F7, 0xF0F8, 0xF0F9, 0xF0FA, 0xF0FB, 0xF0FC, 0xF0FD, 0xF0FE, 0xF0FF, 0xF100, 0xF101, 0xF102, 0xF103, 0xF104, - 0xF105, 0xF106, 0xF107, 0xF108, 0xF109, 0xF10A, 0xF10B, 0xF10C, 0xF10D, 0xF10E, 0xF10F, 0xF110, 0xF111, 0xF112, 0xF113, 0xF114, - 0xF115, 0xF116, 0xF117, 0xF118, 0xF119, 0xF11A, 0xF11B, 0xF11C, 0xF11D, 0xF11E, 0xF11F, 0xF120, 0xF121, 0xF122, 0xF123, 0xF124, - 0xF125, 0xF126, 0xF127, 0xF128, 0xF129, 0xF12A, 0xF12B, - /* Big5-HKSCS 0x8540 .. 0x857E */ - 0xF12C, 0xF12D, 0xF12E, 0xF12F, 0xF130, 0xF131, 0xF132, 0xF133, 0xF134, 0xF135, 0xF136, 0xF137, 0xF138, 0xF139, 0xF13A, 0xF13B, - 0xF13C, 0xF13D, 0xF13E, 0xF13F, 0xF140, 0xF141, 0xF142, 0xF143, 0xF144, 0xF145, 0xF146, 0xF147, 0xF148, 0xF149, 0xF14A, 0xF14B, - 0xF14C, 0xF14D, 0xF14E, 0xF14F, 0xF150, 0xF151, 0xF152, 0xF153, 0xF154, 0xF155, 0xF156, 0xF157, 0xF158, 0xF159, 0xF15A, 0xF15B, - 0xF15C, 0xF15D, 0xF15E, 0xF15F, 0xF160, 0xF161, 0xF162, 0xF163, 0xF164, 0xF165, 0xF166, 0xF167, 0xF168, 0xF169, 0xF16A, - /* Big5-HKSCS 0x85A1 .. 0x85FE */ - 0xF16B, 0xF16C, 0xF16D, 0xF16E, 0xF16F, 0xF170, 0xF171, - 0xF172, 0xF173, 0xF174, 0xF175, 0xF176, 0xF177, 0xF178, 0xF179, 0xF17A, 0xF17B, 0xF17C, 0xF17D, 0xF17E, 0xF17F, 0xF180, 0xF181, - 0xF182, 0xF183, 0xF184, 0xF185, 0xF186, 0xF187, 0xF188, 0xF189, 0xF18A, 0xF18B, 0xF18C, 0xF18D, 0xF18E, 0xF18F, 0xF190, 0xF191, - 0xF192, 0xF193, 0xF194, 0xF195, 0xF196, 0xF197, 0xF198, 0xF199, 0xF19A, 0xF19B, 0xF19C, 0xF19D, 0xF19E, 0xF19F, 0xF1A0, 0xF1A1, - 0xF1A2, 0xF1A3, 0xF1A4, 0xF1A5, 0xF1A6, 0xF1A7, 0xF1A8, 0xF1A9, 0xF1AA, 0xF1AB, 0xF1AC, 0xF1AD, 0xF1AE, 0xF1AF, 0xF1B0, 0xF1B1, - 0xF1B2, 0xF1B3, 0xF1B4, 0xF1B5, 0xF1B6, 0xF1B7, 0xF1B8, 0xF1B9, 0xF1BA, 0xF1BB, 0xF1BC, 0xF1BD, 0xF1BE, 0xF1BF, 0xF1C0, 0xF1C1, - 0xF1C2, 0xF1C3, 0xF1C4, 0xF1C5, 0xF1C6, 0xF1C7, 0xF1C8, - /* Big5-HKSCS 0x8640 .. 0x867E */ - 0xF1C9, 0xF1CA, 0xF1CB, 0xF1CC, 0xF1CD, 0xF1CE, 0xF1CF, 0xF1D0, 0xF1D1, 0xF1D2, 0xF1D3, 0xF1D4, 0xF1D5, 0xF1D6, 0xF1D7, 0xF1D8, - 0xF1D9, 0xF1DA, 0xF1DB, 0xF1DC, 0xF1DD, 0xF1DE, 0xF1DF, 0xF1E0, 0xF1E1, 0xF1E2, 0xF1E3, 0xF1E4, 0xF1E5, 0xF1E6, 0xF1E7, 0xF1E8, - 0xF1E9, 0xF1EA, 0xF1EB, 0xF1EC, 0xF1ED, 0xF1EE, 0xF1EF, 0xF1F0, 0xF1F1, 0xF1F2, 0xF1F3, 0xF1F4, 0xF1F5, 0xF1F6, 0xF1F7, 0xF1F8, - 0xF1F9, 0xF1FA, 0xF1FB, 0xF1FC, 0xF1FD, 0xF1FE, 0xF1FF, 0xF200, 0xF201, 0xF202, 0xF203, 0xF204, 0xF205, 0xF206, 0xF207, - /* Big5-HKSCS 0x86A1 .. 0x86FE */ - 0xF208, 0xF209, 0xF20A, 0xF20B, 0xF20C, 0xF20D, 0xF20E, - 0xF20F, 0xF210, 0xF211, 0xF212, 0xF213, 0xF214, 0xF215, 0xF216, 0xF217, 0xF218, 0xF219, 0xF21A, 0xF21B, 0xF21C, 0xF21D, 0xF21E, - 0xF21F, 0xF220, 0xF221, 0xF222, 0xF223, 0xF224, 0xF225, 0xF226, 0xF227, 0xF228, 0xF229, 0xF22A, 0xF22B, 0xF22C, 0xF22D, 0xF22E, - 0xF22F, 0xF230, 0xF231, 0xF232, 0xF233, 0xF234, 0xF235, 0xF236, 0xF237, 0xF238, 0xF239, 0xF23A, 0xF23B, 0xF23C, 0xF23D, 0xF23E, - 0xF23F, 0xF240, 0xF241, 0xF242, 0xF243, 0xF244, 0xF245, 0xF246, 0xF247, 0xF248, 0xF249, 0xF24A, 0xF24B, 0xF24C, 0xF24D, 0xF24E, - 0xF24F, 0xF250, 0xF251, 0xF252, 0xF253, 0xF254, 0xF255, 0xF256, 0xF257, 0xF258, 0xF259, 0xF25A, 0xF25B, 0xF25C, 0xF25D, 0xF25E, - 0xF25F, 0xF260, 0xF261, 0xF262, 0xF263, 0xF264, 0xF265, - /* Big5-HKSCS 0x8740 .. 0x877E */ - 0xF266, 0xF267, 0xF268, 0xF269, 0xF26A, 0xF26B, 0xF26C, 0xF26D, 0xF26E, 0xF26F, 0xF270, 0xF271, 0xF272, 0xF273, 0xF274, 0xF275, - 0xF276, 0xF277, 0xF278, 0xF279, 0xF27A, 0xF27B, 0xF27C, 0xF27D, 0xF27E, 0xF27F, 0xF280, 0xF281, 0xF282, 0xF283, 0xF284, 0xF285, - 0xF286, 0xF287, 0xF288, 0xF289, 0xF28A, 0xF28B, 0xF28C, 0xF28D, 0xF28E, 0xF28F, 0xF290, 0xF291, 0xF292, 0xF293, 0xF294, 0xF295, - 0xF296, 0xF297, 0xF298, 0xF299, 0xF29A, 0xF29B, 0xF29C, 0xF29D, 0xF29E, 0xF29F, 0xF2A0, 0xF2A1, 0xF2A2, 0xF2A3, 0xF2A4, - /* Big5-HKSCS 0x87A1 .. 0x87FE */ - 0xF2A5, 0xF2A6, 0xF2A7, 0xF2A8, 0xF2A9, 0xF2AA, 0xF2AB, - 0xF2AC, 0xF2AD, 0xF2AE, 0xF2AF, 0xF2B0, 0xF2B1, 0xF2B2, 0xF2B3, 0xF2B4, 0xF2B5, 0xF2B6, 0xF2B7, 0xF2B8, 0xF2B9, 0xF2BA, 0xF2BB, - 0xF2BC, 0xF2BD, 0xF2BE, 0xF2BF, 0xF2C0, 0xF2C1, 0xF2C2, 0xF2C3, 0xF2C4, 0xF2C5, 0xF2C6, 0xF2C7, 0xF2C8, 0xF2C9, 0xF2CA, 0xF2CB, - 0xF2CC, 0xF2CD, 0xF2CE, 0xF2CF, 0xF2D0, 0xF2D1, 0xF2D2, 0xF2D3, 0xF2D4, 0xF2D5, 0xF2D6, 0xF2D7, 0xF2D8, 0xF2D9, 0xF2DA, 0xF2DB, - 0xF2DC, 0xF2DD, 0xF2DE, 0xF2DF, 0xF2E0, 0xF2E1, 0xF2E2, 0xF2E3, 0xF2E4, 0xF2E5, 0xF2E6, 0xF2E7, 0xF2E8, 0xF2E9, 0xF2EA, 0xF2EB, - 0xF2EC, 0xF2ED, 0xF2EE, 0xF2EF, 0xF2F0, 0xF2F1, 0xF2F2, 0xF2F3, 0xF2F4, 0xF2F5, 0xF2F6, 0xF2F7, 0xF2F8, 0xF2F9, 0xF2FA, 0xF2FB, - 0xF2FC, 0xF2FD, 0xF2FE, 0xF2FF, 0xF300, 0xF301, 0xF302, - /* Big5-HKSCS 0x8840 .. 0x887E */ - 0xF303, 0xF304, 0xF305, 0xF306, 0xF307, 0xF308, 0xF309, 0xF30A, 0xF30B, 0xF30C, 0xF30D, 0xF30E, 0xF30F, 0xF310, 0xF311, 0xF312, - 0xF313, 0xF314, 0xF315, 0xF316, 0xF317, 0xF318, 0x0100, 0x00C1, 0x01CD, 0x00C0, 0x0112, 0x00C9, 0x011A, 0x00C8, 0x014C, 0x00D3, - 0x01D1, 0x00D2, 0xF325, 0x1EBE, 0xF327, 0x1EC0, 0x00CA, 0x0101, 0x00E1, 0x01CE, 0x00E0, 0x0251, 0x0113, 0x00E9, 0x011B, 0x00E8, - 0x012B, 0x00ED, 0x01D0, 0x00EC, 0x014D, 0x00F3, 0x01D2, 0x00F2, 0x016B, 0x00FA, 0x01D4, 0x00F9, 0x01D6, 0x01D8, 0x01DA, - /* Big5-HKSCS 0x88A1 .. 0x88FE */ - 0x01DC, 0x00FC, 0xF344, 0x1EBF, 0xF346, 0x1EC1, 0x00EA, - 0x0261, 0xF34A, 0xF34B, 0xF34C, 0xF34D, 0xF34E, 0xF34F, 0xF350, 0xF351, 0xF352, 0xF353, 0xF354, 0xF355, 0xF356, 0xF357, 0xF358, - 0xF359, 0xF35A, 0xF35B, 0xF35C, 0xF35D, 0xF35E, 0xF35F, 0xF360, 0xF361, 0xF362, 0xF363, 0xF364, 0xF365, 0xF366, 0xF367, 0xF368, - 0xF369, 0xF36A, 0xF36B, 0xF36C, 0xF36D, 0xF36E, 0xF36F, 0xF370, 0xF371, 0xF372, 0xF373, 0xF374, 0xF375, 0xF376, 0xF377, 0xF378, - 0xF379, 0xF37A, 0xF37B, 0xF37C, 0xF37D, 0xF37E, 0xF37F, 0xF380, 0xF381, 0xF382, 0xF383, 0xF384, 0xF385, 0xF386, 0xF387, 0xF388, - 0xF389, 0xF38A, 0xF38B, 0xF38C, 0xF38D, 0xF38E, 0xF38F, 0xF390, 0xF391, 0xF392, 0xF393, 0xF394, 0xF395, 0xF396, 0xF397, 0xF398, - 0xF399, 0xF39A, 0xF39B, 0xF39C, 0xF39D, 0xF39E, 0xF39F, - /* Big5-HKSCS 0x8940 .. 0x897E */ - 0xF3A0, 0xF3A1, 0xF3A2, 0x650A, 0xF3A4, 0xF3A5, 0x4E3D, 0x6EDD, 0x9D4E, 0x91DF, 0xF3AA, 0xF3AB, 0xF3AC, 0x6491, 0x4F1A, 0x4F28, - 0x4FA8, 0x5156, 0x5174, 0x519C, 0x51E4, 0x52A1, 0x52A8, 0x533B, 0x534E, 0x53D1, 0x53D8, 0x56E2, 0x58F0, 0x5904, 0x5907, 0x5932, - 0x5934, 0x5B66, 0x5B9E, 0x5B9F, 0x5C9A, 0x5E86, 0x603B, 0x6589, 0x67FE, 0x6804, 0x6865, 0x6D4E, 0x70BC, 0x7535, 0x7EA4, 0x7EAC, - 0x7EBA, 0x7EC7, 0x7ECF, 0x7EDF, 0x7F06, 0x7F37, 0x827A, 0x82CF, 0x836F, 0x89C6, 0x8BBE, 0x8BE2, 0x8F66, 0x8F67, 0x8F6E, - /* Big5-HKSCS 0x89A1 .. 0x89FE */ - 0x7411, 0x7CFC, 0x7DCD, 0x6946, 0x7AC9, 0x5227, 0xF3E5, - 0xF3E6, 0xF3E7, 0xF3E8, 0x918C, 0x78B8, 0x915E, 0x80BC, 0xF3ED, 0x8D0B, 0x80F6, 0xF3F0, 0xF3F1, 0xF3F2, 0x809F, 0x9EC7, 0x4CCD, - 0x9DC9, 0x9E0C, 0x4C3E, 0xF3F9, 0xF3FA, 0x9E0A, 0xF3FC, 0x35C1, 0xF3FE, 0x6E9A, 0x823E, 0x7519, 0xF402, 0x4911, 0x9A6C, 0x9A8F, - 0x9F99, 0x7987, 0xF408, 0xF409, 0xF40A, 0xF40B, 0x4E24, 0x4E81, 0x4E80, 0x4E87, 0x4EBF, 0x4EEB, 0x4F37, 0x344C, 0x4FBD, 0x3E48, - 0x5003, 0x5088, 0x347D, 0x3493, 0x34A5, 0x5186, 0x5905, 0x51DB, 0x51FC, 0x5205, 0x4E89, 0x5279, 0x5290, 0x5327, 0x35C7, 0x53A9, - 0x3551, 0x53B0, 0x3553, 0x53C2, 0x5423, 0x356D, 0x3572, 0x3681, 0x5493, 0x54A3, 0x54B4, 0x54B9, 0x54D0, 0x54EF, 0x5518, 0x5523, - 0x5528, 0x3598, 0x553F, 0x35A5, 0x35BF, 0x55D7, 0x35C5, - /* Big5-HKSCS 0x8A40 .. 0x8A7E */ - 0xF43D, 0x5525, 0xF43F, 0xF440, 0xF441, 0xF442, 0x5590, 0xF444, 0x39EC, 0xF446, 0x8E46, 0xF448, 0xF449, 0x4053, 0xF44B, 0x777A, - 0xF44D, 0x3A34, 0x47D5, 0xF450, 0xF451, 0xF452, 0x64DD, 0xF454, 0xF455, 0xF456, 0xF457, 0x648D, 0x8E7E, 0xF45A, 0xF45B, 0xF45C, - 0xF45D, 0xF45E, 0xF45F, 0xF460, 0xF461, 0xF462, 0xF463, 0x47F4, 0xF465, 0xF466, 0x9AB2, 0x3A67, 0xF469, 0x3FED, 0x3506, 0xF46C, - 0xF46D, 0xF46E, 0xF46F, 0x9D6E, 0x9815, 0xF472, 0x43D9, 0xF474, 0x64B4, 0x54E3, 0xF477, 0xF478, 0xF479, 0x39FB, 0xF47B, - /* Big5-HKSCS 0x8AA1 .. 0x8AFE */ - 0xF47C, 0xF47D, 0xF47E, 0x64EA, 0xF480, 0xF481, 0x8E68, - 0xF483, 0xF484, 0xF485, 0xF486, 0x480B, 0xF488, 0x3FFA, 0x5873, 0xF48B, 0xF48C, 0xF48D, 0xF48E, 0xF48F, 0xF490, 0xF491, 0x5579, - 0x40BB, 0x43BA, 0xF495, 0x4AB4, 0xF497, 0xF498, 0x81AA, 0x98F5, 0xF49B, 0x6379, 0x39FE, 0xF49E, 0x8DC0, 0x56A1, 0x647C, 0x3E43, - 0xF4A3, 0xF4A4, 0xF4A5, 0xF4A6, 0xF4A7, 0xF4A8, 0xF4A9, 0xF4AA, 0x3992, 0x3A06, 0xF4AD, 0x3578, 0xF4AF, 0xF4B0, 0x5652, 0xF4B2, - 0xF4B3, 0xF4B4, 0x34BC, 0x6C3D, 0xF4B7, 0xF4B8, 0xF4B9, 0xF4BA, 0xF4BB, 0xF4BC, 0xF4BD, 0xF4BE, 0xF4BF, 0xF4C0, 0xF4C1, 0x7F93, - 0xF4C3, 0xF4C4, 0xF4C5, 0x35FB, 0xF4C7, 0xF4C8, 0xF4C9, 0xF4CA, 0x3F93, 0xF4CC, 0xF4CD, 0xF4CE, 0xF4CF, 0xF4D0, 0xF4D1, 0xF4D2, - 0xF4D3, 0xF4D4, 0xF4D5, 0x3FF9, 0xF4D7, 0x6432, 0xF4D9, - /* Big5-HKSCS 0x8B40 .. 0x8B7E */ - 0xF4DA, 0xF4DB, 0xF4DC, 0xF4DD, 0xF4DE, 0xF4DF, 0xF4E0, 0x3A18, 0xF4E2, 0xF4E3, 0xF4E4, 0xF4E5, 0xF4E6, 0xF4E7, 0xF4E8, 0xF4E9, - 0x95AA, 0x54CC, 0x82C4, 0x55B9, 0xF4EE, 0xF4EF, 0x9C26, 0x9AB6, 0xF4F2, 0xF4F3, 0x7140, 0x816D, 0x80EC, 0x5C1C, 0xF4F8, 0x8134, - 0x3797, 0x535F, 0xF4FC, 0x91B6, 0xF4FE, 0xF4FF, 0xF500, 0xF501, 0x35DD, 0xF503, 0x3609, 0xF505, 0x56AF, 0xF507, 0xF508, 0xF509, - 0xF50A, 0xF50B, 0xF50C, 0xF50D, 0xF50E, 0xF50F, 0xF510, 0xF511, 0x5A54, 0xF513, 0xF514, 0xF515, 0xF516, 0x579C, 0xF518, - /* Big5-HKSCS 0x8BA1 .. 0x8BFE */ - 0xF519, 0xF51A, 0xF51B, 0xF51C, 0xF51D, 0x3703, 0xF51F, - 0xF520, 0xF521, 0xF522, 0xF523, 0xF524, 0xF525, 0xF526, 0x5899, 0x5268, 0x361A, 0xF52A, 0x7BB2, 0x5B68, 0x4800, 0x4B2C, 0x9F27, - 0x49E7, 0x9C1F, 0x9B8D, 0xF533, 0xF534, 0x55FB, 0x35F2, 0x5689, 0x4E28, 0x5902, 0xF53A, 0xF53B, 0x9751, 0xF53D, 0x4E5B, 0x4EBB, - 0x353E, 0x5C23, 0x5F51, 0x5FC4, 0x38FA, 0x624C, 0x6535, 0x6B7A, 0x6C35, 0x6C3A, 0x706C, 0x722B, 0x4E2C, 0x72AD, 0xF54E, 0x7F52, - 0x793B, 0x7CF9, 0x7F53, 0xF553, 0x34C1, 0xF555, 0xF556, 0x8002, 0x8080, 0xF559, 0xF55A, 0x535D, 0x8864, 0x89C1, 0xF55E, 0x8BA0, - 0x8D1D, 0x9485, 0x9578, 0x957F, 0x95E8, 0xF565, 0x97E6, 0x9875, 0x98CE, 0x98DE, 0x9963, 0xF56B, 0x9C7C, 0x9E1F, 0x9EC4, 0x6B6F, - 0xF907, 0x4E37, 0xF572, 0x961D, 0x6237, 0x94A2, 0xF576, - /* Big5-HKSCS 0x8C40 .. 0x8C7E */ - 0x503B, 0x6DFE, 0xF579, 0xF57A, 0x3DC9, 0x888F, 0xF57D, 0x7077, 0x5CF5, 0x4B20, 0xF581, 0x3559, 0xF583, 0x6122, 0xF585, 0x8FA7, - 0x91F6, 0x7191, 0x6719, 0x73BA, 0xF58B, 0xF58C, 0x3C8B, 0xF58E, 0x4B10, 0x78E4, 0x7402, 0x51AE, 0xF593, 0x4009, 0x6A63, 0xF596, - 0x4223, 0x860F, 0xF599, 0x7A2A, 0xF59B, 0xF59C, 0x9755, 0x704D, 0x5324, 0xF5A0, 0x93F4, 0x76D9, 0xF5A3, 0xF5A4, 0x77DD, 0x4EA3, - 0x4FF0, 0x50BC, 0x4E2F, 0x4F17, 0xF5AB, 0x5434, 0x7D8B, 0x5892, 0x58D0, 0xF5B0, 0x5E92, 0x5E99, 0x5FC2, 0xF5B4, 0x658B, - /* Big5-HKSCS 0x8CA1 .. 0x8CFE */ - 0xF5B6, 0x6919, 0x6A43, 0xF5B9, 0x6CFF, 0xF5BB, 0x7200, - 0xF5BD, 0x738C, 0x3EDB, 0xF5C0, 0x5B15, 0x74B9, 0x8B83, 0xF5C4, 0xF5C5, 0x7A93, 0x7BEC, 0x7CC3, 0x7E6C, 0x82F8, 0x8597, 0xF5CC, - 0x8890, 0xF5CE, 0x8EB9, 0xF5D0, 0x8FCF, 0x855F, 0x99E0, 0x9221, 0xF5D5, 0xF5D6, 0xF5D7, 0x4071, 0x42A2, 0x5A1A, 0xF5DB, 0xF5DC, - 0xF5DD, 0x9868, 0x676B, 0x4276, 0x573D, 0xF5E2, 0x85D6, 0xF5E4, 0x82BF, 0xF5E6, 0x4C81, 0xF5E8, 0x5D7B, 0xF5EA, 0xF5EB, 0xF5EC, - 0xF5ED, 0x5B96, 0xF5EF, 0xF5F0, 0x7E5B, 0xF5F2, 0xF5F3, 0xF5F4, 0xF5F5, 0xF5F6, 0xF5F7, 0xF5F8, 0xF5F9, 0xF5FA, 0xF5FB, 0xF5FC, - 0xF5FD, 0xF5FE, 0xF5FF, 0xF600, 0xF601, 0xF602, 0xF603, 0xF604, 0xF605, 0xF606, 0xF607, 0xF608, 0xF609, 0xF60A, 0xF60B, 0xF60C, - 0xF60D, 0xF60E, 0xF60F, 0xF610, 0xF611, 0xF612, 0xF613, - /* Big5-HKSCS 0x8D40 .. 0x8D7E */ - 0xF614, 0xF615, 0xF616, 0xF617, 0xF618, 0xF619, 0xF61A, 0xF61B, 0xF61C, 0xF61D, 0xF61E, 0xF61F, 0xF620, 0xF621, 0xF622, 0xF623, - 0xF624, 0xF625, 0xF626, 0xF627, 0xF628, 0xF629, 0xF62A, 0xF62B, 0xF62C, 0xF62D, 0xF62E, 0xF62F, 0xF630, 0xF631, 0xF632, 0xF633, - 0x5D3E, 0x5D48, 0x5D56, 0x3DFC, 0x380F, 0x5DA4, 0x5DB9, 0x3820, 0x3838, 0x5E42, 0x5EBD, 0x5F25, 0x5F83, 0x3908, 0x3914, 0x393F, - 0x394D, 0x60D7, 0x613D, 0x5CE5, 0x3989, 0x61B7, 0x61B9, 0x61CF, 0x39B8, 0x622C, 0x6290, 0x62E5, 0x6318, 0x39F8, 0x56B1, - /* Big5-HKSCS 0x8DA1 .. 0x8DFE */ - 0x3A03, 0x63E2, 0x63FB, 0x6407, 0x645A, 0x3A4B, 0x64C0, - 0x5D15, 0x5621, 0x9F9F, 0x3A97, 0x6586, 0x3ABD, 0x65FF, 0x6653, 0x3AF2, 0x6692, 0x3B22, 0x6716, 0x3B42, 0x67A4, 0x6800, 0x3B58, - 0x684A, 0x6884, 0x3B72, 0x3B71, 0x3B7B, 0x6909, 0x6943, 0x725C, 0x6964, 0x699F, 0x6985, 0x3BBC, 0x69D6, 0x3BDD, 0x6A65, 0x6A74, - 0x6A71, 0x6A82, 0x3BEC, 0x6A99, 0x3BF2, 0x6AAB, 0x6AB5, 0x6AD4, 0x6AF6, 0x6B81, 0x6BC1, 0x6BEA, 0x6C75, 0x6CAA, 0x3CCB, 0x6D02, - 0x6D06, 0x6D26, 0x6D81, 0x3CEF, 0x6DA4, 0x6DB1, 0x6E15, 0x6E18, 0x6E29, 0x6E86, 0xF694, 0x6EBB, 0x6EE2, 0x6EDA, 0x9F7F, 0x6EE8, - 0x6EE9, 0x6F24, 0x6F34, 0x3D46, 0xF69E, 0x6F81, 0x6FBE, 0x3D6A, 0x3D75, 0x71B7, 0x5C99, 0x3D8A, 0x702C, 0x3D91, 0x7050, 0x7054, - 0x706F, 0x707F, 0x7089, 0xF6AD, 0x43C1, 0x35F1, 0xF6B0, - /* Big5-HKSCS 0x8E40 .. 0x8E7E */ - 0xE311, 0x57BE, 0xE313, 0x713E, 0xE315, 0x364E, 0x69A2, 0xE318, 0x5B74, 0x7A49, 0xE31B, 0xE31C, 0x7A65, 0x7A7D, 0xE31F, 0x7ABB, - 0x7AB0, 0x7AC2, 0x7AC3, 0x71D1, 0xE325, 0x41CA, 0x7ADA, 0x7ADD, 0x7AEA, 0x41EF, 0x54B2, 0xE32C, 0x7B0B, 0x7B55, 0x7B29, 0xE330, - 0xE331, 0x7BA2, 0x7B6F, 0x839C, 0xE335, 0xE336, 0x7BD0, 0x8421, 0x7B92, 0x7BB8, 0xE33B, 0x3DAD, 0xE33D, 0x8492, 0x7BFA, 0x7C06, - 0x7C35, 0xE342, 0x7C44, 0x7C83, 0xE345, 0x7CA6, 0x667D, 0xE348, 0x7CC9, 0x7CC7, 0x7CE6, 0x7C74, 0x7CF3, 0x7CF5, 0x7CCE, - /* Big5-HKSCS 0x8EA1 .. 0x8EFE */ - 0x7E67, 0x451D, 0xE352, 0x7D5D, 0xE354, 0x748D, 0x7D89, - 0x7DAB, 0x7135, 0x7DB3, 0x7DD2, 0xE35B, 0xE35C, 0x7DE4, 0x3D13, 0x7DF5, 0xE360, 0x7DE5, 0xE362, 0x7E1D, 0xE364, 0xE365, 0x7E6E, - 0x7E92, 0x432B, 0x946C, 0x7E27, 0x7F40, 0x7F41, 0x7F47, 0x7936, 0xE36F, 0x99E1, 0x7F97, 0xE372, 0x7FA3, 0xE374, 0xE375, 0x455C, - 0xE377, 0x4503, 0xE379, 0x7FFA, 0xE37B, 0x8005, 0x8008, 0x801D, 0x8028, 0x802F, 0xE381, 0xE382, 0x803B, 0x803C, 0x8061, 0xE386, - 0x4989, 0xE388, 0xE389, 0xE38A, 0x6725, 0x80A7, 0xE38D, 0x8107, 0x811A, 0x58B0, 0xE391, 0x6C7F, 0xE393, 0xE394, 0x64E7, 0xE396, - 0x8218, 0xE398, 0x6A53, 0xE39A, 0xE39B, 0x447A, 0x8229, 0xE39E, 0xE39F, 0xE3A0, 0x4FF9, 0xE3A2, 0x84E2, 0x8362, 0xE3A5, 0xE3A6, - 0xE3A7, 0xE3A8, 0xE3A9, 0x82AA, 0x691B, 0xE3AC, 0x41DB, - /* Big5-HKSCS 0x8F40 .. 0x8F7E */ - 0x854B, 0x82D0, 0x831A, 0xE3B1, 0xE3B2, 0x36C1, 0xE3B4, 0xE3B5, 0x827B, 0x82E2, 0x8318, 0xE3B9, 0xE3BA, 0xE3BB, 0xE3BC, 0xE3BD, - 0x3DBF, 0x831D, 0x55EC, 0x8385, 0x450B, 0xE3C3, 0x83AC, 0x83C1, 0x83D3, 0x347E, 0xE3C8, 0x6A57, 0x855A, 0x3496, 0xE3CC, 0xE3CD, - 0x8458, 0xE3CF, 0x8471, 0x3DD3, 0x44E4, 0x6AA7, 0x844A, 0xE3D5, 0x7958, 0x84A8, 0xE3D8, 0xE3D9, 0xE3DA, 0x84DE, 0x840F, 0x8391, - 0x44A0, 0x8493, 0x84E4, 0xE3E1, 0x4240, 0xE3E3, 0x4543, 0x8534, 0x5AF2, 0xE3E7, 0x4527, 0x8573, 0x4516, 0x67BF, 0x8616, - /* Big5-HKSCS 0x8FA1 .. 0x8FFE */ - 0xE3ED, 0xE3EE, 0x85C1, 0xE3F0, 0x8602, 0xE3F2, 0xE3F3, - 0xE3F4, 0x456A, 0x8628, 0x3648, 0xE3F8, 0x53F7, 0xE3FA, 0x867E, 0x8771, 0xE3FD, 0x87EE, 0xE3FF, 0x87B1, 0x87DA, 0x880F, 0x5661, - 0x866C, 0x6856, 0x460F, 0x8845, 0x8846, 0xE409, 0xE40A, 0xE40B, 0x885E, 0x889C, 0x465B, 0x88B4, 0x88B5, 0x63C1, 0x88C5, 0x7777, - 0xE414, 0x8987, 0x898A, 0x89A6, 0x89A9, 0x89A7, 0x89BC, 0xE41B, 0x89E7, 0xE41D, 0xE41E, 0x8A9C, 0x7793, 0x91FE, 0x8A90, 0xE423, - 0x7AE9, 0xE425, 0xE426, 0x4713, 0xE428, 0x717C, 0x8B0C, 0x8B1F, 0xE42C, 0xE42D, 0x8B3F, 0x8B4C, 0x8B4D, 0x8AA9, 0xE432, 0x8B90, - 0x8B9B, 0x8AAF, 0xE436, 0x4615, 0x884F, 0x8C9B, 0xE43A, 0xE43B, 0xE43C, 0x3725, 0xE43E, 0x8CD6, 0xE440, 0xE441, 0x8D12, 0x8D03, - 0xE444, 0x8CDB, 0x705C, 0x8D11, 0xE448, 0x3ED0, 0x8D77, - /* Big5-HKSCS 0x9040 .. 0x907E */ - 0x8DA9, 0xE44C, 0xE44D, 0xE44E, 0x3B7C, 0xE450, 0xE451, 0x7AE7, 0x8EAD, 0x8EB6, 0x8EC3, 0x92D4, 0x8F19, 0x8F2D, 0xE459, 0xE45A, - 0x8FA5, 0x9303, 0xE45D, 0xE45E, 0x8FB3, 0x492A, 0xE461, 0xE462, 0xE463, 0x5EF8, 0xE465, 0x8FF9, 0xE467, 0xE468, 0xE469, 0xE46A, - 0x3980, 0xE46C, 0x9037, 0xE46E, 0xE46F, 0x9061, 0xE471, 0xE472, 0x90A8, 0xE474, 0x90C4, 0xE476, 0x90AE, 0x90FD, 0x9167, 0x3AF0, - 0x91A9, 0x91C4, 0x7CAC, 0xE47E, 0xE47F, 0x920E, 0x6C9F, 0x9241, 0x9262, 0xE484, 0x92B9, 0xE486, 0xE487, 0xE488, 0xE489, - /* Big5-HKSCS 0x90A1 .. 0x90FE */ - 0xE48A, 0x932C, 0x936B, 0xE48D, 0xE48E, 0x708F, 0x5AC3, - 0xE491, 0xE492, 0x4965, 0x9244, 0xE495, 0xE496, 0xE497, 0x9373, 0x945B, 0x8EBC, 0x9585, 0x95A6, 0x9426, 0x95A0, 0x6FF6, 0x42B9, - 0xE4A1, 0xE4A2, 0xE4A3, 0xE4A4, 0x49DF, 0x6C1C, 0x967B, 0x9696, 0x416C, 0x96A3, 0xE4AB, 0x61DA, 0x96B6, 0x78F5, 0xE4AF, 0x96BD, - 0x53CC, 0x49A1, 0xE4B3, 0xE4B4, 0xE4B5, 0xE4B6, 0xE4B7, 0xE4B8, 0xE4B9, 0xE4BA, 0x9731, 0x8642, 0x9736, 0x4A0F, 0x453D, 0x4585, - 0xE4C1, 0x7075, 0x5B41, 0x971B, 0x975C, 0xE4C6, 0x9757, 0x5B4A, 0xE4C9, 0x975F, 0x9425, 0x50D0, 0xE4CD, 0xE4CE, 0x9789, 0x979F, - 0x97B1, 0x97BE, 0x97C0, 0x97D2, 0x97E0, 0xE4D6, 0x97EE, 0x741C, 0xE4D9, 0x97FF, 0x97F5, 0xE4DC, 0xE4DD, 0x4AD1, 0x9834, 0x9833, - 0x984B, 0x9866, 0x3B0E, 0xE4E4, 0x3D51, 0xE4E6, 0xE4E7, - /* Big5-HKSCS 0x9140 .. 0x917E */ - 0xE4E8, 0x98CA, 0x98B7, 0x98C8, 0x98C7, 0x4AFF, 0xE4EE, 0xE4EF, 0x55B0, 0x98E1, 0x98E6, 0x98EC, 0x9378, 0x9939, 0xE4F6, 0x4B72, - 0xE4F8, 0xE4F9, 0x99F5, 0x9A0C, 0x9A3B, 0x9A10, 0x9A58, 0xE4FF, 0x36C4, 0xE501, 0xE502, 0x9AE0, 0x9AE2, 0xE505, 0x9AF4, 0x4C0E, - 0x9B14, 0x9B2D, 0xE50A, 0x5034, 0x9B34, 0xE50D, 0x38C3, 0xE50F, 0x9B50, 0x9B40, 0xE512, 0x5A45, 0xE514, 0x9B8E, 0xE516, 0x9C02, - 0x9BFF, 0x9C0C, 0xE51A, 0x9DD4, 0xE51C, 0xE51D, 0xE51E, 0xE51F, 0xE520, 0xE521, 0x9D7E, 0x9D83, 0xE524, 0x9E0E, 0x6888, - /* Big5-HKSCS 0x91A1 .. 0x91FE */ - 0x9DC4, 0xE528, 0xE529, 0xE52A, 0xE52B, 0xE52C, 0x9D39, - 0xE52E, 0xE52F, 0x9E90, 0x9E95, 0x9E9E, 0x9EA2, 0x4D34, 0x9EAA, 0x9EAF, 0xE537, 0x9EC1, 0x3B60, 0x39E5, 0x3D1D, 0x4F32, 0x37BE, - 0xE53E, 0x9F02, 0x9F08, 0x4B96, 0x9424, 0xE543, 0x9F17, 0x9F16, 0x9F39, 0x569F, 0x568A, 0x9F45, 0x99B8, 0xE54B, 0x97F2, 0x847F, - 0x9F62, 0x9F69, 0x7ADC, 0x9F8E, 0x7216, 0x4BBE, 0xE554, 0xE555, 0x7177, 0xE557, 0xE558, 0xE559, 0x739E, 0xE55B, 0xE55C, 0x799F, - 0xE55E, 0xE55F, 0x9369, 0x93F3, 0xE562, 0x92EC, 0x9381, 0x93CB, 0xE566, 0xE567, 0x7217, 0x3EEB, 0x7772, 0x7A43, 0x70D0, 0xE56D, - 0xE56E, 0x717E, 0xE570, 0x70A3, 0xE572, 0xE573, 0x3EC7, 0xE575, 0xE576, 0xE577, 0x3722, 0xE579, 0xE57A, 0x36E1, 0xE57C, 0xE57D, - 0xE57E, 0x3723, 0xE580, 0x575B, 0xE582, 0xE583, 0xE584, - /* Big5-HKSCS 0x9240 .. 0x927E */ - 0xE585, 0xE586, 0x8503, 0xE588, 0x8503, 0x8455, 0xE58B, 0xE58C, 0xE58D, 0xE58E, 0xE58F, 0xE590, 0x44F4, 0xE592, 0xE593, 0xE594, - 0x67F9, 0x3733, 0x3C15, 0x3DE7, 0x586C, 0xE59A, 0x6810, 0x4057, 0xE59D, 0xE59E, 0xE59F, 0xE5A0, 0xE5A1, 0x54CB, 0x569E, 0xE5A4, - 0x5692, 0xE5A6, 0xE5A7, 0xE5A8, 0x93C6, 0xE5AA, 0x939C, 0x4EF8, 0x512B, 0x3819, 0xE5AF, 0x4EBC, 0xE5B1, 0xE5B2, 0x4F4B, 0x4F8A, - 0xE5B5, 0x5A68, 0xE5B7, 0xE5B8, 0x3999, 0xE5BA, 0xE5BB, 0x3435, 0x4F29, 0xE5BE, 0xE5BF, 0xE5C0, 0x8ADA, 0xE5C2, 0x4E98, - /* Big5-HKSCS 0x92A1 .. 0x92FE */ - 0x50CD, 0x510D, 0x4FA2, 0x4F03, 0xE5C8, 0xE5C9, 0x4F42, - 0x502E, 0x506C, 0x5081, 0x4FCC, 0x4FE5, 0x5058, 0x50FC, 0x5159, 0x515B, 0x515D, 0x515E, 0x6E76, 0xE5D7, 0xE5D8, 0xE5D9, 0x6D72, - 0xE5DB, 0xE5DC, 0x51A8, 0x51C3, 0xE5DF, 0x44DD, 0xE5E1, 0xE5E2, 0xE5E3, 0x8D7A, 0xE5E5, 0xE5E6, 0x5259, 0x52A4, 0xE5E9, 0x52E1, - 0x936E, 0x467A, 0x718C, 0xE5EE, 0xE5EF, 0xE5F0, 0xE5F1, 0x69D1, 0xE5F3, 0x7479, 0x3EDE, 0x7499, 0x7414, 0x7456, 0x7398, 0x4B8E, - 0xE5FB, 0xE5FC, 0x53D0, 0x3584, 0x720F, 0xE600, 0x55B4, 0xE602, 0x54CD, 0xE604, 0x571D, 0x925D, 0x96F4, 0x9366, 0x57DD, 0x578D, - 0x577F, 0x363E, 0x58CB, 0x5A99, 0xE60F, 0xE610, 0xE611, 0xE612, 0x5A2C, 0x59B8, 0x928F, 0x5A7E, 0x5ACF, 0x5A12, 0xE619, 0xE61A, - 0xE61B, 0xE61C, 0x36F5, 0x6D05, 0x7443, 0x5A21, 0xE621, - /* Big5-HKSCS 0x9340 .. 0x937E */ - 0x5A81, 0xE623, 0xE624, 0x93E0, 0x748C, 0xE627, 0x7105, 0x4972, 0x9408, 0xE62B, 0x93BD, 0x37A0, 0x5C1E, 0x5C9E, 0x5E5E, 0x5E48, - 0xE632, 0xE633, 0xE634, 0x5ECD, 0x5B4F, 0xE637, 0xE638, 0x3701, 0xE63A, 0x36DD, 0xE63C, 0x36D3, 0x812A, 0xE63F, 0xE640, 0xE641, - 0xE642, 0x5F0C, 0x5F0E, 0xE645, 0xE646, 0x5A6B, 0xE648, 0x5B44, 0x8614, 0xE64B, 0x8860, 0x607E, 0xE64E, 0xE64F, 0x5FDB, 0x3EB8, - 0xE652, 0xE653, 0xE654, 0xE655, 0x61C0, 0xE657, 0xE658, 0xE659, 0x6199, 0x6198, 0x6075, 0xE65D, 0xE65E, 0xE65F, 0xE660, - /* Big5-HKSCS 0x93A1 .. 0x93FE */ - 0x6471, 0xE662, 0xE663, 0x3A29, 0xE665, 0xE666, 0xE667, - 0xE668, 0x6337, 0xE66A, 0x64B6, 0x6331, 0x63D1, 0xE66E, 0xE66F, 0x62A4, 0xE671, 0x643B, 0x656B, 0x6972, 0x3BF4, 0xE676, 0xE677, - 0xE678, 0xE679, 0x550D, 0xE67B, 0xE67C, 0xE67D, 0x66CE, 0xE67F, 0xE680, 0x3AE0, 0x4190, 0xE683, 0xE684, 0xE685, 0xE686, 0xE687, - 0xE688, 0x78EE, 0xE68A, 0xE68B, 0xE68C, 0x3464, 0xE68E, 0xE68F, 0xE690, 0x668E, 0xE692, 0x666B, 0x4B93, 0x6630, 0xE696, 0xE697, - 0x6663, 0xE699, 0xE69A, 0x661E, 0xE69C, 0x38D1, 0xE69E, 0xE69F, 0x3B99, 0xE6A1, 0xE6A2, 0x74D0, 0x3B96, 0x678F, 0xE6A6, 0x68B6, - 0x681E, 0x3BC4, 0x6ABE, 0x3863, 0xE6AC, 0xE6AD, 0x6A33, 0x6A52, 0x6AC9, 0x6B05, 0xE6B2, 0x6511, 0x6898, 0x6A4C, 0x3BD7, 0x6A7A, - 0x6B57, 0xE6B9, 0xE6BA, 0x93A0, 0x92F2, 0xE6BD, 0xE6BE, - /* Big5-HKSCS 0x9440 .. 0x947E */ - 0x9289, 0xE6C0, 0xE6C1, 0x9467, 0x6DA5, 0x6F0B, 0xE6C5, 0x6D67, 0xE6C7, 0x3D8F, 0x6E04, 0xE6CA, 0x5A3D, 0x6E0A, 0x5847, 0x6D24, - 0x7842, 0x713B, 0xE6D1, 0xE6D2, 0x70F1, 0x7250, 0x7287, 0x7294, 0xE6D7, 0xE6D8, 0x5179, 0xE6DA, 0xE6DB, 0x747A, 0xE6DD, 0xE6DE, - 0xE6DF, 0xE6E0, 0xE6E1, 0x3F06, 0x3EB1, 0xE6E4, 0xE6E5, 0xE6E6, 0x60A7, 0x3EF3, 0x74CC, 0x743C, 0x9387, 0x7437, 0x449F, 0xE6EE, - 0x4551, 0x7583, 0x3F63, 0xE6F2, 0xE6F3, 0x3F58, 0x7555, 0x7673, 0xE6F7, 0x3B19, 0x7468, 0xE6FA, 0xE6FB, 0xE6FC, 0x3AFB, - /* Big5-HKSCS 0x94A1 .. 0x94FE */ - 0x3DCD, 0xE6FF, 0x3EFF, 0xE701, 0xE702, 0x91FA, 0x5732, - 0x9342, 0xE706, 0xE707, 0x50DF, 0xE709, 0xE70A, 0x7778, 0xE70C, 0x770E, 0x770F, 0x777B, 0xE710, 0xE711, 0x3A5E, 0xE713, 0x7438, - 0x749B, 0x3EBF, 0xE717, 0xE718, 0x40C8, 0xE71A, 0xE71B, 0x9307, 0xE71D, 0x781E, 0x788D, 0x7888, 0x78D2, 0x73D0, 0x7959, 0xE724, - 0xE725, 0x410E, 0x799B, 0x8496, 0x79A5, 0x6A2D, 0xE72B, 0x7A3A, 0x79F4, 0x416E, 0xE72F, 0x4132, 0x9235, 0x79F1, 0xE733, 0xE734, - 0xE735, 0xE736, 0xE737, 0x3597, 0x556B, 0x3570, 0x36AA, 0xE73C, 0xE73D, 0x7AE2, 0x5A59, 0xE740, 0xE741, 0xE742, 0x5A0D, 0xE744, - 0x78F0, 0x5A2A, 0xE747, 0x7AFE, 0x41F9, 0x7C5D, 0x7C6D, 0x4211, 0xE74D, 0xE74E, 0xE74F, 0x7CCD, 0xE751, 0xE752, 0x7C8E, 0x7C7C, - 0x7CAE, 0x6AB2, 0x7DDC, 0x7E07, 0x7DD3, 0x7F4E, 0xE75B, - /* Big5-HKSCS 0x9540 .. 0x957E */ - 0xE75C, 0xE75D, 0x7D97, 0xE75F, 0x426A, 0xE761, 0xE762, 0x67D6, 0xE764, 0xE765, 0x57C4, 0xE767, 0xE768, 0xE769, 0x7FDD, 0x7B27, - 0xE76C, 0xE76D, 0xE76E, 0x7B0C, 0xE770, 0x99E6, 0x8645, 0x9A63, 0x6A1C, 0xE775, 0x39E2, 0xE777, 0xE778, 0x9A1F, 0xE77A, 0x8480, - 0xE77C, 0xE77D, 0x44EA, 0x8137, 0x4402, 0x80C6, 0x8109, 0x8142, 0xE784, 0x98C3, 0xE786, 0x8262, 0x8265, 0xE789, 0x8453, 0xE78B, - 0x8610, 0xE78D, 0x5A86, 0x417F, 0xE790, 0x5B2B, 0xE792, 0x5AE4, 0xE794, 0x86A0, 0xE796, 0xE797, 0x882D, 0xE799, 0x5A02, - /* Big5-HKSCS 0x95A1 .. 0x95FE */ - 0x886E, 0x4F45, 0x8887, 0x88BF, 0x88E6, 0x8965, 0x894D, - 0xE7A2, 0x8954, 0xE7A4, 0xE7A5, 0xE7A6, 0xE7A7, 0xE7A8, 0xE7A9, 0x3EAD, 0x84A3, 0x46F5, 0x46CF, 0x37F2, 0x8A3D, 0x8A1C, 0xE7B1, - 0x5F4D, 0x922B, 0xE7B4, 0x65D4, 0x7129, 0x70C4, 0xE7B8, 0x9D6D, 0x8C9F, 0x8CE9, 0xE7BC, 0x599A, 0x77C3, 0x59F0, 0x436E, 0x36D4, - 0x8E2A, 0x8EA7, 0xE7C4, 0x8F30, 0x8F4A, 0x42F4, 0x6C58, 0x6FBB, 0xE7CA, 0x489B, 0x6F79, 0x6E8B, 0xE7CE, 0x9BE9, 0x36B5, 0xE7D1, - 0x90BB, 0x9097, 0x5571, 0x4906, 0x91BB, 0x9404, 0xE7D8, 0x4062, 0xE7DA, 0x9427, 0xE7DC, 0xE7DD, 0x84E5, 0x8A2B, 0x9599, 0x95A7, - 0x9597, 0x9596, 0xE7E4, 0x7445, 0x3EC2, 0xE7E7, 0xE7E8, 0xE7E9, 0x3EE7, 0xE7EB, 0x968F, 0xE7ED, 0xE7EE, 0xE7EF, 0x3ECC, 0xE7F1, - 0xE7F2, 0xE7F3, 0x7412, 0x746B, 0x3EFC, 0x9741, 0xE7F8, - /* Big5-HKSCS 0x9640 .. 0x967E */ - 0x6847, 0x4A1D, 0xE7FB, 0xE7FC, 0x975D, 0x9368, 0xE7FF, 0xE800, 0xE801, 0xE802, 0x92BA, 0x5B11, 0x8B69, 0x493C, 0x73F9, 0xE808, - 0x979B, 0x9771, 0x9938, 0xE80C, 0x5DC1, 0xE80E, 0xE80F, 0x981F, 0xE811, 0x92F6, 0xE813, 0x91E5, 0x44C0, 0xE816, 0xE817, 0xE818, - 0x98DC, 0xE81A, 0x3F00, 0x922A, 0x4925, 0x8414, 0x993B, 0x994D, 0xE821, 0x3DFD, 0x999B, 0x4B6F, 0x99AA, 0x9A5C, 0xE827, 0xE828, - 0x6A8F, 0x9A21, 0x5AFE, 0x9A2F, 0xE82D, 0x4B90, 0xE82F, 0x99BC, 0x4BBD, 0x4B97, 0x937D, 0x5872, 0xE835, 0x5822, 0xE837, - /* Big5-HKSCS 0x96A1 .. 0x96FE */ - 0xE838, 0x7844, 0xE83A, 0xE83B, 0x68C5, 0x3D7D, 0x9458, - 0x3927, 0x6150, 0xE841, 0xE842, 0x6107, 0x9C4F, 0x9C53, 0x9C7B, 0x9C35, 0x9C10, 0x9B7F, 0x9BCF, 0xE84B, 0x9B9F, 0xE84D, 0xE84E, - 0x9D21, 0x4CAE, 0xE851, 0x9E18, 0x4CB0, 0x9D0C, 0xE855, 0xE856, 0xE857, 0xE858, 0x9DA5, 0x84BD, 0xE85B, 0xE85C, 0xE85D, 0x85FC, - 0x4533, 0xE860, 0xE861, 0xE862, 0x8420, 0x85EE, 0xE865, 0xE866, 0xE867, 0x79E2, 0xE869, 0xE86A, 0x492D, 0xE86C, 0x3D62, 0x93DB, - 0x92BE, 0x9348, 0xE871, 0x78B9, 0x9277, 0x944D, 0x4FE4, 0x3440, 0x9064, 0xE878, 0x783D, 0x7854, 0x78B6, 0x784B, 0xE87D, 0xE87E, - 0xE87F, 0x369A, 0x4F72, 0x6FDA, 0x6FD9, 0x701E, 0x701E, 0x5414, 0xE887, 0x57BB, 0x58F3, 0x578A, 0x9D16, 0x57D7, 0x7134, 0x34AF, - 0xE88F, 0x71EB, 0xE891, 0xE892, 0x5B28, 0xE894, 0xE895, - /* Big5-HKSCS 0x9740 .. 0x977E */ - 0x610C, 0x5ACE, 0x5A0B, 0x42BC, 0xE89A, 0x372C, 0x4B7B, 0xE89D, 0x93BB, 0x93B8, 0xE8A0, 0xE8A1, 0x8472, 0xE8A3, 0xE8A4, 0xE8A5, - 0xE8A6, 0xE8A7, 0x5994, 0xE8A9, 0xE8AA, 0x7DA8, 0xE8AC, 0xE8AD, 0xE8AE, 0xE8AF, 0xE8B0, 0x92E5, 0x73E2, 0x3EE9, 0x74B4, 0xE8B5, - 0xE8B6, 0x3EE1, 0xE8B8, 0x6AD8, 0x73F3, 0x73FB, 0x3ED6, 0xE8BD, 0xE8BE, 0xE8BF, 0xE8C0, 0xE8C1, 0xE8C2, 0xE8C3, 0x7448, 0xE8C5, - 0x70A5, 0xE8C7, 0x9284, 0x73E6, 0x935F, 0xE8CB, 0x9331, 0xE8CD, 0xE8CE, 0x9386, 0xE8D0, 0xE8D1, 0x4935, 0xE8D3, 0x716B, - /* Big5-HKSCS 0x97A1 .. 0x97FE */ - 0xE8D5, 0xE8D6, 0x56A4, 0xE8D8, 0xE8D9, 0xE8DA, 0x5502, - 0x79C4, 0xE8DD, 0x7DFE, 0xE8DF, 0xE8E0, 0xE8E1, 0x452E, 0x9401, 0x370A, 0xE8E5, 0xE8E6, 0x59B0, 0xE8E8, 0xE8E9, 0xE8EA, 0x5AA1, - 0x36E2, 0xE8ED, 0x36B0, 0x925F, 0x5A79, 0xE8F1, 0xE8F2, 0x9374, 0x3CCD, 0xE8F5, 0x4A96, 0x398A, 0x50F4, 0x3D69, 0x3D4C, 0xE8FB, - 0x7175, 0x42FB, 0xE8FE, 0x6E0F, 0xE900, 0x44EB, 0x6D57, 0xE903, 0x7067, 0x6CAF, 0x3CD6, 0xE907, 0xE908, 0x6E02, 0x6F0C, 0x3D6F, - 0xE90C, 0x7551, 0x36BC, 0x34C8, 0x4680, 0x3EDA, 0x4871, 0x59C4, 0x926E, 0x493E, 0x8F41, 0xE917, 0xE918, 0x5812, 0x57C8, 0x36D6, - 0xE91C, 0x70FE, 0xE91E, 0xE91F, 0xE920, 0xE921, 0xE922, 0x68B9, 0x6967, 0xE925, 0xE926, 0xE927, 0xE928, 0xE929, 0xE92A, 0xE92B, - 0xE92C, 0x6A1A, 0xE92E, 0xE92F, 0x843E, 0x44DF, 0x44CE, - /* Big5-HKSCS 0x9840 .. 0x987E */ - 0xE933, 0xE934, 0xE935, 0xE936, 0x6F17, 0xE938, 0x833D, 0xE93A, 0x83ED, 0xE93C, 0xE93D, 0xE93E, 0x5989, 0x5A82, 0xE941, 0x5A61, - 0x5A71, 0xE944, 0xE945, 0x372D, 0x59EF, 0xE948, 0x36C7, 0x718E, 0x9390, 0x669A, 0xE94D, 0x5A6E, 0x5A2B, 0xE950, 0x6A2B, 0xE952, - 0xE953, 0xE954, 0xE955, 0x711D, 0xE957, 0xE958, 0x4FB0, 0xE95A, 0x5CC2, 0xE95C, 0xE95D, 0xE95E, 0x6A0C, 0xE960, 0xE961, 0x70A6, - 0x7133, 0xE964, 0x3DA5, 0x6CDF, 0xE967, 0xE968, 0x7E65, 0x59EB, 0x5D2F, 0x3DF3, 0x5F5C, 0xE96E, 0xE96F, 0x7DA4, 0x8426, - /* Big5-HKSCS 0x98A1 .. 0x98FE */ - 0x5485, 0xE973, 0xE974, 0xE975, 0x577E, 0xE977, 0xE978, - 0x3FE5, 0xE97A, 0xE97B, 0x7003, 0xE97D, 0x5D70, 0x738F, 0x7CD3, 0xE981, 0xE982, 0x4FC8, 0x7FE7, 0x72CD, 0x7310, 0xE987, 0x7338, - 0x7339, 0xE98A, 0x7341, 0x7348, 0x3EA9, 0xE98E, 0x906C, 0x71F5, 0xE991, 0x73E1, 0x81F6, 0x3ECA, 0x770C, 0x3ED1, 0x6CA2, 0x56FD, - 0x7419, 0x741E, 0x741F, 0x3EE2, 0x3EF0, 0x3EF4, 0x3EFA, 0x74D3, 0x3F0E, 0x3F53, 0x7542, 0x756D, 0x7572, 0x758D, 0x3F7C, 0x75C8, - 0x75DC, 0x3FC0, 0x764D, 0x3FD7, 0x7674, 0x3FDC, 0x767A, 0xE9B0, 0x7188, 0x5623, 0x8980, 0x5869, 0x401D, 0x7743, 0x4039, 0x6761, - 0x4045, 0x35DB, 0x7798, 0x406A, 0x406F, 0x5C5E, 0x77BE, 0x77CB, 0x58F2, 0x7818, 0x70B9, 0x781C, 0x40A8, 0x7839, 0x7847, 0x7851, - 0x7866, 0x8448, 0xE9CB, 0x7933, 0x6803, 0x7932, 0x4103, - /* Big5-HKSCS 0x9940 .. 0x997E */ - 0x4109, 0x7991, 0x7999, 0x8FBB, 0x7A06, 0x8FBC, 0x4167, 0x7A91, 0x41B2, 0x7ABC, 0x8279, 0x41C4, 0x7ACF, 0x7ADB, 0x41CF, 0x4E21, - 0x7B62, 0x7B6C, 0x7B7B, 0x7C12, 0x7C1B, 0x4260, 0x427A, 0x7C7B, 0x7C9C, 0x428C, 0x7CB8, 0x4294, 0x7CED, 0x8F93, 0x70C0, 0xE9EF, - 0x7DCF, 0x7DD4, 0x7DD0, 0x7DFD, 0x7FAE, 0x7FB4, 0x729F, 0x4397, 0x8020, 0x8025, 0x7B39, 0x802E, 0x8031, 0x8054, 0x3DCC, 0x57B4, - 0x70A0, 0x80B7, 0x80E9, 0x43ED, 0x810C, 0x732A, 0x810E, 0x8112, 0x7560, 0x8114, 0x4401, 0x3B39, 0x8156, 0x8159, 0x815A, - /* Big5-HKSCS 0x99A1 .. 0x99FE */ - 0x4413, 0x583A, 0x817C, 0x8184, 0x4425, 0x8193, 0x442D, - 0x81A5, 0x57EF, 0x81C1, 0x81E4, 0x8254, 0x448F, 0x82A6, 0x8276, 0x82CA, 0x82D8, 0x82FF, 0x44B0, 0x8357, 0x9669, 0x698A, 0x8405, - 0x70F5, 0x8464, 0x60E3, 0x8488, 0x4504, 0x84BE, 0x84E1, 0x84F8, 0x8510, 0x8538, 0x8552, 0x453B, 0x856F, 0x8570, 0x85E0, 0x4577, - 0x8672, 0x8692, 0x86B2, 0x86EF, 0x9645, 0x878B, 0x4606, 0x4617, 0x88AE, 0x88FF, 0x8924, 0x8947, 0x8991, 0xEA43, 0x8A29, 0x8A38, - 0x8A94, 0x8AB4, 0x8C51, 0x8CD4, 0x8CF2, 0x8D1C, 0x4798, 0x585F, 0x8DC3, 0x47ED, 0x4EEE, 0x8E3A, 0x55D8, 0x5754, 0x8E71, 0x55F5, - 0x8EB0, 0x4837, 0x8ECE, 0x8EE2, 0x8EE4, 0x8EED, 0x8EF2, 0x8FB7, 0x8FC1, 0x8FCA, 0x8FCC, 0x9033, 0x99C4, 0x48AD, 0x98E0, 0x9213, - 0x491E, 0x9228, 0x9258, 0x926B, 0x92B1, 0x92AE, 0x92BF, - /* Big5-HKSCS 0x9A40 .. 0x9A7E */ - 0x92E3, 0x92EB, 0x92F3, 0x92F4, 0x92FD, 0x9343, 0x9384, 0x93AD, 0x4945, 0x4951, 0x9EBF, 0x9417, 0x5301, 0x941D, 0x942D, 0x943E, - 0x496A, 0x9454, 0x9479, 0x952D, 0x95A2, 0x49A7, 0x95F4, 0x9633, 0x49E5, 0x67A0, 0x4A24, 0x9740, 0x4A35, 0x97B2, 0x97C2, 0x5654, - 0x4AE4, 0x60E8, 0x98B9, 0x4B19, 0x98F1, 0x5844, 0x990E, 0x9919, 0x51B4, 0x991C, 0x9937, 0x9942, 0x995D, 0x9962, 0x4B70, 0x99C5, - 0x4B9D, 0x9A3C, 0x9B0F, 0x7A83, 0x9B69, 0x9B81, 0x9BDD, 0x9BF1, 0x9BF4, 0x4C6D, 0x9C20, 0x376F, 0xEAA9, 0x9D49, 0x9C3A, - /* Big5-HKSCS 0x9AA1 .. 0x9AFE */ - 0x9EFE, 0x5650, 0x9D93, 0x9DBD, 0x9DC0, 0x9DFC, 0x94F6, - 0x8FB6, 0x9E7B, 0x9EAC, 0x9EB1, 0x9EBD, 0x9EC6, 0x94DC, 0x9EE2, 0x9EF1, 0x9EF8, 0x7AC8, 0x9F44, 0xEABF, 0xEAC0, 0xEAC1, 0x691A, - 0x94C3, 0x59AC, 0xEAC5, 0x5840, 0x94C1, 0x37B9, 0xEAC9, 0xEACA, 0xEACB, 0xEACC, 0x5757, 0x7173, 0xEACF, 0xEAD0, 0xEAD1, 0x546A, - 0xEAD3, 0xEAD4, 0x549E, 0xEAD6, 0xEAD7, 0xEAD8, 0xEAD9, 0xEADA, 0x60E7, 0xEADC, 0x567A, 0xEADE, 0xEADF, 0xEAE0, 0xEAE1, 0xEAE2, - 0xEAE3, 0x6955, 0x9C2F, 0x87A5, 0xEAE7, 0xEAE8, 0xEAE9, 0xEAEA, 0xEAEB, 0xEAEC, 0x5C20, 0xEAEE, 0x5E0B, 0xEAF0, 0xEAF1, 0xEAF2, - 0x671E, 0xEAF4, 0xEAF5, 0xEAF6, 0x3647, 0xEAF8, 0xEAF9, 0xEAFA, 0xEAFB, 0x5364, 0x84AD, 0xEAFE, 0xEAFF, 0xEB00, 0x8B81, 0xEB02, - 0xEB03, 0xEB04, 0xEB05, 0x4E78, 0x70BB, 0xEB08, 0xEB09, - /* Big5-HKSCS 0x9B40 .. 0x9B7E */ - 0xEB0A, 0xEB0B, 0xEB0C, 0xEB0D, 0xEB0E, 0xEB0F, 0x62C3, 0xEB11, 0xEB12, 0x7198, 0x6855, 0xEB15, 0x69E9, 0x36C8, 0xEB18, 0xEB19, - 0xEB1A, 0xEB1B, 0xEB1C, 0xEB1D, 0x82FD, 0xEB1F, 0xEB20, 0xEB21, 0x89A5, 0xEB23, 0x8FA0, 0xEB25, 0x97B8, 0xEB27, 0x9847, 0x9ABD, - 0xEB2A, 0xEB2B, 0xEB2C, 0xEB2D, 0xEB2E, 0xEB2F, 0xEB30, 0xEB31, 0xEB32, 0xEB33, 0xEB34, 0xEB35, 0xEB36, 0xEB37, 0xEB38, 0xEB39, - 0x5FB1, 0x6648, 0x66BF, 0xEB3D, 0xEB3E, 0xEB3F, 0x7201, 0xEB41, 0x77D7, 0xEB43, 0xEB44, 0x7E87, 0xEB46, 0x58B5, 0x670E, - /* Big5-HKSCS 0x9BA1 .. 0x9BFE */ - 0x6918, 0xEB4A, 0xEB4B, 0xEB4C, 0xEB4D, 0xEB4E, 0xEB4F, - 0xEB50, 0x48D0, 0x4AB8, 0xEB53, 0xEB54, 0xEB55, 0xEB56, 0xEB57, 0xEB58, 0xEB59, 0xEB5A, 0xEB5B, 0x51D2, 0xEB5D, 0x599F, 0xEB5F, - 0x3BBE, 0xEB61, 0xEB62, 0xEB63, 0x5788, 0xEB65, 0x399B, 0xEB67, 0xEB68, 0xEB69, 0x3762, 0xEB6B, 0x8B5E, 0xEB6D, 0x99D6, 0xEB6F, - 0xEB70, 0xEB71, 0x7209, 0xEB73, 0xEB74, 0x5965, 0xEB76, 0xEB77, 0xEB78, 0x8EDA, 0xEB7A, 0x528F, 0x573F, 0x7171, 0xEB7E, 0xEB7F, - 0xEB80, 0xEB81, 0x55BC, 0xEB83, 0xEB84, 0xEB85, 0x91D4, 0x3473, 0xEB88, 0xEB89, 0xEB8A, 0x4718, 0xEB8C, 0xEB8D, 0xEB8E, 0xEB8F, - 0xEB90, 0x5066, 0x34FB, 0xEB93, 0x60DE, 0xEB95, 0x477C, 0xEB97, 0xEB98, 0xEB99, 0xEB9A, 0xEB9B, 0x57A1, 0x7151, 0x6FB6, 0xEB9F, - 0xEBA0, 0x9056, 0xEBA2, 0xEBA3, 0x8B62, 0xEBA5, 0xEBA6, - /* Big5-HKSCS 0x9C40 .. 0x9C7E */ - 0x5D5B, 0xEBA8, 0x8F36, 0xEBAA, 0xEBAB, 0x8AEA, 0xEBAD, 0xEBAE, 0xEBAF, 0xEBB0, 0x4BC0, 0xEBB2, 0xEBB3, 0xEBB4, 0x9465, 0xEBB6, - 0x6195, 0x5A27, 0xEBB9, 0x4FBB, 0x56B9, 0xEBBC, 0xEBBD, 0x4E6A, 0xEBBF, 0x9656, 0x6D8F, 0xEBC2, 0x3618, 0x8977, 0xEBC5, 0xEBC6, - 0xEBC7, 0xEBC8, 0x71DF, 0xEBCA, 0x7B42, 0xEBCC, 0xEBCD, 0xEBCE, 0x9104, 0xEBD0, 0x7A45, 0x9DF0, 0xEBD3, 0x9A26, 0xEBD5, 0x365F, - 0xEBD7, 0xEBD8, 0x7983, 0xEBDA, 0xEBDB, 0x5D2C, 0xEBDD, 0x83CF, 0xEBDF, 0x46D0, 0xEBE1, 0x753B, 0x8865, 0xEBE4, 0x58B6, - /* Big5-HKSCS 0x9CA1 .. 0x9CFE */ - 0x371C, 0xEBE7, 0xEBE8, 0xEBE9, 0x3C54, 0xEBEB, 0xEBEC, - 0x9281, 0xEBEE, 0xEBEF, 0x9330, 0xEBF1, 0xEBF2, 0x6C39, 0x949F, 0xEBF5, 0xEBF6, 0x8827, 0x88F5, 0xEBF9, 0xEBFA, 0xEBFB, 0x6EB8, - 0xEBFD, 0xEBFE, 0x39A4, 0x36B9, 0x5C10, 0x79E3, 0x453F, 0x66B6, 0xEC05, 0xEC06, 0x8943, 0xEC08, 0xEC09, 0x56D6, 0x40DF, 0xEC0C, - 0x39A1, 0xEC0E, 0xEC0F, 0xEC10, 0x71AD, 0x8366, 0xEC13, 0xEC14, 0x5A67, 0x4CB7, 0xEC17, 0xEC18, 0xEC19, 0xEC1A, 0xEC1B, 0xEC1C, - 0xEC1D, 0x7B43, 0x797E, 0xEC20, 0x6FB5, 0xEC22, 0x6A03, 0xEC24, 0x53A2, 0xEC26, 0x93BF, 0x6836, 0x975D, 0xEC2A, 0xEC2B, 0xEC2C, - 0xEC2D, 0xEC2E, 0xEC2F, 0x5D85, 0xEC31, 0xEC32, 0x5715, 0x9823, 0xEC35, 0x5DAB, 0xEC37, 0x65BE, 0x69D5, 0x53D2, 0xEC3B, 0xEC3C, - 0x3C11, 0x6736, 0xEC3F, 0xEC40, 0xEC41, 0xEC42, 0xEC43, - /* Big5-HKSCS 0x9D40 .. 0x9D7E */ - 0xEC44, 0xEC45, 0xEC46, 0xEC47, 0xEC48, 0xEC49, 0x35CA, 0xEC4B, 0xEC4C, 0x48FA, 0x63E6, 0xEC4F, 0x7808, 0x9255, 0xEC52, 0x43F2, - 0xEC54, 0x43DF, 0xEC56, 0xEC57, 0xEC58, 0x59F8, 0xEC5A, 0x8F0B, 0xEC5C, 0xEC5D, 0x7B51, 0xEC5F, 0xEC60, 0x3DF7, 0xEC62, 0xEC63, - 0x8FD0, 0x728F, 0x568B, 0xEC67, 0xEC68, 0xEC69, 0xEC6A, 0xEC6B, 0xEC6C, 0xEC6D, 0xEC6E, 0xEC6F, 0xEC70, 0xEC71, 0xEC72, 0xEC73, - 0x7E9F, 0xEC75, 0xEC76, 0x4CA4, 0x9547, 0xEC79, 0x71A2, 0xEC7B, 0x4D91, 0x9012, 0xEC7E, 0x4D9C, 0xEC80, 0x8FBE, 0x55C1, - /* Big5-HKSCS 0x9DA1 .. 0x9DFE */ - 0x8FBA, 0xEC84, 0x8FB9, 0xEC86, 0x4509, 0x7E7F, 0x6F56, - 0x6AB1, 0x4EEA, 0x34E4, 0xEC8D, 0xEC8E, 0x373A, 0x8E80, 0xEC91, 0xEC92, 0xEC93, 0xEC94, 0xEC95, 0xEC96, 0x3DEB, 0xEC98, 0xEC99, - 0xEC9A, 0xEC9B, 0x4E9A, 0xEC9D, 0xEC9E, 0x56BF, 0xECA0, 0x8E0E, 0x5B6D, 0xECA3, 0xECA4, 0x63DE, 0x62D0, 0xECA7, 0xECA8, 0x6530, - 0x562D, 0xECAB, 0x541A, 0xECAD, 0x3DC6, 0xECAF, 0x4C7D, 0x5622, 0x561E, 0x7F49, 0xECB4, 0x5975, 0xECB6, 0x8770, 0x4E1C, 0xECB9, - 0xECBA, 0xECBB, 0x8117, 0x9D5E, 0x8D18, 0x763B, 0x9C45, 0x764E, 0x77B9, 0x9345, 0x5432, 0x8148, 0x82F7, 0x5625, 0x8132, 0x8418, - 0x80BD, 0x55EA, 0x7962, 0x5643, 0x5416, 0xECCF, 0x35CE, 0x5605, 0x55F1, 0x66F1, 0xECD4, 0x362D, 0x7534, 0x55F0, 0x55BA, 0x5497, - 0x5572, 0xECDB, 0xECDC, 0x5ED0, 0xECDE, 0xECDF, 0xECE0, - /* Big5-HKSCS 0x9E40 .. 0x9E7E */ - 0xECE1, 0x9EAB, 0x7D5A, 0x55DE, 0xECE5, 0x629D, 0x976D, 0x5494, 0x8CCD, 0x71F6, 0x9176, 0x63FC, 0x63B9, 0x63FE, 0x5569, 0xECF0, - 0x9C72, 0xECF2, 0x519A, 0x34DF, 0xECF5, 0x51A7, 0x544D, 0x551E, 0x5513, 0x7666, 0x8E2D, 0xECFC, 0x75B1, 0x80B6, 0x8804, 0x8786, - 0x88C7, 0x81B6, 0x841C, 0xED04, 0x44EC, 0x7304, 0xED07, 0x5B90, 0x830B, 0xED0A, 0x567B, 0xED0C, 0xED0D, 0xED0E, 0xED0F, 0xED10, - 0xED11, 0x9170, 0xED13, 0x9208, 0xED15, 0xED16, 0xED17, 0xED18, 0x7266, 0xED1A, 0x474E, 0xED1C, 0xED1D, 0xED1E, 0x40FA, - /* Big5-HKSCS 0x9EA1 .. 0x9EFE */ - 0x9C5D, 0x651F, 0xED22, 0x48F3, 0xED24, 0xED25, 0xED26, - 0xED27, 0x6062, 0xED29, 0xED2A, 0xED2B, 0xED2C, 0xED2D, 0x71A3, 0x7E8E, 0x9D50, 0x4E1A, 0x4E04, 0x3577, 0x5B0D, 0x6CB2, 0x5367, - 0x36AC, 0x39DC, 0x537D, 0x36A5, 0xED3B, 0x589A, 0xED3D, 0x822D, 0x544B, 0x57AA, 0xED41, 0xED42, 0xED43, 0x3A52, 0xED45, 0x7374, - 0xED47, 0x4D09, 0x9BED, 0xED4A, 0xED4B, 0x4C5B, 0xED4D, 0xED4E, 0xED4F, 0x845C, 0xED51, 0xED52, 0xED53, 0xED54, 0x632E, 0x7D25, - 0xED57, 0xED58, 0x3A2A, 0x9008, 0x52CC, 0x3E74, 0x367A, 0x45E9, 0xED5F, 0x7640, 0x5AF0, 0xED62, 0x787A, 0x47B6, 0x58A7, 0x40BF, - 0x567C, 0x9B8B, 0x5D74, 0x7654, 0xED6B, 0x9E85, 0x4CE1, 0x75F9, 0x37FB, 0x6119, 0xED71, 0xED72, 0xED73, 0x565D, 0xED75, 0x57A7, - 0xED77, 0xED78, 0x5234, 0xED7A, 0x35AD, 0x6C4A, 0x9D7C, - /* Big5-HKSCS 0x9F40 .. 0x9F7E */ - 0x7C56, 0x9B39, 0x57DE, 0xED81, 0x5C53, 0x64D3, 0xED84, 0xED85, 0xED86, 0x86AD, 0xED88, 0xED89, 0xED8A, 0xED8B, 0xED8C, 0x51FE, - 0xED8E, 0x5D8E, 0x9703, 0xED91, 0x9E81, 0x904C, 0x7B1F, 0x9B02, 0x5CD1, 0x7BA3, 0x6268, 0x6335, 0x9AFF, 0x7BCF, 0x9B2A, 0x7C7E, - 0x9B2E, 0x7C42, 0x7C86, 0x9C15, 0x7BFC, 0x9B09, 0x9F17, 0x9C1B, 0xEDA6, 0x9F5A, 0x5573, 0x5BC3, 0x4FFD, 0x9E98, 0x4FF2, 0x5260, - 0x3E06, 0x52D1, 0x5767, 0x5056, 0x59B7, 0x5E12, 0x97C8, 0x9DAB, 0x8F5C, 0x5469, 0x97B4, 0x9940, 0x97BA, 0x532C, 0x6130, - /* Big5-HKSCS 0x9FA1 .. 0x9FFE */ - 0x692C, 0x53DA, 0x9C0A, 0x9D02, 0x4C3B, 0x9641, 0x6980, - 0x50A6, 0x7546, 0xEDC6, 0x99DA, 0x5273, 0xEDC9, 0x9159, 0x9681, 0x915C, 0xEDCD, 0x9151, 0xEDCF, 0x637F, 0xEDD1, 0x6ACA, 0x5611, - 0x918E, 0x757A, 0x6285, 0xEDD7, 0x734F, 0x7C70, 0xEDDA, 0xEDDB, 0xEDDC, 0xEDDD, 0x76D6, 0x9B9D, 0x4E2A, 0xEDE1, 0x83BE, 0x8842, - 0xEDE4, 0x5C4A, 0x69C0, 0x50ED, 0x577A, 0x521F, 0x5DF5, 0x4ECE, 0x6C31, 0xEDED, 0x4F39, 0x549C, 0x54DA, 0x529A, 0x8D82, 0x35FE, - 0x5F0C, 0x35F3, 0xEDF6, 0x6B52, 0x917C, 0x9FA5, 0x9B97, 0x982E, 0x98B4, 0x9ABA, 0x9EA8, 0x9E84, 0x717A, 0x7B14, 0xEE02, 0x6BFA, - 0x8818, 0x7F78, 0xEE06, 0x5620, 0xEE08, 0x8E77, 0x9F53, 0xEE0B, 0x8DD4, 0x8E4F, 0x9E1C, 0x8E01, 0x6282, 0xEE11, 0x8E28, 0x8E75, - 0x7AD3, 0xEE15, 0x7A3E, 0x78D8, 0x6CEA, 0x8A67, 0x7607, - /* Big5-HKSCS 0xA040 .. 0xA07E */ - 0xEE1B, 0x9F26, 0x6CCE, 0x87D6, 0x75C3, 0xEE20, 0x7853, 0xEE22, 0x8D0C, 0x72E2, 0x7371, 0x8B2D, 0x7302, 0x74F1, 0x8CEB, 0xEE2A, - 0x862F, 0x5FBA, 0x88A0, 0x44B7, 0xEE2F, 0xEE30, 0xEE31, 0xEE32, 0x8A7E, 0xEE34, 0xEE35, 0x60FD, 0x7667, 0x9AD7, 0x9D44, 0x936E, - 0x9B8F, 0x87F5, 0xEE3D, 0x880F, 0x8CF7, 0x732C, 0x9721, 0x9BB0, 0x35D6, 0x72B2, 0x4C07, 0x7C51, 0x994A, 0xEE48, 0x6159, 0x4C04, - 0x9E96, 0x617D, 0xEE4D, 0x575F, 0x616F, 0x62A6, 0x6239, 0x62CE, 0x3A5C, 0x61E2, 0x53AA, 0xEE56, 0x6364, 0x6802, 0x35D2, - /* Big5-HKSCS 0xA0A1 .. 0xA0FE */ - 0x5D57, 0xEE5B, 0x8FDA, 0xEE5D, 0xEE5E, 0x50D9, 0xEE60, - 0x7906, 0x5332, 0x9638, 0xEE64, 0x4065, 0xEE66, 0x77FE, 0xEE68, 0x7CC2, 0xEE6A, 0x7CDA, 0x7A2D, 0x8066, 0x8063, 0x7D4D, 0x7505, - 0x74F2, 0x8994, 0x821A, 0x670C, 0x8062, 0xEE76, 0x805B, 0x74F0, 0x8103, 0x7724, 0x8989, 0xEE7C, 0x7553, 0xEE7E, 0x87A9, 0x87CE, - 0x81C8, 0x878C, 0x8A49, 0x8CAD, 0x8B43, 0x772B, 0x74F8, 0x84DA, 0x3635, 0x69B2, 0x8DA6, 0xEE8C, 0x89A9, 0x7468, 0x6DB9, 0x87C1, - 0xEE91, 0x74E7, 0x3DDB, 0x7176, 0x60A4, 0x619C, 0x3CD1, 0x7162, 0x6077, 0xEE9A, 0x7F71, 0xEE9C, 0x7250, 0x60E9, 0x4B7E, 0x5220, - 0x3C18, 0xEEA2, 0xEEA3, 0xEEA4, 0xEEA5, 0xEEA6, 0xEEA7, 0xEEA8, 0xEEA9, 0xEEAA, 0x5CC1, 0xEEAC, 0xEEAD, 0xEEAE, 0xEEAF, 0xEEB0, - 0xEEB1, 0x4562, 0x5B1F, 0xEEB4, 0x9F50, 0x9EA6, 0xEEB7, - /* Big5-HKSCS 0xA140 .. 0xA17E */ - 0x3000, 0xFF0C, 0x3001, 0x3002, 0xFF0E, 0x2027, 0xFF1B, 0xFF1A, 0xFF1F, 0xFF01, 0xFE30, 0x2026, 0x2025, 0xFE50, 0xFE51, 0xFE52, - 0x00B7, 0xFE54, 0xFE55, 0xFE56, 0xFE57, 0xFF5C, 0x2013, 0xFE31, 0x2014, 0xFE33, 0x2574, 0xFE34, 0xFE4F, 0xFF08, 0xFF09, 0xFE35, - 0xFE36, 0xFF5B, 0xFF5D, 0xFE37, 0xFE38, 0x3014, 0x3015, 0xFE39, 0xFE3A, 0x3010, 0x3011, 0xFE3B, 0xFE3C, 0x300A, 0x300B, 0xFE3D, - 0xFE3E, 0x3008, 0x3009, 0xFE3F, 0xFE40, 0x300C, 0x300D, 0xFE41, 0xFE42, 0x300E, 0x300F, 0xFE43, 0xFE44, 0xFE59, 0xFE5A, - /* Big5-HKSCS 0xA1A1 .. 0xA1FE */ - 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0x2018, 0x2019, 0x201C, - 0x201D, 0x301D, 0x301E, 0x2035, 0x2032, 0xFF03, 0xFF06, 0xFF0A, 0x203B, 0x00A7, 0x3003, 0x25CB, 0x25CF, 0x25B3, 0x25B2, 0x25CE, - 0x2606, 0x2605, 0x25C7, 0x25C6, 0x25A1, 0x25A0, 0x25BD, 0x25BC, 0x32A3, 0x2105, 0x00AF, 0xFFE3, 0xFF3F, 0x02CD, 0xFE49, 0xFE4A, - 0xFE4D, 0xFE4E, 0xFE4B, 0xFE4C, 0xFE5F, 0xFE60, 0xFE61, 0xFF0B, 0xFF0D, 0x00D7, 0x00F7, 0x00B1, 0x221A, 0xFF1C, 0xFF1E, 0xFF1D, - 0x2266, 0x2267, 0x2260, 0x221E, 0x2252, 0x2261, 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFF5E, 0x2229, 0x222A, 0x22A5, 0x2220, - 0x221F, 0x22BF, 0x33D2, 0x33D1, 0x222B, 0x222E, 0x2235, 0x2234, 0x2640, 0x2642, 0x2295, 0x2299, 0x2191, 0x2193, 0x2190, 0x2192, - 0x2196, 0x2197, 0x2199, 0x2198, 0x2225, 0x2223, 0xFF0F, - /* Big5-HKSCS 0xA240 .. 0xA27E */ - 0xFF3C, 0x2215, 0xFE68, 0xFF04, 0xFFE5, 0x3012, 0xFFE0, 0xFFE1, 0xFF05, 0xFF20, 0x2103, 0x2109, 0xFE69, 0xFE6A, 0xFE6B, 0x33D5, - 0x339C, 0x339D, 0x339E, 0x33CE, 0x33A1, 0x338E, 0x338F, 0x33C4, 0x00B0, 0x5159, 0x515B, 0x515E, 0x515D, 0x5161, 0x5163, 0x55E7, - 0x74E9, 0x7CCE, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587, 0x2588, 0x258F, 0x258E, 0x258D, 0x258C, 0x258B, 0x258A, - 0x2589, 0x253C, 0x2534, 0x252C, 0x2524, 0x251C, 0x2594, 0x2500, 0x2502, 0x2595, 0x250C, 0x2510, 0x2514, 0x2518, 0x256D, - /* Big5-HKSCS 0xA2A1 .. 0xA2FE */ - 0x256E, 0x2570, 0x256F, 0x2550, 0x255E, 0x256A, 0x2561, - 0x25E2, 0x25E3, 0x25E5, 0x25E4, 0x2571, 0x2572, 0x2573, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, - 0xFF19, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, - 0x3026, 0x3027, 0x3028, 0x3029, 0x5341, 0x5344, 0x5345, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, - 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, - 0xFF3A, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, - 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, - /* Big5-HKSCS 0xA340 .. 0xA37E */ - 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, - 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, - 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, - 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x3105, 0x3106, 0x3107, 0x3108, 0x3109, 0x310A, 0x310B, 0x310C, 0x310D, 0x310E, 0x310F, - /* Big5-HKSCS 0xA3A1 .. 0xA3FE */ - 0x3110, 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, - 0x3117, 0x3118, 0x3119, 0x311A, 0x311B, 0x311C, 0x311D, 0x311E, 0x311F, 0x3120, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, - 0x3127, 0x3128, 0x3129, 0x02D9, 0x02C9, 0x02CA, 0x02C7, 0x02CB, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x20AC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, - /* Big5-HKSCS 0xA440 .. 0xA47E */ - 0x4E00, 0x4E59, 0x4E01, 0x4E03, 0x4E43, 0x4E5D, 0x4E86, 0x4E8C, 0x4EBA, 0x513F, 0x5165, 0x516B, 0x51E0, 0x5200, 0x5201, 0x529B, - 0x5315, 0x5341, 0x535C, 0x53C8, 0x4E09, 0x4E0B, 0x4E08, 0x4E0A, 0x4E2B, 0x4E38, 0x51E1, 0x4E45, 0x4E48, 0x4E5F, 0x4E5E, 0x4E8E, - 0x4EA1, 0x5140, 0x5203, 0x52FA, 0x5343, 0x53C9, 0x53E3, 0x571F, 0x58EB, 0x5915, 0x5927, 0x5973, 0x5B50, 0x5B51, 0x5B53, 0x5BF8, - 0x5C0F, 0x5C22, 0x5C38, 0x5C71, 0x5DDD, 0x5DE5, 0x5DF1, 0x5DF2, 0x5DF3, 0x5DFE, 0x5E72, 0x5EFE, 0x5F0B, 0x5F13, 0x624D, - /* Big5-HKSCS 0xA4A1 .. 0xA4FE */ - 0x4E11, 0x4E10, 0x4E0D, 0x4E2D, 0x4E30, 0x4E39, 0x4E4B, - 0x5C39, 0x4E88, 0x4E91, 0x4E95, 0x4E92, 0x4E94, 0x4EA2, 0x4EC1, 0x4EC0, 0x4EC3, 0x4EC6, 0x4EC7, 0x4ECD, 0x4ECA, 0x4ECB, 0x4EC4, - 0x5143, 0x5141, 0x5167, 0x516D, 0x516E, 0x516C, 0x5197, 0x51F6, 0x5206, 0x5207, 0x5208, 0x52FB, 0x52FE, 0x52FF, 0x5316, 0x5339, - 0x5348, 0x5347, 0x5345, 0x535E, 0x5384, 0x53CB, 0x53CA, 0x53CD, 0x58EC, 0x5929, 0x592B, 0x592A, 0x592D, 0x5B54, 0x5C11, 0x5C24, - 0x5C3A, 0x5C6F, 0x5DF4, 0x5E7B, 0x5EFF, 0x5F14, 0x5F15, 0x5FC3, 0x6208, 0x6236, 0x624B, 0x624E, 0x652F, 0x6587, 0x6597, 0x65A4, - 0x65B9, 0x65E5, 0x66F0, 0x6708, 0x6728, 0x6B20, 0x6B62, 0x6B79, 0x6BCB, 0x6BD4, 0x6BDB, 0x6C0F, 0x6C34, 0x706B, 0x722A, 0x7236, - 0x723B, 0x7247, 0x7259, 0x725B, 0x72AC, 0x738B, 0x4E19, - /* Big5-HKSCS 0xA540 .. 0xA57E */ - 0x4E16, 0x4E15, 0x4E14, 0x4E18, 0x4E3B, 0x4E4D, 0x4E4F, 0x4E4E, 0x4EE5, 0x4ED8, 0x4ED4, 0x4ED5, 0x4ED6, 0x4ED7, 0x4EE3, 0x4EE4, - 0x4ED9, 0x4EDE, 0x5145, 0x5144, 0x5189, 0x518A, 0x51AC, 0x51F9, 0x51FA, 0x51F8, 0x520A, 0x52A0, 0x529F, 0x5305, 0x5306, 0x5317, - 0x531D, 0x4EDF, 0x534A, 0x5349, 0x5361, 0x5360, 0x536F, 0x536E, 0x53BB, 0x53EF, 0x53E4, 0x53F3, 0x53EC, 0x53EE, 0x53E9, 0x53E8, - 0x53FC, 0x53F8, 0x53F5, 0x53EB, 0x53E6, 0x53EA, 0x53F2, 0x53F1, 0x53F0, 0x53E5, 0x53ED, 0x53FB, 0x56DB, 0x56DA, 0x5916, - /* Big5-HKSCS 0xA5A1 .. 0xA5FE */ - 0x592E, 0x5931, 0x5974, 0x5976, 0x5B55, 0x5B83, 0x5C3C, - 0x5DE8, 0x5DE7, 0x5DE6, 0x5E02, 0x5E03, 0x5E73, 0x5E7C, 0x5F01, 0x5F18, 0x5F17, 0x5FC5, 0x620A, 0x6253, 0x6254, 0x6252, 0x6251, - 0x65A5, 0x65E6, 0x672E, 0x672C, 0x672A, 0x672B, 0x672D, 0x6B63, 0x6BCD, 0x6C11, 0x6C10, 0x6C38, 0x6C41, 0x6C40, 0x6C3E, 0x72AF, - 0x7384, 0x7389, 0x74DC, 0x74E6, 0x7518, 0x751F, 0x7528, 0x7529, 0x7530, 0x7531, 0x7532, 0x7533, 0x758B, 0x767D, 0x76AE, 0x76BF, - 0x76EE, 0x77DB, 0x77E2, 0x77F3, 0x793A, 0x79BE, 0x7A74, 0x7ACB, 0x4E1E, 0x4E1F, 0x4E52, 0x4E53, 0x4E69, 0x4E99, 0x4EA4, 0x4EA6, - 0x4EA5, 0x4EFF, 0x4F09, 0x4F19, 0x4F0A, 0x4F15, 0x4F0D, 0x4F10, 0x4F11, 0x4F0F, 0x4EF2, 0x4EF6, 0x4EFB, 0x4EF0, 0x4EF3, 0x4EFD, - 0x4F01, 0x4F0B, 0x5149, 0x5147, 0x5146, 0x5148, 0x5168, - /* Big5-HKSCS 0xA640 .. 0xA67E */ - 0x5171, 0x518D, 0x51B0, 0x5217, 0x5211, 0x5212, 0x520E, 0x5216, 0x52A3, 0x5308, 0x5321, 0x5320, 0x5370, 0x5371, 0x5409, 0x540F, - 0x540C, 0x540A, 0x5410, 0x5401, 0x540B, 0x5404, 0x5411, 0x540D, 0x5408, 0x5403, 0x540E, 0x5406, 0x5412, 0x56E0, 0x56DE, 0x56DD, - 0x5733, 0x5730, 0x5728, 0x572D, 0x572C, 0x572F, 0x5729, 0x5919, 0x591A, 0x5937, 0x5938, 0x5984, 0x5978, 0x5983, 0x597D, 0x5979, - 0x5982, 0x5981, 0x5B57, 0x5B58, 0x5B87, 0x5B88, 0x5B85, 0x5B89, 0x5BFA, 0x5C16, 0x5C79, 0x5DDE, 0x5E06, 0x5E76, 0x5E74, - /* Big5-HKSCS 0xA6A1 .. 0xA6FE */ - 0x5F0F, 0x5F1B, 0x5FD9, 0x5FD6, 0x620E, 0x620C, 0x620D, - 0x6210, 0x6263, 0x625B, 0x6258, 0x6536, 0x65E9, 0x65E8, 0x65EC, 0x65ED, 0x66F2, 0x66F3, 0x6709, 0x673D, 0x6734, 0x6731, 0x6735, - 0x6B21, 0x6B64, 0x6B7B, 0x6C16, 0x6C5D, 0x6C57, 0x6C59, 0x6C5F, 0x6C60, 0x6C50, 0x6C55, 0x6C61, 0x6C5B, 0x6C4D, 0x6C4E, 0x7070, - 0x725F, 0x725D, 0x767E, 0x7AF9, 0x7C73, 0x7CF8, 0x7F36, 0x7F8A, 0x7FBD, 0x8001, 0x8003, 0x800C, 0x8012, 0x8033, 0x807F, 0x8089, - 0x808B, 0x808C, 0x81E3, 0x81EA, 0x81F3, 0x81FC, 0x820C, 0x821B, 0x821F, 0x826E, 0x8272, 0x827E, 0x866B, 0x8840, 0x884C, 0x8863, - 0x897F, 0x9621, 0x4E32, 0x4EA8, 0x4F4D, 0x4F4F, 0x4F47, 0x4F57, 0x4F5E, 0x4F34, 0x4F5B, 0x4F55, 0x4F30, 0x4F50, 0x4F51, 0x4F3D, - 0x4F3A, 0x4F38, 0x4F43, 0x4F54, 0x4F3C, 0x4F46, 0x4F63, - /* Big5-HKSCS 0xA740 .. 0xA77E */ - 0x4F5C, 0x4F60, 0x4F2F, 0x4F4E, 0x4F36, 0x4F59, 0x4F5D, 0x4F48, 0x4F5A, 0x514C, 0x514B, 0x514D, 0x5175, 0x51B6, 0x51B7, 0x5225, - 0x5224, 0x5229, 0x522A, 0x5228, 0x52AB, 0x52A9, 0x52AA, 0x52AC, 0x5323, 0x5373, 0x5375, 0x541D, 0x542D, 0x541E, 0x543E, 0x5426, - 0x544E, 0x5427, 0x5446, 0x5443, 0x5433, 0x5448, 0x5442, 0x541B, 0x5429, 0x544A, 0x5439, 0x543B, 0x5438, 0x542E, 0x5435, 0x5436, - 0x5420, 0x543C, 0x5440, 0x5431, 0x542B, 0x541F, 0x542C, 0x56EA, 0x56F0, 0x56E4, 0x56EB, 0x574A, 0x5751, 0x5740, 0x574D, - /* Big5-HKSCS 0xA7A1 .. 0xA7FE */ - 0x5747, 0x574E, 0x573E, 0x5750, 0x574F, 0x573B, 0x58EF, - 0x593E, 0x599D, 0x5992, 0x59A8, 0x599E, 0x59A3, 0x5999, 0x5996, 0x598D, 0x59A4, 0x5993, 0x598A, 0x59A5, 0x5B5D, 0x5B5C, 0x5B5A, - 0x5B5B, 0x5B8C, 0x5B8B, 0x5B8F, 0x5C2C, 0x5C40, 0x5C41, 0x5C3F, 0x5C3E, 0x5C90, 0x5C91, 0x5C94, 0x5C8C, 0x5DEB, 0x5E0C, 0x5E8F, - 0x5E87, 0x5E8A, 0x5EF7, 0x5F04, 0x5F1F, 0x5F64, 0x5F62, 0x5F77, 0x5F79, 0x5FD8, 0x5FCC, 0x5FD7, 0x5FCD, 0x5FF1, 0x5FEB, 0x5FF8, - 0x5FEA, 0x6212, 0x6211, 0x6284, 0x6297, 0x6296, 0x6280, 0x6276, 0x6289, 0x626D, 0x628A, 0x627C, 0x627E, 0x6279, 0x6273, 0x6292, - 0x626F, 0x6298, 0x626E, 0x6295, 0x6293, 0x6291, 0x6286, 0x6539, 0x653B, 0x6538, 0x65F1, 0x66F4, 0x675F, 0x674E, 0x674F, 0x6750, - 0x6751, 0x675C, 0x6756, 0x675E, 0x6749, 0x6746, 0x6760, - /* Big5-HKSCS 0xA840 .. 0xA87E */ - 0x6753, 0x6757, 0x6B65, 0x6BCF, 0x6C42, 0x6C5E, 0x6C99, 0x6C81, 0x6C88, 0x6C89, 0x6C85, 0x6C9B, 0x6C6A, 0x6C7A, 0x6C90, 0x6C70, - 0x6C8C, 0x6C68, 0x6C96, 0x6C92, 0x6C7D, 0x6C83, 0x6C72, 0x6C7E, 0x6C74, 0x6C86, 0x6C76, 0x6C8D, 0x6C94, 0x6C98, 0x6C82, 0x7076, - 0x707C, 0x707D, 0x7078, 0x7262, 0x7261, 0x7260, 0x72C4, 0x72C2, 0x7396, 0x752C, 0x752B, 0x7537, 0x7538, 0x7682, 0x76EF, 0x77E3, - 0x79C1, 0x79C0, 0x79BF, 0x7A76, 0x7CFB, 0x7F55, 0x8096, 0x8093, 0x809D, 0x8098, 0x809B, 0x809A, 0x80B2, 0x826F, 0x8292, - /* Big5-HKSCS 0xA8A1 .. 0xA8FE */ - 0x828B, 0x828D, 0x898B, 0x89D2, 0x8A00, 0x8C37, 0x8C46, - 0x8C55, 0x8C9D, 0x8D64, 0x8D70, 0x8DB3, 0x8EAB, 0x8ECA, 0x8F9B, 0x8FB0, 0x8FC2, 0x8FC6, 0x8FC5, 0x8FC4, 0x5DE1, 0x9091, 0x90A2, - 0x90AA, 0x90A6, 0x90A3, 0x9149, 0x91C6, 0x91CC, 0x9632, 0x962E, 0x9631, 0x962A, 0x962C, 0x4E26, 0x4E56, 0x4E73, 0x4E8B, 0x4E9B, - 0x4E9E, 0x4EAB, 0x4EAC, 0x4F6F, 0x4F9D, 0x4F8D, 0x4F73, 0x4F7F, 0x4F6C, 0x4F9B, 0x4F8B, 0x4F86, 0x4F83, 0x4F70, 0x4F75, 0x4F88, - 0x4F69, 0x4F7B, 0x4F96, 0x4F7E, 0x4F8F, 0x4F91, 0x4F7A, 0x5154, 0x5152, 0x5155, 0x5169, 0x5177, 0x5176, 0x5178, 0x51BD, 0x51FD, - 0x523B, 0x5238, 0x5237, 0x523A, 0x5230, 0x522E, 0x5236, 0x5241, 0x52BE, 0x52BB, 0x5352, 0x5354, 0x5353, 0x5351, 0x5366, 0x5377, - 0x5378, 0x5379, 0x53D6, 0x53D4, 0x53D7, 0x5473, 0x5475, - /* Big5-HKSCS 0xA940 .. 0xA97E */ - 0x5496, 0x5478, 0x5495, 0x5480, 0x547B, 0x5477, 0x5484, 0x5492, 0x5486, 0x547C, 0x5490, 0x5471, 0x5476, 0x548C, 0x549A, 0x5462, - 0x5468, 0x548B, 0x547D, 0x548E, 0x56FA, 0x5783, 0x5777, 0x576A, 0x5769, 0x5761, 0x5766, 0x5764, 0x577C, 0x591C, 0x5949, 0x5947, - 0x5948, 0x5944, 0x5954, 0x59BE, 0x59BB, 0x59D4, 0x59B9, 0x59AE, 0x59D1, 0x59C6, 0x59D0, 0x59CD, 0x59CB, 0x59D3, 0x59CA, 0x59AF, - 0x59B3, 0x59D2, 0x59C5, 0x5B5F, 0x5B64, 0x5B63, 0x5B97, 0x5B9A, 0x5B98, 0x5B9C, 0x5B99, 0x5B9B, 0x5C1A, 0x5C48, 0x5C45, - /* Big5-HKSCS 0xA9A1 .. 0xA9FE */ - 0x5C46, 0x5CB7, 0x5CA1, 0x5CB8, 0x5CA9, 0x5CAB, 0x5CB1, - 0x5CB3, 0x5E18, 0x5E1A, 0x5E16, 0x5E15, 0x5E1B, 0x5E11, 0x5E78, 0x5E9A, 0x5E97, 0x5E9C, 0x5E95, 0x5E96, 0x5EF6, 0x5F26, 0x5F27, - 0x5F29, 0x5F80, 0x5F81, 0x5F7F, 0x5F7C, 0x5FDD, 0x5FE0, 0x5FFD, 0x5FF5, 0x5FFF, 0x600F, 0x6014, 0x602F, 0x6035, 0x6016, 0x602A, - 0x6015, 0x6021, 0x6027, 0x6029, 0x602B, 0x601B, 0x6216, 0x6215, 0x623F, 0x623E, 0x6240, 0x627F, 0x62C9, 0x62CC, 0x62C4, 0x62BF, - 0x62C2, 0x62B9, 0x62D2, 0x62DB, 0x62AB, 0x62D3, 0x62D4, 0x62CB, 0x62C8, 0x62A8, 0x62BD, 0x62BC, 0x62D0, 0x62D9, 0x62C7, 0x62CD, - 0x62B5, 0x62DA, 0x62B1, 0x62D8, 0x62D6, 0x62D7, 0x62C6, 0x62AC, 0x62CE, 0x653E, 0x65A7, 0x65BC, 0x65FA, 0x6614, 0x6613, 0x660C, - 0x6606, 0x6602, 0x660E, 0x6600, 0x660F, 0x6615, 0x660A, - /* Big5-HKSCS 0xAA40 .. 0xAA7E */ - 0x6607, 0x670D, 0x670B, 0x676D, 0x678B, 0x6795, 0x6771, 0x679C, 0x6773, 0x6777, 0x6787, 0x679D, 0x6797, 0x676F, 0x6770, 0x677F, - 0x6789, 0x677E, 0x6790, 0x6775, 0x679A, 0x6793, 0x677C, 0x676A, 0x6772, 0x6B23, 0x6B66, 0x6B67, 0x6B7F, 0x6C13, 0x6C1B, 0x6CE3, - 0x6CE8, 0x6CF3, 0x6CB1, 0x6CCC, 0x6CE5, 0x6CB3, 0x6CBD, 0x6CBE, 0x6CBC, 0x6CE2, 0x6CAB, 0x6CD5, 0x6CD3, 0x6CB8, 0x6CC4, 0x6CB9, - 0x6CC1, 0x6CAE, 0x6CD7, 0x6CC5, 0x6CF1, 0x6CBF, 0x6CBB, 0x6CE1, 0x6CDB, 0x6CCA, 0x6CAC, 0x6CEF, 0x6CDC, 0x6CD6, 0x6CE0, - /* Big5-HKSCS 0xAAA1 .. 0xAAFE */ - 0x7095, 0x708E, 0x7092, 0x708A, 0x7099, 0x722C, 0x722D, - 0x7238, 0x7248, 0x7267, 0x7269, 0x72C0, 0x72CE, 0x72D9, 0x72D7, 0x72D0, 0x73A9, 0x73A8, 0x739F, 0x73AB, 0x73A5, 0x753D, 0x759D, - 0x7599, 0x759A, 0x7684, 0x76C2, 0x76F2, 0x76F4, 0x77E5, 0x77FD, 0x793E, 0x7940, 0x7941, 0x79C9, 0x79C8, 0x7A7A, 0x7A79, 0x7AFA, - 0x7CFE, 0x7F54, 0x7F8C, 0x7F8B, 0x8005, 0x80BA, 0x80A5, 0x80A2, 0x80B1, 0x80A1, 0x80AB, 0x80A9, 0x80B4, 0x80AA, 0x80AF, 0x81E5, - 0x81FE, 0x820D, 0x82B3, 0x829D, 0x8299, 0x82AD, 0x82BD, 0x829F, 0x82B9, 0x82B1, 0x82AC, 0x82A5, 0x82AF, 0x82B8, 0x82A3, 0x82B0, - 0x82BE, 0x82B7, 0x864E, 0x8671, 0x521D, 0x8868, 0x8ECB, 0x8FCE, 0x8FD4, 0x8FD1, 0x90B5, 0x90B8, 0x90B1, 0x90B6, 0x91C7, 0x91D1, - 0x9577, 0x9580, 0x961C, 0x9640, 0x963F, 0x963B, 0x9644, - /* Big5-HKSCS 0xAB40 .. 0xAB7E */ - 0x9642, 0x96B9, 0x96E8, 0x9752, 0x975E, 0x4E9F, 0x4EAD, 0x4EAE, 0x4FE1, 0x4FB5, 0x4FAF, 0x4FBF, 0x4FE0, 0x4FD1, 0x4FCF, 0x4FDD, - 0x4FC3, 0x4FB6, 0x4FD8, 0x4FDF, 0x4FCA, 0x4FD7, 0x4FAE, 0x4FD0, 0x4FC4, 0x4FC2, 0x4FDA, 0x4FCE, 0x4FDE, 0x4FB7, 0x5157, 0x5192, - 0x5191, 0x51A0, 0x524E, 0x5243, 0x524A, 0x524D, 0x524C, 0x524B, 0x5247, 0x52C7, 0x52C9, 0x52C3, 0x52C1, 0x530D, 0x5357, 0x537B, - 0x539A, 0x53DB, 0x54AC, 0x54C0, 0x54A8, 0x54CE, 0x54C9, 0x54B8, 0x54A6, 0x54B3, 0x54C7, 0x54C2, 0x54BD, 0x54AA, 0x54C1, - /* Big5-HKSCS 0xABA1 .. 0xABFE */ - 0x54C4, 0x54C8, 0x54AF, 0x54AB, 0x54B1, 0x54BB, 0x54A9, - 0x54A7, 0x54BF, 0x56FF, 0x5782, 0x578B, 0x57A0, 0x57A3, 0x57A2, 0x57CE, 0x57AE, 0x5793, 0x5955, 0x5951, 0x594F, 0x594E, 0x5950, - 0x59DC, 0x59D8, 0x59FF, 0x59E3, 0x59E8, 0x5A03, 0x59E5, 0x59EA, 0x59DA, 0x59E6, 0x5A01, 0x59FB, 0x5B69, 0x5BA3, 0x5BA6, 0x5BA4, - 0x5BA2, 0x5BA5, 0x5C01, 0x5C4E, 0x5C4F, 0x5C4D, 0x5C4B, 0x5CD9, 0x5CD2, 0x5DF7, 0x5E1D, 0x5E25, 0x5E1F, 0x5E7D, 0x5EA0, 0x5EA6, - 0x5EFA, 0x5F08, 0x5F2D, 0x5F65, 0x5F88, 0x5F85, 0x5F8A, 0x5F8B, 0x5F87, 0x5F8C, 0x5F89, 0x6012, 0x601D, 0x6020, 0x6025, 0x600E, - 0x6028, 0x604D, 0x6070, 0x6068, 0x6062, 0x6046, 0x6043, 0x606C, 0x606B, 0x606A, 0x6064, 0x6241, 0x62DC, 0x6316, 0x6309, 0x62FC, - 0x62ED, 0x6301, 0x62EE, 0x62FD, 0x6307, 0x62F1, 0x62F7, - /* Big5-HKSCS 0xAC40 .. 0xAC7E */ - 0x62EF, 0x62EC, 0x62FE, 0x62F4, 0x6311, 0x6302, 0x653F, 0x6545, 0x65AB, 0x65BD, 0x65E2, 0x6625, 0x662D, 0x6620, 0x6627, 0x662F, - 0x661F, 0x6628, 0x6631, 0x6624, 0x66F7, 0x67FF, 0x67D3, 0x67F1, 0x67D4, 0x67D0, 0x67EC, 0x67B6, 0x67AF, 0x67F5, 0x67E9, 0x67EF, - 0x67C4, 0x67D1, 0x67B4, 0x67DA, 0x67E5, 0x67B8, 0x67CF, 0x67DE, 0x67F3, 0x67B0, 0x67D9, 0x67E2, 0x67DD, 0x67D2, 0x6B6A, 0x6B83, - 0x6B86, 0x6BB5, 0x6BD2, 0x6BD7, 0x6C1F, 0x6CC9, 0x6D0B, 0x6D32, 0x6D2A, 0x6D41, 0x6D25, 0x6D0C, 0x6D31, 0x6D1E, 0x6D17, - /* Big5-HKSCS 0xACA1 .. 0xACFE */ - 0x6D3B, 0x6D3D, 0x6D3E, 0x6D36, 0x6D1B, 0x6CF5, 0x6D39, - 0x6D27, 0x6D38, 0x6D29, 0x6D2E, 0x6D35, 0x6D0E, 0x6D2B, 0x70AB, 0x70BA, 0x70B3, 0x70AC, 0x70AF, 0x70AD, 0x70B8, 0x70AE, 0x70A4, - 0x7230, 0x7272, 0x726F, 0x7274, 0x72E9, 0x72E0, 0x72E1, 0x73B7, 0x73CA, 0x73BB, 0x73B2, 0x73CD, 0x73C0, 0x73B3, 0x751A, 0x752D, - 0x754F, 0x754C, 0x754E, 0x754B, 0x75AB, 0x75A4, 0x75A5, 0x75A2, 0x75A3, 0x7678, 0x7686, 0x7687, 0x7688, 0x76C8, 0x76C6, 0x76C3, - 0x76C5, 0x7701, 0x76F9, 0x76F8, 0x7709, 0x770B, 0x76FE, 0x76FC, 0x7707, 0x77DC, 0x7802, 0x7814, 0x780C, 0x780D, 0x7946, 0x7949, - 0x7948, 0x7947, 0x79B9, 0x79BA, 0x79D1, 0x79D2, 0x79CB, 0x7A7F, 0x7A81, 0x7AFF, 0x7AFD, 0x7C7D, 0x7D02, 0x7D05, 0x7D00, 0x7D09, - 0x7D07, 0x7D04, 0x7D06, 0x7F38, 0x7F8E, 0x7FBF, 0x8004, - /* Big5-HKSCS 0xAD40 .. 0xAD7E */ - 0x8010, 0x800D, 0x8011, 0x8036, 0x80D6, 0x80E5, 0x80DA, 0x80C3, 0x80C4, 0x80CC, 0x80E1, 0x80DB, 0x80CE, 0x80DE, 0x80E4, 0x80DD, - 0x81F4, 0x8222, 0x82E7, 0x8303, 0x8305, 0x82E3, 0x82DB, 0x82E6, 0x8304, 0x82E5, 0x8302, 0x8309, 0x82D2, 0x82D7, 0x82F1, 0x8301, - 0x82DC, 0x82D4, 0x82D1, 0x82DE, 0x82D3, 0x82DF, 0x82EF, 0x8306, 0x8650, 0x8679, 0x867B, 0x867A, 0x884D, 0x886B, 0x8981, 0x89D4, - 0x8A08, 0x8A02, 0x8A03, 0x8C9E, 0x8CA0, 0x8D74, 0x8D73, 0x8DB4, 0x8ECD, 0x8ECC, 0x8FF0, 0x8FE6, 0x8FE2, 0x8FEA, 0x8FE5, - /* Big5-HKSCS 0xADA1 .. 0xADFE */ - 0x8FED, 0x8FEB, 0x8FE4, 0x8FE8, 0x90CA, 0x90CE, 0x90C1, - 0x90C3, 0x914B, 0x914A, 0x91CD, 0x9582, 0x9650, 0x964B, 0x964C, 0x964D, 0x9762, 0x9769, 0x97CB, 0x97ED, 0x97F3, 0x9801, 0x98A8, - 0x98DB, 0x98DF, 0x9996, 0x9999, 0x4E58, 0x4EB3, 0x500C, 0x500D, 0x5023, 0x4FEF, 0x5026, 0x5025, 0x4FF8, 0x5029, 0x5016, 0x5006, - 0x503C, 0x501F, 0x501A, 0x5012, 0x5011, 0x4FFA, 0x5000, 0x5014, 0x5028, 0x4FF1, 0x5021, 0x500B, 0x5019, 0x5018, 0x4FF3, 0x4FEE, - 0x502D, 0x502A, 0x4FFE, 0x502B, 0x5009, 0x517C, 0x51A4, 0x51A5, 0x51A2, 0x51CD, 0x51CC, 0x51C6, 0x51CB, 0x5256, 0x525C, 0x5254, - 0x525B, 0x525D, 0x532A, 0x537F, 0x539F, 0x539D, 0x53DF, 0x54E8, 0x5510, 0x5501, 0x5537, 0x54FC, 0x54E5, 0x54F2, 0x5506, 0x54FA, - 0x5514, 0x54E9, 0x54ED, 0x54E1, 0x5509, 0x54EE, 0x54EA, - /* Big5-HKSCS 0xAE40 .. 0xAE7E */ - 0x54E6, 0x5527, 0x5507, 0x54FD, 0x550F, 0x5703, 0x5704, 0x57C2, 0x57D4, 0x57CB, 0x57C3, 0x5809, 0x590F, 0x5957, 0x5958, 0x595A, - 0x5A11, 0x5A18, 0x5A1C, 0x5A1F, 0x5A1B, 0x5A13, 0x59EC, 0x5A20, 0x5A23, 0x5A29, 0x5A25, 0x5A0C, 0x5A09, 0x5B6B, 0x5C58, 0x5BB0, - 0x5BB3, 0x5BB6, 0x5BB4, 0x5BAE, 0x5BB5, 0x5BB9, 0x5BB8, 0x5C04, 0x5C51, 0x5C55, 0x5C50, 0x5CED, 0x5CFD, 0x5CFB, 0x5CEA, 0x5CE8, - 0x5CF0, 0x5CF6, 0x5D01, 0x5CF4, 0x5DEE, 0x5E2D, 0x5E2B, 0x5EAB, 0x5EAD, 0x5EA7, 0x5F31, 0x5F92, 0x5F91, 0x5F90, 0x6059, - /* Big5-HKSCS 0xAEA1 .. 0xAEFE */ - 0x6063, 0x6065, 0x6050, 0x6055, 0x606D, 0x6069, 0x606F, - 0x6084, 0x609F, 0x609A, 0x608D, 0x6094, 0x608C, 0x6085, 0x6096, 0x6247, 0x62F3, 0x6308, 0x62FF, 0x634E, 0x633E, 0x632F, 0x6355, - 0x6342, 0x6346, 0x634F, 0x6349, 0x633A, 0x6350, 0x633D, 0x632A, 0x632B, 0x6328, 0x634D, 0x634C, 0x6548, 0x6549, 0x6599, 0x65C1, - 0x65C5, 0x6642, 0x6649, 0x664F, 0x6643, 0x6652, 0x664C, 0x6645, 0x6641, 0x66F8, 0x6714, 0x6715, 0x6717, 0x6821, 0x6838, 0x6848, - 0x6846, 0x6853, 0x6839, 0x6842, 0x6854, 0x6829, 0x68B3, 0x6817, 0x684C, 0x6851, 0x683D, 0x67F4, 0x6850, 0x6840, 0x683C, 0x6843, - 0x682A, 0x6845, 0x6813, 0x6818, 0x6841, 0x6B8A, 0x6B89, 0x6BB7, 0x6C23, 0x6C27, 0x6C28, 0x6C26, 0x6C24, 0x6CF0, 0x6D6A, 0x6D95, - 0x6D88, 0x6D87, 0x6D66, 0x6D78, 0x6D77, 0x6D59, 0x6D93, - /* Big5-HKSCS 0xAF40 .. 0xAF7E */ - 0x6D6C, 0x6D89, 0x6D6E, 0x6D5A, 0x6D74, 0x6D69, 0x6D8C, 0x6D8A, 0x6D79, 0x6D85, 0x6D65, 0x6D94, 0x70CA, 0x70D8, 0x70E4, 0x70D9, - 0x70C8, 0x70CF, 0x7239, 0x7279, 0x72FC, 0x72F9, 0x72FD, 0x72F8, 0x72F7, 0x7386, 0x73ED, 0x7409, 0x73EE, 0x73E0, 0x73EA, 0x73DE, - 0x7554, 0x755D, 0x755C, 0x755A, 0x7559, 0x75BE, 0x75C5, 0x75C7, 0x75B2, 0x75B3, 0x75BD, 0x75BC, 0x75B9, 0x75C2, 0x75B8, 0x768B, - 0x76B0, 0x76CA, 0x76CD, 0x76CE, 0x7729, 0x771F, 0x7720, 0x7728, 0x77E9, 0x7830, 0x7827, 0x7838, 0x781D, 0x7834, 0x7837, - /* Big5-HKSCS 0xAFA1 .. 0xAFFE */ - 0x7825, 0x782D, 0x7820, 0x781F, 0x7832, 0x7955, 0x7950, - 0x7960, 0x795F, 0x7956, 0x795E, 0x795D, 0x7957, 0x795A, 0x79E4, 0x79E3, 0x79E7, 0x79DF, 0x79E6, 0x79E9, 0x79D8, 0x7A84, 0x7A88, - 0x7AD9, 0x7B06, 0x7B11, 0x7C89, 0x7D21, 0x7D17, 0x7D0B, 0x7D0A, 0x7D20, 0x7D22, 0x7D14, 0x7D10, 0x7D15, 0x7D1A, 0x7D1C, 0x7D0D, - 0x7D19, 0x7D1B, 0x7F3A, 0x7F5F, 0x7F94, 0x7FC5, 0x7FC1, 0x8006, 0x8018, 0x8015, 0x8019, 0x8017, 0x803D, 0x803F, 0x80F1, 0x8102, - 0x80F0, 0x8105, 0x80ED, 0x80F4, 0x8106, 0x80F8, 0x80F3, 0x8108, 0x80FD, 0x810A, 0x80FC, 0x80EF, 0x81ED, 0x81EC, 0x8200, 0x8210, - 0x822A, 0x822B, 0x8228, 0x822C, 0x82BB, 0x832B, 0x8352, 0x8354, 0x834A, 0x8338, 0x8350, 0x8349, 0x8335, 0x8334, 0x834F, 0x8332, - 0x8339, 0x8336, 0x8317, 0x8340, 0x8331, 0x8328, 0x8343, - /* Big5-HKSCS 0xB040 .. 0xB07E */ - 0x8654, 0x868A, 0x86AA, 0x8693, 0x86A4, 0x86A9, 0x868C, 0x86A3, 0x869C, 0x8870, 0x8877, 0x8881, 0x8882, 0x887D, 0x8879, 0x8A18, - 0x8A10, 0x8A0E, 0x8A0C, 0x8A15, 0x8A0A, 0x8A17, 0x8A13, 0x8A16, 0x8A0F, 0x8A11, 0x8C48, 0x8C7A, 0x8C79, 0x8CA1, 0x8CA2, 0x8D77, - 0x8EAC, 0x8ED2, 0x8ED4, 0x8ECF, 0x8FB1, 0x9001, 0x9006, 0x8FF7, 0x9000, 0x8FFA, 0x8FF4, 0x9003, 0x8FFD, 0x9005, 0x8FF8, 0x9095, - 0x90E1, 0x90DD, 0x90E2, 0x9152, 0x914D, 0x914C, 0x91D8, 0x91DD, 0x91D7, 0x91DC, 0x91D9, 0x9583, 0x9662, 0x9663, 0x9661, - /* Big5-HKSCS 0xB0A1 .. 0xB0FE */ - 0x965B, 0x965D, 0x9664, 0x9658, 0x965E, 0x96BB, 0x98E2, - 0x99AC, 0x9AA8, 0x9AD8, 0x9B25, 0x9B32, 0x9B3C, 0x4E7E, 0x507A, 0x507D, 0x505C, 0x5047, 0x5043, 0x504C, 0x505A, 0x5049, 0x5065, - 0x5076, 0x504E, 0x5055, 0x5075, 0x5074, 0x5077, 0x504F, 0x500F, 0x506F, 0x506D, 0x515C, 0x5195, 0x51F0, 0x526A, 0x526F, 0x52D2, - 0x52D9, 0x52D8, 0x52D5, 0x5310, 0x530F, 0x5319, 0x533F, 0x5340, 0x533E, 0x53C3, 0x66FC, 0x5546, 0x556A, 0x5566, 0x5544, 0x555E, - 0x5561, 0x5543, 0x554A, 0x5531, 0x5556, 0x554F, 0x5555, 0x552F, 0x5564, 0x5538, 0x552E, 0x555C, 0x552C, 0x5563, 0x5533, 0x5541, - 0x5557, 0x5708, 0x570B, 0x5709, 0x57DF, 0x5805, 0x580A, 0x5806, 0x57E0, 0x57E4, 0x57FA, 0x5802, 0x5835, 0x57F7, 0x57F9, 0x5920, - 0x5962, 0x5A36, 0x5A41, 0x5A49, 0x5A66, 0x5A6A, 0x5A40, - /* Big5-HKSCS 0xB140 .. 0xB17E */ - 0x5A3C, 0x5A62, 0x5A5A, 0x5A46, 0x5A4A, 0x5B70, 0x5BC7, 0x5BC5, 0x5BC4, 0x5BC2, 0x5BBF, 0x5BC6, 0x5C09, 0x5C08, 0x5C07, 0x5C60, - 0x5C5C, 0x5C5D, 0x5D07, 0x5D06, 0x5D0E, 0x5D1B, 0x5D16, 0x5D22, 0x5D11, 0x5D29, 0x5D14, 0x5D19, 0x5D24, 0x5D27, 0x5D17, 0x5DE2, - 0x5E38, 0x5E36, 0x5E33, 0x5E37, 0x5EB7, 0x5EB8, 0x5EB6, 0x5EB5, 0x5EBE, 0x5F35, 0x5F37, 0x5F57, 0x5F6C, 0x5F69, 0x5F6B, 0x5F97, - 0x5F99, 0x5F9E, 0x5F98, 0x5FA1, 0x5FA0, 0x5F9C, 0x607F, 0x60A3, 0x6089, 0x60A0, 0x60A8, 0x60CB, 0x60B4, 0x60E6, 0x60BD, - /* Big5-HKSCS 0xB1A1 .. 0xB1FE */ - 0x60C5, 0x60BB, 0x60B5, 0x60DC, 0x60BC, 0x60D8, 0x60D5, - 0x60C6, 0x60DF, 0x60B8, 0x60DA, 0x60C7, 0x621A, 0x621B, 0x6248, 0x63A0, 0x63A7, 0x6372, 0x6396, 0x63A2, 0x63A5, 0x6377, 0x6367, - 0x6398, 0x63AA, 0x6371, 0x63A9, 0x6389, 0x6383, 0x639B, 0x636B, 0x63A8, 0x6384, 0x6388, 0x6399, 0x63A1, 0x63AC, 0x6392, 0x638F, - 0x6380, 0x637B, 0x6369, 0x6368, 0x637A, 0x655D, 0x6556, 0x6551, 0x6559, 0x6557, 0x555F, 0x654F, 0x6558, 0x6555, 0x6554, 0x659C, - 0x659B, 0x65AC, 0x65CF, 0x65CB, 0x65CC, 0x65CE, 0x665D, 0x665A, 0x6664, 0x6668, 0x6666, 0x665E, 0x66F9, 0x52D7, 0x671B, 0x6881, - 0x68AF, 0x68A2, 0x6893, 0x68B5, 0x687F, 0x6876, 0x68B1, 0x68A7, 0x6897, 0x68B0, 0x6883, 0x68C4, 0x68AD, 0x6886, 0x6885, 0x6894, - 0x689D, 0x68A8, 0x689F, 0x68A1, 0x6882, 0x6B32, 0x6BBA, - /* Big5-HKSCS 0xB240 .. 0xB27E */ - 0x6BEB, 0x6BEC, 0x6C2B, 0x6D8E, 0x6DBC, 0x6DF3, 0x6DD9, 0x6DB2, 0x6DE1, 0x6DCC, 0x6DE4, 0x6DFB, 0x6DFA, 0x6E05, 0x6DC7, 0x6DCB, - 0x6DAF, 0x6DD1, 0x6DAE, 0x6DDE, 0x6DF9, 0x6DB8, 0x6DF7, 0x6DF5, 0x6DC5, 0x6DD2, 0x6E1A, 0x6DB5, 0x6DDA, 0x6DEB, 0x6DD8, 0x6DEA, - 0x6DF1, 0x6DEE, 0x6DE8, 0x6DC6, 0x6DC4, 0x6DAA, 0x6DEC, 0x6DBF, 0x6DE6, 0x70F9, 0x7109, 0x710A, 0x70FD, 0x70EF, 0x723D, 0x727D, - 0x7281, 0x731C, 0x731B, 0x7316, 0x7313, 0x7319, 0x7387, 0x7405, 0x740A, 0x7403, 0x7406, 0x73FE, 0x740D, 0x74E0, 0x74F6, - /* Big5-HKSCS 0xB2A1 .. 0xB2FE */ - 0x74F7, 0x751C, 0x7522, 0x7565, 0x7566, 0x7562, 0x7570, - 0x758F, 0x75D4, 0x75D5, 0x75B5, 0x75CA, 0x75CD, 0x768E, 0x76D4, 0x76D2, 0x76DB, 0x7737, 0x773E, 0x773C, 0x7736, 0x7738, 0x773A, - 0x786B, 0x7843, 0x784E, 0x7965, 0x7968, 0x796D, 0x79FB, 0x7A92, 0x7A95, 0x7B20, 0x7B28, 0x7B1B, 0x7B2C, 0x7B26, 0x7B19, 0x7B1E, - 0x7B2E, 0x7C92, 0x7C97, 0x7C95, 0x7D46, 0x7D43, 0x7D71, 0x7D2E, 0x7D39, 0x7D3C, 0x7D40, 0x7D30, 0x7D33, 0x7D44, 0x7D2F, 0x7D42, - 0x7D32, 0x7D31, 0x7F3D, 0x7F9E, 0x7F9A, 0x7FCC, 0x7FCE, 0x7FD2, 0x801C, 0x804A, 0x8046, 0x812F, 0x8116, 0x8123, 0x812B, 0x8129, - 0x8130, 0x8124, 0x8202, 0x8235, 0x8237, 0x8236, 0x8239, 0x838E, 0x839E, 0x8398, 0x8378, 0x83A2, 0x8396, 0x83BD, 0x83AB, 0x8392, - 0x838A, 0x8393, 0x8389, 0x83A0, 0x8377, 0x837B, 0x837C, - /* Big5-HKSCS 0xB340 .. 0xB37E */ - 0x8386, 0x83A7, 0x8655, 0x5F6A, 0x86C7, 0x86C0, 0x86B6, 0x86C4, 0x86B5, 0x86C6, 0x86CB, 0x86B1, 0x86AF, 0x86C9, 0x8853, 0x889E, - 0x8888, 0x88AB, 0x8892, 0x8896, 0x888D, 0x888B, 0x8993, 0x898F, 0x8A2A, 0x8A1D, 0x8A23, 0x8A25, 0x8A31, 0x8A2D, 0x8A1F, 0x8A1B, - 0x8A22, 0x8C49, 0x8C5A, 0x8CA9, 0x8CAC, 0x8CAB, 0x8CA8, 0x8CAA, 0x8CA7, 0x8D67, 0x8D66, 0x8DBE, 0x8DBA, 0x8EDB, 0x8EDF, 0x9019, - 0x900D, 0x901A, 0x9017, 0x9023, 0x901F, 0x901D, 0x9010, 0x9015, 0x901E, 0x9020, 0x900F, 0x9022, 0x9016, 0x901B, 0x9014, - /* Big5-HKSCS 0xB3A1 .. 0xB3FE */ - 0x90E8, 0x90ED, 0x90FD, 0x9157, 0x91CE, 0x91F5, 0x91E6, - 0x91E3, 0x91E7, 0x91ED, 0x91E9, 0x9589, 0x966A, 0x9675, 0x9673, 0x9678, 0x9670, 0x9674, 0x9676, 0x9677, 0x966C, 0x96C0, 0x96EA, - 0x96E9, 0x7AE0, 0x7ADF, 0x9802, 0x9803, 0x9B5A, 0x9CE5, 0x9E75, 0x9E7F, 0x9EA5, 0x9EBB, 0x50A2, 0x508D, 0x5085, 0x5099, 0x5091, - 0x5080, 0x5096, 0x5098, 0x509A, 0x6700, 0x51F1, 0x5272, 0x5274, 0x5275, 0x5269, 0x52DE, 0x52DD, 0x52DB, 0x535A, 0x53A5, 0x557B, - 0x5580, 0x55A7, 0x557C, 0x558A, 0x559D, 0x5598, 0x5582, 0x559C, 0x55AA, 0x5594, 0x5587, 0x558B, 0x5583, 0x55B3, 0x55AE, 0x559F, - 0x553E, 0x55B2, 0x559A, 0x55BB, 0x55AC, 0x55B1, 0x557E, 0x5589, 0x55AB, 0x5599, 0x570D, 0x582F, 0x582A, 0x5834, 0x5824, 0x5830, - 0x5831, 0x5821, 0x581D, 0x5820, 0x58F9, 0x58FA, 0x5960, - /* Big5-HKSCS 0xB440 .. 0xB47E */ - 0x5A77, 0x5A9A, 0x5A7F, 0x5A92, 0x5A9B, 0x5AA7, 0x5B73, 0x5B71, 0x5BD2, 0x5BCC, 0x5BD3, 0x5BD0, 0x5C0A, 0x5C0B, 0x5C31, 0x5D4C, - 0x5D50, 0x5D34, 0x5D47, 0x5DFD, 0x5E45, 0x5E3D, 0x5E40, 0x5E43, 0x5E7E, 0x5ECA, 0x5EC1, 0x5EC2, 0x5EC4, 0x5F3C, 0x5F6D, 0x5FA9, - 0x5FAA, 0x5FA8, 0x60D1, 0x60E1, 0x60B2, 0x60B6, 0x60E0, 0x611C, 0x6123, 0x60FA, 0x6115, 0x60F0, 0x60FB, 0x60F4, 0x6168, 0x60F1, - 0x610E, 0x60F6, 0x6109, 0x6100, 0x6112, 0x621F, 0x6249, 0x63A3, 0x638C, 0x63CF, 0x63C0, 0x63E9, 0x63C9, 0x63C6, 0x63CD, - /* Big5-HKSCS 0xB4A1 .. 0xB4FE */ - 0x63D2, 0x63E3, 0x63D0, 0x63E1, 0x63D6, 0x63ED, 0x63EE, - 0x6376, 0x63F4, 0x63EA, 0x63DB, 0x6452, 0x63DA, 0x63F9, 0x655E, 0x6566, 0x6562, 0x6563, 0x6591, 0x6590, 0x65AF, 0x666E, 0x6670, - 0x6674, 0x6676, 0x666F, 0x6691, 0x667A, 0x667E, 0x6677, 0x66FE, 0x66FF, 0x671F, 0x671D, 0x68FA, 0x68D5, 0x68E0, 0x68D8, 0x68D7, - 0x6905, 0x68DF, 0x68F5, 0x68EE, 0x68E7, 0x68F9, 0x68D2, 0x68F2, 0x68E3, 0x68CB, 0x68CD, 0x690D, 0x6912, 0x690E, 0x68C9, 0x68DA, - 0x696E, 0x68FB, 0x6B3E, 0x6B3A, 0x6B3D, 0x6B98, 0x6B96, 0x6BBC, 0x6BEF, 0x6C2E, 0x6C2F, 0x6C2C, 0x6E2F, 0x6E38, 0x6E54, 0x6E21, - 0x6E32, 0x6E67, 0x6E4A, 0x6E20, 0x6E25, 0x6E23, 0x6E1B, 0x6E5B, 0x6E58, 0x6E24, 0x6E56, 0x6E6E, 0x6E2D, 0x6E26, 0x6E6F, 0x6E34, - 0x6E4D, 0x6E3A, 0x6E2C, 0x6E43, 0x6E1D, 0x6E3E, 0x6ECB, - /* Big5-HKSCS 0xB540 .. 0xB57E */ - 0x6E89, 0x6E19, 0x6E4E, 0x6E63, 0x6E44, 0x6E72, 0x6E69, 0x6E5F, 0x7119, 0x711A, 0x7126, 0x7130, 0x7121, 0x7136, 0x716E, 0x711C, - 0x724C, 0x7284, 0x7280, 0x7336, 0x7325, 0x7334, 0x7329, 0x743A, 0x742A, 0x7433, 0x7422, 0x7425, 0x7435, 0x7436, 0x7434, 0x742F, - 0x741B, 0x7426, 0x7428, 0x7525, 0x7526, 0x756B, 0x756A, 0x75E2, 0x75DB, 0x75E3, 0x75D9, 0x75D8, 0x75DE, 0x75E0, 0x767B, 0x767C, - 0x7696, 0x7693, 0x76B4, 0x76DC, 0x774F, 0x77ED, 0x785D, 0x786C, 0x786F, 0x7A0D, 0x7A08, 0x7A0B, 0x7A05, 0x7A00, 0x7A98, - /* Big5-HKSCS 0xB5A1 .. 0xB5FE */ - 0x7A97, 0x7A96, 0x7AE5, 0x7AE3, 0x7B49, 0x7B56, 0x7B46, - 0x7B50, 0x7B52, 0x7B54, 0x7B4D, 0x7B4B, 0x7B4F, 0x7B51, 0x7C9F, 0x7CA5, 0x7D5E, 0x7D50, 0x7D68, 0x7D55, 0x7D2B, 0x7D6E, 0x7D72, - 0x7D61, 0x7D66, 0x7D62, 0x7D70, 0x7D73, 0x5584, 0x7FD4, 0x7FD5, 0x800B, 0x8052, 0x8085, 0x8155, 0x8154, 0x814B, 0x8151, 0x814E, - 0x8139, 0x8146, 0x813E, 0x814C, 0x8153, 0x8174, 0x8212, 0x821C, 0x83E9, 0x8403, 0x83F8, 0x840D, 0x83E0, 0x83C5, 0x840B, 0x83C1, - 0x83EF, 0x83F1, 0x83F4, 0x8457, 0x840A, 0x83F0, 0x840C, 0x83CC, 0x83FD, 0x83F2, 0x83CA, 0x8438, 0x840E, 0x8404, 0x83DC, 0x8407, - 0x83D4, 0x83DF, 0x865B, 0x86DF, 0x86D9, 0x86ED, 0x86D4, 0x86DB, 0x86E4, 0x86D0, 0x86DE, 0x8857, 0x88C1, 0x88C2, 0x88B1, 0x8983, - 0x8996, 0x8A3B, 0x8A60, 0x8A55, 0x8A5E, 0x8A3C, 0x8A41, - /* Big5-HKSCS 0xB640 .. 0xB67E */ - 0x8A54, 0x8A5B, 0x8A50, 0x8A46, 0x8A34, 0x8A3A, 0x8A36, 0x8A56, 0x8C61, 0x8C82, 0x8CAF, 0x8CBC, 0x8CB3, 0x8CBD, 0x8CC1, 0x8CBB, - 0x8CC0, 0x8CB4, 0x8CB7, 0x8CB6, 0x8CBF, 0x8CB8, 0x8D8A, 0x8D85, 0x8D81, 0x8DCE, 0x8DDD, 0x8DCB, 0x8DDA, 0x8DD1, 0x8DCC, 0x8DDB, - 0x8DC6, 0x8EFB, 0x8EF8, 0x8EFC, 0x8F9C, 0x902E, 0x9035, 0x9031, 0x9038, 0x9032, 0x9036, 0x9102, 0x90F5, 0x9109, 0x90FE, 0x9163, - 0x9165, 0x91CF, 0x9214, 0x9215, 0x9223, 0x9209, 0x921E, 0x920D, 0x9210, 0x9207, 0x9211, 0x9594, 0x958F, 0x958B, 0x9591, - /* Big5-HKSCS 0xB6A1 .. 0xB6FE */ - 0x9593, 0x9592, 0x958E, 0x968A, 0x968E, 0x968B, 0x967D, - 0x9685, 0x9686, 0x968D, 0x9672, 0x9684, 0x96C1, 0x96C5, 0x96C4, 0x96C6, 0x96C7, 0x96EF, 0x96F2, 0x97CC, 0x9805, 0x9806, 0x9808, - 0x98E7, 0x98EA, 0x98EF, 0x98E9, 0x98F2, 0x98ED, 0x99AE, 0x99AD, 0x9EC3, 0x9ECD, 0x9ED1, 0x4E82, 0x50AD, 0x50B5, 0x50B2, 0x50B3, - 0x50C5, 0x50BE, 0x50AC, 0x50B7, 0x50BB, 0x50AF, 0x50C7, 0x527F, 0x5277, 0x527D, 0x52DF, 0x52E6, 0x52E4, 0x52E2, 0x52E3, 0x532F, - 0x55DF, 0x55E8, 0x55D3, 0x55E6, 0x55CE, 0x55DC, 0x55C7, 0x55D1, 0x55E3, 0x55E4, 0x55EF, 0x55DA, 0x55E1, 0x55C5, 0x55C6, 0x55E5, - 0x55C9, 0x5712, 0x5713, 0x585E, 0x5851, 0x5858, 0x5857, 0x585A, 0x5854, 0x586B, 0x584C, 0x586D, 0x584A, 0x5862, 0x5852, 0x584B, - 0x5967, 0x5AC1, 0x5AC9, 0x5ACC, 0x5ABE, 0x5ABD, 0x5ABC, - /* Big5-HKSCS 0xB740 .. 0xB77E */ - 0x5AB3, 0x5AC2, 0x5AB2, 0x5D69, 0x5D6F, 0x5E4C, 0x5E79, 0x5EC9, 0x5EC8, 0x5F12, 0x5F59, 0x5FAC, 0x5FAE, 0x611A, 0x610F, 0x6148, - 0x611F, 0x60F3, 0x611B, 0x60F9, 0x6101, 0x6108, 0x614E, 0x614C, 0x6144, 0x614D, 0x613E, 0x6134, 0x6127, 0x610D, 0x6106, 0x6137, - 0x6221, 0x6222, 0x6413, 0x643E, 0x641E, 0x642A, 0x642D, 0x643D, 0x642C, 0x640F, 0x641C, 0x6414, 0x640D, 0x6436, 0x6416, 0x6417, - 0x6406, 0x656C, 0x659F, 0x65B0, 0x6697, 0x6689, 0x6687, 0x6688, 0x6696, 0x6684, 0x6698, 0x668D, 0x6703, 0x6994, 0x696D, - /* Big5-HKSCS 0xB7A1 .. 0xB7FE */ - 0x695A, 0x6977, 0x6960, 0x6954, 0x6975, 0x6930, 0x6982, - 0x694A, 0x6968, 0x696B, 0x695E, 0x6953, 0x6979, 0x6986, 0x695D, 0x6963, 0x695B, 0x6B47, 0x6B72, 0x6BC0, 0x6BBF, 0x6BD3, 0x6BFD, - 0x6EA2, 0x6EAF, 0x6ED3, 0x6EB6, 0x6EC2, 0x6E90, 0x6E9D, 0x6EC7, 0x6EC5, 0x6EA5, 0x6E98, 0x6EBC, 0x6EBA, 0x6EAB, 0x6ED1, 0x6E96, - 0x6E9C, 0x6EC4, 0x6ED4, 0x6EAA, 0x6EA7, 0x6EB4, 0x714E, 0x7159, 0x7169, 0x7164, 0x7149, 0x7167, 0x715C, 0x716C, 0x7166, 0x714C, - 0x7165, 0x715E, 0x7146, 0x7168, 0x7156, 0x723A, 0x7252, 0x7337, 0x7345, 0x733F, 0x733E, 0x746F, 0x745A, 0x7455, 0x745F, 0x745E, - 0x7441, 0x743F, 0x7459, 0x745B, 0x745C, 0x7576, 0x7578, 0x7600, 0x75F0, 0x7601, 0x75F2, 0x75F1, 0x75FA, 0x75FF, 0x75F4, 0x75F3, - 0x76DE, 0x76DF, 0x775B, 0x776B, 0x7766, 0x775E, 0x7763, - /* Big5-HKSCS 0xB840 .. 0xB87E */ - 0x7779, 0x776A, 0x776C, 0x775C, 0x7765, 0x7768, 0x7762, 0x77EE, 0x788E, 0x78B0, 0x7897, 0x7898, 0x788C, 0x7889, 0x787C, 0x7891, - 0x7893, 0x787F, 0x797A, 0x797F, 0x7981, 0x842C, 0x79BD, 0x7A1C, 0x7A1A, 0x7A20, 0x7A14, 0x7A1F, 0x7A1E, 0x7A9F, 0x7AA0, 0x7B77, - 0x7BC0, 0x7B60, 0x7B6E, 0x7B67, 0x7CB1, 0x7CB3, 0x7CB5, 0x7D93, 0x7D79, 0x7D91, 0x7D81, 0x7D8F, 0x7D5B, 0x7F6E, 0x7F69, 0x7F6A, - 0x7F72, 0x7FA9, 0x7FA8, 0x7FA4, 0x8056, 0x8058, 0x8086, 0x8084, 0x8171, 0x8170, 0x8178, 0x8165, 0x816E, 0x8173, 0x816B, - /* Big5-HKSCS 0xB8A1 .. 0xB8FE */ - 0x8179, 0x817A, 0x8166, 0x8205, 0x8247, 0x8482, 0x8477, - 0x843D, 0x8431, 0x8475, 0x8466, 0x846B, 0x8449, 0x846C, 0x845B, 0x843C, 0x8435, 0x8461, 0x8463, 0x8469, 0x846D, 0x8446, 0x865E, - 0x865C, 0x865F, 0x86F9, 0x8713, 0x8708, 0x8707, 0x8700, 0x86FE, 0x86FB, 0x8702, 0x8703, 0x8706, 0x870A, 0x8859, 0x88DF, 0x88D4, - 0x88D9, 0x88DC, 0x88D8, 0x88DD, 0x88E1, 0x88CA, 0x88D5, 0x88D2, 0x899C, 0x89E3, 0x8A6B, 0x8A72, 0x8A73, 0x8A66, 0x8A69, 0x8A70, - 0x8A87, 0x8A7C, 0x8A63, 0x8AA0, 0x8A71, 0x8A85, 0x8A6D, 0x8A62, 0x8A6E, 0x8A6C, 0x8A79, 0x8A7B, 0x8A3E, 0x8A68, 0x8C62, 0x8C8A, - 0x8C89, 0x8CCA, 0x8CC7, 0x8CC8, 0x8CC4, 0x8CB2, 0x8CC3, 0x8CC2, 0x8CC5, 0x8DE1, 0x8DDF, 0x8DE8, 0x8DEF, 0x8DF3, 0x8DFA, 0x8DEA, - 0x8DE4, 0x8DE6, 0x8EB2, 0x8F03, 0x8F09, 0x8EFE, 0x8F0A, - /* Big5-HKSCS 0xB940 .. 0xB97E */ - 0x8F9F, 0x8FB2, 0x904B, 0x904A, 0x9053, 0x9042, 0x9054, 0x903C, 0x9055, 0x9050, 0x9047, 0x904F, 0x904E, 0x904D, 0x9051, 0x903E, - 0x9041, 0x9112, 0x9117, 0x916C, 0x916A, 0x9169, 0x91C9, 0x9237, 0x9257, 0x9238, 0x923D, 0x9240, 0x923E, 0x925B, 0x924B, 0x9264, - 0x9251, 0x9234, 0x9249, 0x924D, 0x9245, 0x9239, 0x923F, 0x925A, 0x9598, 0x9698, 0x9694, 0x9695, 0x96CD, 0x96CB, 0x96C9, 0x96CA, - 0x96F7, 0x96FB, 0x96F9, 0x96F6, 0x9756, 0x9774, 0x9776, 0x9810, 0x9811, 0x9813, 0x980A, 0x9812, 0x980C, 0x98FC, 0x98F4, - /* Big5-HKSCS 0xB9A1 .. 0xB9FE */ - 0x98FD, 0x98FE, 0x99B3, 0x99B1, 0x99B4, 0x9AE1, 0x9CE9, - 0x9E82, 0x9F0E, 0x9F13, 0x9F20, 0x50E7, 0x50EE, 0x50E5, 0x50D6, 0x50ED, 0x50DA, 0x50D5, 0x50CF, 0x50D1, 0x50F1, 0x50CE, 0x50E9, - 0x5162, 0x51F3, 0x5283, 0x5282, 0x5331, 0x53AD, 0x55FE, 0x5600, 0x561B, 0x5617, 0x55FD, 0x5614, 0x5606, 0x5609, 0x560D, 0x560E, - 0x55F7, 0x5616, 0x561F, 0x5608, 0x5610, 0x55F6, 0x5718, 0x5716, 0x5875, 0x587E, 0x5883, 0x5893, 0x588A, 0x5879, 0x5885, 0x587D, - 0x58FD, 0x5925, 0x5922, 0x5924, 0x596A, 0x5969, 0x5AE1, 0x5AE6, 0x5AE9, 0x5AD7, 0x5AD6, 0x5AD8, 0x5AE3, 0x5B75, 0x5BDE, 0x5BE7, - 0x5BE1, 0x5BE5, 0x5BE6, 0x5BE8, 0x5BE2, 0x5BE4, 0x5BDF, 0x5C0D, 0x5C62, 0x5D84, 0x5D87, 0x5E5B, 0x5E63, 0x5E55, 0x5E57, 0x5E54, - 0x5ED3, 0x5ED6, 0x5F0A, 0x5F46, 0x5F70, 0x5FB9, 0x6147, - /* Big5-HKSCS 0xBA40 .. 0xBA7E */ - 0x613F, 0x614B, 0x6177, 0x6162, 0x6163, 0x615F, 0x615A, 0x6158, 0x6175, 0x622A, 0x6487, 0x6458, 0x6454, 0x64A4, 0x6478, 0x645F, - 0x647A, 0x6451, 0x6467, 0x6434, 0x646D, 0x647B, 0x6572, 0x65A1, 0x65D7, 0x65D6, 0x66A2, 0x66A8, 0x669D, 0x699C, 0x69A8, 0x6995, - 0x69C1, 0x69AE, 0x69D3, 0x69CB, 0x699B, 0x69B7, 0x69BB, 0x69AB, 0x69B4, 0x69D0, 0x69CD, 0x69AD, 0x69CC, 0x69A6, 0x69C3, 0x69A3, - 0x6B49, 0x6B4C, 0x6C33, 0x6F33, 0x6F14, 0x6EFE, 0x6F13, 0x6EF4, 0x6F29, 0x6F3E, 0x6F20, 0x6F2C, 0x6F0F, 0x6F02, 0x6F22, - /* Big5-HKSCS 0xBAA1 .. 0xBAFE */ - 0x6EFF, 0x6EEF, 0x6F06, 0x6F31, 0x6F38, 0x6F32, 0x6F23, - 0x6F15, 0x6F2B, 0x6F2F, 0x6F88, 0x6F2A, 0x6EEC, 0x6F01, 0x6EF2, 0x6ECC, 0x6EF7, 0x7194, 0x7199, 0x717D, 0x718A, 0x7184, 0x7192, - 0x723E, 0x7292, 0x7296, 0x7344, 0x7350, 0x7464, 0x7463, 0x746A, 0x7470, 0x746D, 0x7504, 0x7591, 0x7627, 0x760D, 0x760B, 0x7609, - 0x7613, 0x76E1, 0x76E3, 0x7784, 0x777D, 0x777F, 0x7761, 0x78C1, 0x789F, 0x78A7, 0x78B3, 0x78A9, 0x78A3, 0x798E, 0x798F, 0x798D, - 0x7A2E, 0x7A31, 0x7AAA, 0x7AA9, 0x7AED, 0x7AEF, 0x7BA1, 0x7B95, 0x7B8B, 0x7B75, 0x7B97, 0x7B9D, 0x7B94, 0x7B8F, 0x7BB8, 0x7B87, - 0x7B84, 0x7CB9, 0x7CBD, 0x7CBE, 0x7DBB, 0x7DB0, 0x7D9C, 0x7DBD, 0x7DBE, 0x7DA0, 0x7DCA, 0x7DB4, 0x7DB2, 0x7DB1, 0x7DBA, 0x7DA2, - 0x7DBF, 0x7DB5, 0x7DB8, 0x7DAD, 0x7DD2, 0x7DC7, 0x7DAC, - /* Big5-HKSCS 0xBB40 .. 0xBB7E */ - 0x7F70, 0x7FE0, 0x7FE1, 0x7FDF, 0x805E, 0x805A, 0x8087, 0x8150, 0x8180, 0x818F, 0x8188, 0x818A, 0x817F, 0x8182, 0x81E7, 0x81FA, - 0x8207, 0x8214, 0x821E, 0x824B, 0x84C9, 0x84BF, 0x84C6, 0x84C4, 0x8499, 0x849E, 0x84B2, 0x849C, 0x84CB, 0x84B8, 0x84C0, 0x84D3, - 0x8490, 0x84BC, 0x84D1, 0x84CA, 0x873F, 0x871C, 0x873B, 0x8722, 0x8725, 0x8734, 0x8718, 0x8755, 0x8737, 0x8729, 0x88F3, 0x8902, - 0x88F4, 0x88F9, 0x88F8, 0x88FD, 0x88E8, 0x891A, 0x88EF, 0x8AA6, 0x8A8C, 0x8A9E, 0x8AA3, 0x8A8D, 0x8AA1, 0x8A93, 0x8AA4, - /* Big5-HKSCS 0xBBA1 .. 0xBBFE */ - 0x8AAA, 0x8AA5, 0x8AA8, 0x8A98, 0x8A91, 0x8A9A, 0x8AA7, - 0x8C6A, 0x8C8D, 0x8C8C, 0x8CD3, 0x8CD1, 0x8CD2, 0x8D6B, 0x8D99, 0x8D95, 0x8DFC, 0x8F14, 0x8F12, 0x8F15, 0x8F13, 0x8FA3, 0x9060, - 0x9058, 0x905C, 0x9063, 0x9059, 0x905E, 0x9062, 0x905D, 0x905B, 0x9119, 0x9118, 0x911E, 0x9175, 0x9178, 0x9177, 0x9174, 0x9278, - 0x9280, 0x9285, 0x9298, 0x9296, 0x927B, 0x9293, 0x929C, 0x92A8, 0x927C, 0x9291, 0x95A1, 0x95A8, 0x95A9, 0x95A3, 0x95A5, 0x95A4, - 0x9699, 0x969C, 0x969B, 0x96CC, 0x96D2, 0x9700, 0x977C, 0x9785, 0x97F6, 0x9817, 0x9818, 0x98AF, 0x98B1, 0x9903, 0x9905, 0x990C, - 0x9909, 0x99C1, 0x9AAF, 0x9AB0, 0x9AE6, 0x9B41, 0x9B42, 0x9CF4, 0x9CF6, 0x9CF3, 0x9EBC, 0x9F3B, 0x9F4A, 0x5104, 0x5100, 0x50FB, - 0x50F5, 0x50F9, 0x5102, 0x5108, 0x5109, 0x5105, 0x51DC, - /* Big5-HKSCS 0xBC40 .. 0xBC7E */ - 0x5287, 0x5288, 0x5289, 0x528D, 0x528A, 0x52F0, 0x53B2, 0x562E, 0x563B, 0x5639, 0x5632, 0x563F, 0x5634, 0x5629, 0x5653, 0x564E, - 0x5657, 0x5674, 0x5636, 0x562F, 0x5630, 0x5880, 0x589F, 0x589E, 0x58B3, 0x589C, 0x58AE, 0x58A9, 0x58A6, 0x596D, 0x5B09, 0x5AFB, - 0x5B0B, 0x5AF5, 0x5B0C, 0x5B08, 0x5BEE, 0x5BEC, 0x5BE9, 0x5BEB, 0x5C64, 0x5C65, 0x5D9D, 0x5D94, 0x5E62, 0x5E5F, 0x5E61, 0x5EE2, - 0x5EDA, 0x5EDF, 0x5EDD, 0x5EE3, 0x5EE0, 0x5F48, 0x5F71, 0x5FB7, 0x5FB5, 0x6176, 0x6167, 0x616E, 0x615D, 0x6155, 0x6182, - /* Big5-HKSCS 0xBCA1 .. 0xBCFE */ - 0x617C, 0x6170, 0x616B, 0x617E, 0x61A7, 0x6190, 0x61AB, - 0x618E, 0x61AC, 0x619A, 0x61A4, 0x6194, 0x61AE, 0x622E, 0x6469, 0x646F, 0x6479, 0x649E, 0x64B2, 0x6488, 0x6490, 0x64B0, 0x64A5, - 0x6493, 0x6495, 0x64A9, 0x6492, 0x64AE, 0x64AD, 0x64AB, 0x649A, 0x64AC, 0x6499, 0x64A2, 0x64B3, 0x6575, 0x6577, 0x6578, 0x66AE, - 0x66AB, 0x66B4, 0x66B1, 0x6A23, 0x6A1F, 0x69E8, 0x6A01, 0x6A1E, 0x6A19, 0x69FD, 0x6A21, 0x6A13, 0x6A0A, 0x69F3, 0x6A02, 0x6A05, - 0x69ED, 0x6A11, 0x6B50, 0x6B4E, 0x6BA4, 0x6BC5, 0x6BC6, 0x6F3F, 0x6F7C, 0x6F84, 0x6F51, 0x6F66, 0x6F54, 0x6F86, 0x6F6D, 0x6F5B, - 0x6F78, 0x6F6E, 0x6F8E, 0x6F7A, 0x6F70, 0x6F64, 0x6F97, 0x6F58, 0x6ED5, 0x6F6F, 0x6F60, 0x6F5F, 0x719F, 0x71AC, 0x71B1, 0x71A8, - 0x7256, 0x729B, 0x734E, 0x7357, 0x7469, 0x748B, 0x7483, - /* Big5-HKSCS 0xBD40 .. 0xBD7E */ - 0x747E, 0x7480, 0x757F, 0x7620, 0x7629, 0x761F, 0x7624, 0x7626, 0x7621, 0x7622, 0x769A, 0x76BA, 0x76E4, 0x778E, 0x7787, 0x778C, - 0x7791, 0x778B, 0x78CB, 0x78C5, 0x78BA, 0x78CA, 0x78BE, 0x78D5, 0x78BC, 0x78D0, 0x7A3F, 0x7A3C, 0x7A40, 0x7A3D, 0x7A37, 0x7A3B, - 0x7AAF, 0x7AAE, 0x7BAD, 0x7BB1, 0x7BC4, 0x7BB4, 0x7BC6, 0x7BC7, 0x7BC1, 0x7BA0, 0x7BCC, 0x7CCA, 0x7DE0, 0x7DF4, 0x7DEF, 0x7DFB, - 0x7DD8, 0x7DEC, 0x7DDD, 0x7DE8, 0x7DE3, 0x7DDA, 0x7DDE, 0x7DE9, 0x7D9E, 0x7DD9, 0x7DF2, 0x7DF9, 0x7F75, 0x7F77, 0x7FAF, - /* Big5-HKSCS 0xBDA1 .. 0xBDFE */ - 0x7FE9, 0x8026, 0x819B, 0x819C, 0x819D, 0x81A0, 0x819A, - 0x8198, 0x8517, 0x853D, 0x851A, 0x84EE, 0x852C, 0x852D, 0x8513, 0x8511, 0x8523, 0x8521, 0x8514, 0x84EC, 0x8525, 0x84FF, 0x8506, - 0x8782, 0x8774, 0x8776, 0x8760, 0x8766, 0x8778, 0x8768, 0x8759, 0x8757, 0x874C, 0x8753, 0x885B, 0x885D, 0x8910, 0x8907, 0x8912, - 0x8913, 0x8915, 0x890A, 0x8ABC, 0x8AD2, 0x8AC7, 0x8AC4, 0x8A95, 0x8ACB, 0x8AF8, 0x8AB2, 0x8AC9, 0x8AC2, 0x8ABF, 0x8AB0, 0x8AD6, - 0x8ACD, 0x8AB6, 0x8AB9, 0x8ADB, 0x8C4C, 0x8C4E, 0x8C6C, 0x8CE0, 0x8CDE, 0x8CE6, 0x8CE4, 0x8CEC, 0x8CED, 0x8CE2, 0x8CE3, 0x8CDC, - 0x8CEA, 0x8CE1, 0x8D6D, 0x8D9F, 0x8DA3, 0x8E2B, 0x8E10, 0x8E1D, 0x8E22, 0x8E0F, 0x8E29, 0x8E1F, 0x8E21, 0x8E1E, 0x8EBA, 0x8F1D, - 0x8F1B, 0x8F1F, 0x8F29, 0x8F26, 0x8F2A, 0x8F1C, 0x8F1E, - /* Big5-HKSCS 0xBE40 .. 0xBE7E */ - 0x8F25, 0x9069, 0x906E, 0x9068, 0x906D, 0x9077, 0x9130, 0x912D, 0x9127, 0x9131, 0x9187, 0x9189, 0x918B, 0x9183, 0x92C5, 0x92BB, - 0x92B7, 0x92EA, 0x92AC, 0x92E4, 0x92C1, 0x92B3, 0x92BC, 0x92D2, 0x92C7, 0x92F0, 0x92B2, 0x95AD, 0x95B1, 0x9704, 0x9706, 0x9707, - 0x9709, 0x9760, 0x978D, 0x978B, 0x978F, 0x9821, 0x982B, 0x981C, 0x98B3, 0x990A, 0x9913, 0x9912, 0x9918, 0x99DD, 0x99D0, 0x99DF, - 0x99DB, 0x99D1, 0x99D5, 0x99D2, 0x99D9, 0x9AB7, 0x9AEE, 0x9AEF, 0x9B27, 0x9B45, 0x9B44, 0x9B77, 0x9B6F, 0x9D06, 0x9D09, - /* Big5-HKSCS 0xBEA1 .. 0xBEFE */ - 0x9D03, 0x9EA9, 0x9EBE, 0x9ECE, 0x58A8, 0x9F52, 0x5112, - 0x5118, 0x5114, 0x5110, 0x5115, 0x5180, 0x51AA, 0x51DD, 0x5291, 0x5293, 0x52F3, 0x5659, 0x566B, 0x5679, 0x5669, 0x5664, 0x5678, - 0x566A, 0x5668, 0x5665, 0x5671, 0x566F, 0x566C, 0x5662, 0x5676, 0x58C1, 0x58BE, 0x58C7, 0x58C5, 0x596E, 0x5B1D, 0x5B34, 0x5B78, - 0x5BF0, 0x5C0E, 0x5F4A, 0x61B2, 0x6191, 0x61A9, 0x618A, 0x61CD, 0x61B6, 0x61BE, 0x61CA, 0x61C8, 0x6230, 0x64C5, 0x64C1, 0x64CB, - 0x64BB, 0x64BC, 0x64DA, 0x64C4, 0x64C7, 0x64C2, 0x64CD, 0x64BF, 0x64D2, 0x64D4, 0x64BE, 0x6574, 0x66C6, 0x66C9, 0x66B9, 0x66C4, - 0x66C7, 0x66B8, 0x6A3D, 0x6A38, 0x6A3A, 0x6A59, 0x6A6B, 0x6A58, 0x6A39, 0x6A44, 0x6A62, 0x6A61, 0x6A4B, 0x6A47, 0x6A35, 0x6A5F, - 0x6A48, 0x6B59, 0x6B77, 0x6C05, 0x6FC2, 0x6FB1, 0x6FA1, - /* Big5-HKSCS 0xBF40 .. 0xBF7E */ - 0x6FC3, 0x6FA4, 0x6FC1, 0x6FA7, 0x6FB3, 0x6FC0, 0x6FB9, 0x6FB6, 0x6FA6, 0x6FA0, 0x6FB4, 0x71BE, 0x71C9, 0x71D0, 0x71D2, 0x71C8, - 0x71D5, 0x71B9, 0x71CE, 0x71D9, 0x71DC, 0x71C3, 0x71C4, 0x7368, 0x749C, 0x74A3, 0x7498, 0x749F, 0x749E, 0x74E2, 0x750C, 0x750D, - 0x7634, 0x7638, 0x763A, 0x76E7, 0x76E5, 0x77A0, 0x779E, 0x779F, 0x77A5, 0x78E8, 0x78DA, 0x78EC, 0x78E7, 0x79A6, 0x7A4D, 0x7A4E, - 0x7A46, 0x7A4C, 0x7A4B, 0x7ABA, 0x7BD9, 0x7C11, 0x7BC9, 0x7BE4, 0x7BDB, 0x7BE1, 0x7BE9, 0x7BE6, 0x7CD5, 0x7CD6, 0x7E0A, - /* Big5-HKSCS 0xBFA1 .. 0xBFFE */ - 0x7E11, 0x7E08, 0x7E1B, 0x7E23, 0x7E1E, 0x7E1D, 0x7E09, - 0x7E10, 0x7F79, 0x7FB2, 0x7FF0, 0x7FF1, 0x7FEE, 0x8028, 0x81B3, 0x81A9, 0x81A8, 0x81FB, 0x8208, 0x8258, 0x8259, 0x854A, 0x8559, - 0x8548, 0x8568, 0x8569, 0x8543, 0x8549, 0x856D, 0x856A, 0x855E, 0x8783, 0x879F, 0x879E, 0x87A2, 0x878D, 0x8861, 0x892A, 0x8932, - 0x8925, 0x892B, 0x8921, 0x89AA, 0x89A6, 0x8AE6, 0x8AFA, 0x8AEB, 0x8AF1, 0x8B00, 0x8ADC, 0x8AE7, 0x8AEE, 0x8AFE, 0x8B01, 0x8B02, - 0x8AF7, 0x8AED, 0x8AF3, 0x8AF6, 0x8AFC, 0x8C6B, 0x8C6D, 0x8C93, 0x8CF4, 0x8E44, 0x8E31, 0x8E34, 0x8E42, 0x8E39, 0x8E35, 0x8F3B, - 0x8F2F, 0x8F38, 0x8F33, 0x8FA8, 0x8FA6, 0x9075, 0x9074, 0x9078, 0x9072, 0x907C, 0x907A, 0x9134, 0x9192, 0x9320, 0x9336, 0x92F8, - 0x9333, 0x932F, 0x9322, 0x92FC, 0x932B, 0x9304, 0x931A, - /* Big5-HKSCS 0xC040 .. 0xC07E */ - 0x9310, 0x9326, 0x9321, 0x9315, 0x932E, 0x9319, 0x95BB, 0x96A7, 0x96A8, 0x96AA, 0x96D5, 0x970E, 0x9711, 0x9716, 0x970D, 0x9713, - 0x970F, 0x975B, 0x975C, 0x9766, 0x9798, 0x9830, 0x9838, 0x983B, 0x9837, 0x982D, 0x9839, 0x9824, 0x9910, 0x9928, 0x991E, 0x991B, - 0x9921, 0x991A, 0x99ED, 0x99E2, 0x99F1, 0x9AB8, 0x9ABC, 0x9AFB, 0x9AED, 0x9B28, 0x9B91, 0x9D15, 0x9D23, 0x9D26, 0x9D28, 0x9D12, - 0x9D1B, 0x9ED8, 0x9ED4, 0x9F8D, 0x9F9C, 0x512A, 0x511F, 0x5121, 0x5132, 0x52F5, 0x568E, 0x5680, 0x5690, 0x5685, 0x5687, - /* Big5-HKSCS 0xC0A1 .. 0xC0FE */ - 0x568F, 0x58D5, 0x58D3, 0x58D1, 0x58CE, 0x5B30, 0x5B2A, - 0x5B24, 0x5B7A, 0x5C37, 0x5C68, 0x5DBC, 0x5DBA, 0x5DBD, 0x5DB8, 0x5E6B, 0x5F4C, 0x5FBD, 0x61C9, 0x61C2, 0x61C7, 0x61E6, 0x61CB, - 0x6232, 0x6234, 0x64CE, 0x64CA, 0x64D8, 0x64E0, 0x64F0, 0x64E6, 0x64EC, 0x64F1, 0x64E2, 0x64ED, 0x6582, 0x6583, 0x66D9, 0x66D6, - 0x6A80, 0x6A94, 0x6A84, 0x6AA2, 0x6A9C, 0x6ADB, 0x6AA3, 0x6A7E, 0x6A97, 0x6A90, 0x6AA0, 0x6B5C, 0x6BAE, 0x6BDA, 0x6C08, 0x6FD8, - 0x6FF1, 0x6FDF, 0x6FE0, 0x6FDB, 0x6FE4, 0x6FEB, 0x6FEF, 0x6F80, 0x6FEC, 0x6FE1, 0x6FE9, 0x6FD5, 0x6FEE, 0x6FF0, 0x71E7, 0x71DF, - 0x71EE, 0x71E6, 0x71E5, 0x71ED, 0x71EC, 0x71F4, 0x71E0, 0x7235, 0x7246, 0x7370, 0x7372, 0x74A9, 0x74B0, 0x74A6, 0x74A8, 0x7646, - 0x7642, 0x764C, 0x76EA, 0x77B3, 0x77AA, 0x77B0, 0x77AC, - /* Big5-HKSCS 0xC140 .. 0xC17E */ - 0x77A7, 0x77AD, 0x77EF, 0x78F7, 0x78FA, 0x78F4, 0x78EF, 0x7901, 0x79A7, 0x79AA, 0x7A57, 0x7ABF, 0x7C07, 0x7C0D, 0x7BFE, 0x7BF7, - 0x7C0C, 0x7BE0, 0x7CE0, 0x7CDC, 0x7CDE, 0x7CE2, 0x7CDF, 0x7CD9, 0x7CDD, 0x7E2E, 0x7E3E, 0x7E46, 0x7E37, 0x7E32, 0x7E43, 0x7E2B, - 0x7E3D, 0x7E31, 0x7E45, 0x7E41, 0x7E34, 0x7E39, 0x7E48, 0x7E35, 0x7E3F, 0x7E2F, 0x7F44, 0x7FF3, 0x7FFC, 0x8071, 0x8072, 0x8070, - 0x806F, 0x8073, 0x81C6, 0x81C3, 0x81BA, 0x81C2, 0x81C0, 0x81BF, 0x81BD, 0x81C9, 0x81BE, 0x81E8, 0x8209, 0x8271, 0x85AA, - /* Big5-HKSCS 0xC1A1 .. 0xC1FE */ - 0x8584, 0x857E, 0x859C, 0x8591, 0x8594, 0x85AF, 0x859B, - 0x8587, 0x85A8, 0x858A, 0x8667, 0x87C0, 0x87D1, 0x87B3, 0x87D2, 0x87C6, 0x87AB, 0x87BB, 0x87BA, 0x87C8, 0x87CB, 0x893B, 0x8936, - 0x8944, 0x8938, 0x893D, 0x89AC, 0x8B0E, 0x8B17, 0x8B19, 0x8B1B, 0x8B0A, 0x8B20, 0x8B1D, 0x8B04, 0x8B10, 0x8C41, 0x8C3F, 0x8C73, - 0x8CFA, 0x8CFD, 0x8CFC, 0x8CF8, 0x8CFB, 0x8DA8, 0x8E49, 0x8E4B, 0x8E48, 0x8E4A, 0x8F44, 0x8F3E, 0x8F42, 0x8F45, 0x8F3F, 0x907F, - 0x907D, 0x9084, 0x9081, 0x9082, 0x9080, 0x9139, 0x91A3, 0x919E, 0x919C, 0x934D, 0x9382, 0x9328, 0x9375, 0x934A, 0x9365, 0x934B, - 0x9318, 0x937E, 0x936C, 0x935B, 0x9370, 0x935A, 0x9354, 0x95CA, 0x95CB, 0x95CC, 0x95C8, 0x95C6, 0x96B1, 0x96B8, 0x96D6, 0x971C, - 0x971E, 0x97A0, 0x97D3, 0x9846, 0x98B6, 0x9935, 0x9A01, - /* Big5-HKSCS 0xC240 .. 0xC27E */ - 0x99FF, 0x9BAE, 0x9BAB, 0x9BAA, 0x9BAD, 0x9D3B, 0x9D3F, 0x9E8B, 0x9ECF, 0x9EDE, 0x9EDC, 0x9EDD, 0x9EDB, 0x9F3E, 0x9F4B, 0x53E2, - 0x5695, 0x56AE, 0x58D9, 0x58D8, 0x5B38, 0x5F5D, 0x61E3, 0x6233, 0x64F4, 0x64F2, 0x64FE, 0x6506, 0x64FA, 0x64FB, 0x64F7, 0x65B7, - 0x66DC, 0x6726, 0x6AB3, 0x6AAC, 0x6AC3, 0x6ABB, 0x6AB8, 0x6AC2, 0x6AAE, 0x6AAF, 0x6B5F, 0x6B78, 0x6BAF, 0x7009, 0x700B, 0x6FFE, - 0x7006, 0x6FFA, 0x7011, 0x700F, 0x71FB, 0x71FC, 0x71FE, 0x71F8, 0x7377, 0x7375, 0x74A7, 0x74BF, 0x7515, 0x7656, 0x7658, - /* Big5-HKSCS 0xC2A1 .. 0xC2FE */ - 0x7652, 0x77BD, 0x77BF, 0x77BB, 0x77BC, 0x790E, 0x79AE, - 0x7A61, 0x7A62, 0x7A60, 0x7AC4, 0x7AC5, 0x7C2B, 0x7C27, 0x7C2A, 0x7C1E, 0x7C23, 0x7C21, 0x7CE7, 0x7E54, 0x7E55, 0x7E5E, 0x7E5A, - 0x7E61, 0x7E52, 0x7E59, 0x7F48, 0x7FF9, 0x7FFB, 0x8077, 0x8076, 0x81CD, 0x81CF, 0x820A, 0x85CF, 0x85A9, 0x85CD, 0x85D0, 0x85C9, - 0x85B0, 0x85BA, 0x85B9, 0x85A6, 0x87EF, 0x87EC, 0x87F2, 0x87E0, 0x8986, 0x89B2, 0x89F4, 0x8B28, 0x8B39, 0x8B2C, 0x8B2B, 0x8C50, - 0x8D05, 0x8E59, 0x8E63, 0x8E66, 0x8E64, 0x8E5F, 0x8E55, 0x8EC0, 0x8F49, 0x8F4D, 0x9087, 0x9083, 0x9088, 0x91AB, 0x91AC, 0x91D0, - 0x9394, 0x938A, 0x9396, 0x93A2, 0x93B3, 0x93AE, 0x93AC, 0x93B0, 0x9398, 0x939A, 0x9397, 0x95D4, 0x95D6, 0x95D0, 0x95D5, 0x96E2, - 0x96DC, 0x96D9, 0x96DB, 0x96DE, 0x9724, 0x97A3, 0x97A6, - /* Big5-HKSCS 0xC340 .. 0xC37E */ - 0x97AD, 0x97F9, 0x984D, 0x984F, 0x984C, 0x984E, 0x9853, 0x98BA, 0x993E, 0x993F, 0x993D, 0x992E, 0x99A5, 0x9A0E, 0x9AC1, 0x9B03, - 0x9B06, 0x9B4F, 0x9B4E, 0x9B4D, 0x9BCA, 0x9BC9, 0x9BFD, 0x9BC8, 0x9BC0, 0x9D51, 0x9D5D, 0x9D60, 0x9EE0, 0x9F15, 0x9F2C, 0x5133, - 0x56A5, 0x58DE, 0x58DF, 0x58E2, 0x5BF5, 0x9F90, 0x5EEC, 0x61F2, 0x61F7, 0x61F6, 0x61F5, 0x6500, 0x650F, 0x66E0, 0x66DD, 0x6AE5, - 0x6ADD, 0x6ADA, 0x6AD3, 0x701B, 0x701F, 0x7028, 0x701A, 0x701D, 0x7015, 0x7018, 0x7206, 0x720D, 0x7258, 0x72A2, 0x7378, - /* Big5-HKSCS 0xC3A1 .. 0xC3FE */ - 0x737A, 0x74BD, 0x74CA, 0x74E3, 0x7587, 0x7586, 0x765F, - 0x7661, 0x77C7, 0x7919, 0x79B1, 0x7A6B, 0x7A69, 0x7C3E, 0x7C3F, 0x7C38, 0x7C3D, 0x7C37, 0x7C40, 0x7E6B, 0x7E6D, 0x7E79, 0x7E69, - 0x7E6A, 0x7F85, 0x7E73, 0x7FB6, 0x7FB9, 0x7FB8, 0x81D8, 0x85E9, 0x85DD, 0x85EA, 0x85D5, 0x85E4, 0x85E5, 0x85F7, 0x87FB, 0x8805, - 0x880D, 0x87F9, 0x87FE, 0x8960, 0x895F, 0x8956, 0x895E, 0x8B41, 0x8B5C, 0x8B58, 0x8B49, 0x8B5A, 0x8B4E, 0x8B4F, 0x8B46, 0x8B59, - 0x8D08, 0x8D0A, 0x8E7C, 0x8E72, 0x8E87, 0x8E76, 0x8E6C, 0x8E7A, 0x8E74, 0x8F54, 0x8F4E, 0x8FAD, 0x908A, 0x908B, 0x91B1, 0x91AE, - 0x93E1, 0x93D1, 0x93DF, 0x93C3, 0x93C8, 0x93DC, 0x93DD, 0x93D6, 0x93E2, 0x93CD, 0x93D8, 0x93E4, 0x93D7, 0x93E8, 0x95DC, 0x96B4, - 0x96E3, 0x972A, 0x9727, 0x9761, 0x97DC, 0x97FB, 0x985E, - /* Big5-HKSCS 0xC440 .. 0xC47E */ - 0x9858, 0x985B, 0x98BC, 0x9945, 0x9949, 0x9A16, 0x9A19, 0x9B0D, 0x9BE8, 0x9BE7, 0x9BD6, 0x9BDB, 0x9D89, 0x9D61, 0x9D72, 0x9D6A, - 0x9D6C, 0x9E92, 0x9E97, 0x9E93, 0x9EB4, 0x52F8, 0x56A8, 0x56B7, 0x56B6, 0x56B4, 0x56BC, 0x58E4, 0x5B40, 0x5B43, 0x5B7D, 0x5BF6, - 0x5DC9, 0x61F8, 0x61FA, 0x6518, 0x6514, 0x6519, 0x66E6, 0x6727, 0x6AEC, 0x703E, 0x7030, 0x7032, 0x7210, 0x737B, 0x74CF, 0x7662, - 0x7665, 0x7926, 0x792A, 0x792C, 0x792B, 0x7AC7, 0x7AF6, 0x7C4C, 0x7C43, 0x7C4D, 0x7CEF, 0x7CF0, 0x8FAE, 0x7E7D, 0x7E7C, - /* Big5-HKSCS 0xC4A1 .. 0xC4FE */ - 0x7E82, 0x7F4C, 0x8000, 0x81DA, 0x8266, 0x85FB, 0x85F9, - 0x8611, 0x85FA, 0x8606, 0x860B, 0x8607, 0x860A, 0x8814, 0x8815, 0x8964, 0x89BA, 0x89F8, 0x8B70, 0x8B6C, 0x8B66, 0x8B6F, 0x8B5F, - 0x8B6B, 0x8D0F, 0x8D0D, 0x8E89, 0x8E81, 0x8E85, 0x8E82, 0x91B4, 0x91CB, 0x9418, 0x9403, 0x93FD, 0x95E1, 0x9730, 0x98C4, 0x9952, - 0x9951, 0x99A8, 0x9A2B, 0x9A30, 0x9A37, 0x9A35, 0x9C13, 0x9C0D, 0x9E79, 0x9EB5, 0x9EE8, 0x9F2F, 0x9F5F, 0x9F63, 0x9F61, 0x5137, - 0x5138, 0x56C1, 0x56C0, 0x56C2, 0x5914, 0x5C6C, 0x5DCD, 0x61FC, 0x61FE, 0x651D, 0x651C, 0x6595, 0x66E9, 0x6AFB, 0x6B04, 0x6AFA, - 0x6BB2, 0x704C, 0x721B, 0x72A7, 0x74D6, 0x74D4, 0x7669, 0x77D3, 0x7C50, 0x7E8F, 0x7E8C, 0x7FBC, 0x8617, 0x862D, 0x861A, 0x8823, - 0x8822, 0x8821, 0x881F, 0x896A, 0x896C, 0x89BD, 0x8B74, - /* Big5-HKSCS 0xC540 .. 0xC57E */ - 0x8B77, 0x8B7D, 0x8D13, 0x8E8A, 0x8E8D, 0x8E8B, 0x8F5F, 0x8FAF, 0x91BA, 0x942E, 0x9433, 0x9435, 0x943A, 0x9438, 0x9432, 0x942B, - 0x95E2, 0x9738, 0x9739, 0x9732, 0x97FF, 0x9867, 0x9865, 0x9957, 0x9A45, 0x9A43, 0x9A40, 0x9A3E, 0x9ACF, 0x9B54, 0x9B51, 0x9C2D, - 0x9C25, 0x9DAF, 0x9DB4, 0x9DC2, 0x9DB8, 0x9E9D, 0x9EEF, 0x9F19, 0x9F5C, 0x9F66, 0x9F67, 0x513C, 0x513B, 0x56C8, 0x56CA, 0x56C9, - 0x5B7F, 0x5DD4, 0x5DD2, 0x5F4E, 0x61FF, 0x6524, 0x6B0A, 0x6B61, 0x7051, 0x7058, 0x7380, 0x74E4, 0x758A, 0x766E, 0x766C, - /* Big5-HKSCS 0xC5A1 .. 0xC5FE */ - 0x79B3, 0x7C60, 0x7C5F, 0x807E, 0x807D, 0x81DF, 0x8972, - 0x896F, 0x89FC, 0x8B80, 0x8D16, 0x8D17, 0x8E91, 0x8E93, 0x8F61, 0x9148, 0x9444, 0x9451, 0x9452, 0x973D, 0x973E, 0x97C3, 0x97C1, - 0x986B, 0x9955, 0x9A55, 0x9A4D, 0x9AD2, 0x9B1A, 0x9C49, 0x9C31, 0x9C3E, 0x9C3B, 0x9DD3, 0x9DD7, 0x9F34, 0x9F6C, 0x9F6A, 0x9F94, - 0x56CC, 0x5DD6, 0x6200, 0x6523, 0x652B, 0x652A, 0x66EC, 0x6B10, 0x74DA, 0x7ACA, 0x7C64, 0x7C63, 0x7C65, 0x7E93, 0x7E96, 0x7E94, - 0x81E2, 0x8638, 0x863F, 0x8831, 0x8B8A, 0x9090, 0x908F, 0x9463, 0x9460, 0x9464, 0x9768, 0x986F, 0x995C, 0x9A5A, 0x9A5B, 0x9A57, - 0x9AD3, 0x9AD4, 0x9AD1, 0x9C54, 0x9C57, 0x9C56, 0x9DE5, 0x9E9F, 0x9EF4, 0x56D1, 0x58E9, 0x652C, 0x705E, 0x7671, 0x7672, 0x77D7, - 0x7F50, 0x7F88, 0x8836, 0x8839, 0x8862, 0x8B93, 0x8B92, - /* Big5-HKSCS 0xC640 .. 0xC67E */ - 0x8B96, 0x8277, 0x8D1B, 0x91C0, 0x946A, 0x9742, 0x9748, 0x9744, 0x97C6, 0x9870, 0x9A5F, 0x9B22, 0x9B58, 0x9C5F, 0x9DF9, 0x9DFA, - 0x9E7C, 0x9E7D, 0x9F07, 0x9F77, 0x9F72, 0x5EF3, 0x6B16, 0x7063, 0x7C6C, 0x7C6E, 0x883B, 0x89C0, 0x8EA1, 0x91C1, 0x9472, 0x9470, - 0x9871, 0x995E, 0x9AD6, 0x9B23, 0x9ECC, 0x7064, 0x77DA, 0x8B9A, 0x9477, 0x97C9, 0x9A62, 0x9A65, 0x7E9C, 0x8B9C, 0x8EAA, 0x91C5, - 0x947D, 0x947E, 0x947C, 0x9C77, 0x9C78, 0x9EF7, 0x8C54, 0x947F, 0x9E1A, 0x7228, 0x9A6A, 0x9B31, 0x9E1B, 0x9E1E, 0x7C72, - /* Big5-HKSCS 0xC6A1 .. 0xC6FE */ - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, - 0x2467, 0x2468, 0x2469, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C, 0x247D, 0x2170, 0x2171, 0x2172, - 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x4E36, 0x4E3F, 0x4E85, 0x4EA0, 0x5182, 0x5196, 0x51AB, 0x52F9, 0x5338, - 0x5369, 0x53B6, 0x590A, 0x5B80, 0x5DDB, 0x2F33, 0x5E7F, 0xF6DF, 0x5F50, 0x5F61, 0x6534, 0xF6E3, 0x7592, 0xF6E5, 0x8FB5, 0xF6E7, - 0x00A8, 0x02C6, 0x30FD, 0x30FE, 0x309D, 0x309E, 0xF6EE, 0xF6EF, 0x3005, 0x3006, 0x3007, 0x30FC, 0xFF3B, 0xFF3D, 0x273D, 0x3041, - 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050, 0x3051, - 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, - /* Big5-HKSCS 0xC740 .. 0xC77E */ - 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, - 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, - 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, - 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, 0x3091, 0x3092, 0x3093, 0x30A1, 0x30A2, 0x30A3, 0x30A4, - /* Big5-HKSCS 0xC7A1 .. 0xC7FE */ - 0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB, - 0x30AC, 0x30AD, 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB, - 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, - 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB, - 0x30DC, 0x30DD, 0x30DE, 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, 0x30EA, 0x30EB, - 0x30EC, 0x30ED, 0x30EE, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, - 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, - /* Big5-HKSCS 0xC840 .. 0xC87E */ - 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, - 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, - 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, - 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x21E7, 0x21B8, 0x21B9, 0xF7E5, 0xF7E6, 0x4E5A, 0xF7E8, 0x5202, 0xF7EA, - /* Big5-HKSCS 0xC8A1 .. 0xC8FE */ - 0xF7EB, 0x5188, 0xF7ED, 0xF7EE, 0xF7EF, 0xF7F0, 0xF7F1, - 0xF7F2, 0xF7F3, 0xF7F4, 0xF7F5, 0xF7F6, 0xF7F7, 0xF7F8, 0xF7F9, 0xF7FA, 0xF7FB, 0xF7FC, 0xF7FD, 0xF7FE, 0xF7FF, 0xF800, 0xF801, - 0xF802, 0xF803, 0xF804, 0xF805, 0xF806, 0xF807, 0xF808, 0xF809, 0xF80A, 0xF80B, 0xF80C, 0xF80D, 0xF80E, 0xF80F, 0xF810, 0xF811, - 0xF812, 0xF813, 0xF814, 0xF815, 0xF816, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02, 0x3231, 0x2116, 0x2121, 0x309B, 0x309C, 0x2E80, 0x2E84, - 0x2E86, 0x2E87, 0x2E88, 0x2E8A, 0x2E8C, 0x2E8D, 0x2E95, 0x2E9C, 0x2E9D, 0x2EA5, 0x2EA7, 0x2EAA, 0x2EAC, 0x2EAE, 0x2EB6, 0x2EBC, - 0x2EBE, 0x2EC6, 0x2ECA, 0x2ECC, 0x2ECD, 0x2ECF, 0x2ED6, 0x2ED7, 0x2EDE, 0x2EE3, 0xF83C, 0xF83D, 0xF83E, 0x0283, 0x0250, 0x025B, - 0x0254, 0x0275, 0x0153, 0x00F8, 0x014B, 0x028A, 0x026A, - /* Big5-HKSCS 0xC940 .. 0xC97E */ - 0x4E42, 0x4E5C, 0x51F5, 0x531A, 0x5382, 0x4E07, 0x4E0C, 0x4E47, 0x4E8D, 0x56D7, 0xFA0C, 0x5C6E, 0x5F73, 0x4E0F, 0x5187, 0x4E0E, - 0x4E2E, 0x4E93, 0x4EC2, 0x4EC9, 0x4EC8, 0x5198, 0x52FC, 0x536C, 0x53B9, 0x5720, 0x5903, 0x592C, 0x5C10, 0x5DFF, 0x65E1, 0x6BB3, - 0x6BCC, 0x6C14, 0x723F, 0x4E31, 0x4E3C, 0x4EE8, 0x4EDC, 0x4EE9, 0x4EE1, 0x4EDD, 0x4EDA, 0x520C, 0x531C, 0x534C, 0x5722, 0x5723, - 0x5917, 0x592F, 0x5B81, 0x5B84, 0x5C12, 0x5C3B, 0x5C74, 0x5C73, 0x5E04, 0x5E80, 0x5E82, 0x5FC9, 0x6209, 0x6250, 0x6C15, - /* Big5-HKSCS 0xC9A1 .. 0xC9FE */ - 0x6C36, 0x6C43, 0x6C3F, 0x6C3B, 0x72AE, 0x72B0, 0x738A, - 0x79B8, 0x808A, 0x961E, 0x4F0E, 0x4F18, 0x4F2C, 0x4EF5, 0x4F14, 0x4EF1, 0x4F00, 0x4EF7, 0x4F08, 0x4F1D, 0x4F02, 0x4F05, 0x4F22, - 0x4F13, 0x4F04, 0x4EF4, 0x4F12, 0x51B1, 0x5213, 0x5209, 0x5210, 0x52A6, 0x5322, 0x531F, 0x534D, 0x538A, 0x5407, 0x56E1, 0x56DF, - 0x572E, 0x572A, 0x5734, 0x593C, 0x5980, 0x597C, 0x5985, 0x597B, 0x597E, 0x5977, 0x597F, 0x5B56, 0x5C15, 0x5C25, 0x5C7C, 0x5C7A, - 0x5C7B, 0x5C7E, 0x5DDF, 0x5E75, 0x5E84, 0x5F02, 0x5F1A, 0x5F74, 0x5FD5, 0x5FD4, 0x5FCF, 0x625C, 0x625E, 0x6264, 0x6261, 0x6266, - 0x6262, 0x6259, 0x6260, 0x625A, 0x6265, 0x65EF, 0x65EE, 0x673E, 0x6739, 0x6738, 0x673B, 0x673A, 0x673F, 0x673C, 0x6733, 0x6C18, - 0x6C46, 0x6C52, 0x6C5C, 0x6C4F, 0x6C4A, 0x6C54, 0x6C4B, - /* Big5-HKSCS 0xCA40 .. 0xCA7E */ - 0x6C4C, 0x7071, 0x725E, 0x72B4, 0x72B5, 0x738E, 0x752A, 0x767F, 0x7A75, 0x7F51, 0x8278, 0x827C, 0x8280, 0x827D, 0x827F, 0x864D, - 0x897E, 0x9099, 0x9097, 0x9098, 0x909B, 0x9094, 0x9622, 0x9624, 0x9620, 0x9623, 0x4F56, 0x4F3B, 0x4F62, 0x4F49, 0x4F53, 0x4F64, - 0x4F3E, 0x4F67, 0x4F52, 0x4F5F, 0x4F41, 0x4F58, 0x4F2D, 0x4F33, 0x4F3F, 0x4F61, 0x518F, 0x51B9, 0x521C, 0x521E, 0x5221, 0x52AD, - 0x52AE, 0x5309, 0x5363, 0x5372, 0x538E, 0x538F, 0x5430, 0x5437, 0x542A, 0x5454, 0x5445, 0x5419, 0x541C, 0x5425, 0x5418, - /* Big5-HKSCS 0xCAA1 .. 0xCAFE */ - 0x543D, 0x544F, 0x5441, 0x5428, 0x5424, 0x5447, 0x56EE, - 0x56E7, 0x56E5, 0x5741, 0x5745, 0x574C, 0x5749, 0x574B, 0x5752, 0x5906, 0x5940, 0x59A6, 0x5998, 0x59A0, 0x5997, 0x598E, 0x59A2, - 0x5990, 0x598F, 0x59A7, 0x59A1, 0x5B8E, 0x5B92, 0x5C28, 0x5C2A, 0x5C8D, 0x5C8F, 0x5C88, 0x5C8B, 0x5C89, 0x5C92, 0x5C8A, 0x5C86, - 0x5C93, 0x5C95, 0x5DE0, 0x5E0A, 0x5E0E, 0x5E8B, 0x5E89, 0x5E8C, 0x5E88, 0x5E8D, 0x5F05, 0x5F1D, 0x5F78, 0x5F76, 0x5FD2, 0x5FD1, - 0x5FD0, 0x5FED, 0x5FE8, 0x5FEE, 0x5FF3, 0x5FE1, 0x5FE4, 0x5FE3, 0x5FFA, 0x5FEF, 0x5FF7, 0x5FFB, 0x6000, 0x5FF4, 0x623A, 0x6283, - 0x628C, 0x628E, 0x628F, 0x6294, 0x6287, 0x6271, 0x627B, 0x627A, 0x6270, 0x6281, 0x6288, 0x6277, 0x627D, 0x6272, 0x6274, 0x6537, - 0x65F0, 0x65F4, 0x65F3, 0x65F2, 0x65F5, 0x6745, 0x6747, - /* Big5-HKSCS 0xCB40 .. 0xCB7E */ - 0x6759, 0x6755, 0x674C, 0x6748, 0x675D, 0x674D, 0x675A, 0x674B, 0x6BD0, 0x6C19, 0x6C1A, 0x6C78, 0x6C67, 0x6C6B, 0x6C84, 0x6C8B, - 0x6C8F, 0x6C71, 0x6C6F, 0x6C69, 0x6C9A, 0x6C6D, 0x6C87, 0x6C95, 0x6C9C, 0x6C66, 0x6C73, 0x6C65, 0x6C7B, 0x6C8E, 0x7074, 0x707A, - 0x7263, 0x72BF, 0x72BD, 0x72C3, 0x72C6, 0x72C1, 0x72BA, 0x72C5, 0x7395, 0x7397, 0x7393, 0x7394, 0x7392, 0x753A, 0x7539, 0x7594, - 0x7595, 0x7681, 0x793D, 0x8034, 0x8095, 0x8099, 0x8090, 0x8092, 0x809C, 0x8290, 0x828F, 0x8285, 0x828E, 0x8291, 0x8293, - /* Big5-HKSCS 0xCBA1 .. 0xCBFE */ - 0x828A, 0x8283, 0x8284, 0x8C78, 0x8FC9, 0x8FBF, 0x909F, - 0x90A1, 0x90A5, 0x909E, 0x90A7, 0x90A0, 0x9630, 0x9628, 0x962F, 0x962D, 0x4E33, 0x4F98, 0x4F7C, 0x4F85, 0x4F7D, 0x4F80, 0x4F87, - 0x4F76, 0x4F74, 0x4F89, 0x4F84, 0x4F77, 0x4F4C, 0x4F97, 0x4F6A, 0x4F9A, 0x4F79, 0x4F81, 0x4F78, 0x4F90, 0x4F9C, 0x4F94, 0x4F9E, - 0x4F92, 0x4F82, 0x4F95, 0x4F6B, 0x4F6E, 0x519E, 0x51BC, 0x51BE, 0x5235, 0x5232, 0x5233, 0x5246, 0x5231, 0x52BC, 0x530A, 0x530B, - 0x533C, 0x5392, 0x5394, 0x5487, 0x547F, 0x5481, 0x5491, 0x5482, 0x5488, 0x546B, 0x547A, 0x547E, 0x5465, 0x546C, 0x5474, 0x5466, - 0x548D, 0x546F, 0x5461, 0x5460, 0x5498, 0x5463, 0x5467, 0x5464, 0x56F7, 0x56F9, 0x576F, 0x5772, 0x576D, 0x576B, 0x5771, 0x5770, - 0x5776, 0x5780, 0x5775, 0x577B, 0x5773, 0x5774, 0x5762, - /* Big5-HKSCS 0xCC40 .. 0xCC7E */ - 0x5768, 0x577D, 0x590C, 0x5945, 0x59B5, 0x59BA, 0x59CF, 0x59CE, 0x59B2, 0x59CC, 0x59C1, 0x59B6, 0x59BC, 0x59C3, 0x59D6, 0x59B1, - 0x59BD, 0x59C0, 0x59C8, 0x59B4, 0x59C7, 0x5B62, 0x5B65, 0x5B93, 0x5B95, 0x5C44, 0x5C47, 0x5CAE, 0x5CA4, 0x5CA0, 0x5CB5, 0x5CAF, - 0x5CA8, 0x5CAC, 0x5C9F, 0x5CA3, 0x5CAD, 0x5CA2, 0x5CAA, 0x5CA7, 0x5C9D, 0x5CA5, 0x5CB6, 0x5CB0, 0x5CA6, 0x5E17, 0x5E14, 0x5E19, - 0x5F28, 0x5F22, 0x5F23, 0x5F24, 0x5F54, 0x5F82, 0x5F7E, 0x5F7D, 0x5FDE, 0x5FE5, 0x602D, 0x6026, 0x6019, 0x6032, 0x600B, - /* Big5-HKSCS 0xCCA1 .. 0xCCFE */ - 0x6034, 0x600A, 0x6017, 0x6033, 0x601A, 0x601E, 0x602C, - 0x6022, 0x600D, 0x6010, 0x602E, 0x6013, 0x6011, 0x600C, 0x6009, 0x601C, 0x6214, 0x623D, 0x62AD, 0x62B4, 0x62D1, 0x62BE, 0x62AA, - 0x62B6, 0x62CA, 0x62AE, 0x62B3, 0x62AF, 0x62BB, 0x62A9, 0x62B0, 0x62B8, 0x653D, 0x65A8, 0x65BB, 0x6609, 0x65FC, 0x6604, 0x6612, - 0x6608, 0x65FB, 0x6603, 0x660B, 0x660D, 0x6605, 0x65FD, 0x6611, 0x6610, 0x66F6, 0x670A, 0x6785, 0x676C, 0x678E, 0x6792, 0x6776, - 0x677B, 0x6798, 0x6786, 0x6784, 0x6774, 0x678D, 0x678C, 0x677A, 0x679F, 0x6791, 0x6799, 0x6783, 0x677D, 0x6781, 0x6778, 0x6779, - 0x6794, 0x6B25, 0x6B80, 0x6B7E, 0x6BDE, 0x6C1D, 0x6C93, 0x6CEC, 0x6CEB, 0x6CEE, 0x6CD9, 0x6CB6, 0x6CD4, 0x6CAD, 0x6CE7, 0x6CB7, - 0x6CD0, 0x6CC2, 0x6CBA, 0x6CC3, 0x6CC6, 0x6CED, 0x6CF2, - /* Big5-HKSCS 0xCD40 .. 0xCD7E */ - 0x6CD2, 0x6CDD, 0x6CB4, 0x6C8A, 0x6C9D, 0x6C80, 0x6CDE, 0x6CC0, 0x6D30, 0x6CCD, 0x6CC7, 0x6CB0, 0x6CF9, 0x6CCF, 0x6CE9, 0x6CD1, - 0x7094, 0x7098, 0x7085, 0x7093, 0x7086, 0x7084, 0x7091, 0x7096, 0x7082, 0x709A, 0x7083, 0x726A, 0x72D6, 0x72CB, 0x72D8, 0x72C9, - 0x72DC, 0x72D2, 0x72D4, 0x72DA, 0x72CC, 0x72D1, 0x73A4, 0x73A1, 0x73AD, 0x73A6, 0x73A2, 0x73A0, 0x73AC, 0x739D, 0x74DD, 0x74E8, - 0x753F, 0x7540, 0x753E, 0x758C, 0x7598, 0x76AF, 0x76F3, 0x76F1, 0x76F0, 0x76F5, 0x77F8, 0x77FC, 0x77F9, 0x77FB, 0x77FA, - /* Big5-HKSCS 0xCDA1 .. 0xCDFE */ - 0x77F7, 0x7942, 0x793F, 0x79C5, 0x7A78, 0x7A7B, 0x7AFB, - 0x7C75, 0x7CFD, 0x8035, 0x808F, 0x80AE, 0x80A3, 0x80B8, 0x80B5, 0x80AD, 0x8220, 0x82A0, 0x82C0, 0x82AB, 0x829A, 0x8298, 0x829B, - 0x82B5, 0x82A7, 0x82AE, 0x82BC, 0x829E, 0x82BA, 0x82B4, 0x82A8, 0x82A1, 0x82A9, 0x82C2, 0x82A4, 0x82C3, 0x82B6, 0x82A2, 0x8670, - 0x866F, 0x866D, 0x866E, 0x8C56, 0x8FD2, 0x8FCB, 0x8FD3, 0x8FCD, 0x8FD6, 0x8FD5, 0x8FD7, 0x90B2, 0x90B4, 0x90AF, 0x90B3, 0x90B0, - 0x9639, 0x963D, 0x963C, 0x963A, 0x9643, 0x4FCD, 0x4FC5, 0x4FD3, 0x4FB2, 0x4FC9, 0x4FCB, 0x4FC1, 0x4FD4, 0x4FDC, 0x4FD9, 0x4FBB, - 0x4FB3, 0x4FDB, 0x4FC7, 0x4FD6, 0x4FBA, 0x4FC0, 0x4FB9, 0x4FEC, 0x5244, 0x5249, 0x52C0, 0x52C2, 0x533D, 0x537C, 0x5397, 0x5396, - 0x5399, 0x5398, 0x54BA, 0x54A1, 0x54AD, 0x54A5, 0x54CF, - /* Big5-HKSCS 0xCE40 .. 0xCE7E */ - 0x54C3, 0x830D, 0x54B7, 0x54AE, 0x54D6, 0x54B6, 0x54C5, 0x54C6, 0x54A0, 0x5470, 0x54BC, 0x54A2, 0x54BE, 0x5472, 0x54DE, 0x54B0, - 0x57B5, 0x579E, 0x579F, 0x57A4, 0x578C, 0x5797, 0x579D, 0x579B, 0x5794, 0x5798, 0x578F, 0x5799, 0x57A5, 0x579A, 0x5795, 0x58F4, - 0x590D, 0x5953, 0x59E1, 0x59DE, 0x59EE, 0x5A00, 0x59F1, 0x59DD, 0x59FA, 0x59FD, 0x59FC, 0x59F6, 0x59E4, 0x59F2, 0x59F7, 0x59DB, - 0x59E9, 0x59F3, 0x59F5, 0x59E0, 0x59FE, 0x59F4, 0x59ED, 0x5BA8, 0x5C4C, 0x5CD0, 0x5CD8, 0x5CCC, 0x5CD7, 0x5CCB, 0x5CDB, - /* Big5-HKSCS 0xCEA1 .. 0xCEFE */ - 0x5CDE, 0x5CDA, 0x5CC9, 0x5CC7, 0x5CCA, 0x5CD6, 0x5CD3, - 0x5CD4, 0x5CCF, 0x5CC8, 0x5CC6, 0x5CCE, 0x5CDF, 0x5CF8, 0x5DF9, 0x5E21, 0x5E22, 0x5E23, 0x5E20, 0x5E24, 0x5EB0, 0x5EA4, 0x5EA2, - 0x5E9B, 0x5EA3, 0x5EA5, 0x5F07, 0x5F2E, 0x5F56, 0x5F86, 0x6037, 0x6039, 0x6054, 0x6072, 0x605E, 0x6045, 0x6053, 0x6047, 0x6049, - 0x605B, 0x604C, 0x6040, 0x6042, 0x605F, 0x6024, 0x6044, 0x6058, 0x6066, 0x606E, 0x6242, 0x6243, 0x62CF, 0x630D, 0x630B, 0x62F5, - 0x630E, 0x6303, 0x62EB, 0x62F9, 0x630F, 0x630C, 0x62F8, 0x62F6, 0x6300, 0x6313, 0x6314, 0x62FA, 0x6315, 0x62FB, 0x62F0, 0x6541, - 0x6543, 0x65AA, 0x65BF, 0x6636, 0x6621, 0x6632, 0x6635, 0x661C, 0x6626, 0x6622, 0x6633, 0x662B, 0x663A, 0x661D, 0x6634, 0x6639, - 0x662E, 0x670F, 0x6710, 0x67C1, 0x67F2, 0x67C8, 0x67BA, - /* Big5-HKSCS 0xCF40 .. 0xCF7E */ - 0x67DC, 0x67BB, 0x67F8, 0x67D8, 0x67C0, 0x67B7, 0x67C5, 0x67EB, 0x67E4, 0x67DF, 0x67B5, 0x67CD, 0x67B3, 0x67F7, 0x67F6, 0x67EE, - 0x67E3, 0x67C2, 0x67B9, 0x67CE, 0x67E7, 0x67F0, 0x67B2, 0x67FC, 0x67C6, 0x67ED, 0x67CC, 0x67AE, 0x67E6, 0x67DB, 0x67FA, 0x67C9, - 0x67CA, 0x67C3, 0x67EA, 0x67CB, 0x6B28, 0x6B82, 0x6B84, 0x6BB6, 0x6BD6, 0x6BD8, 0x6BE0, 0x6C20, 0x6C21, 0x6D28, 0x6D34, 0x6D2D, - 0x6D1F, 0x6D3C, 0x6D3F, 0x6D12, 0x6D0A, 0x6CDA, 0x6D33, 0x6D04, 0x6D19, 0x6D3A, 0x6D1A, 0x6D11, 0x6D00, 0x6D1D, 0x6D42, - /* Big5-HKSCS 0xCFA1 .. 0xCFFE */ - 0x6D01, 0x6D18, 0x6D37, 0x6D03, 0x6D0F, 0x6D40, 0x6D07, - 0x6D20, 0x6D2C, 0x6D08, 0x6D22, 0x6D09, 0x6D10, 0x70B7, 0x709F, 0x70BE, 0x70B1, 0x70B0, 0x70A1, 0x70B4, 0x70B5, 0x70A9, 0x7241, - 0x7249, 0x724A, 0x726C, 0x7270, 0x7273, 0x726E, 0x72CA, 0x72E4, 0x72E8, 0x72EB, 0x72DF, 0x72EA, 0x72E6, 0x72E3, 0x7385, 0x73CC, - 0x73C2, 0x73C8, 0x73C5, 0x73B9, 0x73B6, 0x73B5, 0x73B4, 0x73EB, 0x73BF, 0x73C7, 0x73BE, 0x73C3, 0x73C6, 0x73B8, 0x73CB, 0x74EC, - 0x74EE, 0x752E, 0x7547, 0x7548, 0x75A7, 0x75AA, 0x7679, 0x76C4, 0x7708, 0x7703, 0x7704, 0x7705, 0x770A, 0x76F7, 0x76FB, 0x76FA, - 0x77E7, 0x77E8, 0x7806, 0x7811, 0x7812, 0x7805, 0x7810, 0x780F, 0x780E, 0x7809, 0x7803, 0x7813, 0x794A, 0x794C, 0x794B, 0x7945, - 0x7944, 0x79D5, 0x79CD, 0x79CF, 0x79D6, 0x79CE, 0x7A80, - /* Big5-HKSCS 0xD040 .. 0xD07E */ - 0x7A7E, 0x7AD1, 0x7B00, 0x7B01, 0x7C7A, 0x7C78, 0x7C79, 0x7C7F, 0x7C80, 0x7C81, 0x7D03, 0x7D08, 0x7D01, 0x7F58, 0x7F91, 0x7F8D, - 0x7FBE, 0x8007, 0x800E, 0x800F, 0x8014, 0x8037, 0x80D8, 0x80C7, 0x80E0, 0x80D1, 0x80C8, 0x80C2, 0x80D0, 0x80C5, 0x80E3, 0x80D9, - 0x80DC, 0x80CA, 0x80D5, 0x80C9, 0x80CF, 0x80D7, 0x80E6, 0x80CD, 0x81FF, 0x8221, 0x8294, 0x82D9, 0x82FE, 0x82F9, 0x8307, 0x82E8, - 0x8300, 0x82D5, 0x833A, 0x82EB, 0x82D6, 0x82F4, 0x82EC, 0x82E1, 0x82F2, 0x82F5, 0x830C, 0x82FB, 0x82F6, 0x82F0, 0x82EA, - /* Big5-HKSCS 0xD0A1 .. 0xD0FE */ - 0x82E4, 0x82E0, 0x82FA, 0x82F3, 0x82ED, 0x8677, 0x8674, - 0x867C, 0x8673, 0x8841, 0x884E, 0x8867, 0x886A, 0x8869, 0x89D3, 0x8A04, 0x8A07, 0x8D72, 0x8FE3, 0x8FE1, 0x8FEE, 0x8FE0, 0x90F1, - 0x90BD, 0x90BF, 0x90D5, 0x90C5, 0x90BE, 0x90C7, 0x90CB, 0x90C8, 0x91D4, 0x91D3, 0x9654, 0x964F, 0x9651, 0x9653, 0x964A, 0x964E, - 0x501E, 0x5005, 0x5007, 0x5013, 0x5022, 0x5030, 0x501B, 0x4FF5, 0x4FF4, 0x5033, 0x5037, 0x502C, 0x4FF6, 0x4FF7, 0x5017, 0x501C, - 0x5020, 0x5027, 0x5035, 0x502F, 0x5031, 0x500E, 0x515A, 0x5194, 0x5193, 0x51CA, 0x51C4, 0x51C5, 0x51C8, 0x51CE, 0x5261, 0x525A, - 0x5252, 0x525E, 0x525F, 0x5255, 0x5262, 0x52CD, 0x530E, 0x539E, 0x5526, 0x54E2, 0x5517, 0x5512, 0x54E7, 0x54F3, 0x54E4, 0x551A, - 0x54FF, 0x5504, 0x5508, 0x54EB, 0x5511, 0x5505, 0x54F1, - /* Big5-HKSCS 0xD140 .. 0xD17E */ - 0x550A, 0x54FB, 0x54F7, 0x54F8, 0x54E0, 0x550E, 0x5503, 0x550B, 0x5701, 0x5702, 0x57CC, 0x5832, 0x57D5, 0x57D2, 0x57BA, 0x57C6, - 0x57BD, 0x57BC, 0x57B8, 0x57B6, 0x57BF, 0x57C7, 0x57D0, 0x57B9, 0x57C1, 0x590E, 0x594A, 0x5A19, 0x5A16, 0x5A2D, 0x5A2E, 0x5A15, - 0x5A0F, 0x5A17, 0x5A0A, 0x5A1E, 0x5A33, 0x5B6C, 0x5BA7, 0x5BAD, 0x5BAC, 0x5C03, 0x5C56, 0x5C54, 0x5CEC, 0x5CFF, 0x5CEE, 0x5CF1, - 0x5CF7, 0x5D00, 0x5CF9, 0x5E29, 0x5E28, 0x5EA8, 0x5EAE, 0x5EAA, 0x5EAC, 0x5F33, 0x5F30, 0x5F67, 0x605D, 0x605A, 0x6067, - /* Big5-HKSCS 0xD1A1 .. 0xD1FE */ - 0x6041, 0x60A2, 0x6088, 0x6080, 0x6092, 0x6081, 0x609D, - 0x6083, 0x6095, 0x609B, 0x6097, 0x6087, 0x609C, 0x608E, 0x6219, 0x6246, 0x62F2, 0x6310, 0x6356, 0x632C, 0x6344, 0x6345, 0x6336, - 0x6343, 0x63E4, 0x6339, 0x634B, 0x634A, 0x633C, 0x6329, 0x6341, 0x6334, 0x6358, 0x6354, 0x6359, 0x632D, 0x6347, 0x6333, 0x635A, - 0x6351, 0x6338, 0x6357, 0x6340, 0x6348, 0x654A, 0x6546, 0x65C6, 0x65C3, 0x65C4, 0x65C2, 0x664A, 0x665F, 0x6647, 0x6651, 0x6712, - 0x6713, 0x681F, 0x681A, 0x6849, 0x6832, 0x6833, 0x683B, 0x684B, 0x684F, 0x6816, 0x6831, 0x681C, 0x6835, 0x682B, 0x682D, 0x682F, - 0x684E, 0x6844, 0x6834, 0x681D, 0x6812, 0x6814, 0x6826, 0x6828, 0x682E, 0x684D, 0x683A, 0x6825, 0x6820, 0x6B2C, 0x6B2F, 0x6B2D, - 0x6B31, 0x6B34, 0x6B6D, 0x8082, 0x6B88, 0x6BE6, 0x6BE4, - /* Big5-HKSCS 0xD240 .. 0xD27E */ - 0x6BE8, 0x6BE3, 0x6BE2, 0x6BE7, 0x6C25, 0x6D7A, 0x6D63, 0x6D64, 0x6D76, 0x6D0D, 0x6D61, 0x6D92, 0x6D58, 0x6D62, 0x6D6D, 0x6D6F, - 0x6D91, 0x6D8D, 0x6DEF, 0x6D7F, 0x6D86, 0x6D5E, 0x6D67, 0x6D60, 0x6D97, 0x6D70, 0x6D7C, 0x6D5F, 0x6D82, 0x6D98, 0x6D2F, 0x6D68, - 0x6D8B, 0x6D7E, 0x6D80, 0x6D84, 0x6D16, 0x6D83, 0x6D7B, 0x6D7D, 0x6D75, 0x6D90, 0x70DC, 0x70D3, 0x70D1, 0x70DD, 0x70CB, 0x7F39, - 0x70E2, 0x70D7, 0x70D2, 0x70DE, 0x70E0, 0x70D4, 0x70CD, 0x70C5, 0x70C6, 0x70C7, 0x70DA, 0x70CE, 0x70E1, 0x7242, 0x7278, - /* Big5-HKSCS 0xD2A1 .. 0xD2FE */ - 0x7277, 0x7276, 0x7300, 0x72FA, 0x72F4, 0x72FE, 0x72F6, - 0x72F3, 0x72FB, 0x7301, 0x73D3, 0x73D9, 0x73E5, 0x73D6, 0x73BC, 0x73E7, 0x73E3, 0x73E9, 0x73DC, 0x73D2, 0x73DB, 0x73D4, 0x73DD, - 0x73DA, 0x73D7, 0x73D8, 0x73E8, 0x74DE, 0x74DF, 0x74F4, 0x74F5, 0x7521, 0x755B, 0x755F, 0x75B0, 0x75C1, 0x75BB, 0x75C4, 0x75C0, - 0x75BF, 0x75B6, 0x75BA, 0x768A, 0x76C9, 0x771D, 0x771B, 0x7710, 0x7713, 0x7712, 0x7723, 0x7711, 0x7715, 0x7719, 0x771A, 0x7722, - 0x7727, 0x7823, 0x782C, 0x7822, 0x7835, 0x782F, 0x7828, 0x782E, 0x782B, 0x7821, 0x7829, 0x7833, 0x782A, 0x7831, 0x7954, 0x795B, - 0x794F, 0x795C, 0x7953, 0x7952, 0x7951, 0x79EB, 0x79EC, 0x79E0, 0x79EE, 0x79ED, 0x79EA, 0x79DC, 0x79DE, 0x79DD, 0x7A86, 0x7A89, - 0x7A85, 0x7A8B, 0x7A8C, 0x7A8A, 0x7A87, 0x7AD8, 0x7B10, - /* Big5-HKSCS 0xD340 .. 0xD37E */ - 0x7B04, 0x7B13, 0x7B05, 0x7B0F, 0x7B08, 0x7B0A, 0x7B0E, 0x7B09, 0x7B12, 0x7C84, 0x7C91, 0x7C8A, 0x7C8C, 0x7C88, 0x7C8D, 0x7C85, - 0x7D1E, 0x7D1D, 0x7D11, 0x7D0E, 0x7D18, 0x7D16, 0x7D13, 0x7D1F, 0x7D12, 0x7D0F, 0x7D0C, 0x7F5C, 0x7F61, 0x7F5E, 0x7F60, 0x7F5D, - 0x7F5B, 0x7F96, 0x7F92, 0x7FC3, 0x7FC2, 0x7FC0, 0x8016, 0x803E, 0x8039, 0x80FA, 0x80F2, 0x80F9, 0x80F5, 0x8101, 0x80FB, 0x8100, - 0x8201, 0x822F, 0x8225, 0x8333, 0x832D, 0x8344, 0x8319, 0x8351, 0x8325, 0x8356, 0x833F, 0x8341, 0x8326, 0x831C, 0x8322, - /* Big5-HKSCS 0xD3A1 .. 0xD3FE */ - 0x8342, 0x834E, 0x831B, 0x832A, 0x8308, 0x833C, 0x834D, - 0x8316, 0x8324, 0x8320, 0x8337, 0x832F, 0x8329, 0x8347, 0x8345, 0x834C, 0x8353, 0x831E, 0x832C, 0x834B, 0x8327, 0x8348, 0x8653, - 0x8652, 0x86A2, 0x86A8, 0x8696, 0x868D, 0x8691, 0x869E, 0x8687, 0x8697, 0x8686, 0x868B, 0x869A, 0x8685, 0x86A5, 0x8699, 0x86A1, - 0x86A7, 0x8695, 0x8698, 0x868E, 0x869D, 0x8690, 0x8694, 0x8843, 0x8844, 0x886D, 0x8875, 0x8876, 0x8872, 0x8880, 0x8871, 0x887F, - 0x886F, 0x8883, 0x887E, 0x8874, 0x887C, 0x8A12, 0x8C47, 0x8C57, 0x8C7B, 0x8CA4, 0x8CA3, 0x8D76, 0x8D78, 0x8DB5, 0x8DB7, 0x8DB6, - 0x8ED1, 0x8ED3, 0x8FFE, 0x8FF5, 0x9002, 0x8FFF, 0x8FFB, 0x9004, 0x8FFC, 0x8FF6, 0x90D6, 0x90E0, 0x90D9, 0x90DA, 0x90E3, 0x90DF, - 0x90E5, 0x90D8, 0x90DB, 0x90D7, 0x90DC, 0x90E4, 0x9150, - /* Big5-HKSCS 0xD440 .. 0xD47E */ - 0x914E, 0x914F, 0x91D5, 0x91E2, 0x91DA, 0x965C, 0x965F, 0x96BC, 0x98E3, 0x9ADF, 0x9B2F, 0x4E7F, 0x5070, 0x506A, 0x5061, 0x505E, - 0x5060, 0x5053, 0x504B, 0x505D, 0x5072, 0x5048, 0x504D, 0x5041, 0x505B, 0x504A, 0x5062, 0x5015, 0x5045, 0x505F, 0x5069, 0x506B, - 0x5063, 0x5064, 0x5046, 0x5040, 0x506E, 0x5073, 0x5057, 0x5051, 0x51D0, 0x526B, 0x526D, 0x526C, 0x526E, 0x52D6, 0x52D3, 0x532D, - 0x539C, 0x5575, 0x5576, 0x553C, 0x554D, 0x5550, 0x5534, 0x552A, 0x5551, 0x5562, 0x5536, 0x5535, 0x5530, 0x5552, 0x5545, - /* Big5-HKSCS 0xD4A1 .. 0xD4FE */ - 0x550C, 0x5532, 0x5565, 0x554E, 0x5539, 0x5548, 0x552D, - 0x553B, 0x5540, 0x554B, 0x570A, 0x5707, 0x57FB, 0x5814, 0x57E2, 0x57F6, 0x57DC, 0x57F4, 0x5800, 0x57ED, 0x57FD, 0x5808, 0x57F8, - 0x580B, 0x57F3, 0x57CF, 0x5807, 0x57EE, 0x57E3, 0x57F2, 0x57E5, 0x57EC, 0x57E1, 0x580E, 0x57FC, 0x5810, 0x57E7, 0x5801, 0x580C, - 0x57F1, 0x57E9, 0x57F0, 0x580D, 0x5804, 0x595C, 0x5A60, 0x5A58, 0x5A55, 0x5A67, 0x5A5E, 0x5A38, 0x5A35, 0x5A6D, 0x5A50, 0x5A5F, - 0x5A65, 0x5A6C, 0x5A53, 0x5A64, 0x5A57, 0x5A43, 0x5A5D, 0x5A52, 0x5A44, 0x5A5B, 0x5A48, 0x5A8E, 0x5A3E, 0x5A4D, 0x5A39, 0x5A4C, - 0x5A70, 0x5A69, 0x5A47, 0x5A51, 0x5A56, 0x5A42, 0x5A5C, 0x5B72, 0x5B6E, 0x5BC1, 0x5BC0, 0x5C59, 0x5D1E, 0x5D0B, 0x5D1D, 0x5D1A, - 0x5D20, 0x5D0C, 0x5D28, 0x5D0D, 0x5D26, 0x5D25, 0x5D0F, - /* Big5-HKSCS 0xD540 .. 0xD57E */ - 0x5D30, 0x5D12, 0x5D23, 0x5D1F, 0x5D2E, 0x5E3E, 0x5E34, 0x5EB1, 0x5EB4, 0x5EB9, 0x5EB2, 0x5EB3, 0x5F36, 0x5F38, 0x5F9B, 0x5F96, - 0x5F9F, 0x608A, 0x6090, 0x6086, 0x60BE, 0x60B0, 0x60BA, 0x60D3, 0x60D4, 0x60CF, 0x60E4, 0x60D9, 0x60DD, 0x60C8, 0x60B1, 0x60DB, - 0x60B7, 0x60CA, 0x60BF, 0x60C3, 0x60CD, 0x60C0, 0x6332, 0x6365, 0x638A, 0x6382, 0x637D, 0x63BD, 0x639E, 0x63AD, 0x639D, 0x6397, - 0x63AB, 0x638E, 0x636F, 0x6387, 0x6390, 0x636E, 0x63AF, 0x6375, 0x639C, 0x636D, 0x63AE, 0x637C, 0x63A4, 0x633B, 0x639F, - /* Big5-HKSCS 0xD5A1 .. 0xD5FE */ - 0x6378, 0x6385, 0x6381, 0x6391, 0x638D, 0x6370, 0x6553, - 0x65CD, 0x6665, 0x6661, 0x665B, 0x6659, 0x665C, 0x6662, 0x6718, 0x6879, 0x6887, 0x6890, 0x689C, 0x686D, 0x686E, 0x68AE, 0x68AB, - 0x6956, 0x686F, 0x68A3, 0x68AC, 0x68A9, 0x6875, 0x6874, 0x68B2, 0x688F, 0x6877, 0x6892, 0x687C, 0x686B, 0x6872, 0x68AA, 0x6880, - 0x6871, 0x687E, 0x689B, 0x6896, 0x688B, 0x68A0, 0x6889, 0x68A4, 0x6878, 0x687B, 0x6891, 0x688C, 0x688A, 0x687D, 0x6B36, 0x6B33, - 0x6B37, 0x6B38, 0x6B91, 0x6B8F, 0x6B8D, 0x6B8E, 0x6B8C, 0x6C2A, 0x6DC0, 0x6DAB, 0x6DB4, 0x6DB3, 0x6E74, 0x6DAC, 0x6DE9, 0x6DE2, - 0x6DB7, 0x6DF6, 0x6DD4, 0x6E00, 0x6DC8, 0x6DE0, 0x6DDF, 0x6DD6, 0x6DBE, 0x6DE5, 0x6DDC, 0x6DDD, 0x6DDB, 0x6DF4, 0x6DCA, 0x6DBD, - 0x6DED, 0x6DF0, 0x6DBA, 0x6DD5, 0x6DC2, 0x6DCF, 0x6DC9, - /* Big5-HKSCS 0xD640 .. 0xD67E */ - 0x6DD0, 0x6DF2, 0x6DD3, 0x6DFD, 0x6DD7, 0x6DCD, 0x6DE3, 0x6DBB, 0x70FA, 0x710D, 0x70F7, 0x7117, 0x70F4, 0x710C, 0x70F0, 0x7104, - 0x70F3, 0x7110, 0x70FC, 0x70FF, 0x7106, 0x7113, 0x7100, 0x70F8, 0x70F6, 0x710B, 0x7102, 0x710E, 0x727E, 0x727B, 0x727C, 0x727F, - 0x731D, 0x7317, 0x7307, 0x7311, 0x7318, 0x730A, 0x7308, 0x72FF, 0x730F, 0x731E, 0x7388, 0x73F6, 0x73F8, 0x73F5, 0x7404, 0x7401, - 0x73FD, 0x7407, 0x7400, 0x73FA, 0x73FC, 0x73FF, 0x740C, 0x740B, 0x73F4, 0x7408, 0x7564, 0x7563, 0x75CE, 0x75D2, 0x75CF, - /* Big5-HKSCS 0xD6A1 .. 0xD6FE */ - 0x75CB, 0x75CC, 0x75D1, 0x75D0, 0x768F, 0x7689, 0x76D3, - 0x7739, 0x772F, 0x772D, 0x7731, 0x7732, 0x7734, 0x7733, 0x773D, 0x7725, 0x773B, 0x7735, 0x7848, 0x7852, 0x7849, 0x784D, 0x784A, - 0x784C, 0x7826, 0x7845, 0x7850, 0x7964, 0x7967, 0x7969, 0x796A, 0x7963, 0x796B, 0x7961, 0x79BB, 0x79FA, 0x79F8, 0x79F6, 0x79F7, - 0x7A8F, 0x7A94, 0x7A90, 0x7B35, 0x7B47, 0x7B34, 0x7B25, 0x7B30, 0x7B22, 0x7B24, 0x7B33, 0x7B18, 0x7B2A, 0x7B1D, 0x7B31, 0x7B2B, - 0x7B2D, 0x7B2F, 0x7B32, 0x7B38, 0x7B1A, 0x7B23, 0x7C94, 0x7C98, 0x7C96, 0x7CA3, 0x7D35, 0x7D3D, 0x7D38, 0x7D36, 0x7D3A, 0x7D45, - 0x7D2C, 0x7D29, 0x7D41, 0x7D47, 0x7D3E, 0x7D3F, 0x7D4A, 0x7D3B, 0x7D28, 0x7F63, 0x7F95, 0x7F9C, 0x7F9D, 0x7F9B, 0x7FCA, 0x7FCB, - 0x7FCD, 0x7FD0, 0x7FD1, 0x7FC7, 0x7FCF, 0x7FC9, 0x801F, - /* Big5-HKSCS 0xD740 .. 0xD77E */ - 0x801E, 0x801B, 0x8047, 0x8043, 0x8048, 0x8118, 0x8125, 0x8119, 0x811B, 0x812D, 0x811F, 0x812C, 0x811E, 0x8121, 0x8115, 0x8127, - 0x811D, 0x8122, 0x8211, 0x8238, 0x8233, 0x823A, 0x8234, 0x8232, 0x8274, 0x8390, 0x83A3, 0x83A8, 0x838D, 0x837A, 0x8373, 0x83A4, - 0x8374, 0x838F, 0x8381, 0x8395, 0x8399, 0x8375, 0x8394, 0x83A9, 0x837D, 0x8383, 0x838C, 0x839D, 0x839B, 0x83AA, 0x838B, 0x837E, - 0x83A5, 0x83AF, 0x8388, 0x8397, 0x83B0, 0x837F, 0x83A6, 0x8387, 0x83AE, 0x8376, 0x839A, 0x8659, 0x8656, 0x86BF, 0x86B7, - /* Big5-HKSCS 0xD7A1 .. 0xD7FE */ - 0x86C2, 0x86C1, 0x86C5, 0x86BA, 0x86B0, 0x86C8, 0x86B9, - 0x86B3, 0x86B8, 0x86CC, 0x86B4, 0x86BB, 0x86BC, 0x86C3, 0x86BD, 0x86BE, 0x8852, 0x8889, 0x8895, 0x88A8, 0x88A2, 0x88AA, 0x889A, - 0x8891, 0x88A1, 0x889F, 0x8898, 0x88A7, 0x8899, 0x889B, 0x8897, 0x88A4, 0x88AC, 0x888C, 0x8893, 0x888E, 0x8982, 0x89D6, 0x89D9, - 0x89D5, 0x8A30, 0x8A27, 0x8A2C, 0x8A1E, 0x8C39, 0x8C3B, 0x8C5C, 0x8C5D, 0x8C7D, 0x8CA5, 0x8D7D, 0x8D7B, 0x8D79, 0x8DBC, 0x8DC2, - 0x8DB9, 0x8DBF, 0x8DC1, 0x8ED8, 0x8EDE, 0x8EDD, 0x8EDC, 0x8ED7, 0x8EE0, 0x8EE1, 0x9024, 0x900B, 0x9011, 0x901C, 0x900C, 0x9021, - 0x90EF, 0x90EA, 0x90F0, 0x90F4, 0x90F2, 0x90F3, 0x90D4, 0x90EB, 0x90EC, 0x90E9, 0x9156, 0x9158, 0x915A, 0x9153, 0x9155, 0x91EC, - 0x91F4, 0x91F1, 0x91F3, 0x91F8, 0x91E4, 0x91F9, 0x91EA, - /* Big5-HKSCS 0xD840 .. 0xD87E */ - 0x91EB, 0x91F7, 0x91E8, 0x91EE, 0x957A, 0x9586, 0x9588, 0x967C, 0x966D, 0x966B, 0x9671, 0x966F, 0x96BF, 0x976A, 0x9804, 0x98E5, - 0x9997, 0x509B, 0x5095, 0x5094, 0x509E, 0x508B, 0x50A3, 0x5083, 0x508C, 0x508E, 0x509D, 0x5068, 0x509C, 0x5092, 0x5082, 0x5087, - 0x515F, 0x51D4, 0x5312, 0x5311, 0x53A4, 0x53A7, 0x5591, 0x55A8, 0x55A5, 0x55AD, 0x5577, 0x5645, 0x55A2, 0x5593, 0x5588, 0x558F, - 0x55B5, 0x5581, 0x55A3, 0x5592, 0x55A4, 0x557D, 0x558C, 0x55A6, 0x557F, 0x5595, 0x55A1, 0x558E, 0x570C, 0x5829, 0x5837, - /* Big5-HKSCS 0xD8A1 .. 0xD8FE */ - 0x5819, 0x581E, 0x5827, 0x5823, 0x5828, 0x57F5, 0x5848, - 0x5825, 0x581C, 0x581B, 0x5833, 0x583F, 0x5836, 0x582E, 0x5839, 0x5838, 0x582D, 0x582C, 0x583B, 0x5961, 0x5AAF, 0x5A94, 0x5A9F, - 0x5A7A, 0x5AA2, 0x5A9E, 0x5A78, 0x5AA6, 0x5A7C, 0x5AA5, 0x5AAC, 0x5A95, 0x5AAE, 0x5A37, 0x5A84, 0x5A8A, 0x5A97, 0x5A83, 0x5A8B, - 0x5AA9, 0x5A7B, 0x5A7D, 0x5A8C, 0x5A9C, 0x5A8F, 0x5A93, 0x5A9D, 0x5BEA, 0x5BCD, 0x5BCB, 0x5BD4, 0x5BD1, 0x5BCA, 0x5BCE, 0x5C0C, - 0x5C30, 0x5D37, 0x5D43, 0x5D6B, 0x5D41, 0x5D4B, 0x5D3F, 0x5D35, 0x5D51, 0x5D4E, 0x5D55, 0x5D33, 0x5D3A, 0x5D52, 0x5D3D, 0x5D31, - 0x5D59, 0x5D42, 0x5D39, 0x5D49, 0x5D38, 0x5D3C, 0x5D32, 0x5D36, 0x5D40, 0x5D45, 0x5E44, 0x5E41, 0x5F58, 0x5FA6, 0x5FA5, 0x5FAB, - 0x60C9, 0x60B9, 0x60CC, 0x60E2, 0x60CE, 0x60C4, 0x6114, - /* Big5-HKSCS 0xD940 .. 0xD97E */ - 0x60F2, 0x610A, 0x6116, 0x6105, 0x60F5, 0x6113, 0x60F8, 0x60FC, 0x60FE, 0x60C1, 0x6103, 0x6118, 0x611D, 0x6110, 0x60FF, 0x6104, - 0x610B, 0x624A, 0x6394, 0x63B1, 0x63B0, 0x63CE, 0x63E5, 0x63E8, 0x63EF, 0x63C3, 0x649D, 0x63F3, 0x63CA, 0x63E0, 0x63F6, 0x63D5, - 0x63F2, 0x63F5, 0x6461, 0x63DF, 0x63BE, 0x63DD, 0x63DC, 0x63C4, 0x63D8, 0x63D3, 0x63C2, 0x63C7, 0x63CC, 0x63CB, 0x63C8, 0x63F0, - 0x63D7, 0x63D9, 0x6532, 0x6567, 0x656A, 0x6564, 0x655C, 0x6568, 0x6565, 0x658C, 0x659D, 0x659E, 0x65AE, 0x65D0, 0x65D2, - /* Big5-HKSCS 0xD9A1 .. 0xD9FE */ - 0x667C, 0x666C, 0x667B, 0x6680, 0x6671, 0x6679, 0x666A, - 0x6672, 0x6701, 0x690C, 0x68D3, 0x6904, 0x68DC, 0x692A, 0x68EC, 0x68EA, 0x68F1, 0x690F, 0x68D6, 0x68F7, 0x68EB, 0x68E4, 0x68F6, - 0x6913, 0x6910, 0x68F3, 0x68E1, 0x6907, 0x68CC, 0x6908, 0x6970, 0x68B4, 0x6911, 0x68EF, 0x68C6, 0x6914, 0x68F8, 0x68D0, 0x68FD, - 0x68FC, 0x68E8, 0x690B, 0x690A, 0x6917, 0x68CE, 0x68C8, 0x68DD, 0x68DE, 0x68E6, 0x68F4, 0x68D1, 0x6906, 0x68D4, 0x68E9, 0x6915, - 0x6925, 0x68C7, 0x6B39, 0x6B3B, 0x6B3F, 0x6B3C, 0x6B94, 0x6B97, 0x6B99, 0x6B95, 0x6BBD, 0x6BF0, 0x6BF2, 0x6BF3, 0x6C30, 0x6DFC, - 0x6E46, 0x6E47, 0x6E1F, 0x6E49, 0x6E88, 0x6E3C, 0x6E3D, 0x6E45, 0x6E62, 0x6E2B, 0x6E3F, 0x6E41, 0x6E5D, 0x6E73, 0x6E1C, 0x6E33, - 0x6E4B, 0x6E40, 0x6E51, 0x6E3B, 0x6E03, 0x6E2E, 0x6E5E, - /* Big5-HKSCS 0xDA40 .. 0xDA7E */ - 0x6E68, 0x6E5C, 0x6E61, 0x6E31, 0x6E28, 0x6E60, 0x6E71, 0x6E6B, 0x6E39, 0x6E22, 0x6E30, 0x6E53, 0x6E65, 0x6E27, 0x6E78, 0x6E64, - 0x6E77, 0x6E55, 0x6E79, 0x6E52, 0x6E66, 0x6E35, 0x6E36, 0x6E5A, 0x7120, 0x711E, 0x712F, 0x70FB, 0x712E, 0x7131, 0x7123, 0x7125, - 0x7122, 0x7132, 0x711F, 0x7128, 0x713A, 0x711B, 0x724B, 0x725A, 0x7288, 0x7289, 0x7286, 0x7285, 0x728B, 0x7312, 0x730B, 0x7330, - 0x7322, 0x7331, 0x7333, 0x7327, 0x7332, 0x732D, 0x7326, 0x7323, 0x7335, 0x730C, 0x742E, 0x742C, 0x7430, 0x742B, 0x7416, - /* Big5-HKSCS 0xDAA1 .. 0xDAFE */ - 0x741A, 0x7421, 0x742D, 0x7431, 0x7424, 0x7423, 0x741D, - 0x7429, 0x7420, 0x7432, 0x74FB, 0x752F, 0x756F, 0x756C, 0x75E7, 0x75DA, 0x75E1, 0x75E6, 0x75DD, 0x75DF, 0x75E4, 0x75D7, 0x7695, - 0x7692, 0x76DA, 0x7746, 0x7747, 0x7744, 0x774D, 0x7745, 0x774A, 0x774E, 0x774B, 0x774C, 0x77DE, 0x77EC, 0x7860, 0x7864, 0x7865, - 0x785C, 0x786D, 0x7871, 0x786A, 0x786E, 0x7870, 0x7869, 0x7868, 0x785E, 0x7862, 0x7974, 0x7973, 0x7972, 0x7970, 0x7A02, 0x7A0A, - 0x7A03, 0x7A0C, 0x7A04, 0x7A99, 0x7AE6, 0x7AE4, 0x7B4A, 0x7B3B, 0x7B44, 0x7B48, 0x7B4C, 0x7B4E, 0x7B40, 0x7B58, 0x7B45, 0x7CA2, - 0x7C9E, 0x7CA8, 0x7CA1, 0x7D58, 0x7D6F, 0x7D63, 0x7D53, 0x7D56, 0x7D67, 0x7D6A, 0x7D4F, 0x7D6D, 0x7D5C, 0x7D6B, 0x7D52, 0x7D54, - 0x7D69, 0x7D51, 0x7D5F, 0x7D4E, 0x7F3E, 0x7F3F, 0x7F65, - /* Big5-HKSCS 0xDB40 .. 0xDB7E */ - 0x7F66, 0x7FA2, 0x7FA0, 0x7FA1, 0x7FD7, 0x8051, 0x804F, 0x8050, 0x80FE, 0x80D4, 0x8143, 0x814A, 0x8152, 0x814F, 0x8147, 0x813D, - 0x814D, 0x813A, 0x81E6, 0x81EE, 0x81F7, 0x81F8, 0x81F9, 0x8204, 0x823C, 0x823D, 0x823F, 0x8275, 0x833B, 0x83CF, 0x83F9, 0x8423, - 0x83C0, 0x83E8, 0x8412, 0x83E7, 0x83E4, 0x83FC, 0x83F6, 0x8410, 0x83C6, 0x83C8, 0x83EB, 0x83E3, 0x83BF, 0x8401, 0x83DD, 0x83E5, - 0x83D8, 0x83FF, 0x83E1, 0x83CB, 0x83CE, 0x83D6, 0x83F5, 0x83C9, 0x8409, 0x840F, 0x83DE, 0x8411, 0x8406, 0x83C2, 0x83F3, - /* Big5-HKSCS 0xDBA1 .. 0xDBFE */ - 0x83D5, 0x83FA, 0x83C7, 0x83D1, 0x83EA, 0x8413, 0x83C3, - 0x83EC, 0x83EE, 0x83C4, 0x83FB, 0x83D7, 0x83E2, 0x841B, 0x83DB, 0x83FE, 0x86D8, 0x86E2, 0x86E6, 0x86D3, 0x86E3, 0x86DA, 0x86EA, - 0x86DD, 0x86EB, 0x86DC, 0x86EC, 0x86E9, 0x86D7, 0x86E8, 0x86D1, 0x8848, 0x8856, 0x8855, 0x88BA, 0x88D7, 0x88B9, 0x88B8, 0x88C0, - 0x88BE, 0x88B6, 0x88BC, 0x88B7, 0x88BD, 0x88B2, 0x8901, 0x88C9, 0x8995, 0x8998, 0x8997, 0x89DD, 0x89DA, 0x89DB, 0x8A4E, 0x8A4D, - 0x8A39, 0x8A59, 0x8A40, 0x8A57, 0x8A58, 0x8A44, 0x8A45, 0x8A52, 0x8A48, 0x8A51, 0x8A4A, 0x8A4C, 0x8A4F, 0x8C5F, 0x8C81, 0x8C80, - 0x8CBA, 0x8CBE, 0x8CB0, 0x8CB9, 0x8CB5, 0x8D84, 0x8D80, 0x8D89, 0x8DD8, 0x8DD3, 0x8DCD, 0x8DC7, 0x8DD6, 0x8DDC, 0x8DCF, 0x8DD5, - 0x8DD9, 0x8DC8, 0x8DD7, 0x8DC5, 0x8EEF, 0x8EF7, 0x8EFA, - /* Big5-HKSCS 0xDC40 .. 0xDC7E */ - 0x8EF9, 0x8EE6, 0x8EEE, 0x8EE5, 0x8EF5, 0x8EE7, 0x8EE8, 0x8EF6, 0x8EEB, 0x8EF1, 0x8EEC, 0x8EF4, 0x8EE9, 0x902D, 0x9034, 0x902F, - 0x9106, 0x912C, 0x9104, 0x90FF, 0x90FC, 0x9108, 0x90F9, 0x90FB, 0x9101, 0x9100, 0x9107, 0x9105, 0x9103, 0x9161, 0x9164, 0x915F, - 0x9162, 0x9160, 0x9201, 0x920A, 0x9225, 0x9203, 0x921A, 0x9226, 0x920F, 0x920C, 0x9200, 0x9212, 0x91FF, 0x91FD, 0x9206, 0x9204, - 0x9227, 0x9202, 0x921C, 0x9224, 0x9219, 0x9217, 0x9205, 0x9216, 0x957B, 0x958D, 0x958C, 0x9590, 0x9687, 0x967E, 0x9688, - /* Big5-HKSCS 0xDCA1 .. 0xDCFE */ - 0x9689, 0x9683, 0x9680, 0x96C2, 0x96C8, 0x96C3, 0x96F1, - 0x96F0, 0x976C, 0x9770, 0x976E, 0x9807, 0x98A9, 0x98EB, 0x9CE6, 0x9EF9, 0x4E83, 0x4E84, 0x4EB6, 0x50BD, 0x50BF, 0x50C6, 0x50AE, - 0x50C4, 0x50CA, 0x50B4, 0x50C8, 0x50C2, 0x50B0, 0x50C1, 0x50BA, 0x50B1, 0x50CB, 0x50C9, 0x50B6, 0x50B8, 0x51D7, 0x527A, 0x5278, - 0x527B, 0x527C, 0x55C3, 0x55DB, 0x55CC, 0x55D0, 0x55CB, 0x55CA, 0x55DD, 0x55C0, 0x55D4, 0x55C4, 0x55E9, 0x55BF, 0x55D2, 0x558D, - 0x55CF, 0x55D5, 0x55E2, 0x55D6, 0x55C8, 0x55F2, 0x55CD, 0x55D9, 0x55C2, 0x5714, 0x5853, 0x5868, 0x5864, 0x584F, 0x584D, 0x5849, - 0x586F, 0x5855, 0x584E, 0x585D, 0x5859, 0x5865, 0x585B, 0x583D, 0x5863, 0x5871, 0x58FC, 0x5AC7, 0x5AC4, 0x5ACB, 0x5ABA, 0x5AB8, - 0x5AB1, 0x5AB5, 0x5AB0, 0x5ABF, 0x5AC8, 0x5ABB, 0x5AC6, - /* Big5-HKSCS 0xDD40 .. 0xDD7E */ - 0x5AB7, 0x5AC0, 0x5ACA, 0x5AB4, 0x5AB6, 0x5ACD, 0x5AB9, 0x5A90, 0x5BD6, 0x5BD8, 0x5BD9, 0x5C1F, 0x5C33, 0x5D71, 0x5D63, 0x5D4A, - 0x5D65, 0x5D72, 0x5D6C, 0x5D5E, 0x5D68, 0x5D67, 0x5D62, 0x5DF0, 0x5E4F, 0x5E4E, 0x5E4A, 0x5E4D, 0x5E4B, 0x5EC5, 0x5ECC, 0x5EC6, - 0x5ECB, 0x5EC7, 0x5F40, 0x5FAF, 0x5FAD, 0x60F7, 0x6149, 0x614A, 0x612B, 0x6145, 0x6136, 0x6132, 0x612E, 0x6146, 0x612F, 0x614F, - 0x6129, 0x6140, 0x6220, 0x9168, 0x6223, 0x6225, 0x6224, 0x63C5, 0x63F1, 0x63EB, 0x6410, 0x6412, 0x6409, 0x6420, 0x6424, - /* Big5-HKSCS 0xDDA1 .. 0xDDFE */ - 0x6433, 0x6443, 0x641F, 0x6415, 0x6418, 0x6439, 0x6437, - 0x6422, 0x6423, 0x640C, 0x6426, 0x6430, 0x6428, 0x6441, 0x6435, 0x642F, 0x640A, 0x641A, 0x6440, 0x6425, 0x6427, 0x640B, 0x63E7, - 0x641B, 0x642E, 0x6421, 0x640E, 0x656F, 0x6592, 0x65D3, 0x6686, 0x668C, 0x6695, 0x6690, 0x668B, 0x668A, 0x6699, 0x6694, 0x6678, - 0x6720, 0x6966, 0x695F, 0x6938, 0x694E, 0x6962, 0x6971, 0x693F, 0x6945, 0x696A, 0x6939, 0x6942, 0x6957, 0x6959, 0x697A, 0x6948, - 0x6949, 0x6935, 0x696C, 0x6933, 0x693D, 0x6965, 0x68F0, 0x6978, 0x6934, 0x6969, 0x6940, 0x696F, 0x6944, 0x6976, 0x6958, 0x6941, - 0x6974, 0x694C, 0x693B, 0x694B, 0x6937, 0x695C, 0x694F, 0x6951, 0x6932, 0x6952, 0x692F, 0x697B, 0x693C, 0x6B46, 0x6B45, 0x6B43, - 0x6B42, 0x6B48, 0x6B41, 0x6B9B, 0xFA0D, 0x6BFB, 0x6BFC, - /* Big5-HKSCS 0xDE40 .. 0xDE7E */ - 0x6BF9, 0x6BF7, 0x6BF8, 0x6E9B, 0x6ED6, 0x6EC8, 0x6E8F, 0x6EC0, 0x6E9F, 0x6E93, 0x6E94, 0x6EA0, 0x6EB1, 0x6EB9, 0x6EC6, 0x6ED2, - 0x6EBD, 0x6EC1, 0x6E9E, 0x6EC9, 0x6EB7, 0x6EB0, 0x6ECD, 0x6EA6, 0x6ECF, 0x6EB2, 0x6EBE, 0x6EC3, 0x6EDC, 0x6ED8, 0x6E99, 0x6E92, - 0x6E8E, 0x6E8D, 0x6EA4, 0x6EA1, 0x6EBF, 0x6EB3, 0x6ED0, 0x6ECA, 0x6E97, 0x6EAE, 0x6EA3, 0x7147, 0x7154, 0x7152, 0x7163, 0x7160, - 0x7141, 0x715D, 0x7162, 0x7172, 0x7178, 0x716A, 0x7161, 0x7142, 0x7158, 0x7143, 0x714B, 0x7170, 0x715F, 0x7150, 0x7153, - /* Big5-HKSCS 0xDEA1 .. 0xDEFE */ - 0x7144, 0x714D, 0x715A, 0x724F, 0x728D, 0x728C, 0x7291, - 0x7290, 0x728E, 0x733C, 0x7342, 0x733B, 0x733A, 0x7340, 0x734A, 0x7349, 0x7444, 0x744A, 0x744B, 0x7452, 0x7451, 0x7457, 0x7440, - 0x744F, 0x7450, 0x744E, 0x7442, 0x7446, 0x744D, 0x7454, 0x74E1, 0x74FF, 0x74FE, 0x74FD, 0x751D, 0x7579, 0x7577, 0x6983, 0x75EF, - 0x760F, 0x7603, 0x75F7, 0x75FE, 0x75FC, 0x75F9, 0x75F8, 0x7610, 0x75FB, 0x75F6, 0x75ED, 0x75F5, 0x75FD, 0x7699, 0x76B5, 0x76DD, - 0x7755, 0x775F, 0x7760, 0x7752, 0x7756, 0x775A, 0x7769, 0x7767, 0x7754, 0x7759, 0x776D, 0x77E0, 0x7887, 0x789A, 0x7894, 0x788F, - 0x7884, 0x7895, 0x7885, 0x7886, 0x78A1, 0x7883, 0x7879, 0x7899, 0x7880, 0x7896, 0x787B, 0x797C, 0x7982, 0x797D, 0x7979, 0x7A11, - 0x7A18, 0x7A19, 0x7A12, 0x7A17, 0x7A15, 0x7A22, 0x7A13, - /* Big5-HKSCS 0xDF40 .. 0xDF7E */ - 0x7A1B, 0x7A10, 0x7AA3, 0x7AA2, 0x7A9E, 0x7AEB, 0x7B66, 0x7B64, 0x7B6D, 0x7B74, 0x7B69, 0x7B72, 0x7B65, 0x7B73, 0x7B71, 0x7B70, - 0x7B61, 0x7B78, 0x7B76, 0x7B63, 0x7CB2, 0x7CB4, 0x7CAF, 0x7D88, 0x7D86, 0x7D80, 0x7D8D, 0x7D7F, 0x7D85, 0x7D7A, 0x7D8E, 0x7D7B, - 0x7D83, 0x7D7C, 0x7D8C, 0x7D94, 0x7D84, 0x7D7D, 0x7D92, 0x7F6D, 0x7F6B, 0x7F67, 0x7F68, 0x7F6C, 0x7FA6, 0x7FA5, 0x7FA7, 0x7FDB, - 0x7FDC, 0x8021, 0x8164, 0x8160, 0x8177, 0x815C, 0x8169, 0x815B, 0x8162, 0x8172, 0x6721, 0x815E, 0x8176, 0x8167, 0x816F, - /* Big5-HKSCS 0xDFA1 .. 0xDFFE */ - 0x8144, 0x8161, 0x821D, 0x8249, 0x8244, 0x8240, 0x8242, - 0x8245, 0x84F1, 0x843F, 0x8456, 0x8476, 0x8479, 0x848F, 0x848D, 0x8465, 0x8451, 0x8440, 0x8486, 0x8467, 0x8430, 0x844D, 0x847D, - 0x845A, 0x8459, 0x8474, 0x8473, 0x845D, 0x8507, 0x845E, 0x8437, 0x843A, 0x8434, 0x847A, 0x8443, 0x8478, 0x8432, 0x8445, 0x8429, - 0x83D9, 0x844B, 0x842F, 0x8442, 0x842D, 0x845F, 0x8470, 0x8439, 0x844E, 0x844C, 0x8452, 0x846F, 0x84C5, 0x848E, 0x843B, 0x8447, - 0x8436, 0x8433, 0x8468, 0x847E, 0x8444, 0x842B, 0x8460, 0x8454, 0x846E, 0x8450, 0x870B, 0x8704, 0x86F7, 0x870C, 0x86FA, 0x86D6, - 0x86F5, 0x874D, 0x86F8, 0x870E, 0x8709, 0x8701, 0x86F6, 0x870D, 0x8705, 0x88D6, 0x88CB, 0x88CD, 0x88CE, 0x88DE, 0x88DB, 0x88DA, - 0x88CC, 0x88D0, 0x8985, 0x899B, 0x89DF, 0x89E5, 0x89E4, - /* Big5-HKSCS 0xE040 .. 0xE07E */ - 0x89E1, 0x89E0, 0x89E2, 0x89DC, 0x89E6, 0x8A76, 0x8A86, 0x8A7F, 0x8A61, 0x8A3F, 0x8A77, 0x8A82, 0x8A84, 0x8A75, 0x8A83, 0x8A81, - 0x8A74, 0x8A7A, 0x8C3C, 0x8C4B, 0x8C4A, 0x8C65, 0x8C64, 0x8C66, 0x8C86, 0x8C84, 0x8C85, 0x8CCC, 0x8D68, 0x8D69, 0x8D91, 0x8D8C, - 0x8D8E, 0x8D8F, 0x8D8D, 0x8D93, 0x8D94, 0x8D90, 0x8D92, 0x8DF0, 0x8DE0, 0x8DEC, 0x8DF1, 0x8DEE, 0x8DD0, 0x8DE9, 0x8DE3, 0x8DE2, - 0x8DE7, 0x8DF2, 0x8DEB, 0x8DF4, 0x8F06, 0x8EFF, 0x8F01, 0x8F00, 0x8F05, 0x8F07, 0x8F08, 0x8F02, 0x8F0B, 0x9052, 0x903F, - /* Big5-HKSCS 0xE0A1 .. 0xE0FE */ - 0x9044, 0x9049, 0x903D, 0x9110, 0x910D, 0x910F, 0x9111, - 0x9116, 0x9114, 0x910B, 0x910E, 0x916E, 0x916F, 0x9248, 0x9252, 0x9230, 0x923A, 0x9266, 0x9233, 0x9265, 0x925E, 0x9283, 0x922E, - 0x924A, 0x9246, 0x926D, 0x926C, 0x924F, 0x9260, 0x9267, 0x926F, 0x9236, 0x9261, 0x9270, 0x9231, 0x9254, 0x9263, 0x9250, 0x9272, - 0x924E, 0x9253, 0x924C, 0x9256, 0x9232, 0x959F, 0x959C, 0x959E, 0x959B, 0x9692, 0x9693, 0x9691, 0x9697, 0x96CE, 0x96FA, 0x96FD, - 0x96F8, 0x96F5, 0x9773, 0x9777, 0x9778, 0x9772, 0x980F, 0x980D, 0x980E, 0x98AC, 0x98F6, 0x98F9, 0x99AF, 0x99B2, 0x99B0, 0x99B5, - 0x9AAD, 0x9AAB, 0x9B5B, 0x9CEA, 0x9CED, 0x9CE7, 0x9E80, 0x9EFD, 0x50E6, 0x50D4, 0x50D7, 0x50E8, 0x50F3, 0x50DB, 0x50EA, 0x50DD, - 0x50E4, 0x50D3, 0x50EC, 0x50F0, 0x50EF, 0x50E3, 0x50E0, - /* Big5-HKSCS 0xE140 .. 0xE17E */ - 0x51D8, 0x5280, 0x5281, 0x52E9, 0x52EB, 0x5330, 0x53AC, 0x5627, 0x5615, 0x560C, 0x5612, 0x55FC, 0x560F, 0x561C, 0x5601, 0x5613, - 0x5602, 0x55FA, 0x561D, 0x5604, 0x55FF, 0x55F9, 0x5889, 0x587C, 0x5890, 0x5898, 0x5886, 0x5881, 0x587F, 0x5874, 0x588B, 0x587A, - 0x5887, 0x5891, 0x588E, 0x5876, 0x5882, 0x5888, 0x587B, 0x5894, 0x588F, 0x58FE, 0x596B, 0x5ADC, 0x5AEE, 0x5AE5, 0x5AD5, 0x5AEA, - 0x5ADA, 0x5AED, 0x5AEB, 0x5AF3, 0x5AE2, 0x5AE0, 0x5ADB, 0x5AEC, 0x5ADE, 0x5ADD, 0x5AD9, 0x5AE8, 0x5ADF, 0x5B77, 0x5BE0, - /* Big5-HKSCS 0xE1A1 .. 0xE1FE */ - 0x5BE3, 0x5C63, 0x5D82, 0x5D80, 0x5D7D, 0x5D86, 0x5D7A, - 0x5D81, 0x5D77, 0x5D8A, 0x5D89, 0x5D88, 0x5D7E, 0x5D7C, 0x5D8D, 0x5D79, 0x5D7F, 0x5E58, 0x5E59, 0x5E53, 0x5ED8, 0x5ED1, 0x5ED7, - 0x5ECE, 0x5EDC, 0x5ED5, 0x5ED9, 0x5ED2, 0x5ED4, 0x5F44, 0x5F43, 0x5F6F, 0x5FB6, 0x612C, 0x6128, 0x6141, 0x615E, 0x6171, 0x6173, - 0x6152, 0x6153, 0x6172, 0x616C, 0x6180, 0x6174, 0x6154, 0x617A, 0x615B, 0x6165, 0x613B, 0x616A, 0x6161, 0x6156, 0x6229, 0x6227, - 0x622B, 0x642B, 0x644D, 0x645B, 0x645D, 0x6474, 0x6476, 0x6472, 0x6473, 0x647D, 0x6475, 0x6466, 0x64A6, 0x644E, 0x6482, 0x645E, - 0x645C, 0x644B, 0x6453, 0x6460, 0x6450, 0x647F, 0x643F, 0x646C, 0x646B, 0x6459, 0x6465, 0x6477, 0x6573, 0x65A0, 0x66A1, 0x66A0, - 0x669F, 0x6705, 0x6704, 0x6722, 0x69B1, 0x69B6, 0x69C9, - /* Big5-HKSCS 0xE240 .. 0xE27E */ - 0x69A0, 0x69CE, 0x6996, 0x69B0, 0x69AC, 0x69BC, 0x6991, 0x6999, 0x698E, 0x69A7, 0x698D, 0x69A9, 0x69BE, 0x69AF, 0x69BF, 0x69C4, - 0x69BD, 0x69A4, 0x69D4, 0x69B9, 0x69CA, 0x699A, 0x69CF, 0x69B3, 0x6993, 0x69AA, 0x69A1, 0x699E, 0x69D9, 0x6997, 0x6990, 0x69C2, - 0x69B5, 0x69A5, 0x69C6, 0x6B4A, 0x6B4D, 0x6B4B, 0x6B9E, 0x6B9F, 0x6BA0, 0x6BC3, 0x6BC4, 0x6BFE, 0x6ECE, 0x6EF5, 0x6EF1, 0x6F03, - 0x6F25, 0x6EF8, 0x6F37, 0x6EFB, 0x6F2E, 0x6F09, 0x6F4E, 0x6F19, 0x6F1A, 0x6F27, 0x6F18, 0x6F3B, 0x6F12, 0x6EED, 0x6F0A, - /* Big5-HKSCS 0xE2A1 .. 0xE2FE */ - 0x6F36, 0x6F73, 0x6EF9, 0x6EEE, 0x6F2D, 0x6F40, 0x6F30, - 0x6F3C, 0x6F35, 0x6EEB, 0x6F07, 0x6F0E, 0x6F43, 0x6F05, 0x6EFD, 0x6EF6, 0x6F39, 0x6F1C, 0x6EFC, 0x6F3A, 0x6F1F, 0x6F0D, 0x6F1E, - 0x6F08, 0x6F21, 0x7187, 0x7190, 0x7189, 0x7180, 0x7185, 0x7182, 0x718F, 0x717B, 0x7186, 0x7181, 0x7197, 0x7244, 0x7253, 0x7297, - 0x7295, 0x7293, 0x7343, 0x734D, 0x7351, 0x734C, 0x7462, 0x7473, 0x7471, 0x7475, 0x7472, 0x7467, 0x746E, 0x7500, 0x7502, 0x7503, - 0x757D, 0x7590, 0x7616, 0x7608, 0x760C, 0x7615, 0x7611, 0x760A, 0x7614, 0x76B8, 0x7781, 0x777C, 0x7785, 0x7782, 0x776E, 0x7780, - 0x776F, 0x777E, 0x7783, 0x78B2, 0x78AA, 0x78B4, 0x78AD, 0x78A8, 0x787E, 0x78AB, 0x789E, 0x78A5, 0x78A0, 0x78AC, 0x78A2, 0x78A4, - 0x7998, 0x798A, 0x798B, 0x7996, 0x7995, 0x7994, 0x7993, - /* Big5-HKSCS 0xE340 .. 0xE37E */ - 0x7997, 0x7988, 0x7992, 0x7990, 0x7A2B, 0x7A4A, 0x7A30, 0x7A2F, 0x7A28, 0x7A26, 0x7AA8, 0x7AAB, 0x7AAC, 0x7AEE, 0x7B88, 0x7B9C, - 0x7B8A, 0x7B91, 0x7B90, 0x7B96, 0x7B8D, 0x7B8C, 0x7B9B, 0x7B8E, 0x7B85, 0x7B98, 0x5284, 0x7B99, 0x7BA4, 0x7B82, 0x7CBB, 0x7CBF, - 0x7CBC, 0x7CBA, 0x7DA7, 0x7DB7, 0x7DC2, 0x7DA3, 0x7DAA, 0x7DC1, 0x7DC0, 0x7DC5, 0x7D9D, 0x7DCE, 0x7DC4, 0x7DC6, 0x7DCB, 0x7DCC, - 0x7DAF, 0x7DB9, 0x7D96, 0x7DBC, 0x7D9F, 0x7DA6, 0x7DAE, 0x7DA9, 0x7DA1, 0x7DC9, 0x7F73, 0x7FE2, 0x7FE3, 0x7FE5, 0x7FDE, - /* Big5-HKSCS 0xE3A1 .. 0xE3FE */ - 0x8024, 0x805D, 0x805C, 0x8189, 0x8186, 0x8183, 0x8187, - 0x818D, 0x818C, 0x818B, 0x8215, 0x8497, 0x84A4, 0x84A1, 0x849F, 0x84BA, 0x84CE, 0x84C2, 0x84AC, 0x84AE, 0x84AB, 0x84B9, 0x84B4, - 0x84C1, 0x84CD, 0x84AA, 0x849A, 0x84B1, 0x84D0, 0x849D, 0x84A7, 0x84BB, 0x84A2, 0x8494, 0x84C7, 0x84CC, 0x849B, 0x84A9, 0x84AF, - 0x84A8, 0x84D6, 0x8498, 0x84B6, 0x84CF, 0x84A0, 0x84D7, 0x84D4, 0x84D2, 0x84DB, 0x84B0, 0x8491, 0x8661, 0x8733, 0x8723, 0x8728, - 0x876B, 0x8740, 0x872E, 0x871E, 0x8721, 0x8719, 0x871B, 0x8743, 0x872C, 0x8741, 0x873E, 0x8746, 0x8720, 0x8732, 0x872A, 0x872D, - 0x873C, 0x8712, 0x873A, 0x8731, 0x8735, 0x8742, 0x8726, 0x8727, 0x8738, 0x8724, 0x871A, 0x8730, 0x8711, 0x88F7, 0x88E7, 0x88F1, - 0x88F2, 0x88FA, 0x88FE, 0x88EE, 0x88FC, 0x88F6, 0x88FB, - /* Big5-HKSCS 0xE440 .. 0xE47E */ - 0x88F0, 0x88EC, 0x88EB, 0x899D, 0x89A1, 0x899F, 0x899E, 0x89E9, 0x89EB, 0x89E8, 0x8AAB, 0x8A99, 0x8A8B, 0x8A92, 0x8A8F, 0x8A96, - 0x8C3D, 0x8C68, 0x8C69, 0x8CD5, 0x8CCF, 0x8CD7, 0x8D96, 0x8E09, 0x8E02, 0x8DFF, 0x8E0D, 0x8DFD, 0x8E0A, 0x8E03, 0x8E07, 0x8E06, - 0x8E05, 0x8DFE, 0x8E00, 0x8E04, 0x8F10, 0x8F11, 0x8F0E, 0x8F0D, 0x9123, 0x911C, 0x9120, 0x9122, 0x911F, 0x911D, 0x911A, 0x9124, - 0x9121, 0x911B, 0x917A, 0x9172, 0x9179, 0x9173, 0x92A5, 0x92A4, 0x9276, 0x929B, 0x927A, 0x92A0, 0x9294, 0x92AA, 0x928D, - /* Big5-HKSCS 0xE4A1 .. 0xE4FE */ - 0x92A6, 0x929A, 0x92AB, 0x9279, 0x9297, 0x927F, 0x92A3, - 0x92EE, 0x928E, 0x9282, 0x9295, 0x92A2, 0x927D, 0x9288, 0x92A1, 0x928A, 0x9286, 0x928C, 0x9299, 0x92A7, 0x927E, 0x9287, 0x92A9, - 0x929D, 0x928B, 0x922D, 0x969E, 0x96A1, 0x96FF, 0x9758, 0x977D, 0x977A, 0x977E, 0x9783, 0x9780, 0x9782, 0x977B, 0x9784, 0x9781, - 0x977F, 0x97CE, 0x97CD, 0x9816, 0x98AD, 0x98AE, 0x9902, 0x9900, 0x9907, 0x999D, 0x999C, 0x99C3, 0x99B9, 0x99BB, 0x99BA, 0x99C2, - 0x99BD, 0x99C7, 0x9AB1, 0x9AE3, 0x9AE7, 0x9B3E, 0x9B3F, 0x9B60, 0x9B61, 0x9B5F, 0x9CF1, 0x9CF2, 0x9CF5, 0x9EA7, 0x50FF, 0x5103, - 0x5130, 0x50F8, 0x5106, 0x5107, 0x50F6, 0x50FE, 0x510B, 0x510C, 0x50FD, 0x510A, 0x528B, 0x528C, 0x52F1, 0x52EF, 0x5648, 0x5642, - 0x564C, 0x5635, 0x5641, 0x564A, 0x5649, 0x5646, 0x5658, - /* Big5-HKSCS 0xE540 .. 0xE57E */ - 0x565A, 0x5640, 0x5633, 0x563D, 0x562C, 0x563E, 0x5638, 0x562A, 0x563A, 0x571A, 0x58AB, 0x589D, 0x58B1, 0x58A0, 0x58A3, 0x58AF, - 0x58AC, 0x58A5, 0x58A1, 0x58FF, 0x5AFF, 0x5AF4, 0x5AFD, 0x5AF7, 0x5AF6, 0x5B03, 0x5AF8, 0x5B02, 0x5AF9, 0x5B01, 0x5B07, 0x5B05, - 0x5B0F, 0x5C67, 0x5D99, 0x5D97, 0x5D9F, 0x5D92, 0x5DA2, 0x5D93, 0x5D95, 0x5DA0, 0x5D9C, 0x5DA1, 0x5D9A, 0x5D9E, 0x5E69, 0x5E5D, - 0x5E60, 0x5E5C, 0x7DF3, 0x5EDB, 0x5EDE, 0x5EE1, 0x5F49, 0x5FB2, 0x618B, 0x6183, 0x6179, 0x61B1, 0x61B0, 0x61A2, 0x6189, - /* Big5-HKSCS 0xE5A1 .. 0xE5FE */ - 0x619B, 0x6193, 0x61AF, 0x61AD, 0x619F, 0x6192, 0x61AA, - 0x61A1, 0x618D, 0x6166, 0x61B3, 0x622D, 0x646E, 0x6470, 0x6496, 0x64A0, 0x6485, 0x6497, 0x649C, 0x648F, 0x648B, 0x648A, 0x648C, - 0x64A3, 0x649F, 0x6468, 0x64B1, 0x6498, 0x6576, 0x657A, 0x6579, 0x657B, 0x65B2, 0x65B3, 0x66B5, 0x66B0, 0x66A9, 0x66B2, 0x66B7, - 0x66AA, 0x66AF, 0x6A00, 0x6A06, 0x6A17, 0x69E5, 0x69F8, 0x6A15, 0x69F1, 0x69E4, 0x6A20, 0x69FF, 0x69EC, 0x69E2, 0x6A1B, 0x6A1D, - 0x69FE, 0x6A27, 0x69F2, 0x69EE, 0x6A14, 0x69F7, 0x69E7, 0x6A40, 0x6A08, 0x69E6, 0x69FB, 0x6A0D, 0x69FC, 0x69EB, 0x6A09, 0x6A04, - 0x6A18, 0x6A25, 0x6A0F, 0x69F6, 0x6A26, 0x6A07, 0x69F4, 0x6A16, 0x6B51, 0x6BA5, 0x6BA3, 0x6BA2, 0x6BA6, 0x6C01, 0x6C00, 0x6BFF, - 0x6C02, 0x6F41, 0x6F26, 0x6F7E, 0x6F87, 0x6FC6, 0x6F92, - /* Big5-HKSCS 0xE640 .. 0xE67E */ - 0x6F8D, 0x6F89, 0x6F8C, 0x6F62, 0x6F4F, 0x6F85, 0x6F5A, 0x6F96, 0x6F76, 0x6F6C, 0x6F82, 0x6F55, 0x6F72, 0x6F52, 0x6F50, 0x6F57, - 0x6F94, 0x6F93, 0x6F5D, 0x6F00, 0x6F61, 0x6F6B, 0x6F7D, 0x6F67, 0x6F90, 0x6F53, 0x6F8B, 0x6F69, 0x6F7F, 0x6F95, 0x6F63, 0x6F77, - 0x6F6A, 0x6F7B, 0x71B2, 0x71AF, 0x719B, 0x71B0, 0x71A0, 0x719A, 0x71A9, 0x71B5, 0x719D, 0x71A5, 0x719E, 0x71A4, 0x71A1, 0x71AA, - 0x719C, 0x71A7, 0x71B3, 0x7298, 0x729A, 0x7358, 0x7352, 0x735E, 0x735F, 0x7360, 0x735D, 0x735B, 0x7361, 0x735A, 0x7359, - /* Big5-HKSCS 0xE6A1 .. 0xE6FE */ - 0x7362, 0x7487, 0x7489, 0x748A, 0x7486, 0x7481, 0x747D, - 0x7485, 0x7488, 0x747C, 0x7479, 0x7508, 0x7507, 0x757E, 0x7625, 0x761E, 0x7619, 0x761D, 0x761C, 0x7623, 0x761A, 0x7628, 0x761B, - 0x769C, 0x769D, 0x769E, 0x769B, 0x778D, 0x778F, 0x7789, 0x7788, 0x78CD, 0x78BB, 0x78CF, 0x78CC, 0x78D1, 0x78CE, 0x78D4, 0x78C8, - 0x78C3, 0x78C4, 0x78C9, 0x799A, 0x79A1, 0x79A0, 0x799C, 0x79A2, 0x799B, 0x6B76, 0x7A39, 0x7AB2, 0x7AB4, 0x7AB3, 0x7BB7, 0x7BCB, - 0x7BBE, 0x7BAC, 0x7BCE, 0x7BAF, 0x7BB9, 0x7BCA, 0x7BB5, 0x7CC5, 0x7CC8, 0x7CCC, 0x7CCB, 0x7DF7, 0x7DDB, 0x7DEA, 0x7DE7, 0x7DD7, - 0x7DE1, 0x7E03, 0x7DFA, 0x7DE6, 0x7DF6, 0x7DF1, 0x7DF0, 0x7DEE, 0x7DDF, 0x7F76, 0x7FAC, 0x7FB0, 0x7FAD, 0x7FED, 0x7FEB, 0x7FEA, - 0x7FEC, 0x7FE6, 0x7FE8, 0x8064, 0x8067, 0x81A3, 0x819F, - /* Big5-HKSCS 0xE740 .. 0xE77E */ - 0x819E, 0x8195, 0x81A2, 0x8199, 0x8197, 0x8216, 0x824F, 0x8253, 0x8252, 0x8250, 0x824E, 0x8251, 0x8524, 0x853B, 0x850F, 0x8500, - 0x8529, 0x850E, 0x8509, 0x850D, 0x851F, 0x850A, 0x8527, 0x851C, 0x84FB, 0x852B, 0x84FA, 0x8508, 0x850C, 0x84F4, 0x852A, 0x84F2, - 0x8515, 0x84F7, 0x84EB, 0x84F3, 0x84FC, 0x8512, 0x84EA, 0x84E9, 0x8516, 0x84FE, 0x8528, 0x851D, 0x852E, 0x8502, 0x84FD, 0x851E, - 0x84F6, 0x8531, 0x8526, 0x84E7, 0x84E8, 0x84F0, 0x84EF, 0x84F9, 0x8518, 0x8520, 0x8530, 0x850B, 0x8519, 0x852F, 0x8662, - /* Big5-HKSCS 0xE7A1 .. 0xE7FE */ - 0x8756, 0x8763, 0x8764, 0x8777, 0x87E1, 0x8773, 0x8758, - 0x8754, 0x875B, 0x8752, 0x8761, 0x875A, 0x8751, 0x875E, 0x876D, 0x876A, 0x8750, 0x874E, 0x875F, 0x875D, 0x876F, 0x876C, 0x877A, - 0x876E, 0x875C, 0x8765, 0x874F, 0x877B, 0x8775, 0x8762, 0x8767, 0x8769, 0x885A, 0x8905, 0x890C, 0x8914, 0x890B, 0x8917, 0x8918, - 0x8919, 0x8906, 0x8916, 0x8911, 0x890E, 0x8909, 0x89A2, 0x89A4, 0x89A3, 0x89ED, 0x89F0, 0x89EC, 0x8ACF, 0x8AC6, 0x8AB8, 0x8AD3, - 0x8AD1, 0x8AD4, 0x8AD5, 0x8ABB, 0x8AD7, 0x8ABE, 0x8AC0, 0x8AC5, 0x8AD8, 0x8AC3, 0x8ABA, 0x8ABD, 0x8AD9, 0x8C3E, 0x8C4D, 0x8C8F, - 0x8CE5, 0x8CDF, 0x8CD9, 0x8CE8, 0x8CDA, 0x8CDD, 0x8CE7, 0x8DA0, 0x8D9C, 0x8DA1, 0x8D9B, 0x8E20, 0x8E23, 0x8E25, 0x8E24, 0x8E2E, - 0x8E15, 0x8E1B, 0x8E16, 0x8E11, 0x8E19, 0x8E26, 0x8E27, - /* Big5-HKSCS 0xE840 .. 0xE87E */ - 0x8E14, 0x8E12, 0x8E18, 0x8E13, 0x8E1C, 0x8E17, 0x8E1A, 0x8F2C, 0x8F24, 0x8F18, 0x8F1A, 0x8F20, 0x8F23, 0x8F16, 0x8F17, 0x9073, - 0x9070, 0x906F, 0x9067, 0x906B, 0x912F, 0x912B, 0x9129, 0x912A, 0x9132, 0x9126, 0x912E, 0x9185, 0x9186, 0x918A, 0x9181, 0x9182, - 0x9184, 0x9180, 0x92D0, 0x92C3, 0x92C4, 0x92C0, 0x92D9, 0x92B6, 0x92CF, 0x92F1, 0x92DF, 0x92D8, 0x92E9, 0x92D7, 0x92DD, 0x92CC, - 0x92EF, 0x92C2, 0x92E8, 0x92CA, 0x92C8, 0x92CE, 0x92E6, 0x92CD, 0x92D5, 0x92C9, 0x92E0, 0x92DE, 0x92E7, 0x92D1, 0x92D3, - /* Big5-HKSCS 0xE8A1 .. 0xE8FE */ - 0x92B5, 0x92E1, 0x92C6, 0x92B4, 0x957C, 0x95AC, 0x95AB, - 0x95AE, 0x95B0, 0x96A4, 0x96A2, 0x96D3, 0x9705, 0x9708, 0x9702, 0x975A, 0x978A, 0x978E, 0x9788, 0x97D0, 0x97CF, 0x981E, 0x981D, - 0x9826, 0x9829, 0x9828, 0x9820, 0x981B, 0x9827, 0x98B2, 0x9908, 0x98FA, 0x9911, 0x9914, 0x9916, 0x9917, 0x9915, 0x99DC, 0x99CD, - 0x99CF, 0x99D3, 0x99D4, 0x99CE, 0x99C9, 0x99D6, 0x99D8, 0x99CB, 0x99D7, 0x99CC, 0x9AB3, 0x9AEC, 0x9AEB, 0x9AF3, 0x9AF2, 0x9AF1, - 0x9B46, 0x9B43, 0x9B67, 0x9B74, 0x9B71, 0x9B66, 0x9B76, 0x9B75, 0x9B70, 0x9B68, 0x9B64, 0x9B6C, 0x9CFC, 0x9CFA, 0x9CFD, 0x9CFF, - 0x9CF7, 0x9D07, 0x9D00, 0x9CF9, 0x9CFB, 0x9D08, 0x9D05, 0x9D04, 0x9E83, 0x9ED3, 0x9F0F, 0x9F10, 0x511C, 0x5113, 0x5117, 0x511A, - 0x5111, 0x51DE, 0x5334, 0x53E1, 0x5670, 0x5660, 0x566E, - /* Big5-HKSCS 0xE940 .. 0xE97E */ - 0x5673, 0x5666, 0x5663, 0x566D, 0x5672, 0x565E, 0x5677, 0x571C, 0x571B, 0x58C8, 0x58BD, 0x58C9, 0x58BF, 0x58BA, 0x58C2, 0x58BC, - 0x58C6, 0x5B17, 0x5B19, 0x5B1B, 0x5B21, 0x5B14, 0x5B13, 0x5B10, 0x5B16, 0x5B28, 0x5B1A, 0x5B20, 0x5B1E, 0x5BEF, 0x5DAC, 0x5DB1, - 0x5DA9, 0x5DA7, 0x5DB5, 0x5DB0, 0x5DAE, 0x5DAA, 0x5DA8, 0x5DB2, 0x5DAD, 0x5DAF, 0x5DB4, 0x5E67, 0x5E68, 0x5E66, 0x5E6F, 0x5EE9, - 0x5EE7, 0x5EE6, 0x5EE8, 0x5EE5, 0x5F4B, 0x5FBC, 0x619D, 0x61A8, 0x6196, 0x61C5, 0x61B4, 0x61C6, 0x61C1, 0x61CC, 0x61BA, - /* Big5-HKSCS 0xE9A1 .. 0xE9FE */ - 0x61BF, 0x61B8, 0x618C, 0x64D7, 0x64D6, 0x64D0, 0x64CF, - 0x64C9, 0x64BD, 0x6489, 0x64C3, 0x64DB, 0x64F3, 0x64D9, 0x6533, 0x657F, 0x657C, 0x65A2, 0x66C8, 0x66BE, 0x66C0, 0x66CA, 0x66CB, - 0x66CF, 0x66BD, 0x66BB, 0x66BA, 0x66CC, 0x6723, 0x6A34, 0x6A66, 0x6A49, 0x6A67, 0x6A32, 0x6A68, 0x6A3E, 0x6A5D, 0x6A6D, 0x6A76, - 0x6A5B, 0x6A51, 0x6A28, 0x6A5A, 0x6A3B, 0x6A3F, 0x6A41, 0x6A6A, 0x6A64, 0x6A50, 0x6A4F, 0x6A54, 0x6A6F, 0x6A69, 0x6A60, 0x6A3C, - 0x6A5E, 0x6A56, 0x6A55, 0x6A4D, 0x6A4E, 0x6A46, 0x6B55, 0x6B54, 0x6B56, 0x6BA7, 0x6BAA, 0x6BAB, 0x6BC8, 0x6BC7, 0x6C04, 0x6C03, - 0x6C06, 0x6FAD, 0x6FCB, 0x6FA3, 0x6FC7, 0x6FBC, 0x6FCE, 0x6FC8, 0x6F5E, 0x6FC4, 0x6FBD, 0x6F9E, 0x6FCA, 0x6FA8, 0x7004, 0x6FA5, - 0x6FAE, 0x6FBA, 0x6FAC, 0x6FAA, 0x6FCF, 0x6FBF, 0x6FB8, - /* Big5-HKSCS 0xEA40 .. 0xEA7E */ - 0x6FA2, 0x6FC9, 0x6FAB, 0x6FCD, 0x6FAF, 0x6FB2, 0x6FB0, 0x71C5, 0x71C2, 0x71BF, 0x71B8, 0x71D6, 0x71C0, 0x71C1, 0x71CB, 0x71D4, - 0x71CA, 0x71C7, 0x71CF, 0x71BD, 0x71D8, 0x71BC, 0x71C6, 0x71DA, 0x71DB, 0x729D, 0x729E, 0x7369, 0x7366, 0x7367, 0x736C, 0x7365, - 0x736B, 0x736A, 0x747F, 0x749A, 0x74A0, 0x7494, 0x7492, 0x7495, 0x74A1, 0x750B, 0x7580, 0x762F, 0x762D, 0x7631, 0x763D, 0x7633, - 0x763C, 0x7635, 0x7632, 0x7630, 0x76BB, 0x76E6, 0x779A, 0x779D, 0x77A1, 0x779C, 0x779B, 0x77A2, 0x77A3, 0x7795, 0x7799, - /* Big5-HKSCS 0xEAA1 .. 0xEAFE */ - 0x7797, 0x78DD, 0x78E9, 0x78E5, 0x78EA, 0x78DE, 0x78E3, - 0x78DB, 0x78E1, 0x78E2, 0x78ED, 0x78DF, 0x78E0, 0x79A4, 0x7A44, 0x7A48, 0x7A47, 0x7AB6, 0x7AB8, 0x7AB5, 0x7AB1, 0x7AB7, 0x7BDE, - 0x7BE3, 0x7BE7, 0x7BDD, 0x7BD5, 0x7BE5, 0x7BDA, 0x7BE8, 0x7BF9, 0x7BD4, 0x7BEA, 0x7BE2, 0x7BDC, 0x7BEB, 0x7BD8, 0x7BDF, 0x7CD2, - 0x7CD4, 0x7CD7, 0x7CD0, 0x7CD1, 0x7E12, 0x7E21, 0x7E17, 0x7E0C, 0x7E1F, 0x7E20, 0x7E13, 0x7E0E, 0x7E1C, 0x7E15, 0x7E1A, 0x7E22, - 0x7E0B, 0x7E0F, 0x7E16, 0x7E0D, 0x7E14, 0x7E25, 0x7E24, 0x7F43, 0x7F7B, 0x7F7C, 0x7F7A, 0x7FB1, 0x7FEF, 0x802A, 0x8029, 0x806C, - 0x81B1, 0x81A6, 0x81AE, 0x81B9, 0x81B5, 0x81AB, 0x81B0, 0x81AC, 0x81B4, 0x81B2, 0x81B7, 0x81A7, 0x81F2, 0x8255, 0x8256, 0x8257, - 0x8556, 0x8545, 0x856B, 0x854D, 0x8553, 0x8561, 0x8558, - /* Big5-HKSCS 0xEB40 .. 0xEB7E */ - 0x8540, 0x8546, 0x8564, 0x8541, 0x8562, 0x8544, 0x8551, 0x8547, 0x8563, 0x853E, 0x855B, 0x8571, 0x854E, 0x856E, 0x8575, 0x8555, - 0x8567, 0x8560, 0x858C, 0x8566, 0x855D, 0x8554, 0x8565, 0x856C, 0x8663, 0x8665, 0x8664, 0x879B, 0x878F, 0x8797, 0x8793, 0x8792, - 0x8788, 0x8781, 0x8796, 0x8798, 0x8779, 0x8787, 0x87A3, 0x8785, 0x8790, 0x8791, 0x879D, 0x8784, 0x8794, 0x879C, 0x879A, 0x8789, - 0x891E, 0x8926, 0x8930, 0x892D, 0x892E, 0x8927, 0x8931, 0x8922, 0x8929, 0x8923, 0x892F, 0x892C, 0x891F, 0x89F1, 0x8AE0, - /* Big5-HKSCS 0xEBA1 .. 0xEBFE */ - 0x8AE2, 0x8AF2, 0x8AF4, 0x8AF5, 0x8ADD, 0x8B14, 0x8AE4, - 0x8ADF, 0x8AF0, 0x8AC8, 0x8ADE, 0x8AE1, 0x8AE8, 0x8AFF, 0x8AEF, 0x8AFB, 0x8C91, 0x8C92, 0x8C90, 0x8CF5, 0x8CEE, 0x8CF1, 0x8CF0, - 0x8CF3, 0x8D6C, 0x8D6E, 0x8DA5, 0x8DA7, 0x8E33, 0x8E3E, 0x8E38, 0x8E40, 0x8E45, 0x8E36, 0x8E3C, 0x8E3D, 0x8E41, 0x8E30, 0x8E3F, - 0x8EBD, 0x8F36, 0x8F2E, 0x8F35, 0x8F32, 0x8F39, 0x8F37, 0x8F34, 0x9076, 0x9079, 0x907B, 0x9086, 0x90FA, 0x9133, 0x9135, 0x9136, - 0x9193, 0x9190, 0x9191, 0x918D, 0x918F, 0x9327, 0x931E, 0x9308, 0x931F, 0x9306, 0x930F, 0x937A, 0x9338, 0x933C, 0x931B, 0x9323, - 0x9312, 0x9301, 0x9346, 0x932D, 0x930E, 0x930D, 0x92CB, 0x931D, 0x92FA, 0x9325, 0x9313, 0x92F9, 0x92F7, 0x9334, 0x9302, 0x9324, - 0x92FF, 0x9329, 0x9339, 0x9335, 0x932A, 0x9314, 0x930C, - /* Big5-HKSCS 0xEC40 .. 0xEC7E */ - 0x930B, 0x92FE, 0x9309, 0x9300, 0x92FB, 0x9316, 0x95BC, 0x95CD, 0x95BE, 0x95B9, 0x95BA, 0x95B6, 0x95BF, 0x95B5, 0x95BD, 0x96A9, - 0x96D4, 0x970B, 0x9712, 0x9710, 0x9799, 0x9797, 0x9794, 0x97F0, 0x97F8, 0x9835, 0x982F, 0x9832, 0x9924, 0x991F, 0x9927, 0x9929, - 0x999E, 0x99EE, 0x99EC, 0x99E5, 0x99E4, 0x99F0, 0x99E3, 0x99EA, 0x99E9, 0x99E7, 0x9AB9, 0x9ABF, 0x9AB4, 0x9ABB, 0x9AF6, 0x9AFA, - 0x9AF9, 0x9AF7, 0x9B33, 0x9B80, 0x9B85, 0x9B87, 0x9B7C, 0x9B7E, 0x9B7B, 0x9B82, 0x9B93, 0x9B92, 0x9B90, 0x9B7A, 0x9B95, - /* Big5-HKSCS 0xECA1 .. 0xECFE */ - 0x9B7D, 0x9B88, 0x9D25, 0x9D17, 0x9D20, 0x9D1E, 0x9D14, - 0x9D29, 0x9D1D, 0x9D18, 0x9D22, 0x9D10, 0x9D19, 0x9D1F, 0x9E88, 0x9E86, 0x9E87, 0x9EAE, 0x9EAD, 0x9ED5, 0x9ED6, 0x9EFA, 0x9F12, - 0x9F3D, 0x5126, 0x5125, 0x5122, 0x5124, 0x5120, 0x5129, 0x52F4, 0x5693, 0x568C, 0x568D, 0x5686, 0x5684, 0x5683, 0x567E, 0x5682, - 0x567F, 0x5681, 0x58D6, 0x58D4, 0x58CF, 0x58D2, 0x5B2D, 0x5B25, 0x5B32, 0x5B23, 0x5B2C, 0x5B27, 0x5B26, 0x5B2F, 0x5B2E, 0x5B7B, - 0x5BF1, 0x5BF2, 0x5DB7, 0x5E6C, 0x5E6A, 0x5FBE, 0x5FBB, 0x61C3, 0x61B5, 0x61BC, 0x61E7, 0x61E0, 0x61E5, 0x61E4, 0x61E8, 0x61DE, - 0x64EF, 0x64E9, 0x64E3, 0x64EB, 0x64E4, 0x64E8, 0x6581, 0x6580, 0x65B6, 0x65DA, 0x66D2, 0x6A8D, 0x6A96, 0x6A81, 0x6AA5, 0x6A89, - 0x6A9F, 0x6A9B, 0x6AA1, 0x6A9E, 0x6A87, 0x6A93, 0x6A8E, - /* Big5-HKSCS 0xED40 .. 0xED7E */ - 0x6A95, 0x6A83, 0x6AA8, 0x6AA4, 0x6A91, 0x6A7F, 0x6AA6, 0x6A9A, 0x6A85, 0x6A8C, 0x6A92, 0x6B5B, 0x6BAD, 0x6C09, 0x6FCC, 0x6FA9, - 0x6FF4, 0x6FD4, 0x6FE3, 0x6FDC, 0x6FED, 0x6FE7, 0x6FE6, 0x6FDE, 0x6FF2, 0x6FDD, 0x6FE2, 0x6FE8, 0x71E1, 0x71F1, 0x71E8, 0x71F2, - 0x71E4, 0x71F0, 0x71E2, 0x7373, 0x736E, 0x736F, 0x7497, 0x74B2, 0x74AB, 0x7490, 0x74AA, 0x74AD, 0x74B1, 0x74A5, 0x74AF, 0x7510, - 0x7511, 0x7512, 0x750F, 0x7584, 0x7643, 0x7648, 0x7649, 0x7647, 0x76A4, 0x76E9, 0x77B5, 0x77AB, 0x77B2, 0x77B7, 0x77B6, - /* Big5-HKSCS 0xEDA1 .. 0xEDFE */ - 0x77B4, 0x77B1, 0x77A8, 0x77F0, 0x78F3, 0x78FD, 0x7902, - 0x78FB, 0x78FC, 0x78F2, 0x7905, 0x78F9, 0x78FE, 0x7904, 0x79AB, 0x79A8, 0x7A5C, 0x7A5B, 0x7A56, 0x7A58, 0x7A54, 0x7A5A, 0x7ABE, - 0x7AC0, 0x7AC1, 0x7C05, 0x7C0F, 0x7BF2, 0x7C00, 0x7BFF, 0x7BFB, 0x7C0E, 0x7BF4, 0x7C0B, 0x7BF3, 0x7C02, 0x7C09, 0x7C03, 0x7C01, - 0x7BF8, 0x7BFD, 0x7C06, 0x7BF0, 0x7BF1, 0x7C10, 0x7C0A, 0x7CE8, 0x7E2D, 0x7E3C, 0x7E42, 0x7E33, 0x9848, 0x7E38, 0x7E2A, 0x7E49, - 0x7E40, 0x7E47, 0x7E29, 0x7E4C, 0x7E30, 0x7E3B, 0x7E36, 0x7E44, 0x7E3A, 0x7F45, 0x7F7F, 0x7F7E, 0x7F7D, 0x7FF4, 0x7FF2, 0x802C, - 0x81BB, 0x81C4, 0x81CC, 0x81CA, 0x81C5, 0x81C7, 0x81BC, 0x81E9, 0x825B, 0x825A, 0x825C, 0x8583, 0x8580, 0x858F, 0x85A7, 0x8595, - 0x85A0, 0x858B, 0x85A3, 0x857B, 0x85A4, 0x859A, 0x859E, - /* Big5-HKSCS 0xEE40 .. 0xEE7E */ - 0x8577, 0x857C, 0x8589, 0x85A1, 0x857A, 0x8578, 0x8557, 0x858E, 0x8596, 0x8586, 0x858D, 0x8599, 0x859D, 0x8581, 0x85A2, 0x8582, - 0x8588, 0x8585, 0x8579, 0x8576, 0x8598, 0x8590, 0x859F, 0x8668, 0x87BE, 0x87AA, 0x87AD, 0x87C5, 0x87B0, 0x87AC, 0x87B9, 0x87B5, - 0x87BC, 0x87AE, 0x87C9, 0x87C3, 0x87C2, 0x87CC, 0x87B7, 0x87AF, 0x87C4, 0x87CA, 0x87B4, 0x87B6, 0x87BF, 0x87B8, 0x87BD, 0x87DE, - 0x87B2, 0x8935, 0x8933, 0x893C, 0x893E, 0x8941, 0x8952, 0x8937, 0x8942, 0x89AD, 0x89AF, 0x89AE, 0x89F2, 0x89F3, 0x8B1E, - /* Big5-HKSCS 0xEEA1 .. 0xEEFE */ - 0x8B18, 0x8B16, 0x8B11, 0x8B05, 0x8B0B, 0x8B22, 0x8B0F, - 0x8B12, 0x8B15, 0x8B07, 0x8B0D, 0x8B08, 0x8B06, 0x8B1C, 0x8B13, 0x8B1A, 0x8C4F, 0x8C70, 0x8C72, 0x8C71, 0x8C6F, 0x8C95, 0x8C94, - 0x8CF9, 0x8D6F, 0x8E4E, 0x8E4D, 0x8E53, 0x8E50, 0x8E4C, 0x8E47, 0x8F43, 0x8F40, 0x9085, 0x907E, 0x9138, 0x919A, 0x91A2, 0x919B, - 0x9199, 0x919F, 0x91A1, 0x919D, 0x91A0, 0x93A1, 0x9383, 0x93AF, 0x9364, 0x9356, 0x9347, 0x937C, 0x9358, 0x935C, 0x9376, 0x9349, - 0x9350, 0x9351, 0x9360, 0x936D, 0x938F, 0x934C, 0x936A, 0x9379, 0x9357, 0x9355, 0x9352, 0x934F, 0x9371, 0x9377, 0x937B, 0x9361, - 0x935E, 0x9363, 0x9367, 0x9380, 0x934E, 0x9359, 0x95C7, 0x95C0, 0x95C9, 0x95C3, 0x95C5, 0x95B7, 0x96AE, 0x96B0, 0x96AC, 0x9720, - 0x971F, 0x9718, 0x971D, 0x9719, 0x979A, 0x97A1, 0x979C, - /* Big5-HKSCS 0xEF40 .. 0xEF7E */ - 0x979E, 0x979D, 0x97D5, 0x97D4, 0x97F1, 0x9841, 0x9844, 0x984A, 0x9849, 0x9845, 0x9843, 0x9925, 0x992B, 0x992C, 0x992A, 0x9933, - 0x9932, 0x992F, 0x992D, 0x9931, 0x9930, 0x9998, 0x99A3, 0x99A1, 0x9A02, 0x99FA, 0x99F4, 0x99F7, 0x99F9, 0x99F8, 0x99F6, 0x99FB, - 0x99FD, 0x99FE, 0x99FC, 0x9A03, 0x9ABE, 0x9AFE, 0x9AFD, 0x9B01, 0x9AFC, 0x9B48, 0x9B9A, 0x9BA8, 0x9B9E, 0x9B9B, 0x9BA6, 0x9BA1, - 0x9BA5, 0x9BA4, 0x9B86, 0x9BA2, 0x9BA0, 0x9BAF, 0x9D33, 0x9D41, 0x9D67, 0x9D36, 0x9D2E, 0x9D2F, 0x9D31, 0x9D38, 0x9D30, - /* Big5-HKSCS 0xEFA1 .. 0xEFFE */ - 0x9D45, 0x9D42, 0x9D43, 0x9D3E, 0x9D37, 0x9D40, 0x9D3D, - 0x7FF5, 0x9D2D, 0x9E8A, 0x9E89, 0x9E8D, 0x9EB0, 0x9EC8, 0x9EDA, 0x9EFB, 0x9EFF, 0x9F24, 0x9F23, 0x9F22, 0x9F54, 0x9FA0, 0x5131, - 0x512D, 0x512E, 0x5698, 0x569C, 0x5697, 0x569A, 0x569D, 0x5699, 0x5970, 0x5B3C, 0x5C69, 0x5C6A, 0x5DC0, 0x5E6D, 0x5E6E, 0x61D8, - 0x61DF, 0x61ED, 0x61EE, 0x61F1, 0x61EA, 0x61F0, 0x61EB, 0x61D6, 0x61E9, 0x64FF, 0x6504, 0x64FD, 0x64F8, 0x6501, 0x6503, 0x64FC, - 0x6594, 0x65DB, 0x66DA, 0x66DB, 0x66D8, 0x6AC5, 0x6AB9, 0x6ABD, 0x6AE1, 0x6AC6, 0x6ABA, 0x6AB6, 0x6AB7, 0x6AC7, 0x6AB4, 0x6AAD, - 0x6B5E, 0x6BC9, 0x6C0B, 0x7007, 0x700C, 0x700D, 0x7001, 0x7005, 0x7014, 0x700E, 0x6FFF, 0x7000, 0x6FFB, 0x7026, 0x6FFC, 0x6FF7, - 0x700A, 0x7201, 0x71FF, 0x71F9, 0x7203, 0x71FD, 0x7376, - /* Big5-HKSCS 0xF040 .. 0xF07E */ - 0x74B8, 0x74C0, 0x74B5, 0x74C1, 0x74BE, 0x74B6, 0x74BB, 0x74C2, 0x7514, 0x7513, 0x765C, 0x7664, 0x7659, 0x7650, 0x7653, 0x7657, - 0x765A, 0x76A6, 0x76BD, 0x76EC, 0x77C2, 0x77BA, 0x78FF, 0x790C, 0x7913, 0x7914, 0x7909, 0x7910, 0x7912, 0x7911, 0x79AD, 0x79AC, - 0x7A5F, 0x7C1C, 0x7C29, 0x7C19, 0x7C20, 0x7C1F, 0x7C2D, 0x7C1D, 0x7C26, 0x7C28, 0x7C22, 0x7C25, 0x7C30, 0x7E5C, 0x7E50, 0x7E56, - 0x7E63, 0x7E58, 0x7E62, 0x7E5F, 0x7E51, 0x7E60, 0x7E57, 0x7E53, 0x7FB5, 0x7FB3, 0x7FF7, 0x7FF8, 0x8075, 0x81D1, 0x81D2, - /* Big5-HKSCS 0xF0A1 .. 0xF0FE */ - 0x81D0, 0x825F, 0x825E, 0x85B4, 0x85C6, 0x85C0, 0x85C3, - 0x85C2, 0x85B3, 0x85B5, 0x85BD, 0x85C7, 0x85C4, 0x85BF, 0x85CB, 0x85CE, 0x85C8, 0x85C5, 0x85B1, 0x85B6, 0x85D2, 0x8624, 0x85B8, - 0x85B7, 0x85BE, 0x8669, 0x87E7, 0x87E6, 0x87E2, 0x87DB, 0x87EB, 0x87EA, 0x87E5, 0x87DF, 0x87F3, 0x87E4, 0x87D4, 0x87DC, 0x87D3, - 0x87ED, 0x87D8, 0x87E3, 0x87A4, 0x87D7, 0x87D9, 0x8801, 0x87F4, 0x87E8, 0x87DD, 0x8953, 0x894B, 0x894F, 0x894C, 0x8946, 0x8950, - 0x8951, 0x8949, 0x8B2A, 0x8B27, 0x8B23, 0x8B33, 0x8B30, 0x8B35, 0x8B47, 0x8B2F, 0x8B3C, 0x8B3E, 0x8B31, 0x8B25, 0x8B37, 0x8B26, - 0x8B36, 0x8B2E, 0x8B24, 0x8B3B, 0x8B3D, 0x8B3A, 0x8C42, 0x8C75, 0x8C99, 0x8C98, 0x8C97, 0x8CFE, 0x8D04, 0x8D02, 0x8D00, 0x8E5C, - 0x8E62, 0x8E60, 0x8E57, 0x8E56, 0x8E5E, 0x8E65, 0x8E67, - /* Big5-HKSCS 0xF140 .. 0xF17E */ - 0x8E5B, 0x8E5A, 0x8E61, 0x8E5D, 0x8E69, 0x8E54, 0x8F46, 0x8F47, 0x8F48, 0x8F4B, 0x9128, 0x913A, 0x913B, 0x913E, 0x91A8, 0x91A5, - 0x91A7, 0x91AF, 0x91AA, 0x93B5, 0x938C, 0x9392, 0x93B7, 0x939B, 0x939D, 0x9389, 0x93A7, 0x938E, 0x93AA, 0x939E, 0x93A6, 0x9395, - 0x9388, 0x9399, 0x939F, 0x938D, 0x93B1, 0x9391, 0x93B2, 0x93A4, 0x93A8, 0x93B4, 0x93A3, 0x93A5, 0x95D2, 0x95D3, 0x95D1, 0x96B3, - 0x96D7, 0x96DA, 0x5DC2, 0x96DF, 0x96D8, 0x96DD, 0x9723, 0x9722, 0x9725, 0x97AC, 0x97AE, 0x97A8, 0x97AB, 0x97A4, 0x97AA, - /* Big5-HKSCS 0xF1A1 .. 0xF1FE */ - 0x97A2, 0x97A5, 0x97D7, 0x97D9, 0x97D6, 0x97D8, 0x97FA, - 0x9850, 0x9851, 0x9852, 0x98B8, 0x9941, 0x993C, 0x993A, 0x9A0F, 0x9A0B, 0x9A09, 0x9A0D, 0x9A04, 0x9A11, 0x9A0A, 0x9A05, 0x9A07, - 0x9A06, 0x9AC0, 0x9ADC, 0x9B08, 0x9B04, 0x9B05, 0x9B29, 0x9B35, 0x9B4A, 0x9B4C, 0x9B4B, 0x9BC7, 0x9BC6, 0x9BC3, 0x9BBF, 0x9BC1, - 0x9BB5, 0x9BB8, 0x9BD3, 0x9BB6, 0x9BC4, 0x9BB9, 0x9BBD, 0x9D5C, 0x9D53, 0x9D4F, 0x9D4A, 0x9D5B, 0x9D4B, 0x9D59, 0x9D56, 0x9D4C, - 0x9D57, 0x9D52, 0x9D54, 0x9D5F, 0x9D58, 0x9D5A, 0x9E8E, 0x9E8C, 0x9EDF, 0x9F01, 0x9F00, 0x9F16, 0x9F25, 0x9F2B, 0x9F2A, 0x9F29, - 0x9F28, 0x9F4C, 0x9F55, 0x5134, 0x5135, 0x5296, 0x52F7, 0x53B4, 0x56AB, 0x56AD, 0x56A6, 0x56A7, 0x56AA, 0x56AC, 0x58DA, 0x58DD, - 0x58DB, 0x5912, 0x5B3D, 0x5B3E, 0x5B3F, 0x5DC3, 0x5E70, - /* Big5-HKSCS 0xF240 .. 0xF27E */ - 0x5FBF, 0x61FB, 0x6507, 0x6510, 0x650D, 0x6509, 0x650C, 0x650E, 0x6584, 0x65DE, 0x65DD, 0x66DE, 0x6AE7, 0x6AE0, 0x6ACC, 0x6AD1, - 0x6AD9, 0x6ACB, 0x6ADF, 0x6ADC, 0x6AD0, 0x6AEB, 0x6ACF, 0x6ACD, 0x6ADE, 0x6B60, 0x6BB0, 0x6C0C, 0x7019, 0x7027, 0x7020, 0x7016, - 0x702B, 0x7021, 0x7022, 0x7023, 0x7029, 0x7017, 0x7024, 0x701C, 0x702A, 0x720C, 0x720A, 0x7207, 0x7202, 0x7205, 0x72A5, 0x72A6, - 0x72A4, 0x72A3, 0x72A1, 0x74CB, 0x74C5, 0x74B7, 0x74C3, 0x7516, 0x7660, 0x77C9, 0x77CA, 0x77C4, 0x77F1, 0x791D, 0x791B, - /* Big5-HKSCS 0xF2A1 .. 0xF2FE */ - 0x7921, 0x791C, 0x7917, 0x791E, 0x79B0, 0x7A67, 0x7A68, - 0x7C33, 0x7C3C, 0x7C39, 0x7C2C, 0x7C3B, 0x7CEC, 0x7CEA, 0x7E76, 0x7E75, 0x7E78, 0x7E70, 0x7E77, 0x7E6F, 0x7E7A, 0x7E72, 0x7E74, - 0x7E68, 0x7F4B, 0x7F4A, 0x7F83, 0x7F86, 0x7FB7, 0x7FFD, 0x7FFE, 0x8078, 0x81D7, 0x81D5, 0x8264, 0x8261, 0x8263, 0x85EB, 0x85F1, - 0x85ED, 0x85D9, 0x85E1, 0x85E8, 0x85DA, 0x85D7, 0x85EC, 0x85F2, 0x85F8, 0x85D8, 0x85DF, 0x85E3, 0x85DC, 0x85D1, 0x85F0, 0x85E6, - 0x85EF, 0x85DE, 0x85E2, 0x8800, 0x87FA, 0x8803, 0x87F6, 0x87F7, 0x8809, 0x880C, 0x880B, 0x8806, 0x87FC, 0x8808, 0x87FF, 0x880A, - 0x8802, 0x8962, 0x895A, 0x895B, 0x8957, 0x8961, 0x895C, 0x8958, 0x895D, 0x8959, 0x8988, 0x89B7, 0x89B6, 0x89F6, 0x8B50, 0x8B48, - 0x8B4A, 0x8B40, 0x8B53, 0x8B56, 0x8B54, 0x8B4B, 0x8B55, - /* Big5-HKSCS 0xF340 .. 0xF37E */ - 0x8B51, 0x8B42, 0x8B52, 0x8B57, 0x8C43, 0x8C77, 0x8C76, 0x8C9A, 0x8D06, 0x8D07, 0x8D09, 0x8DAC, 0x8DAA, 0x8DAD, 0x8DAB, 0x8E6D, - 0x8E78, 0x8E73, 0x8E6A, 0x8E6F, 0x8E7B, 0x8EC2, 0x8F52, 0x8F51, 0x8F4F, 0x8F50, 0x8F53, 0x8FB4, 0x9140, 0x913F, 0x91B0, 0x91AD, - 0x93DE, 0x93C7, 0x93CF, 0x93C2, 0x93DA, 0x93D0, 0x93F9, 0x93EC, 0x93CC, 0x93D9, 0x93A9, 0x93E6, 0x93CA, 0x93D4, 0x93EE, 0x93E3, - 0x93D5, 0x93C4, 0x93CE, 0x93C0, 0x93D2, 0x93E7, 0x957D, 0x95DA, 0x95DB, 0x96E1, 0x9729, 0x972B, 0x972C, 0x9728, 0x9726, - /* Big5-HKSCS 0xF3A1 .. 0xF3FE */ - 0x97B3, 0x97B7, 0x97B6, 0x97DD, 0x97DE, 0x97DF, 0x985C, - 0x9859, 0x985D, 0x9857, 0x98BF, 0x98BD, 0x98BB, 0x98BE, 0x9948, 0x9947, 0x9943, 0x99A6, 0x99A7, 0x9A1A, 0x9A15, 0x9A25, 0x9A1D, - 0x9A24, 0x9A1B, 0x9A22, 0x9A20, 0x9A27, 0x9A23, 0x9A1E, 0x9A1C, 0x9A14, 0x9AC2, 0x9B0B, 0x9B0A, 0x9B0E, 0x9B0C, 0x9B37, 0x9BEA, - 0x9BEB, 0x9BE0, 0x9BDE, 0x9BE4, 0x9BE6, 0x9BE2, 0x9BF0, 0x9BD4, 0x9BD7, 0x9BEC, 0x9BDC, 0x9BD9, 0x9BE5, 0x9BD5, 0x9BE1, 0x9BDA, - 0x9D77, 0x9D81, 0x9D8A, 0x9D84, 0x9D88, 0x9D71, 0x9D80, 0x9D78, 0x9D86, 0x9D8B, 0x9D8C, 0x9D7D, 0x9D6B, 0x9D74, 0x9D75, 0x9D70, - 0x9D69, 0x9D85, 0x9D73, 0x9D7B, 0x9D82, 0x9D6F, 0x9D79, 0x9D7F, 0x9D87, 0x9D68, 0x9E94, 0x9E91, 0x9EC0, 0x9EFC, 0x9F2D, 0x9F40, - 0x9F41, 0x9F4D, 0x9F56, 0x9F57, 0x9F58, 0x5337, 0x56B2, - /* Big5-HKSCS 0xF440 .. 0xF47E */ - 0x56B5, 0x56B3, 0x58E3, 0x5B45, 0x5DC6, 0x5DC7, 0x5EEE, 0x5EEF, 0x5FC0, 0x5FC1, 0x61F9, 0x6517, 0x6516, 0x6515, 0x6513, 0x65DF, - 0x66E8, 0x66E3, 0x66E4, 0x6AF3, 0x6AF0, 0x6AEA, 0x6AE8, 0x6AF9, 0x6AF1, 0x6AEE, 0x6AEF, 0x703C, 0x7035, 0x702F, 0x7037, 0x7034, - 0x7031, 0x7042, 0x7038, 0x703F, 0x703A, 0x7039, 0x7040, 0x703B, 0x7033, 0x7041, 0x7213, 0x7214, 0x72A8, 0x737D, 0x737C, 0x74BA, - 0x76AB, 0x76AA, 0x76BE, 0x76ED, 0x77CC, 0x77CE, 0x77CF, 0x77CD, 0x77F2, 0x7925, 0x7923, 0x7927, 0x7928, 0x7924, 0x7929, - /* Big5-HKSCS 0xF4A1 .. 0xF4FE */ - 0x79B2, 0x7A6E, 0x7A6C, 0x7A6D, 0x7AF7, 0x7C49, 0x7C48, - 0x7C4A, 0x7C47, 0x7C45, 0x7CEE, 0x7E7B, 0x7E7E, 0x7E81, 0x7E80, 0x7FBA, 0x7FFF, 0x8079, 0x81DB, 0x81D9, 0x820B, 0x8268, 0x8269, - 0x8622, 0x85FF, 0x8601, 0x85FE, 0x861B, 0x8600, 0x85F6, 0x8604, 0x8609, 0x8605, 0x860C, 0x85FD, 0x8819, 0x8810, 0x8811, 0x8817, - 0x8813, 0x8816, 0x8963, 0x8966, 0x89B9, 0x89F7, 0x8B60, 0x8B6A, 0x8B5D, 0x8B68, 0x8B63, 0x8B65, 0x8B67, 0x8B6D, 0x8DAE, 0x8E86, - 0x8E88, 0x8E84, 0x8F59, 0x8F56, 0x8F57, 0x8F55, 0x8F58, 0x8F5A, 0x908D, 0x9143, 0x9141, 0x91B7, 0x91B5, 0x91B2, 0x91B3, 0x940B, - 0x9413, 0x93FB, 0x9420, 0x940F, 0x9414, 0x93FE, 0x9415, 0x9410, 0x9428, 0x9419, 0x940D, 0x93F5, 0x9400, 0x93F7, 0x9407, 0x940E, - 0x9416, 0x9412, 0x93FA, 0x9409, 0x93F8, 0x940A, 0x93FF, - /* Big5-HKSCS 0xF540 .. 0xF57E */ - 0x93FC, 0x940C, 0x93F6, 0x9411, 0x9406, 0x95DE, 0x95E0, 0x95DF, 0x972E, 0x972F, 0x97B9, 0x97BB, 0x97FD, 0x97FE, 0x9860, 0x9862, - 0x9863, 0x985F, 0x98C1, 0x98C2, 0x9950, 0x994E, 0x9959, 0x994C, 0x994B, 0x9953, 0x9A32, 0x9A34, 0x9A31, 0x9A2C, 0x9A2A, 0x9A36, - 0x9A29, 0x9A2E, 0x9A38, 0x9A2D, 0x9AC7, 0x9ACA, 0x9AC6, 0x9B10, 0x9B12, 0x9B11, 0x9C0B, 0x9C08, 0x9BF7, 0x9C05, 0x9C12, 0x9BF8, - 0x9C40, 0x9C07, 0x9C0E, 0x9C06, 0x9C17, 0x9C14, 0x9C09, 0x9D9F, 0x9D99, 0x9DA4, 0x9D9D, 0x9D92, 0x9D98, 0x9D90, 0x9D9B, - /* Big5-HKSCS 0xF5A1 .. 0xF5FE */ - 0x9DA0, 0x9D94, 0x9D9C, 0x9DAA, 0x9D97, 0x9DA1, 0x9D9A, - 0x9DA2, 0x9DA8, 0x9D9E, 0x9DA3, 0x9DBF, 0x9DA9, 0x9D96, 0x9DA6, 0x9DA7, 0x9E99, 0x9E9B, 0x9E9A, 0x9EE5, 0x9EE4, 0x9EE7, 0x9EE6, - 0x9F30, 0x9F2E, 0x9F5B, 0x9F60, 0x9F5E, 0x9F5D, 0x9F59, 0x9F91, 0x513A, 0x5139, 0x5298, 0x5297, 0x56C3, 0x56BD, 0x56BE, 0x5B48, - 0x5B47, 0x5DCB, 0x5DCF, 0x5EF1, 0x61FD, 0x651B, 0x6B02, 0x6AFC, 0x6B03, 0x6AF8, 0x6B00, 0x7043, 0x7044, 0x704A, 0x7048, 0x7049, - 0x7045, 0x7046, 0x721D, 0x721A, 0x7219, 0x737E, 0x7517, 0x766A, 0x77D0, 0x792D, 0x7931, 0x792F, 0x7C54, 0x7C53, 0x7CF2, 0x7E8A, - 0x7E87, 0x7E88, 0x7E8B, 0x7E86, 0x7E8D, 0x7F4D, 0x7FBB, 0x8030, 0x81DD, 0x8618, 0x862A, 0x8626, 0x861F, 0x8623, 0x861C, 0x8619, - 0x8627, 0x862E, 0x8621, 0x8620, 0x8629, 0x861E, 0x8625, - /* Big5-HKSCS 0xF640 .. 0xF67E */ - 0x8829, 0x881D, 0x881B, 0x8820, 0x8824, 0x881C, 0x882B, 0x884A, 0x896D, 0x8969, 0x896E, 0x896B, 0x89FA, 0x8B79, 0x8B78, 0x8B45, - 0x8B7A, 0x8B7B, 0x8D10, 0x8D14, 0x8DAF, 0x8E8E, 0x8E8C, 0x8F5E, 0x8F5B, 0x8F5D, 0x9146, 0x9144, 0x9145, 0x91B9, 0x943F, 0x943B, - 0x9436, 0x9429, 0x943D, 0x943C, 0x9430, 0x9439, 0x942A, 0x9437, 0x942C, 0x9440, 0x9431, 0x95E5, 0x95E4, 0x95E3, 0x9735, 0x973A, - 0x97BF, 0x97E1, 0x9864, 0x98C9, 0x98C6, 0x98C0, 0x9958, 0x9956, 0x9A39, 0x9A3D, 0x9A46, 0x9A44, 0x9A42, 0x9A41, 0x9A3A, - /* Big5-HKSCS 0xF6A1 .. 0xF6FE */ - 0x9A3F, 0x9ACD, 0x9B15, 0x9B17, 0x9B18, 0x9B16, 0x9B3A, - 0x9B52, 0x9C2B, 0x9C1D, 0x9C1C, 0x9C2C, 0x9C23, 0x9C28, 0x9C29, 0x9C24, 0x9C21, 0x9DB7, 0x9DB6, 0x9DBC, 0x9DC1, 0x9DC7, 0x9DCA, - 0x9DCF, 0x9DBE, 0x9DC5, 0x9DC3, 0x9DBB, 0x9DB5, 0x9DCE, 0x9DB9, 0x9DBA, 0x9DAC, 0x9DC8, 0x9DB1, 0x9DAD, 0x9DCC, 0x9DB3, 0x9DCD, - 0x9DB2, 0x9E7A, 0x9E9C, 0x9EEB, 0x9EEE, 0x9EED, 0x9F1B, 0x9F18, 0x9F1A, 0x9F31, 0x9F4E, 0x9F65, 0x9F64, 0x9F92, 0x4EB9, 0x56C6, - 0x56C5, 0x56CB, 0x5971, 0x5B4B, 0x5B4C, 0x5DD5, 0x5DD1, 0x5EF2, 0x6521, 0x6520, 0x6526, 0x6522, 0x6B0B, 0x6B08, 0x6B09, 0x6C0D, - 0x7055, 0x7056, 0x7057, 0x7052, 0x721E, 0x721F, 0x72A9, 0x737F, 0x74D8, 0x74D5, 0x74D9, 0x74D7, 0x766D, 0x76AD, 0x7935, 0x79B4, - 0x7A70, 0x7A71, 0x7C57, 0x7C5C, 0x7C59, 0x7C5B, 0x7C5A, - /* Big5-HKSCS 0xF740 .. 0xF77E */ - 0x7CF4, 0x7CF1, 0x7E91, 0x7F4F, 0x7F87, 0x81DE, 0x826B, 0x8634, 0x8635, 0x8633, 0x862C, 0x8632, 0x8636, 0x882C, 0x8828, 0x8826, - 0x882A, 0x8825, 0x8971, 0x89BF, 0x89BE, 0x89FB, 0x8B7E, 0x8B84, 0x8B82, 0x8B86, 0x8B85, 0x8B7F, 0x8D15, 0x8E95, 0x8E94, 0x8E9A, - 0x8E92, 0x8E90, 0x8E96, 0x8E97, 0x8F60, 0x8F62, 0x9147, 0x944C, 0x9450, 0x944A, 0x944B, 0x944F, 0x9447, 0x9445, 0x9448, 0x9449, - 0x9446, 0x973F, 0x97E3, 0x986A, 0x9869, 0x98CB, 0x9954, 0x995B, 0x9A4E, 0x9A53, 0x9A54, 0x9A4C, 0x9A4F, 0x9A48, 0x9A4A, - /* Big5-HKSCS 0xF7A1 .. 0xF7FE */ - 0x9A49, 0x9A52, 0x9A50, 0x9AD0, 0x9B19, 0x9B2B, 0x9B3B, - 0x9B56, 0x9B55, 0x9C46, 0x9C48, 0x9C3F, 0x9C44, 0x9C39, 0x9C33, 0x9C41, 0x9C3C, 0x9C37, 0x9C34, 0x9C32, 0x9C3D, 0x9C36, 0x9DDB, - 0x9DD2, 0x9DDE, 0x9DDA, 0x9DCB, 0x9DD0, 0x9DDC, 0x9DD1, 0x9DDF, 0x9DE9, 0x9DD9, 0x9DD8, 0x9DD6, 0x9DF5, 0x9DD5, 0x9DDD, 0x9EB6, - 0x9EF0, 0x9F35, 0x9F33, 0x9F32, 0x9F42, 0x9F6B, 0x9F95, 0x9FA2, 0x513D, 0x5299, 0x58E8, 0x58E7, 0x5972, 0x5B4D, 0x5DD8, 0x882F, - 0x5F4F, 0x6201, 0x6203, 0x6204, 0x6529, 0x6525, 0x6596, 0x66EB, 0x6B11, 0x6B12, 0x6B0F, 0x6BCA, 0x705B, 0x705A, 0x7222, 0x7382, - 0x7381, 0x7383, 0x7670, 0x77D4, 0x7C67, 0x7C66, 0x7E95, 0x826C, 0x863A, 0x8640, 0x8639, 0x863C, 0x8631, 0x863B, 0x863E, 0x8830, - 0x8832, 0x882E, 0x8833, 0x8976, 0x8974, 0x8973, 0x89FE, - /* Big5-HKSCS 0xF840 .. 0xF87E */ - 0x8B8C, 0x8B8E, 0x8B8B, 0x8B88, 0x8C45, 0x8D19, 0x8E98, 0x8F64, 0x8F63, 0x91BC, 0x9462, 0x9455, 0x945D, 0x9457, 0x945E, 0x97C4, - 0x97C5, 0x9800, 0x9A56, 0x9A59, 0x9B1E, 0x9B1F, 0x9B20, 0x9C52, 0x9C58, 0x9C50, 0x9C4A, 0x9C4D, 0x9C4B, 0x9C55, 0x9C59, 0x9C4C, - 0x9C4E, 0x9DFB, 0x9DF7, 0x9DEF, 0x9DE3, 0x9DEB, 0x9DF8, 0x9DE4, 0x9DF6, 0x9DE1, 0x9DEE, 0x9DE6, 0x9DF2, 0x9DF0, 0x9DE2, 0x9DEC, - 0x9DF4, 0x9DF3, 0x9DE8, 0x9DED, 0x9EC2, 0x9ED0, 0x9EF2, 0x9EF3, 0x9F06, 0x9F1C, 0x9F38, 0x9F37, 0x9F36, 0x9F43, 0x9F4F, - /* Big5-HKSCS 0xF8A1 .. 0xF8FE */ - 0x9F71, 0x9F70, 0x9F6E, 0x9F6F, 0x56D3, 0x56CD, 0x5B4E, - 0x5C6D, 0x652D, 0x66ED, 0x66EE, 0x6B13, 0x705F, 0x7061, 0x705D, 0x7060, 0x7223, 0x74DB, 0x74E5, 0x77D5, 0x7938, 0x79B7, 0x79B6, - 0x7C6A, 0x7E97, 0x7F89, 0x826D, 0x8643, 0x8838, 0x8837, 0x8835, 0x884B, 0x8B94, 0x8B95, 0x8E9E, 0x8E9F, 0x8EA0, 0x8E9D, 0x91BE, - 0x91BD, 0x91C2, 0x946B, 0x9468, 0x9469, 0x96E5, 0x9746, 0x9743, 0x9747, 0x97C7, 0x97E5, 0x9A5E, 0x9AD5, 0x9B59, 0x9C63, 0x9C67, - 0x9C66, 0x9C62, 0x9C5E, 0x9C60, 0x9E02, 0x9DFE, 0x9E07, 0x9E03, 0x9E06, 0x9E05, 0x9E00, 0x9E01, 0x9E09, 0x9DFF, 0x9DFD, 0x9E04, - 0x9EA0, 0x9F1E, 0x9F46, 0x9F74, 0x9F75, 0x9F76, 0x56D4, 0x652E, 0x65B8, 0x6B18, 0x6B19, 0x6B17, 0x6B1A, 0x7062, 0x7226, 0x72AA, - 0x77D8, 0x77D9, 0x7939, 0x7C69, 0x7C6B, 0x7CF6, 0x7E9A, - /* Big5-HKSCS 0xF940 .. 0xF97E */ - 0x7E98, 0x7E9B, 0x7E99, 0x81E0, 0x81E1, 0x8646, 0x8647, 0x8648, 0x8979, 0x897A, 0x897C, 0x897B, 0x89FF, 0x8B98, 0x8B99, 0x8EA5, - 0x8EA4, 0x8EA3, 0x946E, 0x946D, 0x946F, 0x9471, 0x9473, 0x9749, 0x9872, 0x995F, 0x9C68, 0x9C6E, 0x9C6D, 0x9E0B, 0x9E0D, 0x9E10, - 0x9E0F, 0x9E12, 0x9E11, 0x9EA1, 0x9EF5, 0x9F09, 0x9F47, 0x9F78, 0x9F7B, 0x9F7A, 0x9F79, 0x571E, 0x7066, 0x7C6F, 0x883C, 0x8DB2, - 0x8EA6, 0x91C3, 0x9474, 0x9478, 0x9476, 0x9475, 0x9A60, 0x9C74, 0x9C73, 0x9C71, 0x9C75, 0x9E14, 0x9E13, 0x9EF6, 0x9F0A, - /* Big5-HKSCS 0xF9A1 .. 0xF9FE */ - 0x9FA4, 0x7068, 0x7065, 0x7CF7, 0x866A, 0x883E, 0x883D, - 0x883F, 0x8B9E, 0x8C9C, 0x8EA9, 0x8EC9, 0x974B, 0x9873, 0x9874, 0x98CC, 0x9961, 0x99AB, 0x9A64, 0x9A66, 0x9A67, 0x9B24, 0x9E15, - 0x9E17, 0x9F48, 0x6207, 0x6B1E, 0x7227, 0x864C, 0x8EA8, 0x9482, 0x9480, 0x9481, 0x9A69, 0x9A68, 0x9B2E, 0x9E19, 0x7229, 0x864B, - 0x8B9F, 0x9483, 0x9C79, 0x9EB7, 0x7675, 0x9A6B, 0x9C7A, 0x9E1D, 0x7069, 0x706A, 0x9EA4, 0x9F7E, 0x9F49, 0x9F98, 0x7881, 0x92B9, - 0x88CF, 0x58BB, 0x6052, 0x7CA7, 0x5AFA, 0x2554, 0x2566, 0x2557, 0x2560, 0x256C, 0x2563, 0x255A, 0x2569, 0x255D, 0x2552, 0x2564, - 0x2555, 0x255E, 0x256A, 0x2561, 0x2558, 0x2567, 0x255B, 0x2553, 0x2565, 0x2556, 0x255F, 0x256B, 0x2562, 0x2559, 0x2568, 0x255C, - 0x2551, 0x2550, 0x256D, 0x256E, 0x2570, 0x256F, 0xFFED, - /* Big5-HKSCS 0xFA40 .. 0xFA7E */ - 0xE000, 0x92DB, 0xE002, 0xE003, 0x854C, 0x42B5, 0x73EF, 0x51B5, 0x3649, 0xE009, 0xE00A, 0x9344, 0xE00C, 0x82EE, 0xE00E, 0x783C, - 0x6744, 0x62DF, 0xE012, 0xE013, 0xE014, 0xE015, 0xE016, 0x4FAB, 0xE018, 0x5008, 0xE01A, 0xE01B, 0xE01C, 0xE01D, 0xE01E, 0x5029, - 0xE020, 0x5FA4, 0xE022, 0xE023, 0x6EDB, 0xE025, 0x507D, 0x5101, 0x347A, 0x510E, 0x986C, 0x3743, 0x8416, 0xE02D, 0xE02E, 0x5160, - 0xE030, 0x516A, 0xE032, 0xE033, 0xE034, 0xE035, 0xE036, 0xE037, 0xE038, 0x5B82, 0x877D, 0xE03B, 0xE03C, 0x51B2, 0x51B8, - /* Big5-HKSCS 0xFAA1 .. 0xFAFE */ - 0x9D34, 0x51C9, 0x51CF, 0x51D1, 0x3CDC, 0x51D3, 0xE045, - 0x51B3, 0x51E2, 0x5342, 0x51ED, 0x83CD, 0x693E, 0xE04C, 0x5F7B, 0x520B, 0x5226, 0x523C, 0x52B5, 0x5257, 0x5294, 0x52B9, 0x52C5, - 0x7C15, 0x8542, 0x52E0, 0x860D, 0xE05A, 0x5305, 0xE05C, 0x5549, 0x6ED9, 0xE05F, 0xE060, 0xE061, 0x5333, 0x5344, 0xE064, 0x6CCB, - 0xE066, 0x681B, 0x73D5, 0x604A, 0x3EAA, 0x38CC, 0xE06C, 0x71DD, 0x44A2, 0x536D, 0x5374, 0xE071, 0x537E, 0x537F, 0xE074, 0xE075, - 0x77E6, 0x5393, 0xE078, 0x53A0, 0x53AB, 0x53AE, 0x73A7, 0xE07D, 0x3F59, 0x739C, 0x53C1, 0x53C5, 0x6C49, 0x4E49, 0x57FE, 0x53D9, - 0x3AAB, 0xE087, 0x53E0, 0xE089, 0xE08A, 0x53F6, 0xE08C, 0x5413, 0x7079, 0x552B, 0x6657, 0x6D5B, 0x546D, 0xE093, 0xE094, 0x555D, - 0x548F, 0x54A4, 0x47A6, 0xE099, 0xE09A, 0x3DB4, 0xE09C, - /* Big5-HKSCS 0xFB40 .. 0xFB7E */ - 0xE09D, 0xE09E, 0x5547, 0x4CED, 0x542F, 0x7417, 0x5586, 0x55A9, 0x5605, 0xE0A6, 0xE0A7, 0x4552, 0xE0A9, 0x66B3, 0xE0AB, 0x5637, - 0x66CD, 0xE0AE, 0x66A4, 0x66AD, 0x564D, 0x564F, 0x78F1, 0x56F1, 0x9787, 0x53FE, 0x5700, 0x56EF, 0x56ED, 0xE0BA, 0x3623, 0xE0BC, - 0x5746, 0xE0BE, 0x6C6E, 0x708B, 0x5742, 0x36B1, 0xE0C3, 0x57E6, 0xE0C5, 0x5803, 0xE0C7, 0xE0C8, 0x5826, 0xE0CA, 0x585C, 0x58AA, - 0x3561, 0x58E0, 0x58DC, 0xE0D0, 0x58FB, 0x5BFF, 0x5743, 0xE0D4, 0xE0D5, 0x93D3, 0x35A1, 0x591F, 0x68A6, 0x36C3, 0x6E59, - /* Big5-HKSCS 0xFBA1 .. 0xFBFE */ - 0xE0DC, 0x5A24, 0x5553, 0xE0DF, 0x8505, 0x59C9, 0xE0E2, - 0xE0E3, 0xE0E4, 0xE0E5, 0x59D9, 0xE0E7, 0xE0E8, 0xE0E9, 0x6D71, 0xE0EB, 0xE0EC, 0x59F9, 0xE0EE, 0x5AAB, 0x5A63, 0x36E6, 0xE0F2, - 0x5A77, 0x3708, 0x5A96, 0x7465, 0x5AD3, 0xE0F8, 0xE0F9, 0x3D85, 0xE0FB, 0x3732, 0xE0FD, 0x5E83, 0x52D0, 0x5B76, 0x6588, 0x5B7C, - 0xE103, 0x4004, 0x485D, 0xE106, 0x5BD5, 0x6160, 0xE109, 0xE10A, 0xE10B, 0x5BF3, 0x5B9D, 0x4D10, 0x5C05, 0xE110, 0x5C13, 0x73CE, - 0x5C14, 0xE114, 0xE115, 0x5C49, 0x48DD, 0x5C85, 0x5CE9, 0x5CEF, 0x5D8B, 0xE11C, 0xE11D, 0x5D10, 0x5D18, 0x5D46, 0xE121, 0x5CBA, - 0x5DD7, 0x82FC, 0x382D, 0xE126, 0xE127, 0xE128, 0x8287, 0x3836, 0x3BC2, 0x5E2E, 0x6A8A, 0x5E75, 0x5E7A, 0xE130, 0xE131, 0x53A6, - 0x4EB7, 0x5ED0, 0x53A8, 0xE136, 0x5E09, 0x5EF4, 0xE139, - /* Big5-HKSCS 0xFC40 .. 0xFC7E */ - 0x5EF9, 0x5EFB, 0x38A0, 0x5EFC, 0x683E, 0x941B, 0x5F0D, 0xE141, 0xE142, 0x3ADE, 0x48AE, 0xE145, 0x5F3A, 0xE147, 0xE148, 0x5F58, - 0xE14A, 0x5F63, 0x97BD, 0xE14D, 0x5F72, 0x9340, 0xE150, 0x5FA7, 0x5DB6, 0x3D5F, 0xE154, 0xE155, 0xE156, 0xE157, 0x91D6, 0xE159, - 0xE15A, 0x6031, 0x6685, 0xE15D, 0x3963, 0x3DC7, 0x3639, 0x5790, 0xE162, 0x7971, 0x3E40, 0x609E, 0x60A4, 0x60B3, 0xE168, 0xE169, - 0xE16A, 0x74A4, 0x50E1, 0x5AA0, 0x6164, 0x8424, 0x6142, 0xE171, 0xE172, 0x6181, 0x51F4, 0xE175, 0x6187, 0x5BAA, 0xE178, - /* Big5-HKSCS 0xFCA1 .. 0xFCFE */ - 0xE179, 0x61D3, 0xE17B, 0xE17C, 0x61D0, 0x3932, 0xE17F, - 0xE180, 0x6023, 0x615C, 0x651E, 0x638B, 0xE185, 0x62C5, 0xE187, 0x62D5, 0xE189, 0x636C, 0xE18B, 0x3A17, 0x6438, 0x63F8, 0xE18F, - 0xE190, 0x6490, 0x6F8A, 0xE193, 0x9814, 0xE195, 0xE196, 0x64E1, 0x64E5, 0x947B, 0x3A66, 0x643A, 0x3A57, 0x654D, 0x6F16, 0xE19F, - 0xE1A0, 0x6585, 0x656D, 0x655F, 0xE1A4, 0x65B5, 0xE1A6, 0x4B37, 0x65D1, 0x40D8, 0xE1AA, 0x65E0, 0x65E3, 0x5FDF, 0xE1AE, 0x6618, - 0xE1B0, 0xE1B1, 0x6644, 0xE1B3, 0xE1B4, 0x664B, 0xE1B6, 0x6667, 0xE1B8, 0x6673, 0x6674, 0xE1BB, 0xE1BC, 0xE1BD, 0xE1BE, 0xE1BF, - 0x77C5, 0xE1C1, 0x99A4, 0x6702, 0xE1C4, 0xE1C5, 0x3B2B, 0x69FA, 0xE1C8, 0x675E, 0x6767, 0x6762, 0xE1CC, 0xE1CD, 0x67D7, 0x44E9, - 0x6822, 0x6E50, 0x923C, 0x6801, 0xE1D4, 0xE1D5, 0x685D, - /* Big5-HKSCS 0xFD40 .. 0xFD7E */ - 0xE1D7, 0x69E1, 0x6A0B, 0xE1DA, 0x6973, 0x68C3, 0xE1DD, 0x6901, 0x6900, 0x3D32, 0x3A01, 0xE1E2, 0x3B80, 0x67AC, 0x6961, 0xE1E6, - 0x42FC, 0x6936, 0x6998, 0x3BA1, 0xE1EB, 0x8363, 0x5090, 0x69F9, 0xE1EF, 0xE1F0, 0x6A45, 0xE1F2, 0x6A9D, 0x3BF3, 0x67B1, 0x6AC8, - 0xE1F7, 0x3C0D, 0x6B1D, 0xE1FA, 0x60DE, 0x6B35, 0x6B74, 0xE1FE, 0x6EB5, 0xE200, 0xE201, 0xE202, 0x3740, 0x5421, 0xE205, 0x6BE1, - 0xE207, 0x6BDC, 0x6C37, 0xE20A, 0xE20B, 0xE20C, 0x6C5A, 0x8226, 0x6C79, 0xE210, 0x44C5, 0xE212, 0xE213, 0xE214, 0xE215, - /* Big5-HKSCS 0xFDA1 .. 0xFDFE */ - 0xE216, 0x36E5, 0x3CEB, 0xE219, 0x9B83, 0xE21B, 0xE21C, - 0x7F8F, 0x6837, 0xE21F, 0xE220, 0xE221, 0x6D96, 0x6D5C, 0x6E7C, 0x6F04, 0xE226, 0xE227, 0xE228, 0x8533, 0xE22A, 0x51C7, 0x6C9C, - 0x6E1D, 0x842E, 0xE22F, 0x6E2F, 0xE231, 0x7453, 0xE233, 0x79CC, 0x6E4F, 0x5A91, 0xE237, 0x6FF8, 0x370D, 0x6F9D, 0xE23B, 0x6EFA, - 0xE23D, 0xE23E, 0x4555, 0x93F0, 0x6F44, 0x6F5C, 0x3D4E, 0x6F74, 0xE245, 0x3D3B, 0x6F9F, 0xE248, 0x6FD3, 0xE24A, 0xE24B, 0xE24C, - 0xE24D, 0xE24E, 0xE24F, 0x51DF, 0xE251, 0xE252, 0xE253, 0xE254, 0x704B, 0x707E, 0x70A7, 0x7081, 0x70CC, 0x70D5, 0x70D6, 0x70DF, - 0x4104, 0x3DE8, 0x71B4, 0x7196, 0xE261, 0x712B, 0x7145, 0x5A88, 0x714A, 0x716E, 0x5C9C, 0xE268, 0x714F, 0x9362, 0xE26B, 0x712C, - 0xE26D, 0xE26E, 0xE26F, 0x71BA, 0xE271, 0x70BD, 0x720E, - /* Big5-HKSCS 0xFE40 .. 0xFE7E */ - 0x9442, 0x7215, 0x5911, 0x9443, 0x7224, 0x9341, 0xE27A, 0x722E, 0x7240, 0xE27D, 0x68BD, 0x7255, 0x7257, 0x3E55, 0xE282, 0x680D, - 0x6F3D, 0x7282, 0x732A, 0x732B, 0xE288, 0xE289, 0x48ED, 0xE28B, 0x7328, 0x732E, 0x73CF, 0x73AA, 0xE290, 0xE291, 0x73C9, 0x7449, - 0xE294, 0xE295, 0xE296, 0x6623, 0x36C5, 0xE299, 0xE29A, 0xE29B, 0x73F7, 0x7415, 0x6903, 0xE29F, 0x7439, 0xE2A1, 0x3ED7, 0x745C, - 0xE2A4, 0x7460, 0xE2A6, 0x7447, 0x73E4, 0x7476, 0x83B9, 0x746C, 0x3730, 0x7474, 0x93F1, 0x6A2C, 0x7482, 0x4953, 0xE2B2, - /* Big5-HKSCS 0xFEA1 .. 0xFEFE */ - 0xE2B3, 0xE2B4, 0xE2B5, 0x5B46, 0xE2B7, 0xE2B8, 0x74C8, - 0xE2BA, 0x750E, 0x74E9, 0x751E, 0xE2BE, 0xE2BF, 0x5BD7, 0xE2C1, 0x9385, 0x754D, 0x754A, 0x7567, 0x756E, 0xE2C7, 0x3F04, 0xE2C9, - 0x758E, 0x745D, 0x759E, 0x75B4, 0x7602, 0x762C, 0x7651, 0x764F, 0x766F, 0x7676, 0xE2D4, 0x7690, 0x81EF, 0x37F8, 0xE2D8, 0xE2D9, - 0x76A1, 0x76A5, 0x76B7, 0x76CC, 0xE2DE, 0x8462, 0xE2E0, 0xE2E1, 0xE2E2, 0x771E, 0x7726, 0x7740, 0x64AF, 0xE2E7, 0x7758, 0xE2E9, - 0x77AF, 0xE2EB, 0xE2EC, 0xE2ED, 0x77F4, 0x7809, 0xE2F0, 0xE2F1, 0x68CA, 0x78AF, 0x78C7, 0x78D3, 0x96A5, 0x792E, 0xE2F8, 0x78D7, - 0x7934, 0x78B1, 0xE2FC, 0x8FB8, 0x8884, 0xE2FF, 0xE300, 0xE301, 0x7986, 0x8900, 0x6902, 0x7980, 0xE306, 0x799D, 0xE308, 0x793C, - 0x79A9, 0x6E2A, 0xE30C, 0x3EA8, 0x79C6, 0xE30F, 0x79D4, -}; - -static const uint16_t REPLACEMENT = 0xfffd; - -static inline bool IsFirstByte(unsigned c) -{ - return c >= 0x81 && c <= 0xFE; -} - -static inline bool IsSecondByte(unsigned c) -{ - return (c >= 0x40 && c <= 0x7E) || (c >= 0xA1 && c <= 0xFE); -} - -static inline uint16_t ValidChar(unsigned u) -{ - return u != 0 ? static_cast(u) : REPLACEMENT; -} - -/* Returns the number of bytes of Bytes consumed. */ -static int qt_Big5hkscsToUnicode(const uint8_t *s, unsigned *pwc) -{ - uint8_t c1 = s[0]; - if ((c1 >= 0x81 && c1 <= 0xfe)) { - uint8_t c2 = s[1]; - if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { - unsigned i = 157 * (c1 - 0x81) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); - uint16_t wc = 0xfffd; - if (i < 19782) - wc = big5hkscs_to_ucs[i]; - if (wc != 0xfffd) { - *pwc = (unsigned)wc; - return 2; - } - } - return 0; - } - else if (c1 < 0x80) { - *pwc = (unsigned)c1; - return 1; - } - return 0; -} - -static int qt_Big5ToUnicode(const uint8_t *buf, unsigned *u) -{ - //for this conversion only first 4 tables are used. - for (int i = 0; i < 4; i++) { - int start = 0; - int end = b5_map_table[i].tableSize - 1; - - unsigned b5 = (buf[0] << 8) + buf[1]; - while (start <= end) { - int middle = (end + start + 1) / 2; - if (b5_map_table[i].table[middle].x == b5) { - *u = b5_map_table[i].table[middle].y; - return 2; - } - else if (b5_map_table[i].table[middle].x > b5) { - end = middle - 1; - } - else { - start = middle + 1; - } - } - } - return qt_Big5hkscsToUnicode(buf, u); -} - -void -Big5TextDecoder::AppendBig5(std::vector& result, const uint8_t* bytes, size_t length) -{ - uint8_t buf[2] = { 0 }; - int nbuf = 0; -// int invalid = 0; - result.reserve(length); - - for (size_t i = 0; i -#include -#include - -class Big5TextDecoder -{ -public: - static void AppendBig5(std::vector& utf16, const uint8_t* bytes, size_t length); -}; diff --git a/core/src/textcodec/Big5TextEncoder.cpp b/core/src/textcodec/Big5TextEncoder.cpp deleted file mode 100644 index 4baa88aa61..0000000000 --- a/core/src/textcodec/Big5TextEncoder.cpp +++ /dev/null @@ -1,4272 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Big5TextEncoder.h" -#include "Big5MapTable.h" - -/* - * ucs4 to big5hkscs convert routing - */ - -struct Summary16 { - uint16_t index; /* index into big table */ - uint16_t used; /* bitmask of used entries */ -}; - -/* ISO-10646-UCS-4 to big5hkscs convert table */ -static const uint8_t big5hkscs_to_charset[24908][2] = { - {0x21,0x00}, {0xa2,0x46}, {0xa2,0x47}, {0xa2,0x44}, {0x7c,0x00}, {0xa1,0xb1}, {0xc6,0xd8}, {0x63,0x00}, {0x61,0x00}, {0x2d,0x00}, - {0x52,0x00}, {0xa1,0xc2}, {0xa2,0x58}, {0xa1,0xd3}, {0x32,0x00}, {0x33,0x00}, {0xa1,0xa6}, {0xa3,0x67}, {0xa1,0x50}, {0xa1,0x4d}, - {0x31,0x00}, {0x6f,0x00}, {0x3f,0x00}, {0x88,0x59}, {0x88,0x57}, {0x41,0x00}, {0x41,0x00}, {0x41,0x00}, {0x41,0x00}, {0x41,0x00}, - {0x43,0x00}, {0x88,0x5d}, {0x88,0x5b}, {0x88,0x66}, {0x45,0x00}, {0x49,0x00}, {0x49,0x00}, {0x49,0x00}, {0x49,0x00}, {0x44,0x00}, - {0x4e,0x00}, {0x88,0x61}, {0x88,0x5f}, {0x4f,0x00}, {0x4f,0x00}, {0x4f,0x00}, {0xa1,0xd1}, {0x4f,0x00}, {0x55,0x00}, {0x55,0x00}, - {0x55,0x00}, {0x55,0x00}, {0x59,0x00}, {0x54,0x00}, {0x73,0x00}, {0x88,0x6a}, {0x88,0x68}, {0x61,0x00}, {0x61,0x00}, {0x61,0x00}, - {0x61,0x00}, {0x61,0x00}, {0x63,0x00}, {0x88,0x6f}, {0x88,0x6d}, {0x88,0xa7}, {0x65,0x00}, {0x88,0x73}, {0x88,0x71}, {0x69,0x00}, - {0x69,0x00}, {0x65,0x00}, {0x6e,0x00}, {0x88,0x77}, {0x88,0x75}, {0x6f,0x00}, {0x6f,0x00}, {0x6f,0x00}, {0xa1,0xd2}, {0xc8,0xfb}, - {0x88,0x7b}, {0x88,0x79}, {0x75,0x00}, {0x88,0xa2}, {0x79,0x00}, {0x74,0x00}, {0x79,0x00}, {0x88,0x56}, {0x88,0x67}, {0x88,0x5a}, - {0x88,0x6c}, {0x88,0x5c}, {0x88,0x6e}, {0x88,0x70}, {0xc8,0xfc}, {0x88,0x5e}, {0x88,0x74}, {0xc8,0xfa}, {0x88,0x78}, {0x88,0x58}, - {0x88,0x69}, {0x88,0x72}, {0x88,0x60}, {0x88,0x76}, {0x88,0x7a}, {0x88,0x7c}, {0x88,0x7d}, {0x88,0x7e}, {0x88,0xa1}, {0xc8,0xf6}, - {0x88,0x6b}, {0xc8,0xf8}, {0xc8,0xf7}, {0x88,0xa8}, {0xc8,0xfe}, {0xc8,0xf9}, {0xc8,0xf5}, {0xc8,0xfd}, {0xc6,0xd9}, {0xa3,0xbe}, - {0xa3,0xbc}, {0xa3,0xbd}, {0xa3,0xbf}, {0xa1,0xc5}, {0xa3,0xbb}, {0xa1,0xc2}, {0xa3,0x44}, {0xa3,0x45}, {0xa3,0x46}, {0xa3,0x47}, - {0xa3,0x48}, {0xa3,0x49}, {0xa3,0x4a}, {0xa3,0x4b}, {0xa3,0x4c}, {0xa3,0x4d}, {0xa3,0x4e}, {0xa3,0x4f}, {0xa3,0x50}, {0xa3,0x51}, - {0xa3,0x52}, {0xa3,0x53}, {0xa3,0x54}, {0xa3,0x55}, {0xa3,0x56}, {0xa3,0x57}, {0xa3,0x58}, {0xa3,0x59}, {0xa3,0x5a}, {0xa3,0x5b}, - {0xa3,0x5c}, {0xa3,0x5d}, {0xa3,0x5e}, {0xa3,0x5f}, {0xa3,0x60}, {0xa3,0x61}, {0xa3,0x62}, {0xa3,0x63}, {0xa3,0x64}, {0xa3,0x65}, - {0xa3,0x66}, {0xa3,0x67}, {0xa3,0x68}, {0xa3,0x69}, {0xa3,0x6a}, {0xa3,0x6b}, {0xa3,0x6c}, {0xa3,0x6d}, {0xa3,0x6e}, {0xa3,0x6f}, - {0xa3,0x70}, {0xa3,0x71}, {0xa3,0x72}, {0xa3,0x73}, {0xc7,0xf9}, {0xc7,0xf3}, {0xc7,0xf4}, {0xc7,0xf5}, {0xc7,0xf6}, {0xc7,0xf7}, - {0xc7,0xf8}, {0xc7,0xfa}, {0xc7,0xfb}, {0xc7,0xfc}, {0xc7,0xfd}, {0xc7,0xfe}, {0xc8,0x40}, {0xc8,0x41}, {0xc8,0x42}, {0xc8,0x43}, - {0xc8,0x44}, {0xc8,0x45}, {0xc8,0x46}, {0xc8,0x47}, {0xc8,0x48}, {0xc8,0x49}, {0xc8,0x4a}, {0xc8,0x4b}, {0xc8,0x4c}, {0xc8,0x4d}, - {0xc8,0x4e}, {0xc8,0x4f}, {0xc8,0x50}, {0xc8,0x51}, {0xc8,0x52}, {0xc8,0x53}, {0xc8,0x54}, {0xc8,0x55}, {0xc8,0x56}, {0xc8,0x57}, - {0xc8,0x58}, {0xc8,0x59}, {0xc8,0x5a}, {0xc8,0x5c}, {0xc8,0x5d}, {0xc8,0x5e}, {0xc8,0x5f}, {0xc8,0x60}, {0xc8,0x61}, {0xc8,0x62}, - {0xc8,0x63}, {0xc8,0x64}, {0xc8,0x65}, {0xc8,0x66}, {0xc8,0x67}, {0xc8,0x68}, {0xc8,0x69}, {0xc8,0x6a}, {0xc8,0x6b}, {0xc8,0x6c}, - {0xc8,0x6d}, {0xc8,0x6e}, {0xc8,0x6f}, {0xc8,0x70}, {0xc8,0x71}, {0xc8,0x72}, {0xc8,0x73}, {0xc8,0x74}, {0xc8,0x75}, {0xc8,0x5b}, - {0x88,0x63}, {0x88,0xa4}, {0x88,0x65}, {0x88,0xa6}, {0xa1,0x56}, {0xa1,0x58}, {0xa2,0x77}, {0xa1,0xfc}, {0xa1,0xa5}, {0xa1,0xa6}, - {0xa1,0xa7}, {0xa1,0xa8}, {0xa1,0x45}, {0xa3,0xbb}, {0xa1,0x4c}, {0xa1,0x4b}, {0xa1,0x45}, {0xa1,0xac}, {0xa1,0xb2}, {0xa1,0xab}, - {0xa1,0xb0}, {0xa1,0xc3}, {0xa3,0xe1}, {0xa2,0x4a}, {0xa1,0xc1}, {0xa2,0x4b}, {0xc8,0xd2}, {0xc8,0xd3}, {0xa2,0xb9}, {0xa2,0xba}, - {0xa2,0xbb}, {0xa2,0xbc}, {0xa2,0xbd}, {0xa2,0xbe}, {0xa2,0xbf}, {0xa2,0xc0}, {0xa2,0xc1}, {0xa2,0xc2}, {0xc6,0xb5}, {0xc6,0xb6}, - {0xc6,0xb7}, {0xc6,0xb8}, {0xc6,0xb9}, {0xc6,0xba}, {0xc6,0xbb}, {0xc6,0xbc}, {0xc6,0xbd}, {0xc6,0xbe}, {0xa1,0xf6}, {0xa1,0xf4}, - {0xa1,0xf7}, {0xa1,0xf5}, {0xa1,0xf8}, {0xa1,0xf9}, {0xa1,0xfb}, {0xa1,0xfa}, {0xc8,0x77}, {0xc8,0x78}, {0xc8,0x76}, {0xa2,0x41}, - {0xa2,0x42}, {0xa2,0x58}, {0xa1,0xd4}, {0xa1,0xdb}, {0xa1,0xe8}, {0xa1,0xe7}, {0xa1,0xfd}, {0xa1,0xfc}, {0xa1,0xe4}, {0xa1,0xe5}, - {0xa1,0xec}, {0xa1,0xed}, {0xa1,0xef}, {0xa1,0xee}, {0xa1,0xdc}, {0xa1,0xda}, {0xa1,0xdd}, {0xa1,0xdd}, {0xa1,0xd8}, {0xa1,0xd9}, - {0xa1,0xf2}, {0xa1,0xf3}, {0xa1,0xe6}, {0xa1,0xe9}, {0xa1,0x5b}, {0xc6,0xa1}, {0xc6,0xa2}, {0xc6,0xa3}, {0xc6,0xa4}, {0xc6,0xa5}, - {0xc6,0xa6}, {0xc6,0xa7}, {0xc6,0xa8}, {0xc6,0xa9}, {0xc6,0xaa}, {0xc6,0xab}, {0xc6,0xac}, {0xc6,0xad}, {0xc6,0xae}, {0xc6,0xaf}, - {0xc6,0xb0}, {0xc6,0xb1}, {0xc6,0xb2}, {0xc6,0xb3}, {0xc6,0xb4}, {0xa2,0x77}, {0xa2,0x78}, {0xa2,0x7a}, {0xa2,0x7b}, {0xa2,0x7c}, - {0xa2,0x7d}, {0xa2,0x75}, {0xa2,0x74}, {0xa2,0x73}, {0xa2,0x72}, {0xa2,0x71}, {0xf9,0xf9}, {0xf9,0xf8}, {0xf9,0xe6}, {0xf9,0xef}, - {0xf9,0xdd}, {0xf9,0xe8}, {0xf9,0xf1}, {0xf9,0xdf}, {0xf9,0xec}, {0xf9,0xf5}, {0xf9,0xe3}, {0xf9,0xee}, {0xf9,0xf7}, {0xf9,0xe5}, - {0xf9,0xe9}, {0xf9,0xf2}, {0xf9,0xe0}, {0xf9,0xeb}, {0xf9,0xf4}, {0xf9,0xe2}, {0xf9,0xe7}, {0xf9,0xf0}, {0xf9,0xde}, {0xf9,0xed}, - {0xf9,0xf6}, {0xf9,0xe4}, {0xf9,0xea}, {0xf9,0xf3}, {0xf9,0xe1}, {0xf9,0xfa}, {0xf9,0xfb}, {0xf9,0xfd}, {0xf9,0xfc}, {0xa2,0xac}, - {0xa2,0xad}, {0xa2,0xae}, {0xa1,0x5a}, {0xa2,0x62}, {0xa2,0x63}, {0xa2,0x64}, {0xa2,0x65}, {0xa2,0x66}, {0xa2,0x67}, {0xa2,0x68}, - {0xa2,0x69}, {0xa2,0x70}, {0xa2,0x6f}, {0xa2,0x6e}, {0xa2,0x6d}, {0xa2,0x6c}, {0xa2,0x6b}, {0xa2,0x6a}, {0xf9,0xfe}, {0xa2,0x76}, - {0xa2,0x79}, {0xa1,0xbd}, {0xa1,0xbc}, {0xa1,0xb6}, {0xa1,0xb5}, {0xa1,0xbf}, {0xa1,0xbe}, {0xa1,0xbb}, {0xa1,0xba}, {0xa1,0xb3}, - {0xa1,0xb7}, {0xa1,0xb4}, {0xa2,0xa8}, {0xa2,0xa9}, {0xa2,0xab}, {0xa2,0xaa}, {0xa1,0xb9}, {0xa1,0xb8}, {0xa1,0xf3}, {0xa1,0xf0}, - {0xa1,0xf2}, {0xa1,0xf1}, {0xc6,0xe6}, {0xc8,0xd6}, {0xc8,0xd7}, {0xc8,0xd8}, {0xc8,0xd9}, {0xc8,0xda}, {0xc8,0xdb}, {0xc8,0xdc}, - {0xc8,0xdd}, {0xc8,0xde}, {0xc8,0xdf}, {0xc8,0xe0}, {0xc8,0xe1}, {0xc8,0xe2}, {0xc8,0xe3}, {0xc8,0xe4}, {0xc8,0xe5}, {0xc8,0xe6}, - {0xc8,0xe7}, {0xc8,0xe8}, {0xc8,0xe9}, {0xc8,0xea}, {0xc8,0xeb}, {0xc8,0xec}, {0xc8,0xed}, {0xc8,0xee}, {0xc8,0xef}, {0xc8,0xf0}, - {0xc8,0xf1}, {0xc6,0xcd}, {0xa1,0x40}, {0xa1,0x42}, {0xa1,0x43}, {0xa1,0xb2}, {0xc6,0xe0}, {0xc6,0xe1}, {0xc6,0xe2}, {0xa1,0x71}, - {0xa1,0x72}, {0xa1,0x6d}, {0xa1,0x6e}, {0xa1,0x75}, {0xa1,0x76}, {0xa1,0x79}, {0xa1,0x7a}, {0xa1,0x69}, {0xa1,0x6a}, {0xa2,0x45}, - {0xa1,0x65}, {0xa1,0x66}, {0xa1,0xe3}, {0xa1,0xa9}, {0xa1,0xaa}, {0xa2,0xc3}, {0xa2,0xc4}, {0xa2,0xc5}, {0xa2,0xc6}, {0xa2,0xc7}, - {0xa2,0xc8}, {0xa2,0xc9}, {0xa2,0xca}, {0xa2,0xcb}, {0xa1,0xca}, {0xc6,0xe7}, {0xc6,0xe8}, {0xc6,0xe9}, {0xc6,0xea}, {0xc6,0xeb}, - {0xc6,0xec}, {0xc6,0xed}, {0xc6,0xee}, {0xc6,0xef}, {0xc6,0xf0}, {0xc6,0xf1}, {0xc6,0xf2}, {0xc6,0xf3}, {0xc6,0xf4}, {0xc6,0xf5}, - {0xc6,0xf6}, {0xc6,0xf7}, {0xc6,0xf8}, {0xc6,0xf9}, {0xc6,0xfa}, {0xc6,0xfb}, {0xc6,0xfc}, {0xc6,0xfd}, {0xc6,0xfe}, {0xc7,0x40}, - {0xc7,0x41}, {0xc7,0x42}, {0xc7,0x43}, {0xc7,0x44}, {0xc7,0x45}, {0xc7,0x46}, {0xc7,0x47}, {0xc7,0x48}, {0xc7,0x49}, {0xc7,0x4a}, - {0xc7,0x4b}, {0xc7,0x4c}, {0xc7,0x4d}, {0xc7,0x4e}, {0xc7,0x4f}, {0xc7,0x50}, {0xc7,0x51}, {0xc7,0x52}, {0xc7,0x53}, {0xc7,0x54}, - {0xc7,0x55}, {0xc7,0x56}, {0xc7,0x57}, {0xc7,0x58}, {0xc7,0x59}, {0xc7,0x5a}, {0xc7,0x5b}, {0xc7,0x5c}, {0xc7,0x5d}, {0xc7,0x5e}, - {0xc7,0x5f}, {0xc7,0x60}, {0xc7,0x61}, {0xc7,0x62}, {0xc7,0x63}, {0xc7,0x64}, {0xc7,0x65}, {0xc7,0x66}, {0xc7,0x67}, {0xc7,0x68}, - {0xc7,0x69}, {0xc7,0x6a}, {0xc7,0x6b}, {0xc7,0x6c}, {0xc7,0x6d}, {0xc7,0x6e}, {0xc7,0x6f}, {0xc7,0x70}, {0xc7,0x71}, {0xc7,0x72}, - {0xc7,0x73}, {0xc7,0x74}, {0xc7,0x75}, {0xc7,0x76}, {0xc7,0x77}, {0xc7,0x78}, {0xc7,0x79}, {0xc7,0x7a}, {0xc8,0xd4}, {0xc8,0xd5}, - {0xc6,0xdc}, {0xc6,0xdd}, {0xc7,0x7b}, {0xc7,0x7c}, {0xc7,0x7d}, {0xc7,0x7e}, {0xc7,0xa1}, {0xc7,0xa2}, {0xc7,0xa3}, {0xc7,0xa4}, - {0xc7,0xa5}, {0xc7,0xa6}, {0xc7,0xa7}, {0xc7,0xa8}, {0xc7,0xa9}, {0xc7,0xaa}, {0xc7,0xab}, {0xc7,0xac}, {0xc7,0xad}, {0xc7,0xae}, - {0xc7,0xaf}, {0xc7,0xb0}, {0xc7,0xb1}, {0xc7,0xb2}, {0xc7,0xb3}, {0xc7,0xb4}, {0xc7,0xb5}, {0xc7,0xb6}, {0xc7,0xb7}, {0xc7,0xb8}, - {0xc7,0xb9}, {0xc7,0xba}, {0xc7,0xbb}, {0xc7,0xbc}, {0xc7,0xbd}, {0xc7,0xbe}, {0xc7,0xbf}, {0xc7,0xc0}, {0xc7,0xc1}, {0xc7,0xc2}, - {0xc7,0xc3}, {0xc7,0xc4}, {0xc7,0xc5}, {0xc7,0xc6}, {0xc7,0xc7}, {0xc7,0xc8}, {0xc7,0xc9}, {0xc7,0xca}, {0xc7,0xcb}, {0xc7,0xcc}, - {0xc7,0xcd}, {0xc7,0xce}, {0xc7,0xcf}, {0xc7,0xd0}, {0xc7,0xd1}, {0xc7,0xd2}, {0xc7,0xd3}, {0xc7,0xd4}, {0xc7,0xd5}, {0xc7,0xd6}, - {0xc7,0xd7}, {0xc7,0xd8}, {0xc7,0xd9}, {0xc7,0xda}, {0xc7,0xdb}, {0xc7,0xdc}, {0xc7,0xdd}, {0xc7,0xde}, {0xc7,0xdf}, {0xc7,0xe0}, - {0xc7,0xe1}, {0xc7,0xe2}, {0xc7,0xe3}, {0xc7,0xe4}, {0xc7,0xe5}, {0xc7,0xe6}, {0xc7,0xe7}, {0xc7,0xe8}, {0xc7,0xe9}, {0xc7,0xea}, - {0xc7,0xeb}, {0xc7,0xec}, {0xc7,0xed}, {0xc7,0xee}, {0xc7,0xef}, {0xc7,0xf0}, {0xc7,0xf1}, {0xc7,0xf2}, {0xc6,0xe3}, {0xc6,0xda}, - {0xc6,0xdb}, {0xa3,0x74}, {0xa3,0x75}, {0xa3,0x76}, {0xa3,0x77}, {0xa3,0x78}, {0xa3,0x79}, {0xa3,0x7a}, {0xa3,0x7b}, {0xa3,0x7c}, - {0xa3,0x7d}, {0xa3,0x7e}, {0xa3,0xa1}, {0xa3,0xa2}, {0xa3,0xa3}, {0xa3,0xa4}, {0xa3,0xa5}, {0xa3,0xa6}, {0xa3,0xa7}, {0xa3,0xa8}, - {0xa3,0xa9}, {0xa3,0xaa}, {0xa3,0xab}, {0xa3,0xac}, {0xa3,0xad}, {0xa3,0xae}, {0xa3,0xaf}, {0xa3,0xb0}, {0xa3,0xb1}, {0xa3,0xb2}, - {0xa3,0xb3}, {0xa3,0xb4}, {0xa3,0xb5}, {0xa3,0xb6}, {0xa3,0xb7}, {0xa3,0xb8}, {0xa3,0xb9}, {0xa3,0xba}, {0xa4,0x40}, {0xa4,0x47}, - {0xa4,0x54}, {0xa5,0x7c}, {0xa4,0x57}, {0xa4,0xa4}, {0xa4,0x55}, {0xa5,0xd2}, {0xa4,0x41}, {0xa4,0xfe}, {0xa4,0x42}, {0xa4,0xd1}, - {0xa6,0x61}, {0xa4,0x48}, {0xa4,0x40}, {0xa4,0x47}, {0xa4,0x54}, {0xa5,0x7c}, {0xa4,0xad}, {0xa4,0xbb}, {0xa4,0x43}, {0xa4,0x4b}, - {0xa4,0x45}, {0xa4,0x51}, {0xa4,0xeb}, {0xa4,0xf5}, {0xa4,0xf4}, {0xa4,0xec}, {0xaa,0xf7}, {0xa4,0x67}, {0xa4,0xe9}, {0xc8,0xd1}, - {0xa6,0xb3}, {0xaa,0xc0}, {0xa6,0x57}, {0xaf,0x53}, {0xb0,0x5d}, {0xaf,0xac}, {0xb3,0xd2}, {0xa5,0x4e}, {0xa9,0x49}, {0xbe,0xc7}, - {0xba,0xca}, {0xa5,0xf8}, {0xb8,0xea}, {0xa8,0xf3}, {0xb2,0xbd}, {0xa5,0xf0}, {0xa6,0xdb}, {0xa6,0xdc}, {0xa4,0x40}, {0xa4,0x47}, - {0xa4,0x54}, {0xa5,0x7c}, {0xa4,0xad}, {0xa4,0xbb}, {0xa4,0x43}, {0xa4,0x4b}, {0xa4,0x45}, {0xa4,0x51}, {0xa4,0xeb}, {0xa4,0xf5}, - {0xa4,0xf4}, {0xa4,0xec}, {0xaa,0xf7}, {0xa4,0x67}, {0xa4,0xe9}, {0xae,0xe8}, {0xa6,0xb3}, {0xaa,0xc0}, {0xa6,0x57}, {0xaf,0x53}, - {0xb0,0x5d}, {0xaf,0xac}, {0xb3,0xd2}, {0xaf,0xb5}, {0xa8,0x6b}, {0xa4,0x6b}, {0xbe,0x41}, {0xc0,0x75}, {0xa6,0x4c}, {0xaa,0x60}, - {0xb6,0xb5}, {0xa5,0xf0}, {0xbc,0x67}, {0xa1,0xc0}, {0xa4,0x57}, {0xa4,0xa4}, {0xa4,0x55}, {0xa5,0xaa}, {0xa5,0x6b}, {0xc2,0xe5}, - {0xa9,0x76}, {0xbe,0xc7}, {0xba,0xca}, {0xa5,0xf8}, {0xb8,0xea}, {0xa8,0xf3}, {0xa9,0x5d}, {0xa2,0x55}, {0xa2,0x56}, {0xa2,0x50}, - {0xa2,0x51}, {0xa2,0x52}, {0xa2,0x54}, {0xa2,0x57}, {0xa2,0x53}, {0xa1,0xeb}, {0xa1,0xea}, {0xa2,0x4f}, {0x92,0x77}, {0x96,0xdf}, - {0x89,0xd5}, {0x93,0xcd}, {0x9b,0xdf}, {0xfa,0x68}, {0x89,0xda}, {0x8f,0x59}, {0x89,0xdb}, {0x8f,0x5d}, {0x89,0xdc}, {0x96,0xf7}, - {0x8a,0xda}, {0x8b,0xdc}, {0x97,0xdb}, {0x9e,0x53}, {0x9d,0xaa}, {0x9b,0xea}, {0x8a,0x6e}, {0x8b,0xc8}, {0x89,0xe8}, {0x89,0xea}, - {0x8c,0x4b}, {0xfb,0x70}, {0x89,0xed}, {0x94,0xdd}, {0x89,0xee}, {0x9e,0xb4}, {0x8a,0xd3}, {0x92,0xdb}, {0x94,0xdb}, {0x89,0xf9}, - {0xfb,0x7a}, {0x89,0xfb}, {0x9e,0xfc}, {0x89,0xfc}, {0x89,0xbf}, {0x89,0xfe}, {0x89,0xe6}, {0x9d,0x46}, {0x9d,0xee}, {0xa0,0x7e}, - {0xa0,0x68}, {0x98,0xe9}, {0x8b,0x68}, {0x8d,0xfd}, {0x8b,0xbe}, {0x9f,0xd9}, {0x8a,0xeb}, {0x9f,0xd7}, {0x8b,0x6a}, {0x9c,0x5c}, - {0x8b,0xb1}, {0xfb,0x5e}, {0x9d,0xf3}, {0xa0,0xd0}, {0xfc,0x66}, {0x92,0xe9}, {0x9a,0xec}, {0x8f,0xab}, {0xfa,0x48}, {0x8e,0x45}, - {0x9c,0x6f}, {0x9e,0xde}, {0x89,0xef}, {0x96,0xe9}, {0x9e,0xbb}, {0x94,0xde}, {0x9e,0xb8}, {0x97,0xba}, {0xfb,0x65}, {0x95,0xd6}, - {0x9c,0xbb}, {0x97,0xda}, {0x8f,0x45}, {0xfb,0x7d}, {0x91,0x58}, {0xfe,0x64}, {0x98,0x56}, {0x9b,0x4d}, {0x93,0x5b}, {0x95,0xc7}, - {0x97,0xe7}, {0x93,0x59}, {0x91,0xf5}, {0x97,0xb8}, {0xfd,0xa2}, {0xfb,0xb6}, {0x92,0xfa}, {0x93,0x57}, {0x8b,0xa6}, {0xfb,0xb9}, - {0x97,0xb0}, {0xfd,0xc4}, {0x9c,0xa1}, {0x91,0xf2}, {0x91,0xf9}, {0x8f,0xf1}, {0x97,0x45}, {0x98,0x53}, {0xfe,0x78}, {0xfb,0xc1}, - {0x92,0x51}, {0x9d,0xad}, {0xfd,0x6c}, {0xfa,0x6b}, {0x9b,0xc2}, {0x9a,0x7b}, {0x8b,0x60}, {0x93,0x4b}, {0x9a,0xbd}, {0x91,0xb7}, - {0x95,0xb4}, {0xfe,0xc5}, {0x9e,0xf0}, {0x8d,0x64}, {0x92,0x69}, {0x8d,0x67}, {0xfb,0xea}, {0xfb,0xef}, {0x8d,0x68}, {0x93,0xeb}, - {0xfc,0x42}, {0x91,0x66}, {0xfa,0xcd}, {0x93,0xdd}, {0x8b,0xcc}, {0x8d,0x6d}, {0x8d,0x6e}, {0x96,0xa8}, {0xfc,0xa6}, {0x8d,0x6f}, - {0x8d,0x70}, {0xfc,0x64}, {0x90,0x60}, {0x8d,0x74}, {0x97,0xc3}, {0x8a,0xd0}, {0x92,0x74}, {0x9b,0xbe}, {0x9c,0xc8}, {0x9c,0xba}, - {0x8d,0x78}, {0x9e,0xb9}, {0x95,0x5a}, {0x91,0xb4}, {0x8a,0x48}, {0x8d,0x7d}, {0x8a,0x7d}, {0x8a,0xc2}, {0xfd,0x4a}, {0x8d,0xa1}, - {0x8a,0xd1}, {0xfc,0xb4}, {0x8b,0x47}, {0x93,0xa4}, {0x9e,0xda}, {0x8a,0x51}, {0x8d,0xa6}, {0x9e,0xc5}, {0xfc,0xc4}, {0xa0,0x78}, - {0x94,0xb5}, {0xfc,0xc2}, {0x8a,0x6b}, {0x8d,0xab}, {0xfa,0xe8}, {0x8d,0xad}, {0xfc,0x49}, {0x93,0xc1}, {0x90,0x6f}, {0x8d,0xb0}, - {0x94,0x7e}, {0x90,0xfa}, {0x94,0x79}, {0x8d,0xb2}, {0xfc,0xee}, {0x99,0x7b}, {0x8d,0xb4}, {0x8d,0xb7}, {0x91,0xb3}, {0x8d,0xbb}, - {0x8d,0xba}, {0x8d,0xbc}, {0x90,0x44}, {0xfd,0x4c}, {0x93,0xe4}, {0x93,0xe0}, {0xfd,0x53}, {0x8d,0xc3}, {0x9b,0xb8}, {0xfb,0xf0}, - {0x93,0xe9}, {0x93,0xf6}, {0x8d,0xc5}, {0x8d,0xca}, {0x8d,0xcc}, {0xfd,0x5d}, {0x93,0xb5}, {0xfd,0x61}, {0x9c,0xf8}, {0x92,0x52}, - {0xa0,0xe8}, {0x9c,0xa5}, {0x8c,0x56}, {0x8d,0xd6}, {0x97,0xc0}, {0xa0,0xde}, {0x97,0xd2}, {0xfa,0xa5}, {0xfd,0xa3}, {0x8d,0xdb}, - {0x8e,0xaf}, {0x91,0xb5}, {0xfd,0x49}, {0xfd,0xd1}, {0x8d,0xeb}, {0x97,0xc6}, {0xfd,0xce}, {0x90,0xfc}, {0xfc,0x59}, {0x96,0xd6}, - {0x97,0xc5}, {0x8d,0xef}, {0x97,0xd7}, {0x8d,0xf0}, {0x96,0xa6}, {0xfb,0xbf}, {0x8d,0xf3}, {0x94,0x49}, {0x8d,0xf5}, {0x98,0x72}, - {0x8e,0x6b}, {0xfa,0xfd}, {0x8f,0x50}, {0x9d,0xcc}, {0xfc,0x65}, {0x8c,0x44}, {0x99,0x6e}, {0x94,0xa1}, {0x8f,0x63}, {0xa0,0xda}, - {0x92,0x53}, {0xfd,0xe9}, {0x9d,0xb5}, {0x98,0x79}, {0x9d,0x5d}, {0x8d,0x63}, {0x96,0x69}, {0x9f,0x70}, {0xfc,0x6a}, {0x8a,0xc7}, - {0x89,0xd7}, {0xfe,0x4d}, {0x9e,0xdd}, {0xfe,0xfb}, {0x98,0xbc}, {0xfa,0xcc}, {0x95,0xb0}, {0x94,0x64}, {0x93,0x6f}, {0x94,0xb9}, - {0x95,0xec}, {0x91,0xee}, {0x98,0xc3}, {0x95,0xf6}, {0x8f,0xfd}, {0x98,0xc5}, {0x97,0x66}, {0xfe,0x6e}, {0x97,0xdd}, {0x8c,0xaa}, - {0x92,0xd2}, {0x97,0x61}, {0x98,0xcb}, {0x95,0xf0}, {0x97,0x5d}, {0x91,0xe3}, {0x98,0xcc}, {0x94,0x69}, {0x98,0xcd}, {0x98,0xce}, - {0x95,0xfc}, {0x94,0xa3}, {0x96,0x62}, {0xfe,0xb6}, {0x94,0x63}, {0x98,0xd0}, {0x98,0xd1}, {0x94,0x75}, {0xfa,0xe0}, {0x94,0x72}, - {0x98,0xd6}, {0x8a,0xf0}, {0x98,0xd9}, {0x98,0xdb}, {0x98,0xdd}, {0x98,0xa8}, {0x8a,0x6d}, {0x8a,0xfb}, {0x8a,0xae}, {0xfb,0xc9}, - {0x8c,0x5d}, {0x98,0xe4}, {0x98,0xe6}, {0x98,0xe8}, {0x8a,0x4d}, {0x92,0x57}, {0x95,0xdf}, {0xa0,0xac}, {0x98,0xeb}, {0x98,0xec}, - {0x8c,0xc3}, {0x98,0xf4}, {0x8a,0xb8}, {0x9e,0xe7}, {0x94,0xbc}, {0xfc,0xd1}, {0x9c,0xc6}, {0x9e,0x7e}, {0x98,0xfe}, {0xfd,0xe8}, - {0x99,0x40}, {0x94,0xc9}, {0x94,0xd3}, {0x99,0x46}, {0x90,0xc0}, {0x94,0xd1}, {0x95,0x73}, {0x93,0xc2}, {0x99,0x48}, {0x99,0x4b}, - {0x8e,0x55}, {0x99,0x4e}, {0x8e,0xfe}, {0x8e,0x59}, {0x94,0xec}, {0x94,0xef}, {0x8c,0x60}, {0x8f,0x74}, {0x99,0x55}, {0x95,0x44}, - {0x8c,0xcb}, {0x99,0x56}, {0x99,0x59}, {0x99,0x5b}, {0x8c,0xc4}, {0xfa,0x45}, {0x90,0xb7}, {0x97,0x43}, {0x95,0xcd}, {0x97,0xc9}, - {0xfd,0x50}, {0x8e,0xb9}, {0x95,0xc6}, {0x99,0x67}, {0x8a,0xb9}, {0x8d,0xfc}, {0x8a,0x76}, {0x9d,0x51}, {0x99,0x73}, {0x9d,0x4f}, - {0x99,0x7a}, {0x95,0x64}, {0x99,0xa1}, {0x99,0xa5}, {0x99,0xa7}, {0x8e,0xed}, {0x99,0xad}, {0x94,0x6e}, {0x8f,0x70}, {0xfa,0xd0}, - {0x99,0xb3}, {0xa0,0x53}, {0x96,0x5c}, {0xfd,0x7a}, {0x97,0xfe}, {0x92,0xbd}, {0x97,0xfd}, {0x8f,0x64}, {0xfc,0xf7}, {0x95,0x62}, - {0x97,0xcd}, {0x9e,0x64}, {0x92,0x4c}, {0x8e,0xc9}, {0x99,0xbc}, {0x9d,0xa5}, {0x8f,0x54}, {0x8f,0x7c}, {0x8e,0xa2}, {0x8f,0x7a}, - {0x97,0xae}, {0x96,0xc8}, {0x99,0xc3}, {0x90,0xd6}, {0x9c,0xbe}, {0x8f,0x76}, {0x94,0x70}, {0xfb,0x4b}, {0xfd,0xca}, {0x8e,0xc7}, - {0xa0,0xf9}, {0x8f,0xa9}, {0x99,0xc7}, {0x90,0xd7}, {0x9e,0xdf}, {0x99,0xce}, {0x8f,0xba}, {0x8f,0xeb}, {0x99,0xcf}, {0x8f,0xc2}, - {0x92,0xc9}, {0x97,0xdc}, {0x95,0xb3}, {0x9c,0x79}, {0x95,0xb2}, {0x8f,0xdb}, {0x9b,0xe3}, {0x9e,0x7a}, {0x9b,0xee}, {0x99,0xde}, - {0xfa,0xfa}, {0x9e,0xe5}, {0x8a,0x52}, {0x99,0xe1}, {0x8a,0x67}, {0x8b,0xb5}, {0x8a,0xac}, {0x99,0xe9}, {0xfb,0xca}, {0x97,0xde}, - {0x95,0xd1}, {0x99,0xf5}, {0xfc,0x4a}, {0x9b,0xa9}, {0xfb,0xdc}, {0xfe,0x56}, {0x9e,0xa4}, {0x9d,0x49}, {0x95,0xdb}, {0x89,0xc5}, - {0x99,0xf8}, {0x96,0x64}, {0x90,0x55}, {0x96,0xd4}, {0x97,0x7c}, {0x96,0x4d}, {0x97,0xe1}, {0x9a,0x48}, {0x9a,0x49}, {0xfe,0x7d}, - {0x90,0xaa}, {0x9a,0x50}, {0x93,0x47}, {0x8e,0xd8}, {0x90,0xc9}, {0x9a,0x55}, {0x90,0xbc}, {0x9a,0x58}, {0x8b,0xb8}, {0x90,0xd5}, - {0x96,0x41}, {0x9a,0x5a}, {0x9a,0x5c}, {0x97,0xc2}, {0x8a,0xbb}, {0x9b,0xaa}, {0x90,0xf5}, {0x9a,0x60}, {0x91,0x45}, {0x8c,0x58}, - {0x9a,0x63}, {0x8c,0x49}, {0x8b,0xb6}, {0xfc,0xcf}, {0x96,0x6b}, {0x9a,0x6e}, {0x91,0x4f}, {0x97,0x46}, {0xa0,0xe6}, {0x92,0xd7}, - {0x96,0x75}, {0x93,0xd4}, {0x91,0xbb}, {0x96,0x79}, {0x9a,0x70}, {0x96,0x78}, {0x91,0xcd}, {0x9c,0x4a}, {0xa0,0x6f}, {0xa0,0x6a}, - {0x91,0x5f}, {0x9f,0xa5}, {0x89,0xba}, {0x9e,0xcd}, {0x9a,0x79}, {0x9d,0xce}, {0x8c,0xd2}, {0x9d,0x73}, {0x96,0xb9}, {0x96,0xbc}, - {0x9c,0xd1}, {0x89,0xb7}, {0x9e,0xee}, {0xfb,0x43}, {0x9e,0xc9}, {0xfb,0xd3}, {0x91,0xae}, {0x9d,0x78}, {0x9d,0x7b}, {0xa4,0x40}, - {0xa4,0x42}, {0xa4,0x43}, {0x9e,0xb3}, {0xc9,0x45}, {0xa4,0x56}, {0xa4,0x54}, {0xa4,0x57}, {0xa4,0x55}, {0xc9,0x46}, {0xa4,0xa3}, - {0xc9,0x4f}, {0xc9,0x4d}, {0xa4,0xa2}, {0xa4,0xa1}, {0xa5,0x42}, {0xa5,0x41}, {0xa5,0x40}, {0xa5,0x43}, {0xa4,0xfe}, {0x9e,0xb2}, - {0x9d,0xd6}, {0xa5,0xe0}, {0xa5,0xe1}, {0x99,0x4f}, {0x89,0xce}, {0xa8,0xc3}, {0x8b,0xc0}, {0x9f,0xc4}, {0xa4,0x58}, {0x8b,0xd4}, - {0xa4,0xa4}, {0xc9,0x50}, {0x8c,0x72}, {0xa4,0xa5}, {0xc9,0x63}, {0xa6,0xea}, {0xcb,0xb1}, {0xc6,0xbf}, {0x8b,0xf9}, {0xa4,0x59}, - {0xa4,0xa6}, {0xa5,0x44}, {0xc9,0x64}, {0x89,0x46}, {0xc6,0xc0}, {0xc9,0x40}, {0xa4,0x44}, {0xa4,0x5b}, {0xc9,0x47}, {0xa4,0x5c}, - {0xfa,0xe5}, {0xa4,0xa7}, {0xa5,0x45}, {0xa5,0x47}, {0xa5,0x46}, {0xa5,0xe2}, {0xa5,0xe3}, {0xa8,0xc4}, {0xad,0xbc}, {0xa4,0x41}, - {0xc8,0x7b}, {0x8b,0xc6}, {0xc9,0x41}, {0xa4,0x45}, {0xa4,0x5e}, {0xa4,0x5d}, {0xa5,0xe4}, {0x9c,0x57}, {0xa8,0xc5}, {0x9a,0xfb}, - {0xb0,0xae}, {0xd4,0x4b}, {0x89,0xd0}, {0x89,0xcf}, {0xb6,0xc3}, {0xdc,0xb1}, {0xdc,0xb2}, {0xc6,0xc1}, {0xa4,0x46}, {0x89,0xd1}, - {0xa4,0xa9}, {0x89,0xe2}, {0xa8,0xc6}, {0xa4,0x47}, {0xc9,0x48}, {0xa4,0x5f}, {0xa4,0xaa}, {0xa4,0xac}, {0xc9,0x51}, {0xa4,0xad}, - {0xa4,0xab}, {0x92,0x7e}, {0xa5,0xe5}, {0x9d,0xba}, {0xa8,0xc7}, {0xa8,0xc8}, {0xab,0x45}, {0xc6,0xc2}, {0xa4,0x60}, {0xa4,0xae}, - {0x8c,0x6f}, {0xa5,0xe6}, {0xa5,0xe8}, {0xa5,0xe7}, {0xa6,0xeb}, {0xa8,0xc9}, {0xa8,0xca}, {0xab,0x46}, {0xab,0x47}, {0xad,0xbd}, - {0xdc,0xb3}, {0xfb,0xf8}, {0xf6,0xd6}, {0xa4,0x48}, {0x8b,0xc7}, {0x92,0x6b}, {0x89,0xd2}, {0xa4,0xb0}, {0xa4,0xaf}, {0xc9,0x52}, - {0xa4,0xb1}, {0xa4,0xb7}, {0xa4,0xb2}, {0xa4,0xb3}, {0xc9,0x54}, {0xc9,0x53}, {0xa4,0xb5}, {0xa4,0xb6}, {0xa4,0xb4}, {0x9f,0xcf}, - {0xa5,0x4a}, {0xa5,0x4b}, {0xa5,0x4c}, {0xa5,0x4d}, {0xa5,0x49}, {0xa5,0x50}, {0xc9,0x6a}, {0xc9,0x66}, {0xc9,0x69}, {0xa5,0x51}, - {0xa5,0x61}, {0xc9,0x68}, {0xa5,0x4e}, {0xa5,0x4f}, {0xa5,0x48}, {0xc9,0x65}, {0xc9,0x67}, {0x9d,0xa9}, {0x89,0xd3}, {0x99,0xe2}, - {0xa5,0xf5}, {0xc9,0xb0}, {0xa5,0xf2}, {0xa5,0xf6}, {0xc9,0xba}, {0xc9,0xae}, {0xa5,0xf3}, {0xc9,0xb2}, {0x92,0x67}, {0xa5,0xf4}, - {0xa5,0xf7}, {0xa5,0xe9}, {0xc9,0xb1}, {0xa5,0xf8}, {0xc9,0xb5}, {0x92,0xa4}, {0xc9,0xb9}, {0xc9,0xb6}, {0xc9,0xb3}, {0xa5,0xea}, - {0xa5,0xec}, {0xa5,0xf9}, {0xa5,0xee}, {0xc9,0xab}, {0xa5,0xf1}, {0xa5,0xef}, {0xa5,0xf0}, {0xc9,0xbb}, {0xc9,0xb8}, {0xc9,0xaf}, - {0xa5,0xed}, {0x8c,0x73}, {0xc9,0xac}, {0xa5,0xeb}, {0x89,0x4e}, {0xc9,0xb4}, {0xc9,0xb7}, {0x89,0x4f}, {0x92,0x78}, {0xc9,0xad}, - {0xca,0x66}, {0xa7,0x42}, {0xa6,0xf4}, {0x91,0xb6}, {0xca,0x67}, {0xa6,0xf1}, {0xa7,0x44}, {0x89,0xd4}, {0xa6,0xf9}, {0x9f,0xd2}, - {0xa6,0xf8}, {0xca,0x5b}, {0xa6,0xfc}, {0xa6,0xf7}, {0xca,0x60}, {0xca,0x68}, {0xca,0x64}, {0x92,0xa7}, {0xa6,0xfa}, {0x95,0xa2}, - {0xa6,0xfd}, {0xa6,0xee}, {0xa7,0x47}, {0xca,0x5d}, {0x92,0x6e}, {0xcb,0xbd}, {0xa6,0xec}, {0xa7,0x43}, {0xa6,0xed}, {0xa6,0xf5}, - {0xa6,0xf6}, {0xca,0x62}, {0xca,0x5e}, {0xa6,0xfb}, {0xa6,0xf3}, {0xca,0x5a}, {0xa6,0xef}, {0xca,0x65}, {0xa7,0x45}, {0xa7,0x48}, - {0xa6,0xf2}, {0xa7,0x40}, {0xa7,0x46}, {0xa6,0xf0}, {0xca,0x63}, {0xa7,0x41}, {0xca,0x69}, {0xca,0x5c}, {0xa6,0xfe}, {0xca,0x5f}, - {0xca,0x61}, {0xa8,0xd8}, {0xcb,0xbf}, {0xcb,0xcb}, {0xa8,0xd0}, {0xcb,0xcc}, {0xa8,0xcb}, {0xa8,0xd5}, {0x96,0xea}, {0xa8,0xce}, - {0xcb,0xb9}, {0xa8,0xd6}, {0xcb,0xb8}, {0xcb,0xbc}, {0xcb,0xc3}, {0xcb,0xc1}, {0xa8,0xde}, {0xa8,0xd9}, {0xcb,0xb3}, {0xcb,0xb5}, - {0xa8,0xdb}, {0xa8,0xcf}, {0xcb,0xb6}, {0xcb,0xc2}, {0xcb,0xc9}, {0xa8,0xd4}, {0xcb,0xbb}, {0xcb,0xb4}, {0xa8,0xd3}, {0xcb,0xb7}, - {0xa8,0xd7}, {0xcb,0xba}, {0x92,0x6f}, {0xa8,0xd2}, {0xa8,0xcd}, {0xa8,0xdc}, {0xcb,0xc4}, {0xa8,0xdd}, {0xcb,0xc8}, {0xcb,0xc6}, - {0xcb,0xca}, {0xa8,0xda}, {0xcb,0xbe}, {0xcb,0xb2}, {0xcb,0xc0}, {0xa8,0xd1}, {0xcb,0xc5}, {0xa8,0xcc}, {0xcb,0xc7}, {0x92,0xa3}, - {0x89,0x50}, {0xfa,0x57}, {0xab,0x56}, {0xab,0x4a}, {0x98,0x66}, {0xcd,0xe0}, {0xcd,0xe8}, {0xab,0x49}, {0xab,0x51}, {0xab,0x5d}, - {0xcd,0xee}, {0xcd,0xec}, {0xcd,0xe7}, {0x89,0xd6}, {0xab,0x4b}, {0xcd,0xed}, {0xcd,0xe3}, {0xab,0x59}, {0xab,0x50}, {0xab,0x58}, - {0xcd,0xde}, {0xcd,0xea}, {0x98,0xb2}, {0xcd,0xe1}, {0xab,0x54}, {0xcd,0xe2}, {0x92,0xab}, {0xcd,0xdd}, {0xab,0x5b}, {0xab,0x4e}, - {0xab,0x57}, {0xab,0x4d}, {0xcd,0xdf}, {0xcd,0xe4}, {0xcd,0xeb}, {0xab,0x55}, {0xab,0x52}, {0xcd,0xe6}, {0xab,0x5a}, {0xcd,0xe9}, - {0xcd,0xe5}, {0xab,0x4f}, {0xab,0x5c}, {0xab,0x53}, {0xab,0x4c}, {0xab,0x48}, {0x96,0xde}, {0x92,0xac}, {0xcd,0xef}, {0xad,0xd7}, - {0xad,0xc1}, {0x8c,0x70}, {0xad,0xd1}, {0x9f,0x6e}, {0xad,0xd6}, {0xd0,0xd0}, {0xd0,0xcf}, {0xd0,0xd4}, {0xd0,0xd5}, {0xad,0xc4}, - {0x8e,0xf2}, {0xad,0xcd}, {0x9f,0x6c}, {0xad,0xda}, {0xad,0xce}, {0x89,0xd8}, {0xd0,0xc9}, {0xad,0xc7}, {0xd0,0xca}, {0xfa,0x59}, - {0xad,0xdc}, {0xad,0xd3}, {0xad,0xbe}, {0xad,0xbf}, {0xd0,0xdd}, {0xb0,0xbf}, {0xad,0xcc}, {0xad,0xcb}, {0xd0,0xcb}, {0xad,0xcf}, - {0xd4,0x5b}, {0xad,0xc6}, {0xd0,0xd6}, {0xad,0xd5}, {0xad,0xd4}, {0xad,0xca}, {0xd0,0xce}, {0xd0,0xd7}, {0xd0,0xc8}, {0xad,0xc9}, - {0xd0,0xd8}, {0xad,0xd2}, {0xd0,0xcc}, {0xad,0xc0}, {0xad,0xc3}, {0xad,0xc2}, {0xd0,0xd9}, {0xad,0xd0}, {0xad,0xc5}, {0xad,0xd9}, - {0xad,0xdb}, {0xd0,0xd3}, {0xad,0xd8}, {0x92,0xa8}, {0xd0,0xdb}, {0xd0,0xcd}, {0xd0,0xdc}, {0xd0,0xd1}, {0x91,0x63}, {0xd0,0xda}, - {0xd0,0xd2}, {0x8c,0x40}, {0xad,0xc8}, {0xd4,0x63}, {0xd4,0x57}, {0xb0,0xb3}, {0xd4,0x5c}, {0xd4,0x62}, {0xb0,0xb2}, {0xd4,0x55}, - {0xb0,0xb6}, {0xd4,0x59}, {0xd4,0x52}, {0xb0,0xb4}, {0xd4,0x56}, {0xb0,0xb9}, {0xb0,0xbe}, {0xd4,0x67}, {0xd4,0x51}, {0xb0,0xba}, - {0x9f,0x73}, {0xd4,0x66}, {0x92,0xad}, {0xb0,0xb5}, {0xd4,0x58}, {0xb0,0xb1}, {0xd4,0x53}, {0xd4,0x4f}, {0xd4,0x5d}, {0xd4,0x50}, - {0xd4,0x4e}, {0xd4,0x5a}, {0xd4,0x60}, {0xd4,0x61}, {0xb0,0xb7}, {0x9b,0xe9}, {0xd8,0x5b}, {0xd4,0x5e}, {0xd4,0x4d}, {0xd4,0x5f}, - {0x92,0xa9}, {0xb0,0xc1}, {0xd4,0x64}, {0xb0,0xc0}, {0xd4,0x4c}, {0xd4,0x54}, {0xd4,0x65}, {0xb0,0xbc}, {0xb0,0xbb}, {0xb0,0xb8}, - {0xb0,0xbd}, {0xb0,0xaf}, {0xb0,0xb0}, {0xb3,0xc8}, {0x92,0xaa}, {0xd8,0x5e}, {0xd8,0x57}, {0xb3,0xc5}, {0xd8,0x5f}, {0x89,0xd9}, - {0xd8,0x55}, {0xd8,0x58}, {0xb3,0xc4}, {0xd8,0x59}, {0xfd,0x56}, {0xb3,0xc7}, {0xd8,0x5d}, {0xd8,0x53}, {0xd8,0x52}, {0xb3,0xc9}, - {0xb3,0xca}, {0xb3,0xc6}, {0xb3,0xcb}, {0xd8,0x51}, {0xd8,0x5c}, {0xd8,0x5a}, {0xd8,0x54}, {0xb3,0xc3}, {0xd8,0x56}, {0x9f,0xa8}, - {0xb6,0xca}, {0xb6,0xc4}, {0xdc,0xb7}, {0xb6,0xcd}, {0xdc,0xbd}, {0xdc,0xc0}, {0xb6,0xc6}, {0xb6,0xc7}, {0xdc,0xba}, {0xb6,0xc5}, - {0xdc,0xc3}, {0xb6,0xcb}, {0xdc,0xc4}, {0xdc,0xbf}, {0xb6,0xcc}, {0x8c,0x71}, {0xdc,0xb4}, {0xb6,0xc9}, {0xdc,0xb5}, {0xdc,0xbe}, - {0xdc,0xbc}, {0xdc,0xb8}, {0xb6,0xc8}, {0xdc,0xb6}, {0xb6,0xce}, {0xdc,0xbb}, {0xdc,0xc2}, {0xdc,0xb9}, {0xdc,0xc1}, {0x92,0xa1}, - {0xb9,0xb6}, {0xb9,0xb3}, {0x90,0xe3}, {0xb9,0xb4}, {0xe0,0xf9}, {0xe0,0xf1}, {0xb9,0xb2}, {0xb9,0xaf}, {0xe0,0xf2}, {0xa0,0xa6}, - {0xb9,0xb1}, {0xe0,0xf5}, {0xe0,0xf7}, {0x94,0xab}, {0xe0,0xfe}, {0xfc,0x72}, {0xe0,0xfd}, {0xe0,0xf8}, {0xb9,0xae}, {0xe0,0xf0}, - {0xb9,0xac}, {0xe0,0xf3}, {0xb9,0xb7}, {0xe0,0xf6}, {0xe0,0xfa}, {0xb9,0xb0}, {0xb9,0xad}, {0xe0,0xfc}, {0xe0,0xfb}, {0xb9,0xb5}, - {0xe0,0xf4}, {0x97,0xc4}, {0xbb,0xf8}, {0xe4,0xec}, {0xe4,0xe9}, {0xbb,0xf9}, {0xbb,0xf7}, {0x92,0xae}, {0xe4,0xf0}, {0xe4,0xed}, - {0xe4,0xe6}, {0xbb,0xf6}, {0xfa,0x67}, {0xbb,0xfa}, {0xe4,0xe7}, {0xbb,0xf5}, {0xbb,0xfd}, {0xe4,0xea}, {0xe4,0xeb}, {0xbb,0xfb}, - {0xbb,0xfc}, {0xe4,0xf1}, {0xe4,0xee}, {0xe4,0xef}, {0x92,0xa2}, {0xfa,0x69}, {0xbe,0xaa}, {0xe8,0xf8}, {0xbe,0xa7}, {0xe8,0xf5}, - {0xbe,0xa9}, {0xbe,0xab}, {0xe8,0xf6}, {0xbe,0xa8}, {0xe8,0xf7}, {0xe8,0xf4}, {0xc0,0x76}, {0xec,0xbd}, {0xc0,0x77}, {0xec,0xbb}, - {0xec,0xbc}, {0xec,0xba}, {0xec,0xb9}, {0xec,0xbe}, {0xc0,0x75}, {0x92,0x68}, {0xef,0xb8}, {0xef,0xb9}, {0xe4,0xe8}, {0xef,0xb7}, - {0xc0,0x78}, {0xc3,0x5f}, {0xf1,0xeb}, {0xf1,0xec}, {0xc4,0xd7}, {0xc4,0xd8}, {0xf5,0xc1}, {0xf5,0xc0}, {0xc5,0x6c}, {0xc5,0x6b}, - {0xf7,0xd0}, {0xa4,0x49}, {0xa4,0x61}, {0xa4,0xb9}, {0xa4,0xb8}, {0xa5,0x53}, {0xa5,0x52}, {0xa5,0xfc}, {0xa5,0xfb}, {0xa5,0xfd}, - {0xa5,0xfa}, {0xa7,0x4a}, {0xa7,0x49}, {0xa7,0x4b}, {0xa8,0xe0}, {0xa8,0xdf}, {0xa8,0xe1}, {0x89,0x51}, {0xab,0x5e}, {0xa2,0x59}, - {0xd0,0xde}, {0xa2,0x5a}, {0xb0,0xc2}, {0xa2,0x5c}, {0xa2,0x5b}, {0xd8,0x60}, {0xfa,0x6f}, {0xa2,0x5d}, {0xb9,0xb8}, {0xa2,0x5e}, - {0xa4,0x4a}, {0xa4,0xba}, {0xa5,0xfe}, {0xa8,0xe2}, {0xfa,0x71}, {0xa4,0x4b}, {0xa4,0xbd}, {0xa4,0xbb}, {0xa4,0xbc}, {0xa6,0x40}, - {0x89,0x52}, {0xa7,0x4c}, {0xa8,0xe4}, {0xa8,0xe3}, {0xa8,0xe5}, {0x94,0x5a}, {0xad,0xdd}, {0xbe,0xac}, {0xc6,0xc3}, {0x89,0xdd}, - {0xc9,0x4e}, {0xc8,0xa2}, {0xa5,0x54}, {0xa5,0x55}, {0xa6,0x41}, {0xca,0x6a}, {0xab,0x60}, {0xab,0x5f}, {0xd0,0xe0}, {0xd0,0xdf}, - {0xb0,0xc3}, {0xc6,0xc4}, {0xa4,0xbe}, {0xc9,0x55}, {0x9e,0x52}, {0x89,0x53}, {0xcb,0xcd}, {0xab,0x61}, {0xad,0xe0}, {0xad,0xde}, - {0xad,0xdf}, {0x9e,0x55}, {0x92,0xba}, {0xbe,0xad}, {0xc6,0xc5}, {0xa5,0x56}, {0x8c,0x5b}, {0xa6,0x42}, {0xc9,0xbc}, {0xfa,0x7d}, - {0xfa,0xa8}, {0x9a,0x68}, {0xfa,0x47}, {0xa7,0x4d}, {0xa7,0x4e}, {0xfa,0x7e}, {0xca,0x6b}, {0xcb,0xce}, {0xa8,0xe6}, {0xcb,0xcf}, - {0x92,0xbb}, {0xd0,0xe2}, {0xd0,0xe3}, {0xad,0xe3}, {0xfd,0xb6}, {0xd0,0xe4}, {0xfa,0xa2}, {0xd0,0xe1}, {0xad,0xe4}, {0xad,0xe2}, - {0xad,0xe1}, {0xd0,0xe5}, {0xfa,0xa3}, {0xd4,0x68}, {0xfa,0xa4}, {0x9b,0xb4}, {0xfa,0xa6}, {0xd8,0x61}, {0xdc,0xc5}, {0xe1,0x40}, - {0x89,0xdf}, {0xbb,0xfe}, {0xbe,0xae}, {0xe8,0xf9}, {0xfd,0xdb}, {0xa4,0x4c}, {0xa4,0x5a}, {0xfa,0xa9}, {0x89,0x54}, {0xfa,0xab}, - {0xb0,0xc4}, {0xb3,0xcd}, {0xb9,0xb9}, {0xfc,0x7a}, {0xc9,0x42}, {0xa4,0xbf}, {0xa5,0x59}, {0xa5,0x57}, {0xa5,0x58}, {0x89,0xe0}, - {0xa8,0xe7}, {0x9f,0x4f}, {0xa4,0x4d}, {0xa4,0x4e}, {0xc8,0x7d}, {0xa4,0x62}, {0x89,0xe1}, {0xa4,0xc0}, {0xa4,0xc1}, {0xa4,0xc2}, - {0xc9,0xbe}, {0xa5,0x5a}, {0xfa,0xb0}, {0xc9,0x6b}, {0xa6,0x46}, {0xc9,0xbf}, {0xa6,0x44}, {0xa6,0x45}, {0xc9,0xbd}, {0xa6,0x47}, - {0xa6,0x43}, {0xca,0x6c}, {0xaa,0xec}, {0xca,0x6d}, {0x9f,0xcd}, {0xa0,0xe7}, {0xca,0x6e}, {0xa7,0x50}, {0xa7,0x4f}, {0xfa,0xb1}, - {0x89,0xa6}, {0xa7,0x53}, {0xa7,0x51}, {0xa7,0x52}, {0xa8,0xed}, {0xa8,0xec}, {0xcb,0xd4}, {0xcb,0xd1}, {0xcb,0xd2}, {0x9e,0xfa}, - {0xcb,0xd0}, {0xa8,0xee}, {0xa8,0xea}, {0xa8,0xe9}, {0xa8,0xeb}, {0xa8,0xe8}, {0xfa,0xb2}, {0xa8,0xef}, {0xab,0x63}, {0xcd,0xf0}, - {0xcb,0xd3}, {0xab,0x68}, {0xcd,0xf1}, {0xab,0x64}, {0xab,0x67}, {0xab,0x66}, {0xab,0x65}, {0xab,0x62}, {0xd0,0xe8}, {0xad,0xe7}, - {0xd0,0xeb}, {0xad,0xe5}, {0xfa,0xb4}, {0x92,0xc4}, {0xd0,0xe7}, {0xad,0xe8}, {0xad,0xe6}, {0xad,0xe9}, {0xd0,0xe9}, {0xd0,0xea}, - {0x9f,0x6f}, {0xd0,0xe6}, {0xd0,0xec}, {0x8b,0xb0}, {0xb3,0xd1}, {0xb0,0xc5}, {0xd4,0x69}, {0xd4,0x6b}, {0xd4,0x6a}, {0xd4,0x6c}, - {0xb0,0xc6}, {0xb3,0xce}, {0x9f,0xac}, {0xb3,0xcf}, {0xb3,0xd0}, {0xb6,0xd0}, {0xdc,0xc7}, {0x89,0xe3}, {0xdc,0xc6}, {0xdc,0xc8}, - {0xdc,0xc9}, {0xb6,0xd1}, {0xb6,0xcf}, {0xe1,0x41}, {0xe1,0x42}, {0xb9,0xbb}, {0xb9,0xba}, {0xe3,0x5a}, {0xbc,0x40}, {0xbc,0x41}, - {0xbc,0x42}, {0xbc,0x44}, {0xe4,0xf2}, {0xe4,0xf3}, {0xbc,0x43}, {0x9b,0xd3}, {0x89,0xe4}, {0xbe,0xaf}, {0xbe,0xb0}, {0xfa,0xb5}, - {0xf1,0xed}, {0xf5,0xc3}, {0xf5,0xc2}, {0xf7,0xd1}, {0x9f,0xd5}, {0xa4,0x4f}, {0xa5,0x5c}, {0xa5,0x5b}, {0x89,0x55}, {0xa6,0x48}, - {0x92,0xc5}, {0xc9,0xc0}, {0x89,0x56}, {0xa7,0x55}, {0xa7,0x56}, {0xa7,0x54}, {0xa7,0x57}, {0xca,0x6f}, {0xca,0x70}, {0xfa,0xb3}, - {0xfa,0xb6}, {0xa8,0xf1}, {0xcb,0xd5}, {0xa8,0xf0}, {0xcd,0xf2}, {0xab,0x6c}, {0xcd,0xf3}, {0xab,0x6b}, {0xfa,0xb7}, {0xab,0x69}, - {0xab,0x6a}, {0x9e,0xdc}, {0xd0,0xed}, {0xfb,0xc4}, {0x9f,0x71}, {0xb0,0xc7}, {0xd4,0x6e}, {0xb0,0xca}, {0xd4,0x6d}, {0xb1,0xe5}, - {0xb0,0xc9}, {0xb0,0xc8}, {0xb3,0xd4}, {0xb3,0xd3}, {0xb3,0xd2}, {0xb6,0xd2}, {0xfa,0xba}, {0x92,0xc7}, {0xb6,0xd5}, {0xb6,0xd6}, - {0xb6,0xd4}, {0xb6,0xd3}, {0xe1,0x43}, {0xe1,0x44}, {0xe4,0xf5}, {0xbc,0x45}, {0xe4,0xf4}, {0xbe,0xb1}, {0xec,0xbf}, {0xc0,0x79}, - {0xf1,0xee}, {0xc4,0x55}, {0xc6,0xc6}, {0xa4,0x63}, {0xa4,0xc3}, {0xc9,0x56}, {0xa4,0xc4}, {0xa4,0xc5}, {0x9a,0x4c}, {0xa5,0x5d}, - {0xa5,0x5e}, {0xa6,0x49}, {0xca,0x71}, {0xcb,0xd6}, {0xcb,0xd7}, {0xab,0x6d}, {0xd0,0xee}, {0xb0,0xcc}, {0xb0,0xcb}, {0xd8,0x63}, - {0xd8,0x62}, {0xa4,0x50}, {0xa4,0xc6}, {0xa5,0x5f}, {0xb0,0xcd}, {0xc9,0x43}, {0xc9,0x6c}, {0xa5,0x60}, {0xc9,0xc2}, {0xa6,0x4b}, - {0xa6,0x4a}, {0xc9,0xc1}, {0xa7,0x58}, {0x8c,0x68}, {0x89,0xe5}, {0xad,0xea}, {0x9f,0x7d}, {0xd4,0x6f}, {0xb6,0xd7}, {0xe1,0x45}, - {0xb9,0xbc}, {0xa0,0xa9}, {0xfa,0xc4}, {0xe8,0xfa}, {0xf3,0xfd}, {0xc6,0xc7}, {0xa4,0xc7}, {0x89,0x57}, {0xcb,0xd8}, {0xcd,0xf4}, - {0xb0,0xd0}, {0xb0,0xce}, {0xb0,0xcf}, {0xa4,0x51}, {0xfa,0xaa}, {0xa4,0x64}, {0xa2,0xcd}, {0xa4,0xca}, {0xa4,0xc9}, {0xa4,0xc8}, - {0xa5,0x63}, {0xa5,0x62}, {0xc9,0x6d}, {0xc9,0xc3}, {0x89,0x58}, {0xa8,0xf5}, {0xa8,0xf2}, {0xa8,0xf4}, {0xa8,0xf3}, {0xab,0x6e}, - {0xb3,0xd5}, {0xa4,0x52}, {0x8b,0xe3}, {0xa4,0xcb}, {0x8b,0x61}, {0xa5,0x65}, {0xa5,0x64}, {0xca,0x72}, {0x9a,0xf1}, {0xa8,0xf6}, - {0x9e,0xb7}, {0xc6,0xc8}, {0xc9,0x57}, {0xfa,0xd1}, {0xa5,0x67}, {0xa5,0x66}, {0xa6,0x4c}, {0xa6,0x4d}, {0xca,0x73}, {0xa7,0x59}, - {0xfa,0xd2}, {0xa7,0x5a}, {0xa8,0xf7}, {0xa8,0xf8}, {0xa8,0xf9}, {0xab,0x6f}, {0xcd,0xf5}, {0x9e,0xba}, {0xfa,0xd4}, {0xad,0xeb}, - {0xc9,0x44}, {0xa4,0xcc}, {0xc9,0xc4}, {0xca,0x74}, {0xca,0x75}, {0xcb,0xd9}, {0xfa,0xd9}, {0xcb,0xda}, {0xcd,0xf7}, {0xcd,0xf6}, - {0xcd,0xf9}, {0xcd,0xf8}, {0xab,0x70}, {0xd4,0x70}, {0xad,0xed}, {0xd0,0xef}, {0xad,0xec}, {0xfa,0xdb}, {0x9c,0xe0}, {0xd8,0x64}, - {0xb3,0xd6}, {0xfb,0xf7}, {0xd8,0x65}, {0xfb,0xfa}, {0x89,0xe7}, {0xa0,0x7a}, {0xfa,0xdc}, {0xe1,0x46}, {0xb9,0xbd}, {0xfa,0xdd}, - {0x89,0xe9}, {0xbc,0x46}, {0xf1,0xef}, {0xc6,0xc9}, {0xc9,0x58}, {0xa5,0x68}, {0xfa,0xe2}, {0x89,0xeb}, {0xb0,0xd1}, {0xfa,0xe3}, - {0xa4,0x53}, {0xa4,0x65}, {0xa4,0xce}, {0xa4,0xcd}, {0x90,0xc8}, {0xa4,0xcf}, {0x92,0xda}, {0x89,0x59}, {0x9c,0xf5}, {0xa8,0xfb}, - {0xa8,0xfa}, {0xa8,0xfc}, {0x89,0x5a}, {0xfa,0xe7}, {0x9f,0xa2}, {0xab,0x71}, {0xad,0xee}, {0xfa,0xea}, {0xe8,0xfb}, {0xc2,0x4f}, - {0xa4,0x66}, {0xa5,0x6a}, {0xa5,0x79}, {0xa5,0x74}, {0xa5,0x6f}, {0xa5,0x6e}, {0xa5,0x75}, {0xa5,0x73}, {0xa5,0x6c}, {0xa5,0x7a}, - {0xa5,0x6d}, {0xa5,0x69}, {0xa5,0x78}, {0xa5,0x77}, {0xa5,0x76}, {0xa5,0x6b}, {0xa5,0x72}, {0xfa,0xed}, {0x8f,0xad}, {0xa5,0x71}, - {0xa5,0x7b}, {0xa5,0x70}, {0xfb,0x59}, {0xa6,0x53}, {0xa6,0x59}, {0xa6,0x55}, {0xa6,0x5b}, {0xc9,0xc5}, {0xa6,0x58}, {0xa6,0x4e}, - {0xa6,0x51}, {0xa6,0x54}, {0xa6,0x50}, {0xa6,0x57}, {0xa6,0x5a}, {0xa6,0x4f}, {0xa6,0x52}, {0xa6,0x56}, {0xa6,0x5c}, {0xfa,0xef}, - {0x96,0xef}, {0x9d,0xec}, {0xca,0x7e}, {0xca,0x7b}, {0x9d,0xca}, {0xa7,0x67}, {0xca,0x7c}, {0xa7,0x5b}, {0xa7,0x5d}, {0xa7,0x75}, - {0xa7,0x70}, {0xfd,0x6d}, {0x89,0xec}, {0xca,0xa5}, {0xca,0x7d}, {0xa7,0x5f}, {0xa7,0x61}, {0xca,0xa4}, {0xa7,0x68}, {0xca,0x78}, - {0xa7,0x74}, {0xa7,0x76}, {0xa7,0x5c}, {0xa7,0x6d}, {0xfb,0x44}, {0xca,0x76}, {0xa7,0x73}, {0x9d,0xe2}, {0xa7,0x64}, {0x8c,0x75}, - {0xa7,0x6e}, {0xa7,0x6f}, {0xca,0x77}, {0xa7,0x6c}, {0xa7,0x6a}, {0xa7,0x6b}, {0xa7,0x71}, {0xca,0xa1}, {0xa7,0x5e}, {0xa7,0x72}, - {0xca,0xa3}, {0xa7,0x66}, {0xa7,0x63}, {0xca,0x7a}, {0xa7,0x62}, {0xca,0xa6}, {0xa7,0x65}, {0xa7,0x69}, {0x9e,0xc0}, {0x9e,0x56}, - {0xa7,0x60}, {0xca,0xa2}, {0xca,0x79}, {0xcb,0xeb}, {0xcb,0xea}, {0xa9,0x4f}, {0xcb,0xed}, {0xcb,0xef}, {0xcb,0xe4}, {0xcb,0xe7}, - {0xcb,0xee}, {0xa9,0x50}, {0x9f,0x79}, {0x9a,0xc7}, {0xcb,0xe1}, {0xcb,0xe5}, {0xfa,0xf4}, {0xcb,0xe9}, {0xce,0x49}, {0xa9,0x4b}, - {0xce,0x4d}, {0xa8,0xfd}, {0xcb,0xe6}, {0xa8,0xfe}, {0xa9,0x4c}, {0xa9,0x45}, {0xa9,0x41}, {0xcb,0xe2}, {0xa9,0x44}, {0xa9,0x49}, - {0xa9,0x52}, {0xcb,0xe3}, {0xcb,0xdc}, {0xa9,0x43}, {0xcb,0xdd}, {0xcb,0xdf}, {0xa9,0x46}, {0x98,0xa1}, {0xa9,0x48}, {0xcb,0xdb}, - {0xcb,0xe0}, {0xa9,0x51}, {0xa9,0x4d}, {0xcb,0xe8}, {0xa9,0x53}, {0xfa,0xf8}, {0xa9,0x4a}, {0xcb,0xde}, {0xa9,0x47}, {0x89,0xf0}, - {0x9e,0x47}, {0xa9,0x42}, {0xa9,0x40}, {0x9d,0xf7}, {0xcb,0xec}, {0xa9,0x4e}, {0x9f,0xd3}, {0x9a,0xca}, {0xce,0x48}, {0xcd,0xfb}, - {0xce,0x4b}, {0x89,0xf1}, {0xfa,0xf9}, {0xcd,0xfd}, {0xab,0x78}, {0xab,0xa8}, {0xab,0x74}, {0xab,0xa7}, {0xab,0x7d}, {0xab,0xa4}, - {0xab,0x72}, {0xcd,0xfc}, {0xce,0x43}, {0xab,0xa3}, {0xce,0x4f}, {0xab,0xa5}, {0x8e,0x5a}, {0xab,0x79}, {0x89,0xf2}, {0xce,0x45}, - {0xce,0x42}, {0xab,0x77}, {0x89,0xf3}, {0xcd,0xfa}, {0xab,0xa6}, {0xce,0x4a}, {0xab,0x7c}, {0xce,0x4c}, {0xab,0xa9}, {0xab,0x73}, - {0xab,0x7e}, {0xab,0x7b}, {0xce,0x40}, {0xab,0xa1}, {0xce,0x46}, {0xce,0x47}, {0xab,0x7a}, {0xab,0xa2}, {0xab,0x76}, {0x92,0x5d}, - {0x8b,0x51}, {0x92,0xe0}, {0xab,0x75}, {0xcd,0xfe}, {0x89,0xf4}, {0xce,0x44}, {0x9f,0xd4}, {0xce,0x4e}, {0xd1,0x44}, {0xad,0xfb}, - {0xd0,0xf1}, {0x8a,0x79}, {0xd0,0xf6}, {0xad,0xf4}, {0xae,0x40}, {0xd0,0xf4}, {0xad,0xef}, {0xad,0xf9}, {0xad,0xfe}, {0xd0,0xfb}, - {0xad,0xfa}, {0xad,0xfd}, {0x89,0xf5}, {0xd0,0xfe}, {0xad,0xf5}, {0xd0,0xf5}, {0xd1,0x42}, {0xd1,0x43}, {0xad,0xf7}, {0xd1,0x41}, - {0xad,0xf3}, {0xae,0x43}, {0xd0,0xf8}, {0xad,0xf1}, {0x97,0xa7}, {0xd1,0x46}, {0xd0,0xf9}, {0xd0,0xfd}, {0xad,0xf6}, {0xae,0x42}, - {0xd0,0xfa}, {0xad,0xfc}, {0xd1,0x40}, {0xd1,0x47}, {0xd4,0xa1}, {0x93,0xba}, {0xd1,0x45}, {0xae,0x44}, {0xad,0xf0}, {0xd0,0xfc}, - {0xd0,0xf3}, {0x9e,0x58}, {0xad,0xf8}, {0xd0,0xf2}, {0x89,0xf6}, {0xd0,0xf7}, {0x9e,0x57}, {0x89,0xf7}, {0x8a,0x41}, {0xd0,0xf0}, - {0xae,0x41}, {0x89,0xf8}, {0xd4,0x77}, {0xfa,0xf1}, {0xb0,0xe4}, {0xd4,0xa7}, {0xb0,0xe2}, {0xb0,0xdf}, {0xd4,0x7c}, {0xb0,0xdb}, - {0xd4,0xa2}, {0xb0,0xe6}, {0xd4,0x76}, {0xd4,0x7b}, {0xd4,0x7a}, {0xad,0xf2}, {0xb0,0xe1}, {0xd4,0xa5}, {0xd4,0xa8}, {0xd4,0x73}, - {0xb3,0xe8}, {0x89,0xfa}, {0xd4,0xa9}, {0xb0,0xe7}, {0xb0,0xd9}, {0xb0,0xd6}, {0xd4,0x7e}, {0xb0,0xd3}, {0xfb,0x42}, {0xd4,0xa6}, - {0xfa,0xbf}, {0xb0,0xda}, {0xd4,0xaa}, {0xd4,0x74}, {0xd4,0xa4}, {0xb0,0xdd}, {0xd4,0x75}, {0xd4,0x78}, {0xd4,0x7d}, {0xfb,0xa3}, - {0xb0,0xde}, {0xb0,0xdc}, {0xb0,0xe8}, {0xb0,0xe3}, {0xfa,0xf7}, {0xb0,0xd7}, {0xb1,0xd2}, {0xb0,0xd8}, {0xd4,0x79}, {0xb0,0xe5}, - {0xb0,0xe0}, {0xd4,0xa3}, {0xb0,0xd5}, {0x9e,0x4e}, {0xb0,0xd4}, {0x94,0xdc}, {0x95,0xda}, {0x9d,0xf8}, {0x9f,0x6a}, {0xd4,0x71}, - {0xd4,0x72}, {0xd8,0x6a}, {0x8a,0xb7}, {0xb3,0xd7}, {0xb3,0xda}, {0xd8,0x75}, {0xb3,0xee}, {0xd8,0x78}, {0xb3,0xd8}, {0xd8,0x71}, - {0xb3,0xde}, {0xb3,0xe4}, {0xb5,0xbd}, {0xfb,0x46}, {0xb3,0xe2}, {0xd8,0x6e}, {0xb3,0xef}, {0xb3,0xdb}, {0xb3,0xe3}, {0xd8,0x76}, - {0xdc,0xd7}, {0xd8,0x7b}, {0xd8,0x6f}, {0x8a,0x46}, {0xd8,0x66}, {0xd8,0x73}, {0xd8,0x6d}, {0xb3,0xe1}, {0xd8,0x79}, {0xb3,0xdd}, - {0xb3,0xf1}, {0xb3,0xea}, {0xb3,0xdf}, {0xb3,0xdc}, {0xb3,0xe7}, {0xd8,0x7a}, {0xd8,0x6c}, {0xd8,0x72}, {0xd8,0x74}, {0xd8,0x68}, - {0xd8,0x77}, {0xb3,0xd9}, {0xd8,0x67}, {0xfb,0x47}, {0xb3,0xe0}, {0xb3,0xf0}, {0xb3,0xec}, {0xd8,0x69}, {0xb3,0xe6}, {0x91,0x48}, - {0xb3,0xed}, {0xb3,0xe9}, {0xb3,0xe5}, {0x92,0xde}, {0xd8,0x70}, {0x8b,0x53}, {0x9d,0xf6}, {0xb3,0xeb}, {0x9b,0xda}, {0xdc,0xd5}, - {0xdc,0xd1}, {0x9d,0x7e}, {0xdc,0xe0}, {0xdc,0xca}, {0xdc,0xd3}, {0xb6,0xe5}, {0xb6,0xe6}, {0xb6,0xde}, {0xdc,0xdc}, {0xb6,0xe8}, - {0xdc,0xcf}, {0xdc,0xce}, {0xdc,0xcc}, {0xdc,0xde}, {0xb6,0xdc}, {0xdc,0xd8}, {0xdc,0xcd}, {0xb6,0xdf}, {0xdc,0xd6}, {0xb6,0xda}, - {0xdc,0xd2}, {0xdc,0xd9}, {0xdc,0xdb}, {0x89,0xfd}, {0x99,0xe4}, {0xdc,0xdf}, {0xb6,0xe3}, {0xdc,0xcb}, {0xb6,0xdd}, {0xdc,0xd0}, - {0x9e,0x43}, {0xb6,0xd8}, {0xb6,0xe4}, {0xdc,0xda}, {0xb6,0xe0}, {0xb6,0xe1}, {0xb6,0xe7}, {0xb6,0xdb}, {0xa2,0x5f}, {0xb6,0xd9}, - {0xdc,0xd4}, {0x9d,0xe9}, {0x8f,0x52}, {0xb6,0xe2}, {0x9d,0xf5}, {0x9d,0xf0}, {0xdc,0xdd}, {0x99,0xe7}, {0xb9,0xcd}, {0xb9,0xc8}, - {0xe1,0x55}, {0xe1,0x51}, {0x8b,0xbd}, {0xe1,0x4b}, {0xb9,0xc2}, {0xb9,0xbe}, {0xe1,0x54}, {0xb9,0xbf}, {0xe1,0x4e}, {0xe1,0x50}, - {0xe1,0x53}, {0x9d,0xef}, {0xb9,0xc4}, {0xb9,0xcb}, {0xb9,0xc5}, {0xe1,0x49}, {0xb9,0xc6}, {0xb9,0xc7}, {0xe1,0x4c}, {0xb9,0xcc}, - {0x9f,0xb7}, {0xe1,0x4a}, {0xe1,0x4f}, {0xb9,0xc3}, {0xe1,0x48}, {0xb9,0xc9}, {0xb9,0xc1}, {0xb9,0xc0}, {0xe1,0x4d}, {0xe1,0x52}, - {0x9d,0xd0}, {0xb9,0xca}, {0x9f,0xeb}, {0x8d,0xa9}, {0x9d,0xcf}, {0x98,0xe1}, {0x9d,0xe5}, {0xe1,0x47}, {0xbc,0x4d}, {0xe5,0x47}, - {0xe5,0x44}, {0x9d,0xc8}, {0xbc,0x47}, {0xbc,0x53}, {0xbc,0x54}, {0xbc,0x4a}, {0xe5,0x42}, {0xbc,0x4c}, {0xe4,0xf9}, {0xbc,0x52}, - {0xfb,0x4f}, {0xe5,0x46}, {0xbc,0x49}, {0xe5,0x48}, {0xbc,0x48}, {0xe5,0x43}, {0xe5,0x45}, {0xbc,0x4b}, {0xe5,0x41}, {0xe4,0xfa}, - {0xe4,0xf7}, {0x9d,0xeb}, {0xd8,0x6b}, {0xe4,0xfd}, {0xe4,0xf6}, {0xe4,0xfc}, {0xe4,0xfb}, {0xe4,0xf8}, {0xfb,0x54}, {0xbc,0x4f}, - {0xfb,0x55}, {0x9a,0xa2}, {0x8a,0xd6}, {0xbc,0x4e}, {0x9a,0x5f}, {0xbc,0x50}, {0xe4,0xfe}, {0xbe,0xb2}, {0xe5,0x40}, {0x9e,0xf5}, - {0xe9,0x45}, {0xe8,0xfd}, {0x8f,0xb7}, {0xbe,0xbe}, {0xe9,0x42}, {0xbe,0xb6}, {0xbe,0xba}, {0xe9,0x41}, {0xbe,0xb9}, {0xbe,0xb5}, - {0xbe,0xb8}, {0xbe,0xb3}, {0xbe,0xbd}, {0xe9,0x43}, {0xe8,0xfe}, {0xbe,0xbc}, {0xe8,0xfc}, {0xbe,0xbb}, {0xe9,0x44}, {0xe9,0x40}, - {0xbc,0x51}, {0xbe,0xbf}, {0xe9,0x46}, {0xbe,0xb7}, {0xbe,0xb4}, {0x9a,0xd2}, {0x9e,0x6a}, {0x9e,0xe8}, {0xec,0xc6}, {0xec,0xc8}, - {0xc0,0x7b}, {0xec,0xc9}, {0xec,0xc7}, {0xec,0xc5}, {0xec,0xc4}, {0xc0,0x7d}, {0xec,0xc3}, {0xc0,0x7e}, {0x8b,0xbf}, {0x91,0xc2}, - {0x9d,0x62}, {0xec,0xc1}, {0xec,0xc2}, {0xc0,0x7a}, {0xc0,0xa1}, {0xc0,0x7c}, {0x92,0x60}, {0xec,0xc0}, {0xc2,0x50}, {0xef,0xbc}, - {0xef,0xba}, {0xef,0xbf}, {0xef,0xbd}, {0xef,0xbb}, {0xef,0xbe}, {0x92,0x5e}, {0x91,0xc1}, {0x8a,0xc5}, {0x97,0xa3}, {0xc3,0x60}, - {0xf1,0xf2}, {0xf1,0xf3}, {0xc4,0x56}, {0xf1,0xf4}, {0xf1,0xf0}, {0xf1,0xf5}, {0xf1,0xf1}, {0xc2,0x51}, {0x8b,0x6c}, {0x8d,0x7e}, - {0xf3,0xfe}, {0xf4,0x41}, {0xc4,0x59}, {0xf4,0x40}, {0xc4,0x58}, {0xc4,0x57}, {0x9c,0x54}, {0xc4,0x5a}, {0xf5,0xc5}, {0xf5,0xc6}, - {0x9d,0xbd}, {0xc4,0xda}, {0xc4,0xd9}, {0xc4,0xdb}, {0xf5,0xc4}, {0xf6,0xd8}, {0xf6,0xd7}, {0xc5,0x6d}, {0xc5,0x6f}, {0xc5,0x6e}, - {0xf6,0xd9}, {0xc5,0xc8}, {0xf8,0xa6}, {0xc5,0xf1}, {0xf8,0xa5}, {0xf8,0xee}, {0x9c,0xc5}, {0xc9,0x49}, {0xa5,0x7d}, {0xa5,0x7c}, - {0xa6,0x5f}, {0xa6,0x5e}, {0xc9,0xc7}, {0xa6,0x5d}, {0xc9,0xc6}, {0x89,0x5b}, {0xa7,0x79}, {0xca,0xa9}, {0xca,0xa8}, {0xa7,0x77}, - {0xa7,0x7a}, {0xfb,0x5c}, {0xca,0xa7}, {0xfb,0x5b}, {0xa7,0x78}, {0xfb,0x57}, {0xcb,0xf0}, {0xcb,0xf1}, {0xa9,0x54}, {0x98,0xc7}, - {0xab,0xaa}, {0xfb,0x5a}, {0xd1,0x48}, {0xd1,0x49}, {0xae,0x45}, {0xae,0x46}, {0xd4,0xac}, {0xb0,0xe9}, {0xb0,0xeb}, {0xd4,0xab}, - {0xb0,0xea}, {0xd8,0x7c}, {0xb3,0xf2}, {0xb6,0xe9}, {0xb6,0xea}, {0xdc,0xe1}, {0x9c,0xee}, {0xb9,0xcf}, {0xb9,0xce}, {0xe5,0x49}, - {0xe9,0x48}, {0xe9,0x47}, {0x92,0xe2}, {0xf9,0x6b}, {0xa4,0x67}, {0xc9,0x59}, {0xc9,0x6e}, {0xc9,0x6f}, {0xa6,0x62}, {0xa6,0x66}, - {0xc9,0xc9}, {0xa6,0x64}, {0xa6,0x63}, {0xc9,0xc8}, {0xa6,0x65}, {0xa6,0x61}, {0x94,0xa7}, {0xa6,0x60}, {0xc9,0xca}, {0xa7,0xa6}, - {0x8c,0xcc}, {0xa7,0xa3}, {0x9b,0xd4}, {0xa7,0x7d}, {0xca,0xaa}, {0xfb,0x64}, {0xfb,0x76}, {0xca,0xab}, {0xfb,0x60}, {0xa7,0xa1}, - {0xca,0xad}, {0xa7,0x7b}, {0xca,0xae}, {0xca,0xac}, {0xa7,0x7e}, {0xa7,0xa2}, {0xa7,0xa5}, {0xa7,0xa4}, {0xa7,0x7c}, {0xca,0xaf}, - {0x99,0xe5}, {0x9a,0xc2}, {0x91,0xfb}, {0xa0,0x73}, {0xa9,0x59}, {0xcb,0xfe}, {0xa9,0x5b}, {0xa9,0x5a}, {0x9f,0x72}, {0xcc,0x40}, - {0xa9,0x58}, {0xa9,0x57}, {0xcb,0xf5}, {0xcb,0xf4}, {0xcb,0xf2}, {0xcb,0xf7}, {0xcb,0xf6}, {0xcb,0xf3}, {0xcb,0xfc}, {0xcb,0xfd}, - {0xcb,0xfa}, {0xcb,0xf8}, {0xa9,0x56}, {0x9f,0xcc}, {0xcb,0xfb}, {0xa9,0x5c}, {0xcc,0x41}, {0x98,0xa5}, {0x92,0xe8}, {0xcb,0xf9}, - {0xab,0xab}, {0xa9,0x55}, {0x9b,0xbc}, {0x96,0xf3}, {0xab,0xac}, {0xce,0x54}, {0x92,0xe7}, {0xce,0x5a}, {0xfc,0x67}, {0xab,0xb2}, - {0xce,0x58}, {0xce,0x5e}, {0xce,0x55}, {0xce,0x59}, {0xce,0x5b}, {0xce,0x5d}, {0xce,0x57}, {0x8b,0x7d}, {0xce,0x56}, {0xce,0x51}, - {0xce,0x52}, {0xab,0xad}, {0x9b,0xf4}, {0xab,0xaf}, {0xab,0xae}, {0xce,0x53}, {0xce,0x5c}, {0x9e,0xf7}, {0x9e,0xc1}, {0xab,0xb1}, - {0x99,0x6f}, {0xce,0x50}, {0xd1,0x53}, {0xd1,0x52}, {0xd1,0x57}, {0xd1,0x4e}, {0x96,0xf1}, {0xd1,0x51}, {0xd1,0x50}, {0x8e,0x41}, - {0xd1,0x54}, {0xd1,0x58}, {0xae,0x47}, {0xae,0x4a}, {0x95,0x4a}, {0xd1,0x4f}, {0xd1,0x55}, {0x97,0xe6}, {0xae,0x49}, {0xd1,0x4a}, - {0xab,0xb0}, {0xd4,0xba}, {0xd1,0x56}, {0xd1,0x4d}, {0xae,0x48}, {0xd1,0x4c}, {0x96,0xf5}, {0xd4,0xb1}, {0x92,0xe6}, {0x9f,0x42}, - {0xb0,0xec}, {0xb0,0xf0}, {0xd4,0xc1}, {0xd4,0xaf}, {0xd4,0xbd}, {0xb0,0xf1}, {0xd4,0xbf}, {0xfb,0x67}, {0xd4,0xc5}, {0xd4,0xc9}, - {0xd4,0xc0}, {0xd4,0xb4}, {0xd4,0xbc}, {0x99,0xa9}, {0xd4,0xca}, {0xd4,0xc8}, {0xd4,0xbe}, {0xd4,0xb9}, {0xd4,0xb2}, {0xd8,0xa6}, - {0xd4,0xb0}, {0xb0,0xf5}, {0xd4,0xb7}, {0xb0,0xf6}, {0xb0,0xf2}, {0xd4,0xad}, {0xd4,0xc3}, {0xd4,0xb5}, {0xfa,0xe6}, {0xd4,0xb3}, - {0xd4,0xc6}, {0xb0,0xf3}, {0xfb,0x69}, {0xd4,0xcc}, {0xb0,0xed}, {0xb0,0xef}, {0xd4,0xbb}, {0xd4,0xb6}, {0xae,0x4b}, {0xb0,0xee}, - {0xd4,0xb8}, {0xd4,0xc7}, {0xd4,0xcb}, {0xd4,0xc2}, {0xd4,0xc4}, {0x97,0xe5}, {0xd4,0xae}, {0xd8,0xa1}, {0xd8,0xaa}, {0xd8,0xa9}, - {0xb3,0xfa}, {0xd8,0xa2}, {0xb3,0xfb}, {0xb3,0xf9}, {0x96,0x7d}, {0xd8,0xa4}, {0xb3,0xf6}, {0xd8,0xa8}, {0xfb,0x6c}, {0xd8,0xa3}, - {0xd8,0xa5}, {0xd8,0x7d}, {0xb3,0xf4}, {0xd8,0xb2}, {0xd8,0xb1}, {0xd8,0xae}, {0xb3,0xf3}, {0xb3,0xf7}, {0xb3,0xf8}, {0xd1,0x4b}, - {0xd8,0xab}, {0xb3,0xf5}, {0xb0,0xf4}, {0xd8,0xad}, {0xd8,0x7e}, {0xd8,0xb0}, {0xd8,0xaf}, {0x99,0xa2}, {0xd8,0xb3}, {0xdc,0xef}, - {0xd8,0xac}, {0x9a,0xbb}, {0x9a,0x65}, {0x94,0x4e}, {0xd8,0xa7}, {0xdc,0xe7}, {0xb6,0xf4}, {0xb6,0xf7}, {0xb6,0xf2}, {0xdc,0xe6}, - {0xdc,0xea}, {0xdc,0xe5}, {0xb6,0xec}, {0xb6,0xf6}, {0xdc,0xe2}, {0xb6,0xf0}, {0xdc,0xe9}, {0xb6,0xee}, {0xb6,0xed}, {0xdc,0xec}, - {0xb6,0xef}, {0xdc,0xee}, {0xfb,0x6e}, {0xdc,0xeb}, {0xb6,0xeb}, {0x99,0xdf}, {0xb6,0xf5}, {0xdc,0xf0}, {0xdc,0xe4}, {0xdc,0xed}, - {0xdc,0xe3}, {0x98,0xe3}, {0xb6,0xf1}, {0x92,0x54}, {0xb6,0xf3}, {0xdc,0xe8}, {0xdc,0xf1}, {0x96,0x7b}, {0x8a,0xaf}, {0xe1,0x5d}, - {0xb9,0xd0}, {0xe1,0x63}, {0xb9,0xd5}, {0xe1,0x5f}, {0xe1,0x66}, {0xe1,0x57}, {0xb9,0xd7}, {0xb9,0xd1}, {0xe1,0x5c}, {0xbc,0x55}, - {0xe1,0x5b}, {0xe1,0x64}, {0xb9,0xd2}, {0xb9,0xd6}, {0xe1,0x5a}, {0xe1,0x60}, {0xe1,0x65}, {0xe1,0x56}, {0xb9,0xd4}, {0xe1,0x5e}, - {0xe1,0x62}, {0xe1,0x68}, {0xe1,0x58}, {0xe1,0x61}, {0x8c,0x77}, {0xb9,0xd3}, {0xe1,0x67}, {0xe1,0x59}, {0x8b,0xaf}, {0x9e,0xbd}, - {0xbc,0x59}, {0xe5,0x4b}, {0xbc,0x57}, {0xbc,0x56}, {0xe5,0x4d}, {0xe5,0x52}, {0xe5,0x4e}, {0xe5,0x51}, {0xbc,0x5c}, {0x9e,0xe6}, - {0xbe,0xa5}, {0xbc,0x5b}, {0xfb,0x6f}, {0xe5,0x4a}, {0xe5,0x50}, {0xbc,0x5a}, {0xe5,0x4f}, {0x8e,0xe1}, {0xe5,0x4c}, {0xbc,0x58}, - {0x9b,0x7d}, {0x9c,0x7e}, {0xe9,0x4d}, {0xf9,0xd9}, {0xe9,0x4f}, {0xe9,0x4a}, {0xbe,0xc1}, {0xe9,0x4c}, {0xbe,0xc0}, {0xe9,0x4e}, - {0xbe,0xc3}, {0xe9,0x50}, {0xbe,0xc2}, {0xe9,0x49}, {0xe9,0x4b}, {0x92,0xea}, {0xc0,0xa5}, {0xec,0xcc}, {0x8c,0x78}, {0xc0,0xa4}, - {0xec,0xcd}, {0xc0,0xa3}, {0xec,0xcb}, {0xc0,0xa2}, {0xec,0xca}, {0xc2,0x53}, {0xc2,0x52}, {0xf1,0xf6}, {0xf1,0xf8}, {0xfb,0x72}, - {0xf1,0xf7}, {0xc3,0x61}, {0xc3,0x62}, {0xfb,0x71}, {0xc3,0x63}, {0xf4,0x42}, {0xc4,0x5b}, {0xf7,0xd3}, {0xf7,0xd2}, {0xc5,0xf2}, - {0xa4,0x68}, {0xa4,0xd0}, {0xa7,0xa7}, {0x89,0x5c}, {0x98,0xf0}, {0x96,0xf2}, {0xce,0x5f}, {0xb3,0xfc}, {0xb3,0xfd}, {0xfb,0x74}, - {0xdc,0xf2}, {0xb9,0xd8}, {0xe1,0x69}, {0xe5,0x53}, {0x8b,0xc1}, {0xc9,0x5a}, {0x89,0x5d}, {0x89,0xde}, {0xca,0xb0}, {0x89,0x5e}, - {0xc6,0xca}, {0xcc,0x42}, {0xce,0x60}, {0xd1,0x59}, {0xae,0x4c}, {0xfe,0x42}, {0xf1,0xf9}, {0xc4,0xdc}, {0xa4,0x69}, {0xa5,0x7e}, - {0xc9,0x70}, {0xa6,0x67}, {0xa6,0x68}, {0xa9,0x5d}, {0xfb,0x7b}, {0xb0,0xf7}, {0xb9,0xda}, {0xb9,0xdb}, {0xb9,0xd9}, {0xa4,0x6a}, - {0xa4,0xd1}, {0xa4,0xd3}, {0xa4,0xd2}, {0xc9,0x5b}, {0xa4,0xd4}, {0xa5,0xa1}, {0xc9,0x71}, {0xa5,0xa2}, {0x89,0x5f}, {0x89,0x60}, - {0xa6,0x69}, {0xa6,0x6a}, {0xc9,0xcb}, {0xa7,0xa8}, {0xca,0xb1}, {0xa9,0x61}, {0xcc,0x43}, {0xa9,0x5f}, {0xa9,0x60}, {0xa9,0x5e}, - {0xd1,0x5a}, {0xab,0xb6}, {0xab,0xb5}, {0xab,0xb7}, {0xab,0xb4}, {0xce,0x61}, {0xa9,0x62}, {0xab,0xb3}, {0xae,0x4d}, {0xae,0x4e}, - {0xae,0x4f}, {0xd4,0xcd}, {0xb3,0xfe}, {0xd8,0xb4}, {0xb0,0xf8}, {0x9b,0xcd}, {0xb6,0xf8}, {0xb9,0xdd}, {0xb9,0xdc}, {0xe1,0x6a}, - {0xbc,0x5d}, {0xbe,0xc4}, {0xef,0xc0}, {0xf6,0xda}, {0xf7,0xd4}, {0xa4,0x6b}, {0xa5,0xa3}, {0x9d,0xd3}, {0xa5,0xa4}, {0xc9,0xd1}, - {0xa6,0x6c}, {0xa6,0x6f}, {0xc9,0xcf}, {0xc9,0xcd}, {0xa6,0x6e}, {0xc9,0xd0}, {0xc9,0xd2}, {0xc9,0xcc}, {0xa6,0x71}, {0xa6,0x70}, - {0xa6,0x6d}, {0xa6,0x6b}, {0xc9,0xce}, {0x98,0x4c}, {0xa7,0xb3}, {0xa7,0xb0}, {0xca,0xb6}, {0xca,0xb9}, {0xca,0xb8}, {0xa7,0xaa}, - {0xa7,0xb2}, {0x97,0x52}, {0xa7,0xaf}, {0xca,0xb5}, {0xca,0xb3}, {0xa7,0xae}, {0x95,0xc3}, {0xa7,0xa9}, {0xa7,0xac}, {0x9b,0xb6}, - {0xca,0xb4}, {0xca,0xbb}, {0xca,0xb7}, {0xa7,0xad}, {0xa7,0xb1}, {0xa7,0xb4}, {0xca,0xb2}, {0xca,0xba}, {0xa7,0xab}, {0x9a,0xb9}, - {0xa9,0x67}, {0xa9,0x6f}, {0x97,0xb3}, {0xcc,0x4f}, {0xcc,0x48}, {0xa9,0x70}, {0xcc,0x53}, {0xcc,0x44}, {0xcc,0x4b}, {0x9f,0x74}, - {0x92,0xf1}, {0xa9,0x66}, {0xcc,0x45}, {0xa9,0x64}, {0xcc,0x4c}, {0xcc,0x50}, {0xa9,0x63}, {0xcc,0x51}, {0xcc,0x4a}, {0xcc,0x4d}, - {0x97,0xdf}, {0xa9,0x72}, {0xa9,0x69}, {0xcc,0x54}, {0xcc,0x52}, {0xfb,0xa6}, {0xa9,0x6e}, {0xa9,0x6c}, {0xcc,0x49}, {0xa9,0x6b}, - {0xcc,0x47}, {0xcc,0x46}, {0xa9,0x6a}, {0xa9,0x68}, {0xa9,0x71}, {0xa9,0x6d}, {0xa9,0x65}, {0xcc,0x4e}, {0xab,0xb9}, {0xfb,0xab}, - {0xab,0xc0}, {0xce,0x6f}, {0xab,0xb8}, {0xce,0x67}, {0xce,0x63}, {0xce,0x73}, {0xce,0x62}, {0xab,0xbb}, {0xce,0x6c}, {0xab,0xbe}, - {0xab,0xc1}, {0xab,0xbc}, {0xce,0x70}, {0xab,0xbf}, {0x98,0x77}, {0xae,0x56}, {0xce,0x76}, {0xce,0x64}, {0x98,0x54}, {0x95,0xc5}, - {0xce,0x66}, {0xce,0x6d}, {0xce,0x71}, {0xce,0x75}, {0xce,0x72}, {0xce,0x6b}, {0xce,0x6e}, {0x9d,0x55}, {0xfb,0xb2}, {0xce,0x68}, - {0xab,0xc3}, {0xce,0x6a}, {0xce,0x69}, {0xce,0x74}, {0xab,0xba}, {0xce,0x65}, {0xab,0xc2}, {0x95,0x7e}, {0xab,0xbd}, {0xae,0x5c}, - {0xd1,0x62}, {0x97,0x42}, {0xae,0x5b}, {0x94,0xe6}, {0xd1,0x60}, {0xae,0x50}, {0x92,0xf5}, {0xae,0x55}, {0xd1,0x5f}, {0xd1,0x5c}, - {0xd1,0x61}, {0xae,0x51}, {0xd1,0x5b}, {0x8c,0xc5}, {0xae,0x54}, {0xae,0x52}, {0xd1,0x63}, {0xae,0x53}, {0xae,0x57}, {0x92,0xfd}, - {0xae,0x58}, {0xfb,0xa2}, {0xae,0x5a}, {0x9c,0x51}, {0xae,0x59}, {0x94,0xe9}, {0x98,0x5c}, {0x92,0xf0}, {0xd1,0x5d}, {0xd1,0x5e}, - {0xd1,0x64}, {0xd4,0xd4}, {0xb0,0xf9}, {0xd8,0xc2}, {0xd4,0xd3}, {0xd4,0xe6}, {0xb1,0x40}, {0x94,0x4c}, {0xd4,0xe4}, {0xb0,0xfe}, - {0xb0,0xfa}, {0xd4,0xed}, {0xd4,0xdd}, {0xd4,0xe0}, {0x91,0x6b}, {0xb1,0x43}, {0xd4,0xea}, {0xd4,0xe2}, {0xb0,0xfb}, {0xb1,0x44}, - {0xd4,0xe7}, {0xd4,0xe5}, {0xd4,0xd6}, {0xd4,0xeb}, {0xd4,0xdf}, {0xd4,0xda}, {0x8b,0x78}, {0xd4,0xd0}, {0xd4,0xec}, {0xd4,0xdc}, - {0xd4,0xcf}, {0x94,0xe2}, {0xb1,0x42}, {0xd4,0xe1}, {0xd4,0xee}, {0xd4,0xde}, {0xd4,0xd2}, {0xd4,0xd7}, {0xd4,0xce}, {0x98,0x4f}, - {0xb1,0x41}, {0xfb,0xb5}, {0xd4,0xdb}, {0xd4,0xd8}, {0xb0,0xfc}, {0xd4,0xd1}, {0x92,0x71}, {0xd4,0xe9}, {0xb0,0xfd}, {0x93,0x65}, - {0xd4,0xd9}, {0xd4,0xd5}, {0x98,0x5b}, {0xd4,0xe8}, {0x98,0x50}, {0xb4,0x40}, {0xd8,0xbb}, {0x97,0xbc}, {0xd8,0xb8}, {0xd8,0xc9}, - {0xd8,0xbd}, {0xd8,0xca}, {0x92,0xf3}, {0xb4,0x42}, {0x93,0x40}, {0x98,0x4d}, {0xd8,0xc6}, {0xd8,0xc3}, {0x95,0x72}, {0xfd,0xef}, - {0xd8,0xc4}, {0xd8,0xc7}, {0xd8,0xcb}, {0xd4,0xe3}, {0xd8,0xcd}, {0xdd,0x47}, {0xfd,0xc1}, {0xb4,0x43}, {0xd8,0xce}, {0xd8,0xb6}, - {0xd8,0xc0}, {0xfb,0xba}, {0xd8,0xc5}, {0x92,0xeb}, {0xb4,0x41}, {0xb4,0x44}, {0xd8,0xcc}, {0xd8,0xcf}, {0xd8,0xba}, {0xd8,0xb7}, - {0xfc,0x73}, {0x97,0xb7}, {0xd8,0xb9}, {0xd8,0xbe}, {0xd8,0xbc}, {0xb4,0x45}, {0xd8,0xc8}, {0xfb,0xb4}, {0xd8,0xbf}, {0xd8,0xc1}, - {0xd8,0xb5}, {0xdc,0xfa}, {0xdc,0xf8}, {0xb7,0x42}, {0xb7,0x40}, {0xdd,0x43}, {0xdc,0xf9}, {0xdd,0x44}, {0xdd,0x40}, {0xdc,0xf7}, - {0xdd,0x46}, {0xdc,0xf6}, {0xdc,0xfd}, {0xb6,0xfe}, {0xb6,0xfd}, {0xb6,0xfc}, {0xdc,0xfb}, {0xdd,0x41}, {0xb6,0xf9}, {0xb7,0x41}, - {0x90,0xa7}, {0xdc,0xf4}, {0xdc,0xfe}, {0xdc,0xf3}, {0xdc,0xfc}, {0xb6,0xfa}, {0xdd,0x42}, {0xdc,0xf5}, {0xb6,0xfb}, {0xdd,0x45}, - {0x97,0x41}, {0x92,0xf4}, {0xfb,0xbc}, {0xe1,0x6e}, {0xb9,0xe2}, {0xb9,0xe1}, {0xb9,0xe3}, {0xe1,0x7a}, {0xe1,0x70}, {0xe1,0x76}, - {0xe1,0x6b}, {0xe1,0x79}, {0xe1,0x78}, {0xe1,0x7c}, {0xe1,0x75}, {0xb9,0xde}, {0xe1,0x74}, {0xb9,0xe4}, {0x95,0x77}, {0xe1,0x6d}, - {0xb9,0xdf}, {0xe1,0x7b}, {0xb9,0xe0}, {0xe1,0x6f}, {0xe1,0x72}, {0xe1,0x77}, {0xe1,0x71}, {0xe1,0x6c}, {0x9e,0xe2}, {0x8f,0x78}, - {0xe1,0x73}, {0xe5,0x55}, {0xbc,0x61}, {0xe5,0x58}, {0xe5,0x57}, {0xe5,0x5a}, {0xe5,0x5c}, {0xf9,0xdc}, {0xbc,0x5f}, {0xe5,0x56}, - {0x96,0x72}, {0xe5,0x54}, {0xe5,0x5d}, {0xe5,0x5b}, {0xe5,0x59}, {0xe5,0x5f}, {0xe5,0x5e}, {0xbc,0x63}, {0xbc,0x5e}, {0xbc,0x60}, - {0xbc,0x62}, {0x9e,0xb5}, {0xe5,0x60}, {0xe9,0x57}, {0x96,0x4b}, {0xe9,0x56}, {0xe9,0x55}, {0x8c,0xac}, {0xe9,0x58}, {0xe9,0x51}, - {0xe9,0x52}, {0xe9,0x5a}, {0xe9,0x53}, {0xbe,0xc5}, {0xe9,0x5c}, {0xa0,0xfa}, {0xe9,0x5b}, {0xe9,0x54}, {0xec,0xd1}, {0xc0,0xa8}, - {0xec,0xcf}, {0xec,0xd4}, {0xec,0xd3}, {0xe9,0x59}, {0xc0,0xa7}, {0x95,0x75}, {0xec,0xd2}, {0xec,0xce}, {0xec,0xd6}, {0xec,0xd5}, - {0xc0,0xa6}, {0xec,0xd0}, {0xbe,0xc6}, {0xc2,0x54}, {0xef,0xc1}, {0xf1,0xfa}, {0xf1,0xfb}, {0xf1,0xfc}, {0xc4,0x5c}, {0x90,0xda}, - {0xc4,0x5d}, {0x93,0x67}, {0xf4,0x43}, {0xfe,0xa4}, {0xf5,0xc8}, {0xf5,0xc7}, {0x90,0xdf}, {0xf6,0xdb}, {0xf6,0xdc}, {0xf7,0xd5}, - {0xf8,0xa7}, {0x93,0x54}, {0xa4,0x6c}, {0xa4,0x6d}, {0xa4,0x6e}, {0xa4,0xd5}, {0xa5,0xa5}, {0xc9,0xd3}, {0xa6,0x72}, {0xa6,0x73}, - {0xa7,0xb7}, {0xa7,0xb8}, {0xa7,0xb6}, {0xa7,0xb5}, {0xa9,0x73}, {0xcc,0x55}, {0xa9,0x75}, {0xa9,0x74}, {0xcc,0x56}, {0x89,0x61}, - {0x8b,0xb4}, {0xab,0xc4}, {0xae,0x5d}, {0xd1,0x65}, {0x9d,0xc0}, {0xd4,0xf0}, {0xb1,0x45}, {0xb4,0x47}, {0xd4,0xef}, {0xb4,0x46}, - {0x8e,0x48}, {0xb9,0xe5}, {0xfb,0xc5}, {0xe1,0x7d}, {0xbe,0xc7}, {0xc0,0xa9}, {0xec,0xd7}, {0xfb,0xc7}, {0xc4,0x5e}, {0xc5,0x70}, - {0xc6,0xcb}, {0xc9,0x72}, {0xfa,0x79}, {0xa5,0xa6}, {0xc9,0x73}, {0xa6,0x76}, {0xa6,0x74}, {0xa6,0x75}, {0xa6,0x77}, {0xa7,0xba}, - {0xa7,0xb9}, {0xca,0xbc}, {0xa7,0xbb}, {0x9e,0x67}, {0xca,0xbd}, {0xcc,0x57}, {0xcc,0x58}, {0x8c,0xd9}, {0xa9,0x76}, {0xa9,0x78}, - {0xa9,0x7a}, {0xa9,0x77}, {0xa9,0x7b}, {0xa9,0x79}, {0xfb,0xd2}, {0x89,0x62}, {0x89,0x63}, {0xab,0xc8}, {0xab,0xc5}, {0xab,0xc7}, - {0xab,0xc9}, {0xab,0xc6}, {0xd1,0x66}, {0xce,0x77}, {0xfc,0x7d}, {0xd1,0x68}, {0xd1,0x67}, {0xae,0x63}, {0xae,0x5f}, {0xae,0x60}, - {0xae,0x62}, {0xae,0x64}, {0xae,0x61}, {0xae,0x66}, {0xae,0x65}, {0xb1,0x4a}, {0xd4,0xf2}, {0xd4,0xf1}, {0xb1,0x49}, {0x9f,0x6b}, - {0xb1,0x48}, {0xb1,0x47}, {0xb1,0x4b}, {0xb1,0x46}, {0xd8,0xd5}, {0xd8,0xd2}, {0xb4,0x49}, {0xd8,0xd1}, {0xd8,0xd6}, {0xb4,0x4b}, - {0xd8,0xd4}, {0xb4,0x48}, {0xb4,0x4a}, {0xd8,0xd3}, {0xfb,0xcc}, {0xdd,0x48}, {0xfe,0xae}, {0xdd,0x49}, {0xdd,0x4a}, {0xb9,0xe6}, - {0xb9,0xee}, {0xe1,0x7e}, {0xb9,0xe8}, {0xb9,0xec}, {0xe1,0xa1}, {0xb9,0xed}, {0xb9,0xe9}, {0xb9,0xea}, {0xb9,0xe7}, {0xb9,0xeb}, - {0xbc,0x66}, {0xd8,0xd0}, {0xbc,0x67}, {0xbc,0x65}, {0xbc,0x64}, {0xe9,0x5d}, {0xbe,0xc8}, {0xec,0xd8}, {0xec,0xd9}, {0xfb,0xd1}, - {0xc3,0x64}, {0xc4,0x5f}, {0xa4,0x6f}, {0xa6,0x78}, {0xfb,0x75}, {0xab,0xca}, {0xd1,0x69}, {0xae,0x67}, {0xfb,0xd4}, {0xb1,0x4e}, - {0xb1,0x4d}, {0xb1,0x4c}, {0xb4,0x4c}, {0xb4,0x4d}, {0xd8,0xd7}, {0xb9,0xef}, {0xbe,0xc9}, {0xa4,0x70}, {0xc9,0x5c}, {0xa4,0xd6}, - {0xc9,0x74}, {0xfb,0xd6}, {0xfb,0xd8}, {0xc9,0xd4}, {0xa6,0x79}, {0xa9,0x7c}, {0x8b,0x5d}, {0x93,0x4c}, {0xdd,0x4b}, {0x9a,0xe2}, - {0xa4,0x71}, {0x8b,0xc9}, {0xa4,0xd7}, {0xc9,0xd5}, {0xca,0xbe}, {0xca,0xbf}, {0xa7,0xbc}, {0xd8,0xd8}, {0xb4,0x4e}, {0xdd,0x4c}, - {0xc0,0xaa}, {0xa4,0x72}, {0xa4,0xa8}, {0xa4,0xd8}, {0xc9,0x75}, {0xa5,0xa7}, {0xa7,0xc0}, {0xa7,0xbf}, {0xa7,0xbd}, {0xa7,0xbe}, - {0xcc,0x59}, {0xa9,0x7e}, {0xa9,0xa1}, {0xcc,0x5a}, {0xa9,0x7d}, {0xfb,0xdb}, {0x9f,0xc9}, {0xab,0xce}, {0xce,0x78}, {0xab,0xcd}, - {0xab,0xcb}, {0xab,0xcc}, {0xae,0x6a}, {0xae,0x68}, {0x9f,0x44}, {0xd1,0x6b}, {0xae,0x69}, {0xd1,0x6a}, {0xae,0x5e}, {0xd4,0xf3}, - {0xb1,0x50}, {0xb1,0x51}, {0x98,0xed}, {0xb1,0x4f}, {0xb9,0xf0}, {0xe1,0xa2}, {0xbc,0x68}, {0xbc,0x69}, {0xe5,0x61}, {0xc0,0xab}, - {0xef,0xc2}, {0xef,0xc3}, {0xc4,0xdd}, {0xf8,0xa8}, {0xc9,0x4b}, {0xa4,0xd9}, {0xa4,0x73}, {0xc9,0x77}, {0xc9,0x76}, {0xa6,0x7a}, - {0xc9,0xd7}, {0xc9,0xd8}, {0xc9,0xd6}, {0xc9,0xd9}, {0xfb,0xdd}, {0xca,0xc7}, {0xca,0xc2}, {0xca,0xc4}, {0xca,0xc6}, {0xca,0xc3}, - {0xa7,0xc4}, {0xca,0xc0}, {0xca,0xc1}, {0xa7,0xc1}, {0xa7,0xc2}, {0xca,0xc5}, {0xca,0xc8}, {0xa7,0xc3}, {0xca,0xc9}, {0x8d,0xf2}, - {0x89,0x64}, {0xfd,0xf2}, {0xcc,0x68}, {0x93,0x4d}, {0xcc,0x62}, {0xcc,0x5d}, {0xa9,0xa3}, {0xcc,0x65}, {0xcc,0x63}, {0xcc,0x5c}, - {0xcc,0x69}, {0xcc,0x6c}, {0xcc,0x67}, {0xcc,0x60}, {0xa9,0xa5}, {0xcc,0x66}, {0xa9,0xa6}, {0xcc,0x61}, {0xcc,0x64}, {0xcc,0x5b}, - {0xcc,0x5f}, {0xcc,0x6b}, {0xa9,0xa7}, {0xa9,0xa8}, {0xcc,0x5e}, {0xcc,0x6a}, {0xa9,0xa2}, {0xa9,0xa4}, {0xfb,0xe7}, {0xa0,0xf2}, - {0x98,0x68}, {0xce,0xab}, {0xce,0xa4}, {0xce,0xaa}, {0xce,0xa3}, {0xce,0xa5}, {0xce,0x7d}, {0xce,0x7b}, {0xce,0xac}, {0xce,0xa9}, - {0xce,0x79}, {0x9f,0x58}, {0xab,0xd0}, {0xce,0xa7}, {0xce,0xa8}, {0xce,0xa6}, {0xce,0x7c}, {0xce,0x7a}, {0xab,0xcf}, {0xce,0xa2}, - {0xce,0x7e}, {0xce,0xa1}, {0xce,0xad}, {0x8d,0x73}, {0xae,0x6f}, {0xfb,0xde}, {0xae,0x6e}, {0xd1,0x6c}, {0xae,0x6b}, {0xd1,0x6e}, - {0xfb,0xdf}, {0xae,0x70}, {0xd1,0x6f}, {0xae,0x73}, {0x8c,0x48}, {0xae,0x71}, {0xd1,0x70}, {0xce,0xae}, {0xd1,0x72}, {0xae,0x6d}, - {0xae,0x6c}, {0xd1,0x6d}, {0xd1,0x71}, {0xae,0x72}, {0xb1,0x53}, {0xb1,0x52}, {0xd4,0xf5}, {0xd4,0xf9}, {0xd4,0xfb}, {0xb1,0x54}, - {0xd4,0xfe}, {0xfb,0xe3}, {0xb1,0x58}, {0xd5,0x41}, {0xb1,0x5a}, {0x8d,0xa8}, {0xb1,0x56}, {0xb1,0x5e}, {0xfb,0xe4}, {0xb1,0x5b}, - {0xd4,0xf7}, {0xb1,0x55}, {0xd4,0xf6}, {0xd4,0xf4}, {0xd5,0x43}, {0xd4,0xf8}, {0xb1,0x57}, {0xd5,0x42}, {0xb1,0x5c}, {0xd4,0xfd}, - {0xd4,0xfc}, {0xb1,0x5d}, {0xd4,0xfa}, {0xb1,0x59}, {0x9c,0x75}, {0xd5,0x44}, {0x98,0x78}, {0xd5,0x40}, {0xd8,0xe7}, {0xd8,0xee}, - {0xd8,0xe3}, {0xb4,0x51}, {0xd8,0xdf}, {0xd8,0xef}, {0xd8,0xd9}, {0xd8,0xec}, {0xd8,0xea}, {0xd8,0xe4}, {0xd8,0xed}, {0xd8,0xe6}, - {0x8d,0x60}, {0xd8,0xde}, {0xd8,0xf0}, {0xd8,0xdc}, {0xd8,0xe9}, {0xd8,0xda}, {0xd8,0xf1}, {0xfb,0xe5}, {0xb4,0x52}, {0x8d,0x61}, - {0xd8,0xeb}, {0xdd,0x4f}, {0xd8,0xdd}, {0xb4,0x4f}, {0xd8,0xe1}, {0xb4,0x50}, {0xd8,0xe0}, {0xd8,0xe5}, {0xd8,0xe2}, {0x8d,0x62}, - {0xa0,0xa1}, {0xd8,0xe8}, {0x9c,0x40}, {0xdd,0x53}, {0xdd,0x56}, {0xdd,0x4e}, {0xdd,0x50}, {0xdd,0x55}, {0xdd,0x54}, {0xb7,0x43}, - {0xd8,0xdb}, {0xdd,0x52}, {0xb7,0x44}, {0x98,0xad}, {0xdd,0x4d}, {0xdd,0x51}, {0x9e,0xea}, {0xe1,0xa9}, {0xe1,0xb0}, {0xe1,0xa7}, - {0x8c,0xd4}, {0xe1,0xae}, {0xe1,0xa5}, {0xe1,0xad}, {0xe1,0xb1}, {0xe1,0xa4}, {0xe1,0xa8}, {0xe1,0xa3}, {0xb9,0xf1}, {0x9c,0xeb}, - {0xe1,0xa6}, {0xb9,0xf2}, {0xe1,0xac}, {0xe1,0xab}, {0xe1,0xaa}, {0xfb,0xe0}, {0xe1,0xaf}, {0x9f,0x51}, {0xe5,0x65}, {0xe5,0x67}, - {0xbc,0x6b}, {0xe5,0x68}, {0xe5,0x63}, {0xe5,0x62}, {0xe5,0x6c}, {0xe5,0x6a}, {0xbc,0x6a}, {0xe5,0x6d}, {0xe5,0x64}, {0xe5,0x69}, - {0xe5,0x6b}, {0xe5,0x66}, {0x8d,0x65}, {0xe9,0x61}, {0xe9,0x66}, {0xe9,0x60}, {0xe9,0x65}, {0x9c,0xf1}, {0xe9,0x5e}, {0xe9,0x68}, - {0xe9,0x64}, {0xe9,0x69}, {0xe9,0x63}, {0xe9,0x5f}, {0xe9,0x67}, {0xe9,0x6a}, {0xe9,0x62}, {0xfc,0x58}, {0xec,0xda}, {0xc0,0xaf}, - {0x8d,0x66}, {0xc0,0xad}, {0xc0,0xac}, {0xc0,0xae}, {0xef,0xc4}, {0x96,0x54}, {0xf1,0x72}, {0xf1,0xfd}, {0xf4,0x44}, {0xf4,0x45}, - {0xc4,0x60}, {0xf5,0xc9}, {0xc4,0xde}, {0xf5,0xca}, {0xf6,0xde}, {0xc5,0x72}, {0xc5,0x71}, {0xf6,0xdd}, {0xc5,0xc9}, {0xfb,0xe8}, - {0xf7,0xd6}, {0xc6,0xcc}, {0xa4,0x74}, {0xa6,0x7b}, {0xc9,0xda}, {0xca,0xca}, {0xa8,0xb5}, {0xb1,0x5f}, {0xa4,0x75}, {0xa5,0xaa}, - {0xa5,0xa9}, {0xa5,0xa8}, {0xa7,0xc5}, {0xae,0x74}, {0xdd,0x57}, {0xa4,0x76}, {0xa4,0x77}, {0xa4,0x78}, {0xa4,0xda}, {0x9f,0xce}, - {0xab,0xd1}, {0xce,0xaf}, {0xb4,0x53}, {0xa4,0x79}, {0xc9,0x5d}, {0xa5,0xab}, {0xa5,0xac}, {0xc9,0x78}, {0xa6,0x7c}, {0xfb,0xfc}, - {0xca,0xcb}, {0x9a,0xe4}, {0xa7,0xc6}, {0xca,0xcc}, {0xa9,0xae}, {0x9f,0x75}, {0xcc,0x6e}, {0xa9,0xac}, {0xa9,0xab}, {0xcc,0x6d}, - {0xa9,0xa9}, {0xcc,0x6f}, {0xa9,0xaa}, {0xa9,0xad}, {0xab,0xd2}, {0xab,0xd4}, {0xce,0xb3}, {0xce,0xb0}, {0xce,0xb1}, {0xce,0xb2}, - {0xce,0xb4}, {0xab,0xd3}, {0xd1,0x74}, {0xd1,0x73}, {0xae,0x76}, {0xae,0x75}, {0xfb,0xf1}, {0xb1,0x62}, {0xd5,0x46}, {0xb1,0x61}, - {0xb1,0x63}, {0xb1,0x60}, {0xb4,0x55}, {0xd5,0x45}, {0xb4,0x56}, {0xd8,0xf3}, {0x8d,0x69}, {0xb4,0x57}, {0xd8,0xf2}, {0xb4,0x54}, - {0x93,0x4f}, {0xdd,0x5a}, {0xdd,0x5c}, {0xb7,0x45}, {0xdd,0x5b}, {0xdd,0x59}, {0xdd,0x58}, {0xe1,0xb4}, {0xb9,0xf7}, {0xb9,0xf5}, - {0xb9,0xf6}, {0xe1,0xb2}, {0xe1,0xb3}, {0xb9,0xf3}, {0xe5,0x71}, {0xe5,0x6f}, {0x93,0x4e}, {0xbc,0x6d}, {0xe5,0x70}, {0xbc,0x6e}, - {0xbc,0x6c}, {0xb9,0xf4}, {0xe9,0x6d}, {0xe9,0x6b}, {0xe9,0x6c}, {0xe5,0x6e}, {0xec,0xdc}, {0xc0,0xb0}, {0xec,0xdb}, {0xef,0xc5}, - {0xef,0xc6}, {0xe9,0x6e}, {0xf1,0xfe}, {0xa4,0x7a}, {0xa5,0xad}, {0xa6,0x7e}, {0xc9,0xdb}, {0xa6,0x7d}, {0xa9,0xaf}, {0xb7,0x46}, - {0xfb,0xf4}, {0xa4,0xdb}, {0xa5,0xae}, {0xab,0xd5}, {0xb4,0x58}, {0xc6,0xce}, {0xc9,0x79}, {0xc9,0x7a}, {0xfb,0xc3}, {0xc9,0xdc}, - {0x89,0x65}, {0xa7,0xc8}, {0xca,0xd0}, {0xca,0xce}, {0xa7,0xc9}, {0xca,0xcd}, {0xca,0xcf}, {0xca,0xd1}, {0xa7,0xc7}, {0x8c,0x7a}, - {0xa9,0xb3}, {0xa9,0xb4}, {0xa9,0xb1}, {0x8c,0x7b}, {0xa9,0xb0}, {0xce,0xb8}, {0xa9,0xb2}, {0xab,0xd6}, {0xce,0xb7}, {0xce,0xb9}, - {0xce,0xb6}, {0xce,0xba}, {0xab,0xd7}, {0xae,0x79}, {0xd1,0x75}, {0xd1,0x77}, {0xae,0x77}, {0xd1,0x78}, {0xae,0x78}, {0xd1,0x76}, - {0xce,0xb5}, {0xd5,0x47}, {0xd5,0x4a}, {0xd5,0x4b}, {0xd5,0x48}, {0xb1,0x67}, {0xb1,0x66}, {0xb1,0x64}, {0xb1,0x65}, {0xd5,0x49}, - {0x8d,0x6a}, {0xb1,0x68}, {0xb4,0x5a}, {0xb4,0x5b}, {0xb4,0x5c}, {0xdd,0x5d}, {0xdd,0x5f}, {0xdd,0x61}, {0xb7,0x48}, {0xb7,0x47}, - {0xb4,0x59}, {0xdd,0x60}, {0xdd,0x5e}, {0x93,0x53}, {0xe1,0xb8}, {0x9d,0xfb}, {0xe1,0xb6}, {0xe1,0xbc}, {0xb9,0xf8}, {0xe1,0xbd}, - {0xe1,0xba}, {0xb9,0xf9}, {0xe1,0xb7}, {0xe1,0xb5}, {0xe1,0xbb}, {0xbc,0x70}, {0xe5,0x73}, {0xe1,0xb9}, {0xbc,0x72}, {0xe5,0x74}, - {0xbc,0x71}, {0xbc,0x74}, {0xe5,0x75}, {0xbc,0x6f}, {0xbc,0x73}, {0xe9,0x73}, {0xe9,0x71}, {0xe9,0x70}, {0xe9,0x72}, {0xe9,0x6f}, - {0xc3,0x66}, {0xf4,0x46}, {0xf4,0x47}, {0xf5,0xcb}, {0xf6,0xdf}, {0xc6,0x55}, {0xfb,0xfd}, {0xa9,0xb5}, {0xa7,0xca}, {0x90,0x59}, - {0xfc,0x40}, {0xab,0xd8}, {0xfc,0x41}, {0xfc,0x43}, {0xa4,0x7b}, {0xa4,0xdc}, {0xa5,0xaf}, {0xc9,0xdd}, {0xa7,0xcb}, {0xca,0xd2}, - {0xce,0xbb}, {0xab,0xd9}, {0xb9,0xfa}, {0xa4,0x7c}, {0x93,0x61}, {0xfc,0x46}, {0x93,0x62}, {0xa6,0xa1}, {0xb7,0x49}, {0xa4,0x7d}, - {0xa4,0xdd}, {0xa4,0xde}, {0xa5,0xb1}, {0xa5,0xb0}, {0xc9,0xde}, {0xa6,0xa2}, {0xca,0xd3}, {0xa7,0xcc}, {0xcc,0x71}, {0xcc,0x72}, - {0xcc,0x73}, {0x8d,0x6b}, {0xa9,0xb6}, {0xa9,0xb7}, {0xcc,0x70}, {0xa9,0xb8}, {0xab,0xda}, {0xce,0xbc}, {0xd1,0x7a}, {0xae,0x7a}, - {0xd1,0x79}, {0xb1,0x69}, {0xd5,0x4c}, {0xb1,0x6a}, {0xd5,0x4d}, {0xfc,0x4c}, {0xb4,0x5d}, {0xdd,0x62}, {0xe1,0xbf}, {0xe1,0xbe}, - {0xb9,0xfb}, {0xbc,0x75}, {0xe5,0x76}, {0xbe,0xca}, {0xe9,0x74}, {0xc0,0xb1}, {0x95,0xb8}, {0xc5,0x73}, {0xf7,0xd8}, {0xc6,0xd0}, - {0x8b,0xca}, {0xcc,0x74}, {0xce,0xbd}, {0xb1,0x6b}, {0xd8,0xf4}, {0xb7,0x4a}, {0x98,0x7a}, {0xc2,0x55}, {0xc6,0xd1}, {0xa7,0xce}, - {0xfc,0x51}, {0xa7,0xcd}, {0xab,0xdb}, {0xd1,0x7b}, {0xb1,0x6d}, {0xb3,0x43}, {0xb1,0x6e}, {0xb1,0x6c}, {0xb4,0x5e}, {0xe1,0xc0}, - {0xb9,0xfc}, {0xbc,0x76}, {0xfc,0x54}, {0xc9,0x4c}, {0xc9,0xdf}, {0xca,0xd5}, {0xa7,0xcf}, {0xca,0xd4}, {0xa7,0xd0}, {0xfa,0xaf}, - {0xa9,0xbc}, {0xcc,0x77}, {0xcc,0x76}, {0xa9,0xbb}, {0xa9,0xb9}, {0xa9,0xba}, {0xcc,0x75}, {0x8d,0x6c}, {0xab,0xdd}, {0xce,0xbe}, - {0xab,0xe0}, {0xab,0xdc}, {0xab,0xe2}, {0xab,0xde}, {0xab,0xdf}, {0xab,0xe1}, {0xae,0x7d}, {0xae,0x7c}, {0xae,0x7b}, {0xd5,0x4f}, - {0xb1,0x6f}, {0xb1,0x72}, {0xb1,0x70}, {0xd5,0x4e}, {0xb1,0x75}, {0xb1,0x71}, {0xd5,0x50}, {0xb1,0x74}, {0xb1,0x73}, {0xfa,0x61}, - {0xd8,0xf6}, {0xd8,0xf5}, {0xfc,0x57}, {0xb4,0x61}, {0xb4,0x5f}, {0xb4,0x60}, {0xd8,0xf7}, {0xb7,0x4b}, {0xdd,0x64}, {0xb7,0x4c}, - {0xdd,0x63}, {0x9b,0x70}, {0xe5,0x77}, {0xbc,0x78}, {0xe1,0xc1}, {0xbc,0x77}, {0xb9,0xfd}, {0xa0,0x51}, {0xec,0xde}, {0xe9,0x75}, - {0xc0,0xb2}, {0xec,0xdd}, {0xf2,0x40}, {0xf4,0x48}, {0xf4,0x49}, {0x8c,0x7c}, {0xa4,0xdf}, {0x8b,0xcb}, {0xa5,0xb2}, {0xc9,0x7b}, - {0xa7,0xd2}, {0xa7,0xd4}, {0xc9,0xe2}, {0xca,0xd8}, {0xca,0xd7}, {0xca,0xd6}, {0xc9,0xe1}, {0xc9,0xe0}, {0xa6,0xa4}, {0xa7,0xd3}, - {0xa7,0xd1}, {0xa6,0xa3}, {0x93,0x6e}, {0xa9,0xbd}, {0xcc,0x78}, {0xfc,0xd5}, {0xa9,0xbe}, {0xca,0xdd}, {0xca,0xdf}, {0xca,0xde}, - {0xcc,0x79}, {0xca,0xda}, {0xa7,0xd8}, {0xa7,0xd6}, {0xca,0xd9}, {0xca,0xdb}, {0xca,0xe1}, {0xa7,0xd5}, {0xca,0xdc}, {0xca,0xe5}, - {0xa9,0xc0}, {0xca,0xe2}, {0xa7,0xd7}, {0xca,0xe0}, {0xca,0xe3}, {0xa9,0xbf}, {0xa9,0xc1}, {0xca,0xe4}, {0xcc,0xaf}, {0xcc,0xa2}, - {0xcc,0x7e}, {0xcc,0xae}, {0xcc,0xa9}, {0xab,0xe7}, {0xa9,0xc2}, {0xcc,0xaa}, {0xcc,0xad}, {0xab,0xe3}, {0xcc,0xac}, {0xa9,0xc3}, - {0xa9,0xc8}, {0xa9,0xc6}, {0xcc,0xa3}, {0xcc,0x7c}, {0xcc,0xa5}, {0xa9,0xcd}, {0xcc,0xb0}, {0xab,0xe4}, {0xcc,0xa6}, {0xab,0xe5}, - {0xa9,0xc9}, {0xcc,0xa8}, {0xfc,0xa9}, {0xce,0xcd}, {0xab,0xe6}, {0xcc,0x7b}, {0xa9,0xca}, {0xab,0xe8}, {0xa9,0xcb}, {0xa9,0xc7}, - {0xa9,0xcc}, {0xcc,0xa7}, {0xcc,0x7a}, {0xcc,0xab}, {0xa9,0xc4}, {0xfc,0x61}, {0xcc,0x7d}, {0xcc,0xa4}, {0xcc,0xa1}, {0xa9,0xc5}, - {0xce,0xbf}, {0xce,0xc0}, {0x89,0x66}, {0xce,0xca}, {0xd1,0xa1}, {0xce,0xcb}, {0xab,0xee}, {0xce,0xce}, {0xce,0xc4}, {0xab,0xed}, - {0xce,0xc6}, {0xce,0xc7}, {0xfa,0xcb}, {0xce,0xc9}, {0xab,0xe9}, {0xae,0xa3}, {0xf9,0xda}, {0xce,0xc5}, {0xce,0xc1}, {0xae,0xa4}, - {0xce,0xcf}, {0xae,0x7e}, {0xd1,0x7d}, {0xce,0xc8}, {0xd1,0x7c}, {0xce,0xc3}, {0xce,0xcc}, {0xab,0xec}, {0xae,0xa1}, {0xab,0xf2}, - {0xae,0xa2}, {0xce,0xd0}, {0xd1,0x7e}, {0xab,0xeb}, {0xae,0xa6}, {0xab,0xf1}, {0xab,0xf0}, {0xab,0xef}, {0xae,0xa5}, {0xce,0xd1}, - {0xae,0xa7}, {0xab,0xea}, {0xce,0xc2}, {0x93,0x7a}, {0xa0,0xe0}, {0x93,0x6b}, {0xb1,0x76}, {0xd1,0xa4}, {0xd1,0xa6}, {0xd1,0xa8}, - {0xae,0xa8}, {0xae,0xae}, {0xd5,0x53}, {0xd1,0xac}, {0xd1,0xa3}, {0xb1,0x78}, {0xd5,0x51}, {0xae,0xad}, {0xae,0xab}, {0xd1,0xae}, - {0xd5,0x52}, {0xd1,0xa5}, {0xae,0xac}, {0xd1,0xa9}, {0xae,0xaf}, {0xd1,0xab}, {0xae,0xaa}, {0xd1,0xaa}, {0xd1,0xad}, {0xd1,0xa7}, - {0xfc,0x6b}, {0xae,0xa9}, {0xb1,0x79}, {0xd1,0xa2}, {0xb1,0x77}, {0xa0,0xdc}, {0x94,0x68}, {0xb1,0x7a}, {0xd5,0x55}, {0xd5,0x5e}, - {0xb4,0x64}, {0xfc,0x6d}, {0xb1,0x7c}, {0xb1,0xa3}, {0xb4,0x65}, {0xd5,0x60}, {0xb1,0xaa}, {0xd8,0xf9}, {0xd5,0x56}, {0xb1,0xa2}, - {0xb1,0xa5}, {0xb1,0x7e}, {0xd5,0x54}, {0xd5,0x62}, {0xd5,0x65}, {0xd9,0x49}, {0xd5,0x63}, {0xd8,0xfd}, {0xb1,0xa1}, {0xb1,0xa8}, - {0xb1,0xac}, {0xd5,0x5d}, {0xd8,0xf8}, {0xd5,0x61}, {0xb1,0x7b}, {0xd8,0xfa}, {0xd5,0x64}, {0xd8,0xfc}, {0xd5,0x59}, {0xb4,0x62}, - {0xd5,0x57}, {0xd5,0x58}, {0xb1,0xa7}, {0x8d,0x71}, {0xb1,0xa6}, {0xd5,0x5b}, {0xb1,0xab}, {0xd5,0x5f}, {0xb1,0xa4}, {0xd5,0x5c}, - {0xfd,0x64}, {0xb1,0xa9}, {0xb4,0x66}, {0xb4,0x63}, {0xd8,0xfb}, {0x99,0xba}, {0xd5,0x5a}, {0xb1,0x7d}, {0x9a,0xd0}, {0x9a,0x61}, - {0xa0,0xe5}, {0xb4,0x6b}, {0xb4,0x6f}, {0xd9,0x40}, {0xb7,0x51}, {0xb4,0x6d}, {0xd9,0x44}, {0xb4,0x71}, {0xdd,0x65}, {0xd9,0x46}, - {0xb7,0x53}, {0xb4,0x69}, {0xb4,0x6c}, {0xd9,0x47}, {0xa0,0x5b}, {0xd9,0x48}, {0xd9,0x4e}, {0xb4,0x73}, {0xb7,0x54}, {0xd9,0x4a}, - {0xd9,0x4f}, {0xd9,0x43}, {0xb7,0x5e}, {0x96,0xac}, {0xb7,0x55}, {0xb4,0x72}, {0xd9,0x41}, {0xd9,0x50}, {0x97,0x40}, {0xb7,0x5d}, - {0xb4,0x70}, {0xb7,0x4e}, {0xd9,0x4d}, {0xb4,0x74}, {0xd9,0x45}, {0xd8,0xfe}, {0xb4,0x6a}, {0xd9,0x42}, {0xd9,0x4b}, {0x9e,0xf1}, - {0xb7,0x4d}, {0xb7,0x52}, {0xb4,0x67}, {0xd9,0x4c}, {0xb7,0x50}, {0x8c,0x4d}, {0xb4,0x68}, {0xb7,0x5c}, {0xe1,0xc3}, {0xdd,0x70}, - {0xdd,0x68}, {0xe1,0xc2}, {0xdd,0x6c}, {0xdd,0x6e}, {0x9f,0x7e}, {0xdd,0x6b}, {0xb7,0x5b}, {0xdd,0x6a}, {0xb7,0x5f}, {0xe1,0xd2}, - {0x8d,0x72}, {0xb7,0x5a}, {0xba,0x40}, {0xdd,0x71}, {0xe1,0xc4}, {0xfc,0x76}, {0xb7,0x58}, {0xdd,0x69}, {0xdd,0x6d}, {0xb9,0xfe}, - {0xb7,0x4f}, {0xdd,0x66}, {0xdd,0x67}, {0xba,0x41}, {0xb7,0x57}, {0xb7,0x59}, {0xb7,0x56}, {0xdd,0x6f}, {0x96,0xa9}, {0xe1,0xc8}, - {0xe1,0xc9}, {0xe1,0xce}, {0xbc,0x7d}, {0xe1,0xd5}, {0xba,0x47}, {0xa0,0x6e}, {0xba,0x46}, {0xe1,0xd0}, {0xfc,0xaa}, {0xbc,0x7c}, - {0xe1,0xc5}, {0xba,0x45}, {0xfb,0xcd}, {0xe1,0xd4}, {0xba,0x43}, {0xba,0x44}, {0xfc,0x74}, {0xe1,0xd1}, {0xe5,0xaa}, {0xbc,0x7a}, - {0xb4,0x6e}, {0xe1,0xd3}, {0xbc,0xa3}, {0xe1,0xcb}, {0xbc,0x7b}, {0xa0,0x74}, {0xbc,0xa2}, {0xe1,0xc6}, {0xe1,0xca}, {0xe1,0xc7}, - {0xe1,0xcd}, {0xba,0x48}, {0xbc,0x79}, {0xba,0x42}, {0xe5,0x7a}, {0xe1,0xcf}, {0xbc,0xa1}, {0xa0,0x71}, {0xbc,0xa4}, {0xe1,0xcc}, - {0xfc,0x79}, {0xbc,0x7e}, {0xe5,0x79}, {0xfc,0x7c}, {0xe5,0x7e}, {0xbe,0xce}, {0xe5,0x78}, {0xe9,0xa3}, {0xe5,0xa9}, {0xbc,0xa8}, - {0xbc,0xa6}, {0xbe,0xcc}, {0xe5,0xa6}, {0xe5,0xa2}, {0xbc,0xac}, {0x9c,0x50}, {0xe9,0x78}, {0x93,0x79}, {0x93,0x78}, {0xbc,0xaa}, - {0xe5,0xa1}, {0xa0,0xdd}, {0xe9,0x76}, {0xe5,0xa5}, {0xe5,0xa8}, {0xe5,0x7d}, {0xbc,0xab}, {0xbc,0xa5}, {0xe9,0x77}, {0xbe,0xcd}, - {0xe5,0xa7}, {0xbc,0xa7}, {0xbc,0xa9}, {0xe5,0xa4}, {0xbc,0xad}, {0xe5,0xa3}, {0xe5,0x7c}, {0xe5,0x7b}, {0xbe,0xcb}, {0xe5,0xab}, - {0xe9,0x7a}, {0xec,0xe0}, {0xbe,0xd0}, {0x8d,0x75}, {0xe9,0xa2}, {0x8d,0x76}, {0xe9,0x7e}, {0xec,0xe1}, {0xbe,0xd1}, {0xe9,0xa1}, - {0x93,0x74}, {0xe9,0x7c}, {0xc0,0xb4}, {0xec,0xdf}, {0xe9,0x79}, {0xe9,0x7b}, {0xc0,0xb5}, {0xbe,0xd3}, {0xc0,0xb3}, {0xbe,0xd2}, - {0xc0,0xb7}, {0xe9,0x7d}, {0xbe,0xcf}, {0x8d,0x77}, {0xfc,0xa5}, {0xfc,0xa2}, {0xef,0xcf}, {0xef,0xc7}, {0x90,0xc3}, {0xec,0xe7}, - {0xef,0xc8}, {0xec,0xe3}, {0xa0,0x79}, {0xc2,0x56}, {0xec,0xe5}, {0xec,0xe4}, {0xc0,0xb6}, {0xec,0xe2}, {0xec,0xe6}, {0xef,0xd0}, - {0xef,0xcc}, {0xef,0xce}, {0xef,0xc9}, {0xef,0xca}, {0xef,0xcd}, {0xef,0xcb}, {0xc3,0x67}, {0xc3,0x6a}, {0xc3,0x69}, {0xc3,0x68}, - {0xc4,0x61}, {0xf4,0x4a}, {0xc4,0x62}, {0xf2,0x41}, {0xc4,0xdf}, {0xf5,0xcc}, {0xc4,0xe0}, {0xc5,0x74}, {0xc5,0xca}, {0xf7,0xd9}, - {0xf7,0xda}, {0xf7,0xdb}, {0xf9,0xba}, {0xa4,0xe0}, {0xc9,0x7c}, {0xa5,0xb3}, {0xa6,0xa6}, {0xa6,0xa7}, {0xa6,0xa5}, {0xa6,0xa8}, - {0xa7,0xda}, {0xa7,0xd9}, {0xcc,0xb1}, {0xa9,0xcf}, {0xa9,0xce}, {0xd1,0xaf}, {0xb1,0xad}, {0xb1,0xae}, {0xb4,0x75}, {0xdd,0x72}, - {0xb7,0x60}, {0xb7,0x61}, {0xdd,0x74}, {0xdd,0x76}, {0xdd,0x75}, {0xe1,0xd7}, {0xe1,0xd6}, {0xba,0x49}, {0xe1,0xd8}, {0x8d,0x79}, - {0xe5,0xac}, {0xbc,0xae}, {0xbe,0xd4}, {0xc0,0xb8}, {0xc2,0x57}, {0xc0,0xb9}, {0xa4,0xe1}, {0x8b,0xfc}, {0xa0,0x76}, {0xca,0xe6}, - {0xcc,0xb2}, {0xa9,0xd1}, {0xa9,0xd0}, {0xa9,0xd2}, {0xab,0xf3}, {0xce,0xd2}, {0xce,0xd3}, {0xd1,0xb0}, {0xae,0xb0}, {0xb1,0xaf}, - {0xb4,0x76}, {0xd9,0x51}, {0xa4,0xe2}, {0x8b,0xcd}, {0xa4,0x7e}, {0xa4,0xe3}, {0xc9,0x7d}, {0xa5,0xb7}, {0xa5,0xb6}, {0xa5,0xb4}, - {0xa5,0xb5}, {0xa6,0xab}, {0xc9,0xe9}, {0xc9,0xeb}, {0xa6,0xaa}, {0xc9,0xe3}, {0xc9,0xe4}, {0xc9,0xea}, {0xc9,0xe6}, {0xc9,0xe8}, - {0xa6,0xa9}, {0xc9,0xe5}, {0xc9,0xec}, {0xc9,0xe7}, {0x9f,0x5a}, {0xa7,0xe1}, {0xa7,0xea}, {0xa7,0xe8}, {0xca,0xf0}, {0xca,0xed}, - {0xca,0xf5}, {0xa7,0xe6}, {0xca,0xf6}, {0xa7,0xdf}, {0xca,0xf3}, {0xa7,0xe5}, {0xca,0xef}, {0xca,0xee}, {0xa7,0xe3}, {0xca,0xf4}, - {0xa7,0xe4}, {0xa9,0xd3}, {0xa7,0xde}, {0xca,0xf1}, {0x9f,0xf4}, {0xca,0xe7}, {0xa7,0xdb}, {0x9f,0xba}, {0xa7,0xee}, {0xca,0xec}, - {0xca,0xf2}, {0xa7,0xe0}, {0xa7,0xe2}, {0xca,0xe8}, {0xca,0xe9}, {0xca,0xea}, {0x8d,0x7a}, {0xa7,0xed}, {0xa7,0xe7}, {0xa7,0xec}, - {0xca,0xeb}, {0xa7,0xeb}, {0xa7,0xdd}, {0xa7,0xdc}, {0xa7,0xe9}, {0x9e,0x45}, {0x93,0xb0}, {0xa0,0x75}, {0xa9,0xe1}, {0xcc,0xbe}, - {0xcc,0xb7}, {0xa9,0xdc}, {0xa9,0xef}, {0xcc,0xb3}, {0xcc,0xba}, {0xcc,0xbc}, {0xcc,0xbf}, {0xa9,0xea}, {0xcc,0xbb}, {0xcc,0xb4}, - {0xa9,0xe8}, {0xcc,0xb8}, {0xcc,0xc0}, {0xa9,0xd9}, {0xcc,0xbd}, {0xa9,0xe3}, {0xa9,0xe2}, {0xcc,0xb6}, {0xa9,0xd7}, {0xa9,0xd8}, - {0x9b,0x46}, {0xa9,0xd6}, {0xfc,0xae}, {0xa9,0xee}, {0xa9,0xe6}, {0xa9,0xe0}, {0xa9,0xd4}, {0xcc,0xb9}, {0xa9,0xdf}, {0xa9,0xd5}, - {0xa9,0xe7}, {0xa9,0xf0}, {0xce,0xd4}, {0xa9,0xe4}, {0xcc,0xb5}, {0xa9,0xda}, {0xa9,0xdd}, {0xa9,0xde}, {0xfc,0xb0}, {0xa9,0xec}, - {0xa9,0xed}, {0xa9,0xeb}, {0xa9,0xe5}, {0xa9,0xe9}, {0xa9,0xdb}, {0xab,0xf4}, {0xfa,0x51}, {0x8d,0x7b}, {0xce,0xda}, {0xac,0x41}, - {0xab,0xf8}, {0xab,0xfa}, {0xac,0x40}, {0xce,0xe6}, {0xab,0xfd}, {0xd1,0xb1}, {0xae,0xb1}, {0xac,0x43}, {0xce,0xd7}, {0xce,0xdf}, - {0xab,0xfe}, {0xce,0xde}, {0xce,0xdb}, {0xce,0xe3}, {0xce,0xe5}, {0xab,0xf7}, {0xab,0xfb}, {0xac,0x42}, {0xae,0xb3}, {0xce,0xe0}, - {0xab,0xf9}, {0xac,0x45}, {0xce,0xd9}, {0xab,0xfc}, {0xae,0xb2}, {0xab,0xf6}, {0xce,0xd6}, {0xce,0xdd}, {0xce,0xd5}, {0xce,0xd8}, - {0xce,0xdc}, {0xd1,0xb2}, {0xac,0x44}, {0xce,0xe1}, {0xce,0xe2}, {0xce,0xe4}, {0xab,0xf5}, {0x8d,0x7c}, {0xae,0xc1}, {0xd1,0xbe}, - {0xae,0xbf}, {0xae,0xc0}, {0xd1,0xb4}, {0xd1,0xc4}, {0x9e,0xd6}, {0xae,0xb6}, {0x93,0xac}, {0xd5,0x66}, {0xd1,0xc6}, {0xd1,0xc0}, - {0x9f,0x5b}, {0xd1,0xb7}, {0x93,0xa9}, {0xd1,0xc9}, {0xd1,0xba}, {0xae,0xbc}, {0xd5,0x7d}, {0xd1,0xbd}, {0xae,0xbe}, {0xae,0xb5}, - {0xd1,0xcb}, {0xd1,0xbf}, {0xae,0xb8}, {0xd1,0xb8}, {0xd1,0xb5}, {0xd1,0xb6}, {0xae,0xb9}, {0xd1,0xc5}, {0xd1,0xcc}, {0xae,0xbb}, - {0xd1,0xbc}, {0xd1,0xbb}, {0xae,0xc3}, {0xae,0xc2}, {0xae,0xb4}, {0xae,0xba}, {0xae,0xbd}, {0xd1,0xc8}, {0xd1,0xc2}, {0xae,0xb7}, - {0xd1,0xb3}, {0xd1,0xca}, {0xd1,0xc1}, {0xd1,0xc3}, {0xd1,0xc7}, {0xa0,0x7c}, {0xd5,0x67}, {0xb1,0xb7}, {0xb1,0xcb}, {0xb1,0xca}, - {0xb1,0xbf}, {0xfc,0xb2}, {0xd5,0x79}, {0xd5,0x75}, {0xd5,0x72}, {0xd5,0xa6}, {0xb1,0xba}, {0xb1,0xb2}, {0xd5,0x77}, {0xb4,0xa8}, - {0xb1,0xb6}, {0xd5,0xa1}, {0x8a,0xc1}, {0xb1,0xcc}, {0xb1,0xc9}, {0xd5,0x7b}, {0xd5,0x6a}, {0x9f,0xb4}, {0xb1,0xc8}, {0xd5,0xa3}, - {0xd5,0x69}, {0xb1,0xbd}, {0xb1,0xc1}, {0xd5,0xa2}, {0xd5,0x73}, {0xb1,0xc2}, {0xb1,0xbc}, {0xd5,0x68}, {0xfc,0xac}, {0xb4,0x78}, - {0xd5,0xa5}, {0xd5,0x71}, {0xb1,0xc7}, {0xd5,0x74}, {0xd5,0xa4}, {0xb1,0xc6}, {0xd9,0x52}, {0xb1,0xb3}, {0xd5,0x6f}, {0xb1,0xb8}, - {0xb1,0xc3}, {0xb1,0xbe}, {0xd5,0x78}, {0xd5,0x6e}, {0xd5,0x6c}, {0xd5,0x7e}, {0xb1,0xb0}, {0xb1,0xc4}, {0xb1,0xb4}, {0xb4,0x77}, - {0xd5,0x7c}, {0xb1,0xb5}, {0xb1,0xb1}, {0xb1,0xc0}, {0xb1,0xbb}, {0xb1,0xb9}, {0xd5,0x70}, {0xb1,0xc5}, {0xd5,0x6d}, {0xd5,0x7a}, - {0xd5,0x76}, {0xd9,0x54}, {0xd9,0x53}, {0x9e,0x4c}, {0xd5,0x6b}, {0xd9,0x64}, {0xb4,0x7a}, {0x8f,0xc5}, {0xd9,0x6a}, {0xd9,0x59}, - {0xd9,0x67}, {0xdd,0x77}, {0xb4,0x7d}, {0xd9,0x6b}, {0xd9,0x6e}, {0xb4,0x7c}, {0xd9,0x5c}, {0xd9,0x6d}, {0xd9,0x6c}, {0xb4,0x7e}, - {0xd9,0x55}, {0xb4,0x79}, {0xb4,0xa3}, {0x93,0xad}, {0xb4,0xa1}, {0xd9,0x69}, {0xd9,0x5f}, {0xb4,0xa5}, {0xd9,0x70}, {0xd9,0x68}, - {0xd9,0x71}, {0xb4,0xad}, {0xb4,0xab}, {0xd9,0x66}, {0xd9,0x65}, {0x9d,0xc3}, {0xd9,0x63}, {0xd9,0x5d}, {0xb4,0xa4}, {0x8d,0xa2}, - {0xb4,0xa2}, {0xd1,0xb9}, {0xd9,0x56}, {0x9d,0x4a}, {0xdd,0xb7}, {0xd9,0x57}, {0xb4,0x7b}, {0xb4,0xaa}, {0xdd,0x79}, {0xb4,0xa6}, - {0xb4,0xa7}, {0xd9,0x58}, {0xd9,0x6f}, {0xdd,0x78}, {0xd9,0x60}, {0xd9,0x5b}, {0xb4,0xa9}, {0xd9,0x61}, {0xd9,0x5e}, {0xfc,0xb6}, - {0xb4,0xae}, {0x8d,0xa3}, {0x9e,0x4b}, {0x9e,0x4d}, {0xb7,0x70}, {0x8d,0xa4}, {0xdd,0x7c}, {0xdd,0xb1}, {0xdd,0xb6}, {0xdd,0xaa}, - {0xb7,0x6c}, {0xdd,0xbb}, {0xb7,0x69}, {0xdd,0x7a}, {0xdd,0x7b}, {0xb7,0x62}, {0xb7,0x6b}, {0xdd,0xa4}, {0xb7,0x6e}, {0xb7,0x6f}, - {0xdd,0xa5}, {0xdd,0xb2}, {0xdd,0xb8}, {0xb7,0x6a}, {0xb7,0x64}, {0xdd,0xa3}, {0xdd,0x7d}, {0xdd,0xba}, {0xdd,0xa8}, {0xdd,0xa9}, - {0xdd,0x7e}, {0xdd,0xb4}, {0xdd,0xab}, {0xdd,0xb5}, {0xdd,0xad}, {0xb7,0x65}, {0xe1,0xd9}, {0xb7,0x68}, {0xb7,0x66}, {0xdd,0xb9}, - {0xdd,0xb0}, {0xdd,0xac}, {0x8a,0xfd}, {0xdd,0xa1}, {0xba,0x53}, {0xdd,0xaf}, {0xb7,0x6d}, {0xdd,0xa7}, {0xfc,0xb5}, {0xdd,0xa6}, - {0xfc,0xc3}, {0x93,0xb2}, {0xb7,0x67}, {0xb7,0x63}, {0xe1,0xee}, {0xdd,0xb3}, {0xdd,0xae}, {0xdd,0xa2}, {0xe1,0xe9}, {0xe1,0xda}, - {0xe1,0xe5}, {0xe1,0xec}, {0xba,0x51}, {0xb4,0xac}, {0xe1,0xea}, {0xba,0x4c}, {0xba,0x4b}, {0xe1,0xf1}, {0x8d,0xa5}, {0xe1,0xdb}, - {0xe1,0xe8}, {0xe1,0xdc}, {0xe1,0xe7}, {0xba,0x4f}, {0xe1,0xeb}, {0xd9,0x62}, {0xe1,0xf2}, {0xe1,0xe3}, {0xba,0x52}, {0xe5,0xba}, - {0xbc,0xaf}, {0xe1,0xf0}, {0xe1,0xef}, {0xba,0x54}, {0xe5,0xad}, {0xbc,0xb0}, {0xe5,0xae}, {0x93,0xa1}, {0xe1,0xdf}, {0xe1,0xe0}, - {0xe1,0xdd}, {0xe1,0xe2}, {0xe1,0xde}, {0xe1,0xf3}, {0xba,0x4e}, {0xbc,0xb1}, {0xba,0x50}, {0xba,0x55}, {0x8a,0xc6}, {0xe1,0xe1}, - {0xe1,0xed}, {0xe1,0xe6}, {0xe5,0xb1}, {0xba,0x4a}, {0xbc,0xb4}, {0xe9,0xaa}, {0xe5,0xb6}, {0xe5,0xb5}, {0xe5,0xb7}, {0x8a,0x5b}, - {0xe5,0xb4}, {0xbc,0xb5}, {0x89,0x4d}, {0xbc,0xbb}, {0xbc,0xb8}, {0xbc,0xb9}, {0xe5,0xaf}, {0xe5,0xb2}, {0xe5,0xbc}, {0xbc,0xc1}, - {0xbc,0xbf}, {0xe5,0xb3}, {0xd9,0x5a}, {0xbc,0xb2}, {0xe5,0xb9}, {0xe5,0xb0}, {0xbc,0xc2}, {0xe5,0xb8}, {0xba,0x4d}, {0xbc,0xb7}, - {0xe1,0xe4}, {0xbc,0xba}, {0xbc,0xbe}, {0xbc,0xc0}, {0xbc,0xbd}, {0xbc,0xbc}, {0xfe,0xd4}, {0xbc,0xb6}, {0xe5,0xbb}, {0xbc,0xb3}, - {0xbc,0xc3}, {0x8a,0x78}, {0x93,0xab}, {0xbe,0xd8}, {0xbe,0xd9}, {0xe9,0xa9}, {0xbe,0xe2}, {0xbe,0xdf}, {0x8d,0xa7}, {0xbe,0xd6}, - {0xbe,0xdd}, {0xe9,0xab}, {0xbe,0xdb}, {0xbe,0xd5}, {0xbe,0xdc}, {0xe9,0xa8}, {0xc0,0xbb}, {0xbe,0xd7}, {0xbe,0xde}, {0xc0,0xba}, - {0xe9,0xa7}, {0xe9,0xa6}, {0xbe,0xe0}, {0x9f,0x45}, {0xbe,0xe1}, {0xe9,0xa5}, {0xe9,0xa4}, {0xc0,0xbc}, {0xe9,0xae}, {0xbe,0xda}, - {0xe9,0xac}, {0x8a,0x56}, {0xc0,0xbd}, {0xfc,0xbf}, {0xc0,0xc2}, {0xec,0xea}, {0xec,0xec}, {0xfc,0xc0}, {0xc0,0xbf}, {0x8e,0xe6}, - {0xec,0xed}, {0xec,0xe9}, {0x8a,0xa4}, {0xec,0xeb}, {0xc0,0xc0}, {0xc0,0xc3}, {0xec,0xe8}, {0xc0,0xbe}, {0xc0,0xc1}, {0xc2,0x59}, - {0xe9,0xad}, {0xc2,0x58}, {0xc2,0x5e}, {0xef,0xd4}, {0xc2,0x5c}, {0xc2,0x5d}, {0xef,0xd7}, {0xef,0xd3}, {0xc2,0x5a}, {0xef,0xd1}, - {0xc3,0x6b}, {0xef,0xd5}, {0xef,0xd6}, {0xef,0xd2}, {0xc2,0x5b}, {0xf2,0x42}, {0xf2,0x45}, {0x89,0x43}, {0xf2,0x46}, {0xf2,0x44}, - {0xf2,0x47}, {0xc3,0x6c}, {0xf2,0x43}, {0x93,0xf3}, {0xf4,0x4e}, {0xc4,0x64}, {0xf4,0x4d}, {0xf4,0x4c}, {0xf4,0x4b}, {0xc4,0x63}, - {0xc4,0x65}, {0xf5,0xcd}, {0xc4,0xe2}, {0xc4,0xe1}, {0xfc,0xab}, {0x9e,0xa2}, {0xf6,0xe1}, {0xf6,0xe0}, {0xf6,0xe3}, {0xc5,0xcb}, - {0xc5,0x75}, {0xf7,0xdd}, {0xf6,0xe2}, {0xf7,0xdc}, {0xc5,0xcd}, {0xc5,0xcc}, {0xc5,0xf3}, {0xf8,0xa9}, {0xf8,0xef}, {0xa4,0xe4}, - {0x9d,0xc7}, {0xd9,0x72}, {0xe9,0xaf}, {0xc6,0xd2}, {0x8b,0xce}, {0xa6,0xac}, {0xca,0xf7}, {0xa7,0xf1}, {0xa7,0xef}, {0xa7,0xf0}, - {0xcc,0xc1}, {0xa9,0xf1}, {0xac,0x46}, {0xce,0xe7}, {0xce,0xe8}, {0xac,0x47}, {0xd1,0xce}, {0xae,0xc4}, {0xae,0xc5}, {0xd1,0xcd}, - {0xfc,0xc5}, {0xb1,0xd3}, {0xb1,0xcf}, {0xd5,0xa7}, {0xb1,0xd6}, {0xb1,0xd5}, {0xb1,0xce}, {0xb1,0xd1}, {0xb1,0xd4}, {0xb1,0xd0}, - {0xd9,0x76}, {0xb1,0xcd}, {0xb4,0xaf}, {0xfc,0xcb}, {0xb4,0xb1}, {0xb4,0xb2}, {0xd9,0x75}, {0xd9,0x78}, {0xb4,0xb0}, {0xd9,0x73}, - {0xd9,0x77}, {0xd9,0x74}, {0x93,0xb3}, {0xb7,0x71}, {0xfc,0xca}, {0xdd,0xbc}, {0xba,0x56}, {0xe1,0xf4}, {0xbe,0xe3}, {0xbc,0xc4}, - {0xe5,0xbd}, {0xbc,0xc5}, {0xbc,0xc6}, {0xe5,0xbf}, {0xe5,0xbe}, {0xe5,0xc0}, {0xe9,0xb1}, {0xe9,0xb0}, {0xec,0xef}, {0xec,0xee}, - {0xc0,0xc4}, {0xc0,0xc5}, {0xf2,0x48}, {0xfc,0xc9}, {0x8d,0xac}, {0xa4,0xe5}, {0xfb,0xc6}, {0x89,0x67}, {0x8c,0x7e}, {0xd9,0x79}, - {0xb4,0xb4}, {0xb4,0xb3}, {0xdd,0xbd}, {0xef,0xd8}, {0xc4,0xe3}, {0xf7,0xde}, {0xa4,0xe6}, {0xae,0xc6}, {0xb1,0xd8}, {0xb1,0xd7}, - {0xd9,0x7a}, {0xd9,0x7b}, {0xb7,0x72}, {0xe1,0xf5}, {0xba,0x57}, {0xe9,0xb2}, {0xa4,0xe7}, {0xa5,0xb8}, {0xa9,0xf2}, {0xcc,0xc2}, - {0xce,0xe9}, {0xac,0x48}, {0xb1,0xd9}, {0xd9,0x7c}, {0xb4,0xb5}, {0xb7,0x73}, {0xe5,0xc1}, {0xe5,0xc2}, {0xfc,0xcd}, {0xec,0xf0}, - {0xc2,0x5f}, {0xf8,0xf0}, {0xa4,0xe8}, {0xcc,0xc3}, {0xa9,0xf3}, {0xac,0x49}, {0x9c,0xf3}, {0xce,0xea}, {0xae,0xc7}, {0xd1,0xd2}, - {0xd1,0xd0}, {0xd1,0xd1}, {0xae,0xc8}, {0xd1,0xcf}, {0xb1,0xdb}, {0xb1,0xdc}, {0xd5,0xa8}, {0xb1,0xdd}, {0xb1,0xda}, {0xd9,0x7d}, - {0xfc,0xd0}, {0xd9,0x7e}, {0xdd,0xbe}, {0x95,0xbb}, {0xba,0x59}, {0xba,0x58}, {0xec,0xf1}, {0xef,0xd9}, {0xf2,0x4a}, {0xf2,0x49}, - {0xf4,0x4f}, {0xfc,0xd3}, {0xc9,0x5e}, {0xac,0x4a}, {0xfc,0xd4}, {0xa4,0xe9}, {0xa5,0xb9}, {0xa6,0xae}, {0xa6,0xad}, {0xa6,0xaf}, - {0xa6,0xb0}, {0xc9,0xee}, {0xc9,0xed}, {0xca,0xf8}, {0xa7,0xf2}, {0xca,0xfb}, {0xca,0xfa}, {0xca,0xf9}, {0xca,0xfc}, {0xa9,0xf4}, - {0xcc,0xc9}, {0xcc,0xc5}, {0xcc,0xce}, {0x8d,0xae}, {0xa9,0xfb}, {0xa9,0xf9}, {0xcc,0xca}, {0xcc,0xc6}, {0xcc,0xcd}, {0xa9,0xf8}, - {0xaa,0x40}, {0xcc,0xc8}, {0xcc,0xc4}, {0xa9,0xfe}, {0xcc,0xcb}, {0xa9,0xf7}, {0xcc,0xcc}, {0xa9,0xfa}, {0xa9,0xfc}, {0xcc,0xd0}, - {0xcc,0xcf}, {0xcc,0xc7}, {0xa9,0xf6}, {0xa9,0xf5}, {0xa9,0xfd}, {0xfc,0xd7}, {0xce,0xef}, {0xce,0xf5}, {0x93,0xdb}, {0xac,0x50}, - {0xac,0x4d}, {0xce,0xec}, {0xce,0xf1}, {0xfe,0x63}, {0xac,0x53}, {0xac,0x4b}, {0xce,0xf0}, {0xac,0x4e}, {0xac,0x51}, {0xce,0xf3}, - {0xac,0x4c}, {0xce,0xf8}, {0xac,0x4f}, {0x93,0xd5}, {0xac,0x52}, {0xce,0xed}, {0xce,0xf2}, {0xce,0xf6}, {0xce,0xee}, {0xce,0xeb}, - {0xce,0xf7}, {0xce,0xf4}, {0xae,0xd0}, {0xae,0xc9}, {0xae,0xcc}, {0xfc,0xda}, {0xae,0xcf}, {0xd1,0xd5}, {0x9b,0x71}, {0xae,0xca}, - {0xd1,0xd3}, {0xfc,0xdd}, {0xae,0xce}, {0xae,0xcb}, {0xd1,0xd6}, {0xae,0xcd}, {0x8d,0xaf}, {0xfa,0xf2}, {0xd5,0xac}, {0xb1,0xdf}, - {0xd5,0xab}, {0xd5,0xad}, {0xb1,0xde}, {0xb1,0xe3}, {0xd1,0xd4}, {0xd5,0xaa}, {0xd5,0xae}, {0x93,0xd8}, {0xb1,0xe0}, {0xd5,0xa9}, - {0xb1,0xe2}, {0xfc,0xdf}, {0xb1,0xe1}, {0xd9,0xa7}, {0x93,0xd3}, {0xd9,0xa2}, {0xb4,0xb6}, {0xb4,0xba}, {0xb4,0xb7}, {0xd9,0xa5}, - {0xd9,0xa8}, {0xfc,0xe1}, {0xb4,0xb8}, {0xb4,0xb9}, {0xb4,0xbe}, {0xdd,0xc7}, {0xd9,0xa6}, {0xb4,0xbc}, {0xd9,0xa3}, {0xd9,0xa1}, - {0x8e,0x76}, {0xb4,0xbd}, {0xd9,0xa4}, {0xb7,0x79}, {0xfc,0x62}, {0xdd,0xbf}, {0xb7,0x76}, {0xb7,0x77}, {0xb7,0x75}, {0xdd,0xc4}, - {0xdd,0xc3}, {0xdd,0xc0}, {0xb7,0x7b}, {0x93,0xd1}, {0xdd,0xc2}, {0xb4,0xbb}, {0x8d,0xb1}, {0xdd,0xc6}, {0xdd,0xc1}, {0xb7,0x78}, - {0xb7,0x74}, {0xb7,0x7a}, {0xdd,0xc5}, {0x98,0x59}, {0xba,0x5c}, {0xe1,0xf8}, {0xe1,0xf7}, {0xe1,0xf6}, {0xba,0x5a}, {0xfb,0x52}, - {0xba,0x5b}, {0xe5,0xc5}, {0xe5,0xc8}, {0xbc,0xc8}, {0xfb,0x53}, {0xbc,0xc7}, {0xe5,0xc9}, {0xe5,0xc4}, {0xbc,0xca}, {0xe5,0xc6}, - {0xfb,0x4d}, {0xbc,0xc9}, {0xe5,0xc3}, {0x9c,0xbf}, {0xe5,0xc7}, {0xbe,0xe9}, {0xbe,0xe6}, {0xe9,0xbb}, {0xe9,0xba}, {0xe9,0xb9}, - {0xe9,0xb4}, {0x9b,0x72}, {0xe9,0xb5}, {0xbe,0xe7}, {0xbe,0xe4}, {0xbe,0xe8}, {0xe9,0xb3}, {0xbe,0xe5}, {0xe9,0xb6}, {0xe9,0xb7}, - {0xe9,0xbc}, {0xfb,0x50}, {0x93,0xbe}, {0xe9,0xb8}, {0xec,0xf2}, {0xc0,0xc7}, {0xef,0xdc}, {0xc0,0xc6}, {0xef,0xda}, {0xef,0xdb}, - {0xc2,0x60}, {0xc3,0x6e}, {0xf2,0x4b}, {0xc3,0x6d}, {0xf4,0x51}, {0xf4,0x52}, {0xc4,0x66}, {0xf4,0x50}, {0xc4,0xe4}, {0xf7,0xdf}, - {0xc5,0xce}, {0xf8,0xaa}, {0xf8,0xab}, {0xa4,0xea}, {0x9d,0xf1}, {0xa6,0xb1}, {0xa6,0xb2}, {0xa7,0xf3}, {0xcc,0xd1}, {0xac,0x54}, - {0xae,0xd1}, {0xb1,0xe4}, {0xb0,0xd2}, {0xb4,0xbf}, {0xb4,0xc0}, {0xb3,0xcc}, {0xd9,0xa9}, {0xfc,0xeb}, {0xb7,0x7c}, {0xe1,0xfa}, - {0xe1,0xf9}, {0xa4,0xeb}, {0xa6,0xb3}, {0xcc,0xd2}, {0xaa,0x42}, {0xa0,0xbb}, {0xaa,0x41}, {0x9b,0x7e}, {0xce,0xf9}, {0xce,0xfa}, - {0xd1,0xd7}, {0xd1,0xd8}, {0xae,0xd2}, {0xae,0xd3}, {0x8d,0xb3}, {0xae,0xd4}, {0xd5,0xaf}, {0x8c,0x52}, {0xb1,0xe6}, {0xb4,0xc2}, - {0x9a,0xe8}, {0xb4,0xc1}, {0xdd,0xc8}, {0xdf,0x7a}, {0xe1,0xfb}, {0xe9,0xbd}, {0x8e,0xdc}, {0xc2,0x61}, {0xc4,0x67}, {0xa4,0xec}, - {0xa5,0xbc}, {0xa5,0xbd}, {0xa5,0xbb}, {0xa5,0xbe}, {0xa5,0xba}, {0xa6,0xb6}, {0xc9,0xf6}, {0xa6,0xb5}, {0xa6,0xb7}, {0x9c,0xf9}, - {0xc9,0xf1}, {0xc9,0xf0}, {0xc9,0xf3}, {0xc9,0xf2}, {0xc9,0xf5}, {0xa6,0xb4}, {0xc9,0xef}, {0xc9,0xf4}, {0xfa,0x50}, {0xca,0xfd}, - {0xa7,0xfd}, {0xca,0xfe}, {0xcb,0x43}, {0xa7,0xfc}, {0xcb,0x47}, {0xcb,0x42}, {0xcb,0x45}, {0xa7,0xf5}, {0xa7,0xf6}, {0xa7,0xf7}, - {0xa7,0xf8}, {0xa8,0x40}, {0xcb,0x41}, {0xa7,0xfa}, {0xa8,0x41}, {0xcb,0x40}, {0xcb,0x46}, {0xa7,0xf9}, {0xcb,0x44}, {0xa7,0xfb}, - {0xa7,0xf4}, {0xa7,0xfe}, {0x98,0xe7}, {0xfc,0xf3}, {0xfc,0xf2}, {0xaa,0x57}, {0x8c,0xca}, {0xcc,0xd4}, {0xaa,0x43}, {0xaa,0x4d}, - {0xaa,0x4e}, {0xaa,0x46}, {0xaa,0x58}, {0xaa,0x48}, {0xcc,0xdc}, {0xaa,0x53}, {0xcc,0xd7}, {0xaa,0x49}, {0xcc,0xe6}, {0xcc,0xe7}, - {0xcc,0xdf}, {0xcc,0xd8}, {0xaa,0x56}, {0xcc,0xe4}, {0xaa,0x51}, {0xaa,0x4f}, {0xcc,0xe5}, {0xcc,0xe3}, {0xcc,0xdb}, {0xcc,0xd3}, - {0xcc,0xda}, {0xaa,0x4a}, {0xaa,0x50}, {0xaa,0x44}, {0xcc,0xde}, {0xcc,0xdd}, {0xcc,0xd5}, {0x93,0xe5}, {0xaa,0x52}, {0xcc,0xe1}, - {0xcc,0xd6}, {0xaa,0x55}, {0xcc,0xe8}, {0xaa,0x45}, {0xaa,0x4c}, {0xcc,0xd9}, {0xcc,0xe2}, {0xaa,0x54}, {0xaa,0x47}, {0xaa,0x4b}, - {0xcc,0xe0}, {0x9a,0x59}, {0x8d,0xb5}, {0xfd,0x4d}, {0xcf,0x5b}, {0xac,0x5c}, {0xac,0x69}, {0xfd,0x5e}, {0xcf,0x56}, {0xcf,0x4c}, - {0xac,0x62}, {0xcf,0x4a}, {0xac,0x5b}, {0xcf,0x45}, {0xac,0x65}, {0xcf,0x52}, {0xce,0xfe}, {0xcf,0x41}, {0x8f,0x7d}, {0xcf,0x44}, - {0xce,0xfb}, {0xcf,0x51}, {0xcf,0x61}, {0xac,0x60}, {0xcf,0x46}, {0xcf,0x58}, {0xce,0xfd}, {0xcf,0x5f}, {0xcf,0x60}, {0xcf,0x63}, - {0xcf,0x5a}, {0xcf,0x4b}, {0xcf,0x53}, {0xac,0x66}, {0xac,0x59}, {0xac,0x61}, {0xac,0x6d}, {0xac,0x56}, {0xac,0x58}, {0x95,0x47}, - {0xfc,0xf6}, {0xcf,0x43}, {0xac,0x6a}, {0xac,0x63}, {0xcf,0x5d}, {0xcf,0x40}, {0xac,0x6c}, {0xac,0x67}, {0xcf,0x49}, {0xac,0x6b}, - {0xcf,0x50}, {0xcf,0x48}, {0xac,0x64}, {0xcf,0x5c}, {0xcf,0x54}, {0xac,0x5e}, {0xcf,0x62}, {0xcf,0x47}, {0xac,0x5a}, {0xcf,0x59}, - {0xcf,0x4f}, {0xac,0x5f}, {0xcf,0x55}, {0xac,0x57}, {0xce,0xfc}, {0xac,0x68}, {0xae,0xe3}, {0xac,0x5d}, {0xcf,0x4e}, {0xcf,0x4d}, - {0xcf,0x42}, {0x92,0x50}, {0xcf,0x5e}, {0xcf,0x57}, {0x89,0x68}, {0xac,0x55}, {0x8d,0xb6}, {0xfc,0xfb}, {0xa0,0x7d}, {0x98,0xfc}, - {0x89,0x69}, {0xfe,0x4f}, {0x92,0x56}, {0xd1,0xec}, {0xae,0xea}, {0xd1,0xed}, {0xd1,0xe1}, {0xae,0xdf}, {0xae,0xeb}, {0xd1,0xda}, - {0xfa,0xc9}, {0xd1,0xe3}, {0xd1,0xeb}, {0x93,0xe8}, {0xd1,0xd9}, {0xd1,0xf4}, {0xae,0xd5}, {0xfc,0xf8}, {0xd1,0xf3}, {0xd1,0xee}, - {0xd1,0xef}, {0xae,0xdd}, {0xae,0xe8}, {0xd1,0xe5}, {0xd1,0xe6}, {0xd1,0xf0}, {0xd1,0xe7}, {0xd1,0xe2}, {0xd1,0xdc}, {0xd1,0xdd}, - {0xd1,0xea}, {0xd1,0xe4}, {0x9c,0xe3}, {0xfd,0xa9}, {0xae,0xd6}, {0xae,0xda}, {0xd1,0xf2}, {0xd1,0xde}, {0xae,0xe6}, {0xae,0xe2}, - {0xfc,0x44}, {0xae,0xe5}, {0xae,0xec}, {0xae,0xdb}, {0xae,0xe7}, {0xd1,0xe9}, {0xae,0xe9}, {0xae,0xd8}, {0x96,0x40}, {0xae,0xd7}, - {0xd1,0xdb}, {0x8d,0xb8}, {0xd1,0xdf}, {0xae,0xe0}, {0xd1,0xf1}, {0xd1,0xe8}, {0xd1,0xe0}, {0xae,0xe4}, {0xae,0xe1}, {0xae,0xd9}, - {0xae,0xdc}, {0x9b,0x4a}, {0x8f,0xb9}, {0xfc,0xfe}, {0x89,0x6a}, {0xd5,0xc4}, {0xd5,0xb4}, {0xd5,0xb5}, {0xd5,0xb9}, {0xd5,0xc8}, - {0xd5,0xc5}, {0xd5,0xbe}, {0xd5,0xbd}, {0xb1,0xed}, {0xd5,0xc1}, {0xd5,0xd0}, {0xd5,0xb0}, {0xd5,0xd1}, {0xd5,0xc3}, {0xd5,0xd5}, - {0xd5,0xc9}, {0xb1,0xec}, {0xd5,0xc7}, {0xb1,0xe7}, {0xb1,0xfc}, {0xb1,0xf2}, {0x8d,0xb9}, {0xb1,0xf6}, {0xb1,0xf5}, {0xd5,0xb1}, - {0x91,0x7e}, {0xd5,0xce}, {0xd5,0xd4}, {0xd5,0xcc}, {0xd5,0xd3}, {0xd5,0xc0}, {0xd5,0xb2}, {0xd5,0xd2}, {0xd5,0xc2}, {0xb1,0xea}, - {0xb1,0xf7}, {0xd5,0xcb}, {0xb1,0xf0}, {0x93,0xf4}, {0xd5,0xca}, {0xd5,0xb3}, {0xb1,0xf8}, {0xb1,0xfa}, {0xd5,0xcd}, {0xb1,0xfb}, - {0xb1,0xe9}, {0xd5,0xba}, {0xd5,0xcf}, {0xfb,0x7c}, {0xb1,0xef}, {0xb1,0xf9}, {0xd5,0xbc}, {0xd5,0xc6}, {0xd5,0xb7}, {0xd5,0xbb}, - {0xb1,0xf4}, {0xd5,0xb6}, {0xb1,0xe8}, {0xb1,0xf1}, {0xb1,0xee}, {0xd5,0xbf}, {0xae,0xde}, {0xd9,0xc0}, {0xb1,0xeb}, {0x93,0xe7}, - {0x97,0xef}, {0xfe,0x4a}, {0xfd,0x45}, {0xb1,0xf3}, {0x96,0xa5}, {0xd9,0xc3}, {0xd9,0xd9}, {0xd9,0xce}, {0xb4,0xd6}, {0xfe,0xe0}, - {0xb4,0xd1}, {0xd9,0xbd}, {0xb4,0xd2}, {0xd9,0xcd}, {0xd9,0xc6}, {0xd9,0xd3}, {0xb4,0xce}, {0xd9,0xab}, {0xd9,0xd5}, {0xb4,0xc4}, - {0xd9,0xb3}, {0xb4,0xc7}, {0xb4,0xc6}, {0xb4,0xd7}, {0xd9,0xad}, {0xd9,0xcf}, {0xd9,0xd0}, {0xb4,0xc9}, {0xb4,0xc5}, {0xd9,0xbb}, - {0xb4,0xd0}, {0xd9,0xb6}, {0xd9,0xd1}, {0xb4,0xcc}, {0xd9,0xc9}, {0xd9,0xd6}, {0xd9,0xb0}, {0xd9,0xb5}, {0xd9,0xaf}, {0xb4,0xcb}, - {0xd9,0xc2}, {0xdd,0xde}, {0xd9,0xb1}, {0xb4,0xcf}, {0xd9,0xba}, {0xd9,0xd2}, {0xb4,0xca}, {0xd9,0xb7}, {0xd9,0xb4}, {0xd9,0xc5}, - {0xb4,0xcd}, {0xb4,0xc3}, {0xb4,0xd9}, {0xd9,0xc8}, {0xd9,0xc7}, {0xfd,0x48}, {0xfd,0x47}, {0xfe,0xf2}, {0xfe,0x6a}, {0xd9,0xac}, - {0xb4,0xc8}, {0xd9,0xd4}, {0xd9,0xbc}, {0xd9,0xbe}, {0x8d,0xbd}, {0xd9,0xcb}, {0xd9,0xca}, {0xd9,0xaa}, {0xb4,0xd3}, {0xb4,0xd5}, - {0xd9,0xb2}, {0xd9,0xb9}, {0xd9,0xc1}, {0xb4,0xd4}, {0xd9,0xb8}, {0xd9,0xc4}, {0xd9,0xd7}, {0xd9,0xcc}, {0x9b,0xa1}, {0x8c,0xa2}, - {0x9a,0xb7}, {0x8e,0xfc}, {0xd9,0xd8}, {0xd9,0xae}, {0x9f,0xa1}, {0xdd,0xf2}, {0xb7,0xa6}, {0xdd,0xf0}, {0xdd,0xdb}, {0xdd,0xe0}, - {0xdd,0xd9}, {0xfd,0x51}, {0xdd,0xec}, {0xdd,0xcb}, {0xdd,0xd2}, {0xdd,0xea}, {0xdd,0xf4}, {0xdd,0xdc}, {0xfa,0xad}, {0xdd,0xcf}, - {0xdd,0xe2}, {0xdd,0xe7}, {0xdd,0xd3}, {0x8d,0xbe}, {0xdd,0xe4}, {0xdd,0xd0}, {0x89,0xa4}, {0xdd,0xd7}, {0xdd,0xd8}, {0xb7,0xa8}, - {0xdd,0xeb}, {0xdd,0xe9}, {0xdd,0xcc}, {0xdd,0xee}, {0xdd,0xef}, {0xdd,0xf1}, {0xb7,0xac}, {0xb7,0xa4}, {0x9a,0xd9}, {0xd5,0xb8}, - {0xdd,0xd4}, {0xdd,0xe6}, {0xdd,0xd5}, {0xb7,0xa1}, {0xb7,0xb1}, {0xdd,0xed}, {0xb7,0xaf}, {0xb7,0xab}, {0xdd,0xca}, {0xb7,0xa3}, - {0xfd,0x4e}, {0xdd,0xcd}, {0xb7,0xb0}, {0x8d,0xc0}, {0xdd,0xdd}, {0xdd,0xc9}, {0x97,0xf0}, {0xb7,0xa9}, {0xdd,0xe1}, {0xdd,0xd1}, - {0xb7,0xaa}, {0xdd,0xda}, {0xb7,0x7e}, {0xb4,0xd8}, {0xdd,0xe3}, {0xd9,0xbf}, {0xdd,0xce}, {0x93,0xb4}, {0xfd,0x44}, {0xdd,0xe8}, - {0xb7,0xa5}, {0xdd,0xe5}, {0xb7,0xa2}, {0xdd,0xdf}, {0xb7,0xad}, {0xdd,0xd6}, {0xdd,0xf3}, {0x9f,0xa7}, {0xb7,0xa7}, {0xde,0xc6}, - {0x8d,0xc2}, {0xb7,0xae}, {0x99,0xb6}, {0xe2,0x4a}, {0xe2,0x48}, {0xe2,0x5e}, {0xe2,0x46}, {0xe2,0x58}, {0xb7,0x7d}, {0xba,0x5f}, - {0xe2,0x42}, {0xe2,0x5d}, {0xfd,0x52}, {0xe2,0x47}, {0xe2,0x55}, {0xba,0x64}, {0xba,0x5d}, {0xe2,0x5b}, {0x8d,0xc1}, {0xe2,0x40}, - {0xe2,0x5a}, {0x8e,0x46}, {0xba,0x6f}, {0xe2,0x51}, {0xe2,0x61}, {0xba,0x6d}, {0xe2,0x49}, {0xba,0x5e}, {0xe2,0x4b}, {0xe2,0x59}, - {0xba,0x67}, {0xe2,0x44}, {0xba,0x6b}, {0xba,0x61}, {0xe2,0x4d}, {0xe2,0x43}, {0xe1,0xfc}, {0xa0,0xd1}, {0xe2,0x57}, {0xba,0x68}, - {0xe2,0x60}, {0xe1,0xfd}, {0xba,0x65}, {0xe2,0x53}, {0xba,0x66}, {0xe2,0x45}, {0xe2,0x50}, {0xe2,0x4c}, {0xe2,0x4e}, {0x9f,0xca}, - {0xba,0x60}, {0xe2,0x5f}, {0xba,0x6e}, {0xe2,0x4f}, {0xe2,0x62}, {0xe1,0xfe}, {0xe2,0x54}, {0xba,0x63}, {0xba,0x6c}, {0xba,0x6a}, - {0xe2,0x41}, {0xe2,0x56}, {0xba,0x69}, {0x92,0xcf}, {0xba,0x62}, {0xe2,0x52}, {0x9c,0xf4}, {0x8d,0xc4}, {0xe2,0x5c}, {0xfd,0x41}, - {0xe5,0xd5}, {0xe5,0xd1}, {0xe5,0xcd}, {0xe5,0xe1}, {0xe5,0xde}, {0xbc,0xcd}, {0x9b,0x4c}, {0xe5,0xe5}, {0xe5,0xd4}, {0xbc,0xd8}, - {0xe5,0xdb}, {0xe5,0xd0}, {0xe5,0xda}, {0xbc,0xd5}, {0xe5,0xee}, {0xe5,0xeb}, {0xe5,0xdd}, {0xe5,0xce}, {0xfd,0x57}, {0xfc,0xef}, - {0xe5,0xe2}, {0xe5,0xe4}, {0xbc,0xd1}, {0xe5,0xd8}, {0xe5,0xd3}, {0xe5,0xca}, {0xbc,0xce}, {0xbc,0xd6}, {0x9c,0xde}, {0xe5,0xe7}, - {0xbc,0xd7}, {0xe5,0xcb}, {0xe5,0xed}, {0xe5,0xe0}, {0xe5,0xe6}, {0xbc,0xd4}, {0xfd,0x42}, {0x98,0x6c}, {0xe5,0xe3}, {0xe5,0xea}, - {0xbc,0xd9}, {0xbc,0xd3}, {0xe5,0xdc}, {0xe5,0xcf}, {0xe5,0xef}, {0xe5,0xcc}, {0xe5,0xe8}, {0xbc,0xd0}, {0x97,0xf9}, {0xe5,0xd6}, - {0x95,0x58}, {0xe5,0xd7}, {0xbc,0xcf}, {0xbc,0xcc}, {0xe5,0xd2}, {0xbc,0xd2}, {0xbc,0xcb}, {0xe5,0xe9}, {0xe5,0xec}, {0xe5,0xd9}, - {0xe9,0xca}, {0x98,0x5e}, {0xfe,0x7b}, {0x94,0xcd}, {0xe9,0xc2}, {0x93,0xee}, {0xe9,0xbe}, {0xbe,0xf6}, {0xbe,0xeb}, {0xbe,0xf0}, - {0xbe,0xec}, {0xe9,0xcc}, {0xe9,0xd7}, {0xbe,0xea}, {0xe9,0xc4}, {0xe9,0xcd}, {0xe5,0xdf}, {0xe9,0xce}, {0x8c,0xa3}, {0xbe,0xf1}, - {0xfd,0x5a}, {0xe9,0xdd}, {0xbe,0xf5}, {0xbe,0xf8}, {0xe9,0xc0}, {0xbe,0xf4}, {0x93,0xf5}, {0xe9,0xdb}, {0xe9,0xdc}, {0xe9,0xd2}, - {0xe9,0xd1}, {0xe9,0xc9}, {0x93,0xef}, {0x8e,0xea}, {0xe9,0xd3}, {0xe9,0xda}, {0xe9,0xd9}, {0x8f,0x5b}, {0xbe,0xef}, {0xbe,0xed}, - {0xe9,0xcb}, {0xe9,0xc8}, {0xe9,0xc5}, {0xe9,0xd8}, {0xbe,0xf7}, {0xe9,0xd6}, {0xbe,0xf3}, {0xbe,0xf2}, {0x8c,0x5e}, {0xe9,0xd0}, - {0x8d,0xc6}, {0xe9,0xbf}, {0xe9,0xc1}, {0xe9,0xc3}, {0xe9,0xd5}, {0xe9,0xcf}, {0xbe,0xee}, {0xe9,0xc6}, {0xe9,0xd4}, {0x8d,0xc8}, - {0x8d,0xc7}, {0xe9,0xc7}, {0x93,0xf7}, {0xc0,0xcf}, {0xed,0x45}, {0xc0,0xc8}, {0xec,0xf5}, {0x8d,0xc9}, {0xed,0x41}, {0xc0,0xca}, - {0xed,0x48}, {0xec,0xfc}, {0xec,0xf7}, {0xfb,0xf2}, {0xed,0x49}, {0xec,0xf3}, {0xec,0xfe}, {0x96,0x70}, {0xc0,0xd1}, {0xed,0x44}, - {0xed,0x4a}, {0xec,0xfd}, {0xc0,0xc9}, {0xed,0x40}, {0xec,0xf4}, {0xc0,0xd0}, {0x8d,0xcb}, {0xed,0x47}, {0xec,0xf9}, {0xc0,0xcc}, - {0xfd,0x5c}, {0xec,0xfb}, {0xec,0xf8}, {0xc0,0xd2}, {0xec,0xfa}, {0xc0,0xcb}, {0xc0,0xce}, {0xed,0x43}, {0xec,0xf6}, {0xed,0x46}, - {0x8f,0x65}, {0xed,0x42}, {0x8d,0xcd}, {0xc2,0x63}, {0xef,0xe7}, {0xc2,0x68}, {0xc2,0x69}, {0x9d,0xa8}, {0x94,0xf9}, {0xc2,0x62}, - {0xef,0xe6}, {0x8d,0xce}, {0xef,0xe3}, {0xef,0xe4}, {0xc2,0x66}, {0xef,0xde}, {0xef,0xe2}, {0xc2,0x65}, {0xef,0xdf}, {0x93,0xea}, - {0xc2,0x67}, {0xc2,0x64}, {0xef,0xdd}, {0xef,0xe1}, {0xef,0xe5}, {0xfd,0x5f}, {0x93,0xf0}, {0x9f,0xb6}, {0xf2,0x51}, {0xf2,0x4e}, - {0xf2,0x57}, {0xf2,0x56}, {0xf2,0x54}, {0xf2,0x4f}, {0xc3,0x72}, {0x8d,0xcf}, {0x97,0x63}, {0xf2,0x50}, {0xc3,0x71}, {0xc0,0xcd}, - {0xf2,0x53}, {0xc3,0x70}, {0xf2,0x58}, {0xf2,0x52}, {0xf2,0x4d}, {0xef,0xe0}, {0xc3,0x6f}, {0xf2,0x4c}, {0xf4,0x56}, {0xf4,0x55}, - {0xf2,0x55}, {0xc4,0x68}, {0xf4,0x59}, {0xf4,0x5a}, {0xf4,0x54}, {0xf4,0x58}, {0xf4,0x53}, {0x8d,0xd0}, {0xf5,0xd1}, {0xf4,0x57}, - {0xc4,0xe7}, {0xc4,0xe5}, {0xf5,0xcf}, {0xf5,0xd2}, {0xf5,0xce}, {0xf5,0xd0}, {0xc4,0xe6}, {0x93,0xf1}, {0xf6,0xe5}, {0xf6,0xe6}, - {0xc5,0x76}, {0xf6,0xe4}, {0xf7,0xe2}, {0xc5,0xcf}, {0xf7,0xe0}, {0xf7,0xe1}, {0xf8,0xac}, {0xc6,0x56}, {0xf8,0xf3}, {0xf8,0xf1}, - {0xf8,0xf2}, {0xf8,0xf4}, {0xfd,0x62}, {0xf9,0xbb}, {0xa4,0xed}, {0xa6,0xb8}, {0xaa,0x59}, {0xcc,0xe9}, {0xcf,0x64}, {0xd1,0xf5}, - {0xd1,0xf7}, {0xd1,0xf6}, {0xd1,0xf8}, {0xb1,0xfd}, {0xd5,0xd7}, {0xd1,0xf9}, {0xfd,0x65}, {0xd5,0xd6}, {0xd5,0xd8}, {0xd5,0xd9}, - {0xd9,0xda}, {0xb4,0xdb}, {0xd9,0xdb}, {0xd9,0xdd}, {0xb4,0xdc}, {0xb4,0xda}, {0xd9,0xdc}, {0xdd,0xfa}, {0xdd,0xf8}, {0xdd,0xf7}, - {0xdd,0xf6}, {0xdd,0xf5}, {0xb7,0xb2}, {0xdd,0xf9}, {0xba,0x70}, {0xe2,0x63}, {0xe2,0x65}, {0xba,0x71}, {0xe2,0x64}, {0xbc,0xdb}, - {0xbc,0xda}, {0xe5,0xf0}, {0x9f,0xdb}, {0xe9,0xdf}, {0xe9,0xde}, {0xe9,0xe0}, {0x93,0xf8}, {0xbe,0xf9}, {0xed,0x4b}, {0xc0,0xd3}, - {0xef,0xe8}, {0xc2,0x6a}, {0xf2,0x59}, {0xc5,0x77}, {0xa4,0xee}, {0xa5,0xbf}, {0xa6,0xb9}, {0xa8,0x42}, {0xaa,0x5a}, {0xaa,0x5b}, - {0xac,0x6e}, {0xd1,0xfa}, {0x8b,0xf7}, {0xb7,0xb3}, {0xfd,0x66}, {0xe6,0xd1}, {0xbe,0xfa}, {0xc2,0x6b}, {0xa4,0xef}, {0x8b,0xcf}, - {0xa6,0xba}, {0xcc,0xeb}, {0xaa,0x5c}, {0xcc,0xea}, {0x8d,0xd1}, {0xcf,0x65}, {0xac,0x6f}, {0xcf,0x66}, {0xac,0x70}, {0xd1,0xfc}, - {0xae,0xee}, {0xae,0xed}, {0xd5,0xde}, {0xd5,0xdc}, {0xd5,0xdd}, {0xd5,0xdb}, {0xd5,0xda}, {0xd9,0xde}, {0xd9,0xe1}, {0xb4,0xde}, - {0xd9,0xdf}, {0xb4,0xdd}, {0xd9,0xe0}, {0xdd,0xfb}, {0xe2,0x66}, {0xe2,0x67}, {0xe2,0x68}, {0xe5,0xf3}, {0xe5,0xf2}, {0xbc,0xdc}, - {0xe5,0xf1}, {0xe5,0xf4}, {0xe9,0xe1}, {0xe9,0xe2}, {0xe9,0xe3}, {0xed,0x4c}, {0xc0,0xd4}, {0xc2,0x6c}, {0xf2,0x5a}, {0xc4,0xe8}, - {0xc9,0x5f}, {0xac,0x71}, {0xcf,0x67}, {0xae,0xef}, {0xb1,0xfe}, {0xb4,0xdf}, {0xd9,0xe2}, {0xb7,0xb5}, {0xb7,0xb4}, {0x8d,0xd2}, - {0xe2,0x69}, {0xe2,0x6a}, {0xbc,0xdd}, {0xbc,0xde}, {0xe9,0xe5}, {0xe9,0xe4}, {0xef,0xe9}, {0xf7,0xe3}, {0xa4,0xf0}, {0xc9,0x60}, - {0xa5,0xc0}, {0xa8,0x43}, {0xcb,0x48}, {0xac,0x72}, {0xb7,0xb6}, {0xa4,0xf1}, {0xcf,0x68}, {0xac,0x73}, {0xcf,0x69}, {0xc0,0xd5}, - {0xa4,0xf2}, {0xfd,0x71}, {0xcc,0xec}, {0xcf,0x6a}, {0xfd,0x6f}, {0xd2,0x42}, {0xd2,0x41}, {0xd1,0xfe}, {0xd1,0xfd}, {0xd2,0x43}, - {0xd2,0x40}, {0x8d,0xd3}, {0xb2,0x40}, {0xb2,0x41}, {0xb4,0xe0}, {0xd9,0xe3}, {0xd9,0xe4}, {0xd9,0xe5}, {0xde,0x41}, {0xde,0x42}, - {0xde,0x40}, {0x9f,0xe7}, {0xdd,0xfd}, {0xdd,0xfe}, {0xb7,0xb7}, {0xe2,0x6b}, {0xe5,0xf7}, {0xe5,0xf6}, {0xe5,0xf5}, {0xe5,0xf8}, - {0xe9,0xe7}, {0xe9,0xe6}, {0xbe,0xfb}, {0xe9,0xe8}, {0xc0,0xd6}, {0xed,0x4d}, {0xef,0xea}, {0xf2,0x5b}, {0xf6,0xe7}, {0xa4,0xf3}, - {0xa5,0xc2}, {0xa5,0xc1}, {0xaa,0x5d}, {0xc9,0x61}, {0xc9,0x7e}, {0xa6,0xbb}, {0xc9,0xf7}, {0xcb,0x49}, {0xcb,0x4a}, {0xaa,0x5e}, - {0x90,0xbd}, {0xcc,0xed}, {0xac,0x74}, {0xcf,0x6b}, {0xcf,0x6c}, {0xae,0xf0}, {0xae,0xf4}, {0xd2,0x44}, {0xae,0xf3}, {0xae,0xf1}, - {0xae,0xf2}, {0xd5,0xdf}, {0xb2,0x42}, {0xb4,0xe3}, {0xb4,0xe1}, {0xb4,0xe2}, {0xd9,0xe6}, {0x9f,0xd0}, {0xba,0x72}, {0xa4,0xf4}, - {0x8b,0xd0}, {0xc9,0xa1}, {0xfd,0x72}, {0xa5,0xc3}, {0x9c,0xae}, {0x8b,0xd1}, {0xc9,0xa4}, {0x8a,0xdb}, {0xa5,0xc6}, {0xc9,0xa3}, - {0xa5,0xc5}, {0xa5,0xc4}, {0xa8,0x44}, {0xc9,0xa2}, {0xc9,0xf8}, {0xfa,0xe4}, {0xc9,0xfc}, {0xc9,0xfe}, {0xca,0x40}, {0xa6,0xc5}, - {0xa6,0xc6}, {0xc9,0xfb}, {0xa6,0xc1}, {0xc9,0xf9}, {0xc9,0xfd}, {0xa6,0xc2}, {0xa6,0xbd}, {0x95,0xce}, {0xa6,0xbe}, {0xfd,0x76}, - {0xa6,0xc4}, {0xc9,0xfa}, {0xa6,0xbc}, {0xa8,0x45}, {0xa6,0xbf}, {0xa6,0xc0}, {0xa6,0xc3}, {0xcb,0x5b}, {0xcb,0x59}, {0xcb,0x4c}, - {0xa8,0x51}, {0xcb,0x53}, {0xa8,0x4c}, {0xcb,0x4d}, {0xcb,0x55}, {0xfb,0x62}, {0xcb,0x52}, {0xa8,0x4f}, {0xcb,0x51}, {0xa8,0x56}, - {0xcb,0x5a}, {0xa8,0x58}, {0x8d,0xd4}, {0xa8,0x5a}, {0xcb,0x4b}, {0xfd,0x78}, {0xa8,0x4d}, {0xcb,0x5c}, {0xa8,0x54}, {0xa8,0x57}, - {0x8e,0xe3}, {0xcd,0x45}, {0xa8,0x47}, {0xa8,0x5e}, {0xa8,0x55}, {0xcb,0x4e}, {0xa8,0x4a}, {0xa8,0x59}, {0xcb,0x56}, {0xa8,0x48}, - {0xa8,0x49}, {0xcd,0x43}, {0xcb,0x4f}, {0xa8,0x50}, {0xa8,0x5b}, {0xcb,0x5d}, {0xcb,0x50}, {0xa8,0x4e}, {0xa8,0x53}, {0xcc,0xee}, - {0xa8,0x5c}, {0xcb,0x57}, {0xa8,0x52}, {0xa8,0x5d}, {0xa8,0x46}, {0xcb,0x54}, {0xa8,0x4b}, {0xcb,0x58}, {0xcd,0x44}, {0x90,0x76}, - {0x98,0xc6}, {0x8d,0xd5}, {0xaa,0x6a}, {0xaa,0x7a}, {0xcc,0xf5}, {0xaa,0x71}, {0x97,0xd1}, {0xcd,0x4b}, {0xaa,0x62}, {0x9e,0xb6}, - {0xaa,0x65}, {0xcd,0x42}, {0xcc,0xf3}, {0xcc,0xf7}, {0xaa,0x6d}, {0xaa,0x6f}, {0xcc,0xfa}, {0xaa,0x76}, {0xaa,0x68}, {0xaa,0x66}, - {0xaa,0x67}, {0xaa,0x75}, {0xcd,0x47}, {0xaa,0x70}, {0xcc,0xf9}, {0xcc,0xfb}, {0xaa,0x6e}, {0xaa,0x73}, {0xcc,0xfc}, {0xcd,0x4a}, - {0xac,0x75}, {0xaa,0x79}, {0xfa,0xc7}, {0xaa,0x63}, {0xcd,0x49}, {0xa0,0x42}, {0xcd,0x4d}, {0xcc,0xf8}, {0xcd,0x4f}, {0xcd,0x40}, - {0xaa,0x6c}, {0xcc,0xf4}, {0xaa,0x6b}, {0xaa,0x7d}, {0xaa,0x72}, {0xcc,0xf2}, {0xcf,0x75}, {0xaa,0x78}, {0xaa,0x7c}, {0xcd,0x41}, - {0xcd,0x46}, {0x98,0x73}, {0xaa,0x7e}, {0xaa,0x77}, {0xaa,0x69}, {0xaa,0x5f}, {0xaa,0x64}, {0xcc,0xf6}, {0xaa,0x60}, {0xcd,0x4e}, - {0x9f,0xfc}, {0xcc,0xf0}, {0xcc,0xef}, {0xcc,0xfd}, {0xcc,0xf1}, {0xaa,0x7b}, {0xae,0xf5}, {0xaa,0x74}, {0xcc,0xfe}, {0xaa,0x61}, - {0xac,0xa6}, {0xcd,0x4c}, {0x8c,0xa5}, {0xcf,0x7c}, {0xcf,0xa1}, {0x8d,0xd7}, {0xcf,0xa4}, {0xcf,0x77}, {0x92,0xfb}, {0x8d,0xd8}, - {0xcf,0xa7}, {0xcf,0xaa}, {0xcf,0xac}, {0xcf,0x74}, {0xac,0x76}, {0xac,0x7b}, {0xd2,0x49}, {0xac,0xad}, {0xcf,0xa5}, {0xcf,0xad}, - {0xcf,0x7b}, {0xcf,0x73}, {0xd2,0x64}, {0xac,0x7e}, {0xcf,0xa2}, {0xcf,0x78}, {0xcf,0x7a}, {0xac,0xa5}, {0xcf,0x7d}, {0xac,0x7d}, - {0xcf,0x70}, {0xcf,0xa8}, {0xcf,0xab}, {0x94,0x4f}, {0xac,0x7a}, {0x8d,0xd9}, {0xac,0xa8}, {0xcf,0x6d}, {0xac,0xaa}, {0xac,0x78}, - {0xac,0xae}, {0xcf,0xa9}, {0xcf,0x6f}, {0xac,0xab}, {0xd2,0x5e}, {0xcd,0x48}, {0xac,0x7c}, {0xac,0x77}, {0xcf,0x76}, {0xcf,0x6e}, - {0xac,0xac}, {0xac,0xa4}, {0xcf,0xa3}, {0xac,0xa9}, {0xac,0xa7}, {0xcf,0x79}, {0xac,0xa1}, {0xcf,0x71}, {0xac,0xa2}, {0xac,0xa3}, - {0xcf,0x72}, {0xcf,0xa6}, {0xac,0x79}, {0xcf,0x7e}, {0x89,0x6b}, {0x97,0xce}, {0xd2,0x4c}, {0xae,0xfd}, {0xaf,0x43}, {0xfa,0xf3}, - {0xfd,0xae}, {0xd2,0x55}, {0xd2,0x5b}, {0xd2,0x57}, {0xd2,0x4a}, {0xd2,0x4d}, {0xd2,0x46}, {0xd2,0x47}, {0xaf,0x4a}, {0xae,0xfa}, - {0xd2,0x56}, {0xd2,0x5f}, {0xaf,0x45}, {0xae,0xf6}, {0xaf,0x40}, {0xd2,0x4e}, {0xaf,0x42}, {0xd2,0x4f}, {0xd2,0x59}, {0xfb,0xaf}, - {0x92,0xb7}, {0xaf,0x44}, {0xd2,0x68}, {0xd2,0x48}, {0xae,0xfc}, {0xae,0xfb}, {0xaf,0x48}, {0xd2,0x45}, {0xd2,0x66}, {0xd2,0x5a}, - {0xd2,0x67}, {0xd2,0x61}, {0xd2,0x53}, {0xd2,0x62}, {0x8d,0xda}, {0xd2,0x5c}, {0xd2,0x65}, {0xd2,0x63}, {0xaf,0x49}, {0xd2,0x54}, - {0xae,0xf9}, {0xae,0xf8}, {0xaf,0x41}, {0xaf,0x47}, {0xd2,0x60}, {0xaf,0x46}, {0xd2,0x51}, {0xb2,0x43}, {0x9c,0x5a}, {0xd2,0x69}, - {0xd2,0x50}, {0xd2,0x4b}, {0xae,0xfe}, {0xaf,0x4b}, {0xae,0xf7}, {0xfd,0xad}, {0xd2,0x58}, {0xd2,0x5d}, {0x8d,0xdc}, {0x94,0x44}, - {0xb2,0x65}, {0xd5,0xe1}, {0xd5,0xe5}, {0xb2,0x52}, {0xb2,0x50}, {0x8d,0xdd}, {0xb2,0x47}, {0xd5,0xe3}, {0xd5,0xe2}, {0xb2,0x5b}, - {0xd5,0xe8}, {0xb2,0x55}, {0xa0,0xd6}, {0xd5,0xfa}, {0xd6,0x47}, {0xb2,0x44}, {0xd5,0xf7}, {0xd5,0xf0}, {0xb2,0x67}, {0xd5,0xe0}, - {0xd5,0xfc}, {0xb2,0x64}, {0xb2,0x58}, {0xb2,0x63}, {0xb2,0x4e}, {0xd5,0xec}, {0xd5,0xfe}, {0xd5,0xf6}, {0xb2,0x4f}, {0xb2,0x49}, - {0xd6,0x45}, {0xd5,0xfd}, {0xd6,0x40}, {0xb2,0x51}, {0xb2,0x59}, {0xd6,0x42}, {0xd5,0xea}, {0xd5,0xfb}, {0xd5,0xef}, {0xd6,0x44}, - {0xb2,0x5e}, {0xb2,0x46}, {0xb2,0x5c}, {0xd5,0xf4}, {0xd5,0xf2}, {0xd5,0xf3}, {0xb2,0x53}, {0xd5,0xee}, {0xd5,0xed}, {0xb2,0x48}, - {0xd5,0xe7}, {0xd6,0x46}, {0xb2,0x4a}, {0xd5,0xf1}, {0xb2,0x68}, {0xb2,0x62}, {0xd5,0xe6}, {0xb2,0x5f}, {0xb2,0x5d}, {0xb2,0x66}, - {0xd5,0xf8}, {0xb2,0x61}, {0xd2,0x52}, {0xd5,0xf9}, {0xb2,0x60}, {0xd6,0x41}, {0xb2,0x45}, {0xd5,0xf5}, {0xb2,0x57}, {0xd5,0xe9}, - {0xb2,0x56}, {0xb2,0x54}, {0xb2,0x4c}, {0xb2,0x4b}, {0xd9,0xe7}, {0xd6,0x43}, {0x8c,0x41}, {0xd5,0xeb}, {0x97,0xd5}, {0xd9,0xfc}, - {0x94,0x4a}, {0xb2,0x4d}, {0x94,0x4d}, {0x97,0xcb}, {0x8d,0xde}, {0x8d,0xdf}, {0xb5,0x41}, {0xb2,0x5a}, {0xb4,0xee}, {0xd9,0xf6}, - {0xb4,0xfc}, {0xd9,0xea}, {0xb4,0xeb}, {0xb4,0xe7}, {0xda,0x49}, {0xb4,0xed}, {0xb4,0xf1}, {0xb4,0xec}, {0xb4,0xf5}, {0xda,0x4d}, - {0xda,0x44}, {0x8d,0xe0}, {0xfe,0xf9}, {0xd9,0xf1}, {0xb4,0xfa}, {0xb4,0xf4}, {0xd9,0xfd}, {0xb4,0xe4}, {0xda,0x4a}, {0xda,0x43}, - {0xb4,0xe8}, {0xd9,0xf7}, {0xb4,0xf7}, {0xda,0x55}, {0xda,0x56}, {0xb4,0xe5}, {0xda,0x48}, {0xb4,0xf9}, {0xd9,0xfb}, {0xd9,0xed}, - {0xd9,0xee}, {0xb4,0xfd}, {0xd9,0xf2}, {0xd9,0xf9}, {0xd9,0xf3}, {0xb4,0xfb}, {0xb5,0x44}, {0xd9,0xef}, {0xd9,0xe8}, {0xd9,0xe9}, - {0xd9,0xeb}, {0xb4,0xea}, {0xd9,0xf8}, {0xb4,0xf8}, {0xb5,0x42}, {0xfd,0xc0}, {0xfc,0xf9}, {0xd9,0xfa}, {0xda,0x53}, {0xda,0x4b}, - {0xb4,0xe6}, {0xda,0x51}, {0xb4,0xf2}, {0xb4,0xf0}, {0xfb,0x7e}, {0xda,0x57}, {0xb4,0xef}, {0xda,0x41}, {0xd9,0xf4}, {0xd9,0xfe}, - {0xb5,0x47}, {0xda,0x45}, {0xda,0x42}, {0xd9,0xf0}, {0xb5,0x43}, {0xda,0x4f}, {0xda,0x4c}, {0xda,0x54}, {0xb4,0xe9}, {0xda,0x40}, - {0xb5,0x46}, {0xda,0x47}, {0xb4,0xf3}, {0xb4,0xf6}, {0xda,0x46}, {0xb5,0x45}, {0xd9,0xf5}, {0xd5,0xe4}, {0x92,0xb3}, {0xda,0x50}, - {0xda,0x4e}, {0xda,0x52}, {0xfd,0xaf}, {0x8d,0xe1}, {0xd9,0xec}, {0xb5,0x40}, {0x95,0xd3}, {0xde,0x61}, {0xde,0x60}, {0xde,0x46}, - {0xb7,0xbd}, {0xde,0x5f}, {0xde,0x49}, {0xde,0x4a}, {0xb7,0xc7}, {0xde,0x68}, {0xb7,0xc2}, {0xde,0x5e}, {0x89,0xc1}, {0xde,0x43}, - {0xb7,0xc8}, {0xb7,0xbe}, {0xde,0x52}, {0xde,0x48}, {0xde,0x4b}, {0xde,0x63}, {0xb7,0xb8}, {0xde,0x6a}, {0xde,0x62}, {0xb7,0xc1}, - {0xde,0x57}, {0xb7,0xcc}, {0xb7,0xcb}, {0xb7,0xc5}, {0xde,0x69}, {0xb7,0xb9}, {0xde,0x55}, {0xde,0x4c}, {0xde,0x59}, {0xde,0x65}, - {0xb7,0xcd}, {0xfd,0x68}, {0xb7,0xbb}, {0xde,0x54}, {0x9c,0xb7}, {0xde,0x4d}, {0xb7,0xc4}, {0x8d,0xe3}, {0xb7,0xc3}, {0xde,0x50}, - {0xde,0x5a}, {0xde,0x64}, {0xde,0x47}, {0xde,0x51}, {0xb7,0xbc}, {0xde,0x5b}, {0xb7,0xc9}, {0xb7,0xc0}, {0xde,0x4e}, {0xb7,0xbf}, - {0xde,0x45}, {0xde,0x53}, {0xde,0x67}, {0xb4,0xfe}, {0xba,0xb0}, {0xde,0x56}, {0xe2,0x6c}, {0xde,0x58}, {0xde,0x66}, {0xb7,0xc6}, - {0xde,0x4f}, {0xb7,0xba}, {0xb7,0xca}, {0xbc,0xf0}, {0xde,0x44}, {0xde,0x5d}, {0xfa,0xc0}, {0x8d,0xe5}, {0xfa,0x64}, {0xde,0x5c}, - {0x89,0x47}, {0x8d,0xe4}, {0x8d,0xe7}, {0x8d,0xe8}, {0xe2,0xaa}, {0xba,0xad}, {0xe2,0x7d}, {0xe2,0xa4}, {0xba,0xa2}, {0xe2,0x6e}, - {0xba,0xaf}, {0xba,0x77}, {0xe2,0x6d}, {0xe2,0xb0}, {0xba,0xb1}, {0xe2,0x71}, {0xe2,0xa3}, {0xfd,0xc7}, {0xe2,0x73}, {0xe2,0xb3}, - {0xe2,0xaf}, {0xba,0x75}, {0xba,0xa1}, {0xe6,0x53}, {0xba,0xae}, {0xba,0x7d}, {0xe2,0x6f}, {0xfd,0xb0}, {0xe2,0xae}, {0xba,0xa3}, - {0xe2,0xab}, {0xe2,0xb8}, {0xe2,0x75}, {0xe2,0x7e}, {0x94,0x45}, {0x97,0xd6}, {0xe2,0xb6}, {0xe2,0xac}, {0xba,0x7c}, {0xe2,0x7c}, - {0xba,0x76}, {0xba,0x74}, {0xba,0xa8}, {0xfc,0xc6}, {0x98,0x44}, {0xe2,0x7a}, {0xe2,0x77}, {0xe2,0x78}, {0xe2,0xb2}, {0xe2,0xb7}, - {0xe2,0xb5}, {0xba,0x7a}, {0xe2,0xb9}, {0xba,0x7e}, {0xba,0xa7}, {0x8d,0xe9}, {0xe2,0x70}, {0xe5,0xfa}, {0xe2,0x79}, {0xba,0x78}, - {0xba,0xac}, {0xba,0xa9}, {0xba,0x7b}, {0xe2,0xa5}, {0xe2,0x74}, {0xba,0xaa}, {0xe2,0xa7}, {0xba,0xa4}, {0xba,0xa6}, {0xba,0x73}, - {0x8d,0xea}, {0xe2,0xa9}, {0xe2,0xa1}, {0xe2,0x72}, {0xba,0xa5}, {0xe2,0xb1}, {0xe2,0xb4}, {0xe2,0x7b}, {0xe2,0xa8}, {0xfe,0x50}, - {0xba,0x79}, {0xbc,0xdf}, {0xe2,0xa6}, {0xe5,0xf9}, {0xe2,0xad}, {0xfd,0xcc}, {0xe2,0x76}, {0xe6,0x44}, {0xe6,0x4e}, {0xbc,0xe2}, - {0xe6,0x4d}, {0xe6,0x59}, {0xbc,0xe4}, {0xe6,0x4b}, {0x9d,0xa7}, {0xe6,0x4f}, {0xbc,0xef}, {0xe6,0x46}, {0xbc,0xe7}, {0xfd,0xcd}, - {0xe6,0x52}, {0xe9,0xf0}, {0xbc,0xf3}, {0xbc,0xf2}, {0xe6,0x54}, {0xe6,0x43}, {0xe6,0x5e}, {0xbc,0xed}, {0xbc,0xe3}, {0xe6,0x57}, - {0xe6,0x5b}, {0xe6,0x60}, {0xe6,0x55}, {0xe6,0x49}, {0xbc,0xe6}, {0xbc,0xe9}, {0xbc,0xf1}, {0xbc,0xec}, {0xe6,0x4c}, {0xe2,0xa2}, - {0xfd,0xcf}, {0xe6,0x48}, {0xe6,0x5f}, {0xbc,0xe8}, {0x95,0xd2}, {0xbc,0xeb}, {0xe6,0x61}, {0xbc,0xe0}, {0xe6,0x56}, {0xe5,0xfb}, - {0xe6,0x5c}, {0xc0,0xdf}, {0x8d,0xed}, {0xe6,0x4a}, {0xbc,0xe1}, {0xe6,0x45}, {0xbc,0xe5}, {0xe5,0xfc}, {0xba,0xab}, {0xe6,0x41}, - {0xfc,0xba}, {0xe6,0x5a}, {0xe6,0x42}, {0xe6,0x40}, {0xbc,0xea}, {0xe6,0x58}, {0xe5,0xfe}, {0xe6,0x51}, {0xe6,0x50}, {0xe6,0x5d}, - {0xe6,0x47}, {0xbc,0xee}, {0xfd,0xc5}, {0xe9,0xf3}, {0xfd,0xd2}, {0xbf,0x49}, {0xbe,0xfe}, {0xea,0x40}, {0xe9,0xeb}, {0xbf,0x41}, - {0xe9,0xf7}, {0xbf,0x48}, {0xbf,0x43}, {0xe9,0xf5}, {0xed,0x4f}, {0xe9,0xfb}, {0xea,0x42}, {0xe9,0xfa}, {0xe9,0xe9}, {0xe9,0xf8}, - {0xea,0x44}, {0xea,0x46}, {0xbe,0xfd}, {0xea,0x45}, {0xbf,0x44}, {0xbf,0x4a}, {0x9c,0xdc}, {0xbf,0x47}, {0xe9,0xfe}, {0xbf,0x46}, - {0xe9,0xf9}, {0x95,0xcf}, {0xe9,0xed}, {0xe9,0xf2}, {0x8d,0xee}, {0xe9,0xfd}, {0xbf,0x45}, {0xbf,0x42}, {0xbe,0xfc}, {0xbf,0x40}, - {0xe9,0xf1}, {0xe5,0xfd}, {0xe9,0xec}, {0xe9,0xef}, {0xea,0x41}, {0xe9,0xf4}, {0xe9,0xea}, {0xed,0x4e}, {0xea,0x43}, {0xe9,0xee}, - {0xe9,0xfc}, {0xfd,0xd4}, {0xed,0x51}, {0xc0,0xe3}, {0xc0,0xd7}, {0x96,0xec}, {0x96,0xeb}, {0xc0,0xdb}, {0xed,0x53}, {0xed,0x59}, - {0xed,0x57}, {0xc0,0xd9}, {0xc0,0xda}, {0xc0,0xe1}, {0xed,0x5a}, {0xed,0x52}, {0xc0,0xdc}, {0xed,0x56}, {0xed,0x55}, {0xed,0x5b}, - {0xc0,0xe2}, {0xc0,0xdd}, {0xc0,0xe0}, {0xed,0x54}, {0xc0,0xe4}, {0xc0,0xde}, {0xc0,0xe5}, {0xc0,0xd8}, {0xed,0x58}, {0xed,0x50}, - {0x90,0xb6}, {0xef,0xf7}, {0xfd,0xc3}, {0xc2,0x71}, {0xef,0xf4}, {0xef,0xf6}, {0xc2,0x6f}, {0xef,0xf2}, {0xef,0xf3}, {0xef,0xee}, - {0x98,0xab}, {0xe9,0xf6}, {0xef,0xef}, {0xc2,0x70}, {0xef,0xeb}, {0xc2,0x6d}, {0xef,0xf8}, {0xc2,0x6e}, {0xef,0xec}, {0xef,0xed}, - {0xef,0xf1}, {0xc2,0x73}, {0xc2,0x72}, {0xef,0xf0}, {0xc3,0x78}, {0xf2,0x5f}, {0xf2,0x65}, {0xc3,0x79}, {0xf2,0x5c}, {0xc3,0x76}, - {0xc3,0x73}, {0xf2,0x67}, {0xc3,0x77}, {0x96,0xee}, {0xc3,0x74}, {0xf2,0x5e}, {0xf2,0x61}, {0xf2,0x62}, {0xf2,0x63}, {0xf2,0x66}, - {0xef,0xf5}, {0xf2,0x5d}, {0xc3,0x75}, {0xf2,0x64}, {0xf2,0x68}, {0xf2,0x60}, {0x8d,0xf4}, {0xf4,0x5d}, {0xc4,0x6a}, {0xf4,0x60}, - {0xc4,0x6b}, {0xf4,0x68}, {0xf4,0x5f}, {0xf4,0x5c}, {0xf4,0x5e}, {0xf4,0x62}, {0xf4,0x65}, {0xf4,0x64}, {0xf4,0x67}, {0xf4,0x5b}, - {0xc4,0x69}, {0xf4,0x63}, {0xf4,0x66}, {0xf4,0x69}, {0xf4,0x61}, {0xf5,0xd3}, {0xf5,0xd4}, {0xf5,0xd8}, {0xf5,0xd9}, {0xf5,0xd6}, - {0xf5,0xd7}, {0xf5,0xd5}, {0xfd,0xe0}, {0xc4,0xe9}, {0x8c,0x67}, {0x8d,0xf6}, {0xc5,0x78}, {0xf6,0xeb}, {0x8d,0xf7}, {0xf6,0xe8}, - {0xf6,0xe9}, {0xf6,0xea}, {0xc5,0x79}, {0xf7,0xe5}, {0xf7,0xe4}, {0x8f,0xfa}, {0xf8,0xaf}, {0xc5,0xf4}, {0xf8,0xad}, {0xf8,0xb0}, - {0xf8,0xae}, {0xf8,0xf5}, {0xc6,0x57}, {0xc6,0x65}, {0xf9,0xa3}, {0xf9,0x6c}, {0x97,0xd0}, {0xf9,0xa2}, {0xf9,0xd0}, {0xf9,0xd1}, - {0xa4,0xf5}, {0x8b,0xd2}, {0x8d,0xf8}, {0xa6,0xc7}, {0xca,0x41}, {0xcb,0x5e}, {0x90,0xd9}, {0xa8,0x5f}, {0x8c,0x47}, {0xa8,0x62}, - {0xfa,0xf0}, {0xcb,0x5f}, {0xa8,0x60}, {0xa8,0x61}, {0xfd,0xe1}, {0x8d,0xf9}, {0xfd,0xe3}, {0xcd,0x58}, {0xcd,0x5a}, {0xcd,0x55}, - {0xcd,0x52}, {0xcd,0x54}, {0x8d,0xfa}, {0xaa,0xa4}, {0xfb,0x63}, {0xaa,0xa2}, {0x90,0xa6}, {0xcd,0x56}, {0xaa,0xa3}, {0xcd,0x53}, - {0xcd,0x50}, {0xaa,0xa1}, {0xcd,0x57}, {0xcd,0x51}, {0xaa,0xa5}, {0xcd,0x59}, {0xcf,0xaf}, {0x99,0x70}, {0xcf,0xb3}, {0x91,0xeb}, - {0xac,0xb7}, {0x97,0x70}, {0x98,0x6f}, {0xfd,0xe2}, {0xcf,0xb6}, {0xac,0xaf}, {0xac,0xb2}, {0xac,0xb4}, {0xac,0xb6}, {0xac,0xb3}, - {0xcf,0xb2}, {0xcf,0xb1}, {0xac,0xb1}, {0xcf,0xb4}, {0xcf,0xb5}, {0xcf,0xae}, {0xac,0xb5}, {0x98,0xf2}, {0xac,0xb0}, {0x9a,0xfc}, - {0x89,0x6c}, {0xfd,0xfd}, {0xcf,0xb0}, {0x99,0x5e}, {0x95,0xbd}, {0xd2,0x77}, {0xd2,0x78}, {0xd2,0x79}, {0xaf,0x50}, {0xaf,0x4c}, - {0xd2,0x6e}, {0xfd,0xe4}, {0xd2,0x76}, {0xd2,0x7b}, {0xaf,0x51}, {0x91,0xe6}, {0xd2,0x6c}, {0xd2,0x72}, {0xd2,0x6b}, {0xd2,0x75}, - {0xfd,0xe5}, {0xfd,0xe6}, {0xd2,0x71}, {0xaf,0x4d}, {0xaf,0x4f}, {0xd2,0x7a}, {0xd2,0x6a}, {0xd2,0x6d}, {0xd2,0x73}, {0xfd,0xe7}, - {0xd2,0x74}, {0xd2,0x7c}, {0xd2,0x70}, {0xaf,0x4e}, {0xb2,0x6d}, {0xd6,0x4e}, {0x94,0x54}, {0xd6,0x50}, {0xd6,0x4c}, {0x99,0xb8}, - {0xd6,0x58}, {0xd6,0x4a}, {0xd6,0x57}, {0xb2,0x69}, {0xd6,0x48}, {0xda,0x5b}, {0xd6,0x52}, {0xb2,0x6c}, {0x97,0xe9}, {0xd6,0x53}, - {0xd6,0x56}, {0xd6,0x5a}, {0xd6,0x4f}, {0x93,0x46}, {0xd6,0x54}, {0xb2,0x6a}, {0xb2,0x6b}, {0xd6,0x59}, {0xd6,0x4d}, {0xd6,0x49}, - {0xd6,0x5b}, {0xd6,0x51}, {0xd6,0x55}, {0xd6,0x4b}, {0xb5,0x48}, {0xb5,0x49}, {0xda,0x65}, {0xb5,0x4f}, {0x98,0x63}, {0xda,0x59}, - {0xda,0x62}, {0xda,0x58}, {0xb5,0x4c}, {0xda,0x60}, {0xda,0x5e}, {0xda,0x5f}, {0xb5,0x4a}, {0xda,0x63}, {0x95,0xbc}, {0xfd,0xed}, - {0xfd,0xf7}, {0xda,0x5c}, {0xda,0x5a}, {0xb5,0x4b}, {0xda,0x5d}, {0xda,0x61}, {0x98,0x70}, {0x96,0xf6}, {0x8e,0xa9}, {0xb5,0x4d}, - {0xda,0x64}, {0x94,0x51}, {0x8e,0x43}, {0x8b,0x5a}, {0xde,0x70}, {0xde,0x77}, {0xde,0x79}, {0xde,0xa1}, {0xfd,0xee}, {0xb7,0xda}, - {0xde,0x6b}, {0xb7,0xd2}, {0xfd,0xf0}, {0xde,0x7a}, {0xb7,0xd7}, {0xde,0xa2}, {0xb7,0xce}, {0xfd,0xf4}, {0xde,0x7d}, {0x9b,0xf5}, - {0xde,0x6d}, {0xde,0x7e}, {0xde,0x6c}, {0xb7,0xdc}, {0xde,0x78}, {0xb7,0xcf}, {0xde,0xa3}, {0xb7,0xd4}, {0xde,0x71}, {0xb7,0xd9}, - {0xde,0x7c}, {0xde,0x6f}, {0xde,0x76}, {0xde,0x72}, {0xde,0x6e}, {0xb7,0xd1}, {0xb7,0xd8}, {0xb7,0xd6}, {0xb7,0xd3}, {0xb7,0xdb}, - {0xb7,0xd0}, {0xde,0x75}, {0x97,0x7e}, {0xb7,0xd5}, {0xb5,0x4e}, {0xde,0x7b}, {0x9b,0xd5}, {0xde,0x73}, {0x9a,0xc3}, {0x97,0xc8}, - {0xa0,0xdb}, {0x91,0xd0}, {0xde,0x74}, {0x9f,0xe4}, {0xe2,0xc1}, {0x8f,0xdd}, {0xba,0xb4}, {0x91,0xe9}, {0xe2,0xbd}, {0xe2,0xc3}, - {0xe2,0xbf}, {0xba,0xb6}, {0xe2,0xbe}, {0xe2,0xc2}, {0xe2,0xba}, {0x98,0xe0}, {0xe2,0xbc}, {0xba,0xb5}, {0x92,0xca}, {0x98,0x57}, - {0xe2,0xc0}, {0xe2,0xbb}, {0x8c,0x51}, {0xba,0xb7}, {0xba,0xb2}, {0xfd,0xeb}, {0xe2,0xc4}, {0x9b,0x49}, {0xba,0xb3}, {0xe6,0x67}, - {0xe6,0x64}, {0xe6,0x70}, {0xe6,0x6a}, {0xe6,0x6c}, {0xbc,0xf4}, {0xe6,0x66}, {0xe6,0x6e}, {0x9d,0x76}, {0x9e,0xaf}, {0xe6,0x6d}, - {0xe6,0x6b}, {0xe6,0x71}, {0xbc,0xf7}, {0xe6,0x68}, {0xe6,0x6f}, {0xbc,0xf5}, {0x9c,0xcc}, {0xe6,0x63}, {0xe6,0x65}, {0xbc,0xf6}, - {0xe6,0x62}, {0xe6,0x72}, {0xfd,0xea}, {0xe6,0x69}, {0x8d,0xf1}, {0xea,0x4a}, {0xbf,0x51}, {0xfd,0xfb}, {0xea,0x55}, {0xea,0x53}, - {0xbf,0x4b}, {0xea,0x49}, {0xea,0x4c}, {0xea,0x4d}, {0xea,0x48}, {0xbf,0x55}, {0xbf,0x56}, {0xea,0x47}, {0xea,0x56}, {0xea,0x51}, - {0xbf,0x4f}, {0xbf,0x4c}, {0xea,0x50}, {0xea,0x4e}, {0xbf,0x52}, {0xea,0x52}, {0xbf,0x4d}, {0x8e,0x53}, {0xbf,0x4e}, {0xea,0x4f}, - {0xbf,0x50}, {0xea,0x4b}, {0xea,0x54}, {0xbf,0x53}, {0xea,0x57}, {0xea,0x58}, {0xbf,0x54}, {0xfa,0xcf}, {0xc0,0xe7}, {0xc0,0xee}, - {0xed,0x5c}, {0xed,0x62}, {0xed,0x60}, {0xc0,0xea}, {0xc0,0xe9}, {0xc0,0xe6}, {0xed,0x5e}, {0x96,0xf9}, {0xc0,0xec}, {0xc0,0xeb}, - {0xc0,0xe8}, {0xed,0x61}, {0xed,0x5d}, {0xed,0x5f}, {0xc0,0xed}, {0x98,0xbf}, {0x9e,0x49}, {0xc2,0x77}, {0xef,0xfb}, {0xc2,0x74}, - {0xc2,0x75}, {0xef,0xfd}, {0xc2,0x76}, {0xef,0xfa}, {0x8c,0xa7}, {0xef,0xf9}, {0xf2,0x6c}, {0xef,0xfc}, {0xf2,0x6d}, {0xc3,0x7a}, - {0xf2,0x6b}, {0x9b,0xca}, {0xf2,0x6a}, {0xf2,0x69}, {0xc3,0x7b}, {0xfd,0xfe}, {0x92,0xdc}, {0xc4,0x6c}, {0xf4,0x6a}, {0xf4,0x6b}, - {0xfe,0x41}, {0x91,0xcc}, {0x91,0xe2}, {0xf5,0xdc}, {0xf5,0xdb}, {0xc4,0xea}, {0xf5,0xda}, {0xf6,0xec}, {0xf6,0xed}, {0xf7,0xe6}, - {0xf8,0xb1}, {0xfe,0x44}, {0xf8,0xf6}, {0xf9,0xbc}, {0xc6,0x79}, {0xf9,0xc6}, {0xa4,0xf6}, {0x8b,0xd3}, {0xaa,0xa6}, {0xaa,0xa7}, - {0xfe,0x47}, {0xac,0xb8}, {0xc0,0xef}, {0xa4,0xf7}, {0xaa,0xa8}, {0xaf,0x52}, {0xb7,0xdd}, {0xa4,0xf8}, {0xb2,0x6e}, {0xba,0xb8}, - {0xc9,0x62}, {0xfe,0x48}, {0xcf,0xb7}, {0xd2,0x7d}, {0xe2,0xc5}, {0xc0,0xf0}, {0xa4,0xf9}, {0xaa,0xa9}, {0xcf,0xb8}, {0xcf,0xb9}, - {0xda,0x66}, {0xb5,0x50}, {0xde,0xa4}, {0x94,0x55}, {0xb7,0xde}, {0xe2,0xc6}, {0xfe,0x4b}, {0xbc,0xf8}, {0xfe,0x4c}, {0xc3,0x7c}, - {0xa4,0xfa}, {0xda,0x67}, {0xa4,0xfb}, {0x8d,0xbf}, {0xa6,0xc9}, {0xca,0x42}, {0xa6,0xc8}, {0xa8,0x65}, {0xa8,0x64}, {0xa8,0x63}, - {0xcb,0x60}, {0x9e,0x78}, {0xaa,0xaa}, {0xaa,0xab}, {0xcd,0x5b}, {0xcf,0xba}, {0xcf,0xbd}, {0xac,0xba}, {0xcf,0xbb}, {0xac,0xb9}, - {0xcf,0xbc}, {0xac,0xbb}, {0xd2,0xa2}, {0xd2,0xa1}, {0xd2,0x7e}, {0xaf,0x53}, {0xd6,0x5d}, {0xd6,0x5e}, {0xb2,0x6f}, {0xd6,0x5c}, - {0xd6,0x5f}, {0xb5,0x52}, {0xb2,0x70}, {0xfe,0x51}, {0xb5,0x51}, {0xda,0x6b}, {0xda,0x6a}, {0x94,0x56}, {0xda,0x68}, {0xda,0x69}, - {0xda,0x6c}, {0xde,0xa6}, {0xde,0xa5}, {0xde,0xa9}, {0x9d,0x61}, {0xde,0xa8}, {0xde,0xa7}, {0xba,0xb9}, {0xe2,0xc9}, {0x94,0x57}, - {0xe2,0xc8}, {0xba,0xba}, {0xe2,0xc7}, {0xe6,0x73}, {0xe6,0x74}, {0xbc,0xf9}, {0xea,0x59}, {0xea,0x5a}, {0x99,0x66}, {0xf2,0x72}, - {0xc3,0x7d}, {0xf2,0x71}, {0xf2,0x70}, {0xf2,0x6e}, {0xf2,0x6f}, {0xc4,0xeb}, {0xf4,0x6c}, {0xf6,0xee}, {0xf8,0xf7}, {0xa4,0xfc}, - {0x8b,0xd5}, {0xc9,0xa5}, {0xa5,0xc7}, {0xc9,0xa6}, {0xa0,0x69}, {0xca,0x43}, {0xca,0x44}, {0xcb,0x66}, {0xcb,0x62}, {0xcb,0x61}, - {0xaa,0xac}, {0xcb,0x65}, {0xa8,0x67}, {0xcb,0x63}, {0xa8,0x66}, {0xcb,0x67}, {0xcb,0x64}, {0xcd,0x5f}, {0xcf,0xbe}, {0xcd,0x5d}, - {0xcd,0x64}, {0x98,0xb4}, {0xaa,0xad}, {0xaa,0xb0}, {0xcd,0x65}, {0xcd,0x61}, {0xcd,0x62}, {0xcd,0x5c}, {0xaa,0xaf}, {0xcd,0x5e}, - {0xaa,0xae}, {0xcd,0x63}, {0xcd,0x60}, {0xcf,0xc2}, {0xac,0xbd}, {0xac,0xbe}, {0xa0,0x49}, {0xcf,0xc5}, {0xcf,0xbf}, {0xcf,0xc4}, - {0xcf,0xc0}, {0xac,0xbc}, {0xcf,0xc3}, {0xcf,0xc1}, {0xd2,0xa8}, {0xd2,0xa5}, {0xd2,0xa7}, {0xaf,0x58}, {0xaf,0x57}, {0xaf,0x55}, - {0xd2,0xa4}, {0xd2,0xa9}, {0xaf,0x54}, {0xaf,0x56}, {0xd2,0xa6}, {0xd6,0x67}, {0xd2,0xa3}, {0xd2,0xaa}, {0xa0,0x4c}, {0x9e,0x65}, - {0xd6,0x62}, {0xd6,0x66}, {0xd6,0x65}, {0xda,0x6e}, {0xda,0x79}, {0xd6,0x68}, {0x98,0xb5}, {0xd6,0x63}, {0xda,0x6d}, {0xb2,0x74}, - {0xb2,0x73}, {0xd6,0x61}, {0xd6,0x64}, {0xb2,0x75}, {0xb2,0x72}, {0xb2,0x71}, {0xd6,0x60}, {0xd6,0x69}, {0xda,0x70}, {0xda,0x77}, - {0xb5,0x54}, {0xda,0x76}, {0xda,0x73}, {0xfe,0x58}, {0xb5,0x56}, {0x99,0x75}, {0xfe,0x53}, {0xa0,0x65}, {0xda,0x75}, {0xfe,0x59}, - {0xda,0x6f}, {0xda,0x71}, {0xda,0x74}, {0xda,0x72}, {0xb5,0x55}, {0xda,0x78}, {0xb5,0x53}, {0xb7,0xdf}, {0x98,0xb7}, {0x98,0xb8}, - {0xde,0xad}, {0xde,0xac}, {0xde,0xaa}, {0xb7,0xe2}, {0xb7,0xe1}, {0xde,0xae}, {0x98,0xba}, {0xde,0xab}, {0xe2,0xca}, {0xba,0xbb}, - {0xb7,0xe0}, {0x98,0xbb}, {0xde,0xb0}, {0xde,0xaf}, {0xe2,0xcd}, {0xe2,0xcb}, {0xbc,0xfa}, {0x9f,0xbc}, {0xba,0xbc}, {0xe2,0xcc}, - {0xe6,0x76}, {0xbc,0xfb}, {0xe6,0x75}, {0xe6,0x7e}, {0xe6,0x7d}, {0xe6,0x7b}, {0xe6,0x7a}, {0xe6,0x77}, {0xe6,0x78}, {0xe6,0x79}, - {0xe6,0x7c}, {0xe6,0xa1}, {0xea,0x5f}, {0xea,0x5c}, {0xea,0x5d}, {0xbf,0x57}, {0xea,0x5b}, {0xea,0x61}, {0xea,0x60}, {0xea,0x5e}, - {0xed,0x64}, {0xed,0x65}, {0xc0,0xf1}, {0xa0,0x4a}, {0xc0,0xf2}, {0xed,0x63}, {0x9e,0xc7}, {0xc2,0x79}, {0xef,0xfe}, {0xc2,0x78}, - {0xc3,0x7e}, {0xc3,0xa1}, {0xc4,0x6d}, {0xf4,0x6e}, {0xf4,0x6d}, {0xf5,0xdd}, {0xf6,0xef}, {0xc5,0x7a}, {0xf7,0xe8}, {0xf7,0xe7}, - {0xf7,0xe9}, {0xa5,0xc8}, {0xcf,0xc6}, {0xaf,0x59}, {0xb2,0x76}, {0xd6,0x6a}, {0xa5,0xc9}, {0xc9,0xa7}, {0xa4,0xfd}, {0x8c,0xa9}, - {0xca,0x45}, {0x98,0xae}, {0xcb,0x6c}, {0xcb,0x6a}, {0xcb,0x6b}, {0xcb,0x68}, {0xa8,0x68}, {0xcb,0x69}, {0x92,0xd6}, {0xfa,0xe1}, - {0xcd,0x6d}, {0x91,0xd4}, {0xaa,0xb3}, {0xcd,0x6b}, {0xcd,0x67}, {0xcd,0x6a}, {0xcd,0x66}, {0xaa,0xb5}, {0xcd,0x69}, {0xfa,0xde}, - {0xaa,0xb2}, {0xaa,0xb1}, {0xfe,0x5b}, {0xaa,0xb4}, {0xcd,0x6c}, {0xcd,0x68}, {0xac,0xc2}, {0xac,0xc5}, {0xcf,0xce}, {0xcf,0xcd}, - {0xcf,0xcc}, {0xac,0xbf}, {0xcf,0xd5}, {0xcf,0xcb}, {0x8c,0x53}, {0xac,0xc1}, {0xd2,0xaf}, {0xcf,0xd2}, {0xcf,0xd0}, {0xac,0xc4}, - {0xcf,0xc8}, {0xcf,0xd3}, {0xcf,0xca}, {0xcf,0xd4}, {0xcf,0xd1}, {0xcf,0xc9}, {0xfe,0x5e}, {0xac,0xc0}, {0xcf,0xd6}, {0xcf,0xc7}, - {0xac,0xc3}, {0xfb,0xd7}, {0xfe,0x5a}, {0x94,0xc5}, {0xd2,0xb4}, {0xd2,0xab}, {0xd2,0xb6}, {0xfa,0xca}, {0xd2,0xae}, {0xd2,0xb9}, - {0xd2,0xba}, {0xd2,0xac}, {0xd2,0xb8}, {0xd2,0xb5}, {0xd2,0xb3}, {0xd2,0xb7}, {0xaf,0x5f}, {0xaf,0x5d}, {0x98,0xc1}, {0x97,0x5c}, - {0xd2,0xb1}, {0xfe,0x74}, {0xd2,0xad}, {0x97,0x73}, {0xd2,0xb0}, {0xd2,0xbb}, {0xd2,0xb2}, {0xaf,0x5e}, {0xcf,0xcf}, {0xaf,0x5a}, - {0xaf,0x5c}, {0xfa,0x46}, {0x97,0x64}, {0xd6,0x78}, {0xd6,0x6d}, {0xd6,0x6b}, {0xfe,0x68}, {0xd6,0x6c}, {0x96,0x4e}, {0xd6,0x73}, - {0x97,0x65}, {0xd6,0x74}, {0xd6,0x70}, {0xb2,0x7b}, {0xd6,0x75}, {0xd6,0x72}, {0xd6,0x6f}, {0x8c,0x5a}, {0xb2,0x79}, {0xd6,0x6e}, - {0xb2,0x77}, {0xb2,0x7a}, {0xd6,0x71}, {0xd6,0x79}, {0xaf,0x5b}, {0xb2,0x78}, {0xd6,0x77}, {0xd6,0x76}, {0xb2,0x7c}, {0x89,0xa1}, - {0x95,0xfa}, {0x92,0xd4}, {0xfe,0x69}, {0xda,0x7e}, {0xfb,0x45}, {0x98,0xc8}, {0xda,0xa1}, {0xb5,0x60}, {0x90,0xef}, {0xda,0xa7}, - {0x98,0xc9}, {0x98,0xca}, {0xda,0xa9}, {0xda,0xa2}, {0xb5,0x5a}, {0xda,0xa6}, {0xda,0xa5}, {0xb5,0x5b}, {0xb5,0x61}, {0xb5,0x62}, - {0xda,0xa8}, {0xb5,0x58}, {0xda,0x7d}, {0xda,0x7b}, {0xda,0xa3}, {0xda,0x7a}, {0xb5,0x5f}, {0xda,0x7c}, {0xda,0xa4}, {0xda,0xaa}, - {0xb5,0x59}, {0xb5,0x5e}, {0xb5,0x5c}, {0xb5,0x5d}, {0x94,0x6d}, {0x94,0xb7}, {0xfe,0x6c}, {0xb5,0x57}, {0x94,0x6b}, {0xb7,0xe9}, - {0xde,0xb7}, {0xb7,0xe8}, {0xde,0xbb}, {0x92,0xfc}, {0xde,0xb1}, {0x95,0xeb}, {0xde,0xbc}, {0xfe,0x73}, {0x97,0x6e}, {0xfe,0x5f}, - {0xde,0xb2}, {0xde,0xb3}, {0xde,0xbd}, {0xde,0xba}, {0xde,0xb8}, {0xde,0xb9}, {0xde,0xb5}, {0xde,0xb4}, {0xfd,0xbd}, {0xde,0xbe}, - {0xb7,0xe5}, {0x92,0xd5}, {0xde,0xb6}, {0xb7,0xea}, {0xb7,0xe4}, {0xb7,0xeb}, {0xb7,0xec}, {0xfe,0xb9}, {0xb7,0xe7}, {0xb7,0xe6}, - {0xfe,0x71}, {0xe2,0xce}, {0xba,0xbe}, {0xba,0xbd}, {0xfb,0xbb}, {0xe2,0xd3}, {0x94,0x7a}, {0xbc,0xfc}, {0xba,0xbf}, {0x95,0xfb}, - {0xfe,0x77}, {0xba,0xc1}, {0xe2,0xd4}, {0xb7,0xe3}, {0xba,0xc0}, {0xe2,0xd0}, {0xe2,0xd2}, {0xe2,0xcf}, {0xfe,0x79}, {0xe2,0xd1}, - {0xfe,0x75}, {0xe6,0xab}, {0x94,0x5d}, {0xe6,0xaa}, {0xe6,0xa7}, {0xbd,0x40}, {0xea,0x62}, {0xbd,0x41}, {0xe6,0xa6}, {0xfe,0x7c}, - {0xbc,0xfe}, {0xe6,0xa8}, {0xe6,0xa5}, {0xe6,0xa2}, {0xe6,0xa9}, {0xe6,0xa3}, {0xe6,0xa4}, {0xbc,0xfd}, {0x93,0x44}, {0x8e,0xa6}, - {0xed,0x69}, {0xea,0x66}, {0xea,0x65}, {0xea,0x67}, {0xed,0x66}, {0xbf,0x5a}, {0x92,0xd3}, {0xea,0x63}, {0x94,0xb8}, {0xbf,0x58}, - {0xbf,0x5c}, {0xbf,0x5b}, {0xea,0x64}, {0xea,0x68}, {0xbf,0x59}, {0xfc,0x71}, {0xed,0x6d}, {0xc0,0xf5}, {0xc2,0x7a}, {0xc0,0xf6}, - {0xc0,0xf3}, {0xed,0x6a}, {0xed,0x68}, {0xed,0x6b}, {0xed,0x6e}, {0xc0,0xf4}, {0xed,0x6c}, {0xed,0x67}, {0x97,0x5e}, {0xf0,0x42}, - {0xf0,0x45}, {0xf2,0x75}, {0xf0,0x40}, {0x8c,0xad}, {0xf4,0x6f}, {0xf0,0x46}, {0xc3,0xa2}, {0xf0,0x44}, {0xc2,0x7b}, {0xf0,0x41}, - {0xf0,0x43}, {0xf0,0x47}, {0xf2,0x76}, {0xf2,0x74}, {0xfe,0xa7}, {0xc3,0xa3}, {0xf2,0x73}, {0x94,0x6a}, {0xc4,0x6e}, {0x93,0xe3}, - {0x98,0xcf}, {0xc4,0xed}, {0xf6,0xf1}, {0xc4,0xec}, {0xf6,0xf3}, {0xf6,0xf0}, {0xf6,0xf2}, {0xc5,0xd0}, {0xf8,0xb2}, {0xa5,0xca}, - {0xcd,0x6e}, {0xd2,0xbc}, {0xd2,0xbd}, {0xb2,0x7d}, {0xde,0xbf}, {0xbf,0x5d}, {0xc3,0xa4}, {0xc5,0x7b}, {0xf8,0xb3}, {0xa5,0xcb}, - {0xa0,0xd9}, {0xcd,0x6f}, {0xa2,0x60}, {0xcf,0xd7}, {0xcf,0xd8}, {0xa0,0xbf}, {0xa0,0x4d}, {0xa0,0xb8}, {0xd2,0xbe}, {0xd2,0xbf}, - {0xb2,0x7e}, {0xb2,0xa1}, {0xa0,0xce}, {0xda,0xab}, {0xde,0xc2}, {0xde,0xc1}, {0xde,0xc0}, {0xe2,0xd5}, {0xe2,0xd6}, {0xe2,0xd7}, - {0xba,0xc2}, {0xa0,0xb7}, {0xe6,0xad}, {0xe6,0xac}, {0xea,0x69}, {0xbf,0x5e}, {0xbf,0x5f}, {0xfe,0xa9}, {0xed,0x72}, {0xed,0x6f}, - {0xed,0x70}, {0xed,0x71}, {0xf0,0x49}, {0xf0,0x48}, {0xc2,0x7c}, {0xf2,0x77}, {0xf5,0xde}, {0xa5,0xcc}, {0x89,0xc3}, {0xac,0xc6}, - {0xb2,0xa2}, {0xde,0xc3}, {0xfe,0xab}, {0xa5,0xcd}, {0xd2,0xc0}, {0xb2,0xa3}, {0xb5,0x63}, {0xb5,0x64}, {0xa5,0xce}, {0xa5,0xcf}, - {0xca,0x46}, {0xa8,0x6a}, {0xa8,0x69}, {0xac,0xc7}, {0xcf,0xd9}, {0xda,0xac}, {0xa5,0xd0}, {0xa5,0xd1}, {0xa5,0xd2}, {0xa5,0xd3}, - {0x9d,0xf4}, {0x89,0x6d}, {0xa8,0x6b}, {0xa8,0x6c}, {0xcb,0x6e}, {0xcb,0x6d}, {0x9c,0x7b}, {0xaa,0xb6}, {0xcd,0x72}, {0xcd,0x70}, - {0xcd,0x71}, {0x98,0xd2}, {0x9f,0xa9}, {0xcf,0xda}, {0xcf,0xdb}, {0xfe,0xb2}, {0xac,0xcb}, {0xac,0xc9}, {0xfe,0xb1}, {0xac,0xca}, - {0xac,0xc8}, {0x97,0xd9}, {0xa0,0xc4}, {0xaf,0x60}, {0x94,0x76}, {0xaf,0x64}, {0xaf,0x63}, {0xd2,0xc1}, {0xaf,0x62}, {0xaf,0x61}, - {0xd2,0xc2}, {0x99,0x78}, {0xb2,0xa6}, {0xd6,0x7b}, {0xd6,0x7a}, {0xb2,0xa4}, {0xb2,0xa5}, {0xfe,0xb3}, {0xb5,0x66}, {0xb5,0x65}, - {0xda,0xae}, {0x98,0xd3}, {0xfe,0xb4}, {0xda,0xad}, {0xb2,0xa7}, {0x98,0xd4}, {0xb7,0xed}, {0xde,0xc5}, {0xb7,0xee}, {0xde,0xc4}, - {0x9f,0xb9}, {0xe2,0xd8}, {0xe6,0xae}, {0xbd,0x42}, {0xea,0x6a}, {0x94,0x71}, {0xed,0x73}, {0xc3,0xa6}, {0xc3,0xa5}, {0xc5,0x7c}, - {0xa5,0xd4}, {0xcd,0x73}, {0x98,0xd5}, {0xfe,0xb8}, {0xb2,0xa8}, {0xe2,0xd9}, {0xba,0xc3}, {0xc6,0xd4}, {0xcb,0x6f}, {0xcb,0x70}, - {0xcd,0x74}, {0xaa,0xb8}, {0xaa,0xb9}, {0xaa,0xb7}, {0xfe,0xba}, {0xac,0xcf}, {0xac,0xd0}, {0xac,0xcd}, {0xac,0xce}, {0xcf,0xdc}, - {0xcf,0xdd}, {0xac,0xcc}, {0xd2,0xc3}, {0x9e,0x5c}, {0xaf,0x68}, {0xaf,0x69}, {0xfe,0xbb}, {0xb2,0xab}, {0xd2,0xc9}, {0xaf,0x6e}, - {0xaf,0x6c}, {0xd2,0xca}, {0xd2,0xc5}, {0xaf,0x6b}, {0xaf,0x6a}, {0xaf,0x65}, {0xd2,0xc8}, {0xd2,0xc7}, {0xd2,0xc4}, {0xaf,0x6d}, - {0xa0,0x44}, {0xd2,0xc6}, {0xaf,0x66}, {0xaf,0x67}, {0x98,0xd7}, {0xb2,0xac}, {0xd6,0xa1}, {0xd6,0xa2}, {0xb2,0xad}, {0xd6,0x7c}, - {0xd6,0x7e}, {0xd6,0xa4}, {0xd6,0xa3}, {0xd6,0x7d}, {0xb2,0xa9}, {0xb2,0xaa}, {0xda,0xb6}, {0xb5,0x6b}, {0xb5,0x6a}, {0xda,0xb0}, - {0xb5,0x68}, {0x98,0xd8}, {0xda,0xb3}, {0xb5,0x6c}, {0xda,0xb4}, {0xb5,0x6d}, {0xda,0xb1}, {0xb5,0x67}, {0xb5,0x69}, {0xda,0xb5}, - {0xda,0xb2}, {0xda,0xaf}, {0xde,0xd2}, {0xde,0xc7}, {0xb7,0xf0}, {0xb7,0xf3}, {0xb7,0xf2}, {0xb7,0xf7}, {0xb7,0xf6}, {0xde,0xd3}, - {0xde,0xd1}, {0xde,0xca}, {0xde,0xce}, {0xde,0xcd}, {0xb7,0xf4}, {0xde,0xd0}, {0xde,0xcc}, {0xde,0xd4}, {0xde,0xcb}, {0xb7,0xf5}, - {0xb7,0xef}, {0xb7,0xf1}, {0xfe,0xbc}, {0xde,0xc9}, {0x9f,0xfe}, {0xe2,0xdb}, {0xba,0xc7}, {0xe2,0xdf}, {0xba,0xc6}, {0xe2,0xdc}, - {0xba,0xc5}, {0xde,0xc8}, {0xde,0xcf}, {0xe2,0xde}, {0xba,0xc8}, {0xe2,0xe0}, {0xe2,0xdd}, {0xe2,0xda}, {0xe6,0xb1}, {0xe6,0xb5}, - {0xe6,0xb7}, {0xe6,0xb3}, {0xe6,0xb2}, {0xe6,0xb0}, {0xbd,0x45}, {0xbd,0x43}, {0xbd,0x48}, {0xbd,0x49}, {0xe6,0xb4}, {0xbd,0x46}, - {0xe6,0xaf}, {0xbd,0x47}, {0xba,0xc4}, {0xe6,0xb6}, {0xbd,0x44}, {0xfe,0xbd}, {0xea,0x6c}, {0xea,0x6b}, {0xea,0x73}, {0xea,0x6d}, - {0xea,0x72}, {0xea,0x6f}, {0xbf,0x60}, {0xea,0x71}, {0xbf,0x61}, {0xbf,0x62}, {0x9d,0xdd}, {0xea,0x70}, {0xea,0x6e}, {0x9e,0xe1}, - {0xc0,0xf8}, {0xed,0x74}, {0xc0,0xf7}, {0xed,0x77}, {0xed,0x75}, {0xed,0x76}, {0xc0,0xf9}, {0x98,0xda}, {0x9d,0xdf}, {0xfe,0xbf}, - {0xf0,0x4d}, {0xfe,0xbe}, {0xc2,0xa1}, {0xf0,0x4e}, {0x9e,0xeb}, {0xc2,0x7d}, {0xf0,0x4f}, {0xc2,0x7e}, {0xf0,0x4c}, {0xf0,0x50}, - {0xf0,0x4a}, {0xc3,0xa7}, {0xf2,0x78}, {0xc3,0xa8}, {0xc4,0x6f}, {0xf0,0x4b}, {0xc4,0x70}, {0x9e,0x59}, {0xa0,0x5c}, {0xc4,0xee}, - {0xf5,0xdf}, {0xc5,0x7e}, {0xf6,0xf4}, {0xc5,0x7d}, {0xfe,0xc0}, {0xf7,0xea}, {0xc5,0xf5}, {0xc5,0xf6}, {0x94,0x77}, {0x98,0xdc}, - {0xf9,0xcc}, {0xfe,0xc1}, {0xac,0xd1}, {0xcf,0xde}, {0x98,0xde}, {0xb5,0x6e}, {0xb5,0x6f}, {0xa5,0xd5}, {0xa6,0xca}, {0xca,0x47}, - {0xcb,0x71}, {0xa8,0x6d}, {0xaa,0xba}, {0xac,0xd2}, {0xac,0xd3}, {0xac,0xd4}, {0xd6,0xa6}, {0xd2,0xcb}, {0xaf,0x6f}, {0xb2,0xae}, - {0xd6,0xa5}, {0xfe,0xc3}, {0xda,0xb8}, {0xb5,0x71}, {0xda,0xb7}, {0xb5,0x70}, {0xde,0xd5}, {0xbd,0x4a}, {0xe6,0xbb}, {0xe6,0xb8}, - {0xe6,0xb9}, {0xe6,0xba}, {0xfe,0xc8}, {0xed,0x78}, {0xfe,0xc9}, {0xf0,0x51}, {0xf4,0x71}, {0xf4,0x70}, {0xf6,0xf5}, {0xa5,0xd6}, - {0xcd,0x75}, {0xaf,0x70}, {0xb5,0x72}, {0xde,0xd6}, {0xfe,0xca}, {0xe2,0xe1}, {0xbd,0x4b}, {0xea,0x74}, {0xf0,0x52}, {0xf4,0x72}, - {0xa5,0xd7}, {0xaa,0xbb}, {0xac,0xd7}, {0xcf,0xdf}, {0xac,0xd8}, {0xac,0xd6}, {0xac,0xd5}, {0xd2,0xcc}, {0xaf,0x71}, {0xfe,0xcb}, - {0xaf,0x72}, {0xaf,0x73}, {0xb2,0xb0}, {0xd6,0xa7}, {0xb2,0xaf}, {0x9f,0xc2}, {0x8c,0x6b}, {0xda,0xb9}, {0xb2,0xb1}, {0xb5,0x73}, - {0xde,0xd7}, {0xb7,0xf8}, {0xb7,0xf9}, {0xba,0xc9}, {0xba,0xca}, {0xbd,0x4c}, {0xbf,0x64}, {0xea,0x75}, {0xbf,0x63}, {0xed,0x79}, - {0xc0,0xfa}, {0xf0,0x53}, {0xf4,0x73}, {0xa5,0xd8}, {0xa8,0x6e}, {0xcd,0x78}, {0xcd,0x77}, {0xaa,0xbc}, {0xcd,0x76}, {0xaa,0xbd}, - {0xcd,0x79}, {0xcf,0xe5}, {0xac,0xdb}, {0xac,0xda}, {0xcf,0xe7}, {0xcf,0xe6}, {0xac,0xdf}, {0xac,0xde}, {0xac,0xd9}, {0xcf,0xe1}, - {0xcf,0xe2}, {0xcf,0xe3}, {0xac,0xe0}, {0xcf,0xe0}, {0xac,0xdc}, {0xcf,0xe4}, {0xac,0xdd}, {0x98,0xc4}, {0x94,0xb0}, {0x94,0xb1}, - {0xd2,0xcf}, {0xd2,0xd3}, {0xd2,0xd1}, {0xd2,0xd0}, {0xd2,0xd4}, {0xd2,0xd5}, {0xd2,0xd6}, {0xd2,0xce}, {0xd2,0xcd}, {0xfe,0xd1}, - {0xaf,0x75}, {0xaf,0x76}, {0xd2,0xd7}, {0xd2,0xd2}, {0xa0,0xc1}, {0xd6,0xb0}, {0xfe,0xd2}, {0xd2,0xd8}, {0xaf,0x77}, {0xaf,0x74}, - {0xa0,0xcd}, {0xd6,0xaa}, {0xd6,0xa9}, {0xd6,0xab}, {0xd6,0xac}, {0xd6,0xae}, {0xd6,0xad}, {0xd6,0xb2}, {0xb2,0xb5}, {0xb2,0xb2}, - {0xb2,0xb6}, {0xd6,0xa8}, {0xb2,0xb7}, {0xd6,0xb1}, {0xb2,0xb4}, {0xd6,0xaf}, {0xb2,0xb3}, {0xfe,0xd3}, {0x98,0xe5}, {0xda,0xbc}, - {0xda,0xbe}, {0xda,0xba}, {0xda,0xbb}, {0xda,0xbf}, {0xda,0xc1}, {0xda,0xc2}, {0xda,0xbd}, {0xda,0xc0}, {0xb5,0x74}, {0xde,0xdb}, - {0xde,0xe0}, {0xde,0xd8}, {0xde,0xdc}, {0xfe,0xd6}, {0xde,0xe1}, {0xde,0xdd}, {0xb7,0xfa}, {0xb8,0x43}, {0xb7,0xfd}, {0xde,0xd9}, - {0xde,0xda}, {0xba,0xce}, {0xb8,0x46}, {0xb7,0xfe}, {0xb8,0x44}, {0xb7,0xfc}, {0xde,0xdf}, {0xb8,0x45}, {0xde,0xde}, {0xb8,0x41}, - {0xb7,0xfb}, {0xb8,0x42}, {0xde,0xe2}, {0xe2,0xe6}, {0xe2,0xe8}, {0x91,0xe4}, {0x8f,0xc7}, {0x94,0xae}, {0xb8,0x40}, {0x8a,0x4f}, - {0x94,0xb2}, {0xe2,0xe3}, {0xba,0xcc}, {0xe2,0xe9}, {0xba,0xcd}, {0xe2,0xe7}, {0xe2,0xe2}, {0xe2,0xe5}, {0xe2,0xea}, {0xba,0xcb}, - {0xe2,0xe4}, {0xbd,0x4e}, {0xe6,0xbf}, {0xe6,0xbe}, {0xbd,0x51}, {0xbd,0x4f}, {0xe6,0xbc}, {0xbd,0x4d}, {0xe6,0xbd}, {0xbd,0x50}, - {0x8f,0xd4}, {0xea,0x7d}, {0xea,0xa1}, {0x98,0xea}, {0xea,0x7e}, {0xea,0x76}, {0xea,0x7a}, {0xea,0x79}, {0xea,0x77}, {0xbf,0x66}, - {0xbf,0x67}, {0xbf,0x65}, {0xea,0x78}, {0xea,0x7b}, {0xea,0x7c}, {0xbf,0x68}, {0xc1,0x40}, {0xed,0xa3}, {0xc0,0xfc}, {0xed,0x7b}, - {0xc0,0xfe}, {0xc1,0x41}, {0xfe,0xd8}, {0xc0,0xfd}, {0xed,0xa2}, {0xed,0x7c}, {0xc0,0xfb}, {0xed,0xa1}, {0xed,0x7a}, {0xed,0x7e}, - {0xed,0x7d}, {0x9d,0xe0}, {0xf0,0x55}, {0xc2,0xa4}, {0xc2,0xa5}, {0xc2,0xa2}, {0x98,0xee}, {0xc2,0xa3}, {0xf0,0x54}, {0x95,0xc4}, - {0xf2,0x7b}, {0xfc,0xe8}, {0xc3,0xa9}, {0xf2,0x79}, {0xf2,0x7a}, {0x98,0xef}, {0xf4,0x74}, {0xf4,0x77}, {0xf4,0x75}, {0xf4,0x76}, - {0xf5,0xe0}, {0xc4,0xef}, {0xf7,0xeb}, {0xf8,0xb4}, {0xc5,0xf7}, {0xf8,0xf8}, {0xf8,0xf9}, {0xc6,0x66}, {0xa5,0xd9}, {0xac,0xe1}, - {0x8c,0x6e}, {0xda,0xc3}, {0xde,0xe3}, {0xa5,0xda}, {0xa8,0x6f}, {0xaa,0xbe}, {0xfa,0xd8}, {0xcf,0xe8}, {0xcf,0xe9}, {0xaf,0x78}, - {0xda,0xc4}, {0xb5,0x75}, {0xb8,0x47}, {0xc1,0x42}, {0xed,0xa4}, {0xf2,0x7c}, {0xf4,0x78}, {0xa5,0xdb}, {0xfe,0xdc}, {0xcd,0xa1}, - {0xcd,0x7a}, {0xcd,0x7c}, {0xcd,0x7e}, {0xcd,0x7d}, {0xcd,0x7b}, {0xaa,0xbf}, {0xa0,0xae}, {0xac,0xe2}, {0xcf,0xf2}, {0xcf,0xed}, - {0xcf,0xea}, {0x9d,0x4c}, {0xcf,0xf1}, {0xac,0xe4}, {0xac,0xe5}, {0xcf,0xf0}, {0xcf,0xef}, {0xcf,0xee}, {0xcf,0xeb}, {0xcf,0xec}, - {0xcf,0xf3}, {0xac,0xe3}, {0x98,0xf1}, {0x98,0xf3}, {0xaf,0x7c}, {0x94,0xc1}, {0xaf,0xa4}, {0xaf,0xa3}, {0xd2,0xe1}, {0xd2,0xdb}, - {0xd2,0xd9}, {0xaf,0xa1}, {0xd6,0xb9}, {0xaf,0x7a}, {0xd2,0xde}, {0xd2,0xe2}, {0xd2,0xe4}, {0xd2,0xe0}, {0xd2,0xda}, {0xaf,0xa2}, - {0xd2,0xdf}, {0xd2,0xdd}, {0xaf,0x79}, {0xd2,0xe5}, {0xaf,0xa5}, {0xd2,0xe3}, {0xaf,0x7d}, {0xd2,0xdc}, {0xaf,0x7e}, {0xaf,0x7b}, - {0x98,0xf5}, {0xfa,0x4f}, {0x96,0xe2}, {0x94,0x50}, {0xb2,0xb9}, {0x96,0xa2}, {0xd6,0xba}, {0x98,0xf6}, {0xd6,0xb3}, {0xd6,0xb5}, - {0xd6,0xb7}, {0x96,0xe5}, {0xd6,0xb8}, {0xd6,0xb6}, {0xb2,0xba}, {0xd6,0xbb}, {0x98,0xf7}, {0xd6,0xb4}, {0xa0,0x46}, {0x96,0xe3}, - {0xda,0xc8}, {0xb5,0x76}, {0xda,0xd0}, {0xda,0xc5}, {0xda,0xd1}, {0xda,0xc6}, {0xda,0xc7}, {0x98,0xf8}, {0xda,0xcf}, {0xda,0xce}, - {0xda,0xcb}, {0xb2,0xb8}, {0xb5,0x77}, {0xda,0xc9}, {0xda,0xcc}, {0xb5,0x78}, {0xda,0xcd}, {0xda,0xca}, {0xde,0xee}, {0x9e,0xe4}, - {0xde,0xf2}, {0xb8,0x4e}, {0xe2,0xf0}, {0xb8,0x51}, {0xde,0xf0}, {0xf9,0xd6}, {0xde,0xed}, {0xde,0xe8}, {0xde,0xea}, {0xde,0xeb}, - {0xde,0xe4}, {0x94,0xc3}, {0xb8,0x4d}, {0xb8,0x4c}, {0x94,0xc2}, {0xb8,0x48}, {0xde,0xe7}, {0xb8,0x4f}, {0xb8,0x50}, {0xde,0xe6}, - {0xde,0xe9}, {0xde,0xf1}, {0xb8,0x4a}, {0xb8,0x4b}, {0xde,0xef}, {0xde,0xe5}, {0xe2,0xf2}, {0xba,0xd0}, {0xe2,0xf4}, {0xde,0xec}, - {0xe2,0xf6}, {0xba,0xd4}, {0xe2,0xf7}, {0xe2,0xf3}, {0xba,0xd1}, {0xe2,0xef}, {0xba,0xd3}, {0xe2,0xec}, {0xe2,0xf1}, {0xe2,0xf5}, - {0xe2,0xee}, {0xfe,0xe1}, {0xb8,0x49}, {0xfe,0xe9}, {0xe2,0xeb}, {0xba,0xd2}, {0xe2,0xed}, {0x96,0xe4}, {0x89,0xac}, {0x96,0xdb}, - {0xbd,0x54}, {0xe6,0xc1}, {0xbd,0x58}, {0xbd,0x56}, {0xba,0xcf}, {0xe6,0xc8}, {0xe6,0xc9}, {0xbd,0x53}, {0xfe,0xe2}, {0xe6,0xc7}, - {0xe6,0xca}, {0xbd,0x55}, {0xbd,0x52}, {0xe6,0xc3}, {0xe6,0xc0}, {0xe6,0xc5}, {0xe6,0xc2}, {0xbd,0x59}, {0xe6,0xc4}, {0x94,0xc4}, - {0xfe,0xe3}, {0xe6,0xc6}, {0xbd,0x57}, {0xfe,0xe7}, {0x9f,0xfb}, {0xbf,0x6a}, {0xea,0xa8}, {0xea,0xa2}, {0xea,0xa6}, {0xea,0xac}, - {0xea,0xad}, {0xea,0xa9}, {0xea,0xaa}, {0xea,0xa7}, {0x8c,0x59}, {0xea,0xa4}, {0xbf,0x6c}, {0xbf,0x69}, {0xea,0xa3}, {0xea,0xa5}, - {0xbf,0x6b}, {0xea,0xab}, {0x93,0xc9}, {0xc1,0x46}, {0x94,0xe8}, {0xfb,0x56}, {0xed,0xaa}, {0xed,0xa5}, {0xc1,0x45}, {0x90,0xc5}, - {0xc1,0x43}, {0xed,0xac}, {0xc1,0x44}, {0xed,0xa8}, {0xed,0xa9}, {0xed,0xa6}, {0xed,0xad}, {0xf0,0x56}, {0xc1,0x47}, {0xed,0xa7}, - {0xed,0xae}, {0xed,0xab}, {0xa0,0xa8}, {0xf0,0x5a}, {0xf0,0x57}, {0xc2,0xa6}, {0xf0,0x5b}, {0xf0,0x5d}, {0xf0,0x5c}, {0xf0,0x58}, - {0xf0,0x59}, {0xf2,0xa3}, {0xc3,0xaa}, {0xf2,0x7e}, {0xf2,0xa2}, {0xf2,0x7d}, {0xf2,0xa4}, {0xf2,0xa1}, {0xf4,0x7a}, {0xf4,0x7d}, - {0xf4,0x79}, {0xc4,0x71}, {0xf4,0x7b}, {0xf4,0x7c}, {0xf4,0x7e}, {0xc4,0x72}, {0xc4,0x74}, {0xc4,0x73}, {0xf5,0xe1}, {0xfe,0xe5}, - {0xf5,0xe3}, {0xf5,0xe2}, {0x98,0xfd}, {0x98,0xfb}, {0xfe,0xe8}, {0xf6,0xf6}, {0x8e,0xbf}, {0xf8,0xb5}, {0xf8,0xfa}, {0xa5,0xdc}, - {0x8b,0xd8}, {0xfe,0xf7}, {0xcb,0x72}, {0xaa,0xc0}, {0xcd,0xa3}, {0xaa,0xc1}, {0xaa,0xc2}, {0xcd,0xa2}, {0xcf,0xf8}, {0xcf,0xf7}, - {0xac,0xe6}, {0xac,0xe9}, {0xac,0xe8}, {0xac,0xe7}, {0xcf,0xf4}, {0xcf,0xf6}, {0xcf,0xf5}, {0xd2,0xe8}, {0xaf,0xa7}, {0xd2,0xec}, - {0xd2,0xeb}, {0xd2,0xea}, {0xd2,0xe6}, {0xaf,0xa6}, {0xaf,0xaa}, {0xaf,0xad}, {0x8f,0x68}, {0x94,0xc6}, {0xaf,0xae}, {0xd2,0xe7}, - {0xd2,0xe9}, {0xaf,0xac}, {0xaf,0xab}, {0xaf,0xa9}, {0xaf,0xa8}, {0xd6,0xc2}, {0x9d,0xea}, {0xd6,0xc0}, {0xd6,0xbc}, {0xb2,0xbb}, - {0xd6,0xbd}, {0xb2,0xbc}, {0xd6,0xbe}, {0xd6,0xbf}, {0xd6,0xc1}, {0xb2,0xbd}, {0xda,0xd5}, {0xfc,0x69}, {0xda,0xd4}, {0xda,0xd3}, - {0xda,0xd2}, {0xde,0xf6}, {0xb8,0x52}, {0xde,0xf3}, {0xde,0xf5}, {0x9c,0xda}, {0xb8,0x53}, {0xfe,0xf3}, {0xb8,0x54}, {0xde,0xf4}, - {0x9c,0x72}, {0xfe,0xf0}, {0x89,0xc9}, {0xe3,0x41}, {0xe2,0xf9}, {0xe2,0xfa}, {0xba,0xd7}, {0xba,0xd5}, {0xba,0xd6}, {0xe3,0x43}, - {0x99,0x41}, {0xe3,0x42}, {0xe2,0xfe}, {0xe2,0xfd}, {0xe2,0xfc}, {0xe2,0xfb}, {0xe3,0x40}, {0xe2,0xf8}, {0x99,0x42}, {0xe6,0xcb}, - {0xe6,0xd0}, {0xe6,0xce}, {0xfe,0xf5}, {0x91,0xd7}, {0xe6,0xcd}, {0xe6,0xcc}, {0xe6,0xcf}, {0xea,0xae}, {0x94,0xcc}, {0xbf,0x6d}, - {0xc1,0x48}, {0xed,0xb0}, {0xfe,0xf8}, {0xc1,0x49}, {0xed,0xaf}, {0xf0,0x5f}, {0xf0,0x5e}, {0xc2,0xa7}, {0xf2,0xa5}, {0xc3,0xab}, - {0xf4,0xa1}, {0xc5,0xa1}, {0xf6,0xf7}, {0xf8,0xb7}, {0xf8,0xb6}, {0xc9,0xa8}, {0xac,0xea}, {0xac,0xeb}, {0xd6,0xc3}, {0xb8,0x56}, - {0xa5,0xdd}, {0xa8,0x72}, {0xa8,0x71}, {0xa8,0x70}, {0x97,0xa8}, {0xcd,0xa4}, {0xfe,0xfc}, {0xaa,0xc4}, {0xaa,0xc3}, {0xac,0xee}, - {0xfd,0xbf}, {0xcf,0xfa}, {0xcf,0xfd}, {0xcf,0xfb}, {0xac,0xec}, {0xac,0xed}, {0xfe,0xfe}, {0xcf,0xf9}, {0xcf,0xfc}, {0xaf,0xb5}, - {0xd2,0xf3}, {0xd2,0xf5}, {0xd2,0xf4}, {0xaf,0xb2}, {0xd2,0xef}, {0x96,0xd1}, {0xaf,0xb0}, {0xaf,0xaf}, {0xaf,0xb3}, {0xaf,0xb1}, - {0xaf,0xb4}, {0xd2,0xf2}, {0xd2,0xed}, {0xd2,0xee}, {0xd2,0xf1}, {0xd2,0xf0}, {0x94,0xd5}, {0x94,0xd0}, {0xd6,0xc6}, {0xd6,0xc7}, - {0xd6,0xc5}, {0xd6,0xc4}, {0xb2,0xbe}, {0xb5,0x7d}, {0xda,0xd6}, {0xda,0xd8}, {0xda,0xda}, {0xb5,0x7c}, {0x99,0x44}, {0xb5,0x7a}, - {0xda,0xd7}, {0xb5,0x7b}, {0xda,0xd9}, {0xb5,0x79}, {0xdf,0x41}, {0xde,0xf7}, {0xde,0xfa}, {0xde,0xfe}, {0xb8,0x5a}, {0xde,0xfc}, - {0xde,0xfb}, {0xde,0xf8}, {0xde,0xf9}, {0xb8,0x58}, {0xdf,0x40}, {0xb8,0x57}, {0xb8,0x5c}, {0xb8,0x5b}, {0xb8,0x59}, {0xde,0xfd}, - {0xe3,0x49}, {0xe3,0x48}, {0x8c,0x63}, {0xe3,0x44}, {0xa0,0xb3}, {0xba,0xd8}, {0xe3,0x47}, {0xe3,0x46}, {0xba,0xd9}, {0xbd,0x5e}, - {0xe6,0xd2}, {0x94,0xcf}, {0xbd,0x5f}, {0xbd,0x5b}, {0xbd,0x5d}, {0x9f,0xfa}, {0xbd,0x5a}, {0xbd,0x5c}, {0x91,0xe5}, {0xea,0xaf}, - {0x9c,0x6a}, {0xbf,0x70}, {0xea,0xb1}, {0xea,0xb0}, {0x8e,0x49}, {0xe3,0x45}, {0xbf,0x72}, {0xbf,0x71}, {0xbf,0x6e}, {0xbf,0x6f}, - {0xed,0xb5}, {0xed,0xb3}, {0xc1,0x4a}, {0xed,0xb4}, {0xed,0xb6}, {0xed,0xb2}, {0xed,0xb1}, {0xf0,0x60}, {0xc2,0xaa}, {0xc2,0xa8}, - {0xc2,0xa9}, {0x8e,0x4c}, {0xf2,0xa6}, {0xf2,0xa7}, {0xc3,0xad}, {0xc3,0xac}, {0xf4,0xa3}, {0xf4,0xa4}, {0xf4,0xa2}, {0xf6,0xf8}, - {0xf6,0xf9}, {0xa5,0xde}, {0xca,0x48}, {0xa8,0x73}, {0xcd,0xa5}, {0xaa,0xc6}, {0xaa,0xc5}, {0xcd,0xa6}, {0x8e,0x4d}, {0xd0,0x40}, - {0xac,0xef}, {0xcf,0xfe}, {0xac,0xf0}, {0x9a,0x73}, {0xaf,0xb6}, {0xd2,0xf8}, {0xd2,0xf6}, {0xd2,0xfc}, {0xaf,0xb7}, {0xd2,0xf7}, - {0xd2,0xfb}, {0xd2,0xf9}, {0xd2,0xfa}, {0xd6,0xc8}, {0xd6,0xca}, {0x99,0x47}, {0xb2,0xbf}, {0x8c,0xb1}, {0xd6,0xc9}, {0xb2,0xc0}, - {0xb5,0xa2}, {0xb5,0xa1}, {0xb5,0x7e}, {0xda,0xdb}, {0xdf,0x44}, {0xb8,0x5d}, {0xb8,0x5e}, {0xdf,0x43}, {0xdf,0x42}, {0xe3,0x4a}, - {0xba,0xdb}, {0xba,0xda}, {0xe3,0x4b}, {0xe3,0x4c}, {0xbd,0x61}, {0xbd,0x60}, {0x8e,0x50}, {0xea,0xb5}, {0xe6,0xd3}, {0xe6,0xd5}, - {0xe6,0xd4}, {0xea,0xb4}, {0xea,0xb2}, {0xea,0xb6}, {0xea,0xb3}, {0xbf,0x73}, {0x8e,0x4f}, {0x99,0x49}, {0xed,0xb7}, {0xc1,0x4b}, - {0xed,0xb8}, {0xed,0xb9}, {0x8e,0x51}, {0x8e,0x52}, {0xc2,0xab}, {0xc2,0xac}, {0xc4,0x75}, {0x9a,0xb2}, {0x89,0xa5}, {0xc5,0xd1}, - {0xa5,0xdf}, {0x99,0x4c}, {0xd0,0x41}, {0x9f,0xf8}, {0xd2,0xfd}, {0xaf,0xb8}, {0x8e,0x56}, {0x99,0x4d}, {0x91,0xca}, {0x8e,0x57}, - {0xb3,0xba}, {0xb3,0xb9}, {0x94,0xe1}, {0xb5,0xa4}, {0xda,0xdd}, {0xb5,0xa3}, {0xda,0xdc}, {0x90,0x47}, {0x8f,0xd8}, {0x8e,0x58}, - {0xdf,0x45}, {0xba,0xdc}, {0xe3,0x4d}, {0xba,0xdd}, {0xc4,0x76}, {0xf4,0xa5}, {0xa6,0xcb}, {0xaa,0xc7}, {0xcd,0xa7}, {0xac,0xf2}, - {0x94,0xeb}, {0xac,0xf1}, {0xd0,0x42}, {0xd0,0x43}, {0xd3,0x40}, {0xd3,0x42}, {0xaf,0xb9}, {0xd3,0x44}, {0xd3,0x47}, {0xd3,0x45}, - {0x8e,0x5c}, {0x95,0x53}, {0xd3,0x46}, {0xd3,0x43}, {0xd2,0xfe}, {0xaf,0xba}, {0xd3,0x48}, {0xd3,0x41}, {0x9f,0xe5}, {0xd6,0xd3}, - {0xb2,0xc6}, {0xd6,0xdc}, {0xb2,0xc3}, {0xd6,0xd5}, {0xb2,0xc7}, {0x9f,0x56}, {0xb2,0xc1}, {0xd6,0xd0}, {0xd6,0xdd}, {0xd6,0xd1}, - {0xd6,0xce}, {0xb2,0xc5}, {0x95,0x4f}, {0xb2,0xc2}, {0x8e,0x5e}, {0xd6,0xd4}, {0xd6,0xd7}, {0xb2,0xc4}, {0xd6,0xd8}, {0xb2,0xc8}, - {0xd6,0xd9}, {0xd6,0xcf}, {0xd6,0xd6}, {0xd6,0xda}, {0xd6,0xd2}, {0xd6,0xcd}, {0xd6,0xcb}, {0xd6,0xdb}, {0x99,0x6a}, {0xda,0xdf}, - {0xda,0xe4}, {0x9c,0x64}, {0x9c,0xd9}, {0xda,0xe0}, {0xda,0xe6}, {0xb5,0xa7}, {0xd6,0xcc}, {0xda,0xe1}, {0xb5,0xa5}, {0xda,0xde}, - {0xb5,0xac}, {0xda,0xe2}, {0xb5,0xab}, {0xda,0xe3}, {0xb5,0xad}, {0xb5,0xa8}, {0xb5,0xae}, {0xb5,0xa9}, {0xb5,0xaa}, {0x8e,0x5d}, - {0xb5,0xa6}, {0xda,0xe5}, {0xb8,0x61}, {0xdf,0x50}, {0x99,0x50}, {0xdf,0x53}, {0xdf,0x47}, {0xdf,0x4c}, {0xdf,0x46}, {0xb8,0x63}, - {0xdf,0x4a}, {0x99,0x51}, {0xdf,0x48}, {0xb8,0x62}, {0x8e,0x62}, {0xdf,0x4f}, {0xdf,0x4e}, {0xdf,0x4b}, {0xdf,0x4d}, {0xdf,0x49}, - {0xba,0xe1}, {0xdf,0x52}, {0xb8,0x5f}, {0xdf,0x51}, {0x99,0x52}, {0xe3,0x5d}, {0xba,0xe8}, {0xe3,0x58}, {0xba,0xe7}, {0xe3,0x4e}, - {0xe3,0x50}, {0xba,0xe0}, {0xe3,0x55}, {0xe3,0x54}, {0xe3,0x57}, {0xba,0xe5}, {0xe3,0x52}, {0xe3,0x51}, {0x8e,0x68}, {0xba,0xe4}, - {0xba,0xdf}, {0xe3,0x53}, {0xba,0xe2}, {0xe3,0x59}, {0xe3,0x5b}, {0xe3,0x56}, {0xe3,0x4f}, {0xba,0xe3}, {0xbd,0x69}, {0xba,0xde}, - {0x8e,0x61}, {0x9f,0x59}, {0xe3,0x5c}, {0xe6,0xd9}, {0xbd,0x62}, {0xe6,0xdb}, {0xbd,0x63}, {0x8b,0xb3}, {0xbd,0x65}, {0xe6,0xde}, - {0xe6,0xd6}, {0xba,0xe6}, {0xe6,0xdc}, {0xe6,0xd8}, {0xb8,0x60}, {0xbd,0x68}, {0xbd,0x64}, {0xbd,0x66}, {0xbd,0x67}, {0xbf,0x76}, - {0xe6,0xdd}, {0xe6,0xd7}, {0xbd,0x6a}, {0xe6,0xda}, {0x9f,0x5d}, {0x8e,0x66}, {0xea,0xc0}, {0xea,0xbb}, {0xea,0xc5}, {0xbf,0x74}, - {0xea,0xbd}, {0xbf,0x78}, {0xea,0xc3}, {0xea,0xba}, {0xea,0xb7}, {0xea,0xc6}, {0xc1,0x51}, {0xbf,0x79}, {0xea,0xc2}, {0xea,0xb8}, - {0xbf,0x77}, {0xea,0xbc}, {0xbf,0x7b}, {0xea,0xb9}, {0xea,0xbe}, {0xbf,0x7a}, {0xea,0xc1}, {0xea,0xc4}, {0x8c,0xb2}, {0xed,0xcb}, - {0xed,0xcc}, {0xed,0xbc}, {0xed,0xc3}, {0xed,0xc1}, {0xc1,0x4f}, {0xed,0xc8}, {0xea,0xbf}, {0x8e,0x6e}, {0xed,0xbf}, {0x9f,0x64}, - {0xed,0xc9}, {0xc1,0x4e}, {0xed,0xbe}, {0xed,0xbd}, {0xed,0xc7}, {0xed,0xc4}, {0xed,0xc6}, {0xed,0xba}, {0xed,0xca}, {0xc1,0x4c}, - {0xed,0xc5}, {0xed,0xce}, {0xed,0xc2}, {0xc1,0x50}, {0xc1,0x4d}, {0xed,0xc0}, {0xed,0xbb}, {0xed,0xcd}, {0xbf,0x75}, {0x99,0x53}, - {0xfa,0xb8}, {0xf0,0x63}, {0x99,0x54}, {0xf0,0x61}, {0xf0,0x67}, {0xc2,0xb0}, {0xf0,0x65}, {0xf0,0x64}, {0xc2,0xb2}, {0xf0,0x6a}, - {0xc2,0xb1}, {0xf0,0x6b}, {0xf0,0x68}, {0xc2,0xae}, {0xf0,0x69}, {0xf0,0x62}, {0xc2,0xaf}, {0xc2,0xad}, {0xf2,0xab}, {0xf0,0x66}, - {0xf0,0x6c}, {0xf2,0xa8}, {0x8e,0x70}, {0xc3,0xb2}, {0xc3,0xb0}, {0xf2,0xaa}, {0xf2,0xac}, {0xf2,0xa9}, {0xc3,0xb1}, {0xc3,0xae}, - {0xc3,0xaf}, {0xc3,0xb3}, {0x9f,0x61}, {0xc4,0x78}, {0x8e,0x72}, {0xf4,0xaa}, {0xf4,0xa9}, {0xf4,0xa7}, {0xf4,0xa6}, {0xf4,0xa8}, - {0xc4,0x77}, {0xc4,0x79}, {0xc4,0xf0}, {0xa0,0x6b}, {0xf5,0xe5}, {0xf5,0xe4}, {0x9f,0x40}, {0xf6,0xfa}, {0xf6,0xfc}, {0xf6,0xfe}, - {0xf6,0xfd}, {0xf6,0xfb}, {0x94,0xed}, {0xc5,0xa3}, {0xc5,0xa2}, {0xc5,0xd3}, {0xc5,0xd2}, {0xc5,0xd4}, {0xf7,0xed}, {0xf7,0xec}, - {0xf8,0xfb}, {0xf8,0xb8}, {0xf8,0xfc}, {0xc6,0x58}, {0x94,0xee}, {0xc6,0x59}, {0xf9,0x6d}, {0x9f,0xbd}, {0xc6,0x7e}, {0xa6,0xcc}, - {0x8e,0x7b}, {0xcd,0xa8}, {0xd0,0x45}, {0xd0,0x46}, {0xd0,0x44}, {0x99,0x57}, {0x94,0xf7}, {0xac,0xf3}, {0x9f,0x5f}, {0xd0,0x47}, - {0xd0,0x48}, {0xd0,0x49}, {0x8e,0x73}, {0xd3,0x49}, {0xd3,0x4f}, {0x9f,0x62}, {0xd3,0x4d}, {0xaf,0xbb}, {0xd3,0x4b}, {0xd3,0x4c}, - {0xd3,0x4e}, {0x94,0xf6}, {0xd3,0x4a}, {0xb2,0xc9}, {0xd6,0xde}, {0xb2,0xcb}, {0xd6,0xe0}, {0xb2,0xca}, {0xd6,0xdf}, {0x99,0x58}, - {0xda,0xe8}, {0xb5,0xaf}, {0xda,0xea}, {0xda,0xe7}, {0xd6,0xe1}, {0xb5,0xb0}, {0x8e,0x75}, {0xf9,0xdb}, {0xda,0xe9}, {0x90,0x72}, - {0x94,0xf8}, {0xdf,0x56}, {0xb8,0x64}, {0xdf,0x54}, {0xb8,0x65}, {0xdf,0x55}, {0xb8,0x66}, {0x99,0x5a}, {0xba,0xe9}, {0xe3,0x61}, - {0xe3,0x5e}, {0xe3,0x60}, {0xba,0xea}, {0xba,0xeb}, {0xe3,0x5f}, {0xa0,0xb0}, {0x8c,0xb3}, {0xe6,0xdf}, {0x8e,0x79}, {0xe6,0xe0}, - {0x8e,0x78}, {0xbd,0x6b}, {0xe6,0xe2}, {0xe6,0xe1}, {0x94,0xf3}, {0xa2,0x61}, {0xea,0xca}, {0xea,0xcb}, {0xea,0xc7}, {0x98,0xaf}, - {0xea,0xc8}, {0xbf,0x7c}, {0xbf,0x7d}, {0xea,0xc9}, {0xc1,0x57}, {0xa0,0xb2}, {0xc1,0x53}, {0xc1,0x58}, {0xc1,0x54}, {0xc1,0x56}, - {0xc1,0x52}, {0xc1,0x55}, {0x8e,0x7a}, {0xc2,0xb3}, {0xed,0xcf}, {0xf2,0xae}, {0xf2,0xad}, {0x99,0x5c}, {0xf4,0xab}, {0xc4,0x7a}, - {0xc4,0x7b}, {0xf7,0x41}, {0xf5,0xe6}, {0x8e,0x7c}, {0xf7,0x40}, {0x8e,0x7d}, {0xf8,0xfd}, {0xf9,0xa4}, {0xa6,0xcd}, {0x8b,0xd9}, - {0xa8,0x74}, {0x89,0xa2}, {0xcd,0xa9}, {0xaa,0xc8}, {0xac,0xf6}, {0xd0,0x4c}, {0xac,0xf4}, {0xd0,0x4a}, {0xac,0xf9}, {0xac,0xf5}, - {0xac,0xfa}, {0xac,0xf8}, {0xd0,0x4b}, {0xac,0xf7}, {0xaf,0xbf}, {0xaf,0xbe}, {0xd3,0x5a}, {0xaf,0xc7}, {0xd3,0x53}, {0xd3,0x59}, - {0xaf,0xc3}, {0xd3,0x52}, {0xd3,0x58}, {0xd3,0x56}, {0xaf,0xc2}, {0xaf,0xc4}, {0xd3,0x55}, {0xaf,0xbd}, {0xd3,0x54}, {0xaf,0xc8}, - {0xaf,0xc5}, {0xaf,0xc9}, {0xaf,0xc6}, {0xd3,0x51}, {0xd3,0x50}, {0xd3,0x57}, {0xaf,0xc0}, {0xaf,0xbc}, {0xaf,0xc1}, {0x9e,0xd7}, - {0xd6,0xf0}, {0xd6,0xe9}, {0xb5,0xb5}, {0xd6,0xe8}, {0xb2,0xcf}, {0xb2,0xd6}, {0xb2,0xd3}, {0xb2,0xd9}, {0xb2,0xd8}, {0xb2,0xd4}, - {0xd6,0xe2}, {0xd6,0xe5}, {0xd6,0xe4}, {0xb2,0xd0}, {0xd6,0xe6}, {0xd6,0xef}, {0xb2,0xd1}, {0xd6,0xe3}, {0xd6,0xec}, {0xd6,0xed}, - {0xb2,0xd2}, {0xd6,0xea}, {0xb2,0xd7}, {0xb2,0xcd}, {0xb2,0xd5}, {0xd6,0xe7}, {0xb2,0xcc}, {0xd6,0xeb}, {0xd6,0xee}, {0xa0,0xb6}, - {0xda,0xfb}, {0xda,0xf2}, {0xb5,0xb2}, {0xda,0xf9}, {0xda,0xf6}, {0xda,0xee}, {0xda,0xf7}, {0xb5,0xb4}, {0xda,0xef}, {0xda,0xeb}, - {0x9e,0x42}, {0xb8,0x6c}, {0xda,0xf4}, {0x8e,0xa4}, {0xb5,0xb1}, {0xda,0xfa}, {0xb5,0xb8}, {0xb5,0xba}, {0xda,0xed}, {0xb5,0xb9}, - {0xda,0xf0}, {0xb5,0xb3}, {0xda,0xf8}, {0xda,0xf1}, {0xda,0xf5}, {0xda,0xf3}, {0xb5,0xb6}, {0xda,0xec}, {0xb5,0xbb}, {0xb2,0xce}, - {0xb5,0xb7}, {0xb5,0xbc}, {0xb8,0x68}, {0xdf,0x5d}, {0xdf,0x5f}, {0xdf,0x61}, {0xdf,0x65}, {0xdf,0x5b}, {0xdf,0x59}, {0xb8,0x6a}, - {0xdf,0x60}, {0xdf,0x64}, {0xdf,0x5c}, {0xdf,0x58}, {0xdf,0x57}, {0x8e,0xa7}, {0x8c,0x76}, {0xdf,0x62}, {0xdf,0x5a}, {0xdf,0x5e}, - {0xb8,0x6b}, {0xb8,0x69}, {0xdf,0x66}, {0xb8,0x67}, {0xdf,0x63}, {0xe3,0x72}, {0x95,0x42}, {0xba,0xee}, {0xe3,0x6a}, {0xbd,0x78}, - {0xe3,0x74}, {0xba,0xf1}, {0xe3,0x78}, {0xba,0xf7}, {0xe3,0x65}, {0x98,0x7d}, {0xe3,0x75}, {0xe3,0x62}, {0x97,0x55}, {0xe3,0x77}, - {0xe3,0x66}, {0x8e,0xa8}, {0xba,0xfe}, {0xba,0xfb}, {0xe3,0x76}, {0xe3,0x70}, {0xba,0xed}, {0xba,0xf5}, {0xba,0xf4}, {0x8e,0xaa}, - {0xba,0xf3}, {0xba,0xf9}, {0xe3,0x63}, {0xba,0xfa}, {0xe3,0x71}, {0xba,0xf6}, {0xba,0xec}, {0xe3,0x73}, {0xba,0xef}, {0xba,0xf0}, - {0xba,0xf8}, {0xe3,0x68}, {0xe3,0x67}, {0xe3,0x64}, {0xe3,0x6c}, {0xe3,0x69}, {0xe3,0x6d}, {0xba,0xfd}, {0xe3,0x79}, {0xba,0xf2}, - {0xe3,0x6e}, {0xe3,0x6f}, {0x89,0xa3}, {0xe3,0x6b}, {0x99,0x60}, {0x99,0x62}, {0xba,0xfc}, {0x94,0xfc}, {0x99,0x61}, {0xe6,0xe7}, - {0xbd,0x70}, {0xbd,0x79}, {0xbd,0x75}, {0xe6,0xe4}, {0x94,0xfa}, {0xbd,0x72}, {0xbd,0x76}, {0xe6,0xf0}, {0xbd,0x6c}, {0xe6,0xe8}, - {0xbd,0x74}, {0x8e,0xae}, {0x8e,0xb2}, {0xe6,0xeb}, {0xe6,0xe6}, {0xbd,0x73}, {0xbd,0x77}, {0xe6,0xe5}, {0xbd,0x71}, {0xe6,0xef}, - {0xbd,0x6e}, {0xe6,0xee}, {0xe6,0xed}, {0xbd,0x7a}, {0xe5,0x72}, {0xbd,0x6d}, {0x8e,0xb0}, {0xe6,0xec}, {0xe6,0xe3}, {0xbd,0x7b}, - {0xe6,0xea}, {0xbd,0x6f}, {0x99,0x63}, {0x97,0xaa}, {0xe6,0xe9}, {0x94,0xfb}, {0xbf,0xa2}, {0xbf,0xa7}, {0xbf,0x7e}, {0xea,0xd8}, - {0xea,0xcf}, {0xea,0xdb}, {0xea,0xd3}, {0xea,0xd9}, {0xbf,0xa8}, {0xbf,0xa1}, {0xea,0xcc}, {0xea,0xd2}, {0xea,0xdc}, {0xea,0xd5}, - {0xea,0xda}, {0xea,0xce}, {0xea,0xd6}, {0xbf,0xa3}, {0xea,0xd4}, {0xbf,0xa6}, {0xbf,0xa5}, {0xea,0xd0}, {0xea,0xd1}, {0xea,0xcd}, - {0xea,0xd7}, {0xbf,0xa4}, {0xea,0xde}, {0xea,0xdd}, {0x8e,0xbb}, {0xed,0xda}, {0xed,0xd6}, {0xc1,0x5f}, {0xed,0xd0}, {0xc1,0x59}, - {0xc1,0x69}, {0xed,0xdc}, {0xc1,0x61}, {0xc1,0x5d}, {0xed,0xd3}, {0xc1,0x64}, {0xc1,0x67}, {0xed,0xde}, {0xc1,0x5c}, {0xed,0xd5}, - {0xc1,0x65}, {0xed,0xe0}, {0xed,0xdd}, {0xed,0xd1}, {0xc1,0x60}, {0xc1,0x5a}, {0xc1,0x68}, {0xed,0xd8}, {0xc1,0x63}, {0xed,0xd2}, - {0xc1,0x5e}, {0xed,0xdf}, {0xc1,0x62}, {0xc1,0x5b}, {0xed,0xd9}, {0xc1,0x66}, {0xed,0xd7}, {0xed,0xdb}, {0xf0,0x6e}, {0xf0,0x74}, - {0xc2,0xb9}, {0xf0,0x77}, {0xc2,0xb4}, {0xc2,0xb5}, {0xf0,0x6f}, {0xf0,0x76}, {0xf0,0x71}, {0xc2,0xba}, {0xc2,0xb7}, {0x8c,0xdc}, - {0xf0,0x6d}, {0xc2,0xb6}, {0xf0,0x73}, {0xf0,0x75}, {0xc2,0xb8}, {0xf0,0x72}, {0xf0,0x70}, {0x98,0x76}, {0x8e,0xa1}, {0xf2,0xb8}, - {0xc3,0xb7}, {0xc3,0xb8}, {0xc3,0xb4}, {0x8c,0xb4}, {0xc3,0xb5}, {0x8e,0xb7}, {0xf2,0xb4}, {0xf2,0xb2}, {0xf2,0xb6}, {0xc3,0xba}, - {0xf2,0xb7}, {0xf2,0xb0}, {0xf2,0xaf}, {0xf2,0xb3}, {0xf2,0xb1}, {0xc3,0xb6}, {0xf2,0xb5}, {0xf4,0xac}, {0xc4,0x7e}, {0xc4,0x7d}, - {0xf4,0xad}, {0x9d,0xa6}, {0xf4,0xaf}, {0xf4,0xae}, {0xc4,0xa1}, {0xf5,0xeb}, {0xf5,0xe8}, {0xf5,0xe9}, {0xf5,0xe7}, {0xf5,0xea}, - {0xc4,0xf2}, {0xf5,0xec}, {0x9e,0xb0}, {0xc4,0xf1}, {0xf7,0x42}, {0x8e,0xb8}, {0xc5,0xd5}, {0xc5,0xd7}, {0xf7,0xee}, {0xc5,0xd6}, - {0xf8,0xb9}, {0xf9,0x40}, {0xf9,0x42}, {0xf8,0xfe}, {0xf9,0x41}, {0xc6,0x6c}, {0x9d,0x70}, {0x89,0x6e}, {0x89,0x6f}, {0x89,0x70}, - {0x89,0x71}, {0x89,0x72}, {0x89,0x73}, {0x89,0x74}, {0xa6,0xce}, {0x89,0x75}, {0xac,0xfb}, {0xd2,0x6f}, {0xaf,0xca}, {0xb2,0xda}, - {0xda,0xfc}, {0xda,0xfd}, {0x8e,0xbc}, {0x8e,0xbd}, {0xea,0xdf}, {0xc1,0x6a}, {0xed,0xe1}, {0x8e,0xbe}, {0xc2,0xbb}, {0x9d,0xd1}, - {0xf2,0xba}, {0xf2,0xb9}, {0xc4,0xa2}, {0xf5,0xed}, {0x94,0xfd}, {0xf7,0x43}, {0xc5,0xf8}, {0xca,0x49}, {0x8b,0xd7}, {0x8b,0xda}, - {0xaa,0xc9}, {0xa8,0x75}, {0xd0,0x4d}, {0xd3,0x60}, {0xd3,0x5b}, {0xd3,0x5f}, {0xd3,0x5d}, {0xaf,0xcb}, {0xd3,0x5e}, {0xd3,0x5c}, - {0xd6,0xf1}, {0xda,0xfe}, {0xdb,0x40}, {0xdf,0x69}, {0xdf,0x6a}, {0xb8,0x6e}, {0xb8,0x6f}, {0xdf,0x68}, {0xdf,0x6b}, {0xdf,0x67}, - {0xb8,0x6d}, {0xbb,0x40}, {0xa0,0xe2}, {0xb8,0x70}, {0xe3,0x7a}, {0xbd,0x7c}, {0xe6,0xf1}, {0xbd,0x7d}, {0x9f,0xe9}, {0xbf,0xa9}, - {0xea,0xe2}, {0xea,0xe0}, {0xea,0xe1}, {0xed,0xe4}, {0xed,0xe3}, {0xed,0xe2}, {0xf2,0xbb}, {0xc3,0xb9}, {0xf2,0xbc}, {0xf7,0x44}, - {0xc5,0xf9}, {0xf8,0xba}, {0xa6,0xcf}, {0xaa,0xcb}, {0xaa,0xca}, {0xd0,0x4f}, {0xac,0xfc}, {0xfd,0xa8}, {0xd0,0x4e}, {0xd3,0x62}, - {0x8a,0xe7}, {0xaf,0xcc}, {0xd6,0xf2}, {0xd3,0x61}, {0x8e,0xc2}, {0xb2,0xdc}, {0xd6,0xf5}, {0xd6,0xf3}, {0xd6,0xf4}, {0xb2,0xdb}, - {0xdb,0x42}, {0xdb,0x43}, {0xdb,0x41}, {0x8e,0xc4}, {0xb8,0x73}, {0xdf,0x6d}, {0xdf,0x6c}, {0xdf,0x6e}, {0xb8,0x72}, {0xb8,0x71}, - {0xe6,0xf2}, {0xe6,0xf4}, {0x99,0x64}, {0xbd,0x7e}, {0xe6,0xf3}, {0xea,0xe3}, {0xbf,0xaa}, {0xf0,0x79}, {0x99,0x65}, {0xf0,0x78}, - {0xc3,0xbb}, {0xf2,0xbd}, {0xc3,0xbd}, {0xc3,0xbc}, {0xf4,0xb0}, {0xf5,0xee}, {0xc4,0xf3}, {0xa6,0xd0}, {0xd0,0x50}, {0xac,0xfd}, - {0xd3,0x65}, {0xaf,0xce}, {0xd3,0x64}, {0xd3,0x63}, {0xaf,0xcd}, {0xd6,0xfb}, {0xd6,0xfd}, {0xd6,0xf6}, {0xd6,0xf7}, {0xb2,0xdd}, - {0xd6,0xf8}, {0xb2,0xde}, {0xd6,0xfc}, {0xd6,0xf9}, {0xd6,0xfa}, {0xb2,0xdf}, {0xb5,0xbe}, {0xb5,0xbf}, {0xdb,0x44}, {0xdf,0x6f}, - {0xdf,0x70}, {0x95,0x4e}, {0xe3,0x7e}, {0xbb,0x43}, {0xbb,0x41}, {0xbb,0x42}, {0xe3,0x7b}, {0xe3,0x7c}, {0xe3,0x7d}, {0xe6,0xf9}, - {0x98,0xb3}, {0xe6,0xfa}, {0xbd,0xa1}, {0xe6,0xf7}, {0xe6,0xf6}, {0xe6,0xf8}, {0xe6,0xf5}, {0xbf,0xad}, {0xea,0xe4}, {0xbf,0xab}, - {0xbf,0xac}, {0xed,0xe6}, {0xc1,0x6b}, {0xed,0xe5}, {0xef,0xa8}, {0xf0,0x7a}, {0xf0,0x7b}, {0xc2,0xbc}, {0x8e,0xcb}, {0xc2,0xbd}, - {0xc1,0x6c}, {0xf2,0xbe}, {0xf2,0xbf}, {0xf4,0xb1}, {0xc4,0xa3}, {0xa6,0xd1}, {0x8b,0xdf}, {0xa6,0xd2}, {0xac,0xfe}, {0xaa,0xcc}, - {0xaf,0xcf}, {0xd0,0x51}, {0x8e,0xce}, {0xb5,0xc0}, {0xa6,0xd3}, {0xad,0x41}, {0xd0,0x52}, {0xd0,0x53}, {0xad,0x40}, {0xad,0x42}, - {0xa6,0xd4}, {0xd0,0x54}, {0xaf,0xd1}, {0xd3,0x66}, {0xaf,0xd3}, {0xaf,0xd0}, {0xaf,0xd2}, {0xd7,0x41}, {0xb2,0xe0}, {0x8e,0xcf}, - {0xd7,0x40}, {0xd6,0xfe}, {0x99,0x68}, {0xdf,0x71}, {0xe3,0xa1}, {0x99,0x69}, {0xbd,0xa2}, {0xbf,0xae}, {0xea,0xe6}, {0xea,0xe5}, - {0xed,0xe7}, {0x99,0x6b}, {0x8e,0xd1}, {0xf5,0xef}, {0x99,0x6c}, {0xa6,0xd5}, {0xcb,0x73}, {0xcd,0xaa}, {0xad,0x43}, {0xd0,0x55}, - {0xd3,0x68}, {0x8e,0xd4}, {0x8e,0xd5}, {0xaf,0xd4}, {0xd3,0x67}, {0xaf,0xd5}, {0xd7,0x43}, {0xb2,0xe2}, {0xd7,0x42}, {0xd7,0x44}, - {0xb2,0xe1}, {0xdb,0x46}, {0xdb,0x47}, {0xdb,0x45}, {0xb5,0xc1}, {0x99,0x6d}, {0xb8,0x74}, {0xb8,0x75}, {0xbb,0x45}, {0xa0,0xbe}, - {0xe3,0xa3}, {0xe3,0xa2}, {0xbb,0x44}, {0x8e,0xd6}, {0xa0,0xbc}, {0xa0,0xb5}, {0xe6,0xfb}, {0xa0,0xb4}, {0xe6,0xfc}, {0xea,0xe7}, - {0xc1,0x70}, {0xc1,0x6f}, {0xc1,0x6d}, {0xc1,0x6e}, {0xc1,0x71}, {0xf0,0x7c}, {0xc2,0xbf}, {0xc2,0xbe}, {0xf2,0xc0}, {0xf4,0xb2}, - {0xc5,0xa5}, {0xc5,0xa4}, {0xa6,0xd6}, {0x8b,0xe0}, {0xd1,0xfb}, {0xb8,0x77}, {0xb5,0xc2}, {0xb8,0x76}, {0xbb,0x46}, {0xa6,0xd7}, - {0xc9,0xa9}, {0xa6,0xd8}, {0xa6,0xd9}, {0xcd,0xab}, {0xcb,0x76}, {0xcb,0x77}, {0xa8,0x77}, {0xcb,0x74}, {0xa8,0x76}, {0xa8,0x79}, - {0xcb,0x75}, {0xa8,0x7b}, {0xa8,0x7a}, {0xcb,0x78}, {0xa8,0x78}, {0x89,0xb5}, {0xaa,0xd1}, {0xaa,0xcf}, {0xcd,0xad}, {0xaa,0xce}, - {0x8e,0xdd}, {0xaa,0xd3}, {0xaa,0xd5}, {0xaa,0xd2}, {0xcd,0xb0}, {0xcd,0xac}, {0xaa,0xd6}, {0xaa,0xd0}, {0xa8,0x7c}, {0xaa,0xd4}, - {0xcd,0xaf}, {0x9e,0x5d}, {0x99,0x71}, {0xcd,0xae}, {0xaa,0xcd}, {0x89,0xae}, {0x9d,0xe8}, {0xd0,0x5b}, {0xad,0x47}, {0xad,0x48}, - {0xd0,0x5d}, {0x95,0x65}, {0xd0,0x57}, {0xd0,0x5a}, {0xd0,0x63}, {0xd0,0x61}, {0xad,0x49}, {0xd0,0x67}, {0xad,0x4c}, {0xd0,0x64}, - {0xd0,0x5c}, {0xd0,0x59}, {0xdb,0x49}, {0xd0,0x62}, {0xad,0x44}, {0xd0,0x65}, {0xd0,0x56}, {0xd0,0x5f}, {0xad,0x46}, {0xad,0x4b}, - {0xd0,0x60}, {0xad,0x4f}, {0xad,0x4d}, {0xd0,0x58}, {0xad,0x4a}, {0xd0,0x5e}, {0xad,0x4e}, {0xad,0x45}, {0xd0,0x66}, {0x99,0x72}, - {0x8b,0x5c}, {0xaf,0xda}, {0xaf,0xe3}, {0xaf,0xd8}, {0xaf,0xd6}, {0xd3,0x6a}, {0xaf,0xde}, {0xaf,0xdb}, {0xd3,0x6c}, {0x89,0xb1}, - {0xaf,0xdd}, {0xd3,0x6b}, {0xd3,0x69}, {0xd3,0x6e}, {0xaf,0xe2}, {0xaf,0xe0}, {0xdb,0x48}, {0xd3,0x6f}, {0xd3,0x6d}, {0xaf,0xd7}, - {0xa0,0xc0}, {0xaf,0xd9}, {0xaf,0xdc}, {0x8e,0xdf}, {0xaf,0xdf}, {0x95,0x66}, {0xaf,0xe1}, {0x99,0x74}, {0x99,0x76}, {0x99,0x77}, - {0x99,0x79}, {0xd7,0x4e}, {0xb2,0xe4}, {0x9d,0xda}, {0xd7,0x45}, {0xd7,0x47}, {0x8e,0xe0}, {0xd7,0x48}, {0xd7,0x50}, {0xd7,0x4c}, - {0xd7,0x4a}, {0xd7,0x4d}, {0xd7,0x51}, {0xb2,0xe5}, {0xb2,0xe9}, {0xd7,0x46}, {0xd7,0x4f}, {0xb2,0xe7}, {0x93,0x5c}, {0xb2,0xe6}, - {0xd7,0x4b}, {0xd7,0x49}, {0xb2,0xe3}, {0xb2,0xe8}, {0x9d,0xe6}, {0x8b,0x5f}, {0x95,0x63}, {0xb5,0xc8}, {0xdb,0x51}, {0xdb,0x4f}, - {0xb5,0xca}, {0x95,0x67}, {0xdb,0x4a}, {0xdf,0xa1}, {0xb5,0xc9}, {0xdb,0x4e}, {0x9d,0xe3}, {0xdb,0x4b}, {0xb5,0xc5}, {0xb5,0xcb}, - {0xdb,0x50}, {0xb5,0xc7}, {0xdb,0x4d}, {0xbb,0x47}, {0xb5,0xc6}, {0xdb,0x4c}, {0xb5,0xcc}, {0xb5,0xc4}, {0xb5,0xc3}, {0x99,0x7c}, - {0x99,0x7d}, {0x99,0x7e}, {0xdf,0x77}, {0xdf,0x75}, {0xdf,0x7b}, {0xdf,0x73}, {0xdf,0xa2}, {0xdf,0x78}, {0xdf,0x72}, {0xb8,0x7b}, - {0xb8,0xa3}, {0xdf,0x7d}, {0xdf,0x76}, {0xb8,0x7e}, {0x8b,0x5b}, {0xb8,0x7c}, {0xdf,0x7e}, {0xb8,0x79}, {0xb8,0x78}, {0xdf,0x79}, - {0xb8,0x7d}, {0xb5,0xcd}, {0xdf,0x7c}, {0xdf,0x74}, {0xb8,0x7a}, {0xb8,0xa1}, {0xb8,0xa2}, {0x99,0xa3}, {0xbb,0x4c}, {0xbb,0x48}, - {0xbb,0x4d}, {0xe3,0xa6}, {0x99,0xa4}, {0xe3,0xa5}, {0xe3,0xa7}, {0xbb,0x4a}, {0xe3,0xa4}, {0xbb,0x4b}, {0xe3,0xaa}, {0xe3,0xa9}, - {0xe3,0xa8}, {0xbb,0x49}, {0x99,0xa6}, {0xe7,0x41}, {0xe7,0x44}, {0xbd,0xa8}, {0xe7,0x43}, {0xbd,0xa7}, {0xbd,0xa3}, {0xbd,0xa4}, - {0xbd,0xa5}, {0xe7,0x40}, {0xe6,0xfe}, {0xbd,0xa6}, {0xe7,0x42}, {0xe6,0xfd}, {0x99,0xa8}, {0xea,0xe9}, {0xea,0xf3}, {0xbf,0xb1}, - {0xbf,0xb0}, {0x8a,0xbe}, {0xea,0xed}, {0xea,0xef}, {0xea,0xea}, {0xea,0xee}, {0xea,0xe8}, {0xea,0xf1}, {0xbf,0xaf}, {0xea,0xf0}, - {0xea,0xec}, {0x9e,0x61}, {0xea,0xf2}, {0xea,0xeb}, {0xc1,0x74}, {0xed,0xe8}, {0xed,0xee}, {0xc1,0x78}, {0xc1,0x7a}, {0xc1,0x77}, - {0xc1,0x76}, {0x99,0xaa}, {0xc1,0x75}, {0xc1,0x73}, {0xed,0xe9}, {0xed,0xec}, {0xc1,0x72}, {0xed,0xed}, {0xa0,0xc8}, {0xc1,0x79}, - {0xed,0xeb}, {0xed,0xea}, {0xc2,0xc0}, {0xc2,0xc1}, {0xf0,0xa1}, {0xf0,0x7d}, {0xf0,0x7e}, {0xf2,0xc2}, {0xf2,0xc1}, {0xc3,0xbe}, - {0xf4,0xb4}, {0xc4,0xa4}, {0xf4,0xb3}, {0xf5,0xf0}, {0xf7,0x45}, {0xc5,0xa6}, {0xf9,0x43}, {0xf9,0x44}, {0xc5,0xd8}, {0xa6,0xda}, - {0x99,0xab}, {0xaa,0xd7}, {0xdb,0x52}, {0xbb,0x4e}, {0xc1,0x7b}, {0xed,0xef}, {0xa6,0xdb}, {0xaf,0xe5}, {0xaf,0xe4}, {0xdb,0x53}, - {0xfe,0xc4}, {0xea,0xf4}, {0xa6,0xdc}, {0xad,0x50}, {0x98,0xc2}, {0xdb,0x54}, {0xdb,0x55}, {0xdb,0x56}, {0xbb,0x4f}, {0xbf,0xb2}, - {0xa6,0xdd}, {0xaa,0xd8}, {0xd0,0x68}, {0xaf,0xe6}, {0xd3,0x70}, {0xb2,0xea}, {0xdb,0x57}, {0xb8,0xa4}, {0xbb,0x50}, {0xbf,0xb3}, - {0xc1,0x7c}, {0xc2,0xc2}, {0xf4,0xb5}, {0xa6,0xde}, {0xaa,0xd9}, {0xaf,0xe7}, {0xd7,0x52}, {0xb5,0xce}, {0xbb,0x51}, {0xe3,0xab}, - {0xe7,0x45}, {0x8e,0xe8}, {0xa0,0xba}, {0xa6,0xdf}, {0xb5,0xcf}, {0xdf,0xa3}, {0xbb,0x52}, {0xa6,0xe0}, {0xcd,0xb1}, {0xd0,0x69}, - {0xad,0x51}, {0xd3,0x72}, {0xfd,0x77}, {0xaf,0xea}, {0x8e,0xee}, {0xaf,0xe8}, {0xaf,0xe9}, {0xaf,0xeb}, {0x9e,0xbf}, {0xd3,0x71}, - {0xd7,0x57}, {0xd7,0x54}, {0xd7,0x56}, {0xb2,0xeb}, {0xb2,0xed}, {0xb2,0xec}, {0xd7,0x53}, {0xb2,0xee}, {0xd7,0x55}, {0xdb,0x58}, - {0xdb,0x59}, {0x89,0xc2}, {0xdb,0x5a}, {0xdf,0xa6}, {0xdf,0xa7}, {0xdf,0xa5}, {0xdf,0xa8}, {0xb8,0xa5}, {0xdf,0xa4}, {0xbb,0x53}, - {0xe7,0x4a}, {0xe7,0x46}, {0xe7,0x49}, {0xe7,0x4b}, {0xe7,0x48}, {0xe7,0x47}, {0x99,0xac}, {0xea,0xf5}, {0xea,0xf6}, {0xea,0xf7}, - {0xbf,0xb4}, {0xbf,0xb5}, {0xed,0xf1}, {0xed,0xf0}, {0xed,0xf2}, {0xf0,0xa3}, {0xf0,0xa2}, {0xf2,0xc4}, {0x95,0x6b}, {0xf2,0xc5}, - {0xf2,0xc3}, {0x95,0x6c}, {0xc4,0xa5}, {0xf4,0xb6}, {0xf4,0xb7}, {0xf7,0x46}, {0xf7,0xef}, {0xf8,0xbb}, {0xa6,0xe1}, {0xa8,0x7d}, - {0xc1,0x7d}, {0xa6,0xe2}, {0xd7,0x58}, {0xdb,0x5b}, {0x99,0xaf}, {0xc6,0x41}, {0xca,0x4a}, {0x99,0x4a}, {0x89,0x76}, {0x8f,0x48}, - {0xca,0x4b}, {0xca,0x4d}, {0xa6,0xe3}, {0xca,0x4e}, {0xca,0x4c}, {0xcb,0xa2}, {0xcb,0xa3}, {0xcb,0x7b}, {0xfb,0xee}, {0xcb,0xa1}, - {0xa8,0xa1}, {0xa8,0xa2}, {0xcb,0x7c}, {0xcb,0x7a}, {0xcb,0x79}, {0xcb,0x7d}, {0xa8,0x7e}, {0xcb,0x7e}, {0xd0,0x6a}, {0xcd,0xb6}, - {0xaa,0xdc}, {0xcd,0xb5}, {0xcd,0xb7}, {0xaa,0xdb}, {0xcd,0xbc}, {0xaa,0xdf}, {0xcd,0xb2}, {0xcd,0xc0}, {0xcd,0xc6}, {0xaa,0xe6}, - {0xcd,0xc3}, {0xaa,0xe3}, {0x99,0xae}, {0xcd,0xb9}, {0xcd,0xbf}, {0xcd,0xc1}, {0x8e,0xfb}, {0xcd,0xb4}, {0xaa,0xe2}, {0xaa,0xdd}, - {0xcd,0xba}, {0xaa,0xe4}, {0xaa,0xe7}, {0xaa,0xe1}, {0xaa,0xda}, {0xcd,0xbe}, {0xcd,0xb8}, {0xcd,0xc5}, {0xaa,0xe9}, {0xaa,0xe5}, - {0xaa,0xe0}, {0xcd,0xbd}, {0xaf,0xec}, {0xcd,0xbb}, {0xaa,0xde}, {0xaa,0xe8}, {0x8c,0xd0}, {0xcd,0xb3}, {0xcd,0xc2}, {0xcd,0xc4}, - {0x8b,0x52}, {0x99,0xb0}, {0x89,0x77}, {0x8f,0x41}, {0xad,0x62}, {0xad,0x5c}, {0xad,0x64}, {0xad,0x61}, {0xd0,0x71}, {0xd0,0x74}, - {0xad,0x5d}, {0x99,0xb1}, {0xd0,0x6b}, {0xad,0x56}, {0xad,0x60}, {0xad,0x63}, {0xad,0x65}, {0xd0,0xa2}, {0xd0,0x77}, {0x8f,0x49}, - {0xad,0x55}, {0xd0,0xa1}, {0xad,0x59}, {0xad,0x57}, {0xad,0x52}, {0xd0,0x6f}, {0xd0,0x7e}, {0xd0,0x73}, {0xd0,0x76}, {0xd0,0xa5}, - {0xfa,0x4d}, {0xad,0x66}, {0xd0,0x7d}, {0xad,0x5e}, {0xd0,0x78}, {0xd0,0xa4}, {0xd0,0x75}, {0xd0,0x79}, {0xd0,0x7c}, {0x9d,0xe4}, - {0x8c,0xb5}, {0xd0,0x6d}, {0xd0,0xa3}, {0xd0,0x7b}, {0xfb,0xe9}, {0x9b,0x54}, {0xd0,0x6c}, {0x99,0xb2}, {0xd0,0x70}, {0xad,0x5f}, - {0xad,0x5a}, {0xad,0x53}, {0xad,0x58}, {0xad,0x54}, {0xad,0x67}, {0xd0,0x6e}, {0xd3,0xa5}, {0xad,0x5b}, {0x9e,0x68}, {0xd0,0x7a}, - {0xce,0x41}, {0xd3,0xa8}, {0xaf,0xfa}, {0x8f,0x4a}, {0xd3,0x76}, {0x8f,0x42}, {0xd3,0xa3}, {0xd3,0x7d}, {0x8f,0x51}, {0xd3,0xb2}, - {0xd3,0xaa}, {0xd3,0x7e}, {0xd3,0xa9}, {0xd3,0x78}, {0xd3,0x7c}, {0xd3,0xb5}, {0xaf,0xfd}, {0xd3,0xad}, {0xd3,0xa4}, {0xaf,0xed}, - {0xd3,0xb3}, {0xd3,0x74}, {0xd3,0xac}, {0xaf,0xfc}, {0xaf,0xf7}, {0xd3,0x73}, {0xaf,0xf5}, {0xaf,0xf4}, {0xaf,0xf9}, {0xd3,0xab}, - {0xaf,0xf1}, {0xaf,0xf8}, {0xd0,0x72}, {0xdb,0x5c}, {0xd3,0xa6}, {0x98,0x46}, {0xd3,0x7a}, {0xaf,0xfb}, {0xd3,0x7b}, {0xd3,0xa1}, - {0xaf,0xfe}, {0xd3,0x75}, {0xd3,0xaf}, {0xd3,0xae}, {0xd3,0xb6}, {0xaf,0xf3}, {0xaf,0xf0}, {0xd3,0xb4}, {0xd3,0xb0}, {0xd3,0xa7}, - {0xd3,0xa2}, {0xaf,0xf6}, {0xaf,0xf2}, {0xd3,0x77}, {0xaf,0xee}, {0xd3,0xb1}, {0xaf,0xef}, {0xd3,0x79}, {0x99,0xb4}, {0x8e,0xf5}, - {0xfd,0x55}, {0x9c,0xcd}, {0x89,0x78}, {0xd7,0x5e}, {0xd7,0x60}, {0xd7,0x65}, {0xd7,0x79}, {0xb2,0xfc}, {0xb2,0xf2}, {0xd7,0x5d}, - {0xb2,0xfd}, {0xb2,0xfe}, {0xd7,0x68}, {0xd7,0x6f}, {0xd7,0x75}, {0xd7,0x62}, {0xd7,0x69}, {0x8f,0x53}, {0xb3,0x40}, {0xd7,0x77}, - {0xd7,0x72}, {0xb2,0xfa}, {0xb2,0xf8}, {0xd7,0x6e}, {0xd7,0x6a}, {0xd7,0x5c}, {0xb2,0xef}, {0xd7,0x61}, {0xd7,0x59}, {0x8f,0x6f}, - {0xb2,0xf7}, {0xb2,0xf9}, {0xd7,0x66}, {0xd7,0x63}, {0xb2,0xf4}, {0xd7,0x73}, {0xb2,0xf1}, {0xd7,0x64}, {0xd7,0x7a}, {0xd7,0x6c}, - {0x8e,0x63}, {0xd7,0x6b}, {0xb2,0xf0}, {0xb2,0xfb}, {0xb2,0xf3}, {0xd7,0x5a}, {0xd7,0x5f}, {0xd7,0x70}, {0xd7,0x76}, {0xb3,0x41}, - {0xd7,0x5b}, {0xd7,0x67}, {0xd7,0x6d}, {0xb2,0xf6}, {0x8f,0x56}, {0xd7,0x78}, {0xd7,0x71}, {0xd7,0x74}, {0xfe,0x76}, {0xb2,0xf5}, - {0x9f,0xc6}, {0xdb,0x6c}, {0xdb,0x60}, {0xb5,0xd7}, {0xdb,0x7d}, {0xdb,0xa7}, {0xdb,0xaa}, {0xb5,0xd5}, {0xdb,0x68}, {0xdb,0xa3}, - {0xdb,0x69}, {0xdb,0x77}, {0xb5,0xe2}, {0xdb,0x73}, {0xb5,0xdf}, {0xfa,0xac}, {0xdb,0x74}, {0xdb,0x5d}, {0xdb,0xa4}, {0x8f,0x58}, - {0xb5,0xe8}, {0xdb,0xa1}, {0xdb,0x75}, {0xdb,0xac}, {0xdb,0x70}, {0xdf,0xc8}, {0xdb,0xaf}, {0xb5,0xe6}, {0xdb,0x6e}, {0xdb,0x7a}, - {0xb5,0xe9}, {0xb5,0xd4}, {0xdb,0x72}, {0xdb,0xad}, {0xdb,0x6b}, {0xdb,0x64}, {0xdb,0x6f}, {0xdb,0x63}, {0xdb,0x61}, {0xb5,0xd0}, - {0xdb,0xa5}, {0xdb,0x6a}, {0xdb,0xa8}, {0x98,0x48}, {0xdb,0xa9}, {0xb5,0xd8}, {0xb5,0xdd}, {0xb5,0xd9}, {0xb5,0xe1}, {0xdb,0x7e}, - {0xb5,0xda}, {0xdb,0x76}, {0xdb,0x66}, {0xb5,0xd2}, {0xdb,0x5e}, {0xdb,0xa2}, {0xdb,0xab}, {0xdb,0x65}, {0xb5,0xe0}, {0xdb,0xb0}, - {0xdb,0x71}, {0xdb,0x6d}, {0xb5,0xd1}, {0xb5,0xe5}, {0x99,0xb7}, {0xdb,0x7c}, {0xb5,0xe7}, {0xdb,0x78}, {0xb5,0xdc}, {0xb5,0xd6}, - {0xb5,0xde}, {0xb5,0xd3}, {0xb5,0xe4}, {0xdb,0x79}, {0xdb,0x67}, {0xdb,0x7b}, {0xdb,0x62}, {0xdb,0xa6}, {0x96,0x65}, {0xfa,0x6c}, - {0x9d,0xe7}, {0xdb,0xae}, {0x9e,0x62}, {0x96,0xcc}, {0x8e,0x67}, {0xdb,0x5f}, {0xfc,0x75}, {0x98,0x7e}, {0xdf,0xc7}, {0xdf,0xdd}, - {0xb8,0x55}, {0xdf,0xcc}, {0xfd,0xb9}, {0xdf,0xca}, {0xdf,0xb5}, {0xb8,0xa9}, {0xdf,0xc5}, {0xdf,0xd9}, {0xdf,0xc1}, {0xb8,0xb1}, - {0xdf,0xd8}, {0xdf,0xbf}, {0xb5,0xe3}, {0xdf,0xcf}, {0xdf,0xc0}, {0xdf,0xd6}, {0xb8,0xb0}, {0xb8,0xa8}, {0x97,0xfc}, {0xdf,0xaa}, - {0xdf,0xb2}, {0xdf,0xcb}, {0xdf,0xc3}, {0xdf,0xdc}, {0xdf,0xc6}, {0xb8,0xb6}, {0xdf,0xd7}, {0x98,0xf9}, {0xb8,0xad}, {0x8f,0x66}, - {0xdf,0xc9}, {0xdf,0xd1}, {0xdf,0xb6}, {0xdf,0xd0}, {0xdf,0xe1}, {0xdf,0xb1}, {0xdf,0xd2}, {0x95,0x6e}, {0xdf,0xdf}, {0x92,0x45}, - {0xdf,0xab}, {0xb5,0xdb}, {0x8f,0x60}, {0xdf,0xb9}, {0xdf,0xb8}, {0xb8,0xaf}, {0x9e,0xd1}, {0xdf,0xbc}, {0xdf,0xbe}, {0xdf,0xcd}, - {0xdf,0xde}, {0xb8,0xb2}, {0xfe,0xcd}, {0xb8,0xb3}, {0x99,0xb9}, {0xdf,0xb0}, {0xb8,0xab}, {0xdf,0xb4}, {0xdf,0xda}, {0xb8,0xb4}, - {0xb8,0xac}, {0xb8,0xae}, {0xb8,0xb5}, {0xdf,0xe0}, {0xdf,0xd3}, {0xdf,0xce}, {0x8f,0x62}, {0x97,0x4c}, {0xdf,0xbb}, {0xdf,0xba}, - {0xb8,0xaa}, {0xdf,0xac}, {0xb8,0xa7}, {0xdf,0xc4}, {0xdf,0xad}, {0xdf,0xc2}, {0xdf,0xb7}, {0xdf,0xdb}, {0x91,0xc7}, {0x95,0x5f}, - {0xb8,0xa6}, {0xdf,0xb3}, {0x99,0xbb}, {0xdf,0xaf}, {0xdf,0xd5}, {0xdf,0xae}, {0xbb,0x60}, {0xe3,0xd3}, {0x8e,0x6d}, {0x8f,0x71}, - {0xe3,0xc2}, {0x94,0xcb}, {0xe3,0xac}, {0xe3,0xca}, {0xbb,0x58}, {0xe3,0xbb}, {0xe3,0xc5}, {0xbb,0x5b}, {0xe3,0xbe}, {0xbb,0x59}, - {0xe3,0xaf}, {0xe3,0xcd}, {0xe3,0xae}, {0xe3,0xc1}, {0x95,0xb1}, {0xe3,0xad}, {0xe3,0xbf}, {0xe3,0xc8}, {0xe3,0xc6}, {0xe3,0xba}, - {0xe3,0xb5}, {0xe3,0xb3}, {0x9a,0xf2}, {0xe3,0xb4}, {0xe3,0xc7}, {0xe3,0xd2}, {0xe3,0xbc}, {0xbb,0x5a}, {0xe3,0xb7}, {0xe3,0xcb}, - {0xbb,0x5d}, {0xe3,0xb6}, {0xe3,0xb0}, {0xe3,0xc0}, {0xbb,0x61}, {0x96,0xc3}, {0x99,0xbd}, {0xbb,0x55}, {0xbb,0x5e}, {0xe3,0xb8}, - {0xe3,0xb2}, {0xbb,0x57}, {0xdf,0xd4}, {0xbb,0x56}, {0xe3,0xc3}, {0xbb,0x54}, {0xbb,0x63}, {0xbb,0x5c}, {0xe3,0xc4}, {0xe3,0xb9}, - {0xe3,0xb1}, {0xe3,0xcc}, {0xe3,0xbd}, {0xbb,0x62}, {0xe3,0xd0}, {0xbb,0x5f}, {0xe3,0xcf}, {0xe3,0xc9}, {0xe3,0xce}, {0xa0,0xcf}, - {0xe3,0xd1}, {0x8f,0x6d}, {0x99,0xbe}, {0x8e,0xf4}, {0x8f,0x72}, {0x95,0xe4}, {0xe7,0x73}, {0xe7,0x74}, {0xe7,0x67}, {0xe7,0x66}, - {0xe7,0x62}, {0xbd,0xb4}, {0xbd,0xac}, {0xe7,0x76}, {0xe7,0x75}, {0xdf,0xa9}, {0xe7,0x5f}, {0xe7,0x63}, {0xe7,0x5d}, {0xe7,0x70}, - {0xe7,0x61}, {0x99,0xbf}, {0xe7,0x77}, {0xe7,0x5a}, {0xe7,0x58}, {0xe7,0x64}, {0xe7,0x6e}, {0xe7,0x69}, {0xbd,0xb6}, {0xe7,0x4f}, - {0xe7,0x6d}, {0x92,0x42}, {0xfb,0xa5}, {0xbd,0xb7}, {0xdf,0xbd}, {0xe7,0x5b}, {0xe7,0x52}, {0xe7,0x55}, {0xe7,0x7b}, {0xe7,0x5c}, - {0xe7,0x53}, {0xe7,0x51}, {0xe7,0x4e}, {0x99,0xc0}, {0xbd,0xb0}, {0xe7,0x65}, {0xbd,0xaf}, {0xbd,0xb3}, {0xe7,0x60}, {0xe7,0x68}, - {0xbd,0xa9}, {0xe7,0x78}, {0xe7,0x7c}, {0xbd,0xab}, {0xe7,0x57}, {0xe7,0x6b}, {0xe7,0x6f}, {0xe7,0x54}, {0xe7,0x79}, {0xbd,0xb2}, - {0xbd,0xb1}, {0xe7,0x4c}, {0xbd,0xb5}, {0xe7,0x72}, {0xe7,0x56}, {0xe7,0x6a}, {0xe7,0x50}, {0xe7,0x5e}, {0xe7,0x59}, {0xbd,0xad}, - {0xbd,0xae}, {0xe7,0x6c}, {0xe7,0x7d}, {0xe7,0x7a}, {0xe7,0x71}, {0xfd,0xb4}, {0x8f,0x77}, {0x99,0xc1}, {0xe7,0x4d}, {0xbd,0xaa}, - {0xeb,0x49}, {0xeb,0x40}, {0xeb,0x43}, {0xfa,0xb9}, {0xbf,0xbb}, {0xeb,0x45}, {0xea,0xf9}, {0xeb,0x41}, {0xeb,0x47}, {0xbf,0xb8}, - {0xbf,0xbc}, {0xbf,0xb6}, {0x8f,0x40}, {0xfa,0x44}, {0xea,0xfb}, {0xeb,0x4c}, {0xeb,0x46}, {0x99,0xc2}, {0xea,0xfc}, {0xeb,0x55}, - {0xeb,0x4f}, {0xea,0xf8}, {0xee,0x46}, {0xea,0xfe}, {0xbf,0xb7}, {0x8f,0x5c}, {0xeb,0x4a}, {0xeb,0x54}, {0xbf,0xbf}, {0x8c,0xbd}, - {0xeb,0x51}, {0xea,0xfd}, {0xeb,0x44}, {0xeb,0x48}, {0xeb,0x42}, {0xeb,0x56}, {0xeb,0x53}, {0xeb,0x50}, {0xbf,0xb9}, {0xbf,0xba}, - {0xbf,0xbe}, {0xea,0xfa}, {0xeb,0x57}, {0xbf,0xbd}, {0xeb,0x4d}, {0x99,0xc4}, {0x99,0xc5}, {0xeb,0x4b}, {0x8f,0x7b}, {0xeb,0x4e}, - {0xee,0x53}, {0xee,0x40}, {0xee,0x45}, {0xee,0x52}, {0xee,0x44}, {0xed,0xfb}, {0xee,0x41}, {0xc1,0xa2}, {0xed,0xf4}, {0xee,0x4d}, - {0xee,0x4f}, {0xed,0xf3}, {0xc1,0xa1}, {0xee,0x51}, {0xee,0x49}, {0xc1,0xa8}, {0xee,0x50}, {0xee,0x42}, {0xc1,0xaa}, {0xed,0xf9}, - {0xeb,0x52}, {0xee,0x4a}, {0xee,0x47}, {0xed,0xf5}, {0xee,0x55}, {0xc1,0xa4}, {0xc1,0xa5}, {0xed,0xf7}, {0xee,0x48}, {0x8c,0xb6}, - {0xee,0x54}, {0xee,0x4b}, {0xed,0xfd}, {0xc1,0xa7}, {0xc1,0xa3}, {0xee,0x4c}, {0xed,0xfe}, {0xee,0x56}, {0xed,0xf8}, {0xee,0x43}, - {0xee,0x4e}, {0xed,0xfa}, {0xed,0xfc}, {0xc2,0xcb}, {0xed,0xf6}, {0xc1,0xa9}, {0xc2,0xc4}, {0xc1,0x7e}, {0xc1,0xa6}, {0xc2,0xc8}, - {0xf0,0xb3}, {0xf0,0xa9}, {0xf0,0xa4}, {0xf0,0xaa}, {0xf0,0xb4}, {0xf0,0xb8}, {0xf0,0xb7}, {0xc2,0xca}, {0xc2,0xc9}, {0xf0,0xab}, - {0xf0,0xb9}, {0xf0,0xae}, {0xf0,0xa6}, {0x8f,0xa3}, {0xf0,0xa8}, {0xf0,0xa7}, {0xf0,0xad}, {0xf0,0xb2}, {0xf0,0xa5}, {0xf0,0xac}, - {0xf0,0xb1}, {0xc2,0xc7}, {0xf0,0xaf}, {0xc2,0xc5}, {0xf0,0xb0}, {0xc2,0xc3}, {0xc2,0xc6}, {0xf2,0xd5}, {0xf0,0xb5}, {0xc3,0xc2}, - {0x8c,0xce}, {0xf2,0xcd}, {0xf2,0xd1}, {0xf2,0xc9}, {0xf2,0xcc}, {0xf2,0xd4}, {0xc3,0xc0}, {0xf2,0xd9}, {0xf2,0xd2}, {0x99,0xc6}, - {0xf2,0xca}, {0xf2,0xda}, {0xf2,0xd3}, {0xc3,0xc3}, {0xc3,0xc4}, {0xf2,0xd7}, {0xf2,0xcb}, {0xc3,0xbf}, {0xc3,0xc1}, {0xf2,0xc6}, - {0xf2,0xce}, {0xf2,0xc8}, {0x96,0xcd}, {0xf2,0xd8}, {0xf2,0xd6}, {0xf2,0xc7}, {0xf2,0xcf}, {0xf4,0xbe}, {0xc3,0xc5}, {0xf2,0xd0}, - {0xc4,0xa7}, {0xc4,0xa9}, {0xc4,0xa6}, {0x96,0xc7}, {0xf4,0xc3}, {0xf4,0xbb}, {0xf4,0xb9}, {0xf4,0xbd}, {0xf4,0xba}, {0x8f,0xa5}, - {0xf4,0xbf}, {0xf4,0xc1}, {0xc4,0xaa}, {0xc4,0xac}, {0xf4,0xc0}, {0xc4,0xad}, {0xc4,0xab}, {0xf4,0xc2}, {0xfa,0xbb}, {0x8c,0x61}, - {0x95,0x70}, {0xc4,0xa8}, {0x93,0x68}, {0x8f,0x7e}, {0xc4,0xf4}, {0xf5,0xf1}, {0xf5,0xf7}, {0xc4,0xf6}, {0xf4,0xbc}, {0xf5,0xf6}, - {0xf5,0xfd}, {0xf5,0xf4}, {0xf5,0xfb}, {0xf5,0xfa}, {0xf4,0xb8}, {0xf5,0xf5}, {0xf0,0xb6}, {0xf5,0xfe}, {0xf5,0xf3}, {0xf5,0xf8}, - {0x8f,0xaa}, {0xf5,0xfc}, {0xf5,0xf2}, {0xf7,0x4a}, {0xc4,0xf5}, {0xf5,0xf9}, {0xa0,0x50}, {0xf7,0xf4}, {0xf7,0x4b}, {0xf7,0x49}, - {0xf7,0x47}, {0xf7,0x48}, {0xf7,0x4c}, {0xc5,0xd9}, {0xf7,0xf2}, {0xf7,0xf0}, {0xf7,0xf5}, {0xf7,0xf3}, {0xf7,0xf6}, {0xc5,0xda}, - {0xf7,0xf1}, {0x90,0xd3}, {0xf8,0xbc}, {0x95,0x56}, {0xf9,0x45}, {0xf9,0x46}, {0xf9,0x47}, {0xf9,0xc7}, {0xf9,0xbd}, {0xca,0x4f}, - {0xaa,0xea}, {0xad,0x68}, {0xd3,0xb8}, {0xd3,0xb7}, {0xb0,0x40}, {0xb3,0x42}, {0xd7,0x7c}, {0xd7,0x7b}, {0xb5,0xea}, {0xb8,0xb8}, - {0xb8,0xb7}, {0xb8,0xb9}, {0xe3,0xd4}, {0xe7,0x7e}, {0xeb,0x58}, {0xeb,0x5a}, {0xeb,0x59}, {0xc1,0xab}, {0xee,0x57}, {0xf0,0xba}, - {0xf9,0xa5}, {0xa6,0xe4}, {0x8f,0xb8}, {0xcd,0xc9}, {0xcd,0xca}, {0xcd,0xc8}, {0xcd,0xc7}, {0xaa,0xeb}, {0x99,0xc8}, {0xd0,0xa9}, - {0xd0,0xa7}, {0xd0,0xa6}, {0xad,0x69}, {0xad,0x6b}, {0xad,0x6a}, {0xd0,0xa8}, {0x8f,0xaf}, {0xd3,0xc4}, {0xd3,0xc1}, {0xd3,0xbf}, - {0xb0,0x41}, {0xd3,0xc2}, {0xb0,0x46}, {0xd3,0xbc}, {0xd3,0xcb}, {0xd3,0xcd}, {0xd3,0xbd}, {0x99,0xc9}, {0xb0,0x43}, {0xd3,0xce}, - {0xd3,0xc9}, {0xd3,0xbb}, {0xd3,0xc0}, {0xd3,0xca}, {0xd3,0xc6}, {0xd3,0xc3}, {0xb0,0x48}, {0xd3,0xcc}, {0xd3,0xbe}, {0x95,0x79}, - {0xd3,0xc7}, {0xd3,0xb9}, {0xb0,0x47}, {0xb0,0x44}, {0xd3,0xc5}, {0xd3,0xc8}, {0xd3,0xba}, {0xb0,0x45}, {0xb0,0x42}, {0x9f,0x49}, - {0xb3,0x4c}, {0xd7,0xa5}, {0xb3,0x4b}, {0x99,0xca}, {0xd7,0xa8}, {0xd7,0xab}, {0xb3,0x48}, {0xb3,0x46}, {0xd7,0x7e}, {0xd7,0xa9}, - {0xd7,0xa7}, {0xd7,0xa4}, {0xd7,0xac}, {0xd7,0xad}, {0xd7,0xaf}, {0xd7,0xb0}, {0xd7,0x7d}, {0xb3,0x45}, {0xd7,0xa2}, {0xd7,0xa1}, - {0xd7,0xae}, {0xb3,0x47}, {0xd7,0xa3}, {0xb3,0x49}, {0xb3,0x44}, {0xd7,0xa6}, {0xb3,0x4d}, {0xb3,0x4a}, {0xd7,0xaa}, {0xb5,0xf1}, - {0xdb,0xbf}, {0xdb,0xb4}, {0xb5,0xee}, {0xdf,0xe7}, {0xdb,0xbd}, {0xdb,0xb1}, {0xb5,0xec}, {0xdb,0xb6}, {0xb5,0xef}, {0xdb,0xba}, - {0xdb,0xb8}, {0xb5,0xf2}, {0xb5,0xeb}, {0xdb,0xb2}, {0xdb,0xb5}, {0xb5,0xf0}, {0xdb,0xb3}, {0xdb,0xbe}, {0xdb,0xbc}, {0xdb,0xb7}, - {0xdb,0xb9}, {0xdb,0xbb}, {0xb5,0xed}, {0x99,0xcb}, {0xdf,0xe8}, {0xdf,0xee}, {0xdf,0xe4}, {0xdf,0xea}, {0xb8,0xba}, {0xdf,0xe6}, - {0xb8,0xc0}, {0xb8,0xbf}, {0xb8,0xbe}, {0xdf,0xed}, {0xb8,0xc1}, {0xb8,0xc2}, {0xdf,0xe3}, {0xdf,0xf0}, {0xb8,0xc3}, {0xb8,0xbd}, - {0xb8,0xbc}, {0xdf,0xec}, {0xb8,0xc4}, {0xdf,0xe2}, {0xdf,0xe5}, {0xdf,0xef}, {0xdf,0xeb}, {0xe3,0xf4}, {0xe3,0xe9}, {0xb8,0xbb}, - {0xbb,0x6a}, {0xe3,0xdd}, {0xe3,0xf2}, {0xe3,0xde}, {0xbb,0x65}, {0xe3,0xdb}, {0xe3,0xe4}, {0xe3,0xdc}, {0xbb,0x67}, {0xe3,0xd6}, - {0xe3,0xf1}, {0xbb,0x68}, {0xe3,0xee}, {0xe3,0xef}, {0xe3,0xd7}, {0xbb,0x6d}, {0xe3,0xe6}, {0xe3,0xe0}, {0xe3,0xe7}, {0xe3,0xda}, - {0xe3,0xf3}, {0xe3,0xeb}, {0xe3,0xe5}, {0xe3,0xd5}, {0xbb,0x69}, {0xe3,0xec}, {0xbb,0x6c}, {0xe3,0xf0}, {0xe3,0xea}, {0xbb,0x66}, - {0xe3,0xe8}, {0xe3,0xe2}, {0xbb,0x64}, {0xe3,0xd9}, {0xe3,0xe1}, {0xe3,0xed}, {0xe3,0xdf}, {0xe3,0xe3}, {0xbd,0xc1}, {0xdf,0xe9}, - {0xe7,0xb2}, {0xe7,0xbb}, {0xe7,0xb1}, {0xe7,0xad}, {0xe7,0xaa}, {0xbd,0xc2}, {0xe7,0xa8}, {0xbb,0x6b}, {0xe7,0xa1}, {0xbd,0xc0}, - {0xe7,0xa7}, {0xbd,0xbf}, {0xe7,0xac}, {0xe7,0xa9}, {0xe7,0xb9}, {0xe7,0xb4}, {0xe7,0xae}, {0xe7,0xb3}, {0xbd,0xbb}, {0xe7,0xab}, - {0xe7,0xbe}, {0xe7,0xa2}, {0xe7,0xa3}, {0xe7,0xba}, {0xbd,0xbc}, {0xe7,0xbf}, {0xbd,0xbe}, {0xe7,0xc0}, {0xe7,0xb0}, {0xe3,0xd8}, - {0xe7,0xb6}, {0xe7,0xaf}, {0xe7,0xb8}, {0xe7,0xb5}, {0x9d,0xd5}, {0x8f,0xb0}, {0xe7,0xa6}, {0xbd,0xb9}, {0xe7,0xbd}, {0xbd,0xba}, - {0xe7,0xa4}, {0xbd,0xbd}, {0xeb,0x64}, {0xe7,0xb7}, {0xe7,0xbc}, {0xfa,0x7a}, {0xeb,0x61}, {0xbd,0xb8}, {0xbf,0xc0}, {0xeb,0x6b}, - {0xeb,0x67}, {0x9e,0x5f}, {0xeb,0x65}, {0xeb,0x60}, {0xeb,0x6f}, {0x99,0xcd}, {0xa0,0xc9}, {0xbf,0xc4}, {0xeb,0x5c}, {0xeb,0x68}, - {0xeb,0x69}, {0xeb,0x5f}, {0xeb,0x5e}, {0xeb,0x6c}, {0xeb,0x62}, {0xeb,0x5d}, {0xeb,0x63}, {0xeb,0x6e}, {0xeb,0x5b}, {0xeb,0x6d}, - {0xeb,0x6a}, {0xbf,0xc2}, {0xbf,0xc1}, {0xbf,0xc3}, {0xeb,0x66}, {0xf0,0xcb}, {0x9a,0xdb}, {0xa0,0xc6}, {0xee,0x59}, {0xc1,0xb1}, - {0xee,0x5d}, {0xee,0x5a}, {0xee,0x61}, {0xee,0x67}, {0xee,0x5c}, {0x8f,0xb4}, {0xee,0x70}, {0xc1,0xae}, {0xee,0x6a}, {0xee,0x5f}, - {0xee,0x6b}, {0xee,0x66}, {0xee,0x6d}, {0xee,0x5e}, {0xc1,0xb3}, {0xc1,0xb2}, {0xee,0x60}, {0xee,0x6e}, {0xee,0x58}, {0xee,0x6c}, - {0xc1,0xac}, {0xa0,0xd7}, {0xee,0x64}, {0xee,0x63}, {0xee,0x68}, {0xee,0x5b}, {0xc1,0xb0}, {0xc1,0xb4}, {0xee,0x62}, {0xee,0x69}, - {0xc1,0xb5}, {0xee,0x65}, {0xa0,0xc7}, {0xc1,0xad}, {0xc1,0xaf}, {0xf0,0xc7}, {0xf0,0xc5}, {0xa0,0x43}, {0xf0,0xcc}, {0xf0,0xc9}, - {0xf0,0xcd}, {0x8f,0xb5}, {0xf0,0xbe}, {0xf0,0xc6}, {0xf0,0xd1}, {0xee,0x6f}, {0xf0,0xc2}, {0xc2,0xcf}, {0xe7,0xa5}, {0xf0,0xbd}, - {0xf0,0xca}, {0xf0,0xc4}, {0xf0,0xc1}, {0xf0,0xbc}, {0xf0,0xbb}, {0xf0,0xd0}, {0xf0,0xc0}, {0xf0,0xbf}, {0xc2,0xcd}, {0xf0,0xc8}, - {0x8f,0xb2}, {0xc2,0xcc}, {0xc2,0xce}, {0xf0,0xc3}, {0xf0,0xcf}, {0xa0,0x61}, {0xf2,0xde}, {0xf2,0xdf}, {0xc3,0xc9}, {0xf2,0xdc}, - {0xc3,0xc6}, {0xf2,0xe4}, {0xc3,0xca}, {0xf2,0xe6}, {0xf2,0xdb}, {0xf0,0xce}, {0xf2,0xe8}, {0xf2,0xdd}, {0x9e,0x5e}, {0xc3,0xc7}, - {0xf2,0xe3}, {0xf2,0xe5}, {0xf2,0xe0}, {0xf2,0xe7}, {0xf2,0xe2}, {0xf2,0xe1}, {0xc3,0xc8}, {0x8f,0xb6}, {0xf4,0xc5}, {0xf4,0xc6}, - {0xf4,0xc8}, {0xc4,0xae}, {0xc4,0xaf}, {0xf4,0xc9}, {0xf4,0xc7}, {0x9f,0xe8}, {0xf4,0xc4}, {0xf6,0x42}, {0xf6,0x45}, {0xf6,0x41}, - {0xc4,0xfa}, {0xf6,0x43}, {0xc4,0xf9}, {0xc4,0xf8}, {0xc4,0xf7}, {0xf6,0x44}, {0xf7,0x51}, {0xf7,0x4f}, {0x9c,0xb2}, {0xf7,0x4e}, - {0xf6,0x40}, {0xf7,0x50}, {0xf6,0x46}, {0xf7,0x4d}, {0x95,0x7c}, {0xf7,0xf9}, {0xf7,0xd7}, {0xf7,0xf7}, {0xc5,0xdb}, {0xf7,0xf8}, - {0xf7,0xfa}, {0xf8,0xbf}, {0xc5,0xfa}, {0xf8,0xbe}, {0xf8,0xbd}, {0xc5,0xfb}, {0xc6,0x5a}, {0xf9,0x6e}, {0xf9,0xa7}, {0xf9,0xa6}, - {0xf9,0xa8}, {0xa6,0xe5}, {0xd0,0xaa}, {0x9f,0xc7}, {0xd3,0xcf}, {0xd3,0xd0}, {0x8f,0xbb}, {0x8f,0xbc}, {0xdb,0xc0}, {0xf6,0x47}, - {0xf8,0xc0}, {0xa6,0xe6}, {0xad,0x6c}, {0xd0,0xab}, {0x8f,0xec}, {0xd7,0xb1}, {0xb3,0x4e}, {0xdb,0xc2}, {0xdb,0xc1}, {0xb5,0xf3}, - {0xb8,0xc5}, {0xe7,0xc1}, {0xbd,0xc3}, {0xbd,0xc4}, {0x8f,0xc0}, {0x93,0x6a}, {0xbf,0xc5}, {0xc5,0xfc}, {0xa6,0xe7}, {0x8b,0xe4}, - {0x9c,0x7c}, {0xd0,0xac}, {0xaa,0xed}, {0xd0,0xae}, {0xd0,0xad}, {0xad,0x6d}, {0xd3,0xd1}, {0x95,0xa1}, {0xd3,0xd8}, {0xb0,0x49}, - {0xd3,0xd6}, {0xd3,0xd4}, {0xd3,0xdb}, {0xd3,0xd2}, {0xd3,0xd3}, {0xb0,0x4a}, {0xb0,0x4e}, {0xd3,0xdc}, {0xb0,0x4d}, {0xd3,0xda}, - {0xd3,0xd7}, {0xd3,0xd5}, {0xb0,0x4b}, {0xb0,0x4c}, {0xd3,0xd9}, {0xfe,0xec}, {0x95,0xa3}, {0xb3,0x50}, {0xd7,0xb2}, {0xb3,0x55}, - {0xd7,0xc2}, {0xb3,0x54}, {0xd7,0xc4}, {0x8c,0x45}, {0x8c,0xb8}, {0xd7,0xb8}, {0xb3,0x52}, {0xd7,0xc3}, {0xd7,0xb3}, {0xb3,0x53}, - {0xd7,0xbf}, {0xd7,0xbb}, {0xd7,0xbd}, {0xd7,0xb7}, {0xd7,0xbe}, {0x8f,0xc1}, {0xb3,0x4f}, {0xd7,0xba}, {0xa0,0x52}, {0xd7,0xb9}, - {0xd7,0xb5}, {0xd7,0xc0}, {0xd7,0xbc}, {0xd7,0xb4}, {0xd7,0xb6}, {0xb3,0x51}, {0xd7,0xc1}, {0x99,0xd0}, {0xb5,0xf6}, {0xdb,0xcd}, - {0x8f,0xc3}, {0x8f,0xc4}, {0xdb,0xc9}, {0xdb,0xcb}, {0xdb,0xc6}, {0xdb,0xc5}, {0xdb,0xc3}, {0xdb,0xca}, {0xdb,0xcc}, {0xdb,0xc8}, - {0x95,0xa4}, {0xdb,0xc7}, {0xb5,0xf4}, {0xb5,0xf5}, {0x8f,0xc6}, {0x9e,0x60}, {0xdb,0xcf}, {0xb8,0xcd}, {0xdf,0xf2}, {0xdf,0xf8}, - {0xdf,0xf3}, {0xdf,0xf4}, {0xf9,0xd8}, {0xdf,0xf9}, {0xb8,0xcf}, {0xb8,0xc7}, {0xb8,0xce}, {0xdf,0xf1}, {0xdb,0xc4}, {0xb8,0xca}, - {0xb8,0xc8}, {0xdf,0xf7}, {0xdf,0xf6}, {0xb8,0xc9}, {0xb8,0xcb}, {0xdf,0xf5}, {0xb8,0xc6}, {0xb8,0xcc}, {0x95,0xa5}, {0xe3,0xf6}, - {0xbb,0x74}, {0xe4,0x42}, {0xe4,0x41}, {0xe3,0xfb}, {0xbb,0x76}, {0xe4,0x40}, {0xe3,0xf7}, {0xe3,0xf8}, {0xbb,0x6e}, {0xbb,0x70}, - {0x9c,0xb3}, {0xe3,0xfd}, {0xe3,0xf5}, {0xbb,0x72}, {0xbb,0x71}, {0xe3,0xf9}, {0xe3,0xfe}, {0xe3,0xfc}, {0xbb,0x73}, {0xe3,0xfa}, - {0x99,0xd1}, {0xfe,0xf1}, {0xdb,0xce}, {0xbb,0x6f}, {0xe7,0xc2}, {0xe7,0xc9}, {0xbd,0xc6}, {0xe7,0xcd}, {0xbd,0xca}, {0xe7,0xc5}, - {0xe7,0xc3}, {0xe7,0xcc}, {0xbd,0xc5}, {0xe7,0xcb}, {0xbd,0xc7}, {0xbd,0xc8}, {0xe7,0xc4}, {0xbd,0xc9}, {0xe7,0xca}, {0xe7,0xc6}, - {0xe7,0xc7}, {0xe7,0xc8}, {0xbb,0x75}, {0xeb,0x70}, {0xeb,0x7c}, {0xbf,0xca}, {0xeb,0x77}, {0xeb,0x79}, {0x99,0xd2}, {0xbf,0xc8}, - {0xeb,0x71}, {0xeb,0x75}, {0xeb,0x78}, {0xbf,0xc6}, {0xbf,0xc9}, {0xeb,0x7b}, {0xeb,0x73}, {0xeb,0x74}, {0xeb,0x7a}, {0xeb,0x72}, - {0xeb,0x76}, {0xbf,0xc7}, {0xee,0x72}, {0xee,0x71}, {0xc1,0xb7}, {0xee,0x77}, {0xc1,0xb9}, {0xc1,0xb6}, {0xee,0x73}, {0xc1,0xba}, - {0xee,0x74}, {0xee,0x75}, {0xee,0x78}, {0x9c,0xc2}, {0xc1,0xb8}, {0xf0,0xd6}, {0x99,0xd3}, {0xf0,0xd9}, {0xf0,0xd3}, {0xf0,0xd5}, - {0x95,0xa7}, {0xf0,0xd4}, {0xf0,0xd7}, {0xf0,0xd8}, {0xee,0x76}, {0xf0,0xd2}, {0x95,0xa9}, {0xc3,0xcd}, {0xf2,0xec}, {0xf2,0xef}, - {0xf2,0xf1}, {0xf2,0xea}, {0xf2,0xeb}, {0xf2,0xee}, {0xf2,0xf0}, {0xc3,0xce}, {0xc3,0xcc}, {0xc3,0xcb}, {0xf2,0xed}, {0xf2,0xe9}, - {0xf4,0xca}, {0xc4,0xb0}, {0x95,0xa6}, {0xf4,0xcb}, {0xf6,0x49}, {0xc4,0xfb}, {0xf6,0x4b}, {0xc4,0xfc}, {0xf6,0x48}, {0xf6,0x4a}, - {0xc5,0xa8}, {0xf7,0x52}, {0xc5,0xa7}, {0xf7,0xfd}, {0xf7,0xfc}, {0xf7,0xfb}, {0x9c,0x5d}, {0xf9,0x48}, {0xf9,0x49}, {0xf9,0x4b}, - {0xf9,0x4a}, {0xca,0x50}, {0xa6,0xe8}, {0x98,0xe2}, {0xad,0x6e}, {0xd7,0xc5}, {0xb5,0xf7}, {0xdf,0xfa}, {0xc2,0xd0}, {0x8f,0xc9}, - {0xf2,0xf2}, {0xa0,0xc2}, {0x8f,0xca}, {0xa8,0xa3}, {0xb3,0x57}, {0x99,0xd4}, {0xb3,0x56}, {0xa0,0xb9}, {0xdb,0xd0}, {0xb5,0xf8}, - {0xdb,0xd2}, {0xdb,0xd1}, {0xdf,0xfb}, {0xb8,0xd0}, {0xe4,0x43}, {0xe4,0x46}, {0xe4,0x45}, {0xe4,0x44}, {0xe7,0xce}, {0xe7,0xd0}, - {0xe7,0xcf}, {0x9b,0x58}, {0xbf,0xcc}, {0x8f,0xcd}, {0xa0,0xd4}, {0xbf,0xcb}, {0xc1,0xbb}, {0xee,0x79}, {0xee,0x7b}, {0xee,0x7a}, - {0xc2,0xd1}, {0xf2,0xf4}, {0xf2,0xf3}, {0xf4,0xcc}, {0xc4,0xb1}, {0x8f,0xce}, {0xc4,0xfd}, {0xf7,0x54}, {0xf7,0x53}, {0xc6,0x5b}, - {0x8b,0xe5}, {0x89,0x79}, {0xa8,0xa4}, {0xd0,0xaf}, {0xad,0x6f}, {0xd7,0xc8}, {0xd7,0xc6}, {0xd7,0xc7}, {0xdb,0xd4}, {0xdb,0xd5}, - {0xe0,0x43}, {0xdb,0xd3}, {0xdf,0xfc}, {0xe0,0x41}, {0xe0,0x40}, {0xe0,0x42}, {0xb8,0xd1}, {0xdf,0xfe}, {0xdf,0xfd}, {0xe0,0x44}, - {0x8f,0xd0}, {0xe4,0x49}, {0xe4,0x47}, {0xe4,0x48}, {0xe7,0xd3}, {0xe7,0xd1}, {0xe7,0xd2}, {0xeb,0x7d}, {0xee,0x7c}, {0xee,0x7d}, - {0xc2,0xd2}, {0xf2,0xf5}, {0xf4,0xcd}, {0xc4,0xb2}, {0xf6,0x4c}, {0xf7,0x55}, {0xc5,0xa9}, {0xf7,0xfe}, {0xf9,0x4c}, {0xa8,0xa5}, - {0xad,0x71}, {0xad,0x72}, {0xd0,0xb0}, {0xd0,0xb1}, {0xad,0x70}, {0xb0,0x54}, {0xb0,0x52}, {0xb0,0x51}, {0xb0,0x58}, {0xb0,0x50}, - {0xb0,0x59}, {0xd3,0xdd}, {0xb0,0x56}, {0xb0,0x53}, {0xb0,0x57}, {0xb0,0x55}, {0xb0,0x4f}, {0xb3,0x5f}, {0x95,0xb6}, {0xb3,0x59}, - {0xd7,0xcc}, {0xb3,0x5e}, {0xb3,0x60}, {0xb3,0x5a}, {0xb3,0x5b}, {0xd7,0xca}, {0x99,0xd6}, {0xb3,0x58}, {0x95,0xe5}, {0xd7,0xcb}, - {0xb3,0x5d}, {0xd7,0xc9}, {0xb3,0x5c}, {0xb6,0x44}, {0xb6,0x46}, {0x99,0xd7}, {0xdb,0xd8}, {0xb6,0x45}, {0xb5,0xf9}, {0xb5,0xfd}, - {0x95,0xb5}, {0xb8,0xe4}, {0xe0,0x49}, {0xdb,0xda}, {0xb5,0xfe}, {0xdb,0xdd}, {0xdb,0xde}, {0xb6,0x43}, {0xdb,0xe0}, {0xa0,0xca}, - {0xdb,0xe2}, {0xdb,0xe3}, {0xdb,0xd7}, {0xdb,0xd6}, {0xdb,0xe4}, {0xb6,0x42}, {0xdb,0xe1}, {0xdb,0xdf}, {0xb6,0x40}, {0xb5,0xfb}, - {0xb6,0x47}, {0xdb,0xdb}, {0xdb,0xdc}, {0xdb,0xd9}, {0xb6,0x41}, {0xb5,0xfc}, {0xb5,0xfa}, {0xe0,0x48}, {0xb8,0xdf}, {0xb8,0xda}, - {0xb8,0xd5}, {0x9f,0xfd}, {0xb8,0xe5}, {0xb8,0xd6}, {0xb8,0xd2}, {0xb8,0xe1}, {0xb8,0xde}, {0xb8,0xe0}, {0xb8,0xd7}, {0xb8,0xdc}, - {0xb8,0xd3}, {0xb8,0xd4}, {0xe0,0x50}, {0xe0,0x4d}, {0xe0,0x45}, {0xe0,0x4a}, {0xb8,0xe2}, {0xe0,0x51}, {0xb8,0xe3}, {0xb8,0xd9}, - {0xa0,0x58}, {0xe0,0x47}, {0xe0,0x4f}, {0xe0,0x4b}, {0xe0,0x4e}, {0xe0,0x4c}, {0xb8,0xdd}, {0xe0,0x46}, {0xb8,0xd8}, {0xe4,0x4c}, - {0xbb,0x78}, {0xbb,0x7b}, {0xe4,0x4e}, {0x8f,0xd6}, {0xbb,0xa5}, {0xe4,0x4d}, {0xbb,0x7d}, {0x99,0xd8}, {0xbd,0xcf}, {0xe4,0x4f}, - {0xbb,0xa4}, {0xe4,0x4b}, {0xbb,0xa6}, {0x8f,0xd3}, {0xbb,0x79}, {0xb8,0xdb}, {0xbb,0x7c}, {0xbb,0x7a}, {0xbb,0x7e}, {0xbb,0xa2}, - {0xbb,0x77}, {0xbb,0xa7}, {0xbb,0xa3}, {0x8f,0xe5}, {0xbb,0xa1}, {0xe4,0x4a}, {0x8f,0xe9}, {0xbd,0xd6}, {0xbd,0xd2}, {0x99,0xd9}, - {0xbd,0xd9}, {0xe7,0xd6}, {0xbd,0xda}, {0xe7,0xe2}, {0xe7,0xdb}, {0xbd,0xcb}, {0xe7,0xe3}, {0xe7,0xdd}, {0xbd,0xd5}, {0xe7,0xde}, - {0xbd,0xd4}, {0xe7,0xe1}, {0xbd,0xce}, {0xe7,0xdf}, {0xe7,0xd5}, {0xbd,0xcd}, {0xeb,0xaa}, {0xbd,0xd3}, {0xbd,0xd0}, {0xbd,0xd8}, - {0xe7,0xd4}, {0xe7,0xd8}, {0xbd,0xcc}, {0xe7,0xd7}, {0xe7,0xd9}, {0xe7,0xda}, {0xbd,0xd7}, {0xe7,0xdc}, {0xe7,0xe0}, {0xe7,0xe4}, - {0x92,0x7c}, {0xbd,0xdb}, {0xbf,0xd2}, {0xeb,0xa5}, {0xeb,0xab}, {0xeb,0xa8}, {0xeb,0x7e}, {0xeb,0xac}, {0xeb,0xa1}, {0xeb,0xa7}, - {0xbf,0xcd}, {0xbf,0xd3}, {0xeb,0xad}, {0x9c,0x45}, {0xbf,0xcf}, {0xbf,0xd9}, {0xbf,0xd4}, {0xeb,0xaf}, {0xeb,0xa9}, {0xbf,0xd0}, - {0xeb,0xa2}, {0xbf,0xda}, {0xeb,0xa3}, {0xeb,0xa4}, {0xbf,0xdb}, {0xbf,0xd8}, {0xbd,0xd1}, {0xbf,0xce}, {0xeb,0xb0}, {0xbf,0xdc}, - {0xbf,0xd5}, {0xeb,0xae}, {0xbf,0xd1}, {0xbf,0xd6}, {0xbf,0xd7}, {0xc1,0xc3}, {0xee,0xa4}, {0xee,0xad}, {0xee,0xaa}, {0xee,0xac}, - {0xc1,0xc0}, {0xee,0xa5}, {0x8f,0xde}, {0xee,0xab}, {0xc1,0xbc}, {0xee,0xa7}, {0xc1,0xc4}, {0xee,0xa3}, {0xee,0xa8}, {0xee,0xaf}, - {0xeb,0xa6}, {0xee,0xa9}, {0xee,0xa2}, {0xc1,0xbd}, {0xee,0xa1}, {0xc1,0xbe}, {0xee,0xb0}, {0xc1,0xbf}, {0xee,0xae}, {0xc1,0xc2}, - {0xee,0x7e}, {0x8f,0xdf}, {0xc1,0xc1}, {0xee,0xa6}, {0xf0,0xdc}, {0xf0,0xea}, {0xf0,0xe5}, {0xf0,0xe7}, {0xf0,0xdb}, {0xc2,0xd3}, - {0xf0,0xda}, {0xc2,0xd6}, {0xc2,0xd5}, {0xa0,0x4b}, {0xf0,0xe9}, {0xf0,0xe1}, {0xf0,0xde}, {0xf0,0xe4}, {0xf0,0xdd}, {0xf0,0xdf}, - {0xf0,0xe8}, {0xf0,0xe6}, {0xc2,0xd4}, {0xf0,0xed}, {0xf0,0xeb}, {0xf0,0xe2}, {0xf0,0xec}, {0xf0,0xe3}, {0x8f,0xe2}, {0xf2,0xf9}, - {0xc3,0xcf}, {0xf3,0x41}, {0xa0,0xcc}, {0xf6,0x4f}, {0xc3,0xd6}, {0xf0,0xe0}, {0xf2,0xf7}, {0xc3,0xd2}, {0xf2,0xf8}, {0xf2,0xfd}, - {0x8f,0xe3}, {0x8f,0xe4}, {0xc3,0xd4}, {0xc3,0xd5}, {0xf2,0xf6}, {0xf3,0x40}, {0xf3,0x42}, {0xf2,0xfa}, {0xf2,0xfc}, {0xf2,0xfe}, - {0xf2,0xfb}, {0xf3,0x43}, {0xc3,0xd1}, {0xc3,0xd7}, {0xc3,0xd3}, {0xc3,0xd0}, {0xf4,0xd0}, {0x9b,0xc4}, {0xc4,0xb7}, {0xf4,0xce}, - {0x9b,0xfc}, {0xf4,0xd2}, {0xf4,0xd3}, {0xc4,0xb5}, {0xf4,0xd4}, {0xf4,0xd1}, {0x96,0x4c}, {0xf4,0xcf}, {0xc4,0xb8}, {0xc4,0xb4}, - {0xf4,0xd5}, {0xc4,0xb6}, {0xc4,0xb3}, {0xc4,0xfe}, {0xc5,0x40}, {0xf6,0x4e}, {0xf6,0x4d}, {0xf6,0x50}, {0xf6,0x51}, {0xc5,0x41}, - {0xf7,0x56}, {0xf7,0x5b}, {0xc5,0xaa}, {0x9a,0xf6}, {0xf7,0x58}, {0x8c,0xae}, {0xf7,0x57}, {0xf7,0x5a}, {0xf7,0x59}, {0xf8,0x43}, - {0xc5,0xdc}, {0xf8,0x42}, {0xf8,0x40}, {0xf8,0x41}, {0x8f,0xe7}, {0xc5,0xfe}, {0xc5,0xfd}, {0xf8,0xc1}, {0xf8,0xc2}, {0xc6,0x40}, - {0xf9,0x4d}, {0xf9,0x4e}, {0xc6,0x67}, {0x8f,0xe8}, {0xc6,0x6d}, {0xf9,0xa9}, {0xf9,0xc8}, {0x8b,0xe7}, {0x89,0x7a}, {0x89,0x7b}, - {0xa8,0xa6}, {0xd7,0xcd}, {0xd7,0xce}, {0xe0,0x52}, {0xe4,0x50}, {0xe7,0xe5}, {0xc1,0xc6}, {0xc1,0xc5}, {0xf0,0xee}, {0xf3,0x44}, - {0xf8,0x44}, {0xa8,0xa7}, {0xd3,0xde}, {0xb0,0x5a}, {0xb3,0x61}, {0xe0,0x54}, {0xe0,0x53}, {0xbd,0xdc}, {0xe7,0xe6}, {0xbd,0xdd}, - {0xee,0xb1}, {0xc2,0xd7}, {0x99,0xda}, {0xc6,0x76}, {0xa8,0xa8}, {0xcd,0xcb}, {0xd3,0xdf}, {0xb3,0x62}, {0xd7,0xcf}, {0xd7,0xd0}, - {0xdb,0xe5}, {0xb6,0x48}, {0xb8,0xe6}, {0xe0,0x56}, {0xe0,0x55}, {0xe0,0x57}, {0xe4,0x51}, {0xe4,0x52}, {0xbb,0xa8}, {0xbf,0xdd}, - {0xbd,0xde}, {0xbf,0xde}, {0xee,0xb5}, {0xee,0xb2}, {0xee,0xb4}, {0xee,0xb3}, {0xc1,0xc7}, {0xf0,0xef}, {0xf3,0x46}, {0xf3,0x45}, - {0xcb,0xa4}, {0xb0,0x5c}, {0xb0,0x5b}, {0xd3,0xe0}, {0xd7,0xd1}, {0xdb,0xe7}, {0xdb,0xe6}, {0xb6,0x49}, {0xe0,0x59}, {0xe0,0x5a}, - {0xe0,0x58}, {0xb8,0xe8}, {0xb8,0xe7}, {0xbb,0xaa}, {0xbb,0xa9}, {0xe7,0xe7}, {0xeb,0xb3}, {0xeb,0xb1}, {0xeb,0xb2}, {0xbf,0xdf}, - {0xee,0xb7}, {0xee,0xb6}, {0xf0,0xf2}, {0xf0,0xf1}, {0xf0,0xf0}, {0xf3,0x47}, {0x8f,0xed}, {0xf9,0xaa}, {0xa8,0xa9}, {0xad,0x73}, - {0x95,0xc0}, {0xad,0x74}, {0xb0,0x5d}, {0xb0,0x5e}, {0xd3,0xe2}, {0xd3,0xe1}, {0xd7,0xd2}, {0xb3,0x68}, {0xb3,0x66}, {0xb3,0x63}, - {0xb3,0x67}, {0xb3,0x65}, {0xb3,0x64}, {0xa0,0xcb}, {0xb6,0x4a}, {0xdb,0xea}, {0xb8,0xed}, {0xb6,0x4c}, {0xb6,0x51}, {0xdb,0xec}, - {0xb6,0x53}, {0xb6,0x52}, {0xb6,0x55}, {0xdb,0xeb}, {0xdb,0xe8}, {0xb6,0x4f}, {0xb6,0x4b}, {0xb6,0x4d}, {0xdb,0xe9}, {0xb6,0x54}, - {0xb6,0x50}, {0xb6,0x4e}, {0xb8,0xef}, {0xb8,0xee}, {0xb8,0xec}, {0xb8,0xf0}, {0xb8,0xea}, {0xb8,0xeb}, {0xb8,0xe9}, {0xe0,0x5b}, - {0x9e,0x48}, {0xe4,0x54}, {0xbb,0xac}, {0xbb,0xad}, {0xbb,0xab}, {0x99,0xdb}, {0xe4,0x53}, {0x8f,0xf3}, {0xe4,0x55}, {0xe7,0xea}, - {0xe7,0xec}, {0x8f,0xf9}, {0xbd,0xe7}, {0xe7,0xed}, {0xbd,0xe0}, {0xe7,0xe9}, {0xbd,0xdf}, {0xbd,0xe9}, {0xbd,0xe5}, {0xbd,0xe6}, - {0xbd,0xe2}, {0xe7,0xe8}, {0xbd,0xe1}, {0xe7,0xee}, {0xe7,0xeb}, {0x95,0xc1}, {0xbd,0xe8}, {0xa0,0x4e}, {0xbd,0xe3}, {0xbd,0xe4}, - {0xeb,0xb5}, {0xeb,0xb7}, {0xeb,0xb6}, {0x99,0xdc}, {0xeb,0xb8}, {0xbf,0xe0}, {0xeb,0xb4}, {0xa0,0x64}, {0xc1,0xcb}, {0xee,0xb8}, - {0xc1,0xc8}, {0xc1,0xcc}, {0xc1,0xca}, {0xc1,0xc9}, {0xf0,0xf3}, {0xf0,0xf6}, {0xf0,0xf5}, {0x8f,0xf7}, {0xf0,0xf4}, {0xc2,0xd8}, - {0xf3,0x48}, {0xf3,0x49}, {0xc3,0xd8}, {0xf3,0x4a}, {0xc3,0xd9}, {0x89,0xb0}, {0xa0,0x48}, {0xc4,0xba}, {0xc4,0xb9}, {0xf6,0x52}, - {0x8f,0xfb}, {0x8f,0xf6}, {0xc5,0x42}, {0xf6,0x53}, {0xf7,0x5c}, {0xc5,0xab}, {0xc5,0xac}, {0x9d,0xdc}, {0xf8,0x45}, {0xc6,0x42}, - {0x99,0xdd}, {0x8b,0xe8}, {0xa8,0xaa}, {0xb3,0x6a}, {0xb3,0x69}, {0xe0,0x5c}, {0xe0,0x5d}, {0xbb,0xae}, {0xeb,0xb9}, {0xbd,0xea}, - {0xeb,0xba}, {0xee,0xb9}, {0xa8,0xab}, {0xd0,0xb2}, {0xad,0x76}, {0xad,0x75}, {0xd3,0xe3}, {0xb0,0x5f}, {0xd3,0xe4}, {0xd7,0xd5}, - {0x92,0xc1}, {0xd7,0xd4}, {0xd7,0xd3}, {0xdb,0xee}, {0xb6,0x58}, {0x9f,0xd6}, {0xdb,0xed}, {0xb6,0x57}, {0xdb,0xef}, {0xb6,0x56}, - {0xe0,0x5f}, {0xe0,0x62}, {0xe0,0x60}, {0xe0,0x61}, {0xe0,0x65}, {0xe0,0x5e}, {0xe0,0x66}, {0xe0,0x63}, {0xe0,0x64}, {0xbb,0xb0}, - {0xe4,0x56}, {0xbb,0xaf}, {0xe7,0xf2}, {0xe7,0xf0}, {0xbd,0xeb}, {0xe7,0xef}, {0xe7,0xf1}, {0xbd,0xec}, {0xeb,0xbb}, {0xa0,0xd2}, - {0xeb,0xbc}, {0xc1,0xcd}, {0x90,0x40}, {0xf3,0x4c}, {0xf3,0x4e}, {0xf3,0x4b}, {0xf3,0x4d}, {0xf4,0xd6}, {0xf6,0x54}, {0xf9,0x6f}, - {0xa8,0xac}, {0xad,0x77}, {0xd3,0xe5}, {0xd3,0xe7}, {0xd3,0xe6}, {0xd7,0xd8}, {0xb3,0x6c}, {0xd7,0xd6}, {0xb3,0x6b}, {0xd7,0xd9}, - {0x8a,0xc4}, {0xd7,0xda}, {0xd7,0xd7}, {0x99,0xe0}, {0xdb,0xfb}, {0xb6,0x60}, {0xdb,0xf3}, {0xdb,0xf9}, {0xb6,0x5b}, {0xb6,0x5e}, - {0xdb,0xf2}, {0xb6,0x59}, {0xdb,0xf6}, {0xe0,0x6c}, {0xb6,0x5d}, {0xdb,0xf1}, {0x9f,0xf0}, {0xdb,0xf7}, {0xdb,0xf4}, {0xdb,0xfa}, - {0xdb,0xf0}, {0xdb,0xf8}, {0xb6,0x5c}, {0xb6,0x5f}, {0xdb,0xf5}, {0xb6,0x5a}, {0xb8,0xf2}, {0xe0,0x68}, {0xb8,0xf1}, {0xe0,0x6f}, - {0xe0,0x6e}, {0xb8,0xf8}, {0xb8,0xf9}, {0xe0,0x70}, {0xb8,0xf3}, {0xe0,0x6d}, {0xb8,0xf7}, {0xe0,0x72}, {0xe0,0x69}, {0xe0,0x6b}, - {0xb8,0xf4}, {0xe0,0x67}, {0xe0,0x6a}, {0xe0,0x71}, {0xb8,0xf5}, {0xe0,0x73}, {0xb8,0xf6}, {0xbb,0xb1}, {0xe4,0x5b}, {0xe4,0x61}, - {0xe4,0x59}, {0xe4,0x62}, {0x9f,0xf3}, {0xe4,0x58}, {0xe4,0x5d}, {0xe4,0x63}, {0xe4,0x60}, {0xe4,0x5f}, {0xe4,0x5e}, {0xe4,0x57}, - {0xe4,0x5c}, {0xe4,0x5a}, {0x9d,0xbf}, {0xbd,0xf1}, {0xbd,0xee}, {0xe7,0xfb}, {0xe8,0x41}, {0xe8,0x43}, {0xe8,0x40}, {0xe7,0xf8}, - {0xe7,0xfa}, {0xe8,0x45}, {0xe8,0x42}, {0xe7,0xfc}, {0xe8,0x46}, {0xe7,0xf9}, {0xe8,0x44}, {0xbd,0xef}, {0xbd,0xf5}, {0xbd,0xf3}, - {0xe7,0xf3}, {0xbd,0xf4}, {0xbd,0xf0}, {0xe7,0xf4}, {0xe7,0xf6}, {0xe7,0xf5}, {0xe7,0xfd}, {0xe7,0xfe}, {0x9f,0xf6}, {0xbd,0xf2}, - {0x95,0xc8}, {0xbd,0xed}, {0x9e,0x5a}, {0xe7,0xf7}, {0xeb,0xc6}, {0xbf,0xe2}, {0xeb,0xbd}, {0xbf,0xe3}, {0xbf,0xe6}, {0xeb,0xc2}, - {0xeb,0xbf}, {0xbf,0xe5}, {0x99,0xe3}, {0xeb,0xc3}, {0xeb,0xc4}, {0xeb,0xbe}, {0xeb,0xc7}, {0xeb,0xc0}, {0xeb,0xc5}, {0xbf,0xe4}, - {0xbf,0xe1}, {0xeb,0xc1}, {0x8a,0x4a}, {0xee,0xbf}, {0xc1,0xd0}, {0xc1,0xce}, {0xc1,0xd1}, {0xc1,0xcf}, {0xee,0xbe}, {0xee,0xbb}, - {0xee,0xba}, {0x9f,0xf1}, {0xee,0xbd}, {0xee,0xbc}, {0xf1,0x45}, {0xc2,0xde}, {0xf0,0xfb}, {0xf0,0xfa}, {0xc2,0xd9}, {0xf1,0x41}, - {0xf1,0x40}, {0xf0,0xf7}, {0xf1,0x43}, {0xf0,0xfc}, {0xc2,0xdd}, {0xf0,0xf9}, {0xf1,0x42}, {0xf0,0xf8}, {0xc2,0xda}, {0xc2,0xdc}, - {0xf0,0xfd}, {0xc2,0xdb}, {0xf0,0xfe}, {0x8a,0xa7}, {0xf1,0x44}, {0xf3,0x52}, {0xc3,0xde}, {0xf3,0x4f}, {0xf3,0x53}, {0x99,0xe6}, - {0xc3,0xdb}, {0xf3,0x51}, {0xc3,0xe0}, {0x9f,0xf7}, {0xc3,0xdd}, {0x9f,0xed}, {0xf3,0x50}, {0xc3,0xdf}, {0xf3,0x54}, {0xc3,0xda}, - {0x8a,0x5c}, {0x9d,0xae}, {0xc4,0xbc}, {0xc4,0xbe}, {0xf4,0xd9}, {0xc4,0xbd}, {0xf4,0xd7}, {0xc3,0xdc}, {0xf4,0xd8}, {0xc4,0xbb}, - {0xc5,0x43}, {0xc5,0x45}, {0xf6,0x56}, {0xc5,0x44}, {0xf6,0x55}, {0xf7,0x61}, {0xc5,0xad}, {0xf7,0x60}, {0xc5,0xae}, {0xf7,0x5e}, - {0xf7,0x5d}, {0xf7,0x62}, {0xf7,0x63}, {0xf8,0x46}, {0xf7,0x5f}, {0xf8,0xc6}, {0xf8,0xc3}, {0xf8,0xc4}, {0xf8,0xc5}, {0xc6,0x5c}, - {0xf9,0x51}, {0xf9,0x50}, {0xf9,0x4f}, {0xf9,0x70}, {0x95,0xc9}, {0xf9,0xbe}, {0xf9,0xab}, {0xc6,0x6e}, {0xa8,0xad}, {0xb0,0x60}, - {0x90,0x48}, {0x99,0xe8}, {0xb8,0xfa}, {0x90,0x49}, {0x8c,0xba}, {0xbd,0xf6}, {0x90,0xb1}, {0xeb,0xc8}, {0xc2,0xdf}, {0xf3,0x55}, - {0x90,0x4a}, {0xf9,0xac}, {0xa8,0xae}, {0xaa,0xee}, {0xad,0x79}, {0xad,0x78}, {0x99,0xea}, {0xb0,0x63}, {0xd3,0xe8}, {0xb0,0x61}, - {0xd3,0xe9}, {0xb0,0x62}, {0xd7,0xdf}, {0xd7,0xdb}, {0x9b,0xd1}, {0xb3,0x6d}, {0xd7,0xde}, {0xd7,0xdd}, {0xd7,0xdc}, {0xb3,0x6e}, - {0xd7,0xe0}, {0xd7,0xe1}, {0x99,0xeb}, {0x99,0xec}, {0xdc,0x43}, {0xdc,0x41}, {0xdc,0x45}, {0xdc,0x46}, {0xdc,0x4c}, {0xdc,0x48}, - {0xdc,0x4a}, {0x99,0xed}, {0xdc,0x42}, {0xdb,0xfc}, {0xdc,0x49}, {0x99,0xee}, {0xdc,0x4b}, {0xdc,0x44}, {0xdc,0x47}, {0xdb,0xfd}, - {0xb6,0x62}, {0xdc,0x40}, {0xdb,0xfe}, {0xb6,0x61}, {0xb6,0x63}, {0xb8,0xfd}, {0xe0,0x75}, {0xe0,0x77}, {0xe0,0x76}, {0xe0,0x7b}, - {0xb8,0xfb}, {0xe0,0x78}, {0xe0,0x74}, {0xe0,0x79}, {0xe0,0x7a}, {0xb8,0xfc}, {0xb8,0xfe}, {0xe0,0x7c}, {0xe4,0x67}, {0xe4,0x66}, - {0xe4,0x64}, {0xe4,0x65}, {0xbb,0xb3}, {0xbb,0xb5}, {0xbb,0xb2}, {0xbb,0xb4}, {0xe8,0x4d}, {0xe8,0x4e}, {0xe8,0x49}, {0x90,0x4c}, - {0xe8,0x4a}, {0xbd,0xf8}, {0xbd,0xfd}, {0xbd,0xf7}, {0xbd,0xfe}, {0xbd,0xf9}, {0xe8,0x4b}, {0xe8,0x4c}, {0xe8,0x48}, {0xbe,0x40}, - {0xbd,0xfb}, {0xbd,0xfa}, {0xbd,0xfc}, {0xe8,0x47}, {0x90,0x4d}, {0xeb,0xca}, {0xbf,0xe8}, {0x95,0xcb}, {0xeb,0xcc}, {0xbf,0xea}, - {0xeb,0xcf}, {0xeb,0xcb}, {0xeb,0xc9}, {0xeb,0xce}, {0xbf,0xe9}, {0xeb,0xcd}, {0xbf,0xe7}, {0xc1,0xd3}, {0xc1,0xd6}, {0xee,0xc1}, - {0x97,0xe2}, {0xc1,0xd4}, {0xee,0xc0}, {0xc1,0xd2}, {0xc1,0xd5}, {0xf1,0x46}, {0xf1,0x47}, {0xf1,0x48}, {0xc2,0xe0}, {0x95,0xcc}, - {0xf1,0x49}, {0xc2,0xe1}, {0xc3,0xe2}, {0xf3,0x58}, {0xf3,0x59}, {0xf3,0x57}, {0xf3,0x56}, {0xf3,0x5a}, {0xc3,0xe1}, {0xf4,0xdd}, - {0xf4,0xdb}, {0xf4,0xdc}, {0xf4,0xde}, {0xf4,0xda}, {0xf4,0xdf}, {0xf6,0x58}, {0x9f,0x78}, {0xf6,0x59}, {0xf6,0x57}, {0xc5,0x46}, - {0xf7,0x64}, {0xc5,0xaf}, {0xf7,0x65}, {0xf8,0x48}, {0xf8,0x47}, {0x89,0x7c}, {0x89,0x7d}, {0x89,0x7e}, {0x99,0x5d}, {0xa8,0xaf}, - {0xb6,0x64}, {0xb9,0x40}, {0x9b,0x5a}, {0xbb,0xb6}, {0x90,0x50}, {0xbf,0xec}, {0x8c,0x4f}, {0xbf,0xeb}, {0xc3,0xe3}, {0xc4,0x7c}, - {0xc5,0x47}, {0xa8,0xb0}, {0xb0,0x64}, {0xb9,0x41}, {0x90,0x54}, {0xf3,0x5b}, {0xc6,0xd6}, {0x9a,0xa8}, {0x99,0xef}, {0xfe,0xeb}, - {0x9d,0xa3}, {0x9d,0xa1}, {0x99,0x43}, {0x99,0x45}, {0x9d,0x7d}, {0xcb,0xa6}, {0x99,0xf0}, {0xa8,0xb1}, {0xa8,0xb4}, {0xa8,0xb3}, - {0xa8,0xb2}, {0xcb,0xa5}, {0x99,0xf1}, {0xcd,0xcd}, {0x99,0xf2}, {0xcd,0xcf}, {0xaa,0xef}, {0x8c,0xbc}, {0x9d,0x60}, {0xaa,0xf1}, - {0xcd,0xcc}, {0xcd,0xce}, {0xaa,0xf0}, {0xcd,0xd1}, {0xcd,0xd0}, {0xcd,0xd2}, {0xa0,0xa3}, {0xd0,0xb6}, {0xd0,0xb4}, {0xad,0x7c}, - {0xd0,0xb3}, {0xad,0xa3}, {0xad,0x7e}, {0xad,0x7b}, {0xad,0xa4}, {0xad,0x7d}, {0xad,0xa2}, {0xad,0xa1}, {0xd0,0xb5}, {0xad,0x7a}, - {0xb0,0x6a}, {0xd3,0xeb}, {0xd3,0xf1}, {0xb0,0x67}, {0xb0,0x6e}, {0x90,0x5b}, {0xb0,0x69}, {0xd3,0xee}, {0xd3,0xf0}, {0xb0,0x6c}, - {0xd3,0xea}, {0xd3,0xed}, {0xb0,0x68}, {0xb0,0x65}, {0xd3,0xec}, {0xb0,0x6b}, {0xd3,0xef}, {0xb0,0x6d}, {0xb0,0x66}, {0x9e,0xdb}, - {0xd7,0xe3}, {0xd7,0xe6}, {0xb3,0x70}, {0xb3,0x7a}, {0xb3,0x76}, {0xd7,0xe4}, {0x9d,0x79}, {0xb3,0x7e}, {0xb3,0x77}, {0xb3,0x7c}, - {0xb3,0x72}, {0xb3,0x6f}, {0xb3,0x71}, {0xb3,0x7d}, {0xd7,0xe5}, {0xb3,0x75}, {0xb3,0x78}, {0xb3,0x74}, {0xb3,0x79}, {0xd7,0xe7}, - {0xb3,0x7b}, {0xb3,0x73}, {0xd7,0xe2}, {0xdc,0x4d}, {0xb6,0x65}, {0xdc,0x4f}, {0xb6,0x67}, {0xb6,0x69}, {0x99,0xf3}, {0xdc,0x4e}, - {0xb6,0x66}, {0xb6,0x6a}, {0x90,0x62}, {0xb6,0x68}, {0xb9,0x47}, {0xe0,0xa3}, {0xb9,0x4f}, {0xe0,0x7e}, {0xb9,0x50}, {0xb9,0x45}, - {0xe0,0xa1}, {0xb9,0x4a}, {0xe0,0xa2}, {0xb9,0x43}, {0xb9,0x42}, {0x9f,0x55}, {0xb9,0x4d}, {0xb9,0x4c}, {0xb9,0x4b}, {0xb9,0x49}, - {0xb9,0x4e}, {0xe0,0x7d}, {0xb9,0x44}, {0xb9,0x46}, {0xb9,0x48}, {0x9b,0xf9}, {0xbb,0xb8}, {0xbb,0xbb}, {0xbb,0xbf}, {0xbb,0xb9}, - {0xbb,0xbe}, {0xbb,0xbc}, {0xbb,0xb7}, {0x90,0x65}, {0xbb,0xbd}, {0xbb,0xba}, {0x96,0xe0}, {0xe8,0x52}, {0xbe,0x43}, {0xbe,0x41}, - {0xe8,0x53}, {0x98,0xbe}, {0xbe,0x44}, {0xbe,0x42}, {0xe8,0x51}, {0xe8,0x50}, {0xbf,0xf0}, {0xe8,0x4f}, {0xbf,0xee}, {0xbf,0xed}, - {0xeb,0xd0}, {0xbe,0x45}, {0xbf,0xef}, {0xeb,0xd1}, {0xbf,0xf2}, {0xeb,0xd2}, {0xbf,0xf1}, {0xc1,0xd8}, {0xee,0xc3}, {0xc1,0xd7}, - {0xc1,0xdc}, {0xc1,0xda}, {0xc1,0xdb}, {0xc2,0xe3}, {0xc1,0xd9}, {0xee,0xc2}, {0xeb,0xd3}, {0xc2,0xe2}, {0xc2,0xe4}, {0xc3,0xe4}, - {0xc3,0xe5}, {0xf4,0xe0}, {0xc5,0xde}, {0xc5,0xdd}, {0xa8,0xb6}, {0xca,0x55}, {0xb0,0x6f}, {0xca,0x52}, {0xca,0x53}, {0xca,0x51}, - {0xca,0x54}, {0xcb,0xaa}, {0xcb,0xa7}, {0xcb,0xac}, {0xcb,0xa8}, {0xa8,0xb7}, {0xa8,0xba}, {0xcb,0xa9}, {0xa8,0xb9}, {0xcb,0xab}, - {0x90,0x68}, {0xa8,0xb8}, {0x90,0x6c}, {0xcd,0xd5}, {0xcd,0xd7}, {0xaa,0xf4}, {0xcd,0xd3}, {0xcd,0xd6}, {0xcd,0xd4}, {0xaa,0xf2}, - {0xaa,0xf5}, {0xaa,0xf3}, {0x95,0xd8}, {0xd0,0xb8}, {0xd0,0xbc}, {0xd0,0xb9}, {0xad,0xa7}, {0xad,0xa8}, {0x90,0x6a}, {0xd0,0xbb}, - {0xd0,0xbd}, {0xd0,0xbf}, {0xad,0xa5}, {0xd0,0xbe}, {0xad,0xa6}, {0xd7,0xee}, {0xd0,0xba}, {0xd3,0xf2}, {0xd3,0xfb}, {0xd3,0xf9}, - {0xd3,0xf4}, {0xd3,0xf5}, {0xd3,0xfa}, {0xd3,0xfc}, {0xb0,0x71}, {0xd3,0xf7}, {0xd3,0xf3}, {0xb0,0x70}, {0xb0,0x72}, {0xd3,0xf6}, - {0xd3,0xfd}, {0xd3,0xf8}, {0xb3,0xa1}, {0xd7,0xf1}, {0xd7,0xe9}, {0xd7,0xef}, {0xd7,0xf0}, {0xb3,0xa2}, {0xd7,0xe8}, {0xd7,0xea}, - {0xd0,0xb7}, {0xd7,0xec}, {0xd7,0xed}, {0xd7,0xeb}, {0xb6,0x6c}, {0xdc,0x56}, {0xeb,0xd4}, {0xdc,0x57}, {0xdc,0x54}, {0xb3,0xa3}, - {0xb6,0x6e}, {0xdc,0x53}, {0xdc,0x59}, {0xdc,0x58}, {0xb6,0x6b}, {0xdc,0x5c}, {0xdc,0x52}, {0xdc,0x5b}, {0xdc,0x50}, {0xdc,0x5a}, - {0xdc,0x55}, {0xb6,0x6d}, {0xe0,0xaa}, {0xe0,0xa5}, {0xe0,0xab}, {0xe0,0xa6}, {0xe0,0xa4}, {0xe0,0xa7}, {0xb9,0x51}, {0xe0,0xa9}, - {0xe0,0xa8}, {0xb9,0x52}, {0xbb,0xc1}, {0xbb,0xc0}, {0xe4,0x6e}, {0xe4,0x71}, {0xe4,0x69}, {0xe4,0x6d}, {0xbb,0xc2}, {0xe4,0x6c}, - {0xe4,0x6a}, {0xe4,0x70}, {0xe4,0x6b}, {0xe4,0x68}, {0xe4,0x6f}, {0xe8,0x59}, {0xbe,0x48}, {0xf1,0x4a}, {0xe8,0x56}, {0xe8,0x57}, - {0xe8,0x55}, {0xdc,0x51}, {0xbe,0x47}, {0xe8,0x5a}, {0xe8,0x54}, {0xbe,0x46}, {0xbe,0x49}, {0xe8,0x58}, {0xeb,0xd5}, {0xbf,0xf3}, - {0xeb,0xd6}, {0xeb,0xd7}, {0xee,0xc4}, {0xc1,0xdd}, {0xf1,0x4b}, {0xf1,0x4c}, {0xf1,0x4d}, {0xf3,0x5d}, {0xf3,0x5c}, {0xf4,0xe2}, - {0xf4,0xe1}, {0xf6,0x5b}, {0xf6,0x5c}, {0xf6,0x5a}, {0xf7,0x66}, {0xc5,0xb0}, {0xa8,0xbb}, {0xad,0xaa}, {0xad,0xa9}, {0xb0,0x75}, - {0xb0,0x74}, {0xd4,0x40}, {0xd4,0x41}, {0xd3,0xfe}, {0x9f,0xb2}, {0xb0,0x73}, {0xd7,0xf5}, {0xd7,0xf6}, {0xd7,0xf2}, {0xb3,0xa4}, - {0xd7,0xf3}, {0x9f,0xae}, {0xd7,0xf4}, {0x9f,0xb0}, {0x89,0xad}, {0xdc,0x5f}, {0xdc,0x61}, {0xdc,0x5d}, {0xdc,0x60}, {0xb6,0x6f}, - {0xdc,0x5e}, {0xb6,0x70}, {0x90,0x6e}, {0xdd,0x73}, {0xb9,0x55}, {0xb9,0x54}, {0xb9,0x53}, {0xe0,0xac}, {0xe0,0xad}, {0x9e,0x71}, - {0xe4,0x73}, {0xe4,0x75}, {0xbb,0xc6}, {0xbb,0xc3}, {0x9e,0x4a}, {0xbb,0xc5}, {0xbb,0xc4}, {0xe4,0x74}, {0xe4,0x72}, {0x9f,0xdc}, - {0xe8,0x61}, {0xe8,0x5e}, {0xe8,0x5f}, {0xbe,0x4d}, {0xe8,0x60}, {0xe8,0x5b}, {0xe8,0x5c}, {0xbe,0x4a}, {0xbe,0x4b}, {0xe8,0x5d}, - {0xbe,0x4c}, {0x89,0xab}, {0xeb,0xdb}, {0x9f,0xb8}, {0xeb,0xdc}, {0xeb,0xd9}, {0xeb,0xda}, {0xbf,0xf4}, {0xeb,0xd8}, {0xee,0xc8}, - {0xee,0xc5}, {0xee,0xc7}, {0xc1,0xe0}, {0xee,0xcb}, {0xc1,0xdf}, {0xee,0xc9}, {0xee,0xcc}, {0xee,0xca}, {0xee,0xc6}, {0xc1,0xde}, - {0xf1,0x4f}, {0xf1,0x50}, {0xf1,0x4e}, {0x90,0x70}, {0xf1,0x52}, {0xc2,0xe5}, {0xc2,0xe6}, {0xf3,0x5f}, {0xc3,0xe7}, {0xf1,0x51}, - {0xf3,0x5e}, {0xc3,0xe6}, {0xf4,0xe5}, {0xf4,0xe6}, {0xc4,0xbf}, {0xf4,0xe4}, {0x8b,0x63}, {0xf4,0xe3}, {0xf6,0x5d}, {0xc5,0x48}, - {0x95,0xdc}, {0xf8,0x49}, {0xf8,0xc8}, {0xf8,0xc7}, {0xc6,0x43}, {0xc6,0x5d}, {0xf8,0xc9}, {0xf9,0x71}, {0x90,0x71}, {0xc6,0x6f}, - {0xa8,0xbc}, {0xaa,0xf6}, {0xb9,0x56}, {0xc4,0xc0}, {0xa8,0xbd}, {0xad,0xab}, {0xb3,0xa5}, {0xb6,0x71}, {0xc2,0xe7}, {0xaa,0xf7}, - {0xd0,0xc1}, {0xd0,0xc0}, {0xd4,0x42}, {0xfc,0x5e}, {0xb0,0x78}, {0xb0,0x76}, {0xb0,0x7a}, {0xd4,0x44}, {0xb0,0x79}, {0xb0,0x77}, - {0x89,0x49}, {0xd4,0x43}, {0xb3,0xa8}, {0xd7,0xfc}, {0x96,0x5b}, {0xb3,0xa7}, {0xb3,0xa9}, {0xd8,0x42}, {0xb3,0xab}, {0xd7,0xfe}, - {0xd8,0x40}, {0xd7,0xf7}, {0xb3,0xaa}, {0xd8,0x43}, {0xd7,0xf9}, {0xd7,0xfa}, {0xd7,0xf8}, {0xb3,0xa6}, {0x8c,0x50}, {0xd8,0x41}, - {0xd7,0xfb}, {0xd7,0xfd}, {0x94,0xa6}, {0xdc,0x6d}, {0x8f,0xd5}, {0xdc,0x6c}, {0xdc,0x6a}, {0xdc,0x62}, {0xdc,0x71}, {0xdc,0x65}, - {0xdc,0x6f}, {0xdc,0x76}, {0xdc,0x6e}, {0xb6,0x79}, {0x9e,0x73}, {0xb6,0x75}, {0xdc,0x63}, {0xdc,0x69}, {0xb6,0x77}, {0x90,0x75}, - {0xdc,0x68}, {0xb6,0x78}, {0xb6,0x7a}, {0xdc,0x6b}, {0x99,0xf7}, {0xb6,0x72}, {0xb6,0x73}, {0xdc,0x77}, {0xdc,0x75}, {0xdc,0x74}, - {0xdc,0x66}, {0xdc,0x72}, {0xb6,0x76}, {0x8c,0xbf}, {0xb6,0x74}, {0xdc,0x73}, {0xdc,0x64}, {0xdc,0x67}, {0xdc,0x70}, {0x99,0xf9}, - {0x96,0x63}, {0x95,0xb9}, {0xe4,0xba}, {0xe0,0xb7}, {0xe0,0xb0}, {0xe0,0xc3}, {0xe0,0xcc}, {0xe0,0xb3}, {0xb9,0x61}, {0x94,0xd4}, - {0xe0,0xc0}, {0xb9,0x57}, {0xb9,0x59}, {0xb9,0x65}, {0xe0,0xb1}, {0xfc,0xfa}, {0xb9,0x5a}, {0xb9,0x5c}, {0xb9,0x66}, {0xb9,0x5b}, - {0x90,0x77}, {0x90,0xab}, {0xb9,0x64}, {0xe0,0xb9}, {0xe0,0xae}, {0xb9,0x62}, {0xe0,0xb8}, {0xb9,0x5e}, {0xe0,0xca}, {0xb9,0x63}, - {0xe0,0xc8}, {0xe0,0xbc}, {0xe0,0xc6}, {0xb9,0x60}, {0xe0,0xaf}, {0xe0,0xc9}, {0xe0,0xc4}, {0x9d,0x4d}, {0xe0,0xcb}, {0xb9,0x58}, - {0x99,0xfa}, {0xb9,0x67}, {0xb9,0x5d}, {0x92,0xe3}, {0xe0,0xb5}, {0x97,0xbb}, {0xe0,0xbd}, {0xe0,0xc1}, {0x90,0x78}, {0xe0,0xc5}, - {0xb9,0x5f}, {0xe0,0xb4}, {0xe0,0xb2}, {0xe0,0xbe}, {0x99,0xfb}, {0xe0,0xbb}, {0xe0,0xba}, {0x97,0xe0}, {0xe0,0xbf}, {0xe0,0xc2}, - {0xe0,0xc7}, {0xe4,0x78}, {0x96,0xdc}, {0xbb,0xc7}, {0xe4,0xa4}, {0xe4,0x7a}, {0xbb,0xcc}, {0xbb,0xd0}, {0xe4,0xad}, {0xe4,0xb5}, - {0xe4,0xa6}, {0xbb,0xc8}, {0x9c,0xa8}, {0xe4,0xaa}, {0xe0,0xb6}, {0x97,0x72}, {0xbb,0xc9}, {0xe4,0xb1}, {0xe4,0xb6}, {0xe4,0xae}, - {0x94,0x40}, {0xe4,0xb0}, {0xe4,0xb9}, {0xe4,0xb2}, {0xe4,0x7e}, {0xe4,0xa9}, {0x92,0xf2}, {0xbb,0xd1}, {0xbb,0xcd}, {0xe4,0x7c}, - {0xe4,0xab}, {0xbb,0xcb}, {0xe4,0xa5}, {0xbb,0xca}, {0xe4,0xb3}, {0xe4,0xa2}, {0xe4,0x79}, {0xbb,0xce}, {0xe4,0xb8}, {0xe4,0x7b}, - {0xe4,0xaf}, {0xe4,0xac}, {0xe4,0xa7}, {0xe4,0x77}, {0xe4,0x76}, {0xe4,0xa1}, {0xe4,0xb4}, {0xbb,0xcf}, {0xe4,0xb7}, {0xe4,0x7d}, - {0xe4,0xa3}, {0xbe,0x52}, {0x99,0xfd}, {0x99,0xfc}, {0xbe,0x5a}, {0xbe,0x55}, {0xe8,0xa4}, {0xe8,0xa1}, {0xe8,0x67}, {0xbe,0x50}, - {0xf9,0xd7}, {0x96,0x4a}, {0xbe,0x4f}, {0xbe,0x56}, {0x96,0xd8}, {0x99,0xfe}, {0xe8,0x65}, {0xbe,0x54}, {0xe8,0x71}, {0xe8,0x63}, - {0xe8,0x64}, {0xbe,0x4e}, {0xe8,0xa3}, {0xbe,0x58}, {0xe8,0x74}, {0xe8,0x79}, {0xe8,0x73}, {0xeb,0xee}, {0xe8,0x6f}, {0xe8,0x77}, - {0xe8,0x75}, {0xe8,0x68}, {0xe8,0x62}, {0xe8,0x7d}, {0xbe,0x57}, {0xe8,0x7e}, {0x90,0x4b}, {0xe8,0x78}, {0xe8,0x6d}, {0xe8,0x6b}, - {0xe8,0x66}, {0xfa,0x41}, {0xe8,0x6e}, {0xe8,0x7b}, {0xe8,0x6a}, {0xe8,0x7a}, {0xe8,0xa2}, {0x9a,0x40}, {0xbe,0x53}, {0x97,0x5b}, - {0xe8,0x76}, {0xe8,0x7c}, {0xe8,0x72}, {0xe8,0x6c}, {0xbe,0x51}, {0x9a,0x41}, {0x91,0xdd}, {0xe4,0xa8}, {0xe8,0x70}, {0xbe,0x59}, - {0xe8,0x69}, {0x93,0xfc}, {0x9a,0x42}, {0x9a,0x43}, {0x96,0x59}, {0xeb,0xf4}, {0xbf,0xf7}, {0xeb,0xf3}, {0xeb,0xf0}, {0xec,0x44}, - {0xbf,0xfb}, {0x9a,0x44}, {0xec,0x41}, {0xeb,0xf8}, {0xec,0x43}, {0xeb,0xe9}, {0xeb,0xf6}, {0x90,0x51}, {0xbf,0xfd}, {0xeb,0xe1}, - {0x94,0xbf}, {0xeb,0xdf}, {0xec,0x42}, {0xec,0x40}, {0xeb,0xfe}, {0xeb,0xed}, {0xeb,0xec}, {0xeb,0xe2}, {0xc0,0x40}, {0xeb,0xe8}, - {0xeb,0xf2}, {0xeb,0xfd}, {0xc0,0x43}, {0xec,0x45}, {0xc1,0xe8}, {0xc0,0x45}, {0xbf,0xfe}, {0xeb,0xe6}, {0xeb,0xef}, {0xeb,0xde}, - {0xeb,0xe0}, {0xbf,0xf5}, {0xc0,0x42}, {0xbf,0xfa}, {0xeb,0xe7}, {0xeb,0xf7}, {0xeb,0xf1}, {0xc0,0x41}, {0xeb,0xdd}, {0xc1,0xe3}, - {0xeb,0xf9}, {0xeb,0xfc}, {0xbf,0xfc}, {0x90,0xa2}, {0xeb,0xeb}, {0xc0,0x44}, {0xbf,0xf9}, {0x9c,0xab}, {0x97,0x76}, {0xbf,0xf8}, - {0xeb,0xf5}, {0xeb,0xfb}, {0xbf,0xf6}, {0xeb,0xe4}, {0xeb,0xfa}, {0xeb,0xe5}, {0xfc,0x55}, {0xfe,0x45}, {0x94,0xa8}, {0x9a,0x45}, - {0xfa,0x4b}, {0x9d,0xe1}, {0xeb,0xea}, {0xee,0xd2}, {0x96,0xd9}, {0xee,0xd7}, {0xc1,0xe5}, {0xc1,0xe7}, {0xee,0xdd}, {0xc1,0xe1}, - {0xee,0xec}, {0xee,0xe3}, {0xee,0xd8}, {0xee,0xd9}, {0xee,0xe2}, {0xc1,0xee}, {0xee,0xe1}, {0xee,0xd1}, {0xee,0xe0}, {0xee,0xd4}, - {0xee,0xed}, {0xc1,0xed}, {0xc1,0xeb}, {0xee,0xd5}, {0xee,0xe8}, {0x97,0x74}, {0xee,0xda}, {0xee,0xe7}, {0xfd,0xf5}, {0xee,0xe9}, - {0xee,0xd0}, {0xc1,0xe6}, {0x92,0xe5}, {0xee,0xea}, {0x96,0x45}, {0x91,0xda}, {0xee,0xde}, {0x90,0xa3}, {0xc1,0xea}, {0xee,0xdb}, - {0xa0,0x5f}, {0xc1,0xec}, {0xee,0xe4}, {0x90,0xaf}, {0x97,0xbf}, {0xc1,0xe4}, {0xee,0xd6}, {0xee,0xe5}, {0x91,0x4c}, {0xee,0xdf}, - {0xeb,0xe3}, {0xee,0xe6}, {0xee,0xd3}, {0x96,0x7a}, {0xc1,0xe9}, {0xee,0xeb}, {0x91,0xde}, {0xc1,0xe2}, {0xee,0xce}, {0x9a,0x46}, - {0xfe,0xb0}, {0x97,0x79}, {0x94,0x6c}, {0xf1,0x60}, {0xf1,0x59}, {0xc2,0xe9}, {0xf1,0x54}, {0xf1,0x63}, {0xf1,0x5b}, {0xee,0xdc}, - {0x98,0x58}, {0xf1,0x65}, {0xf1,0x55}, {0xc2,0xe8}, {0xf1,0x5f}, {0xc2,0xea}, {0xc2,0xf2}, {0xc2,0xf0}, {0xf1,0x61}, {0xc2,0xf1}, - {0xf1,0x57}, {0x92,0x66}, {0xf1,0x58}, {0xf1,0x5d}, {0xf1,0x62}, {0x93,0xfb}, {0xee,0xcd}, {0xc2,0xeb}, {0xf1,0x6a}, {0xf1,0x67}, - {0xf1,0x6b}, {0xf1,0x5e}, {0xf1,0x5a}, {0xf1,0x68}, {0xf3,0x6a}, {0xf1,0x5c}, {0xc2,0xee}, {0x9a,0x47}, {0xc2,0xed}, {0xee,0xcf}, - {0xc2,0xef}, {0xf1,0x64}, {0xf1,0x66}, {0xc2,0xec}, {0xf1,0x69}, {0xf1,0x53}, {0xf1,0x56}, {0x97,0x49}, {0x97,0x48}, {0x93,0x4a}, - {0x9c,0xe2}, {0xf3,0x73}, {0xf3,0x63}, {0xc3,0xeb}, {0xf3,0x71}, {0x92,0x64}, {0xf3,0x61}, {0xc3,0xec}, {0xf3,0x6c}, {0x91,0xdf}, - {0xf3,0x68}, {0xc3,0xf1}, {0xf3,0x72}, {0xf3,0x62}, {0xf3,0x65}, {0xc3,0xe9}, {0xf3,0x74}, {0xfb,0x79}, {0xf3,0x6d}, {0xf3,0x70}, - {0xc3,0xef}, {0xc3,0xf4}, {0xc3,0xf2}, {0xf3,0x69}, {0xf3,0x64}, {0x96,0xd7}, {0xc3,0xed}, {0xc3,0xee}, {0xf3,0x60}, {0xc3,0xea}, - {0x93,0x43}, {0xc3,0xe8}, {0xc3,0xf0}, {0xf3,0x6f}, {0xc3,0xf3}, {0xf3,0x6b}, {0xf3,0x75}, {0xc3,0xf5}, {0xf3,0x67}, {0xf3,0x6e}, - {0xfd,0xcb}, {0xfe,0x7a}, {0x91,0xdb}, {0x8c,0x6a}, {0xf4,0xf3}, {0xf5,0x42}, {0xf4,0xf5}, {0xf4,0xfc}, {0xf3,0x66}, {0xf4,0xfa}, - {0xf4,0xe9}, {0xf5,0x40}, {0xc4,0xc3}, {0xf4,0xed}, {0xf4,0xfe}, {0xf4,0xf4}, {0x97,0xaf}, {0xc4,0xc2}, {0x95,0xdd}, {0xf5,0x44}, - {0xf4,0xf6}, {0x93,0x48}, {0xf4,0xfb}, {0xf4,0xfd}, {0xf4,0xe7}, {0xf5,0x41}, {0xf4,0xf2}, {0xf4,0xf7}, {0xf4,0xeb}, {0xf4,0xef}, - {0xf5,0x43}, {0xf4,0xf9}, {0xf4,0xe8}, {0xf4,0xec}, {0xf4,0xee}, {0xf4,0xf8}, {0x9a,0x4b}, {0xc4,0xc1}, {0xf4,0xf1}, {0xfc,0x45}, - {0x9a,0x4d}, {0xf4,0xea}, {0x91,0xbc}, {0x90,0xe2}, {0x90,0xb4}, {0x95,0xe1}, {0xf4,0xf0}, {0xf6,0x61}, {0xf6,0x66}, {0xc5,0x4f}, - {0xf6,0x68}, {0x9a,0x4e}, {0xc5,0x49}, {0xf6,0x64}, {0xf6,0x6a}, {0xc5,0x4e}, {0xc5,0x4a}, {0xc5,0x4b}, {0xf6,0x60}, {0xf6,0x67}, - {0xc5,0x4d}, {0xf6,0x65}, {0xc5,0x4c}, {0xf6,0x5f}, {0xf6,0x63}, {0xf6,0x62}, {0x9a,0x4f}, {0xf6,0x5e}, {0xf6,0x69}, {0xfe,0x40}, - {0xfe,0x43}, {0xc5,0xb1}, {0xf7,0x6d}, {0xf7,0x70}, {0xf7,0x6c}, {0xf7,0x6e}, {0xf7,0x6f}, {0xf7,0x69}, {0xf7,0x6a}, {0xf7,0x67}, - {0x96,0xdd}, {0xf7,0x6b}, {0xf7,0x68}, {0xc5,0xb2}, {0xc5,0xb3}, {0x9a,0x51}, {0xf8,0x4b}, {0xf8,0x4d}, {0x96,0xa7}, {0x90,0xb0}, - {0xf8,0x4c}, {0xf8,0x4e}, {0xc5,0xe0}, {0xf8,0x4a}, {0xc5,0xdf}, {0xc5,0xe1}, {0x9c,0x4e}, {0x94,0x43}, {0xf8,0xcb}, {0xf8,0xcc}, - {0xc6,0x44}, {0xf8,0xca}, {0x8e,0xba}, {0xf9,0x53}, {0xf9,0x52}, {0xf9,0x54}, {0xc6,0x5f}, {0xf9,0x55}, {0xc6,0x5e}, {0xf9,0x56}, - {0xf9,0x72}, {0xf9,0x75}, {0xf9,0x74}, {0xc6,0x68}, {0xf9,0x73}, {0x9a,0x52}, {0xfc,0xc1}, {0xc6,0x72}, {0xc6,0x70}, {0xc6,0x71}, - {0xc6,0x77}, {0xf9,0xc0}, {0xf9,0xc1}, {0xf9,0xbf}, {0xf9,0xc9}, {0x8b,0xe9}, {0x9c,0xaf}, {0x8b,0xfd}, {0x9a,0xbc}, {0x9a,0xb8}, - {0x9a,0xae}, {0x9a,0xa7}, {0x9a,0x53}, {0x9d,0x74}, {0xaa,0xf8}, {0x8b,0xea}, {0xd8,0x44}, {0xdc,0x78}, {0xe8,0xa5}, {0xf3,0x76}, - {0x8b,0xeb}, {0xaa,0xf9}, {0xad,0xac}, {0xb0,0x7b}, {0x90,0xb2}, {0xd8,0x45}, {0xd8,0x46}, {0xb3,0xac}, {0xb6,0x7d}, {0xdc,0x7a}, - {0xdc,0x79}, {0xb6,0xa3}, {0xb6,0x7c}, {0xdc,0x7b}, {0xb6,0x7e}, {0xb6,0xa2}, {0xb6,0xa1}, {0xb6,0x7b}, {0x95,0xe9}, {0x95,0xe8}, - {0xb9,0x68}, {0x95,0xe6}, {0xe0,0xd0}, {0xe0,0xce}, {0xe0,0xcf}, {0xe0,0xcd}, {0x90,0xb5}, {0xbb,0xd2}, {0x9a,0x54}, {0xbb,0xd5}, - {0xbb,0xd7}, {0xbb,0xd6}, {0x90,0xb3}, {0x95,0xe7}, {0xbb,0xd3}, {0xbb,0xd4}, {0x8b,0x50}, {0xe8,0xa7}, {0xe8,0xa6}, {0xbe,0x5b}, - {0xe8,0xa8}, {0xe8,0xa9}, {0xbe,0x5c}, {0xec,0x4d}, {0xec,0x4b}, {0xee,0xf3}, {0xec,0x49}, {0xec,0x4a}, {0xc0,0x46}, {0xec,0x46}, - {0xec,0x4e}, {0xec,0x48}, {0xec,0x4c}, {0xee,0xef}, {0xee,0xf1}, {0xee,0xf2}, {0xc1,0xf3}, {0xee,0xee}, {0xc1,0xf2}, {0xee,0xf0}, - {0xc1,0xef}, {0xc1,0xf0}, {0xc1,0xf1}, {0xec,0x47}, {0xc2,0xf5}, {0xf1,0x6e}, {0xf1,0x6c}, {0xf1,0x6d}, {0xc2,0xf3}, {0xc2,0xf6}, - {0xc2,0xf4}, {0xf3,0x77}, {0xf3,0x78}, {0xc3,0xf6}, {0xf5,0x45}, {0xf5,0x47}, {0xf5,0x46}, {0xc4,0xc4}, {0xc5,0x50}, {0xf6,0x6d}, - {0xf6,0x6c}, {0xf6,0x6b}, {0x8b,0xec}, {0x9a,0x56}, {0xaa,0xfa}, {0x8b,0xfb}, {0xc9,0xaa}, {0xca,0x58}, {0xa6,0xe9}, {0xca,0x56}, - {0xca,0x59}, {0xca,0x57}, {0xcb,0xae}, {0xa8,0xc1}, {0xa8,0xc2}, {0xcb,0xb0}, {0xa8,0xbf}, {0xcb,0xaf}, {0xcb,0xad}, {0xa8,0xc0}, - {0xa8,0xbe}, {0x9a,0x57}, {0xa0,0xaa}, {0xcd,0xd8}, {0xcd,0xdb}, {0xaa,0xfd}, {0xcd,0xda}, {0xcd,0xd9}, {0xaa,0xfc}, {0xaa,0xfb}, - {0x9f,0xa6}, {0xab,0x40}, {0xcd,0xdc}, {0xaa,0xfe}, {0x99,0xcc}, {0xd0,0xc6}, {0xad,0xae}, {0xad,0xaf}, {0xad,0xb0}, {0xd0,0xc7}, - {0xd0,0xc3}, {0xad,0xad}, {0xd0,0xc4}, {0xd0,0xc5}, {0xd0,0xc2}, {0x9c,0x59}, {0xb0,0xa4}, {0xb0,0xa1}, {0xd4,0x45}, {0xb0,0xa2}, - {0xb0,0xa5}, {0xd4,0x46}, {0xb0,0x7e}, {0xb0,0x7c}, {0xb0,0x7d}, {0xb0,0xa3}, {0x99,0xb5}, {0xb3,0xad}, {0xd8,0x49}, {0xb3,0xb5}, - {0xd8,0x48}, {0xd8,0x4b}, {0xb3,0xb1}, {0xd8,0x4a}, {0xb6,0xab}, {0xb3,0xaf}, {0xb3,0xb2}, {0xb3,0xae}, {0xb3,0xb3}, {0xb3,0xb4}, - {0xb3,0xb0}, {0x90,0xbe}, {0xd8,0x47}, {0xb6,0xa7}, {0xdc,0x7d}, {0xdc,0xa3}, {0x9f,0xaf}, {0xdc,0xa2}, {0xb6,0xac}, {0xb6,0xa8}, - {0xb6,0xa9}, {0xdc,0x7c}, {0xdc,0x7e}, {0xdc,0xa1}, {0xb6,0xa4}, {0xb6,0xa6}, {0xb6,0xaa}, {0xb6,0xa5}, {0x95,0xf2}, {0xe0,0xd3}, - {0xe0,0xd1}, {0xe0,0xd2}, {0xb9,0x6a}, {0xb9,0x6b}, {0x90,0xbf}, {0xe0,0xd4}, {0xb9,0x69}, {0xbb,0xd8}, {0xbb,0xda}, {0xbb,0xd9}, - {0xe4,0xbb}, {0xe4,0xbc}, {0xe8,0xab}, {0x90,0xc1}, {0xe8,0xaa}, {0xfe,0xe4}, {0xc0,0x47}, {0xc0,0x48}, {0xec,0x4f}, {0xc0,0x49}, - {0xee,0xf6}, {0xee,0xf4}, {0xee,0xf5}, {0xc1,0xf4}, {0xf1,0x6f}, {0xc3,0xf7}, {0x90,0xc4}, {0xc1,0xf5}, {0xab,0x41}, {0xb0,0xa6}, - {0xd4,0x47}, {0x90,0xc7}, {0xd8,0x4c}, {0xb3,0xb6}, {0xb6,0xad}, {0xdc,0xa4}, {0xdc,0xa6}, {0xb6,0xaf}, {0xb6,0xae}, {0xb6,0xb0}, - {0xb6,0xb1}, {0xdc,0xa5}, {0xb9,0x6e}, {0xb9,0x6f}, {0xb9,0x6d}, {0xbb,0xdb}, {0xb9,0x6c}, {0xe0,0xd5}, {0xbb,0xdc}, {0xe8,0xac}, - {0xec,0x50}, {0xc0,0x4a}, {0xc1,0xf6}, {0xf1,0x70}, {0xf1,0x74}, {0xc2,0xf9}, {0xf1,0x71}, {0xc2,0xfa}, {0xc2,0xf8}, {0xf1,0x75}, - {0xc2,0xfb}, {0xf1,0x73}, {0xf3,0x79}, {0xc2,0xf7}, {0xc3,0xf8}, {0xf8,0xcd}, {0xab,0x42}, {0xb3,0xb8}, {0xb3,0xb7}, {0xb6,0xb2}, - {0xdc,0xa8}, {0xdc,0xa7}, {0xb6,0xb3}, {0x92,0xe4}, {0xe0,0xd9}, {0xb9,0x73}, {0xb9,0x70}, {0xe0,0xd8}, {0xb9,0x72}, {0xe0,0xd6}, - {0xb9,0x71}, {0xe0,0xd7}, {0xe4,0xbd}, {0xbb,0xdd}, {0xe8,0xaf}, {0x9f,0x52}, {0xbe,0x5d}, {0xe8,0xad}, {0xbe,0x5e}, {0xbe,0x5f}, - {0xe8,0xae}, {0xbe,0x60}, {0xec,0x51}, {0xc0,0x4e}, {0xc0,0x4b}, {0xc0,0x50}, {0xec,0x53}, {0xc0,0x4c}, {0xec,0x52}, {0xc0,0x4f}, - {0xc0,0x4d}, {0xee,0xf9}, {0xee,0xfb}, {0x90,0xdb}, {0xc1,0xf7}, {0xee,0xfa}, {0xc1,0xf8}, {0xee,0xf8}, {0xee,0xf7}, {0xa0,0x66}, - {0xf1,0x77}, {0xf1,0x76}, {0xc2,0xfc}, {0xf1,0x78}, {0xf3,0x7e}, {0xc3,0xfa}, {0xf3,0x7d}, {0xf3,0x7a}, {0xc3,0xf9}, {0xf3,0x7b}, - {0xf3,0x7c}, {0xf5,0x48}, {0xf5,0x49}, {0xc4,0xc5}, {0x90,0xd2}, {0xc5,0x53}, {0xf6,0x6e}, {0x90,0xd4}, {0xc5,0x51}, {0xc5,0x52}, - {0xf6,0x6f}, {0xc5,0xb4}, {0xc5,0xb5}, {0xf7,0x71}, {0x9a,0x5b}, {0x95,0xfd}, {0xc6,0x45}, {0xf8,0xcf}, {0xc6,0x47}, {0xf8,0xce}, - {0xf8,0xd0}, {0xc6,0x46}, {0xf9,0x57}, {0xf9,0xad}, {0x8b,0xc4}, {0xab,0x43}, {0x8c,0x66}, {0xb9,0x74}, {0x90,0xde}, {0xe4,0xbe}, - {0xe8,0xb0}, {0xc0,0x51}, {0xc0,0x52}, {0x9c,0xe4}, {0xab,0x44}, {0x90,0xe1}, {0xbe,0x61}, {0xc3,0xfb}, {0xad,0xb1}, {0xc0,0x53}, - {0xc5,0xe2}, {0xad,0xb2}, {0xd8,0x4d}, {0xdc,0xa9}, {0x9e,0x46}, {0xdc,0xab}, {0xdc,0xaa}, {0x96,0x51}, {0xe0,0xdd}, {0xe0,0xda}, - {0xb9,0x75}, {0xb9,0x76}, {0xe0,0xdb}, {0xe0,0xdc}, {0xe4,0xc0}, {0xe4,0xc5}, {0xbb,0xde}, {0xe4,0xbf}, {0xe4,0xc1}, {0xe4,0xc8}, - {0xe4,0xc3}, {0xe4,0xc7}, {0xe4,0xc4}, {0xe4,0xc2}, {0xe4,0xc6}, {0xbb,0xdf}, {0xfb,0x58}, {0xe8,0xb3}, {0x90,0xe6}, {0xe8,0xb1}, - {0xbe,0x63}, {0xbe,0x62}, {0xe8,0xb2}, {0xbe,0x64}, {0xec,0x56}, {0xec,0x55}, {0xc0,0x54}, {0xec,0x54}, {0xee,0xfc}, {0x96,0x50}, - {0xee,0xfe}, {0xef,0x41}, {0xef,0x40}, {0x90,0xe7}, {0xc1,0xf9}, {0xee,0xfd}, {0xf1,0xa1}, {0xc2,0xfd}, {0xf1,0x7d}, {0xf1,0xa2}, - {0xc2,0xfe}, {0xf1,0x7b}, {0xf1,0x7e}, {0xf1,0x7c}, {0xf1,0x79}, {0xc3,0x40}, {0xf1,0x7a}, {0x90,0xe8}, {0x9a,0x5d}, {0xf3,0xa1}, - {0x9f,0x7a}, {0xf3,0xa3}, {0xf3,0xa2}, {0x9b,0x5c}, {0xf5,0x4a}, {0x9f,0x7c}, {0xf5,0x4b}, {0xfc,0x52}, {0x90,0xe9}, {0xf6,0x70}, - {0x90,0xea}, {0xc5,0xb7}, {0x9a,0x5e}, {0xc5,0xb6}, {0xf8,0x4f}, {0xf8,0x50}, {0xc6,0x48}, {0xf8,0xd1}, {0x9f,0x76}, {0xc6,0x69}, - {0xad,0xb3}, {0xb6,0xb4}, {0xe4,0xca}, {0xe4,0xc9}, {0xe8,0xb5}, {0xe8,0xb4}, {0x90,0xeb}, {0xc1,0xfa}, {0xef,0x43}, {0xef,0x42}, - {0xf1,0xa5}, {0xf1,0xa3}, {0xf1,0xa6}, {0xf1,0xa4}, {0xc3,0xfc}, {0xf3,0xa4}, {0xf3,0xa5}, {0xf3,0xa6}, {0x90,0xec}, {0xf6,0x71}, - {0xf7,0x72}, {0xf8,0xd2}, {0x8b,0xee}, {0xad,0xb4}, {0x90,0xee}, {0xec,0x57}, {0xef,0x44}, {0x91,0xc6}, {0xad,0xb5}, {0x90,0xf2}, - {0xbb,0xe0}, {0xec,0x58}, {0xc3,0x41}, {0xf1,0xa7}, {0xc3,0xfd}, {0xf5,0x4c}, {0xf5,0x4d}, {0xc5,0x54}, {0xf8,0x51}, {0xad,0xb6}, - {0xb3,0xbb}, {0xb3,0xbc}, {0xd8,0x4e}, {0xb6,0xb5}, {0xb6,0xb6}, {0xdc,0xac}, {0xb6,0xb7}, {0xb9,0x7a}, {0xb9,0x7c}, {0xe0,0xdf}, - {0xe0,0xe0}, {0xe0,0xde}, {0xb9,0x77}, {0xb9,0x78}, {0xb9,0x7b}, {0xb9,0x79}, {0xfc,0xbc}, {0x8a,0x74}, {0xe4,0xcb}, {0xbb,0xe1}, - {0xbb,0xe2}, {0xe8,0xbc}, {0xbe,0x67}, {0xe8,0xb7}, {0xe8,0xb6}, {0x96,0x57}, {0xe8,0xbb}, {0xbe,0x65}, {0x9c,0xef}, {0xc0,0x5b}, - {0xe8,0xb8}, {0xe8,0xbd}, {0xe8,0xba}, {0xe8,0xb9}, {0xbe,0x66}, {0xc0,0x59}, {0x9f,0xdf}, {0xec,0x5a}, {0xc0,0x55}, {0xec,0x5b}, - {0x90,0xf7}, {0x90,0xf6}, {0xec,0x59}, {0xc0,0x58}, {0xc0,0x56}, {0xc0,0x5a}, {0xc0,0x57}, {0xef,0x45}, {0xef,0x4a}, {0xef,0x46}, - {0xef,0x49}, {0xc1,0xfb}, {0x9b,0x5e}, {0xed,0xd4}, {0xef,0x48}, {0xef,0x47}, {0x90,0xf8}, {0xc3,0x44}, {0xc3,0x42}, {0xc3,0x45}, - {0xc3,0x43}, {0xf1,0xa8}, {0xf1,0xa9}, {0xf1,0xaa}, {0xc3,0x46}, {0xf3,0xaa}, {0xc4,0x40}, {0xf3,0xa8}, {0xc4,0x41}, {0xf3,0xa7}, - {0xf3,0xa9}, {0xc3,0xfe}, {0xf5,0x51}, {0xf5,0x4e}, {0xf5,0x4f}, {0xf5,0x50}, {0xf6,0x72}, {0xc5,0x56}, {0x90,0xf9}, {0xc5,0x55}, - {0x8c,0xc9}, {0xf7,0x74}, {0xf7,0x73}, {0xc5,0xb8}, {0xfa,0x6a}, {0xc5,0xe3}, {0xc6,0x49}, {0xc6,0x60}, {0xf9,0x58}, {0xf9,0xae}, - {0xf9,0xaf}, {0x8b,0xef}, {0xad,0xb7}, {0xdc,0xad}, {0xe0,0xe1}, {0xe4,0xcc}, {0xe4,0xcd}, {0xbb,0xe3}, {0xbb,0xe4}, {0xe8,0xbe}, - {0xbe,0x68}, {0x9f,0xe0}, {0xc1,0xfc}, {0x91,0x42}, {0xf1,0xab}, {0x9a,0x62}, {0xc3,0x47}, {0xf3,0xad}, {0xc4,0x42}, {0xf3,0xac}, - {0xf3,0xae}, {0xf3,0xab}, {0xf6,0x75}, {0xf5,0x52}, {0xf5,0x53}, {0x95,0x69}, {0xc4,0xc6}, {0xf6,0x74}, {0x91,0x44}, {0x91,0x43}, - {0xf6,0x73}, {0x91,0x41}, {0xf7,0x75}, {0xf9,0xb0}, {0x8b,0xf0}, {0xad,0xb8}, {0x96,0x60}, {0x8b,0xf1}, {0xad,0xb9}, {0x99,0xf6}, - {0x91,0x49}, {0xb0,0xa7}, {0xd4,0x48}, {0xd8,0x4f}, {0x91,0x4a}, {0xb6,0xb8}, {0xb6,0xbb}, {0xb6,0xb9}, {0xdc,0xae}, {0x91,0x4b}, - {0xb6,0xbd}, {0xb6,0xba}, {0x9a,0x64}, {0xb6,0xbc}, {0xb9,0x7e}, {0x8a,0xbf}, {0xe0,0xe2}, {0xe0,0xe3}, {0xe8,0xc0}, {0xb9,0x7d}, - {0xb9,0xa1}, {0xb9,0xa2}, {0xe4,0xcf}, {0xe4,0xce}, {0xbb,0xe5}, {0xbb,0xe6}, {0xe4,0xd0}, {0xe8,0xbf}, {0xbb,0xe8}, {0xbe,0x69}, - {0xbb,0xe7}, {0x9a,0x66}, {0xc0,0x5c}, {0xe8,0xc1}, {0xbe,0x6b}, {0xbe,0x6a}, {0xe8,0xc2}, {0xe8,0xc5}, {0xe8,0xc3}, {0xe8,0xc4}, - {0xbe,0x6c}, {0x9a,0x67}, {0xc0,0x61}, {0xc0,0x5f}, {0x9a,0x69}, {0xc0,0x5e}, {0xec,0x5d}, {0xc0,0x60}, {0xec,0x5c}, {0xef,0x4b}, - {0xec,0x5e}, {0xc0,0x5d}, {0xec,0x5f}, {0xef,0x4e}, {0xef,0x4c}, {0xef,0x4d}, {0xef,0x52}, {0xc3,0x4b}, {0xef,0x51}, {0xef,0x54}, - {0xef,0x53}, {0xef,0x50}, {0xef,0x4f}, {0xc1,0xfd}, {0x9a,0x6a}, {0x96,0x52}, {0x91,0x4d}, {0xf1,0xae}, {0x96,0x66}, {0xf1,0xad}, - {0xc3,0x4a}, {0xc3,0x48}, {0xc3,0x49}, {0x9f,0x7b}, {0xf1,0xac}, {0x9a,0x6b}, {0xf3,0xb1}, {0xc4,0x43}, {0xf3,0xb0}, {0xf3,0xaf}, - {0xc4,0x44}, {0xa0,0x6c}, {0xf5,0x58}, {0xf5,0x57}, {0x96,0x67}, {0xf5,0x55}, {0xf5,0x54}, {0xc4,0xc8}, {0xc4,0xc7}, {0xf5,0x59}, - {0xf7,0x76}, {0xc5,0xb9}, {0xf6,0x77}, {0xc5,0x57}, {0xf6,0x76}, {0xf5,0x56}, {0xf7,0x77}, {0xc5,0xe4}, {0x9a,0x6c}, {0xc6,0x61}, - {0xf9,0x59}, {0xf9,0xb1}, {0x9a,0x6d}, {0x8b,0xf2}, {0xad,0xba}, {0xd8,0x50}, {0xef,0x55}, {0xad,0xbb}, {0x96,0x6a}, {0xe4,0xd2}, - {0xe4,0xd1}, {0xec,0x60}, {0xef,0x57}, {0xef,0x56}, {0xfc,0xea}, {0xc3,0x4c}, {0xf3,0xb2}, {0xf3,0xb3}, {0xc4,0xc9}, {0x96,0x6c}, - {0xf9,0xb2}, {0xb0,0xa8}, {0xb6,0xbf}, {0xb6,0xbe}, {0xe0,0xe4}, {0xe0,0xe6}, {0xb9,0xa4}, {0xe0,0xe5}, {0xb9,0xa3}, {0xb9,0xa5}, - {0xe0,0xe7}, {0x91,0xc4}, {0xe4,0xd4}, {0xe4,0xd6}, {0xe4,0xd5}, {0x96,0x77}, {0xe4,0xd8}, {0xbb,0xe9}, {0xe4,0xd7}, {0xe4,0xd3}, - {0x99,0xf4}, {0x9a,0x6f}, {0xe4,0xd9}, {0xe8,0xcc}, {0xe8,0xcf}, {0xe8,0xd1}, {0xe8,0xc7}, {0xe8,0xcb}, {0xe8,0xc8}, {0xbe,0x6e}, - {0xbe,0x71}, {0xbe,0x73}, {0xe8,0xc9}, {0xe8,0xca}, {0xbe,0x72}, {0xe8,0xcd}, {0xe8,0xd0}, {0xe8,0xce}, {0xbe,0x74}, {0x9f,0xab}, - {0xbe,0x70}, {0xe8,0xc6}, {0xbe,0x6d}, {0xbe,0x6f}, {0x8c,0xbe}, {0x8e,0xc1}, {0xc0,0x63}, {0xec,0x66}, {0xec,0x64}, {0xec,0x63}, - {0x95,0x55}, {0xec,0x69}, {0xec,0x68}, {0xec,0x67}, {0xec,0x62}, {0xc0,0x62}, {0xec,0x61}, {0xec,0x65}, {0xc0,0x64}, {0xef,0x5a}, - {0x91,0x52}, {0xef,0x5e}, {0xef,0x5b}, {0xef,0x5d}, {0xef,0x5c}, {0xef,0x59}, {0xef,0x5f}, {0xef,0x62}, {0xef,0x60}, {0xef,0x61}, - {0xc2,0x40}, {0xc1,0xfe}, {0xef,0x58}, {0xef,0x63}, {0xf1,0xb3}, {0xf1,0xb6}, {0xf1,0xb8}, {0xf1,0xb7}, {0xf1,0xb1}, {0xf1,0xb5}, - {0xf1,0xb0}, {0x91,0x53}, {0xf1,0xb2}, {0xc3,0x4d}, {0xf1,0xaf}, {0x91,0x55}, {0xf1,0xb4}, {0xf3,0xc0}, {0xf3,0xb5}, {0xc4,0x45}, - {0xc4,0x46}, {0xf3,0xb4}, {0xf3,0xb9}, {0xf3,0xbf}, {0xf3,0xb7}, {0xf3,0xbe}, {0x95,0x5d}, {0xf3,0xbb}, {0x96,0x71}, {0xf3,0xba}, - {0xf3,0xbd}, {0xf3,0xb8}, {0xf3,0xb6}, {0x9c,0x6d}, {0xf3,0xbc}, {0xf5,0x60}, {0xf5,0x5e}, {0xc4,0xca}, {0xf5,0x5d}, {0xf5,0x63}, - {0xf5,0x61}, {0x96,0x73}, {0xc4,0xcb}, {0xf5,0x5c}, {0xf5,0x5a}, {0xf5,0x5b}, {0xc4,0xcd}, {0xf5,0x5f}, {0xc4,0xcc}, {0xf5,0x62}, - {0xf6,0x78}, {0xf6,0x7e}, {0x91,0x54}, {0x9a,0x71}, {0xf6,0x79}, {0xc5,0x5b}, {0xf6,0xa1}, {0xc5,0x5a}, {0xf6,0x7d}, {0xf6,0x7c}, - {0xc5,0x59}, {0xf6,0x7b}, {0xc5,0x58}, {0xf6,0x7a}, {0xf7,0x7d}, {0xf7,0xa1}, {0xf7,0x7e}, {0xf7,0x7b}, {0xc5,0xbb}, {0xf7,0x78}, - {0xf7,0x7c}, {0xf7,0xa3}, {0xf7,0xa2}, {0xf7,0x79}, {0xf7,0x7a}, {0xc5,0xba}, {0xf8,0x52}, {0xc5,0xe7}, {0x91,0x56}, {0xf8,0x53}, - {0xc5,0xe5}, {0xc5,0xe6}, {0x96,0x6d}, {0xf8,0xd3}, {0xc6,0x4a}, {0xf9,0x76}, {0xc6,0x6a}, {0x95,0x57}, {0xf9,0xb3}, {0xc6,0x6b}, - {0xf9,0xb4}, {0xf9,0xb5}, {0xf9,0xc3}, {0xf9,0xc2}, {0xc6,0x7a}, {0xf9,0xcd}, {0x89,0xc6}, {0x89,0xc7}, {0xb0,0xa9}, {0xe0,0xe9}, - {0xe0,0xe8}, {0xbb,0xea}, {0xbb,0xeb}, {0xe4,0xda}, {0x8a,0x6a}, {0xe8,0xd2}, {0xec,0x6c}, {0x8b,0x57}, {0xbe,0x75}, {0xc0,0x65}, - {0xec,0x6a}, {0x9f,0xe1}, {0xec,0x6d}, {0xc0,0x66}, {0x9b,0x5f}, {0xef,0x64}, {0xec,0x6b}, {0xf1,0xb9}, {0xc3,0x4e}, {0xf3,0xc1}, - {0xf5,0x66}, {0xf5,0x64}, {0xf5,0x65}, {0xf6,0xa2}, {0xc5,0x5c}, {0xf7,0xa4}, {0xc5,0xea}, {0xc5,0xbc}, {0xc5,0xe8}, {0xc5,0xe9}, - {0xf8,0xd4}, {0xc6,0x62}, {0xa0,0x5d}, {0xb0,0xaa}, {0xf1,0xba}, {0xd4,0x49}, {0x91,0x5b}, {0xb9,0xa6}, {0x91,0x5c}, {0xe4,0xdb}, - {0xbb,0xec}, {0xe4,0xdc}, {0xe8,0xd4}, {0xe8,0xd3}, {0xc0,0x68}, {0xbe,0x76}, {0xbe,0x77}, {0xe8,0xd7}, {0xe8,0xd6}, {0xe8,0xd5}, - {0x91,0x5e}, {0xec,0x6e}, {0xec,0x71}, {0xec,0x70}, {0xec,0x6f}, {0xc0,0x67}, {0xef,0x68}, {0xef,0x66}, {0xef,0x65}, {0x9f,0x5c}, - {0xef,0x67}, {0x9f,0x57}, {0xc3,0x4f}, {0xf1,0xbc}, {0xf1,0xbd}, {0xc3,0x50}, {0xf1,0xbb}, {0x9f,0x65}, {0xf3,0xc3}, {0xf3,0xc2}, - {0xf3,0xc5}, {0xc4,0x47}, {0xf3,0xc4}, {0x9a,0x72}, {0xf5,0x67}, {0xf5,0x69}, {0xf5,0x68}, {0x91,0x60}, {0xf6,0xa3}, {0xf6,0xa6}, - {0xf6,0xa4}, {0xf6,0xa5}, {0xf7,0xa5}, {0xc5,0xbd}, {0xf8,0x54}, {0xf8,0x55}, {0xf8,0x56}, {0xc6,0x4b}, {0xc6,0x63}, {0xf9,0xb6}, - {0xb0,0xab}, {0xbe,0x78}, {0xc0,0x69}, {0xf1,0xbe}, {0x9f,0x5e}, {0xf7,0xa6}, {0x91,0x61}, {0xf9,0xc4}, {0xd4,0x4a}, {0xc6,0x7b}, - {0xb0,0xac}, {0xec,0x72}, {0x91,0x64}, {0xf1,0xbf}, {0xf3,0xc6}, {0x9f,0x41}, {0xf6,0xa7}, {0xf7,0xa7}, {0xb0,0xad}, {0xe4,0xdd}, - {0xe4,0xde}, {0x91,0x69}, {0xbb,0xed}, {0xbb,0xee}, {0xe8,0xd9}, {0xbe,0x7a}, {0xbe,0x79}, {0xe8,0xd8}, {0xef,0x69}, {0xf1,0xc0}, - {0xf1,0xc2}, {0xf1,0xc1}, {0xc3,0x53}, {0xc3,0x52}, {0xc3,0x51}, {0x91,0x68}, {0xc5,0x5e}, {0xf6,0xa8}, {0xc5,0x5d}, {0xf7,0xa9}, - {0xf7,0xa8}, {0xc6,0x4c}, {0xf8,0xd5}, {0xb3,0xbd}, {0xe0,0xea}, {0xe4,0xe1}, {0xe4,0xdf}, {0xe4,0xe0}, {0xe8,0xe2}, {0xe8,0xdd}, - {0xe8,0xda}, {0xe8,0xe1}, {0x9a,0x74}, {0xe8,0xe3}, {0xbe,0x7c}, {0xe8,0xe0}, {0xe8,0xdc}, {0xe8,0xdb}, {0xe8,0xdf}, {0xe8,0xde}, - {0xbe,0x7b}, {0xec,0x7d}, {0xec,0x78}, {0xec,0x76}, {0xec,0xa1}, {0xec,0x77}, {0x96,0xb2}, {0xec,0x73}, {0x9a,0x75}, {0xec,0x79}, - {0xfd,0xa5}, {0xec,0x74}, {0xef,0x72}, {0xec,0x75}, {0xec,0xa2}, {0x9e,0xe9}, {0x8b,0xba}, {0x91,0x6d}, {0xa0,0x60}, {0xec,0x7c}, - {0xc0,0x6a}, {0xec,0x7b}, {0xec,0x7a}, {0xec,0x7e}, {0x9f,0xde}, {0xef,0x6a}, {0xef,0x6d}, {0x9f,0xc3}, {0xef,0x6c}, {0x96,0xb5}, - {0xef,0x74}, {0xef,0x6f}, {0xef,0x73}, {0xef,0x71}, {0xef,0x70}, {0xef,0x6e}, {0xef,0x6b}, {0xc2,0x43}, {0xc2,0x42}, {0xc2,0x44}, - {0xc2,0x41}, {0xef,0x75}, {0xa0,0x67}, {0xf1,0xc8}, {0xf1,0xcb}, {0xf1,0xc9}, {0xf1,0xcd}, {0xf1,0xce}, {0xf1,0xc6}, {0xc3,0x58}, - {0xf1,0xc7}, {0xf1,0xc5}, {0xf1,0xcc}, {0xf1,0xc4}, {0xf1,0xc3}, {0xc3,0x57}, {0xc3,0x55}, {0xc3,0x54}, {0x96,0xb3}, {0xf1,0xca}, - {0xf3,0xcf}, {0xf3,0xd5}, {0xc4,0x4a}, {0xf3,0xd0}, {0xf3,0xd3}, {0xf3,0xd7}, {0xc4,0x4b}, {0xf3,0xd2}, {0x9a,0x76}, {0xf3,0xca}, - {0xf3,0xc9}, {0xf3,0xd6}, {0xf3,0xcd}, {0xf3,0xcb}, {0xf3,0xd4}, {0xf3,0xcc}, {0xc4,0x49}, {0xc4,0x48}, {0x95,0xd5}, {0xf3,0xc7}, - {0xf3,0xc8}, {0xf3,0xd1}, {0x9e,0xca}, {0xf3,0xce}, {0x9a,0x77}, {0x9a,0x78}, {0xf5,0x6c}, {0xf5,0x6f}, {0xc3,0x56}, {0x91,0x70}, - {0x91,0x6f}, {0xf5,0x6d}, {0xf5,0x73}, {0xf5,0x71}, {0xf5,0x6b}, {0xf5,0x76}, {0x9f,0xa3}, {0xf5,0x6a}, {0x91,0x71}, {0xc4,0xcf}, - {0xf5,0x72}, {0x96,0xb1}, {0xf5,0x6e}, {0xc4,0xce}, {0xf5,0x75}, {0x9f,0x63}, {0xf5,0x74}, {0x9f,0x67}, {0xf6,0xab}, {0xf6,0xaa}, - {0x8b,0xb9}, {0x9a,0x7a}, {0xf6,0xb1}, {0xf6,0xad}, {0xf6,0xb0}, {0xc5,0x60}, {0x8b,0x56}, {0xf6,0xae}, {0xf6,0xaf}, {0xf6,0xa9}, - {0xf6,0xac}, {0xc5,0x5f}, {0x9a,0xda}, {0xc5,0xbf}, {0xf7,0xb4}, {0xf7,0xaf}, {0xf7,0xb3}, {0x96,0xb0}, {0xf7,0xb6}, {0xf7,0xb2}, - {0xf7,0xae}, {0x9a,0x7e}, {0xc5,0xc1}, {0xf7,0xb1}, {0xf7,0xb5}, {0xc5,0xc0}, {0xf7,0xac}, {0xf5,0x70}, {0xf7,0xb0}, {0xf7,0xad}, - {0x9d,0xde}, {0xf7,0xaa}, {0xf7,0xab}, {0xc5,0xbe}, {0xf8,0x5a}, {0xf8,0x5c}, {0xf8,0x5f}, {0xf8,0x5b}, {0xf8,0x60}, {0x96,0xad}, - {0xf8,0x59}, {0xf8,0x57}, {0x96,0xae}, {0xc5,0xeb}, {0xf8,0x5d}, {0xc5,0xed}, {0xc5,0xec}, {0xf8,0x58}, {0xf8,0x5e}, {0x9e,0xa1}, - {0xf8,0xda}, {0xc6,0x4d}, {0xf8,0xdb}, {0xf8,0xd9}, {0xf8,0xd6}, {0xf8,0xd8}, {0xf8,0xd7}, {0xf9,0x5a}, {0xf9,0x5c}, {0xf9,0x5b}, - {0xf9,0x79}, {0x9e,0x50}, {0xf9,0x78}, {0xf9,0x77}, {0xf9,0x7a}, {0xc6,0x73}, {0xc6,0x74}, {0xf9,0xca}, {0xf9,0xce}, {0x96,0xaf}, - {0x8b,0xf4}, {0xb3,0xbe}, {0xdc,0xaf}, {0xe0,0xed}, {0xb9,0xa7}, {0xe0,0xeb}, {0xe0,0xec}, {0xe4,0xe2}, {0xe4,0xe3}, {0xbb,0xf1}, - {0xbb,0xef}, {0xe4,0xe4}, {0xbb,0xf0}, {0xe8,0xe8}, {0xe8,0xeb}, {0xe8,0xe5}, {0xe8,0xec}, {0xe8,0xe4}, {0xe8,0xe6}, {0xe8,0xe7}, - {0xe8,0xea}, {0x9f,0xa4}, {0xbe,0xa1}, {0xe8,0xef}, {0xe8,0xee}, {0xbe,0x7d}, {0xe8,0xe9}, {0xe8,0xed}, {0xbe,0x7e}, {0x96,0xbd}, - {0xec,0xac}, {0xc0,0x6f}, {0xec,0xa7}, {0xc0,0x6b}, {0x96,0xf4}, {0xec,0xa4}, {0xec,0xaa}, {0xec,0xad}, {0xc0,0x70}, {0xec,0xa9}, - {0xec,0xa6}, {0xec,0xae}, {0xec,0xa5}, {0x96,0xb8}, {0xec,0xab}, {0xc0,0x6c}, {0xec,0xa3}, {0xc0,0x6d}, {0xc0,0x6e}, {0xec,0xa8}, - {0xef,0xa9}, {0xef,0x7a}, {0xef,0x7b}, {0xef,0x7e}, {0xef,0x7c}, {0xef,0x76}, {0xfa,0xa1}, {0xef,0x79}, {0xef,0xa5}, {0xef,0x7d}, - {0x91,0xa7}, {0xc2,0x45}, {0xef,0xa7}, {0xef,0xa4}, {0xc2,0x46}, {0xef,0xa6}, {0xef,0x77}, {0xef,0xa2}, {0xef,0xa3}, {0xa0,0x5e}, - {0xef,0xa1}, {0x9a,0x7d}, {0xf1,0xd2}, {0xf1,0xd4}, {0xf1,0xd7}, {0x89,0x48}, {0xf1,0xd1}, {0x9e,0xb1}, {0xc3,0x59}, {0xf1,0xd9}, - {0xf1,0xd0}, {0xf1,0xda}, {0xf1,0xd6}, {0xf1,0xd8}, {0xf1,0xdc}, {0xf1,0xd5}, {0xf1,0xdd}, {0xf1,0xd3}, {0xf1,0xcf}, {0xc3,0x5a}, - {0x9d,0xdb}, {0xf1,0xdb}, {0xc3,0x5b}, {0xc4,0x4d}, {0xef,0x78}, {0xf3,0xf1}, {0xf3,0xe8}, {0xc4,0x4f}, {0xf3,0xe4}, {0xc4,0x50}, - {0x95,0xbf}, {0x8a,0x73}, {0xf3,0xed}, {0xf3,0xe7}, {0xf3,0xdd}, {0xc4,0x4e}, {0xf3,0xea}, {0xf3,0xe5}, {0xf3,0xe6}, {0xf3,0xd8}, - {0xf3,0xdf}, {0xf3,0xee}, {0xf3,0xeb}, {0x9e,0xfe}, {0xf3,0xe3}, {0x91,0x7a}, {0xf3,0xef}, {0xf3,0xde}, {0xf3,0xd9}, {0xf3,0xec}, - {0x91,0x7b}, {0xf3,0xdb}, {0xf3,0xe9}, {0xf3,0xe0}, {0xf3,0xf0}, {0xf3,0xdc}, {0xc4,0x4c}, {0xf3,0xda}, {0xf3,0xe1}, {0xf3,0xe2}, - {0xf5,0x7d}, {0xf5,0x7b}, {0x9a,0xa3}, {0xf5,0xa2}, {0xf5,0xae}, {0xf5,0xa5}, {0xf5,0x7c}, {0xf5,0x78}, {0xf5,0xa7}, {0xf5,0x7e}, - {0xf5,0xa3}, {0xf5,0x7a}, {0xf5,0xaa}, {0xf5,0x77}, {0xf5,0xa1}, {0xf5,0xa6}, {0xf5,0xa8}, {0xf5,0xab}, {0xf5,0x79}, {0x96,0xc2}, - {0xf5,0xaf}, {0xf5,0xb0}, {0xf5,0xa9}, {0xf5,0xad}, {0xf5,0xa4}, {0x9f,0x77}, {0xf6,0xc1}, {0xf6,0xc4}, {0xc5,0x61}, {0xf6,0xc3}, - {0xf6,0xc8}, {0xf6,0xc6}, {0xc5,0x62}, {0xf6,0xbd}, {0xf6,0xb3}, {0xf6,0xb2}, {0xc5,0x64}, {0xf6,0xbf}, {0xf6,0xc0}, {0xf6,0xbc}, - {0xf6,0xb4}, {0x9a,0xa4}, {0xf6,0xb9}, {0xf5,0xac}, {0x9a,0xa5}, {0xf6,0xb5}, {0xc5,0x63}, {0xf6,0xbb}, {0x91,0xa1}, {0xf6,0xba}, - {0xf6,0xb6}, {0xf6,0xc2}, {0x89,0xb8}, {0xf6,0xb7}, {0xf7,0xbb}, {0xf6,0xc5}, {0xf6,0xc7}, {0xf6,0xbe}, {0xf6,0xb8}, {0xf7,0xbc}, - {0xf7,0xbe}, {0xf7,0xb8}, {0xc5,0xc2}, {0x91,0x73}, {0xf7,0xc5}, {0xf7,0xc3}, {0xc5,0xc3}, {0xf7,0xc2}, {0xf7,0xc1}, {0xf7,0xba}, - {0xf7,0xb7}, {0xf7,0xbd}, {0xf7,0xc6}, {0xf7,0xb9}, {0xf7,0xbf}, {0xf8,0x69}, {0xf8,0x6e}, {0xf8,0x64}, {0xf8,0x67}, {0xc5,0xee}, - {0xf8,0x6b}, {0xf8,0x72}, {0xf7,0xc0}, {0xf8,0x65}, {0xf8,0x6f}, {0xf8,0x73}, {0xf8,0x6a}, {0xf8,0x63}, {0xf8,0x6d}, {0xf8,0x6c}, - {0xf8,0x71}, {0xf8,0x70}, {0xf7,0xc4}, {0xf8,0x68}, {0xf8,0x62}, {0xf8,0x66}, {0xc6,0x4e}, {0xc6,0x4f}, {0xf8,0x61}, {0x9a,0xa6}, - {0xf8,0xe6}, {0xf8,0xdd}, {0xf8,0xe5}, {0xf8,0xe2}, {0xf8,0xe3}, {0xf8,0xdc}, {0xf8,0xdf}, {0xf8,0xe7}, {0xf8,0xe1}, {0xf8,0xe0}, - {0xf8,0xde}, {0xf8,0xe4}, {0x89,0xbd}, {0xf9,0x5d}, {0x89,0xb9}, {0xf9,0x5e}, {0x91,0x7d}, {0xf9,0x60}, {0xf9,0x5f}, {0xf9,0x62}, - {0xf9,0x61}, {0xf9,0x7c}, {0xf9,0x7b}, {0xf9,0xb7}, {0xf9,0xb8}, {0x96,0xbb}, {0xf9,0xc5}, {0xc6,0x78}, {0xc6,0x7c}, {0x9f,0xf2}, - {0xf9,0xcf}, {0xc6,0x7d}, {0x8b,0xf5}, {0xb3,0xbf}, {0xc4,0xd0}, {0xf6,0xc9}, {0x9a,0xa9}, {0xc6,0x50}, {0xc6,0x51}, {0xb3,0xc0}, - {0xe0,0xee}, {0x9f,0x54}, {0xb9,0xa8}, {0xe8,0xf0}, {0x9f,0xe3}, {0x9e,0xed}, {0xec,0xb0}, {0xec,0xb1}, {0xec,0xaf}, {0xef,0xab}, - {0xef,0xaa}, {0xc2,0x47}, {0xf1,0xdf}, {0xef,0xac}, {0xf1,0xde}, {0x91,0xaa}, {0xf3,0xf3}, {0xc4,0x51}, {0xc4,0x53}, {0xf3,0xf2}, - {0x91,0xab}, {0xa0,0x70}, {0xc4,0x52}, {0x9f,0x6d}, {0xf5,0xb1}, {0xf5,0xb3}, {0xf5,0xb2}, {0xf6,0xca}, {0xc5,0x65}, {0x91,0xac}, - {0xc5,0xef}, {0xf8,0xe8}, {0xf9,0x63}, {0x91,0xad}, {0xf9,0xd2}, {0xb3,0xc1}, {0xa0,0xfd}, {0xe4,0xe5}, {0x9f,0xe2}, {0xbe,0xa2}, - {0x91,0xaf}, {0x9e,0x41}, {0x9a,0xaa}, {0xec,0xb3}, {0xec,0xb2}, {0x91,0xb0}, {0xef,0xad}, {0x9a,0xab}, {0xc4,0x54}, {0xc4,0xd1}, - {0xf7,0xc7}, {0xf9,0xcb}, {0xb3,0xc2}, {0xbb,0xf2}, {0x9a,0xac}, {0xbe,0xa3}, {0x9a,0x4a}, {0xf3,0xf4}, {0x91,0xb2}, {0xf8,0x74}, - {0xb6,0xc0}, {0x8b,0xf6}, {0x9a,0xad}, {0x89,0xb6}, {0xef,0xae}, {0xc6,0x64}, {0xb6,0xc1}, {0xbe,0xa4}, {0xc2,0x48}, {0xf8,0x75}, - {0xb6,0xc2}, {0xe8,0xf1}, {0xc0,0x72}, {0xec,0xb4}, {0xec,0xb5}, {0xc0,0x71}, {0xef,0xaf}, {0xc2,0x4c}, {0xc2,0x4a}, {0xc2,0x4b}, - {0xc2,0x49}, {0xf1,0xe0}, {0xc3,0x5c}, {0x9a,0xaf}, {0xf5,0xb5}, {0xf5,0xb4}, {0xf5,0xb7}, {0xf5,0xb6}, {0xc4,0xd2}, {0xf6,0xcb}, - {0xf6,0xcd}, {0xf6,0xcc}, {0xc5,0x66}, {0xf7,0xc8}, {0x9a,0xb0}, {0xf8,0x76}, {0xf8,0x77}, {0xc5,0xf0}, {0xf9,0x64}, {0xf9,0x7d}, - {0xc6,0x75}, {0x9a,0xb1}, {0xdc,0xb0}, {0xec,0xb6}, {0xef,0xb0}, {0xf3,0xf5}, {0xe0,0xef}, {0x9a,0xa1}, {0xef,0xb1}, {0xf1,0xe2}, - {0xf1,0xe1}, {0x91,0xb9}, {0xf8,0x78}, {0xc6,0x52}, {0x91,0xba}, {0xf9,0x65}, {0xf9,0x7e}, {0xb9,0xa9}, {0xe8,0xf2}, {0xe8,0xf3}, - {0xec,0xb7}, {0xb9,0xaa}, {0xc3,0x5d}, {0xf1,0xe3}, {0x91,0xbe}, {0xf6,0xcf}, {0xc5,0x67}, {0xf6,0xd0}, {0xf6,0xce}, {0xf8,0x79}, - {0xf8,0xe9}, {0xb9,0xab}, {0xef,0xb4}, {0xef,0xb3}, {0xef,0xb2}, {0xf1,0xe4}, {0xa0,0x41}, {0x8b,0xb7}, {0xf1,0xe8}, {0xf1,0xe7}, - {0xf1,0xe6}, {0xf1,0xe5}, {0xc3,0x5e}, {0xf3,0xf6}, {0xf5,0xb9}, {0xc4,0xd3}, {0xf5,0xb8}, {0xf6,0xd1}, {0xf7,0xcb}, {0xf7,0xca}, - {0xc5,0xc4}, {0xf7,0xc9}, {0xf8,0x7c}, {0xf8,0x7b}, {0xf8,0x7a}, {0x91,0xc0}, {0xbb,0xf3}, {0xec,0xb8}, {0xc2,0x4d}, {0xf3,0xf7}, - {0xf3,0xf8}, {0xf7,0xcc}, {0xf8,0x7d}, {0x9a,0xb3}, {0x91,0xc3}, {0xf8,0xea}, {0xf9,0x66}, {0xf9,0xb9}, {0xf9,0xd4}, {0xbb,0xf4}, - {0xc2,0x4e}, {0xf1,0xe9}, {0xf3,0xf9}, {0xf6,0xd2}, {0xf8,0x7e}, {0xa0,0xfc}, {0xbe,0xa6}, {0x9f,0xee}, {0xef,0xb5}, {0xf1,0xea}, - {0xf3,0xfa}, {0xf3,0xfb}, {0xf3,0xfc}, {0xf5,0xbe}, {0x9f,0x69}, {0xf5,0xba}, {0xc5,0x68}, {0xf5,0xbd}, {0xf5,0xbc}, {0xc4,0xd4}, - {0xf5,0xbb}, {0xc4,0xd6}, {0x91,0xc8}, {0xc4,0xd5}, {0xf6,0xd4}, {0xf6,0xd3}, {0xc5,0x69}, {0xc5,0x6a}, {0x91,0xc9}, {0xc5,0xc6}, - {0xf7,0xcd}, {0xc5,0xc5}, {0xf8,0xa3}, {0xf8,0xa4}, {0xf8,0xa2}, {0xf8,0xa1}, {0xc6,0x54}, {0xf8,0xeb}, {0xf8,0xec}, {0xf8,0xed}, - {0xc6,0x53}, {0xf9,0x67}, {0xf9,0x6a}, {0xf9,0x69}, {0xf9,0x68}, {0xf9,0xd3}, {0x8d,0xe6}, {0xc0,0x73}, {0x91,0xcb}, {0xc3,0x65}, - {0xf5,0xbf}, {0xf6,0xd5}, {0xc5,0xc7}, {0xf7,0xce}, {0xf9,0xd5}, {0x89,0xc8}, {0xc0,0x74}, {0x8d,0xaa}, {0xef,0xb6}, {0xf7,0xcf}, - {0xf9,0xa1}, {0x9f,0xdd}, {0xfa,0x40}, {0xfa,0x41}, {0xfa,0x42}, {0xfa,0x43}, {0xfa,0x44}, {0xfa,0x45}, {0xfa,0x46}, {0xfa,0x47}, - {0xfa,0x48}, {0xfa,0x49}, {0xfa,0x4a}, {0xfa,0x4b}, {0xfa,0x4c}, {0xfa,0x4d}, {0xfa,0x4e}, {0xfa,0x4f}, {0xfa,0x50}, {0xfa,0x51}, - {0xfa,0x52}, {0xfa,0x53}, {0xfa,0x54}, {0xfa,0x55}, {0xfa,0x56}, {0xfa,0x57}, {0xfa,0x58}, {0xfa,0x59}, {0xfa,0x5a}, {0xfa,0x5b}, - {0xfa,0x5c}, {0xfa,0x5d}, {0xfa,0x5e}, {0xad,0xc5}, {0xfa,0x60}, {0xfa,0x61}, {0xfa,0x62}, {0xfa,0x63}, {0xfa,0x64}, {0xfa,0x65}, - {0xb0,0xb0}, {0xfa,0x67}, {0xfa,0x68}, {0xfa,0x69}, {0xfa,0x6a}, {0xfa,0x6b}, {0xfa,0x6c}, {0xfa,0x6d}, {0xfa,0x6e}, {0xfa,0x6f}, - {0xfa,0x70}, {0xfa,0x71}, {0xfa,0x72}, {0xfa,0x73}, {0xfa,0x74}, {0xfa,0x75}, {0xfa,0x76}, {0xfa,0x77}, {0xfa,0x78}, {0xfa,0x79}, - {0xfa,0x7a}, {0xfa,0x7b}, {0xfa,0x7c}, {0xfa,0x7d}, {0xfa,0x7e}, {0xfa,0xa1}, {0xfa,0xa2}, {0xfa,0xa3}, {0xfa,0xa4}, {0xfa,0xa5}, - {0xfa,0xa6}, {0xfa,0xa7}, {0xfa,0xa8}, {0xfa,0xa9}, {0xfa,0xaa}, {0xfa,0xab}, {0xfa,0xac}, {0xfa,0xad}, {0xfa,0xae}, {0xfa,0xaf}, - {0xfa,0xb0}, {0xfa,0xb1}, {0xfa,0xb2}, {0xfa,0xb3}, {0xfa,0xb4}, {0xfa,0xb5}, {0xfa,0xb6}, {0xfa,0xb7}, {0xfa,0xb8}, {0xfa,0xb9}, - {0xfa,0xba}, {0xfa,0xbb}, {0xfa,0xbc}, {0xa5,0x5d}, {0xfa,0xbe}, {0xfa,0xbf}, {0xfa,0xc0}, {0xfa,0xc1}, {0xfa,0xc2}, {0xfa,0xc3}, - {0xfa,0xc4}, {0xa2,0xcd}, {0xfa,0xc6}, {0xfa,0xc7}, {0xfa,0xc8}, {0xfa,0xc9}, {0xfa,0xca}, {0xfa,0xcb}, {0xfa,0xcc}, {0xfa,0xcd}, - {0xfa,0xce}, {0xfa,0xcf}, {0xfa,0xd0}, {0xfa,0xd1}, {0xfa,0xd2}, {0xfa,0xd3}, {0xfa,0xd4}, {0xad,0xeb}, {0xfa,0xd6}, {0xfa,0xd7}, - {0xfa,0xd8}, {0xfa,0xd9}, {0xfa,0xda}, {0xfa,0xdb}, {0xfa,0xdc}, {0xfa,0xdd}, {0xfa,0xde}, {0xfa,0xdf}, {0xfa,0xe0}, {0xfa,0xe1}, - {0xfa,0xe2}, {0xfa,0xe3}, {0xfa,0xe4}, {0xfa,0xe5}, {0xfa,0xe6}, {0xfa,0xe7}, {0xfa,0xe8}, {0xfa,0xe9}, {0xfa,0xea}, {0xfa,0xeb}, - {0xfa,0xec}, {0xfa,0xed}, {0xfa,0xee}, {0xfa,0xef}, {0xfa,0xf0}, {0xfa,0xf1}, {0xfa,0xf2}, {0xfa,0xf3}, {0xfa,0xf4}, {0xfa,0xf5}, - {0xfa,0xf6}, {0xfa,0xf7}, {0xfa,0xf8}, {0xfa,0xf9}, {0xfa,0xfa}, {0xfa,0xfb}, {0xfa,0xfc}, {0xfa,0xfd}, {0xfa,0xfe}, {0xfb,0x40}, - {0xfb,0x41}, {0xfb,0x42}, {0xfb,0x43}, {0xfb,0x44}, {0xfb,0x45}, {0xfb,0x46}, {0xfb,0x47}, {0x9d,0xef}, {0xfb,0x49}, {0xfb,0x4a}, - {0xfb,0x4b}, {0xfb,0x4c}, {0xfb,0x4d}, {0xfb,0x4e}, {0xfb,0x4f}, {0xfb,0x50}, {0xfb,0x51}, {0xfb,0x52}, {0xfb,0x53}, {0xfb,0x54}, - {0xfb,0x55}, {0xfb,0x56}, {0xfb,0x57}, {0xfb,0x58}, {0xfb,0x59}, {0xfb,0x5a}, {0xfb,0x5b}, {0xfb,0x5c}, {0xfb,0x5d}, {0xfb,0x5e}, - {0xfb,0x5f}, {0xfb,0x60}, {0xfb,0x61}, {0xfb,0x62}, {0xfb,0x63}, {0xfb,0x64}, {0xfb,0x65}, {0xfb,0x66}, {0xfb,0x67}, {0xfb,0x68}, - {0xfb,0x69}, {0xfb,0x6a}, {0xfb,0x6b}, {0xfb,0x6c}, {0xfb,0x6d}, {0xfb,0x6e}, {0xfb,0x6f}, {0xfb,0x70}, {0xfb,0x71}, {0xfb,0x72}, - {0xfb,0x73}, {0xfb,0x74}, {0xfb,0x75}, {0xfb,0x76}, {0xfb,0x77}, {0xfb,0x78}, {0xfb,0x79}, {0xfb,0x7a}, {0xfb,0x7b}, {0xfb,0x7c}, - {0xfb,0x7d}, {0xfb,0x7e}, {0xfb,0xa1}, {0xfb,0xa2}, {0xfb,0xa3}, {0xfb,0xa4}, {0xfb,0xa5}, {0xfb,0xa6}, {0xfb,0xa7}, {0xfb,0xa8}, - {0xfb,0xa9}, {0xfb,0xaa}, {0xfb,0xab}, {0xfb,0xac}, {0xfb,0xad}, {0xfb,0xae}, {0xfb,0xaf}, {0xfb,0xb0}, {0xfb,0xb1}, {0xfb,0xb2}, - {0xfb,0xb3}, {0xfb,0xb4}, {0xfb,0xb5}, {0xfb,0xb6}, {0xfb,0xb7}, {0xb4,0x40}, {0xfb,0xb9}, {0xfb,0xba}, {0xfb,0xbb}, {0xfb,0xbc}, - {0xfb,0xbd}, {0xfb,0xbe}, {0xfb,0xbf}, {0xfb,0xc0}, {0xfb,0xc1}, {0xfb,0xc2}, {0xfb,0xc3}, {0xfb,0xc4}, {0xfb,0xc5}, {0xfb,0xc6}, - {0xfb,0xc7}, {0xfb,0xc8}, {0xfb,0xc9}, {0xfb,0xca}, {0xfb,0xcb}, {0xfb,0xcc}, {0xfb,0xcd}, {0xfb,0xce}, {0xfb,0xcf}, {0xfb,0xd0}, - {0xfb,0xd1}, {0xfb,0xd2}, {0xfb,0xd3}, {0xfb,0xd4}, {0xfb,0xd5}, {0xfb,0xd6}, {0xfb,0xd7}, {0xfb,0xd8}, {0xfb,0xd9}, {0xfb,0xda}, - {0xfb,0xdb}, {0xfb,0xdc}, {0xfb,0xdd}, {0xfb,0xde}, {0xfb,0xdf}, {0xfb,0xe0}, {0xfb,0xe1}, {0xfb,0xe2}, {0xfb,0xe3}, {0xfb,0xe4}, - {0xfb,0xe5}, {0xfb,0xe6}, {0xfb,0xe7}, {0xfb,0xe8}, {0xfb,0xe9}, {0xfb,0xea}, {0xfb,0xeb}, {0xfb,0xec}, {0xfb,0xed}, {0xfb,0xee}, - {0xfb,0xef}, {0xfb,0xf0}, {0xfb,0xf1}, {0xfb,0xf2}, {0xc9,0xdb}, {0xfb,0xf4}, {0xfb,0xf5}, {0xfb,0xf6}, {0xfb,0xf7}, {0xfb,0xf8}, - {0x9d,0xfb}, {0xfb,0xfa}, {0xfb,0xfb}, {0xfb,0xfc}, {0xfb,0xfd}, {0xfb,0xfe}, {0xfc,0x40}, {0xfc,0x41}, {0xfc,0x42}, {0xfc,0x43}, - {0xfc,0x44}, {0xfc,0x45}, {0xfc,0x46}, {0xfc,0x47}, {0xfc,0x48}, {0xfc,0x49}, {0xfc,0x4a}, {0xfc,0x4b}, {0xfc,0x4c}, {0xfc,0x4d}, - {0xfc,0x4e}, {0xd8,0xf4}, {0xfc,0x50}, {0xfc,0x51}, {0xfc,0x52}, {0xfc,0x53}, {0xfc,0x54}, {0xfc,0x55}, {0xfc,0x56}, {0xfc,0x57}, - {0xfc,0x58}, {0xfc,0x59}, {0xfc,0x5a}, {0xfc,0x5b}, {0xfc,0x5c}, {0xfc,0x5d}, {0xfc,0x5e}, {0xfc,0x5f}, {0xfc,0x60}, {0xfc,0x61}, - {0xfc,0x62}, {0xfc,0x63}, {0xfc,0x64}, {0xfc,0x65}, {0xfc,0x66}, {0xfc,0x67}, {0xfc,0x68}, {0xfc,0x69}, {0xfc,0x6a}, {0xfc,0x6b}, - {0xa0,0xdc}, {0xfc,0x6d}, {0xfc,0x6e}, {0xfc,0x6f}, {0xfc,0x70}, {0xfc,0x71}, {0xfc,0x72}, {0xfc,0x73}, {0xfc,0x74}, {0xfc,0x75}, - {0xfc,0x76}, {0xfc,0x77}, {0xfc,0x78}, {0xfc,0x79}, {0xfc,0x7a}, {0xfc,0x7b}, {0xfc,0x7c}, {0xfc,0x7d}, {0xfc,0x7e}, {0xfc,0xa1}, - {0xfc,0xa2}, {0xfc,0xa3}, {0xfc,0xa4}, {0xfc,0xa5}, {0xfc,0xa6}, {0xfc,0xa7}, {0xfc,0xa8}, {0xfc,0xa9}, {0xfc,0xaa}, {0xfc,0xab}, - {0xfc,0xac}, {0xfc,0xad}, {0xfc,0xae}, {0xfc,0xaf}, {0xfc,0xb0}, {0xfc,0xb1}, {0xfc,0xb2}, {0xfc,0xb3}, {0xfc,0xb4}, {0xfc,0xb5}, - {0xfc,0xb6}, {0xfc,0xb7}, {0xfc,0xb8}, {0xbc,0xb5}, {0xfc,0xba}, {0xfc,0xbb}, {0xfc,0xbc}, {0xfc,0xbd}, {0xfc,0xbe}, {0xfc,0xbf}, - {0xfc,0xc0}, {0xfc,0xc1}, {0xfc,0xc2}, {0xfc,0xc3}, {0xfc,0xc4}, {0xfc,0xc5}, {0xfc,0xc6}, {0xfc,0xc7}, {0xfc,0xc8}, {0xfc,0xc9}, - {0xfc,0xca}, {0xfc,0xcb}, {0xfc,0xcc}, {0xfc,0xcd}, {0xfc,0xce}, {0xfc,0xcf}, {0xfc,0xd0}, {0xfc,0xd1}, {0xfc,0xd2}, {0xfc,0xd3}, - {0xfc,0xd4}, {0xfc,0xd5}, {0xfc,0xd6}, {0xfc,0xd7}, {0xfc,0xd8}, {0xfc,0xd9}, {0xfc,0xda}, {0xfc,0xdb}, {0xfc,0xdc}, {0xfc,0xdd}, - {0xfc,0xde}, {0xfc,0xdf}, {0xfc,0xe0}, {0xfc,0xe1}, {0xb4,0xb8}, {0xfc,0xe3}, {0xfc,0xe4}, {0xfc,0xe5}, {0xfc,0xe6}, {0xfc,0xe7}, - {0xfc,0xe8}, {0xfc,0xe9}, {0xfc,0xea}, {0xfc,0xeb}, {0xfc,0xec}, {0xfc,0xed}, {0xfc,0xee}, {0xfc,0xef}, {0xfc,0xf0}, {0xa7,0xfb}, - {0xfc,0xf2}, {0xfc,0xf3}, {0xfc,0xf4}, {0xfc,0xf5}, {0xfc,0xf6}, {0xfc,0xf7}, {0xfc,0xf8}, {0xfc,0xf9}, {0xfc,0xfa}, {0xfc,0xfb}, - {0xfc,0xfc}, {0xfc,0xfd}, {0xfc,0xfe}, {0xfd,0x40}, {0xfd,0x41}, {0xfd,0x42}, {0xfd,0x43}, {0xfd,0x44}, {0xfd,0x45}, {0xfd,0x46}, - {0xfd,0x47}, {0xfd,0x48}, {0xfd,0x49}, {0xfd,0x4a}, {0xfd,0x4b}, {0xfd,0x4c}, {0xfd,0x4d}, {0xfd,0x4e}, {0xfd,0x4f}, {0xfd,0x50}, - {0xfd,0x51}, {0xfd,0x52}, {0xfd,0x53}, {0xfd,0x54}, {0xfd,0x55}, {0xfd,0x56}, {0xfd,0x57}, {0xfd,0x58}, {0xfd,0x59}, {0xfd,0x5a}, - {0xfd,0x5b}, {0xfd,0x5c}, {0xfd,0x5d}, {0xfd,0x5e}, {0xfd,0x5f}, {0xfd,0x60}, {0xfd,0x61}, {0xfd,0x62}, {0xfd,0x63}, {0xfd,0x64}, - {0xfd,0x65}, {0xfd,0x66}, {0xfd,0x67}, {0xfd,0x68}, {0xfd,0x69}, {0xfd,0x6a}, {0xfd,0x6b}, {0xfd,0x6c}, {0xfd,0x6d}, {0xfd,0x6e}, - {0xfd,0x6f}, {0xfd,0x70}, {0xfd,0x71}, {0xfd,0x72}, {0xfd,0x73}, {0xfd,0x74}, {0xfd,0x75}, {0xfd,0x76}, {0xfd,0x77}, {0xfd,0x78}, - {0xfd,0x79}, {0xfd,0x7a}, {0xfd,0x7b}, {0xfd,0x7c}, {0xfd,0x7d}, {0xfd,0x7e}, {0xfd,0xa1}, {0xfd,0xa2}, {0xfd,0xa3}, {0xfd,0xa4}, - {0xfd,0xa5}, {0xfd,0xa6}, {0xfd,0xa7}, {0xfd,0xa8}, {0xfd,0xa9}, {0xfd,0xaa}, {0xfd,0xab}, {0xfd,0xac}, {0xfd,0xad}, {0xfd,0xae}, - {0xfd,0xaf}, {0xfd,0xb0}, {0xfd,0xb1}, {0xfd,0xb2}, {0xfd,0xb3}, {0xfd,0xb4}, {0xfd,0xb5}, {0xfd,0xb6}, {0xcb,0x58}, {0xb4,0xfc}, - {0xfd,0xb9}, {0xfd,0xba}, {0xb4,0xe4}, {0xfd,0xbc}, {0xfd,0xbd}, {0xfd,0xbe}, {0xfd,0xbf}, {0xfd,0xc0}, {0xfd,0xc1}, {0xfd,0xc2}, - {0xfd,0xc3}, {0xfd,0xc4}, {0xfd,0xc5}, {0xfd,0xc6}, {0xfd,0xc7}, {0xfd,0xc8}, {0xfd,0xc9}, {0xfd,0xca}, {0xfd,0xcb}, {0xfd,0xcc}, - {0xfd,0xcd}, {0xfd,0xce}, {0xfd,0xcf}, {0xfd,0xd0}, {0xfd,0xd1}, {0xfd,0xd2}, {0xfd,0xd3}, {0xfd,0xd4}, {0xfd,0xd5}, {0xfd,0xd6}, - {0xfd,0xd7}, {0xfd,0xd8}, {0xfd,0xd9}, {0xfd,0xda}, {0xfd,0xdb}, {0xfd,0xdc}, {0xfd,0xdd}, {0xfd,0xde}, {0xfd,0xdf}, {0xfd,0xe0}, - {0xfd,0xe1}, {0xfd,0xe2}, {0xfd,0xe3}, {0xfd,0xe4}, {0xfd,0xe5}, {0xfd,0xe6}, {0xfd,0xe7}, {0xfd,0xe8}, {0xfd,0xe9}, {0xfd,0xea}, - {0xfd,0xeb}, {0xfd,0xec}, {0xfd,0xed}, {0xfd,0xee}, {0xfd,0xef}, {0xfd,0xf0}, {0xb5,0x4e}, {0xfd,0xf2}, {0xfd,0xf3}, {0xfd,0xf4}, - {0xfd,0xf5}, {0xfd,0xf6}, {0xfd,0xf7}, {0xfd,0xf8}, {0xfd,0xf9}, {0xfd,0xfa}, {0xfd,0xfb}, {0xfd,0xfc}, {0xfd,0xfd}, {0xfd,0xfe}, - {0xfe,0x40}, {0xfe,0x41}, {0xfe,0x42}, {0xfe,0x43}, {0xfe,0x44}, {0xfe,0x45}, {0xfe,0x46}, {0xfe,0x47}, {0xfe,0x48}, {0xfe,0x49}, - {0xfe,0x4a}, {0xfe,0x4b}, {0xfe,0x4c}, {0xfe,0x4d}, {0xfe,0x4e}, {0xfe,0x4f}, {0xfe,0x50}, {0xfe,0x51}, {0x99,0x75}, {0xfe,0x53}, - {0xfe,0x54}, {0xfe,0x55}, {0xfe,0x56}, {0xfe,0x57}, {0xfe,0x58}, {0xfe,0x59}, {0xfe,0x5a}, {0xfe,0x5b}, {0xfe,0x5c}, {0xfe,0x5d}, - {0xfe,0x5e}, {0xfe,0x5f}, {0xfe,0x60}, {0xfe,0x61}, {0xfe,0x62}, {0xfe,0x63}, {0xfe,0x64}, {0xfe,0x65}, {0xfe,0x66}, {0xfe,0x67}, - {0xfe,0x68}, {0xfe,0x69}, {0xfe,0x6a}, {0xfe,0x6b}, {0xfe,0x6c}, {0xfe,0x6d}, {0xfe,0x6e}, {0xb7,0xec}, {0xfe,0x70}, {0xfe,0x71}, - {0xfe,0x72}, {0xfe,0x73}, {0xfe,0x74}, {0xfe,0x75}, {0xfe,0x76}, {0xfe,0x77}, {0xfe,0x78}, {0xfe,0x79}, {0xfe,0x7a}, {0xfe,0x7b}, - {0xfe,0x7c}, {0xfe,0x7d}, {0xfe,0x7e}, {0xfe,0xa1}, {0xfe,0xa2}, {0xfe,0xa3}, {0xfe,0xa4}, {0xfe,0xa5}, {0xfe,0xa6}, {0xfe,0xa7}, - {0xfe,0xa8}, {0xfe,0xa9}, {0xa2,0x60}, {0xfe,0xab}, {0xfe,0xac}, {0xfe,0xad}, {0xfe,0xae}, {0xfe,0xaf}, {0xfe,0xb0}, {0xfe,0xb1}, - {0xfe,0xb2}, {0xfe,0xb3}, {0xfe,0xb4}, {0xfe,0xb5}, {0xfe,0xb6}, {0xfe,0xb7}, {0xfe,0xb8}, {0xfe,0xb9}, {0xfe,0xba}, {0xfe,0xbb}, - {0xfe,0xbc}, {0xfe,0xbd}, {0xfe,0xbe}, {0xfe,0xbf}, {0xfe,0xc0}, {0xfe,0xc1}, {0xfe,0xc2}, {0xfe,0xc3}, {0xfe,0xc4}, {0xfe,0xc5}, - {0xfe,0xc6}, {0xfe,0xc7}, {0xfe,0xc8}, {0xfe,0xc9}, {0xfe,0xca}, {0xfe,0xcb}, {0xfe,0xcc}, {0xfe,0xcd}, {0xfe,0xce}, {0xfe,0xcf}, - {0xfe,0xd0}, {0xfe,0xd1}, {0xfe,0xd2}, {0xfe,0xd3}, {0xfe,0xd4}, {0xfe,0xd5}, {0xfe,0xd6}, {0xfe,0xd7}, {0xfe,0xd8}, {0xfe,0xd9}, - {0xfe,0xda}, {0xfe,0xdb}, {0xfe,0xdc}, {0xcf,0xf1}, {0xfe,0xde}, {0xfe,0xdf}, {0xfe,0xe0}, {0xfe,0xe1}, {0xfe,0xe2}, {0xfe,0xe3}, - {0xfe,0xe4}, {0xfe,0xe5}, {0xfe,0xe6}, {0xfe,0xe7}, {0xfe,0xe8}, {0xfe,0xe9}, {0xfe,0xea}, {0xfe,0xeb}, {0xfe,0xec}, {0xfe,0xed}, - {0xfe,0xee}, {0xfe,0xef}, {0xfe,0xf0}, {0xfe,0xf1}, {0xfe,0xf2}, {0xfe,0xf3}, {0xfe,0xf4}, {0xfe,0xf5}, {0xfe,0xf6}, {0xfe,0xf7}, - {0xfe,0xf8}, {0xfe,0xf9}, {0xfe,0xfa}, {0xfe,0xfb}, {0xfe,0xfc}, {0xfe,0xfd}, {0xfe,0xfe}, {0x8e,0x40}, {0x8e,0x41}, {0x8e,0x42}, - {0x8e,0x43}, {0x8e,0x44}, {0x8e,0x45}, {0x8e,0x46}, {0x8e,0x47}, {0x8e,0x48}, {0x8e,0x49}, {0x8e,0x4a}, {0x8e,0x4b}, {0x8e,0x4c}, - {0x8e,0x4d}, {0x8e,0x4e}, {0x8e,0x4f}, {0x8e,0x50}, {0x8e,0x51}, {0x8e,0x52}, {0x8e,0x53}, {0x8e,0x54}, {0x8e,0x55}, {0x8e,0x56}, - {0x8e,0x57}, {0x8e,0x58}, {0x8e,0x59}, {0x8e,0x5a}, {0x8e,0x5b}, {0x8e,0x5c}, {0x8e,0x5d}, {0x8e,0x5e}, {0x8e,0x5f}, {0x8e,0x60}, - {0x8e,0x61}, {0x8e,0x62}, {0x8e,0x63}, {0x8e,0x64}, {0x8e,0x65}, {0x8e,0x66}, {0x8e,0x67}, {0x8e,0x68}, {0xba,0xe6}, {0x8e,0x6a}, - {0x8e,0x6b}, {0x8e,0x6c}, {0x8e,0x6d}, {0x8e,0x6e}, {0xed,0xca}, {0x8e,0x70}, {0x8e,0x71}, {0x8e,0x72}, {0x8e,0x73}, {0x8e,0x74}, - {0x8e,0x75}, {0x8e,0x76}, {0x8e,0x77}, {0x8e,0x78}, {0x8e,0x79}, {0x8e,0x7a}, {0x8e,0x7b}, {0x8e,0x7c}, {0x8e,0x7d}, {0xa2,0x61}, - {0x8e,0xa1}, {0x8e,0xa2}, {0x8e,0xa3}, {0x8e,0xa4}, {0x8e,0xa5}, {0x8e,0xa6}, {0x8e,0xa7}, {0x8e,0xa8}, {0x8e,0xa9}, {0x8e,0xaa}, - {0xba,0xfc}, {0x8e,0xac}, {0x8e,0xad}, {0x8e,0xae}, {0x8e,0xaf}, {0x8e,0xb0}, {0x8e,0xb1}, {0x8e,0xb2}, {0x8e,0xb3}, {0xbf,0xa6}, - {0x8e,0xb5}, {0x8e,0xb6}, {0x8e,0xb7}, {0x8e,0xb8}, {0x8e,0xb9}, {0x8e,0xba}, {0x8e,0xbb}, {0x8e,0xbc}, {0x8e,0xbd}, {0x8e,0xbe}, - {0x8e,0xbf}, {0x8e,0xc0}, {0x8e,0xc1}, {0x8e,0xc2}, {0x8e,0xc3}, {0x8e,0xc4}, {0x8e,0xc5}, {0x8e,0xc6}, {0x8e,0xc7}, {0x8e,0xc8}, - {0x8e,0xc9}, {0x8e,0xca}, {0x8e,0xcb}, {0x8e,0xcc}, {0xaa,0xcc}, {0x8e,0xce}, {0x8e,0xcf}, {0xbf,0xae}, {0x8e,0xd1}, {0x8e,0xd2}, - {0x8e,0xd3}, {0x8e,0xd4}, {0x8e,0xd5}, {0x8e,0xd6}, {0x8e,0xd7}, {0x8e,0xd8}, {0x8e,0xd9}, {0x8e,0xda}, {0x8e,0xdb}, {0x8e,0xdc}, - {0x8e,0xdd}, {0x8e,0xde}, {0x8e,0xdf}, {0x8e,0xe0}, {0x8e,0xe1}, {0x8e,0xe2}, {0x8e,0xe3}, {0x8e,0xe4}, {0x8e,0xe5}, {0x8e,0xe6}, - {0x8e,0xe7}, {0x8e,0xe8}, {0x8e,0xe9}, {0x8e,0xea}, {0x8e,0xeb}, {0x8e,0xec}, {0x8e,0xed}, {0x8e,0xee}, {0x8e,0xef}, {0x8e,0xf0}, - {0x8e,0xf1}, {0x8e,0xf2}, {0x8e,0xf3}, {0x8e,0xf4}, {0x8e,0xf5}, {0x8e,0xf6}, {0x8e,0xf7}, {0x8e,0xf8}, {0x8e,0xf9}, {0x8e,0xfa}, - {0x8e,0xfb}, {0x8e,0xfc}, {0x8e,0xfd}, {0x8e,0xfe}, {0x8f,0x40}, {0x8f,0x41}, {0x8f,0x42}, {0x8f,0x43}, {0x8f,0x44}, {0x8f,0x45}, - {0x8f,0x46}, {0x8f,0x47}, {0x8f,0x48}, {0x8f,0x49}, {0x8f,0x4a}, {0x8f,0x4b}, {0x8f,0x4c}, {0x8f,0x4d}, {0x8f,0x4e}, {0x8f,0x4f}, - {0x8f,0x50}, {0x8f,0x51}, {0x8f,0x52}, {0x8f,0x53}, {0x8f,0x54}, {0x8f,0x55}, {0x8f,0x56}, {0xb5,0xd7}, {0x8f,0x58}, {0x8f,0x59}, - {0x8f,0x5a}, {0x8f,0x5b}, {0x8f,0x5c}, {0x8f,0x5d}, {0x8f,0x5e}, {0x8f,0x5f}, {0x8f,0x60}, {0x8f,0x61}, {0x8f,0x62}, {0x8f,0x63}, - {0x8f,0x64}, {0x8f,0x65}, {0x8f,0x66}, {0x8f,0x67}, {0x8f,0x68}, {0xe3,0xc8}, {0x8f,0x6a}, {0x8f,0x6b}, {0x8f,0x6c}, {0x8f,0x6d}, - {0xdb,0x79}, {0x8f,0x6f}, {0x8f,0x70}, {0x8f,0x71}, {0x8f,0x72}, {0x8f,0x73}, {0x8f,0x74}, {0x8f,0x75}, {0x8f,0x76}, {0x8f,0x77}, - {0x8f,0x78}, {0x8f,0x79}, {0x8f,0x7a}, {0x8f,0x7b}, {0x8f,0x7c}, {0x8f,0x7d}, {0x8f,0x7e}, {0x8f,0xa1}, {0x8f,0xa2}, {0x8f,0xa3}, - {0x8f,0xa4}, {0x8f,0xa5}, {0x8f,0xa6}, {0x8f,0xa7}, {0x8f,0xa8}, {0x8f,0xa9}, {0x8f,0xaa}, {0x8f,0xab}, {0x8f,0xac}, {0x8f,0xad}, - {0x8f,0xae}, {0x8f,0xaf}, {0x8f,0xb0}, {0x8f,0xb1}, {0x8f,0xb2}, {0x8f,0xb3}, {0x8f,0xb4}, {0x8f,0xb5}, {0x8f,0xb6}, {0x8f,0xb7}, - {0x8f,0xb8}, {0x8f,0xb9}, {0x8f,0xba}, {0x8f,0xbb}, {0x8f,0xbc}, {0x8f,0xbd}, {0x8f,0xbe}, {0x8f,0xbf}, {0x8f,0xc0}, {0x8f,0xc1}, - {0x8f,0xc2}, {0x8f,0xc3}, {0x8f,0xc4}, {0x8f,0xc5}, {0x8f,0xc6}, {0x8f,0xc7}, {0x8f,0xc8}, {0x8f,0xc9}, {0x8f,0xca}, {0xbf,0xcc}, - {0xa0,0xd4}, {0x8f,0xcd}, {0x8f,0xce}, {0x8f,0xcf}, {0x8f,0xd0}, {0x8f,0xd1}, {0x8f,0xd2}, {0x8f,0xd3}, {0x8f,0xd4}, {0x8f,0xd5}, - {0x8f,0xd6}, {0x8f,0xd7}, {0x8f,0xd8}, {0x8f,0xd9}, {0x8f,0xda}, {0x8f,0xdb}, {0x8f,0xdc}, {0x8f,0xdd}, {0x8f,0xde}, {0x8f,0xdf}, - {0x8f,0xe0}, {0x8f,0xe1}, {0x8f,0xe2}, {0x8f,0xe3}, {0x8f,0xe4}, {0x8f,0xe5}, {0x8f,0xe6}, {0x8f,0xe7}, {0x8f,0xe8}, {0x8f,0xe9}, - {0x8f,0xea}, {0x8f,0xeb}, {0x8f,0xec}, {0x8f,0xed}, {0x8f,0xee}, {0x8f,0xef}, {0x8f,0xf0}, {0x8f,0xf1}, {0x8f,0xf2}, {0x8f,0xf3}, - {0x8f,0xf4}, {0x8f,0xf5}, {0x8f,0xf6}, {0x8f,0xf7}, {0x8f,0xf8}, {0x8f,0xf9}, {0x8f,0xfa}, {0x8f,0xfb}, {0x8f,0xfc}, {0x8f,0xfd}, - {0xb0,0x5f}, {0x90,0x40}, {0x90,0x41}, {0x90,0x42}, {0x90,0x43}, {0x90,0x44}, {0x90,0x45}, {0x90,0x46}, {0x90,0x47}, {0x90,0x48}, - {0x90,0x49}, {0x90,0x4a}, {0x90,0x4b}, {0x90,0x4c}, {0x90,0x4d}, {0x90,0x4e}, {0x90,0x4f}, {0x90,0x50}, {0x90,0x51}, {0x90,0x52}, - {0x90,0x53}, {0x90,0x54}, {0x90,0x55}, {0x90,0x56}, {0x90,0x57}, {0x90,0x58}, {0x90,0x59}, {0x90,0x5a}, {0x90,0x5b}, {0x90,0x5c}, - {0x90,0x5d}, {0x90,0x5e}, {0x90,0x5f}, {0x90,0x60}, {0x90,0x61}, {0x90,0x62}, {0x90,0x63}, {0x90,0x64}, {0x90,0x65}, {0x90,0x66}, - {0x90,0x67}, {0x90,0x68}, {0x90,0x69}, {0x90,0x6a}, {0x90,0x6b}, {0x90,0x6c}, {0xb3,0xa3}, {0x90,0x6e}, {0x90,0x6f}, {0x90,0x70}, - {0x90,0x71}, {0x90,0x72}, {0x90,0x73}, {0x90,0x74}, {0x90,0x75}, {0x90,0x76}, {0x90,0x77}, {0x90,0x78}, {0x90,0x79}, {0xf9,0xd7}, - {0x90,0x7b}, {0x90,0x7c}, {0x90,0x7d}, {0x90,0x7e}, {0x90,0xa1}, {0x90,0xa2}, {0x90,0xa3}, {0x90,0xa4}, {0x90,0xa5}, {0x90,0xa6}, - {0x90,0xa7}, {0x90,0xa8}, {0x90,0xa9}, {0x90,0xaa}, {0x90,0xab}, {0x90,0xac}, {0x90,0xad}, {0x90,0xae}, {0x90,0xaf}, {0x90,0xb0}, - {0x90,0xb1}, {0x90,0xb2}, {0x90,0xb3}, {0x90,0xb4}, {0x90,0xb5}, {0x90,0xb6}, {0x90,0xb7}, {0x90,0xb8}, {0x90,0xb9}, {0x90,0xba}, - {0x90,0xbb}, {0x90,0xbc}, {0x90,0xbd}, {0x90,0xbe}, {0x90,0xbf}, {0x90,0xc0}, {0x90,0xc1}, {0x90,0xc2}, {0x90,0xc3}, {0x90,0xc4}, - {0x90,0xc5}, {0x90,0xc6}, {0x90,0xc7}, {0x90,0xc8}, {0x90,0xc9}, {0x90,0xca}, {0x90,0xcb}, {0x90,0xcc}, {0x90,0xcd}, {0x90,0xce}, - {0x90,0xcf}, {0x90,0xd0}, {0x90,0xd1}, {0x90,0xd2}, {0x90,0xd3}, {0x90,0xd4}, {0x90,0xd5}, {0x90,0xd6}, {0x90,0xd7}, {0x90,0xd8}, - {0x90,0xd9}, {0x90,0xda}, {0x90,0xdb}, {0xc0,0x52}, {0x90,0xdd}, {0x90,0xde}, {0x90,0xdf}, {0x90,0xe0}, {0x90,0xe1}, {0x90,0xe2}, - {0x90,0xe3}, {0x90,0xe4}, {0x90,0xe5}, {0x90,0xe6}, {0x90,0xe7}, {0x90,0xe8}, {0x90,0xe9}, {0x90,0xea}, {0x90,0xeb}, {0x90,0xec}, - {0x90,0xed}, {0x90,0xee}, {0x90,0xef}, {0x90,0xf0}, {0xc5,0x54}, {0x90,0xf2}, {0x90,0xf3}, {0x90,0xf4}, {0x90,0xf5}, {0x90,0xf6}, - {0x90,0xf7}, {0x90,0xf8}, {0x90,0xf9}, {0x90,0xfa}, {0x90,0xfb}, {0x90,0xfc}, {0x90,0xfd}, {0x90,0xfe}, {0x91,0x40}, {0x91,0x41}, - {0x91,0x42}, {0x91,0x43}, {0x91,0x44}, {0x91,0x45}, {0x91,0x46}, {0x91,0x47}, {0x91,0x48}, {0x91,0x49}, {0x91,0x4a}, {0x91,0x4b}, - {0x91,0x4c}, {0x91,0x4d}, {0x91,0x4e}, {0x91,0x4f}, {0x91,0x50}, {0x91,0x51}, {0x91,0x52}, {0x91,0x53}, {0x91,0x54}, {0x91,0x55}, - {0x91,0x56}, {0x91,0x57}, {0x91,0x58}, {0x91,0x59}, {0x91,0x5a}, {0x91,0x5b}, {0x91,0x5c}, {0x91,0x5d}, {0x91,0x5e}, {0x91,0x5f}, - {0x91,0x60}, {0x91,0x61}, {0x91,0x62}, {0x91,0x63}, {0x91,0x64}, {0x91,0x65}, {0x91,0x66}, {0x91,0x67}, {0x91,0x68}, {0x91,0x69}, - {0x91,0x6a}, {0x91,0x6b}, {0x91,0x6c}, {0x91,0x6d}, {0x91,0x6e}, {0x91,0x6f}, {0x91,0x70}, {0x91,0x71}, {0x91,0x72}, {0x91,0x73}, - {0x91,0x74}, {0x91,0x75}, {0x91,0x76}, {0x91,0x77}, {0x91,0x78}, {0x91,0x79}, {0x91,0x7a}, {0x91,0x7b}, {0x91,0x7c}, {0x91,0x7d}, - {0x91,0x7e}, {0x91,0xa1}, {0x91,0xa2}, {0x91,0xa3}, {0x91,0xa4}, {0x91,0xa5}, {0x91,0xa6}, {0x91,0xa7}, {0x91,0xa8}, {0x91,0xa9}, - {0x91,0xaa}, {0x91,0xab}, {0x91,0xac}, {0x91,0xad}, {0x91,0xae}, {0x91,0xaf}, {0x91,0xb0}, {0x91,0xb1}, {0x91,0xb2}, {0x91,0xb3}, - {0x91,0xb4}, {0x91,0xb5}, {0x91,0xb6}, {0x91,0xb7}, {0x91,0xb8}, {0x91,0xb9}, {0x91,0xba}, {0x91,0xbb}, {0x91,0xbc}, {0x91,0xbd}, - {0x91,0xbe}, {0xf1,0xe3}, {0x91,0xc0}, {0x91,0xc1}, {0x91,0xc2}, {0x91,0xc3}, {0x91,0xc4}, {0x91,0xc5}, {0x91,0xc6}, {0x91,0xc7}, - {0x91,0xc8}, {0x91,0xc9}, {0x91,0xca}, {0x91,0xcb}, {0x91,0xcc}, {0x91,0xcd}, {0x91,0xce}, {0x91,0xcf}, {0x91,0xd0}, {0x91,0xd1}, - {0x91,0xd2}, {0x91,0xd3}, {0x91,0xd4}, {0x91,0xd5}, {0x91,0xd6}, {0x91,0xd7}, {0x91,0xd8}, {0x91,0xd9}, {0x91,0xda}, {0x91,0xdb}, - {0x91,0xdc}, {0x91,0xdd}, {0x91,0xde}, {0x91,0xdf}, {0x91,0xe0}, {0x91,0xe1}, {0x91,0xe2}, {0x91,0xe3}, {0x91,0xe4}, {0x91,0xe5}, - {0x91,0xe6}, {0x91,0xe7}, {0x91,0xe8}, {0x91,0xe9}, {0x91,0xea}, {0x91,0xeb}, {0x91,0xec}, {0x91,0xed}, {0x91,0xee}, {0x91,0xef}, - {0x91,0xf0}, {0x91,0xf1}, {0x91,0xf2}, {0x91,0xf3}, {0x91,0xf4}, {0x91,0xf5}, {0x91,0xf6}, {0x91,0xf7}, {0x91,0xf8}, {0x91,0xf9}, - {0x91,0xfa}, {0x91,0xfb}, {0x91,0xfc}, {0x91,0xfd}, {0x91,0xfe}, {0x92,0x40}, {0x92,0x41}, {0x92,0x42}, {0x92,0x43}, {0x92,0x42}, - {0x92,0x45}, {0x92,0x46}, {0x92,0x47}, {0x92,0x48}, {0x92,0x49}, {0x92,0x4a}, {0x92,0x4b}, {0x92,0x4c}, {0x92,0x4d}, {0x92,0x4e}, - {0x92,0x4f}, {0x92,0x50}, {0x92,0x51}, {0x92,0x52}, {0x92,0x53}, {0x92,0x54}, {0x92,0x55}, {0x92,0x56}, {0x92,0x57}, {0x92,0x58}, - {0x92,0x59}, {0x92,0x5a}, {0x92,0x5b}, {0x92,0x5c}, {0x92,0x5d}, {0x92,0x5e}, {0x92,0x5f}, {0x92,0x60}, {0x92,0x61}, {0x92,0x62}, - {0x92,0x63}, {0x92,0x64}, {0x92,0x65}, {0x92,0x66}, {0x92,0x67}, {0x92,0x68}, {0x92,0x69}, {0x92,0x6a}, {0x92,0x6b}, {0x92,0x6c}, - {0x92,0x6d}, {0x92,0x6e}, {0x92,0x6f}, {0x92,0x70}, {0x92,0x71}, {0x92,0x72}, {0x92,0x73}, {0x92,0x74}, {0x92,0x75}, {0x92,0x76}, - {0x92,0x77}, {0x92,0x78}, {0x92,0x79}, {0x92,0x7a}, {0x92,0x7b}, {0x92,0x7c}, {0x92,0x7d}, {0x92,0x7e}, {0x92,0xa1}, {0x92,0xa2}, - {0x92,0xa3}, {0x92,0xa4}, {0x92,0xa5}, {0x92,0xa6}, {0x92,0xa7}, {0x92,0xa8}, {0x92,0xa9}, {0x92,0xaa}, {0x92,0xab}, {0x92,0xac}, - {0x92,0xad}, {0x92,0xae}, {0xa2,0x59}, {0xa2,0x5a}, {0xa2,0x5c}, {0xa2,0x5b}, {0x92,0xb3}, {0x92,0xb4}, {0x92,0xb5}, {0x92,0xb6}, - {0x92,0xb7}, {0x92,0xb8}, {0x92,0xb9}, {0x92,0xba}, {0x92,0xbb}, {0x92,0xbc}, {0x92,0xbd}, {0x92,0xbe}, {0x92,0xbf}, {0x92,0xc0}, - {0x92,0xc1}, {0x92,0xc2}, {0x92,0xc3}, {0x92,0xc4}, {0x92,0xc5}, {0x92,0xc6}, {0x92,0xc7}, {0xa0,0x5f}, {0x92,0xc9}, {0x92,0xca}, - {0x92,0xcb}, {0x92,0xcc}, {0x92,0xcd}, {0x92,0xce}, {0x92,0xcf}, {0x92,0xd0}, {0xe6,0xab}, {0x92,0xd2}, {0x92,0xd3}, {0x92,0xd4}, - {0x92,0xd5}, {0x92,0xd6}, {0x92,0xd7}, {0x92,0xd8}, {0x92,0xd9}, {0x92,0xda}, {0x92,0xdb}, {0x92,0xdc}, {0x92,0xdd}, {0x92,0xde}, - {0x92,0xdf}, {0x92,0xe0}, {0x92,0xe1}, {0x92,0xe2}, {0x92,0xe3}, {0x92,0xe4}, {0x92,0xe5}, {0x92,0xe6}, {0x92,0xe7}, {0x92,0xe8}, - {0x92,0xe9}, {0x92,0xea}, {0x92,0xeb}, {0x92,0xec}, {0x92,0xed}, {0x92,0xee}, {0x92,0xef}, {0x92,0xf0}, {0x92,0xf1}, {0x92,0xf2}, - {0x92,0xf3}, {0x92,0xf4}, {0x92,0xf5}, {0x92,0xf6}, {0x92,0xf7}, {0x92,0xf8}, {0x92,0xf9}, {0x92,0xfa}, {0x92,0xfb}, {0x92,0xfc}, - {0x92,0xfd}, {0x92,0xfe}, {0x93,0x40}, {0x93,0x41}, {0x93,0x42}, {0x93,0x43}, {0x93,0x44}, {0x93,0x45}, {0x93,0x46}, {0x93,0x47}, - {0x93,0x48}, {0x93,0x49}, {0x93,0x4a}, {0x93,0x4b}, {0x93,0x4c}, {0x93,0x4d}, {0x93,0x4e}, {0x93,0x4f}, {0x93,0x50}, {0x93,0x51}, - {0x93,0x52}, {0x93,0x53}, {0x93,0x54}, {0x93,0x55}, {0x93,0x56}, {0x93,0x57}, {0x93,0x58}, {0x93,0x59}, {0x93,0x5a}, {0x93,0x5b}, - {0x93,0x5c}, {0x93,0x5d}, {0x93,0x5e}, {0x93,0x5f}, {0x93,0x60}, {0x93,0x61}, {0x93,0x62}, {0x93,0x63}, {0x93,0x64}, {0x93,0x65}, - {0x93,0x66}, {0x93,0x67}, {0x93,0x68}, {0x93,0x69}, {0x93,0x6a}, {0x93,0x6b}, {0x93,0x6c}, {0x93,0x6d}, {0x93,0x6e}, {0x93,0x6f}, - {0x93,0x70}, {0x93,0x71}, {0x93,0x72}, {0x93,0x73}, {0x93,0x74}, {0x93,0x75}, {0x93,0x76}, {0x93,0x77}, {0x93,0x78}, {0x93,0x79}, - {0x93,0x7a}, {0x93,0x7b}, {0x93,0x7c}, {0x93,0x7d}, {0x93,0x7e}, {0x93,0xa1}, {0x93,0xa2}, {0x93,0xa3}, {0x93,0xa4}, {0x93,0xa5}, - {0x93,0xa6}, {0x93,0xa7}, {0x93,0xa8}, {0x93,0xa9}, {0x93,0xaa}, {0x93,0xab}, {0x93,0xac}, {0x93,0xad}, {0x93,0xae}, {0x93,0xaf}, - {0x93,0xb0}, {0x93,0xb1}, {0x93,0xb2}, {0x93,0xb3}, {0x93,0xb4}, {0x93,0xb5}, {0x93,0xb6}, {0x93,0xb7}, {0x93,0xb8}, {0x93,0xb9}, - {0x93,0xba}, {0x93,0xbb}, {0x93,0xbc}, {0x93,0xbd}, {0x93,0xbe}, {0x93,0xbf}, {0x93,0xc0}, {0x93,0xc1}, {0x93,0xc2}, {0x93,0xc3}, - {0x93,0xc4}, {0x93,0xc5}, {0x93,0xc6}, {0x93,0xc7}, {0x93,0xc8}, {0x93,0xc9}, {0x93,0xca}, {0x93,0xcb}, {0x93,0xcc}, {0x93,0xcd}, - {0x93,0xce}, {0x93,0xcf}, {0x93,0xd0}, {0x93,0xd1}, {0x93,0xd2}, {0x93,0xd3}, {0x93,0xd4}, {0x93,0xd5}, {0x93,0xd6}, {0x93,0xd7}, - {0x93,0xd8}, {0x93,0xd9}, {0x93,0xda}, {0x93,0xdb}, {0x93,0xdc}, {0x93,0xdd}, {0x93,0xde}, {0x93,0xdf}, {0x93,0xe0}, {0x93,0xe1}, - {0x93,0xe2}, {0x93,0xe3}, {0x93,0xe4}, {0x93,0xe5}, {0x93,0xe6}, {0x93,0xe7}, {0x93,0xe8}, {0x93,0xe9}, {0x93,0xea}, {0x93,0xeb}, - {0x93,0xec}, {0x93,0xed}, {0x93,0xee}, {0x93,0xef}, {0x93,0xf0}, {0x93,0xf1}, {0x93,0xf2}, {0x93,0xf3}, {0x93,0xf4}, {0x93,0xf5}, - {0x93,0xf6}, {0x93,0xf7}, {0x93,0xf8}, {0x93,0xf9}, {0x93,0xfa}, {0x93,0xfb}, {0x93,0xfc}, {0x93,0xfd}, {0x93,0xfe}, {0x94,0x40}, - {0x94,0x41}, {0x94,0x42}, {0x94,0x43}, {0x94,0x44}, {0x94,0x45}, {0x94,0x46}, {0xd2,0x56}, {0x94,0x48}, {0x94,0x49}, {0x94,0x4a}, - {0x94,0x4b}, {0x94,0x4c}, {0x94,0x4d}, {0x94,0x4e}, {0x94,0x4f}, {0x94,0x50}, {0x94,0x51}, {0x94,0x52}, {0x94,0x53}, {0x94,0x54}, - {0x94,0x55}, {0x94,0x56}, {0x94,0x57}, {0x94,0x58}, {0x94,0x59}, {0x94,0x5a}, {0x94,0x5b}, {0x94,0x5c}, {0x94,0x5d}, {0x94,0x5e}, - {0x94,0x5f}, {0x94,0x60}, {0x94,0x61}, {0x94,0x62}, {0x94,0x63}, {0x94,0x64}, {0x94,0x65}, {0x94,0x66}, {0x94,0x67}, {0x94,0x68}, - {0x94,0x69}, {0x94,0x6a}, {0x94,0x6b}, {0x94,0x6c}, {0x94,0x6d}, {0x94,0x6e}, {0x94,0x6f}, {0x94,0x70}, {0x94,0x71}, {0x94,0x72}, - {0x94,0x73}, {0x94,0x74}, {0x94,0x75}, {0x94,0x76}, {0x94,0x77}, {0x94,0x78}, {0x94,0x79}, {0x94,0x7a}, {0x94,0x7b}, {0x94,0x7c}, - {0x94,0x7d}, {0x94,0x7e}, {0x94,0xa1}, {0x94,0xa2}, {0x94,0xa3}, {0x94,0xa4}, {0x94,0xa5}, {0x94,0xa6}, {0x94,0xa7}, {0x94,0xa8}, - {0x94,0xa9}, {0x94,0xaa}, {0x94,0xab}, {0x94,0xac}, {0x94,0xad}, {0x94,0xae}, {0x94,0xaf}, {0x94,0xb0}, {0x94,0xb1}, {0x94,0xb2}, - {0x94,0xb3}, {0x94,0xb4}, {0x94,0xb5}, {0x94,0xb6}, {0x94,0xb7}, {0x94,0xb8}, {0x94,0xb9}, {0x94,0xba}, {0x94,0xbb}, {0x94,0xbc}, - {0x94,0xbd}, {0x94,0xbe}, {0x94,0xbf}, {0x94,0xc0}, {0x94,0xc1}, {0x94,0xc2}, {0x94,0xc3}, {0x94,0xc4}, {0x94,0xc5}, {0x94,0xc6}, - {0x94,0xc7}, {0x94,0xc8}, {0x94,0xc9}, {0xe6,0xd0}, {0x94,0xcb}, {0x94,0xcc}, {0x94,0xcd}, {0x94,0xce}, {0x94,0xcf}, {0x94,0xd0}, - {0x94,0xd1}, {0x94,0xd2}, {0x94,0xd3}, {0x94,0xd4}, {0x94,0xd5}, {0x94,0xd6}, {0x94,0xd7}, {0x94,0xd8}, {0x94,0xd9}, {0x94,0xda}, - {0x94,0xdb}, {0x94,0xdc}, {0x94,0xdd}, {0x94,0xde}, {0x94,0xdf}, {0x94,0xe0}, {0x94,0xe1}, {0x94,0xe2}, {0x94,0xe3}, {0x94,0xe4}, - {0x94,0xe5}, {0x94,0xe6}, {0x94,0xe7}, {0x94,0xe8}, {0x94,0xe9}, {0x94,0xea}, {0x94,0xeb}, {0x94,0xec}, {0x94,0xed}, {0x94,0xee}, - {0x94,0xef}, {0x94,0xf0}, {0x94,0xf1}, {0x94,0xf2}, {0x94,0xf3}, {0x94,0xf4}, {0x94,0xf5}, {0x94,0xf6}, {0x94,0xf7}, {0x94,0xf8}, - {0x94,0xf9}, {0x94,0xfa}, {0x94,0xfb}, {0x94,0xfc}, {0x94,0xfd}, {0x94,0xfe}, {0x95,0x40}, {0x95,0x41}, {0x95,0x42}, {0x95,0x43}, - {0x95,0x44}, {0x95,0x45}, {0x95,0x46}, {0x95,0x47}, {0x95,0x48}, {0x95,0x49}, {0x95,0x4a}, {0x95,0x4b}, {0x95,0x4c}, {0x95,0x4d}, - {0x95,0x4e}, {0x95,0x4f}, {0x95,0x50}, {0x95,0x51}, {0x95,0x52}, {0x95,0x53}, {0x95,0x54}, {0x95,0x55}, {0x95,0x56}, {0x95,0x57}, - {0x95,0x58}, {0x95,0x59}, {0x95,0x5a}, {0x95,0x5b}, {0x95,0x5c}, {0x95,0x5d}, {0x95,0x5e}, {0x95,0x5f}, {0x95,0x60}, {0x95,0x61}, - {0x95,0x62}, {0x95,0x63}, {0x95,0x64}, {0x95,0x65}, {0x95,0x66}, {0x95,0x67}, {0x95,0x68}, {0x95,0x69}, {0x95,0x6a}, {0x95,0x6b}, - {0x95,0x6c}, {0x95,0x6d}, {0x95,0x6e}, {0x95,0x6f}, {0x95,0x70}, {0x95,0x71}, {0x95,0x72}, {0x95,0x73}, {0x95,0x74}, {0x95,0x75}, - {0x95,0x76}, {0x95,0x77}, {0x95,0x78}, {0x95,0x79}, {0x95,0x7a}, {0x95,0x7b}, {0x95,0x7c}, {0x95,0x7d}, {0x95,0x7e}, {0x95,0xa1}, - {0x95,0xa2}, {0x95,0xa3}, {0x95,0xa4}, {0x95,0xa5}, {0x95,0xa6}, {0x95,0xa7}, {0x95,0xa8}, {0x95,0xa9}, {0x95,0xaa}, {0x95,0xab}, - {0x95,0xac}, {0x95,0xad}, {0x95,0xae}, {0x95,0xaf}, {0x95,0xb0}, {0x95,0xb1}, {0x95,0xb2}, {0x95,0xb3}, {0x95,0xb4}, {0x95,0xb5}, - {0x95,0xb6}, {0x95,0xb7}, {0x95,0xb8}, {0x95,0xb9}, {0x95,0xba}, {0x95,0xbb}, {0x95,0xbc}, {0x95,0xbd}, {0x95,0xbe}, {0x95,0xbf}, - {0x95,0xc0}, {0x95,0xc1}, {0x95,0xc2}, {0x95,0xc3}, {0x95,0xc4}, {0x95,0xc5}, {0x95,0xc6}, {0x95,0xc7}, {0x95,0xc8}, {0x95,0xc9}, - {0x95,0xca}, {0x95,0xcb}, {0x95,0xcc}, {0x95,0xcd}, {0x95,0xce}, {0x95,0xcf}, {0x95,0xd0}, {0x95,0xd1}, {0x95,0xd2}, {0x95,0xd3}, - {0x95,0xd4}, {0x95,0xd5}, {0x95,0xd6}, {0x95,0xd7}, {0x95,0xd8}, {0xca,0x52}, {0x95,0xda}, {0x95,0xdb}, {0x95,0xdc}, {0x95,0xdd}, - {0x95,0xde}, {0x95,0xdf}, {0x95,0xe0}, {0x95,0xe1}, {0x95,0xe2}, {0x95,0xe3}, {0x95,0xe4}, {0x95,0xe5}, {0x95,0xe6}, {0x95,0xe7}, - {0x95,0xe8}, {0x95,0xe9}, {0x95,0xea}, {0x95,0xeb}, {0x95,0xec}, {0x95,0xed}, {0x95,0xee}, {0x95,0xef}, {0x95,0xf0}, {0x95,0xf1}, - {0x95,0xf2}, {0x95,0xf3}, {0x95,0xf4}, {0x95,0xf5}, {0x95,0xf6}, {0x95,0xf7}, {0x95,0xf8}, {0x95,0xf9}, {0x95,0xfa}, {0x95,0xfb}, - {0x95,0xfc}, {0x95,0xfd}, {0x95,0xfe}, {0x96,0x40}, {0x96,0x41}, {0x96,0x42}, {0x96,0x43}, {0x9c,0xe4}, {0x96,0x45}, {0x96,0x46}, - {0x96,0x47}, {0x96,0x48}, {0x96,0x49}, {0x96,0x4a}, {0x96,0x4b}, {0x96,0x4c}, {0x96,0x4d}, {0x96,0x4e}, {0x96,0x4f}, {0x96,0x50}, - {0x96,0x51}, {0x96,0x52}, {0x96,0x53}, {0x96,0x54}, {0x96,0x55}, {0x96,0x56}, {0x96,0x57}, {0x96,0x58}, {0x96,0x59}, {0x96,0x5a}, - {0x96,0x5b}, {0x96,0x5c}, {0x96,0x5d}, {0x96,0x5e}, {0x96,0x5f}, {0x96,0x60}, {0x96,0x61}, {0x96,0x62}, {0x96,0x63}, {0x96,0x64}, - {0x96,0x65}, {0x96,0x66}, {0x96,0x67}, {0x96,0x68}, {0x96,0x69}, {0x96,0x6a}, {0x96,0x6b}, {0x96,0x6c}, {0x96,0x6d}, {0x96,0x6e}, - {0x96,0x6f}, {0x96,0x70}, {0x96,0x71}, {0x96,0x72}, {0x96,0x73}, {0x96,0x74}, {0x96,0x75}, {0x96,0x76}, {0x96,0x77}, {0x96,0x78}, - {0x96,0x79}, {0x96,0x7a}, {0x96,0x7b}, {0x96,0x7c}, {0x96,0x7d}, {0x96,0x7e}, {0x96,0xa1}, {0x96,0xa2}, {0x96,0xa3}, {0x96,0xa4}, - {0x96,0xa5}, {0x96,0xa6}, {0x96,0xa7}, {0x96,0xa8}, {0x96,0xa9}, {0x96,0xaa}, {0x96,0xab}, {0x96,0xac}, {0x96,0xad}, {0x96,0xae}, - {0x96,0xaf}, {0x96,0xb0}, {0x96,0xb1}, {0x96,0xb2}, {0x96,0xb3}, {0x96,0xb4}, {0x96,0xb5}, {0x96,0xb6}, {0x96,0xb7}, {0x96,0xb8}, - {0x96,0xb9}, {0x96,0xba}, {0x96,0xbb}, {0x96,0xbc}, {0x96,0xbd}, {0x96,0xbe}, {0x96,0xbf}, {0x96,0xc0}, {0x96,0xc1}, {0x96,0xc2}, - {0x96,0xc3}, {0x96,0xc4}, {0x96,0xc5}, {0x96,0xc6}, {0x96,0xc7}, {0x96,0xc8}, {0x96,0xc9}, {0x96,0xca}, {0x96,0xcb}, {0x96,0xcc}, - {0x96,0xcd}, {0x96,0xce}, {0x96,0xcf}, {0x96,0xd0}, {0x96,0xd1}, {0x96,0xd2}, {0x96,0xd3}, {0x96,0xd4}, {0x96,0xd5}, {0x96,0xd6}, - {0x96,0xd7}, {0x96,0xd8}, {0x96,0xd9}, {0x96,0xda}, {0x96,0xdb}, {0x96,0xdc}, {0x96,0xdd}, {0x96,0xde}, {0x96,0xdf}, {0x96,0xe0}, - {0x96,0xe1}, {0x96,0xe2}, {0x96,0xe3}, {0x96,0xe4}, {0x96,0xe5}, {0x96,0xe6}, {0x96,0xe7}, {0x96,0xe8}, {0x96,0xe9}, {0x96,0xea}, - {0x96,0xeb}, {0x96,0xec}, {0x96,0xee}, {0x96,0xee}, {0x96,0xef}, {0x96,0xf0}, {0x96,0xf1}, {0x96,0xf2}, {0x96,0xf3}, {0x96,0xf4}, - {0x96,0xf5}, {0x96,0xf6}, {0x96,0xf7}, {0x96,0xf8}, {0x96,0xf9}, {0x96,0xfa}, {0x96,0xfb}, {0xe9,0x59}, {0x96,0xfd}, {0x96,0xfe}, - {0x97,0x40}, {0x97,0x41}, {0x97,0x42}, {0x97,0x43}, {0x97,0x44}, {0x97,0x45}, {0x97,0x46}, {0x97,0x47}, {0x97,0x48}, {0x97,0x49}, - {0x97,0x4a}, {0x97,0x4b}, {0x97,0x4c}, {0x97,0x4d}, {0x97,0x4e}, {0x97,0x4f}, {0x97,0x50}, {0x97,0x51}, {0x97,0x52}, {0x97,0x53}, - {0x97,0x54}, {0x97,0x55}, {0x97,0x56}, {0x97,0x57}, {0x97,0x58}, {0x97,0x59}, {0x97,0x5a}, {0x97,0x5b}, {0x97,0x5c}, {0x97,0x5d}, - {0x97,0x5e}, {0x97,0x5f}, {0x97,0x60}, {0x97,0x61}, {0x97,0x62}, {0x97,0x63}, {0x97,0x64}, {0x97,0x65}, {0x97,0x66}, {0x97,0x67}, - {0x97,0x68}, {0x97,0x69}, {0x97,0x6a}, {0x97,0x6b}, {0x97,0x6c}, {0x97,0x6d}, {0x97,0x6e}, {0x97,0x6f}, {0x97,0x70}, {0x97,0x71}, - {0x97,0x72}, {0x97,0x73}, {0x97,0x74}, {0x97,0x75}, {0x97,0x76}, {0x97,0x77}, {0x97,0x78}, {0x97,0x79}, {0x97,0x7a}, {0x97,0x7b}, - {0x97,0x7c}, {0x97,0x7d}, {0x97,0x7e}, {0x97,0xa1}, {0x97,0xa2}, {0x97,0xa3}, {0x97,0xa4}, {0x97,0xa5}, {0x97,0xa6}, {0x97,0xa7}, - {0x97,0xa8}, {0x97,0xa9}, {0x97,0xaa}, {0x97,0xab}, {0x97,0xac}, {0x97,0xad}, {0x97,0xae}, {0x97,0xaf}, {0x97,0xb0}, {0x97,0xb1}, - {0x97,0xb2}, {0x97,0xb3}, {0x97,0xb4}, {0x97,0xb5}, {0x97,0xb6}, {0x97,0xb7}, {0x97,0xb8}, {0x97,0xb9}, {0x97,0xba}, {0x97,0xbb}, - {0x97,0xbc}, {0x97,0xbd}, {0x97,0xbe}, {0x97,0xbf}, {0x97,0xc0}, {0x97,0xc1}, {0x97,0xc2}, {0x97,0xc3}, {0x97,0xc4}, {0x97,0xc5}, - {0x97,0xc6}, {0x97,0xc7}, {0x97,0xc8}, {0x97,0xc9}, {0x97,0xca}, {0x97,0xcb}, {0x97,0xcc}, {0x97,0xcd}, {0x97,0xce}, {0x97,0xcf}, - {0x97,0xd0}, {0x97,0xd1}, {0x97,0xd2}, {0x97,0xd3}, {0x97,0xd4}, {0x97,0xd5}, {0x97,0xd6}, {0x97,0xd7}, {0x97,0xd8}, {0x97,0xd9}, - {0x97,0xda}, {0x97,0xdb}, {0x97,0xdc}, {0x97,0xdd}, {0x97,0xde}, {0x97,0xdf}, {0x97,0xe0}, {0x97,0xe1}, {0x97,0xe2}, {0x97,0xe3}, - {0x97,0xe4}, {0x97,0xe5}, {0x97,0xe6}, {0x97,0xe7}, {0x97,0xe8}, {0x97,0xe9}, {0x97,0xea}, {0x97,0xeb}, {0x97,0xec}, {0x97,0xed}, - {0x97,0xee}, {0x97,0xef}, {0x97,0xf0}, {0x97,0xf1}, {0x97,0xf2}, {0x97,0xf3}, {0x97,0xf4}, {0x97,0xf5}, {0x97,0xf6}, {0x97,0xf7}, - {0x97,0xf8}, {0x97,0xf9}, {0x97,0xfa}, {0x97,0xfb}, {0x97,0xfc}, {0x97,0xfd}, {0x97,0xfe}, {0x98,0x40}, {0x98,0x41}, {0x98,0x42}, - {0x98,0x43}, {0x98,0x44}, {0x98,0x45}, {0x98,0x46}, {0x98,0x47}, {0x98,0x48}, {0x98,0x49}, {0x98,0x4a}, {0x98,0x4b}, {0x98,0x4c}, - {0x98,0x4d}, {0x98,0x4e}, {0x98,0x4f}, {0x98,0x50}, {0x98,0x51}, {0x98,0x52}, {0x98,0x53}, {0x98,0x54}, {0x98,0x55}, {0x98,0x56}, - {0x98,0x57}, {0x98,0x58}, {0x98,0x59}, {0x98,0x5a}, {0x98,0x5b}, {0x98,0x5c}, {0x98,0x5d}, {0x98,0x5e}, {0x98,0x5f}, {0x98,0x60}, - {0x98,0x61}, {0x98,0x62}, {0x98,0x63}, {0x98,0x64}, {0x98,0x65}, {0x98,0x66}, {0x98,0x67}, {0x98,0x68}, {0x98,0x69}, {0x98,0x6a}, - {0x98,0x6b}, {0x98,0x6c}, {0x98,0x6d}, {0x98,0x6e}, {0x98,0x6f}, {0x98,0x70}, {0x98,0x71}, {0x98,0x72}, {0x98,0x73}, {0x98,0x74}, - {0x98,0x75}, {0x98,0x76}, {0x98,0x77}, {0x98,0x78}, {0x98,0x79}, {0x98,0x7a}, {0x98,0x7b}, {0x98,0x7c}, {0x98,0x7d}, {0x98,0x7e}, - {0x98,0xa1}, {0x98,0xa2}, {0x98,0xa3}, {0x98,0xa4}, {0x98,0xa5}, {0x98,0xa6}, {0x98,0xa7}, {0x98,0xa8}, {0x98,0xa9}, {0x98,0xaa}, - {0x98,0xab}, {0x98,0xac}, {0x98,0xad}, {0x98,0xae}, {0x98,0xaf}, {0x98,0xb0}, {0x98,0xb1}, {0x98,0xb2}, {0x98,0xb3}, {0x98,0xb4}, - {0x98,0xb5}, {0x98,0xb6}, {0x98,0xb7}, {0x98,0xb8}, {0x98,0xb9}, {0x98,0xba}, {0x98,0xbb}, {0x98,0xbc}, {0x98,0xbd}, {0x98,0xbe}, - {0x98,0xbf}, {0x98,0xc0}, {0x98,0xc1}, {0x98,0xc2}, {0x98,0xc3}, {0x98,0xc4}, {0x98,0xc5}, {0x98,0xc6}, {0x98,0xc7}, {0x98,0xc8}, - {0x98,0xc9}, {0x98,0xca}, {0x98,0xcb}, {0x98,0xcc}, {0x98,0xcd}, {0x98,0xce}, {0x98,0xcf}, {0x98,0xd0}, {0x98,0xd1}, {0x98,0xd2}, - {0x98,0xd3}, {0x98,0xd4}, {0x98,0xd5}, {0x98,0xd6}, {0x98,0xd7}, {0x98,0xd8}, {0x98,0xd9}, {0x98,0xda}, {0x98,0xdb}, {0x98,0xdc}, - {0x98,0xdd}, {0x98,0xde}, {0x98,0xdf}, {0x98,0xe0}, {0x98,0xe1}, {0x98,0xe2}, {0x98,0xe3}, {0x98,0xe4}, {0x98,0xe5}, {0x98,0xe6}, - {0x98,0xe7}, {0x98,0xe8}, {0x98,0xe9}, {0x98,0xea}, {0x98,0xeb}, {0x98,0xec}, {0x98,0xed}, {0x98,0xee}, {0x98,0xef}, {0x98,0xf0}, - {0x98,0xf1}, {0x98,0xf2}, {0x98,0xf3}, {0x98,0xf4}, {0x98,0xf5}, {0x98,0xf6}, {0x98,0xf7}, {0x98,0xf8}, {0x98,0xf9}, {0x98,0xfa}, - {0x98,0xfb}, {0x98,0xfc}, {0x98,0xfd}, {0x98,0xfe}, {0x99,0x40}, {0x99,0x41}, {0x99,0x42}, {0x99,0x43}, {0x99,0x44}, {0x99,0x45}, - {0x99,0x46}, {0x99,0x47}, {0x99,0x48}, {0x99,0x49}, {0x99,0x4a}, {0x99,0x4b}, {0x99,0x4c}, {0x99,0x4d}, {0x99,0x4e}, {0x99,0x4f}, - {0x99,0x50}, {0x99,0x51}, {0x99,0x52}, {0x99,0x53}, {0x99,0x54}, {0x99,0x55}, {0x99,0x56}, {0x99,0x57}, {0x99,0x58}, {0x99,0x59}, - {0x99,0x5a}, {0x99,0x5b}, {0x99,0x5c}, {0x99,0x5d}, {0x99,0x5e}, {0x99,0x5f}, {0x99,0x60}, {0x99,0x61}, {0x99,0x62}, {0x99,0x63}, - {0x99,0x64}, {0x99,0x65}, {0x99,0x66}, {0x99,0x67}, {0x99,0x68}, {0x99,0x69}, {0x99,0x6a}, {0x99,0x6b}, {0x99,0x6c}, {0x99,0x6d}, - {0x99,0x6e}, {0x99,0x6f}, {0x99,0x70}, {0x99,0x71}, {0x99,0x72}, {0x99,0x73}, {0x99,0x74}, {0x99,0x75}, {0x99,0x76}, {0x99,0x77}, - {0x99,0x78}, {0x99,0x79}, {0x99,0x7a}, {0x99,0x7b}, {0x99,0x7c}, {0x99,0x7d}, {0x99,0x7e}, {0x99,0xa1}, {0x99,0xa2}, {0x99,0xa3}, - {0x99,0xa4}, {0x99,0xa5}, {0x99,0xa6}, {0x99,0xa7}, {0x99,0xa8}, {0x99,0xa9}, {0x99,0xaa}, {0x99,0xab}, {0x99,0xac}, {0x99,0xad}, - {0x99,0xae}, {0x99,0xaf}, {0x99,0xb0}, {0x99,0xb1}, {0x99,0xb2}, {0x99,0xb3}, {0x99,0xb4}, {0x99,0xb5}, {0x99,0xb6}, {0x99,0xb7}, - {0x99,0xb8}, {0x99,0xb9}, {0x99,0xba}, {0x99,0xbb}, {0x99,0xbc}, {0x99,0xbd}, {0x99,0xbe}, {0x99,0xbf}, {0x99,0xc0}, {0x99,0xc1}, - {0x99,0xc2}, {0x99,0xc3}, {0x99,0xc4}, {0x99,0xc5}, {0x99,0xc6}, {0x99,0xc7}, {0x99,0xc8}, {0x99,0xc9}, {0x99,0xca}, {0x99,0xcb}, - {0x99,0xcc}, {0x99,0xcd}, {0x99,0xce}, {0x99,0xcf}, {0x99,0xd0}, {0x99,0xd1}, {0x99,0xd2}, {0x99,0xd3}, {0x99,0xd4}, {0x99,0xd5}, - {0x99,0xd6}, {0x99,0xd7}, {0x99,0xd8}, {0x99,0xd9}, {0x99,0xda}, {0x99,0xdb}, {0x99,0xdc}, {0x99,0xdd}, {0x99,0xde}, {0x99,0xdf}, - {0x99,0xe0}, {0x99,0xe1}, {0x99,0xe2}, {0x99,0xe3}, {0x99,0xe4}, {0x99,0xe5}, {0x99,0xe6}, {0x99,0xe7}, {0x99,0xe8}, {0x99,0xe9}, - {0x99,0xea}, {0x99,0xeb}, {0x99,0xec}, {0x99,0xed}, {0x99,0xee}, {0x99,0xef}, {0x99,0xf0}, {0x99,0xf1}, {0x99,0xf2}, {0x99,0xf3}, - {0x99,0xf4}, {0x99,0xf5}, {0x99,0xf6}, {0x99,0xf7}, {0x99,0xf8}, {0x99,0xf9}, {0x99,0xfa}, {0x99,0xfb}, {0x99,0xfc}, {0x99,0xfd}, - {0x99,0xfe}, {0x9a,0x40}, {0x9a,0x41}, {0x9a,0x42}, {0x9a,0x43}, {0x9a,0x44}, {0x9a,0x45}, {0x9a,0x46}, {0x9a,0x47}, {0x9a,0x48}, - {0x9a,0x49}, {0x9a,0x4a}, {0x9a,0x4b}, {0x9a,0x4c}, {0x9a,0x4d}, {0x9a,0x4e}, {0x9a,0x4f}, {0x9a,0x50}, {0x9a,0x51}, {0x9a,0x52}, - {0x9a,0x53}, {0x9a,0x54}, {0x9a,0x55}, {0x9a,0x56}, {0x9a,0x57}, {0x9a,0x58}, {0x9a,0x59}, {0x9a,0x5a}, {0x9a,0x5b}, {0x9a,0x5c}, - {0x9a,0x5d}, {0x9a,0x5e}, {0x9a,0x5f}, {0x9a,0x60}, {0x9a,0x61}, {0x9a,0x62}, {0x9a,0x63}, {0x9a,0x64}, {0x9a,0x65}, {0x9a,0x66}, - {0x9a,0x67}, {0x9a,0x68}, {0x9a,0x69}, {0x9a,0x6a}, {0x9a,0x6b}, {0x9a,0x6c}, {0x9a,0x6d}, {0x9a,0x6e}, {0x9a,0x6f}, {0x9a,0x70}, - {0x9a,0x71}, {0x9a,0x72}, {0x9a,0x73}, {0x9a,0x74}, {0x9a,0x75}, {0x9a,0x76}, {0x9a,0x77}, {0x9a,0x78}, {0x9a,0x79}, {0x9a,0x7a}, - {0x9a,0x7b}, {0x9a,0x7c}, {0x9a,0x7d}, {0x9a,0x7e}, {0x9a,0xa1}, {0x9a,0xa2}, {0x9a,0xa3}, {0x9a,0xa4}, {0x9a,0xa5}, {0x9a,0xa6}, - {0x9a,0xa7}, {0x9a,0xa8}, {0x9a,0xa9}, {0x9a,0xaa}, {0x9a,0xab}, {0x9a,0xac}, {0x9a,0xad}, {0x9a,0xae}, {0x9a,0xaf}, {0x9a,0xb0}, - {0x9a,0xb1}, {0x9a,0xb2}, {0x9a,0xb3}, {0x9a,0xb4}, {0x9a,0xb5}, {0x9a,0xb6}, {0x9a,0xb7}, {0x9a,0xb8}, {0x9a,0xb9}, {0x9a,0xba}, - {0x9a,0xbb}, {0x9a,0xbc}, {0x9a,0xbd}, {0x9a,0xbe}, {0x9a,0xbf}, {0x9a,0xc0}, {0x9a,0xc1}, {0x9a,0xc2}, {0x9a,0xc3}, {0x9a,0xc4}, - {0x9a,0xc5}, {0x9a,0xc6}, {0x9a,0xc7}, {0x9a,0xc8}, {0x9a,0xc9}, {0x9a,0xca}, {0x9a,0xcb}, {0x9a,0xcc}, {0x9a,0xcd}, {0x9a,0xce}, - {0x9a,0xcf}, {0x9a,0xd0}, {0x9a,0xd1}, {0x9a,0xd2}, {0x9a,0xd3}, {0x9a,0xd4}, {0x9a,0xd5}, {0x9a,0xd6}, {0x9a,0xd7}, {0x9a,0xd8}, - {0x9a,0xd9}, {0x9a,0xda}, {0x9a,0xdb}, {0x9a,0xdc}, {0x9a,0xdd}, {0x9a,0xde}, {0x9a,0xdf}, {0x9a,0xe0}, {0x9a,0xe1}, {0x9a,0xe2}, - {0x9a,0xe3}, {0x9a,0xe4}, {0x9a,0xe5}, {0x9a,0xe6}, {0x9a,0xe7}, {0x9a,0xe8}, {0x9a,0xe9}, {0x9a,0xea}, {0x9a,0xeb}, {0x9a,0xec}, - {0x9a,0xed}, {0x9a,0xee}, {0x9a,0xef}, {0x9a,0xf0}, {0x9a,0xf1}, {0x9a,0xf2}, {0x9a,0xf3}, {0x9a,0xf4}, {0x9a,0xf5}, {0x9a,0xf6}, - {0x9a,0xf7}, {0x9a,0xf8}, {0x9a,0xf9}, {0x9a,0xfa}, {0x9a,0xfb}, {0x9a,0xfc}, {0x9a,0xfd}, {0x9a,0xfe}, {0x9b,0x40}, {0x9b,0x41}, - {0x9b,0x42}, {0x9b,0x43}, {0x9b,0x44}, {0x9b,0x45}, {0x9b,0x46}, {0x9b,0x47}, {0x9b,0x48}, {0x9b,0x49}, {0x9b,0x4a}, {0x9b,0x4b}, - {0x9b,0x4c}, {0x9b,0x4d}, {0x9b,0x4e}, {0x9b,0x4f}, {0x9b,0x50}, {0x9b,0x51}, {0x9b,0x52}, {0x9b,0x53}, {0x9b,0x54}, {0x9b,0x55}, - {0x9b,0x56}, {0x9b,0x57}, {0x9b,0x58}, {0x9b,0x59}, {0x9b,0x5a}, {0x9b,0x5b}, {0x9b,0x5c}, {0x9b,0x5d}, {0x9b,0x5e}, {0x9b,0x5f}, - {0x9b,0x60}, {0x9b,0x61}, {0x9b,0x62}, {0x9b,0x63}, {0x9b,0x64}, {0x9b,0x65}, {0x9b,0x66}, {0x9b,0x67}, {0x9b,0x68}, {0x9b,0x69}, - {0x9b,0x6a}, {0x9b,0x6b}, {0x9b,0x6c}, {0x9b,0x6d}, {0x9b,0x6e}, {0x9b,0x6f}, {0x9b,0x70}, {0x9b,0x71}, {0x9b,0x72}, {0x9b,0x73}, - {0x9b,0x74}, {0x9b,0x75}, {0xef,0xf9}, {0x9b,0x77}, {0xc5,0xf7}, {0x9b,0x79}, {0x9b,0x7a}, {0xf5,0xe8}, {0x9b,0x7c}, {0x9b,0x7d}, - {0x9b,0x7e}, {0x9b,0xa1}, {0x9b,0xa2}, {0x9b,0xa3}, {0x9b,0xa4}, {0x9b,0xa5}, {0x9b,0xa6}, {0x9b,0xa7}, {0x9b,0xa8}, {0x9b,0xa9}, - {0x9b,0xaa}, {0x9b,0xab}, {0x9b,0xac}, {0x9b,0xad}, {0x9b,0xae}, {0x9b,0xaf}, {0x9b,0xb0}, {0x9b,0xb1}, {0x9b,0xb2}, {0x9b,0xb3}, - {0x9b,0xb4}, {0x9b,0xb5}, {0x9b,0xb6}, {0x9b,0xb7}, {0x9b,0xb8}, {0x9b,0xb9}, {0x9b,0xba}, {0x9b,0xbb}, {0x9b,0xbc}, {0x9b,0xbd}, - {0x9b,0xbe}, {0x9b,0xbf}, {0x9b,0xc0}, {0x9b,0xc1}, {0x9b,0xc2}, {0x9b,0xc3}, {0x9b,0xc4}, {0x9b,0xc5}, {0xe8,0xcd}, {0x9b,0xc7}, - {0x9b,0xc8}, {0x9b,0xc9}, {0x9b,0xca}, {0x9b,0xcb}, {0x9b,0xcc}, {0x9b,0xcd}, {0x9b,0xce}, {0x9b,0xcf}, {0x9b,0xd0}, {0x9b,0xd1}, - {0x9b,0xd2}, {0x9b,0xd3}, {0x9b,0xd4}, {0x9b,0xd5}, {0x9b,0xd6}, {0x9b,0xd7}, {0x9b,0xd8}, {0x9b,0xd9}, {0x9b,0xda}, {0x9b,0xdb}, - {0x9b,0xdc}, {0x9b,0xdd}, {0xd0,0xc0}, {0x9b,0xdf}, {0x9b,0xe0}, {0x9b,0xe1}, {0x9b,0xe2}, {0x9b,0xe3}, {0x9b,0xe4}, {0x9b,0xe5}, - {0x9b,0xe6}, {0x9b,0xe7}, {0x9b,0xe8}, {0x9b,0xe9}, {0x9b,0xea}, {0x9b,0xeb}, {0xfd,0x64}, {0x9b,0xed}, {0x9b,0xee}, {0x9b,0xef}, - {0x9b,0xf0}, {0x9b,0xf1}, {0x9b,0xf2}, {0x9b,0xf3}, {0x9b,0xf4}, {0x9b,0xf5}, {0xbf,0x47}, {0x9b,0xf7}, {0x9b,0xf8}, {0x9b,0xf9}, - {0x9b,0xfa}, {0x9b,0xfb}, {0x9b,0xfc}, {0x9b,0xfd}, {0x9b,0xfe}, {0x9c,0x40}, {0x9c,0x41}, {0xeb,0xc9}, {0x9c,0x43}, {0x9c,0x44}, - {0x9c,0x45}, {0x9c,0x46}, {0x9c,0x47}, {0x9c,0x48}, {0x9c,0x49}, {0x9c,0x4a}, {0x9c,0x4b}, {0x9c,0x4c}, {0x9c,0x4d}, {0x9c,0x4e}, - {0x9c,0x4f}, {0x9c,0x50}, {0x9c,0x51}, {0x9c,0x52}, {0xcd,0xe7}, {0x9c,0x54}, {0x9c,0x55}, {0x9c,0x56}, {0x9c,0x57}, {0x9c,0x58}, - {0x9c,0x59}, {0x9c,0x5a}, {0x9c,0x5b}, {0x9c,0x5c}, {0x9c,0x5d}, {0x9c,0x5e}, {0x9c,0x5f}, {0x9c,0x60}, {0x9c,0x61}, {0xc0,0xe7}, - {0x9c,0x63}, {0x9c,0x64}, {0x9c,0x65}, {0x9c,0x66}, {0x9c,0x67}, {0xdc,0x52}, {0x9c,0x69}, {0x9c,0x6a}, {0xf8,0x6d}, {0x9c,0x6c}, - {0x9c,0x6d}, {0x9c,0x6e}, {0x9c,0x6f}, {0x9c,0x70}, {0x9c,0x71}, {0x9c,0x72}, {0x9c,0x73}, {0x9c,0x74}, {0x9c,0x75}, {0x9c,0x76}, - {0xdb,0x5d}, {0x9c,0x78}, {0x9c,0x79}, {0x9c,0x7a}, {0x9c,0x7b}, {0x9c,0x7c}, {0x9c,0x7d}, {0x9c,0x7e}, {0x9c,0xa1}, {0x9c,0xa2}, - {0x9c,0xa3}, {0x9c,0xa4}, {0x9c,0xa5}, {0x9c,0xa6}, {0x9c,0xa7}, {0x9c,0xa8}, {0x9c,0xa9}, {0x9c,0xaa}, {0x9c,0xab}, {0x9c,0xac}, - {0x9c,0xad}, {0x9c,0xae}, {0x9c,0xaf}, {0x9c,0xb0}, {0x9c,0xb1}, {0x9c,0xb2}, {0x9c,0xb3}, {0x9c,0xb4}, {0x9c,0xb5}, {0x9c,0xb6}, - {0x9c,0xb7}, {0x9c,0xb8}, {0x9c,0xb9}, {0x9c,0xba}, {0x9c,0xbb}, {0xc9,0x5c}, {0xaf,0xb0}, {0x9c,0xbe}, {0x9c,0xbf}, {0x9c,0xc0}, - {0x9c,0xc1}, {0x9c,0xc2}, {0x9c,0xc3}, {0x9c,0xc4}, {0x9c,0xc5}, {0x9c,0xc6}, {0x9c,0xc7}, {0x9c,0xc8}, {0x9c,0xc9}, {0x9c,0xca}, - {0x9c,0xcb}, {0x9c,0xcc}, {0x9c,0xcd}, {0x9c,0xce}, {0x9c,0xcf}, {0xd4,0xd1}, {0x9c,0xd1}, {0x9c,0xd2}, {0x9c,0xd3}, {0x9c,0xd4}, - {0x9c,0xd5}, {0x9c,0xd6}, {0x9c,0xd7}, {0x9c,0xd8}, {0x9c,0xd9}, {0x9c,0xda}, {0x9c,0xdb}, {0x9c,0xdc}, {0x9c,0xdd}, {0x9c,0xde}, - {0x9c,0xdf}, {0x9c,0xe0}, {0x9c,0xe1}, {0x9c,0xe2}, {0x9c,0xe3}, {0x9c,0xe4}, {0x9c,0xe5}, {0x9c,0xe6}, {0x9c,0xe7}, {0x9c,0xe8}, - {0x9c,0xe9}, {0x9c,0xea}, {0x9c,0xeb}, {0x9c,0xec}, {0x9c,0xed}, {0x9c,0xee}, {0x9c,0xef}, {0x9c,0xf0}, {0x9c,0xf1}, {0x9c,0xf2}, - {0x9c,0xf3}, {0x9c,0xf4}, {0x9c,0xf5}, {0x9c,0xf6}, {0x9c,0xf7}, {0x9c,0xf8}, {0x9c,0xf9}, {0x9c,0xfa}, {0x9c,0xfb}, {0x9c,0xfc}, - {0x9c,0xfd}, {0x9c,0xfe}, {0x9d,0x40}, {0x9d,0x41}, {0x9d,0x42}, {0x9d,0x43}, {0x9d,0x44}, {0x9d,0x45}, {0x9d,0x46}, {0x9d,0x47}, - {0x9d,0x48}, {0x9d,0x49}, {0x9d,0x4a}, {0x9d,0x4b}, {0x9d,0x4c}, {0x9d,0x4d}, {0x9d,0x4e}, {0x9d,0x4f}, {0x9d,0x50}, {0x9d,0x51}, - {0x9d,0x52}, {0x9d,0x53}, {0x9d,0x54}, {0x9d,0x55}, {0x9d,0x56}, {0xe0,0x7c}, {0x9d,0x58}, {0x9d,0x59}, {0xb5,0xae}, {0x9d,0x5b}, - {0x9d,0x5c}, {0x9d,0x5d}, {0x9d,0x5e}, {0x9d,0x5f}, {0x9d,0x60}, {0x9d,0x61}, {0x9d,0x62}, {0x9d,0x63}, {0x9d,0x64}, {0x9d,0x65}, - {0x9d,0x66}, {0x9d,0x67}, {0x9d,0x68}, {0x9d,0x69}, {0x9d,0x6a}, {0x9d,0x6b}, {0x9d,0x6c}, {0x9d,0x6d}, {0x9d,0x6e}, {0x9d,0x6f}, - {0x9d,0x70}, {0x9d,0x71}, {0x9d,0x72}, {0x9d,0x73}, {0x9d,0x74}, {0x9d,0x75}, {0x9d,0x76}, {0x9d,0x77}, {0x9d,0x78}, {0x9d,0x79}, - {0x9d,0x7a}, {0x9d,0x7b}, {0x9d,0x7c}, {0x9d,0x7d}, {0x9d,0x7e}, {0x9d,0xa1}, {0x9d,0xa2}, {0x9d,0xa3}, {0x9d,0xa4}, {0x9d,0xa5}, - {0x9d,0xa6}, {0x9d,0xa7}, {0x9d,0xa8}, {0x9d,0xa9}, {0x9d,0xaa}, {0x9d,0xab}, {0x9d,0xac}, {0x9d,0xad}, {0x9d,0xae}, {0x9d,0xaf}, - {0x9d,0xb0}, {0x9d,0xb1}, {0x9d,0xb2}, {0x9d,0xb3}, {0x9d,0xb4}, {0x9d,0xb5}, {0x9d,0xb6}, {0x9d,0xb7}, {0x9d,0xb8}, {0x9d,0xb9}, - {0x9d,0xba}, {0x9d,0xbb}, {0x9d,0xbc}, {0x9d,0xbd}, {0x9d,0xbe}, {0x9d,0xbf}, {0x9d,0xc0}, {0x9d,0xc1}, {0x9d,0xc2}, {0x9d,0xc3}, - {0xa9,0xe4}, {0x9d,0xc5}, {0x9d,0xc6}, {0x9d,0xc7}, {0x9d,0xc8}, {0x9d,0xc9}, {0x9d,0xca}, {0x9d,0xcb}, {0x9d,0xcc}, {0x9d,0xcd}, - {0x9d,0xce}, {0x9d,0xcf}, {0x9d,0xd0}, {0x9d,0xd1}, {0x9d,0xd2}, {0x9d,0xd3}, {0x9d,0xd4}, {0x9d,0xd5}, {0x9d,0xd6}, {0x9d,0xd7}, - {0x9d,0xd8}, {0x9d,0xd9}, {0x9d,0xda}, {0x9d,0xdb}, {0x9d,0xdc}, {0x9d,0xdd}, {0x9d,0xde}, {0x9d,0xdf}, {0x9d,0xe0}, {0x9d,0xe1}, - {0x9d,0xe2}, {0x9d,0xe3}, {0x9d,0xe4}, {0x9d,0xe5}, {0x9d,0xe6}, {0x9d,0xe7}, {0x9d,0xe8}, {0x9d,0xe9}, {0x9d,0xea}, {0x9d,0xeb}, - {0x9d,0xec}, {0x9d,0xed}, {0x9d,0xee}, {0x9d,0xef}, {0x9d,0xf0}, {0x9d,0xf1}, {0x9d,0xf2}, {0x9d,0xf3}, {0x9d,0xf4}, {0x9d,0xf5}, - {0x9d,0xf6}, {0x9d,0xf7}, {0x9d,0xf8}, {0x9d,0xf9}, {0x9d,0xfa}, {0x9d,0xfb}, {0x9d,0xfc}, {0x9d,0xfd}, {0x9d,0xfe}, {0x9e,0x40}, - {0x9e,0x41}, {0x9e,0x42}, {0x9e,0x43}, {0x9e,0x44}, {0x9e,0x45}, {0x9e,0x46}, {0x9e,0x47}, {0x9e,0x48}, {0x9e,0x49}, {0x9e,0x4a}, - {0x9e,0x4b}, {0x9e,0x4c}, {0x9e,0x4d}, {0x9e,0x4e}, {0x9e,0x4f}, {0x9e,0x50}, {0x9e,0x51}, {0x9e,0x52}, {0x9e,0x53}, {0x9e,0x54}, - {0x9e,0x55}, {0x9e,0x56}, {0x9e,0x57}, {0x9e,0x58}, {0x9e,0x59}, {0x9e,0x5a}, {0x9e,0x5b}, {0x9e,0x5c}, {0x9e,0x5d}, {0x9e,0x5e}, - {0x9e,0x5f}, {0x9e,0x60}, {0x9e,0x61}, {0x9e,0x62}, {0x9e,0x63}, {0x9e,0x64}, {0x9e,0x65}, {0x9e,0x66}, {0x9e,0x67}, {0x9e,0x68}, - {0x9e,0x69}, {0x9e,0x6a}, {0x9e,0x6b}, {0x9e,0x6c}, {0x9e,0x6d}, {0x9e,0x6e}, {0x9e,0x6f}, {0x9e,0x70}, {0x9e,0x71}, {0x9e,0x72}, - {0x9e,0x73}, {0x9e,0x74}, {0x9e,0x75}, {0x9e,0x76}, {0x9e,0x77}, {0x9e,0x78}, {0x9e,0x79}, {0x9e,0x7a}, {0x9e,0x7b}, {0x9e,0x7c}, - {0x9e,0x7d}, {0x9e,0x7e}, {0x9e,0xa1}, {0x9e,0xa2}, {0x9e,0xa3}, {0x9e,0xa4}, {0x9e,0xa5}, {0x9e,0xa6}, {0x9e,0xa7}, {0x9e,0xa8}, - {0xab,0xec}, {0x9e,0xaa}, {0x9e,0xab}, {0x9e,0xac}, {0x9e,0xad}, {0x9e,0xae}, {0x9e,0xaf}, {0x9e,0xb0}, {0x9e,0xb1}, {0x9e,0xb2}, - {0x9e,0xb3}, {0x9e,0xb4}, {0x9e,0xb5}, {0x9e,0xb6}, {0x9e,0xb7}, {0x9e,0xb8}, {0x9e,0xb9}, {0x9e,0xba}, {0x9e,0xbb}, {0x9e,0xbc}, - {0x9e,0xbd}, {0x9e,0xbe}, {0x9e,0xbf}, {0x9e,0xc0}, {0x9e,0xc1}, {0x9e,0xc2}, {0x9e,0xc3}, {0x9e,0xc4}, {0x9e,0xc5}, {0x9e,0xc6}, - {0x9e,0xc7}, {0x9e,0xc8}, {0x9e,0xc9}, {0x9e,0xca}, {0x9e,0xcb}, {0x9e,0xcc}, {0x9e,0xcd}, {0x9e,0xce}, {0x9e,0xcf}, {0x9e,0xd0}, - {0x9e,0xd1}, {0x9e,0xd2}, {0x9e,0xd3}, {0x9e,0xd4}, {0x9e,0xd5}, {0x9e,0xd6}, {0x9e,0xd7}, {0x9e,0xd8}, {0x9e,0xd9}, {0x9e,0xda}, - {0x9e,0xdb}, {0x9e,0xdc}, {0x9e,0xdd}, {0x9e,0xde}, {0x9e,0xdf}, {0x9e,0xe0}, {0x9e,0xe1}, {0x9e,0xe2}, {0x9e,0xe3}, {0x9e,0xe4}, - {0x9e,0xe5}, {0x9e,0xe6}, {0x9e,0xe7}, {0x9e,0xe8}, {0x9e,0xe9}, {0x9e,0xea}, {0x9e,0xeb}, {0x9e,0xec}, {0x9e,0xed}, {0x9e,0xee}, - {0xde,0xcd}, {0x9e,0xf0}, {0x9e,0xf1}, {0x9e,0xf2}, {0x9e,0xf3}, {0x9e,0xf4}, {0x9e,0xf5}, {0x9e,0xf6}, {0x9e,0xf7}, {0x9e,0xf8}, - {0x9e,0xf9}, {0x9e,0xfa}, {0x9e,0xfb}, {0x9e,0xfc}, {0xc9,0xfc}, {0x9e,0xfe}, {0x9f,0x40}, {0x9f,0x41}, {0x9f,0x42}, {0x9f,0x43}, - {0x9f,0x44}, {0x9f,0x45}, {0x9f,0x46}, {0x9f,0x47}, {0x9f,0x48}, {0x9f,0x49}, {0x9f,0x4a}, {0x9f,0x4b}, {0x9f,0x4c}, {0x9f,0x4d}, - {0x9f,0x4e}, {0x9f,0x4f}, {0x9f,0x50}, {0x9f,0x51}, {0x9f,0x52}, {0x9f,0x53}, {0x9f,0x54}, {0x9f,0x55}, {0x9f,0x56}, {0x9f,0x57}, - {0x9f,0x58}, {0x9f,0x59}, {0x9f,0x5a}, {0x9f,0x5b}, {0x9f,0x5c}, {0x9f,0x5d}, {0x9f,0x5e}, {0x9f,0x5f}, {0xf9,0xc4}, {0x9f,0x61}, - {0x9f,0x62}, {0x9f,0x63}, {0x9f,0x64}, {0x9f,0x65}, {0x91,0xbe}, {0x9f,0x67}, {0x9f,0x68}, {0x9f,0x69}, {0x9f,0x6a}, {0x9f,0x6b}, - {0x9f,0x6c}, {0x9f,0x6d}, {0x9f,0x6e}, {0x9f,0x6f}, {0x9f,0x70}, {0x9f,0x71}, {0x9f,0x72}, {0x9f,0x73}, {0x9f,0x74}, {0x9f,0x75}, - {0x9f,0x76}, {0x9f,0x77}, {0x9f,0x78}, {0x9f,0x79}, {0x9f,0x7a}, {0x9f,0x7b}, {0x9f,0x7c}, {0x9f,0x7d}, {0x9f,0x7e}, {0x9f,0xa1}, - {0x9f,0xa2}, {0x9f,0xa3}, {0x9f,0xa4}, {0x9f,0xa5}, {0x9f,0xa6}, {0x9f,0xa7}, {0x9f,0xa8}, {0x9f,0xa9}, {0x9f,0xaa}, {0x9f,0xab}, - {0x9f,0xac}, {0x9f,0xad}, {0x9f,0xae}, {0x9f,0xaf}, {0x9f,0xb0}, {0x9f,0xb1}, {0x9f,0xb2}, {0x9f,0xb3}, {0x9f,0xb4}, {0x9f,0xb5}, - {0x9f,0xb6}, {0x9f,0xb7}, {0x9f,0xb8}, {0x9f,0xb9}, {0x9f,0xba}, {0x9f,0xbb}, {0x9f,0xbc}, {0x9f,0xbd}, {0x9f,0xbe}, {0x9f,0xbf}, - {0x9f,0xc0}, {0x9f,0xc1}, {0x9f,0xc2}, {0x9f,0xc3}, {0x9f,0xc4}, {0x9f,0xc5}, {0x9f,0xc6}, {0x9f,0xc7}, {0x9f,0xc8}, {0x9f,0xc9}, - {0x9f,0xca}, {0xb9,0xb0}, {0x9f,0xcc}, {0x9f,0xcd}, {0x9f,0xce}, {0x9f,0xcf}, {0x9f,0xd0}, {0x9f,0xd1}, {0x9f,0xd2}, {0x9f,0xd3}, - {0x9f,0xd4}, {0x9f,0xd5}, {0x9f,0xd6}, {0x9f,0xd7}, {0x93,0x61}, {0x9f,0xd9}, {0x9f,0xda}, {0x9f,0xdb}, {0x9f,0xdc}, {0x9f,0xdd}, - {0x9f,0xde}, {0x9f,0xdf}, {0x9f,0xe0}, {0x9f,0xe1}, {0x9f,0xe2}, {0x9f,0xe3}, {0x9f,0xe4}, {0x9f,0xe5}, {0x9f,0xe6}, {0x9f,0xe7}, - {0x9f,0xe8}, {0x9f,0xe9}, {0x9f,0xea}, {0x9f,0xeb}, {0x9f,0xec}, {0x9f,0xed}, {0x9f,0xee}, {0x9f,0xef}, {0x9f,0xf0}, {0x9f,0xf1}, - {0x9f,0xf2}, {0x9f,0xf3}, {0x9f,0xf4}, {0x9f,0xf5}, {0x9f,0xf6}, {0x9f,0xf7}, {0x9f,0xf8}, {0x9f,0xf9}, {0x9f,0xfa}, {0x9f,0xfb}, - {0x9f,0xfc}, {0x9f,0xfd}, {0x9f,0xfe}, {0xa0,0x40}, {0xa0,0x41}, {0xa0,0x42}, {0xa0,0x43}, {0xa0,0x44}, {0xa0,0x45}, {0xa0,0x46}, - {0xa0,0x47}, {0xa0,0x48}, {0xa0,0x49}, {0xa0,0x4a}, {0xa0,0x4b}, {0xa0,0x4c}, {0xa0,0x4d}, {0xa0,0x4e}, {0xa0,0x4f}, {0xa0,0x50}, - {0xa0,0x51}, {0xa0,0x52}, {0xa0,0x53}, {0xa0,0x54}, {0xa0,0x55}, {0xa0,0x56}, {0xa0,0x57}, {0xa0,0x58}, {0xa0,0x59}, {0xa0,0x5a}, - {0xa0,0x5b}, {0xa0,0x5c}, {0xa0,0x5d}, {0xa0,0x5e}, {0xa0,0x5f}, {0xa0,0x60}, {0xa0,0x61}, {0xa0,0x62}, {0x8f,0xb6}, {0xa0,0x64}, - {0xa0,0x65}, {0xa0,0x66}, {0xa0,0x67}, {0xa0,0x68}, {0xa0,0x69}, {0xa0,0x6a}, {0xa0,0x6b}, {0xa0,0x6c}, {0xa0,0x6d}, {0xa0,0x6e}, - {0xa0,0x6f}, {0xa0,0x70}, {0xa0,0x71}, {0xa0,0x72}, {0xa0,0x73}, {0xa0,0x74}, {0xa0,0x75}, {0xa0,0x76}, {0xa9,0xf0}, {0xa0,0x78}, - {0xa0,0x79}, {0xa0,0x7a}, {0xa0,0x7b}, {0xa0,0x7c}, {0xa0,0x7d}, {0xa0,0x7e}, {0xa0,0xa1}, {0xa0,0xa2}, {0xa0,0xa3}, {0xa0,0xa4}, - {0xa0,0xa5}, {0xa0,0xa6}, {0xa0,0xa7}, {0xa0,0xa8}, {0xa0,0xa9}, {0xa0,0xaa}, {0xa0,0xab}, {0xa0,0xac}, {0xa0,0xad}, {0xa0,0xae}, - {0xa0,0xaf}, {0xa0,0xb0}, {0xa0,0xb1}, {0xa0,0xb2}, {0xa0,0xb3}, {0xa0,0xb4}, {0xa0,0xb5}, {0xa0,0xb6}, {0xa0,0xb7}, {0xa0,0xb8}, - {0xa0,0xb9}, {0xa0,0xba}, {0xa0,0xbb}, {0xa0,0xbc}, {0xa0,0xbd}, {0xa0,0xbe}, {0xa0,0xbf}, {0xa0,0xc0}, {0xa0,0xc1}, {0xa0,0xc2}, - {0xa0,0xc3}, {0xa0,0xc4}, {0xa0,0xc5}, {0xa0,0xc6}, {0xa0,0xc7}, {0xa0,0xc8}, {0xa0,0xc9}, {0xa0,0xca}, {0xa0,0xcb}, {0xa0,0xcc}, - {0xa0,0xcd}, {0xa0,0xce}, {0xa0,0xcf}, {0xa0,0xd0}, {0xa0,0xd1}, {0xa0,0xd2}, {0xa0,0xd3}, {0xa0,0xd4}, {0x94,0x7a}, {0xa0,0xd6}, - {0xa0,0xd7}, {0xa0,0xd8}, {0xa0,0xd9}, {0xa0,0xda}, {0xa0,0xdb}, {0xa0,0xdc}, {0xa0,0xdd}, {0xa0,0xde}, {0xde,0x72}, {0xa0,0xe0}, - {0xa0,0xe1}, {0xa0,0xe2}, {0xa0,0xe3}, {0x94,0x55}, {0xa0,0xe5}, {0xa0,0xe6}, {0xa0,0xe7}, {0xa0,0xe8}, {0xa0,0xe9}, {0xa0,0xea}, - {0xa0,0xeb}, {0xa0,0xec}, {0xa0,0xed}, {0xa0,0xee}, {0xa0,0xef}, {0xa0,0xf0}, {0xa0,0xf1}, {0xa0,0xf2}, {0xa0,0xf3}, {0xa0,0xf4}, - {0xa0,0xf5}, {0xa0,0xf6}, {0xa0,0xf7}, {0xa0,0xf8}, {0xa0,0xf9}, {0xa0,0xfa}, {0xa0,0xfb}, {0xa0,0xfc}, {0xa0,0xfd}, {0xa0,0xfe}, - {0x81,0x40}, {0x81,0x41}, {0x81,0x42}, {0x81,0x43}, {0x81,0x44}, {0x81,0x45}, {0x81,0x46}, {0x81,0x47}, {0x81,0x48}, {0x81,0x49}, - {0x81,0x4a}, {0x81,0x4b}, {0x81,0x4c}, {0x81,0x4d}, {0x81,0x4e}, {0x81,0x4f}, {0x81,0x50}, {0x81,0x51}, {0x81,0x52}, {0x81,0x53}, - {0x81,0x54}, {0x81,0x55}, {0x81,0x56}, {0x81,0x57}, {0x81,0x58}, {0x81,0x59}, {0x81,0x5a}, {0x81,0x5b}, {0x81,0x5c}, {0x81,0x5d}, - {0x81,0x5e}, {0x81,0x5f}, {0x81,0x60}, {0x81,0x61}, {0x81,0x62}, {0x81,0x63}, {0x81,0x64}, {0x81,0x65}, {0x81,0x66}, {0x81,0x67}, - {0x81,0x68}, {0x81,0x69}, {0x81,0x6a}, {0x81,0x6b}, {0x81,0x6c}, {0x81,0x6d}, {0x81,0x6e}, {0x81,0x6f}, {0x81,0x70}, {0x81,0x71}, - {0x81,0x72}, {0x81,0x73}, {0x81,0x74}, {0x81,0x75}, {0x81,0x76}, {0x81,0x77}, {0x81,0x78}, {0x81,0x79}, {0x81,0x7a}, {0x81,0x7b}, - {0x81,0x7c}, {0x81,0x7d}, {0x81,0x7e}, {0x81,0xa1}, {0x81,0xa2}, {0x81,0xa3}, {0x81,0xa4}, {0x81,0xa5}, {0x81,0xa6}, {0x81,0xa7}, - {0x81,0xa8}, {0x81,0xa9}, {0x81,0xaa}, {0x81,0xab}, {0x81,0xac}, {0x81,0xad}, {0x81,0xae}, {0x81,0xaf}, {0x81,0xb0}, {0x81,0xb1}, - {0x81,0xb2}, {0x81,0xb3}, {0x81,0xb4}, {0x81,0xb5}, {0x81,0xb6}, {0x81,0xb7}, {0x81,0xb8}, {0x81,0xb9}, {0x81,0xba}, {0x81,0xbb}, - {0x81,0xbc}, {0x81,0xbd}, {0x81,0xbe}, {0x81,0xbf}, {0x81,0xc0}, {0x81,0xc1}, {0x81,0xc2}, {0x81,0xc3}, {0x81,0xc4}, {0x81,0xc5}, - {0x81,0xc6}, {0x81,0xc7}, {0x81,0xc8}, {0x81,0xc9}, {0x81,0xca}, {0x81,0xcb}, {0x81,0xcc}, {0x81,0xcd}, {0x81,0xce}, {0x81,0xcf}, - {0x81,0xd0}, {0x81,0xd1}, {0x81,0xd2}, {0x81,0xd3}, {0x81,0xd4}, {0x81,0xd5}, {0x81,0xd6}, {0x81,0xd7}, {0x81,0xd8}, {0x81,0xd9}, - {0x81,0xda}, {0x81,0xdb}, {0x81,0xdc}, {0x81,0xdd}, {0x81,0xde}, {0x81,0xdf}, {0x81,0xe0}, {0x81,0xe1}, {0x81,0xe2}, {0x81,0xe3}, - {0x81,0xe4}, {0x81,0xe5}, {0x81,0xe6}, {0x81,0xe7}, {0x81,0xe8}, {0x81,0xe9}, {0x81,0xea}, {0x81,0xeb}, {0x81,0xec}, {0x81,0xed}, - {0x81,0xee}, {0x81,0xef}, {0x81,0xf0}, {0x81,0xf1}, {0x81,0xf2}, {0x81,0xf3}, {0x81,0xf4}, {0x81,0xf5}, {0x81,0xf6}, {0x81,0xf7}, - {0x81,0xf8}, {0x81,0xf9}, {0x81,0xfa}, {0x81,0xfb}, {0x81,0xfc}, {0x81,0xfd}, {0x81,0xfe}, {0x82,0x40}, {0x82,0x41}, {0x82,0x42}, - {0x82,0x43}, {0x82,0x44}, {0x82,0x45}, {0x82,0x46}, {0x82,0x47}, {0x82,0x48}, {0x82,0x49}, {0x82,0x4a}, {0x82,0x4b}, {0x82,0x4c}, - {0x82,0x4d}, {0x82,0x4e}, {0x82,0x4f}, {0x82,0x50}, {0x82,0x51}, {0x82,0x52}, {0x82,0x53}, {0x82,0x54}, {0x82,0x55}, {0x82,0x56}, - {0x82,0x57}, {0x82,0x58}, {0x82,0x59}, {0x82,0x5a}, {0x82,0x5b}, {0x82,0x5c}, {0x82,0x5d}, {0x82,0x5e}, {0x82,0x5f}, {0x82,0x60}, - {0x82,0x61}, {0x82,0x62}, {0x82,0x63}, {0x82,0x64}, {0x82,0x65}, {0x82,0x66}, {0x82,0x67}, {0x82,0x68}, {0x82,0x69}, {0x82,0x6a}, - {0x82,0x6b}, {0x82,0x6c}, {0x82,0x6d}, {0x82,0x6e}, {0x82,0x6f}, {0x82,0x70}, {0x82,0x71}, {0x82,0x72}, {0x82,0x73}, {0x82,0x74}, - {0x82,0x75}, {0x82,0x76}, {0x82,0x77}, {0x82,0x78}, {0x82,0x79}, {0x82,0x7a}, {0x82,0x7b}, {0x82,0x7c}, {0x82,0x7d}, {0x82,0x7e}, - {0x82,0xa1}, {0x82,0xa2}, {0x82,0xa3}, {0x82,0xa4}, {0x82,0xa5}, {0x82,0xa6}, {0x82,0xa7}, {0x82,0xa8}, {0x82,0xa9}, {0x82,0xaa}, - {0x82,0xab}, {0x82,0xac}, {0x82,0xad}, {0x82,0xae}, {0x82,0xaf}, {0x82,0xb0}, {0x82,0xb1}, {0x82,0xb2}, {0x82,0xb3}, {0x82,0xb4}, - {0x82,0xb5}, {0x82,0xb6}, {0x82,0xb7}, {0x82,0xb8}, {0x82,0xb9}, {0x82,0xba}, {0x82,0xbb}, {0x82,0xbc}, {0x82,0xbd}, {0x82,0xbe}, - {0x82,0xbf}, {0x82,0xc0}, {0x82,0xc1}, {0x82,0xc2}, {0x82,0xc3}, {0x82,0xc4}, {0x82,0xc5}, {0x82,0xc6}, {0x82,0xc7}, {0x82,0xc8}, - {0x82,0xc9}, {0x82,0xca}, {0x82,0xcb}, {0x82,0xcc}, {0x82,0xcd}, {0x82,0xce}, {0x82,0xcf}, {0x82,0xd0}, {0x82,0xd1}, {0x82,0xd2}, - {0x82,0xd3}, {0x82,0xd4}, {0x82,0xd5}, {0x82,0xd6}, {0x82,0xd7}, {0x82,0xd8}, {0x82,0xd9}, {0x82,0xda}, {0x82,0xdb}, {0x82,0xdc}, - {0x82,0xdd}, {0x82,0xde}, {0x82,0xdf}, {0x82,0xe0}, {0x82,0xe1}, {0x82,0xe2}, {0x82,0xe3}, {0x82,0xe4}, {0x82,0xe5}, {0x82,0xe6}, - {0x82,0xe7}, {0x82,0xe8}, {0x82,0xe9}, {0x82,0xea}, {0x82,0xeb}, {0x82,0xec}, {0x82,0xed}, {0x82,0xee}, {0x82,0xef}, {0x82,0xf0}, - {0x82,0xf1}, {0x82,0xf2}, {0x82,0xf3}, {0x82,0xf4}, {0x82,0xf5}, {0x82,0xf6}, {0x82,0xf7}, {0x82,0xf8}, {0x82,0xf9}, {0x82,0xfa}, - {0x82,0xfb}, {0x82,0xfc}, {0x82,0xfd}, {0x82,0xfe}, {0x83,0x40}, {0x83,0x41}, {0x83,0x42}, {0x83,0x43}, {0x83,0x44}, {0x83,0x45}, - {0x83,0x46}, {0x83,0x47}, {0x83,0x48}, {0x83,0x49}, {0x83,0x4a}, {0x83,0x4b}, {0x83,0x4c}, {0x83,0x4d}, {0x83,0x4e}, {0x83,0x4f}, - {0x83,0x50}, {0x83,0x51}, {0x83,0x52}, {0x83,0x53}, {0x83,0x54}, {0x83,0x55}, {0x83,0x56}, {0x83,0x57}, {0x83,0x58}, {0x83,0x59}, - {0x83,0x5a}, {0x83,0x5b}, {0x83,0x5c}, {0x83,0x5d}, {0x83,0x5e}, {0x83,0x5f}, {0x83,0x60}, {0x83,0x61}, {0x83,0x62}, {0x83,0x63}, - {0x83,0x64}, {0x83,0x65}, {0x83,0x66}, {0x83,0x67}, {0x83,0x68}, {0x83,0x69}, {0x83,0x6a}, {0x83,0x6b}, {0x83,0x6c}, {0x83,0x6d}, - {0x83,0x6e}, {0x83,0x6f}, {0x83,0x70}, {0x83,0x71}, {0x83,0x72}, {0x83,0x73}, {0x83,0x74}, {0x83,0x75}, {0x83,0x76}, {0x83,0x77}, - {0x83,0x78}, {0x83,0x79}, {0x83,0x7a}, {0x83,0x7b}, {0x83,0x7c}, {0x83,0x7d}, {0x83,0x7e}, {0x83,0xa1}, {0x83,0xa2}, {0x83,0xa3}, - {0x83,0xa4}, {0x83,0xa5}, {0x83,0xa6}, {0x83,0xa7}, {0x83,0xa8}, {0x83,0xa9}, {0x83,0xaa}, {0x83,0xab}, {0x83,0xac}, {0x83,0xad}, - {0x83,0xae}, {0x83,0xaf}, {0x83,0xb0}, {0x83,0xb1}, {0x83,0xb2}, {0x83,0xb3}, {0x83,0xb4}, {0x83,0xb5}, {0x83,0xb6}, {0x83,0xb7}, - {0x83,0xb8}, {0x83,0xb9}, {0x83,0xba}, {0x83,0xbb}, {0x83,0xbc}, {0x83,0xbd}, {0x83,0xbe}, {0x83,0xbf}, {0x83,0xc0}, {0x83,0xc1}, - {0x83,0xc2}, {0x83,0xc3}, {0x83,0xc4}, {0x83,0xc5}, {0x83,0xc6}, {0x83,0xc7}, {0x83,0xc8}, {0x83,0xc9}, {0x83,0xca}, {0x83,0xcb}, - {0x83,0xcc}, {0x83,0xcd}, {0x83,0xce}, {0x83,0xcf}, {0x83,0xd0}, {0x83,0xd1}, {0x83,0xd2}, {0x83,0xd3}, {0x83,0xd4}, {0x83,0xd5}, - {0x83,0xd6}, {0x83,0xd7}, {0x83,0xd8}, {0x83,0xd9}, {0x83,0xda}, {0x83,0xdb}, {0x83,0xdc}, {0x83,0xdd}, {0x83,0xde}, {0x83,0xdf}, - {0x83,0xe0}, {0x83,0xe1}, {0x83,0xe2}, {0x83,0xe3}, {0x83,0xe4}, {0x83,0xe5}, {0x83,0xe6}, {0x83,0xe7}, {0x83,0xe8}, {0x83,0xe9}, - {0x83,0xea}, {0x83,0xeb}, {0x83,0xec}, {0x83,0xed}, {0x83,0xee}, {0x83,0xef}, {0x83,0xf0}, {0x83,0xf1}, {0x83,0xf2}, {0x83,0xf3}, - {0x83,0xf4}, {0x83,0xf5}, {0x83,0xf6}, {0x83,0xf7}, {0x83,0xf8}, {0x83,0xf9}, {0x83,0xfa}, {0x83,0xfb}, {0x83,0xfc}, {0x83,0xfd}, - {0x83,0xfe}, {0x84,0x40}, {0x84,0x41}, {0x84,0x42}, {0x84,0x43}, {0x84,0x44}, {0x84,0x45}, {0x84,0x46}, {0x84,0x47}, {0x84,0x48}, - {0x84,0x49}, {0x84,0x4a}, {0x84,0x4b}, {0x84,0x4c}, {0x84,0x4d}, {0x84,0x4e}, {0x84,0x4f}, {0x84,0x50}, {0x84,0x51}, {0x84,0x52}, - {0x84,0x53}, {0x84,0x54}, {0x84,0x55}, {0x84,0x56}, {0x84,0x57}, {0x84,0x58}, {0x84,0x59}, {0x84,0x5a}, {0x84,0x5b}, {0x84,0x5c}, - {0x84,0x5d}, {0x84,0x5e}, {0x84,0x5f}, {0x84,0x60}, {0x84,0x61}, {0x84,0x62}, {0x84,0x63}, {0x84,0x64}, {0x84,0x65}, {0x84,0x66}, - {0x84,0x67}, {0x84,0x68}, {0x84,0x69}, {0x84,0x6a}, {0x84,0x6b}, {0x84,0x6c}, {0x84,0x6d}, {0x84,0x6e}, {0x84,0x6f}, {0x84,0x70}, - {0x84,0x71}, {0x84,0x72}, {0x84,0x73}, {0x84,0x74}, {0x84,0x75}, {0x84,0x76}, {0x84,0x77}, {0x84,0x78}, {0x84,0x79}, {0x84,0x7a}, - {0x84,0x7b}, {0x84,0x7c}, {0x84,0x7d}, {0x84,0x7e}, {0x84,0xa1}, {0x84,0xa2}, {0x84,0xa3}, {0x84,0xa4}, {0x84,0xa5}, {0x84,0xa6}, - {0x84,0xa7}, {0x84,0xa8}, {0x84,0xa9}, {0x84,0xaa}, {0x84,0xab}, {0x84,0xac}, {0x84,0xad}, {0x84,0xae}, {0x84,0xaf}, {0x84,0xb0}, - {0x84,0xb1}, {0x84,0xb2}, {0x84,0xb3}, {0x84,0xb4}, {0x84,0xb5}, {0x84,0xb6}, {0x84,0xb7}, {0x84,0xb8}, {0x84,0xb9}, {0x84,0xba}, - {0x84,0xbb}, {0x84,0xbc}, {0x84,0xbd}, {0x84,0xbe}, {0x84,0xbf}, {0x84,0xc0}, {0x84,0xc1}, {0x84,0xc2}, {0x84,0xc3}, {0x84,0xc4}, - {0x84,0xc5}, {0x84,0xc6}, {0x84,0xc7}, {0x84,0xc8}, {0x84,0xc9}, {0x84,0xca}, {0x84,0xcb}, {0x84,0xcc}, {0x84,0xcd}, {0x84,0xce}, - {0x84,0xcf}, {0x84,0xd0}, {0x84,0xd1}, {0x84,0xd2}, {0x84,0xd3}, {0x84,0xd4}, {0x84,0xd5}, {0x84,0xd6}, {0x84,0xd7}, {0x84,0xd8}, - {0x84,0xd9}, {0x84,0xda}, {0x84,0xdb}, {0x84,0xdc}, {0x84,0xdd}, {0x84,0xde}, {0x84,0xdf}, {0x84,0xe0}, {0x84,0xe1}, {0x84,0xe2}, - {0x84,0xe3}, {0x84,0xe4}, {0x84,0xe5}, {0x84,0xe6}, {0x84,0xe7}, {0x84,0xe8}, {0x84,0xe9}, {0x84,0xea}, {0x84,0xeb}, {0x84,0xec}, - {0x84,0xed}, {0x84,0xee}, {0x84,0xef}, {0x84,0xf0}, {0x84,0xf1}, {0x84,0xf2}, {0x84,0xf3}, {0x84,0xf4}, {0x84,0xf5}, {0x84,0xf6}, - {0x84,0xf7}, {0x84,0xf8}, {0x84,0xf9}, {0x84,0xfa}, {0x84,0xfb}, {0x84,0xfc}, {0x84,0xfd}, {0x84,0xfe}, {0x85,0x40}, {0x85,0x41}, - {0x85,0x42}, {0x85,0x43}, {0x85,0x44}, {0x85,0x45}, {0x85,0x46}, {0x85,0x47}, {0x85,0x48}, {0x85,0x49}, {0x85,0x4a}, {0x85,0x4b}, - {0x85,0x4c}, {0x85,0x4d}, {0x85,0x4e}, {0x85,0x4f}, {0x85,0x50}, {0x85,0x51}, {0x85,0x52}, {0x85,0x53}, {0x85,0x54}, {0x85,0x55}, - {0x85,0x56}, {0x85,0x57}, {0x85,0x58}, {0x85,0x59}, {0x85,0x5a}, {0x85,0x5b}, {0x85,0x5c}, {0x85,0x5d}, {0x85,0x5e}, {0x85,0x5f}, - {0x85,0x60}, {0x85,0x61}, {0x85,0x62}, {0x85,0x63}, {0x85,0x64}, {0x85,0x65}, {0x85,0x66}, {0x85,0x67}, {0x85,0x68}, {0x85,0x69}, - {0x85,0x6a}, {0x85,0x6b}, {0x85,0x6c}, {0x85,0x6d}, {0x85,0x6e}, {0x85,0x6f}, {0x85,0x70}, {0x85,0x71}, {0x85,0x72}, {0x85,0x73}, - {0x85,0x74}, {0x85,0x75}, {0x85,0x76}, {0x85,0x77}, {0x85,0x78}, {0x85,0x79}, {0x85,0x7a}, {0x85,0x7b}, {0x85,0x7c}, {0x85,0x7d}, - {0x85,0x7e}, {0x85,0xa1}, {0x85,0xa2}, {0x85,0xa3}, {0x85,0xa4}, {0x85,0xa5}, {0x85,0xa6}, {0x85,0xa7}, {0x85,0xa8}, {0x85,0xa9}, - {0x85,0xaa}, {0x85,0xab}, {0x85,0xac}, {0x85,0xad}, {0x85,0xae}, {0x85,0xaf}, {0x85,0xb0}, {0x85,0xb1}, {0x85,0xb2}, {0x85,0xb3}, - {0x85,0xb4}, {0x85,0xb5}, {0x85,0xb6}, {0x85,0xb7}, {0x85,0xb8}, {0x85,0xb9}, {0x85,0xba}, {0x85,0xbb}, {0x85,0xbc}, {0x85,0xbd}, - {0x85,0xbe}, {0x85,0xbf}, {0x85,0xc0}, {0x85,0xc1}, {0x85,0xc2}, {0x85,0xc3}, {0x85,0xc4}, {0x85,0xc5}, {0x85,0xc6}, {0x85,0xc7}, - {0x85,0xc8}, {0x85,0xc9}, {0x85,0xca}, {0x85,0xcb}, {0x85,0xcc}, {0x85,0xcd}, {0x85,0xce}, {0x85,0xcf}, {0x85,0xd0}, {0x85,0xd1}, - {0x85,0xd2}, {0x85,0xd3}, {0x85,0xd4}, {0x85,0xd5}, {0x85,0xd6}, {0x85,0xd7}, {0x85,0xd8}, {0x85,0xd9}, {0x85,0xda}, {0x85,0xdb}, - {0x85,0xdc}, {0x85,0xdd}, {0x85,0xde}, {0x85,0xdf}, {0x85,0xe0}, {0x85,0xe1}, {0x85,0xe2}, {0x85,0xe3}, {0x85,0xe4}, {0x85,0xe5}, - {0x85,0xe6}, {0x85,0xe7}, {0x85,0xe8}, {0x85,0xe9}, {0x85,0xea}, {0x85,0xeb}, {0x85,0xec}, {0x85,0xed}, {0x85,0xee}, {0x85,0xef}, - {0x85,0xf0}, {0x85,0xf1}, {0x85,0xf2}, {0x85,0xf3}, {0x85,0xf4}, {0x85,0xf5}, {0x85,0xf6}, {0x85,0xf7}, {0x85,0xf8}, {0x85,0xf9}, - {0x85,0xfa}, {0x85,0xfb}, {0x85,0xfc}, {0x85,0xfd}, {0x85,0xfe}, {0x86,0x40}, {0x86,0x41}, {0x86,0x42}, {0x86,0x43}, {0x86,0x44}, - {0x86,0x45}, {0x86,0x46}, {0x86,0x47}, {0x86,0x48}, {0x86,0x49}, {0x86,0x4a}, {0x86,0x4b}, {0x86,0x4c}, {0x86,0x4d}, {0x86,0x4e}, - {0x86,0x4f}, {0x86,0x50}, {0x86,0x51}, {0x86,0x52}, {0x86,0x53}, {0x86,0x54}, {0x86,0x55}, {0x86,0x56}, {0x86,0x57}, {0x86,0x58}, - {0x86,0x59}, {0x86,0x5a}, {0x86,0x5b}, {0x86,0x5c}, {0x86,0x5d}, {0x86,0x5e}, {0x86,0x5f}, {0x86,0x60}, {0x86,0x61}, {0x86,0x62}, - {0x86,0x63}, {0x86,0x64}, {0x86,0x65}, {0x86,0x66}, {0x86,0x67}, {0x86,0x68}, {0x86,0x69}, {0x86,0x6a}, {0x86,0x6b}, {0x86,0x6c}, - {0x86,0x6d}, {0x86,0x6e}, {0x86,0x6f}, {0x86,0x70}, {0x86,0x71}, {0x86,0x72}, {0x86,0x73}, {0x86,0x74}, {0x86,0x75}, {0x86,0x76}, - {0x86,0x77}, {0x86,0x78}, {0x86,0x79}, {0x86,0x7a}, {0x86,0x7b}, {0x86,0x7c}, {0x86,0x7d}, {0x86,0x7e}, {0x86,0xa1}, {0x86,0xa2}, - {0x86,0xa3}, {0x86,0xa4}, {0x86,0xa5}, {0x86,0xa6}, {0x86,0xa7}, {0x86,0xa8}, {0x86,0xa9}, {0x86,0xaa}, {0x86,0xab}, {0x86,0xac}, - {0x86,0xad}, {0x86,0xae}, {0x86,0xaf}, {0x86,0xb0}, {0x86,0xb1}, {0x86,0xb2}, {0x86,0xb3}, {0x86,0xb4}, {0x86,0xb5}, {0x86,0xb6}, - {0x86,0xb7}, {0x86,0xb8}, {0x86,0xb9}, {0x86,0xba}, {0x86,0xbb}, {0x86,0xbc}, {0x86,0xbd}, {0x86,0xbe}, {0x86,0xbf}, {0x86,0xc0}, - {0x86,0xc1}, {0x86,0xc2}, {0x86,0xc3}, {0x86,0xc4}, {0x86,0xc5}, {0x86,0xc6}, {0x86,0xc7}, {0x86,0xc8}, {0x86,0xc9}, {0x86,0xca}, - {0x86,0xcb}, {0x86,0xcc}, {0x86,0xcd}, {0x86,0xce}, {0x86,0xcf}, {0x86,0xd0}, {0x86,0xd1}, {0x86,0xd2}, {0x86,0xd3}, {0x86,0xd4}, - {0x86,0xd5}, {0x86,0xd6}, {0x86,0xd7}, {0x86,0xd8}, {0x86,0xd9}, {0x86,0xda}, {0x86,0xdb}, {0x86,0xdc}, {0x86,0xdd}, {0x86,0xde}, - {0x86,0xdf}, {0x86,0xe0}, {0x86,0xe1}, {0x86,0xe2}, {0x86,0xe3}, {0x86,0xe4}, {0x86,0xe5}, {0x86,0xe6}, {0x86,0xe7}, {0x86,0xe8}, - {0x86,0xe9}, {0x86,0xea}, {0x86,0xeb}, {0x86,0xec}, {0x86,0xed}, {0x86,0xee}, {0x86,0xef}, {0x86,0xf0}, {0x86,0xf1}, {0x86,0xf2}, - {0x86,0xf3}, {0x86,0xf4}, {0x86,0xf5}, {0x86,0xf6}, {0x86,0xf7}, {0x86,0xf8}, {0x86,0xf9}, {0x86,0xfa}, {0x86,0xfb}, {0x86,0xfc}, - {0x86,0xfd}, {0x86,0xfe}, {0x87,0x40}, {0x87,0x41}, {0x87,0x42}, {0x87,0x43}, {0x87,0x44}, {0x87,0x45}, {0x87,0x46}, {0x87,0x47}, - {0x87,0x48}, {0x87,0x49}, {0x87,0x4a}, {0x87,0x4b}, {0x87,0x4c}, {0x87,0x4d}, {0x87,0x4e}, {0x87,0x4f}, {0x87,0x50}, {0x87,0x51}, - {0x87,0x52}, {0x87,0x53}, {0x87,0x54}, {0x87,0x55}, {0x87,0x56}, {0x87,0x57}, {0x87,0x58}, {0x87,0x59}, {0x87,0x5a}, {0x87,0x5b}, - {0x87,0x5c}, {0x87,0x5d}, {0x87,0x5e}, {0x87,0x5f}, {0x87,0x60}, {0x87,0x61}, {0x87,0x62}, {0x87,0x63}, {0x87,0x64}, {0x87,0x65}, - {0x87,0x66}, {0x87,0x67}, {0x87,0x68}, {0x87,0x69}, {0x87,0x6a}, {0x87,0x6b}, {0x87,0x6c}, {0x87,0x6d}, {0x87,0x6e}, {0x87,0x6f}, - {0x87,0x70}, {0x87,0x71}, {0x87,0x72}, {0x87,0x73}, {0x87,0x74}, {0x87,0x75}, {0x87,0x76}, {0x87,0x77}, {0x87,0x78}, {0x87,0x79}, - {0x87,0x7a}, {0x87,0x7b}, {0x87,0x7c}, {0x87,0x7d}, {0x87,0x7e}, {0x87,0xa1}, {0x87,0xa2}, {0x87,0xa3}, {0x87,0xa4}, {0x87,0xa5}, - {0x87,0xa6}, {0x87,0xa7}, {0x87,0xa8}, {0x87,0xa9}, {0x87,0xaa}, {0x87,0xab}, {0x87,0xac}, {0x87,0xad}, {0x87,0xae}, {0x87,0xaf}, - {0x87,0xb0}, {0x87,0xb1}, {0x87,0xb2}, {0x87,0xb3}, {0x87,0xb4}, {0x87,0xb5}, {0x87,0xb6}, {0x87,0xb7}, {0x87,0xb8}, {0x87,0xb9}, - {0x87,0xba}, {0x87,0xbb}, {0x87,0xbc}, {0x87,0xbd}, {0x87,0xbe}, {0x87,0xbf}, {0x87,0xc0}, {0x87,0xc1}, {0x87,0xc2}, {0x87,0xc3}, - {0x87,0xc4}, {0x87,0xc5}, {0x87,0xc6}, {0x87,0xc7}, {0x87,0xc8}, {0x87,0xc9}, {0x87,0xca}, {0x87,0xcb}, {0x87,0xcc}, {0x87,0xcd}, - {0x87,0xce}, {0x87,0xcf}, {0x87,0xd0}, {0x87,0xd1}, {0x87,0xd2}, {0x87,0xd3}, {0x87,0xd4}, {0x87,0xd5}, {0x87,0xd6}, {0x87,0xd7}, - {0x87,0xd8}, {0x87,0xd9}, {0x87,0xda}, {0x87,0xdb}, {0x87,0xdc}, {0x87,0xdd}, {0x87,0xde}, {0x87,0xdf}, {0x87,0xe0}, {0x87,0xe1}, - {0x87,0xe2}, {0x87,0xe3}, {0x87,0xe4}, {0x87,0xe5}, {0x87,0xe6}, {0x87,0xe7}, {0x87,0xe8}, {0x87,0xe9}, {0x87,0xea}, {0x87,0xeb}, - {0x87,0xec}, {0x87,0xed}, {0x87,0xee}, {0x87,0xef}, {0x87,0xf0}, {0x87,0xf1}, {0x87,0xf2}, {0x87,0xf3}, {0x87,0xf4}, {0x87,0xf5}, - {0x87,0xf6}, {0x87,0xf7}, {0x87,0xf8}, {0x87,0xf9}, {0x87,0xfa}, {0x87,0xfb}, {0x87,0xfc}, {0x87,0xfd}, {0x87,0xfe}, {0x88,0x40}, - {0x88,0x41}, {0x88,0x42}, {0x88,0x43}, {0x88,0x44}, {0x88,0x45}, {0x88,0x46}, {0x88,0x47}, {0x88,0x48}, {0x88,0x49}, {0x88,0x4a}, - {0x88,0x4b}, {0x88,0x4c}, {0x88,0x4d}, {0x88,0x4e}, {0x88,0x4f}, {0x88,0x50}, {0x88,0x51}, {0x88,0x52}, {0x88,0x53}, {0x88,0x54}, - {0x88,0x55}, {0x88,0x56}, {0x88,0x57}, {0x88,0x58}, {0x88,0x59}, {0x88,0x5a}, {0x88,0x5b}, {0x88,0x5c}, {0x88,0x5d}, {0x88,0x5e}, - {0x88,0x5f}, {0x88,0x60}, {0x88,0x61}, {0x88,0x62}, {0x88,0x63}, {0x88,0x64}, {0x88,0x65}, {0x88,0x66}, {0x88,0x67}, {0x88,0x68}, - {0x88,0x69}, {0x88,0x6a}, {0x88,0x6b}, {0x88,0x6c}, {0x88,0x6d}, {0x88,0x6e}, {0x88,0x6f}, {0x88,0x70}, {0x88,0x71}, {0x88,0x72}, - {0x88,0x73}, {0x88,0x74}, {0x88,0x75}, {0x88,0x76}, {0x88,0x77}, {0x88,0x78}, {0x88,0x79}, {0x88,0x7a}, {0x88,0x7b}, {0x88,0x7c}, - {0x88,0x7d}, {0x88,0x7e}, {0x88,0xa1}, {0x88,0xa2}, {0x88,0xa3}, {0x88,0xa4}, {0x88,0xa5}, {0x88,0xa6}, {0x88,0xa7}, {0x88,0xa8}, - {0x88,0xa9}, {0x88,0xaa}, {0x88,0xab}, {0x88,0xac}, {0x88,0xad}, {0x88,0xae}, {0x88,0xaf}, {0x88,0xb0}, {0x88,0xb1}, {0x88,0xb2}, - {0x88,0xb3}, {0x88,0xb4}, {0x88,0xb5}, {0x88,0xb6}, {0x88,0xb7}, {0x88,0xb8}, {0x88,0xb9}, {0x88,0xba}, {0x88,0xbb}, {0x88,0xbc}, - {0x88,0xbd}, {0x88,0xbe}, {0x88,0xbf}, {0x88,0xc0}, {0x88,0xc1}, {0x88,0xc2}, {0x88,0xc3}, {0x88,0xc4}, {0x88,0xc5}, {0x88,0xc6}, - {0x88,0xc7}, {0x88,0xc8}, {0x88,0xc9}, {0x88,0xca}, {0x88,0xcb}, {0x88,0xcc}, {0x88,0xcd}, {0x88,0xce}, {0x88,0xcf}, {0x88,0xd0}, - {0x88,0xd1}, {0x88,0xd2}, {0x88,0xd3}, {0x88,0xd4}, {0x88,0xd5}, {0x88,0xd6}, {0x88,0xd7}, {0x88,0xd8}, {0x88,0xd9}, {0x88,0xda}, - {0x88,0xdb}, {0x88,0xdc}, {0x88,0xdd}, {0x88,0xde}, {0x88,0xdf}, {0x88,0xe0}, {0x88,0xe1}, {0x88,0xe2}, {0x88,0xe3}, {0x88,0xe4}, - {0x88,0xe5}, {0x88,0xe6}, {0x88,0xe7}, {0x88,0xe8}, {0x88,0xe9}, {0x88,0xea}, {0x88,0xeb}, {0x88,0xec}, {0x88,0xed}, {0x88,0xee}, - {0x88,0xef}, {0x88,0xf0}, {0x88,0xf1}, {0x88,0xf2}, {0x88,0xf3}, {0x88,0xf4}, {0x88,0xf5}, {0x88,0xf6}, {0x88,0xf7}, {0x88,0xf8}, - {0x88,0xf9}, {0x88,0xfa}, {0x88,0xfb}, {0x88,0xfc}, {0x88,0xfd}, {0x88,0xfe}, {0x89,0x40}, {0x89,0x41}, {0x89,0x42}, {0x89,0x43}, - {0x89,0x44}, {0x89,0x45}, {0x89,0x46}, {0x89,0x47}, {0x89,0x48}, {0x89,0x49}, {0x89,0x4a}, {0x89,0x4b}, {0x89,0x4c}, {0x89,0x4d}, - {0x89,0x4e}, {0x89,0x4f}, {0x89,0x50}, {0x89,0x51}, {0x89,0x52}, {0x89,0x53}, {0x89,0x54}, {0x89,0x55}, {0x89,0x56}, {0x89,0x57}, - {0x89,0x58}, {0x89,0x59}, {0x89,0x5a}, {0x89,0x5b}, {0x89,0x5c}, {0x89,0x5d}, {0x89,0x5e}, {0x89,0x5f}, {0x89,0x60}, {0x89,0x61}, - {0x89,0x62}, {0x89,0x63}, {0x89,0x64}, {0x89,0x65}, {0x89,0x66}, {0x89,0x67}, {0x89,0x68}, {0x89,0x69}, {0x89,0x6a}, {0x89,0x6b}, - {0x89,0x6c}, {0x89,0x6d}, {0x89,0x6e}, {0x89,0x6f}, {0x89,0x70}, {0x89,0x71}, {0x89,0x72}, {0x89,0x73}, {0x89,0x74}, {0x89,0x75}, - {0x89,0x76}, {0x89,0x77}, {0x89,0x78}, {0x89,0x79}, {0x89,0x7a}, {0x89,0x7b}, {0x89,0x7c}, {0x89,0x7d}, {0x89,0x7e}, {0x89,0xa1}, - {0x89,0xa2}, {0x89,0xa3}, {0x89,0xa4}, {0x89,0xa5}, {0x89,0xa6}, {0x89,0xa7}, {0x89,0xa8}, {0x89,0xa9}, {0x89,0xaa}, {0x89,0xab}, - {0x89,0xac}, {0x89,0xad}, {0x89,0xae}, {0x89,0xaf}, {0x89,0xb0}, {0x89,0xb1}, {0x89,0xb2}, {0x89,0xb3}, {0x89,0xb4}, {0x89,0xb5}, - {0x89,0xb6}, {0x89,0xb7}, {0x89,0xb8}, {0x89,0xb9}, {0x89,0xba}, {0x89,0xbb}, {0x89,0xbc}, {0x89,0xbd}, {0x89,0xbe}, {0x89,0xbf}, - {0x89,0xc0}, {0x89,0xc1}, {0x89,0xc2}, {0x89,0xc3}, {0x89,0xc4}, {0x89,0xc5}, {0x89,0xc6}, {0x89,0xc7}, {0x89,0xc8}, {0x89,0xc9}, - {0x89,0xca}, {0x89,0xcb}, {0x89,0xcc}, {0x89,0xcd}, {0x89,0xce}, {0x89,0xcf}, {0x89,0xd0}, {0x89,0xd1}, {0x89,0xd2}, {0x89,0xd3}, - {0x89,0xd4}, {0x89,0xd5}, {0x89,0xd6}, {0x89,0xd7}, {0x89,0xd8}, {0x89,0xd9}, {0x89,0xda}, {0x89,0xdb}, {0x89,0xdc}, {0x89,0xdd}, - {0x89,0xde}, {0x89,0xdf}, {0x89,0xe0}, {0x89,0xe1}, {0x89,0xe2}, {0x89,0xe3}, {0x89,0xe4}, {0x89,0xe5}, {0x89,0xe6}, {0x89,0xe7}, - {0x89,0xe8}, {0x89,0xe9}, {0x89,0xea}, {0x89,0xeb}, {0x89,0xec}, {0x89,0xed}, {0x89,0xee}, {0x89,0xef}, {0x89,0xf0}, {0x89,0xf1}, - {0x89,0xf2}, {0x89,0xf3}, {0x89,0xf4}, {0x89,0xf5}, {0x89,0xf6}, {0x89,0xf7}, {0x89,0xf8}, {0x89,0xf9}, {0x89,0xfa}, {0x89,0xfb}, - {0x89,0xfc}, {0x89,0xfd}, {0x89,0xfe}, {0x8a,0x40}, {0x8a,0x41}, {0x8a,0x42}, {0x8a,0x43}, {0x8a,0x44}, {0x8a,0x45}, {0x8a,0x46}, - {0x8a,0x47}, {0x8a,0x48}, {0x8a,0x49}, {0x8a,0x4a}, {0x8a,0x4b}, {0x8a,0x4c}, {0x8a,0x4d}, {0x8a,0x4e}, {0x8a,0x4f}, {0x8a,0x50}, - {0x8a,0x51}, {0x8a,0x52}, {0x8a,0x53}, {0x8a,0x54}, {0x8a,0x55}, {0x8a,0x56}, {0x8a,0x57}, {0x8a,0x58}, {0x8a,0x59}, {0x8a,0x5a}, - {0x8a,0x5b}, {0x8a,0x5c}, {0x8a,0x5d}, {0x8a,0x5e}, {0x8a,0x5f}, {0x8a,0x60}, {0x8a,0x61}, {0x8a,0x62}, {0x8a,0x63}, {0x8a,0x64}, - {0x8a,0x65}, {0x8a,0x66}, {0x8a,0x67}, {0x8a,0x68}, {0x8a,0x69}, {0x8a,0x6a}, {0x8a,0x6b}, {0x8a,0x6c}, {0x8a,0x6d}, {0x8a,0x6e}, - {0x8a,0x6f}, {0x8a,0x70}, {0x8a,0x71}, {0x8a,0x72}, {0x8a,0x73}, {0x8a,0x74}, {0x8a,0x75}, {0x8a,0x76}, {0x8a,0x77}, {0x8a,0x78}, - {0x8a,0x79}, {0x8a,0x7a}, {0x8a,0x7b}, {0x8a,0x7c}, {0x8a,0x7d}, {0x8a,0x7e}, {0x8a,0xa1}, {0x8a,0xa2}, {0x8a,0xa3}, {0x8a,0xa4}, - {0x8a,0xa5}, {0x8a,0xa6}, {0x8a,0xa7}, {0x8a,0xa8}, {0x8a,0xa9}, {0x8a,0xaa}, {0x8a,0xab}, {0x8a,0xac}, {0x8a,0xad}, {0x8a,0xae}, - {0x8a,0xaf}, {0x8a,0xb0}, {0x8a,0xb1}, {0x8a,0xb2}, {0x8a,0xb3}, {0x8a,0xb4}, {0x8a,0xb5}, {0x8a,0xb6}, {0x8a,0xb7}, {0x8a,0xb8}, - {0x8a,0xb9}, {0x8a,0xba}, {0x8a,0xbb}, {0x8a,0xbc}, {0x8a,0xbd}, {0x8a,0xbe}, {0x8a,0xbf}, {0x8a,0xc0}, {0x8a,0xc1}, {0x8a,0xc2}, - {0x8a,0xc3}, {0x8a,0xc4}, {0x8a,0xc5}, {0x8a,0xc6}, {0x8a,0xc7}, {0x8a,0xc8}, {0x8a,0xc9}, {0x8a,0xca}, {0x8a,0xcb}, {0x8a,0xcc}, - {0x8a,0xcd}, {0x8a,0xce}, {0x8a,0xcf}, {0x8a,0xd0}, {0x8a,0xd1}, {0x8a,0xd2}, {0x8a,0xd3}, {0x8a,0xd4}, {0x8a,0xd5}, {0x8a,0xd6}, - {0x8a,0xd7}, {0x8a,0xd8}, {0x8a,0xd9}, {0x8a,0xda}, {0x8a,0xdb}, {0x8a,0xdc}, {0x8a,0xdd}, {0x8a,0xde}, {0x8a,0xdf}, {0x8a,0xe0}, - {0x8a,0xe1}, {0x8a,0xe2}, {0x8a,0xe3}, {0x8a,0xe4}, {0x8a,0xe5}, {0x8a,0xe6}, {0x8a,0xe7}, {0x8a,0xe8}, {0x8a,0xe9}, {0x8a,0xea}, - {0x8a,0xeb}, {0x8a,0xec}, {0x8a,0xed}, {0x8a,0xee}, {0x8a,0xef}, {0x8a,0xf0}, {0x8a,0xf1}, {0x8a,0xf2}, {0x8a,0xf3}, {0x8a,0xf4}, - {0x8a,0xf5}, {0x8a,0xf6}, {0x8a,0xf7}, {0x8a,0xf8}, {0x8a,0xf9}, {0x8a,0xfa}, {0x8a,0xfb}, {0x8a,0xfc}, {0x8a,0xfd}, {0x8a,0xfe}, - {0x8b,0x40}, {0x8b,0x41}, {0x8b,0x42}, {0x8b,0x43}, {0x8b,0x44}, {0x8b,0x45}, {0x8b,0x46}, {0x8b,0x47}, {0x8b,0x48}, {0x8b,0x49}, - {0x8b,0x4a}, {0x8b,0x4b}, {0x8b,0x4c}, {0x8b,0x4d}, {0x8b,0x4e}, {0x8b,0x4f}, {0x8b,0x50}, {0x8b,0x51}, {0x8b,0x52}, {0x8b,0x53}, - {0x8b,0x54}, {0x8b,0x55}, {0x8b,0x56}, {0x8b,0x57}, {0x8b,0x58}, {0x8b,0x59}, {0x8b,0x5a}, {0x8b,0x5b}, {0x8b,0x5c}, {0x8b,0x5d}, - {0x8b,0x5e}, {0x8b,0x5f}, {0x8b,0x60}, {0x8b,0x61}, {0x8b,0x62}, {0x8b,0x63}, {0x8b,0x64}, {0x8b,0x65}, {0x8b,0x66}, {0x8b,0x67}, - {0x8b,0x68}, {0x8b,0x69}, {0x8b,0x6a}, {0x8b,0x6b}, {0x8b,0x6c}, {0x8b,0x6d}, {0x8b,0x6e}, {0x8b,0x6f}, {0x8b,0x70}, {0x8b,0x71}, - {0x8b,0x72}, {0x8b,0x73}, {0x8b,0x74}, {0x8b,0x75}, {0x8b,0x76}, {0x8b,0x77}, {0x8b,0x78}, {0x8b,0x79}, {0x8b,0x7a}, {0x8b,0x7b}, - {0x8b,0x7c}, {0x8b,0x7d}, {0x8b,0x7e}, {0x8b,0xa1}, {0x8b,0xa2}, {0x8b,0xa3}, {0x8b,0xa4}, {0x8b,0xa5}, {0x8b,0xa6}, {0x8b,0xa7}, - {0x8b,0xa8}, {0x8b,0xa9}, {0x8b,0xaa}, {0x8b,0xab}, {0x8b,0xac}, {0x8b,0xad}, {0x8b,0xae}, {0x8b,0xaf}, {0x8b,0xb0}, {0x8b,0xb1}, - {0x8b,0xb2}, {0x8b,0xb3}, {0x8b,0xb4}, {0x8b,0xb5}, {0x8b,0xb6}, {0x8b,0xb7}, {0x8b,0xb8}, {0x8b,0xb9}, {0x8b,0xba}, {0x8b,0xbb}, - {0x8b,0xbc}, {0x8b,0xbd}, {0x8b,0xbe}, {0x8b,0xbf}, {0x8b,0xc0}, {0x8b,0xc1}, {0x8b,0xc2}, {0x8b,0xc3}, {0x8b,0xc4}, {0x8b,0xc5}, - {0x8b,0xc6}, {0x8b,0xc7}, {0x8b,0xc8}, {0x8b,0xc9}, {0x8b,0xca}, {0x8b,0xcb}, {0x8b,0xcc}, {0x8b,0xcd}, {0x8b,0xce}, {0x8b,0xcf}, - {0x8b,0xd0}, {0x8b,0xd1}, {0x8b,0xd2}, {0x8b,0xd3}, {0x8b,0xd4}, {0x8b,0xd5}, {0x8b,0xd6}, {0x8b,0xd7}, {0x8b,0xd8}, {0x8b,0xd9}, - {0x8b,0xda}, {0x8b,0xdb}, {0x8b,0xdc}, {0x8b,0xdd}, {0x8b,0xde}, {0x8b,0xdf}, {0x8b,0xe0}, {0x8b,0xe1}, {0x8b,0xe2}, {0x8b,0xe3}, - {0x8b,0xe4}, {0x8b,0xe5}, {0x8b,0xe6}, {0x8b,0xe7}, {0x8b,0xe8}, {0x8b,0xe9}, {0x8b,0xea}, {0x8b,0xeb}, {0x8b,0xec}, {0x8b,0xed}, - {0x8b,0xee}, {0x8b,0xef}, {0x8b,0xf0}, {0x8b,0xf1}, {0x8b,0xf2}, {0x8b,0xf3}, {0x8b,0xf4}, {0x8b,0xf5}, {0x8b,0xf6}, {0x8b,0xf7}, - {0x8b,0xf8}, {0x8b,0xf9}, {0x8b,0xfa}, {0x8b,0xfb}, {0x8b,0xfc}, {0x8b,0xfd}, {0x8b,0xfe}, {0x8c,0x40}, {0x8c,0x41}, {0x8c,0x42}, - {0x8c,0x43}, {0x8c,0x44}, {0x8c,0x45}, {0x8c,0x46}, {0x8c,0x47}, {0x8c,0x48}, {0x8c,0x49}, {0x8c,0x4a}, {0x8c,0x4b}, {0x8c,0x4c}, - {0x8c,0x4d}, {0x8c,0x4e}, {0x8c,0x4f}, {0x8c,0x50}, {0x8c,0x51}, {0x8c,0x52}, {0x8c,0x53}, {0x8c,0x54}, {0x8c,0x55}, {0x8c,0x56}, - {0x8c,0x57}, {0x8c,0x58}, {0x8c,0x59}, {0x8c,0x5a}, {0x8c,0x5b}, {0x8c,0x5c}, {0x8c,0x5d}, {0x8c,0x5e}, {0x8c,0x5f}, {0x8c,0x60}, - {0x8c,0x61}, {0x8c,0x62}, {0x8c,0x63}, {0x8c,0x64}, {0x8c,0x65}, {0x8c,0x66}, {0x8c,0x67}, {0x8c,0x68}, {0x8c,0x69}, {0x8c,0x6a}, - {0x8c,0x6b}, {0x8c,0x6c}, {0x8c,0x6d}, {0x8c,0x6e}, {0x8c,0x6f}, {0x8c,0x70}, {0x8c,0x71}, {0x8c,0x72}, {0x8c,0x73}, {0x8c,0x74}, - {0x8c,0x75}, {0x8c,0x76}, {0x8c,0x77}, {0x8c,0x78}, {0x8c,0x79}, {0x8c,0x7a}, {0x8c,0x7b}, {0x8c,0x7c}, {0x8c,0x7d}, {0x8c,0x7e}, - {0x8c,0xa1}, {0x8c,0xa2}, {0x8c,0xa3}, {0x8c,0xa4}, {0x8c,0xa5}, {0x8c,0xa6}, {0x8c,0xa7}, {0x8c,0xa8}, {0x8c,0xa9}, {0x8c,0xaa}, - {0x8c,0xab}, {0x8c,0xac}, {0x8c,0xad}, {0x8c,0xae}, {0x8c,0xaf}, {0x8c,0xb0}, {0x8c,0xb1}, {0x8c,0xb2}, {0x8c,0xb3}, {0x8c,0xb4}, - {0x8c,0xb5}, {0x8c,0xb6}, {0x8c,0xb7}, {0x8c,0xb8}, {0x8c,0xb9}, {0x8c,0xba}, {0x8c,0xbb}, {0x8c,0xbc}, {0x8c,0xbd}, {0x8c,0xbe}, - {0x8c,0xbf}, {0x8c,0xc0}, {0x8c,0xc1}, {0x8c,0xc2}, {0x8c,0xc3}, {0x8c,0xc4}, {0x8c,0xc5}, {0x8c,0xc6}, {0x8c,0xc7}, {0x8c,0xc8}, - {0x8c,0xc9}, {0x8c,0xca}, {0x8c,0xcb}, {0x8c,0xcc}, {0x8c,0xcd}, {0x8c,0xce}, {0x8c,0xcf}, {0x8c,0xd0}, {0x8c,0xd1}, {0x8c,0xd2}, - {0x8c,0xd3}, {0x8c,0xd4}, {0x8c,0xd5}, {0x8c,0xd6}, {0x8c,0xd7}, {0x8c,0xd8}, {0x8c,0xd9}, {0x8c,0xda}, {0x8c,0xdb}, {0x8c,0xdc}, - {0x8c,0xdd}, {0x8c,0xde}, {0x8c,0xdf}, {0x8c,0xe0}, {0x8c,0xe1}, {0x8c,0xe2}, {0x8c,0xe3}, {0x8c,0xe4}, {0x8c,0xe5}, {0x8c,0xe6}, - {0x8c,0xe7}, {0x8c,0xe8}, {0x8c,0xe9}, {0x8c,0xea}, {0x8c,0xeb}, {0x8c,0xec}, {0x8c,0xed}, {0x8c,0xee}, {0x8c,0xef}, {0x8c,0xf0}, - {0x8c,0xf1}, {0x8c,0xf2}, {0x8c,0xf3}, {0x8c,0xf4}, {0x8c,0xf5}, {0x8c,0xf6}, {0x8c,0xf7}, {0x8c,0xf8}, {0x8c,0xf9}, {0x8c,0xfa}, - {0x8c,0xfb}, {0x8c,0xfc}, {0x8c,0xfd}, {0x8c,0xfe}, {0x8d,0x40}, {0x8d,0x41}, {0x8d,0x42}, {0x8d,0x43}, {0x8d,0x44}, {0x8d,0x45}, - {0x8d,0x46}, {0x8d,0x47}, {0x8d,0x48}, {0x8d,0x49}, {0x8d,0x4a}, {0x8d,0x4b}, {0x8d,0x4c}, {0x8d,0x4d}, {0x8d,0x4e}, {0x8d,0x4f}, - {0x8d,0x50}, {0x8d,0x51}, {0x8d,0x52}, {0x8d,0x53}, {0x8d,0x54}, {0x8d,0x55}, {0x8d,0x56}, {0x8d,0x57}, {0x8d,0x58}, {0x8d,0x59}, - {0x8d,0x5a}, {0x8d,0x5b}, {0x8d,0x5c}, {0x8d,0x5d}, {0x8d,0x5e}, {0x8d,0x5f}, {0x8d,0x60}, {0x8d,0x61}, {0x8d,0x62}, {0x8d,0x63}, - {0x8d,0x64}, {0x8d,0x65}, {0x8d,0x66}, {0x8d,0x67}, {0x8d,0x68}, {0x8d,0x69}, {0x8d,0x6a}, {0x8d,0x6b}, {0x8d,0x6c}, {0x8d,0x6d}, - {0x8d,0x6e}, {0x8d,0x6f}, {0x8d,0x70}, {0x8d,0x71}, {0x8d,0x72}, {0x8d,0x73}, {0x8d,0x74}, {0x8d,0x75}, {0x8d,0x76}, {0x8d,0x77}, - {0x8d,0x78}, {0x8d,0x79}, {0x8d,0x7a}, {0x8d,0x7b}, {0x8d,0x7c}, {0x8d,0x7d}, {0x8d,0x7e}, {0x8d,0xa1}, {0x8d,0xa2}, {0x8d,0xa3}, - {0x8d,0xa4}, {0x8d,0xa5}, {0x8d,0xa6}, {0x8d,0xa7}, {0x8d,0xa8}, {0x8d,0xa9}, {0x8d,0xaa}, {0x8d,0xab}, {0x8d,0xac}, {0x8d,0xad}, - {0x8d,0xae}, {0x8d,0xaf}, {0x8d,0xb0}, {0x8d,0xb1}, {0x8d,0xb2}, {0x8d,0xb3}, {0x8d,0xb4}, {0x8d,0xb5}, {0x8d,0xb6}, {0x8d,0xb7}, - {0x8d,0xb8}, {0x8d,0xb9}, {0x8d,0xba}, {0x8d,0xbb}, {0x8d,0xbc}, {0x8d,0xbd}, {0x8d,0xbe}, {0x8d,0xbf}, {0x8d,0xc0}, {0x8d,0xc1}, - {0x8d,0xc2}, {0x8d,0xc3}, {0x8d,0xc4}, {0x8d,0xc5}, {0x8d,0xc6}, {0x8d,0xc7}, {0x8d,0xc8}, {0x8d,0xc9}, {0x8d,0xca}, {0x8d,0xcb}, - {0x8d,0xcc}, {0x8d,0xcd}, {0x8d,0xce}, {0x8d,0xcf}, {0x8d,0xd0}, {0x8d,0xd1}, {0x8d,0xd2}, {0x8d,0xd3}, {0x8d,0xd4}, {0x8d,0xd5}, - {0x8d,0xd6}, {0x8d,0xd7}, {0x8d,0xd8}, {0x8d,0xd9}, {0x8d,0xda}, {0x8d,0xdb}, {0x8d,0xdc}, {0x8d,0xdd}, {0x8d,0xde}, {0x8d,0xdf}, - {0x8d,0xe0}, {0x8d,0xe1}, {0x8d,0xe2}, {0x8d,0xe3}, {0x8d,0xe4}, {0x8d,0xe5}, {0x8d,0xe6}, {0x8d,0xe7}, {0x8d,0xe8}, {0x8d,0xe9}, - {0x8d,0xea}, {0x8d,0xeb}, {0x8d,0xec}, {0x8d,0xed}, {0x8d,0xee}, {0x8d,0xef}, {0x8d,0xf0}, {0x8d,0xf1}, {0x8d,0xf2}, {0x8d,0xf3}, - {0x8d,0xf4}, {0x8d,0xf5}, {0x8d,0xf6}, {0x8d,0xf7}, {0x8d,0xf8}, {0x8d,0xf9}, {0x8d,0xfa}, {0x8d,0xfb}, {0x8d,0xfc}, {0x8d,0xfd}, - {0x8d,0xfe}, {0xc6,0xa1}, {0xc6,0xa2}, {0xc6,0xa3}, {0xc6,0xa4}, {0xc6,0xa5}, {0xc6,0xa6}, {0xc6,0xa7}, {0xc6,0xa8}, {0xc6,0xa9}, - {0xc6,0xaa}, {0xc6,0xab}, {0xc6,0xac}, {0xc6,0xad}, {0xc6,0xae}, {0xc6,0xaf}, {0xc6,0xb0}, {0xc6,0xb1}, {0xc6,0xb2}, {0xc6,0xb3}, - {0xc6,0xb4}, {0xc6,0xb5}, {0xc6,0xb6}, {0xc6,0xb7}, {0xc6,0xb8}, {0xc6,0xb9}, {0xc6,0xba}, {0xc6,0xbb}, {0xc6,0xbc}, {0xc6,0xbd}, - {0xc6,0xbe}, {0xc6,0xbf}, {0xc6,0xc0}, {0xc6,0xc1}, {0xc6,0xc2}, {0xc6,0xc3}, {0xc6,0xc4}, {0xc6,0xc5}, {0xc6,0xc6}, {0xc6,0xc7}, - {0xc6,0xc8}, {0xc6,0xc9}, {0xc6,0xca}, {0xc6,0xcb}, {0xc6,0xcc}, {0xc6,0xcd}, {0xc6,0xce}, {0xc6,0xcf}, {0xc6,0xd0}, {0xc6,0xd1}, - {0xc6,0xd2}, {0xc6,0xd3}, {0xc6,0xd4}, {0xc6,0xd5}, {0xc6,0xd6}, {0xc6,0xd7}, {0xc6,0xd8}, {0xc6,0xd9}, {0xc6,0xda}, {0xc6,0xdb}, - {0xc6,0xdc}, {0xc6,0xdd}, {0xc6,0xde}, {0xc6,0xdf}, {0xc6,0xe0}, {0xc6,0xe1}, {0xc6,0xe2}, {0xc6,0xe3}, {0xc6,0xe4}, {0xc6,0xe5}, - {0xc6,0xe6}, {0xc6,0xe7}, {0xc6,0xe8}, {0xc6,0xe9}, {0xc6,0xea}, {0xc6,0xeb}, {0xc6,0xec}, {0xc6,0xed}, {0xc6,0xee}, {0xc6,0xef}, - {0xc6,0xf0}, {0xc6,0xf1}, {0xc6,0xf2}, {0xc6,0xf3}, {0xc6,0xf4}, {0xc6,0xf5}, {0xc6,0xf6}, {0xc6,0xf7}, {0xc6,0xf8}, {0xc6,0xf9}, - {0xc6,0xfa}, {0xc6,0xfb}, {0xc6,0xfc}, {0xc6,0xfd}, {0xc6,0xfe}, {0xc7,0x40}, {0xc7,0x41}, {0xc7,0x42}, {0xc7,0x43}, {0xc7,0x44}, - {0xc7,0x45}, {0xc7,0x46}, {0xc7,0x47}, {0xc7,0x48}, {0xc7,0x49}, {0xc7,0x4a}, {0xc7,0x4b}, {0xc7,0x4c}, {0xc7,0x4d}, {0xc7,0x4e}, - {0xc7,0x4f}, {0xc7,0x50}, {0xc7,0x51}, {0xc7,0x52}, {0xc7,0x53}, {0xc7,0x54}, {0xc7,0x55}, {0xc7,0x56}, {0xc7,0x57}, {0xc7,0x58}, - {0xc7,0x59}, {0xc7,0x5a}, {0xc7,0x5b}, {0xc7,0x5c}, {0xc7,0x5d}, {0xc7,0x5e}, {0xc7,0x5f}, {0xc7,0x60}, {0xc7,0x61}, {0xc7,0x62}, - {0xc7,0x63}, {0xc7,0x64}, {0xc7,0x65}, {0xc7,0x66}, {0xc7,0x67}, {0xc7,0x68}, {0xc7,0x69}, {0xc7,0x6a}, {0xc7,0x6b}, {0xc7,0x6c}, - {0xc7,0x6d}, {0xc7,0x6e}, {0xc7,0x6f}, {0xc7,0x70}, {0xc7,0x71}, {0xc7,0x72}, {0xc7,0x73}, {0xc7,0x74}, {0xc7,0x75}, {0xc7,0x76}, - {0xc7,0x77}, {0xc7,0x78}, {0xc7,0x79}, {0xc7,0x7a}, {0xc7,0x7b}, {0xc7,0x7c}, {0xc7,0x7d}, {0xc7,0x7e}, {0xc7,0xa1}, {0xc7,0xa2}, - {0xc7,0xa3}, {0xc7,0xa4}, {0xc7,0xa5}, {0xc7,0xa6}, {0xc7,0xa7}, {0xc7,0xa8}, {0xc7,0xa9}, {0xc7,0xaa}, {0xc7,0xab}, {0xc7,0xac}, - {0xc7,0xad}, {0xc7,0xae}, {0xc7,0xaf}, {0xc7,0xb0}, {0xc7,0xb1}, {0xc7,0xb2}, {0xc7,0xb3}, {0xc7,0xb4}, {0xc7,0xb5}, {0xc7,0xb6}, - {0xc7,0xb7}, {0xc7,0xb8}, {0xc7,0xb9}, {0xc7,0xba}, {0xc7,0xbb}, {0xc7,0xbc}, {0xc7,0xbd}, {0xc7,0xbe}, {0xc7,0xbf}, {0xc7,0xc0}, - {0xc7,0xc1}, {0xc7,0xc2}, {0xc7,0xc3}, {0xc7,0xc4}, {0xc7,0xc5}, {0xc7,0xc6}, {0xc7,0xc7}, {0xc7,0xc8}, {0xc7,0xc9}, {0xc7,0xca}, - {0xc7,0xcb}, {0xc7,0xcc}, {0xc7,0xcd}, {0xc7,0xce}, {0xc7,0xcf}, {0xc7,0xd0}, {0xc7,0xd1}, {0xc7,0xd2}, {0xc7,0xd3}, {0xc7,0xd4}, - {0xc7,0xd5}, {0xc7,0xd6}, {0xc7,0xd7}, {0xc7,0xd8}, {0xc7,0xd9}, {0xc7,0xda}, {0xc7,0xdb}, {0xc7,0xdc}, {0xc7,0xdd}, {0xc7,0xde}, - {0xc7,0xdf}, {0xc7,0xe0}, {0xc7,0xe1}, {0xc7,0xe2}, {0xc7,0xe3}, {0xc7,0xe4}, {0xc7,0xe5}, {0xc7,0xe6}, {0xc7,0xe7}, {0xc7,0xe8}, - {0xc7,0xe9}, {0xc7,0xea}, {0xc7,0xeb}, {0xc7,0xec}, {0xc7,0xed}, {0xc7,0xee}, {0xc7,0xef}, {0xc7,0xf0}, {0xc7,0xf1}, {0xc7,0xf2}, - {0xc7,0xf3}, {0xc7,0xf4}, {0xc7,0xf5}, {0xc7,0xf6}, {0xc7,0xf7}, {0xc7,0xf8}, {0xc7,0xf9}, {0xc7,0xfa}, {0xc7,0xfb}, {0xc7,0xfc}, - {0xc7,0xfd}, {0xc7,0xfe}, {0xc8,0x40}, {0xc8,0x41}, {0xc8,0x42}, {0xc8,0x43}, {0xc8,0x44}, {0xc8,0x45}, {0xc8,0x46}, {0xc8,0x47}, - {0xc8,0x48}, {0xc8,0x49}, {0xc8,0x4a}, {0xc8,0x4b}, {0xc8,0x4c}, {0xc8,0x4d}, {0xc8,0x4e}, {0xc8,0x4f}, {0xc8,0x50}, {0xc8,0x51}, - {0xc8,0x52}, {0xc8,0x53}, {0xc8,0x54}, {0xc8,0x55}, {0xc8,0x56}, {0xc8,0x57}, {0xc8,0x58}, {0xc8,0x59}, {0xc8,0x5a}, {0xc8,0x5b}, - {0xc8,0x5c}, {0xc8,0x5d}, {0xc8,0x5e}, {0xc8,0x5f}, {0xc8,0x60}, {0xc8,0x61}, {0xc8,0x62}, {0xc8,0x63}, {0xc8,0x64}, {0xc8,0x65}, - {0xc8,0x66}, {0xc8,0x67}, {0xc8,0x68}, {0xc8,0x69}, {0xc8,0x6a}, {0xc8,0x6b}, {0xc8,0x6c}, {0xc8,0x6d}, {0xc8,0x6e}, {0xc8,0x6f}, - {0xc8,0x70}, {0xc8,0x71}, {0xc8,0x72}, {0xc8,0x73}, {0xc8,0x74}, {0xc8,0x75}, {0xc8,0x76}, {0xc8,0x77}, {0xc8,0x78}, {0xc8,0x79}, - {0xc8,0x7a}, {0xc8,0x7b}, {0xc8,0x7c}, {0xc8,0x7d}, {0xc8,0x7e}, {0xc8,0xa1}, {0xc8,0xa2}, {0xc8,0xa3}, {0xc8,0xa4}, {0xc8,0xa5}, - {0xc8,0xa6}, {0xc8,0xa7}, {0xc8,0xa8}, {0xc8,0xa9}, {0xc8,0xaa}, {0xc8,0xab}, {0xc8,0xac}, {0xc8,0xad}, {0xc8,0xae}, {0xc8,0xaf}, - {0xc8,0xb0}, {0xc8,0xb1}, {0xc8,0xb2}, {0xc8,0xb3}, {0xc8,0xb4}, {0xc8,0xb5}, {0xc8,0xb6}, {0xc8,0xb7}, {0xc8,0xb8}, {0xc8,0xb9}, - {0xc8,0xba}, {0xc8,0xbb}, {0xc8,0xbc}, {0xc8,0xbd}, {0xc8,0xbe}, {0xc8,0xbf}, {0xc8,0xc0}, {0xc8,0xc1}, {0xc8,0xc2}, {0xc8,0xc3}, - {0xc8,0xc4}, {0xc8,0xc5}, {0xc8,0xc6}, {0xc8,0xc7}, {0xc8,0xc8}, {0xc8,0xc9}, {0xc8,0xca}, {0xc8,0xcb}, {0xc8,0xcc}, {0xc8,0xcd}, - {0xc8,0xce}, {0xc8,0xcf}, {0xc8,0xd0}, {0xc8,0xd1}, {0xc8,0xd2}, {0xc8,0xd3}, {0xc8,0xd4}, {0xc8,0xd5}, {0xc8,0xd6}, {0xc8,0xd7}, - {0xc8,0xd8}, {0xc8,0xd9}, {0xc8,0xda}, {0xc8,0xdb}, {0xc8,0xdc}, {0xc8,0xdd}, {0xc8,0xde}, {0xc8,0xdf}, {0xc8,0xe0}, {0xc8,0xe1}, - {0xc8,0xe2}, {0xc8,0xe3}, {0xc8,0xe4}, {0xc8,0xe5}, {0xc8,0xe6}, {0xc8,0xe7}, {0xc8,0xe8}, {0xc8,0xe9}, {0xc8,0xea}, {0xc8,0xeb}, - {0xc8,0xec}, {0xc8,0xed}, {0xc8,0xee}, {0xc8,0xef}, {0xc8,0xf0}, {0xc8,0xf1}, {0xc8,0xf2}, {0xc8,0xf3}, {0xc8,0xf4}, {0xc8,0xf5}, - {0xc8,0xf6}, {0xc8,0xf7}, {0xc8,0xf8}, {0xc8,0xf9}, {0xc8,0xfa}, {0xc8,0xfb}, {0xc8,0xfc}, {0xc8,0xfd}, {0xc8,0xfe}, {0xff,0x00}, - {0xb0,0x5a}, {0xa7,0xf3}, {0xa8,0xae}, {0xb8,0xeb}, {0xb7,0xc6}, {0xa6,0xea}, {0xa5,0x79}, {0x8b,0xf8}, {0xc0,0x74}, {0xab,0xb4}, - {0xaa,0xf7}, {0xb3,0xe2}, {0xa9,0x60}, {0xc3,0x69}, {0xc4,0xee}, {0xc3,0xb9}, {0xc5,0xda}, {0xc1,0xb3}, {0xbb,0x72}, {0xc5,0xde}, - {0xbc,0xd6}, {0xac,0xa5}, {0xaf,0x4f}, {0xaf,0x5f}, {0xb8,0xa8}, {0xb9,0x54}, {0xc0,0x64}, {0xb6,0xc3}, {0xa7,0x5a}, {0xc4,0xe6}, - {0xc4,0xea}, {0xc4,0xf5}, {0xc6,0x7d}, {0xb4,0x50}, {0xc0,0xdd}, {0xc2,0xc5}, {0xc4,0xb0}, {0xa9,0xd4}, {0xc3,0xbe}, {0xc4,0xfa}, - {0xb4,0x59}, {0xae,0xd4}, {0xae,0xf6}, {0xaf,0x54}, {0xa8,0xd3}, {0xa7,0x4e}, {0xb3,0xd2}, {0xbe,0xdb}, {0xc3,0x72}, {0xc4,0x6c}, - {0xbf,0x63}, {0xa6,0xd1}, {0xc4,0xaa}, {0xb8,0xb8}, {0xb8,0xf4}, {0xc5,0x53}, {0xbe,0x7c}, {0xc6,0x4f}, {0xb8,0x4c}, {0xb8,0x53}, - {0xba,0xf1}, {0xdb,0x77}, {0xbf,0xfd}, {0xb3,0xc0}, {0xbd,0xd7}, {0xc3,0x62}, {0xa7,0xcb}, {0xc5,0xa2}, {0xc5,0xa4}, {0xa8,0x63}, - {0xbd,0x55}, {0xb8,0xef}, {0xb9,0x70}, {0xc2,0x53}, {0xb9,0xf0}, {0xbc,0xd3}, {0xb2,0x5c}, {0xba,0x7c}, {0xb2,0xd6}, {0xc1,0x5c}, - {0xad,0xae}, {0xb0,0xc7}, {0xa6,0xd8}, {0xbb,0xfe}, {0xad,0xe2}, {0xb8,0x57}, {0xba,0xf0}, {0xb5,0xd9}, {0xb3,0xae}, {0xc5,0xaa}, - {0xce,0xd4}, {0xbc,0xd6}, {0xbf,0xd5}, {0xa4,0xa6}, {0xb9,0xe7}, {0xab,0xe3}, {0xb2,0x76}, {0xb2,0xa7}, {0xa5,0x5f}, {0xed,0xa8}, - {0xab,0x4b}, {0xb4,0x5f}, {0xa4,0xa3}, {0xaa,0x63}, {0xbc,0xc6}, {0xaf,0xc1}, {0xb0,0xd1}, {0xb6,0xeb}, {0xac,0xd9}, {0xb8,0xad}, - {0xbb,0xa1}, {0xb1,0xfe}, {0xa8,0xb0}, {0xa8,0x48}, {0xac,0x42}, {0xad,0x59}, {0xb1,0xb0}, {0xb2,0xa4}, {0xab,0x47}, {0xa8,0xe2}, - {0xb1,0xe7}, {0xc2,0xb3}, {0xa8,0x7d}, {0xbd,0xcc}, {0xb6,0x71}, {0xc0,0x79}, {0xa7,0x66}, {0xa4,0x6b}, {0xc3,0x66}, {0xae,0xc8}, - {0xc2,0x6f}, {0xc4,0x72}, {0xbe,0x5b}, {0xc6,0x7a}, {0xc4,0x52}, {0xbe,0xa4}, {0xa4,0x4f}, {0xbe,0xe4}, {0xbe,0xfa}, {0xf7,0x65}, - {0xa6,0x7e}, {0xbc,0xa6}, {0xc5,0xca}, {0xbc,0xbf}, {0xba,0xa7}, {0xb7,0xd2}, {0xe6,0xa3}, {0xbd,0x6d}, {0xc1,0x70}, {0xbd,0xfb}, - {0xbd,0xac}, {0xb3,0x73}, {0xc1,0xe5}, {0xa6,0x43}, {0xa6,0x48}, {0xab,0x7c}, {0xaf,0x50}, {0xb5,0xf5}, {0xbb,0xa1}, {0xb7,0x47}, - {0xa9,0xc0}, {0xb1,0xc9}, {0xc0,0xd4}, {0xc3,0xae}, {0xc2,0x79}, {0xa5,0x4f}, {0xcb,0xf1}, {0xb9,0xe7}, {0xc0,0xad}, {0xcc,0xb0}, - {0xac,0xc2}, {0xbc,0xfc}, {0xb2,0xdc}, {0xb2,0xe2}, {0xb9,0x61}, {0xb9,0x73}, {0xc6,0x46}, {0xbb,0xe2}, {0xa8,0xd2}, {0xc2,0xa7}, - {0xc4,0xbf}, {0xc1,0xf5}, {0xb4,0x63}, {0xa4,0x46}, {0xb9,0xb1}, {0xbc,0x64}, {0xa7,0xbf}, {0xae,0xc6}, {0xbc,0xd6}, {0xbf,0x52}, - {0xc0,0xf8}, {0xe7,0x64}, {0xbf,0xf1}, {0xc0,0x73}, {0xb7,0x77}, {0xa8,0xbf}, {0xbc,0x42}, {0xcc,0xd8}, {0xac,0x68}, {0xac,0x79}, - {0xb7,0xc8}, {0xaf,0x5b}, {0xaf,0x64}, {0xb2,0xb8}, {0xaf,0xc3}, {0xc3,0xfe}, {0xa4,0xbb}, {0xbc,0xae}, {0xb3,0xb0}, {0xad,0xdb}, - {0xb1,0x5b}, {0xb2,0x5f}, {0xbd,0xfc}, {0xab,0xdf}, {0xb7,0x58}, {0xae,0xdf}, {0xb2,0x76}, {0xb6,0xa9}, {0xa7,0x51}, {0xa6,0x4f}, - {0xbc,0x69}, {0xa9,0xf6}, {0xa7,0xf5}, {0xb1,0xf9}, {0xaa,0x64}, {0xb2,0x7a}, {0xb5,0x67}, {0xbf,0xa9}, {0xb8,0xcc}, {0xa8,0xbd}, - {0xc2,0xf7}, {0xb0,0xce}, {0xb7,0xc4}, {0xa7,0x5b}, {0xbf,0x4d}, {0xbf,0x5a}, {0xc4,0xa9}, {0xc5,0xec}, {0xc5,0xef}, {0xaa,0x4c}, - {0xb2,0x4f}, {0xc1,0x7b}, {0xa5,0xdf}, {0xb2,0xc1}, {0xb2,0xc9}, {0xaa,0xac}, {0xaa,0xa5}, {0xc3,0xd1}, {0xa4,0xb0}, {0xaf,0xf9}, - {0xa8,0xeb}, {0xa4,0xc1}, {0xab,0xd7}, {0xa9,0xdd}, {0xbf,0x7d}, {0xa6,0x76}, {0xac,0x7d}, {0xbc,0xc9}, {0xbf,0xe7}, {0xa6,0xe6}, - {0xad,0xb0}, {0xa8,0xa3}, {0xb9,0xf8}, {0xc9,0x4a}, {0xdd,0xfc}, {0xb6,0xef}, {0xb4,0xb8}, {0xe8,0xf9}, {0xbd,0xde}, {0xaf,0x71}, - {0xaf,0xab}, {0xb2,0xbb}, {0xba,0xd6}, {0xb9,0x74}, {0xba,0xeb}, {0xa6,0xd0}, {0xbd,0xd1}, {0xb6,0x68}, {0xb3,0xa3}, {0xb6,0xba}, - {0xb9,0x7d}, {0xc0,0x5d}, {0xc5,0x62}, {0xa1,0x4a}, {0xa1,0x57}, {0xa1,0x59}, {0xa1,0x5b}, {0xa1,0x5f}, {0xa1,0x60}, {0xa1,0x63}, - {0xa1,0x64}, {0xa1,0x67}, {0xa1,0x68}, {0xa1,0x6b}, {0xa1,0x6c}, {0xa1,0x6f}, {0xa1,0x70}, {0xa1,0x73}, {0xa1,0x74}, {0xa1,0x77}, - {0xa1,0x78}, {0xa1,0x7b}, {0xa1,0x7c}, {0xa1,0xc6}, {0xa1,0xc7}, {0xa1,0xca}, {0xa1,0xcb}, {0xa1,0xc8}, {0xa1,0xc9}, {0xa1,0x5c}, - {0xa1,0x4d}, {0xa1,0x4e}, {0xa1,0x4f}, {0xa1,0x51}, {0xa1,0x52}, {0xa1,0x53}, {0xa1,0x54}, {0xa1,0x7d}, {0xa1,0x7e}, {0xa1,0xa1}, - {0xa1,0xa2}, {0xa1,0xa3}, {0xa1,0xa4}, {0xa1,0xcc}, {0xa1,0xcd}, {0xa1,0xce}, {0xa1,0xde}, {0xa1,0xdf}, {0xa1,0xe0}, {0xa1,0xe1}, - {0xa1,0xe2}, {0xa2,0x42}, {0xa2,0x4c}, {0xa2,0x4d}, {0xa2,0x4e}, {0xa1,0x49}, {0xc8,0xd0}, {0xa1,0xad}, {0xa2,0x43}, {0xa2,0x48}, - {0xa1,0xae}, {0xc8,0xcf}, {0xa1,0x5d}, {0xa1,0x5e}, {0xa1,0xaf}, {0xa1,0xcf}, {0xa1,0x41}, {0xa1,0xd0}, {0xa1,0x44}, {0xa1,0xfe}, - {0xa2,0xaf}, {0xa2,0xb0}, {0xa2,0xb1}, {0xa2,0xb2}, {0xa2,0xb3}, {0xa2,0xb4}, {0xa2,0xb5}, {0xa2,0xb6}, {0xa2,0xb7}, {0xa2,0xb8}, - {0xa1,0x47}, {0xa1,0x46}, {0xa1,0xd5}, {0xa1,0xd7}, {0xa1,0xd6}, {0xa1,0x48}, {0xa2,0x49}, {0xa2,0xcf}, {0xa2,0xd0}, {0xa2,0xd1}, - {0xa2,0xd2}, {0xa2,0xd3}, {0xa2,0xd4}, {0xa2,0xd5}, {0xa2,0xd6}, {0xa2,0xd7}, {0xa2,0xd8}, {0xa2,0xd9}, {0xa2,0xda}, {0xa2,0xdb}, - {0xa2,0xdc}, {0xa2,0xdd}, {0xa2,0xde}, {0xa2,0xdf}, {0xa2,0xe0}, {0xa2,0xe1}, {0xa2,0xe2}, {0xa2,0xe3}, {0xa2,0xe4}, {0xa2,0xe5}, - {0xa2,0xe6}, {0xa2,0xe7}, {0xa2,0xe8}, {0xc6,0xe4}, {0xa2,0x40}, {0xc6,0xe5}, {0xa1,0x73}, {0xa1,0xc4}, {0xa1,0xa5}, {0xa2,0xe9}, - {0xa2,0xea}, {0xa2,0xeb}, {0xa2,0xec}, {0xa2,0xed}, {0xa2,0xee}, {0xa2,0xef}, {0xa2,0xf0}, {0xa2,0xf1}, {0xa2,0xf2}, {0xa2,0xf3}, - {0xa2,0xf4}, {0xa2,0xf5}, {0xa2,0xf6}, {0xa2,0xf7}, {0xa2,0xf8}, {0xa2,0xf9}, {0xa2,0xfa}, {0xa2,0xfb}, {0xa2,0xfc}, {0xa2,0xfd}, - {0xa2,0xfe}, {0xa3,0x40}, {0xa3,0x41}, {0xa3,0x42}, {0xa3,0x43}, {0xa1,0x61}, {0xa1,0x55}, {0xa1,0x62}, {0xa1,0xe3}, {0xa1,0x4e}, - {0xa2,0x46}, {0xa2,0x47}, {0xc8,0xcd}, {0xa1,0xc3}, {0xc8,0xce}, {0xa2,0x44}, {0xf9,0xfe}, {0x9c,0x71}, {0x93,0x75}, {0x93,0x76}, - {0x95,0x48}, {0x8e,0xc6}, {0x8b,0xc5}, {0x8b,0xfa}, {0xc8,0x7c}, {0x9a,0xb4}, {0x88,0x4e}, {0x88,0x4b}, {0xc8,0x7a}, {0x88,0x48}, - {0x88,0x47}, {0xa0,0xf6}, {0x88,0x45}, {0x88,0x53}, {0xfc,0xad}, {0x8a,0xad}, {0x92,0x72}, {0xfc,0x47}, {0x94,0xdf}, {0x9f,0xd1}, - {0xfb,0xcb}, {0x92,0x7d}, {0x98,0xa4}, {0x94,0xe7}, {0x90,0xcb}, {0x92,0x7b}, {0x94,0xd8}, {0xfc,0x5f}, {0xfa,0x54}, {0x9a,0xb5}, - {0x96,0xda}, {0x92,0x79}, {0xfa,0x74}, {0x92,0x75}, {0x8d,0xfb}, {0x8a,0x49}, {0x92,0xdf}, {0x9b,0x7c}, {0xfa,0x63}, {0xfa,0x60}, - {0x92,0x6d}, {0xfa,0x62}, {0x9a,0xb6}, {0x97,0x6b}, {0xfd,0x6a}, {0xfd,0x54}, {0x92,0x73}, {0x97,0xd8}, {0x9f,0xbb}, {0x93,0x42}, - {0x92,0x76}, {0xfa,0x65}, {0x92,0x6c}, {0xfa,0x6e}, {0x9e,0xe0}, {0x92,0xc0}, {0x92,0xbf}, {0x92,0xbe}, {0x9a,0xba}, {0x8a,0xb3}, - {0x97,0x75}, {0xfa,0x40}, {0xfa,0x76}, {0xfb,0xd0}, {0xfa,0x7b}, {0xfe,0x6d}, {0x9b,0xb3}, {0x89,0xcc}, {0x9a,0xbe}, {0xfa,0x42}, - {0x92,0xbc}, {0x94,0x5c}, {0x9b,0xb5}, {0x9a,0xbf}, {0x98,0xa7}, {0x97,0xa4}, {0x90,0xfd}, {0xfc,0x7b}, {0x9a,0xc0}, {0x92,0xc3}, - {0x8a,0xaa}, {0x9b,0xd0}, {0x95,0x50}, {0x92,0xc6}, {0x98,0xa6}, {0x95,0x46}, {0xfd,0x63}, {0xfa,0xc2}, {0x9e,0xc3}, {0x89,0xb2}, - {0x9c,0x66}, {0x90,0x53}, {0x97,0xc1}, {0x9a,0xc4}, {0x9a,0xc5}, {0x8e,0xef}, {0xfa,0xe9}, {0x92,0x62}, {0x8a,0xf7}, {0x9a,0xc6}, - {0x92,0xe1}, {0x9a,0xc9}, {0xfa,0xc6}, {0x97,0xa5}, {0x9a,0xcb}, {0xfa,0x72}, {0x8a,0x5e}, {0x94,0xe0}, {0x92,0xcc}, {0x8a,0xe5}, - {0xfe,0x5c}, {0x9a,0xcc}, {0x9d,0xf9}, {0x8a,0x43}, {0x8a,0xa6}, {0x9a,0xcd}, {0x9a,0xce}, {0xfa,0xee}, {0x9b,0xcc}, {0x9a,0xcf}, - {0x9a,0xd1}, {0x9d,0xfa}, {0x9d,0x7c}, {0x9a,0xd3}, {0x97,0xa6}, {0x99,0x5f}, {0xfb,0xf6}, {0x9f,0xc5}, {0x8a,0x59}, {0x8b,0x6b}, - {0x9a,0xd4}, {0x9a,0xd5}, {0x97,0xa2}, {0x8a,0x44}, {0x9f,0x4a}, {0x90,0xa1}, {0xfd,0xa4}, {0x8a,0x64}, {0x8a,0xf2}, {0x8a,0xf8}, - {0x9d,0xd8}, {0x94,0xd6}, {0xfa,0xfe}, {0xfb,0xa7}, {0x9a,0xd6}, {0x9f,0x4d}, {0xfa,0xf6}, {0x8a,0x57}, {0x8b,0x43}, {0x8b,0x44}, - {0x8a,0xb6}, {0x8a,0xc0}, {0x9e,0x54}, {0x9a,0xd7}, {0x9a,0xd8}, {0x9a,0xdc}, {0x8a,0xca}, {0x9e,0xa8}, {0x92,0x63}, {0x9a,0xdd}, - {0x8b,0x65}, {0x8b,0x6f}, {0x8b,0x7e}, {0x8f,0x43}, {0x92,0xd0}, {0x8a,0xf4}, {0x9d,0xbe}, {0x9a,0xe1}, {0xfc,0xde}, {0x9d,0xfd}, - {0x8b,0x66}, {0x8b,0x70}, {0x8b,0x75}, {0x8a,0xe4}, {0x8b,0xa4}, {0x8a,0xed}, {0x8a,0x5d}, {0x8b,0x48}, {0x9d,0xed}, {0x9e,0x40}, - {0x8a,0xef}, {0x8a,0xf6}, {0x9e,0x76}, {0x9e,0xe3}, {0x9a,0xde}, {0x8d,0xfe}, {0xfa,0xfc}, {0x9c,0xb1}, {0x9e,0x77}, {0x8b,0x64}, - {0x8b,0x67}, {0x97,0x4b}, {0x96,0x53}, {0x9a,0xe0}, {0x8b,0x4a}, {0x8a,0xf1}, {0x8a,0xd7}, {0xa0,0xab}, {0x8a,0xb5}, {0x8a,0x5f}, - {0x8a,0xee}, {0x9a,0xdf}, {0x8a,0xfe}, {0x8a,0x58}, {0x8b,0xa3}, {0x8b,0xa7}, {0x9a,0xe3}, {0x92,0x61}, {0x9d,0xd7}, {0x9e,0x7d}, - {0x9e,0xa7}, {0x9e,0xab}, {0x90,0x42}, {0x8b,0x79}, {0x8b,0x7a}, {0x9a,0xe6}, {0x9a,0xe5}, {0x8a,0x7e}, {0x9e,0x44}, {0x9a,0xe7}, - {0x8a,0x7c}, {0x8b,0x71}, {0x9a,0xe9}, {0x9a,0xea}, {0x9a,0xeb}, {0x8a,0xbd}, {0xfb,0x4e}, {0x9a,0xed}, {0x8a,0xf9}, {0x9e,0x63}, - {0x8b,0x49}, {0x8a,0xce}, {0x8b,0x6e}, {0x8a,0xe8}, {0x9a,0xee}, {0x92,0xce}, {0x8a,0x5a}, {0x8b,0x7b}, {0x8b,0x7c}, {0x9a,0xef}, - {0x9a,0xf0}, {0x8a,0xfa}, {0x89,0x41}, {0x8b,0x72}, {0x8a,0xf3}, {0x8b,0xa8}, {0x9e,0xae}, {0x9e,0x72}, {0xfb,0x73}, {0xfb,0x5f}, - {0x90,0xba}, {0x91,0xfe}, {0x9e,0xf6}, {0x97,0xed}, {0x9a,0xf3}, {0xa0,0xee}, {0x96,0x7c}, {0x93,0x45}, {0x98,0x6e}, {0xfa,0x56}, - {0x9a,0xf5}, {0xfc,0x4b}, {0x9a,0xf4}, {0xfe,0xde}, {0xfc,0xb7}, {0x97,0xf1}, {0x97,0xc7}, {0x9c,0xcb}, {0x92,0x40}, {0x9c,0xe8}, - {0x91,0xfd}, {0x97,0x4e}, {0xfb,0x68}, {0x97,0x6c}, {0x8c,0xc2}, {0x97,0xe8}, {0xfb,0x6a}, {0x8b,0x74}, {0x8e,0xe7}, {0xfd,0xc8}, - {0x92,0x41}, {0x96,0xa1}, {0x8e,0xf3}, {0x9a,0xf7}, {0x8f,0xa6}, {0xfa,0xd6}, {0x9c,0xc7}, {0xfa,0xd7}, {0x9a,0xf8}, {0xfb,0xa1}, - {0x8e,0xc5}, {0xfb,0xa4}, {0xfb,0xc2}, {0x9a,0xc1}, {0x91,0xfa}, {0xfe,0xdb}, {0x97,0xab}, {0x91,0x47}, {0xfb,0xb1}, {0x8f,0xea}, - {0x94,0xd2}, {0xfe,0x61}, {0xfa,0xce}, {0x92,0xed}, {0x91,0xf3}, {0x93,0xc6}, {0x93,0x5a}, {0xfa,0xfb}, {0x92,0xef}, {0xfa,0xc8}, - {0x98,0x47}, {0x93,0x66}, {0x98,0x55}, {0x96,0xe6}, {0x9f,0x43}, {0x9f,0xaa}, {0x94,0xda}, {0x92,0xee}, {0xfc,0xaf}, {0xfb,0xfb}, - {0x8e,0xf9}, {0x91,0xf6}, {0x93,0x64}, {0x94,0xf5}, {0x9c,0xb6}, {0xfb,0xad}, {0x98,0x4e}, {0x8f,0x44}, {0x96,0xfd}, {0x9a,0xf9}, - {0x9a,0xfa}, {0x97,0x69}, {0x95,0xd4}, {0x98,0x4b}, {0xfb,0xaa}, {0x98,0x7c}, {0x91,0xea}, {0x9d,0xaf}, {0x9d,0xc5}, {0x91,0xf1}, - {0x8e,0xb1}, {0x97,0xa9}, {0xfb,0xac}, {0xfc,0xb8}, {0x9c,0xb9}, {0xfb,0xb0}, {0xfc,0xd2}, {0x93,0xcb}, {0x9a,0xfd}, {0x91,0xf4}, - {0x8b,0xac}, {0xa0,0x55}, {0x95,0x74}, {0x95,0xbe}, {0x97,0xad}, {0x8e,0xe9}, {0x92,0xf8}, {0x97,0xbe}, {0x91,0x6c}, {0x94,0xaa}, - {0xfc,0x63}, {0x9d,0xc6}, {0x97,0xb5}, {0x92,0xb8}, {0x91,0xef}, {0xfe,0xa6}, {0x97,0x60}, {0x93,0x58}, {0x95,0x76}, {0x8f,0xac}, - {0x91,0xec}, {0x97,0xb4}, {0x91,0xf7}, {0x97,0x4a}, {0xfb,0x49}, {0x95,0x78}, {0x93,0xbc}, {0x91,0xd6}, {0x93,0x55}, {0x93,0x56}, - {0x98,0x51}, {0x8f,0xf8}, {0xfb,0xc0}, {0x93,0xf2}, {0x90,0xd0}, {0x9c,0x44}, {0x92,0x55}, {0x93,0x63}, {0x91,0xa5}, {0xa0,0xed}, - {0xfd,0x6b}, {0x9a,0xfe}, {0x93,0x51}, {0x8c,0x57}, {0xfa,0x78}, {0xfe,0xa8}, {0x93,0x50}, {0xfa,0x4c}, {0x92,0xf7}, {0x9b,0x40}, - {0xfb,0xce}, {0x9b,0x41}, {0xfe,0xad}, {0xfb,0xd5}, {0x8b,0xc2}, {0x9a,0x7c}, {0x9b,0x42}, {0x9b,0x43}, {0x9e,0x79}, {0xfb,0xd9}, - {0x9b,0x44}, {0xa0,0xa7}, {0x9b,0xf3}, {0x8c,0x79}, {0x93,0x5e}, {0x89,0xcb}, {0x9f,0x53}, {0x93,0xd7}, {0xfb,0xe1}, {0xfe,0xd0}, - {0xfb,0xe2}, {0xfc,0xe3}, {0x90,0x74}, {0xfb,0xe6}, {0x9b,0xb7}, {0x9b,0x45}, {0x9b,0x47}, {0x9f,0x50}, {0x9b,0x48}, {0xfc,0x5b}, - {0x98,0xa9}, {0x9c,0xfd}, {0x88,0x4c}, {0x9b,0x4b}, {0xfb,0xec}, {0x8c,0x69}, {0x9b,0xa8}, {0x8a,0xd5}, {0xfa,0x73}, {0xfd,0x59}, - {0x91,0xa2}, {0xfb,0xed}, {0x9c,0xa9}, {0x8a,0xa8}, {0x9b,0xc3}, {0x8a,0xe1}, {0x9b,0x4e}, {0x95,0xd0}, {0x90,0x5f}, {0x97,0xee}, - {0xfc,0x4e}, {0x9b,0x4f}, {0x9b,0x50}, {0x9e,0xc6}, {0xfc,0x50}, {0xfd,0x73}, {0xfd,0xa7}, {0x9d,0xa2}, {0xfa,0x58}, {0xfa,0x5e}, - {0xa0,0x59}, {0xfa,0x75}, {0xfb,0xbe}, {0x9c,0xa2}, {0x93,0x70}, {0x93,0x71}, {0x93,0x77}, {0xfe,0xef}, {0x93,0x6d}, {0xfc,0x5d}, - {0x90,0xb8}, {0x8a,0xfc}, {0xfb,0x41}, {0x9e,0x6b}, {0x94,0xe3}, {0x8e,0xe2}, {0x8c,0x7d}, {0x8e,0xd7}, {0x9c,0x4d}, {0x96,0xa3}, - {0x9b,0x51}, {0x8a,0xc3}, {0x96,0xaa}, {0xfc,0x68}, {0x8b,0x6d}, {0xfd,0x67}, {0x8a,0xe9}, {0xfc,0xa1}, {0x93,0x6c}, {0x9b,0x52}, - {0xfe,0x70}, {0xfc,0xa8}, {0xfc,0xe9}, {0x9c,0xb4}, {0x8a,0xea}, {0x9b,0x53}, {0x9b,0x55}, {0x96,0xab}, {0xfc,0xa7}, {0x9b,0x56}, - {0x8a,0xbc}, {0x8a,0xcb}, {0x9b,0x57}, {0x89,0xcd}, {0x9b,0x59}, {0x9b,0x5b}, {0x93,0xa5}, {0x9b,0x5d}, {0x9e,0x4f}, {0x93,0xa3}, - {0x8a,0x7b}, {0x8b,0x42}, {0x97,0x50}, {0x8f,0xb3}, {0x8a,0x50}, {0x9b,0x60}, {0x8b,0x45}, {0x8b,0x46}, {0x9d,0xfe}, {0x9b,0x62}, - {0x93,0x7b}, {0x93,0xb1}, {0x8a,0x60}, {0x8a,0xd8}, {0x9b,0x63}, {0x8a,0x69}, {0x8a,0x47}, {0x8a,0xcc}, {0x93,0x7c}, {0x9b,0x65}, - {0x9b,0x66}, {0x8a,0x72}, {0x8a,0x7a}, {0x93,0xaf}, {0x8a,0xb0}, {0x9b,0x68}, {0x9e,0xa3}, {0xfa,0xec}, {0x8b,0x77}, {0x9b,0x67}, - {0x8b,0x59}, {0xfc,0xb1}, {0xfc,0xbb}, {0x9b,0x69}, {0x93,0xa8}, {0x8a,0xe0}, {0x9e,0x51}, {0x8f,0x5f}, {0x9b,0x6a}, {0x9b,0x6b}, - {0x97,0xec}, {0x9b,0x6c}, {0xfe,0x4e}, {0xfd,0xc2}, {0x9b,0x6d}, {0x91,0x67}, {0xfc,0xcc}, {0x93,0xb6}, {0x90,0xe4}, {0x90,0xe5}, - {0x9e,0xf2}, {0x93,0xca}, {0x8b,0xbc}, {0x8f,0x46}, {0x93,0xcf}, {0xfc,0xdb}, {0xfc,0xdc}, {0x93,0xc0}, {0xfc,0xe6}, {0x96,0xe7}, - {0xfc,0xd8}, {0xfc,0xd9}, {0xfd,0xa6}, {0x93,0xce}, {0x95,0xf1}, {0x9c,0xe9}, {0xfc,0xe4}, {0x94,0xaf}, {0xfa,0x77}, {0x93,0xcc}, - {0x90,0x5a}, {0x8c,0x54}, {0x93,0xbf}, {0xfb,0x51}, {0x93,0xb9}, {0xfe,0xd7}, {0x93,0xb7}, {0x93,0xd9}, {0x93,0xbb}, {0x93,0xda}, - {0x98,0xa3}, {0x90,0xd1}, {0x9b,0x6e}, {0xfa,0x70}, {0x9b,0xeb}, {0x9b,0x6f}, {0xfc,0xfc}, {0x8b,0x40}, {0xa0,0x7b}, {0x8c,0xa1}, - {0x97,0xf7}, {0x93,0xe2}, {0xfc,0xd6}, {0x95,0x59}, {0x93,0xa6}, {0xfd,0x40}, {0x93,0x5f}, {0x97,0xf2}, {0x9c,0x76}, {0x8e,0xf8}, - {0x8f,0x47}, {0x9b,0x74}, {0x92,0xb4}, {0x91,0xed}, {0x96,0xd2}, {0xfd,0x46}, {0x8f,0x4f}, {0x95,0x49}, {0x9b,0x75}, {0xfa,0x5c}, - {0x9b,0x79}, {0xfd,0x4b}, {0x96,0xd3}, {0xfd,0x58}, {0x94,0x5f}, {0xa0,0xf5}, {0x92,0x43}, {0x97,0xfa}, {0x9d,0xd9}, {0x97,0xf4}, - {0x92,0x4d}, {0xfd,0x5b}, {0x9b,0x7a}, {0x9e,0xd5}, {0xfa,0xae}, {0x9c,0xc9}, {0x92,0x58}, {0x8e,0xc8}, {0x94,0xb4}, {0x93,0xe1}, - {0x93,0xdf}, {0xfc,0xf0}, {0x93,0xec}, {0x97,0xf6}, {0x96,0xcf}, {0x93,0xde}, {0x8a,0xcf}, {0x9b,0xa2}, {0xfd,0x69}, {0x93,0x52}, - {0x98,0xa2}, {0xfd,0x6e}, {0x8c,0xa4}, {0xfa,0x7c}, {0x93,0xfa}, {0x90,0x7c}, {0x8f,0x67}, {0x9d,0xb7}, {0xa0,0xe9}, {0xfa,0x4e}, - {0xfd,0xa1}, {0x9e,0x74}, {0x9f,0xbf}, {0x9e,0xcb}, {0x9b,0xb9}, {0x9d,0xd4}, {0x97,0xb9}, {0x8e,0xf1}, {0x95,0x7b}, {0x9e,0xd2}, - {0x97,0x53}, {0x96,0xa4}, {0x8f,0xbe}, {0x94,0xd9}, {0x90,0x58}, {0xfd,0x79}, {0xfd,0x7b}, {0x8e,0xda}, {0x8e,0xfa}, {0x9b,0xa5}, - {0x9e,0xd9}, {0x97,0xd4}, {0x90,0xbb}, {0xfd,0xbc}, {0xfd,0xc6}, {0x92,0x48}, {0x92,0xb5}, {0x9d,0xc1}, {0x92,0xb9}, {0x92,0xa6}, - {0x8f,0x4b}, {0x9b,0xa6}, {0x92,0xb6}, {0x8e,0x40}, {0x9e,0xd8}, {0x94,0x5e}, {0x98,0x5f}, {0x94,0xce}, {0x92,0x4a}, {0xfd,0x70}, - {0x94,0x67}, {0x8d,0xec}, {0x9b,0xd8}, {0x94,0x48}, {0xfa,0xc1}, {0x9c,0xf7}, {0xfd,0xbe}, {0x8f,0xda}, {0xfd,0xd9}, {0xfc,0x7e}, - {0x93,0xf9}, {0xfa,0x43}, {0xfa,0xeb}, {0xfa,0xc3}, {0x97,0xd3}, {0x95,0xf9}, {0x9c,0x48}, {0xfd,0xd8}, {0xa0,0xd8}, {0xfd,0xd7}, - {0xfb,0x4a}, {0x9b,0xaf}, {0x94,0x4b}, {0xfd,0xc9}, {0x8e,0xac}, {0xfd,0xb2}, {0x92,0x5a}, {0xfc,0xbd}, {0x92,0xd9}, {0xfd,0xd5}, - {0x92,0xdd}, {0x92,0x59}, {0x96,0xba}, {0x92,0x5b}, {0x9b,0xab}, {0xfd,0xda}, {0xfd,0xde}, {0xfd,0xd3}, {0x8c,0x46}, {0xfd,0xd6}, - {0xfd,0xdc}, {0xfd,0xdd}, {0x90,0xfe}, {0xfe,0xa1}, {0x8b,0xad}, {0x9c,0xd8}, {0x9e,0x6d}, {0xfd,0x7c}, {0xfb,0x61}, {0x96,0xf8}, - {0x96,0xf0}, {0xfc,0xf4}, {0xfe,0x60}, {0x98,0x52}, {0x96,0x4f}, {0x91,0x6e}, {0x98,0x6d}, {0x98,0x64}, {0x94,0x53}, {0xfd,0xec}, - {0xfb,0x78}, {0x95,0xba}, {0x98,0x5d}, {0x92,0xf9}, {0x98,0x5a}, {0xfd,0xf6}, {0x93,0xd0}, {0x98,0x62}, {0x9b,0xad}, {0x97,0x4f}, - {0x9b,0xae}, {0x94,0x52}, {0x9b,0xb0}, {0x91,0xd2}, {0x97,0xea}, {0xfb,0x6b}, {0x91,0xb1}, {0xfd,0xf3}, {0x92,0xcb}, {0x9b,0xb1}, - {0xfc,0xec}, {0x98,0x6b}, {0x97,0x51}, {0x98,0x71}, {0x95,0xef}, {0x9e,0xf3}, {0x91,0xe8}, {0x9b,0xba}, {0xfb,0x4c}, {0x92,0x6a}, - {0xfd,0xf8}, {0x98,0x61}, {0x91,0xe7}, {0x93,0xed}, {0x97,0x44}, {0x91,0xe1}, {0xfb,0xf5}, {0x98,0x69}, {0x8a,0x62}, {0x9b,0xbb}, - {0x8c,0xa8}, {0x9c,0x55}, {0x8e,0x77}, {0x8a,0xb2}, {0x9e,0xbc}, {0x93,0xe6}, {0x93,0xa2}, {0x9b,0xbd}, {0x94,0xb3}, {0x93,0x7d}, - {0x9e,0x66}, {0x94,0x59}, {0x9b,0xbf}, {0x94,0x58}, {0x9e,0xa5}, {0x9b,0xc7}, {0xfe,0x54}, {0x8e,0x74}, {0x8b,0xd6}, {0x94,0xb6}, - {0xfd,0x74}, {0x98,0xc0}, {0x94,0xa5}, {0x9b,0xc8}, {0x95,0xed}, {0xfd,0x7e}, {0xfb,0xeb}, {0xfd,0x7d}, {0x97,0x6f}, {0x94,0x61}, - {0x9f,0xc1}, {0x95,0xd7}, {0xfa,0x52}, {0x9c,0x58}, {0x9f,0x68}, {0x9b,0xe7}, {0xfc,0xce}, {0x96,0xe8}, {0xfa,0x49}, {0x97,0xa1}, - {0x95,0x4d}, {0x9e,0xf8}, {0xfe,0x49}, {0x91,0xce}, {0x97,0x71}, {0x8c,0xcf}, {0xfd,0xb1}, {0xfc,0x6e}, {0x9c,0xf2}, {0x93,0xb8}, - {0x90,0x43}, {0x97,0x59}, {0x94,0xd7}, {0xfe,0x66}, {0x94,0x7d}, {0xfc,0x6f}, {0x92,0x46}, {0xfa,0x6d}, {0x8e,0xf7}, {0xfb,0xb7}, - {0x94,0x7c}, {0x92,0xcd}, {0x97,0xb2}, {0xfe,0x65}, {0x96,0x7e}, {0x97,0x58}, {0x9b,0x77}, {0x91,0xcf}, {0x94,0xa4}, {0x9c,0xad}, - {0x8b,0xab}, {0x96,0xd5}, {0xfc,0xb3}, {0x93,0xae}, {0x97,0x6d}, {0x94,0x46}, {0x95,0xf7}, {0x9c,0x46}, {0x95,0x5b}, {0x91,0xd1}, - {0x94,0xf4}, {0xfe,0x67}, {0x92,0xa5}, {0xfe,0xdf}, {0x8c,0xab}, {0x9b,0xc9}, {0xfc,0xed}, {0xfd,0xfa}, {0xfc,0xc8}, {0xfe,0x62}, - {0x91,0xfc}, {0xfe,0x6b}, {0xfd,0xf9}, {0xfc,0xc7}, {0x91,0x4e}, {0x9c,0xb8}, {0x97,0x67}, {0x95,0xee}, {0x9b,0xb2}, {0x94,0x60}, - {0x94,0xa2}, {0x98,0x75}, {0x97,0xac}, {0x91,0xd3}, {0x98,0x7b}, {0x8e,0xeb}, {0x97,0x6a}, {0x96,0x5e}, {0x97,0xeb}, {0x9f,0xf9}, - {0x95,0xf8}, {0xfe,0xa2}, {0x8f,0xe6}, {0xfe,0x7e}, {0x9d,0xa4}, {0x97,0x68}, {0x8e,0xec}, {0x94,0xbd}, {0x94,0x5b}, {0x9c,0xf6}, - {0xfa,0xa7}, {0x9b,0xd9}, {0xfa,0x5d}, {0x96,0x56}, {0x97,0x62}, {0x94,0xba}, {0xa0,0x4f}, {0x92,0xd8}, {0x9b,0xcb}, {0x94,0xbb}, - {0x9d,0x5f}, {0x90,0xcf}, {0x94,0x65}, {0x9f,0x4c}, {0x90,0xd8}, {0x9e,0xbe}, {0xfb,0x6d}, {0x95,0xca}, {0x9d,0xc2}, {0x97,0xf8}, - {0x8f,0xfc}, {0x94,0x73}, {0x94,0x74}, {0xfe,0xb7}, {0x8a,0x4b}, {0x8a,0x55}, {0x8b,0x69}, {0x8a,0xdc}, {0x8b,0x76}, {0x9b,0xce}, - {0x8a,0x68}, {0xa0,0xf8}, {0x98,0xdf}, {0xfe,0xb5}, {0x9b,0xcf}, {0x96,0xfb}, {0x9b,0xfb}, {0x9e,0xce}, {0x8e,0xe5}, {0x9e,0x7b}, - {0x9b,0xd2}, {0x8a,0xa5}, {0xfe,0xce}, {0x8a,0x45}, {0x9d,0xfc}, {0xfe,0xcf}, {0x8b,0xa5}, {0x8c,0x4a}, {0x8a,0xec}, {0xfc,0xe0}, - {0x94,0xad}, {0xfe,0xd5}, {0x94,0xac}, {0xfc,0x5a}, {0x9b,0xd6}, {0x8a,0x6f}, {0x8b,0xa9}, {0x8e,0x5f}, {0x9d,0xcb}, {0xfc,0xe7}, - {0x9b,0xd7}, {0x93,0xc8}, {0x91,0xf0}, {0x8f,0xe0}, {0x9b,0xdb}, {0x90,0xed}, {0x9b,0xdc}, {0xa0,0xec}, {0x98,0xfa}, {0x9b,0xe0}, - {0x93,0xc7}, {0x92,0x49}, {0x96,0xe1}, {0x9b,0xe2}, {0x9b,0xe4}, {0x8f,0xe1}, {0x9b,0xe5}, {0x94,0xc0}, {0x93,0xc3}, {0x93,0xc5}, - {0x90,0x79}, {0x97,0x7b}, {0x90,0x7e}, {0xfe,0xe6}, {0xfe,0x46}, {0x9d,0xb8}, {0x92,0x70}, {0x95,0xa8}, {0x8c,0xb0}, {0x94,0xc8}, - {0x98,0xb9}, {0x91,0x40}, {0xfc,0xbe}, {0x91,0x57}, {0x8b,0xb2}, {0xfa,0xdf}, {0x9b,0xe6}, {0x96,0x43}, {0x8e,0x44}, {0x9c,0x4f}, - {0xfe,0xf4}, {0x9b,0xe8}, {0x93,0xdc}, {0x96,0x6f}, {0x8e,0x4a}, {0x9b,0xed}, {0x92,0xf6}, {0x9d,0xb9}, {0x8e,0x4e}, {0xfb,0xcf}, - {0x9e,0xc2}, {0x94,0xe5}, {0x9b,0xf0}, {0x94,0xe4}, {0x95,0x51}, {0x8b,0xbb}, {0x9b,0xf1}, {0x94,0xf0}, {0x8e,0x64}, {0x94,0xea}, - {0x8f,0x61}, {0x9b,0x64}, {0x8e,0x5b}, {0x9b,0xf2}, {0x9f,0xbe}, {0x9d,0xc9}, {0x8e,0x6c}, {0x8f,0x73}, {0x8c,0xaf}, {0x8f,0x75}, - {0x8e,0x71}, {0x8e,0x60}, {0x8e,0x6a}, {0x8c,0x4c}, {0x95,0x52}, {0x95,0x54}, {0x8a,0xd4}, {0x9d,0xbb}, {0x95,0x43}, {0x92,0xfe}, - {0x94,0xf2}, {0x94,0xf1}, {0xa0,0xea}, {0x9d,0xd2}, {0xa0,0xb1}, {0x91,0xf8}, {0x94,0x62}, {0x9b,0xa4}, {0x8e,0xad}, {0x9e,0xad}, - {0x96,0xd0}, {0xfe,0xee}, {0x8a,0xb4}, {0x97,0x57}, {0x8a,0x77}, {0x9b,0xf7}, {0x8e,0xb5}, {0xa0,0x6d}, {0x8e,0xb6}, {0x97,0x56}, - {0x95,0x40}, {0xa0,0xf3}, {0x94,0xbe}, {0x9b,0xfa}, {0xfd,0xdf}, {0x9d,0xbc}, {0x94,0xfe}, {0x8b,0xdb}, {0xa0,0xfe}, {0x8e,0xc0}, - {0x9f,0x47}, {0x8b,0xde}, {0xa0,0xfb}, {0x8e,0xc3}, {0x96,0x49}, {0xfe,0xc2}, {0x95,0x4c}, {0x9b,0xfd}, {0x90,0xcc}, {0x9c,0x60}, - {0x95,0x4b}, {0x9b,0xfe}, {0x9c,0x70}, {0x9c,0x43}, {0x9c,0x47}, {0x8e,0xcc}, {0x8e,0x54}, {0x8e,0xe4}, {0x9c,0x49}, {0x8b,0x5e}, - {0x95,0x5e}, {0x95,0x5c}, {0x9c,0x4b}, {0x8b,0xe1}, {0x8e,0xd9}, {0x9d,0xb4}, {0x92,0x5f}, {0x9c,0x4c}, {0x8a,0xa1}, {0x8e,0xdb}, - {0x9c,0x56}, {0x8a,0xa2}, {0x97,0x54}, {0x9c,0x5e}, {0x9e,0xd4}, {0x95,0x68}, {0xa0,0xc3}, {0x8a,0xe6}, {0xa0,0xf7}, {0x9c,0x61}, - {0x9c,0x5f}, {0xfc,0x4d}, {0x9e,0x5b}, {0x9e,0x69}, {0x9c,0x63}, {0xfe,0xc7}, {0xfe,0xc6}, {0x9c,0x67}, {0x9c,0x69}, {0x8b,0xe2}, - {0x91,0x65}, {0x9c,0xe7}, {0x8a,0x54}, {0x9c,0x6c}, {0x9c,0x6e}, {0xfe,0x5d}, {0x9c,0x73}, {0x95,0x6a}, {0x95,0x6d}, {0x8e,0xf0}, - {0x8f,0x4d}, {0x8e,0xf6}, {0xfa,0xbc}, {0x8c,0xd5}, {0xfb,0xda}, {0x8b,0x4c}, {0xfd,0x75}, {0x9b,0xdd}, {0xfa,0xf5}, {0x9c,0x74}, - {0x95,0x45}, {0x96,0xc6}, {0x8f,0x6a}, {0x8f,0x4e}, {0x9c,0x78}, {0xfa,0x55}, {0x97,0xe4}, {0x9c,0x41}, {0x92,0x5c}, {0x96,0xfa}, - {0xfb,0x66}, {0x8e,0x65}, {0x98,0x49}, {0xfb,0xa8}, {0x98,0x42}, {0x9c,0x7a}, {0x97,0xfb}, {0x90,0xca}, {0x9c,0x5b}, {0x97,0x4d}, - {0x8e,0xd3}, {0x95,0x61}, {0x9f,0x4b}, {0x9f,0xb5}, {0x93,0xd2}, {0xfd,0xaa}, {0x98,0x40}, {0x91,0x46}, {0x98,0x67}, {0xfa,0x5a}, - {0xfb,0xa9}, {0x98,0x41}, {0x8c,0xd3}, {0xfc,0xfd}, {0xfd,0xab}, {0x91,0xbd}, {0x8f,0x4c}, {0x96,0xc9}, {0x8f,0x55}, {0xfb,0xae}, - {0x95,0x6f}, {0x9c,0x7d}, {0xa0,0xf0}, {0x94,0x6f}, {0xfd,0xac}, {0x96,0xcb}, {0x96,0xce}, {0xa0,0x56}, {0x9c,0xe1}, {0x96,0xc4}, - {0x8f,0x5e}, {0x8f,0x6c}, {0x8e,0xa3}, {0xfb,0xb3}, {0xfc,0x53}, {0xfd,0xb3}, {0x8f,0x6b}, {0x96,0xca}, {0x8f,0x79}, {0x9e,0x6f}, - {0xa0,0xc5}, {0xfc,0x78}, {0x8e,0x42}, {0x8f,0x5a}, {0x90,0xc2}, {0x8e,0xa5}, {0x90,0x61}, {0x92,0x4f}, {0x93,0x73}, {0xfd,0xb5}, - {0xfe,0xcc}, {0xfb,0xbd}, {0x8c,0xd6}, {0x98,0x43}, {0x96,0xc5}, {0x89,0xbc}, {0x9c,0xa3}, {0x92,0x4b}, {0x98,0x4a}, {0x8f,0xa4}, - {0xa0,0xf1}, {0x9e,0xfb}, {0x9c,0xd2}, {0x8f,0xa7}, {0xfc,0x5c}, {0x98,0x45}, {0x90,0x46}, {0x8c,0xd1}, {0xfe,0xfa}, {0x95,0x60}, - {0x9f,0x48}, {0x92,0x47}, {0x90,0xfb}, {0x9c,0xa4}, {0x95,0x71}, {0x9c,0xa6}, {0x9c,0xa7}, {0x9c,0xaa}, {0x9e,0xd3}, {0x9e,0x70}, - {0x9c,0xac}, {0x8f,0xae}, {0x95,0x7d}, {0x9c,0xb0}, {0x97,0xb6}, {0xa0,0xbd}, {0x8a,0xdf}, {0x9e,0xaa}, {0x8f,0xbd}, {0x8f,0xbf}, - {0x93,0x69}, {0x9b,0xa7}, {0xc8,0xa4}, {0xfe,0xea}, {0x9b,0xe1}, {0x8b,0x41}, {0x9d,0xb6}, {0xa0,0xeb}, {0x9b,0xa3}, {0x8b,0xa1}, - {0x8f,0xc8}, {0x89,0x4c}, {0x98,0x60}, {0x94,0xc7}, {0x8b,0x58}, {0x95,0xab}, {0x95,0xaa}, {0x9c,0xc3}, {0x9c,0xc4}, {0x93,0xd6}, - {0x9d,0xac}, {0x8b,0xe6}, {0x8a,0x71}, {0x8f,0xd1}, {0x99,0xd5}, {0x90,0xf4}, {0x8a,0xa3}, {0x9c,0xce}, {0x9c,0xd4}, {0x9c,0xd5}, - {0xfb,0xc8}, {0x9d,0xb3}, {0xfc,0x70}, {0x8f,0xd7}, {0x9b,0x73}, {0xfa,0x5b}, {0x8f,0xd2}, {0x90,0x64}, {0x98,0xb6}, {0x96,0x68}, - {0x9c,0xd6}, {0x98,0xbd}, {0x8f,0xdc}, {0xfe,0xf6}, {0x8f,0xd9}, {0x95,0x41}, {0x97,0xf3}, {0x9b,0xf8}, {0x9e,0x6c}, {0x8f,0xf2}, - {0x8f,0xee}, {0x9c,0xd7}, {0x9e,0x6e}, {0x8a,0x40}, {0x8f,0xef}, {0x8f,0xf4}, {0x8f,0xf5}, {0x95,0xc2}, {0x98,0x6a}, {0x97,0xcf}, - {0x9e,0x7c}, {0x90,0x41}, {0x9c,0xdb}, {0x94,0x41}, {0x9c,0xe6}, {0x9d,0xb0}, {0x9c,0xea}, {0x9c,0xed}, {0x9c,0xfa}, {0x8b,0x62}, - {0x8a,0x4e}, {0x9c,0xca}, {0x8a,0x66}, {0x9c,0xfb}, {0x9c,0xfc}, {0x9c,0xfe}, {0x8a,0x53}, {0x9c,0xe5}, {0x9d,0x40}, {0x9d,0x41}, - {0x90,0x45}, {0x8b,0x73}, {0x97,0xca}, {0x9d,0x42}, {0x8a,0x61}, {0x8b,0xae}, {0x8a,0xd2}, {0x8b,0xa2}, {0x9d,0xf2}, {0x9d,0x43}, - {0x9c,0xdf}, {0x9d,0x44}, {0x8e,0xca}, {0x90,0x4e}, {0x8e,0xb3}, {0x9f,0xf5}, {0x9d,0x45}, {0x90,0x4f}, {0x9d,0x47}, {0x89,0xca}, - {0x9c,0xb5}, {0xfb,0xfe}, {0x90,0x5e}, {0x90,0x63}, {0x90,0x57}, {0x90,0x66}, {0x9b,0xc0}, {0xfc,0xe5}, {0x91,0x62}, {0x90,0x67}, - {0x8f,0xa1}, {0x8f,0xa2}, {0x9d,0x48}, {0xfa,0xd3}, {0x90,0x5d}, {0x90,0xb9}, {0x90,0x6b}, {0x8c,0x5c}, {0x90,0x69}, {0xfe,0x57}, - {0xfe,0x55}, {0x90,0x73}, {0x9b,0xef}, {0x9c,0xf0}, {0x9d,0x4b}, {0xfe,0xd9}, {0xfe,0xda}, {0x91,0xe0}, {0x91,0xd8}, {0x96,0x46}, - {0x93,0x60}, {0xfa,0x53}, {0x9c,0xd3}, {0x9d,0x4e}, {0xfb,0x40}, {0x8d,0xe2}, {0x94,0x42}, {0x90,0x56}, {0x98,0x65}, {0x8c,0x6c}, - {0xfa,0x4a}, {0x9d,0x50}, {0x9d,0x52}, {0x95,0xaf}, {0x97,0x5a}, {0x93,0x49}, {0x97,0x47}, {0xa0,0xf4}, {0x97,0x78}, {0x8f,0xcf}, - {0xfc,0x60}, {0x8c,0x4e}, {0xfc,0x56}, {0x91,0xdc}, {0x96,0x61}, {0x92,0xec}, {0x93,0x5d}, {0x8e,0xde}, {0x96,0xfe}, {0xfd,0x4f}, - {0x95,0xde}, {0x98,0xb0}, {0xa0,0x40}, {0x97,0xbd}, {0x97,0x7d}, {0x97,0xf5}, {0x9b,0xac}, {0xfa,0xda}, {0x92,0xc2}, {0x97,0xb1}, - {0x90,0x7b}, {0x93,0xfe}, {0x94,0x7b}, {0x97,0x77}, {0xfa,0xbe}, {0xfd,0x43}, {0x90,0xc6}, {0x90,0xa4}, {0x90,0xa8}, {0x94,0xa9}, - {0x90,0xa9}, {0x8c,0x65}, {0x95,0xe0}, {0x90,0x7d}, {0x92,0x65}, {0xfd,0xba}, {0x93,0xc4}, {0xfe,0xed}, {0x9d,0xab}, {0xa0,0xe3}, - {0x96,0x48}, {0x9d,0x53}, {0x8a,0xa9}, {0x9b,0xc5}, {0x96,0x5d}, {0x97,0x5f}, {0x96,0x5f}, {0x96,0x6e}, {0xfb,0x5d}, {0x9d,0xb1}, - {0xfe,0xa3}, {0x9d,0xb2}, {0x95,0xae}, {0xfc,0xa3}, {0xa0,0xa2}, {0x96,0x55}, {0x9d,0x54}, {0x93,0x41}, {0x95,0xad}, {0x91,0xd5}, - {0x97,0x7a}, {0xfd,0xfc}, {0x8e,0x47}, {0x93,0xfd}, {0x90,0xa5}, {0x90,0xac}, {0x95,0xac}, {0x90,0xae}, {0xfe,0xa5}, {0x9d,0x56}, - {0x97,0xe3}, {0x95,0xe2}, {0x94,0x66}, {0x96,0x47}, {0x91,0xb8}, {0x9c,0xec}, {0x90,0xad}, {0x95,0xe3}, {0x8b,0x4f}, {0x8a,0xe3}, - {0x8b,0x4d}, {0x95,0xea}, {0x8b,0x4e}, {0x8c,0xc1}, {0x8b,0xed}, {0x91,0xd9}, {0xa0,0xa4}, {0x95,0xf5}, {0x95,0xf4}, {0x9f,0xb3}, - {0xfe,0xaf}, {0xfe,0x72}, {0x92,0x7a}, {0xfe,0xac}, {0x95,0xf3}, {0x9d,0x58}, {0x93,0x72}, {0x91,0xc5}, {0x96,0x42}, {0x90,0xcd}, - {0x95,0xfe}, {0x91,0x59}, {0x9c,0x65}, {0x97,0xcc}, {0x90,0xce}, {0x9d,0x59}, {0xfc,0xf5}, {0xfe,0xfd}, {0x9d,0x5b}, {0x9d,0x5c}, - {0x93,0x7e}, {0x98,0xac}, {0x9d,0x5e}, {0xfd,0xd0}, {0xfd,0x60}, {0x9c,0xcf}, {0x90,0xdd}, {0x90,0xe0}, {0x90,0xf3}, {0x98,0xb1}, - {0x90,0xf0}, {0x93,0xbd}, {0x95,0xb7}, {0x9f,0x46}, {0x8e,0x4b}, {0x96,0x58}, {0x8a,0x4c}, {0x9d,0x63}, {0x9e,0xcf}, {0x9d,0x65}, - {0x9d,0x66}, {0x96,0x5a}, {0x9d,0x64}, {0x8a,0x6c}, {0x8a,0xd9}, {0x9d,0x67}, {0x8a,0x70}, {0x8b,0xf3}, {0x91,0x50}, {0x9c,0xc1}, - {0x9d,0x68}, {0x93,0xa7}, {0x96,0x74}, {0xa0,0xef}, {0x91,0x51}, {0x96,0xc1}, {0x8c,0x64}, {0x96,0x76}, {0x9d,0x69}, {0xfc,0xa4}, - {0x9d,0x6a}, {0x92,0x4e}, {0x9d,0x6b}, {0x9b,0xc1}, {0x9d,0x6c}, {0x8a,0x65}, {0x91,0x5d}, {0x9d,0x6d}, {0x91,0x5a}, {0x8c,0x42}, - {0x9c,0xc0}, {0x91,0x6a}, {0x9d,0x6e}, {0x9e,0xa6}, {0x9d,0xcd}, {0x9d,0x6f}, {0x89,0xbb}, {0x9e,0xf9}, {0x96,0xb4}, {0x91,0x72}, - {0x9e,0xc8}, {0x8b,0x55}, {0x9d,0x71}, {0x9d,0x72}, {0x9e,0xcc}, {0x91,0x74}, {0x9e,0xd0}, {0x90,0x5c}, {0x8e,0xd2}, {0x91,0xa8}, - {0x91,0x77}, {0x96,0xbf}, {0x96,0xc0}, {0x8f,0xb1}, {0x96,0xb7}, {0x8c,0x55}, {0x91,0x78}, {0x89,0xbe}, {0x91,0x7c}, {0xfb,0x77}, - {0x91,0x75}, {0x91,0xa3}, {0x91,0x76}, {0x96,0xbe}, {0x91,0x79}, {0x96,0xb6}, {0x91,0xa4}, {0x91,0xa6}, {0x9d,0x75}, {0x90,0x52}, - {0xa0,0x45}, {0x91,0xa9}, {0x98,0xaa}, {0x8c,0x5f}, {0x8b,0xaa}, {0x9c,0xdd}, {0x9d,0x77}, {0x89,0x40}, {0x9e,0xec}, {0x93,0xaa}, - {0x94,0x78}, {0x9d,0x7a}, {0x8a,0xc9}, {0x8b,0x4b}, {0x9f,0xec}, {0x8a,0xe2}, {0x9e,0x75}, {0x98,0x74}, {0x9a,0xc8}, {0xa0,0x47}, - {0x8b,0xc3}, {0xfc,0x48}, {0xfc,0x77}, {0x9c,0x52}, {0x8e,0xfd}, {0x8f,0xa8}, {0x95,0x7a}, {0x8f,0xf0}, -}; - - -/* Index of the convert table */ -static const Summary16 big5hkscs_uni2index_page00[70] = { - /* 0x0000 */ - { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, - { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, - { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0xE7EE }, { 12, 0x87BF }, - { 23, 0xFFFF }, { 39, 0xFFFF }, { 55, 0xFFFF }, { 71, 0xFFFF }, - /* 0x0100 */ - { 87, 0x0003 }, { 89, 0x0C0C }, { 93, 0x0800 }, { 94, 0x0000 }, - { 94, 0x3800 }, { 97, 0x0008 }, { 98, 0x0800 }, { 99, 0x0000 }, - { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, - { 99, 0x6000 }, { 101, 0x1557 }, { 109, 0x0000 }, { 109, 0x0000 }, - /* 0x0200 */ - { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 }, - { 109, 0x0000 }, { 109, 0x0813 }, { 113, 0x0402 }, { 115, 0x0020 }, - { 116, 0x0408 }, { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, - { 118, 0x2EC0 }, { 124, 0x0200 }, { 125, 0x0000 }, { 125, 0x0000 }, - /* 0x0300 */ - { 125, 0x0020 }, { 126, 0x0000 }, { 126, 0x0000 }, { 126, 0x0000 }, - { 126, 0x0000 }, { 126, 0x0000 }, { 126, 0x0000 }, { 126, 0x0000 }, - { 126, 0x0000 }, { 126, 0xFFFE }, { 141, 0x03FB }, { 150, 0xFFFE }, - { 165, 0x03FB }, { 174, 0x0000 }, { 174, 0x0000 }, { 174, 0x0000 }, - /* 0x0400 */ - { 174, 0x0002 }, { 175, 0xFFFF }, { 191, 0xFFFF }, { 207, 0xFFFF }, - { 223, 0xFFFF }, { 239, 0x0002 }, -}; -static const Summary16 big5hkscs_uni2index_page1e[13] = { - /* 0x1E00 */ - { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, - { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, - { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0xC000 }, - { 242, 0x0003 }, -}; -static const Summary16 big5hkscs_uni2index_page20[116] = { - /* 0x2000 */ - { 244, 0x0000 }, { 244, 0x3378 }, { 252, 0x00F4 }, { 257, 0x482C }, - { 262, 0x0000 }, { 262, 0x0000 }, { 262, 0x0000 }, { 262, 0x0000 }, - { 262, 0x0000 }, { 262, 0x0000 }, { 262, 0x1000 }, { 263, 0x0000 }, - { 263, 0x0000 }, { 263, 0x0000 }, { 263, 0x0000 }, { 263, 0x0000 }, - /* 0x2100 */ - { 263, 0x0228 }, { 266, 0x0040 }, { 267, 0x0002 }, { 268, 0x0000 }, - { 268, 0x0000 }, { 268, 0x0000 }, { 268, 0x03FF }, { 278, 0x03FF }, - { 288, 0x0000 }, { 288, 0x03CF }, { 296, 0x0000 }, { 296, 0x0300 }, - { 298, 0x0000 }, { 298, 0x0000 }, { 298, 0x0080 }, { 299, 0x0000 }, - /* 0x2200 */ - { 299, 0x0000 }, { 299, 0xC560 }, { 305, 0x4E29 }, { 312, 0x0030 }, - { 314, 0x0000 }, { 314, 0x0004 }, { 315, 0x00CB }, { 320, 0x0000 }, - { 320, 0x0000 }, { 320, 0x0220 }, { 322, 0x0020 }, { 323, 0x8000 }, - { 324, 0x0000 }, { 324, 0x0000 }, { 324, 0x0000 }, { 324, 0x0000 }, - /* 0x2300 */ - { 324, 0x0080 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, - { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, - { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, - { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, - /* 0x2400 */ - { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, - { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x03FF }, { 335, 0x3FF0 }, - { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, - { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, - /* 0x2500 */ - { 345, 0x1005 }, { 348, 0x1111 }, { 352, 0x1010 }, { 354, 0x1010 }, - { 356, 0x0000 }, { 356, 0xFFFF }, { 372, 0xFFFF }, { 388, 0x001F }, - { 393, 0xFFFE }, { 408, 0x0038 }, { 411, 0x0003 }, { 413, 0x300C }, - { 417, 0xC8C0 }, { 422, 0x0000 }, { 422, 0x003C }, { 426, 0x0000 }, - /* 0x2600 */ - { 426, 0x0260 }, { 429, 0x0000 }, { 429, 0x0000 }, { 429, 0x0000 }, - { 429, 0x0007 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, - { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, - { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, - /* 0x2700 */ - { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x2000 }, -}; -static const Summary16 big5hkscs_uni2index_page2e[1819] = { - /* 0x2E00 */ - { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 }, - { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 }, - { 433, 0x35D1 }, { 441, 0x3020 }, { 444, 0x54A0 }, { 449, 0x5040 }, - { 452, 0xB440 }, { 457, 0x40C0 }, { 460, 0x0008 }, { 461, 0x0000 }, - /* 0x2F00 */ - { 461, 0x0000 }, { 461, 0x0000 }, { 461, 0x0000 }, { 461, 0x0008 }, - { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, - { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, - { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, - /* 0x3000 */ - { 462, 0xFFEF }, { 477, 0x7037 }, { 485, 0x03FE }, { 494, 0x0001 }, - { 495, 0xFFFE }, { 510, 0xFFFF }, { 526, 0xFFFF }, { 542, 0xFFFF }, - { 558, 0xFFFF }, { 574, 0x780F }, { 582, 0xFFFE }, { 597, 0xFFFF }, - { 613, 0xFFFF }, { 629, 0xFFFF }, { 645, 0xFFFF }, { 661, 0x707F }, - /* 0x3100 */ - { 671, 0xFFE0 }, { 682, 0xFFFF }, { 698, 0x03FF }, { 708, 0x0000 }, - { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, - { 708, 0x0000 }, { 708, 0xFFFC }, { 722, 0x0000 }, { 722, 0x0000 }, - { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0x0000 }, - /* 0x3200 */ - { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0xFFFF }, { 738, 0xFFFF }, - { 754, 0x000F }, { 758, 0x0000 }, { 758, 0x0000 }, { 758, 0x0000 }, - { 758, 0xFFFF }, { 774, 0xFFFF }, { 790, 0xFFFF }, { 806, 0x0001 }, - { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, - /* 0x3300 */ - { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, - { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, - { 807, 0xC000 }, { 809, 0x7000 }, { 812, 0x0002 }, { 813, 0x0000 }, - { 813, 0x4010 }, { 815, 0x0026 }, { 818, 0x0000 }, { 818, 0x0000 }, - /* 0x3400 */ - { 818, 0x0000 }, { 818, 0x0000 }, { 818, 0x0000 }, { 818, 0x0020 }, - { 819, 0x1001 }, { 821, 0x0000 }, { 821, 0x0010 }, { 822, 0x6408 }, - { 826, 0x0000 }, { 826, 0x0048 }, { 828, 0x8020 }, { 830, 0x1000 }, - { 831, 0x0102 }, { 833, 0x8000 }, { 834, 0x0010 }, { 835, 0x0800 }, - /* 0x3500 */ - { 836, 0x0040 }, { 837, 0x0000 }, { 837, 0x0000 }, { 837, 0x4000 }, - { 838, 0x0000 }, { 838, 0x020A }, { 841, 0x2002 }, { 843, 0x0185 }, - { 847, 0x0010 }, { 848, 0x0180 }, { 850, 0x2022 }, { 853, 0x8000 }, - { 854, 0x44A2 }, { 859, 0x2844 }, { 863, 0x0000 }, { 863, 0x480E }, - /* 0x3600 */ - { 868, 0x0200 }, { 869, 0x0500 }, { 871, 0x2008 }, { 873, 0x4220 }, - { 876, 0x4380 }, { 880, 0x8000 }, { 881, 0x0000 }, { 881, 0x0400 }, - { 882, 0x0002 }, { 883, 0x0400 }, { 884, 0x1420 }, { 887, 0x1223 }, - { 892, 0x01BA }, { 898, 0x2058 }, { 902, 0x0066 }, { 906, 0x0020 }, - /* 0x3700 */ - { 907, 0x250A }, { 912, 0x1000 }, { 913, 0x302C }, { 918, 0x040D }, - { 922, 0x0009 }, { 924, 0x0000 }, { 924, 0x8004 }, { 926, 0x0000 }, - { 926, 0x0000 }, { 926, 0x0080 }, { 927, 0x0001 }, { 928, 0x4200 }, - { 930, 0x0000 }, { 930, 0x0000 }, { 930, 0x0000 }, { 930, 0x0904 }, - /* 0x3800 */ - { 933, 0x8000 }, { 934, 0x0200 }, { 935, 0x2001 }, { 937, 0x0140 }, - { 939, 0x0000 }, { 939, 0x0000 }, { 939, 0x0008 }, { 940, 0x0000 }, - { 940, 0x0000 }, { 940, 0x0000 }, { 940, 0x0001 }, { 941, 0x0000 }, - { 941, 0x1008 }, { 943, 0x0002 }, { 944, 0x0000 }, { 944, 0x0400 }, - /* 0x3900 */ - { 945, 0x0100 }, { 946, 0x0010 }, { 947, 0x0080 }, { 948, 0x8004 }, - { 950, 0x2000 }, { 951, 0x0000 }, { 951, 0x0008 }, { 952, 0x0000 }, - { 952, 0x0601 }, { 955, 0x0A04 }, { 958, 0x0012 }, { 960, 0x0100 }, - { 961, 0x0000 }, { 961, 0x1000 }, { 962, 0x1024 }, { 965, 0x4900 }, - /* 0x3A00 */ - { 968, 0x004A }, { 971, 0x0180 }, { 973, 0x0600 }, { 975, 0x0010 }, - { 976, 0x0800 }, { 977, 0x5084 }, { 981, 0x00C0 }, { 983, 0x0000 }, - { 983, 0x0000 }, { 983, 0x0080 }, { 984, 0x0800 }, { 985, 0x2000 }, - { 986, 0x0000 }, { 986, 0x4000 }, { 987, 0x0001 }, { 988, 0x0805 }, - /* 0x3B00 */ - { 991, 0x4000 }, { 992, 0x0200 }, { 993, 0x0804 }, { 995, 0x0200 }, - { 996, 0x0004 }, { 997, 0x0100 }, { 998, 0x0001 }, { 999, 0x1806 }, - { 1003, 0x0001 }, { 1004, 0x0240 }, { 1006, 0x0002 }, { 1007, 0x5000 }, - { 1009, 0x0014 }, { 1011, 0x2080 }, { 1013, 0x1000 }, { 1014, 0x001C }, - /* 0x3C00 */ - { 1017, 0x2000 }, { 1018, 0x0122 }, { 1021, 0x0000 }, { 1021, 0x0000 }, - { 1021, 0x0000 }, { 1021, 0x0010 }, { 1022, 0x0000 }, { 1022, 0x0000 }, - { 1022, 0x0800 }, { 1023, 0x0000 }, { 1023, 0x0000 }, { 1023, 0x0000 }, - { 1023, 0x2800 }, { 1025, 0x1042 }, { 1028, 0x8800 }, { 1030, 0x0000 }, - /* 0x3D00 */ - { 1030, 0x0000 }, { 1030, 0x2008 }, { 1032, 0x0000 }, { 1032, 0x0804 }, - { 1034, 0x5040 }, { 1037, 0x8002 }, { 1039, 0x8604 }, { 1043, 0x2020 }, - { 1045, 0x8420 }, { 1048, 0x0002 }, { 1049, 0x2020 }, { 1051, 0x8010 }, - { 1053, 0x32C0 }, { 1058, 0x0808 }, { 1060, 0x0980 }, { 1063, 0x3088 }, - /* 0x3E00 */ - { 1067, 0x0040 }, { 1068, 0x0000 }, { 1068, 0x0000 }, { 1068, 0x0000 }, - { 1068, 0x0109 }, { 1071, 0x0020 }, { 1072, 0x0000 }, { 1072, 0x0010 }, - { 1073, 0x0000 }, { 1073, 0x0000 }, { 1073, 0x2700 }, { 1077, 0x8102 }, - { 1080, 0x1484 }, { 1084, 0x4CC3 }, { 1091, 0x0A86 }, { 1096, 0x9419 }, - /* 0x3F00 */ - { 1102, 0x4051 }, { 1106, 0x0000 }, { 1106, 0x0000 }, { 1106, 0x0000 }, - { 1106, 0x0000 }, { 1106, 0x0308 }, { 1109, 0x0008 }, { 1110, 0x1000 }, - { 1111, 0x0000 }, { 1111, 0x0008 }, { 1112, 0x0000 }, { 1112, 0x0000 }, - { 1112, 0x0001 }, { 1113, 0x1080 }, { 1115, 0x2020 }, { 1117, 0x0600 }, - /* 0x4000 */ - { 1119, 0x0210 }, { 1121, 0x2000 }, { 1122, 0x0000 }, { 1122, 0x0200 }, - { 1123, 0x0020 }, { 1124, 0x0088 }, { 1126, 0x8424 }, { 1130, 0x0002 }, - { 1131, 0x0000 }, { 1131, 0x0000 }, { 1131, 0x0100 }, { 1132, 0x8800 }, - { 1134, 0x0100 }, { 1135, 0x8100 }, { 1137, 0x0000 }, { 1137, 0x0400 }, - /* 0x4100 */ - { 1138, 0x4218 }, { 1142, 0x0000 }, { 1142, 0x0000 }, { 1142, 0x0004 }, - { 1143, 0x0000 }, { 1143, 0x0000 }, { 1143, 0x5080 }, { 1146, 0x8000 }, - { 1147, 0x0000 }, { 1147, 0x0001 }, { 1148, 0x0000 }, { 1148, 0x0004 }, - { 1149, 0x8410 }, { 1152, 0x0800 }, { 1153, 0x8000 }, { 1154, 0x0200 }, - /* 0x4200 */ - { 1155, 0x0000 }, { 1155, 0x0002 }, { 1156, 0x0008 }, { 1157, 0x0000 }, - { 1157, 0x0001 }, { 1158, 0x0000 }, { 1158, 0x0401 }, { 1160, 0x0440 }, - { 1162, 0x1000 }, { 1163, 0x0010 }, { 1164, 0x0004 }, { 1165, 0x1220 }, - { 1168, 0x0000 }, { 1168, 0x0000 }, { 1168, 0x0000 }, { 1168, 0x1810 }, - /* 0x4300 */ - { 1171, 0x0000 }, { 1171, 0x0000 }, { 1171, 0x0800 }, { 1172, 0x0000 }, - { 1172, 0x0000 }, { 1172, 0x0000 }, { 1172, 0x4000 }, { 1173, 0x0000 }, - { 1173, 0x0000 }, { 1173, 0x0080 }, { 1174, 0x0000 }, { 1174, 0x0400 }, - { 1175, 0x0002 }, { 1176, 0x8200 }, { 1178, 0x2000 }, { 1179, 0x0004 }, - /* 0x4400 */ - { 1180, 0x0006 }, { 1182, 0x0008 }, { 1183, 0x2020 }, { 1185, 0x0000 }, - { 1185, 0x0000 }, { 1185, 0x0000 }, { 1185, 0x0000 }, { 1185, 0x0400 }, - { 1186, 0x8000 }, { 1187, 0x8000 }, { 1188, 0x0005 }, { 1190, 0x0081 }, - { 1192, 0x4021 }, { 1195, 0xA000 }, { 1197, 0x1E10 }, { 1202, 0x0010 }, - /* 0x4500 */ - { 1203, 0x0A18 }, { 1207, 0x2040 }, { 1209, 0x4080 }, { 1211, 0xA808 }, - { 1215, 0x0008 }, { 1216, 0x1026 }, { 1220, 0x0404 }, { 1222, 0x0080 }, - { 1223, 0x0020 }, { 1224, 0x0000 }, { 1224, 0x0000 }, { 1224, 0x0000 }, - { 1224, 0x0000 }, { 1224, 0x0000 }, { 1224, 0x0200 }, { 1225, 0x0000 }, - /* 0x4600 */ - { 1225, 0x8040 }, { 1227, 0x00A0 }, { 1229, 0x0000 }, { 1229, 0x0000 }, - { 1229, 0x0000 }, { 1229, 0x0800 }, { 1230, 0x0000 }, { 1230, 0x0400 }, - { 1231, 0x0001 }, { 1232, 0x0000 }, { 1232, 0x0000 }, { 1232, 0x0000 }, - { 1232, 0x8000 }, { 1233, 0x0001 }, { 1234, 0x0000 }, { 1234, 0x0020 }, - /* 0x4700 */ - { 1235, 0x0000 }, { 1235, 0x0108 }, { 1237, 0x0000 }, { 1237, 0x0000 }, - { 1237, 0x4000 }, { 1238, 0x0000 }, { 1238, 0x0000 }, { 1238, 0x1000 }, - { 1239, 0x0000 }, { 1239, 0x0100 }, { 1240, 0x0040 }, { 1241, 0x0040 }, - { 1242, 0x0000 }, { 1242, 0x0020 }, { 1243, 0x2000 }, { 1244, 0x0010 }, - /* 0x4800 */ - { 1245, 0x0801 }, { 1247, 0x0000 }, { 1247, 0x0000 }, { 1247, 0x0080 }, - { 1248, 0x0000 }, { 1248, 0x2000 }, { 1249, 0x0000 }, { 1249, 0x0002 }, - { 1250, 0x0000 }, { 1250, 0x0800 }, { 1251, 0x6000 }, { 1253, 0x0000 }, - { 1253, 0x0000 }, { 1253, 0x2001 }, { 1255, 0x2000 }, { 1256, 0x0408 }, - /* 0x4900 */ - { 1258, 0x0040 }, { 1259, 0x4002 }, { 1261, 0x2420 }, { 1264, 0x5020 }, - { 1267, 0x0020 }, { 1268, 0x000A }, { 1270, 0x0420 }, { 1272, 0x0004 }, - { 1273, 0x0200 }, { 1274, 0x0000 }, { 1274, 0x0082 }, { 1276, 0x0000 }, - { 1276, 0x0000 }, { 1276, 0x8000 }, { 1277, 0x00A0 }, { 1279, 0x0000 }, - /* 0x4A00 */ - { 1279, 0x8000 }, { 1280, 0x2000 }, { 1281, 0x0010 }, { 1282, 0x0020 }, - { 1283, 0x0000 }, { 1283, 0x0000 }, { 1283, 0x0000 }, { 1283, 0x0000 }, - { 1283, 0x0000 }, { 1283, 0x0040 }, { 1284, 0x0000 }, { 1284, 0x0110 }, - { 1286, 0x0000 }, { 1286, 0x0002 }, { 1287, 0x0010 }, { 1288, 0x8000 }, - /* 0x4B00 */ - { 1289, 0x0000 }, { 1289, 0x0201 }, { 1291, 0x1001 }, { 1293, 0x0080 }, - { 1294, 0x0000 }, { 1294, 0x0000 }, { 1294, 0x8000 }, { 1295, 0x4805 }, - { 1299, 0x4000 }, { 1300, 0x20C9 }, { 1305, 0x0000 }, { 1305, 0x6000 }, - { 1307, 0x0001 }, { 1308, 0x0000 }, { 1308, 0x0000 }, { 1308, 0x0000 }, - /* 0x4C00 */ - { 1308, 0x4090 }, { 1311, 0x0000 }, { 1311, 0x0000 }, { 1311, 0x4800 }, - { 1313, 0x0000 }, { 1313, 0x0800 }, { 1314, 0x2000 }, { 1315, 0x2000 }, - { 1316, 0x0002 }, { 1317, 0x0000 }, { 1317, 0x4010 }, { 1319, 0x0081 }, - { 1321, 0x2000 }, { 1322, 0x0000 }, { 1322, 0x2002 }, { 1324, 0x0000 }, - /* 0x4D00 */ - { 1324, 0x0200 }, { 1325, 0x0001 }, { 1326, 0x0000 }, { 1326, 0x0010 }, - { 1327, 0x0000 }, { 1327, 0x0000 }, { 1327, 0x0000 }, { 1327, 0x0000 }, - { 1327, 0x0000 }, { 1327, 0x1002 }, { 1329, 0x0000 }, { 1329, 0x0000 }, - { 1329, 0x0000 }, { 1329, 0x0000 }, { 1329, 0x0000 }, { 1329, 0x0000 }, - /* 0x4E00 */ - { 1329, 0xFF9B }, { 1342, 0xD773 }, { 1353, 0xFD52 }, { 1363, 0xBBCF }, - { 1375, 0xEBAC }, { 1385, 0xFF4C }, { 1396, 0x0600 }, { 1398, 0xC108 }, - { 1402, 0x7BFF }, { 1416, 0xCF3E }, { 1427, 0x797F }, { 1439, 0x9EC8 }, - { 1447, 0x6FDF }, { 1460, 0xF7F0 }, { 1471, 0x4F3A }, { 1480, 0xA9FF }, - /* 0x4F00 */ - { 1492, 0xEF3F }, { 1505, 0x27BF }, { 1516, 0xB304 }, { 1522, 0xFFDD }, - { 1536, 0xFBEE }, { 1549, 0xFFFF }, { 1565, 0xDE9F }, { 1577, 0xFFFD }, - { 1592, 0xAFFF }, { 1606, 0x7DF7 }, { 1619, 0xC904 }, { 1624, 0xAEED }, - { 1635, 0xFFBF }, { 1650, 0xFFDB }, { 1664, 0xD033 }, { 1671, 0x67FF }, - /* 0x5000 */ - { 1684, 0xFBE9 }, { 1696, 0xDFFE }, { 1710, 0xFFEF }, { 1725, 0x18BB }, - { 1733, 0xFFEB }, { 1747, 0xFDEA }, { 1759, 0xFF7F }, { 1774, 0x24FD }, - { 1783, 0x79AF }, { 1794, 0x7F77 }, { 1807, 0xF04C }, { 1814, 0xFDFF }, - { 1829, 0xEFF6 }, { 1842, 0xAEFB }, { 1854, 0xF7FB }, { 1868, 0xFB7B }, - /* 0x5100 */ - { 1881, 0x7FFF }, { 1896, 0x95BF }, { 1907, 0x6E77 }, { 1918, 0xBFBF }, - { 1932, 0x3BFB }, { 1944, 0xFEF4 }, { 1956, 0x7FAF }, { 1969, 0x13F2 }, - { 1977, 0xA7C5 }, { 1986, 0x55FE }, { 1997, 0x5DB5 }, { 2007, 0x73FF }, - { 2020, 0xFFF8 }, { 2033, 0xF99F }, { 2045, 0x2017 }, { 2050, 0x777B }, - /* 0x5200 */ - { 2062, 0x5FEF }, { 2075, 0xF0CF }, { 2085, 0x47F3 }, { 2095, 0x1DFF }, - { 2107, 0x7EDA }, { 2118, 0xFEF4 }, { 2130, 0xFF07 }, { 2141, 0xBFBC }, - { 2153, 0xBF9F }, { 2166, 0x8FDB }, { 2177, 0x7F5B }, { 2189, 0x5A20 }, - { 2194, 0x32AF }, { 2203, 0xEBEF }, { 2216, 0x8A5F }, { 2225, 0xDFBB }, - /* 0x5300 */ - { 2238, 0xEF62 }, { 2248, 0xB6E7 }, { 2259, 0xB49F }, { 2269, 0xFB9F }, - { 2282, 0x77BF }, { 2295, 0xF49E }, { 2305, 0xF2DB }, { 2316, 0xFBBF }, - { 2330, 0xC414 }, { 2335, 0xF7DC }, { 2347, 0x7FF5 }, { 2360, 0x0A55 }, - { 2366, 0x3F2E }, { 2376, 0x8FD7 }, { 2387, 0xFF7F }, { 2402, 0x59EF }, - /* 0x5400 */ - { 2413, 0xFFDA }, { 2426, 0xFF5F }, { 2440, 0xFFFB }, { 2455, 0x7BFF }, - { 2469, 0xEDEF }, { 2482, 0x0010 }, { 2483, 0xBFFF }, { 2498, 0xFDFF }, - { 2513, 0xF9F7 }, { 2526, 0x55FF }, { 2538, 0xFFFF }, { 2554, 0xFFDF }, - { 2569, 0xFBFF }, { 2584, 0x4441 }, { 2588, 0xEFFF }, { 2603, 0xBD8E }, - /* 0x5500 */ - { 2613, 0xFFFE }, { 2628, 0x459F }, { 2637, 0xFDE8 }, { 2648, 0xDBFF }, - { 2662, 0xEFFB }, { 2676, 0xF0EF }, { 2687, 0x0E7E }, { 2696, 0xFAEE }, - { 2708, 0xFFDF }, { 2723, 0xB73F }, { 2735, 0x7FFE }, { 2749, 0x9E3F }, - { 2760, 0xFFFF }, { 2776, 0xFFFF }, { 2792, 0x97FE }, { 2804, 0xFEE7 }, - /* 0x5600 */ - { 2817, 0xF377 }, { 2829, 0xF8FF }, { 2842, 0xF6AF }, { 2854, 0xEFFD }, - { 2868, 0xF76F }, { 2881, 0x679D }, { 2891, 0xFF7F }, { 2906, 0xDFDF }, - { 2920, 0xFEFF }, { 2935, 0xF7AD }, { 2947, 0xFDF2 }, { 2959, 0xF2FE }, - { 2971, 0x3F6F }, { 2983, 0xECDA }, { 2993, 0xECB7 }, { 3004, 0xA683 }, - /* 0x5700 */ - { 3011, 0x3F9F }, { 3023, 0xFD7C }, { 3035, 0xF70D }, { 3045, 0xE81D }, - { 3053, 0xFEEF }, { 3067, 0x8897 }, { 3074, 0xAFD6 }, { 3085, 0xFCFF }, - { 3099, 0xBD0D }, { 3108, 0xFFB9 }, { 3121, 0x44BF }, { 3130, 0xFF70 }, - { 3141, 0xD9DE }, { 3152, 0xF0B5 }, { 3161, 0xF2FF }, { 3174, 0x7FFF }, - /* 0x5800 */ - { 3189, 0x7FFF }, { 3204, 0x7A15 }, { 3212, 0xF7FF }, { 3227, 0xAFFF }, - { 3241, 0xFF91 }, { 3252, 0xFFBE }, { 3266, 0xBB3C }, { 3276, 0xFE7E }, - { 3289, 0xCFEF }, { 3302, 0xF71F }, { 3314, 0xDFEB }, { 3327, 0xFC6B }, - { 3338, 0xCBE6 }, { 3348, 0xFF7F }, { 3363, 0x9B9D }, { 3373, 0xFE1D }, - /* 0x5900 */ - { 3384, 0xF4FC }, { 3395, 0x96F6 }, { 3405, 0xFEB5 }, { 3417, 0x5196 }, - { 3424, 0xC7B1 }, { 3433, 0x15BB }, { 3442, 0x6EA7 }, { 3452, 0xFBFF }, - { 3467, 0xE63F }, { 3478, 0xE7DD }, { 3490, 0xD1FF }, { 3502, 0x7FFF }, - { 3517, 0xFFFB }, { 3532, 0x7F5F }, { 3545, 0xFF7B }, { 3559, 0xFFFF }, - /* 0x5A00 */ - { 3575, 0xBE0F }, { 3585, 0xDFEE }, { 3598, 0x7EBB }, { 3610, 0x73E8 }, - { 3619, 0x37FF }, { 3632, 0xFFFF }, { 3648, 0x7FFF }, { 3663, 0xFF83 }, - { 3674, 0xDD5E }, { 3685, 0xFEFF }, { 3700, 0xDAE7 }, { 3711, 0xFFFF }, - { 3727, 0xFFDF }, { 3742, 0xFFE8 }, { 3754, 0x7F7F }, { 3768, 0xEFFD }, - /* 0x5B00 */ - { 3782, 0xBBAE }, { 3793, 0xEEFB }, { 3806, 0xFDFB }, { 3820, 0xF115 }, - { 3828, 0xFDFB }, { 3842, 0xBDFB }, { 3855, 0x7B7C }, { 3866, 0xBDFF }, - { 3880, 0xDBBF }, { 3893, 0xFFED }, { 3907, 0x75FC }, { 3918, 0x8379 }, - { 3926, 0x7CFF }, { 3939, 0xC3FF }, { 3951, 0xDFFF }, { 3966, 0x856F }, - /* 0x5C00 */ - { 3975, 0xFFBA }, { 3988, 0xD47F }, { 3999, 0x153D }, { 4007, 0xDF8B }, - { 4018, 0xFFF3 }, { 4032, 0x737B }, { 4043, 0xF7BD }, { 4056, 0x5E1A }, - { 4064, 0xBF60 }, { 4073, 0xF63F }, { 4085, 0xFFFF }, { 4101, 0x05EB }, - { 4109, 0xDFC6 }, { 4120, 0xCFDF }, { 4133, 0xF720 }, { 4141, 0xABF3 }, - /* 0x5D00 */ - { 4152, 0xF8C3 }, { 4161, 0xEFF7 }, { 4175, 0xD3FD }, { 4187, 0xF7FF }, - { 4202, 0x5FEF }, { 4215, 0x4AE7 }, { 4224, 0x9BAC }, { 4233, 0xFE97 }, - { 4245, 0x6FF7 }, { 4258, 0xF6BC }, { 4269, 0xFF97 }, { 4282, 0x37F7 }, - { 4294, 0xAACF }, { 4304, 0xE9F6 }, { 4315, 0x49E7 }, { 4324, 0xE2BF }, - /* 0x5E00 */ - { 4335, 0x5E5C }, { 4344, 0xAFF6 }, { 4356, 0x6B3F }, { 4367, 0x61D8 }, - { 4374, 0xFD3F }, { 4387, 0xFBB8 }, { 4398, 0xFFCF }, { 4412, 0xFF7D }, - { 4426, 0xBFDD }, { 4439, 0x1EE4 }, { 4447, 0x7DFD }, { 4460, 0x63FF }, - { 4472, 0x7FF6 }, { 4485, 0xFFFF }, { 4501, 0xD3EF }, { 4513, 0xDFDE }, - /* 0x5F00 */ - { 4526, 0xFDB6 }, { 4538, 0xADBC }, { 4548, 0x63FC }, { 4558, 0x15EB }, - { 4567, 0xFF59 }, { 4579, 0x33D3 }, { 4588, 0xBEBE }, { 4600, 0xFBDF }, - { 4614, 0x1FEF }, { 4626, 0xDBC7 }, { 4637, 0xFFF3 }, { 4651, 0xFEE6 }, - { 4663, 0xB23F }, { 4673, 0xEBF7 }, { 4686, 0xED3B }, { 4697, 0xADBA }, - /* 0x6000 */ - { 4707, 0xFE01 }, { 4715, 0x7EFF }, { 4729, 0xFFFF }, { 4745, 0x0ABE }, - { 4753, 0x36FF }, { 4765, 0xEF3D }, { 4777, 0xFFFC }, { 4791, 0xC0A5 }, - { 4797, 0x77FB }, { 4810, 0xFCF5 }, { 4822, 0x019D }, { 4828, 0xFFFF }, - { 4844, 0xFFFB }, { 4859, 0xFFBA }, { 4872, 0x03DF }, { 4881, 0xFFFF }, - /* 0x6100 */ - { 4897, 0xFFFB }, { 4912, 0xBF7D }, { 4925, 0xDB8C }, { 4934, 0xE8D5 }, - { 4943, 0xFFF7 }, { 4958, 0xFF7D }, { 4972, 0xDDFF }, { 4986, 0x76FF }, - { 4999, 0x7E8F }, { 5010, 0xBF7F }, { 5024, 0xFF96 }, { 5036, 0xD7FF }, - { 5050, 0xBFEF }, { 5064, 0xC549 }, { 5071, 0x6FFD }, { 5084, 0xFFE7 }, - /* 0x6200 */ - { 5098, 0x779B }, { 5109, 0x8E77 }, { 5119, 0x7EBF }, { 5132, 0xE6DD }, - { 5143, 0x7FCF }, { 5156, 0x5F1F }, { 5167, 0xE17F }, { 5178, 0xFEDF }, - { 5192, 0xD7FF }, { 5206, 0x21FF }, { 5216, 0xFF50 }, { 5226, 0xFB7B }, - { 5239, 0xFFFC }, { 5253, 0x9FFF }, { 5267, 0xF820 }, { 5273, 0xFFFF }, - /* 0x6300 */ - { 5289, 0xFB8F }, { 5301, 0x017B }, { 5308, 0xFF00 }, { 5316, 0x7FFE }, - { 5330, 0xFFFF }, { 5346, 0x07F3 }, { 5355, 0xFBB0 }, { 5365, 0xBFE7 }, - { 5378, 0xFFBF }, { 5393, 0xFBD7 }, { 5406, 0xFFBF }, { 5421, 0x6203 }, - { 5426, 0xFFFF }, { 5442, 0xFFEF }, { 5457, 0xEFFF }, { 5472, 0x5B7F }, - /* 0x6400 */ - { 5484, 0xFEC0 }, { 5493, 0xDDFD }, { 5506, 0xFDFF }, { 5521, 0xEFFD }, - { 5535, 0x680B }, { 5541, 0xFF1F }, { 5554, 0xFBE3 }, { 5566, 0xBFFF }, - { 5581, 0xBFA4 }, { 5591, 0xF7EF }, { 5605, 0xFA7D }, { 5617, 0xF85F }, - { 5628, 0xEEBF }, { 5641, 0x2FDD }, { 5652, 0xBFFF }, { 5667, 0xFD9F }, - /* 0x6500 */ - { 5680, 0xF6DB }, { 5692, 0xFBFB }, { 5706, 0xFE7F }, { 5720, 0xEBFD }, - { 5733, 0xA76A }, { 5742, 0xF3FA }, { 5754, 0xBDFC }, { 5766, 0x9FFC }, - { 5778, 0x1BFF }, { 5790, 0xFAF7 }, { 5803, 0xDDB7 }, { 5815, 0xFBED }, - { 5828, 0xF87E }, { 5839, 0xECDF }, { 5851, 0xF36F }, { 5863, 0xBC3F }, - /* 0x6600 */ - { 5874, 0xFFFD }, { 5889, 0xF13F }, { 5900, 0xE9FF }, { 5913, 0x067F }, - { 5922, 0x9FBE }, { 5934, 0xFE8E }, { 5945, 0xDDFE }, { 5958, 0x7FDF }, - { 5972, 0x7FF1 }, { 5984, 0xA7F7 }, { 5996, 0xEF17 }, { 6007, 0xEFFF }, - { 6022, 0xFFD1 }, { 6034, 0x7F44 }, { 6043, 0x7B59 }, { 6053, 0xD3DF }, - /* 0x6700 */ - { 6065, 0xFF3F }, { 6079, 0xEBFD }, { 6092, 0x7DEF }, { 6105, 0xFF7A }, - { 6118, 0xFBF0 }, { 6129, 0xF6EB }, { 6141, 0xBC87 }, { 6150, 0xFFFF }, - { 6166, 0xFAFA }, { 6178, 0xB7BF }, { 6191, 0xD011 }, { 6196, 0x8FFF }, - { 6209, 0xFF7F }, { 6224, 0xFFDF }, { 6239, 0xFEFC }, { 6252, 0xD7FF }, - /* 0x6800 */ - { 6266, 0x201F }, { 6272, 0xFDDD }, { 6285, 0xEF67 }, { 6297, 0x7FFE }, - { 6311, 0xFFFF }, { 6327, 0x207B }, { 6334, 0xE820 }, { 6339, 0xFBF6 }, - { 6352, 0x9FFF }, { 6366, 0xB9DF }, { 6378, 0xFFDF }, { 6393, 0x227F }, - { 6402, 0x7FF8 }, { 6414, 0xF5FF }, { 6428, 0xDFDB }, { 6441, 0x3FFF }, - /* 0x6900 */ - { 6455, 0xFFFF }, { 6471, 0x0FBF }, { 6482, 0x9420 }, { 6486, 0xFBFD }, - { 6500, 0xDF7F }, { 6514, 0xFFFE }, { 6529, 0xFFFF }, { 6545, 0x0FFF }, - { 6557, 0x646D }, { 6565, 0xDFFB }, { 6579, 0xFFFF }, { 6595, 0xFAFF }, - { 6609, 0xFE5F }, { 6622, 0x027B }, { 6629, 0x7BF6 }, { 6641, 0xFFDE }, - /* 0x6A00 */ - { 6655, 0xBFFF }, { 6670, 0xFFFA }, { 6684, 0x39EB }, { 6694, 0xFF3C }, - { 6706, 0xFBFB }, { 6720, 0xEFFF }, { 6735, 0xAFFF }, { 6749, 0xC452 }, - { 6755, 0xF6BF }, { 6768, 0xFEFF }, { 6783, 0xF9FF }, { 6797, 0x6FFE }, - { 6810, 0xBFEC }, { 6822, 0xFF1B }, { 6834, 0xDDA3 }, { 6844, 0x1F4B }, - /* 0x6B00 */ - { 6853, 0x8F3D }, { 6863, 0x67CF }, { 6874, 0xB12B }, { 6882, 0xFFFE }, - { 6897, 0x7FEE }, { 6910, 0xDAF7 }, { 6922, 0xA4FF }, { 6933, 0xCFD4 }, - { 6943, 0xF75F }, { 6956, 0xCBF2 }, { 6966, 0xECFD }, { 6978, 0xB4ED }, - { 6988, 0xBFFB }, { 7002, 0x5DDD }, { 7013, 0x9DDF }, { 7025, 0xFF8D }, - /* 0x6C00 */ - { 7037, 0xBB7F }, { 7050, 0xBF7B }, { 7063, 0xDDFB }, { 7076, 0xEFFB }, - { 7090, 0xFE4F }, { 7102, 0xFFB5 }, { 7115, 0xEFE3 }, { 7127, 0xEF7F }, - { 7141, 0xFFFF }, { 7157, 0xBF7D }, { 7170, 0xFC04 }, { 7177, 0xFFDF }, - { 7192, 0xFEFF }, { 7207, 0xFEFF }, { 7222, 0xFFAF }, { 7236, 0x822F }, - /* 0x6D00 */ - { 7243, 0xFFFF }, { 7259, 0xEFC7 }, { 7271, 0xFFF5 }, { 7285, 0xFFFF }, - { 7301, 0x4007 }, { 7305, 0xDF80 }, { 7313, 0xF7FF }, { 7328, 0xFFF7 }, - { 7343, 0xFFFF }, { 7359, 0x01FF }, { 7368, 0xDC30 }, { 7375, 0xFFBE }, - { 7389, 0xBFF5 }, { 7402, 0xFFFF }, { 7418, 0xFF7F }, { 7433, 0x7EFF }, - /* 0x6E00 */ - { 7447, 0x843D }, { 7454, 0xBF20 }, { 7462, 0xFFFF }, { 7478, 0xFF7F }, - { 7493, 0xEEFB }, { 7506, 0xFF7F }, { 7521, 0xCBFF }, { 7534, 0x13DE }, - { 7543, 0xEB40 }, { 7550, 0xFFDD }, { 7564, 0xCCFF }, { 7576, 0xFFFF }, - { 7592, 0xFFFF }, { 7608, 0x3F7F }, { 7621, 0xFB04 }, { 7629, 0xFFF6 }, - /* 0x6F00 */ - { 7643, 0xFFFF }, { 7659, 0xD7FC }, { 7671, 0xFEFF }, { 7686, 0xFFFF }, - { 7702, 0xC01B }, { 7708, 0xFDFF }, { 7723, 0xFEDF }, { 7737, 0xFFDD }, - { 7751, 0x7FF7 }, { 7765, 0xE0FD }, { 7775, 0xFFFF }, { 7791, 0xFF7F }, - { 7806, 0xFFDF }, { 7821, 0xFF38 }, { 7832, 0xFBDF }, { 7846, 0xDDD7 }, - /* 0x7000 */ - { 7858, 0xFEFB }, { 7872, 0xFFF2 }, { 7885, 0x9FDF }, { 7898, 0xDFBF }, - { 7912, 0x3F7F }, { 7925, 0xFDF7 }, { 7939, 0x9FFF }, { 7953, 0xF7F3 }, - { 7966, 0xCE7E }, { 7977, 0x877E }, { 7987, 0xFAFB }, { 8000, 0x7FBB }, - { 8013, 0xFDF1 }, { 8025, 0xF7FF }, { 8040, 0x8017 }, { 8045, 0xFFFB }, - /* 0x7100 */ - { 8060, 0x7E75 }, { 8071, 0xFE89 }, { 8081, 0xDB6F }, { 8093, 0x4C7F }, - { 8103, 0xFEFF }, { 8118, 0xF75F }, { 8131, 0x5FFF }, { 8145, 0x7DEF }, - { 8158, 0xD7F7 }, { 8171, 0xFFD7 }, { 8185, 0xB7BF }, { 8198, 0xF7BF }, - { 8212, 0xCFFF }, { 8226, 0xBF77 }, { 8239, 0x79F7 }, { 8251, 0xFB77 }, - /* 0x7200 */ - { 8264, 0xF6EF }, { 8277, 0xEEF9 }, { 8289, 0x7FDC }, { 8301, 0xEF61 }, - { 8311, 0x9FD7 }, { 8323, 0xFFED }, { 8337, 0xD6CF }, { 8348, 0xFBDD }, - { 8361, 0xFBF7 }, { 8375, 0xEDFF }, { 8389, 0xF7FE }, { 8403, 0xA435 }, - { 8410, 0x7E7F }, { 8423, 0x97D7 }, { 8434, 0x0F5F }, { 8444, 0xFFD8 }, - /* 0x7300 */ - { 8456, 0x9D97 }, { 8466, 0x7BCF }, { 8478, 0x7FEC }, { 8490, 0xDFFF }, - { 8505, 0xF73F }, { 8518, 0xEF87 }, { 8529, 0xDFE7 }, { 8542, 0xFDFF }, - { 8557, 0xDFFF }, { 8572, 0xF1FC }, { 8583, 0x3FF7 }, { 8596, 0xDFFC }, - { 8609, 0xFFED }, { 8623, 0x7FFD }, { 8637, 0xEFFF }, { 8652, 0xFFF8 }, - /* 0x7400 */ - { 8665, 0x3FFF }, { 8679, 0xFEF6 }, { 8692, 0xFF7F }, { 8707, 0x97FF }, - { 8720, 0xEFFF }, { 8735, 0xFEFF }, { 8750, 0xFFBD }, { 8764, 0xF67F }, - { 8777, 0x3FEF }, { 8790, 0xDFB5 }, { 8802, 0xAFFB }, { 8815, 0xEFF7 }, - { 8829, 0x9D2F }, { 8839, 0xFFF9 }, { 8853, 0x53FF }, { 8865, 0xE9F7 }, - /* 0x7500 */ - { 8877, 0xF9BD }, { 8889, 0xF7FF }, { 8904, 0xFF66 }, { 8916, 0xEFBF }, - { 8930, 0xFDC5 }, { 8941, 0xBE3A }, { 8951, 0xFCFD }, { 8964, 0xE7C5 }, - { 8974, 0xFCD9 }, { 8985, 0x6737 }, { 8995, 0x0CBC }, { 9002, 0xFF7F }, - { 9017, 0xFDBF }, { 9031, 0xFFB7 }, { 9045, 0xA0DF }, { 9054, 0xFFFF }, - /* 0x7600 */ - { 9070, 0xBF8F }, { 9082, 0xFE7B }, { 9095, 0xB3FF }, { 9108, 0x3D3F }, - { 9119, 0xF3CD }, { 9130, 0x97DF }, { 9142, 0xF6F7 }, { 9155, 0xFF7F }, - { 9170, 0xCFD6 }, { 9181, 0x7E6D }, { 9192, 0xEC72 }, { 9201, 0xEDB1 }, - { 9211, 0x777C }, { 9222, 0xFE5C }, { 9233, 0xF6FA }, { 9245, 0x5FBF }, - /* 0x7700 */ - { 9258, 0xDFBA }, { 9270, 0xEE2F }, { 9281, 0xABFD }, { 9293, 0x7FFE }, - { 9307, 0xFCF9 }, { 9319, 0xDF74 }, { 9330, 0xFFEF }, { 9345, 0xFF84 }, - { 9355, 0xFBBF }, { 9369, 0xFFAA }, { 9381, 0xBDAF }, { 9393, 0xFEFF }, - { 9408, 0xFEBC }, { 9420, 0x7FB9 }, { 9432, 0xF3ED }, { 9444, 0x7F9F }, - /* 0x7800 */ - { 9457, 0xF36C }, { 9467, 0xF11F }, { 9477, 0xFFEF }, { 9492, 0x33BF }, - { 9503, 0x7FBC }, { 9515, 0x701F }, { 9523, 0xFF75 }, { 9536, 0xDE03 }, - { 9544, 0xF3FB }, { 9557, 0xC7FA }, { 9568, 0xBFBF }, { 9582, 0x5F5F }, - { 9594, 0xFFBA }, { 9607, 0xEDBF }, { 9620, 0xF7BF }, { 9634, 0xFEBF }, - /* 0x7900 */ - { 9648, 0x5276 }, { 9656, 0x7A9F }, { 9667, 0xFFFA }, { 9681, 0xFF7E }, - { 9695, 0x9FF7 }, { 9708, 0xFFFF }, { 9724, 0x2FBF }, { 9736, 0xF61F }, - { 9747, 0xEDCF }, { 9759, 0xBFFF }, { 9774, 0x7FF7 }, { 9788, 0xEFDF }, - { 9802, 0xFB73 }, { 9814, 0xF176 }, { 9824, 0x7EDD }, { 9836, 0x0DD2 }, - /* 0x7A00 */ - { 9843, 0x3D7D }, { 9854, 0xDFBF }, { 9868, 0xED45 }, { 9877, 0xFE83 }, - { 9887, 0x7FF9 }, { 9900, 0x9DD0 }, { 9908, 0x7BA7 }, { 9919, 0xEF73 }, - { 9931, 0x9FFB }, { 9944, 0xC3FF }, { 9956, 0xDF0D }, { 9966, 0xDDFF }, - { 9980, 0x8FBF }, { 9992, 0xBF0A }, { 10001, 0xEEFD }, { 10014, 0xEEC0 }, - /* 0x7B00 */ - { 10022, 0xDF73 }, { 10034, 0xEF1F }, { 10046, 0xFFFD }, { 10061, 0x0B3F }, - { 10070, 0xFFFD }, { 10085, 0x0177 }, { 10092, 0xF2FF }, { 10105, 0x09FF }, - { 10115, 0xFDB4 }, { 10126, 0x3BF7 }, { 10138, 0xB01F }, { 10146, 0x43B6 }, - { 10154, 0xDED3 }, { 10165, 0xFF31 }, { 10176, 0x1FFF }, { 10189, 0xFF9F }, - /* 0x7C00 */ - { 10203, 0xFEEF }, { 10217, 0xFA27 }, { 10227, 0x3FEF }, { 10240, 0xFBA9 }, - { 10251, 0x37BD }, { 10262, 0xBEDB }, { 10274, 0xFEF9 }, { 10287, 0xFF3D }, - { 10300, 0x777B }, { 10312, 0xD1F6 }, { 10322, 0xD1EE }, { 10332, 0xFF3E }, - { 10345, 0x7FAC }, { 10356, 0xF6FF }, { 10370, 0xF5C5 }, { 10380, 0x7BFF }, - /* 0x7D00 */ - { 10394, 0xFFFF }, { 10410, 0xFFFF }, { 10426, 0xDB27 }, { 10436, 0xFF6F }, - { 10450, 0xE4FF }, { 10462, 0xFD7F }, { 10476, 0xEFCE }, { 10488, 0xBE0F }, - { 10498, 0xFB7B }, { 10511, 0xF0DE }, { 10521, 0xFFDF }, { 10536, 0xFFBF }, - { 10551, 0xFEF7 }, { 10565, 0xFF9D }, { 10578, 0xD7FB }, { 10591, 0x6EFF }, - /* 0x7E00 */ - { 10604, 0xFF88 }, { 10614, 0xFCFF }, { 10628, 0xEEBF }, { 10641, 0xFFFF }, - { 10657, 0x13FF }, { 10668, 0xDFFF }, { 10683, 0xFFAF }, { 10697, 0xFFFD }, - { 10712, 0xFDC7 }, { 10724, 0x9FFE }, { 10737, 0x1010 }, { 10739, 0x0400 }, - { 10740, 0x8080 }, { 10742, 0x8000 }, { 10743, 0x0000 }, { 10743, 0x0000 }, - /* 0x7F00 */ - { 10743, 0x0040 }, { 10744, 0x0000 }, { 10744, 0x0000 }, { 10744, 0xE7C0 }, - { 10752, 0xFFBB }, { 10766, 0xF93F }, { 10778, 0x7FEB }, { 10791, 0xFFEF }, - { 10806, 0xFFE8 }, { 10818, 0x7CFE }, { 10830, 0xF3FF }, { 10844, 0xFFFF }, - { 10860, 0xFEAF }, { 10873, 0xF8B7 }, { 10884, 0xFFEF }, { 10899, 0xFFBF }, - /* 0x8000 */ - { 10914, 0xF9FF }, { 10928, 0xFBF7 }, { 10942, 0xD773 }, { 10953, 0xFAFB }, - { 10966, 0x85C8 }, { 10972, 0x7D57 }, { 10983, 0x90DE }, { 10991, 0xE3EF }, - { 11003, 0x9EF5 }, { 11014, 0xBF6D }, { 11026, 0xEEAE }, { 11037, 0x35F6 }, - { 11047, 0xF7FC }, { 11060, 0x7FF3 }, { 11073, 0xB27B }, { 11083, 0x7F7F }, - /* 0x8100 */ - { 11097, 0x57EF }, { 11109, 0xEFF4 }, { 11121, 0xBEBE }, { 11133, 0x6695 }, - { 11141, 0xFDDC }, { 11153, 0x5E7F }, { 11165, 0xEAF7 }, { 11177, 0x97DF }, - { 11189, 0xBFDD }, { 11202, 0xFFA8 }, { 11213, 0x5FED }, { 11225, 0xFEFF }, - { 11240, 0xB7FF }, { 11254, 0xEFA7 }, { 11266, 0xF7FF }, { 11281, 0xDFDC }, - /* 0x8200 */ - { 11293, 0x3FB7 }, { 11305, 0xFD77 }, { 11318, 0xBF67 }, { 11330, 0xF7FC }, - { 11343, 0xCAB5 }, { 11352, 0xDFFF }, { 11367, 0xFB7E }, { 11380, 0xFFF6 }, - { 11394, 0xECB9 }, { 11404, 0xEF1F }, { 11416, 0xFFFF }, { 11432, 0xFFFB }, - { 11447, 0x841D }, { 11453, 0xDBFF }, { 11467, 0xFDFF }, { 11482, 0xFFFF }, - /* 0x8300 */ - { 11498, 0x3BFF }, { 11511, 0x7FC0 }, { 11520, 0xBFF5 }, { 11533, 0xBFFE }, - { 11547, 0xFFBF }, { 11562, 0x00DF }, { 11569, 0x804C }, { 11573, 0xFDF8 }, - { 11585, 0xFFEA }, { 11598, 0x7FFF }, { 11613, 0xDFFD }, { 11627, 0xE201 }, - { 11632, 0xFFFF }, { 11648, 0xFBFA }, { 11661, 0xFFBF }, { 11676, 0xFF7F }, - /* 0x8400 */ - { 11691, 0xFEFA }, { 11704, 0x195F }, { 11713, 0xFA5B }, { 11724, 0xFFFF }, - { 11740, 0x7FFD }, { 11754, 0xFFFF }, { 11770, 0xFBFF }, { 11785, 0xE7FF }, - { 11799, 0xE145 }, { 11806, 0xFFDF }, { 11821, 0xFF9F }, { 11835, 0xFF57 }, - { 11848, 0xFEF7 }, { 11862, 0x4CDF }, { 11872, 0xDFB6 }, { 11884, 0xFFDF }, - /* 0x8500 */ - { 11899, 0xFFED }, { 11913, 0xF7FF }, { 11928, 0xFFFB }, { 11943, 0x691B }, - { 11951, 0x7FFF }, { 11966, 0xEFFE }, { 11980, 0xFFFF }, { 11996, 0x5FEB }, - { 12008, 0xFFFF }, { 12024, 0xFFF3 }, { 12038, 0x87DF }, { 12049, 0xE7FB }, - { 12062, 0xEBFF }, { 12076, 0xF7E7 }, { 12089, 0xFF7F }, { 12104, 0xFFC7 }, - /* 0x8600 */ - { 12117, 0xBEF7 }, { 12130, 0xDFD3 }, { 12142, 0xF7FF }, { 12157, 0xDF7E }, - { 12170, 0x79ED }, { 12181, 0xDA7D }, { 12192, 0xFFBE }, { 12206, 0x5E9F }, - { 12217, 0x7CE0 }, { 12225, 0x77FF }, { 12239, 0xA7BF }, { 12251, 0xFFFF }, - { 12267, 0x1BFF }, { 12279, 0xFFDB }, { 12293, 0xBF5C }, { 12304, 0x4FE0 }, - /* 0x8700 */ - { 12312, 0x7FFF }, { 12327, 0x5F0E }, { 12336, 0x77FF }, { 12350, 0xDDBF }, - { 12363, 0xF04F }, { 12372, 0xFFFF }, { 12388, 0xFFFF }, { 12404, 0x2FFB }, - { 12416, 0xBBFE }, { 12429, 0xFDDF }, { 12443, 0xFE3C }, { 12454, 0xFFFF }, - { 12470, 0x5F7F }, { 12483, 0xFFDE }, { 12497, 0xFDFF }, { 12512, 0xDEFC }, - /* 0x8800 */ - { 12524, 0xBF7F }, { 12538, 0xBBFB }, { 12551, 0xFFFF }, { 12567, 0xFBEF }, - { 12581, 0xFD7F }, { 12595, 0x6EEC }, { 12605, 0xEFBF }, { 12619, 0xF2F7 }, - { 12631, 0xFB9F }, { 12644, 0xDFEF }, { 12658, 0x5D97 }, { 12668, 0xF7F6 }, - { 12681, 0xFEA7 }, { 12693, 0xFFF5 }, { 12707, 0xD9C2 }, { 12715, 0xFFFF }, - /* 0x8900 */ - { 12731, 0x5EE7 }, { 12742, 0xC7FF }, { 12755, 0xFEFE }, { 12769, 0x79EF }, - { 12781, 0xBADE }, { 12792, 0xFFDF }, { 12807, 0xFE7F }, { 12821, 0xDEDE }, - { 12833, 0x8FEF }, { 12845, 0xF9FA }, { 12857, 0xF6FE }, { 12870, 0xF6C4 }, - { 12879, 0x0043 }, { 12882, 0xBE7C }, { 12893, 0x3BFF }, { 12906, 0xDDDF }, - /* 0x8A00 */ - { 12919, 0xD59D }, { 12929, 0xF9EF }, { 12942, 0x3EAC }, { 12951, 0xFF53 }, - { 12963, 0xF773 }, { 12975, 0x4BF7 }, { 12986, 0x7BCF }, { 12998, 0xDEFF }, - { 13012, 0xB8FE }, { 13023, 0x577F }, { 13035, 0x8FFB }, { 13047, 0xFF55 }, - { 13059, 0xABFD }, { 13071, 0xFFFE }, { 13086, 0xEDD7 }, { 13098, 0xDDFF }, - /* 0x8B00 */ - { 13112, 0xFDF7 }, { 13126, 0xFFFF }, { 13142, 0xFDFD }, { 13156, 0xFEEB }, - { 13169, 0xFFEF }, { 13184, 0xF7FF }, { 13199, 0xBFED }, { 13212, 0xEF91 }, - { 13222, 0x5D7F }, { 13234, 0xDF7D }, { 13247, 0x0001 }, { 13248, 0x4000 }, - { 13249, 0x0000 }, { 13249, 0x0000 }, { 13249, 0x0004 }, { 13250, 0x0000 }, - /* 0x8C00 */ - { 13250, 0x0000 }, { 13250, 0x0000 }, { 13250, 0x0000 }, { 13250, 0xFA80 }, - { 13257, 0xFFEE }, { 13271, 0xB4F3 }, { 13281, 0xBF76 }, { 13293, 0x2FEF }, - { 13305, 0xB677 }, { 13316, 0xFFBF }, { 13331, 0xBFBF }, { 13345, 0xFFFD }, - { 13360, 0xB5BF }, { 13372, 0xFEFE }, { 13386, 0x7FFF }, { 13401, 0x7FBF }, - /* 0x8D00 */ - { 13415, 0xBFFD }, { 13429, 0x3BFF }, { 13442, 0x0000 }, { 13442, 0x0000 }, - { 13442, 0x0000 }, { 13442, 0x0000 }, { 13442, 0xFBD0 }, { 13452, 0x2FDD }, - { 13463, 0xF637 }, { 13474, 0x9A7F }, { 13485, 0xFFEB }, { 13499, 0xD6FC }, - { 13510, 0xF9EF }, { 13523, 0xBFFB }, { 13537, 0xDFDF }, { 13551, 0xF41F }, - /* 0x8E00 */ - { 13561, 0xE6FF }, { 13574, 0xFFFF }, { 13590, 0x6FFF }, { 13604, 0xF77B }, - { 13617, 0xFFF7 }, { 13632, 0xFEF9 }, { 13645, 0xB7FF }, { 13659, 0x5DFE }, - { 13671, 0x7FF7 }, { 13685, 0xE5FF }, { 13698, 0x3FFB }, { 13711, 0x3645 }, - { 13718, 0xFE0D }, { 13728, 0xFD9E }, { 13740, 0xFBF7 }, { 13754, 0xDFF6 }, - /* 0x8F00 */ - { 13767, 0x6FEF }, { 13780, 0xFFFF }, { 13796, 0xF679 }, { 13807, 0xCBFD }, - { 13819, 0xEFFF }, { 13834, 0xFFFF }, { 13850, 0x40DF }, { 13858, 0x0000 }, - { 13858, 0x0000 }, { 13858, 0x9808 }, { 13862, 0xE1E9 }, { 13871, 0xDFFF }, - { 13886, 0xFE76 }, { 13898, 0x04FF }, { 13907, 0x6D7F }, { 13919, 0xFFF1 }, - /* 0x9000 */ - { 13932, 0xB97F }, { 13944, 0xFEF7 }, { 13958, 0xE01F }, { 13966, 0xF1FE }, - { 13978, 0xFE96 }, { 13989, 0x7B7F }, { 14002, 0xFB9F }, { 14015, 0xFFFD }, - { 14030, 0xADFF }, { 14043, 0xCBB3 }, { 14053, 0xC5EF }, { 14064, 0xE97F }, - { 14076, 0x4DBA }, { 14085, 0xBFF0 }, { 14096, 0xBF3F }, { 14109, 0xFE3F }, - /* 0x9100 */ - { 14122, 0xEBFF }, { 14136, 0xFFD7 }, { 14150, 0xFFDF }, { 14165, 0xCF7F }, - { 14178, 0xFFFB }, { 14193, 0xD7EF }, { 14206, 0xD7BF }, { 14219, 0x17FD }, - { 14230, 0xFEFF }, { 14245, 0xFE0F }, { 14256, 0xFFAF }, { 14270, 0x7EFF }, - { 14284, 0xFAFF }, { 14298, 0xB7FB }, { 14311, 0x7FFC }, { 14324, 0xE7FA }, - /* 0x9200 */ - { 14336, 0xF7FF }, { 14351, 0x56FF }, { 14363, 0x6DFA }, { 14374, 0xF7FF }, - { 14389, 0xFF73 }, { 14402, 0xEDFF }, { 14416, 0xF8FF }, { 14429, 0xFFC5 }, - { 14441, 0xFFFF }, { 14457, 0x3FFA }, { 14469, 0x5FFF }, { 14483, 0xDEFE }, - { 14496, 0xFFFF }, { 14512, 0xEBBF }, { 14525, 0xDFFB }, { 14539, 0xFFDF }, - /* 0x9300 */ - { 14554, 0xFBDF }, { 14568, 0xEF7D }, { 14581, 0xFFFF }, { 14597, 0x137B }, - { 14606, 0xFFFF }, { 14622, 0xDFF7 }, { 14636, 0x7FFF }, { 14651, 0x7FFB }, - { 14665, 0xF7FF }, { 14680, 0xFFF7 }, { 14695, 0xF7FF }, { 14710, 0xA9BF }, - { 14721, 0xFDDD }, { 14734, 0xFFFF }, { 14750, 0x51DF }, { 14760, 0xFFFB }, - /* 0x9400 */ - { 14775, 0xFFDB }, { 14789, 0x2BFF }, { 14801, 0x7FF1 }, { 14813, 0xFFEF }, - { 14828, 0xBFFD }, { 14842, 0x69B7 }, { 14852, 0xFFBD }, { 14866, 0xFBFF }, - { 14881, 0x002F }, { 14886, 0x8000 }, { 14887, 0x0004 }, { 14888, 0x0000 }, - { 14888, 0x000A }, { 14890, 0x1000 }, { 14891, 0x0000 }, { 14891, 0x0040 }, - /* 0x9500 */ - { 14892, 0x0000 }, { 14892, 0x0000 }, { 14892, 0x2000 }, { 14893, 0x0000 }, - { 14893, 0x0080 }, { 14894, 0x0000 }, { 14894, 0x0000 }, { 14894, 0xBD80 }, - { 14901, 0xFB6D }, { 14913, 0xDBDF }, { 14926, 0x7FFF }, { 14941, 0xFEE3 }, - { 14953, 0x3FE9 }, { 14964, 0xDC7F }, { 14976, 0x013F }, { 14983, 0x0010 }, - /* 0x9600 */ - { 14984, 0x0000 }, { 14984, 0x7000 }, { 14987, 0xF51F }, { 14998, 0xBF0F }, - { 15009, 0xFC3F }, { 15021, 0xF95B }, { 15032, 0xBE1E }, { 15042, 0x79FF }, - { 15055, 0xEFFB }, { 15069, 0x5BFE }, { 15081, 0x57BE }, { 15092, 0xBB5B }, - { 15103, 0x7FFF }, { 15118, 0xFFFC }, { 15132, 0x872E }, { 15140, 0xAFF7 }, - /* 0x9700 */ - { 15153, 0xEBFD }, { 15166, 0xFB4F }, { 15178, 0xDFFF }, { 15193, 0xE767 }, - { 15204, 0x0BDF }, { 15214, 0xFDE6 }, { 15226, 0x7747 }, { 15236, 0xFDDF }, - { 15250, 0xEFBF }, { 15264, 0xFF90 }, { 15274, 0x7D7F }, { 15287, 0xEFDE }, - { 15300, 0xFBFF }, { 15315, 0xF3FD }, { 15328, 0x606B }, { 15335, 0xEF6F }, - /* 0x9800 */ - { 15348, 0xF5FF }, { 15362, 0xF9FF }, { 15376, 0xEBDB }, { 15388, 0x0BBD }, - { 15397, 0xFFFA }, { 15411, 0xFB8F }, { 15423, 0x9FFD }, { 15436, 0x003F }, - { 15442, 0x0000 }, { 15442, 0x0000 }, { 15442, 0xF300 }, { 15448, 0xFFDE }, - { 15462, 0x5FDF }, { 15475, 0xD800 }, { 15479, 0xBEEF }, { 15492, 0x7676 }, - /* 0x9900 */ - { 15502, 0x57AD }, { 15512, 0xDFFF }, { 15527, 0xFFB2 }, { 15539, 0xFFAF }, - { 15553, 0x7FAF }, { 15566, 0xFBFF }, { 15581, 0x000E }, { 15584, 0x0000 }, - { 15584, 0x0000 }, { 15584, 0x7BC0 }, { 15592, 0xFDFA }, { 15605, 0x3F3F }, - { 15617, 0xFABE }, { 15629, 0xBFFF }, { 15644, 0x76FF }, { 15657, 0xFFF3 }, - /* 0x9A00 */ - { 15671, 0xFEFE }, { 15685, 0xFE73 }, { 15697, 0xFEFF }, { 15712, 0xFFF7 }, - { 15727, 0xF77F }, { 15741, 0xDFFD }, { 15755, 0x1FFD }, { 15767, 0x0000 }, - { 15767, 0x8000 }, { 15768, 0x0000 }, { 15768, 0xA900 }, { 15772, 0xFFDF }, - { 15787, 0xA4C7 }, { 15795, 0x91FF }, { 15806, 0xF8CF }, { 15817, 0xFEDE }, - /* 0x9B00 */ - { 15830, 0xFF7E }, { 15844, 0xC7F7 }, { 15856, 0xEFBD }, { 15869, 0xDEBE }, - { 15881, 0xFD7F }, { 15895, 0x8F77 }, { 15906, 0x93D3 }, { 15915, 0xFCF3 }, - { 15927, 0xE9EF }, { 15939, 0xECAF }, { 15950, 0xED77 }, { 15962, 0xA361 }, - { 15969, 0x87DB }, { 15979, 0x7EF8 }, { 15990, 0x3FF7 }, { 16003, 0xA193 }, - /* 0x9C00 */ - { 16010, 0x7FE4 }, { 16021, 0xB8BD }, { 16031, 0xBB7B }, { 16043, 0xFEFE }, - { 16057, 0xFF73 }, { 16070, 0xE3FD }, { 16082, 0x61CD }, { 16090, 0x1FBE }, - { 16101, 0x0000 }, { 16101, 0x0000 }, { 16101, 0x0000 }, { 16101, 0x0000 }, - { 16101, 0x0000 }, { 16101, 0x0000 }, { 16101, 0x26E0 }, { 16107, 0xBEFE }, - /* 0x9D00 */ - { 16120, 0x13FD }, { 16130, 0xEBF5 }, { 16142, 0xE36F }, { 16153, 0xEBDB }, - { 16165, 0xDE3F }, { 16177, 0xFFDF }, { 16192, 0xFF83 }, { 16203, 0xFBBF }, - { 16217, 0x1FFF }, { 16230, 0xFFDD }, { 16244, 0xBFFF }, { 16259, 0xFFFE }, - { 16274, 0xFFBF }, { 16289, 0xFFFF }, { 16305, 0xFB7E }, { 16318, 0xFFFD }, - /* 0x9E00 */ - { 16333, 0xFEFF }, { 16348, 0xFFBF }, { 16363, 0x0000 }, { 16363, 0x0000 }, - { 16363, 0x0000 }, { 16363, 0x0000 }, { 16363, 0x0000 }, { 16363, 0xBE20 }, - { 16370, 0x7FFF }, { 16385, 0xFFFF }, { 16401, 0xFFF7 }, { 16416, 0xF8F3 }, - { 16427, 0xF1DF }, { 16439, 0xFD7B }, { 16452, 0xE9F5 }, { 16463, 0xFFFF }, - /* 0x9F00 */ - { 16479, 0xC7C7 }, { 16489, 0x5FED }, { 16501, 0xFFFD }, { 16516, 0x6BFF }, - { 16529, 0xFFFF }, { 16545, 0xFFFD }, { 16560, 0xDEFF }, { 16574, 0xCFF7 }, - { 16587, 0x6000 }, { 16589, 0x9337 }, { 16598, 0x0035 }, -}; -static const Summary16 big5hkscs_uni2index_pagee0[419] = { - /* 0xE000 */ - { 16602, 0xFFFF }, { 16618, 0xFFFF }, { 16634, 0xFFFF }, { 16650, 0xFFFF }, - { 16666, 0xFFFF }, { 16682, 0xFFFF }, { 16698, 0xFFFF }, { 16714, 0xFFFF }, - { 16730, 0xFFFF }, { 16746, 0xFFFF }, { 16762, 0xFFFF }, { 16778, 0xFFFF }, - { 16794, 0xFFFF }, { 16810, 0xFFFF }, { 16826, 0xFFFF }, { 16842, 0xFFFF }, - /* 0xE100 */ - { 16858, 0xFFFF }, { 16874, 0xFFFF }, { 16890, 0xFFFF }, { 16906, 0xFFFF }, - { 16922, 0xFFFF }, { 16938, 0xFFFF }, { 16954, 0xFFFF }, { 16970, 0xFFFF }, - { 16986, 0xFFFF }, { 17002, 0xFFFF }, { 17018, 0xFFFF }, { 17034, 0xFFFF }, - { 17050, 0xFFFF }, { 17066, 0xFFFF }, { 17082, 0xFFFF }, { 17098, 0xFFFF }, - /* 0xE200 */ - { 17114, 0xFFFF }, { 17130, 0xFFFF }, { 17146, 0xFFFF }, { 17162, 0xFFFF }, - { 17178, 0xFFFF }, { 17194, 0xFFFF }, { 17210, 0xFFFF }, { 17226, 0xFFFF }, - { 17242, 0xFFFF }, { 17258, 0xFFFF }, { 17274, 0xFFFF }, { 17290, 0xFFFF }, - { 17306, 0xFFFF }, { 17322, 0xFFFF }, { 17338, 0xFFFF }, { 17354, 0xFFFF }, - /* 0xE300 */ - { 17370, 0xFFFF }, { 17386, 0xFFFF }, { 17402, 0xFFFF }, { 17418, 0xFFFF }, - { 17434, 0xFFFF }, { 17450, 0xFFFF }, { 17466, 0xFFFF }, { 17482, 0xFFFF }, - { 17498, 0xFFFF }, { 17514, 0xFFFF }, { 17530, 0xFFFF }, { 17546, 0xFFFF }, - { 17562, 0xFFFF }, { 17578, 0xFFFF }, { 17594, 0xFFFF }, { 17610, 0xFFFF }, - /* 0xE400 */ - { 17626, 0xFFFF }, { 17642, 0xFFFF }, { 17658, 0xFFFF }, { 17674, 0xFFFF }, - { 17690, 0xFFFF }, { 17706, 0xFFFF }, { 17722, 0xFFFF }, { 17738, 0xFFFF }, - { 17754, 0xFFFF }, { 17770, 0xFFFF }, { 17786, 0xFFFF }, { 17802, 0xFFFF }, - { 17818, 0xFFFF }, { 17834, 0xFFFF }, { 17850, 0xFFFF }, { 17866, 0xFFFF }, - /* 0xE500 */ - { 17882, 0xFFFF }, { 17898, 0xFFFF }, { 17914, 0xFFFF }, { 17930, 0xFFFF }, - { 17946, 0xFFFF }, { 17962, 0xFFFF }, { 17978, 0xFFFF }, { 17994, 0xFFFF }, - { 18010, 0xFFFF }, { 18026, 0xFFFF }, { 18042, 0xFFFF }, { 18058, 0xFFFF }, - { 18074, 0xFFFF }, { 18090, 0xFFFF }, { 18106, 0xFFFF }, { 18122, 0xFFFF }, - /* 0xE600 */ - { 18138, 0xFFFF }, { 18154, 0xFFFF }, { 18170, 0xFFFF }, { 18186, 0xFFFF }, - { 18202, 0xFFFF }, { 18218, 0xFFFF }, { 18234, 0xFFFF }, { 18250, 0xFFFF }, - { 18266, 0xFFFF }, { 18282, 0xFFFF }, { 18298, 0xFFFF }, { 18314, 0xFFFF }, - { 18330, 0xFFFF }, { 18346, 0xFFFF }, { 18362, 0xFFFF }, { 18378, 0xFFFF }, - /* 0xE700 */ - { 18394, 0xFFFF }, { 18410, 0xFFFF }, { 18426, 0xFFFF }, { 18442, 0xFFFF }, - { 18458, 0xFFFF }, { 18474, 0xFFFF }, { 18490, 0xFFFF }, { 18506, 0xFFFF }, - { 18522, 0xFFFF }, { 18538, 0xFFFF }, { 18554, 0xFFFF }, { 18570, 0xFFFF }, - { 18586, 0xFFFF }, { 18602, 0xFFFF }, { 18618, 0xFFFF }, { 18634, 0xFFFF }, - /* 0xE800 */ - { 18650, 0xFFFF }, { 18666, 0xFFFF }, { 18682, 0xFFFF }, { 18698, 0xFFFF }, - { 18714, 0xFFFF }, { 18730, 0xFFFF }, { 18746, 0xFFFF }, { 18762, 0xFFFF }, - { 18778, 0xFFFF }, { 18794, 0xFFFF }, { 18810, 0xFFFF }, { 18826, 0xFFFF }, - { 18842, 0xFFFF }, { 18858, 0xFFFF }, { 18874, 0xFFFF }, { 18890, 0xFFFF }, - /* 0xE900 */ - { 18906, 0xFFFF }, { 18922, 0xFFFF }, { 18938, 0xFFFF }, { 18954, 0xFFFF }, - { 18970, 0xFFFF }, { 18986, 0xFFFF }, { 19002, 0xFFFF }, { 19018, 0xFFFF }, - { 19034, 0xFFFF }, { 19050, 0xFFFF }, { 19066, 0xFFFF }, { 19082, 0xFFFF }, - { 19098, 0xFFFF }, { 19114, 0xFFFF }, { 19130, 0xFFFF }, { 19146, 0xFFFF }, - /* 0xEA00 */ - { 19162, 0xFFFF }, { 19178, 0xFFFF }, { 19194, 0xFFFF }, { 19210, 0xFFFF }, - { 19226, 0xFFFF }, { 19242, 0xFFFF }, { 19258, 0xFFFF }, { 19274, 0xFFFF }, - { 19290, 0xFFFF }, { 19306, 0xFFFF }, { 19322, 0xFFFF }, { 19338, 0xFFFF }, - { 19354, 0xFFFF }, { 19370, 0xFFFF }, { 19386, 0xFFFF }, { 19402, 0xFFFF }, - /* 0xEB00 */ - { 19418, 0xFFFF }, { 19434, 0xFFFF }, { 19450, 0xFFFF }, { 19466, 0xFFFF }, - { 19482, 0xFFFF }, { 19498, 0xFFFF }, { 19514, 0xFFFF }, { 19530, 0xFFFF }, - { 19546, 0xFFFF }, { 19562, 0xFFFF }, { 19578, 0xFFFF }, { 19594, 0xFFFF }, - { 19610, 0xFFFF }, { 19626, 0xFFFF }, { 19642, 0xFFFF }, { 19658, 0xFFFF }, - /* 0xEC00 */ - { 19674, 0xFFFF }, { 19690, 0xFFFF }, { 19706, 0xFFFF }, { 19722, 0xFFFF }, - { 19738, 0xFFFF }, { 19754, 0xFFFF }, { 19770, 0xFFFF }, { 19786, 0xFFFF }, - { 19802, 0xFFFF }, { 19818, 0xFFFF }, { 19834, 0xFFFF }, { 19850, 0xFFFF }, - { 19866, 0xFFFF }, { 19882, 0xFFFF }, { 19898, 0xFFFF }, { 19914, 0xFFFF }, - /* 0xED00 */ - { 19930, 0xFFFF }, { 19946, 0xFFFF }, { 19962, 0xFFFF }, { 19978, 0xFFFF }, - { 19994, 0xFFFF }, { 20010, 0xFFFF }, { 20026, 0xFFFF }, { 20042, 0xFFFF }, - { 20058, 0xFFFF }, { 20074, 0xFFFF }, { 20090, 0xFFFF }, { 20106, 0xFFFF }, - { 20122, 0xFFFF }, { 20138, 0xFFFF }, { 20154, 0xFFFF }, { 20170, 0xFFFF }, - /* 0xEE00 */ - { 20186, 0xFFFF }, { 20202, 0xFFFF }, { 20218, 0xFFFF }, { 20234, 0xFFFF }, - { 20250, 0xFFFF }, { 20266, 0xFFFF }, { 20282, 0xFFFF }, { 20298, 0xFFFF }, - { 20314, 0xFFFF }, { 20330, 0xFFFF }, { 20346, 0xFFFF }, { 20362, 0xFFFF }, - { 20378, 0xFFFF }, { 20394, 0xFFFF }, { 20410, 0xFFFF }, { 20426, 0xFFFF }, - /* 0xEF00 */ - { 20442, 0xFFFF }, { 20458, 0xFFFF }, { 20474, 0xFFFF }, { 20490, 0xFFFF }, - { 20506, 0xFFFF }, { 20522, 0xFFFF }, { 20538, 0xFFFF }, { 20554, 0xFFFF }, - { 20570, 0xFFFF }, { 20586, 0xFFFF }, { 20602, 0xFFFF }, { 20618, 0xFFFF }, - { 20634, 0xFFFF }, { 20650, 0xFFFF }, { 20666, 0xFFFF }, { 20682, 0xFFFF }, - /* 0xF000 */ - { 20698, 0xFFFF }, { 20714, 0xFFFF }, { 20730, 0xFFFF }, { 20746, 0xFFFF }, - { 20762, 0xFFFF }, { 20778, 0xFFFF }, { 20794, 0xFFFF }, { 20810, 0xFFFF }, - { 20826, 0xFFFF }, { 20842, 0xFFFF }, { 20858, 0xFFFF }, { 20874, 0xFFFF }, - { 20890, 0xFFFF }, { 20906, 0xFFFF }, { 20922, 0xFFFF }, { 20938, 0xFFFF }, - /* 0xF100 */ - { 20954, 0xFFFF }, { 20970, 0xFFFF }, { 20986, 0xFFFF }, { 21002, 0xFFFF }, - { 21018, 0xFFFF }, { 21034, 0xFFFF }, { 21050, 0xFFFF }, { 21066, 0xFFFF }, - { 21082, 0xFFFF }, { 21098, 0xFFFF }, { 21114, 0xFFFF }, { 21130, 0xFFFF }, - { 21146, 0xFFFF }, { 21162, 0xFFFF }, { 21178, 0xFFFF }, { 21194, 0xFFFF }, - /* 0xF200 */ - { 21210, 0xFFFF }, { 21226, 0xFFFF }, { 21242, 0xFFFF }, { 21258, 0xFFFF }, - { 21274, 0xFFFF }, { 21290, 0xFFFF }, { 21306, 0xFFFF }, { 21322, 0xFFFF }, - { 21338, 0xFFFF }, { 21354, 0xFFFF }, { 21370, 0xFFFF }, { 21386, 0xFFFF }, - { 21402, 0xFFFF }, { 21418, 0xFFFF }, { 21434, 0xFFFF }, { 21450, 0xFFFF }, - /* 0xF300 */ - { 21466, 0xFFFF }, { 21482, 0xFFFF }, { 21498, 0xFFFF }, { 21514, 0xFFFF }, - { 21530, 0xFFFF }, { 21546, 0xFFFF }, { 21562, 0xFFFF }, { 21578, 0xFFFF }, - { 21594, 0xFFFF }, { 21610, 0xFFFF }, { 21626, 0xFFFF }, { 21642, 0xFFFF }, - { 21658, 0xFFFF }, { 21674, 0xFFFF }, { 21690, 0xFFFF }, { 21706, 0xFFFF }, - /* 0xF400 */ - { 21722, 0xFFFF }, { 21738, 0xFFFF }, { 21754, 0xFFFF }, { 21770, 0xFFFF }, - { 21786, 0xFFFF }, { 21802, 0xFFFF }, { 21818, 0xFFFF }, { 21834, 0xFFFF }, - { 21850, 0xFFFF }, { 21866, 0xFFFF }, { 21882, 0xFFFF }, { 21898, 0xFFFF }, - { 21914, 0xFFFF }, { 21930, 0xFFFF }, { 21946, 0xFFFF }, { 21962, 0xFFFF }, - /* 0xF500 */ - { 21978, 0xFFFF }, { 21994, 0xFFFF }, { 22010, 0xFFFF }, { 22026, 0xFFFF }, - { 22042, 0xFFFF }, { 22058, 0xFFFF }, { 22074, 0xFFFF }, { 22090, 0xFFFF }, - { 22106, 0xFFFF }, { 22122, 0xFFFF }, { 22138, 0xFFFF }, { 22154, 0xFFFF }, - { 22170, 0xFFFF }, { 22186, 0xFFFF }, { 22202, 0xFFFF }, { 22218, 0xFFFF }, - /* 0xF600 */ - { 22234, 0xFFFF }, { 22250, 0xFFFF }, { 22266, 0xFFFF }, { 22282, 0xFFFF }, - { 22298, 0xFFFF }, { 22314, 0xFFFF }, { 22330, 0xFFFF }, { 22346, 0xFFFF }, - { 22362, 0xFFFF }, { 22378, 0xFFFF }, { 22394, 0xFFFF }, { 22410, 0xFFFF }, - { 22426, 0xFFFF }, { 22442, 0xFFFF }, { 22458, 0xFFFF }, { 22474, 0xFFFF }, - /* 0xF700 */ - { 22490, 0xFFFF }, { 22506, 0xFFFF }, { 22522, 0xFFFF }, { 22538, 0xFFFF }, - { 22554, 0xFFFF }, { 22570, 0xFFFF }, { 22586, 0xFFFF }, { 22602, 0xFFFF }, - { 22618, 0xFFFF }, { 22634, 0xFFFF }, { 22650, 0xFFFF }, { 22666, 0xFFFF }, - { 22682, 0xFFFF }, { 22698, 0xFFFF }, { 22714, 0xFFFF }, { 22730, 0xFFFF }, - /* 0xF800 */ - { 22746, 0xFFFF }, { 22762, 0xFFFF }, { 22778, 0xFFFF }, { 22794, 0xFFFF }, - { 22810, 0x01FF }, { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 }, - { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 }, - { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0100 }, - /* 0xF900 */ - { 22820, 0xFFFF }, { 22836, 0xFFFF }, { 22852, 0xEFFF }, { 22867, 0xFFFF }, - { 22883, 0xFFFF }, { 22899, 0xFFFF }, { 22915, 0xFFFF }, { 22931, 0xFDFF }, - { 22946, 0xFFFF }, { 22962, 0xFFDF }, { 22977, 0xFFFF }, { 22993, 0xFFFF }, - { 23009, 0xFFFF }, { 23025, 0xFFFF }, { 23041, 0xFF7F }, { 23056, 0xFFFD }, - /* 0xFA00 */ - { 23071, 0x3FFF }, { 23085, 0x7EE5 }, { 23096, 0x3C64 }, -}; -static const Summary16 big5hkscs_uni2index_pagefe[31] = { - /* 0xFE00 */ - { 23103, 0x0000 }, { 23103, 0x0000 }, { 23103, 0x0000 }, { 23103, 0xFFFB }, - { 23118, 0xFE1F }, { 23130, 0xFEF7 }, { 23144, 0x0F7F }, { 23155, 0x0000 }, - { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 }, - { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 }, - /* 0xFF00 */ - { 23155, 0xFFFE }, { 23170, 0xFFFF }, { 23186, 0xFFFF }, { 23202, 0xFFFF }, - { 23218, 0xFFFF }, { 23234, 0x7FFF }, { 23249, 0x0010 }, { 23250, 0x0000 }, - { 23250, 0x0000 }, { 23250, 0x0000 }, { 23250, 0x0000 }, { 23250, 0x0000 }, - { 23250, 0x0000 }, { 23250, 0x0000 }, { 23250, 0x203F }, -}; -static const Summary16 big5hkscs_uni2index_page200[2335] = { - /* 0x20000 */ - { 23257, 0x0000 }, { 23257, 0x0000 }, { 23257, 0x0002 }, { 23258, 0x4000 }, - { 23259, 0x4040 }, { 23261, 0x0000 }, { 23261, 0x0100 }, { 23262, 0x0000 }, - { 23262, 0x04C0 }, { 23265, 0x0010 }, { 23266, 0x0000 }, { 23266, 0x0000 }, - { 23266, 0x3C00 }, { 23270, 0x0002 }, { 23271, 0x4000 }, { 23272, 0x0000 }, - /* 0x20100 */ - { 23272, 0x5000 }, { 23274, 0x0100 }, { 23275, 0x0000 }, { 23275, 0x0000 }, - { 23275, 0x0000 }, { 23275, 0x0000 }, { 23275, 0x0000 }, { 23275, 0x0000 }, - { 23275, 0x0000 }, { 23275, 0x0000 }, { 23275, 0x0A00 }, { 23277, 0x0000 }, - { 23277, 0x0002 }, { 23278, 0x0010 }, { 23279, 0x0000 }, { 23279, 0x0004 }, - /* 0x20200 */ - { 23280, 0x1010 }, { 23282, 0x0010 }, { 23283, 0x0000 }, { 23283, 0x0000 }, - { 23283, 0x0000 }, { 23283, 0x0800 }, { 23284, 0x0000 }, { 23284, 0x0030 }, - { 23286, 0x0000 }, { 23286, 0x4200 }, { 23288, 0x0001 }, { 23289, 0x8080 }, - { 23291, 0x0001 }, { 23292, 0x0000 }, { 23292, 0x0020 }, { 23293, 0x0000 }, - /* 0x20300 */ - { 23293, 0x0400 }, { 23294, 0x0000 }, { 23294, 0x0020 }, { 23295, 0x0000 }, - { 23295, 0x00E2 }, { 23299, 0x0000 }, { 23299, 0x0000 }, { 23299, 0xC000 }, - { 23301, 0x0001 }, { 23302, 0x0000 }, { 23302, 0x0081 }, { 23304, 0x0020 }, - { 23305, 0x0A00 }, { 23307, 0x0000 }, { 23307, 0x0000 }, { 23307, 0x1020 }, - /* 0x20400 */ - { 23309, 0x0000 }, { 23309, 0x8018 }, { 23312, 0x0000 }, { 23312, 0x0000 }, - { 23312, 0x0000 }, { 23312, 0x0000 }, { 23312, 0x0020 }, { 23313, 0x0000 }, - { 23313, 0x4080 }, { 23315, 0x0006 }, { 23317, 0x0008 }, { 23318, 0x0000 }, - { 23318, 0x0000 }, { 23318, 0x0080 }, { 23319, 0x0000 }, { 23319, 0x5000 }, - /* 0x20500 */ - { 23321, 0x0000 }, { 23321, 0x0000 }, { 23321, 0x0000 }, { 23321, 0x0000 }, - { 23321, 0x0080 }, { 23322, 0x0000 }, { 23322, 0x0000 }, { 23322, 0x0000 }, - { 23322, 0x4000 }, { 23323, 0x0000 }, { 23323, 0x0020 }, { 23324, 0x0008 }, - { 23325, 0x0408 }, { 23327, 0x8021 }, { 23330, 0x0801 }, { 23332, 0x0000 }, - /* 0x20600 */ - { 23332, 0x0000 }, { 23332, 0x0622 }, { 23336, 0x0000 }, { 23336, 0x0001 }, - { 23337, 0x0000 }, { 23337, 0x0040 }, { 23338, 0x0000 }, { 23338, 0x0040 }, - { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 }, - { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 }, - /* 0x20700 */ - { 23339, 0x4000 }, { 23340, 0x0000 }, { 23340, 0x0000 }, { 23340, 0x0002 }, - { 23341, 0x0000 }, { 23341, 0x0000 }, { 23341, 0x0000 }, { 23341, 0x0200 }, - { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 }, - { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 }, - /* 0x20800 */ - { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x1000 }, { 23343, 0x0000 }, - { 23343, 0x0000 }, { 23343, 0x0000 }, { 23343, 0x0000 }, { 23343, 0x0008 }, - { 23344, 0x0000 }, { 23344, 0x0000 }, { 23344, 0x0000 }, { 23344, 0x0000 }, - { 23344, 0x0000 }, { 23344, 0x0020 }, { 23345, 0x0000 }, { 23345, 0x0000 }, - /* 0x20900 */ - { 23345, 0x0000 }, { 23345, 0x0040 }, { 23346, 0x0008 }, { 23347, 0x0000 }, - { 23347, 0x0000 }, { 23347, 0x0010 }, { 23348, 0x0000 }, { 23348, 0x0200 }, - { 23349, 0x0000 }, { 23349, 0x0000 }, { 23349, 0x0000 }, { 23349, 0x0000 }, - { 23349, 0x0000 }, { 23349, 0x0000 }, { 23349, 0x0080 }, { 23350, 0x0000 }, - /* 0x20A00 */ - { 23350, 0x0000 }, { 23350, 0x0002 }, { 23351, 0x0000 }, { 23351, 0x0000 }, - { 23351, 0x0000 }, { 23351, 0x0001 }, { 23352, 0x0000 }, { 23352, 0x0000 }, - { 23352, 0x0000 }, { 23352, 0x0000 }, { 23352, 0x0000 }, { 23352, 0x0010 }, - { 23353, 0x2004 }, { 23355, 0x0000 }, { 23355, 0x0000 }, { 23355, 0x0000 }, - /* 0x20B00 */ - { 23355, 0x2000 }, { 23356, 0x0000 }, { 23356, 0x0000 }, { 23356, 0x0000 }, - { 23356, 0x0000 }, { 23356, 0x0000 }, { 23356, 0x0000 }, { 23356, 0x0000 }, - { 23356, 0x8000 }, { 23357, 0x0000 }, { 23357, 0x0300 }, { 23359, 0x8000 }, - { 23360, 0x0840 }, { 23362, 0x0000 }, { 23362, 0x0804 }, { 23364, 0x8800 }, - /* 0x20C00 */ - { 23366, 0x2800 }, { 23368, 0x0000 }, { 23368, 0x0001 }, { 23369, 0x0C10 }, - { 23372, 0x000E }, { 23375, 0x0008 }, { 23376, 0x0020 }, { 23377, 0x1180 }, - { 23380, 0x2000 }, { 23381, 0x1040 }, { 23383, 0x0000 }, { 23383, 0x0120 }, - { 23385, 0x8000 }, { 23386, 0x2078 }, { 23391, 0x2000 }, { 23392, 0x8000 }, - /* 0x20D00 */ - { 23393, 0x0000 }, { 23393, 0x0020 }, { 23394, 0x0100 }, { 23395, 0x0006 }, - { 23397, 0x73C0 }, { 23404, 0x0000 }, { 23404, 0x8000 }, { 23405, 0xD012 }, - { 23410, 0x0000 }, { 23410, 0x1040 }, { 23412, 0x0080 }, { 23413, 0x0004 }, - { 23414, 0x0100 }, { 23415, 0x0000 }, { 23415, 0x0000 }, { 23415, 0x0000 }, - /* 0x20E00 */ - { 23415, 0xE610 }, { 23421, 0x2043 }, { 23425, 0x0000 }, { 23425, 0x0000 }, - { 23425, 0x1000 }, { 23426, 0x0000 }, { 23426, 0x2000 }, { 23427, 0x0FE8 }, - { 23435, 0x1000 }, { 23436, 0x2140 }, { 23439, 0x1C04 }, { 23443, 0x0040 }, - { 23444, 0x0000 }, { 23444, 0x2180 }, { 23447, 0x0000 }, { 23447, 0x0F00 }, - /* 0x20F00 */ - { 23451, 0x0000 }, { 23451, 0x2000 }, { 23452, 0x6040 }, { 23455, 0x0803 }, - { 23458, 0x1000 }, { 23459, 0x0000 }, { 23459, 0x0010 }, { 23460, 0x0000 }, - { 23460, 0x2000 }, { 23461, 0x0001 }, { 23462, 0x2000 }, { 23463, 0x1070 }, - { 23467, 0x0000 }, { 23467, 0x8000 }, { 23468, 0x3C00 }, { 23472, 0x0000 }, - /* 0x21000 */ - { 23472, 0x0000 }, { 23472, 0x6010 }, { 23475, 0x0000 }, { 23475, 0x0000 }, - { 23475, 0x8000 }, { 23476, 0x1000 }, { 23477, 0x8000 }, { 23478, 0x09E0 }, - { 23483, 0x0100 }, { 23484, 0x2040 }, { 23486, 0x0000 }, { 23486, 0x8010 }, - { 23488, 0x8383 }, { 23494, 0x0008 }, { 23495, 0x0010 }, { 23496, 0x0070 }, - /* 0x21100 */ - { 23499, 0x0000 }, { 23499, 0x0000 }, { 23499, 0x8000 }, { 23500, 0x2800 }, - { 23502, 0x8120 }, { 23505, 0x0000 }, { 23505, 0x0000 }, { 23505, 0x0000 }, - { 23505, 0x0081 }, { 23507, 0x0000 }, { 23507, 0x0000 }, { 23507, 0x0000 }, - { 23507, 0x0000 }, { 23507, 0x0200 }, { 23508, 0x0000 }, { 23508, 0x0000 }, - /* 0x21200 */ - { 23508, 0x0000 }, { 23508, 0x0000 }, { 23508, 0x0000 }, { 23508, 0x1000 }, - { 23509, 0x8000 }, { 23510, 0x0000 }, { 23510, 0x0000 }, { 23510, 0x1000 }, - { 23511, 0x0000 }, { 23511, 0x0000 }, { 23511, 0x0300 }, { 23513, 0x0001 }, - { 23514, 0x0000 }, { 23514, 0x0000 }, { 23514, 0x0008 }, { 23515, 0x4000 }, - /* 0x21300 */ - { 23516, 0x003C }, { 23520, 0x0000 }, { 23520, 0x0000 }, { 23520, 0x0440 }, - { 23522, 0x0000 }, { 23522, 0x0000 }, { 23522, 0x0000 }, { 23522, 0x0060 }, - { 23524, 0x4000 }, { 23525, 0x1100 }, { 23527, 0x0000 }, { 23527, 0x0000 }, - { 23527, 0x0060 }, { 23529, 0x0000 }, { 23529, 0x2000 }, { 23530, 0x4000 }, - /* 0x21400 */ - { 23531, 0x0000 }, { 23531, 0x0048 }, { 23533, 0x0010 }, { 23534, 0x8000 }, - { 23535, 0x0000 }, { 23535, 0x0034 }, { 23538, 0x0000 }, { 23538, 0x0000 }, - { 23538, 0x0400 }, { 23539, 0x0080 }, { 23540, 0x0000 }, { 23540, 0x0040 }, - { 23541, 0x0000 }, { 23541, 0x0000 }, { 23541, 0x0100 }, { 23542, 0x2000 }, - /* 0x21500 */ - { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0000 }, - { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0080 }, - { 23544, 0x0004 }, { 23545, 0x0040 }, { 23546, 0x0000 }, { 23546, 0x0000 }, - { 23546, 0x0000 }, { 23546, 0x0000 }, { 23546, 0x0000 }, { 23546, 0x0000 }, - /* 0x21600 */ - { 23546, 0x0400 }, { 23547, 0x0208 }, { 23549, 0x0000 }, { 23549, 0x4000 }, - { 23550, 0x0000 }, { 23550, 0x0000 }, { 23550, 0x0002 }, { 23551, 0x0000 }, - { 23551, 0x0000 }, { 23551, 0x0004 }, { 23552, 0x0000 }, { 23552, 0x0500 }, - { 23554, 0x0007 }, { 23557, 0x8028 }, { 23560, 0x01C0 }, { 23563, 0x5C00 }, - /* 0x21700 */ - { 23567, 0x2000 }, { 23568, 0x0001 }, { 23569, 0x0040 }, { 23570, 0x1C00 }, - { 23573, 0x0000 }, { 23573, 0x0080 }, { 23574, 0xF000 }, { 23578, 0x001B }, - { 23582, 0x0000 }, { 23582, 0x0000 }, { 23582, 0x0800 }, { 23583, 0x003F }, - { 23589, 0x0088 }, { 23591, 0x9E00 }, { 23596, 0x8000 }, { 23597, 0x1F60 }, - /* 0x21800 */ - { 23604, 0x0000 }, { 23604, 0x0000 }, { 23604, 0x2701 }, { 23609, 0x0E00 }, - { 23612, 0x0021 }, { 23614, 0x4004 }, { 23616, 0x001E }, { 23620, 0x0880 }, - { 23622, 0x0038 }, { 23625, 0xC000 }, { 23627, 0x0007 }, { 23630, 0xC000 }, - { 23632, 0x0000 }, { 23632, 0x03C2 }, { 23637, 0x0000 }, { 23637, 0x0400 }, - /* 0x21900 */ - { 23638, 0x0038 }, { 23641, 0x1027 }, { 23646, 0x0084 }, { 23648, 0x0800 }, - { 23649, 0x0010 }, { 23650, 0x0100 }, { 23651, 0x0400 }, { 23652, 0x1000 }, - { 23653, 0x0109 }, { 23656, 0x0040 }, { 23657, 0x0000 }, { 23657, 0x0000 }, - { 23657, 0x0000 }, { 23657, 0x0800 }, { 23658, 0x0000 }, { 23658, 0x0008 }, - /* 0x21A00 */ - { 23659, 0x0000 }, { 23659, 0x0000 }, { 23659, 0x2000 }, { 23660, 0x0010 }, - { 23661, 0x0820 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, - { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, - { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, - /* 0x21B00 */ - { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, - { 23663, 0x0010 }, { 23664, 0x0000 }, { 23664, 0x0000 }, { 23664, 0x0000 }, - { 23664, 0x0000 }, { 23664, 0x0000 }, { 23664, 0x0000 }, { 23664, 0x0000 }, - { 23664, 0x0006 }, { 23666, 0x0000 }, { 23666, 0x0000 }, { 23666, 0x0000 }, - /* 0x21C00 */ - { 23666, 0x0000 }, { 23666, 0x0000 }, { 23666, 0x0400 }, { 23667, 0x0000 }, - { 23667, 0x0000 }, { 23667, 0x0000 }, { 23667, 0x0000 }, { 23667, 0x0001 }, - { 23668, 0x0000 }, { 23668, 0x0000 }, { 23668, 0x1024 }, { 23671, 0x0000 }, - { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 }, - /* 0x21D00 */ - { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 }, - { 23671, 0x0040 }, { 23672, 0x0000 }, { 23672, 0x0000 }, { 23672, 0x0000 }, - { 23672, 0x0000 }, { 23672, 0x0001 }, { 23673, 0x0000 }, { 23673, 0x0440 }, - { 23675, 0x0400 }, { 23676, 0x0002 }, { 23677, 0x0800 }, { 23678, 0x0200 }, - /* 0x21E00 */ - { 23679, 0x0000 }, { 23679, 0x1000 }, { 23680, 0x0000 }, { 23680, 0x2080 }, - { 23682, 0x0000 }, { 23682, 0x0000 }, { 23682, 0x0000 }, { 23682, 0x0000 }, - { 23682, 0x0200 }, { 23683, 0x0000 }, { 23683, 0x0110 }, { 23685, 0x0000 }, - { 23685, 0x0100 }, { 23686, 0x0020 }, { 23687, 0x0000 }, { 23687, 0x0000 }, - /* 0x21F00 */ - { 23687, 0x8000 }, { 23688, 0x0020 }, { 23689, 0x0000 }, { 23689, 0x0000 }, - { 23689, 0x0000 }, { 23689, 0x0000 }, { 23689, 0x0400 }, { 23690, 0x0000 }, - { 23690, 0x0000 }, { 23690, 0x4000 }, { 23691, 0x0002 }, { 23692, 0x0000 }, - { 23692, 0x0000 }, { 23692, 0x0000 }, { 23692, 0x0100 }, { 23693, 0x0000 }, - /* 0x22000 */ - { 23693, 0x0000 }, { 23693, 0x0000 }, { 23693, 0x0000 }, { 23693, 0x0000 }, - { 23693, 0x0220 }, { 23695, 0x0000 }, { 23695, 0x0000 }, { 23695, 0x4000 }, - { 23696, 0x0000 }, { 23696, 0x0400 }, { 23697, 0x0000 }, { 23697, 0x0000 }, - { 23697, 0x0080 }, { 23698, 0x0000 }, { 23698, 0x0000 }, { 23698, 0x1000 }, - /* 0x22100 */ - { 23699, 0x0000 }, { 23699, 0x0000 }, { 23699, 0x0400 }, { 23700, 0x0000 }, - { 23700, 0x0000 }, { 23700, 0x0800 }, { 23701, 0x0000 }, { 23701, 0x0408 }, - { 23703, 0x0000 }, { 23703, 0x0000 }, { 23703, 0x0002 }, { 23704, 0x0000 }, - { 23704, 0x0008 }, { 23705, 0x0000 }, { 23705, 0x0000 }, { 23705, 0x0000 }, - /* 0x22200 */ - { 23705, 0x0100 }, { 23706, 0x0000 }, { 23706, 0x0000 }, { 23706, 0x0000 }, - { 23706, 0x0000 }, { 23706, 0x0000 }, { 23706, 0x0000 }, { 23706, 0x1000 }, - { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 }, - { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 }, - /* 0x22300 */ - { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0022 }, { 23709, 0x0000 }, - { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x0000 }, - { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x2000 }, - { 23710, 0x0000 }, { 23710, 0x0081 }, { 23712, 0x0000 }, { 23712, 0x0400 }, - /* 0x22400 */ - { 23713, 0x0000 }, { 23713, 0x0000 }, { 23713, 0x0000 }, { 23713, 0x0000 }, - { 23713, 0x0000 }, { 23713, 0x0000 }, { 23713, 0x0020 }, { 23714, 0x0002 }, - { 23715, 0x0800 }, { 23716, 0x0002 }, { 23717, 0x0000 }, { 23717, 0x0001 }, - { 23718, 0x0000 }, { 23718, 0x0000 }, { 23718, 0x2000 }, { 23719, 0x0000 }, - /* 0x22500 */ - { 23719, 0x0000 }, { 23719, 0x0808 }, { 23721, 0x0000 }, { 23721, 0x0001 }, - { 23722, 0x0000 }, { 23722, 0x0010 }, { 23723, 0x0000 }, { 23723, 0x0000 }, - { 23723, 0x2000 }, { 23724, 0x0000 }, { 23724, 0x8000 }, { 23725, 0x4000 }, - { 23726, 0x0000 }, { 23726, 0x0000 }, { 23726, 0x0000 }, { 23726, 0x0000 }, - /* 0x22600 */ - { 23726, 0x0000 }, { 23726, 0x1800 }, { 23728, 0x0800 }, { 23729, 0x0000 }, - { 23729, 0x0000 }, { 23729, 0x0000 }, { 23729, 0x0100 }, { 23730, 0x0400 }, - { 23731, 0x0000 }, { 23731, 0x0140 }, { 23733, 0x0000 }, { 23733, 0x0000 }, - { 23733, 0x0000 }, { 23733, 0x0000 }, { 23733, 0x0000 }, { 23733, 0x0070 }, - /* 0x22700 */ - { 23736, 0x0000 }, { 23736, 0x8814 }, { 23740, 0x0400 }, { 23741, 0x0000 }, - { 23741, 0x0000 }, { 23741, 0x0000 }, { 23741, 0x0000 }, { 23741, 0x0020 }, - { 23742, 0x0002 }, { 23743, 0x0000 }, { 23743, 0x0000 }, { 23743, 0x0030 }, - { 23745, 0x2000 }, { 23746, 0x0000 }, { 23746, 0x0000 }, { 23746, 0x0000 }, - /* 0x22800 */ - { 23746, 0x0008 }, { 23747, 0x0000 }, { 23747, 0x0000 }, { 23747, 0x0000 }, - { 23747, 0x0000 }, { 23747, 0x8000 }, { 23748, 0x0001 }, { 23749, 0x0002 }, - { 23750, 0x0000 }, { 23750, 0x0000 }, { 23750, 0x2000 }, { 23751, 0x0000 }, - { 23751, 0x0002 }, { 23752, 0x0000 }, { 23752, 0x0000 }, { 23752, 0x0080 }, - /* 0x22900 */ - { 23753, 0x0000 }, { 23753, 0x0000 }, { 23753, 0x0040 }, { 23754, 0x0200 }, - { 23755, 0x8000 }, { 23756, 0x0000 }, { 23756, 0x0880 }, { 23758, 0x0000 }, - { 23758, 0x0001 }, { 23759, 0x0008 }, { 23760, 0x0000 }, { 23760, 0x0000 }, - { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 }, - /* 0x22A00 */ - { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 }, - { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0040 }, { 23761, 0x0000 }, - { 23761, 0x0000 }, { 23761, 0x0000 }, { 23761, 0x0000 }, { 23761, 0x0000 }, - { 23761, 0x8000 }, { 23762, 0x0020 }, { 23763, 0x0140 }, { 23765, 0x0000 }, - /* 0x22B00 */ - { 23765, 0x4000 }, { 23766, 0x0000 }, { 23766, 0x0004 }, { 23767, 0x8000 }, - { 23768, 0x0008 }, { 23769, 0x0000 }, { 23769, 0x0400 }, { 23770, 0x0000 }, - { 23770, 0x0000 }, { 23770, 0x0000 }, { 23770, 0x0000 }, { 23770, 0x0000 }, - { 23770, 0x4400 }, { 23772, 0x0000 }, { 23772, 0x0000 }, { 23772, 0x0000 }, - /* 0x22C00 */ - { 23772, 0x0000 }, { 23772, 0x0000 }, { 23772, 0x00C0 }, { 23774, 0x0100 }, - { 23775, 0x1000 }, { 23776, 0x0022 }, { 23778, 0x0004 }, { 23779, 0x0000 }, - { 23779, 0x0100 }, { 23780, 0x0800 }, { 23781, 0x0202 }, { 23783, 0x0084 }, - { 23785, 0x0244 }, { 23788, 0x0000 }, { 23788, 0x0000 }, { 23788, 0x0000 }, - /* 0x22D00 */ - { 23788, 0x0180 }, { 23790, 0x0004 }, { 23791, 0x0000 }, { 23791, 0x0000 }, - { 23791, 0x1010 }, { 23793, 0x0000 }, { 23793, 0x0080 }, { 23794, 0x0000 }, - { 23794, 0x2000 }, { 23795, 0x0020 }, { 23796, 0x0019 }, { 23799, 0x0080 }, - { 23800, 0x0000 }, { 23800, 0x0000 }, { 23800, 0x4000 }, { 23801, 0x0000 }, - /* 0x22E00 */ - { 23801, 0x2000 }, { 23802, 0x0000 }, { 23802, 0x0000 }, { 23802, 0x0040 }, - { 23803, 0x0004 }, { 23804, 0x0000 }, { 23804, 0x0000 }, { 23804, 0x0100 }, - { 23805, 0x0800 }, { 23806, 0x0000 }, { 23806, 0x0000 }, { 23806, 0x0008 }, - { 23807, 0x0000 }, { 23807, 0x0000 }, { 23807, 0x8000 }, { 23808, 0x0000 }, - /* 0x22F00 */ - { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0000 }, - { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0010 }, - { 23809, 0x0000 }, { 23809, 0x0000 }, { 23809, 0x0000 }, { 23809, 0x0000 }, - { 23809, 0x1000 }, { 23810, 0x0000 }, { 23810, 0x0008 }, { 23811, 0x0000 }, - /* 0x23000 */ - { 23811, 0x0000 }, { 23811, 0x0000 }, { 23811, 0x0000 }, { 23811, 0x0008 }, - { 23812, 0x0810 }, { 23814, 0x0000 }, { 23814, 0x0040 }, { 23815, 0x6000 }, - { 23817, 0x4000 }, { 23818, 0x0000 }, { 23818, 0x0000 }, { 23818, 0x1080 }, - { 23820, 0x0000 }, { 23820, 0x0400 }, { 23821, 0x0000 }, { 23821, 0x0000 }, - /* 0x23100 */ - { 23821, 0x0008 }, { 23822, 0x0000 }, { 23822, 0x0000 }, { 23822, 0x2000 }, - { 23823, 0x0000 }, { 23823, 0x0000 }, { 23823, 0x0000 }, { 23823, 0x2000 }, - { 23824, 0x0004 }, { 23825, 0x0000 }, { 23825, 0x0030 }, { 23827, 0x0008 }, - { 23828, 0x0300 }, { 23830, 0x0000 }, { 23830, 0x0000 }, { 23830, 0x0380 }, - /* 0x23200 */ - { 23833, 0x8000 }, { 23834, 0x0000 }, { 23834, 0x8020 }, { 23836, 0x001E }, - { 23840, 0x0000 }, { 23840, 0x0000 }, { 23840, 0x0004 }, { 23841, 0x0000 }, - { 23841, 0x0602 }, { 23844, 0x0000 }, { 23844, 0x3800 }, { 23847, 0x0000 }, - { 23847, 0x0000 }, { 23847, 0x0004 }, { 23848, 0x0003 }, { 23850, 0x0000 }, - /* 0x23300 */ - { 23850, 0x0401 }, { 23852, 0x8000 }, { 23853, 0x0000 }, { 23853, 0x0000 }, - { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0000 }, - { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0010 }, - { 23854, 0x1000 }, { 23855, 0x4000 }, { 23856, 0x0040 }, { 23857, 0x4630 }, - /* 0x23400 */ - { 23862, 0x0001 }, { 23863, 0x0000 }, { 23863, 0x0000 }, { 23863, 0x8000 }, - { 23864, 0x0000 }, { 23864, 0x0001 }, { 23865, 0x8000 }, { 23866, 0x0004 }, - { 23867, 0x0000 }, { 23867, 0x0000 }, { 23867, 0x0000 }, { 23867, 0x0000 }, - { 23867, 0x0000 }, { 23867, 0x0000 }, { 23867, 0x0020 }, { 23868, 0x0000 }, - /* 0x23500 */ - { 23868, 0x0000 }, { 23868, 0x0200 }, { 23869, 0x0000 }, { 23869, 0x0001 }, - { 23870, 0x0000 }, { 23870, 0x0400 }, { 23871, 0x0080 }, { 23872, 0x0000 }, - { 23872, 0x0000 }, { 23872, 0x1220 }, { 23875, 0x0000 }, { 23875, 0x0000 }, - { 23875, 0xE000 }, { 23878, 0x0000 }, { 23878, 0x0000 }, { 23878, 0x0008 }, - /* 0x23600 */ - { 23879, 0x0001 }, { 23880, 0x0400 }, { 23881, 0x0000 }, { 23881, 0x1000 }, - { 23882, 0x0001 }, { 23883, 0x8200 }, { 23885, 0x0000 }, { 23885, 0x0080 }, - { 23886, 0x0000 }, { 23886, 0x0000 }, { 23886, 0x2040 }, { 23888, 0x0400 }, - { 23889, 0x0000 }, { 23889, 0x8000 }, { 23890, 0x4000 }, { 23891, 0x0000 }, - /* 0x23700 */ - { 23891, 0x0008 }, { 23892, 0x0040 }, { 23893, 0xA001 }, { 23896, 0x8000 }, - { 23897, 0x0000 }, { 23897, 0x0000 }, { 23897, 0x0040 }, { 23898, 0x0000 }, - { 23898, 0x0002 }, { 23899, 0x0000 }, { 23899, 0x0004 }, { 23900, 0x1000 }, - { 23901, 0x0004 }, { 23902, 0x00E0 }, { 23905, 0x0000 }, { 23905, 0x0000 }, - /* 0x23800 */ - { 23905, 0x0000 }, { 23905, 0x0000 }, { 23905, 0x0000 }, { 23905, 0x0400 }, - { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, - { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, - { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, - /* 0x23900 */ - { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, - { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, - { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, - { 23906, 0x0004 }, { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 }, - /* 0x23A00 */ - { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 }, - { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 }, - { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0080 }, { 23908, 0x0000 }, - { 23908, 0x0000 }, { 23908, 0x0800 }, { 23909, 0x4000 }, { 23910, 0x0400 }, - /* 0x23B00 */ - { 23911, 0x0000 }, { 23911, 0x0000 }, { 23911, 0x0000 }, { 23911, 0x0000 }, - { 23911, 0x0000 }, { 23911, 0x0400 }, { 23912, 0x0000 }, { 23912, 0x0000 }, - { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, - { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, - /* 0x23C00 */ - { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, - { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0008 }, { 23913, 0x0000 }, - { 23913, 0x0000 }, { 23913, 0x0E00 }, { 23916, 0x0000 }, { 23916, 0x00A0 }, - { 23918, 0x0380 }, { 23921, 0x0000 }, { 23921, 0x0000 }, { 23921, 0xF000 }, - /* 0x23D00 */ - { 23925, 0x0000 }, { 23925, 0x0000 }, { 23925, 0x0000 }, { 23925, 0x0000 }, - { 23925, 0x0001 }, { 23926, 0x0800 }, { 23927, 0x0000 }, { 23927, 0x4000 }, - { 23928, 0x8000 }, { 23929, 0x0000 }, { 23929, 0x0000 }, { 23929, 0x3FC0 }, - { 23937, 0x0000 }, { 23937, 0x0000 }, { 23937, 0x0008 }, { 23938, 0x0100 }, - /* 0x23E00 */ - { 23939, 0x0000 }, { 23939, 0x0002 }, { 23940, 0xF000 }, { 23944, 0x0203 }, - { 23947, 0x0000 }, { 23947, 0x0000 }, { 23947, 0x0000 }, { 23947, 0x0000 }, - { 23947, 0x0F00 }, { 23951, 0x0000 }, { 23951, 0x0000 }, { 23951, 0x8200 }, - { 23953, 0x0000 }, { 23953, 0x0080 }, { 23954, 0x0000 }, { 23954, 0x1F80 }, - /* 0x23F00 */ - { 23960, 0x0000 }, { 23960, 0x0000 }, { 23960, 0x0000 }, { 23960, 0x0020 }, - { 23961, 0x0402 }, { 23963, 0x0000 }, { 23963, 0x0000 }, { 23963, 0x8000 }, - { 23964, 0x8007 }, { 23968, 0x0000 }, { 23968, 0x0000 }, { 23968, 0x0090 }, - { 23970, 0x0021 }, { 23972, 0x0000 }, { 23972, 0xF800 }, { 23977, 0x0001 }, - /* 0x24000 */ - { 23978, 0x0000 }, { 23978, 0x0002 }, { 23979, 0x0000 }, { 23979, 0x3E00 }, - { 23984, 0x0000 }, { 23984, 0x0080 }, { 23985, 0x0000 }, { 23985, 0x0000 }, - { 23985, 0x3820 }, { 23989, 0x0002 }, { 23990, 0x0000 }, { 23990, 0x0000 }, - { 23990, 0x0200 }, { 23991, 0x0000 }, { 23991, 0x0002 }, { 23992, 0x0000 }, - /* 0x24100 */ - { 23992, 0x8010 }, { 23994, 0x0200 }, { 23995, 0x0000 }, { 23995, 0x8000 }, - { 23996, 0x4011 }, { 23999, 0x90E0 }, { 24004, 0x0000 }, { 24004, 0x0480 }, - { 24006, 0x0000 }, { 24006, 0x0000 }, { 24006, 0x1038 }, { 24010, 0x0020 }, - { 24011, 0x2000 }, { 24012, 0x0000 }, { 24012, 0x0004 }, { 24013, 0x1000 }, - /* 0x24200 */ - { 24014, 0x0000 }, { 24014, 0x0800 }, { 24015, 0x0000 }, { 24015, 0x0000 }, - { 24015, 0x0800 }, { 24016, 0x0240 }, { 24018, 0x0000 }, { 24018, 0x01C0 }, - { 24021, 0x0010 }, { 24022, 0x0028 }, { 24024, 0x0020 }, { 24025, 0x0000 }, - { 24025, 0x0602 }, { 24028, 0x0000 }, { 24028, 0x4000 }, { 24029, 0x0400 }, - /* 0x24300 */ - { 24030, 0x2000 }, { 24031, 0x0400 }, { 24032, 0x0000 }, { 24032, 0x0010 }, - { 24033, 0x0100 }, { 24034, 0x0000 }, { 24034, 0x003C }, { 24038, 0x0000 }, - { 24038, 0x1000 }, { 24039, 0x1040 }, { 24041, 0x0000 }, { 24041, 0x2000 }, - { 24042, 0x0002 }, { 24043, 0x0000 }, { 24043, 0x0600 }, { 24045, 0x0104 }, - /* 0x24400 */ - { 24047, 0x0010 }, { 24048, 0x0000 }, { 24048, 0x0000 }, { 24048, 0x0060 }, - { 24050, 0x0000 }, { 24050, 0x0C00 }, { 24052, 0x0000 }, { 24052, 0x0008 }, - { 24053, 0x0180 }, { 24055, 0x0000 }, { 24055, 0x0000 }, { 24055, 0x1200 }, - { 24057, 0x4000 }, { 24058, 0x0048 }, { 24060, 0x0000 }, { 24060, 0x0000 }, - /* 0x24500 */ - { 24060, 0x0020 }, { 24061, 0x0000 }, { 24061, 0x0002 }, { 24062, 0x0000 }, - { 24062, 0x0000 }, { 24062, 0x0000 }, { 24062, 0x0000 }, { 24062, 0x0100 }, - { 24063, 0x0000 }, { 24063, 0x0000 }, { 24063, 0x0000 }, { 24063, 0x0000 }, - { 24063, 0x0100 }, { 24064, 0x0000 }, { 24064, 0x0000 }, { 24064, 0x0000 }, - /* 0x24600 */ - { 24064, 0x0000 }, { 24064, 0x0100 }, { 24065, 0x0400 }, { 24066, 0x0000 }, - { 24066, 0x0000 }, { 24066, 0x0000 }, { 24066, 0x0020 }, { 24067, 0x0010 }, - { 24068, 0x0000 }, { 24068, 0x0080 }, { 24069, 0x0000 }, { 24069, 0x0000 }, - { 24069, 0x0000 }, { 24069, 0x0010 }, { 24070, 0x0000 }, { 24070, 0x0000 }, - /* 0x24700 */ - { 24070, 0x0040 }, { 24071, 0x0000 }, { 24071, 0x8020 }, { 24073, 0x0000 }, - { 24073, 0x0000 }, { 24073, 0x0000 }, { 24073, 0x0000 }, { 24073, 0x0000 }, - { 24073, 0x8000 }, { 24074, 0x0000 }, { 24074, 0x0000 }, { 24074, 0x0000 }, - { 24074, 0x0000 }, { 24074, 0x0000 }, { 24074, 0x0001 }, { 24075, 0x0000 }, - /* 0x24800 */ - { 24075, 0x0000 }, { 24075, 0x0004 }, { 24076, 0x0008 }, { 24077, 0x0000 }, - { 24077, 0x0000 }, { 24077, 0x0000 }, { 24077, 0x0000 }, { 24077, 0x0000 }, - { 24077, 0x0004 }, { 24078, 0x0000 }, { 24078, 0x0000 }, { 24078, 0x0000 }, - { 24078, 0x0000 }, { 24078, 0x0000 }, { 24078, 0x0200 }, { 24079, 0x880F }, - /* 0x24900 */ - { 24085, 0x1003 }, { 24088, 0x02C0 }, { 24091, 0x8000 }, { 24092, 0xC018 }, - { 24096, 0x000F }, { 24100, 0x0000 }, { 24100, 0x000C }, { 24102, 0x8870 }, - { 24107, 0xFF04 }, { 24116, 0x0010 }, { 24117, 0x3A90 }, { 24123, 0x0F80 }, - { 24128, 0x0020 }, { 24129, 0xC401 }, { 24133, 0x3028 }, { 24137, 0x0BC0 }, - /* 0x24A00 */ - { 24142, 0x4000 }, { 24143, 0x002C }, { 24146, 0x07FE }, { 24156, 0x4000 }, - { 24157, 0xC424 }, { 24162, 0x2003 }, { 24165, 0x00E0 }, { 24168, 0x0782 }, - { 24173, 0x1000 }, { 24174, 0x0078 }, { 24178, 0x00F0 }, { 24182, 0x1C0E }, - { 24188, 0x0481 }, { 24191, 0x8002 }, { 24193, 0x0204 }, { 24195, 0x0000 }, - /* 0x24B00 */ - { 24195, 0x0000 }, { 24195, 0x0000 }, { 24195, 0x0000 }, { 24195, 0x0000 }, - { 24195, 0x0000 }, { 24195, 0x0000 }, { 24195, 0x4000 }, { 24196, 0x0000 }, - { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0000 }, - { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0020 }, - /* 0x24C00 */ - { 24197, 0x0200 }, { 24198, 0x0000 }, { 24198, 0x0000 }, { 24198, 0x0000 }, - { 24198, 0x0000 }, { 24198, 0x0000 }, { 24198, 0x0000 }, { 24198, 0x0000 }, - { 24198, 0x0000 }, { 24198, 0xC000 }, { 24200, 0x0000 }, { 24200, 0x0000 }, - { 24200, 0x0200 }, { 24201, 0x0200 }, { 24202, 0x0000 }, { 24202, 0x0000 }, - /* 0x24D00 */ - { 24202, 0x0040 }, { 24203, 0x0008 }, { 24204, 0x0000 }, { 24204, 0x0000 }, - { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0000 }, - { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0100 }, - { 24205, 0x0000 }, { 24205, 0x0000 }, { 24205, 0x0C00 }, { 24207, 0x0000 }, - /* 0x24E00 */ - { 24207, 0x0000 }, { 24207, 0x0000 }, { 24207, 0x0000 }, { 24207, 0x0800 }, - { 24208, 0x0000 }, { 24208, 0x0001 }, { 24209, 0x0000 }, { 24209, 0x0000 }, - { 24209, 0x0000 }, { 24209, 0x0000 }, { 24209, 0x00A0 }, { 24211, 0x0000 }, - { 24211, 0x0000 }, { 24211, 0x0000 }, { 24211, 0x0000 }, { 24211, 0x0000 }, - /* 0x24F00 */ - { 24211, 0x4000 }, { 24212, 0x0000 }, { 24212, 0x0000 }, { 24212, 0x0000 }, - { 24212, 0x0000 }, { 24212, 0x1000 }, { 24213, 0x0000 }, { 24213, 0x0000 }, - { 24213, 0x0044 }, { 24215, 0x0480 }, { 24217, 0x0200 }, { 24218, 0x0100 }, - { 24219, 0x0004 }, { 24220, 0x0000 }, { 24220, 0x0000 }, { 24220, 0x0000 }, - /* 0x25000 */ - { 24220, 0x0000 }, { 24220, 0x0000 }, { 24220, 0x1000 }, { 24221, 0x0000 }, - { 24221, 0x0000 }, { 24221, 0x0004 }, { 24222, 0x0000 }, { 24222, 0x0000 }, - { 24222, 0x0000 }, { 24222, 0x2000 }, { 24223, 0x0000 }, { 24223, 0x0000 }, - { 24223, 0x0000 }, { 24223, 0x0000 }, { 24223, 0x0000 }, { 24223, 0x0000 }, - /* 0x25100 */ - { 24223, 0x0000 }, { 24223, 0x0000 }, { 24223, 0x0800 }, { 24224, 0x0000 }, - { 24224, 0x0100 }, { 24225, 0x0000 }, { 24225, 0x0000 }, { 24225, 0x6000 }, - { 24227, 0x0000 }, { 24227, 0x0000 }, { 24227, 0x0000 }, { 24227, 0x0000 }, - { 24227, 0x2000 }, { 24228, 0x0000 }, { 24228, 0x00C8 }, { 24231, 0x0000 }, - /* 0x25200 */ - { 24231, 0x0000 }, { 24231, 0x0000 }, { 24231, 0x0003 }, { 24233, 0x0000 }, - { 24233, 0x0000 }, { 24233, 0x0001 }, { 24234, 0x0000 }, { 24234, 0x0000 }, - { 24234, 0x0000 }, { 24234, 0x0200 }, { 24235, 0x0000 }, { 24235, 0x0000 }, - { 24235, 0x0080 }, { 24236, 0x0100 }, { 24237, 0x0000 }, { 24237, 0x0000 }, - /* 0x25300 */ - { 24237, 0x4000 }, { 24238, 0x000A }, { 24240, 0x0000 }, { 24240, 0x0000 }, - { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, - { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, - { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, - /* 0x25400 */ - { 24240, 0x0000 }, { 24240, 0x0200 }, { 24241, 0x8020 }, { 24243, 0x0001 }, - { 24244, 0x0040 }, { 24245, 0x0000 }, { 24245, 0x5000 }, { 24247, 0x0000 }, - { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, - { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, - /* 0x25500 */ - { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x8022 }, - { 24250, 0x0000 }, { 24250, 0x7800 }, { 24254, 0x0064 }, { 24257, 0x0000 }, - { 24257, 0x8012 }, { 24260, 0x0000 }, { 24260, 0x0000 }, { 24260, 0x0200 }, - { 24261, 0x0000 }, { 24261, 0x0820 }, { 24263, 0x0001 }, { 24264, 0x0000 }, - /* 0x25600 */ - { 24264, 0x0020 }, { 24265, 0x0000 }, { 24265, 0x0000 }, { 24265, 0x0020 }, - { 24266, 0x0000 }, { 24266, 0x0002 }, { 24267, 0x0000 }, { 24267, 0x0000 }, - { 24267, 0x0008 }, { 24268, 0x0020 }, { 24269, 0x0000 }, { 24269, 0x0000 }, - { 24269, 0x0000 }, { 24269, 0x0000 }, { 24269, 0x0008 }, { 24270, 0x0040 }, - /* 0x25700 */ - { 24271, 0x0040 }, { 24272, 0x2000 }, { 24273, 0x0020 }, { 24274, 0x2000 }, - { 24275, 0x0000 }, { 24275, 0x0000 }, { 24275, 0x0000 }, { 24275, 0x0004 }, - { 24276, 0x0000 }, { 24276, 0x0000 }, { 24276, 0x0000 }, { 24276, 0x0000 }, - { 24276, 0x0080 }, { 24277, 0x8000 }, { 24278, 0x0003 }, { 24280, 0x0000 }, - /* 0x25800 */ - { 24280, 0x0000 }, { 24280, 0x0000 }, { 24280, 0x0000 }, { 24280, 0x0000 }, - { 24280, 0x0000 }, { 24280, 0x2080 }, { 24282, 0x0000 }, { 24282, 0x0004 }, - { 24283, 0x0000 }, { 24283, 0x0000 }, { 24283, 0x0000 }, { 24283, 0x0000 }, - { 24283, 0x0100 }, { 24284, 0x0000 }, { 24284, 0x0002 }, { 24285, 0x0000 }, - /* 0x25900 */ - { 24285, 0x0008 }, { 24286, 0x0000 }, { 24286, 0x0000 }, { 24286, 0x0000 }, - { 24286, 0x0040 }, { 24287, 0x0040 }, { 24288, 0x0000 }, { 24288, 0x0000 }, - { 24288, 0x0000 }, { 24288, 0x0000 }, { 24288, 0x1000 }, { 24289, 0x0000 }, - { 24289, 0x1000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, - /* 0x25A00 */ - { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, - { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, - { 24290, 0x0000 }, { 24290, 0x1020 }, { 24292, 0xC000 }, { 24294, 0x0000 }, - { 24294, 0x0000 }, { 24294, 0x0000 }, { 24294, 0x0200 }, { 24295, 0x0000 }, - /* 0x25B00 */ - { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0000 }, - { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0010 }, - { 24296, 0x0200 }, { 24297, 0x0000 }, { 24297, 0x0000 }, { 24297, 0x0018 }, - { 24299, 0x0040 }, { 24300, 0x0000 }, { 24300, 0x0110 }, { 24302, 0x0000 }, - /* 0x25C00 */ - { 24302, 0x0042 }, { 24304, 0x0000 }, { 24304, 0x0002 }, { 24305, 0x0000 }, - { 24305, 0x0400 }, { 24306, 0x0000 }, { 24306, 0x0020 }, { 24307, 0x0000 }, - { 24307, 0x0000 }, { 24307, 0x0002 }, { 24308, 0x0010 }, { 24309, 0x0000 }, - { 24309, 0x0003 }, { 24311, 0x0000 }, { 24311, 0x0000 }, { 24311, 0x4000 }, - /* 0x25D00 */ - { 24312, 0x0000 }, { 24312, 0x0000 }, { 24312, 0x0001 }, { 24313, 0x0001 }, - { 24314, 0x0008 }, { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, - { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, - { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, - /* 0x25E00 */ - { 24315, 0x4000 }, { 24316, 0x0000 }, { 24316, 0x0000 }, { 24316, 0x0000 }, - { 24316, 0x0200 }, { 24317, 0x0000 }, { 24317, 0x0000 }, { 24317, 0x0000 }, - { 24317, 0x000E }, { 24320, 0x0000 }, { 24320, 0x0040 }, { 24321, 0x1000 }, - { 24322, 0x0000 }, { 24322, 0x0180 }, { 24324, 0x0000 }, { 24324, 0x0000 }, - /* 0x25F00 */ - { 24324, 0x0000 }, { 24324, 0x0400 }, { 24325, 0x0000 }, { 24325, 0x0000 }, - { 24325, 0x0800 }, { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0000 }, - { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0000 }, - { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0006 }, { 24328, 0x0000 }, - /* 0x26000 */ - { 24328, 0x0000 }, { 24328, 0x0000 }, { 24328, 0x0200 }, { 24329, 0x0000 }, - { 24329, 0x0100 }, { 24330, 0x0000 }, { 24330, 0x0010 }, { 24331, 0x0000 }, - { 24331, 0x0008 }, { 24332, 0x0080 }, { 24333, 0x0030 }, { 24335, 0x0000 }, - { 24335, 0x0000 }, { 24335, 0x0000 }, { 24335, 0x0000 }, { 24335, 0x0000 }, - /* 0x26100 */ - { 24335, 0x0004 }, { 24336, 0x0000 }, { 24336, 0x0002 }, { 24337, 0x0000 }, - { 24337, 0x0000 }, { 24337, 0x1E00 }, { 24341, 0x0000 }, { 24341, 0x0000 }, - { 24341, 0x0000 }, { 24341, 0x0000 }, { 24341, 0x6000 }, { 24343, 0x0004 }, - { 24344, 0x0000 }, { 24344, 0x2000 }, { 24345, 0x0000 }, { 24345, 0x0000 }, - /* 0x26200 */ - { 24345, 0x0000 }, { 24345, 0x0000 }, { 24345, 0x0000 }, { 24345, 0x0000 }, - { 24345, 0x0000 }, { 24345, 0x0100 }, { 24346, 0x0C02 }, { 24349, 0x0000 }, - { 24349, 0x0000 }, { 24349, 0x0000 }, { 24349, 0x0000 }, { 24349, 0x0000 }, - { 24349, 0x0000 }, { 24349, 0x0001 }, { 24350, 0x0000 }, { 24350, 0x0000 }, - /* 0x26300 */ - { 24350, 0x0000 }, { 24350, 0x0000 }, { 24350, 0x0000 }, { 24350, 0x0020 }, - { 24351, 0x1800 }, { 24353, 0x0002 }, { 24354, 0x0000 }, { 24354, 0x0000 }, - { 24354, 0x0000 }, { 24354, 0x0000 }, { 24354, 0x0000 }, { 24354, 0x4000 }, - { 24355, 0x0000 }, { 24355, 0x0000 }, { 24355, 0x0000 }, { 24355, 0x0120 }, - /* 0x26400 */ - { 24357, 0x0004 }, { 24358, 0x0007 }, { 24361, 0x0000 }, { 24361, 0x0000 }, - { 24361, 0x0400 }, { 24362, 0x0000 }, { 24362, 0x0200 }, { 24363, 0x0000 }, - { 24363, 0x2310 }, { 24367, 0x0100 }, { 24368, 0x0000 }, { 24368, 0x0000 }, - { 24368, 0x0000 }, { 24368, 0x0000 }, { 24368, 0x0000 }, { 24368, 0x0000 }, - /* 0x26500 */ - { 24368, 0x0000 }, { 24368, 0x0004 }, { 24369, 0x0000 }, { 24369, 0x0000 }, - { 24369, 0x0000 }, { 24369, 0x0000 }, { 24369, 0x0000 }, { 24369, 0x0004 }, - { 24370, 0x0000 }, { 24370, 0x0000 }, { 24370, 0x2001 }, { 24372, 0x8000 }, - { 24373, 0x0000 }, { 24373, 0x0000 }, { 24373, 0x0000 }, { 24373, 0x0000 }, - /* 0x26600 */ - { 24373, 0x0000 }, { 24373, 0x0004 }, { 24374, 0x0040 }, { 24375, 0x0000 }, - { 24375, 0x0000 }, { 24375, 0x0000 }, { 24375, 0x0000 }, { 24375, 0x0000 }, - { 24375, 0x0000 }, { 24375, 0x0000 }, { 24375, 0x8000 }, { 24376, 0x0022 }, - { 24378, 0x0000 }, { 24378, 0x0400 }, { 24379, 0x0100 }, { 24380, 0x1000 }, - /* 0x26700 */ - { 24381, 0x0000 }, { 24381, 0x0040 }, { 24382, 0x0000 }, { 24382, 0x0000 }, - { 24382, 0x0002 }, { 24383, 0x0000 }, { 24383, 0x0000 }, { 24383, 0x0000 }, - { 24383, 0x0000 }, { 24383, 0x0200 }, { 24384, 0x0000 }, { 24384, 0x0018 }, - { 24386, 0x1000 }, { 24387, 0x0000 }, { 24387, 0x0000 }, { 24387, 0x0000 }, - /* 0x26800 */ - { 24387, 0x0000 }, { 24387, 0x1000 }, { 24388, 0x0000 }, { 24388, 0x0000 }, - { 24388, 0x0040 }, { 24389, 0x4000 }, { 24390, 0x4000 }, { 24391, 0x0000 }, - { 24391, 0x0500 }, { 24393, 0x0008 }, { 24394, 0x0000 }, { 24394, 0x0000 }, - { 24394, 0x0080 }, { 24395, 0x0000 }, { 24395, 0x0000 }, { 24395, 0x0000 }, - /* 0x26900 */ - { 24395, 0x4000 }, { 24396, 0x0002 }, { 24397, 0x0040 }, { 24398, 0x0200 }, - { 24399, 0x0000 }, { 24399, 0x0002 }, { 24400, 0x0000 }, { 24400, 0x0000 }, - { 24400, 0x0000 }, { 24400, 0x0000 }, { 24400, 0x0100 }, { 24401, 0x0020 }, - { 24402, 0x0000 }, { 24402, 0x0000 }, { 24402, 0x0000 }, { 24402, 0x0404 }, - /* 0x26A00 */ - { 24404, 0x0000 }, { 24404, 0x0000 }, { 24404, 0x6000 }, { 24406, 0x0010 }, - { 24407, 0x0004 }, { 24408, 0x0006 }, { 24410, 0x0000 }, { 24410, 0x0000 }, - { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 }, - { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 }, - /* 0x26B00 */ - { 24410, 0x0420 }, { 24412, 0x0028 }, { 24414, 0x0100 }, { 24415, 0x0000 }, - { 24415, 0x0000 }, { 24415, 0x080F }, { 24420, 0x0000 }, { 24420, 0x0020 }, - { 24421, 0x0004 }, { 24422, 0x20C0 }, { 24425, 0x0000 }, { 24425, 0x0008 }, - { 24426, 0x0001 }, { 24427, 0x0000 }, { 24427, 0x0000 }, { 24427, 0x0080 }, - /* 0x26C00 */ - { 24428, 0x0000 }, { 24428, 0x0000 }, { 24428, 0x0002 }, { 24429, 0x0000 }, - { 24429, 0x0001 }, { 24430, 0x0000 }, { 24430, 0x0000 }, { 24430, 0xC000 }, - { 24432, 0x0007 }, { 24435, 0x0000 }, { 24435, 0x0010 }, { 24436, 0x2180 }, - { 24439, 0x0009 }, { 24441, 0x0002 }, { 24442, 0x0000 }, { 24442, 0x0000 }, - /* 0x26D00 */ - { 24442, 0x0000 }, { 24442, 0x0000 }, { 24442, 0x07FC }, { 24451, 0x0000 }, - { 24451, 0x0000 }, { 24451, 0x0002 }, { 24452, 0x0000 }, { 24452, 0x0010 }, - { 24453, 0x0000 }, { 24453, 0x0000 }, { 24453, 0x40FF }, { 24462, 0x0000 }, - { 24462, 0x0000 }, { 24462, 0x1000 }, { 24463, 0x0C00 }, { 24465, 0x0001 }, - /* 0x26E00 */ - { 24466, 0x00A1 }, { 24469, 0x0004 }, { 24470, 0x0000 }, { 24470, 0x0000 }, - { 24470, 0x003C }, { 24474, 0x0000 }, { 24474, 0x4000 }, { 24475, 0x0084 }, - { 24477, 0x0010 }, { 24478, 0x0200 }, { 24479, 0x0000 }, { 24479, 0x0000 }, - { 24479, 0x0000 }, { 24479, 0x00FF }, { 24487, 0x0000 }, { 24487, 0x0000 }, - /* 0x26F00 */ - { 24487, 0x0000 }, { 24487, 0x0000 }, { 24487, 0x0040 }, { 24488, 0x0000 }, - { 24488, 0x0000 }, { 24488, 0x0000 }, { 24488, 0x0000 }, { 24488, 0x0018 }, - { 24490, 0x0000 }, { 24490, 0x8000 }, { 24491, 0x0002 }, { 24492, 0x4000 }, - { 24493, 0x0000 }, { 24493, 0xC000 }, { 24495, 0x0000 }, { 24495, 0x0000 }, - /* 0x27000 */ - { 24495, 0x4000 }, { 24496, 0x0000 }, { 24496, 0x0000 }, { 24496, 0x0000 }, - { 24496, 0x0800 }, { 24497, 0x000C }, { 24499, 0x0000 }, { 24499, 0x0000 }, - { 24499, 0x0100 }, { 24500, 0x0000 }, { 24500, 0xE000 }, { 24503, 0x0000 }, - { 24503, 0x2000 }, { 24504, 0x0000 }, { 24504, 0x0000 }, { 24504, 0x0100 }, - /* 0x27100 */ - { 24505, 0x3200 }, { 24508, 0x0000 }, { 24508, 0x00C0 }, { 24510, 0x0000 }, - { 24510, 0x0000 }, { 24510, 0x0000 }, { 24510, 0x0030 }, { 24512, 0x0020 }, - { 24513, 0x0000 }, { 24513, 0x0000 }, { 24513, 0x0000 }, { 24513, 0x0000 }, - { 24513, 0x2000 }, { 24514, 0x0000 }, { 24514, 0x0000 }, { 24514, 0x0000 }, - /* 0x27200 */ - { 24514, 0x0000 }, { 24514, 0x0800 }, { 24515, 0x0000 }, { 24515, 0x0000 }, - { 24515, 0x0000 }, { 24515, 0x0000 }, { 24515, 0x0000 }, { 24515, 0x0000 }, - { 24515, 0x0821 }, { 24518, 0x0000 }, { 24518, 0x0000 }, { 24518, 0x0044 }, - { 24520, 0x0000 }, { 24520, 0x0000 }, { 24520, 0x0040 }, { 24521, 0x0000 }, - /* 0x27300 */ - { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 }, - { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 }, - { 24521, 0x0000 }, { 24521, 0x0400 }, { 24522, 0x0000 }, { 24522, 0x0000 }, - { 24522, 0x0000 }, { 24522, 0x0000 }, { 24522, 0x0000 }, { 24522, 0x0000 }, - /* 0x27400 */ - { 24522, 0x0000 }, { 24522, 0x0000 }, { 24522, 0x0004 }, { 24523, 0x0000 }, - { 24523, 0x0000 }, { 24523, 0x0001 }, { 24524, 0x0000 }, { 24524, 0x0000 }, - { 24524, 0x0050 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, - { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, - /* 0x27500 */ - { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, - { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0010 }, - { 24527, 0x0000 }, { 24527, 0x0000 }, { 24527, 0x0008 }, { 24528, 0x0000 }, - { 24528, 0x0000 }, { 24528, 0x0000 }, { 24528, 0x0011 }, { 24530, 0x6000 }, - /* 0x27600 */ - { 24532, 0x1080 }, { 24534, 0x0000 }, { 24534, 0x0000 }, { 24534, 0x0204 }, - { 24536, 0x0000 }, { 24536, 0x00E0 }, { 24539, 0x0000 }, { 24539, 0x0000 }, - { 24539, 0x0000 }, { 24539, 0x0010 }, { 24540, 0x0000 }, { 24540, 0x0000 }, - { 24540, 0x0000 }, { 24540, 0x0000 }, { 24540, 0x0000 }, { 24540, 0x0000 }, - /* 0x27700 */ - { 24540, 0x8000 }, { 24541, 0x0000 }, { 24541, 0x0000 }, { 24541, 0x0060 }, - { 24543, 0x0002 }, { 24544, 0x4000 }, { 24545, 0x0000 }, { 24545, 0x0000 }, - { 24545, 0x0030 }, { 24547, 0x0000 }, { 24547, 0x0000 }, { 24547, 0x0000 }, - { 24547, 0x1000 }, { 24548, 0x0000 }, { 24548, 0x0000 }, { 24548, 0x0000 }, - /* 0x27800 */ - { 24548, 0x0000 }, { 24548, 0x0000 }, { 24548, 0x0000 }, { 24548, 0x0000 }, - { 24548, 0x0000 }, { 24548, 0x0100 }, { 24549, 0x0000 }, { 24549, 0x0001 }, - { 24550, 0x0000 }, { 24550, 0x2000 }, { 24551, 0x0000 }, { 24551, 0x0004 }, - { 24552, 0x0100 }, { 24553, 0x0000 }, { 24553, 0x0000 }, { 24553, 0x0000 }, - /* 0x27900 */ - { 24553, 0x0000 }, { 24553, 0x0000 }, { 24553, 0x0010 }, { 24554, 0x0000 }, - { 24554, 0x0000 }, { 24554, 0x0000 }, { 24554, 0x0080 }, { 24555, 0x0400 }, - { 24556, 0x0000 }, { 24556, 0x0000 }, { 24556, 0x0001 }, { 24557, 0x0000 }, - { 24557, 0x0000 }, { 24557, 0x2000 }, { 24558, 0x0000 }, { 24558, 0x2000 }, - /* 0x27A00 */ - { 24559, 0x4400 }, { 24561, 0x0000 }, { 24561, 0x0000 }, { 24561, 0x4000 }, - { 24562, 0x0000 }, { 24562, 0x0208 }, { 24564, 0x0000 }, { 24564, 0x0200 }, - { 24565, 0x0010 }, { 24566, 0x0000 }, { 24566, 0x0000 }, { 24566, 0x6000 }, - { 24568, 0x0000 }, { 24568, 0x0000 }, { 24568, 0x0000 }, { 24568, 0x0010 }, - /* 0x27B00 */ - { 24569, 0x0840 }, { 24571, 0x0100 }, { 24572, 0x0000 }, { 24572, 0x0700 }, - { 24575, 0x0100 }, { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 }, - { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 }, - { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0010 }, - /* 0x27C00 */ - { 24577, 0x0000 }, { 24577, 0x0004 }, { 24578, 0x0000 }, { 24578, 0x0000 }, - { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, - { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, - { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, - /* 0x27D00 */ - { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x8000 }, { 24579, 0x0000 }, - { 24579, 0x0000 }, { 24579, 0x0018 }, { 24581, 0x0040 }, { 24582, 0x0008 }, - { 24583, 0x8010 }, { 24585, 0x0100 }, { 24586, 0x0000 }, { 24586, 0x2000 }, - { 24587, 0x0000 }, { 24587, 0x1000 }, { 24588, 0x0000 }, { 24588, 0x0000 }, - /* 0x27E00 */ - { 24588, 0x0000 }, { 24588, 0x0000 }, { 24588, 0x0000 }, { 24588, 0x0000 }, - { 24588, 0xA000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, - { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, - { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, - /* 0x27F00 */ - { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, - { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, - { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, - { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0200 }, - /* 0x28000 */ - { 24591, 0x0204 }, { 24593, 0x4000 }, { 24594, 0x0018 }, { 24596, 0x0000 }, - { 24596, 0x0100 }, { 24597, 0x0000 }, { 24597, 0x0000 }, { 24597, 0x0000 }, - { 24597, 0x0008 }, { 24598, 0x0001 }, { 24599, 0x0000 }, { 24599, 0x6000 }, - { 24601, 0x0000 }, { 24601, 0x0000 }, { 24601, 0x0300 }, { 24603, 0x0010 }, - /* 0x28100 */ - { 24604, 0x0000 }, { 24604, 0x0000 }, { 24604, 0x4000 }, { 24605, 0x0000 }, - { 24605, 0x8000 }, { 24606, 0x2000 }, { 24607, 0x8000 }, { 24608, 0x0000 }, - { 24608, 0x0200 }, { 24609, 0x0000 }, { 24609, 0x8000 }, { 24610, 0x1000 }, - { 24611, 0x0000 }, { 24611, 0x0000 }, { 24611, 0x0000 }, { 24611, 0x0000 }, - /* 0x28200 */ - { 24611, 0x0080 }, { 24612, 0x0500 }, { 24614, 0x0000 }, { 24614, 0x0000 }, - { 24614, 0x0000 }, { 24614, 0x0040 }, { 24615, 0x0000 }, { 24615, 0x1000 }, - { 24616, 0x0000 }, { 24616, 0x0800 }, { 24617, 0x0000 }, { 24617, 0x0000 }, - { 24617, 0x2000 }, { 24618, 0x0000 }, { 24618, 0x0004 }, { 24619, 0x0000 }, - /* 0x28300 */ - { 24619, 0x0040 }, { 24620, 0x0100 }, { 24621, 0x8000 }, { 24622, 0x0400 }, - { 24623, 0x0000 }, { 24623, 0x0000 }, { 24623, 0x2020 }, { 24625, 0x2000 }, - { 24626, 0x0400 }, { 24627, 0x0000 }, { 24627, 0x0000 }, { 24627, 0x0000 }, - { 24627, 0x0000 }, { 24627, 0x0000 }, { 24627, 0x0000 }, { 24627, 0x0000 }, - /* 0x28400 */ - { 24627, 0x0000 }, { 24627, 0x0004 }, { 24628, 0x0000 }, { 24628, 0x0000 }, - { 24628, 0x0000 }, { 24628, 0x0000 }, { 24628, 0x1100 }, { 24630, 0x0008 }, - { 24631, 0x0004 }, { 24632, 0x0000 }, { 24632, 0x0000 }, { 24632, 0x0000 }, - { 24632, 0x0000 }, { 24632, 0x0000 }, { 24632, 0x0000 }, { 24632, 0x0000 }, - /* 0x28500 */ - { 24632, 0x0002 }, { 24633, 0x0000 }, { 24633, 0x0000 }, { 24633, 0x3000 }, - { 24635, 0x0000 }, { 24635, 0x0000 }, { 24635, 0x1000 }, { 24636, 0x0000 }, - { 24636, 0x0000 }, { 24636, 0x0000 }, { 24636, 0x0000 }, { 24636, 0x0000 }, - { 24636, 0x0000 }, { 24636, 0x0000 }, { 24636, 0x0100 }, { 24637, 0x0010 }, - /* 0x28600 */ - { 24638, 0x0801 }, { 24640, 0x0000 }, { 24640, 0x0020 }, { 24641, 0x0800 }, - { 24642, 0x0000 }, { 24642, 0x0000 }, { 24642, 0x0000 }, { 24642, 0x0000 }, - { 24642, 0x0000 }, { 24642, 0x0000 }, { 24642, 0x0C00 }, { 24644, 0x1000 }, - { 24645, 0x0000 }, { 24645, 0x0100 }, { 24646, 0x0040 }, { 24647, 0x0000 }, - /* 0x28700 */ - { 24647, 0x8000 }, { 24648, 0x0008 }, { 24649, 0x0000 }, { 24649, 0x0000 }, - { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, - { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, - { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, - /* 0x28800 */ - { 24649, 0x0010 }, { 24650, 0x0000 }, { 24650, 0x0800 }, { 24651, 0x0000 }, - { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, - { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, - { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, - /* 0x28900 */ - { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0008 }, - { 24652, 0x0300 }, { 24654, 0x0040 }, { 24655, 0x1110 }, { 24658, 0x4000 }, - { 24659, 0x0200 }, { 24660, 0x0000 }, { 24660, 0x0D00 }, { 24663, 0x1100 }, - { 24665, 0x0001 }, { 24666, 0x5000 }, { 24668, 0x019A }, { 24673, 0x1E00 }, - /* 0x28A00 */ - { 24677, 0x8000 }, { 24678, 0x0040 }, { 24679, 0x0220 }, { 24681, 0x0044 }, - { 24683, 0x0FF0 }, { 24691, 0x0600 }, { 24693, 0x0000 }, { 24693, 0x0000 }, - { 24693, 0x000E }, { 24696, 0x1C00 }, { 24699, 0x0000 }, { 24699, 0x0000 }, - { 24699, 0x5841 }, { 24704, 0xC000 }, { 24706, 0x042F }, { 24712, 0x1000 }, - /* 0x28B00 */ - { 24713, 0x1000 }, { 24714, 0x0008 }, { 24715, 0xB806 }, { 24721, 0x0000 }, - { 24721, 0x5040 }, { 24724, 0x0001 }, { 24725, 0x1078 }, { 24730, 0x0000 }, - { 24730, 0x8000 }, { 24731, 0x3200 }, { 24734, 0x0000 }, { 24734, 0x0000 }, - { 24734, 0x0024 }, { 24736, 0x0690 }, { 24740, 0x1F80 }, { 24746, 0x8020 }, - /* 0x28C00 */ - { 24748, 0x0208 }, { 24750, 0x3000 }, { 24752, 0x0848 }, { 24755, 0x0A01 }, - { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 }, - { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 }, - { 24758, 0x2400 }, { 24760, 0x0004 }, { 24761, 0x0000 }, { 24761, 0x0000 }, - /* 0x28D00 */ - { 24761, 0x0000 }, { 24761, 0x0000 }, { 24761, 0x0000 }, { 24761, 0x0010 }, - { 24762, 0x0000 }, { 24762, 0x0000 }, { 24762, 0x0000 }, { 24762, 0x0000 }, - { 24762, 0x0000 }, { 24762, 0x0200 }, { 24763, 0x0000 }, { 24763, 0x0200 }, - { 24764, 0x0000 }, { 24764, 0x0000 }, { 24764, 0x0000 }, { 24764, 0x0000 }, - /* 0x28E00 */ - { 24764, 0x8000 }, { 24765, 0x0000 }, { 24765, 0x0000 }, { 24765, 0x0240 }, - { 24767, 0x0000 }, { 24767, 0x0000 }, { 24767, 0x0060 }, { 24769, 0x0000 }, - { 24769, 0x0000 }, { 24769, 0x0080 }, { 24770, 0x1000 }, { 24771, 0x000C }, - { 24773, 0x0000 }, { 24773, 0x0200 }, { 24774, 0x0080 }, { 24775, 0x0000 }, - /* 0x28F00 */ - { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, - { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, - { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, - { 24775, 0x0020 }, { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 }, - /* 0x29000 */ - { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 }, - { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 }, - { 24776, 0x0900 }, { 24778, 0x0008 }, { 24779, 0x8000 }, { 24780, 0x0003 }, - { 24782, 0x0001 }, { 24783, 0x0000 }, { 24783, 0x3030 }, { 24787, 0x0000 }, - /* 0x29100 */ - { 24787, 0x2000 }, { 24788, 0x0001 }, { 24789, 0x0000 }, { 24789, 0x1000 }, - { 24790, 0x2000 }, { 24791, 0x4800 }, { 24793, 0x0000 }, { 24793, 0x0001 }, - { 24794, 0x0000 }, { 24794, 0x1000 }, { 24795, 0x0100 }, { 24796, 0x0000 }, - { 24796, 0x0000 }, { 24796, 0x0020 }, { 24797, 0x0800 }, -}; -static const Summary16 big5hkscs_uni2index_page294[32] = { - /* 0x29400 */ - { 24798, 0x0000 }, { 24798, 0x2000 }, { 24799, 0x0001 }, { 24800, 0x8008 }, - { 24802, 0x0100 }, { 24803, 0x0000 }, { 24803, 0x0000 }, { 24803, 0x0000 }, - { 24803, 0x0000 }, { 24803, 0x0000 }, { 24803, 0x0000 }, { 24803, 0x0000 }, - { 24803, 0x0000 }, { 24803, 0x0601 }, { 24806, 0x00A0 }, { 24808, 0x0000 }, - /* 0x29500 */ - { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 }, - { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 }, - { 24808, 0x0000 }, { 24808, 0x4000 }, { 24809, 0x0000 }, { 24809, 0x0101 }, - { 24811, 0x0000 }, { 24811, 0x0080 }, { 24812, 0x0200 }, { 24813, 0x0010 }, -}; -static const Summary16 big5hkscs_uni2index_page297[251] = { - /* 0x29700 */ - { 24814, 0x0000 }, { 24814, 0x0000 }, { 24814, 0x0001 }, { 24815, 0x0004 }, - { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 }, - { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 }, - { 24816, 0x0000 }, { 24816, 0x0010 }, { 24817, 0x0000 }, { 24817, 0x0000 }, - /* 0x29800 */ - { 24817, 0x0000 }, { 24817, 0x0001 }, { 24818, 0x0000 }, { 24818, 0x0000 }, - { 24818, 0x0000 }, { 24818, 0x0080 }, { 24819, 0x0000 }, { 24819, 0x0000 }, - { 24819, 0x0000 }, { 24819, 0x0000 }, { 24819, 0x0010 }, { 24820, 0x0000 }, - { 24820, 0x0000 }, { 24820, 0x0002 }, { 24821, 0x0400 }, { 24822, 0x0002 }, - /* 0x29900 */ - { 24823, 0x0028 }, { 24825, 0x0000 }, { 24825, 0x8000 }, { 24826, 0x0000 }, - { 24826, 0x0380 }, { 24829, 0x2000 }, { 24830, 0x0400 }, { 24831, 0x0000 }, - { 24831, 0x0000 }, { 24831, 0x2000 }, { 24832, 0x0000 }, { 24832, 0x0000 }, - { 24832, 0x0208 }, { 24834, 0x0000 }, { 24834, 0x0000 }, { 24834, 0x0000 }, - /* 0x29A00 */ - { 24834, 0x0000 }, { 24834, 0x0000 }, { 24834, 0x0100 }, { 24835, 0x0000 }, - { 24835, 0x2000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, - { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, - { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, - /* 0x29B00 */ - { 24836, 0x4020 }, { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 }, - { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 }, - { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 }, - { 24838, 0x0000 }, { 24838, 0x0020 }, { 24839, 0x0000 }, { 24839, 0x0000 }, - /* 0x29C00 */ - { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0000 }, - { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0008 }, - { 24840, 0x0000 }, { 24840, 0x0000 }, { 24840, 0x2000 }, { 24841, 0x0000 }, - { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x0000 }, - /* 0x29D00 */ - { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x4000 }, - { 24842, 0x0000 }, { 24842, 0x0400 }, { 24843, 0x0000 }, { 24843, 0x1000 }, - { 24844, 0x0000 }, { 24844, 0x0900 }, { 24846, 0x0000 }, { 24846, 0x0000 }, - { 24846, 0x0000 }, { 24846, 0x0000 }, { 24846, 0x0000 }, { 24846, 0x0040 }, - /* 0x29E00 */ - { 24847, 0x0040 }, { 24848, 0x0000 }, { 24848, 0x2000 }, { 24849, 0x0000 }, - { 24849, 0x0000 }, { 24849, 0x0000 }, { 24849, 0x0100 }, { 24850, 0x0000 }, - { 24850, 0x0000 }, { 24850, 0x0000 }, { 24850, 0x1000 }, { 24851, 0x0000 }, - { 24851, 0x0008 }, { 24852, 0x0000 }, { 24852, 0x0000 }, { 24852, 0x0100 }, - /* 0x29F00 */ - { 24853, 0x0000 }, { 24853, 0x0000 }, { 24853, 0x0008 }, { 24854, 0x0001 }, - { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0000 }, - { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0080 }, - { 24856, 0x0000 }, { 24856, 0x4000 }, { 24857, 0x0000 }, { 24857, 0x0000 }, - /* 0x2A000 */ - { 24857, 0x0000 }, { 24857, 0x0010 }, { 24858, 0x0000 }, { 24858, 0x0000 }, - { 24858, 0x0000 }, { 24858, 0x0000 }, { 24858, 0x0000 }, { 24858, 0x0000 }, - { 24858, 0x0080 }, { 24859, 0x0000 }, { 24859, 0x0000 }, { 24859, 0x0200 }, - { 24860, 0x0000 }, { 24860, 0x0000 }, { 24860, 0x2002 }, { 24862, 0x4108 }, - /* 0x2A100 */ - { 24865, 0x0080 }, { 24866, 0x0000 }, { 24866, 0x0008 }, { 24867, 0x0018 }, - { 24869, 0x0000 }, { 24869, 0x0001 }, { 24870, 0x0000 }, { 24870, 0x0000 }, - { 24870, 0x0000 }, { 24870, 0x000C }, { 24872, 0x0800 }, { 24873, 0x0010 }, - { 24874, 0x0000 }, { 24874, 0x8000 }, { 24875, 0x0000 }, { 24875, 0x0020 }, - /* 0x2A200 */ - { 24876, 0x0000 }, { 24876, 0x0000 }, { 24876, 0x0001 }, { 24877, 0x0008 }, - { 24878, 0x0000 }, { 24878, 0x0000 }, { 24878, 0x0000 }, { 24878, 0x0000 }, - { 24878, 0x0000 }, { 24878, 0x8008 }, { 24880, 0x0000 }, { 24880, 0x2454 }, - { 24885, 0x0000 }, { 24885, 0x8000 }, { 24886, 0x0000 }, { 24886, 0x8000 }, - /* 0x2A300 */ - { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 }, - { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 }, - { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0200 }, { 24888, 0x0000 }, - { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0000 }, - /* 0x2A400 */ - { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0010 }, - { 24889, 0x0000 }, { 24889, 0x0800 }, { 24890, 0x0000 }, { 24890, 0x0000 }, - { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, - { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, - /* 0x2A500 */ - { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, - { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, - { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, - { 24890, 0x0840 }, { 24892, 0x0000 }, { 24892, 0x0000 }, { 24892, 0x0000 }, - /* 0x2A600 */ - { 24892, 0x0002 }, { 24893, 0x0000 }, { 24893, 0x0000 }, { 24893, 0x0004 }, - { 24894, 0x0400 }, { 24895, 0x0800 }, { 24896, 0x0000 }, { 24896, 0x0000 }, - { 24896, 0x0000 }, { 24896, 0x0000 }, { 24896, 0x0200 }, -}; -static const Summary16 big5hkscs_uni2index_page2f8[30] = { - /* 0x2F800 */ - { 24897, 0x0000 }, { 24897, 0x0000 }, { 24897, 0x0020 }, { 24898, 0x0800 }, - { 24899, 0x0001 }, { 24900, 0x0000 }, { 24900, 0x0000 }, { 24900, 0x0100 }, - { 24901, 0x0000 }, { 24901, 0x0010 }, { 24902, 0x0040 }, { 24903, 0x0000 }, - { 24903, 0x2000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, - /* 0x2F900 */ - { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, - { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, - { 24904, 0x0000 }, { 24904, 0x0010 }, { 24905, 0x0000 }, { 24905, 0x1004 }, - { 24907, 0x0000 }, { 24907, 0x0010 }, -}; - -static int qt_UnicodeToBig5hkscs(unsigned wc, uint8_t *r) -{ - const Summary16 *summary = NULL; - if (wc < 0x80) { - r[0] = (uint8_t)wc; - return 1; - } - if (wc < 0x0460) - summary = &big5hkscs_uni2index_page00[(wc >> 4)]; - else if (wc >= 0x1e00 && wc < 0x1ed0) - summary = &big5hkscs_uni2index_page1e[(wc >> 4) - 0x1e0]; - else if (wc >= 0x2000 && wc < 0x2740) - summary = &big5hkscs_uni2index_page20[(wc >> 4) - 0x200]; - else if (wc >= 0x2e00 && wc < 0x9fb0) - summary = &big5hkscs_uni2index_page2e[(wc >> 4) - 0x2e0]; - else if (wc >= 0xe000 && wc < 0xfa30) - summary = &big5hkscs_uni2index_pagee0[(wc >> 4) - 0xe00]; - else if (wc >= 0xfe00 && wc < 0xfff0) - summary = &big5hkscs_uni2index_pagefe[(wc >> 4) - 0xfe0]; - else if (wc >= 0x20000 && wc < 0x291f0) - summary = &big5hkscs_uni2index_page200[(wc >> 4) - 0x2000]; - else if (wc >= 0x29400 && wc < 0x29600) - summary = &big5hkscs_uni2index_page294[(wc >> 4) - 0x2940]; - else if (wc >= 0x29700 && wc < 0x2a6b0) - summary = &big5hkscs_uni2index_page297[(wc >> 4) - 0x2970]; - else if (wc >= 0x2f800 && wc < 0x2f9e0) - summary = &big5hkscs_uni2index_page2f8[(wc >> 4) - 0x2f80]; - if (summary) { - uint16_t used = summary->used; - unsigned i = wc & 0x0f; - if (used & ((uint16_t)1 << i)) { - /* Keep in `used' only the bits 0..i-1. */ - used &= ((uint16_t)1 << i) - 1; - /* Add `summary->index' and the number of bits set in `used'. */ - used = (used & 0x5555) + ((used & 0xaaaa) >> 1); - used = (used & 0x3333) + ((used & 0xcccc) >> 2); - used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); - used = (used & 0x00ff) + (used >> 8); - const uint8_t *c = big5hkscs_to_charset[summary->index + used]; - if (c[1] != 0) { - r[0] = c[0]; - r[1] = c[1]; - return 2; - } - else { // (c [1] == 0) - r[0] = c[0]; - return 1; - } - } - } - return 0; -} - -static int qt_UnicodeToBig5(unsigned ch, uint8_t *buf) -{ - //all the tables are individually sorted on Y - for (int i = 0; i < 5; i++) { - int start = 0; - int end = b5_map_table[i].tableSize - 1; - - while (start <= end) { - int middle = (end + start + 1) / 2; - if (b5_map_table[i].table[middle].y == ch) { - buf[0] = b5_map_table[i].table[middle].x >> 8; - buf[1] = b5_map_table[i].table[middle].x & 0xff; - return 2; - } - else if (b5_map_table[i].table[middle].y > ch) { - end = middle - 1; - } - else { - start = middle + 1; - } - } - } - return qt_UnicodeToBig5hkscs(ch, buf); -} - -void -Big5TextEncoder::EncodeBig5(const std::wstring& str, std::string& bytes) -{ - static const char replacement = '?'; - //int invalid = 0; - - bytes.resize(2 * str.length() + 1); - int index = 0; - - uint8_t c[2]; - for (wchar_t ch : str) { - if (ch < 0x80) { - // ASCII - bytes[index++] = static_cast(ch); - } - else if (qt_UnicodeToBig5(ch, c) == 2 && c[0] >= 0xa1 && c[0] <= 0xf9) { - bytes[index++] = c[0]; - bytes[index++] = c[1]; - } - else { - bytes[index++] = replacement; - //++invalid; - } - } - bytes.resize(index); -} diff --git a/core/src/textcodec/Big5TextEncoder.h b/core/src/textcodec/Big5TextEncoder.h deleted file mode 100644 index 3c6a0cdcb2..0000000000 --- a/core/src/textcodec/Big5TextEncoder.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -class Big5TextEncoder -{ -public: - static void EncodeBig5(const std::wstring& str, std::string& bytes); -}; diff --git a/core/src/textcodec/GBTextDecoder.cpp b/core/src/textcodec/GBTextDecoder.cpp deleted file mode 100644 index e104b595e9..0000000000 --- a/core/src/textcodec/GBTextDecoder.cpp +++ /dev/null @@ -1,3576 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "GBTextDecoder.h" - -struct indexTbl_t -{ - uint8_t tblBegin; - uint8_t tblEnd; - uint16_t tblOffset; - uint16_t algOffset; -}; - - -static const indexTbl_t gb18030_to_ucs_index[154] = { - /* U+00__ */ {0x00, 0xFF, 0x0000, 0x0000}, {0x00, 0xFF, 0x0000, 0x0000}, - /* U+02__ */ {0x00, 0xFF, 0x0000, 0x0000}, {0x00, 0x33, 0x0000, 0x041E}, - /* U+04__ */ {0xFF, 0x00, 0x1BBE, 0x051E}, {0xFF, 0x00, 0x1BBE, 0x061E}, - /* U+06__ */ {0xFF, 0x00, 0x1BBE, 0x071E}, {0xFF, 0x00, 0x1BBE, 0x081E}, - /* U+08__ */ {0xFF, 0x00, 0x1BBE, 0x091E}, {0xFF, 0x00, 0x1BBE, 0x0A1E}, - /* U+0A__ */ {0xFF, 0x00, 0x1BBE, 0x0B1E}, {0xFF, 0x00, 0x1BBE, 0x0C1E}, - /* U+0C__ */ {0xFF, 0x00, 0x1BBE, 0x0D1E}, {0xFF, 0x00, 0x1BBE, 0x0E1E}, - /* U+0E__ */ {0xFF, 0x00, 0x1BBE, 0x0F1E}, {0xFF, 0x00, 0x1BBE, 0x101E}, - /* U+10__ */ {0xFF, 0x00, 0x1BBE, 0x111E}, {0xFF, 0x00, 0x1BBE, 0x121E}, - /* U+12__ */ {0xFF, 0x00, 0x1BBE, 0x131E}, {0xFF, 0x00, 0x1BBE, 0x141E}, - /* U+14__ */ {0xFF, 0x00, 0x1BBE, 0x151E}, {0xFF, 0x00, 0x1BBE, 0x161E}, - /* U+16__ */ {0xFF, 0x00, 0x1BBE, 0x171E}, {0xFF, 0x00, 0x1BBE, 0x181E}, - /* U+18__ */ {0xFF, 0x00, 0x1BBE, 0x191E}, {0xFF, 0x00, 0x1BBE, 0x1A1E}, - /* U+1A__ */ {0xFF, 0x00, 0x1BBE, 0x1B1E}, {0xFF, 0x00, 0x1BBE, 0x1C1E}, - /* U+1C__ */ {0xFF, 0x00, 0x1BBE, 0x1D1E}, {0xFF, 0x00, 0x1BBE, 0x1E1E}, - /* U+1E__ */ {0xF2, 0xFF, 0x1BBE, 0x1F1E}, {0x00, 0xFF, 0x1BBE, 0x0000}, - /* U+20__ */ {0x00, 0xFF, 0x1BBE, 0x0000}, {0x00, 0xFF, 0x1BBE, 0x0000}, - /* U+22__ */ {0x00, 0xFF, 0x1BBE, 0x0000}, {0x00, 0xFF, 0x1BBE, 0x0000}, - /* U+24__ */ {0x00, 0x02, 0x1BBE, 0x2640}, {0xFF, 0x00, 0x23FC, 0x2740}, - /* U+26__ */ {0xFF, 0x00, 0x23FC, 0x2840}, {0xFF, 0x00, 0x23FC, 0x2940}, - /* U+28__ */ {0xFF, 0x00, 0x23FC, 0x2A40}, {0xFF, 0x00, 0x23FC, 0x2B40}, - /* U+2A__ */ {0xFF, 0x00, 0x23FC, 0x2C40}, {0xFF, 0x00, 0x23FC, 0x2D40}, - /* U+2C__ */ {0x41, 0xFF, 0x23FC, 0x2E40}, {0x00, 0xFF, 0x23FC, 0x0000}, - /* U+2E__ */ {0x00, 0xFF, 0x23FC, 0x0000}, {0x00, 0xFF, 0x23FC, 0x0000}, - /* U+30__ */ {0x00, 0xFF, 0x23FC, 0x0000}, {0x00, 0xFF, 0x23FC, 0x0000}, - /* U+32__ */ {0x00, 0xAC, 0x23FC, 0x356E}, {0xFF, 0x00, 0x26F9, 0x366E}, - /* U+34__ */ {0xFF, 0x00, 0x26F9, 0x376E}, {0xAA, 0xFF, 0x26F9, 0x386E}, - /* U+36__ */ {0x00, 0xFF, 0x26F9, 0x0000}, {0x00, 0xFF, 0x26F9, 0x0000}, - /* U+38__ */ {0x00, 0xFF, 0x26F9, 0x0000}, {0x00, 0x69, 0x26F9, 0x3C77}, - /* U+3A__ */ {0xFF, 0x00, 0x2A6E, 0x3D77}, {0xFF, 0x00, 0x2A6E, 0x3E77}, - /* U+3C__ */ {0xDF, 0xFF, 0x2A6E, 0x3F77}, {0x00, 0xE6, 0x2A6E, 0x4079}, - /* U+3E__ */ {0xFF, 0x00, 0x2C45, 0x4179}, {0xBE, 0xFF, 0x2C45, 0x4279}, - /* U+40__ */ {0x00, 0xFF, 0x2C45, 0x0000}, {0x00, 0x58, 0x2C45, 0x447E}, - /* U+42__ */ {0xCE, 0xFF, 0x2DBA, 0x457E}, {0x00, 0xFF, 0x2DBA, 0x0000}, - /* U+44__ */ {0x00, 0x09, 0x2DBA, 0x4784}, {0xC3, 0xFF, 0x2F73, 0x4884}, - /* U+46__ */ {0x00, 0x28, 0x2F73, 0x498F}, {0xFF, 0x00, 0x3232, 0x4A8F}, - /* U+48__ */ {0xE8, 0xFF, 0x3232, 0x4B8F}, {0x00, 0xFF, 0x3232, 0x0000}, - /* U+4A__ */ {0x00, 0x62, 0x3232, 0x9F43}, {0xFF, 0x00, 0x6A8C, 0xA043}, - /* U+4C__ */ {0xFF, 0x00, 0x6A8C, 0xA143}, {0xFF, 0x00, 0x6A8C, 0xA243}, - /* U+4E__ */ {0xFF, 0x00, 0x6A8C, 0xA343}, {0xFF, 0x00, 0x6A8C, 0xA443}, - /* U+50__ */ {0xFF, 0x00, 0x6A8C, 0xA543}, {0xFF, 0x00, 0x6A8C, 0xA643}, - /* U+52__ */ {0xFF, 0x00, 0x6A8C, 0xA743}, {0xFF, 0x00, 0x6A8C, 0xA843}, - /* U+54__ */ {0xFF, 0x00, 0x6A8C, 0xA943}, {0xFF, 0x00, 0x6A8C, 0xAA43}, - /* U+56__ */ {0xFF, 0x00, 0x6A8C, 0xAB43}, {0xFF, 0x00, 0x6A8C, 0xAC43}, - /* U+58__ */ {0xFF, 0x00, 0x6A8C, 0xAD43}, {0xFF, 0x00, 0x6A8C, 0xAE43}, - /* U+5A__ */ {0xFF, 0x00, 0x6A8C, 0xAF43}, {0xFF, 0x00, 0x6A8C, 0xB043}, - /* U+5C__ */ {0xFF, 0x00, 0x6A8C, 0xB143}, {0xFF, 0x00, 0x6A8C, 0xB243}, - /* U+5E__ */ {0xFF, 0x00, 0x6A8C, 0xB343}, {0xFF, 0x00, 0x6A8C, 0xB443}, - /* U+60__ */ {0xFF, 0x00, 0x6A8C, 0xB543}, {0xFF, 0x00, 0x6A8C, 0xB643}, - /* U+62__ */ {0xFF, 0x00, 0x6A8C, 0xB743}, {0xFF, 0x00, 0x6A8C, 0xB843}, - /* U+64__ */ {0xFF, 0x00, 0x6A8C, 0xB943}, {0xFF, 0x00, 0x6A8C, 0xBA43}, - /* U+66__ */ {0xFF, 0x00, 0x6A8C, 0xBB43}, {0xFF, 0x00, 0x6A8C, 0xBC43}, - /* U+68__ */ {0xFF, 0x00, 0x6A8C, 0xBD43}, {0xFF, 0x00, 0x6A8C, 0xBE43}, - /* U+6A__ */ {0xFF, 0x00, 0x6A8C, 0xBF43}, {0xFF, 0x00, 0x6A8C, 0xC043}, - /* U+6C__ */ {0xFF, 0x00, 0x6A8C, 0xC143}, {0xFF, 0x00, 0x6A8C, 0xC243}, - /* U+6E__ */ {0xFF, 0x00, 0x6A8C, 0xC343}, {0xFF, 0x00, 0x6A8C, 0xC443}, - /* U+70__ */ {0xFF, 0x00, 0x6A8C, 0xC543}, {0xFF, 0x00, 0x6A8C, 0xC643}, - /* U+72__ */ {0xFF, 0x00, 0x6A8C, 0xC743}, {0xFF, 0x00, 0x6A8C, 0xC843}, - /* U+74__ */ {0xFF, 0x00, 0x6A8C, 0xC943}, {0xFF, 0x00, 0x6A8C, 0xCA43}, - /* U+76__ */ {0xFF, 0x00, 0x6A8C, 0xCB43}, {0xFF, 0x00, 0x6A8C, 0xCC43}, - /* U+78__ */ {0xFF, 0x00, 0x6A8C, 0xCD43}, {0xFF, 0x00, 0x6A8C, 0xCE43}, - /* U+7A__ */ {0xFF, 0x00, 0x6A8C, 0xCF43}, {0xFF, 0x00, 0x6A8C, 0xD043}, - /* U+7C__ */ {0xFF, 0x00, 0x6A8C, 0xD143}, {0xFF, 0x00, 0x6A8C, 0xD243}, - /* U+7E__ */ {0xFF, 0x00, 0x6A8C, 0xD343}, {0xFF, 0x00, 0x6A8C, 0xD443}, - /* U+80__ */ {0xFF, 0x00, 0x6A8C, 0xD543}, {0xFF, 0x00, 0x6A8C, 0xD643}, - /* U+82__ */ {0xBD, 0xFF, 0x6A8C, 0xD743}, {0x00, 0x0D, 0x6A8C, 0xE857}, - /* U+84__ */ {0xFF, 0x00, 0x7B53, 0xE957}, {0xFF, 0x00, 0x7B53, 0xEA57}, - /* U+86__ */ {0xFF, 0x00, 0x7B53, 0xEB57}, {0xFF, 0x00, 0x7B53, 0xEC57}, - /* U+88__ */ {0xFF, 0x00, 0x7B53, 0xED57}, {0xFF, 0x00, 0x7B53, 0xEE57}, - /* U+8A__ */ {0xFF, 0x00, 0x7B53, 0xEF57}, {0xFF, 0x00, 0x7B53, 0xF057}, - /* U+8C__ */ {0xFF, 0x00, 0x7B53, 0xF157}, {0xFF, 0x00, 0x7B53, 0xF257}, - /* U+8E__ */ {0xFF, 0x00, 0x7B53, 0xF357}, {0xFF, 0x00, 0x7B53, 0xF457}, - /* U+90__ */ {0xFF, 0x00, 0x7B53, 0xF557}, {0xFF, 0x00, 0x7B53, 0xF657}, - /* U+92__ */ {0xFF, 0x00, 0x7B53, 0xF757}, {0xD5, 0xFF, 0x7B53, 0xF857}, - /* U+94__ */ {0x00, 0xBD, 0x7B53, 0xF96C}, {0xFF, 0x00, 0x7F59, 0xFA6C}, - /* U+96__ */ {0xFF, 0x00, 0x7F59, 0xFB6C}, {0xFF, 0x00, 0x7F59, 0xFC6C}, - /* U+98__ */ {0xC4, 0xFF, 0x7F59, 0xFD6C}, {0x00, 0xE1, 0x7F59, 0xFF04}, -}; - -static const uint16_t gb18030_2byte_to_ucs[22046] = { - // GB 0x8140..0x817E - 0x4E02, 0x4E04, 0x4E05, 0x4E06, 0x4E0F, 0x4E12, 0x4E17, 0x4E1F, 0x4E20, 0x4E21, 0x4E23, 0x4E26, 0x4E29, 0x4E2E, 0x4E2F, 0x4E31, - 0x4E33, 0x4E35, 0x4E37, 0x4E3C, 0x4E40, 0x4E41, 0x4E42, 0x4E44, 0x4E46, 0x4E4A, 0x4E51, 0x4E55, 0x4E57, 0x4E5A, 0x4E5B, 0x4E62, - 0x4E63, 0x4E64, 0x4E65, 0x4E67, 0x4E68, 0x4E6A, 0x4E6B, 0x4E6C, 0x4E6D, 0x4E6E, 0x4E6F, 0x4E72, 0x4E74, 0x4E75, 0x4E76, 0x4E77, - 0x4E78, 0x4E79, 0x4E7A, 0x4E7B, 0x4E7C, 0x4E7D, 0x4E7F, 0x4E80, 0x4E81, 0x4E82, 0x4E83, 0x4E84, 0x4E85, 0x4E87, 0x4E8A, - // GB 0x8180..0x81FE - 0x4E90, 0x4E96, 0x4E97, 0x4E99, 0x4E9C, 0x4E9D, 0x4E9E, 0x4EA3, - 0x4EAA, 0x4EAF, 0x4EB0, 0x4EB1, 0x4EB4, 0x4EB6, 0x4EB7, 0x4EB8, 0x4EB9, 0x4EBC, 0x4EBD, 0x4EBE, 0x4EC8, 0x4ECC, 0x4ECF, 0x4ED0, - 0x4ED2, 0x4EDA, 0x4EDB, 0x4EDC, 0x4EE0, 0x4EE2, 0x4EE6, 0x4EE7, 0x4EE9, 0x4EED, 0x4EEE, 0x4EEF, 0x4EF1, 0x4EF4, 0x4EF8, 0x4EF9, - 0x4EFA, 0x4EFC, 0x4EFE, 0x4F00, 0x4F02, 0x4F03, 0x4F04, 0x4F05, 0x4F06, 0x4F07, 0x4F08, 0x4F0B, 0x4F0C, 0x4F12, 0x4F13, 0x4F14, - 0x4F15, 0x4F16, 0x4F1C, 0x4F1D, 0x4F21, 0x4F23, 0x4F28, 0x4F29, 0x4F2C, 0x4F2D, 0x4F2E, 0x4F31, 0x4F33, 0x4F35, 0x4F37, 0x4F39, - 0x4F3B, 0x4F3E, 0x4F3F, 0x4F40, 0x4F41, 0x4F42, 0x4F44, 0x4F45, 0x4F47, 0x4F48, 0x4F49, 0x4F4A, 0x4F4B, 0x4F4C, 0x4F52, 0x4F54, - 0x4F56, 0x4F61, 0x4F62, 0x4F66, 0x4F68, 0x4F6A, 0x4F6B, 0x4F6D, 0x4F6E, 0x4F71, 0x4F72, 0x4F75, 0x4F77, 0x4F78, 0x4F79, 0x4F7A, - 0x4F7D, 0x4F80, 0x4F81, 0x4F82, 0x4F85, 0x4F86, 0x4F87, 0x4F8A, 0x4F8C, 0x4F8E, 0x4F90, 0x4F92, 0x4F93, 0x4F95, 0x4F96, 0x4F98, - 0x4F99, 0x4F9A, 0x4F9C, 0x4F9E, 0x4F9F, 0x4FA1, 0x4FA2, - // GB 0x8240..0x827E - 0x4FA4, 0x4FAB, 0x4FAD, 0x4FB0, 0x4FB1, 0x4FB2, 0x4FB3, 0x4FB4, 0x4FB6, 0x4FB7, 0x4FB8, 0x4FB9, 0x4FBA, 0x4FBB, 0x4FBC, 0x4FBD, - 0x4FBE, 0x4FC0, 0x4FC1, 0x4FC2, 0x4FC6, 0x4FC7, 0x4FC8, 0x4FC9, 0x4FCB, 0x4FCC, 0x4FCD, 0x4FD2, 0x4FD3, 0x4FD4, 0x4FD5, 0x4FD6, - 0x4FD9, 0x4FDB, 0x4FE0, 0x4FE2, 0x4FE4, 0x4FE5, 0x4FE7, 0x4FEB, 0x4FEC, 0x4FF0, 0x4FF2, 0x4FF4, 0x4FF5, 0x4FF6, 0x4FF7, 0x4FF9, - 0x4FFB, 0x4FFC, 0x4FFD, 0x4FFF, 0x5000, 0x5001, 0x5002, 0x5003, 0x5004, 0x5005, 0x5006, 0x5007, 0x5008, 0x5009, 0x500A, - // GB 0x8280..0x82FE - 0x500B, 0x500E, 0x5010, 0x5011, 0x5013, 0x5015, 0x5016, 0x5017, - 0x501B, 0x501D, 0x501E, 0x5020, 0x5022, 0x5023, 0x5024, 0x5027, 0x502B, 0x502F, 0x5030, 0x5031, 0x5032, 0x5033, 0x5034, 0x5035, - 0x5036, 0x5037, 0x5038, 0x5039, 0x503B, 0x503D, 0x503F, 0x5040, 0x5041, 0x5042, 0x5044, 0x5045, 0x5046, 0x5049, 0x504A, 0x504B, - 0x504D, 0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5056, 0x5057, 0x5058, 0x5059, 0x505B, 0x505D, 0x505E, 0x505F, 0x5060, 0x5061, - 0x5062, 0x5063, 0x5064, 0x5066, 0x5067, 0x5068, 0x5069, 0x506A, 0x506B, 0x506D, 0x506E, 0x506F, 0x5070, 0x5071, 0x5072, 0x5073, - 0x5074, 0x5075, 0x5078, 0x5079, 0x507A, 0x507C, 0x507D, 0x5081, 0x5082, 0x5083, 0x5084, 0x5086, 0x5087, 0x5089, 0x508A, 0x508B, - 0x508C, 0x508E, 0x508F, 0x5090, 0x5091, 0x5092, 0x5093, 0x5094, 0x5095, 0x5096, 0x5097, 0x5098, 0x5099, 0x509A, 0x509B, 0x509C, - 0x509D, 0x509E, 0x509F, 0x50A0, 0x50A1, 0x50A2, 0x50A4, 0x50A6, 0x50AA, 0x50AB, 0x50AD, 0x50AE, 0x50AF, 0x50B0, 0x50B1, 0x50B3, - 0x50B4, 0x50B5, 0x50B6, 0x50B7, 0x50B8, 0x50B9, 0x50BC, - // GB 0x8340..0x837E - 0x50BD, 0x50BE, 0x50BF, 0x50C0, 0x50C1, 0x50C2, 0x50C3, 0x50C4, 0x50C5, 0x50C6, 0x50C7, 0x50C8, 0x50C9, 0x50CA, 0x50CB, 0x50CC, - 0x50CD, 0x50CE, 0x50D0, 0x50D1, 0x50D2, 0x50D3, 0x50D4, 0x50D5, 0x50D7, 0x50D8, 0x50D9, 0x50DB, 0x50DC, 0x50DD, 0x50DE, 0x50DF, - 0x50E0, 0x50E1, 0x50E2, 0x50E3, 0x50E4, 0x50E5, 0x50E8, 0x50E9, 0x50EA, 0x50EB, 0x50EF, 0x50F0, 0x50F1, 0x50F2, 0x50F4, 0x50F6, - 0x50F7, 0x50F8, 0x50F9, 0x50FA, 0x50FC, 0x50FD, 0x50FE, 0x50FF, 0x5100, 0x5101, 0x5102, 0x5103, 0x5104, 0x5105, 0x5108, - // GB 0x8380..0x83FE - 0x5109, 0x510A, 0x510C, 0x510D, 0x510E, 0x510F, 0x5110, 0x5111, - 0x5113, 0x5114, 0x5115, 0x5116, 0x5117, 0x5118, 0x5119, 0x511A, 0x511B, 0x511C, 0x511D, 0x511E, 0x511F, 0x5120, 0x5122, 0x5123, - 0x5124, 0x5125, 0x5126, 0x5127, 0x5128, 0x5129, 0x512A, 0x512B, 0x512C, 0x512D, 0x512E, 0x512F, 0x5130, 0x5131, 0x5132, 0x5133, - 0x5134, 0x5135, 0x5136, 0x5137, 0x5138, 0x5139, 0x513A, 0x513B, 0x513C, 0x513D, 0x513E, 0x5142, 0x5147, 0x514A, 0x514C, 0x514E, - 0x514F, 0x5150, 0x5152, 0x5153, 0x5157, 0x5158, 0x5159, 0x515B, 0x515D, 0x515E, 0x515F, 0x5160, 0x5161, 0x5163, 0x5164, 0x5166, - 0x5167, 0x5169, 0x516A, 0x516F, 0x5172, 0x517A, 0x517E, 0x517F, 0x5183, 0x5184, 0x5186, 0x5187, 0x518A, 0x518B, 0x518E, 0x518F, - 0x5190, 0x5191, 0x5193, 0x5194, 0x5198, 0x519A, 0x519D, 0x519E, 0x519F, 0x51A1, 0x51A3, 0x51A6, 0x51A7, 0x51A8, 0x51A9, 0x51AA, - 0x51AD, 0x51AE, 0x51B4, 0x51B8, 0x51B9, 0x51BA, 0x51BE, 0x51BF, 0x51C1, 0x51C2, 0x51C3, 0x51C5, 0x51C8, 0x51CA, 0x51CD, 0x51CE, - 0x51D0, 0x51D2, 0x51D3, 0x51D4, 0x51D5, 0x51D6, 0x51D7, - // GB 0x8440..0x847E - 0x51D8, 0x51D9, 0x51DA, 0x51DC, 0x51DE, 0x51DF, 0x51E2, 0x51E3, 0x51E5, 0x51E6, 0x51E7, 0x51E8, 0x51E9, 0x51EA, 0x51EC, 0x51EE, - 0x51F1, 0x51F2, 0x51F4, 0x51F7, 0x51FE, 0x5204, 0x5205, 0x5209, 0x520B, 0x520C, 0x520F, 0x5210, 0x5213, 0x5214, 0x5215, 0x521C, - 0x521E, 0x521F, 0x5221, 0x5222, 0x5223, 0x5225, 0x5226, 0x5227, 0x522A, 0x522C, 0x522F, 0x5231, 0x5232, 0x5234, 0x5235, 0x523C, - 0x523E, 0x5244, 0x5245, 0x5246, 0x5247, 0x5248, 0x5249, 0x524B, 0x524E, 0x524F, 0x5252, 0x5253, 0x5255, 0x5257, 0x5258, - // GB 0x8480..0x84FE - 0x5259, 0x525A, 0x525B, 0x525D, 0x525F, 0x5260, 0x5262, 0x5263, - 0x5264, 0x5266, 0x5268, 0x526B, 0x526C, 0x526D, 0x526E, 0x5270, 0x5271, 0x5273, 0x5274, 0x5275, 0x5276, 0x5277, 0x5278, 0x5279, - 0x527A, 0x527B, 0x527C, 0x527E, 0x5280, 0x5283, 0x5284, 0x5285, 0x5286, 0x5287, 0x5289, 0x528A, 0x528B, 0x528C, 0x528D, 0x528E, - 0x528F, 0x5291, 0x5292, 0x5294, 0x5295, 0x5296, 0x5297, 0x5298, 0x5299, 0x529A, 0x529C, 0x52A4, 0x52A5, 0x52A6, 0x52A7, 0x52AE, - 0x52AF, 0x52B0, 0x52B4, 0x52B5, 0x52B6, 0x52B7, 0x52B8, 0x52B9, 0x52BA, 0x52BB, 0x52BC, 0x52BD, 0x52C0, 0x52C1, 0x52C2, 0x52C4, - 0x52C5, 0x52C6, 0x52C8, 0x52CA, 0x52CC, 0x52CD, 0x52CE, 0x52CF, 0x52D1, 0x52D3, 0x52D4, 0x52D5, 0x52D7, 0x52D9, 0x52DA, 0x52DB, - 0x52DC, 0x52DD, 0x52DE, 0x52E0, 0x52E1, 0x52E2, 0x52E3, 0x52E5, 0x52E6, 0x52E7, 0x52E8, 0x52E9, 0x52EA, 0x52EB, 0x52EC, 0x52ED, - 0x52EE, 0x52EF, 0x52F1, 0x52F2, 0x52F3, 0x52F4, 0x52F5, 0x52F6, 0x52F7, 0x52F8, 0x52FB, 0x52FC, 0x52FD, 0x5301, 0x5302, 0x5303, - 0x5304, 0x5307, 0x5309, 0x530A, 0x530B, 0x530C, 0x530E, - // GB 0x8540..0x857E - 0x5311, 0x5312, 0x5313, 0x5314, 0x5318, 0x531B, 0x531C, 0x531E, 0x531F, 0x5322, 0x5324, 0x5325, 0x5327, 0x5328, 0x5329, 0x532B, - 0x532C, 0x532D, 0x532F, 0x5330, 0x5331, 0x5332, 0x5333, 0x5334, 0x5335, 0x5336, 0x5337, 0x5338, 0x533C, 0x533D, 0x5340, 0x5342, - 0x5344, 0x5346, 0x534B, 0x534C, 0x534D, 0x5350, 0x5354, 0x5358, 0x5359, 0x535B, 0x535D, 0x5365, 0x5368, 0x536A, 0x536C, 0x536D, - 0x5372, 0x5376, 0x5379, 0x537B, 0x537C, 0x537D, 0x537E, 0x5380, 0x5381, 0x5383, 0x5387, 0x5388, 0x538A, 0x538E, 0x538F, - // GB 0x8580..0x85FE - 0x5390, 0x5391, 0x5392, 0x5393, 0x5394, 0x5396, 0x5397, 0x5399, - 0x539B, 0x539C, 0x539E, 0x53A0, 0x53A1, 0x53A4, 0x53A7, 0x53AA, 0x53AB, 0x53AC, 0x53AD, 0x53AF, 0x53B0, 0x53B1, 0x53B2, 0x53B3, - 0x53B4, 0x53B5, 0x53B7, 0x53B8, 0x53B9, 0x53BA, 0x53BC, 0x53BD, 0x53BE, 0x53C0, 0x53C3, 0x53C4, 0x53C5, 0x53C6, 0x53C7, 0x53CE, - 0x53CF, 0x53D0, 0x53D2, 0x53D3, 0x53D5, 0x53DA, 0x53DC, 0x53DD, 0x53DE, 0x53E1, 0x53E2, 0x53E7, 0x53F4, 0x53FA, 0x53FE, 0x53FF, - 0x5400, 0x5402, 0x5405, 0x5407, 0x540B, 0x5414, 0x5418, 0x5419, 0x541A, 0x541C, 0x5422, 0x5424, 0x5425, 0x542A, 0x5430, 0x5433, - 0x5436, 0x5437, 0x543A, 0x543D, 0x543F, 0x5441, 0x5442, 0x5444, 0x5445, 0x5447, 0x5449, 0x544C, 0x544D, 0x544E, 0x544F, 0x5451, - 0x545A, 0x545D, 0x545E, 0x545F, 0x5460, 0x5461, 0x5463, 0x5465, 0x5467, 0x5469, 0x546A, 0x546B, 0x546C, 0x546D, 0x546E, 0x546F, - 0x5470, 0x5474, 0x5479, 0x547A, 0x547E, 0x547F, 0x5481, 0x5483, 0x5485, 0x5487, 0x5488, 0x5489, 0x548A, 0x548D, 0x5491, 0x5493, - 0x5497, 0x5498, 0x549C, 0x549E, 0x549F, 0x54A0, 0x54A1, - // GB 0x8640..0x867E - 0x54A2, 0x54A5, 0x54AE, 0x54B0, 0x54B2, 0x54B5, 0x54B6, 0x54B7, 0x54B9, 0x54BA, 0x54BC, 0x54BE, 0x54C3, 0x54C5, 0x54CA, 0x54CB, - 0x54D6, 0x54D8, 0x54DB, 0x54E0, 0x54E1, 0x54E2, 0x54E3, 0x54E4, 0x54EB, 0x54EC, 0x54EF, 0x54F0, 0x54F1, 0x54F4, 0x54F5, 0x54F6, - 0x54F7, 0x54F8, 0x54F9, 0x54FB, 0x54FE, 0x5500, 0x5502, 0x5503, 0x5504, 0x5505, 0x5508, 0x550A, 0x550B, 0x550C, 0x550D, 0x550E, - 0x5512, 0x5513, 0x5515, 0x5516, 0x5517, 0x5518, 0x5519, 0x551A, 0x551C, 0x551D, 0x551E, 0x551F, 0x5521, 0x5525, 0x5526, - // GB 0x8680..0x86FE - 0x5528, 0x5529, 0x552B, 0x552D, 0x5532, 0x5534, 0x5535, 0x5536, - 0x5538, 0x5539, 0x553A, 0x553B, 0x553D, 0x5540, 0x5542, 0x5545, 0x5547, 0x5548, 0x554B, 0x554C, 0x554D, 0x554E, 0x554F, 0x5551, - 0x5552, 0x5553, 0x5554, 0x5557, 0x5558, 0x5559, 0x555A, 0x555B, 0x555D, 0x555E, 0x555F, 0x5560, 0x5562, 0x5563, 0x5568, 0x5569, - 0x556B, 0x556F, 0x5570, 0x5571, 0x5572, 0x5573, 0x5574, 0x5579, 0x557A, 0x557D, 0x557F, 0x5585, 0x5586, 0x558C, 0x558D, 0x558E, - 0x5590, 0x5592, 0x5593, 0x5595, 0x5596, 0x5597, 0x559A, 0x559B, 0x559E, 0x55A0, 0x55A1, 0x55A2, 0x55A3, 0x55A4, 0x55A5, 0x55A6, - 0x55A8, 0x55A9, 0x55AA, 0x55AB, 0x55AC, 0x55AD, 0x55AE, 0x55AF, 0x55B0, 0x55B2, 0x55B4, 0x55B6, 0x55B8, 0x55BA, 0x55BC, 0x55BF, - 0x55C0, 0x55C1, 0x55C2, 0x55C3, 0x55C6, 0x55C7, 0x55C8, 0x55CA, 0x55CB, 0x55CE, 0x55CF, 0x55D0, 0x55D5, 0x55D7, 0x55D8, 0x55D9, - 0x55DA, 0x55DB, 0x55DE, 0x55E0, 0x55E2, 0x55E7, 0x55E9, 0x55ED, 0x55EE, 0x55F0, 0x55F1, 0x55F4, 0x55F6, 0x55F8, 0x55F9, 0x55FA, - 0x55FB, 0x55FC, 0x55FF, 0x5602, 0x5603, 0x5604, 0x5605, - // GB 0x8740..0x877E - 0x5606, 0x5607, 0x560A, 0x560B, 0x560D, 0x5610, 0x5611, 0x5612, 0x5613, 0x5614, 0x5615, 0x5616, 0x5617, 0x5619, 0x561A, 0x561C, - 0x561D, 0x5620, 0x5621, 0x5622, 0x5625, 0x5626, 0x5628, 0x5629, 0x562A, 0x562B, 0x562E, 0x562F, 0x5630, 0x5633, 0x5635, 0x5637, - 0x5638, 0x563A, 0x563C, 0x563D, 0x563E, 0x5640, 0x5641, 0x5642, 0x5643, 0x5644, 0x5645, 0x5646, 0x5647, 0x5648, 0x5649, 0x564A, - 0x564B, 0x564F, 0x5650, 0x5651, 0x5652, 0x5653, 0x5655, 0x5656, 0x565A, 0x565B, 0x565D, 0x565E, 0x565F, 0x5660, 0x5661, - // GB 0x8780..0x87FE - 0x5663, 0x5665, 0x5666, 0x5667, 0x566D, 0x566E, 0x566F, 0x5670, - 0x5672, 0x5673, 0x5674, 0x5675, 0x5677, 0x5678, 0x5679, 0x567A, 0x567D, 0x567E, 0x567F, 0x5680, 0x5681, 0x5682, 0x5683, 0x5684, - 0x5687, 0x5688, 0x5689, 0x568A, 0x568B, 0x568C, 0x568D, 0x5690, 0x5691, 0x5692, 0x5694, 0x5695, 0x5696, 0x5697, 0x5698, 0x5699, - 0x569A, 0x569B, 0x569C, 0x569D, 0x569E, 0x569F, 0x56A0, 0x56A1, 0x56A2, 0x56A4, 0x56A5, 0x56A6, 0x56A7, 0x56A8, 0x56A9, 0x56AA, - 0x56AB, 0x56AC, 0x56AD, 0x56AE, 0x56B0, 0x56B1, 0x56B2, 0x56B3, 0x56B4, 0x56B5, 0x56B6, 0x56B8, 0x56B9, 0x56BA, 0x56BB, 0x56BD, - 0x56BE, 0x56BF, 0x56C0, 0x56C1, 0x56C2, 0x56C3, 0x56C4, 0x56C5, 0x56C6, 0x56C7, 0x56C8, 0x56C9, 0x56CB, 0x56CC, 0x56CD, 0x56CE, - 0x56CF, 0x56D0, 0x56D1, 0x56D2, 0x56D3, 0x56D5, 0x56D6, 0x56D8, 0x56D9, 0x56DC, 0x56E3, 0x56E5, 0x56E6, 0x56E7, 0x56E8, 0x56E9, - 0x56EA, 0x56EC, 0x56EE, 0x56EF, 0x56F2, 0x56F3, 0x56F6, 0x56F7, 0x56F8, 0x56FB, 0x56FC, 0x5700, 0x5701, 0x5702, 0x5705, 0x5707, - 0x570B, 0x570C, 0x570D, 0x570E, 0x570F, 0x5710, 0x5711, - // GB 0x8840..0x887E - 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 0x5718, 0x5719, 0x571A, 0x571B, 0x571D, 0x571E, 0x5720, 0x5721, 0x5722, 0x5724, - 0x5725, 0x5726, 0x5727, 0x572B, 0x5731, 0x5732, 0x5734, 0x5735, 0x5736, 0x5737, 0x5738, 0x573C, 0x573D, 0x573F, 0x5741, 0x5743, - 0x5744, 0x5745, 0x5746, 0x5748, 0x5749, 0x574B, 0x5752, 0x5753, 0x5754, 0x5755, 0x5756, 0x5758, 0x5759, 0x5762, 0x5763, 0x5765, - 0x5767, 0x576C, 0x576E, 0x5770, 0x5771, 0x5772, 0x5774, 0x5775, 0x5778, 0x5779, 0x577A, 0x577D, 0x577E, 0x577F, 0x5780, - // GB 0x8880..0x88FE - 0x5781, 0x5787, 0x5788, 0x5789, 0x578A, 0x578D, 0x578E, 0x578F, - 0x5790, 0x5791, 0x5794, 0x5795, 0x5796, 0x5797, 0x5798, 0x5799, 0x579A, 0x579C, 0x579D, 0x579E, 0x579F, 0x57A5, 0x57A8, 0x57AA, - 0x57AC, 0x57AF, 0x57B0, 0x57B1, 0x57B3, 0x57B5, 0x57B6, 0x57B7, 0x57B9, 0x57BA, 0x57BB, 0x57BC, 0x57BD, 0x57BE, 0x57BF, 0x57C0, - 0x57C1, 0x57C4, 0x57C5, 0x57C6, 0x57C7, 0x57C8, 0x57C9, 0x57CA, 0x57CC, 0x57CD, 0x57D0, 0x57D1, 0x57D3, 0x57D6, 0x57D7, 0x57DB, - 0x57DC, 0x57DE, 0x57E1, 0x57E2, 0x57E3, 0x57E5, 0x57E6, 0x57E7, 0x57E8, 0x57E9, 0x57EA, 0x57EB, 0x57EC, 0x57EE, 0x57F0, 0x57F1, - 0x57F2, 0x57F3, 0x57F5, 0x57F6, 0x57F7, 0x57FB, 0x57FC, 0x57FE, 0x57FF, 0x5801, 0x5803, 0x5804, 0x5805, 0x5808, 0x5809, 0x580A, - 0x580C, 0x580E, 0x580F, 0x5810, 0x5812, 0x5813, 0x5814, 0x5816, 0x5817, 0x5818, 0x581A, 0x581B, 0x581C, 0x581D, 0x581F, 0x5822, - 0x5823, 0x5825, 0x5826, 0x5827, 0x5828, 0x5829, 0x582B, 0x582C, 0x582D, 0x582E, 0x582F, 0x5831, 0x5832, 0x5833, 0x5834, 0x5836, - 0x5837, 0x5838, 0x5839, 0x583A, 0x583B, 0x583C, 0x583D, - // GB 0x8940..0x897E - 0x583E, 0x583F, 0x5840, 0x5841, 0x5842, 0x5843, 0x5845, 0x5846, 0x5847, 0x5848, 0x5849, 0x584A, 0x584B, 0x584E, 0x584F, 0x5850, - 0x5852, 0x5853, 0x5855, 0x5856, 0x5857, 0x5859, 0x585A, 0x585B, 0x585C, 0x585D, 0x585F, 0x5860, 0x5861, 0x5862, 0x5863, 0x5864, - 0x5866, 0x5867, 0x5868, 0x5869, 0x586A, 0x586D, 0x586E, 0x586F, 0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877, - 0x5878, 0x5879, 0x587A, 0x587B, 0x587C, 0x587D, 0x587F, 0x5882, 0x5884, 0x5886, 0x5887, 0x5888, 0x588A, 0x588B, 0x588C, - // GB 0x8980..0x89FE - 0x588D, 0x588E, 0x588F, 0x5890, 0x5891, 0x5894, 0x5895, 0x5896, - 0x5897, 0x5898, 0x589B, 0x589C, 0x589D, 0x58A0, 0x58A1, 0x58A2, 0x58A3, 0x58A4, 0x58A5, 0x58A6, 0x58A7, 0x58AA, 0x58AB, 0x58AC, - 0x58AD, 0x58AE, 0x58AF, 0x58B0, 0x58B1, 0x58B2, 0x58B3, 0x58B4, 0x58B5, 0x58B6, 0x58B7, 0x58B8, 0x58B9, 0x58BA, 0x58BB, 0x58BD, - 0x58BE, 0x58BF, 0x58C0, 0x58C2, 0x58C3, 0x58C4, 0x58C6, 0x58C7, 0x58C8, 0x58C9, 0x58CA, 0x58CB, 0x58CC, 0x58CD, 0x58CE, 0x58CF, - 0x58D0, 0x58D2, 0x58D3, 0x58D4, 0x58D6, 0x58D7, 0x58D8, 0x58D9, 0x58DA, 0x58DB, 0x58DC, 0x58DD, 0x58DE, 0x58DF, 0x58E0, 0x58E1, - 0x58E2, 0x58E3, 0x58E5, 0x58E6, 0x58E7, 0x58E8, 0x58E9, 0x58EA, 0x58ED, 0x58EF, 0x58F1, 0x58F2, 0x58F4, 0x58F5, 0x58F7, 0x58F8, - 0x58FA, 0x58FB, 0x58FC, 0x58FD, 0x58FE, 0x58FF, 0x5900, 0x5901, 0x5903, 0x5905, 0x5906, 0x5908, 0x5909, 0x590A, 0x590B, 0x590C, - 0x590E, 0x5910, 0x5911, 0x5912, 0x5913, 0x5917, 0x5918, 0x591B, 0x591D, 0x591E, 0x5920, 0x5921, 0x5922, 0x5923, 0x5926, 0x5928, - 0x592C, 0x5930, 0x5932, 0x5933, 0x5935, 0x5936, 0x593B, - // GB 0x8A40..0x8A7E - 0x593D, 0x593E, 0x593F, 0x5940, 0x5943, 0x5945, 0x5946, 0x594A, 0x594C, 0x594D, 0x5950, 0x5952, 0x5953, 0x5959, 0x595B, 0x595C, - 0x595D, 0x595E, 0x595F, 0x5961, 0x5963, 0x5964, 0x5966, 0x5967, 0x5968, 0x5969, 0x596A, 0x596B, 0x596C, 0x596D, 0x596E, 0x596F, - 0x5970, 0x5971, 0x5972, 0x5975, 0x5977, 0x597A, 0x597B, 0x597C, 0x597E, 0x597F, 0x5980, 0x5985, 0x5989, 0x598B, 0x598C, 0x598E, - 0x598F, 0x5990, 0x5991, 0x5994, 0x5995, 0x5998, 0x599A, 0x599B, 0x599C, 0x599D, 0x599F, 0x59A0, 0x59A1, 0x59A2, 0x59A6, - // GB 0x8A80..0x8AFE - 0x59A7, 0x59AC, 0x59AD, 0x59B0, 0x59B1, 0x59B3, 0x59B4, 0x59B5, - 0x59B6, 0x59B7, 0x59B8, 0x59BA, 0x59BC, 0x59BD, 0x59BF, 0x59C0, 0x59C1, 0x59C2, 0x59C3, 0x59C4, 0x59C5, 0x59C7, 0x59C8, 0x59C9, - 0x59CC, 0x59CD, 0x59CE, 0x59CF, 0x59D5, 0x59D6, 0x59D9, 0x59DB, 0x59DE, 0x59DF, 0x59E0, 0x59E1, 0x59E2, 0x59E4, 0x59E6, 0x59E7, - 0x59E9, 0x59EA, 0x59EB, 0x59ED, 0x59EE, 0x59EF, 0x59F0, 0x59F1, 0x59F2, 0x59F3, 0x59F4, 0x59F5, 0x59F6, 0x59F7, 0x59F8, 0x59FA, - 0x59FC, 0x59FD, 0x59FE, 0x5A00, 0x5A02, 0x5A0A, 0x5A0B, 0x5A0D, 0x5A0E, 0x5A0F, 0x5A10, 0x5A12, 0x5A14, 0x5A15, 0x5A16, 0x5A17, - 0x5A19, 0x5A1A, 0x5A1B, 0x5A1D, 0x5A1E, 0x5A21, 0x5A22, 0x5A24, 0x5A26, 0x5A27, 0x5A28, 0x5A2A, 0x5A2B, 0x5A2C, 0x5A2D, 0x5A2E, - 0x5A2F, 0x5A30, 0x5A33, 0x5A35, 0x5A37, 0x5A38, 0x5A39, 0x5A3A, 0x5A3B, 0x5A3D, 0x5A3E, 0x5A3F, 0x5A41, 0x5A42, 0x5A43, 0x5A44, - 0x5A45, 0x5A47, 0x5A48, 0x5A4B, 0x5A4C, 0x5A4D, 0x5A4E, 0x5A4F, 0x5A50, 0x5A51, 0x5A52, 0x5A53, 0x5A54, 0x5A56, 0x5A57, 0x5A58, - 0x5A59, 0x5A5B, 0x5A5C, 0x5A5D, 0x5A5E, 0x5A5F, 0x5A60, - // GB 0x8B40..0x8B7E - 0x5A61, 0x5A63, 0x5A64, 0x5A65, 0x5A66, 0x5A68, 0x5A69, 0x5A6B, 0x5A6C, 0x5A6D, 0x5A6E, 0x5A6F, 0x5A70, 0x5A71, 0x5A72, 0x5A73, - 0x5A78, 0x5A79, 0x5A7B, 0x5A7C, 0x5A7D, 0x5A7E, 0x5A80, 0x5A81, 0x5A82, 0x5A83, 0x5A84, 0x5A85, 0x5A86, 0x5A87, 0x5A88, 0x5A89, - 0x5A8A, 0x5A8B, 0x5A8C, 0x5A8D, 0x5A8E, 0x5A8F, 0x5A90, 0x5A91, 0x5A93, 0x5A94, 0x5A95, 0x5A96, 0x5A97, 0x5A98, 0x5A99, 0x5A9C, - 0x5A9D, 0x5A9E, 0x5A9F, 0x5AA0, 0x5AA1, 0x5AA2, 0x5AA3, 0x5AA4, 0x5AA5, 0x5AA6, 0x5AA7, 0x5AA8, 0x5AA9, 0x5AAB, 0x5AAC, - // GB 0x8B80..0x8BFE - 0x5AAD, 0x5AAE, 0x5AAF, 0x5AB0, 0x5AB1, 0x5AB4, 0x5AB6, 0x5AB7, - 0x5AB9, 0x5ABA, 0x5ABB, 0x5ABC, 0x5ABD, 0x5ABF, 0x5AC0, 0x5AC3, 0x5AC4, 0x5AC5, 0x5AC6, 0x5AC7, 0x5AC8, 0x5ACA, 0x5ACB, 0x5ACD, - 0x5ACE, 0x5ACF, 0x5AD0, 0x5AD1, 0x5AD3, 0x5AD5, 0x5AD7, 0x5AD9, 0x5ADA, 0x5ADB, 0x5ADD, 0x5ADE, 0x5ADF, 0x5AE2, 0x5AE4, 0x5AE5, - 0x5AE7, 0x5AE8, 0x5AEA, 0x5AEC, 0x5AED, 0x5AEE, 0x5AEF, 0x5AF0, 0x5AF2, 0x5AF3, 0x5AF4, 0x5AF5, 0x5AF6, 0x5AF7, 0x5AF8, 0x5AF9, - 0x5AFA, 0x5AFB, 0x5AFC, 0x5AFD, 0x5AFE, 0x5AFF, 0x5B00, 0x5B01, 0x5B02, 0x5B03, 0x5B04, 0x5B05, 0x5B06, 0x5B07, 0x5B08, 0x5B0A, - 0x5B0B, 0x5B0C, 0x5B0D, 0x5B0E, 0x5B0F, 0x5B10, 0x5B11, 0x5B12, 0x5B13, 0x5B14, 0x5B15, 0x5B18, 0x5B19, 0x5B1A, 0x5B1B, 0x5B1C, - 0x5B1D, 0x5B1E, 0x5B1F, 0x5B20, 0x5B21, 0x5B22, 0x5B23, 0x5B24, 0x5B25, 0x5B26, 0x5B27, 0x5B28, 0x5B29, 0x5B2A, 0x5B2B, 0x5B2C, - 0x5B2D, 0x5B2E, 0x5B2F, 0x5B30, 0x5B31, 0x5B33, 0x5B35, 0x5B36, 0x5B38, 0x5B39, 0x5B3A, 0x5B3B, 0x5B3C, 0x5B3D, 0x5B3E, 0x5B3F, - 0x5B41, 0x5B42, 0x5B43, 0x5B44, 0x5B45, 0x5B46, 0x5B47, - // GB 0x8C40..0x8C7E - 0x5B48, 0x5B49, 0x5B4A, 0x5B4B, 0x5B4C, 0x5B4D, 0x5B4E, 0x5B4F, 0x5B52, 0x5B56, 0x5B5E, 0x5B60, 0x5B61, 0x5B67, 0x5B68, 0x5B6B, - 0x5B6D, 0x5B6E, 0x5B6F, 0x5B72, 0x5B74, 0x5B76, 0x5B77, 0x5B78, 0x5B79, 0x5B7B, 0x5B7C, 0x5B7E, 0x5B7F, 0x5B82, 0x5B86, 0x5B8A, - 0x5B8D, 0x5B8E, 0x5B90, 0x5B91, 0x5B92, 0x5B94, 0x5B96, 0x5B9F, 0x5BA7, 0x5BA8, 0x5BA9, 0x5BAC, 0x5BAD, 0x5BAE, 0x5BAF, 0x5BB1, - 0x5BB2, 0x5BB7, 0x5BBA, 0x5BBB, 0x5BBC, 0x5BC0, 0x5BC1, 0x5BC3, 0x5BC8, 0x5BC9, 0x5BCA, 0x5BCB, 0x5BCD, 0x5BCE, 0x5BCF, - // GB 0x8C80..0x8CFE - 0x5BD1, 0x5BD4, 0x5BD5, 0x5BD6, 0x5BD7, 0x5BD8, 0x5BD9, 0x5BDA, - 0x5BDB, 0x5BDC, 0x5BE0, 0x5BE2, 0x5BE3, 0x5BE6, 0x5BE7, 0x5BE9, 0x5BEA, 0x5BEB, 0x5BEC, 0x5BED, 0x5BEF, 0x5BF1, 0x5BF2, 0x5BF3, - 0x5BF4, 0x5BF5, 0x5BF6, 0x5BF7, 0x5BFD, 0x5BFE, 0x5C00, 0x5C02, 0x5C03, 0x5C05, 0x5C07, 0x5C08, 0x5C0B, 0x5C0C, 0x5C0D, 0x5C0E, - 0x5C10, 0x5C12, 0x5C13, 0x5C17, 0x5C19, 0x5C1B, 0x5C1E, 0x5C1F, 0x5C20, 0x5C21, 0x5C23, 0x5C26, 0x5C28, 0x5C29, 0x5C2A, 0x5C2B, - 0x5C2D, 0x5C2E, 0x5C2F, 0x5C30, 0x5C32, 0x5C33, 0x5C35, 0x5C36, 0x5C37, 0x5C43, 0x5C44, 0x5C46, 0x5C47, 0x5C4C, 0x5C4D, 0x5C52, - 0x5C53, 0x5C54, 0x5C56, 0x5C57, 0x5C58, 0x5C5A, 0x5C5B, 0x5C5C, 0x5C5D, 0x5C5F, 0x5C62, 0x5C64, 0x5C67, 0x5C68, 0x5C69, 0x5C6A, - 0x5C6B, 0x5C6C, 0x5C6D, 0x5C70, 0x5C72, 0x5C73, 0x5C74, 0x5C75, 0x5C76, 0x5C77, 0x5C78, 0x5C7B, 0x5C7C, 0x5C7D, 0x5C7E, 0x5C80, - 0x5C83, 0x5C84, 0x5C85, 0x5C86, 0x5C87, 0x5C89, 0x5C8A, 0x5C8B, 0x5C8E, 0x5C8F, 0x5C92, 0x5C93, 0x5C95, 0x5C9D, 0x5C9E, 0x5C9F, - 0x5CA0, 0x5CA1, 0x5CA4, 0x5CA5, 0x5CA6, 0x5CA7, 0x5CA8, - // GB 0x8D40..0x8D7E - 0x5CAA, 0x5CAE, 0x5CAF, 0x5CB0, 0x5CB2, 0x5CB4, 0x5CB6, 0x5CB9, 0x5CBA, 0x5CBB, 0x5CBC, 0x5CBE, 0x5CC0, 0x5CC2, 0x5CC3, 0x5CC5, - 0x5CC6, 0x5CC7, 0x5CC8, 0x5CC9, 0x5CCA, 0x5CCC, 0x5CCD, 0x5CCE, 0x5CCF, 0x5CD0, 0x5CD1, 0x5CD3, 0x5CD4, 0x5CD5, 0x5CD6, 0x5CD7, - 0x5CD8, 0x5CDA, 0x5CDB, 0x5CDC, 0x5CDD, 0x5CDE, 0x5CDF, 0x5CE0, 0x5CE2, 0x5CE3, 0x5CE7, 0x5CE9, 0x5CEB, 0x5CEC, 0x5CEE, 0x5CEF, - 0x5CF1, 0x5CF2, 0x5CF3, 0x5CF4, 0x5CF5, 0x5CF6, 0x5CF7, 0x5CF8, 0x5CF9, 0x5CFA, 0x5CFC, 0x5CFD, 0x5CFE, 0x5CFF, 0x5D00, - // GB 0x8D80..0x8DFE - 0x5D01, 0x5D04, 0x5D05, 0x5D08, 0x5D09, 0x5D0A, 0x5D0B, 0x5D0C, - 0x5D0D, 0x5D0F, 0x5D10, 0x5D11, 0x5D12, 0x5D13, 0x5D15, 0x5D17, 0x5D18, 0x5D19, 0x5D1A, 0x5D1C, 0x5D1D, 0x5D1F, 0x5D20, 0x5D21, - 0x5D22, 0x5D23, 0x5D25, 0x5D28, 0x5D2A, 0x5D2B, 0x5D2C, 0x5D2F, 0x5D30, 0x5D31, 0x5D32, 0x5D33, 0x5D35, 0x5D36, 0x5D37, 0x5D38, - 0x5D39, 0x5D3A, 0x5D3B, 0x5D3C, 0x5D3F, 0x5D40, 0x5D41, 0x5D42, 0x5D43, 0x5D44, 0x5D45, 0x5D46, 0x5D48, 0x5D49, 0x5D4D, 0x5D4E, - 0x5D4F, 0x5D50, 0x5D51, 0x5D52, 0x5D53, 0x5D54, 0x5D55, 0x5D56, 0x5D57, 0x5D59, 0x5D5A, 0x5D5C, 0x5D5E, 0x5D5F, 0x5D60, 0x5D61, - 0x5D62, 0x5D63, 0x5D64, 0x5D65, 0x5D66, 0x5D67, 0x5D68, 0x5D6A, 0x5D6D, 0x5D6E, 0x5D70, 0x5D71, 0x5D72, 0x5D73, 0x5D75, 0x5D76, - 0x5D77, 0x5D78, 0x5D79, 0x5D7A, 0x5D7B, 0x5D7C, 0x5D7D, 0x5D7E, 0x5D7F, 0x5D80, 0x5D81, 0x5D83, 0x5D84, 0x5D85, 0x5D86, 0x5D87, - 0x5D88, 0x5D89, 0x5D8A, 0x5D8B, 0x5D8C, 0x5D8D, 0x5D8E, 0x5D8F, 0x5D90, 0x5D91, 0x5D92, 0x5D93, 0x5D94, 0x5D95, 0x5D96, 0x5D97, - 0x5D98, 0x5D9A, 0x5D9B, 0x5D9C, 0x5D9E, 0x5D9F, 0x5DA0, - // GB 0x8E40..0x8E7E - 0x5DA1, 0x5DA2, 0x5DA3, 0x5DA4, 0x5DA5, 0x5DA6, 0x5DA7, 0x5DA8, 0x5DA9, 0x5DAA, 0x5DAB, 0x5DAC, 0x5DAD, 0x5DAE, 0x5DAF, 0x5DB0, - 0x5DB1, 0x5DB2, 0x5DB3, 0x5DB4, 0x5DB5, 0x5DB6, 0x5DB8, 0x5DB9, 0x5DBA, 0x5DBB, 0x5DBC, 0x5DBD, 0x5DBE, 0x5DBF, 0x5DC0, 0x5DC1, - 0x5DC2, 0x5DC3, 0x5DC4, 0x5DC6, 0x5DC7, 0x5DC8, 0x5DC9, 0x5DCA, 0x5DCB, 0x5DCC, 0x5DCE, 0x5DCF, 0x5DD0, 0x5DD1, 0x5DD2, 0x5DD3, - 0x5DD4, 0x5DD5, 0x5DD6, 0x5DD7, 0x5DD8, 0x5DD9, 0x5DDA, 0x5DDC, 0x5DDF, 0x5DE0, 0x5DE3, 0x5DE4, 0x5DEA, 0x5DEC, 0x5DED, - // GB 0x8E80..0x8EFE - 0x5DF0, 0x5DF5, 0x5DF6, 0x5DF8, 0x5DF9, 0x5DFA, 0x5DFB, 0x5DFC, - 0x5DFF, 0x5E00, 0x5E04, 0x5E07, 0x5E09, 0x5E0A, 0x5E0B, 0x5E0D, 0x5E0E, 0x5E12, 0x5E13, 0x5E17, 0x5E1E, 0x5E1F, 0x5E20, 0x5E21, - 0x5E22, 0x5E23, 0x5E24, 0x5E25, 0x5E28, 0x5E29, 0x5E2A, 0x5E2B, 0x5E2C, 0x5E2F, 0x5E30, 0x5E32, 0x5E33, 0x5E34, 0x5E35, 0x5E36, - 0x5E39, 0x5E3A, 0x5E3E, 0x5E3F, 0x5E40, 0x5E41, 0x5E43, 0x5E46, 0x5E47, 0x5E48, 0x5E49, 0x5E4A, 0x5E4B, 0x5E4D, 0x5E4E, 0x5E4F, - 0x5E50, 0x5E51, 0x5E52, 0x5E53, 0x5E56, 0x5E57, 0x5E58, 0x5E59, 0x5E5A, 0x5E5C, 0x5E5D, 0x5E5F, 0x5E60, 0x5E63, 0x5E64, 0x5E65, - 0x5E66, 0x5E67, 0x5E68, 0x5E69, 0x5E6A, 0x5E6B, 0x5E6C, 0x5E6D, 0x5E6E, 0x5E6F, 0x5E70, 0x5E71, 0x5E75, 0x5E77, 0x5E79, 0x5E7E, - 0x5E81, 0x5E82, 0x5E83, 0x5E85, 0x5E88, 0x5E89, 0x5E8C, 0x5E8D, 0x5E8E, 0x5E92, 0x5E98, 0x5E9B, 0x5E9D, 0x5EA1, 0x5EA2, 0x5EA3, - 0x5EA4, 0x5EA8, 0x5EA9, 0x5EAA, 0x5EAB, 0x5EAC, 0x5EAE, 0x5EAF, 0x5EB0, 0x5EB1, 0x5EB2, 0x5EB4, 0x5EBA, 0x5EBB, 0x5EBC, 0x5EBD, - 0x5EBF, 0x5EC0, 0x5EC1, 0x5EC2, 0x5EC3, 0x5EC4, 0x5EC5, - // GB 0x8F40..0x8F7E - 0x5EC6, 0x5EC7, 0x5EC8, 0x5ECB, 0x5ECC, 0x5ECD, 0x5ECE, 0x5ECF, 0x5ED0, 0x5ED4, 0x5ED5, 0x5ED7, 0x5ED8, 0x5ED9, 0x5EDA, 0x5EDC, - 0x5EDD, 0x5EDE, 0x5EDF, 0x5EE0, 0x5EE1, 0x5EE2, 0x5EE3, 0x5EE4, 0x5EE5, 0x5EE6, 0x5EE7, 0x5EE9, 0x5EEB, 0x5EEC, 0x5EED, 0x5EEE, - 0x5EEF, 0x5EF0, 0x5EF1, 0x5EF2, 0x5EF3, 0x5EF5, 0x5EF8, 0x5EF9, 0x5EFB, 0x5EFC, 0x5EFD, 0x5F05, 0x5F06, 0x5F07, 0x5F09, 0x5F0C, - 0x5F0D, 0x5F0E, 0x5F10, 0x5F12, 0x5F14, 0x5F16, 0x5F19, 0x5F1A, 0x5F1C, 0x5F1D, 0x5F1E, 0x5F21, 0x5F22, 0x5F23, 0x5F24, - // GB 0x8F80..0x8FFE - 0x5F28, 0x5F2B, 0x5F2C, 0x5F2E, 0x5F30, 0x5F32, 0x5F33, 0x5F34, - 0x5F35, 0x5F36, 0x5F37, 0x5F38, 0x5F3B, 0x5F3D, 0x5F3E, 0x5F3F, 0x5F41, 0x5F42, 0x5F43, 0x5F44, 0x5F45, 0x5F46, 0x5F47, 0x5F48, - 0x5F49, 0x5F4A, 0x5F4B, 0x5F4C, 0x5F4D, 0x5F4E, 0x5F4F, 0x5F51, 0x5F54, 0x5F59, 0x5F5A, 0x5F5B, 0x5F5C, 0x5F5E, 0x5F5F, 0x5F60, - 0x5F63, 0x5F65, 0x5F67, 0x5F68, 0x5F6B, 0x5F6E, 0x5F6F, 0x5F72, 0x5F74, 0x5F75, 0x5F76, 0x5F78, 0x5F7A, 0x5F7D, 0x5F7E, 0x5F7F, - 0x5F83, 0x5F86, 0x5F8D, 0x5F8E, 0x5F8F, 0x5F91, 0x5F93, 0x5F94, 0x5F96, 0x5F9A, 0x5F9B, 0x5F9D, 0x5F9E, 0x5F9F, 0x5FA0, 0x5FA2, - 0x5FA3, 0x5FA4, 0x5FA5, 0x5FA6, 0x5FA7, 0x5FA9, 0x5FAB, 0x5FAC, 0x5FAF, 0x5FB0, 0x5FB1, 0x5FB2, 0x5FB3, 0x5FB4, 0x5FB6, 0x5FB8, - 0x5FB9, 0x5FBA, 0x5FBB, 0x5FBE, 0x5FBF, 0x5FC0, 0x5FC1, 0x5FC2, 0x5FC7, 0x5FC8, 0x5FCA, 0x5FCB, 0x5FCE, 0x5FD3, 0x5FD4, 0x5FD5, - 0x5FDA, 0x5FDB, 0x5FDC, 0x5FDE, 0x5FDF, 0x5FE2, 0x5FE3, 0x5FE5, 0x5FE6, 0x5FE8, 0x5FE9, 0x5FEC, 0x5FEF, 0x5FF0, 0x5FF2, 0x5FF3, - 0x5FF4, 0x5FF6, 0x5FF7, 0x5FF9, 0x5FFA, 0x5FFC, 0x6007, - // GB 0x9040..0x907E - 0x6008, 0x6009, 0x600B, 0x600C, 0x6010, 0x6011, 0x6013, 0x6017, 0x6018, 0x601A, 0x601E, 0x601F, 0x6022, 0x6023, 0x6024, 0x602C, - 0x602D, 0x602E, 0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6036, 0x6037, 0x6038, 0x6039, 0x603A, 0x603D, 0x603E, 0x6040, 0x6044, - 0x6045, 0x6046, 0x6047, 0x6048, 0x6049, 0x604A, 0x604C, 0x604E, 0x604F, 0x6051, 0x6053, 0x6054, 0x6056, 0x6057, 0x6058, 0x605B, - 0x605C, 0x605E, 0x605F, 0x6060, 0x6061, 0x6065, 0x6066, 0x606E, 0x6071, 0x6072, 0x6074, 0x6075, 0x6077, 0x607E, 0x6080, - // GB 0x9080..0x90FE - 0x6081, 0x6082, 0x6085, 0x6086, 0x6087, 0x6088, 0x608A, 0x608B, - 0x608E, 0x608F, 0x6090, 0x6091, 0x6093, 0x6095, 0x6097, 0x6098, 0x6099, 0x609C, 0x609E, 0x60A1, 0x60A2, 0x60A4, 0x60A5, 0x60A7, - 0x60A9, 0x60AA, 0x60AE, 0x60B0, 0x60B3, 0x60B5, 0x60B6, 0x60B7, 0x60B9, 0x60BA, 0x60BD, 0x60BE, 0x60BF, 0x60C0, 0x60C1, 0x60C2, - 0x60C3, 0x60C4, 0x60C7, 0x60C8, 0x60C9, 0x60CC, 0x60CD, 0x60CE, 0x60CF, 0x60D0, 0x60D2, 0x60D3, 0x60D4, 0x60D6, 0x60D7, 0x60D9, - 0x60DB, 0x60DE, 0x60E1, 0x60E2, 0x60E3, 0x60E4, 0x60E5, 0x60EA, 0x60F1, 0x60F2, 0x60F5, 0x60F7, 0x60F8, 0x60FB, 0x60FC, 0x60FD, - 0x60FE, 0x60FF, 0x6102, 0x6103, 0x6104, 0x6105, 0x6107, 0x610A, 0x610B, 0x610C, 0x6110, 0x6111, 0x6112, 0x6113, 0x6114, 0x6116, - 0x6117, 0x6118, 0x6119, 0x611B, 0x611C, 0x611D, 0x611E, 0x6121, 0x6122, 0x6125, 0x6128, 0x6129, 0x612A, 0x612C, 0x612D, 0x612E, - 0x612F, 0x6130, 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136, 0x6137, 0x6138, 0x6139, 0x613A, 0x613B, 0x613C, 0x613D, 0x613E, - 0x6140, 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146, - // GB 0x9140..0x917E - 0x6147, 0x6149, 0x614B, 0x614D, 0x614F, 0x6150, 0x6152, 0x6153, 0x6154, 0x6156, 0x6157, 0x6158, 0x6159, 0x615A, 0x615B, 0x615C, - 0x615E, 0x615F, 0x6160, 0x6161, 0x6163, 0x6164, 0x6165, 0x6166, 0x6169, 0x616A, 0x616B, 0x616C, 0x616D, 0x616E, 0x616F, 0x6171, - 0x6172, 0x6173, 0x6174, 0x6176, 0x6178, 0x6179, 0x617A, 0x617B, 0x617C, 0x617D, 0x617E, 0x617F, 0x6180, 0x6181, 0x6182, 0x6183, - 0x6184, 0x6185, 0x6186, 0x6187, 0x6188, 0x6189, 0x618A, 0x618C, 0x618D, 0x618F, 0x6190, 0x6191, 0x6192, 0x6193, 0x6195, - // GB 0x9180..0x91FE - 0x6196, 0x6197, 0x6198, 0x6199, 0x619A, 0x619B, 0x619C, 0x619E, - 0x619F, 0x61A0, 0x61A1, 0x61A2, 0x61A3, 0x61A4, 0x61A5, 0x61A6, 0x61AA, 0x61AB, 0x61AD, 0x61AE, 0x61AF, 0x61B0, 0x61B1, 0x61B2, - 0x61B3, 0x61B4, 0x61B5, 0x61B6, 0x61B8, 0x61B9, 0x61BA, 0x61BB, 0x61BC, 0x61BD, 0x61BF, 0x61C0, 0x61C1, 0x61C3, 0x61C4, 0x61C5, - 0x61C6, 0x61C7, 0x61C9, 0x61CC, 0x61CD, 0x61CE, 0x61CF, 0x61D0, 0x61D3, 0x61D5, 0x61D6, 0x61D7, 0x61D8, 0x61D9, 0x61DA, 0x61DB, - 0x61DC, 0x61DD, 0x61DE, 0x61DF, 0x61E0, 0x61E1, 0x61E2, 0x61E3, 0x61E4, 0x61E5, 0x61E7, 0x61E8, 0x61E9, 0x61EA, 0x61EB, 0x61EC, - 0x61ED, 0x61EE, 0x61EF, 0x61F0, 0x61F1, 0x61F2, 0x61F3, 0x61F4, 0x61F6, 0x61F7, 0x61F8, 0x61F9, 0x61FA, 0x61FB, 0x61FC, 0x61FD, - 0x61FE, 0x6200, 0x6201, 0x6202, 0x6203, 0x6204, 0x6205, 0x6207, 0x6209, 0x6213, 0x6214, 0x6219, 0x621C, 0x621D, 0x621E, 0x6220, - 0x6223, 0x6226, 0x6227, 0x6228, 0x6229, 0x622B, 0x622D, 0x622F, 0x6230, 0x6231, 0x6232, 0x6235, 0x6236, 0x6238, 0x6239, 0x623A, - 0x623B, 0x623C, 0x6242, 0x6244, 0x6245, 0x6246, 0x624A, - // GB 0x9240..0x927E - 0x624F, 0x6250, 0x6255, 0x6256, 0x6257, 0x6259, 0x625A, 0x625C, 0x625D, 0x625E, 0x625F, 0x6260, 0x6261, 0x6262, 0x6264, 0x6265, - 0x6268, 0x6271, 0x6272, 0x6274, 0x6275, 0x6277, 0x6278, 0x627A, 0x627B, 0x627D, 0x6281, 0x6282, 0x6283, 0x6285, 0x6286, 0x6287, - 0x6288, 0x628B, 0x628C, 0x628D, 0x628E, 0x628F, 0x6290, 0x6294, 0x6299, 0x629C, 0x629D, 0x629E, 0x62A3, 0x62A6, 0x62A7, 0x62A9, - 0x62AA, 0x62AD, 0x62AE, 0x62AF, 0x62B0, 0x62B2, 0x62B3, 0x62B4, 0x62B6, 0x62B7, 0x62B8, 0x62BA, 0x62BE, 0x62C0, 0x62C1, - // GB 0x9280..0x92FE - 0x62C3, 0x62CB, 0x62CF, 0x62D1, 0x62D5, 0x62DD, 0x62DE, 0x62E0, - 0x62E1, 0x62E4, 0x62EA, 0x62EB, 0x62F0, 0x62F2, 0x62F5, 0x62F8, 0x62F9, 0x62FA, 0x62FB, 0x6300, 0x6303, 0x6304, 0x6305, 0x6306, - 0x630A, 0x630B, 0x630C, 0x630D, 0x630F, 0x6310, 0x6312, 0x6313, 0x6314, 0x6315, 0x6317, 0x6318, 0x6319, 0x631C, 0x6326, 0x6327, - 0x6329, 0x632C, 0x632D, 0x632E, 0x6330, 0x6331, 0x6333, 0x6334, 0x6335, 0x6336, 0x6337, 0x6338, 0x633B, 0x633C, 0x633E, 0x633F, - 0x6340, 0x6341, 0x6344, 0x6347, 0x6348, 0x634A, 0x6351, 0x6352, 0x6353, 0x6354, 0x6356, 0x6357, 0x6358, 0x6359, 0x635A, 0x635B, - 0x635C, 0x635D, 0x6360, 0x6364, 0x6365, 0x6366, 0x6368, 0x636A, 0x636B, 0x636C, 0x636F, 0x6370, 0x6372, 0x6373, 0x6374, 0x6375, - 0x6378, 0x6379, 0x637C, 0x637D, 0x637E, 0x637F, 0x6381, 0x6383, 0x6384, 0x6385, 0x6386, 0x638B, 0x638D, 0x6391, 0x6393, 0x6394, - 0x6395, 0x6397, 0x6399, 0x639A, 0x639B, 0x639C, 0x639D, 0x639E, 0x639F, 0x63A1, 0x63A4, 0x63A6, 0x63AB, 0x63AF, 0x63B1, 0x63B2, - 0x63B5, 0x63B6, 0x63B9, 0x63BB, 0x63BD, 0x63BF, 0x63C0, - // GB 0x9340..0x937E - 0x63C1, 0x63C2, 0x63C3, 0x63C5, 0x63C7, 0x63C8, 0x63CA, 0x63CB, 0x63CC, 0x63D1, 0x63D3, 0x63D4, 0x63D5, 0x63D7, 0x63D8, 0x63D9, - 0x63DA, 0x63DB, 0x63DC, 0x63DD, 0x63DF, 0x63E2, 0x63E4, 0x63E5, 0x63E6, 0x63E7, 0x63E8, 0x63EB, 0x63EC, 0x63EE, 0x63EF, 0x63F0, - 0x63F1, 0x63F3, 0x63F5, 0x63F7, 0x63F9, 0x63FA, 0x63FB, 0x63FC, 0x63FE, 0x6403, 0x6404, 0x6406, 0x6407, 0x6408, 0x6409, 0x640A, - 0x640D, 0x640E, 0x6411, 0x6412, 0x6415, 0x6416, 0x6417, 0x6418, 0x6419, 0x641A, 0x641D, 0x641F, 0x6422, 0x6423, 0x6424, - // GB 0x9380..0x93FE - 0x6425, 0x6427, 0x6428, 0x6429, 0x642B, 0x642E, 0x642F, 0x6430, - 0x6431, 0x6432, 0x6433, 0x6435, 0x6436, 0x6437, 0x6438, 0x6439, 0x643B, 0x643C, 0x643E, 0x6440, 0x6442, 0x6443, 0x6449, 0x644B, - 0x644C, 0x644D, 0x644E, 0x644F, 0x6450, 0x6451, 0x6453, 0x6455, 0x6456, 0x6457, 0x6459, 0x645A, 0x645B, 0x645C, 0x645D, 0x645F, - 0x6460, 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, 0x6466, 0x6468, 0x646A, 0x646B, 0x646C, 0x646E, 0x646F, 0x6470, 0x6471, 0x6472, - 0x6473, 0x6474, 0x6475, 0x6476, 0x6477, 0x647B, 0x647C, 0x647D, 0x647E, 0x647F, 0x6480, 0x6481, 0x6483, 0x6486, 0x6488, 0x6489, - 0x648A, 0x648B, 0x648C, 0x648D, 0x648E, 0x648F, 0x6490, 0x6493, 0x6494, 0x6497, 0x6498, 0x649A, 0x649B, 0x649C, 0x649D, 0x649F, - 0x64A0, 0x64A1, 0x64A2, 0x64A3, 0x64A5, 0x64A6, 0x64A7, 0x64A8, 0x64AA, 0x64AB, 0x64AF, 0x64B1, 0x64B2, 0x64B3, 0x64B4, 0x64B6, - 0x64B9, 0x64BB, 0x64BD, 0x64BE, 0x64BF, 0x64C1, 0x64C3, 0x64C4, 0x64C6, 0x64C7, 0x64C8, 0x64C9, 0x64CA, 0x64CB, 0x64CC, 0x64CF, - 0x64D1, 0x64D3, 0x64D4, 0x64D5, 0x64D6, 0x64D9, 0x64DA, - // GB 0x9440..0x947E - 0x64DB, 0x64DC, 0x64DD, 0x64DF, 0x64E0, 0x64E1, 0x64E3, 0x64E5, 0x64E7, 0x64E8, 0x64E9, 0x64EA, 0x64EB, 0x64EC, 0x64ED, 0x64EE, - 0x64EF, 0x64F0, 0x64F1, 0x64F2, 0x64F3, 0x64F4, 0x64F5, 0x64F6, 0x64F7, 0x64F8, 0x64F9, 0x64FA, 0x64FB, 0x64FC, 0x64FD, 0x64FE, - 0x64FF, 0x6501, 0x6502, 0x6503, 0x6504, 0x6505, 0x6506, 0x6507, 0x6508, 0x650A, 0x650B, 0x650C, 0x650D, 0x650E, 0x650F, 0x6510, - 0x6511, 0x6513, 0x6514, 0x6515, 0x6516, 0x6517, 0x6519, 0x651A, 0x651B, 0x651C, 0x651D, 0x651E, 0x651F, 0x6520, 0x6521, - // GB 0x9480..0x94FE - 0x6522, 0x6523, 0x6524, 0x6526, 0x6527, 0x6528, 0x6529, 0x652A, - 0x652C, 0x652D, 0x6530, 0x6531, 0x6532, 0x6533, 0x6537, 0x653A, 0x653C, 0x653D, 0x6540, 0x6541, 0x6542, 0x6543, 0x6544, 0x6546, - 0x6547, 0x654A, 0x654B, 0x654D, 0x654E, 0x6550, 0x6552, 0x6553, 0x6554, 0x6557, 0x6558, 0x655A, 0x655C, 0x655F, 0x6560, 0x6561, - 0x6564, 0x6565, 0x6567, 0x6568, 0x6569, 0x656A, 0x656D, 0x656E, 0x656F, 0x6571, 0x6573, 0x6575, 0x6576, 0x6578, 0x6579, 0x657A, - 0x657B, 0x657C, 0x657D, 0x657E, 0x657F, 0x6580, 0x6581, 0x6582, 0x6583, 0x6584, 0x6585, 0x6586, 0x6588, 0x6589, 0x658A, 0x658D, - 0x658E, 0x658F, 0x6592, 0x6594, 0x6595, 0x6596, 0x6598, 0x659A, 0x659D, 0x659E, 0x65A0, 0x65A2, 0x65A3, 0x65A6, 0x65A8, 0x65AA, - 0x65AC, 0x65AE, 0x65B1, 0x65B2, 0x65B3, 0x65B4, 0x65B5, 0x65B6, 0x65B7, 0x65B8, 0x65BA, 0x65BB, 0x65BE, 0x65BF, 0x65C0, 0x65C2, - 0x65C7, 0x65C8, 0x65C9, 0x65CA, 0x65CD, 0x65D0, 0x65D1, 0x65D3, 0x65D4, 0x65D5, 0x65D8, 0x65D9, 0x65DA, 0x65DB, 0x65DC, 0x65DD, - 0x65DE, 0x65DF, 0x65E1, 0x65E3, 0x65E4, 0x65EA, 0x65EB, - // GB 0x9540..0x957E - 0x65F2, 0x65F3, 0x65F4, 0x65F5, 0x65F8, 0x65F9, 0x65FB, 0x65FC, 0x65FD, 0x65FE, 0x65FF, 0x6601, 0x6604, 0x6605, 0x6607, 0x6608, - 0x6609, 0x660B, 0x660D, 0x6610, 0x6611, 0x6612, 0x6616, 0x6617, 0x6618, 0x661A, 0x661B, 0x661C, 0x661E, 0x6621, 0x6622, 0x6623, - 0x6624, 0x6626, 0x6629, 0x662A, 0x662B, 0x662C, 0x662E, 0x6630, 0x6632, 0x6633, 0x6637, 0x6638, 0x6639, 0x663A, 0x663B, 0x663D, - 0x663F, 0x6640, 0x6642, 0x6644, 0x6645, 0x6646, 0x6647, 0x6648, 0x6649, 0x664A, 0x664D, 0x664E, 0x6650, 0x6651, 0x6658, - // GB 0x9580..0x95FE - 0x6659, 0x665B, 0x665C, 0x665D, 0x665E, 0x6660, 0x6662, 0x6663, - 0x6665, 0x6667, 0x6669, 0x666A, 0x666B, 0x666C, 0x666D, 0x6671, 0x6672, 0x6673, 0x6675, 0x6678, 0x6679, 0x667B, 0x667C, 0x667D, - 0x667F, 0x6680, 0x6681, 0x6683, 0x6685, 0x6686, 0x6688, 0x6689, 0x668A, 0x668B, 0x668D, 0x668E, 0x668F, 0x6690, 0x6692, 0x6693, - 0x6694, 0x6695, 0x6698, 0x6699, 0x669A, 0x669B, 0x669C, 0x669E, 0x669F, 0x66A0, 0x66A1, 0x66A2, 0x66A3, 0x66A4, 0x66A5, 0x66A6, - 0x66A9, 0x66AA, 0x66AB, 0x66AC, 0x66AD, 0x66AF, 0x66B0, 0x66B1, 0x66B2, 0x66B3, 0x66B5, 0x66B6, 0x66B7, 0x66B8, 0x66BA, 0x66BB, - 0x66BC, 0x66BD, 0x66BF, 0x66C0, 0x66C1, 0x66C2, 0x66C3, 0x66C4, 0x66C5, 0x66C6, 0x66C7, 0x66C8, 0x66C9, 0x66CA, 0x66CB, 0x66CC, - 0x66CD, 0x66CE, 0x66CF, 0x66D0, 0x66D1, 0x66D2, 0x66D3, 0x66D4, 0x66D5, 0x66D6, 0x66D7, 0x66D8, 0x66DA, 0x66DE, 0x66DF, 0x66E0, - 0x66E1, 0x66E2, 0x66E3, 0x66E4, 0x66E5, 0x66E7, 0x66E8, 0x66EA, 0x66EB, 0x66EC, 0x66ED, 0x66EE, 0x66EF, 0x66F1, 0x66F5, 0x66F6, - 0x66F8, 0x66FA, 0x66FB, 0x66FD, 0x6701, 0x6702, 0x6703, - // GB 0x9640..0x967E - 0x6704, 0x6705, 0x6706, 0x6707, 0x670C, 0x670E, 0x670F, 0x6711, 0x6712, 0x6713, 0x6716, 0x6718, 0x6719, 0x671A, 0x671C, 0x671E, - 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6727, 0x6729, 0x672E, 0x6730, 0x6732, 0x6733, 0x6736, 0x6737, 0x6738, 0x6739, - 0x673B, 0x673C, 0x673E, 0x673F, 0x6741, 0x6744, 0x6745, 0x6747, 0x674A, 0x674B, 0x674D, 0x6752, 0x6754, 0x6755, 0x6757, 0x6758, - 0x6759, 0x675A, 0x675B, 0x675D, 0x6762, 0x6763, 0x6764, 0x6766, 0x6767, 0x676B, 0x676C, 0x676E, 0x6771, 0x6774, 0x6776, - // GB 0x9680..0x96FE - 0x6778, 0x6779, 0x677A, 0x677B, 0x677D, 0x6780, 0x6782, 0x6783, - 0x6785, 0x6786, 0x6788, 0x678A, 0x678C, 0x678D, 0x678E, 0x678F, 0x6791, 0x6792, 0x6793, 0x6794, 0x6796, 0x6799, 0x679B, 0x679F, - 0x67A0, 0x67A1, 0x67A4, 0x67A6, 0x67A9, 0x67AC, 0x67AE, 0x67B1, 0x67B2, 0x67B4, 0x67B9, 0x67BA, 0x67BB, 0x67BC, 0x67BD, 0x67BE, - 0x67BF, 0x67C0, 0x67C2, 0x67C5, 0x67C6, 0x67C7, 0x67C8, 0x67C9, 0x67CA, 0x67CB, 0x67CC, 0x67CD, 0x67CE, 0x67D5, 0x67D6, 0x67D7, - 0x67DB, 0x67DF, 0x67E1, 0x67E3, 0x67E4, 0x67E6, 0x67E7, 0x67E8, 0x67EA, 0x67EB, 0x67ED, 0x67EE, 0x67F2, 0x67F5, 0x67F6, 0x67F7, - 0x67F8, 0x67F9, 0x67FA, 0x67FB, 0x67FC, 0x67FE, 0x6801, 0x6802, 0x6803, 0x6804, 0x6806, 0x680D, 0x6810, 0x6812, 0x6814, 0x6815, - 0x6818, 0x6819, 0x681A, 0x681B, 0x681C, 0x681E, 0x681F, 0x6820, 0x6822, 0x6823, 0x6824, 0x6825, 0x6826, 0x6827, 0x6828, 0x682B, - 0x682C, 0x682D, 0x682E, 0x682F, 0x6830, 0x6831, 0x6834, 0x6835, 0x6836, 0x683A, 0x683B, 0x683F, 0x6847, 0x684B, 0x684D, 0x684F, - 0x6852, 0x6856, 0x6857, 0x6858, 0x6859, 0x685A, 0x685B, - // GB 0x9740..0x977E - 0x685C, 0x685D, 0x685E, 0x685F, 0x686A, 0x686C, 0x686D, 0x686E, 0x686F, 0x6870, 0x6871, 0x6872, 0x6873, 0x6875, 0x6878, 0x6879, - 0x687A, 0x687B, 0x687C, 0x687D, 0x687E, 0x687F, 0x6880, 0x6882, 0x6884, 0x6887, 0x6888, 0x6889, 0x688A, 0x688B, 0x688C, 0x688D, - 0x688E, 0x6890, 0x6891, 0x6892, 0x6894, 0x6895, 0x6896, 0x6898, 0x6899, 0x689A, 0x689B, 0x689C, 0x689D, 0x689E, 0x689F, 0x68A0, - 0x68A1, 0x68A3, 0x68A4, 0x68A5, 0x68A9, 0x68AA, 0x68AB, 0x68AC, 0x68AE, 0x68B1, 0x68B2, 0x68B4, 0x68B6, 0x68B7, 0x68B8, - // GB 0x9780..0x97FE - 0x68B9, 0x68BA, 0x68BB, 0x68BC, 0x68BD, 0x68BE, 0x68BF, 0x68C1, - 0x68C3, 0x68C4, 0x68C5, 0x68C6, 0x68C7, 0x68C8, 0x68CA, 0x68CC, 0x68CE, 0x68CF, 0x68D0, 0x68D1, 0x68D3, 0x68D4, 0x68D6, 0x68D7, - 0x68D9, 0x68DB, 0x68DC, 0x68DD, 0x68DE, 0x68DF, 0x68E1, 0x68E2, 0x68E4, 0x68E5, 0x68E6, 0x68E7, 0x68E8, 0x68E9, 0x68EA, 0x68EB, - 0x68EC, 0x68ED, 0x68EF, 0x68F2, 0x68F3, 0x68F4, 0x68F6, 0x68F7, 0x68F8, 0x68FB, 0x68FD, 0x68FE, 0x68FF, 0x6900, 0x6902, 0x6903, - 0x6904, 0x6906, 0x6907, 0x6908, 0x6909, 0x690A, 0x690C, 0x690F, 0x6911, 0x6913, 0x6914, 0x6915, 0x6916, 0x6917, 0x6918, 0x6919, - 0x691A, 0x691B, 0x691C, 0x691D, 0x691E, 0x6921, 0x6922, 0x6923, 0x6925, 0x6926, 0x6927, 0x6928, 0x6929, 0x692A, 0x692B, 0x692C, - 0x692E, 0x692F, 0x6931, 0x6932, 0x6933, 0x6935, 0x6936, 0x6937, 0x6938, 0x693A, 0x693B, 0x693C, 0x693E, 0x6940, 0x6941, 0x6943, - 0x6944, 0x6945, 0x6946, 0x6947, 0x6948, 0x6949, 0x694A, 0x694B, 0x694C, 0x694D, 0x694E, 0x694F, 0x6950, 0x6951, 0x6952, 0x6953, - 0x6955, 0x6956, 0x6958, 0x6959, 0x695B, 0x695C, 0x695F, - // GB 0x9840..0x987E - 0x6961, 0x6962, 0x6964, 0x6965, 0x6967, 0x6968, 0x6969, 0x696A, 0x696C, 0x696D, 0x696F, 0x6970, 0x6972, 0x6973, 0x6974, 0x6975, - 0x6976, 0x697A, 0x697B, 0x697D, 0x697E, 0x697F, 0x6981, 0x6983, 0x6985, 0x698A, 0x698B, 0x698C, 0x698E, 0x698F, 0x6990, 0x6991, - 0x6992, 0x6993, 0x6996, 0x6997, 0x6999, 0x699A, 0x699D, 0x699E, 0x699F, 0x69A0, 0x69A1, 0x69A2, 0x69A3, 0x69A4, 0x69A5, 0x69A6, - 0x69A9, 0x69AA, 0x69AC, 0x69AE, 0x69AF, 0x69B0, 0x69B2, 0x69B3, 0x69B5, 0x69B6, 0x69B8, 0x69B9, 0x69BA, 0x69BC, 0x69BD, - // GB 0x9880..0x98FE - 0x69BE, 0x69BF, 0x69C0, 0x69C2, 0x69C3, 0x69C4, 0x69C5, 0x69C6, - 0x69C7, 0x69C8, 0x69C9, 0x69CB, 0x69CD, 0x69CF, 0x69D1, 0x69D2, 0x69D3, 0x69D5, 0x69D6, 0x69D7, 0x69D8, 0x69D9, 0x69DA, 0x69DC, - 0x69DD, 0x69DE, 0x69E1, 0x69E2, 0x69E3, 0x69E4, 0x69E5, 0x69E6, 0x69E7, 0x69E8, 0x69E9, 0x69EA, 0x69EB, 0x69EC, 0x69EE, 0x69EF, - 0x69F0, 0x69F1, 0x69F3, 0x69F4, 0x69F5, 0x69F6, 0x69F7, 0x69F8, 0x69F9, 0x69FA, 0x69FB, 0x69FC, 0x69FE, 0x6A00, 0x6A01, 0x6A02, - 0x6A03, 0x6A04, 0x6A05, 0x6A06, 0x6A07, 0x6A08, 0x6A09, 0x6A0B, 0x6A0C, 0x6A0D, 0x6A0E, 0x6A0F, 0x6A10, 0x6A11, 0x6A12, 0x6A13, - 0x6A14, 0x6A15, 0x6A16, 0x6A19, 0x6A1A, 0x6A1B, 0x6A1C, 0x6A1D, 0x6A1E, 0x6A20, 0x6A22, 0x6A23, 0x6A24, 0x6A25, 0x6A26, 0x6A27, - 0x6A29, 0x6A2B, 0x6A2C, 0x6A2D, 0x6A2E, 0x6A30, 0x6A32, 0x6A33, 0x6A34, 0x6A36, 0x6A37, 0x6A38, 0x6A39, 0x6A3A, 0x6A3B, 0x6A3C, - 0x6A3F, 0x6A40, 0x6A41, 0x6A42, 0x6A43, 0x6A45, 0x6A46, 0x6A48, 0x6A49, 0x6A4A, 0x6A4B, 0x6A4C, 0x6A4D, 0x6A4E, 0x6A4F, 0x6A51, - 0x6A52, 0x6A53, 0x6A54, 0x6A55, 0x6A56, 0x6A57, 0x6A5A, - // GB 0x9940..0x997E - 0x6A5C, 0x6A5D, 0x6A5E, 0x6A5F, 0x6A60, 0x6A62, 0x6A63, 0x6A64, 0x6A66, 0x6A67, 0x6A68, 0x6A69, 0x6A6A, 0x6A6B, 0x6A6C, 0x6A6D, - 0x6A6E, 0x6A6F, 0x6A70, 0x6A72, 0x6A73, 0x6A74, 0x6A75, 0x6A76, 0x6A77, 0x6A78, 0x6A7A, 0x6A7B, 0x6A7D, 0x6A7E, 0x6A7F, 0x6A81, - 0x6A82, 0x6A83, 0x6A85, 0x6A86, 0x6A87, 0x6A88, 0x6A89, 0x6A8A, 0x6A8B, 0x6A8C, 0x6A8D, 0x6A8F, 0x6A92, 0x6A93, 0x6A94, 0x6A95, - 0x6A96, 0x6A98, 0x6A99, 0x6A9A, 0x6A9B, 0x6A9C, 0x6A9D, 0x6A9E, 0x6A9F, 0x6AA1, 0x6AA2, 0x6AA3, 0x6AA4, 0x6AA5, 0x6AA6, - // GB 0x9980..0x99FE - 0x6AA7, 0x6AA8, 0x6AAA, 0x6AAD, 0x6AAE, 0x6AAF, 0x6AB0, 0x6AB1, - 0x6AB2, 0x6AB3, 0x6AB4, 0x6AB5, 0x6AB6, 0x6AB7, 0x6AB8, 0x6AB9, 0x6ABA, 0x6ABB, 0x6ABC, 0x6ABD, 0x6ABE, 0x6ABF, 0x6AC0, 0x6AC1, - 0x6AC2, 0x6AC3, 0x6AC4, 0x6AC5, 0x6AC6, 0x6AC7, 0x6AC8, 0x6AC9, 0x6ACA, 0x6ACB, 0x6ACC, 0x6ACD, 0x6ACE, 0x6ACF, 0x6AD0, 0x6AD1, - 0x6AD2, 0x6AD3, 0x6AD4, 0x6AD5, 0x6AD6, 0x6AD7, 0x6AD8, 0x6AD9, 0x6ADA, 0x6ADB, 0x6ADC, 0x6ADD, 0x6ADE, 0x6ADF, 0x6AE0, 0x6AE1, - 0x6AE2, 0x6AE3, 0x6AE4, 0x6AE5, 0x6AE6, 0x6AE7, 0x6AE8, 0x6AE9, 0x6AEA, 0x6AEB, 0x6AEC, 0x6AED, 0x6AEE, 0x6AEF, 0x6AF0, 0x6AF1, - 0x6AF2, 0x6AF3, 0x6AF4, 0x6AF5, 0x6AF6, 0x6AF7, 0x6AF8, 0x6AF9, 0x6AFA, 0x6AFB, 0x6AFC, 0x6AFD, 0x6AFE, 0x6AFF, 0x6B00, 0x6B01, - 0x6B02, 0x6B03, 0x6B04, 0x6B05, 0x6B06, 0x6B07, 0x6B08, 0x6B09, 0x6B0A, 0x6B0B, 0x6B0C, 0x6B0D, 0x6B0E, 0x6B0F, 0x6B10, 0x6B11, - 0x6B12, 0x6B13, 0x6B14, 0x6B15, 0x6B16, 0x6B17, 0x6B18, 0x6B19, 0x6B1A, 0x6B1B, 0x6B1C, 0x6B1D, 0x6B1E, 0x6B1F, 0x6B25, 0x6B26, - 0x6B28, 0x6B29, 0x6B2A, 0x6B2B, 0x6B2C, 0x6B2D, 0x6B2E, - // GB 0x9A40..0x9A7E - 0x6B2F, 0x6B30, 0x6B31, 0x6B33, 0x6B34, 0x6B35, 0x6B36, 0x6B38, 0x6B3B, 0x6B3C, 0x6B3D, 0x6B3F, 0x6B40, 0x6B41, 0x6B42, 0x6B44, - 0x6B45, 0x6B48, 0x6B4A, 0x6B4B, 0x6B4D, 0x6B4E, 0x6B4F, 0x6B50, 0x6B51, 0x6B52, 0x6B53, 0x6B54, 0x6B55, 0x6B56, 0x6B57, 0x6B58, - 0x6B5A, 0x6B5B, 0x6B5C, 0x6B5D, 0x6B5E, 0x6B5F, 0x6B60, 0x6B61, 0x6B68, 0x6B69, 0x6B6B, 0x6B6C, 0x6B6D, 0x6B6E, 0x6B6F, 0x6B70, - 0x6B71, 0x6B72, 0x6B73, 0x6B74, 0x6B75, 0x6B76, 0x6B77, 0x6B78, 0x6B7A, 0x6B7D, 0x6B7E, 0x6B7F, 0x6B80, 0x6B85, 0x6B88, - // GB 0x9A80..0x9AFE - 0x6B8C, 0x6B8E, 0x6B8F, 0x6B90, 0x6B91, 0x6B94, 0x6B95, 0x6B97, - 0x6B98, 0x6B99, 0x6B9C, 0x6B9D, 0x6B9E, 0x6B9F, 0x6BA0, 0x6BA2, 0x6BA3, 0x6BA4, 0x6BA5, 0x6BA6, 0x6BA7, 0x6BA8, 0x6BA9, 0x6BAB, - 0x6BAC, 0x6BAD, 0x6BAE, 0x6BAF, 0x6BB0, 0x6BB1, 0x6BB2, 0x6BB6, 0x6BB8, 0x6BB9, 0x6BBA, 0x6BBB, 0x6BBC, 0x6BBD, 0x6BBE, 0x6BC0, - 0x6BC3, 0x6BC4, 0x6BC6, 0x6BC7, 0x6BC8, 0x6BC9, 0x6BCA, 0x6BCC, 0x6BCE, 0x6BD0, 0x6BD1, 0x6BD8, 0x6BDA, 0x6BDC, 0x6BDD, 0x6BDE, - 0x6BDF, 0x6BE0, 0x6BE2, 0x6BE3, 0x6BE4, 0x6BE5, 0x6BE6, 0x6BE7, 0x6BE8, 0x6BE9, 0x6BEC, 0x6BED, 0x6BEE, 0x6BF0, 0x6BF1, 0x6BF2, - 0x6BF4, 0x6BF6, 0x6BF7, 0x6BF8, 0x6BFA, 0x6BFB, 0x6BFC, 0x6BFE, 0x6BFF, 0x6C00, 0x6C01, 0x6C02, 0x6C03, 0x6C04, 0x6C08, 0x6C09, - 0x6C0A, 0x6C0B, 0x6C0C, 0x6C0E, 0x6C12, 0x6C17, 0x6C1C, 0x6C1D, 0x6C1E, 0x6C20, 0x6C23, 0x6C25, 0x6C2B, 0x6C2C, 0x6C2D, 0x6C31, - 0x6C33, 0x6C36, 0x6C37, 0x6C39, 0x6C3A, 0x6C3B, 0x6C3C, 0x6C3E, 0x6C3F, 0x6C43, 0x6C44, 0x6C45, 0x6C48, 0x6C4B, 0x6C4C, 0x6C4D, - 0x6C4E, 0x6C4F, 0x6C51, 0x6C52, 0x6C53, 0x6C56, 0x6C58, - // GB 0x9B40..0x9B7E - 0x6C59, 0x6C5A, 0x6C62, 0x6C63, 0x6C65, 0x6C66, 0x6C67, 0x6C6B, 0x6C6C, 0x6C6D, 0x6C6E, 0x6C6F, 0x6C71, 0x6C73, 0x6C75, 0x6C77, - 0x6C78, 0x6C7A, 0x6C7B, 0x6C7C, 0x6C7F, 0x6C80, 0x6C84, 0x6C87, 0x6C8A, 0x6C8B, 0x6C8D, 0x6C8E, 0x6C91, 0x6C92, 0x6C95, 0x6C96, - 0x6C97, 0x6C98, 0x6C9A, 0x6C9C, 0x6C9D, 0x6C9E, 0x6CA0, 0x6CA2, 0x6CA8, 0x6CAC, 0x6CAF, 0x6CB0, 0x6CB4, 0x6CB5, 0x6CB6, 0x6CB7, - 0x6CBA, 0x6CC0, 0x6CC1, 0x6CC2, 0x6CC3, 0x6CC6, 0x6CC7, 0x6CC8, 0x6CCB, 0x6CCD, 0x6CCE, 0x6CCF, 0x6CD1, 0x6CD2, 0x6CD8, - // GB 0x9B80..0x9BFE - 0x6CD9, 0x6CDA, 0x6CDC, 0x6CDD, 0x6CDF, 0x6CE4, 0x6CE6, 0x6CE7, - 0x6CE9, 0x6CEC, 0x6CED, 0x6CF2, 0x6CF4, 0x6CF9, 0x6CFF, 0x6D00, 0x6D02, 0x6D03, 0x6D05, 0x6D06, 0x6D08, 0x6D09, 0x6D0A, 0x6D0D, - 0x6D0F, 0x6D10, 0x6D11, 0x6D13, 0x6D14, 0x6D15, 0x6D16, 0x6D18, 0x6D1C, 0x6D1D, 0x6D1F, 0x6D20, 0x6D21, 0x6D22, 0x6D23, 0x6D24, - 0x6D26, 0x6D28, 0x6D29, 0x6D2C, 0x6D2D, 0x6D2F, 0x6D30, 0x6D34, 0x6D36, 0x6D37, 0x6D38, 0x6D3A, 0x6D3F, 0x6D40, 0x6D42, 0x6D44, - 0x6D49, 0x6D4C, 0x6D50, 0x6D55, 0x6D56, 0x6D57, 0x6D58, 0x6D5B, 0x6D5D, 0x6D5F, 0x6D61, 0x6D62, 0x6D64, 0x6D65, 0x6D67, 0x6D68, - 0x6D6B, 0x6D6C, 0x6D6D, 0x6D70, 0x6D71, 0x6D72, 0x6D73, 0x6D75, 0x6D76, 0x6D79, 0x6D7A, 0x6D7B, 0x6D7D, 0x6D7E, 0x6D7F, 0x6D80, - 0x6D81, 0x6D83, 0x6D84, 0x6D86, 0x6D87, 0x6D8A, 0x6D8B, 0x6D8D, 0x6D8F, 0x6D90, 0x6D92, 0x6D96, 0x6D97, 0x6D98, 0x6D99, 0x6D9A, - 0x6D9C, 0x6DA2, 0x6DA5, 0x6DAC, 0x6DAD, 0x6DB0, 0x6DB1, 0x6DB3, 0x6DB4, 0x6DB6, 0x6DB7, 0x6DB9, 0x6DBA, 0x6DBB, 0x6DBC, 0x6DBD, - 0x6DBE, 0x6DC1, 0x6DC2, 0x6DC3, 0x6DC8, 0x6DC9, 0x6DCA, - // GB 0x9C40..0x9C7E - 0x6DCD, 0x6DCE, 0x6DCF, 0x6DD0, 0x6DD2, 0x6DD3, 0x6DD4, 0x6DD5, 0x6DD7, 0x6DDA, 0x6DDB, 0x6DDC, 0x6DDF, 0x6DE2, 0x6DE3, 0x6DE5, - 0x6DE7, 0x6DE8, 0x6DE9, 0x6DEA, 0x6DED, 0x6DEF, 0x6DF0, 0x6DF2, 0x6DF4, 0x6DF5, 0x6DF6, 0x6DF8, 0x6DFA, 0x6DFD, 0x6DFE, 0x6DFF, - 0x6E00, 0x6E01, 0x6E02, 0x6E03, 0x6E04, 0x6E06, 0x6E07, 0x6E08, 0x6E09, 0x6E0B, 0x6E0F, 0x6E12, 0x6E13, 0x6E15, 0x6E18, 0x6E19, - 0x6E1B, 0x6E1C, 0x6E1E, 0x6E1F, 0x6E22, 0x6E26, 0x6E27, 0x6E28, 0x6E2A, 0x6E2C, 0x6E2E, 0x6E30, 0x6E31, 0x6E33, 0x6E35, - // GB 0x9C80..0x9CFE - 0x6E36, 0x6E37, 0x6E39, 0x6E3B, 0x6E3C, 0x6E3D, 0x6E3E, 0x6E3F, - 0x6E40, 0x6E41, 0x6E42, 0x6E45, 0x6E46, 0x6E47, 0x6E48, 0x6E49, 0x6E4A, 0x6E4B, 0x6E4C, 0x6E4F, 0x6E50, 0x6E51, 0x6E52, 0x6E55, - 0x6E57, 0x6E59, 0x6E5A, 0x6E5C, 0x6E5D, 0x6E5E, 0x6E60, 0x6E61, 0x6E62, 0x6E63, 0x6E64, 0x6E65, 0x6E66, 0x6E67, 0x6E68, 0x6E69, - 0x6E6A, 0x6E6C, 0x6E6D, 0x6E6F, 0x6E70, 0x6E71, 0x6E72, 0x6E73, 0x6E74, 0x6E75, 0x6E76, 0x6E77, 0x6E78, 0x6E79, 0x6E7A, 0x6E7B, - 0x6E7C, 0x6E7D, 0x6E80, 0x6E81, 0x6E82, 0x6E84, 0x6E87, 0x6E88, 0x6E8A, 0x6E8B, 0x6E8C, 0x6E8D, 0x6E8E, 0x6E91, 0x6E92, 0x6E93, - 0x6E94, 0x6E95, 0x6E96, 0x6E97, 0x6E99, 0x6E9A, 0x6E9B, 0x6E9D, 0x6E9E, 0x6EA0, 0x6EA1, 0x6EA3, 0x6EA4, 0x6EA6, 0x6EA8, 0x6EA9, - 0x6EAB, 0x6EAC, 0x6EAD, 0x6EAE, 0x6EB0, 0x6EB3, 0x6EB5, 0x6EB8, 0x6EB9, 0x6EBC, 0x6EBE, 0x6EBF, 0x6EC0, 0x6EC3, 0x6EC4, 0x6EC5, - 0x6EC6, 0x6EC8, 0x6EC9, 0x6ECA, 0x6ECC, 0x6ECD, 0x6ECE, 0x6ED0, 0x6ED2, 0x6ED6, 0x6ED8, 0x6ED9, 0x6EDB, 0x6EDC, 0x6EDD, 0x6EE3, - 0x6EE7, 0x6EEA, 0x6EEB, 0x6EEC, 0x6EED, 0x6EEE, 0x6EEF, - // GB 0x9D40..0x9D7E - 0x6EF0, 0x6EF1, 0x6EF2, 0x6EF3, 0x6EF5, 0x6EF6, 0x6EF7, 0x6EF8, 0x6EFA, 0x6EFB, 0x6EFC, 0x6EFD, 0x6EFE, 0x6EFF, 0x6F00, 0x6F01, - 0x6F03, 0x6F04, 0x6F05, 0x6F07, 0x6F08, 0x6F0A, 0x6F0B, 0x6F0C, 0x6F0D, 0x6F0E, 0x6F10, 0x6F11, 0x6F12, 0x6F16, 0x6F17, 0x6F18, - 0x6F19, 0x6F1A, 0x6F1B, 0x6F1C, 0x6F1D, 0x6F1E, 0x6F1F, 0x6F21, 0x6F22, 0x6F23, 0x6F25, 0x6F26, 0x6F27, 0x6F28, 0x6F2C, 0x6F2E, - 0x6F30, 0x6F32, 0x6F34, 0x6F35, 0x6F37, 0x6F38, 0x6F39, 0x6F3A, 0x6F3B, 0x6F3C, 0x6F3D, 0x6F3F, 0x6F40, 0x6F41, 0x6F42, - // GB 0x9D80..0x9DFE - 0x6F43, 0x6F44, 0x6F45, 0x6F48, 0x6F49, 0x6F4A, 0x6F4C, 0x6F4E, - 0x6F4F, 0x6F50, 0x6F51, 0x6F52, 0x6F53, 0x6F54, 0x6F55, 0x6F56, 0x6F57, 0x6F59, 0x6F5A, 0x6F5B, 0x6F5D, 0x6F5F, 0x6F60, 0x6F61, - 0x6F63, 0x6F64, 0x6F65, 0x6F67, 0x6F68, 0x6F69, 0x6F6A, 0x6F6B, 0x6F6C, 0x6F6F, 0x6F70, 0x6F71, 0x6F73, 0x6F75, 0x6F76, 0x6F77, - 0x6F79, 0x6F7B, 0x6F7D, 0x6F7E, 0x6F7F, 0x6F80, 0x6F81, 0x6F82, 0x6F83, 0x6F85, 0x6F86, 0x6F87, 0x6F8A, 0x6F8B, 0x6F8F, 0x6F90, - 0x6F91, 0x6F92, 0x6F93, 0x6F94, 0x6F95, 0x6F96, 0x6F97, 0x6F98, 0x6F99, 0x6F9A, 0x6F9B, 0x6F9D, 0x6F9E, 0x6F9F, 0x6FA0, 0x6FA2, - 0x6FA3, 0x6FA4, 0x6FA5, 0x6FA6, 0x6FA8, 0x6FA9, 0x6FAA, 0x6FAB, 0x6FAC, 0x6FAD, 0x6FAE, 0x6FAF, 0x6FB0, 0x6FB1, 0x6FB2, 0x6FB4, - 0x6FB5, 0x6FB7, 0x6FB8, 0x6FBA, 0x6FBB, 0x6FBC, 0x6FBD, 0x6FBE, 0x6FBF, 0x6FC1, 0x6FC3, 0x6FC4, 0x6FC5, 0x6FC6, 0x6FC7, 0x6FC8, - 0x6FCA, 0x6FCB, 0x6FCC, 0x6FCD, 0x6FCE, 0x6FCF, 0x6FD0, 0x6FD3, 0x6FD4, 0x6FD5, 0x6FD6, 0x6FD7, 0x6FD8, 0x6FD9, 0x6FDA, 0x6FDB, - 0x6FDC, 0x6FDD, 0x6FDF, 0x6FE2, 0x6FE3, 0x6FE4, 0x6FE5, - // GB 0x9E40..0x9E7E - 0x6FE6, 0x6FE7, 0x6FE8, 0x6FE9, 0x6FEA, 0x6FEB, 0x6FEC, 0x6FED, 0x6FF0, 0x6FF1, 0x6FF2, 0x6FF3, 0x6FF4, 0x6FF5, 0x6FF6, 0x6FF7, - 0x6FF8, 0x6FF9, 0x6FFA, 0x6FFB, 0x6FFC, 0x6FFD, 0x6FFE, 0x6FFF, 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007, - 0x7008, 0x7009, 0x700A, 0x700B, 0x700C, 0x700D, 0x700E, 0x700F, 0x7010, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017, 0x7018, - 0x7019, 0x701C, 0x701D, 0x701E, 0x701F, 0x7020, 0x7021, 0x7022, 0x7024, 0x7025, 0x7026, 0x7027, 0x7028, 0x7029, 0x702A, - // GB 0x9E80..0x9EFE - 0x702B, 0x702C, 0x702D, 0x702E, 0x702F, 0x7030, 0x7031, 0x7032, - 0x7033, 0x7034, 0x7036, 0x7037, 0x7038, 0x703A, 0x703B, 0x703C, 0x703D, 0x703E, 0x703F, 0x7040, 0x7041, 0x7042, 0x7043, 0x7044, - 0x7045, 0x7046, 0x7047, 0x7048, 0x7049, 0x704A, 0x704B, 0x704D, 0x704E, 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, - 0x7057, 0x7058, 0x7059, 0x705A, 0x705B, 0x705C, 0x705D, 0x705F, 0x7060, 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067, - 0x7068, 0x7069, 0x706A, 0x706E, 0x7071, 0x7072, 0x7073, 0x7074, 0x7077, 0x7079, 0x707A, 0x707B, 0x707D, 0x7081, 0x7082, 0x7083, - 0x7084, 0x7086, 0x7087, 0x7088, 0x708B, 0x708C, 0x708D, 0x708F, 0x7090, 0x7091, 0x7093, 0x7097, 0x7098, 0x709A, 0x709B, 0x709E, - 0x709F, 0x70A0, 0x70A1, 0x70A2, 0x70A3, 0x70A4, 0x70A5, 0x70A6, 0x70A7, 0x70A8, 0x70A9, 0x70AA, 0x70B0, 0x70B2, 0x70B4, 0x70B5, - 0x70B6, 0x70BA, 0x70BE, 0x70BF, 0x70C4, 0x70C5, 0x70C6, 0x70C7, 0x70C9, 0x70CB, 0x70CC, 0x70CD, 0x70CE, 0x70CF, 0x70D0, 0x70D1, - 0x70D2, 0x70D3, 0x70D4, 0x70D5, 0x70D6, 0x70D7, 0x70DA, - // GB 0x9F40..0x9F7E - 0x70DC, 0x70DD, 0x70DE, 0x70E0, 0x70E1, 0x70E2, 0x70E3, 0x70E5, 0x70EA, 0x70EE, 0x70F0, 0x70F1, 0x70F2, 0x70F3, 0x70F4, 0x70F5, - 0x70F6, 0x70F8, 0x70FA, 0x70FB, 0x70FC, 0x70FE, 0x70FF, 0x7100, 0x7101, 0x7102, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x7108, - 0x710B, 0x710C, 0x710D, 0x710E, 0x710F, 0x7111, 0x7112, 0x7114, 0x7117, 0x711B, 0x711C, 0x711D, 0x711E, 0x711F, 0x7120, 0x7121, - 0x7122, 0x7123, 0x7124, 0x7125, 0x7127, 0x7128, 0x7129, 0x712A, 0x712B, 0x712C, 0x712D, 0x712E, 0x7132, 0x7133, 0x7134, - // GB 0x9F80..0x9FFE - 0x7135, 0x7137, 0x7138, 0x7139, 0x713A, 0x713B, 0x713C, 0x713D, - 0x713E, 0x713F, 0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7146, 0x7147, 0x7148, 0x7149, 0x714B, 0x714D, 0x714F, 0x7150, 0x7151, - 0x7152, 0x7153, 0x7154, 0x7155, 0x7156, 0x7157, 0x7158, 0x7159, 0x715A, 0x715B, 0x715D, 0x715F, 0x7160, 0x7161, 0x7162, 0x7163, - 0x7165, 0x7169, 0x716A, 0x716B, 0x716C, 0x716D, 0x716F, 0x7170, 0x7171, 0x7174, 0x7175, 0x7176, 0x7177, 0x7179, 0x717B, 0x717C, - 0x717E, 0x717F, 0x7180, 0x7181, 0x7182, 0x7183, 0x7185, 0x7186, 0x7187, 0x7188, 0x7189, 0x718B, 0x718C, 0x718D, 0x718E, 0x7190, - 0x7191, 0x7192, 0x7193, 0x7195, 0x7196, 0x7197, 0x719A, 0x719B, 0x719C, 0x719D, 0x719E, 0x71A1, 0x71A2, 0x71A3, 0x71A4, 0x71A5, - 0x71A6, 0x71A7, 0x71A9, 0x71AA, 0x71AB, 0x71AD, 0x71AE, 0x71AF, 0x71B0, 0x71B1, 0x71B2, 0x71B4, 0x71B6, 0x71B7, 0x71B8, 0x71BA, - 0x71BB, 0x71BC, 0x71BD, 0x71BE, 0x71BF, 0x71C0, 0x71C1, 0x71C2, 0x71C4, 0x71C5, 0x71C6, 0x71C7, 0x71C8, 0x71C9, 0x71CA, 0x71CB, - 0x71CC, 0x71CD, 0x71CF, 0x71D0, 0x71D1, 0x71D2, 0x71D3, - // GB 0xA040..0xA07E - 0x71D6, 0x71D7, 0x71D8, 0x71D9, 0x71DA, 0x71DB, 0x71DC, 0x71DD, 0x71DE, 0x71DF, 0x71E1, 0x71E2, 0x71E3, 0x71E4, 0x71E6, 0x71E8, - 0x71E9, 0x71EA, 0x71EB, 0x71EC, 0x71ED, 0x71EF, 0x71F0, 0x71F1, 0x71F2, 0x71F3, 0x71F4, 0x71F5, 0x71F6, 0x71F7, 0x71F8, 0x71FA, - 0x71FB, 0x71FC, 0x71FD, 0x71FE, 0x71FF, 0x7200, 0x7201, 0x7202, 0x7203, 0x7204, 0x7205, 0x7207, 0x7208, 0x7209, 0x720A, 0x720B, - 0x720C, 0x720D, 0x720E, 0x720F, 0x7210, 0x7211, 0x7212, 0x7213, 0x7214, 0x7215, 0x7216, 0x7217, 0x7218, 0x7219, 0x721A, - // GB 0xA080..0xA0FE - 0x721B, 0x721C, 0x721E, 0x721F, 0x7220, 0x7221, 0x7222, 0x7223, - 0x7224, 0x7225, 0x7226, 0x7227, 0x7229, 0x722B, 0x722D, 0x722E, 0x722F, 0x7232, 0x7233, 0x7234, 0x723A, 0x723C, 0x723E, 0x7240, - 0x7241, 0x7242, 0x7243, 0x7244, 0x7245, 0x7246, 0x7249, 0x724A, 0x724B, 0x724E, 0x724F, 0x7250, 0x7251, 0x7253, 0x7254, 0x7255, - 0x7257, 0x7258, 0x725A, 0x725C, 0x725E, 0x7260, 0x7263, 0x7264, 0x7265, 0x7268, 0x726A, 0x726B, 0x726C, 0x726D, 0x7270, 0x7271, - 0x7273, 0x7274, 0x7276, 0x7277, 0x7278, 0x727B, 0x727C, 0x727D, 0x7282, 0x7283, 0x7285, 0x7286, 0x7287, 0x7288, 0x7289, 0x728C, - 0x728E, 0x7290, 0x7291, 0x7293, 0x7294, 0x7295, 0x7296, 0x7297, 0x7298, 0x7299, 0x729A, 0x729B, 0x729C, 0x729D, 0x729E, 0x72A0, - 0x72A1, 0x72A2, 0x72A3, 0x72A4, 0x72A5, 0x72A6, 0x72A7, 0x72A8, 0x72A9, 0x72AA, 0x72AB, 0x72AE, 0x72B1, 0x72B2, 0x72B3, 0x72B5, - 0x72BA, 0x72BB, 0x72BC, 0x72BD, 0x72BE, 0x72BF, 0x72C0, 0x72C5, 0x72C6, 0x72C7, 0x72C9, 0x72CA, 0x72CB, 0x72CC, 0x72CF, 0x72D1, - 0x72D3, 0x72D4, 0x72D5, 0x72D6, 0x72D8, 0x72DA, 0x72DB, - // Skip: GB 0xA140..0xA17E, 0xA180..0xA1A0 (UDA 3) - // GB 0xA2A1..0xA2FE - 0x3000, 0x3001, 0x3002, 0x00B7, 0x02C9, 0x02C7, 0x00A8, 0x3003, 0x3005, 0x2014, 0xFF5E, 0x2016, 0x2026, 0x2018, 0x2019, - 0x201C, 0x201D, 0x3014, 0x3015, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3016, 0x3017, 0x3010, 0x3011, - 0x00B1, 0x00D7, 0x00F7, 0x2236, 0x2227, 0x2228, 0x2211, 0x220F, 0x222A, 0x2229, 0x2208, 0x2237, 0x221A, 0x22A5, 0x2225, 0x2220, - 0x2312, 0x2299, 0x222B, 0x222E, 0x2261, 0x224C, 0x2248, 0x223D, 0x221D, 0x2260, 0x226E, 0x226F, 0x2264, 0x2265, 0x221E, 0x2235, - 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFF04, 0x00A4, 0xFFE0, 0xFFE1, 0x2030, 0x00A7, 0x2116, 0x2606, 0x2605, - 0x25CB, 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x203B, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, - // Skip: GB 0xA240..0xA27E, 0xA280..0xA2A0 (UDA 3) - // GB 0xA3A1..0xA3FE - 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, - 0x2177, 0x2178, 0x2179, 0xE766, 0xE767, 0xE768, 0xE769, 0xE76A, 0xE76B, 0x2488, 0x2489, 0x248A, 0x248B, 0x248C, 0x248D, 0x248E, - 0x248F, 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, 0x2498, 0x2499, 0x249A, 0x249B, 0x2474, 0x2475, 0x2476, - 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C, 0x247D, 0x247E, 0x247F, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, - 0x2487, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x20AC, 0xE76D, 0x3220, 0x3221, 0x3222, - 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0xE76E, 0xE76F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, - 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0xE770, 0xE771, - // Skip: GB 0xA340..0xA37E, 0xA380..0xA3A0 (UDA 3) - // GB 0xA4A1..0xA4FE - 0xFF01, 0xFF02, 0xFF03, 0xFFE5, 0xFF05, 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F, - 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F, - 0xFF20, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, - 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F, - 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, - 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFFE3, - // Skip: GB 0xA440..0xA47E, 0xA480..0xA4A0 (UDA 3) - // GB 0xA5A1..0xA5FE - 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, - 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, - 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, - 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, - 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, - 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, 0x3091, 0x3092, 0x3093, 0xE772, 0xE773, 0xE774, 0xE775, - 0xE776, 0xE777, 0xE778, 0xE779, 0xE77A, 0xE77B, 0xE77C, - // Skip: GB 0xA540..0xA57E, 0xA580..0xA5A0 (UDA 3) - // GB 0xA6A1..0xA6FE - 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, - 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, - 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, - 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF, - 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, - 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0xE77D, 0xE77E, 0xE77F, 0xE780, 0xE781, 0xE782, 0xE783, 0xE784, - // Skip: GB 0xA640..0xA67E, 0xA680..0xA6A0 (UDA 3) - // GB 0xA7A1..0xA7FE - 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, - 0x03A9, 0xE785, 0xE786, 0xE787, 0xE788, 0xE789, 0xE78A, 0xE78B, 0xE78C, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, - 0x03C9, 0xE78D, 0xE78E, 0xE78F, 0xE790, 0xE791, 0xE792, 0xE793, 0xFE35, 0xFE36, 0xFE39, 0xFE3A, 0xFE3F, 0xFE40, 0xFE3D, 0xFE3E, - 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xE794, 0xE795, 0xFE3B, 0xFE3C, 0xFE37, 0xFE38, 0xFE31, 0xE796, 0xFE33, 0xFE34, 0xE797, 0xE798, - 0xE799, 0xE79A, 0xE79B, 0xE79C, 0xE79D, 0xE79E, 0xE79F, - // Skip: GB 0xA740..0xA77E, 0xA780..0xA7A0 (UDA 3) - // GB 0xA8A1..0xA8FE - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, - 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, - 0x042E, 0x042F, 0xE7A0, 0xE7A1, 0xE7A2, 0xE7A3, 0xE7A4, 0xE7A5, 0xE7A6, 0xE7A7, 0xE7A8, 0xE7A9, 0xE7AA, 0xE7AB, 0xE7AC, 0xE7AD, - 0xE7AE, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, - 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, - 0x044E, 0x044F, 0xE7AF, 0xE7B0, 0xE7B1, 0xE7B2, 0xE7B3, 0xE7B4, 0xE7B5, 0xE7B6, 0xE7B7, 0xE7B8, 0xE7B9, 0xE7BA, 0xE7BB, - // GB 0xA840..0xA87E - 0x02CA, 0x02CB, 0x02D9, 0x2013, 0x2015, 0x2025, 0x2035, 0x2105, - 0x2109, 0x2196, 0x2197, 0x2198, 0x2199, 0x2215, 0x221F, 0x2223, 0x2252, 0x2266, 0x2267, 0x22BF, 0x2550, 0x2551, 0x2552, 0x2553, - 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, 0x255F, 0x2560, 0x2561, 0x2562, 0x2563, - 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x256D, 0x256E, 0x256F, 0x2570, 0x2571, 0x2572, 0x2573, - 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587, - // GB 0xA880..0xA8FE - 0x2588, 0x2589, 0x258A, 0x258B, 0x258C, 0x258D, 0x258E, 0x258F, 0x2593, 0x2594, 0x2595, 0x25BC, 0x25BD, 0x25E2, 0x25E3, 0x25E4, - 0x25E5, 0x2609, 0x2295, 0x3012, 0x301D, 0x301E, 0xE7BC, 0xE7BD, 0xE7BE, 0xE7BF, 0xE7C0, 0xE7C1, 0xE7C2, 0xE7C3, 0xE7C4, 0xE7C5, - 0xE7C6, 0x0101, 0x00E1, 0x01CE, 0x00E0, 0x0113, 0x00E9, 0x011B, 0x00E8, 0x012B, 0x00ED, 0x01D0, 0x00EC, 0x014D, 0x00F3, 0x01D2, - 0x00F2, 0x016B, 0x00FA, 0x01D4, 0x00F9, 0x01D6, 0x01D8, 0x01DA, 0x01DC, 0x00FC, 0x00EA, 0x0251, 0xE7C7, 0x0144, 0x0148, 0x01F9, - 0x0261, 0xE7C9, 0xE7CA, 0xE7CB, 0xE7CC, 0x3105, 0x3106, 0x3107, 0x3108, 0x3109, 0x310A, 0x310B, 0x310C, 0x310D, 0x310E, 0x310F, - 0x3110, 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, 0x3119, 0x311A, 0x311B, 0x311C, 0x311D, 0x311E, 0x311F, - 0x3120, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, 0x3129, 0xE7CD, 0xE7CE, 0xE7CF, 0xE7D0, 0xE7D1, 0xE7D2, - 0xE7D3, 0xE7D4, 0xE7D5, 0xE7D6, 0xE7D7, 0xE7D8, 0xE7D9, 0xE7DA, 0xE7DB, 0xE7DC, 0xE7DD, 0xE7DE, 0xE7DF, 0xE7E0, 0xE7E1, - // GB 0xA940..0xA97E - 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 0x3028, - 0x3029, 0x32A3, 0x338E, 0x338F, 0x339C, 0x339D, 0x339E, 0x33A1, 0x33C4, 0x33CE, 0x33D1, 0x33D2, 0x33D5, 0xFE30, 0xFFE2, 0xFFE4, - 0xE7E2, 0x2121, 0x3231, 0xE7E3, 0x2010, 0xE7E4, 0xE7E5, 0xE7E6, 0x30FC, 0x309B, 0x309C, 0x30FD, 0x30FE, 0x3006, 0x309D, 0x309E, - 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F, 0xFE50, 0xFE51, 0xFE52, 0xFE54, 0xFE55, 0xFE56, 0xFE57, 0xFE59, 0xFE5A, - 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F, 0xFE60, 0xFE61, - // GB 0xA980..0xA9FE - 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE68, 0xFE69, 0xFE6A, 0xFE6B, 0x303E, 0x2FF0, 0x2FF1, 0x2FF2, 0x2FF3, 0x2FF4, 0x2FF5, - 0x2FF6, 0x2FF7, 0x2FF8, 0x2FF9, 0x2FFA, 0x2FFB, 0x3007, 0xE7F4, 0xE7F5, 0xE7F6, 0xE7F7, 0xE7F8, 0xE7F9, 0xE7FA, 0xE7FB, 0xE7FC, - 0xE7FD, 0xE7FE, 0xE7FF, 0xE800, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504, 0x2505, 0x2506, 0x2507, 0x2508, 0x2509, 0x250A, 0x250B, - 0x250C, 0x250D, 0x250E, 0x250F, 0x2510, 0x2511, 0x2512, 0x2513, 0x2514, 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x251A, 0x251B, - 0x251C, 0x251D, 0x251E, 0x251F, 0x2520, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252A, 0x252B, - 0x252C, 0x252D, 0x252E, 0x252F, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253A, 0x253B, - 0x253C, 0x253D, 0x253E, 0x253F, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254A, 0x254B, - 0xE801, 0xE802, 0xE803, 0xE804, 0xE805, 0xE806, 0xE807, 0xE808, 0xE809, 0xE80A, 0xE80B, 0xE80C, 0xE80D, 0xE80E, 0xE80F, - // GB 0xAA40..0xAA7E - 0x72DC, 0x72DD, 0x72DF, 0x72E2, 0x72E3, 0x72E4, 0x72E5, 0x72E6, - 0x72E7, 0x72EA, 0x72EB, 0x72F5, 0x72F6, 0x72F9, 0x72FD, 0x72FE, 0x72FF, 0x7300, 0x7302, 0x7304, 0x7305, 0x7306, 0x7307, 0x7308, - 0x7309, 0x730B, 0x730C, 0x730D, 0x730F, 0x7310, 0x7311, 0x7312, 0x7314, 0x7318, 0x7319, 0x731A, 0x731F, 0x7320, 0x7323, 0x7324, - 0x7326, 0x7327, 0x7328, 0x732D, 0x732F, 0x7330, 0x7332, 0x7333, 0x7335, 0x7336, 0x733A, 0x733B, 0x733C, 0x733D, 0x7340, 0x7341, - 0x7342, 0x7343, 0x7344, 0x7345, 0x7346, 0x7347, 0x7348, - // GB 0xAA80..0xAAA0 - 0x7349, 0x734A, 0x734B, 0x734C, 0x734E, 0x734F, 0x7351, 0x7353, 0x7354, 0x7355, 0x7356, 0x7358, 0x7359, 0x735A, 0x735B, 0x735C, - 0x735D, 0x735E, 0x735F, 0x7361, 0x7362, 0x7363, 0x7364, 0x7365, 0x7366, 0x7367, 0x7368, 0x7369, 0x736A, 0x736B, 0x736E, 0x7370, - 0x7371, - // Skip: GB 0xAAA1..0xAAFE (UDA 1) - // GB 0xAB40..0xAB7E - 0x7372, 0x7373, 0x7374, 0x7375, 0x7376, 0x7377, 0x7378, 0x7379, 0x737A, 0x737B, 0x737C, 0x737D, 0x737F, 0x7380, 0x7381, 0x7382, - 0x7383, 0x7385, 0x7386, 0x7388, 0x738A, 0x738C, 0x738D, 0x738F, 0x7390, 0x7392, 0x7393, 0x7394, 0x7395, 0x7397, 0x7398, 0x7399, - 0x739A, 0x739C, 0x739D, 0x739E, 0x73A0, 0x73A1, 0x73A3, 0x73A4, 0x73A5, 0x73A6, 0x73A7, 0x73A8, 0x73AA, 0x73AC, 0x73AD, 0x73B1, - 0x73B4, 0x73B5, 0x73B6, 0x73B8, 0x73B9, 0x73BC, 0x73BD, 0x73BE, 0x73BF, 0x73C1, 0x73C3, 0x73C4, 0x73C5, 0x73C6, 0x73C7, - // GB 0xAB80..0xABA0 - 0x73CB, 0x73CC, 0x73CE, 0x73D2, 0x73D3, 0x73D4, 0x73D5, 0x73D6, - 0x73D7, 0x73D8, 0x73DA, 0x73DB, 0x73DC, 0x73DD, 0x73DF, 0x73E1, 0x73E2, 0x73E3, 0x73E4, 0x73E6, 0x73E8, 0x73EA, 0x73EB, 0x73EC, - 0x73EE, 0x73EF, 0x73F0, 0x73F1, 0x73F3, 0x73F4, 0x73F5, 0x73F6, 0x73F7, - // Skip: GB 0xABA1..0xABFE (UDA 1) - // GB 0xAC40..0xAC7E - 0x73F8, 0x73F9, 0x73FA, 0x73FB, 0x73FC, 0x73FD, 0x73FE, 0x73FF, - 0x7400, 0x7401, 0x7402, 0x7404, 0x7407, 0x7408, 0x740B, 0x740C, 0x740D, 0x740E, 0x7411, 0x7412, 0x7413, 0x7414, 0x7415, 0x7416, - 0x7417, 0x7418, 0x7419, 0x741C, 0x741D, 0x741E, 0x741F, 0x7420, 0x7421, 0x7423, 0x7424, 0x7427, 0x7429, 0x742B, 0x742D, 0x742F, - 0x7431, 0x7432, 0x7437, 0x7438, 0x7439, 0x743A, 0x743B, 0x743D, 0x743E, 0x743F, 0x7440, 0x7442, 0x7443, 0x7444, 0x7445, 0x7446, - 0x7447, 0x7448, 0x7449, 0x744A, 0x744B, 0x744C, 0x744D, - // GB 0xAC80..0xACA0 - 0x744E, 0x744F, 0x7450, 0x7451, 0x7452, 0x7453, 0x7454, 0x7456, 0x7458, 0x745D, 0x7460, 0x7461, 0x7462, 0x7463, 0x7464, 0x7465, - 0x7466, 0x7467, 0x7468, 0x7469, 0x746A, 0x746B, 0x746C, 0x746E, 0x746F, 0x7471, 0x7472, 0x7473, 0x7474, 0x7475, 0x7478, 0x7479, - 0x747A, - // Skip: GB 0xACA1..0xACFE (UDA 1) - // GB 0xAD40..0xAD7E - 0x747B, 0x747C, 0x747D, 0x747F, 0x7482, 0x7484, 0x7485, 0x7486, 0x7488, 0x7489, 0x748A, 0x748C, 0x748D, 0x748F, 0x7491, 0x7492, - 0x7493, 0x7494, 0x7495, 0x7496, 0x7497, 0x7498, 0x7499, 0x749A, 0x749B, 0x749D, 0x749F, 0x74A0, 0x74A1, 0x74A2, 0x74A3, 0x74A4, - 0x74A5, 0x74A6, 0x74AA, 0x74AB, 0x74AC, 0x74AD, 0x74AE, 0x74AF, 0x74B0, 0x74B1, 0x74B2, 0x74B3, 0x74B4, 0x74B5, 0x74B6, 0x74B7, - 0x74B8, 0x74B9, 0x74BB, 0x74BC, 0x74BD, 0x74BE, 0x74BF, 0x74C0, 0x74C1, 0x74C2, 0x74C3, 0x74C4, 0x74C5, 0x74C6, 0x74C7, - // GB 0xAD80..0xADA0 - 0x74C8, 0x74C9, 0x74CA, 0x74CB, 0x74CC, 0x74CD, 0x74CE, 0x74CF, - 0x74D0, 0x74D1, 0x74D3, 0x74D4, 0x74D5, 0x74D6, 0x74D7, 0x74D8, 0x74D9, 0x74DA, 0x74DB, 0x74DD, 0x74DF, 0x74E1, 0x74E5, 0x74E7, - 0x74E8, 0x74E9, 0x74EA, 0x74EB, 0x74EC, 0x74ED, 0x74F0, 0x74F1, 0x74F2, // Skip: GB 0xADA1..0xADFE (UDA 1) - // GB 0xAE40..0xAE7E - 0x74F3, 0x74F5, 0x74F8, 0x74F9, 0x74FA, 0x74FB, 0x74FC, 0x74FD, - 0x74FE, 0x7500, 0x7501, 0x7502, 0x7503, 0x7505, 0x7506, 0x7507, 0x7508, 0x7509, 0x750A, 0x750B, 0x750C, 0x750E, 0x7510, 0x7512, - 0x7514, 0x7515, 0x7516, 0x7517, 0x751B, 0x751D, 0x751E, 0x7520, 0x7521, 0x7522, 0x7523, 0x7524, 0x7526, 0x7527, 0x752A, 0x752E, - 0x7534, 0x7536, 0x7539, 0x753C, 0x753D, 0x753F, 0x7541, 0x7542, 0x7543, 0x7544, 0x7546, 0x7547, 0x7549, 0x754A, 0x754D, 0x7550, - 0x7551, 0x7552, 0x7553, 0x7555, 0x7556, 0x7557, 0x7558, - // GB 0xAE80..0xAEA0 - 0x755D, 0x755E, 0x755F, 0x7560, 0x7561, 0x7562, 0x7563, 0x7564, 0x7567, 0x7568, 0x7569, 0x756B, 0x756C, 0x756D, 0x756E, 0x756F, - 0x7570, 0x7571, 0x7573, 0x7575, 0x7576, 0x7577, 0x757A, 0x757B, 0x757C, 0x757D, 0x757E, 0x7580, 0x7581, 0x7582, 0x7584, 0x7585, - 0x7587, // Skip: GB 0xAEA1..0xAEFE (UDA 1) - // GB 0xAF40..0xAF7E - 0x7588, 0x7589, 0x758A, 0x758C, 0x758D, 0x758E, 0x7590, 0x7593, 0x7595, 0x7598, 0x759B, 0x759C, 0x759E, 0x75A2, 0x75A6, 0x75A7, - 0x75A8, 0x75A9, 0x75AA, 0x75AD, 0x75B6, 0x75B7, 0x75BA, 0x75BB, 0x75BF, 0x75C0, 0x75C1, 0x75C6, 0x75CB, 0x75CC, 0x75CE, 0x75CF, - 0x75D0, 0x75D1, 0x75D3, 0x75D7, 0x75D9, 0x75DA, 0x75DC, 0x75DD, 0x75DF, 0x75E0, 0x75E1, 0x75E5, 0x75E9, 0x75EC, 0x75ED, 0x75EE, - 0x75EF, 0x75F2, 0x75F3, 0x75F5, 0x75F6, 0x75F7, 0x75F8, 0x75FA, 0x75FB, 0x75FD, 0x75FE, 0x7602, 0x7604, 0x7606, 0x7607, - // GB 0xAF80..0xAFA0 - 0x7608, 0x7609, 0x760B, 0x760D, 0x760E, 0x760F, 0x7611, 0x7612, - 0x7613, 0x7614, 0x7616, 0x761A, 0x761C, 0x761D, 0x761E, 0x7621, 0x7623, 0x7627, 0x7628, 0x762C, 0x762E, 0x762F, 0x7631, 0x7632, - 0x7636, 0x7637, 0x7639, 0x763A, 0x763B, 0x763D, 0x7641, 0x7642, 0x7644, // Skip: GB 0xAFA1..0xAFFE (UDA 1) - // GB 0xB040..0xB07E - 0x7645, 0x7646, 0x7647, 0x7648, 0x7649, 0x764A, 0x764B, 0x764E, - 0x764F, 0x7650, 0x7651, 0x7652, 0x7653, 0x7655, 0x7657, 0x7658, 0x7659, 0x765A, 0x765B, 0x765D, 0x765F, 0x7660, 0x7661, 0x7662, - 0x7664, 0x7665, 0x7666, 0x7667, 0x7668, 0x7669, 0x766A, 0x766C, 0x766D, 0x766E, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x7675, - 0x7676, 0x7677, 0x7679, 0x767A, 0x767C, 0x767F, 0x7680, 0x7681, 0x7683, 0x7685, 0x7689, 0x768A, 0x768C, 0x768D, 0x768F, 0x7690, - 0x7692, 0x7694, 0x7695, 0x7697, 0x7698, 0x769A, 0x769B, - // GB 0xB080..0xB0FE - 0x769C, 0x769D, 0x769E, 0x769F, 0x76A0, 0x76A1, 0x76A2, 0x76A3, 0x76A5, 0x76A6, 0x76A7, 0x76A8, 0x76A9, 0x76AA, 0x76AB, 0x76AC, - 0x76AD, 0x76AF, 0x76B0, 0x76B3, 0x76B5, 0x76B6, 0x76B7, 0x76B8, 0x76B9, 0x76BA, 0x76BB, 0x76BC, 0x76BD, 0x76BE, 0x76C0, 0x76C1, - 0x76C3, 0x554A, 0x963F, 0x57C3, 0x6328, 0x54CE, 0x5509, 0x54C0, 0x7691, 0x764C, 0x853C, 0x77EE, 0x827E, 0x788D, 0x7231, 0x9698, - 0x978D, 0x6C28, 0x5B89, 0x4FFA, 0x6309, 0x6697, 0x5CB8, 0x80FA, 0x6848, 0x80AE, 0x6602, 0x76CE, 0x51F9, 0x6556, 0x71AC, 0x7FF1, - 0x8884, 0x50B2, 0x5965, 0x61CA, 0x6FB3, 0x82AD, 0x634C, 0x6252, 0x53ED, 0x5427, 0x7B06, 0x516B, 0x75A4, 0x5DF4, 0x62D4, 0x8DCB, - 0x9776, 0x628A, 0x8019, 0x575D, 0x9738, 0x7F62, 0x7238, 0x767D, 0x67CF, 0x767E, 0x6446, 0x4F70, 0x8D25, 0x62DC, 0x7A17, 0x6591, - 0x73ED, 0x642C, 0x6273, 0x822C, 0x9881, 0x677F, 0x7248, 0x626E, 0x62CC, 0x4F34, 0x74E3, 0x534A, 0x529E, 0x7ECA, 0x90A6, 0x5E2E, - 0x6886, 0x699C, 0x8180, 0x7ED1, 0x68D2, 0x78C5, 0x868C, 0x9551, 0x508D, 0x8C24, 0x82DE, 0x80DE, 0x5305, 0x8912, 0x5265, - // GB 0xB140..0xB17E - 0x76C4, 0x76C7, 0x76C9, 0x76CB, 0x76CC, 0x76D3, 0x76D5, 0x76D9, - 0x76DA, 0x76DC, 0x76DD, 0x76DE, 0x76E0, 0x76E1, 0x76E2, 0x76E3, 0x76E4, 0x76E6, 0x76E7, 0x76E8, 0x76E9, 0x76EA, 0x76EB, 0x76EC, - 0x76ED, 0x76F0, 0x76F3, 0x76F5, 0x76F6, 0x76F7, 0x76FA, 0x76FB, 0x76FD, 0x76FF, 0x7700, 0x7702, 0x7703, 0x7705, 0x7706, 0x770A, - 0x770C, 0x770E, 0x770F, 0x7710, 0x7711, 0x7712, 0x7713, 0x7714, 0x7715, 0x7716, 0x7717, 0x7718, 0x771B, 0x771C, 0x771D, 0x771E, - 0x7721, 0x7723, 0x7724, 0x7725, 0x7727, 0x772A, 0x772B, - // GB 0xB180..0xB1FE - 0x772C, 0x772E, 0x7730, 0x7731, 0x7732, 0x7733, 0x7734, 0x7739, 0x773B, 0x773D, 0x773E, 0x773F, 0x7742, 0x7744, 0x7745, 0x7746, - 0x7748, 0x7749, 0x774A, 0x774B, 0x774C, 0x774D, 0x774E, 0x774F, 0x7752, 0x7753, 0x7754, 0x7755, 0x7756, 0x7757, 0x7758, 0x7759, - 0x775C, 0x8584, 0x96F9, 0x4FDD, 0x5821, 0x9971, 0x5B9D, 0x62B1, 0x62A5, 0x66B4, 0x8C79, 0x9C8D, 0x7206, 0x676F, 0x7891, 0x60B2, - 0x5351, 0x5317, 0x8F88, 0x80CC, 0x8D1D, 0x94A1, 0x500D, 0x72C8, 0x5907, 0x60EB, 0x7119, 0x88AB, 0x5954, 0x82EF, 0x672C, 0x7B28, - 0x5D29, 0x7EF7, 0x752D, 0x6CF5, 0x8E66, 0x8FF8, 0x903C, 0x9F3B, 0x6BD4, 0x9119, 0x7B14, 0x5F7C, 0x78A7, 0x84D6, 0x853D, 0x6BD5, - 0x6BD9, 0x6BD6, 0x5E01, 0x5E87, 0x75F9, 0x95ED, 0x655D, 0x5F0A, 0x5FC5, 0x8F9F, 0x58C1, 0x81C2, 0x907F, 0x965B, 0x97AD, 0x8FB9, - 0x7F16, 0x8D2C, 0x6241, 0x4FBF, 0x53D8, 0x535E, 0x8FA8, 0x8FA9, 0x8FAB, 0x904D, 0x6807, 0x5F6A, 0x8198, 0x8868, 0x9CD6, 0x618B, - 0x522B, 0x762A, 0x5F6C, 0x658C, 0x6FD2, 0x6EE8, 0x5BBE, 0x6448, 0x5175, 0x51B0, 0x67C4, 0x4E19, 0x79C9, 0x997C, 0x70B3, - // GB 0xB240..0xB27E - 0x775D, 0x775E, 0x775F, 0x7760, 0x7764, 0x7767, 0x7769, 0x776A, - 0x776D, 0x776E, 0x776F, 0x7770, 0x7771, 0x7772, 0x7773, 0x7774, 0x7775, 0x7776, 0x7777, 0x7778, 0x777A, 0x777B, 0x777C, 0x7781, - 0x7782, 0x7783, 0x7786, 0x7787, 0x7788, 0x7789, 0x778A, 0x778B, 0x778F, 0x7790, 0x7793, 0x7794, 0x7795, 0x7796, 0x7797, 0x7798, - 0x7799, 0x779A, 0x779B, 0x779C, 0x779D, 0x779E, 0x77A1, 0x77A3, 0x77A4, 0x77A6, 0x77A8, 0x77AB, 0x77AD, 0x77AE, 0x77AF, 0x77B1, - 0x77B2, 0x77B4, 0x77B6, 0x77B7, 0x77B8, 0x77B9, 0x77BA, - // GB 0xB280..0xB2FE - 0x77BC, 0x77BE, 0x77C0, 0x77C1, 0x77C2, 0x77C3, 0x77C4, 0x77C5, 0x77C6, 0x77C7, 0x77C8, 0x77C9, 0x77CA, 0x77CB, 0x77CC, 0x77CE, - 0x77CF, 0x77D0, 0x77D1, 0x77D2, 0x77D3, 0x77D4, 0x77D5, 0x77D6, 0x77D8, 0x77D9, 0x77DA, 0x77DD, 0x77DE, 0x77DF, 0x77E0, 0x77E1, - 0x77E4, 0x75C5, 0x5E76, 0x73BB, 0x83E0, 0x64AD, 0x62E8, 0x94B5, 0x6CE2, 0x535A, 0x52C3, 0x640F, 0x94C2, 0x7B94, 0x4F2F, 0x5E1B, - 0x8236, 0x8116, 0x818A, 0x6E24, 0x6CCA, 0x9A73, 0x6355, 0x535C, 0x54FA, 0x8865, 0x57E0, 0x4E0D, 0x5E03, 0x6B65, 0x7C3F, 0x90E8, - 0x6016, 0x64E6, 0x731C, 0x88C1, 0x6750, 0x624D, 0x8D22, 0x776C, 0x8E29, 0x91C7, 0x5F69, 0x83DC, 0x8521, 0x9910, 0x53C2, 0x8695, - 0x6B8B, 0x60ED, 0x60E8, 0x707F, 0x82CD, 0x8231, 0x4ED3, 0x6CA7, 0x85CF, 0x64CD, 0x7CD9, 0x69FD, 0x66F9, 0x8349, 0x5395, 0x7B56, - 0x4FA7, 0x518C, 0x6D4B, 0x5C42, 0x8E6D, 0x63D2, 0x53C9, 0x832C, 0x8336, 0x67E5, 0x78B4, 0x643D, 0x5BDF, 0x5C94, 0x5DEE, 0x8BE7, - 0x62C6, 0x67F4, 0x8C7A, 0x6400, 0x63BA, 0x8749, 0x998B, 0x8C17, 0x7F20, 0x94F2, 0x4EA7, 0x9610, 0x98A4, 0x660C, 0x7316, - // GB 0xB340..0xB37E - 0x77E6, 0x77E8, 0x77EA, 0x77EF, 0x77F0, 0x77F1, 0x77F2, 0x77F4, - 0x77F5, 0x77F7, 0x77F9, 0x77FA, 0x77FB, 0x77FC, 0x7803, 0x7804, 0x7805, 0x7806, 0x7807, 0x7808, 0x780A, 0x780B, 0x780E, 0x780F, - 0x7810, 0x7813, 0x7815, 0x7819, 0x781B, 0x781E, 0x7820, 0x7821, 0x7822, 0x7824, 0x7828, 0x782A, 0x782B, 0x782E, 0x782F, 0x7831, - 0x7832, 0x7833, 0x7835, 0x7836, 0x783D, 0x783F, 0x7841, 0x7842, 0x7843, 0x7844, 0x7846, 0x7848, 0x7849, 0x784A, 0x784B, 0x784D, - 0x784F, 0x7851, 0x7853, 0x7854, 0x7858, 0x7859, 0x785A, - // GB 0xB380..0xB3FE - 0x785B, 0x785C, 0x785E, 0x785F, 0x7860, 0x7861, 0x7862, 0x7863, 0x7864, 0x7865, 0x7866, 0x7867, 0x7868, 0x7869, 0x786F, 0x7870, - 0x7871, 0x7872, 0x7873, 0x7874, 0x7875, 0x7876, 0x7878, 0x7879, 0x787A, 0x787B, 0x787D, 0x787E, 0x787F, 0x7880, 0x7881, 0x7882, - 0x7883, 0x573A, 0x5C1D, 0x5E38, 0x957F, 0x507F, 0x80A0, 0x5382, 0x655E, 0x7545, 0x5531, 0x5021, 0x8D85, 0x6284, 0x949E, 0x671D, - 0x5632, 0x6F6E, 0x5DE2, 0x5435, 0x7092, 0x8F66, 0x626F, 0x64A4, 0x63A3, 0x5F7B, 0x6F88, 0x90F4, 0x81E3, 0x8FB0, 0x5C18, 0x6668, - 0x5FF1, 0x6C89, 0x9648, 0x8D81, 0x886C, 0x6491, 0x79F0, 0x57CE, 0x6A59, 0x6210, 0x5448, 0x4E58, 0x7A0B, 0x60E9, 0x6F84, 0x8BDA, - 0x627F, 0x901E, 0x9A8B, 0x79E4, 0x5403, 0x75F4, 0x6301, 0x5319, 0x6C60, 0x8FDF, 0x5F1B, 0x9A70, 0x803B, 0x9F7F, 0x4F88, 0x5C3A, - 0x8D64, 0x7FC5, 0x65A5, 0x70BD, 0x5145, 0x51B2, 0x866B, 0x5D07, 0x5BA0, 0x62BD, 0x916C, 0x7574, 0x8E0C, 0x7A20, 0x6101, 0x7B79, - 0x4EC7, 0x7EF8, 0x7785, 0x4E11, 0x81ED, 0x521D, 0x51FA, 0x6A71, 0x53A8, 0x8E87, 0x9504, 0x96CF, 0x6EC1, 0x9664, 0x695A, - // GB 0xB440..0xB47E - 0x7884, 0x7885, 0x7886, 0x7888, 0x788A, 0x788B, 0x788F, 0x7890, - 0x7892, 0x7894, 0x7895, 0x7896, 0x7899, 0x789D, 0x789E, 0x78A0, 0x78A2, 0x78A4, 0x78A6, 0x78A8, 0x78A9, 0x78AA, 0x78AB, 0x78AC, - 0x78AD, 0x78AE, 0x78AF, 0x78B5, 0x78B6, 0x78B7, 0x78B8, 0x78BA, 0x78BB, 0x78BC, 0x78BD, 0x78BF, 0x78C0, 0x78C2, 0x78C3, 0x78C4, - 0x78C6, 0x78C7, 0x78C8, 0x78CC, 0x78CD, 0x78CE, 0x78CF, 0x78D1, 0x78D2, 0x78D3, 0x78D6, 0x78D7, 0x78D8, 0x78DA, 0x78DB, 0x78DC, - 0x78DD, 0x78DE, 0x78DF, 0x78E0, 0x78E1, 0x78E2, 0x78E3, - // GB 0xB480..0xB4FE - 0x78E4, 0x78E5, 0x78E6, 0x78E7, 0x78E9, 0x78EA, 0x78EB, 0x78ED, 0x78EE, 0x78EF, 0x78F0, 0x78F1, 0x78F3, 0x78F5, 0x78F6, 0x78F8, - 0x78F9, 0x78FB, 0x78FC, 0x78FD, 0x78FE, 0x78FF, 0x7900, 0x7902, 0x7903, 0x7904, 0x7906, 0x7907, 0x7908, 0x7909, 0x790A, 0x790B, - 0x790C, 0x7840, 0x50A8, 0x77D7, 0x6410, 0x89E6, 0x5904, 0x63E3, 0x5DDD, 0x7A7F, 0x693D, 0x4F20, 0x8239, 0x5598, 0x4E32, 0x75AE, - 0x7A97, 0x5E62, 0x5E8A, 0x95EF, 0x521B, 0x5439, 0x708A, 0x6376, 0x9524, 0x5782, 0x6625, 0x693F, 0x9187, 0x5507, 0x6DF3, 0x7EAF, - 0x8822, 0x6233, 0x7EF0, 0x75B5, 0x8328, 0x78C1, 0x96CC, 0x8F9E, 0x6148, 0x74F7, 0x8BCD, 0x6B64, 0x523A, 0x8D50, 0x6B21, 0x806A, - 0x8471, 0x56F1, 0x5306, 0x4ECE, 0x4E1B, 0x51D1, 0x7C97, 0x918B, 0x7C07, 0x4FC3, 0x8E7F, 0x7BE1, 0x7A9C, 0x6467, 0x5D14, 0x50AC, - 0x8106, 0x7601, 0x7CB9, 0x6DEC, 0x7FE0, 0x6751, 0x5B58, 0x5BF8, 0x78CB, 0x64AE, 0x6413, 0x63AA, 0x632B, 0x9519, 0x642D, 0x8FBE, - 0x7B54, 0x7629, 0x6253, 0x5927, 0x5446, 0x6B79, 0x50A3, 0x6234, 0x5E26, 0x6B86, 0x4EE3, 0x8D37, 0x888B, 0x5F85, 0x902E, - // GB 0xB540..0xB57E - 0x790D, 0x790E, 0x790F, 0x7910, 0x7911, 0x7912, 0x7914, 0x7915, - 0x7916, 0x7917, 0x7918, 0x7919, 0x791A, 0x791B, 0x791C, 0x791D, 0x791F, 0x7920, 0x7921, 0x7922, 0x7923, 0x7925, 0x7926, 0x7927, - 0x7928, 0x7929, 0x792A, 0x792B, 0x792C, 0x792D, 0x792E, 0x792F, 0x7930, 0x7931, 0x7932, 0x7933, 0x7935, 0x7936, 0x7937, 0x7938, - 0x7939, 0x793D, 0x793F, 0x7942, 0x7943, 0x7944, 0x7945, 0x7947, 0x794A, 0x794B, 0x794C, 0x794D, 0x794E, 0x794F, 0x7950, 0x7951, - 0x7952, 0x7954, 0x7955, 0x7958, 0x7959, 0x7961, 0x7963, - // GB 0xB580..0xB5FE - 0x7964, 0x7966, 0x7969, 0x796A, 0x796B, 0x796C, 0x796E, 0x7970, 0x7971, 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7979, 0x797B, - 0x797C, 0x797D, 0x797E, 0x797F, 0x7982, 0x7983, 0x7986, 0x7987, 0x7988, 0x7989, 0x798B, 0x798C, 0x798D, 0x798E, 0x7990, 0x7991, - 0x7992, 0x6020, 0x803D, 0x62C5, 0x4E39, 0x5355, 0x90F8, 0x63B8, 0x80C6, 0x65E6, 0x6C2E, 0x4F46, 0x60EE, 0x6DE1, 0x8BDE, 0x5F39, - 0x86CB, 0x5F53, 0x6321, 0x515A, 0x8361, 0x6863, 0x5200, 0x6363, 0x8E48, 0x5012, 0x5C9B, 0x7977, 0x5BFC, 0x5230, 0x7A3B, 0x60BC, - 0x9053, 0x76D7, 0x5FB7, 0x5F97, 0x7684, 0x8E6C, 0x706F, 0x767B, 0x7B49, 0x77AA, 0x51F3, 0x9093, 0x5824, 0x4F4E, 0x6EF4, 0x8FEA, - 0x654C, 0x7B1B, 0x72C4, 0x6DA4, 0x7FDF, 0x5AE1, 0x62B5, 0x5E95, 0x5730, 0x8482, 0x7B2C, 0x5E1D, 0x5F1F, 0x9012, 0x7F14, 0x98A0, - 0x6382, 0x6EC7, 0x7898, 0x70B9, 0x5178, 0x975B, 0x57AB, 0x7535, 0x4F43, 0x7538, 0x5E97, 0x60E6, 0x5960, 0x6DC0, 0x6BBF, 0x7889, - 0x53FC, 0x96D5, 0x51CB, 0x5201, 0x6389, 0x540A, 0x9493, 0x8C03, 0x8DCC, 0x7239, 0x789F, 0x8776, 0x8FED, 0x8C0D, 0x53E0, - // GB 0xB640..0xB67E - 0x7993, 0x7994, 0x7995, 0x7996, 0x7997, 0x7998, 0x7999, 0x799B, - 0x799C, 0x799D, 0x799E, 0x799F, 0x79A0, 0x79A1, 0x79A2, 0x79A3, 0x79A4, 0x79A5, 0x79A6, 0x79A8, 0x79A9, 0x79AA, 0x79AB, 0x79AC, - 0x79AD, 0x79AE, 0x79AF, 0x79B0, 0x79B1, 0x79B2, 0x79B4, 0x79B5, 0x79B6, 0x79B7, 0x79B8, 0x79BC, 0x79BF, 0x79C2, 0x79C4, 0x79C5, - 0x79C7, 0x79C8, 0x79CA, 0x79CC, 0x79CE, 0x79CF, 0x79D0, 0x79D3, 0x79D4, 0x79D6, 0x79D7, 0x79D9, 0x79DA, 0x79DB, 0x79DC, 0x79DD, - 0x79DE, 0x79E0, 0x79E1, 0x79E2, 0x79E5, 0x79E8, 0x79EA, - // GB 0xB680..0xB6FE - 0x79EC, 0x79EE, 0x79F1, 0x79F2, 0x79F3, 0x79F4, 0x79F5, 0x79F6, 0x79F7, 0x79F9, 0x79FA, 0x79FC, 0x79FE, 0x79FF, 0x7A01, 0x7A04, - 0x7A05, 0x7A07, 0x7A08, 0x7A09, 0x7A0A, 0x7A0C, 0x7A0F, 0x7A10, 0x7A11, 0x7A12, 0x7A13, 0x7A15, 0x7A16, 0x7A18, 0x7A19, 0x7A1B, - 0x7A1C, 0x4E01, 0x76EF, 0x53EE, 0x9489, 0x9876, 0x9F0E, 0x952D, 0x5B9A, 0x8BA2, 0x4E22, 0x4E1C, 0x51AC, 0x8463, 0x61C2, 0x52A8, - 0x680B, 0x4F97, 0x606B, 0x51BB, 0x6D1E, 0x515C, 0x6296, 0x6597, 0x9661, 0x8C46, 0x9017, 0x75D8, 0x90FD, 0x7763, 0x6BD2, 0x728A, - 0x72EC, 0x8BFB, 0x5835, 0x7779, 0x8D4C, 0x675C, 0x9540, 0x809A, 0x5EA6, 0x6E21, 0x5992, 0x7AEF, 0x77ED, 0x953B, 0x6BB5, 0x65AD, - 0x7F0E, 0x5806, 0x5151, 0x961F, 0x5BF9, 0x58A9, 0x5428, 0x8E72, 0x6566, 0x987F, 0x56E4, 0x949D, 0x76FE, 0x9041, 0x6387, 0x54C6, - 0x591A, 0x593A, 0x579B, 0x8EB2, 0x6735, 0x8DFA, 0x8235, 0x5241, 0x60F0, 0x5815, 0x86FE, 0x5CE8, 0x9E45, 0x4FC4, 0x989D, 0x8BB9, - 0x5A25, 0x6076, 0x5384, 0x627C, 0x904F, 0x9102, 0x997F, 0x6069, 0x800C, 0x513F, 0x8033, 0x5C14, 0x9975, 0x6D31, 0x4E8C, - // GB 0xB740..0xB77E - 0x7A1D, 0x7A1F, 0x7A21, 0x7A22, 0x7A24, 0x7A25, 0x7A26, 0x7A27, - 0x7A28, 0x7A29, 0x7A2A, 0x7A2B, 0x7A2C, 0x7A2D, 0x7A2E, 0x7A2F, 0x7A30, 0x7A31, 0x7A32, 0x7A34, 0x7A35, 0x7A36, 0x7A38, 0x7A3A, - 0x7A3E, 0x7A40, 0x7A41, 0x7A42, 0x7A43, 0x7A44, 0x7A45, 0x7A47, 0x7A48, 0x7A49, 0x7A4A, 0x7A4B, 0x7A4C, 0x7A4D, 0x7A4E, 0x7A4F, - 0x7A50, 0x7A52, 0x7A53, 0x7A54, 0x7A55, 0x7A56, 0x7A58, 0x7A59, 0x7A5A, 0x7A5B, 0x7A5C, 0x7A5D, 0x7A5E, 0x7A5F, 0x7A60, 0x7A61, - 0x7A62, 0x7A63, 0x7A64, 0x7A65, 0x7A66, 0x7A67, 0x7A68, - // GB 0xB780..0xB7FE - 0x7A69, 0x7A6A, 0x7A6B, 0x7A6C, 0x7A6D, 0x7A6E, 0x7A6F, 0x7A71, 0x7A72, 0x7A73, 0x7A75, 0x7A7B, 0x7A7C, 0x7A7D, 0x7A7E, 0x7A82, - 0x7A85, 0x7A87, 0x7A89, 0x7A8A, 0x7A8B, 0x7A8C, 0x7A8E, 0x7A8F, 0x7A90, 0x7A93, 0x7A94, 0x7A99, 0x7A9A, 0x7A9B, 0x7A9E, 0x7AA1, - 0x7AA2, 0x8D30, 0x53D1, 0x7F5A, 0x7B4F, 0x4F10, 0x4E4F, 0x9600, 0x6CD5, 0x73D0, 0x85E9, 0x5E06, 0x756A, 0x7FFB, 0x6A0A, 0x77FE, - 0x9492, 0x7E41, 0x51E1, 0x70E6, 0x53CD, 0x8FD4, 0x8303, 0x8D29, 0x72AF, 0x996D, 0x6CDB, 0x574A, 0x82B3, 0x65B9, 0x80AA, 0x623F, - 0x9632, 0x59A8, 0x4EFF, 0x8BBF, 0x7EBA, 0x653E, 0x83F2, 0x975E, 0x5561, 0x98DE, 0x80A5, 0x532A, 0x8BFD, 0x5420, 0x80BA, 0x5E9F, - 0x6CB8, 0x8D39, 0x82AC, 0x915A, 0x5429, 0x6C1B, 0x5206, 0x7EB7, 0x575F, 0x711A, 0x6C7E, 0x7C89, 0x594B, 0x4EFD, 0x5FFF, 0x6124, - 0x7CAA, 0x4E30, 0x5C01, 0x67AB, 0x8702, 0x5CF0, 0x950B, 0x98CE, 0x75AF, 0x70FD, 0x9022, 0x51AF, 0x7F1D, 0x8BBD, 0x5949, 0x51E4, - 0x4F5B, 0x5426, 0x592B, 0x6577, 0x80A4, 0x5B75, 0x6276, 0x62C2, 0x8F90, 0x5E45, 0x6C1F, 0x7B26, 0x4F0F, 0x4FD8, 0x670D, - // GB 0xB840..0xB87E - 0x7AA3, 0x7AA4, 0x7AA7, 0x7AA9, 0x7AAA, 0x7AAB, 0x7AAE, 0x7AAF, - 0x7AB0, 0x7AB1, 0x7AB2, 0x7AB4, 0x7AB5, 0x7AB6, 0x7AB7, 0x7AB8, 0x7AB9, 0x7ABA, 0x7ABB, 0x7ABC, 0x7ABD, 0x7ABE, 0x7AC0, 0x7AC1, - 0x7AC2, 0x7AC3, 0x7AC4, 0x7AC5, 0x7AC6, 0x7AC7, 0x7AC8, 0x7AC9, 0x7ACA, 0x7ACC, 0x7ACD, 0x7ACE, 0x7ACF, 0x7AD0, 0x7AD1, 0x7AD2, - 0x7AD3, 0x7AD4, 0x7AD5, 0x7AD7, 0x7AD8, 0x7ADA, 0x7ADB, 0x7ADC, 0x7ADD, 0x7AE1, 0x7AE2, 0x7AE4, 0x7AE7, 0x7AE8, 0x7AE9, 0x7AEA, - 0x7AEB, 0x7AEC, 0x7AEE, 0x7AF0, 0x7AF1, 0x7AF2, 0x7AF3, - // GB 0xB880..0xB8FE - 0x7AF4, 0x7AF5, 0x7AF6, 0x7AF7, 0x7AF8, 0x7AFB, 0x7AFC, 0x7AFE, 0x7B00, 0x7B01, 0x7B02, 0x7B05, 0x7B07, 0x7B09, 0x7B0C, 0x7B0D, - 0x7B0E, 0x7B10, 0x7B12, 0x7B13, 0x7B16, 0x7B17, 0x7B18, 0x7B1A, 0x7B1C, 0x7B1D, 0x7B1F, 0x7B21, 0x7B22, 0x7B23, 0x7B27, 0x7B29, - 0x7B2D, 0x6D6E, 0x6DAA, 0x798F, 0x88B1, 0x5F17, 0x752B, 0x629A, 0x8F85, 0x4FEF, 0x91DC, 0x65A7, 0x812F, 0x8151, 0x5E9C, 0x8150, - 0x8D74, 0x526F, 0x8986, 0x8D4B, 0x590D, 0x5085, 0x4ED8, 0x961C, 0x7236, 0x8179, 0x8D1F, 0x5BCC, 0x8BA3, 0x9644, 0x5987, 0x7F1A, - 0x5490, 0x5676, 0x560E, 0x8BE5, 0x6539, 0x6982, 0x9499, 0x76D6, 0x6E89, 0x5E72, 0x7518, 0x6746, 0x67D1, 0x7AFF, 0x809D, 0x8D76, - 0x611F, 0x79C6, 0x6562, 0x8D63, 0x5188, 0x521A, 0x94A2, 0x7F38, 0x809B, 0x7EB2, 0x5C97, 0x6E2F, 0x6760, 0x7BD9, 0x768B, 0x9AD8, - 0x818F, 0x7F94, 0x7CD5, 0x641E, 0x9550, 0x7A3F, 0x544A, 0x54E5, 0x6B4C, 0x6401, 0x6208, 0x9E3D, 0x80F3, 0x7599, 0x5272, 0x9769, - 0x845B, 0x683C, 0x86E4, 0x9601, 0x9694, 0x94EC, 0x4E2A, 0x5404, 0x7ED9, 0x6839, 0x8DDF, 0x8015, 0x66F4, 0x5E9A, 0x7FB9, - // GB 0xB940..0xB97E - 0x7B2F, 0x7B30, 0x7B32, 0x7B34, 0x7B35, 0x7B36, 0x7B37, 0x7B39, - 0x7B3B, 0x7B3D, 0x7B3F, 0x7B40, 0x7B41, 0x7B42, 0x7B43, 0x7B44, 0x7B46, 0x7B48, 0x7B4A, 0x7B4D, 0x7B4E, 0x7B53, 0x7B55, 0x7B57, - 0x7B59, 0x7B5C, 0x7B5E, 0x7B5F, 0x7B61, 0x7B63, 0x7B64, 0x7B65, 0x7B66, 0x7B67, 0x7B68, 0x7B69, 0x7B6A, 0x7B6B, 0x7B6C, 0x7B6D, - 0x7B6F, 0x7B70, 0x7B73, 0x7B74, 0x7B76, 0x7B78, 0x7B7A, 0x7B7C, 0x7B7D, 0x7B7F, 0x7B81, 0x7B82, 0x7B83, 0x7B84, 0x7B86, 0x7B87, - 0x7B88, 0x7B89, 0x7B8A, 0x7B8B, 0x7B8C, 0x7B8E, 0x7B8F, - // GB 0xB980..0xB9FE - 0x7B91, 0x7B92, 0x7B93, 0x7B96, 0x7B98, 0x7B99, 0x7B9A, 0x7B9B, 0x7B9E, 0x7B9F, 0x7BA0, 0x7BA3, 0x7BA4, 0x7BA5, 0x7BAE, 0x7BAF, - 0x7BB0, 0x7BB2, 0x7BB3, 0x7BB5, 0x7BB6, 0x7BB7, 0x7BB9, 0x7BBA, 0x7BBB, 0x7BBC, 0x7BBD, 0x7BBE, 0x7BBF, 0x7BC0, 0x7BC2, 0x7BC3, - 0x7BC4, 0x57C2, 0x803F, 0x6897, 0x5DE5, 0x653B, 0x529F, 0x606D, 0x9F9A, 0x4F9B, 0x8EAC, 0x516C, 0x5BAB, 0x5F13, 0x5DE9, 0x6C5E, - 0x62F1, 0x8D21, 0x5171, 0x94A9, 0x52FE, 0x6C9F, 0x82DF, 0x72D7, 0x57A2, 0x6784, 0x8D2D, 0x591F, 0x8F9C, 0x83C7, 0x5495, 0x7B8D, - 0x4F30, 0x6CBD, 0x5B64, 0x59D1, 0x9F13, 0x53E4, 0x86CA, 0x9AA8, 0x8C37, 0x80A1, 0x6545, 0x987E, 0x56FA, 0x96C7, 0x522E, 0x74DC, - 0x5250, 0x5BE1, 0x6302, 0x8902, 0x4E56, 0x62D0, 0x602A, 0x68FA, 0x5173, 0x5B98, 0x51A0, 0x89C2, 0x7BA1, 0x9986, 0x7F50, 0x60EF, - 0x704C, 0x8D2F, 0x5149, 0x5E7F, 0x901B, 0x7470, 0x89C4, 0x572D, 0x7845, 0x5F52, 0x9F9F, 0x95FA, 0x8F68, 0x9B3C, 0x8BE1, 0x7678, - 0x6842, 0x67DC, 0x8DEA, 0x8D35, 0x523D, 0x8F8A, 0x6EDA, 0x68CD, 0x9505, 0x90ED, 0x56FD, 0x679C, 0x88F9, 0x8FC7, 0x54C8, - // GB 0xBA40..0xBA7E - 0x7BC5, 0x7BC8, 0x7BC9, 0x7BCA, 0x7BCB, 0x7BCD, 0x7BCE, 0x7BCF, - 0x7BD0, 0x7BD2, 0x7BD4, 0x7BD5, 0x7BD6, 0x7BD7, 0x7BD8, 0x7BDB, 0x7BDC, 0x7BDE, 0x7BDF, 0x7BE0, 0x7BE2, 0x7BE3, 0x7BE4, 0x7BE7, - 0x7BE8, 0x7BE9, 0x7BEB, 0x7BEC, 0x7BED, 0x7BEF, 0x7BF0, 0x7BF2, 0x7BF3, 0x7BF4, 0x7BF5, 0x7BF6, 0x7BF8, 0x7BF9, 0x7BFA, 0x7BFB, - 0x7BFD, 0x7BFF, 0x7C00, 0x7C01, 0x7C02, 0x7C03, 0x7C04, 0x7C05, 0x7C06, 0x7C08, 0x7C09, 0x7C0A, 0x7C0D, 0x7C0E, 0x7C10, 0x7C11, - 0x7C12, 0x7C13, 0x7C14, 0x7C15, 0x7C17, 0x7C18, 0x7C19, - // GB 0xBA80..0xBAFE - 0x7C1A, 0x7C1B, 0x7C1C, 0x7C1D, 0x7C1E, 0x7C20, 0x7C21, 0x7C22, 0x7C23, 0x7C24, 0x7C25, 0x7C28, 0x7C29, 0x7C2B, 0x7C2C, 0x7C2D, - 0x7C2E, 0x7C2F, 0x7C30, 0x7C31, 0x7C32, 0x7C33, 0x7C34, 0x7C35, 0x7C36, 0x7C37, 0x7C39, 0x7C3A, 0x7C3B, 0x7C3C, 0x7C3D, 0x7C3E, - 0x7C42, 0x9AB8, 0x5B69, 0x6D77, 0x6C26, 0x4EA5, 0x5BB3, 0x9A87, 0x9163, 0x61A8, 0x90AF, 0x97E9, 0x542B, 0x6DB5, 0x5BD2, 0x51FD, - 0x558A, 0x7F55, 0x7FF0, 0x64BC, 0x634D, 0x65F1, 0x61BE, 0x608D, 0x710A, 0x6C57, 0x6C49, 0x592F, 0x676D, 0x822A, 0x58D5, 0x568E, - 0x8C6A, 0x6BEB, 0x90DD, 0x597D, 0x8017, 0x53F7, 0x6D69, 0x5475, 0x559D, 0x8377, 0x83CF, 0x6838, 0x79BE, 0x548C, 0x4F55, 0x5408, - 0x76D2, 0x8C89, 0x9602, 0x6CB3, 0x6DB8, 0x8D6B, 0x8910, 0x9E64, 0x8D3A, 0x563F, 0x9ED1, 0x75D5, 0x5F88, 0x72E0, 0x6068, 0x54FC, - 0x4EA8, 0x6A2A, 0x8861, 0x6052, 0x8F70, 0x54C4, 0x70D8, 0x8679, 0x9E3F, 0x6D2A, 0x5B8F, 0x5F18, 0x7EA2, 0x5589, 0x4FAF, 0x7334, - 0x543C, 0x539A, 0x5019, 0x540E, 0x547C, 0x4E4E, 0x5FFD, 0x745A, 0x58F6, 0x846B, 0x80E1, 0x8774, 0x72D0, 0x7CCA, 0x6E56, - // GB 0xBB40..0xBB7E - 0x7C43, 0x7C44, 0x7C45, 0x7C46, 0x7C47, 0x7C48, 0x7C49, 0x7C4A, - 0x7C4B, 0x7C4C, 0x7C4E, 0x7C4F, 0x7C50, 0x7C51, 0x7C52, 0x7C53, 0x7C54, 0x7C55, 0x7C56, 0x7C57, 0x7C58, 0x7C59, 0x7C5A, 0x7C5B, - 0x7C5C, 0x7C5D, 0x7C5E, 0x7C5F, 0x7C60, 0x7C61, 0x7C62, 0x7C63, 0x7C64, 0x7C65, 0x7C66, 0x7C67, 0x7C68, 0x7C69, 0x7C6A, 0x7C6B, - 0x7C6C, 0x7C6D, 0x7C6E, 0x7C6F, 0x7C70, 0x7C71, 0x7C72, 0x7C75, 0x7C76, 0x7C77, 0x7C78, 0x7C79, 0x7C7A, 0x7C7E, 0x7C7F, 0x7C80, - 0x7C81, 0x7C82, 0x7C83, 0x7C84, 0x7C85, 0x7C86, 0x7C87, - // GB 0xBB80..0xBBFE - 0x7C88, 0x7C8A, 0x7C8B, 0x7C8C, 0x7C8D, 0x7C8E, 0x7C8F, 0x7C90, 0x7C93, 0x7C94, 0x7C96, 0x7C99, 0x7C9A, 0x7C9B, 0x7CA0, 0x7CA1, - 0x7CA3, 0x7CA6, 0x7CA7, 0x7CA8, 0x7CA9, 0x7CAB, 0x7CAC, 0x7CAD, 0x7CAF, 0x7CB0, 0x7CB4, 0x7CB5, 0x7CB6, 0x7CB7, 0x7CB8, 0x7CBA, - 0x7CBB, 0x5F27, 0x864E, 0x552C, 0x62A4, 0x4E92, 0x6CAA, 0x6237, 0x82B1, 0x54D7, 0x534E, 0x733E, 0x6ED1, 0x753B, 0x5212, 0x5316, - 0x8BDD, 0x69D0, 0x5F8A, 0x6000, 0x6DEE, 0x574F, 0x6B22, 0x73AF, 0x6853, 0x8FD8, 0x7F13, 0x6362, 0x60A3, 0x5524, 0x75EA, 0x8C62, - 0x7115, 0x6DA3, 0x5BA6, 0x5E7B, 0x8352, 0x614C, 0x9EC4, 0x78FA, 0x8757, 0x7C27, 0x7687, 0x51F0, 0x60F6, 0x714C, 0x6643, 0x5E4C, - 0x604D, 0x8C0E, 0x7070, 0x6325, 0x8F89, 0x5FBD, 0x6062, 0x86D4, 0x56DE, 0x6BC1, 0x6094, 0x6167, 0x5349, 0x60E0, 0x6666, 0x8D3F, - 0x79FD, 0x4F1A, 0x70E9, 0x6C47, 0x8BB3, 0x8BF2, 0x7ED8, 0x8364, 0x660F, 0x5A5A, 0x9B42, 0x6D51, 0x6DF7, 0x8C41, 0x6D3B, 0x4F19, - 0x706B, 0x83B7, 0x6216, 0x60D1, 0x970D, 0x8D27, 0x7978, 0x51FB, 0x573E, 0x57FA, 0x673A, 0x7578, 0x7A3D, 0x79EF, 0x7B95, - // GB 0xBC40..0xBC7E - 0x7CBF, 0x7CC0, 0x7CC2, 0x7CC3, 0x7CC4, 0x7CC6, 0x7CC9, 0x7CCB, - 0x7CCE, 0x7CCF, 0x7CD0, 0x7CD1, 0x7CD2, 0x7CD3, 0x7CD4, 0x7CD8, 0x7CDA, 0x7CDB, 0x7CDD, 0x7CDE, 0x7CE1, 0x7CE2, 0x7CE3, 0x7CE4, - 0x7CE5, 0x7CE6, 0x7CE7, 0x7CE9, 0x7CEA, 0x7CEB, 0x7CEC, 0x7CED, 0x7CEE, 0x7CF0, 0x7CF1, 0x7CF2, 0x7CF3, 0x7CF4, 0x7CF5, 0x7CF6, - 0x7CF7, 0x7CF9, 0x7CFA, 0x7CFC, 0x7CFD, 0x7CFE, 0x7CFF, 0x7D00, 0x7D01, 0x7D02, 0x7D03, 0x7D04, 0x7D05, 0x7D06, 0x7D07, 0x7D08, - 0x7D09, 0x7D0B, 0x7D0C, 0x7D0D, 0x7D0E, 0x7D0F, 0x7D10, - // GB 0xBC80..0xBCFE - 0x7D11, 0x7D12, 0x7D13, 0x7D14, 0x7D15, 0x7D16, 0x7D17, 0x7D18, 0x7D19, 0x7D1A, 0x7D1B, 0x7D1C, 0x7D1D, 0x7D1E, 0x7D1F, 0x7D21, - 0x7D23, 0x7D24, 0x7D25, 0x7D26, 0x7D28, 0x7D29, 0x7D2A, 0x7D2C, 0x7D2D, 0x7D2E, 0x7D30, 0x7D31, 0x7D32, 0x7D33, 0x7D34, 0x7D35, - 0x7D36, 0x808C, 0x9965, 0x8FF9, 0x6FC0, 0x8BA5, 0x9E21, 0x59EC, 0x7EE9, 0x7F09, 0x5409, 0x6781, 0x68D8, 0x8F91, 0x7C4D, 0x96C6, - 0x53CA, 0x6025, 0x75BE, 0x6C72, 0x5373, 0x5AC9, 0x7EA7, 0x6324, 0x51E0, 0x810A, 0x5DF1, 0x84DF, 0x6280, 0x5180, 0x5B63, 0x4F0E, - 0x796D, 0x5242, 0x60B8, 0x6D4E, 0x5BC4, 0x5BC2, 0x8BA1, 0x8BB0, 0x65E2, 0x5FCC, 0x9645, 0x5993, 0x7EE7, 0x7EAA, 0x5609, 0x67B7, - 0x5939, 0x4F73, 0x5BB6, 0x52A0, 0x835A, 0x988A, 0x8D3E, 0x7532, 0x94BE, 0x5047, 0x7A3C, 0x4EF7, 0x67B6, 0x9A7E, 0x5AC1, 0x6B7C, - 0x76D1, 0x575A, 0x5C16, 0x7B3A, 0x95F4, 0x714E, 0x517C, 0x80A9, 0x8270, 0x5978, 0x7F04, 0x8327, 0x68C0, 0x67EC, 0x78B1, 0x7877, - 0x62E3, 0x6361, 0x7B80, 0x4FED, 0x526A, 0x51CF, 0x8350, 0x69DB, 0x9274, 0x8DF5, 0x8D31, 0x89C1, 0x952E, 0x7BAD, 0x4EF6, - // GB 0xBD40..0xBD7E - 0x7D37, 0x7D38, 0x7D39, 0x7D3A, 0x7D3B, 0x7D3C, 0x7D3D, 0x7D3E, - 0x7D3F, 0x7D40, 0x7D41, 0x7D42, 0x7D43, 0x7D44, 0x7D45, 0x7D46, 0x7D47, 0x7D48, 0x7D49, 0x7D4A, 0x7D4B, 0x7D4C, 0x7D4D, 0x7D4E, - 0x7D4F, 0x7D50, 0x7D51, 0x7D52, 0x7D53, 0x7D54, 0x7D55, 0x7D56, 0x7D57, 0x7D58, 0x7D59, 0x7D5A, 0x7D5B, 0x7D5C, 0x7D5D, 0x7D5E, - 0x7D5F, 0x7D60, 0x7D61, 0x7D62, 0x7D63, 0x7D64, 0x7D65, 0x7D66, 0x7D67, 0x7D68, 0x7D69, 0x7D6A, 0x7D6B, 0x7D6C, 0x7D6D, 0x7D6F, - 0x7D70, 0x7D71, 0x7D72, 0x7D73, 0x7D74, 0x7D75, 0x7D76, - // GB 0xBD80..0xBDFE - 0x7D78, 0x7D79, 0x7D7A, 0x7D7B, 0x7D7C, 0x7D7D, 0x7D7E, 0x7D7F, 0x7D80, 0x7D81, 0x7D82, 0x7D83, 0x7D84, 0x7D85, 0x7D86, 0x7D87, - 0x7D88, 0x7D89, 0x7D8A, 0x7D8B, 0x7D8C, 0x7D8D, 0x7D8E, 0x7D8F, 0x7D90, 0x7D91, 0x7D92, 0x7D93, 0x7D94, 0x7D95, 0x7D96, 0x7D97, - 0x7D98, 0x5065, 0x8230, 0x5251, 0x996F, 0x6E10, 0x6E85, 0x6DA7, 0x5EFA, 0x50F5, 0x59DC, 0x5C06, 0x6D46, 0x6C5F, 0x7586, 0x848B, - 0x6868, 0x5956, 0x8BB2, 0x5320, 0x9171, 0x964D, 0x8549, 0x6912, 0x7901, 0x7126, 0x80F6, 0x4EA4, 0x90CA, 0x6D47, 0x9A84, 0x5A07, - 0x56BC, 0x6405, 0x94F0, 0x77EB, 0x4FA5, 0x811A, 0x72E1, 0x89D2, 0x997A, 0x7F34, 0x7EDE, 0x527F, 0x6559, 0x9175, 0x8F7F, 0x8F83, - 0x53EB, 0x7A96, 0x63ED, 0x63A5, 0x7686, 0x79F8, 0x8857, 0x9636, 0x622A, 0x52AB, 0x8282, 0x6854, 0x6770, 0x6377, 0x776B, 0x7AED, - 0x6D01, 0x7ED3, 0x89E3, 0x59D0, 0x6212, 0x85C9, 0x82A5, 0x754C, 0x501F, 0x4ECB, 0x75A5, 0x8BEB, 0x5C4A, 0x5DFE, 0x7B4B, 0x65A4, - 0x91D1, 0x4ECA, 0x6D25, 0x895F, 0x7D27, 0x9526, 0x4EC5, 0x8C28, 0x8FDB, 0x9773, 0x664B, 0x7981, 0x8FD1, 0x70EC, 0x6D78, - // GB 0xBE40..0xBE7E - 0x7D99, 0x7D9A, 0x7D9B, 0x7D9C, 0x7D9D, 0x7D9E, 0x7D9F, 0x7DA0, - 0x7DA1, 0x7DA2, 0x7DA3, 0x7DA4, 0x7DA5, 0x7DA7, 0x7DA8, 0x7DA9, 0x7DAA, 0x7DAB, 0x7DAC, 0x7DAD, 0x7DAF, 0x7DB0, 0x7DB1, 0x7DB2, - 0x7DB3, 0x7DB4, 0x7DB5, 0x7DB6, 0x7DB7, 0x7DB8, 0x7DB9, 0x7DBA, 0x7DBB, 0x7DBC, 0x7DBD, 0x7DBE, 0x7DBF, 0x7DC0, 0x7DC1, 0x7DC2, - 0x7DC3, 0x7DC4, 0x7DC5, 0x7DC6, 0x7DC7, 0x7DC8, 0x7DC9, 0x7DCA, 0x7DCB, 0x7DCC, 0x7DCD, 0x7DCE, 0x7DCF, 0x7DD0, 0x7DD1, 0x7DD2, - 0x7DD3, 0x7DD4, 0x7DD5, 0x7DD6, 0x7DD7, 0x7DD8, 0x7DD9, - // GB 0xBE80..0xBEFE - 0x7DDA, 0x7DDB, 0x7DDC, 0x7DDD, 0x7DDE, 0x7DDF, 0x7DE0, 0x7DE1, 0x7DE2, 0x7DE3, 0x7DE4, 0x7DE5, 0x7DE6, 0x7DE7, 0x7DE8, 0x7DE9, - 0x7DEA, 0x7DEB, 0x7DEC, 0x7DED, 0x7DEE, 0x7DEF, 0x7DF0, 0x7DF1, 0x7DF2, 0x7DF3, 0x7DF4, 0x7DF5, 0x7DF6, 0x7DF7, 0x7DF8, 0x7DF9, - 0x7DFA, 0x5C3D, 0x52B2, 0x8346, 0x5162, 0x830E, 0x775B, 0x6676, 0x9CB8, 0x4EAC, 0x60CA, 0x7CBE, 0x7CB3, 0x7ECF, 0x4E95, 0x8B66, - 0x666F, 0x9888, 0x9759, 0x5883, 0x656C, 0x955C, 0x5F84, 0x75C9, 0x9756, 0x7ADF, 0x7ADE, 0x51C0, 0x70AF, 0x7A98, 0x63EA, 0x7A76, - 0x7EA0, 0x7396, 0x97ED, 0x4E45, 0x7078, 0x4E5D, 0x9152, 0x53A9, 0x6551, 0x65E7, 0x81FC, 0x8205, 0x548E, 0x5C31, 0x759A, 0x97A0, - 0x62D8, 0x72D9, 0x75BD, 0x5C45, 0x9A79, 0x83CA, 0x5C40, 0x5480, 0x77E9, 0x4E3E, 0x6CAE, 0x805A, 0x62D2, 0x636E, 0x5DE8, 0x5177, - 0x8DDD, 0x8E1E, 0x952F, 0x4FF1, 0x53E5, 0x60E7, 0x70AC, 0x5267, 0x6350, 0x9E43, 0x5A1F, 0x5026, 0x7737, 0x5377, 0x7EE2, 0x6485, - 0x652B, 0x6289, 0x6398, 0x5014, 0x7235, 0x89C9, 0x51B3, 0x8BC0, 0x7EDD, 0x5747, 0x83CC, 0x94A7, 0x519B, 0x541B, 0x5CFB, - // GB 0xBF40..0xBF7E - 0x7DFB, 0x7DFC, 0x7DFD, 0x7DFE, 0x7DFF, 0x7E00, 0x7E01, 0x7E02, - 0x7E03, 0x7E04, 0x7E05, 0x7E06, 0x7E07, 0x7E08, 0x7E09, 0x7E0A, 0x7E0B, 0x7E0C, 0x7E0D, 0x7E0E, 0x7E0F, 0x7E10, 0x7E11, 0x7E12, - 0x7E13, 0x7E14, 0x7E15, 0x7E16, 0x7E17, 0x7E18, 0x7E19, 0x7E1A, 0x7E1B, 0x7E1C, 0x7E1D, 0x7E1E, 0x7E1F, 0x7E20, 0x7E21, 0x7E22, - 0x7E23, 0x7E24, 0x7E25, 0x7E26, 0x7E27, 0x7E28, 0x7E29, 0x7E2A, 0x7E2B, 0x7E2C, 0x7E2D, 0x7E2E, 0x7E2F, 0x7E30, 0x7E31, 0x7E32, - 0x7E33, 0x7E34, 0x7E35, 0x7E36, 0x7E37, 0x7E38, 0x7E39, - // GB 0xBF80..0xBFFE - 0x7E3A, 0x7E3C, 0x7E3D, 0x7E3E, 0x7E3F, 0x7E40, 0x7E42, 0x7E43, 0x7E44, 0x7E45, 0x7E46, 0x7E48, 0x7E49, 0x7E4A, 0x7E4B, 0x7E4C, - 0x7E4D, 0x7E4E, 0x7E4F, 0x7E50, 0x7E51, 0x7E52, 0x7E53, 0x7E54, 0x7E55, 0x7E56, 0x7E57, 0x7E58, 0x7E59, 0x7E5A, 0x7E5B, 0x7E5C, - 0x7E5D, 0x4FCA, 0x7AE3, 0x6D5A, 0x90E1, 0x9A8F, 0x5580, 0x5496, 0x5361, 0x54AF, 0x5F00, 0x63E9, 0x6977, 0x51EF, 0x6168, 0x520A, - 0x582A, 0x52D8, 0x574E, 0x780D, 0x770B, 0x5EB7, 0x6177, 0x7CE0, 0x625B, 0x6297, 0x4EA2, 0x7095, 0x8003, 0x62F7, 0x70E4, 0x9760, - 0x5777, 0x82DB, 0x67EF, 0x68F5, 0x78D5, 0x9897, 0x79D1, 0x58F3, 0x54B3, 0x53EF, 0x6E34, 0x514B, 0x523B, 0x5BA2, 0x8BFE, 0x80AF, - 0x5543, 0x57A6, 0x6073, 0x5751, 0x542D, 0x7A7A, 0x6050, 0x5B54, 0x63A7, 0x62A0, 0x53E3, 0x6263, 0x5BC7, 0x67AF, 0x54ED, 0x7A9F, - 0x82E6, 0x9177, 0x5E93, 0x88E4, 0x5938, 0x57AE, 0x630E, 0x8DE8, 0x80EF, 0x5757, 0x7B77, 0x4FA9, 0x5FEB, 0x5BBD, 0x6B3E, 0x5321, - 0x7B50, 0x72C2, 0x6846, 0x77FF, 0x7736, 0x65F7, 0x51B5, 0x4E8F, 0x76D4, 0x5CBF, 0x7AA5, 0x8475, 0x594E, 0x9B41, 0x5080, - // GB 0xC040..0xC07E - 0x7E5E, 0x7E5F, 0x7E60, 0x7E61, 0x7E62, 0x7E63, 0x7E64, 0x7E65, - 0x7E66, 0x7E67, 0x7E68, 0x7E69, 0x7E6A, 0x7E6B, 0x7E6C, 0x7E6D, 0x7E6E, 0x7E6F, 0x7E70, 0x7E71, 0x7E72, 0x7E73, 0x7E74, 0x7E75, - 0x7E76, 0x7E77, 0x7E78, 0x7E79, 0x7E7A, 0x7E7B, 0x7E7C, 0x7E7D, 0x7E7E, 0x7E7F, 0x7E80, 0x7E81, 0x7E83, 0x7E84, 0x7E85, 0x7E86, - 0x7E87, 0x7E88, 0x7E89, 0x7E8A, 0x7E8B, 0x7E8C, 0x7E8D, 0x7E8E, 0x7E8F, 0x7E90, 0x7E91, 0x7E92, 0x7E93, 0x7E94, 0x7E95, 0x7E96, - 0x7E97, 0x7E98, 0x7E99, 0x7E9A, 0x7E9C, 0x7E9D, 0x7E9E, - // GB 0xC080..0xC0FE - 0x7EAE, 0x7EB4, 0x7EBB, 0x7EBC, 0x7ED6, 0x7EE4, 0x7EEC, 0x7EF9, 0x7F0A, 0x7F10, 0x7F1E, 0x7F37, 0x7F39, 0x7F3B, 0x7F3C, 0x7F3D, - 0x7F3E, 0x7F3F, 0x7F40, 0x7F41, 0x7F43, 0x7F46, 0x7F47, 0x7F48, 0x7F49, 0x7F4A, 0x7F4B, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F4F, 0x7F52, - 0x7F53, 0x9988, 0x6127, 0x6E83, 0x5764, 0x6606, 0x6346, 0x56F0, 0x62EC, 0x6269, 0x5ED3, 0x9614, 0x5783, 0x62C9, 0x5587, 0x8721, - 0x814A, 0x8FA3, 0x5566, 0x83B1, 0x6765, 0x8D56, 0x84DD, 0x5A6A, 0x680F, 0x62E6, 0x7BEE, 0x9611, 0x5170, 0x6F9C, 0x8C30, 0x63FD, - 0x89C8, 0x61D2, 0x7F06, 0x70C2, 0x6EE5, 0x7405, 0x6994, 0x72FC, 0x5ECA, 0x90CE, 0x6717, 0x6D6A, 0x635E, 0x52B3, 0x7262, 0x8001, - 0x4F6C, 0x59E5, 0x916A, 0x70D9, 0x6D9D, 0x52D2, 0x4E50, 0x96F7, 0x956D, 0x857E, 0x78CA, 0x7D2F, 0x5121, 0x5792, 0x64C2, 0x808B, - 0x7C7B, 0x6CEA, 0x68F1, 0x695E, 0x51B7, 0x5398, 0x68A8, 0x7281, 0x9ECE, 0x7BF1, 0x72F8, 0x79BB, 0x6F13, 0x7406, 0x674E, 0x91CC, - 0x9CA4, 0x793C, 0x8389, 0x8354, 0x540F, 0x6817, 0x4E3D, 0x5389, 0x52B1, 0x783E, 0x5386, 0x5229, 0x5088, 0x4F8B, 0x4FD0, - // GB 0xC140..0xC17E - 0x7F56, 0x7F59, 0x7F5B, 0x7F5C, 0x7F5D, 0x7F5E, 0x7F60, 0x7F63, - 0x7F64, 0x7F65, 0x7F66, 0x7F67, 0x7F6B, 0x7F6C, 0x7F6D, 0x7F6F, 0x7F70, 0x7F73, 0x7F75, 0x7F76, 0x7F77, 0x7F78, 0x7F7A, 0x7F7B, - 0x7F7C, 0x7F7D, 0x7F7F, 0x7F80, 0x7F82, 0x7F83, 0x7F84, 0x7F85, 0x7F86, 0x7F87, 0x7F88, 0x7F89, 0x7F8B, 0x7F8D, 0x7F8F, 0x7F90, - 0x7F91, 0x7F92, 0x7F93, 0x7F95, 0x7F96, 0x7F97, 0x7F98, 0x7F99, 0x7F9B, 0x7F9C, 0x7FA0, 0x7FA2, 0x7FA3, 0x7FA5, 0x7FA6, 0x7FA8, - 0x7FA9, 0x7FAA, 0x7FAB, 0x7FAC, 0x7FAD, 0x7FAE, 0x7FB1, - // GB 0xC180..0xC1FE - 0x7FB3, 0x7FB4, 0x7FB5, 0x7FB6, 0x7FB7, 0x7FBA, 0x7FBB, 0x7FBE, 0x7FC0, 0x7FC2, 0x7FC3, 0x7FC4, 0x7FC6, 0x7FC7, 0x7FC8, 0x7FC9, - 0x7FCB, 0x7FCD, 0x7FCF, 0x7FD0, 0x7FD1, 0x7FD2, 0x7FD3, 0x7FD6, 0x7FD7, 0x7FD9, 0x7FDA, 0x7FDB, 0x7FDC, 0x7FDD, 0x7FDE, 0x7FE2, - 0x7FE3, 0x75E2, 0x7ACB, 0x7C92, 0x6CA5, 0x96B6, 0x529B, 0x7483, 0x54E9, 0x4FE9, 0x8054, 0x83B2, 0x8FDE, 0x9570, 0x5EC9, 0x601C, - 0x6D9F, 0x5E18, 0x655B, 0x8138, 0x94FE, 0x604B, 0x70BC, 0x7EC3, 0x7CAE, 0x51C9, 0x6881, 0x7CB1, 0x826F, 0x4E24, 0x8F86, 0x91CF, - 0x667E, 0x4EAE, 0x8C05, 0x64A9, 0x804A, 0x50DA, 0x7597, 0x71CE, 0x5BE5, 0x8FBD, 0x6F66, 0x4E86, 0x6482, 0x9563, 0x5ED6, 0x6599, - 0x5217, 0x88C2, 0x70C8, 0x52A3, 0x730E, 0x7433, 0x6797, 0x78F7, 0x9716, 0x4E34, 0x90BB, 0x9CDE, 0x6DCB, 0x51DB, 0x8D41, 0x541D, - 0x62CE, 0x73B2, 0x83F1, 0x96F6, 0x9F84, 0x94C3, 0x4F36, 0x7F9A, 0x51CC, 0x7075, 0x9675, 0x5CAD, 0x9886, 0x53E6, 0x4EE4, 0x6E9C, - 0x7409, 0x69B4, 0x786B, 0x998F, 0x7559, 0x5218, 0x7624, 0x6D41, 0x67F3, 0x516D, 0x9F99, 0x804B, 0x5499, 0x7B3C, 0x7ABF, - // GB 0xC240..0xC27E - 0x7FE4, 0x7FE7, 0x7FE8, 0x7FEA, 0x7FEB, 0x7FEC, 0x7FED, 0x7FEF, - 0x7FF2, 0x7FF4, 0x7FF5, 0x7FF6, 0x7FF7, 0x7FF8, 0x7FF9, 0x7FFA, 0x7FFD, 0x7FFE, 0x7FFF, 0x8002, 0x8007, 0x8008, 0x8009, 0x800A, - 0x800E, 0x800F, 0x8011, 0x8013, 0x801A, 0x801B, 0x801D, 0x801E, 0x801F, 0x8021, 0x8023, 0x8024, 0x802B, 0x802C, 0x802D, 0x802E, - 0x802F, 0x8030, 0x8032, 0x8034, 0x8039, 0x803A, 0x803C, 0x803E, 0x8040, 0x8041, 0x8044, 0x8045, 0x8047, 0x8048, 0x8049, 0x804E, - 0x804F, 0x8050, 0x8051, 0x8053, 0x8055, 0x8056, 0x8057, - // GB 0xC280..0xC2FE - 0x8059, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063, 0x8064, 0x8065, 0x8066, 0x8067, 0x8068, 0x806B, - 0x806C, 0x806D, 0x806E, 0x806F, 0x8070, 0x8072, 0x8073, 0x8074, 0x8075, 0x8076, 0x8077, 0x8078, 0x8079, 0x807A, 0x807B, 0x807C, - 0x807D, 0x9686, 0x5784, 0x62E2, 0x9647, 0x697C, 0x5A04, 0x6402, 0x7BD3, 0x6F0F, 0x964B, 0x82A6, 0x5362, 0x9885, 0x5E90, 0x7089, - 0x63B3, 0x5364, 0x864F, 0x9C81, 0x9E93, 0x788C, 0x9732, 0x8DEF, 0x8D42, 0x9E7F, 0x6F5E, 0x7984, 0x5F55, 0x9646, 0x622E, 0x9A74, - 0x5415, 0x94DD, 0x4FA3, 0x65C5, 0x5C65, 0x5C61, 0x7F15, 0x8651, 0x6C2F, 0x5F8B, 0x7387, 0x6EE4, 0x7EFF, 0x5CE6, 0x631B, 0x5B6A, - 0x6EE6, 0x5375, 0x4E71, 0x63A0, 0x7565, 0x62A1, 0x8F6E, 0x4F26, 0x4ED1, 0x6CA6, 0x7EB6, 0x8BBA, 0x841D, 0x87BA, 0x7F57, 0x903B, - 0x9523, 0x7BA9, 0x9AA1, 0x88F8, 0x843D, 0x6D1B, 0x9A86, 0x7EDC, 0x5988, 0x9EBB, 0x739B, 0x7801, 0x8682, 0x9A6C, 0x9A82, 0x561B, - 0x5417, 0x57CB, 0x4E70, 0x9EA6, 0x5356, 0x8FC8, 0x8109, 0x7792, 0x9992, 0x86EE, 0x6EE1, 0x8513, 0x66FC, 0x6162, 0x6F2B, - // GB 0xC340..0xC37E - 0x807E, 0x8081, 0x8082, 0x8085, 0x8088, 0x808A, 0x808D, 0x808E, - 0x808F, 0x8090, 0x8091, 0x8092, 0x8094, 0x8095, 0x8097, 0x8099, 0x809E, 0x80A3, 0x80A6, 0x80A7, 0x80A8, 0x80AC, 0x80B0, 0x80B3, - 0x80B5, 0x80B6, 0x80B8, 0x80B9, 0x80BB, 0x80C5, 0x80C7, 0x80C8, 0x80C9, 0x80CA, 0x80CB, 0x80CF, 0x80D0, 0x80D1, 0x80D2, 0x80D3, - 0x80D4, 0x80D5, 0x80D8, 0x80DF, 0x80E0, 0x80E2, 0x80E3, 0x80E6, 0x80EE, 0x80F5, 0x80F7, 0x80F9, 0x80FB, 0x80FE, 0x80FF, 0x8100, - 0x8101, 0x8103, 0x8104, 0x8105, 0x8107, 0x8108, 0x810B, - // GB 0xC380..0xC3FE - 0x810C, 0x8115, 0x8117, 0x8119, 0x811B, 0x811C, 0x811D, 0x811F, 0x8120, 0x8121, 0x8122, 0x8123, 0x8124, 0x8125, 0x8126, 0x8127, - 0x8128, 0x8129, 0x812A, 0x812B, 0x812D, 0x812E, 0x8130, 0x8133, 0x8134, 0x8135, 0x8137, 0x8139, 0x813A, 0x813B, 0x813C, 0x813D, - 0x813F, 0x8C29, 0x8292, 0x832B, 0x76F2, 0x6C13, 0x5FD9, 0x83BD, 0x732B, 0x8305, 0x951A, 0x6BDB, 0x77DB, 0x94C6, 0x536F, 0x8302, - 0x5192, 0x5E3D, 0x8C8C, 0x8D38, 0x4E48, 0x73AB, 0x679A, 0x6885, 0x9176, 0x9709, 0x7164, 0x6CA1, 0x7709, 0x5A92, 0x9541, 0x6BCF, - 0x7F8E, 0x6627, 0x5BD0, 0x59B9, 0x5A9A, 0x95E8, 0x95F7, 0x4EEC, 0x840C, 0x8499, 0x6AAC, 0x76DF, 0x9530, 0x731B, 0x68A6, 0x5B5F, - 0x772F, 0x919A, 0x9761, 0x7CDC, 0x8FF7, 0x8C1C, 0x5F25, 0x7C73, 0x79D8, 0x89C5, 0x6CCC, 0x871C, 0x5BC6, 0x5E42, 0x68C9, 0x7720, - 0x7EF5, 0x5195, 0x514D, 0x52C9, 0x5A29, 0x7F05, 0x9762, 0x82D7, 0x63CF, 0x7784, 0x85D0, 0x79D2, 0x6E3A, 0x5E99, 0x5999, 0x8511, - 0x706D, 0x6C11, 0x62BF, 0x76BF, 0x654F, 0x60AF, 0x95FD, 0x660E, 0x879F, 0x9E23, 0x94ED, 0x540D, 0x547D, 0x8C2C, 0x6478, - // GB 0xC440..0xC47E - 0x8140, 0x8141, 0x8142, 0x8143, 0x8144, 0x8145, 0x8147, 0x8149, - 0x814D, 0x814E, 0x814F, 0x8152, 0x8156, 0x8157, 0x8158, 0x815B, 0x815C, 0x815D, 0x815E, 0x815F, 0x8161, 0x8162, 0x8163, 0x8164, - 0x8166, 0x8168, 0x816A, 0x816B, 0x816C, 0x816F, 0x8172, 0x8173, 0x8175, 0x8176, 0x8177, 0x8178, 0x8181, 0x8183, 0x8184, 0x8185, - 0x8186, 0x8187, 0x8189, 0x818B, 0x818C, 0x818D, 0x818E, 0x8190, 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8199, 0x819A, - 0x819E, 0x819F, 0x81A0, 0x81A1, 0x81A2, 0x81A4, 0x81A5, - // GB 0xC480..0xC4FE - 0x81A7, 0x81A9, 0x81AB, 0x81AC, 0x81AD, 0x81AE, 0x81AF, 0x81B0, 0x81B1, 0x81B2, 0x81B4, 0x81B5, 0x81B6, 0x81B7, 0x81B8, 0x81B9, - 0x81BC, 0x81BD, 0x81BE, 0x81BF, 0x81C4, 0x81C5, 0x81C7, 0x81C8, 0x81C9, 0x81CB, 0x81CD, 0x81CE, 0x81CF, 0x81D0, 0x81D1, 0x81D2, - 0x81D3, 0x6479, 0x8611, 0x6A21, 0x819C, 0x78E8, 0x6469, 0x9B54, 0x62B9, 0x672B, 0x83AB, 0x58A8, 0x9ED8, 0x6CAB, 0x6F20, 0x5BDE, - 0x964C, 0x8C0B, 0x725F, 0x67D0, 0x62C7, 0x7261, 0x4EA9, 0x59C6, 0x6BCD, 0x5893, 0x66AE, 0x5E55, 0x52DF, 0x6155, 0x6728, 0x76EE, - 0x7766, 0x7267, 0x7A46, 0x62FF, 0x54EA, 0x5450, 0x94A0, 0x90A3, 0x5A1C, 0x7EB3, 0x6C16, 0x4E43, 0x5976, 0x8010, 0x5948, 0x5357, - 0x7537, 0x96BE, 0x56CA, 0x6320, 0x8111, 0x607C, 0x95F9, 0x6DD6, 0x5462, 0x9981, 0x5185, 0x5AE9, 0x80FD, 0x59AE, 0x9713, 0x502A, - 0x6CE5, 0x5C3C, 0x62DF, 0x4F60, 0x533F, 0x817B, 0x9006, 0x6EBA, 0x852B, 0x62C8, 0x5E74, 0x78BE, 0x64B5, 0x637B, 0x5FF5, 0x5A18, - 0x917F, 0x9E1F, 0x5C3F, 0x634F, 0x8042, 0x5B7D, 0x556E, 0x954A, 0x954D, 0x6D85, 0x60A8, 0x67E0, 0x72DE, 0x51DD, 0x5B81, - // GB 0xC540..0xC57E - 0x81D4, 0x81D5, 0x81D6, 0x81D7, 0x81D8, 0x81D9, 0x81DA, 0x81DB, - 0x81DC, 0x81DD, 0x81DE, 0x81DF, 0x81E0, 0x81E1, 0x81E2, 0x81E4, 0x81E5, 0x81E6, 0x81E8, 0x81E9, 0x81EB, 0x81EE, 0x81EF, 0x81F0, - 0x81F1, 0x81F2, 0x81F5, 0x81F6, 0x81F7, 0x81F8, 0x81F9, 0x81FA, 0x81FD, 0x81FF, 0x8203, 0x8207, 0x8208, 0x8209, 0x820A, 0x820B, - 0x820E, 0x820F, 0x8211, 0x8213, 0x8215, 0x8216, 0x8217, 0x8218, 0x8219, 0x821A, 0x821D, 0x8220, 0x8224, 0x8225, 0x8226, 0x8227, - 0x8229, 0x822E, 0x8232, 0x823A, 0x823C, 0x823D, 0x823F, - // GB 0xC580..0xC5FE - 0x8240, 0x8241, 0x8242, 0x8243, 0x8245, 0x8246, 0x8248, 0x824A, 0x824C, 0x824D, 0x824E, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, - 0x8255, 0x8256, 0x8257, 0x8259, 0x825B, 0x825C, 0x825D, 0x825E, 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, - 0x8269, 0x62E7, 0x6CDE, 0x725B, 0x626D, 0x94AE, 0x7EBD, 0x8113, 0x6D53, 0x519C, 0x5F04, 0x5974, 0x52AA, 0x6012, 0x5973, 0x6696, - 0x8650, 0x759F, 0x632A, 0x61E6, 0x7CEF, 0x8BFA, 0x54E6, 0x6B27, 0x9E25, 0x6BB4, 0x85D5, 0x5455, 0x5076, 0x6CA4, 0x556A, 0x8DB4, - 0x722C, 0x5E15, 0x6015, 0x7436, 0x62CD, 0x6392, 0x724C, 0x5F98, 0x6E43, 0x6D3E, 0x6500, 0x6F58, 0x76D8, 0x78D0, 0x76FC, 0x7554, - 0x5224, 0x53DB, 0x4E53, 0x5E9E, 0x65C1, 0x802A, 0x80D6, 0x629B, 0x5486, 0x5228, 0x70AE, 0x888D, 0x8DD1, 0x6CE1, 0x5478, 0x80DA, - 0x57F9, 0x88F4, 0x8D54, 0x966A, 0x914D, 0x4F69, 0x6C9B, 0x55B7, 0x76C6, 0x7830, 0x62A8, 0x70F9, 0x6F8E, 0x5F6D, 0x84EC, 0x68DA, - 0x787C, 0x7BF7, 0x81A8, 0x670B, 0x9E4F, 0x6367, 0x78B0, 0x576F, 0x7812, 0x9739, 0x6279, 0x62AB, 0x5288, 0x7435, 0x6BD7, - // GB 0xC640..0xC67E - 0x826A, 0x826B, 0x826C, 0x826D, 0x8271, 0x8275, 0x8276, 0x8277, - 0x8278, 0x827B, 0x827C, 0x8280, 0x8281, 0x8283, 0x8285, 0x8286, 0x8287, 0x8289, 0x828C, 0x8290, 0x8293, 0x8294, 0x8295, 0x8296, - 0x829A, 0x829B, 0x829E, 0x82A0, 0x82A2, 0x82A3, 0x82A7, 0x82B2, 0x82B5, 0x82B6, 0x82BA, 0x82BB, 0x82BC, 0x82BF, 0x82C0, 0x82C2, - 0x82C3, 0x82C5, 0x82C6, 0x82C9, 0x82D0, 0x82D6, 0x82D9, 0x82DA, 0x82DD, 0x82E2, 0x82E7, 0x82E8, 0x82E9, 0x82EA, 0x82EC, 0x82ED, - 0x82EE, 0x82F0, 0x82F2, 0x82F3, 0x82F5, 0x82F6, 0x82F8, - // GB 0xC680..0xC6FE - 0x82FA, 0x82FC, 0x82FD, 0x82FE, 0x82FF, 0x8300, 0x830A, 0x830B, 0x830D, 0x8310, 0x8312, 0x8313, 0x8316, 0x8318, 0x8319, 0x831D, - 0x831E, 0x831F, 0x8320, 0x8321, 0x8322, 0x8323, 0x8324, 0x8325, 0x8326, 0x8329, 0x832A, 0x832E, 0x8330, 0x8332, 0x8337, 0x833B, - 0x833D, 0x5564, 0x813E, 0x75B2, 0x76AE, 0x5339, 0x75DE, 0x50FB, 0x5C41, 0x8B6C, 0x7BC7, 0x504F, 0x7247, 0x9A97, 0x98D8, 0x6F02, - 0x74E2, 0x7968, 0x6487, 0x77A5, 0x62FC, 0x9891, 0x8D2B, 0x54C1, 0x8058, 0x4E52, 0x576A, 0x82F9, 0x840D, 0x5E73, 0x51ED, 0x74F6, - 0x8BC4, 0x5C4F, 0x5761, 0x6CFC, 0x9887, 0x5A46, 0x7834, 0x9B44, 0x8FEB, 0x7C95, 0x5256, 0x6251, 0x94FA, 0x4EC6, 0x8386, 0x8461, - 0x83E9, 0x84B2, 0x57D4, 0x6734, 0x5703, 0x666E, 0x6D66, 0x8C31, 0x66DD, 0x7011, 0x671F, 0x6B3A, 0x6816, 0x621A, 0x59BB, 0x4E03, - 0x51C4, 0x6F06, 0x67D2, 0x6C8F, 0x5176, 0x68CB, 0x5947, 0x6B67, 0x7566, 0x5D0E, 0x8110, 0x9F50, 0x65D7, 0x7948, 0x7941, 0x9A91, - 0x8D77, 0x5C82, 0x4E5E, 0x4F01, 0x542F, 0x5951, 0x780C, 0x5668, 0x6C14, 0x8FC4, 0x5F03, 0x6C7D, 0x6CE3, 0x8BAB, 0x6390, - // GB 0xC740..0xC77E - 0x833E, 0x833F, 0x8341, 0x8342, 0x8344, 0x8345, 0x8348, 0x834A, - 0x834B, 0x834C, 0x834D, 0x834E, 0x8353, 0x8355, 0x8356, 0x8357, 0x8358, 0x8359, 0x835D, 0x8362, 0x8370, 0x8371, 0x8372, 0x8373, - 0x8374, 0x8375, 0x8376, 0x8379, 0x837A, 0x837E, 0x837F, 0x8380, 0x8381, 0x8382, 0x8383, 0x8384, 0x8387, 0x8388, 0x838A, 0x838B, - 0x838C, 0x838D, 0x838F, 0x8390, 0x8391, 0x8394, 0x8395, 0x8396, 0x8397, 0x8399, 0x839A, 0x839D, 0x839F, 0x83A1, 0x83A2, 0x83A3, - 0x83A4, 0x83A5, 0x83A6, 0x83A7, 0x83AC, 0x83AD, 0x83AE, - // GB 0xC780..0xC7FE - 0x83AF, 0x83B5, 0x83BB, 0x83BE, 0x83BF, 0x83C2, 0x83C3, 0x83C4, 0x83C6, 0x83C8, 0x83C9, 0x83CB, 0x83CD, 0x83CE, 0x83D0, 0x83D1, - 0x83D2, 0x83D3, 0x83D5, 0x83D7, 0x83D9, 0x83DA, 0x83DB, 0x83DE, 0x83E2, 0x83E3, 0x83E4, 0x83E6, 0x83E7, 0x83E8, 0x83EB, 0x83EC, - 0x83ED, 0x6070, 0x6D3D, 0x7275, 0x6266, 0x948E, 0x94C5, 0x5343, 0x8FC1, 0x7B7E, 0x4EDF, 0x8C26, 0x4E7E, 0x9ED4, 0x94B1, 0x94B3, - 0x524D, 0x6F5C, 0x9063, 0x6D45, 0x8C34, 0x5811, 0x5D4C, 0x6B20, 0x6B49, 0x67AA, 0x545B, 0x8154, 0x7F8C, 0x5899, 0x8537, 0x5F3A, - 0x62A2, 0x6A47, 0x9539, 0x6572, 0x6084, 0x6865, 0x77A7, 0x4E54, 0x4FA8, 0x5DE7, 0x9798, 0x64AC, 0x7FD8, 0x5CED, 0x4FCF, 0x7A8D, - 0x5207, 0x8304, 0x4E14, 0x602F, 0x7A83, 0x94A6, 0x4FB5, 0x4EB2, 0x79E6, 0x7434, 0x52E4, 0x82B9, 0x64D2, 0x79BD, 0x5BDD, 0x6C81, - 0x9752, 0x8F7B, 0x6C22, 0x503E, 0x537F, 0x6E05, 0x64CE, 0x6674, 0x6C30, 0x60C5, 0x9877, 0x8BF7, 0x5E86, 0x743C, 0x7A77, 0x79CB, - 0x4E18, 0x90B1, 0x7403, 0x6C42, 0x56DA, 0x914B, 0x6CC5, 0x8D8B, 0x533A, 0x86C6, 0x66F2, 0x8EAF, 0x5C48, 0x9A71, 0x6E20, - // GB 0xC840..0xC87E - 0x83EE, 0x83EF, 0x83F3, 0x83F4, 0x83F5, 0x83F6, 0x83F7, 0x83FA, - 0x83FB, 0x83FC, 0x83FE, 0x83FF, 0x8400, 0x8402, 0x8405, 0x8407, 0x8408, 0x8409, 0x840A, 0x8410, 0x8412, 0x8413, 0x8414, 0x8415, - 0x8416, 0x8417, 0x8419, 0x841A, 0x841B, 0x841E, 0x841F, 0x8420, 0x8421, 0x8422, 0x8423, 0x8429, 0x842A, 0x842B, 0x842C, 0x842D, - 0x842E, 0x842F, 0x8430, 0x8432, 0x8433, 0x8434, 0x8435, 0x8436, 0x8437, 0x8439, 0x843A, 0x843B, 0x843E, 0x843F, 0x8440, 0x8441, - 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, 0x8449, - // GB 0xC880..0xC8FE - 0x844A, 0x844B, 0x844C, 0x844D, 0x844E, 0x844F, 0x8450, 0x8452, 0x8453, 0x8454, 0x8455, 0x8456, 0x8458, 0x845D, 0x845E, 0x845F, - 0x8460, 0x8462, 0x8464, 0x8465, 0x8466, 0x8467, 0x8468, 0x846A, 0x846E, 0x846F, 0x8470, 0x8472, 0x8474, 0x8477, 0x8479, 0x847B, - 0x847C, 0x53D6, 0x5A36, 0x9F8B, 0x8DA3, 0x53BB, 0x5708, 0x98A7, 0x6743, 0x919B, 0x6CC9, 0x5168, 0x75CA, 0x62F3, 0x72AC, 0x5238, - 0x529D, 0x7F3A, 0x7094, 0x7638, 0x5374, 0x9E4A, 0x69B7, 0x786E, 0x96C0, 0x88D9, 0x7FA4, 0x7136, 0x71C3, 0x5189, 0x67D3, 0x74E4, - 0x58E4, 0x6518, 0x56B7, 0x8BA9, 0x9976, 0x6270, 0x7ED5, 0x60F9, 0x70ED, 0x58EC, 0x4EC1, 0x4EBA, 0x5FCD, 0x97E7, 0x4EFB, 0x8BA4, - 0x5203, 0x598A, 0x7EAB, 0x6254, 0x4ECD, 0x65E5, 0x620E, 0x8338, 0x84C9, 0x8363, 0x878D, 0x7194, 0x6EB6, 0x5BB9, 0x7ED2, 0x5197, - 0x63C9, 0x67D4, 0x8089, 0x8339, 0x8815, 0x5112, 0x5B7A, 0x5982, 0x8FB1, 0x4E73, 0x6C5D, 0x5165, 0x8925, 0x8F6F, 0x962E, 0x854A, - 0x745E, 0x9510, 0x95F0, 0x6DA6, 0x82E5, 0x5F31, 0x6492, 0x6D12, 0x8428, 0x816E, 0x9CC3, 0x585E, 0x8D5B, 0x4E09, 0x53C1, - // GB 0xC940..0xC97E - 0x847D, 0x847E, 0x847F, 0x8480, 0x8481, 0x8483, 0x8484, 0x8485, - 0x8486, 0x848A, 0x848D, 0x848F, 0x8490, 0x8491, 0x8492, 0x8493, 0x8494, 0x8495, 0x8496, 0x8498, 0x849A, 0x849B, 0x849D, 0x849E, - 0x849F, 0x84A0, 0x84A2, 0x84A3, 0x84A4, 0x84A5, 0x84A6, 0x84A7, 0x84A8, 0x84A9, 0x84AA, 0x84AB, 0x84AC, 0x84AD, 0x84AE, 0x84B0, - 0x84B1, 0x84B3, 0x84B5, 0x84B6, 0x84B7, 0x84BB, 0x84BC, 0x84BE, 0x84C0, 0x84C2, 0x84C3, 0x84C5, 0x84C6, 0x84C7, 0x84C8, 0x84CB, - 0x84CC, 0x84CE, 0x84CF, 0x84D2, 0x84D4, 0x84D5, 0x84D7, - // GB 0xC980..0xC9FE - 0x84D8, 0x84D9, 0x84DA, 0x84DB, 0x84DC, 0x84DE, 0x84E1, 0x84E2, 0x84E4, 0x84E7, 0x84E8, 0x84E9, 0x84EA, 0x84EB, 0x84ED, 0x84EE, - 0x84EF, 0x84F1, 0x84F2, 0x84F3, 0x84F4, 0x84F5, 0x84F6, 0x84F7, 0x84F8, 0x84F9, 0x84FA, 0x84FB, 0x84FD, 0x84FE, 0x8500, 0x8501, - 0x8502, 0x4F1E, 0x6563, 0x6851, 0x55D3, 0x4E27, 0x6414, 0x9A9A, 0x626B, 0x5AC2, 0x745F, 0x8272, 0x6DA9, 0x68EE, 0x50E7, 0x838E, - 0x7802, 0x6740, 0x5239, 0x6C99, 0x7EB1, 0x50BB, 0x5565, 0x715E, 0x7B5B, 0x6652, 0x73CA, 0x82EB, 0x6749, 0x5C71, 0x5220, 0x717D, - 0x886B, 0x95EA, 0x9655, 0x64C5, 0x8D61, 0x81B3, 0x5584, 0x6C55, 0x6247, 0x7F2E, 0x5892, 0x4F24, 0x5546, 0x8D4F, 0x664C, 0x4E0A, - 0x5C1A, 0x88F3, 0x68A2, 0x634E, 0x7A0D, 0x70E7, 0x828D, 0x52FA, 0x97F6, 0x5C11, 0x54E8, 0x90B5, 0x7ECD, 0x5962, 0x8D4A, 0x86C7, - 0x820C, 0x820D, 0x8D66, 0x6444, 0x5C04, 0x6151, 0x6D89, 0x793E, 0x8BBE, 0x7837, 0x7533, 0x547B, 0x4F38, 0x8EAB, 0x6DF1, 0x5A20, - 0x7EC5, 0x795E, 0x6C88, 0x5BA1, 0x5A76, 0x751A, 0x80BE, 0x614E, 0x6E17, 0x58F0, 0x751F, 0x7525, 0x7272, 0x5347, 0x7EF3, - // GB 0xCA40..0xCA7E - 0x8503, 0x8504, 0x8505, 0x8506, 0x8507, 0x8508, 0x8509, 0x850A, - 0x850B, 0x850D, 0x850E, 0x850F, 0x8510, 0x8512, 0x8514, 0x8515, 0x8516, 0x8518, 0x8519, 0x851B, 0x851C, 0x851D, 0x851E, 0x8520, - 0x8522, 0x8523, 0x8524, 0x8525, 0x8526, 0x8527, 0x8528, 0x8529, 0x852A, 0x852D, 0x852E, 0x852F, 0x8530, 0x8531, 0x8532, 0x8533, - 0x8534, 0x8535, 0x8536, 0x853E, 0x853F, 0x8540, 0x8541, 0x8542, 0x8544, 0x8545, 0x8546, 0x8547, 0x854B, 0x854C, 0x854D, 0x854E, - 0x854F, 0x8550, 0x8551, 0x8552, 0x8553, 0x8554, 0x8555, - // GB 0xCA80..0xCAFE - 0x8557, 0x8558, 0x855A, 0x855B, 0x855C, 0x855D, 0x855F, 0x8560, 0x8561, 0x8562, 0x8563, 0x8565, 0x8566, 0x8567, 0x8569, 0x856A, - 0x856B, 0x856C, 0x856D, 0x856E, 0x856F, 0x8570, 0x8571, 0x8573, 0x8575, 0x8576, 0x8577, 0x8578, 0x857C, 0x857D, 0x857F, 0x8580, - 0x8581, 0x7701, 0x76DB, 0x5269, 0x80DC, 0x5723, 0x5E08, 0x5931, 0x72EE, 0x65BD, 0x6E7F, 0x8BD7, 0x5C38, 0x8671, 0x5341, 0x77F3, - 0x62FE, 0x65F6, 0x4EC0, 0x98DF, 0x8680, 0x5B9E, 0x8BC6, 0x53F2, 0x77E2, 0x4F7F, 0x5C4E, 0x9A76, 0x59CB, 0x5F0F, 0x793A, 0x58EB, - 0x4E16, 0x67FF, 0x4E8B, 0x62ED, 0x8A93, 0x901D, 0x52BF, 0x662F, 0x55DC, 0x566C, 0x9002, 0x4ED5, 0x4F8D, 0x91CA, 0x9970, 0x6C0F, - 0x5E02, 0x6043, 0x5BA4, 0x89C6, 0x8BD5, 0x6536, 0x624B, 0x9996, 0x5B88, 0x5BFF, 0x6388, 0x552E, 0x53D7, 0x7626, 0x517D, 0x852C, - 0x67A2, 0x68B3, 0x6B8A, 0x6292, 0x8F93, 0x53D4, 0x8212, 0x6DD1, 0x758F, 0x4E66, 0x8D4E, 0x5B70, 0x719F, 0x85AF, 0x6691, 0x66D9, - 0x7F72, 0x8700, 0x9ECD, 0x9F20, 0x5C5E, 0x672F, 0x8FF0, 0x6811, 0x675F, 0x620D, 0x7AD6, 0x5885, 0x5EB6, 0x6570, 0x6F31, - // GB 0xCB40..0xCB7E - 0x8582, 0x8583, 0x8586, 0x8588, 0x8589, 0x858A, 0x858B, 0x858C, - 0x858D, 0x858E, 0x8590, 0x8591, 0x8592, 0x8593, 0x8594, 0x8595, 0x8596, 0x8597, 0x8598, 0x8599, 0x859A, 0x859D, 0x859E, 0x859F, - 0x85A0, 0x85A1, 0x85A2, 0x85A3, 0x85A5, 0x85A6, 0x85A7, 0x85A9, 0x85AB, 0x85AC, 0x85AD, 0x85B1, 0x85B2, 0x85B3, 0x85B4, 0x85B5, - 0x85B6, 0x85B8, 0x85BA, 0x85BB, 0x85BC, 0x85BD, 0x85BE, 0x85BF, 0x85C0, 0x85C2, 0x85C3, 0x85C4, 0x85C5, 0x85C6, 0x85C7, 0x85C8, - 0x85CA, 0x85CB, 0x85CC, 0x85CD, 0x85CE, 0x85D1, 0x85D2, - // GB 0xCB80..0xCBFE - 0x85D4, 0x85D6, 0x85D7, 0x85D8, 0x85D9, 0x85DA, 0x85DB, 0x85DD, 0x85DE, 0x85DF, 0x85E0, 0x85E1, 0x85E2, 0x85E3, 0x85E5, 0x85E6, - 0x85E7, 0x85E8, 0x85EA, 0x85EB, 0x85EC, 0x85ED, 0x85EE, 0x85EF, 0x85F0, 0x85F1, 0x85F2, 0x85F3, 0x85F4, 0x85F5, 0x85F6, 0x85F7, - 0x85F8, 0x6055, 0x5237, 0x800D, 0x6454, 0x8870, 0x7529, 0x5E05, 0x6813, 0x62F4, 0x971C, 0x53CC, 0x723D, 0x8C01, 0x6C34, 0x7761, - 0x7A0E, 0x542E, 0x77AC, 0x987A, 0x821C, 0x8BF4, 0x7855, 0x6714, 0x70C1, 0x65AF, 0x6495, 0x5636, 0x601D, 0x79C1, 0x53F8, 0x4E1D, - 0x6B7B, 0x8086, 0x5BFA, 0x55E3, 0x56DB, 0x4F3A, 0x4F3C, 0x9972, 0x5DF3, 0x677E, 0x8038, 0x6002, 0x9882, 0x9001, 0x5B8B, 0x8BBC, - 0x8BF5, 0x641C, 0x8258, 0x64DE, 0x55FD, 0x82CF, 0x9165, 0x4FD7, 0x7D20, 0x901F, 0x7C9F, 0x50F3, 0x5851, 0x6EAF, 0x5BBF, 0x8BC9, - 0x8083, 0x9178, 0x849C, 0x7B97, 0x867D, 0x968B, 0x968F, 0x7EE5, 0x9AD3, 0x788E, 0x5C81, 0x7A57, 0x9042, 0x96A7, 0x795F, 0x5B59, - 0x635F, 0x7B0B, 0x84D1, 0x68AD, 0x5506, 0x7F29, 0x7410, 0x7D22, 0x9501, 0x6240, 0x584C, 0x4ED6, 0x5B83, 0x5979, 0x5854, - // GB 0xCC40..0xCC7E - 0x85F9, 0x85FA, 0x85FC, 0x85FD, 0x85FE, 0x8600, 0x8601, 0x8602, - 0x8603, 0x8604, 0x8606, 0x8607, 0x8608, 0x8609, 0x860A, 0x860B, 0x860C, 0x860D, 0x860E, 0x860F, 0x8610, 0x8612, 0x8613, 0x8614, - 0x8615, 0x8617, 0x8618, 0x8619, 0x861A, 0x861B, 0x861C, 0x861D, 0x861E, 0x861F, 0x8620, 0x8621, 0x8622, 0x8623, 0x8624, 0x8625, - 0x8626, 0x8628, 0x862A, 0x862B, 0x862C, 0x862D, 0x862E, 0x862F, 0x8630, 0x8631, 0x8632, 0x8633, 0x8634, 0x8635, 0x8636, 0x8637, - 0x8639, 0x863A, 0x863B, 0x863D, 0x863E, 0x863F, 0x8640, - // GB 0xCC80..0xCCFE - 0x8641, 0x8642, 0x8643, 0x8644, 0x8645, 0x8646, 0x8647, 0x8648, 0x8649, 0x864A, 0x864B, 0x864C, 0x8652, 0x8653, 0x8655, 0x8656, - 0x8657, 0x8658, 0x8659, 0x865B, 0x865C, 0x865D, 0x865F, 0x8660, 0x8661, 0x8663, 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669, - 0x866A, 0x736D, 0x631E, 0x8E4B, 0x8E0F, 0x80CE, 0x82D4, 0x62AC, 0x53F0, 0x6CF0, 0x915E, 0x592A, 0x6001, 0x6C70, 0x574D, 0x644A, - 0x8D2A, 0x762B, 0x6EE9, 0x575B, 0x6A80, 0x75F0, 0x6F6D, 0x8C2D, 0x8C08, 0x5766, 0x6BEF, 0x8892, 0x78B3, 0x63A2, 0x53F9, 0x70AD, - 0x6C64, 0x5858, 0x642A, 0x5802, 0x68E0, 0x819B, 0x5510, 0x7CD6, 0x5018, 0x8EBA, 0x6DCC, 0x8D9F, 0x70EB, 0x638F, 0x6D9B, 0x6ED4, - 0x7EE6, 0x8404, 0x6843, 0x9003, 0x6DD8, 0x9676, 0x8BA8, 0x5957, 0x7279, 0x85E4, 0x817E, 0x75BC, 0x8A8A, 0x68AF, 0x5254, 0x8E22, - 0x9511, 0x63D0, 0x9898, 0x8E44, 0x557C, 0x4F53, 0x66FF, 0x568F, 0x60D5, 0x6D95, 0x5243, 0x5C49, 0x5929, 0x6DFB, 0x586B, 0x7530, - 0x751C, 0x606C, 0x8214, 0x8146, 0x6311, 0x6761, 0x8FE2, 0x773A, 0x8DF3, 0x8D34, 0x94C1, 0x5E16, 0x5385, 0x542C, 0x70C3, - // GB 0xCD40..0xCD7E - 0x866D, 0x866F, 0x8670, 0x8672, 0x8673, 0x8674, 0x8675, 0x8676, - 0x8677, 0x8678, 0x8683, 0x8684, 0x8685, 0x8686, 0x8687, 0x8688, 0x8689, 0x868E, 0x868F, 0x8690, 0x8691, 0x8692, 0x8694, 0x8696, - 0x8697, 0x8698, 0x8699, 0x869A, 0x869B, 0x869E, 0x869F, 0x86A0, 0x86A1, 0x86A2, 0x86A5, 0x86A6, 0x86AB, 0x86AD, 0x86AE, 0x86B2, - 0x86B3, 0x86B7, 0x86B8, 0x86B9, 0x86BB, 0x86BC, 0x86BD, 0x86BE, 0x86BF, 0x86C1, 0x86C2, 0x86C3, 0x86C5, 0x86C8, 0x86CC, 0x86CD, - 0x86D2, 0x86D3, 0x86D5, 0x86D6, 0x86D7, 0x86DA, 0x86DC, - // GB 0xCD80..0xCDFE - 0x86DD, 0x86E0, 0x86E1, 0x86E2, 0x86E3, 0x86E5, 0x86E6, 0x86E7, 0x86E8, 0x86EA, 0x86EB, 0x86EC, 0x86EF, 0x86F5, 0x86F6, 0x86F7, - 0x86FA, 0x86FB, 0x86FC, 0x86FD, 0x86FF, 0x8701, 0x8704, 0x8705, 0x8706, 0x870B, 0x870C, 0x870E, 0x870F, 0x8710, 0x8711, 0x8714, - 0x8716, 0x6C40, 0x5EF7, 0x505C, 0x4EAD, 0x5EAD, 0x633A, 0x8247, 0x901A, 0x6850, 0x916E, 0x77B3, 0x540C, 0x94DC, 0x5F64, 0x7AE5, - 0x6876, 0x6345, 0x7B52, 0x7EDF, 0x75DB, 0x5077, 0x6295, 0x5934, 0x900F, 0x51F8, 0x79C3, 0x7A81, 0x56FE, 0x5F92, 0x9014, 0x6D82, - 0x5C60, 0x571F, 0x5410, 0x5154, 0x6E4D, 0x56E2, 0x63A8, 0x9893, 0x817F, 0x8715, 0x892A, 0x9000, 0x541E, 0x5C6F, 0x81C0, 0x62D6, - 0x6258, 0x8131, 0x9E35, 0x9640, 0x9A6E, 0x9A7C, 0x692D, 0x59A5, 0x62D3, 0x553E, 0x6316, 0x54C7, 0x86D9, 0x6D3C, 0x5A03, 0x74E6, - 0x889C, 0x6B6A, 0x5916, 0x8C4C, 0x5F2F, 0x6E7E, 0x73A9, 0x987D, 0x4E38, 0x70F7, 0x5B8C, 0x7897, 0x633D, 0x665A, 0x7696, 0x60CB, - 0x5B9B, 0x5A49, 0x4E07, 0x8155, 0x6C6A, 0x738B, 0x4EA1, 0x6789, 0x7F51, 0x5F80, 0x65FA, 0x671B, 0x5FD8, 0x5984, 0x5A01, - // GB 0xCE40..0xCE7E - 0x8719, 0x871B, 0x871D, 0x871F, 0x8720, 0x8724, 0x8726, 0x8727, - 0x8728, 0x872A, 0x872B, 0x872C, 0x872D, 0x872F, 0x8730, 0x8732, 0x8733, 0x8735, 0x8736, 0x8738, 0x8739, 0x873A, 0x873C, 0x873D, - 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745, 0x8746, 0x874A, 0x874B, 0x874D, 0x874F, 0x8750, 0x8751, 0x8752, 0x8754, 0x8755, - 0x8756, 0x8758, 0x875A, 0x875B, 0x875C, 0x875D, 0x875E, 0x875F, 0x8761, 0x8762, 0x8766, 0x8767, 0x8768, 0x8769, 0x876A, 0x876B, - 0x876C, 0x876D, 0x876F, 0x8771, 0x8772, 0x8773, 0x8775, - // GB 0xCE80..0xCEFE - 0x8777, 0x8778, 0x8779, 0x877A, 0x877F, 0x8780, 0x8781, 0x8784, 0x8786, 0x8787, 0x8789, 0x878A, 0x878C, 0x878E, 0x878F, 0x8790, - 0x8791, 0x8792, 0x8794, 0x8795, 0x8796, 0x8798, 0x8799, 0x879A, 0x879B, 0x879C, 0x879D, 0x879E, 0x87A0, 0x87A1, 0x87A2, 0x87A3, - 0x87A4, 0x5DCD, 0x5FAE, 0x5371, 0x97E6, 0x8FDD, 0x6845, 0x56F4, 0x552F, 0x60DF, 0x4E3A, 0x6F4D, 0x7EF4, 0x82C7, 0x840E, 0x59D4, - 0x4F1F, 0x4F2A, 0x5C3E, 0x7EAC, 0x672A, 0x851A, 0x5473, 0x754F, 0x80C3, 0x5582, 0x9B4F, 0x4F4D, 0x6E2D, 0x8C13, 0x5C09, 0x6170, - 0x536B, 0x761F, 0x6E29, 0x868A, 0x6587, 0x95FB, 0x7EB9, 0x543B, 0x7A33, 0x7D0A, 0x95EE, 0x55E1, 0x7FC1, 0x74EE, 0x631D, 0x8717, - 0x6DA1, 0x7A9D, 0x6211, 0x65A1, 0x5367, 0x63E1, 0x6C83, 0x5DEB, 0x545C, 0x94A8, 0x4E4C, 0x6C61, 0x8BEC, 0x5C4B, 0x65E0, 0x829C, - 0x68A7, 0x543E, 0x5434, 0x6BCB, 0x6B66, 0x4E94, 0x6342, 0x5348, 0x821E, 0x4F0D, 0x4FAE, 0x575E, 0x620A, 0x96FE, 0x6664, 0x7269, - 0x52FF, 0x52A1, 0x609F, 0x8BEF, 0x6614, 0x7199, 0x6790, 0x897F, 0x7852, 0x77FD, 0x6670, 0x563B, 0x5438, 0x9521, 0x727A, - // GB 0xCF40..0xCF7E - 0x87A5, 0x87A6, 0x87A7, 0x87A9, 0x87AA, 0x87AE, 0x87B0, 0x87B1, - 0x87B2, 0x87B4, 0x87B6, 0x87B7, 0x87B8, 0x87B9, 0x87BB, 0x87BC, 0x87BE, 0x87BF, 0x87C1, 0x87C2, 0x87C3, 0x87C4, 0x87C5, 0x87C7, - 0x87C8, 0x87C9, 0x87CC, 0x87CD, 0x87CE, 0x87CF, 0x87D0, 0x87D4, 0x87D5, 0x87D6, 0x87D7, 0x87D8, 0x87D9, 0x87DA, 0x87DC, 0x87DD, - 0x87DE, 0x87DF, 0x87E1, 0x87E2, 0x87E3, 0x87E4, 0x87E6, 0x87E7, 0x87E8, 0x87E9, 0x87EB, 0x87EC, 0x87ED, 0x87EF, 0x87F0, 0x87F1, - 0x87F2, 0x87F3, 0x87F4, 0x87F5, 0x87F6, 0x87F7, 0x87F8, - // GB 0xCF80..0xCFFE - 0x87FA, 0x87FB, 0x87FC, 0x87FD, 0x87FF, 0x8800, 0x8801, 0x8802, 0x8804, 0x8805, 0x8806, 0x8807, 0x8808, 0x8809, 0x880B, 0x880C, - 0x880D, 0x880E, 0x880F, 0x8810, 0x8811, 0x8812, 0x8814, 0x8817, 0x8818, 0x8819, 0x881A, 0x881C, 0x881D, 0x881E, 0x881F, 0x8820, - 0x8823, 0x7A00, 0x606F, 0x5E0C, 0x6089, 0x819D, 0x5915, 0x60DC, 0x7184, 0x70EF, 0x6EAA, 0x6C50, 0x7280, 0x6A84, 0x88AD, 0x5E2D, - 0x4E60, 0x5AB3, 0x559C, 0x94E3, 0x6D17, 0x7CFB, 0x9699, 0x620F, 0x7EC6, 0x778E, 0x867E, 0x5323, 0x971E, 0x8F96, 0x6687, 0x5CE1, - 0x4FA0, 0x72ED, 0x4E0B, 0x53A6, 0x590F, 0x5413, 0x6380, 0x9528, 0x5148, 0x4ED9, 0x9C9C, 0x7EA4, 0x54B8, 0x8D24, 0x8854, 0x8237, - 0x95F2, 0x6D8E, 0x5F26, 0x5ACC, 0x663E, 0x9669, 0x73B0, 0x732E, 0x53BF, 0x817A, 0x9985, 0x7FA1, 0x5BAA, 0x9677, 0x9650, 0x7EBF, - 0x76F8, 0x53A2, 0x9576, 0x9999, 0x7BB1, 0x8944, 0x6E58, 0x4E61, 0x7FD4, 0x7965, 0x8BE6, 0x60F3, 0x54CD, 0x4EAB, 0x9879, 0x5DF7, - 0x6A61, 0x50CF, 0x5411, 0x8C61, 0x8427, 0x785D, 0x9704, 0x524A, 0x54EE, 0x56A3, 0x9500, 0x6D88, 0x5BB5, 0x6DC6, 0x6653, - // GB 0xD040..0xD07E - 0x8824, 0x8825, 0x8826, 0x8827, 0x8828, 0x8829, 0x882A, 0x882B, - 0x882C, 0x882D, 0x882E, 0x882F, 0x8830, 0x8831, 0x8833, 0x8834, 0x8835, 0x8836, 0x8837, 0x8838, 0x883A, 0x883B, 0x883D, 0x883E, - 0x883F, 0x8841, 0x8842, 0x8843, 0x8846, 0x8847, 0x8848, 0x8849, 0x884A, 0x884B, 0x884E, 0x884F, 0x8850, 0x8851, 0x8852, 0x8853, - 0x8855, 0x8856, 0x8858, 0x885A, 0x885B, 0x885C, 0x885D, 0x885E, 0x885F, 0x8860, 0x8866, 0x8867, 0x886A, 0x886D, 0x886F, 0x8871, - 0x8873, 0x8874, 0x8875, 0x8876, 0x8878, 0x8879, 0x887A, - // GB 0xD080..0xD0FE - 0x887B, 0x887C, 0x8880, 0x8883, 0x8886, 0x8887, 0x8889, 0x888A, 0x888C, 0x888E, 0x888F, 0x8890, 0x8891, 0x8893, 0x8894, 0x8895, - 0x8897, 0x8898, 0x8899, 0x889A, 0x889B, 0x889D, 0x889E, 0x889F, 0x88A0, 0x88A1, 0x88A3, 0x88A5, 0x88A6, 0x88A7, 0x88A8, 0x88A9, - 0x88AA, 0x5C0F, 0x5B5D, 0x6821, 0x8096, 0x5578, 0x7B11, 0x6548, 0x6954, 0x4E9B, 0x6B47, 0x874E, 0x978B, 0x534F, 0x631F, 0x643A, - 0x90AA, 0x659C, 0x80C1, 0x8C10, 0x5199, 0x68B0, 0x5378, 0x87F9, 0x61C8, 0x6CC4, 0x6CFB, 0x8C22, 0x5C51, 0x85AA, 0x82AF, 0x950C, - 0x6B23, 0x8F9B, 0x65B0, 0x5FFB, 0x5FC3, 0x4FE1, 0x8845, 0x661F, 0x8165, 0x7329, 0x60FA, 0x5174, 0x5211, 0x578B, 0x5F62, 0x90A2, - 0x884C, 0x9192, 0x5E78, 0x674F, 0x6027, 0x59D3, 0x5144, 0x51F6, 0x80F8, 0x5308, 0x6C79, 0x96C4, 0x718A, 0x4F11, 0x4FEE, 0x7F9E, - 0x673D, 0x55C5, 0x9508, 0x79C0, 0x8896, 0x7EE3, 0x589F, 0x620C, 0x9700, 0x865A, 0x5618, 0x987B, 0x5F90, 0x8BB8, 0x84C4, 0x9157, - 0x53D9, 0x65ED, 0x5E8F, 0x755C, 0x6064, 0x7D6E, 0x5A7F, 0x7EEA, 0x7EED, 0x8F69, 0x55A7, 0x5BA3, 0x60AC, 0x65CB, 0x7384, - // GB 0xD140..0xD17E - 0x88AC, 0x88AE, 0x88AF, 0x88B0, 0x88B2, 0x88B3, 0x88B4, 0x88B5, - 0x88B6, 0x88B8, 0x88B9, 0x88BA, 0x88BB, 0x88BD, 0x88BE, 0x88BF, 0x88C0, 0x88C3, 0x88C4, 0x88C7, 0x88C8, 0x88CA, 0x88CB, 0x88CC, - 0x88CD, 0x88CF, 0x88D0, 0x88D1, 0x88D3, 0x88D6, 0x88D7, 0x88DA, 0x88DB, 0x88DC, 0x88DD, 0x88DE, 0x88E0, 0x88E1, 0x88E6, 0x88E7, - 0x88E9, 0x88EA, 0x88EB, 0x88EC, 0x88ED, 0x88EE, 0x88EF, 0x88F2, 0x88F5, 0x88F6, 0x88F7, 0x88FA, 0x88FB, 0x88FD, 0x88FF, 0x8900, - 0x8901, 0x8903, 0x8904, 0x8905, 0x8906, 0x8907, 0x8908, - // GB 0xD180..0xD1FE - 0x8909, 0x890B, 0x890C, 0x890D, 0x890E, 0x890F, 0x8911, 0x8914, 0x8915, 0x8916, 0x8917, 0x8918, 0x891C, 0x891D, 0x891E, 0x891F, - 0x8920, 0x8922, 0x8923, 0x8924, 0x8926, 0x8927, 0x8928, 0x8929, 0x892C, 0x892D, 0x892E, 0x892F, 0x8931, 0x8932, 0x8933, 0x8935, - 0x8937, 0x9009, 0x7663, 0x7729, 0x7EDA, 0x9774, 0x859B, 0x5B66, 0x7A74, 0x96EA, 0x8840, 0x52CB, 0x718F, 0x5FAA, 0x65EC, 0x8BE2, - 0x5BFB, 0x9A6F, 0x5DE1, 0x6B89, 0x6C5B, 0x8BAD, 0x8BAF, 0x900A, 0x8FC5, 0x538B, 0x62BC, 0x9E26, 0x9E2D, 0x5440, 0x4E2B, 0x82BD, - 0x7259, 0x869C, 0x5D16, 0x8859, 0x6DAF, 0x96C5, 0x54D1, 0x4E9A, 0x8BB6, 0x7109, 0x54BD, 0x9609, 0x70DF, 0x6DF9, 0x76D0, 0x4E25, - 0x7814, 0x8712, 0x5CA9, 0x5EF6, 0x8A00, 0x989C, 0x960E, 0x708E, 0x6CBF, 0x5944, 0x63A9, 0x773C, 0x884D, 0x6F14, 0x8273, 0x5830, - 0x71D5, 0x538C, 0x781A, 0x96C1, 0x5501, 0x5F66, 0x7130, 0x5BB4, 0x8C1A, 0x9A8C, 0x6B83, 0x592E, 0x9E2F, 0x79E7, 0x6768, 0x626C, - 0x4F6F, 0x75A1, 0x7F8A, 0x6D0B, 0x9633, 0x6C27, 0x4EF0, 0x75D2, 0x517B, 0x6837, 0x6F3E, 0x9080, 0x8170, 0x5996, 0x7476, - // GB 0xD240..0xD27E - 0x8938, 0x8939, 0x893A, 0x893B, 0x893C, 0x893D, 0x893E, 0x893F, - 0x8940, 0x8942, 0x8943, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949, 0x894A, 0x894B, 0x894C, 0x894D, 0x894E, 0x894F, 0x8950, 0x8951, - 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, 0x895A, 0x895B, 0x895C, 0x895D, 0x8960, 0x8961, 0x8962, 0x8963, - 0x8964, 0x8965, 0x8967, 0x8968, 0x8969, 0x896A, 0x896B, 0x896C, 0x896D, 0x896E, 0x896F, 0x8970, 0x8971, 0x8972, 0x8973, 0x8974, - 0x8975, 0x8976, 0x8977, 0x8978, 0x8979, 0x897A, 0x897C, - // GB 0xD280..0xD2FE - 0x897D, 0x897E, 0x8980, 0x8982, 0x8984, 0x8985, 0x8987, 0x8988, 0x8989, 0x898A, 0x898B, 0x898C, 0x898D, 0x898E, 0x898F, 0x8990, - 0x8991, 0x8992, 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, 0x899A, 0x899B, 0x899C, 0x899D, 0x899E, 0x899F, 0x89A0, - 0x89A1, 0x6447, 0x5C27, 0x9065, 0x7A91, 0x8C23, 0x59DA, 0x54AC, 0x8200, 0x836F, 0x8981, 0x8000, 0x6930, 0x564E, 0x8036, 0x7237, - 0x91CE, 0x51B6, 0x4E5F, 0x9875, 0x6396, 0x4E1A, 0x53F6, 0x66F3, 0x814B, 0x591C, 0x6DB2, 0x4E00, 0x58F9, 0x533B, 0x63D6, 0x94F1, - 0x4F9D, 0x4F0A, 0x8863, 0x9890, 0x5937, 0x9057, 0x79FB, 0x4EEA, 0x80F0, 0x7591, 0x6C82, 0x5B9C, 0x59E8, 0x5F5D, 0x6905, 0x8681, - 0x501A, 0x5DF2, 0x4E59, 0x77E3, 0x4EE5, 0x827A, 0x6291, 0x6613, 0x9091, 0x5C79, 0x4EBF, 0x5F79, 0x81C6, 0x9038, 0x8084, 0x75AB, - 0x4EA6, 0x88D4, 0x610F, 0x6BC5, 0x5FC6, 0x4E49, 0x76CA, 0x6EA2, 0x8BE3, 0x8BAE, 0x8C0A, 0x8BD1, 0x5F02, 0x7FFC, 0x7FCC, 0x7ECE, - 0x8335, 0x836B, 0x56E0, 0x6BB7, 0x97F3, 0x9634, 0x59FB, 0x541F, 0x94F6, 0x6DEB, 0x5BC5, 0x996E, 0x5C39, 0x5F15, 0x9690, - // GB 0xD340..0xD37E - 0x89A2, 0x89A3, 0x89A4, 0x89A5, 0x89A6, 0x89A7, 0x89A8, 0x89A9, - 0x89AA, 0x89AB, 0x89AC, 0x89AD, 0x89AE, 0x89AF, 0x89B0, 0x89B1, 0x89B2, 0x89B3, 0x89B4, 0x89B5, 0x89B6, 0x89B7, 0x89B8, 0x89B9, - 0x89BA, 0x89BB, 0x89BC, 0x89BD, 0x89BE, 0x89BF, 0x89C0, 0x89C3, 0x89CD, 0x89D3, 0x89D4, 0x89D5, 0x89D7, 0x89D8, 0x89D9, 0x89DB, - 0x89DD, 0x89DF, 0x89E0, 0x89E1, 0x89E2, 0x89E4, 0x89E7, 0x89E8, 0x89E9, 0x89EA, 0x89EC, 0x89ED, 0x89EE, 0x89F0, 0x89F1, 0x89F2, - 0x89F4, 0x89F5, 0x89F6, 0x89F7, 0x89F8, 0x89F9, 0x89FA, - // GB 0xD380..0xD3FE - 0x89FB, 0x89FC, 0x89FD, 0x89FE, 0x89FF, 0x8A01, 0x8A02, 0x8A03, 0x8A04, 0x8A05, 0x8A06, 0x8A08, 0x8A09, 0x8A0A, 0x8A0B, 0x8A0C, - 0x8A0D, 0x8A0E, 0x8A0F, 0x8A10, 0x8A11, 0x8A12, 0x8A13, 0x8A14, 0x8A15, 0x8A16, 0x8A17, 0x8A18, 0x8A19, 0x8A1A, 0x8A1B, 0x8A1C, - 0x8A1D, 0x5370, 0x82F1, 0x6A31, 0x5A74, 0x9E70, 0x5E94, 0x7F28, 0x83B9, 0x8424, 0x8425, 0x8367, 0x8747, 0x8FCE, 0x8D62, 0x76C8, - 0x5F71, 0x9896, 0x786C, 0x6620, 0x54DF, 0x62E5, 0x4F63, 0x81C3, 0x75C8, 0x5EB8, 0x96CD, 0x8E0A, 0x86F9, 0x548F, 0x6CF3, 0x6D8C, - 0x6C38, 0x607F, 0x52C7, 0x7528, 0x5E7D, 0x4F18, 0x60A0, 0x5FE7, 0x5C24, 0x7531, 0x90AE, 0x94C0, 0x72B9, 0x6CB9, 0x6E38, 0x9149, - 0x6709, 0x53CB, 0x53F3, 0x4F51, 0x91C9, 0x8BF1, 0x53C8, 0x5E7C, 0x8FC2, 0x6DE4, 0x4E8E, 0x76C2, 0x6986, 0x865E, 0x611A, 0x8206, - 0x4F59, 0x4FDE, 0x903E, 0x9C7C, 0x6109, 0x6E1D, 0x6E14, 0x9685, 0x4E88, 0x5A31, 0x96E8, 0x4E0E, 0x5C7F, 0x79B9, 0x5B87, 0x8BED, - 0x7FBD, 0x7389, 0x57DF, 0x828B, 0x90C1, 0x5401, 0x9047, 0x55BB, 0x5CEA, 0x5FA1, 0x6108, 0x6B32, 0x72F1, 0x80B2, 0x8A89, - // GB 0xD440..0xD47E - 0x8A1E, 0x8A1F, 0x8A20, 0x8A21, 0x8A22, 0x8A23, 0x8A24, 0x8A25, - 0x8A26, 0x8A27, 0x8A28, 0x8A29, 0x8A2A, 0x8A2B, 0x8A2C, 0x8A2D, 0x8A2E, 0x8A2F, 0x8A30, 0x8A31, 0x8A32, 0x8A33, 0x8A34, 0x8A35, - 0x8A36, 0x8A37, 0x8A38, 0x8A39, 0x8A3A, 0x8A3B, 0x8A3C, 0x8A3D, 0x8A3F, 0x8A40, 0x8A41, 0x8A42, 0x8A43, 0x8A44, 0x8A45, 0x8A46, - 0x8A47, 0x8A49, 0x8A4A, 0x8A4B, 0x8A4C, 0x8A4D, 0x8A4E, 0x8A4F, 0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x8A54, 0x8A55, 0x8A56, 0x8A57, - 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A5E, - // GB 0xD480..0xD4FE - 0x8A5F, 0x8A60, 0x8A61, 0x8A62, 0x8A63, 0x8A64, 0x8A65, 0x8A66, 0x8A67, 0x8A68, 0x8A69, 0x8A6A, 0x8A6B, 0x8A6C, 0x8A6D, 0x8A6E, - 0x8A6F, 0x8A70, 0x8A71, 0x8A72, 0x8A73, 0x8A74, 0x8A75, 0x8A76, 0x8A77, 0x8A78, 0x8A7A, 0x8A7B, 0x8A7C, 0x8A7D, 0x8A7E, 0x8A7F, - 0x8A80, 0x6D74, 0x5BD3, 0x88D5, 0x9884, 0x8C6B, 0x9A6D, 0x9E33, 0x6E0A, 0x51A4, 0x5143, 0x57A3, 0x8881, 0x539F, 0x63F4, 0x8F95, - 0x56ED, 0x5458, 0x5706, 0x733F, 0x6E90, 0x7F18, 0x8FDC, 0x82D1, 0x613F, 0x6028, 0x9662, 0x66F0, 0x7EA6, 0x8D8A, 0x8DC3, 0x94A5, - 0x5CB3, 0x7CA4, 0x6708, 0x60A6, 0x9605, 0x8018, 0x4E91, 0x90E7, 0x5300, 0x9668, 0x5141, 0x8FD0, 0x8574, 0x915D, 0x6655, 0x97F5, - 0x5B55, 0x531D, 0x7838, 0x6742, 0x683D, 0x54C9, 0x707E, 0x5BB0, 0x8F7D, 0x518D, 0x5728, 0x54B1, 0x6512, 0x6682, 0x8D5E, 0x8D43, - 0x810F, 0x846C, 0x906D, 0x7CDF, 0x51FF, 0x85FB, 0x67A3, 0x65E9, 0x6FA1, 0x86A4, 0x8E81, 0x566A, 0x9020, 0x7682, 0x7076, 0x71E5, - 0x8D23, 0x62E9, 0x5219, 0x6CFD, 0x8D3C, 0x600E, 0x589E, 0x618E, 0x66FE, 0x8D60, 0x624E, 0x55B3, 0x6E23, 0x672D, 0x8F67, - // GB 0xD540..0xD57E - 0x8A81, 0x8A82, 0x8A83, 0x8A84, 0x8A85, 0x8A86, 0x8A87, 0x8A88, - 0x8A8B, 0x8A8C, 0x8A8D, 0x8A8E, 0x8A8F, 0x8A90, 0x8A91, 0x8A92, 0x8A94, 0x8A95, 0x8A96, 0x8A97, 0x8A98, 0x8A99, 0x8A9A, 0x8A9B, - 0x8A9C, 0x8A9D, 0x8A9E, 0x8A9F, 0x8AA0, 0x8AA1, 0x8AA2, 0x8AA3, 0x8AA4, 0x8AA5, 0x8AA6, 0x8AA7, 0x8AA8, 0x8AA9, 0x8AAA, 0x8AAB, - 0x8AAC, 0x8AAD, 0x8AAE, 0x8AAF, 0x8AB0, 0x8AB1, 0x8AB2, 0x8AB3, 0x8AB4, 0x8AB5, 0x8AB6, 0x8AB7, 0x8AB8, 0x8AB9, 0x8ABA, 0x8ABB, - 0x8ABC, 0x8ABD, 0x8ABE, 0x8ABF, 0x8AC0, 0x8AC1, 0x8AC2, - // GB 0xD580..0xD5FE - 0x8AC3, 0x8AC4, 0x8AC5, 0x8AC6, 0x8AC7, 0x8AC8, 0x8AC9, 0x8ACA, 0x8ACB, 0x8ACC, 0x8ACD, 0x8ACE, 0x8ACF, 0x8AD0, 0x8AD1, 0x8AD2, - 0x8AD3, 0x8AD4, 0x8AD5, 0x8AD6, 0x8AD7, 0x8AD8, 0x8AD9, 0x8ADA, 0x8ADB, 0x8ADC, 0x8ADD, 0x8ADE, 0x8ADF, 0x8AE0, 0x8AE1, 0x8AE2, - 0x8AE3, 0x94E1, 0x95F8, 0x7728, 0x6805, 0x69A8, 0x548B, 0x4E4D, 0x70B8, 0x8BC8, 0x6458, 0x658B, 0x5B85, 0x7A84, 0x503A, 0x5BE8, - 0x77BB, 0x6BE1, 0x8A79, 0x7C98, 0x6CBE, 0x76CF, 0x65A9, 0x8F97, 0x5D2D, 0x5C55, 0x8638, 0x6808, 0x5360, 0x6218, 0x7AD9, 0x6E5B, - 0x7EFD, 0x6A1F, 0x7AE0, 0x5F70, 0x6F33, 0x5F20, 0x638C, 0x6DA8, 0x6756, 0x4E08, 0x5E10, 0x8D26, 0x4ED7, 0x80C0, 0x7634, 0x969C, - 0x62DB, 0x662D, 0x627E, 0x6CBC, 0x8D75, 0x7167, 0x7F69, 0x5146, 0x8087, 0x53EC, 0x906E, 0x6298, 0x54F2, 0x86F0, 0x8F99, 0x8005, - 0x9517, 0x8517, 0x8FD9, 0x6D59, 0x73CD, 0x659F, 0x771F, 0x7504, 0x7827, 0x81FB, 0x8D1E, 0x9488, 0x4FA6, 0x6795, 0x75B9, 0x8BCA, - 0x9707, 0x632F, 0x9547, 0x9635, 0x84B8, 0x6323, 0x7741, 0x5F81, 0x72F0, 0x4E89, 0x6014, 0x6574, 0x62EF, 0x6B63, 0x653F, - // GB 0xD640..0xD67E - 0x8AE4, 0x8AE5, 0x8AE6, 0x8AE7, 0x8AE8, 0x8AE9, 0x8AEA, 0x8AEB, - 0x8AEC, 0x8AED, 0x8AEE, 0x8AEF, 0x8AF0, 0x8AF1, 0x8AF2, 0x8AF3, 0x8AF4, 0x8AF5, 0x8AF6, 0x8AF7, 0x8AF8, 0x8AF9, 0x8AFA, 0x8AFB, - 0x8AFC, 0x8AFD, 0x8AFE, 0x8AFF, 0x8B00, 0x8B01, 0x8B02, 0x8B03, 0x8B04, 0x8B05, 0x8B06, 0x8B08, 0x8B09, 0x8B0A, 0x8B0B, 0x8B0C, - 0x8B0D, 0x8B0E, 0x8B0F, 0x8B10, 0x8B11, 0x8B12, 0x8B13, 0x8B14, 0x8B15, 0x8B16, 0x8B17, 0x8B18, 0x8B19, 0x8B1A, 0x8B1B, 0x8B1C, - 0x8B1D, 0x8B1E, 0x8B1F, 0x8B20, 0x8B21, 0x8B22, 0x8B23, - // GB 0xD680..0xD6FE - 0x8B24, 0x8B25, 0x8B27, 0x8B28, 0x8B29, 0x8B2A, 0x8B2B, 0x8B2C, 0x8B2D, 0x8B2E, 0x8B2F, 0x8B30, 0x8B31, 0x8B32, 0x8B33, 0x8B34, - 0x8B35, 0x8B36, 0x8B37, 0x8B38, 0x8B39, 0x8B3A, 0x8B3B, 0x8B3C, 0x8B3D, 0x8B3E, 0x8B3F, 0x8B40, 0x8B41, 0x8B42, 0x8B43, 0x8B44, - 0x8B45, 0x5E27, 0x75C7, 0x90D1, 0x8BC1, 0x829D, 0x679D, 0x652F, 0x5431, 0x8718, 0x77E5, 0x80A2, 0x8102, 0x6C41, 0x4E4B, 0x7EC7, - 0x804C, 0x76F4, 0x690D, 0x6B96, 0x6267, 0x503C, 0x4F84, 0x5740, 0x6307, 0x6B62, 0x8DBE, 0x53EA, 0x65E8, 0x7EB8, 0x5FD7, 0x631A, - 0x63B7, 0x81F3, 0x81F4, 0x7F6E, 0x5E1C, 0x5CD9, 0x5236, 0x667A, 0x79E9, 0x7A1A, 0x8D28, 0x7099, 0x75D4, 0x6EDE, 0x6CBB, 0x7A92, - 0x4E2D, 0x76C5, 0x5FE0, 0x949F, 0x8877, 0x7EC8, 0x79CD, 0x80BF, 0x91CD, 0x4EF2, 0x4F17, 0x821F, 0x5468, 0x5DDE, 0x6D32, 0x8BCC, - 0x7CA5, 0x8F74, 0x8098, 0x5E1A, 0x5492, 0x76B1, 0x5B99, 0x663C, 0x9AA4, 0x73E0, 0x682A, 0x86DB, 0x6731, 0x732A, 0x8BF8, 0x8BDB, - 0x9010, 0x7AF9, 0x70DB, 0x716E, 0x62C4, 0x77A9, 0x5631, 0x4E3B, 0x8457, 0x67F1, 0x52A9, 0x86C0, 0x8D2E, 0x94F8, 0x7B51, - // GB 0xD740..0xD77E - 0x8B46, 0x8B47, 0x8B48, 0x8B49, 0x8B4A, 0x8B4B, 0x8B4C, 0x8B4D, - 0x8B4E, 0x8B4F, 0x8B50, 0x8B51, 0x8B52, 0x8B53, 0x8B54, 0x8B55, 0x8B56, 0x8B57, 0x8B58, 0x8B59, 0x8B5A, 0x8B5B, 0x8B5C, 0x8B5D, - 0x8B5E, 0x8B5F, 0x8B60, 0x8B61, 0x8B62, 0x8B63, 0x8B64, 0x8B65, 0x8B67, 0x8B68, 0x8B69, 0x8B6A, 0x8B6B, 0x8B6D, 0x8B6E, 0x8B6F, - 0x8B70, 0x8B71, 0x8B72, 0x8B73, 0x8B74, 0x8B75, 0x8B76, 0x8B77, 0x8B78, 0x8B79, 0x8B7A, 0x8B7B, 0x8B7C, 0x8B7D, 0x8B7E, 0x8B7F, - 0x8B80, 0x8B81, 0x8B82, 0x8B83, 0x8B84, 0x8B85, 0x8B86, - // GB 0xD780..0xD7FE - 0x8B87, 0x8B88, 0x8B89, 0x8B8A, 0x8B8B, 0x8B8C, 0x8B8D, 0x8B8E, 0x8B8F, 0x8B90, 0x8B91, 0x8B92, 0x8B93, 0x8B94, 0x8B95, 0x8B96, - 0x8B97, 0x8B98, 0x8B99, 0x8B9A, 0x8B9B, 0x8B9C, 0x8B9D, 0x8B9E, 0x8B9F, 0x8BAC, 0x8BB1, 0x8BBB, 0x8BC7, 0x8BD0, 0x8BEA, 0x8C09, - 0x8C1E, 0x4F4F, 0x6CE8, 0x795D, 0x9A7B, 0x6293, 0x722A, 0x62FD, 0x4E13, 0x7816, 0x8F6C, 0x64B0, 0x8D5A, 0x7BC6, 0x6869, 0x5E84, - 0x88C5, 0x5986, 0x649E, 0x58EE, 0x72B6, 0x690E, 0x9525, 0x8FFD, 0x8D58, 0x5760, 0x7F00, 0x8C06, 0x51C6, 0x6349, 0x62D9, 0x5353, - 0x684C, 0x7422, 0x8301, 0x914C, 0x5544, 0x7740, 0x707C, 0x6D4A, 0x5179, 0x54A8, 0x8D44, 0x59FF, 0x6ECB, 0x6DC4, 0x5B5C, 0x7D2B, - 0x4ED4, 0x7C7D, 0x6ED3, 0x5B50, 0x81EA, 0x6E0D, 0x5B57, 0x9B03, 0x68D5, 0x8E2A, 0x5B97, 0x7EFC, 0x603B, 0x7EB5, 0x90B9, 0x8D70, - 0x594F, 0x63CD, 0x79DF, 0x8DB3, 0x5352, 0x65CF, 0x7956, 0x8BC5, 0x963B, 0x7EC4, 0x94BB, 0x7E82, 0x5634, 0x9189, 0x6700, 0x7F6A, - 0x5C0A, 0x9075, 0x6628, 0x5DE6, 0x4F50, 0x67DE, 0x505A, 0x4F5C, 0x5750, 0x5EA7, 0xE810, 0xE811, 0xE812, 0xE813, 0xE814, - // GB 0xD840..0xD87E - 0x8C38, 0x8C39, 0x8C3A, 0x8C3B, 0x8C3C, 0x8C3D, 0x8C3E, 0x8C3F, - 0x8C40, 0x8C42, 0x8C43, 0x8C44, 0x8C45, 0x8C48, 0x8C4A, 0x8C4B, 0x8C4D, 0x8C4E, 0x8C4F, 0x8C50, 0x8C51, 0x8C52, 0x8C53, 0x8C54, - 0x8C56, 0x8C57, 0x8C58, 0x8C59, 0x8C5B, 0x8C5C, 0x8C5D, 0x8C5E, 0x8C5F, 0x8C60, 0x8C63, 0x8C64, 0x8C65, 0x8C66, 0x8C67, 0x8C68, - 0x8C69, 0x8C6C, 0x8C6D, 0x8C6E, 0x8C6F, 0x8C70, 0x8C71, 0x8C72, 0x8C74, 0x8C75, 0x8C76, 0x8C77, 0x8C7B, 0x8C7C, 0x8C7D, 0x8C7E, - 0x8C7F, 0x8C80, 0x8C81, 0x8C83, 0x8C84, 0x8C86, 0x8C87, - // GB 0xD880..0xD8FE - 0x8C88, 0x8C8B, 0x8C8D, 0x8C8E, 0x8C8F, 0x8C90, 0x8C91, 0x8C92, 0x8C93, 0x8C95, 0x8C96, 0x8C97, 0x8C99, 0x8C9A, 0x8C9B, 0x8C9C, - 0x8C9D, 0x8C9E, 0x8C9F, 0x8CA0, 0x8CA1, 0x8CA2, 0x8CA3, 0x8CA4, 0x8CA5, 0x8CA6, 0x8CA7, 0x8CA8, 0x8CA9, 0x8CAA, 0x8CAB, 0x8CAC, - 0x8CAD, 0x4E8D, 0x4E0C, 0x5140, 0x4E10, 0x5EFF, 0x5345, 0x4E15, 0x4E98, 0x4E1E, 0x9B32, 0x5B6C, 0x5669, 0x4E28, 0x79BA, 0x4E3F, - 0x5315, 0x4E47, 0x592D, 0x723B, 0x536E, 0x6C10, 0x56DF, 0x80E4, 0x9997, 0x6BD3, 0x777E, 0x9F17, 0x4E36, 0x4E9F, 0x9F10, 0x4E5C, - 0x4E69, 0x4E93, 0x8288, 0x5B5B, 0x556C, 0x560F, 0x4EC4, 0x538D, 0x539D, 0x53A3, 0x53A5, 0x53AE, 0x9765, 0x8D5D, 0x531A, 0x53F5, - 0x5326, 0x532E, 0x533E, 0x8D5C, 0x5366, 0x5363, 0x5202, 0x5208, 0x520E, 0x522D, 0x5233, 0x523F, 0x5240, 0x524C, 0x525E, 0x5261, - 0x525C, 0x84AF, 0x527D, 0x5282, 0x5281, 0x5290, 0x5293, 0x5182, 0x7F54, 0x4EBB, 0x4EC3, 0x4EC9, 0x4EC2, 0x4EE8, 0x4EE1, 0x4EEB, - 0x4EDE, 0x4F1B, 0x4EF3, 0x4F22, 0x4F64, 0x4EF5, 0x4F25, 0x4F27, 0x4F09, 0x4F2B, 0x4F5E, 0x4F67, 0x6538, 0x4F5A, 0x4F5D, - // GB 0xD940..0xD97E - 0x8CAE, 0x8CAF, 0x8CB0, 0x8CB1, 0x8CB2, 0x8CB3, 0x8CB4, 0x8CB5, - 0x8CB6, 0x8CB7, 0x8CB8, 0x8CB9, 0x8CBA, 0x8CBB, 0x8CBC, 0x8CBD, 0x8CBE, 0x8CBF, 0x8CC0, 0x8CC1, 0x8CC2, 0x8CC3, 0x8CC4, 0x8CC5, - 0x8CC6, 0x8CC7, 0x8CC8, 0x8CC9, 0x8CCA, 0x8CCB, 0x8CCC, 0x8CCD, 0x8CCE, 0x8CCF, 0x8CD0, 0x8CD1, 0x8CD2, 0x8CD3, 0x8CD4, 0x8CD5, - 0x8CD6, 0x8CD7, 0x8CD8, 0x8CD9, 0x8CDA, 0x8CDB, 0x8CDC, 0x8CDD, 0x8CDE, 0x8CDF, 0x8CE0, 0x8CE1, 0x8CE2, 0x8CE3, 0x8CE4, 0x8CE5, - 0x8CE6, 0x8CE7, 0x8CE8, 0x8CE9, 0x8CEA, 0x8CEB, 0x8CEC, - // GB 0xD980..0xD9FE - 0x8CED, 0x8CEE, 0x8CEF, 0x8CF0, 0x8CF1, 0x8CF2, 0x8CF3, 0x8CF4, 0x8CF5, 0x8CF6, 0x8CF7, 0x8CF8, 0x8CF9, 0x8CFA, 0x8CFB, 0x8CFC, - 0x8CFD, 0x8CFE, 0x8CFF, 0x8D00, 0x8D01, 0x8D02, 0x8D03, 0x8D04, 0x8D05, 0x8D06, 0x8D07, 0x8D08, 0x8D09, 0x8D0A, 0x8D0B, 0x8D0C, - 0x8D0D, 0x4F5F, 0x4F57, 0x4F32, 0x4F3D, 0x4F76, 0x4F74, 0x4F91, 0x4F89, 0x4F83, 0x4F8F, 0x4F7E, 0x4F7B, 0x4FAA, 0x4F7C, 0x4FAC, - 0x4F94, 0x4FE6, 0x4FE8, 0x4FEA, 0x4FC5, 0x4FDA, 0x4FE3, 0x4FDC, 0x4FD1, 0x4FDF, 0x4FF8, 0x5029, 0x504C, 0x4FF3, 0x502C, 0x500F, - 0x502E, 0x502D, 0x4FFE, 0x501C, 0x500C, 0x5025, 0x5028, 0x507E, 0x5043, 0x5055, 0x5048, 0x504E, 0x506C, 0x507B, 0x50A5, 0x50A7, - 0x50A9, 0x50BA, 0x50D6, 0x5106, 0x50ED, 0x50EC, 0x50E6, 0x50EE, 0x5107, 0x510B, 0x4EDD, 0x6C3D, 0x4F58, 0x4F65, 0x4FCE, 0x9FA0, - 0x6C46, 0x7C74, 0x516E, 0x5DFD, 0x9EC9, 0x9998, 0x5181, 0x5914, 0x52F9, 0x530D, 0x8A07, 0x5310, 0x51EB, 0x5919, 0x5155, 0x4EA0, - 0x5156, 0x4EB3, 0x886E, 0x88A4, 0x4EB5, 0x8114, 0x88D2, 0x7980, 0x5B34, 0x8803, 0x7FB8, 0x51AB, 0x51B1, 0x51BD, 0x51BC, - // GB 0xDA40..0xDA7E - 0x8D0E, 0x8D0F, 0x8D10, 0x8D11, 0x8D12, 0x8D13, 0x8D14, 0x8D15, - 0x8D16, 0x8D17, 0x8D18, 0x8D19, 0x8D1A, 0x8D1B, 0x8D1C, 0x8D20, 0x8D51, 0x8D52, 0x8D57, 0x8D5F, 0x8D65, 0x8D68, 0x8D69, 0x8D6A, - 0x8D6C, 0x8D6E, 0x8D6F, 0x8D71, 0x8D72, 0x8D78, 0x8D79, 0x8D7A, 0x8D7B, 0x8D7C, 0x8D7D, 0x8D7E, 0x8D7F, 0x8D80, 0x8D82, 0x8D83, - 0x8D86, 0x8D87, 0x8D88, 0x8D89, 0x8D8C, 0x8D8D, 0x8D8E, 0x8D8F, 0x8D90, 0x8D92, 0x8D93, 0x8D95, 0x8D96, 0x8D97, 0x8D98, 0x8D99, - 0x8D9A, 0x8D9B, 0x8D9C, 0x8D9D, 0x8D9E, 0x8DA0, 0x8DA1, - // GB 0xDA80..0xDAFE - 0x8DA2, 0x8DA4, 0x8DA5, 0x8DA6, 0x8DA7, 0x8DA8, 0x8DA9, 0x8DAA, 0x8DAB, 0x8DAC, 0x8DAD, 0x8DAE, 0x8DAF, 0x8DB0, 0x8DB2, 0x8DB6, - 0x8DB7, 0x8DB9, 0x8DBB, 0x8DBD, 0x8DC0, 0x8DC1, 0x8DC2, 0x8DC5, 0x8DC7, 0x8DC8, 0x8DC9, 0x8DCA, 0x8DCD, 0x8DD0, 0x8DD2, 0x8DD3, - 0x8DD4, 0x51C7, 0x5196, 0x51A2, 0x51A5, 0x8BA0, 0x8BA6, 0x8BA7, 0x8BAA, 0x8BB4, 0x8BB5, 0x8BB7, 0x8BC2, 0x8BC3, 0x8BCB, 0x8BCF, - 0x8BCE, 0x8BD2, 0x8BD3, 0x8BD4, 0x8BD6, 0x8BD8, 0x8BD9, 0x8BDC, 0x8BDF, 0x8BE0, 0x8BE4, 0x8BE8, 0x8BE9, 0x8BEE, 0x8BF0, 0x8BF3, - 0x8BF6, 0x8BF9, 0x8BFC, 0x8BFF, 0x8C00, 0x8C02, 0x8C04, 0x8C07, 0x8C0C, 0x8C0F, 0x8C11, 0x8C12, 0x8C14, 0x8C15, 0x8C16, 0x8C19, - 0x8C1B, 0x8C18, 0x8C1D, 0x8C1F, 0x8C20, 0x8C21, 0x8C25, 0x8C27, 0x8C2A, 0x8C2B, 0x8C2E, 0x8C2F, 0x8C32, 0x8C33, 0x8C35, 0x8C36, - 0x5369, 0x537A, 0x961D, 0x9622, 0x9621, 0x9631, 0x962A, 0x963D, 0x963C, 0x9642, 0x9649, 0x9654, 0x965F, 0x9667, 0x966C, 0x9672, - 0x9674, 0x9688, 0x968D, 0x9697, 0x96B0, 0x9097, 0x909B, 0x909D, 0x9099, 0x90AC, 0x90A1, 0x90B4, 0x90B3, 0x90B6, 0x90BA, - // GB 0xDB40..0xDB7E - 0x8DD5, 0x8DD8, 0x8DD9, 0x8DDC, 0x8DE0, 0x8DE1, 0x8DE2, 0x8DE5, - 0x8DE6, 0x8DE7, 0x8DE9, 0x8DED, 0x8DEE, 0x8DF0, 0x8DF1, 0x8DF2, 0x8DF4, 0x8DF6, 0x8DFC, 0x8DFE, 0x8DFF, 0x8E00, 0x8E01, 0x8E02, - 0x8E03, 0x8E04, 0x8E06, 0x8E07, 0x8E08, 0x8E0B, 0x8E0D, 0x8E0E, 0x8E10, 0x8E11, 0x8E12, 0x8E13, 0x8E15, 0x8E16, 0x8E17, 0x8E18, - 0x8E19, 0x8E1A, 0x8E1B, 0x8E1C, 0x8E20, 0x8E21, 0x8E24, 0x8E25, 0x8E26, 0x8E27, 0x8E28, 0x8E2B, 0x8E2D, 0x8E30, 0x8E32, 0x8E33, - 0x8E34, 0x8E36, 0x8E37, 0x8E38, 0x8E3B, 0x8E3C, 0x8E3E, - // GB 0xDB80..0xDBFE - 0x8E3F, 0x8E43, 0x8E45, 0x8E46, 0x8E4C, 0x8E4D, 0x8E4E, 0x8E4F, 0x8E50, 0x8E53, 0x8E54, 0x8E55, 0x8E56, 0x8E57, 0x8E58, 0x8E5A, - 0x8E5B, 0x8E5C, 0x8E5D, 0x8E5E, 0x8E5F, 0x8E60, 0x8E61, 0x8E62, 0x8E63, 0x8E64, 0x8E65, 0x8E67, 0x8E68, 0x8E6A, 0x8E6B, 0x8E6E, - 0x8E71, 0x90B8, 0x90B0, 0x90CF, 0x90C5, 0x90BE, 0x90D0, 0x90C4, 0x90C7, 0x90D3, 0x90E6, 0x90E2, 0x90DC, 0x90D7, 0x90DB, 0x90EB, - 0x90EF, 0x90FE, 0x9104, 0x9122, 0x911E, 0x9123, 0x9131, 0x912F, 0x9139, 0x9143, 0x9146, 0x520D, 0x5942, 0x52A2, 0x52AC, 0x52AD, - 0x52BE, 0x54FF, 0x52D0, 0x52D6, 0x52F0, 0x53DF, 0x71EE, 0x77CD, 0x5EF4, 0x51F5, 0x51FC, 0x9B2F, 0x53B6, 0x5F01, 0x755A, 0x5DEF, - 0x574C, 0x57A9, 0x57A1, 0x587E, 0x58BC, 0x58C5, 0x58D1, 0x5729, 0x572C, 0x572A, 0x5733, 0x5739, 0x572E, 0x572F, 0x575C, 0x573B, - 0x5742, 0x5769, 0x5785, 0x576B, 0x5786, 0x577C, 0x577B, 0x5768, 0x576D, 0x5776, 0x5773, 0x57AD, 0x57A4, 0x578C, 0x57B2, 0x57CF, - 0x57A7, 0x57B4, 0x5793, 0x57A0, 0x57D5, 0x57D8, 0x57DA, 0x57D9, 0x57D2, 0x57B8, 0x57F4, 0x57EF, 0x57F8, 0x57E4, 0x57DD, - // GB 0xDC40..0xDC7E - 0x8E73, 0x8E75, 0x8E77, 0x8E78, 0x8E79, 0x8E7A, 0x8E7B, 0x8E7D, - 0x8E7E, 0x8E80, 0x8E82, 0x8E83, 0x8E84, 0x8E86, 0x8E88, 0x8E89, 0x8E8A, 0x8E8B, 0x8E8C, 0x8E8D, 0x8E8E, 0x8E91, 0x8E92, 0x8E93, - 0x8E95, 0x8E96, 0x8E97, 0x8E98, 0x8E99, 0x8E9A, 0x8E9B, 0x8E9D, 0x8E9F, 0x8EA0, 0x8EA1, 0x8EA2, 0x8EA3, 0x8EA4, 0x8EA5, 0x8EA6, - 0x8EA7, 0x8EA8, 0x8EA9, 0x8EAA, 0x8EAD, 0x8EAE, 0x8EB0, 0x8EB1, 0x8EB3, 0x8EB4, 0x8EB5, 0x8EB6, 0x8EB7, 0x8EB8, 0x8EB9, 0x8EBB, - 0x8EBC, 0x8EBD, 0x8EBE, 0x8EBF, 0x8EC0, 0x8EC1, 0x8EC2, - // GB 0xDC80..0xDCFE - 0x8EC3, 0x8EC4, 0x8EC5, 0x8EC6, 0x8EC7, 0x8EC8, 0x8EC9, 0x8ECA, 0x8ECB, 0x8ECC, 0x8ECD, 0x8ECF, 0x8ED0, 0x8ED1, 0x8ED2, 0x8ED3, - 0x8ED4, 0x8ED5, 0x8ED6, 0x8ED7, 0x8ED8, 0x8ED9, 0x8EDA, 0x8EDB, 0x8EDC, 0x8EDD, 0x8EDE, 0x8EDF, 0x8EE0, 0x8EE1, 0x8EE2, 0x8EE3, - 0x8EE4, 0x580B, 0x580D, 0x57FD, 0x57ED, 0x5800, 0x581E, 0x5819, 0x5844, 0x5820, 0x5865, 0x586C, 0x5881, 0x5889, 0x589A, 0x5880, - 0x99A8, 0x9F19, 0x61FF, 0x8279, 0x827D, 0x827F, 0x828F, 0x828A, 0x82A8, 0x8284, 0x828E, 0x8291, 0x8297, 0x8299, 0x82AB, 0x82B8, - 0x82BE, 0x82B0, 0x82C8, 0x82CA, 0x82E3, 0x8298, 0x82B7, 0x82AE, 0x82CB, 0x82CC, 0x82C1, 0x82A9, 0x82B4, 0x82A1, 0x82AA, 0x829F, - 0x82C4, 0x82CE, 0x82A4, 0x82E1, 0x8309, 0x82F7, 0x82E4, 0x830F, 0x8307, 0x82DC, 0x82F4, 0x82D2, 0x82D8, 0x830C, 0x82FB, 0x82D3, - 0x8311, 0x831A, 0x8306, 0x8314, 0x8315, 0x82E0, 0x82D5, 0x831C, 0x8351, 0x835B, 0x835C, 0x8308, 0x8392, 0x833C, 0x8334, 0x8331, - 0x839B, 0x835E, 0x832F, 0x834F, 0x8347, 0x8343, 0x835F, 0x8340, 0x8317, 0x8360, 0x832D, 0x833A, 0x8333, 0x8366, 0x8365, - // GB 0xDD40..0xDD7E - 0x8EE5, 0x8EE6, 0x8EE7, 0x8EE8, 0x8EE9, 0x8EEA, 0x8EEB, 0x8EEC, - 0x8EED, 0x8EEE, 0x8EEF, 0x8EF0, 0x8EF1, 0x8EF2, 0x8EF3, 0x8EF4, 0x8EF5, 0x8EF6, 0x8EF7, 0x8EF8, 0x8EF9, 0x8EFA, 0x8EFB, 0x8EFC, - 0x8EFD, 0x8EFE, 0x8EFF, 0x8F00, 0x8F01, 0x8F02, 0x8F03, 0x8F04, 0x8F05, 0x8F06, 0x8F07, 0x8F08, 0x8F09, 0x8F0A, 0x8F0B, 0x8F0C, - 0x8F0D, 0x8F0E, 0x8F0F, 0x8F10, 0x8F11, 0x8F12, 0x8F13, 0x8F14, 0x8F15, 0x8F16, 0x8F17, 0x8F18, 0x8F19, 0x8F1A, 0x8F1B, 0x8F1C, - 0x8F1D, 0x8F1E, 0x8F1F, 0x8F20, 0x8F21, 0x8F22, 0x8F23, - // GB 0xDD80..0xDDFE - 0x8F24, 0x8F25, 0x8F26, 0x8F27, 0x8F28, 0x8F29, 0x8F2A, 0x8F2B, 0x8F2C, 0x8F2D, 0x8F2E, 0x8F2F, 0x8F30, 0x8F31, 0x8F32, 0x8F33, - 0x8F34, 0x8F35, 0x8F36, 0x8F37, 0x8F38, 0x8F39, 0x8F3A, 0x8F3B, 0x8F3C, 0x8F3D, 0x8F3E, 0x8F3F, 0x8F40, 0x8F41, 0x8F42, 0x8F43, - 0x8F44, 0x8368, 0x831B, 0x8369, 0x836C, 0x836A, 0x836D, 0x836E, 0x83B0, 0x8378, 0x83B3, 0x83B4, 0x83A0, 0x83AA, 0x8393, 0x839C, - 0x8385, 0x837C, 0x83B6, 0x83A9, 0x837D, 0x83B8, 0x837B, 0x8398, 0x839E, 0x83A8, 0x83BA, 0x83BC, 0x83C1, 0x8401, 0x83E5, 0x83D8, - 0x5807, 0x8418, 0x840B, 0x83DD, 0x83FD, 0x83D6, 0x841C, 0x8438, 0x8411, 0x8406, 0x83D4, 0x83DF, 0x840F, 0x8403, 0x83F8, 0x83F9, - 0x83EA, 0x83C5, 0x83C0, 0x8426, 0x83F0, 0x83E1, 0x845C, 0x8451, 0x845A, 0x8459, 0x8473, 0x8487, 0x8488, 0x847A, 0x8489, 0x8478, - 0x843C, 0x8446, 0x8469, 0x8476, 0x848C, 0x848E, 0x8431, 0x846D, 0x84C1, 0x84CD, 0x84D0, 0x84E6, 0x84BD, 0x84D3, 0x84CA, 0x84BF, - 0x84BA, 0x84E0, 0x84A1, 0x84B9, 0x84B4, 0x8497, 0x84E5, 0x84E3, 0x850C, 0x750D, 0x8538, 0x84F0, 0x8539, 0x851F, 0x853A, - // GB 0xDE40..0xDE7E - 0x8F45, 0x8F46, 0x8F47, 0x8F48, 0x8F49, 0x8F4A, 0x8F4B, 0x8F4C, - 0x8F4D, 0x8F4E, 0x8F4F, 0x8F50, 0x8F51, 0x8F52, 0x8F53, 0x8F54, 0x8F55, 0x8F56, 0x8F57, 0x8F58, 0x8F59, 0x8F5A, 0x8F5B, 0x8F5C, - 0x8F5D, 0x8F5E, 0x8F5F, 0x8F60, 0x8F61, 0x8F62, 0x8F63, 0x8F64, 0x8F65, 0x8F6A, 0x8F80, 0x8F8C, 0x8F92, 0x8F9D, 0x8FA0, 0x8FA1, - 0x8FA2, 0x8FA4, 0x8FA5, 0x8FA6, 0x8FA7, 0x8FAA, 0x8FAC, 0x8FAD, 0x8FAE, 0x8FAF, 0x8FB2, 0x8FB3, 0x8FB4, 0x8FB5, 0x8FB7, 0x8FB8, - 0x8FBA, 0x8FBB, 0x8FBC, 0x8FBF, 0x8FC0, 0x8FC3, 0x8FC6, - // GB 0xDE80..0xDEFE - 0x8FC9, 0x8FCA, 0x8FCB, 0x8FCC, 0x8FCD, 0x8FCF, 0x8FD2, 0x8FD6, 0x8FD7, 0x8FDA, 0x8FE0, 0x8FE1, 0x8FE3, 0x8FE7, 0x8FEC, 0x8FEF, - 0x8FF1, 0x8FF2, 0x8FF4, 0x8FF5, 0x8FF6, 0x8FFA, 0x8FFB, 0x8FFC, 0x8FFE, 0x8FFF, 0x9007, 0x9008, 0x900C, 0x900E, 0x9013, 0x9015, - 0x9018, 0x8556, 0x853B, 0x84FF, 0x84FC, 0x8559, 0x8548, 0x8568, 0x8564, 0x855E, 0x857A, 0x77A2, 0x8543, 0x8572, 0x857B, 0x85A4, - 0x85A8, 0x8587, 0x858F, 0x8579, 0x85AE, 0x859C, 0x8585, 0x85B9, 0x85B7, 0x85B0, 0x85D3, 0x85C1, 0x85DC, 0x85FF, 0x8627, 0x8605, - 0x8629, 0x8616, 0x863C, 0x5EFE, 0x5F08, 0x593C, 0x5941, 0x8037, 0x5955, 0x595A, 0x5958, 0x530F, 0x5C22, 0x5C25, 0x5C2C, 0x5C34, - 0x624C, 0x626A, 0x629F, 0x62BB, 0x62CA, 0x62DA, 0x62D7, 0x62EE, 0x6322, 0x62F6, 0x6339, 0x634B, 0x6343, 0x63AD, 0x63F6, 0x6371, - 0x637A, 0x638E, 0x63B4, 0x636D, 0x63AC, 0x638A, 0x6369, 0x63AE, 0x63BC, 0x63F2, 0x63F8, 0x63E0, 0x63FF, 0x63C4, 0x63DE, 0x63CE, - 0x6452, 0x63C6, 0x63BE, 0x6445, 0x6441, 0x640B, 0x641B, 0x6420, 0x640C, 0x6426, 0x6421, 0x645E, 0x6484, 0x646D, 0x6496, - // GB 0xDF40..0xDF7E - 0x9019, 0x901C, 0x9023, 0x9024, 0x9025, 0x9027, 0x9028, 0x9029, - 0x902A, 0x902B, 0x902C, 0x9030, 0x9031, 0x9032, 0x9033, 0x9034, 0x9037, 0x9039, 0x903A, 0x903D, 0x903F, 0x9040, 0x9043, 0x9045, - 0x9046, 0x9048, 0x9049, 0x904A, 0x904B, 0x904C, 0x904E, 0x9054, 0x9055, 0x9056, 0x9059, 0x905A, 0x905C, 0x905D, 0x905E, 0x905F, - 0x9060, 0x9061, 0x9064, 0x9066, 0x9067, 0x9069, 0x906A, 0x906B, 0x906C, 0x906F, 0x9070, 0x9071, 0x9072, 0x9073, 0x9076, 0x9077, - 0x9078, 0x9079, 0x907A, 0x907B, 0x907C, 0x907E, 0x9081, - // GB 0xDF80..0xDFFE - 0x9084, 0x9085, 0x9086, 0x9087, 0x9089, 0x908A, 0x908C, 0x908D, 0x908E, 0x908F, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909A, - 0x909C, 0x909E, 0x909F, 0x90A0, 0x90A4, 0x90A5, 0x90A7, 0x90A8, 0x90A9, 0x90AB, 0x90AD, 0x90B2, 0x90B7, 0x90BC, 0x90BD, 0x90BF, - 0x90C0, 0x647A, 0x64B7, 0x64B8, 0x6499, 0x64BA, 0x64C0, 0x64D0, 0x64D7, 0x64E4, 0x64E2, 0x6509, 0x6525, 0x652E, 0x5F0B, 0x5FD2, - 0x7519, 0x5F11, 0x535F, 0x53F1, 0x53FD, 0x53E9, 0x53E8, 0x53FB, 0x5412, 0x5416, 0x5406, 0x544B, 0x5452, 0x5453, 0x5454, 0x5456, - 0x5443, 0x5421, 0x5457, 0x5459, 0x5423, 0x5432, 0x5482, 0x5494, 0x5477, 0x5471, 0x5464, 0x549A, 0x549B, 0x5484, 0x5476, 0x5466, - 0x549D, 0x54D0, 0x54AD, 0x54C2, 0x54B4, 0x54D2, 0x54A7, 0x54A6, 0x54D3, 0x54D4, 0x5472, 0x54A3, 0x54D5, 0x54BB, 0x54BF, 0x54CC, - 0x54D9, 0x54DA, 0x54DC, 0x54A9, 0x54AA, 0x54A4, 0x54DD, 0x54CF, 0x54DE, 0x551B, 0x54E7, 0x5520, 0x54FD, 0x5514, 0x54F3, 0x5522, - 0x5523, 0x550F, 0x5511, 0x5527, 0x552A, 0x5567, 0x558F, 0x55B5, 0x5549, 0x556D, 0x5541, 0x5555, 0x553F, 0x5550, 0x553C, - // GB 0xE040..0xE07E - 0x90C2, 0x90C3, 0x90C6, 0x90C8, 0x90C9, 0x90CB, 0x90CC, 0x90CD, - 0x90D2, 0x90D4, 0x90D5, 0x90D6, 0x90D8, 0x90D9, 0x90DA, 0x90DE, 0x90DF, 0x90E0, 0x90E3, 0x90E4, 0x90E5, 0x90E9, 0x90EA, 0x90EC, - 0x90EE, 0x90F0, 0x90F1, 0x90F2, 0x90F3, 0x90F5, 0x90F6, 0x90F7, 0x90F9, 0x90FA, 0x90FB, 0x90FC, 0x90FF, 0x9100, 0x9101, 0x9103, - 0x9105, 0x9106, 0x9107, 0x9108, 0x9109, 0x910A, 0x910B, 0x910C, 0x910D, 0x910E, 0x910F, 0x9110, 0x9111, 0x9112, 0x9113, 0x9114, - 0x9115, 0x9116, 0x9117, 0x9118, 0x911A, 0x911B, 0x911C, - // GB 0xE080..0xE0FE - 0x911D, 0x911F, 0x9120, 0x9121, 0x9124, 0x9125, 0x9126, 0x9127, 0x9128, 0x9129, 0x912A, 0x912B, 0x912C, 0x912D, 0x912E, 0x9130, - 0x9132, 0x9133, 0x9134, 0x9135, 0x9136, 0x9137, 0x9138, 0x913A, 0x913B, 0x913C, 0x913D, 0x913E, 0x913F, 0x9140, 0x9141, 0x9142, - 0x9144, 0x5537, 0x5556, 0x5575, 0x5576, 0x5577, 0x5533, 0x5530, 0x555C, 0x558B, 0x55D2, 0x5583, 0x55B1, 0x55B9, 0x5588, 0x5581, - 0x559F, 0x557E, 0x55D6, 0x5591, 0x557B, 0x55DF, 0x55BD, 0x55BE, 0x5594, 0x5599, 0x55EA, 0x55F7, 0x55C9, 0x561F, 0x55D1, 0x55EB, - 0x55EC, 0x55D4, 0x55E6, 0x55DD, 0x55C4, 0x55EF, 0x55E5, 0x55F2, 0x55F3, 0x55CC, 0x55CD, 0x55E8, 0x55F5, 0x55E4, 0x8F94, 0x561E, - 0x5608, 0x560C, 0x5601, 0x5624, 0x5623, 0x55FE, 0x5600, 0x5627, 0x562D, 0x5658, 0x5639, 0x5657, 0x562C, 0x564D, 0x5662, 0x5659, - 0x565C, 0x564C, 0x5654, 0x5686, 0x5664, 0x5671, 0x566B, 0x567B, 0x567C, 0x5685, 0x5693, 0x56AF, 0x56D4, 0x56D7, 0x56DD, 0x56E1, - 0x56F5, 0x56EB, 0x56F9, 0x56FF, 0x5704, 0x570A, 0x5709, 0x571C, 0x5E0F, 0x5E19, 0x5E14, 0x5E11, 0x5E31, 0x5E3B, 0x5E3C, - // GB 0xE140..0xE17E - 0x9145, 0x9147, 0x9148, 0x9151, 0x9153, 0x9154, 0x9155, 0x9156, - 0x9158, 0x9159, 0x915B, 0x915C, 0x915F, 0x9160, 0x9166, 0x9167, 0x9168, 0x916B, 0x916D, 0x9173, 0x917A, 0x917B, 0x917C, 0x9180, - 0x9181, 0x9182, 0x9183, 0x9184, 0x9186, 0x9188, 0x918A, 0x918E, 0x918F, 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, - 0x919C, 0x919D, 0x919E, 0x919F, 0x91A0, 0x91A1, 0x91A4, 0x91A5, 0x91A6, 0x91A7, 0x91A8, 0x91A9, 0x91AB, 0x91AC, 0x91B0, 0x91B1, - 0x91B2, 0x91B3, 0x91B6, 0x91B7, 0x91B8, 0x91B9, 0x91BB, - // GB 0xE180..0xE1FE - 0x91BC, 0x91BD, 0x91BE, 0x91BF, 0x91C0, 0x91C1, 0x91C2, 0x91C3, 0x91C4, 0x91C5, 0x91C6, 0x91C8, 0x91CB, 0x91D0, 0x91D2, 0x91D3, - 0x91D4, 0x91D5, 0x91D6, 0x91D7, 0x91D8, 0x91D9, 0x91DA, 0x91DB, 0x91DD, 0x91DE, 0x91DF, 0x91E0, 0x91E1, 0x91E2, 0x91E3, 0x91E4, - 0x91E5, 0x5E37, 0x5E44, 0x5E54, 0x5E5B, 0x5E5E, 0x5E61, 0x5C8C, 0x5C7A, 0x5C8D, 0x5C90, 0x5C96, 0x5C88, 0x5C98, 0x5C99, 0x5C91, - 0x5C9A, 0x5C9C, 0x5CB5, 0x5CA2, 0x5CBD, 0x5CAC, 0x5CAB, 0x5CB1, 0x5CA3, 0x5CC1, 0x5CB7, 0x5CC4, 0x5CD2, 0x5CE4, 0x5CCB, 0x5CE5, - 0x5D02, 0x5D03, 0x5D27, 0x5D26, 0x5D2E, 0x5D24, 0x5D1E, 0x5D06, 0x5D1B, 0x5D58, 0x5D3E, 0x5D34, 0x5D3D, 0x5D6C, 0x5D5B, 0x5D6F, - 0x5D5D, 0x5D6B, 0x5D4B, 0x5D4A, 0x5D69, 0x5D74, 0x5D82, 0x5D99, 0x5D9D, 0x8C73, 0x5DB7, 0x5DC5, 0x5F73, 0x5F77, 0x5F82, 0x5F87, - 0x5F89, 0x5F8C, 0x5F95, 0x5F99, 0x5F9C, 0x5FA8, 0x5FAD, 0x5FB5, 0x5FBC, 0x8862, 0x5F61, 0x72AD, 0x72B0, 0x72B4, 0x72B7, 0x72B8, - 0x72C3, 0x72C1, 0x72CE, 0x72CD, 0x72D2, 0x72E8, 0x72EF, 0x72E9, 0x72F2, 0x72F4, 0x72F7, 0x7301, 0x72F3, 0x7303, 0x72FA, - // GB 0xE240..0xE27E - 0x91E6, 0x91E7, 0x91E8, 0x91E9, 0x91EA, 0x91EB, 0x91EC, 0x91ED, - 0x91EE, 0x91EF, 0x91F0, 0x91F1, 0x91F2, 0x91F3, 0x91F4, 0x91F5, 0x91F6, 0x91F7, 0x91F8, 0x91F9, 0x91FA, 0x91FB, 0x91FC, 0x91FD, - 0x91FE, 0x91FF, 0x9200, 0x9201, 0x9202, 0x9203, 0x9204, 0x9205, 0x9206, 0x9207, 0x9208, 0x9209, 0x920A, 0x920B, 0x920C, 0x920D, - 0x920E, 0x920F, 0x9210, 0x9211, 0x9212, 0x9213, 0x9214, 0x9215, 0x9216, 0x9217, 0x9218, 0x9219, 0x921A, 0x921B, 0x921C, 0x921D, - 0x921E, 0x921F, 0x9220, 0x9221, 0x9222, 0x9223, 0x9224, - // GB 0xE280..0xE2FE - 0x9225, 0x9226, 0x9227, 0x9228, 0x9229, 0x922A, 0x922B, 0x922C, 0x922D, 0x922E, 0x922F, 0x9230, 0x9231, 0x9232, 0x9233, 0x9234, - 0x9235, 0x9236, 0x9237, 0x9238, 0x9239, 0x923A, 0x923B, 0x923C, 0x923D, 0x923E, 0x923F, 0x9240, 0x9241, 0x9242, 0x9243, 0x9244, - 0x9245, 0x72FB, 0x7317, 0x7313, 0x7321, 0x730A, 0x731E, 0x731D, 0x7315, 0x7322, 0x7339, 0x7325, 0x732C, 0x7338, 0x7331, 0x7350, - 0x734D, 0x7357, 0x7360, 0x736C, 0x736F, 0x737E, 0x821B, 0x5925, 0x98E7, 0x5924, 0x5902, 0x9963, 0x9967, 0x9968, 0x9969, 0x996A, - 0x996B, 0x996C, 0x9974, 0x9977, 0x997D, 0x9980, 0x9984, 0x9987, 0x998A, 0x998D, 0x9990, 0x9991, 0x9993, 0x9994, 0x9995, 0x5E80, - 0x5E91, 0x5E8B, 0x5E96, 0x5EA5, 0x5EA0, 0x5EB9, 0x5EB5, 0x5EBE, 0x5EB3, 0x8D53, 0x5ED2, 0x5ED1, 0x5EDB, 0x5EE8, 0x5EEA, 0x81BA, - 0x5FC4, 0x5FC9, 0x5FD6, 0x5FCF, 0x6003, 0x5FEE, 0x6004, 0x5FE1, 0x5FE4, 0x5FFE, 0x6005, 0x6006, 0x5FEA, 0x5FED, 0x5FF8, 0x6019, - 0x6035, 0x6026, 0x601B, 0x600F, 0x600D, 0x6029, 0x602B, 0x600A, 0x603F, 0x6021, 0x6078, 0x6079, 0x607B, 0x607A, 0x6042, - // GB 0xE340..0xE37E - 0x9246, 0x9247, 0x9248, 0x9249, 0x924A, 0x924B, 0x924C, 0x924D, - 0x924E, 0x924F, 0x9250, 0x9251, 0x9252, 0x9253, 0x9254, 0x9255, 0x9256, 0x9257, 0x9258, 0x9259, 0x925A, 0x925B, 0x925C, 0x925D, - 0x925E, 0x925F, 0x9260, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265, 0x9266, 0x9267, 0x9268, 0x9269, 0x926A, 0x926B, 0x926C, 0x926D, - 0x926E, 0x926F, 0x9270, 0x9271, 0x9272, 0x9273, 0x9275, 0x9276, 0x9277, 0x9278, 0x9279, 0x927A, 0x927B, 0x927C, 0x927D, 0x927E, - 0x927F, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284, 0x9285, - // GB 0xE380..0xE3FE - 0x9286, 0x9287, 0x9288, 0x9289, 0x928A, 0x928B, 0x928C, 0x928D, 0x928F, 0x9290, 0x9291, 0x9292, 0x9293, 0x9294, 0x9295, 0x9296, - 0x9297, 0x9298, 0x9299, 0x929A, 0x929B, 0x929C, 0x929D, 0x929E, 0x929F, 0x92A0, 0x92A1, 0x92A2, 0x92A3, 0x92A4, 0x92A5, 0x92A6, - 0x92A7, 0x606A, 0x607D, 0x6096, 0x609A, 0x60AD, 0x609D, 0x6083, 0x6092, 0x608C, 0x609B, 0x60EC, 0x60BB, 0x60B1, 0x60DD, 0x60D8, - 0x60C6, 0x60DA, 0x60B4, 0x6120, 0x6126, 0x6115, 0x6123, 0x60F4, 0x6100, 0x610E, 0x612B, 0x614A, 0x6175, 0x61AC, 0x6194, 0x61A7, - 0x61B7, 0x61D4, 0x61F5, 0x5FDD, 0x96B3, 0x95E9, 0x95EB, 0x95F1, 0x95F3, 0x95F5, 0x95F6, 0x95FC, 0x95FE, 0x9603, 0x9604, 0x9606, - 0x9608, 0x960A, 0x960B, 0x960C, 0x960D, 0x960F, 0x9612, 0x9615, 0x9616, 0x9617, 0x9619, 0x961A, 0x4E2C, 0x723F, 0x6215, 0x6C35, - 0x6C54, 0x6C5C, 0x6C4A, 0x6CA3, 0x6C85, 0x6C90, 0x6C94, 0x6C8C, 0x6C68, 0x6C69, 0x6C74, 0x6C76, 0x6C86, 0x6CA9, 0x6CD0, 0x6CD4, - 0x6CAD, 0x6CF7, 0x6CF8, 0x6CF1, 0x6CD7, 0x6CB2, 0x6CE0, 0x6CD6, 0x6CFA, 0x6CEB, 0x6CEE, 0x6CB1, 0x6CD3, 0x6CEF, 0x6CFE, - // GB 0xE440..0xE47E - 0x92A8, 0x92A9, 0x92AA, 0x92AB, 0x92AC, 0x92AD, 0x92AF, 0x92B0, - 0x92B1, 0x92B2, 0x92B3, 0x92B4, 0x92B5, 0x92B6, 0x92B7, 0x92B8, 0x92B9, 0x92BA, 0x92BB, 0x92BC, 0x92BD, 0x92BE, 0x92BF, 0x92C0, - 0x92C1, 0x92C2, 0x92C3, 0x92C4, 0x92C5, 0x92C6, 0x92C7, 0x92C9, 0x92CA, 0x92CB, 0x92CC, 0x92CD, 0x92CE, 0x92CF, 0x92D0, 0x92D1, - 0x92D2, 0x92D3, 0x92D4, 0x92D5, 0x92D6, 0x92D7, 0x92D8, 0x92D9, 0x92DA, 0x92DB, 0x92DC, 0x92DD, 0x92DE, 0x92DF, 0x92E0, 0x92E1, - 0x92E2, 0x92E3, 0x92E4, 0x92E5, 0x92E6, 0x92E7, 0x92E8, - // GB 0xE480..0xE4FE - 0x92E9, 0x92EA, 0x92EB, 0x92EC, 0x92ED, 0x92EE, 0x92EF, 0x92F0, 0x92F1, 0x92F2, 0x92F3, 0x92F4, 0x92F5, 0x92F6, 0x92F7, 0x92F8, - 0x92F9, 0x92FA, 0x92FB, 0x92FC, 0x92FD, 0x92FE, 0x92FF, 0x9300, 0x9301, 0x9302, 0x9303, 0x9304, 0x9305, 0x9306, 0x9307, 0x9308, - 0x9309, 0x6D39, 0x6D27, 0x6D0C, 0x6D43, 0x6D48, 0x6D07, 0x6D04, 0x6D19, 0x6D0E, 0x6D2B, 0x6D4D, 0x6D2E, 0x6D35, 0x6D1A, 0x6D4F, - 0x6D52, 0x6D54, 0x6D33, 0x6D91, 0x6D6F, 0x6D9E, 0x6DA0, 0x6D5E, 0x6D93, 0x6D94, 0x6D5C, 0x6D60, 0x6D7C, 0x6D63, 0x6E1A, 0x6DC7, - 0x6DC5, 0x6DDE, 0x6E0E, 0x6DBF, 0x6DE0, 0x6E11, 0x6DE6, 0x6DDD, 0x6DD9, 0x6E16, 0x6DAB, 0x6E0C, 0x6DAE, 0x6E2B, 0x6E6E, 0x6E4E, - 0x6E6B, 0x6EB2, 0x6E5F, 0x6E86, 0x6E53, 0x6E54, 0x6E32, 0x6E25, 0x6E44, 0x6EDF, 0x6EB1, 0x6E98, 0x6EE0, 0x6F2D, 0x6EE2, 0x6EA5, - 0x6EA7, 0x6EBD, 0x6EBB, 0x6EB7, 0x6ED7, 0x6EB4, 0x6ECF, 0x6E8F, 0x6EC2, 0x6E9F, 0x6F62, 0x6F46, 0x6F47, 0x6F24, 0x6F15, 0x6EF9, - 0x6F2F, 0x6F36, 0x6F4B, 0x6F74, 0x6F2A, 0x6F09, 0x6F29, 0x6F89, 0x6F8D, 0x6F8C, 0x6F78, 0x6F72, 0x6F7C, 0x6F7A, 0x6FD1, - // GB 0xE540..0xE57E - 0x930A, 0x930B, 0x930C, 0x930D, 0x930E, 0x930F, 0x9310, 0x9311, - 0x9312, 0x9313, 0x9314, 0x9315, 0x9316, 0x9317, 0x9318, 0x9319, 0x931A, 0x931B, 0x931C, 0x931D, 0x931E, 0x931F, 0x9320, 0x9321, - 0x9322, 0x9323, 0x9324, 0x9325, 0x9326, 0x9327, 0x9328, 0x9329, 0x932A, 0x932B, 0x932C, 0x932D, 0x932E, 0x932F, 0x9330, 0x9331, - 0x9332, 0x9333, 0x9334, 0x9335, 0x9336, 0x9337, 0x9338, 0x9339, 0x933A, 0x933B, 0x933C, 0x933D, 0x933F, 0x9340, 0x9341, 0x9342, - 0x9343, 0x9344, 0x9345, 0x9346, 0x9347, 0x9348, 0x9349, - // GB 0xE580..0xE5FE - 0x934A, 0x934B, 0x934C, 0x934D, 0x934E, 0x934F, 0x9350, 0x9351, 0x9352, 0x9353, 0x9354, 0x9355, 0x9356, 0x9357, 0x9358, 0x9359, - 0x935A, 0x935B, 0x935C, 0x935D, 0x935E, 0x935F, 0x9360, 0x9361, 0x9362, 0x9363, 0x9364, 0x9365, 0x9366, 0x9367, 0x9368, 0x9369, - 0x936B, 0x6FC9, 0x6FA7, 0x6FB9, 0x6FB6, 0x6FC2, 0x6FE1, 0x6FEE, 0x6FDE, 0x6FE0, 0x6FEF, 0x701A, 0x7023, 0x701B, 0x7039, 0x7035, - 0x704F, 0x705E, 0x5B80, 0x5B84, 0x5B95, 0x5B93, 0x5BA5, 0x5BB8, 0x752F, 0x9A9E, 0x6434, 0x5BE4, 0x5BEE, 0x8930, 0x5BF0, 0x8E47, - 0x8B07, 0x8FB6, 0x8FD3, 0x8FD5, 0x8FE5, 0x8FEE, 0x8FE4, 0x8FE9, 0x8FE6, 0x8FF3, 0x8FE8, 0x9005, 0x9004, 0x900B, 0x9026, 0x9011, - 0x900D, 0x9016, 0x9021, 0x9035, 0x9036, 0x902D, 0x902F, 0x9044, 0x9051, 0x9052, 0x9050, 0x9068, 0x9058, 0x9062, 0x905B, 0x66B9, - 0x9074, 0x907D, 0x9082, 0x9088, 0x9083, 0x908B, 0x5F50, 0x5F57, 0x5F56, 0x5F58, 0x5C3B, 0x54AB, 0x5C50, 0x5C59, 0x5B71, 0x5C63, - 0x5C66, 0x7FBC, 0x5F2A, 0x5F29, 0x5F2D, 0x8274, 0x5F3C, 0x9B3B, 0x5C6E, 0x5981, 0x5983, 0x598D, 0x59A9, 0x59AA, 0x59A3, - // GB 0xE640..0xE67E - 0x936C, 0x936D, 0x936E, 0x936F, 0x9370, 0x9371, 0x9372, 0x9373, - 0x9374, 0x9375, 0x9376, 0x9377, 0x9378, 0x9379, 0x937A, 0x937B, 0x937C, 0x937D, 0x937E, 0x937F, 0x9380, 0x9381, 0x9382, 0x9383, - 0x9384, 0x9385, 0x9386, 0x9387, 0x9388, 0x9389, 0x938A, 0x938B, 0x938C, 0x938D, 0x938E, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394, - 0x9395, 0x9396, 0x9397, 0x9398, 0x9399, 0x939A, 0x939B, 0x939C, 0x939D, 0x939E, 0x939F, 0x93A0, 0x93A1, 0x93A2, 0x93A3, 0x93A4, - 0x93A5, 0x93A6, 0x93A7, 0x93A8, 0x93A9, 0x93AA, 0x93AB, - // GB 0xE680..0xE6FE - 0x93AC, 0x93AD, 0x93AE, 0x93AF, 0x93B0, 0x93B1, 0x93B2, 0x93B3, 0x93B4, 0x93B5, 0x93B6, 0x93B7, 0x93B8, 0x93B9, 0x93BA, 0x93BB, - 0x93BC, 0x93BD, 0x93BE, 0x93BF, 0x93C0, 0x93C1, 0x93C2, 0x93C3, 0x93C4, 0x93C5, 0x93C6, 0x93C7, 0x93C8, 0x93C9, 0x93CB, 0x93CC, - 0x93CD, 0x5997, 0x59CA, 0x59AB, 0x599E, 0x59A4, 0x59D2, 0x59B2, 0x59AF, 0x59D7, 0x59BE, 0x5A05, 0x5A06, 0x59DD, 0x5A08, 0x59E3, - 0x59D8, 0x59F9, 0x5A0C, 0x5A09, 0x5A32, 0x5A34, 0x5A11, 0x5A23, 0x5A13, 0x5A40, 0x5A67, 0x5A4A, 0x5A55, 0x5A3C, 0x5A62, 0x5A75, - 0x80EC, 0x5AAA, 0x5A9B, 0x5A77, 0x5A7A, 0x5ABE, 0x5AEB, 0x5AB2, 0x5AD2, 0x5AD4, 0x5AB8, 0x5AE0, 0x5AE3, 0x5AF1, 0x5AD6, 0x5AE6, - 0x5AD8, 0x5ADC, 0x5B09, 0x5B17, 0x5B16, 0x5B32, 0x5B37, 0x5B40, 0x5C15, 0x5C1C, 0x5B5A, 0x5B65, 0x5B73, 0x5B51, 0x5B53, 0x5B62, - 0x9A75, 0x9A77, 0x9A78, 0x9A7A, 0x9A7F, 0x9A7D, 0x9A80, 0x9A81, 0x9A85, 0x9A88, 0x9A8A, 0x9A90, 0x9A92, 0x9A93, 0x9A96, 0x9A98, - 0x9A9B, 0x9A9C, 0x9A9D, 0x9A9F, 0x9AA0, 0x9AA2, 0x9AA3, 0x9AA5, 0x9AA7, 0x7E9F, 0x7EA1, 0x7EA3, 0x7EA5, 0x7EA8, 0x7EA9, - // GB 0xE740..0xE77E - 0x93CE, 0x93CF, 0x93D0, 0x93D1, 0x93D2, 0x93D3, 0x93D4, 0x93D5, - 0x93D7, 0x93D8, 0x93D9, 0x93DA, 0x93DB, 0x93DC, 0x93DD, 0x93DE, 0x93DF, 0x93E0, 0x93E1, 0x93E2, 0x93E3, 0x93E4, 0x93E5, 0x93E6, - 0x93E7, 0x93E8, 0x93E9, 0x93EA, 0x93EB, 0x93EC, 0x93ED, 0x93EE, 0x93EF, 0x93F0, 0x93F1, 0x93F2, 0x93F3, 0x93F4, 0x93F5, 0x93F6, - 0x93F7, 0x93F8, 0x93F9, 0x93FA, 0x93FB, 0x93FC, 0x93FD, 0x93FE, 0x93FF, 0x9400, 0x9401, 0x9402, 0x9403, 0x9404, 0x9405, 0x9406, - 0x9407, 0x9408, 0x9409, 0x940A, 0x940B, 0x940C, 0x940D, - // GB 0xE780..0xE7FE - 0x940E, 0x940F, 0x9410, 0x9411, 0x9412, 0x9413, 0x9414, 0x9415, 0x9416, 0x9417, 0x9418, 0x9419, 0x941A, 0x941B, 0x941C, 0x941D, - 0x941E, 0x941F, 0x9420, 0x9421, 0x9422, 0x9423, 0x9424, 0x9425, 0x9426, 0x9427, 0x9428, 0x9429, 0x942A, 0x942B, 0x942C, 0x942D, - 0x942E, 0x7EAD, 0x7EB0, 0x7EBE, 0x7EC0, 0x7EC1, 0x7EC2, 0x7EC9, 0x7ECB, 0x7ECC, 0x7ED0, 0x7ED4, 0x7ED7, 0x7EDB, 0x7EE0, 0x7EE1, - 0x7EE8, 0x7EEB, 0x7EEE, 0x7EEF, 0x7EF1, 0x7EF2, 0x7F0D, 0x7EF6, 0x7EFA, 0x7EFB, 0x7EFE, 0x7F01, 0x7F02, 0x7F03, 0x7F07, 0x7F08, - 0x7F0B, 0x7F0C, 0x7F0F, 0x7F11, 0x7F12, 0x7F17, 0x7F19, 0x7F1C, 0x7F1B, 0x7F1F, 0x7F21, 0x7F22, 0x7F23, 0x7F24, 0x7F25, 0x7F26, - 0x7F27, 0x7F2A, 0x7F2B, 0x7F2C, 0x7F2D, 0x7F2F, 0x7F30, 0x7F31, 0x7F32, 0x7F33, 0x7F35, 0x5E7A, 0x757F, 0x5DDB, 0x753E, 0x9095, - 0x738E, 0x7391, 0x73AE, 0x73A2, 0x739F, 0x73CF, 0x73C2, 0x73D1, 0x73B7, 0x73B3, 0x73C0, 0x73C9, 0x73C8, 0x73E5, 0x73D9, 0x987C, - 0x740A, 0x73E9, 0x73E7, 0x73DE, 0x73BA, 0x73F2, 0x740F, 0x742A, 0x745B, 0x7426, 0x7425, 0x7428, 0x7430, 0x742E, 0x742C, - // GB 0xE840..0xE87E - 0x942F, 0x9430, 0x9431, 0x9432, 0x9433, 0x9434, 0x9435, 0x9436, - 0x9437, 0x9438, 0x9439, 0x943A, 0x943B, 0x943C, 0x943D, 0x943F, 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447, - 0x9448, 0x9449, 0x944A, 0x944B, 0x944C, 0x944D, 0x944E, 0x944F, 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, - 0x9458, 0x9459, 0x945A, 0x945B, 0x945C, 0x945D, 0x945E, 0x945F, 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, - 0x9468, 0x9469, 0x946A, 0x946C, 0x946D, 0x946E, 0x946F, - // GB 0xE880..0xE8FE - 0x9470, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477, 0x9478, 0x9479, 0x947A, 0x947B, 0x947C, 0x947D, 0x947E, 0x947F, - 0x9480, 0x9481, 0x9482, 0x9483, 0x9484, 0x9491, 0x9496, 0x9498, 0x94C7, 0x94CF, 0x94D3, 0x94D4, 0x94DA, 0x94E6, 0x94FB, 0x951C, - 0x9520, 0x741B, 0x741A, 0x7441, 0x745C, 0x7457, 0x7455, 0x7459, 0x7477, 0x746D, 0x747E, 0x749C, 0x748E, 0x7480, 0x7481, 0x7487, - 0x748B, 0x749E, 0x74A8, 0x74A9, 0x7490, 0x74A7, 0x74D2, 0x74BA, 0x97EA, 0x97EB, 0x97EC, 0x674C, 0x6753, 0x675E, 0x6748, 0x6769, - 0x67A5, 0x6787, 0x676A, 0x6773, 0x6798, 0x67A7, 0x6775, 0x67A8, 0x679E, 0x67AD, 0x678B, 0x6777, 0x677C, 0x67F0, 0x6809, 0x67D8, - 0x680A, 0x67E9, 0x67B0, 0x680C, 0x67D9, 0x67B5, 0x67DA, 0x67B3, 0x67DD, 0x6800, 0x67C3, 0x67B8, 0x67E2, 0x680E, 0x67C1, 0x67FD, - 0x6832, 0x6833, 0x6860, 0x6861, 0x684E, 0x6862, 0x6844, 0x6864, 0x6883, 0x681D, 0x6855, 0x6866, 0x6841, 0x6867, 0x6840, 0x683E, - 0x684A, 0x6849, 0x6829, 0x68B5, 0x688F, 0x6874, 0x6877, 0x6893, 0x686B, 0x68C2, 0x696E, 0x68FC, 0x691F, 0x6920, 0x68F9, - // GB 0xE940..0xE97E - 0x9527, 0x9533, 0x953D, 0x9543, 0x9548, 0x954B, 0x9555, 0x955A, - 0x9560, 0x956E, 0x9574, 0x9575, 0x9577, 0x9578, 0x9579, 0x957A, 0x957B, 0x957C, 0x957D, 0x957E, 0x9580, 0x9581, 0x9582, 0x9583, - 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958A, 0x958B, 0x958C, 0x958D, 0x958E, 0x958F, 0x9590, 0x9591, 0x9592, 0x9593, - 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959A, 0x959B, 0x959C, 0x959D, 0x959E, 0x959F, 0x95A0, 0x95A1, 0x95A2, 0x95A3, - 0x95A4, 0x95A5, 0x95A6, 0x95A7, 0x95A8, 0x95A9, 0x95AA, - // GB 0xE980..0xE9FE - 0x95AB, 0x95AC, 0x95AD, 0x95AE, 0x95AF, 0x95B0, 0x95B1, 0x95B2, 0x95B3, 0x95B4, 0x95B5, 0x95B6, 0x95B7, 0x95B8, 0x95B9, 0x95BA, - 0x95BB, 0x95BC, 0x95BD, 0x95BE, 0x95BF, 0x95C0, 0x95C1, 0x95C2, 0x95C3, 0x95C4, 0x95C5, 0x95C6, 0x95C7, 0x95C8, 0x95C9, 0x95CA, - 0x95CB, 0x6924, 0x68F0, 0x690B, 0x6901, 0x6957, 0x68E3, 0x6910, 0x6971, 0x6939, 0x6960, 0x6942, 0x695D, 0x6984, 0x696B, 0x6980, - 0x6998, 0x6978, 0x6934, 0x69CC, 0x6987, 0x6988, 0x69CE, 0x6989, 0x6966, 0x6963, 0x6979, 0x699B, 0x69A7, 0x69BB, 0x69AB, 0x69AD, - 0x69D4, 0x69B1, 0x69C1, 0x69CA, 0x69DF, 0x6995, 0x69E0, 0x698D, 0x69FF, 0x6A2F, 0x69ED, 0x6A17, 0x6A18, 0x6A65, 0x69F2, 0x6A44, - 0x6A3E, 0x6AA0, 0x6A50, 0x6A5B, 0x6A35, 0x6A8E, 0x6A79, 0x6A3D, 0x6A28, 0x6A58, 0x6A7C, 0x6A91, 0x6A90, 0x6AA9, 0x6A97, 0x6AAB, - 0x7337, 0x7352, 0x6B81, 0x6B82, 0x6B87, 0x6B84, 0x6B92, 0x6B93, 0x6B8D, 0x6B9A, 0x6B9B, 0x6BA1, 0x6BAA, 0x8F6B, 0x8F6D, 0x8F71, - 0x8F72, 0x8F73, 0x8F75, 0x8F76, 0x8F78, 0x8F77, 0x8F79, 0x8F7A, 0x8F7C, 0x8F7E, 0x8F81, 0x8F82, 0x8F84, 0x8F87, 0x8F8B, - // GB 0xEA40..0xEA7E - 0x95CC, 0x95CD, 0x95CE, 0x95CF, 0x95D0, 0x95D1, 0x95D2, 0x95D3, - 0x95D4, 0x95D5, 0x95D6, 0x95D7, 0x95D8, 0x95D9, 0x95DA, 0x95DB, 0x95DC, 0x95DD, 0x95DE, 0x95DF, 0x95E0, 0x95E1, 0x95E2, 0x95E3, - 0x95E4, 0x95E5, 0x95E6, 0x95E7, 0x95EC, 0x95FF, 0x9607, 0x9613, 0x9618, 0x961B, 0x961E, 0x9620, 0x9623, 0x9624, 0x9625, 0x9626, - 0x9627, 0x9628, 0x9629, 0x962B, 0x962C, 0x962D, 0x962F, 0x9630, 0x9637, 0x9638, 0x9639, 0x963A, 0x963E, 0x9641, 0x9643, 0x964A, - 0x964E, 0x964F, 0x9651, 0x9652, 0x9653, 0x9656, 0x9657, - // GB 0xEA80..0xEAFE - 0x9658, 0x9659, 0x965A, 0x965C, 0x965D, 0x965E, 0x9660, 0x9663, 0x9665, 0x9666, 0x966B, 0x966D, 0x966E, 0x966F, 0x9670, 0x9671, - 0x9673, 0x9678, 0x9679, 0x967A, 0x967B, 0x967C, 0x967D, 0x967E, 0x967F, 0x9680, 0x9681, 0x9682, 0x9683, 0x9684, 0x9687, 0x9689, - 0x968A, 0x8F8D, 0x8F8E, 0x8F8F, 0x8F98, 0x8F9A, 0x8ECE, 0x620B, 0x6217, 0x621B, 0x621F, 0x6222, 0x6221, 0x6225, 0x6224, 0x622C, - 0x81E7, 0x74EF, 0x74F4, 0x74FF, 0x750F, 0x7511, 0x7513, 0x6534, 0x65EE, 0x65EF, 0x65F0, 0x660A, 0x6619, 0x6772, 0x6603, 0x6615, - 0x6600, 0x7085, 0x66F7, 0x661D, 0x6634, 0x6631, 0x6636, 0x6635, 0x8006, 0x665F, 0x6654, 0x6641, 0x664F, 0x6656, 0x6661, 0x6657, - 0x6677, 0x6684, 0x668C, 0x66A7, 0x669D, 0x66BE, 0x66DB, 0x66DC, 0x66E6, 0x66E9, 0x8D32, 0x8D33, 0x8D36, 0x8D3B, 0x8D3D, 0x8D40, - 0x8D45, 0x8D46, 0x8D48, 0x8D49, 0x8D47, 0x8D4D, 0x8D55, 0x8D59, 0x89C7, 0x89CA, 0x89CB, 0x89CC, 0x89CE, 0x89CF, 0x89D0, 0x89D1, - 0x726E, 0x729F, 0x725D, 0x7266, 0x726F, 0x727E, 0x727F, 0x7284, 0x728B, 0x728D, 0x728F, 0x7292, 0x6308, 0x6332, 0x63B0, - // GB 0xEB40..0xEB7E - 0x968C, 0x968E, 0x9691, 0x9692, 0x9693, 0x9695, 0x9696, 0x969A, - 0x969B, 0x969D, 0x969E, 0x969F, 0x96A0, 0x96A1, 0x96A2, 0x96A3, 0x96A4, 0x96A5, 0x96A6, 0x96A8, 0x96A9, 0x96AA, 0x96AB, 0x96AC, - 0x96AD, 0x96AE, 0x96AF, 0x96B1, 0x96B2, 0x96B4, 0x96B5, 0x96B7, 0x96B8, 0x96BA, 0x96BB, 0x96BF, 0x96C2, 0x96C3, 0x96C8, 0x96CA, - 0x96CB, 0x96D0, 0x96D1, 0x96D3, 0x96D4, 0x96D6, 0x96D7, 0x96D8, 0x96D9, 0x96DA, 0x96DB, 0x96DC, 0x96DD, 0x96DE, 0x96DF, 0x96E1, - 0x96E2, 0x96E3, 0x96E4, 0x96E5, 0x96E6, 0x96E7, 0x96EB, - // GB 0xEB80..0xEBFE - 0x96EC, 0x96ED, 0x96EE, 0x96F0, 0x96F1, 0x96F2, 0x96F4, 0x96F5, 0x96F8, 0x96FA, 0x96FB, 0x96FC, 0x96FD, 0x96FF, 0x9702, 0x9703, - 0x9705, 0x970A, 0x970B, 0x970C, 0x9710, 0x9711, 0x9712, 0x9714, 0x9715, 0x9717, 0x9718, 0x9719, 0x971A, 0x971B, 0x971D, 0x971F, - 0x9720, 0x643F, 0x64D8, 0x8004, 0x6BEA, 0x6BF3, 0x6BFD, 0x6BF5, 0x6BF9, 0x6C05, 0x6C07, 0x6C06, 0x6C0D, 0x6C15, 0x6C18, 0x6C19, - 0x6C1A, 0x6C21, 0x6C29, 0x6C24, 0x6C2A, 0x6C32, 0x6535, 0x6555, 0x656B, 0x724D, 0x7252, 0x7256, 0x7230, 0x8662, 0x5216, 0x809F, - 0x809C, 0x8093, 0x80BC, 0x670A, 0x80BD, 0x80B1, 0x80AB, 0x80AD, 0x80B4, 0x80B7, 0x80E7, 0x80E8, 0x80E9, 0x80EA, 0x80DB, 0x80C2, - 0x80C4, 0x80D9, 0x80CD, 0x80D7, 0x6710, 0x80DD, 0x80EB, 0x80F1, 0x80F4, 0x80ED, 0x810D, 0x810E, 0x80F2, 0x80FC, 0x6715, 0x8112, - 0x8C5A, 0x8136, 0x811E, 0x812C, 0x8118, 0x8132, 0x8148, 0x814C, 0x8153, 0x8174, 0x8159, 0x815A, 0x8171, 0x8160, 0x8169, 0x817C, - 0x817D, 0x816D, 0x8167, 0x584D, 0x5AB5, 0x8188, 0x8182, 0x8191, 0x6ED5, 0x81A3, 0x81AA, 0x81CC, 0x6726, 0x81CA, 0x81BB, - // GB 0xEC40..0xEC7E - 0x9721, 0x9722, 0x9723, 0x9724, 0x9725, 0x9726, 0x9727, 0x9728, - 0x9729, 0x972B, 0x972C, 0x972E, 0x972F, 0x9731, 0x9733, 0x9734, 0x9735, 0x9736, 0x9737, 0x973A, 0x973B, 0x973C, 0x973D, 0x973F, - 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745, 0x9746, 0x9747, 0x9748, 0x9749, 0x974A, 0x974B, 0x974C, 0x974D, 0x974E, 0x974F, - 0x9750, 0x9751, 0x9754, 0x9755, 0x9757, 0x9758, 0x975A, 0x975C, 0x975D, 0x975F, 0x9763, 0x9764, 0x9766, 0x9767, 0x9768, 0x976A, - 0x976B, 0x976C, 0x976D, 0x976E, 0x976F, 0x9770, 0x9771, - // GB 0xEC80..0xECFE - 0x9772, 0x9775, 0x9777, 0x9778, 0x9779, 0x977A, 0x977B, 0x977D, 0x977E, 0x977F, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9786, - 0x9787, 0x9788, 0x9789, 0x978A, 0x978C, 0x978E, 0x978F, 0x9790, 0x9793, 0x9795, 0x9796, 0x9797, 0x9799, 0x979A, 0x979B, 0x979C, - 0x979D, 0x81C1, 0x81A6, 0x6B24, 0x6B37, 0x6B39, 0x6B43, 0x6B46, 0x6B59, 0x98D1, 0x98D2, 0x98D3, 0x98D5, 0x98D9, 0x98DA, 0x6BB3, - 0x5F40, 0x6BC2, 0x89F3, 0x6590, 0x9F51, 0x6593, 0x65BC, 0x65C6, 0x65C4, 0x65C3, 0x65CC, 0x65CE, 0x65D2, 0x65D6, 0x7080, 0x709C, - 0x7096, 0x709D, 0x70BB, 0x70C0, 0x70B7, 0x70AB, 0x70B1, 0x70E8, 0x70CA, 0x7110, 0x7113, 0x7116, 0x712F, 0x7131, 0x7173, 0x715C, - 0x7168, 0x7145, 0x7172, 0x714A, 0x7178, 0x717A, 0x7198, 0x71B3, 0x71B5, 0x71A8, 0x71A0, 0x71E0, 0x71D4, 0x71E7, 0x71F9, 0x721D, - 0x7228, 0x706C, 0x7118, 0x7166, 0x71B9, 0x623E, 0x623D, 0x6243, 0x6248, 0x6249, 0x793B, 0x7940, 0x7946, 0x7949, 0x795B, 0x795C, - 0x7953, 0x795A, 0x7962, 0x7957, 0x7960, 0x796F, 0x7967, 0x797A, 0x7985, 0x798A, 0x799A, 0x79A7, 0x79B3, 0x5FD1, 0x5FD0, - // GB 0xED40..0xED7E - 0x979E, 0x979F, 0x97A1, 0x97A2, 0x97A4, 0x97A5, 0x97A6, 0x97A7, - 0x97A8, 0x97A9, 0x97AA, 0x97AC, 0x97AE, 0x97B0, 0x97B1, 0x97B3, 0x97B5, 0x97B6, 0x97B7, 0x97B8, 0x97B9, 0x97BA, 0x97BB, 0x97BC, - 0x97BD, 0x97BE, 0x97BF, 0x97C0, 0x97C1, 0x97C2, 0x97C3, 0x97C4, 0x97C5, 0x97C6, 0x97C7, 0x97C8, 0x97C9, 0x97CA, 0x97CB, 0x97CC, - 0x97CD, 0x97CE, 0x97CF, 0x97D0, 0x97D1, 0x97D2, 0x97D3, 0x97D4, 0x97D5, 0x97D6, 0x97D7, 0x97D8, 0x97D9, 0x97DA, 0x97DB, 0x97DC, - 0x97DD, 0x97DE, 0x97DF, 0x97E0, 0x97E1, 0x97E2, 0x97E3, - // GB 0xED80..0xEDFE - 0x97E4, 0x97E5, 0x97E8, 0x97EE, 0x97EF, 0x97F0, 0x97F1, 0x97F2, 0x97F4, 0x97F7, 0x97F8, 0x97F9, 0x97FA, 0x97FB, 0x97FC, 0x97FD, - 0x97FE, 0x97FF, 0x9800, 0x9801, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806, 0x9807, 0x9808, 0x9809, 0x980A, 0x980B, 0x980C, 0x980D, - 0x980E, 0x603C, 0x605D, 0x605A, 0x6067, 0x6041, 0x6059, 0x6063, 0x60AB, 0x6106, 0x610D, 0x615D, 0x61A9, 0x619D, 0x61CB, 0x61D1, - 0x6206, 0x8080, 0x807F, 0x6C93, 0x6CF6, 0x6DFC, 0x77F6, 0x77F8, 0x7800, 0x7809, 0x7817, 0x7818, 0x7811, 0x65AB, 0x782D, 0x781C, - 0x781D, 0x7839, 0x783A, 0x783B, 0x781F, 0x783C, 0x7825, 0x782C, 0x7823, 0x7829, 0x784E, 0x786D, 0x7856, 0x7857, 0x7826, 0x7850, - 0x7847, 0x784C, 0x786A, 0x789B, 0x7893, 0x789A, 0x7887, 0x789C, 0x78A1, 0x78A3, 0x78B2, 0x78B9, 0x78A5, 0x78D4, 0x78D9, 0x78C9, - 0x78EC, 0x78F2, 0x7905, 0x78F4, 0x7913, 0x7924, 0x791E, 0x7934, 0x9F9B, 0x9EF9, 0x9EFB, 0x9EFC, 0x76F1, 0x7704, 0x770D, 0x76F9, - 0x7707, 0x7708, 0x771A, 0x7722, 0x7719, 0x772D, 0x7726, 0x7735, 0x7738, 0x7750, 0x7751, 0x7747, 0x7743, 0x775A, 0x7768, - // GB 0xEE40..0xEE7E - 0x980F, 0x9810, 0x9811, 0x9812, 0x9813, 0x9814, 0x9815, 0x9816, - 0x9817, 0x9818, 0x9819, 0x981A, 0x981B, 0x981C, 0x981D, 0x981E, 0x981F, 0x9820, 0x9821, 0x9822, 0x9823, 0x9824, 0x9825, 0x9826, - 0x9827, 0x9828, 0x9829, 0x982A, 0x982B, 0x982C, 0x982D, 0x982E, 0x982F, 0x9830, 0x9831, 0x9832, 0x9833, 0x9834, 0x9835, 0x9836, - 0x9837, 0x9838, 0x9839, 0x983A, 0x983B, 0x983C, 0x983D, 0x983E, 0x983F, 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, - 0x9847, 0x9848, 0x9849, 0x984A, 0x984B, 0x984C, 0x984D, - // GB 0xEE80..0xEEFE - 0x984E, 0x984F, 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, 0x9857, 0x9858, 0x9859, 0x985A, 0x985B, 0x985C, 0x985D, - 0x985E, 0x985F, 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, 0x9867, 0x9868, 0x9869, 0x986A, 0x986B, 0x986C, 0x986D, - 0x986E, 0x7762, 0x7765, 0x777F, 0x778D, 0x777D, 0x7780, 0x778C, 0x7791, 0x779F, 0x77A0, 0x77B0, 0x77B5, 0x77BD, 0x753A, 0x7540, - 0x754E, 0x754B, 0x7548, 0x755B, 0x7572, 0x7579, 0x7583, 0x7F58, 0x7F61, 0x7F5F, 0x8A48, 0x7F68, 0x7F74, 0x7F71, 0x7F79, 0x7F81, - 0x7F7E, 0x76CD, 0x76E5, 0x8832, 0x9485, 0x9486, 0x9487, 0x948B, 0x948A, 0x948C, 0x948D, 0x948F, 0x9490, 0x9494, 0x9497, 0x9495, - 0x949A, 0x949B, 0x949C, 0x94A3, 0x94A4, 0x94AB, 0x94AA, 0x94AD, 0x94AC, 0x94AF, 0x94B0, 0x94B2, 0x94B4, 0x94B6, 0x94B7, 0x94B8, - 0x94B9, 0x94BA, 0x94BC, 0x94BD, 0x94BF, 0x94C4, 0x94C8, 0x94C9, 0x94CA, 0x94CB, 0x94CC, 0x94CD, 0x94CE, 0x94D0, 0x94D1, 0x94D2, - 0x94D5, 0x94D6, 0x94D7, 0x94D9, 0x94D8, 0x94DB, 0x94DE, 0x94DF, 0x94E0, 0x94E2, 0x94E4, 0x94E5, 0x94E7, 0x94E8, 0x94EA, - // GB 0xEF40..0xEF7E - 0x986F, 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x988B, 0x988E, - 0x9892, 0x9895, 0x9899, 0x98A3, 0x98A8, 0x98A9, 0x98AA, 0x98AB, 0x98AC, 0x98AD, 0x98AE, 0x98AF, 0x98B0, 0x98B1, 0x98B2, 0x98B3, - 0x98B4, 0x98B5, 0x98B6, 0x98B7, 0x98B8, 0x98B9, 0x98BA, 0x98BB, 0x98BC, 0x98BD, 0x98BE, 0x98BF, 0x98C0, 0x98C1, 0x98C2, 0x98C3, - 0x98C4, 0x98C5, 0x98C6, 0x98C7, 0x98C8, 0x98C9, 0x98CA, 0x98CB, 0x98CC, 0x98CD, 0x98CF, 0x98D0, 0x98D4, 0x98D6, 0x98D7, 0x98DB, - 0x98DC, 0x98DD, 0x98E0, 0x98E1, 0x98E2, 0x98E3, 0x98E4, - // GB 0xEF80..0xEFFE - 0x98E5, 0x98E6, 0x98E9, 0x98EA, 0x98EB, 0x98EC, 0x98ED, 0x98EE, 0x98EF, 0x98F0, 0x98F1, 0x98F2, 0x98F3, 0x98F4, 0x98F5, 0x98F6, - 0x98F7, 0x98F8, 0x98F9, 0x98FA, 0x98FB, 0x98FC, 0x98FD, 0x98FE, 0x98FF, 0x9900, 0x9901, 0x9902, 0x9903, 0x9904, 0x9905, 0x9906, - 0x9907, 0x94E9, 0x94EB, 0x94EE, 0x94EF, 0x94F3, 0x94F4, 0x94F5, 0x94F7, 0x94F9, 0x94FC, 0x94FD, 0x94FF, 0x9503, 0x9502, 0x9506, - 0x9507, 0x9509, 0x950A, 0x950D, 0x950E, 0x950F, 0x9512, 0x9513, 0x9514, 0x9515, 0x9516, 0x9518, 0x951B, 0x951D, 0x951E, 0x951F, - 0x9522, 0x952A, 0x952B, 0x9529, 0x952C, 0x9531, 0x9532, 0x9534, 0x9536, 0x9537, 0x9538, 0x953C, 0x953E, 0x953F, 0x9542, 0x9535, - 0x9544, 0x9545, 0x9546, 0x9549, 0x954C, 0x954E, 0x954F, 0x9552, 0x9553, 0x9554, 0x9556, 0x9557, 0x9558, 0x9559, 0x955B, 0x955E, - 0x955F, 0x955D, 0x9561, 0x9562, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, 0x9569, 0x956A, 0x956B, 0x956C, 0x956F, 0x9571, 0x9572, - 0x9573, 0x953A, 0x77E7, 0x77EC, 0x96C9, 0x79D5, 0x79ED, 0x79E3, 0x79EB, 0x7A06, 0x5D47, 0x7A03, 0x7A02, 0x7A1E, 0x7A14, - // GB 0xF040..0xF07E - 0x9908, 0x9909, 0x990A, 0x990B, 0x990C, 0x990E, 0x990F, 0x9911, - 0x9912, 0x9913, 0x9914, 0x9915, 0x9916, 0x9917, 0x9918, 0x9919, 0x991A, 0x991B, 0x991C, 0x991D, 0x991E, 0x991F, 0x9920, 0x9921, - 0x9922, 0x9923, 0x9924, 0x9925, 0x9926, 0x9927, 0x9928, 0x9929, 0x992A, 0x992B, 0x992C, 0x992D, 0x992F, 0x9930, 0x9931, 0x9932, - 0x9933, 0x9934, 0x9935, 0x9936, 0x9937, 0x9938, 0x9939, 0x993A, 0x993B, 0x993C, 0x993D, 0x993E, 0x993F, 0x9940, 0x9941, 0x9942, - 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949, - // GB 0xF080..0xF0FE - 0x994A, 0x994B, 0x994C, 0x994D, 0x994E, 0x994F, 0x9950, 0x9951, 0x9952, 0x9953, 0x9956, 0x9957, 0x9958, 0x9959, 0x995A, 0x995B, - 0x995C, 0x995D, 0x995E, 0x995F, 0x9960, 0x9961, 0x9962, 0x9964, 0x9966, 0x9973, 0x9978, 0x9979, 0x997B, 0x997E, 0x9982, 0x9983, - 0x9989, 0x7A39, 0x7A37, 0x7A51, 0x9ECF, 0x99A5, 0x7A70, 0x7688, 0x768E, 0x7693, 0x7699, 0x76A4, 0x74DE, 0x74E0, 0x752C, 0x9E20, - 0x9E22, 0x9E28, 0x9E29, 0x9E2A, 0x9E2B, 0x9E2C, 0x9E32, 0x9E31, 0x9E36, 0x9E38, 0x9E37, 0x9E39, 0x9E3A, 0x9E3E, 0x9E41, 0x9E42, - 0x9E44, 0x9E46, 0x9E47, 0x9E48, 0x9E49, 0x9E4B, 0x9E4C, 0x9E4E, 0x9E51, 0x9E55, 0x9E57, 0x9E5A, 0x9E5B, 0x9E5C, 0x9E5E, 0x9E63, - 0x9E66, 0x9E67, 0x9E68, 0x9E69, 0x9E6A, 0x9E6B, 0x9E6C, 0x9E71, 0x9E6D, 0x9E73, 0x7592, 0x7594, 0x7596, 0x75A0, 0x759D, 0x75AC, - 0x75A3, 0x75B3, 0x75B4, 0x75B8, 0x75C4, 0x75B1, 0x75B0, 0x75C3, 0x75C2, 0x75D6, 0x75CD, 0x75E3, 0x75E8, 0x75E6, 0x75E4, 0x75EB, - 0x75E7, 0x7603, 0x75F1, 0x75FC, 0x75FF, 0x7610, 0x7600, 0x7605, 0x760C, 0x7617, 0x760A, 0x7625, 0x7618, 0x7615, 0x7619, - // GB 0xF140..0xF17E - 0x998C, 0x998E, 0x999A, 0x999B, 0x999C, 0x999D, 0x999E, 0x999F, - 0x99A0, 0x99A1, 0x99A2, 0x99A3, 0x99A4, 0x99A6, 0x99A7, 0x99A9, 0x99AA, 0x99AB, 0x99AC, 0x99AD, 0x99AE, 0x99AF, 0x99B0, 0x99B1, - 0x99B2, 0x99B3, 0x99B4, 0x99B5, 0x99B6, 0x99B7, 0x99B8, 0x99B9, 0x99BA, 0x99BB, 0x99BC, 0x99BD, 0x99BE, 0x99BF, 0x99C0, 0x99C1, - 0x99C2, 0x99C3, 0x99C4, 0x99C5, 0x99C6, 0x99C7, 0x99C8, 0x99C9, 0x99CA, 0x99CB, 0x99CC, 0x99CD, 0x99CE, 0x99CF, 0x99D0, 0x99D1, - 0x99D2, 0x99D3, 0x99D4, 0x99D5, 0x99D6, 0x99D7, 0x99D8, - // GB 0xF180..0xF1FE - 0x99D9, 0x99DA, 0x99DB, 0x99DC, 0x99DD, 0x99DE, 0x99DF, 0x99E0, 0x99E1, 0x99E2, 0x99E3, 0x99E4, 0x99E5, 0x99E6, 0x99E7, 0x99E8, - 0x99E9, 0x99EA, 0x99EB, 0x99EC, 0x99ED, 0x99EE, 0x99EF, 0x99F0, 0x99F1, 0x99F2, 0x99F3, 0x99F4, 0x99F5, 0x99F6, 0x99F7, 0x99F8, - 0x99F9, 0x761B, 0x763C, 0x7622, 0x7620, 0x7640, 0x762D, 0x7630, 0x763F, 0x7635, 0x7643, 0x763E, 0x7633, 0x764D, 0x765E, 0x7654, - 0x765C, 0x7656, 0x766B, 0x766F, 0x7FCA, 0x7AE6, 0x7A78, 0x7A79, 0x7A80, 0x7A86, 0x7A88, 0x7A95, 0x7AA6, 0x7AA0, 0x7AAC, 0x7AA8, - 0x7AAD, 0x7AB3, 0x8864, 0x8869, 0x8872, 0x887D, 0x887F, 0x8882, 0x88A2, 0x88C6, 0x88B7, 0x88BC, 0x88C9, 0x88E2, 0x88CE, 0x88E3, - 0x88E5, 0x88F1, 0x891A, 0x88FC, 0x88E8, 0x88FE, 0x88F0, 0x8921, 0x8919, 0x8913, 0x891B, 0x890A, 0x8934, 0x892B, 0x8936, 0x8941, - 0x8966, 0x897B, 0x758B, 0x80E5, 0x76B2, 0x76B4, 0x77DC, 0x8012, 0x8014, 0x8016, 0x801C, 0x8020, 0x8022, 0x8025, 0x8026, 0x8027, - 0x8029, 0x8028, 0x8031, 0x800B, 0x8035, 0x8043, 0x8046, 0x804D, 0x8052, 0x8069, 0x8071, 0x8983, 0x9878, 0x9880, 0x9883, - // GB 0xF240..0xF27E - 0x99FA, 0x99FB, 0x99FC, 0x99FD, 0x99FE, 0x99FF, 0x9A00, 0x9A01, - 0x9A02, 0x9A03, 0x9A04, 0x9A05, 0x9A06, 0x9A07, 0x9A08, 0x9A09, 0x9A0A, 0x9A0B, 0x9A0C, 0x9A0D, 0x9A0E, 0x9A0F, 0x9A10, 0x9A11, - 0x9A12, 0x9A13, 0x9A14, 0x9A15, 0x9A16, 0x9A17, 0x9A18, 0x9A19, 0x9A1A, 0x9A1B, 0x9A1C, 0x9A1D, 0x9A1E, 0x9A1F, 0x9A20, 0x9A21, - 0x9A22, 0x9A23, 0x9A24, 0x9A25, 0x9A26, 0x9A27, 0x9A28, 0x9A29, 0x9A2A, 0x9A2B, 0x9A2C, 0x9A2D, 0x9A2E, 0x9A2F, 0x9A30, 0x9A31, - 0x9A32, 0x9A33, 0x9A34, 0x9A35, 0x9A36, 0x9A37, 0x9A38, - // GB 0xF280..0xF2FE - 0x9A39, 0x9A3A, 0x9A3B, 0x9A3C, 0x9A3D, 0x9A3E, 0x9A3F, 0x9A40, 0x9A41, 0x9A42, 0x9A43, 0x9A44, 0x9A45, 0x9A46, 0x9A47, 0x9A48, - 0x9A49, 0x9A4A, 0x9A4B, 0x9A4C, 0x9A4D, 0x9A4E, 0x9A4F, 0x9A50, 0x9A51, 0x9A52, 0x9A53, 0x9A54, 0x9A55, 0x9A56, 0x9A57, 0x9A58, - 0x9A59, 0x9889, 0x988C, 0x988D, 0x988F, 0x9894, 0x989A, 0x989B, 0x989E, 0x989F, 0x98A1, 0x98A2, 0x98A5, 0x98A6, 0x864D, 0x8654, - 0x866C, 0x866E, 0x867F, 0x867A, 0x867C, 0x867B, 0x86A8, 0x868D, 0x868B, 0x86AC, 0x869D, 0x86A7, 0x86A3, 0x86AA, 0x8693, 0x86A9, - 0x86B6, 0x86C4, 0x86B5, 0x86CE, 0x86B0, 0x86BA, 0x86B1, 0x86AF, 0x86C9, 0x86CF, 0x86B4, 0x86E9, 0x86F1, 0x86F2, 0x86ED, 0x86F3, - 0x86D0, 0x8713, 0x86DE, 0x86F4, 0x86DF, 0x86D8, 0x86D1, 0x8703, 0x8707, 0x86F8, 0x8708, 0x870A, 0x870D, 0x8709, 0x8723, 0x873B, - 0x871E, 0x8725, 0x872E, 0x871A, 0x873E, 0x8748, 0x8734, 0x8731, 0x8729, 0x8737, 0x873F, 0x8782, 0x8722, 0x877D, 0x877E, 0x877B, - 0x8760, 0x8770, 0x874C, 0x876E, 0x878B, 0x8753, 0x8763, 0x877C, 0x8764, 0x8759, 0x8765, 0x8793, 0x87AF, 0x87A8, 0x87D2, - // GB 0xF340..0xF37E - 0x9A5A, 0x9A5B, 0x9A5C, 0x9A5D, 0x9A5E, 0x9A5F, 0x9A60, 0x9A61, - 0x9A62, 0x9A63, 0x9A64, 0x9A65, 0x9A66, 0x9A67, 0x9A68, 0x9A69, 0x9A6A, 0x9A6B, 0x9A72, 0x9A83, 0x9A89, 0x9A8D, 0x9A8E, 0x9A94, - 0x9A95, 0x9A99, 0x9AA6, 0x9AA9, 0x9AAA, 0x9AAB, 0x9AAC, 0x9AAD, 0x9AAE, 0x9AAF, 0x9AB2, 0x9AB3, 0x9AB4, 0x9AB5, 0x9AB9, 0x9ABB, - 0x9ABD, 0x9ABE, 0x9ABF, 0x9AC3, 0x9AC4, 0x9AC6, 0x9AC7, 0x9AC8, 0x9AC9, 0x9ACA, 0x9ACD, 0x9ACE, 0x9ACF, 0x9AD0, 0x9AD2, 0x9AD4, - 0x9AD5, 0x9AD6, 0x9AD7, 0x9AD9, 0x9ADA, 0x9ADB, 0x9ADC, - // GB 0xF380..0xF3FE - 0x9ADD, 0x9ADE, 0x9AE0, 0x9AE2, 0x9AE3, 0x9AE4, 0x9AE5, 0x9AE7, 0x9AE8, 0x9AE9, 0x9AEA, 0x9AEC, 0x9AEE, 0x9AF0, 0x9AF1, 0x9AF2, - 0x9AF3, 0x9AF4, 0x9AF5, 0x9AF6, 0x9AF7, 0x9AF8, 0x9AFA, 0x9AFC, 0x9AFD, 0x9AFE, 0x9AFF, 0x9B00, 0x9B01, 0x9B02, 0x9B04, 0x9B05, - 0x9B06, 0x87C6, 0x8788, 0x8785, 0x87AD, 0x8797, 0x8783, 0x87AB, 0x87E5, 0x87AC, 0x87B5, 0x87B3, 0x87CB, 0x87D3, 0x87BD, 0x87D1, - 0x87C0, 0x87CA, 0x87DB, 0x87EA, 0x87E0, 0x87EE, 0x8816, 0x8813, 0x87FE, 0x880A, 0x881B, 0x8821, 0x8839, 0x883C, 0x7F36, 0x7F42, - 0x7F44, 0x7F45, 0x8210, 0x7AFA, 0x7AFD, 0x7B08, 0x7B03, 0x7B04, 0x7B15, 0x7B0A, 0x7B2B, 0x7B0F, 0x7B47, 0x7B38, 0x7B2A, 0x7B19, - 0x7B2E, 0x7B31, 0x7B20, 0x7B25, 0x7B24, 0x7B33, 0x7B3E, 0x7B1E, 0x7B58, 0x7B5A, 0x7B45, 0x7B75, 0x7B4C, 0x7B5D, 0x7B60, 0x7B6E, - 0x7B7B, 0x7B62, 0x7B72, 0x7B71, 0x7B90, 0x7BA6, 0x7BA7, 0x7BB8, 0x7BAC, 0x7B9D, 0x7BA8, 0x7B85, 0x7BAA, 0x7B9C, 0x7BA2, 0x7BAB, - 0x7BB4, 0x7BD1, 0x7BC1, 0x7BCC, 0x7BDD, 0x7BDA, 0x7BE5, 0x7BE6, 0x7BEA, 0x7C0C, 0x7BFE, 0x7BFC, 0x7C0F, 0x7C16, 0x7C0B, - // GB 0xF440..0xF47E - 0x9B07, 0x9B09, 0x9B0A, 0x9B0B, 0x9B0C, 0x9B0D, 0x9B0E, 0x9B10, - 0x9B11, 0x9B12, 0x9B14, 0x9B15, 0x9B16, 0x9B17, 0x9B18, 0x9B19, 0x9B1A, 0x9B1B, 0x9B1C, 0x9B1D, 0x9B1E, 0x9B20, 0x9B21, 0x9B22, - 0x9B24, 0x9B25, 0x9B26, 0x9B27, 0x9B28, 0x9B29, 0x9B2A, 0x9B2B, 0x9B2C, 0x9B2D, 0x9B2E, 0x9B30, 0x9B31, 0x9B33, 0x9B34, 0x9B35, - 0x9B36, 0x9B37, 0x9B38, 0x9B39, 0x9B3A, 0x9B3D, 0x9B3E, 0x9B3F, 0x9B40, 0x9B46, 0x9B4A, 0x9B4B, 0x9B4C, 0x9B4E, 0x9B50, 0x9B52, - 0x9B53, 0x9B55, 0x9B56, 0x9B57, 0x9B58, 0x9B59, 0x9B5A, - // GB 0xF480..0xF4FE - 0x9B5B, 0x9B5C, 0x9B5D, 0x9B5E, 0x9B5F, 0x9B60, 0x9B61, 0x9B62, 0x9B63, 0x9B64, 0x9B65, 0x9B66, 0x9B67, 0x9B68, 0x9B69, 0x9B6A, - 0x9B6B, 0x9B6C, 0x9B6D, 0x9B6E, 0x9B6F, 0x9B70, 0x9B71, 0x9B72, 0x9B73, 0x9B74, 0x9B75, 0x9B76, 0x9B77, 0x9B78, 0x9B79, 0x9B7A, - 0x9B7B, 0x7C1F, 0x7C2A, 0x7C26, 0x7C38, 0x7C41, 0x7C40, 0x81FE, 0x8201, 0x8202, 0x8204, 0x81EC, 0x8844, 0x8221, 0x8222, 0x8223, - 0x822D, 0x822F, 0x8228, 0x822B, 0x8238, 0x823B, 0x8233, 0x8234, 0x823E, 0x8244, 0x8249, 0x824B, 0x824F, 0x825A, 0x825F, 0x8268, - 0x887E, 0x8885, 0x8888, 0x88D8, 0x88DF, 0x895E, 0x7F9D, 0x7F9F, 0x7FA7, 0x7FAF, 0x7FB0, 0x7FB2, 0x7C7C, 0x6549, 0x7C91, 0x7C9D, - 0x7C9C, 0x7C9E, 0x7CA2, 0x7CB2, 0x7CBC, 0x7CBD, 0x7CC1, 0x7CC7, 0x7CCC, 0x7CCD, 0x7CC8, 0x7CC5, 0x7CD7, 0x7CE8, 0x826E, 0x66A8, - 0x7FBF, 0x7FCE, 0x7FD5, 0x7FE5, 0x7FE1, 0x7FE6, 0x7FE9, 0x7FEE, 0x7FF3, 0x7CF8, 0x7D77, 0x7DA6, 0x7DAE, 0x7E47, 0x7E9B, 0x9EB8, - 0x9EB4, 0x8D73, 0x8D84, 0x8D94, 0x8D91, 0x8DB1, 0x8D67, 0x8D6D, 0x8C47, 0x8C49, 0x914A, 0x9150, 0x914E, 0x914F, 0x9164, - // GB 0xF540..0xF57E - 0x9B7C, 0x9B7D, 0x9B7E, 0x9B7F, 0x9B80, 0x9B81, 0x9B82, 0x9B83, - 0x9B84, 0x9B85, 0x9B86, 0x9B87, 0x9B88, 0x9B89, 0x9B8A, 0x9B8B, 0x9B8C, 0x9B8D, 0x9B8E, 0x9B8F, 0x9B90, 0x9B91, 0x9B92, 0x9B93, - 0x9B94, 0x9B95, 0x9B96, 0x9B97, 0x9B98, 0x9B99, 0x9B9A, 0x9B9B, 0x9B9C, 0x9B9D, 0x9B9E, 0x9B9F, 0x9BA0, 0x9BA1, 0x9BA2, 0x9BA3, - 0x9BA4, 0x9BA5, 0x9BA6, 0x9BA7, 0x9BA8, 0x9BA9, 0x9BAA, 0x9BAB, 0x9BAC, 0x9BAD, 0x9BAE, 0x9BAF, 0x9BB0, 0x9BB1, 0x9BB2, 0x9BB3, - 0x9BB4, 0x9BB5, 0x9BB6, 0x9BB7, 0x9BB8, 0x9BB9, 0x9BBA, - // GB 0xF580..0xF5FE - 0x9BBB, 0x9BBC, 0x9BBD, 0x9BBE, 0x9BBF, 0x9BC0, 0x9BC1, 0x9BC2, 0x9BC3, 0x9BC4, 0x9BC5, 0x9BC6, 0x9BC7, 0x9BC8, 0x9BC9, 0x9BCA, - 0x9BCB, 0x9BCC, 0x9BCD, 0x9BCE, 0x9BCF, 0x9BD0, 0x9BD1, 0x9BD2, 0x9BD3, 0x9BD4, 0x9BD5, 0x9BD6, 0x9BD7, 0x9BD8, 0x9BD9, 0x9BDA, - 0x9BDB, 0x9162, 0x9161, 0x9170, 0x9169, 0x916F, 0x917D, 0x917E, 0x9172, 0x9174, 0x9179, 0x918C, 0x9185, 0x9190, 0x918D, 0x9191, - 0x91A2, 0x91A3, 0x91AA, 0x91AD, 0x91AE, 0x91AF, 0x91B5, 0x91B4, 0x91BA, 0x8C55, 0x9E7E, 0x8DB8, 0x8DEB, 0x8E05, 0x8E59, 0x8E69, - 0x8DB5, 0x8DBF, 0x8DBC, 0x8DBA, 0x8DC4, 0x8DD6, 0x8DD7, 0x8DDA, 0x8DDE, 0x8DCE, 0x8DCF, 0x8DDB, 0x8DC6, 0x8DEC, 0x8DF7, 0x8DF8, - 0x8DE3, 0x8DF9, 0x8DFB, 0x8DE4, 0x8E09, 0x8DFD, 0x8E14, 0x8E1D, 0x8E1F, 0x8E2C, 0x8E2E, 0x8E23, 0x8E2F, 0x8E3A, 0x8E40, 0x8E39, - 0x8E35, 0x8E3D, 0x8E31, 0x8E49, 0x8E41, 0x8E42, 0x8E51, 0x8E52, 0x8E4A, 0x8E70, 0x8E76, 0x8E7C, 0x8E6F, 0x8E74, 0x8E85, 0x8E8F, - 0x8E94, 0x8E90, 0x8E9C, 0x8E9E, 0x8C78, 0x8C82, 0x8C8A, 0x8C85, 0x8C98, 0x8C94, 0x659B, 0x89D6, 0x89DE, 0x89DA, 0x89DC, - // GB 0xF640..0xF67E - 0x9BDC, 0x9BDD, 0x9BDE, 0x9BDF, 0x9BE0, 0x9BE1, 0x9BE2, 0x9BE3, - 0x9BE4, 0x9BE5, 0x9BE6, 0x9BE7, 0x9BE8, 0x9BE9, 0x9BEA, 0x9BEB, 0x9BEC, 0x9BED, 0x9BEE, 0x9BEF, 0x9BF0, 0x9BF1, 0x9BF2, 0x9BF3, - 0x9BF4, 0x9BF5, 0x9BF6, 0x9BF7, 0x9BF8, 0x9BF9, 0x9BFA, 0x9BFB, 0x9BFC, 0x9BFD, 0x9BFE, 0x9BFF, 0x9C00, 0x9C01, 0x9C02, 0x9C03, - 0x9C04, 0x9C05, 0x9C06, 0x9C07, 0x9C08, 0x9C09, 0x9C0A, 0x9C0B, 0x9C0C, 0x9C0D, 0x9C0E, 0x9C0F, 0x9C10, 0x9C11, 0x9C12, 0x9C13, - 0x9C14, 0x9C15, 0x9C16, 0x9C17, 0x9C18, 0x9C19, 0x9C1A, - // GB 0xF680..0xF6FE - 0x9C1B, 0x9C1C, 0x9C1D, 0x9C1E, 0x9C1F, 0x9C20, 0x9C21, 0x9C22, 0x9C23, 0x9C24, 0x9C25, 0x9C26, 0x9C27, 0x9C28, 0x9C29, 0x9C2A, - 0x9C2B, 0x9C2C, 0x9C2D, 0x9C2E, 0x9C2F, 0x9C30, 0x9C31, 0x9C32, 0x9C33, 0x9C34, 0x9C35, 0x9C36, 0x9C37, 0x9C38, 0x9C39, 0x9C3A, - 0x9C3B, 0x89E5, 0x89EB, 0x89EF, 0x8A3E, 0x8B26, 0x9753, 0x96E9, 0x96F3, 0x96EF, 0x9706, 0x9701, 0x9708, 0x970F, 0x970E, 0x972A, - 0x972D, 0x9730, 0x973E, 0x9F80, 0x9F83, 0x9F85, 0x9F86, 0x9F87, 0x9F88, 0x9F89, 0x9F8A, 0x9F8C, 0x9EFE, 0x9F0B, 0x9F0D, 0x96B9, - 0x96BC, 0x96BD, 0x96CE, 0x96D2, 0x77BF, 0x96E0, 0x928E, 0x92AE, 0x92C8, 0x933E, 0x936A, 0x93CA, 0x938F, 0x943E, 0x946B, 0x9C7F, - 0x9C82, 0x9C85, 0x9C86, 0x9C87, 0x9C88, 0x7A23, 0x9C8B, 0x9C8E, 0x9C90, 0x9C91, 0x9C92, 0x9C94, 0x9C95, 0x9C9A, 0x9C9B, 0x9C9E, - 0x9C9F, 0x9CA0, 0x9CA1, 0x9CA2, 0x9CA3, 0x9CA5, 0x9CA6, 0x9CA7, 0x9CA8, 0x9CA9, 0x9CAB, 0x9CAD, 0x9CAE, 0x9CB0, 0x9CB1, 0x9CB2, - 0x9CB3, 0x9CB4, 0x9CB5, 0x9CB6, 0x9CB7, 0x9CBA, 0x9CBB, 0x9CBC, 0x9CBD, 0x9CC4, 0x9CC5, 0x9CC6, 0x9CC7, 0x9CCA, 0x9CCB, - // GB 0xF740..0xF77E - 0x9C3C, 0x9C3D, 0x9C3E, 0x9C3F, 0x9C40, 0x9C41, 0x9C42, 0x9C43, - 0x9C44, 0x9C45, 0x9C46, 0x9C47, 0x9C48, 0x9C49, 0x9C4A, 0x9C4B, 0x9C4C, 0x9C4D, 0x9C4E, 0x9C4F, 0x9C50, 0x9C51, 0x9C52, 0x9C53, - 0x9C54, 0x9C55, 0x9C56, 0x9C57, 0x9C58, 0x9C59, 0x9C5A, 0x9C5B, 0x9C5C, 0x9C5D, 0x9C5E, 0x9C5F, 0x9C60, 0x9C61, 0x9C62, 0x9C63, - 0x9C64, 0x9C65, 0x9C66, 0x9C67, 0x9C68, 0x9C69, 0x9C6A, 0x9C6B, 0x9C6C, 0x9C6D, 0x9C6E, 0x9C6F, 0x9C70, 0x9C71, 0x9C72, 0x9C73, - 0x9C74, 0x9C75, 0x9C76, 0x9C77, 0x9C78, 0x9C79, 0x9C7A, - // GB 0xF780..0xF7FE - 0x9C7B, 0x9C7D, 0x9C7E, 0x9C80, 0x9C83, 0x9C84, 0x9C89, 0x9C8A, 0x9C8C, 0x9C8F, 0x9C93, 0x9C96, 0x9C97, 0x9C98, 0x9C99, 0x9C9D, - 0x9CAA, 0x9CAC, 0x9CAF, 0x9CB9, 0x9CBE, 0x9CBF, 0x9CC0, 0x9CC1, 0x9CC2, 0x9CC8, 0x9CC9, 0x9CD1, 0x9CD2, 0x9CDA, 0x9CDB, 0x9CE0, - 0x9CE1, 0x9CCC, 0x9CCD, 0x9CCE, 0x9CCF, 0x9CD0, 0x9CD3, 0x9CD4, 0x9CD5, 0x9CD7, 0x9CD8, 0x9CD9, 0x9CDC, 0x9CDD, 0x9CDF, 0x9CE2, - 0x977C, 0x9785, 0x9791, 0x9792, 0x9794, 0x97AF, 0x97AB, 0x97A3, 0x97B2, 0x97B4, 0x9AB1, 0x9AB0, 0x9AB7, 0x9E58, 0x9AB6, 0x9ABA, - 0x9ABC, 0x9AC1, 0x9AC0, 0x9AC5, 0x9AC2, 0x9ACB, 0x9ACC, 0x9AD1, 0x9B45, 0x9B43, 0x9B47, 0x9B49, 0x9B48, 0x9B4D, 0x9B51, 0x98E8, - 0x990D, 0x992E, 0x9955, 0x9954, 0x9ADF, 0x9AE1, 0x9AE6, 0x9AEF, 0x9AEB, 0x9AFB, 0x9AED, 0x9AF9, 0x9B08, 0x9B0F, 0x9B13, 0x9B1F, - 0x9B23, 0x9EBD, 0x9EBE, 0x7E3B, 0x9E82, 0x9E87, 0x9E88, 0x9E8B, 0x9E92, 0x93D6, 0x9E9D, 0x9E9F, 0x9EDB, 0x9EDC, 0x9EDD, 0x9EE0, - 0x9EDF, 0x9EE2, 0x9EE9, 0x9EE7, 0x9EE5, 0x9EEA, 0x9EEF, 0x9F22, 0x9F2C, 0x9F2F, 0x9F39, 0x9F37, 0x9F3D, 0x9F3E, 0x9F44, - // GB 0xF840..0xF87E - 0x9CE3, 0x9CE4, 0x9CE5, 0x9CE6, 0x9CE7, 0x9CE8, 0x9CE9, 0x9CEA, - 0x9CEB, 0x9CEC, 0x9CED, 0x9CEE, 0x9CEF, 0x9CF0, 0x9CF1, 0x9CF2, 0x9CF3, 0x9CF4, 0x9CF5, 0x9CF6, 0x9CF7, 0x9CF8, 0x9CF9, 0x9CFA, - 0x9CFB, 0x9CFC, 0x9CFD, 0x9CFE, 0x9CFF, 0x9D00, 0x9D01, 0x9D02, 0x9D03, 0x9D04, 0x9D05, 0x9D06, 0x9D07, 0x9D08, 0x9D09, 0x9D0A, - 0x9D0B, 0x9D0C, 0x9D0D, 0x9D0E, 0x9D0F, 0x9D10, 0x9D11, 0x9D12, 0x9D13, 0x9D14, 0x9D15, 0x9D16, 0x9D17, 0x9D18, 0x9D19, 0x9D1A, - 0x9D1B, 0x9D1C, 0x9D1D, 0x9D1E, 0x9D1F, 0x9D20, 0x9D21, - // GB 0xF880..0xF8A0 - 0x9D22, 0x9D23, 0x9D24, 0x9D25, 0x9D26, 0x9D27, 0x9D28, 0x9D29, 0x9D2A, 0x9D2B, 0x9D2C, 0x9D2D, 0x9D2E, 0x9D2F, 0x9D30, 0x9D31, - 0x9D32, 0x9D33, 0x9D34, 0x9D35, 0x9D36, 0x9D37, 0x9D38, 0x9D39, 0x9D3A, 0x9D3B, 0x9D3C, 0x9D3D, 0x9D3E, 0x9D3F, 0x9D40, 0x9D41, - 0x9D42, // Skip: GB 0xF8A1..0xF8FE (UDA 2) - // GB 0xF940..0xF97E - 0x9D43, 0x9D44, 0x9D45, 0x9D46, 0x9D47, 0x9D48, 0x9D49, 0x9D4A, 0x9D4B, 0x9D4C, 0x9D4D, 0x9D4E, 0x9D4F, 0x9D50, 0x9D51, 0x9D52, - 0x9D53, 0x9D54, 0x9D55, 0x9D56, 0x9D57, 0x9D58, 0x9D59, 0x9D5A, 0x9D5B, 0x9D5C, 0x9D5D, 0x9D5E, 0x9D5F, 0x9D60, 0x9D61, 0x9D62, - 0x9D63, 0x9D64, 0x9D65, 0x9D66, 0x9D67, 0x9D68, 0x9D69, 0x9D6A, 0x9D6B, 0x9D6C, 0x9D6D, 0x9D6E, 0x9D6F, 0x9D70, 0x9D71, 0x9D72, - 0x9D73, 0x9D74, 0x9D75, 0x9D76, 0x9D77, 0x9D78, 0x9D79, 0x9D7A, 0x9D7B, 0x9D7C, 0x9D7D, 0x9D7E, 0x9D7F, 0x9D80, 0x9D81, - // GB 0xF980..0xF9A0 - 0x9D82, 0x9D83, 0x9D84, 0x9D85, 0x9D86, 0x9D87, 0x9D88, 0x9D89, - 0x9D8A, 0x9D8B, 0x9D8C, 0x9D8D, 0x9D8E, 0x9D8F, 0x9D90, 0x9D91, 0x9D92, 0x9D93, 0x9D94, 0x9D95, 0x9D96, 0x9D97, 0x9D98, 0x9D99, - 0x9D9A, 0x9D9B, 0x9D9C, 0x9D9D, 0x9D9E, 0x9D9F, 0x9DA0, 0x9DA1, 0x9DA2, // Skip: GB 0xF9A1..0xF9FE (UDA 2) - // GB 0xFA40..0xFA7E - 0x9DA3, 0x9DA4, 0x9DA5, 0x9DA6, 0x9DA7, 0x9DA8, 0x9DA9, 0x9DAA, - 0x9DAB, 0x9DAC, 0x9DAD, 0x9DAE, 0x9DAF, 0x9DB0, 0x9DB1, 0x9DB2, 0x9DB3, 0x9DB4, 0x9DB5, 0x9DB6, 0x9DB7, 0x9DB8, 0x9DB9, 0x9DBA, - 0x9DBB, 0x9DBC, 0x9DBD, 0x9DBE, 0x9DBF, 0x9DC0, 0x9DC1, 0x9DC2, 0x9DC3, 0x9DC4, 0x9DC5, 0x9DC6, 0x9DC7, 0x9DC8, 0x9DC9, 0x9DCA, - 0x9DCB, 0x9DCC, 0x9DCD, 0x9DCE, 0x9DCF, 0x9DD0, 0x9DD1, 0x9DD2, 0x9DD3, 0x9DD4, 0x9DD5, 0x9DD6, 0x9DD7, 0x9DD8, 0x9DD9, 0x9DDA, - 0x9DDB, 0x9DDC, 0x9DDD, 0x9DDE, 0x9DDF, 0x9DE0, 0x9DE1, - // GB 0xFA80..0xFAA0 - 0x9DE2, 0x9DE3, 0x9DE4, 0x9DE5, 0x9DE6, 0x9DE7, 0x9DE8, 0x9DE9, 0x9DEA, 0x9DEB, 0x9DEC, 0x9DED, 0x9DEE, 0x9DEF, 0x9DF0, 0x9DF1, - 0x9DF2, 0x9DF3, 0x9DF4, 0x9DF5, 0x9DF6, 0x9DF7, 0x9DF8, 0x9DF9, 0x9DFA, 0x9DFB, 0x9DFC, 0x9DFD, 0x9DFE, 0x9DFF, 0x9E00, 0x9E01, - 0x9E02, // Skip: GB 0xFAA1..0xFAFE (UDA 2) - // GB 0xFB40..0xFB7E - 0x9E03, 0x9E04, 0x9E05, 0x9E06, 0x9E07, 0x9E08, 0x9E09, 0x9E0A, 0x9E0B, 0x9E0C, 0x9E0D, 0x9E0E, 0x9E0F, 0x9E10, 0x9E11, 0x9E12, - 0x9E13, 0x9E14, 0x9E15, 0x9E16, 0x9E17, 0x9E18, 0x9E19, 0x9E1A, 0x9E1B, 0x9E1C, 0x9E1D, 0x9E1E, 0x9E24, 0x9E27, 0x9E2E, 0x9E30, - 0x9E34, 0x9E3B, 0x9E3C, 0x9E40, 0x9E4D, 0x9E50, 0x9E52, 0x9E53, 0x9E54, 0x9E56, 0x9E59, 0x9E5D, 0x9E5F, 0x9E60, 0x9E61, 0x9E62, - 0x9E65, 0x9E6E, 0x9E6F, 0x9E72, 0x9E74, 0x9E75, 0x9E76, 0x9E77, 0x9E78, 0x9E79, 0x9E7A, 0x9E7B, 0x9E7C, 0x9E7D, 0x9E80, - // GB 0xFB80..0xFBA0 - 0x9E81, 0x9E83, 0x9E84, 0x9E85, 0x9E86, 0x9E89, 0x9E8A, 0x9E8C, - 0x9E8D, 0x9E8E, 0x9E8F, 0x9E90, 0x9E91, 0x9E94, 0x9E95, 0x9E96, 0x9E97, 0x9E98, 0x9E99, 0x9E9A, 0x9E9B, 0x9E9C, 0x9E9E, 0x9EA0, - 0x9EA1, 0x9EA2, 0x9EA3, 0x9EA4, 0x9EA5, 0x9EA7, 0x9EA8, 0x9EA9, 0x9EAA, // Skip: GB 0xFBA1..0xFBFE (UDA 2) - // GB 0xFC40..0xFC7E - 0x9EAB, 0x9EAC, 0x9EAD, 0x9EAE, 0x9EAF, 0x9EB0, 0x9EB1, 0x9EB2, - 0x9EB3, 0x9EB5, 0x9EB6, 0x9EB7, 0x9EB9, 0x9EBA, 0x9EBC, 0x9EBF, 0x9EC0, 0x9EC1, 0x9EC2, 0x9EC3, 0x9EC5, 0x9EC6, 0x9EC7, 0x9EC8, - 0x9ECA, 0x9ECB, 0x9ECC, 0x9ED0, 0x9ED2, 0x9ED3, 0x9ED5, 0x9ED6, 0x9ED7, 0x9ED9, 0x9EDA, 0x9EDE, 0x9EE1, 0x9EE3, 0x9EE4, 0x9EE6, - 0x9EE8, 0x9EEB, 0x9EEC, 0x9EED, 0x9EEE, 0x9EF0, 0x9EF1, 0x9EF2, 0x9EF3, 0x9EF4, 0x9EF5, 0x9EF6, 0x9EF7, 0x9EF8, 0x9EFA, 0x9EFD, - 0x9EFF, 0x9F00, 0x9F01, 0x9F02, 0x9F03, 0x9F04, 0x9F05, - // GB 0xFC80..0xFCA0 - 0x9F06, 0x9F07, 0x9F08, 0x9F09, 0x9F0A, 0x9F0C, 0x9F0F, 0x9F11, 0x9F12, 0x9F14, 0x9F15, 0x9F16, 0x9F18, 0x9F1A, 0x9F1B, 0x9F1C, - 0x9F1D, 0x9F1E, 0x9F1F, 0x9F21, 0x9F23, 0x9F24, 0x9F25, 0x9F26, 0x9F27, 0x9F28, 0x9F29, 0x9F2A, 0x9F2B, 0x9F2D, 0x9F2E, 0x9F30, - 0x9F31, // Skip: GB 0xFCA1..0xFCFE (UDA 2) - // GB 0xFD40..0xFD7E - 0x9F32, 0x9F33, 0x9F34, 0x9F35, 0x9F36, 0x9F38, 0x9F3A, 0x9F3C, 0x9F3F, 0x9F40, 0x9F41, 0x9F42, 0x9F43, 0x9F45, 0x9F46, 0x9F47, - 0x9F48, 0x9F49, 0x9F4A, 0x9F4B, 0x9F4C, 0x9F4D, 0x9F4E, 0x9F4F, 0x9F52, 0x9F53, 0x9F54, 0x9F55, 0x9F56, 0x9F57, 0x9F58, 0x9F59, - 0x9F5A, 0x9F5B, 0x9F5C, 0x9F5D, 0x9F5E, 0x9F5F, 0x9F60, 0x9F61, 0x9F62, 0x9F63, 0x9F64, 0x9F65, 0x9F66, 0x9F67, 0x9F68, 0x9F69, - 0x9F6A, 0x9F6B, 0x9F6C, 0x9F6D, 0x9F6E, 0x9F6F, 0x9F70, 0x9F71, 0x9F72, 0x9F73, 0x9F74, 0x9F75, 0x9F76, 0x9F77, 0x9F78, - // GB 0xFD80..0xFDA0 - 0x9F79, 0x9F7A, 0x9F7B, 0x9F7C, 0x9F7D, 0x9F7E, 0x9F81, 0x9F82, - 0x9F8D, 0x9F8E, 0x9F8F, 0x9F90, 0x9F91, 0x9F92, 0x9F93, 0x9F94, 0x9F95, 0x9F96, 0x9F97, 0x9F98, 0x9F9C, 0x9F9D, 0x9F9E, 0x9FA1, - 0x9FA2, 0x9FA3, 0x9FA4, 0x9FA5, 0xF92C, 0xF979, 0xF995, 0xF9E7, 0xF9F1, // Skip: GB 0xFDA1..0xFDFE (UDA 2) - // GB 0xFE40..0xFE7E - 0xFA0C, 0xFA0D, 0xFA0E, 0xFA0F, 0xFA11, 0xFA13, 0xFA14, 0xFA18, - 0xFA1F, 0xFA20, 0xFA21, 0xFA23, 0xFA24, 0xFA27, 0xFA28, 0xFA29, 0x2E81, 0xE816, 0xE817, 0xE818, 0x2E84, 0x3473, 0x3447, 0x2E88, - 0x2E8B, 0xE81E, 0x359E, 0x361A, 0x360E, 0x2E8C, 0x2E97, 0x396E, 0x3918, 0xE826, 0x39CF, 0x39DF, 0x3A73, 0x39D0, 0xE82B, 0xE82C, - 0x3B4E, 0x3C6E, 0x3CE0, 0x2EA7, 0xE831, 0xE832, 0x2EAA, 0x4056, 0x415F, 0x2EAE, 0x4337, 0x2EB3, 0x2EB6, 0x2EB7, 0xE83B, 0x43B1, - 0x43AC, 0x2EBB, 0x43DD, 0x44D6, 0x4661, 0x464C, 0xE843, - // GB 0xFE80..0xFEA0 - 0x4723, 0x4729, 0x477C, 0x478D, 0x2ECA, 0x4947, 0x497A, 0x497D, 0x4982, 0x4983, 0x4985, 0x4986, 0x499F, 0x499B, 0x49B7, 0x49B6, - 0xE854, 0xE855, 0x4CA3, 0x4C9F, 0x4CA0, 0x4CA1, 0x4C77, 0x4CA2, 0x4D13, 0x4D14, 0x4D15, 0x4D16, 0x4D17, 0x4D18, 0x4D19, 0x4DAE, - 0xE864, // Skip: GB 0xFEA1..0xFEFE (UDA 2) -}; - - -static const uint16_t gb18030_4byte_to_ucs[6793] = { - /* Contiguous area: GB+81 30 81 30 .. GB+81 30 D2 39 */ - /* GB+81 30 81 30 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, - /* GB+81 30 81 35 */ 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, - /* GB+81 30 82 30 */ 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, - /* GB+81 30 82 35 */ 0x008F, 0x0090, 0x0091, 0x0092, 0x0093, - /* GB+81 30 83 30 */ 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, - /* GB+81 30 83 35 */ 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, - /* GB+81 30 84 30 */ 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, - /* GB+81 30 84 35 */ 0x00A3, 0x00A5, 0x00A6, 0x00A9, 0x00AA, - /* GB+81 30 85 30 */ 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - /* GB+81 30 85 35 */ 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, - /* GB+81 30 86 30 */ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, - /* GB+81 30 86 35 */ 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, - /* GB+81 30 87 30 */ 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, - /* GB+81 30 87 35 */ 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, - /* GB+81 30 88 30 */ 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, - /* GB+81 30 88 35 */ 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, - /* GB+81 30 89 30 */ 0x00D6, 0x00D8, 0x00D9, 0x00DA, 0x00DB, - /* GB+81 30 89 35 */ 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E2, - /* GB+81 30 8A 30 */ 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, - /* GB+81 30 8A 35 */ 0x00EB, 0x00EE, 0x00EF, 0x00F0, 0x00F1, - /* GB+81 30 8B 30 */ 0x00F4, 0x00F5, 0x00F6, 0x00F8, 0x00FB, - /* GB+81 30 8B 35 */ 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0102, - /* GB+81 30 8C 30 */ 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, - /* GB+81 30 8C 35 */ 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, - /* GB+81 30 8D 30 */ 0x010D, 0x010E, 0x010F, 0x0110, 0x0111, - /* GB+81 30 8D 35 */ 0x0112, 0x0114, 0x0115, 0x0116, 0x0117, - /* GB+81 30 8E 30 */ 0x0118, 0x0119, 0x011A, 0x011C, 0x011D, - /* GB+81 30 8E 35 */ 0x011E, 0x011F, 0x0120, 0x0121, 0x0122, - /* GB+81 30 8F 30 */ 0x0123, 0x0124, 0x0125, 0x0126, 0x0127, - /* GB+81 30 8F 35 */ 0x0128, 0x0129, 0x012A, 0x012C, 0x012D, - /* GB+81 30 90 30 */ 0x012E, 0x012F, 0x0130, 0x0131, 0x0132, - /* GB+81 30 90 35 */ 0x0133, 0x0134, 0x0135, 0x0136, 0x0137, - /* GB+81 30 91 30 */ 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, - /* GB+81 30 91 35 */ 0x013D, 0x013E, 0x013F, 0x0140, 0x0141, - /* GB+81 30 92 30 */ 0x0142, 0x0143, 0x0145, 0x0146, 0x0147, - /* GB+81 30 92 35 */ 0x0149, 0x014A, 0x014B, 0x014C, 0x014E, - /* GB+81 30 93 30 */ 0x014F, 0x0150, 0x0151, 0x0152, 0x0153, - /* GB+81 30 93 35 */ 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, - /* GB+81 30 94 30 */ 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, - /* GB+81 30 94 35 */ 0x015E, 0x015F, 0x0160, 0x0161, 0x0162, - /* GB+81 30 95 30 */ 0x0163, 0x0164, 0x0165, 0x0166, 0x0167, - /* GB+81 30 95 35 */ 0x0168, 0x0169, 0x016A, 0x016C, 0x016D, - /* GB+81 30 96 30 */ 0x016E, 0x016F, 0x0170, 0x0171, 0x0172, - /* GB+81 30 96 35 */ 0x0173, 0x0174, 0x0175, 0x0176, 0x0177, - /* GB+81 30 97 30 */ 0x0178, 0x0179, 0x017A, 0x017B, 0x017C, - /* GB+81 30 97 35 */ 0x017D, 0x017E, 0x017F, 0x0180, 0x0181, - /* GB+81 30 98 30 */ 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, - /* GB+81 30 98 35 */ 0x0187, 0x0188, 0x0189, 0x018A, 0x018B, - /* GB+81 30 99 30 */ 0x018C, 0x018D, 0x018E, 0x018F, 0x0190, - /* GB+81 30 99 35 */ 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, - /* GB+81 30 9A 30 */ 0x0196, 0x0197, 0x0198, 0x0199, 0x019A, - /* GB+81 30 9A 35 */ 0x019B, 0x019C, 0x019D, 0x019E, 0x019F, - /* GB+81 30 9B 30 */ 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4, - /* GB+81 30 9B 35 */ 0x01A5, 0x01A6, 0x01A7, 0x01A8, 0x01A9, - /* GB+81 30 9C 30 */ 0x01AA, 0x01AB, 0x01AC, 0x01AD, 0x01AE, - /* GB+81 30 9C 35 */ 0x01AF, 0x01B0, 0x01B1, 0x01B2, 0x01B3, - /* GB+81 30 9D 30 */ 0x01B4, 0x01B5, 0x01B6, 0x01B7, 0x01B8, - /* GB+81 30 9D 35 */ 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BD, - /* GB+81 30 9E 30 */ 0x01BE, 0x01BF, 0x01C0, 0x01C1, 0x01C2, - /* GB+81 30 9E 35 */ 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7, - /* GB+81 30 9F 30 */ 0x01C8, 0x01C9, 0x01CA, 0x01CB, 0x01CC, - /* GB+81 30 9F 35 */ 0x01CD, 0x01CF, 0x01D1, 0x01D3, 0x01D5, - /* GB+81 30 A0 30 */ 0x01D7, 0x01D9, 0x01DB, 0x01DD, 0x01DE, - /* GB+81 30 A0 35 */ 0x01DF, 0x01E0, 0x01E1, 0x01E2, 0x01E3, - /* GB+81 30 A1 30 */ 0x01E4, 0x01E5, 0x01E6, 0x01E7, 0x01E8, - /* GB+81 30 A1 35 */ 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, - /* GB+81 30 A2 30 */ 0x01EE, 0x01EF, 0x01F0, 0x01F1, 0x01F2, - /* GB+81 30 A2 35 */ 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7, - /* GB+81 30 A3 30 */ 0x01F8, 0x01FA, 0x01FB, 0x01FC, 0x01FD, - /* GB+81 30 A3 35 */ 0x01FE, 0x01FF, 0x0200, 0x0201, 0x0202, - /* GB+81 30 A4 30 */ 0x0203, 0x0204, 0x0205, 0x0206, 0x0207, - /* GB+81 30 A4 35 */ 0x0208, 0x0209, 0x020A, 0x020B, 0x020C, - /* GB+81 30 A5 30 */ 0x020D, 0x020E, 0x020F, 0x0210, 0x0211, - /* GB+81 30 A5 35 */ 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, - /* GB+81 30 A6 30 */ 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, - /* GB+81 30 A6 35 */ 0x021C, 0x021D, 0x021E, 0x021F, 0x0220, - /* GB+81 30 A7 30 */ 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, - /* GB+81 30 A7 35 */ 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, - /* GB+81 30 A8 30 */ 0x022B, 0x022C, 0x022D, 0x022E, 0x022F, - /* GB+81 30 A8 35 */ 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, - /* GB+81 30 A9 30 */ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, - /* GB+81 30 A9 35 */ 0x023A, 0x023B, 0x023C, 0x023D, 0x023E, - /* GB+81 30 AA 30 */ 0x023F, 0x0240, 0x0241, 0x0242, 0x0243, - /* GB+81 30 AA 35 */ 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, - /* GB+81 30 AB 30 */ 0x0249, 0x024A, 0x024B, 0x024C, 0x024D, - /* GB+81 30 AB 35 */ 0x024E, 0x024F, 0x0250, 0x0252, 0x0253, - /* GB+81 30 AC 30 */ 0x0254, 0x0255, 0x0256, 0x0257, 0x0258, - /* GB+81 30 AC 35 */ 0x0259, 0x025A, 0x025B, 0x025C, 0x025D, - /* GB+81 30 AD 30 */ 0x025E, 0x025F, 0x0260, 0x0262, 0x0263, - /* GB+81 30 AD 35 */ 0x0264, 0x0265, 0x0266, 0x0267, 0x0268, - /* GB+81 30 AE 30 */ 0x0269, 0x026A, 0x026B, 0x026C, 0x026D, - /* GB+81 30 AE 35 */ 0x026E, 0x026F, 0x0270, 0x0271, 0x0272, - /* GB+81 30 AF 30 */ 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, - /* GB+81 30 AF 35 */ 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, - /* GB+81 30 B0 30 */ 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, - /* GB+81 30 B0 35 */ 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, - /* GB+81 30 B1 30 */ 0x0287, 0x0288, 0x0289, 0x028A, 0x028B, - /* GB+81 30 B1 35 */ 0x028C, 0x028D, 0x028E, 0x028F, 0x0290, - /* GB+81 30 B2 30 */ 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, - /* GB+81 30 B2 35 */ 0x0296, 0x0297, 0x0298, 0x0299, 0x029A, - /* GB+81 30 B3 30 */ 0x029B, 0x029C, 0x029D, 0x029E, 0x029F, - /* GB+81 30 B3 35 */ 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, - /* GB+81 30 B4 30 */ 0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, - /* GB+81 30 B4 35 */ 0x02AA, 0x02AB, 0x02AC, 0x02AD, 0x02AE, - /* GB+81 30 B5 30 */ 0x02AF, 0x02B0, 0x02B1, 0x02B2, 0x02B3, - /* GB+81 30 B5 35 */ 0x02B4, 0x02B5, 0x02B6, 0x02B7, 0x02B8, - /* GB+81 30 B6 30 */ 0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, - /* GB+81 30 B6 35 */ 0x02BE, 0x02BF, 0x02C0, 0x02C1, 0x02C2, - /* GB+81 30 B7 30 */ 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C8, - /* GB+81 30 B7 35 */ 0x02CC, 0x02CD, 0x02CE, 0x02CF, 0x02D0, - /* GB+81 30 B8 30 */ 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, - /* GB+81 30 B8 35 */ 0x02D6, 0x02D7, 0x02D8, 0x02DA, 0x02DB, - /* GB+81 30 B9 30 */ 0x02DC, 0x02DD, 0x02DE, 0x02DF, 0x02E0, - /* GB+81 30 B9 35 */ 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5, - /* GB+81 30 BA 30 */ 0x02E6, 0x02E7, 0x02E8, 0x02E9, 0x02EA, - /* GB+81 30 BA 35 */ 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF, - /* GB+81 30 BB 30 */ 0x02F0, 0x02F1, 0x02F2, 0x02F3, 0x02F4, - /* GB+81 30 BB 35 */ 0x02F5, 0x02F6, 0x02F7, 0x02F8, 0x02F9, - /* GB+81 30 BC 30 */ 0x02FA, 0x02FB, 0x02FC, 0x02FD, 0x02FE, - /* GB+81 30 BC 35 */ 0x02FF, 0x0300, 0x0301, 0x0302, 0x0303, - /* GB+81 30 BD 30 */ 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, - /* GB+81 30 BD 35 */ 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, - /* GB+81 30 BE 30 */ 0x030E, 0x030F, 0x0310, 0x0311, 0x0312, - /* GB+81 30 BE 35 */ 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, - /* GB+81 30 BF 30 */ 0x0318, 0x0319, 0x031A, 0x031B, 0x031C, - /* GB+81 30 BF 35 */ 0x031D, 0x031E, 0x031F, 0x0320, 0x0321, - /* GB+81 30 C0 30 */ 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, - /* GB+81 30 C0 35 */ 0x0327, 0x0328, 0x0329, 0x032A, 0x032B, - /* GB+81 30 C1 30 */ 0x032C, 0x032D, 0x032E, 0x032F, 0x0330, - /* GB+81 30 C1 35 */ 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, - /* GB+81 30 C2 30 */ 0x0336, 0x0337, 0x0338, 0x0339, 0x033A, - /* GB+81 30 C2 35 */ 0x033B, 0x033C, 0x033D, 0x033E, 0x033F, - /* GB+81 30 C3 30 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, - /* GB+81 30 C3 35 */ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, - /* GB+81 30 C4 30 */ 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, - /* GB+81 30 C4 35 */ 0x034F, 0x0350, 0x0351, 0x0352, 0x0353, - /* GB+81 30 C5 30 */ 0x0354, 0x0355, 0x0356, 0x0357, 0x0358, - /* GB+81 30 C5 35 */ 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, - /* GB+81 30 C6 30 */ 0x035E, 0x035F, 0x0360, 0x0361, 0x0362, - /* GB+81 30 C6 35 */ 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, - /* GB+81 30 C7 30 */ 0x0368, 0x0369, 0x036A, 0x036B, 0x036C, - /* GB+81 30 C7 35 */ 0x036D, 0x036E, 0x036F, 0x0370, 0x0371, - /* GB+81 30 C8 30 */ 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, - /* GB+81 30 C8 35 */ 0x0377, 0x0378, 0x0379, 0x037A, 0x037B, - /* GB+81 30 C9 30 */ 0x037C, 0x037D, 0x037E, 0x037F, 0x0380, - /* GB+81 30 C9 35 */ 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, - /* GB+81 30 CA 30 */ 0x0386, 0x0387, 0x0388, 0x0389, 0x038A, - /* GB+81 30 CA 35 */ 0x038B, 0x038C, 0x038D, 0x038E, 0x038F, - /* GB+81 30 CB 30 */ 0x0390, 0x03A2, 0x03AA, 0x03AB, 0x03AC, - /* GB+81 30 CB 35 */ 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03C2, - /* GB+81 30 CC 30 */ 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, - /* GB+81 30 CC 35 */ 0x03CF, 0x03D0, 0x03D1, 0x03D2, 0x03D3, - /* GB+81 30 CD 30 */ 0x03D4, 0x03D5, 0x03D6, 0x03D7, 0x03D8, - /* GB+81 30 CD 35 */ 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, - /* GB+81 30 CE 30 */ 0x03DE, 0x03DF, 0x03E0, 0x03E1, 0x03E2, - /* GB+81 30 CE 35 */ 0x03E3, 0x03E4, 0x03E5, 0x03E6, 0x03E7, - /* GB+81 30 CF 30 */ 0x03E8, 0x03E9, 0x03EA, 0x03EB, 0x03EC, - /* GB+81 30 CF 35 */ 0x03ED, 0x03EE, 0x03EF, 0x03F0, 0x03F1, - /* GB+81 30 D0 30 */ 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, - /* GB+81 30 D0 35 */ 0x03F7, 0x03F8, 0x03F9, 0x03FA, 0x03FB, - /* GB+81 30 D1 30 */ 0x03FC, 0x03FD, 0x03FE, 0x03FF, 0x0400, - /* GB+81 30 D1 35 */ 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, - /* GB+81 30 D2 30 */ 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, - /* GB+81 30 D2 35 */ 0x040C, 0x040D, 0x040E, 0x040F, 0x0450, - /* Contiguous area: GB+81 36 A5 32 .. GB+81 37 A8 38 */ - /* GB+81 36 A5 32 */ 0x2011, 0x2012, 0x2017, - /* GB+81 36 A5 35 */ 0x201A, 0x201B, 0x201E, 0x201F, 0x2020, - /* GB+81 36 A6 30 */ 0x2021, 0x2022, 0x2023, 0x2024, 0x2027, - /* GB+81 36 A6 35 */ 0x2028, 0x2029, 0x202A, 0x202B, 0x202C, - /* GB+81 36 A7 30 */ 0x202D, 0x202E, 0x202F, 0x2031, 0x2034, - /* GB+81 36 A7 35 */ 0x2036, 0x2037, 0x2038, 0x2039, 0x203A, - /* GB+81 36 A8 30 */ 0x203C, 0x203D, 0x203E, 0x203F, 0x2040, - /* GB+81 36 A8 35 */ 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, - /* GB+81 36 A9 30 */ 0x2046, 0x2047, 0x2048, 0x2049, 0x204A, - /* GB+81 36 A9 35 */ 0x204B, 0x204C, 0x204D, 0x204E, 0x204F, - /* GB+81 36 AA 30 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054, - /* GB+81 36 AA 35 */ 0x2055, 0x2056, 0x2057, 0x2058, 0x2059, - /* GB+81 36 AB 30 */ 0x205A, 0x205B, 0x205C, 0x205D, 0x205E, - /* GB+81 36 AB 35 */ 0x205F, 0x2060, 0x2061, 0x2062, 0x2063, - /* GB+81 36 AC 30 */ 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, - /* GB+81 36 AC 35 */ 0x2069, 0x206A, 0x206B, 0x206C, 0x206D, - /* GB+81 36 AD 30 */ 0x206E, 0x206F, 0x2070, 0x2071, 0x2072, - /* GB+81 36 AD 35 */ 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, - /* GB+81 36 AE 30 */ 0x2078, 0x2079, 0x207A, 0x207B, 0x207C, - /* GB+81 36 AE 35 */ 0x207D, 0x207E, 0x207F, 0x2080, 0x2081, - /* GB+81 36 AF 30 */ 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, - /* GB+81 36 AF 35 */ 0x2087, 0x2088, 0x2089, 0x208A, 0x208B, - /* GB+81 36 B0 30 */ 0x208C, 0x208D, 0x208E, 0x208F, 0x2090, - /* GB+81 36 B0 35 */ 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, - /* GB+81 36 B1 30 */ 0x2096, 0x2097, 0x2098, 0x2099, 0x209A, - /* GB+81 36 B1 35 */ 0x209B, 0x209C, 0x209D, 0x209E, 0x209F, - /* GB+81 36 B2 30 */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4, - /* GB+81 36 B2 35 */ 0x20A5, 0x20A6, 0x20A7, 0x20A8, 0x20A9, - /* GB+81 36 B3 30 */ 0x20AA, 0x20AB, 0x20AD, 0x20AE, 0x20AF, - /* GB+81 36 B3 35 */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, - /* GB+81 36 B4 30 */ 0x20B5, 0x20B6, 0x20B7, 0x20B8, 0x20B9, - /* GB+81 36 B4 35 */ 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE, - /* GB+81 36 B5 30 */ 0x20BF, 0x20C0, 0x20C1, 0x20C2, 0x20C3, - /* GB+81 36 B5 35 */ 0x20C4, 0x20C5, 0x20C6, 0x20C7, 0x20C8, - /* GB+81 36 B6 30 */ 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, - /* GB+81 36 B6 35 */ 0x20CE, 0x20CF, 0x20D0, 0x20D1, 0x20D2, - /* GB+81 36 B7 30 */ 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7, - /* GB+81 36 B7 35 */ 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, - /* GB+81 36 B8 30 */ 0x20DD, 0x20DE, 0x20DF, 0x20E0, 0x20E1, - /* GB+81 36 B8 35 */ 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, - /* GB+81 36 B9 30 */ 0x20E7, 0x20E8, 0x20E9, 0x20EA, 0x20EB, - /* GB+81 36 B9 35 */ 0x20EC, 0x20ED, 0x20EE, 0x20EF, 0x20F0, - /* GB+81 36 BA 30 */ 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, - /* GB+81 36 BA 35 */ 0x20F6, 0x20F7, 0x20F8, 0x20F9, 0x20FA, - /* GB+81 36 BB 30 */ 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF, - /* GB+81 36 BB 35 */ 0x2100, 0x2101, 0x2102, 0x2104, 0x2106, - /* GB+81 36 BC 30 */ 0x2107, 0x2108, 0x210A, 0x210B, 0x210C, - /* GB+81 36 BC 35 */ 0x210D, 0x210E, 0x210F, 0x2110, 0x2111, - /* GB+81 36 BD 30 */ 0x2112, 0x2113, 0x2114, 0x2115, 0x2117, - /* GB+81 36 BD 35 */ 0x2118, 0x2119, 0x211A, 0x211B, 0x211C, - /* GB+81 36 BE 30 */ 0x211D, 0x211E, 0x211F, 0x2120, 0x2122, - /* GB+81 36 BE 35 */ 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, - /* GB+81 36 BF 30 */ 0x2128, 0x2129, 0x212A, 0x212B, 0x212C, - /* GB+81 36 BF 35 */ 0x212D, 0x212E, 0x212F, 0x2130, 0x2131, - /* GB+81 36 C0 30 */ 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, - /* GB+81 36 C0 35 */ 0x2137, 0x2138, 0x2139, 0x213A, 0x213B, - /* GB+81 36 C1 30 */ 0x213C, 0x213D, 0x213E, 0x213F, 0x2140, - /* GB+81 36 C1 35 */ 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, - /* GB+81 36 C2 30 */ 0x2146, 0x2147, 0x2148, 0x2149, 0x214A, - /* GB+81 36 C2 35 */ 0x214B, 0x214C, 0x214D, 0x214E, 0x214F, - /* GB+81 36 C3 30 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, - /* GB+81 36 C3 35 */ 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, - /* GB+81 36 C4 30 */ 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, - /* GB+81 36 C4 35 */ 0x215F, 0x216C, 0x216D, 0x216E, 0x216F, - /* GB+81 36 C5 30 */ 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, - /* GB+81 36 C5 35 */ 0x217F, 0x2180, 0x2181, 0x2182, 0x2183, - /* GB+81 36 C6 30 */ 0x2184, 0x2185, 0x2186, 0x2187, 0x2188, - /* GB+81 36 C6 35 */ 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, - /* GB+81 36 C7 30 */ 0x218E, 0x218F, 0x2194, 0x2195, 0x219A, - /* GB+81 36 C7 35 */ 0x219B, 0x219C, 0x219D, 0x219E, 0x219F, - /* GB+81 36 C8 30 */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, - /* GB+81 36 C8 35 */ 0x21A5, 0x21A6, 0x21A7, 0x21A8, 0x21A9, - /* GB+81 36 C9 30 */ 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, - /* GB+81 36 C9 35 */ 0x21AF, 0x21B0, 0x21B1, 0x21B2, 0x21B3, - /* GB+81 36 CA 30 */ 0x21B4, 0x21B5, 0x21B6, 0x21B7, 0x21B8, - /* GB+81 36 CA 35 */ 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, - /* GB+81 36 CB 30 */ 0x21BE, 0x21BF, 0x21C0, 0x21C1, 0x21C2, - /* GB+81 36 CB 35 */ 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7, - /* GB+81 36 CC 30 */ 0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, - /* GB+81 36 CC 35 */ 0x21CD, 0x21CE, 0x21CF, 0x21D0, 0x21D1, - /* GB+81 36 CD 30 */ 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, - /* GB+81 36 CD 35 */ 0x21D7, 0x21D8, 0x21D9, 0x21DA, 0x21DB, - /* GB+81 36 CE 30 */ 0x21DC, 0x21DD, 0x21DE, 0x21DF, 0x21E0, - /* GB+81 36 CE 35 */ 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, - /* GB+81 36 CF 30 */ 0x21E6, 0x21E7, 0x21E8, 0x21E9, 0x21EA, - /* GB+81 36 CF 35 */ 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF, - /* GB+81 36 D0 30 */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, - /* GB+81 36 D0 35 */ 0x21F5, 0x21F6, 0x21F7, 0x21F8, 0x21F9, - /* GB+81 36 D1 30 */ 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, - /* GB+81 36 D1 35 */ 0x21FF, 0x2200, 0x2201, 0x2202, 0x2203, - /* GB+81 36 D2 30 */ 0x2204, 0x2205, 0x2206, 0x2207, 0x2209, - /* GB+81 36 D2 35 */ 0x220A, 0x220B, 0x220C, 0x220D, 0x220E, - /* GB+81 36 D3 30 */ 0x2210, 0x2212, 0x2213, 0x2214, 0x2216, - /* GB+81 36 D3 35 */ 0x2217, 0x2218, 0x2219, 0x221B, 0x221C, - /* GB+81 36 D4 30 */ 0x2221, 0x2222, 0x2224, 0x2226, 0x222C, - /* GB+81 36 D4 35 */ 0x222D, 0x222F, 0x2230, 0x2231, 0x2232, - /* GB+81 36 D5 30 */ 0x2233, 0x2238, 0x2239, 0x223A, 0x223B, - /* GB+81 36 D5 35 */ 0x223C, 0x223E, 0x223F, 0x2240, 0x2241, - /* GB+81 36 D6 30 */ 0x2242, 0x2243, 0x2244, 0x2245, 0x2246, - /* GB+81 36 D6 35 */ 0x2247, 0x2249, 0x224A, 0x224B, 0x224D, - /* GB+81 36 D7 30 */ 0x224E, 0x224F, 0x2250, 0x2251, 0x2253, - /* GB+81 36 D7 35 */ 0x2254, 0x2255, 0x2256, 0x2257, 0x2258, - /* GB+81 36 D8 30 */ 0x2259, 0x225A, 0x225B, 0x225C, 0x225D, - /* GB+81 36 D8 35 */ 0x225E, 0x225F, 0x2262, 0x2263, 0x2268, - /* GB+81 36 D9 30 */ 0x2269, 0x226A, 0x226B, 0x226C, 0x226D, - /* GB+81 36 D9 35 */ 0x2270, 0x2271, 0x2272, 0x2273, 0x2274, - /* GB+81 36 DA 30 */ 0x2275, 0x2276, 0x2277, 0x2278, 0x2279, - /* GB+81 36 DA 35 */ 0x227A, 0x227B, 0x227C, 0x227D, 0x227E, - /* GB+81 36 DB 30 */ 0x227F, 0x2280, 0x2281, 0x2282, 0x2283, - /* GB+81 36 DB 35 */ 0x2284, 0x2285, 0x2286, 0x2287, 0x2288, - /* GB+81 36 DC 30 */ 0x2289, 0x228A, 0x228B, 0x228C, 0x228D, - /* GB+81 36 DC 35 */ 0x228E, 0x228F, 0x2290, 0x2291, 0x2292, - /* GB+81 36 DD 30 */ 0x2293, 0x2294, 0x2296, 0x2297, 0x2298, - /* GB+81 36 DD 35 */ 0x229A, 0x229B, 0x229C, 0x229D, 0x229E, - /* GB+81 36 DE 30 */ 0x229F, 0x22A0, 0x22A1, 0x22A2, 0x22A3, - /* GB+81 36 DE 35 */ 0x22A4, 0x22A6, 0x22A7, 0x22A8, 0x22A9, - /* GB+81 36 DF 30 */ 0x22AA, 0x22AB, 0x22AC, 0x22AD, 0x22AE, - /* GB+81 36 DF 35 */ 0x22AF, 0x22B0, 0x22B1, 0x22B2, 0x22B3, - /* GB+81 36 E0 30 */ 0x22B4, 0x22B5, 0x22B6, 0x22B7, 0x22B8, - /* GB+81 36 E0 35 */ 0x22B9, 0x22BA, 0x22BB, 0x22BC, 0x22BD, - /* GB+81 36 E1 30 */ 0x22BE, 0x22C0, 0x22C1, 0x22C2, 0x22C3, - /* GB+81 36 E1 35 */ 0x22C4, 0x22C5, 0x22C6, 0x22C7, 0x22C8, - /* GB+81 36 E2 30 */ 0x22C9, 0x22CA, 0x22CB, 0x22CC, 0x22CD, - /* GB+81 36 E2 35 */ 0x22CE, 0x22CF, 0x22D0, 0x22D1, 0x22D2, - /* GB+81 36 E3 30 */ 0x22D3, 0x22D4, 0x22D5, 0x22D6, 0x22D7, - /* GB+81 36 E3 35 */ 0x22D8, 0x22D9, 0x22DA, 0x22DB, 0x22DC, - /* GB+81 36 E4 30 */ 0x22DD, 0x22DE, 0x22DF, 0x22E0, 0x22E1, - /* GB+81 36 E4 35 */ 0x22E2, 0x22E3, 0x22E4, 0x22E5, 0x22E6, - /* GB+81 36 E5 30 */ 0x22E7, 0x22E8, 0x22E9, 0x22EA, 0x22EB, - /* GB+81 36 E5 35 */ 0x22EC, 0x22ED, 0x22EE, 0x22EF, 0x22F0, - /* GB+81 36 E6 30 */ 0x22F1, 0x22F2, 0x22F3, 0x22F4, 0x22F5, - /* GB+81 36 E6 35 */ 0x22F6, 0x22F7, 0x22F8, 0x22F9, 0x22FA, - /* GB+81 36 E7 30 */ 0x22FB, 0x22FC, 0x22FD, 0x22FE, 0x22FF, - /* GB+81 36 E7 35 */ 0x2300, 0x2301, 0x2302, 0x2303, 0x2304, - /* GB+81 36 E8 30 */ 0x2305, 0x2306, 0x2307, 0x2308, 0x2309, - /* GB+81 36 E8 35 */ 0x230A, 0x230B, 0x230C, 0x230D, 0x230E, - /* GB+81 36 E9 30 */ 0x230F, 0x2310, 0x2311, 0x2313, 0x2314, - /* GB+81 36 E9 35 */ 0x2315, 0x2316, 0x2317, 0x2318, 0x2319, - /* GB+81 36 EA 30 */ 0x231A, 0x231B, 0x231C, 0x231D, 0x231E, - /* GB+81 36 EA 35 */ 0x231F, 0x2320, 0x2321, 0x2322, 0x2323, - /* GB+81 36 EB 30 */ 0x2324, 0x2325, 0x2326, 0x2327, 0x2328, - /* GB+81 36 EB 35 */ 0x2329, 0x232A, 0x232B, 0x232C, 0x232D, - /* GB+81 36 EC 30 */ 0x232E, 0x232F, 0x2330, 0x2331, 0x2332, - /* GB+81 36 EC 35 */ 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, - /* GB+81 36 ED 30 */ 0x2338, 0x2339, 0x233A, 0x233B, 0x233C, - /* GB+81 36 ED 35 */ 0x233D, 0x233E, 0x233F, 0x2340, 0x2341, - /* GB+81 36 EE 30 */ 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, - /* GB+81 36 EE 35 */ 0x2347, 0x2348, 0x2349, 0x234A, 0x234B, - /* GB+81 36 EF 30 */ 0x234C, 0x234D, 0x234E, 0x234F, 0x2350, - /* GB+81 36 EF 35 */ 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, - /* GB+81 36 F0 30 */ 0x2356, 0x2357, 0x2358, 0x2359, 0x235A, - /* GB+81 36 F0 35 */ 0x235B, 0x235C, 0x235D, 0x235E, 0x235F, - /* GB+81 36 F1 30 */ 0x2360, 0x2361, 0x2362, 0x2363, 0x2364, - /* GB+81 36 F1 35 */ 0x2365, 0x2366, 0x2367, 0x2368, 0x2369, - /* GB+81 36 F2 30 */ 0x236A, 0x236B, 0x236C, 0x236D, 0x236E, - /* GB+81 36 F2 35 */ 0x236F, 0x2370, 0x2371, 0x2372, 0x2373, - /* GB+81 36 F3 30 */ 0x2374, 0x2375, 0x2376, 0x2377, 0x2378, - /* GB+81 36 F3 35 */ 0x2379, 0x237A, 0x237B, 0x237C, 0x237D, - /* GB+81 36 F4 30 */ 0x237E, 0x237F, 0x2380, 0x2381, 0x2382, - /* GB+81 36 F4 35 */ 0x2383, 0x2384, 0x2385, 0x2386, 0x2387, - /* GB+81 36 F5 30 */ 0x2388, 0x2389, 0x238A, 0x238B, 0x238C, - /* GB+81 36 F5 35 */ 0x238D, 0x238E, 0x238F, 0x2390, 0x2391, - /* GB+81 36 F6 30 */ 0x2392, 0x2393, 0x2394, 0x2395, 0x2396, - /* GB+81 36 F6 35 */ 0x2397, 0x2398, 0x2399, 0x239A, 0x239B, - /* GB+81 36 F7 30 */ 0x239C, 0x239D, 0x239E, 0x239F, 0x23A0, - /* GB+81 36 F7 35 */ 0x23A1, 0x23A2, 0x23A3, 0x23A4, 0x23A5, - /* GB+81 36 F8 30 */ 0x23A6, 0x23A7, 0x23A8, 0x23A9, 0x23AA, - /* GB+81 36 F8 35 */ 0x23AB, 0x23AC, 0x23AD, 0x23AE, 0x23AF, - /* GB+81 36 F9 30 */ 0x23B0, 0x23B1, 0x23B2, 0x23B3, 0x23B4, - /* GB+81 36 F9 35 */ 0x23B5, 0x23B6, 0x23B7, 0x23B8, 0x23B9, - /* GB+81 36 FA 30 */ 0x23BA, 0x23BB, 0x23BC, 0x23BD, 0x23BE, - /* GB+81 36 FA 35 */ 0x23BF, 0x23C0, 0x23C1, 0x23C2, 0x23C3, - /* GB+81 36 FB 30 */ 0x23C4, 0x23C5, 0x23C6, 0x23C7, 0x23C8, - /* GB+81 36 FB 35 */ 0x23C9, 0x23CA, 0x23CB, 0x23CC, 0x23CD, - /* GB+81 36 FC 30 */ 0x23CE, 0x23CF, 0x23D0, 0x23D1, 0x23D2, - /* GB+81 36 FC 35 */ 0x23D3, 0x23D4, 0x23D5, 0x23D6, 0x23D7, - /* GB+81 36 FD 30 */ 0x23D8, 0x23D9, 0x23DA, 0x23DB, 0x23DC, - /* GB+81 36 FD 35 */ 0x23DD, 0x23DE, 0x23DF, 0x23E0, 0x23E1, - /* GB+81 36 FE 30 */ 0x23E2, 0x23E3, 0x23E4, 0x23E5, 0x23E6, - /* GB+81 36 FE 35 */ 0x23E7, 0x23E8, 0x23E9, 0x23EA, 0x23EB, - /* GB+81 37 81 30 */ 0x23EC, 0x23ED, 0x23EE, 0x23EF, 0x23F0, - /* GB+81 37 81 35 */ 0x23F1, 0x23F2, 0x23F3, 0x23F4, 0x23F5, - /* GB+81 37 82 30 */ 0x23F6, 0x23F7, 0x23F8, 0x23F9, 0x23FA, - /* GB+81 37 82 35 */ 0x23FB, 0x23FC, 0x23FD, 0x23FE, 0x23FF, - /* GB+81 37 83 30 */ 0x2400, 0x2401, 0x2402, 0x2403, 0x2404, - /* GB+81 37 83 35 */ 0x2405, 0x2406, 0x2407, 0x2408, 0x2409, - /* GB+81 37 84 30 */ 0x240A, 0x240B, 0x240C, 0x240D, 0x240E, - /* GB+81 37 84 35 */ 0x240F, 0x2410, 0x2411, 0x2412, 0x2413, - /* GB+81 37 85 30 */ 0x2414, 0x2415, 0x2416, 0x2417, 0x2418, - /* GB+81 37 85 35 */ 0x2419, 0x241A, 0x241B, 0x241C, 0x241D, - /* GB+81 37 86 30 */ 0x241E, 0x241F, 0x2420, 0x2421, 0x2422, - /* GB+81 37 86 35 */ 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, - /* GB+81 37 87 30 */ 0x2428, 0x2429, 0x242A, 0x242B, 0x242C, - /* GB+81 37 87 35 */ 0x242D, 0x242E, 0x242F, 0x2430, 0x2431, - /* GB+81 37 88 30 */ 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, - /* GB+81 37 88 35 */ 0x2437, 0x2438, 0x2439, 0x243A, 0x243B, - /* GB+81 37 89 30 */ 0x243C, 0x243D, 0x243E, 0x243F, 0x2440, - /* GB+81 37 89 35 */ 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, - /* GB+81 37 8A 30 */ 0x2446, 0x2447, 0x2448, 0x2449, 0x244A, - /* GB+81 37 8A 35 */ 0x244B, 0x244C, 0x244D, 0x244E, 0x244F, - /* GB+81 37 8B 30 */ 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, - /* GB+81 37 8B 35 */ 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, - /* GB+81 37 8C 30 */ 0x245A, 0x245B, 0x245C, 0x245D, 0x245E, - /* GB+81 37 8C 35 */ 0x245F, 0x246A, 0x246B, 0x246C, 0x246D, - /* GB+81 37 8D 30 */ 0x246E, 0x246F, 0x2470, 0x2471, 0x2472, - /* GB+81 37 8D 35 */ 0x2473, 0x249C, 0x249D, 0x249E, 0x249F, - /* GB+81 37 8E 30 */ 0x24A0, 0x24A1, 0x24A2, 0x24A3, 0x24A4, - /* GB+81 37 8E 35 */ 0x24A5, 0x24A6, 0x24A7, 0x24A8, 0x24A9, - /* GB+81 37 8F 30 */ 0x24AA, 0x24AB, 0x24AC, 0x24AD, 0x24AE, - /* GB+81 37 8F 35 */ 0x24AF, 0x24B0, 0x24B1, 0x24B2, 0x24B3, - /* GB+81 37 90 30 */ 0x24B4, 0x24B5, 0x24B6, 0x24B7, 0x24B8, - /* GB+81 37 90 35 */ 0x24B9, 0x24BA, 0x24BB, 0x24BC, 0x24BD, - /* GB+81 37 91 30 */ 0x24BE, 0x24BF, 0x24C0, 0x24C1, 0x24C2, - /* GB+81 37 91 35 */ 0x24C3, 0x24C4, 0x24C5, 0x24C6, 0x24C7, - /* GB+81 37 92 30 */ 0x24C8, 0x24C9, 0x24CA, 0x24CB, 0x24CC, - /* GB+81 37 92 35 */ 0x24CD, 0x24CE, 0x24CF, 0x24D0, 0x24D1, - /* GB+81 37 93 30 */ 0x24D2, 0x24D3, 0x24D4, 0x24D5, 0x24D6, - /* GB+81 37 93 35 */ 0x24D7, 0x24D8, 0x24D9, 0x24DA, 0x24DB, - /* GB+81 37 94 30 */ 0x24DC, 0x24DD, 0x24DE, 0x24DF, 0x24E0, - /* GB+81 37 94 35 */ 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, - /* GB+81 37 95 30 */ 0x24E6, 0x24E7, 0x24E8, 0x24E9, 0x24EA, - /* GB+81 37 95 35 */ 0x24EB, 0x24EC, 0x24ED, 0x24EE, 0x24EF, - /* GB+81 37 96 30 */ 0x24F0, 0x24F1, 0x24F2, 0x24F3, 0x24F4, - /* GB+81 37 96 35 */ 0x24F5, 0x24F6, 0x24F7, 0x24F8, 0x24F9, - /* GB+81 37 97 30 */ 0x24FA, 0x24FB, 0x24FC, 0x24FD, 0x24FE, - /* GB+81 37 97 35 */ 0x24FF, 0x254C, 0x254D, 0x254E, 0x254F, - /* GB+81 37 98 30 */ 0x2574, 0x2575, 0x2576, 0x2577, 0x2578, - /* GB+81 37 98 35 */ 0x2579, 0x257A, 0x257B, 0x257C, 0x257D, - /* GB+81 37 99 30 */ 0x257E, 0x257F, 0x2580, 0x2590, 0x2591, - /* GB+81 37 99 35 */ 0x2592, 0x2596, 0x2597, 0x2598, 0x2599, - /* GB+81 37 9A 30 */ 0x259A, 0x259B, 0x259C, 0x259D, 0x259E, - /* GB+81 37 9A 35 */ 0x259F, 0x25A2, 0x25A3, 0x25A4, 0x25A5, - /* GB+81 37 9B 30 */ 0x25A6, 0x25A7, 0x25A8, 0x25A9, 0x25AA, - /* GB+81 37 9B 35 */ 0x25AB, 0x25AC, 0x25AD, 0x25AE, 0x25AF, - /* GB+81 37 9C 30 */ 0x25B0, 0x25B1, 0x25B4, 0x25B5, 0x25B6, - /* GB+81 37 9C 35 */ 0x25B7, 0x25B8, 0x25B9, 0x25BA, 0x25BB, - /* GB+81 37 9D 30 */ 0x25BE, 0x25BF, 0x25C0, 0x25C1, 0x25C2, - /* GB+81 37 9D 35 */ 0x25C3, 0x25C4, 0x25C5, 0x25C8, 0x25C9, - /* GB+81 37 9E 30 */ 0x25CA, 0x25CC, 0x25CD, 0x25D0, 0x25D1, - /* GB+81 37 9E 35 */ 0x25D2, 0x25D3, 0x25D4, 0x25D5, 0x25D6, - /* GB+81 37 9F 30 */ 0x25D7, 0x25D8, 0x25D9, 0x25DA, 0x25DB, - /* GB+81 37 9F 35 */ 0x25DC, 0x25DD, 0x25DE, 0x25DF, 0x25E0, - /* GB+81 37 A0 30 */ 0x25E1, 0x25E6, 0x25E7, 0x25E8, 0x25E9, - /* GB+81 37 A0 35 */ 0x25EA, 0x25EB, 0x25EC, 0x25ED, 0x25EE, - /* GB+81 37 A1 30 */ 0x25EF, 0x25F0, 0x25F1, 0x25F2, 0x25F3, - /* GB+81 37 A1 35 */ 0x25F4, 0x25F5, 0x25F6, 0x25F7, 0x25F8, - /* GB+81 37 A2 30 */ 0x25F9, 0x25FA, 0x25FB, 0x25FC, 0x25FD, - /* GB+81 37 A2 35 */ 0x25FE, 0x25FF, 0x2600, 0x2601, 0x2602, - /* GB+81 37 A3 30 */ 0x2603, 0x2604, 0x2607, 0x2608, 0x260A, - /* GB+81 37 A3 35 */ 0x260B, 0x260C, 0x260D, 0x260E, 0x260F, - /* GB+81 37 A4 30 */ 0x2610, 0x2611, 0x2612, 0x2613, 0x2614, - /* GB+81 37 A4 35 */ 0x2615, 0x2616, 0x2617, 0x2618, 0x2619, - /* GB+81 37 A5 30 */ 0x261A, 0x261B, 0x261C, 0x261D, 0x261E, - /* GB+81 37 A5 35 */ 0x261F, 0x2620, 0x2621, 0x2622, 0x2623, - /* GB+81 37 A6 30 */ 0x2624, 0x2625, 0x2626, 0x2627, 0x2628, - /* GB+81 37 A6 35 */ 0x2629, 0x262A, 0x262B, 0x262C, 0x262D, - /* GB+81 37 A7 30 */ 0x262E, 0x262F, 0x2630, 0x2631, 0x2632, - /* GB+81 37 A7 35 */ 0x2633, 0x2634, 0x2635, 0x2636, 0x2637, - /* GB+81 37 A8 30 */ 0x2638, 0x2639, 0x263A, 0x263B, 0x263C, - /* GB+81 37 A8 35 */ 0x263D, 0x263E, 0x263F, 0x2641, - /* Contiguous area: GB+81 38 FD 39 .. GB+82 30 A6 32 */ - /* GB+81 38 FD 39 */ 0x2E82, - /* GB+81 38 FE 30 */ 0x2E83, 0x2E85, 0x2E86, 0x2E87, 0x2E89, - /* GB+81 38 FE 35 */ 0x2E8A, 0x2E8D, 0x2E8E, 0x2E8F, 0x2E90, - /* GB+81 39 81 30 */ 0x2E91, 0x2E92, 0x2E93, 0x2E94, 0x2E95, - /* GB+81 39 81 35 */ 0x2E96, 0x2E98, 0x2E99, 0x2E9A, 0x2E9B, - /* GB+81 39 82 30 */ 0x2E9C, 0x2E9D, 0x2E9E, 0x2E9F, 0x2EA0, - /* GB+81 39 82 35 */ 0x2EA1, 0x2EA2, 0x2EA3, 0x2EA4, 0x2EA5, - /* GB+81 39 83 30 */ 0x2EA6, 0x2EA8, 0x2EA9, 0x2EAB, 0x2EAC, - /* GB+81 39 83 35 */ 0x2EAD, 0x2EAF, 0x2EB0, 0x2EB1, 0x2EB2, - /* GB+81 39 84 30 */ 0x2EB4, 0x2EB5, 0x2EB8, 0x2EB9, 0x2EBA, - /* GB+81 39 84 35 */ 0x2EBC, 0x2EBD, 0x2EBE, 0x2EBF, 0x2EC0, - /* GB+81 39 85 30 */ 0x2EC1, 0x2EC2, 0x2EC3, 0x2EC4, 0x2EC5, - /* GB+81 39 85 35 */ 0x2EC6, 0x2EC7, 0x2EC8, 0x2EC9, 0x2ECB, - /* GB+81 39 86 30 */ 0x2ECC, 0x2ECD, 0x2ECE, 0x2ECF, 0x2ED0, - /* GB+81 39 86 35 */ 0x2ED1, 0x2ED2, 0x2ED3, 0x2ED4, 0x2ED5, - /* GB+81 39 87 30 */ 0x2ED6, 0x2ED7, 0x2ED8, 0x2ED9, 0x2EDA, - /* GB+81 39 87 35 */ 0x2EDB, 0x2EDC, 0x2EDD, 0x2EDE, 0x2EDF, - /* GB+81 39 88 30 */ 0x2EE0, 0x2EE1, 0x2EE2, 0x2EE3, 0x2EE4, - /* GB+81 39 88 35 */ 0x2EE5, 0x2EE6, 0x2EE7, 0x2EE8, 0x2EE9, - /* GB+81 39 89 30 */ 0x2EEA, 0x2EEB, 0x2EEC, 0x2EED, 0x2EEE, - /* GB+81 39 89 35 */ 0x2EEF, 0x2EF0, 0x2EF1, 0x2EF2, 0x2EF3, - /* GB+81 39 8A 30 */ 0x2EF4, 0x2EF5, 0x2EF6, 0x2EF7, 0x2EF8, - /* GB+81 39 8A 35 */ 0x2EF9, 0x2EFA, 0x2EFB, 0x2EFC, 0x2EFD, - /* GB+81 39 8B 30 */ 0x2EFE, 0x2EFF, 0x2F00, 0x2F01, 0x2F02, - /* GB+81 39 8B 35 */ 0x2F03, 0x2F04, 0x2F05, 0x2F06, 0x2F07, - /* GB+81 39 8C 30 */ 0x2F08, 0x2F09, 0x2F0A, 0x2F0B, 0x2F0C, - /* GB+81 39 8C 35 */ 0x2F0D, 0x2F0E, 0x2F0F, 0x2F10, 0x2F11, - /* GB+81 39 8D 30 */ 0x2F12, 0x2F13, 0x2F14, 0x2F15, 0x2F16, - /* GB+81 39 8D 35 */ 0x2F17, 0x2F18, 0x2F19, 0x2F1A, 0x2F1B, - /* GB+81 39 8E 30 */ 0x2F1C, 0x2F1D, 0x2F1E, 0x2F1F, 0x2F20, - /* GB+81 39 8E 35 */ 0x2F21, 0x2F22, 0x2F23, 0x2F24, 0x2F25, - /* GB+81 39 8F 30 */ 0x2F26, 0x2F27, 0x2F28, 0x2F29, 0x2F2A, - /* GB+81 39 8F 35 */ 0x2F2B, 0x2F2C, 0x2F2D, 0x2F2E, 0x2F2F, - /* GB+81 39 90 30 */ 0x2F30, 0x2F31, 0x2F32, 0x2F33, 0x2F34, - /* GB+81 39 90 35 */ 0x2F35, 0x2F36, 0x2F37, 0x2F38, 0x2F39, - /* GB+81 39 91 30 */ 0x2F3A, 0x2F3B, 0x2F3C, 0x2F3D, 0x2F3E, - /* GB+81 39 91 35 */ 0x2F3F, 0x2F40, 0x2F41, 0x2F42, 0x2F43, - /* GB+81 39 92 30 */ 0x2F44, 0x2F45, 0x2F46, 0x2F47, 0x2F48, - /* GB+81 39 92 35 */ 0x2F49, 0x2F4A, 0x2F4B, 0x2F4C, 0x2F4D, - /* GB+81 39 93 30 */ 0x2F4E, 0x2F4F, 0x2F50, 0x2F51, 0x2F52, - /* GB+81 39 93 35 */ 0x2F53, 0x2F54, 0x2F55, 0x2F56, 0x2F57, - /* GB+81 39 94 30 */ 0x2F58, 0x2F59, 0x2F5A, 0x2F5B, 0x2F5C, - /* GB+81 39 94 35 */ 0x2F5D, 0x2F5E, 0x2F5F, 0x2F60, 0x2F61, - /* GB+81 39 95 30 */ 0x2F62, 0x2F63, 0x2F64, 0x2F65, 0x2F66, - /* GB+81 39 95 35 */ 0x2F67, 0x2F68, 0x2F69, 0x2F6A, 0x2F6B, - /* GB+81 39 96 30 */ 0x2F6C, 0x2F6D, 0x2F6E, 0x2F6F, 0x2F70, - /* GB+81 39 96 35 */ 0x2F71, 0x2F72, 0x2F73, 0x2F74, 0x2F75, - /* GB+81 39 97 30 */ 0x2F76, 0x2F77, 0x2F78, 0x2F79, 0x2F7A, - /* GB+81 39 97 35 */ 0x2F7B, 0x2F7C, 0x2F7D, 0x2F7E, 0x2F7F, - /* GB+81 39 98 30 */ 0x2F80, 0x2F81, 0x2F82, 0x2F83, 0x2F84, - /* GB+81 39 98 35 */ 0x2F85, 0x2F86, 0x2F87, 0x2F88, 0x2F89, - /* GB+81 39 99 30 */ 0x2F8A, 0x2F8B, 0x2F8C, 0x2F8D, 0x2F8E, - /* GB+81 39 99 35 */ 0x2F8F, 0x2F90, 0x2F91, 0x2F92, 0x2F93, - /* GB+81 39 9A 30 */ 0x2F94, 0x2F95, 0x2F96, 0x2F97, 0x2F98, - /* GB+81 39 9A 35 */ 0x2F99, 0x2F9A, 0x2F9B, 0x2F9C, 0x2F9D, - /* GB+81 39 9B 30 */ 0x2F9E, 0x2F9F, 0x2FA0, 0x2FA1, 0x2FA2, - /* GB+81 39 9B 35 */ 0x2FA3, 0x2FA4, 0x2FA5, 0x2FA6, 0x2FA7, - /* GB+81 39 9C 30 */ 0x2FA8, 0x2FA9, 0x2FAA, 0x2FAB, 0x2FAC, - /* GB+81 39 9C 35 */ 0x2FAD, 0x2FAE, 0x2FAF, 0x2FB0, 0x2FB1, - /* GB+81 39 9D 30 */ 0x2FB2, 0x2FB3, 0x2FB4, 0x2FB5, 0x2FB6, - /* GB+81 39 9D 35 */ 0x2FB7, 0x2FB8, 0x2FB9, 0x2FBA, 0x2FBB, - /* GB+81 39 9E 30 */ 0x2FBC, 0x2FBD, 0x2FBE, 0x2FBF, 0x2FC0, - /* GB+81 39 9E 35 */ 0x2FC1, 0x2FC2, 0x2FC3, 0x2FC4, 0x2FC5, - /* GB+81 39 9F 30 */ 0x2FC6, 0x2FC7, 0x2FC8, 0x2FC9, 0x2FCA, - /* GB+81 39 9F 35 */ 0x2FCB, 0x2FCC, 0x2FCD, 0x2FCE, 0x2FCF, - /* GB+81 39 A0 30 */ 0x2FD0, 0x2FD1, 0x2FD2, 0x2FD3, 0x2FD4, - /* GB+81 39 A0 35 */ 0x2FD5, 0x2FD6, 0x2FD7, 0x2FD8, 0x2FD9, - /* GB+81 39 A1 30 */ 0x2FDA, 0x2FDB, 0x2FDC, 0x2FDD, 0x2FDE, - /* GB+81 39 A1 35 */ 0x2FDF, 0x2FE0, 0x2FE1, 0x2FE2, 0x2FE3, - /* GB+81 39 A2 30 */ 0x2FE4, 0x2FE5, 0x2FE6, 0x2FE7, 0x2FE8, - /* GB+81 39 A2 35 */ 0x2FE9, 0x2FEA, 0x2FEB, 0x2FEC, 0x2FED, - /* GB+81 39 A3 30 */ 0x2FEE, 0x2FEF, 0x2FFC, 0x2FFD, 0x2FFE, - /* GB+81 39 A3 35 */ 0x2FFF, 0x3004, 0x3018, 0x3019, 0x301A, - /* GB+81 39 A4 30 */ 0x301B, 0x301C, 0x301F, 0x3020, 0x302A, - /* GB+81 39 A4 35 */ 0x302B, 0x302C, 0x302D, 0x302E, 0x302F, - /* GB+81 39 A5 30 */ 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, - /* GB+81 39 A5 35 */ 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, - /* GB+81 39 A6 30 */ 0x303A, 0x303B, 0x303C, 0x303D, 0x303F, - /* GB+81 39 A6 35 */ 0x3040, 0x3094, 0x3095, 0x3096, 0x3097, - /* GB+81 39 A7 30 */ 0x3098, 0x3099, 0x309A, 0x309F, 0x30A0, - /* GB+81 39 A7 35 */ 0x30F7, 0x30F8, 0x30F9, 0x30FA, 0x30FB, - /* GB+81 39 A8 30 */ 0x30FF, 0x3100, 0x3101, 0x3102, 0x3103, - /* GB+81 39 A8 35 */ 0x3104, 0x312A, 0x312B, 0x312C, 0x312D, - /* GB+81 39 A9 30 */ 0x312E, 0x312F, 0x3130, 0x3131, 0x3132, - /* GB+81 39 A9 35 */ 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, - /* GB+81 39 AA 30 */ 0x3138, 0x3139, 0x313A, 0x313B, 0x313C, - /* GB+81 39 AA 35 */ 0x313D, 0x313E, 0x313F, 0x3140, 0x3141, - /* GB+81 39 AB 30 */ 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, - /* GB+81 39 AB 35 */ 0x3147, 0x3148, 0x3149, 0x314A, 0x314B, - /* GB+81 39 AC 30 */ 0x314C, 0x314D, 0x314E, 0x314F, 0x3150, - /* GB+81 39 AC 35 */ 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, - /* GB+81 39 AD 30 */ 0x3156, 0x3157, 0x3158, 0x3159, 0x315A, - /* GB+81 39 AD 35 */ 0x315B, 0x315C, 0x315D, 0x315E, 0x315F, - /* GB+81 39 AE 30 */ 0x3160, 0x3161, 0x3162, 0x3163, 0x3164, - /* GB+81 39 AE 35 */ 0x3165, 0x3166, 0x3167, 0x3168, 0x3169, - /* GB+81 39 AF 30 */ 0x316A, 0x316B, 0x316C, 0x316D, 0x316E, - /* GB+81 39 AF 35 */ 0x316F, 0x3170, 0x3171, 0x3172, 0x3173, - /* GB+81 39 B0 30 */ 0x3174, 0x3175, 0x3176, 0x3177, 0x3178, - /* GB+81 39 B0 35 */ 0x3179, 0x317A, 0x317B, 0x317C, 0x317D, - /* GB+81 39 B1 30 */ 0x317E, 0x317F, 0x3180, 0x3181, 0x3182, - /* GB+81 39 B1 35 */ 0x3183, 0x3184, 0x3185, 0x3186, 0x3187, - /* GB+81 39 B2 30 */ 0x3188, 0x3189, 0x318A, 0x318B, 0x318C, - /* GB+81 39 B2 35 */ 0x318D, 0x318E, 0x318F, 0x3190, 0x3191, - /* GB+81 39 B3 30 */ 0x3192, 0x3193, 0x3194, 0x3195, 0x3196, - /* GB+81 39 B3 35 */ 0x3197, 0x3198, 0x3199, 0x319A, 0x319B, - /* GB+81 39 B4 30 */ 0x319C, 0x319D, 0x319E, 0x319F, 0x31A0, - /* GB+81 39 B4 35 */ 0x31A1, 0x31A2, 0x31A3, 0x31A4, 0x31A5, - /* GB+81 39 B5 30 */ 0x31A6, 0x31A7, 0x31A8, 0x31A9, 0x31AA, - /* GB+81 39 B5 35 */ 0x31AB, 0x31AC, 0x31AD, 0x31AE, 0x31AF, - /* GB+81 39 B6 30 */ 0x31B0, 0x31B1, 0x31B2, 0x31B3, 0x31B4, - /* GB+81 39 B6 35 */ 0x31B5, 0x31B6, 0x31B7, 0x31B8, 0x31B9, - /* GB+81 39 B7 30 */ 0x31BA, 0x31BB, 0x31BC, 0x31BD, 0x31BE, - /* GB+81 39 B7 35 */ 0x31BF, 0x31C0, 0x31C1, 0x31C2, 0x31C3, - /* GB+81 39 B8 30 */ 0x31C4, 0x31C5, 0x31C6, 0x31C7, 0x31C8, - /* GB+81 39 B8 35 */ 0x31C9, 0x31CA, 0x31CB, 0x31CC, 0x31CD, - /* GB+81 39 B9 30 */ 0x31CE, 0x31CF, 0x31D0, 0x31D1, 0x31D2, - /* GB+81 39 B9 35 */ 0x31D3, 0x31D4, 0x31D5, 0x31D6, 0x31D7, - /* GB+81 39 BA 30 */ 0x31D8, 0x31D9, 0x31DA, 0x31DB, 0x31DC, - /* GB+81 39 BA 35 */ 0x31DD, 0x31DE, 0x31DF, 0x31E0, 0x31E1, - /* GB+81 39 BB 30 */ 0x31E2, 0x31E3, 0x31E4, 0x31E5, 0x31E6, - /* GB+81 39 BB 35 */ 0x31E7, 0x31E8, 0x31E9, 0x31EA, 0x31EB, - /* GB+81 39 BC 30 */ 0x31EC, 0x31ED, 0x31EE, 0x31EF, 0x31F0, - /* GB+81 39 BC 35 */ 0x31F1, 0x31F2, 0x31F3, 0x31F4, 0x31F5, - /* GB+81 39 BD 30 */ 0x31F6, 0x31F7, 0x31F8, 0x31F9, 0x31FA, - /* GB+81 39 BD 35 */ 0x31FB, 0x31FC, 0x31FD, 0x31FE, 0x31FF, - /* GB+81 39 BE 30 */ 0x3200, 0x3201, 0x3202, 0x3203, 0x3204, - /* GB+81 39 BE 35 */ 0x3205, 0x3206, 0x3207, 0x3208, 0x3209, - /* GB+81 39 BF 30 */ 0x320A, 0x320B, 0x320C, 0x320D, 0x320E, - /* GB+81 39 BF 35 */ 0x320F, 0x3210, 0x3211, 0x3212, 0x3213, - /* GB+81 39 C0 30 */ 0x3214, 0x3215, 0x3216, 0x3217, 0x3218, - /* GB+81 39 C0 35 */ 0x3219, 0x321A, 0x321B, 0x321C, 0x321D, - /* GB+81 39 C1 30 */ 0x321E, 0x321F, 0x322A, 0x322B, 0x322C, - /* GB+81 39 C1 35 */ 0x322D, 0x322E, 0x322F, 0x3230, 0x3232, - /* GB+81 39 C2 30 */ 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, - /* GB+81 39 C2 35 */ 0x3238, 0x3239, 0x323A, 0x323B, 0x323C, - /* GB+81 39 C3 30 */ 0x323D, 0x323E, 0x323F, 0x3240, 0x3241, - /* GB+81 39 C3 35 */ 0x3242, 0x3243, 0x3244, 0x3245, 0x3246, - /* GB+81 39 C4 30 */ 0x3247, 0x3248, 0x3249, 0x324A, 0x324B, - /* GB+81 39 C4 35 */ 0x324C, 0x324D, 0x324E, 0x324F, 0x3250, - /* GB+81 39 C5 30 */ 0x3251, 0x3252, 0x3253, 0x3254, 0x3255, - /* GB+81 39 C5 35 */ 0x3256, 0x3257, 0x3258, 0x3259, 0x325A, - /* GB+81 39 C6 30 */ 0x325B, 0x325C, 0x325D, 0x325E, 0x325F, - /* GB+81 39 C6 35 */ 0x3260, 0x3261, 0x3262, 0x3263, 0x3264, - /* GB+81 39 C7 30 */ 0x3265, 0x3266, 0x3267, 0x3268, 0x3269, - /* GB+81 39 C7 35 */ 0x326A, 0x326B, 0x326C, 0x326D, 0x326E, - /* GB+81 39 C8 30 */ 0x326F, 0x3270, 0x3271, 0x3272, 0x3273, - /* GB+81 39 C8 35 */ 0x3274, 0x3275, 0x3276, 0x3277, 0x3278, - /* GB+81 39 C9 30 */ 0x3279, 0x327A, 0x327B, 0x327C, 0x327D, - /* GB+81 39 C9 35 */ 0x327E, 0x327F, 0x3280, 0x3281, 0x3282, - /* GB+81 39 CA 30 */ 0x3283, 0x3284, 0x3285, 0x3286, 0x3287, - /* GB+81 39 CA 35 */ 0x3288, 0x3289, 0x328A, 0x328B, 0x328C, - /* GB+81 39 CB 30 */ 0x328D, 0x328E, 0x328F, 0x3290, 0x3291, - /* GB+81 39 CB 35 */ 0x3292, 0x3293, 0x3294, 0x3295, 0x3296, - /* GB+81 39 CC 30 */ 0x3297, 0x3298, 0x3299, 0x329A, 0x329B, - /* GB+81 39 CC 35 */ 0x329C, 0x329D, 0x329E, 0x329F, 0x32A0, - /* GB+81 39 CD 30 */ 0x32A1, 0x32A2, 0x32A4, 0x32A5, 0x32A6, - /* GB+81 39 CD 35 */ 0x32A7, 0x32A8, 0x32A9, 0x32AA, 0x32AB, - /* GB+81 39 CE 30 */ 0x32AC, 0x32AD, 0x32AE, 0x32AF, 0x32B0, - /* GB+81 39 CE 35 */ 0x32B1, 0x32B2, 0x32B3, 0x32B4, 0x32B5, - /* GB+81 39 CF 30 */ 0x32B6, 0x32B7, 0x32B8, 0x32B9, 0x32BA, - /* GB+81 39 CF 35 */ 0x32BB, 0x32BC, 0x32BD, 0x32BE, 0x32BF, - /* GB+81 39 D0 30 */ 0x32C0, 0x32C1, 0x32C2, 0x32C3, 0x32C4, - /* GB+81 39 D0 35 */ 0x32C5, 0x32C6, 0x32C7, 0x32C8, 0x32C9, - /* GB+81 39 D1 30 */ 0x32CA, 0x32CB, 0x32CC, 0x32CD, 0x32CE, - /* GB+81 39 D1 35 */ 0x32CF, 0x32D0, 0x32D1, 0x32D2, 0x32D3, - /* GB+81 39 D2 30 */ 0x32D4, 0x32D5, 0x32D6, 0x32D7, 0x32D8, - /* GB+81 39 D2 35 */ 0x32D9, 0x32DA, 0x32DB, 0x32DC, 0x32DD, - /* GB+81 39 D3 30 */ 0x32DE, 0x32DF, 0x32E0, 0x32E1, 0x32E2, - /* GB+81 39 D3 35 */ 0x32E3, 0x32E4, 0x32E5, 0x32E6, 0x32E7, - /* GB+81 39 D4 30 */ 0x32E8, 0x32E9, 0x32EA, 0x32EB, 0x32EC, - /* GB+81 39 D4 35 */ 0x32ED, 0x32EE, 0x32EF, 0x32F0, 0x32F1, - /* GB+81 39 D5 30 */ 0x32F2, 0x32F3, 0x32F4, 0x32F5, 0x32F6, - /* GB+81 39 D5 35 */ 0x32F7, 0x32F8, 0x32F9, 0x32FA, 0x32FB, - /* GB+81 39 D6 30 */ 0x32FC, 0x32FD, 0x32FE, 0x32FF, 0x3300, - /* GB+81 39 D6 35 */ 0x3301, 0x3302, 0x3303, 0x3304, 0x3305, - /* GB+81 39 D7 30 */ 0x3306, 0x3307, 0x3308, 0x3309, 0x330A, - /* GB+81 39 D7 35 */ 0x330B, 0x330C, 0x330D, 0x330E, 0x330F, - /* GB+81 39 D8 30 */ 0x3310, 0x3311, 0x3312, 0x3313, 0x3314, - /* GB+81 39 D8 35 */ 0x3315, 0x3316, 0x3317, 0x3318, 0x3319, - /* GB+81 39 D9 30 */ 0x331A, 0x331B, 0x331C, 0x331D, 0x331E, - /* GB+81 39 D9 35 */ 0x331F, 0x3320, 0x3321, 0x3322, 0x3323, - /* GB+81 39 DA 30 */ 0x3324, 0x3325, 0x3326, 0x3327, 0x3328, - /* GB+81 39 DA 35 */ 0x3329, 0x332A, 0x332B, 0x332C, 0x332D, - /* GB+81 39 DB 30 */ 0x332E, 0x332F, 0x3330, 0x3331, 0x3332, - /* GB+81 39 DB 35 */ 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, - /* GB+81 39 DC 30 */ 0x3338, 0x3339, 0x333A, 0x333B, 0x333C, - /* GB+81 39 DC 35 */ 0x333D, 0x333E, 0x333F, 0x3340, 0x3341, - /* GB+81 39 DD 30 */ 0x3342, 0x3343, 0x3344, 0x3345, 0x3346, - /* GB+81 39 DD 35 */ 0x3347, 0x3348, 0x3349, 0x334A, 0x334B, - /* GB+81 39 DE 30 */ 0x334C, 0x334D, 0x334E, 0x334F, 0x3350, - /* GB+81 39 DE 35 */ 0x3351, 0x3352, 0x3353, 0x3354, 0x3355, - /* GB+81 39 DF 30 */ 0x3356, 0x3357, 0x3358, 0x3359, 0x335A, - /* GB+81 39 DF 35 */ 0x335B, 0x335C, 0x335D, 0x335E, 0x335F, - /* GB+81 39 E0 30 */ 0x3360, 0x3361, 0x3362, 0x3363, 0x3364, - /* GB+81 39 E0 35 */ 0x3365, 0x3366, 0x3367, 0x3368, 0x3369, - /* GB+81 39 E1 30 */ 0x336A, 0x336B, 0x336C, 0x336D, 0x336E, - /* GB+81 39 E1 35 */ 0x336F, 0x3370, 0x3371, 0x3372, 0x3373, - /* GB+81 39 E2 30 */ 0x3374, 0x3375, 0x3376, 0x3377, 0x3378, - /* GB+81 39 E2 35 */ 0x3379, 0x337A, 0x337B, 0x337C, 0x337D, - /* GB+81 39 E3 30 */ 0x337E, 0x337F, 0x3380, 0x3381, 0x3382, - /* GB+81 39 E3 35 */ 0x3383, 0x3384, 0x3385, 0x3386, 0x3387, - /* GB+81 39 E4 30 */ 0x3388, 0x3389, 0x338A, 0x338B, 0x338C, - /* GB+81 39 E4 35 */ 0x338D, 0x3390, 0x3391, 0x3392, 0x3393, - /* GB+81 39 E5 30 */ 0x3394, 0x3395, 0x3396, 0x3397, 0x3398, - /* GB+81 39 E5 35 */ 0x3399, 0x339A, 0x339B, 0x339F, 0x33A0, - /* GB+81 39 E6 30 */ 0x33A2, 0x33A3, 0x33A4, 0x33A5, 0x33A6, - /* GB+81 39 E6 35 */ 0x33A7, 0x33A8, 0x33A9, 0x33AA, 0x33AB, - /* GB+81 39 E7 30 */ 0x33AC, 0x33AD, 0x33AE, 0x33AF, 0x33B0, - /* GB+81 39 E7 35 */ 0x33B1, 0x33B2, 0x33B3, 0x33B4, 0x33B5, - /* GB+81 39 E8 30 */ 0x33B6, 0x33B7, 0x33B8, 0x33B9, 0x33BA, - /* GB+81 39 E8 35 */ 0x33BB, 0x33BC, 0x33BD, 0x33BE, 0x33BF, - /* GB+81 39 E9 30 */ 0x33C0, 0x33C1, 0x33C2, 0x33C3, 0x33C5, - /* GB+81 39 E9 35 */ 0x33C6, 0x33C7, 0x33C8, 0x33C9, 0x33CA, - /* GB+81 39 EA 30 */ 0x33CB, 0x33CC, 0x33CD, 0x33CF, 0x33D0, - /* GB+81 39 EA 35 */ 0x33D3, 0x33D4, 0x33D6, 0x33D7, 0x33D8, - /* GB+81 39 EB 30 */ 0x33D9, 0x33DA, 0x33DB, 0x33DC, 0x33DD, - /* GB+81 39 EB 35 */ 0x33DE, 0x33DF, 0x33E0, 0x33E1, 0x33E2, - /* GB+81 39 EC 30 */ 0x33E3, 0x33E4, 0x33E5, 0x33E6, 0x33E7, - /* GB+81 39 EC 35 */ 0x33E8, 0x33E9, 0x33EA, 0x33EB, 0x33EC, - /* GB+81 39 ED 30 */ 0x33ED, 0x33EE, 0x33EF, 0x33F0, 0x33F1, - /* GB+81 39 ED 35 */ 0x33F2, 0x33F3, 0x33F4, 0x33F5, 0x33F6, - /* GB+81 39 EE 30 */ 0x33F7, 0x33F8, 0x33F9, 0x33FA, 0x33FB, - /* GB+81 39 EE 35 */ 0x33FC, 0x33FD, 0x33FE, 0x33FF, 0x3400, - /* GB+81 39 EF 30 */ 0x3401, 0x3402, 0x3403, 0x3404, 0x3405, - /* GB+81 39 EF 35 */ 0x3406, 0x3407, 0x3408, 0x3409, 0x340A, - /* GB+81 39 F0 30 */ 0x340B, 0x340C, 0x340D, 0x340E, 0x340F, - /* GB+81 39 F0 35 */ 0x3410, 0x3411, 0x3412, 0x3413, 0x3414, - /* GB+81 39 F1 30 */ 0x3415, 0x3416, 0x3417, 0x3418, 0x3419, - /* GB+81 39 F1 35 */ 0x341A, 0x341B, 0x341C, 0x341D, 0x341E, - /* GB+81 39 F2 30 */ 0x341F, 0x3420, 0x3421, 0x3422, 0x3423, - /* GB+81 39 F2 35 */ 0x3424, 0x3425, 0x3426, 0x3427, 0x3428, - /* GB+81 39 F3 30 */ 0x3429, 0x342A, 0x342B, 0x342C, 0x342D, - /* GB+81 39 F3 35 */ 0x342E, 0x342F, 0x3430, 0x3431, 0x3432, - /* GB+81 39 F4 30 */ 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, - /* GB+81 39 F4 35 */ 0x3438, 0x3439, 0x343A, 0x343B, 0x343C, - /* GB+81 39 F5 30 */ 0x343D, 0x343E, 0x343F, 0x3440, 0x3441, - /* GB+81 39 F5 35 */ 0x3442, 0x3443, 0x3444, 0x3445, 0x3446, - /* GB+81 39 F6 30 */ 0x3448, 0x3449, 0x344A, 0x344B, 0x344C, - /* GB+81 39 F6 35 */ 0x344D, 0x344E, 0x344F, 0x3450, 0x3451, - /* GB+81 39 F7 30 */ 0x3452, 0x3453, 0x3454, 0x3455, 0x3456, - /* GB+81 39 F7 35 */ 0x3457, 0x3458, 0x3459, 0x345A, 0x345B, - /* GB+81 39 F8 30 */ 0x345C, 0x345D, 0x345E, 0x345F, 0x3460, - /* GB+81 39 F8 35 */ 0x3461, 0x3462, 0x3463, 0x3464, 0x3465, - /* GB+81 39 F9 30 */ 0x3466, 0x3467, 0x3468, 0x3469, 0x346A, - /* GB+81 39 F9 35 */ 0x346B, 0x346C, 0x346D, 0x346E, 0x346F, - /* GB+81 39 FA 30 */ 0x3470, 0x3471, 0x3472, 0x3474, 0x3475, - /* GB+81 39 FA 35 */ 0x3476, 0x3477, 0x3478, 0x3479, 0x347A, - /* GB+81 39 FB 30 */ 0x347B, 0x347C, 0x347D, 0x347E, 0x347F, - /* GB+81 39 FB 35 */ 0x3480, 0x3481, 0x3482, 0x3483, 0x3484, - /* GB+81 39 FC 30 */ 0x3485, 0x3486, 0x3487, 0x3488, 0x3489, - /* GB+81 39 FC 35 */ 0x348A, 0x348B, 0x348C, 0x348D, 0x348E, - /* GB+81 39 FD 30 */ 0x348F, 0x3490, 0x3491, 0x3492, 0x3493, - /* GB+81 39 FD 35 */ 0x3494, 0x3495, 0x3496, 0x3497, 0x3498, - /* GB+81 39 FE 30 */ 0x3499, 0x349A, 0x349B, 0x349C, 0x349D, - /* GB+81 39 FE 35 */ 0x349E, 0x349F, 0x34A0, 0x34A1, 0x34A2, - /* GB+82 30 81 30 */ 0x34A3, 0x34A4, 0x34A5, 0x34A6, 0x34A7, - /* GB+82 30 81 35 */ 0x34A8, 0x34A9, 0x34AA, 0x34AB, 0x34AC, - /* GB+82 30 82 30 */ 0x34AD, 0x34AE, 0x34AF, 0x34B0, 0x34B1, - /* GB+82 30 82 35 */ 0x34B2, 0x34B3, 0x34B4, 0x34B5, 0x34B6, - /* GB+82 30 83 30 */ 0x34B7, 0x34B8, 0x34B9, 0x34BA, 0x34BB, - /* GB+82 30 83 35 */ 0x34BC, 0x34BD, 0x34BE, 0x34BF, 0x34C0, - /* GB+82 30 84 30 */ 0x34C1, 0x34C2, 0x34C3, 0x34C4, 0x34C5, - /* GB+82 30 84 35 */ 0x34C6, 0x34C7, 0x34C8, 0x34C9, 0x34CA, - /* GB+82 30 85 30 */ 0x34CB, 0x34CC, 0x34CD, 0x34CE, 0x34CF, - /* GB+82 30 85 35 */ 0x34D0, 0x34D1, 0x34D2, 0x34D3, 0x34D4, - /* GB+82 30 86 30 */ 0x34D5, 0x34D6, 0x34D7, 0x34D8, 0x34D9, - /* GB+82 30 86 35 */ 0x34DA, 0x34DB, 0x34DC, 0x34DD, 0x34DE, - /* GB+82 30 87 30 */ 0x34DF, 0x34E0, 0x34E1, 0x34E2, 0x34E3, - /* GB+82 30 87 35 */ 0x34E4, 0x34E5, 0x34E6, 0x34E7, 0x34E8, - /* GB+82 30 88 30 */ 0x34E9, 0x34EA, 0x34EB, 0x34EC, 0x34ED, - /* GB+82 30 88 35 */ 0x34EE, 0x34EF, 0x34F0, 0x34F1, 0x34F2, - /* GB+82 30 89 30 */ 0x34F3, 0x34F4, 0x34F5, 0x34F6, 0x34F7, - /* GB+82 30 89 35 */ 0x34F8, 0x34F9, 0x34FA, 0x34FB, 0x34FC, - /* GB+82 30 8A 30 */ 0x34FD, 0x34FE, 0x34FF, 0x3500, 0x3501, - /* GB+82 30 8A 35 */ 0x3502, 0x3503, 0x3504, 0x3505, 0x3506, - /* GB+82 30 8B 30 */ 0x3507, 0x3508, 0x3509, 0x350A, 0x350B, - /* GB+82 30 8B 35 */ 0x350C, 0x350D, 0x350E, 0x350F, 0x3510, - /* GB+82 30 8C 30 */ 0x3511, 0x3512, 0x3513, 0x3514, 0x3515, - /* GB+82 30 8C 35 */ 0x3516, 0x3517, 0x3518, 0x3519, 0x351A, - /* GB+82 30 8D 30 */ 0x351B, 0x351C, 0x351D, 0x351E, 0x351F, - /* GB+82 30 8D 35 */ 0x3520, 0x3521, 0x3522, 0x3523, 0x3524, - /* GB+82 30 8E 30 */ 0x3525, 0x3526, 0x3527, 0x3528, 0x3529, - /* GB+82 30 8E 35 */ 0x352A, 0x352B, 0x352C, 0x352D, 0x352E, - /* GB+82 30 8F 30 */ 0x352F, 0x3530, 0x3531, 0x3532, 0x3533, - /* GB+82 30 8F 35 */ 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, - /* GB+82 30 90 30 */ 0x3539, 0x353A, 0x353B, 0x353C, 0x353D, - /* GB+82 30 90 35 */ 0x353E, 0x353F, 0x3540, 0x3541, 0x3542, - /* GB+82 30 91 30 */ 0x3543, 0x3544, 0x3545, 0x3546, 0x3547, - /* GB+82 30 91 35 */ 0x3548, 0x3549, 0x354A, 0x354B, 0x354C, - /* GB+82 30 92 30 */ 0x354D, 0x354E, 0x354F, 0x3550, 0x3551, - /* GB+82 30 92 35 */ 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, - /* GB+82 30 93 30 */ 0x3557, 0x3558, 0x3559, 0x355A, 0x355B, - /* GB+82 30 93 35 */ 0x355C, 0x355D, 0x355E, 0x355F, 0x3560, - /* GB+82 30 94 30 */ 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, - /* GB+82 30 94 35 */ 0x3566, 0x3567, 0x3568, 0x3569, 0x356A, - /* GB+82 30 95 30 */ 0x356B, 0x356C, 0x356D, 0x356E, 0x356F, - /* GB+82 30 95 35 */ 0x3570, 0x3571, 0x3572, 0x3573, 0x3574, - /* GB+82 30 96 30 */ 0x3575, 0x3576, 0x3577, 0x3578, 0x3579, - /* GB+82 30 96 35 */ 0x357A, 0x357B, 0x357C, 0x357D, 0x357E, - /* GB+82 30 97 30 */ 0x357F, 0x3580, 0x3581, 0x3582, 0x3583, - /* GB+82 30 97 35 */ 0x3584, 0x3585, 0x3586, 0x3587, 0x3588, - /* GB+82 30 98 30 */ 0x3589, 0x358A, 0x358B, 0x358C, 0x358D, - /* GB+82 30 98 35 */ 0x358E, 0x358F, 0x3590, 0x3591, 0x3592, - /* GB+82 30 99 30 */ 0x3593, 0x3594, 0x3595, 0x3596, 0x3597, - /* GB+82 30 99 35 */ 0x3598, 0x3599, 0x359A, 0x359B, 0x359C, - /* GB+82 30 9A 30 */ 0x359D, 0x359F, 0x35A0, 0x35A1, 0x35A2, - /* GB+82 30 9A 35 */ 0x35A3, 0x35A4, 0x35A5, 0x35A6, 0x35A7, - /* GB+82 30 9B 30 */ 0x35A8, 0x35A9, 0x35AA, 0x35AB, 0x35AC, - /* GB+82 30 9B 35 */ 0x35AD, 0x35AE, 0x35AF, 0x35B0, 0x35B1, - /* GB+82 30 9C 30 */ 0x35B2, 0x35B3, 0x35B4, 0x35B5, 0x35B6, - /* GB+82 30 9C 35 */ 0x35B7, 0x35B8, 0x35B9, 0x35BA, 0x35BB, - /* GB+82 30 9D 30 */ 0x35BC, 0x35BD, 0x35BE, 0x35BF, 0x35C0, - /* GB+82 30 9D 35 */ 0x35C1, 0x35C2, 0x35C3, 0x35C4, 0x35C5, - /* GB+82 30 9E 30 */ 0x35C6, 0x35C7, 0x35C8, 0x35C9, 0x35CA, - /* GB+82 30 9E 35 */ 0x35CB, 0x35CC, 0x35CD, 0x35CE, 0x35CF, - /* GB+82 30 9F 30 */ 0x35D0, 0x35D1, 0x35D2, 0x35D3, 0x35D4, - /* GB+82 30 9F 35 */ 0x35D5, 0x35D6, 0x35D7, 0x35D8, 0x35D9, - /* GB+82 30 A0 30 */ 0x35DA, 0x35DB, 0x35DC, 0x35DD, 0x35DE, - /* GB+82 30 A0 35 */ 0x35DF, 0x35E0, 0x35E1, 0x35E2, 0x35E3, - /* GB+82 30 A1 30 */ 0x35E4, 0x35E5, 0x35E6, 0x35E7, 0x35E8, - /* GB+82 30 A1 35 */ 0x35E9, 0x35EA, 0x35EB, 0x35EC, 0x35ED, - /* GB+82 30 A2 30 */ 0x35EE, 0x35EF, 0x35F0, 0x35F1, 0x35F2, - /* GB+82 30 A2 35 */ 0x35F3, 0x35F4, 0x35F5, 0x35F6, 0x35F7, - /* GB+82 30 A3 30 */ 0x35F8, 0x35F9, 0x35FA, 0x35FB, 0x35FC, - /* GB+82 30 A3 35 */ 0x35FD, 0x35FE, 0x35FF, 0x3600, 0x3601, - /* GB+82 30 A4 30 */ 0x3602, 0x3603, 0x3604, 0x3605, 0x3606, - /* GB+82 30 A4 35 */ 0x3607, 0x3608, 0x3609, 0x360A, 0x360B, - /* GB+82 30 A5 30 */ 0x360C, 0x360D, 0x360F, 0x3610, 0x3611, - /* GB+82 30 A5 35 */ 0x3612, 0x3613, 0x3614, 0x3615, 0x3616, - /* GB+82 30 A6 30 */ 0x3617, 0x3618, 0x3619, - /* Contiguous area: GB+82 30 F2 38 .. GB+82 31 D4 37 */ - /* GB+82 30 F2 38 */ 0x3919, 0x391A, - /* GB+82 30 F3 30 */ 0x391B, 0x391C, 0x391D, 0x391E, 0x391F, - /* GB+82 30 F3 35 */ 0x3920, 0x3921, 0x3922, 0x3923, 0x3924, - /* GB+82 30 F4 30 */ 0x3925, 0x3926, 0x3927, 0x3928, 0x3929, - /* GB+82 30 F4 35 */ 0x392A, 0x392B, 0x392C, 0x392D, 0x392E, - /* GB+82 30 F5 30 */ 0x392F, 0x3930, 0x3931, 0x3932, 0x3933, - /* GB+82 30 F5 35 */ 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, - /* GB+82 30 F6 30 */ 0x3939, 0x393A, 0x393B, 0x393C, 0x393D, - /* GB+82 30 F6 35 */ 0x393E, 0x393F, 0x3940, 0x3941, 0x3942, - /* GB+82 30 F7 30 */ 0x3943, 0x3944, 0x3945, 0x3946, 0x3947, - /* GB+82 30 F7 35 */ 0x3948, 0x3949, 0x394A, 0x394B, 0x394C, - /* GB+82 30 F8 30 */ 0x394D, 0x394E, 0x394F, 0x3950, 0x3951, - /* GB+82 30 F8 35 */ 0x3952, 0x3953, 0x3954, 0x3955, 0x3956, - /* GB+82 30 F9 30 */ 0x3957, 0x3958, 0x3959, 0x395A, 0x395B, - /* GB+82 30 F9 35 */ 0x395C, 0x395D, 0x395E, 0x395F, 0x3960, - /* GB+82 30 FA 30 */ 0x3961, 0x3962, 0x3963, 0x3964, 0x3965, - /* GB+82 30 FA 35 */ 0x3966, 0x3967, 0x3968, 0x3969, 0x396A, - /* GB+82 30 FB 30 */ 0x396B, 0x396C, 0x396D, 0x396F, 0x3970, - /* GB+82 30 FB 35 */ 0x3971, 0x3972, 0x3973, 0x3974, 0x3975, - /* GB+82 30 FC 30 */ 0x3976, 0x3977, 0x3978, 0x3979, 0x397A, - /* GB+82 30 FC 35 */ 0x397B, 0x397C, 0x397D, 0x397E, 0x397F, - /* GB+82 30 FD 30 */ 0x3980, 0x3981, 0x3982, 0x3983, 0x3984, - /* GB+82 30 FD 35 */ 0x3985, 0x3986, 0x3987, 0x3988, 0x3989, - /* GB+82 30 FE 30 */ 0x398A, 0x398B, 0x398C, 0x398D, 0x398E, - /* GB+82 30 FE 35 */ 0x398F, 0x3990, 0x3991, 0x3992, 0x3993, - /* GB+82 31 81 30 */ 0x3994, 0x3995, 0x3996, 0x3997, 0x3998, - /* GB+82 31 81 35 */ 0x3999, 0x399A, 0x399B, 0x399C, 0x399D, - /* GB+82 31 82 30 */ 0x399E, 0x399F, 0x39A0, 0x39A1, 0x39A2, - /* GB+82 31 82 35 */ 0x39A3, 0x39A4, 0x39A5, 0x39A6, 0x39A7, - /* GB+82 31 83 30 */ 0x39A8, 0x39A9, 0x39AA, 0x39AB, 0x39AC, - /* GB+82 31 83 35 */ 0x39AD, 0x39AE, 0x39AF, 0x39B0, 0x39B1, - /* GB+82 31 84 30 */ 0x39B2, 0x39B3, 0x39B4, 0x39B5, 0x39B6, - /* GB+82 31 84 35 */ 0x39B7, 0x39B8, 0x39B9, 0x39BA, 0x39BB, - /* GB+82 31 85 30 */ 0x39BC, 0x39BD, 0x39BE, 0x39BF, 0x39C0, - /* GB+82 31 85 35 */ 0x39C1, 0x39C2, 0x39C3, 0x39C4, 0x39C5, - /* GB+82 31 86 30 */ 0x39C6, 0x39C7, 0x39C8, 0x39C9, 0x39CA, - /* GB+82 31 86 35 */ 0x39CB, 0x39CC, 0x39CD, 0x39CE, 0x39D1, - /* GB+82 31 87 30 */ 0x39D2, 0x39D3, 0x39D4, 0x39D5, 0x39D6, - /* GB+82 31 87 35 */ 0x39D7, 0x39D8, 0x39D9, 0x39DA, 0x39DB, - /* GB+82 31 88 30 */ 0x39DC, 0x39DD, 0x39DE, 0x39E0, 0x39E1, - /* GB+82 31 88 35 */ 0x39E2, 0x39E3, 0x39E4, 0x39E5, 0x39E6, - /* GB+82 31 89 30 */ 0x39E7, 0x39E8, 0x39E9, 0x39EA, 0x39EB, - /* GB+82 31 89 35 */ 0x39EC, 0x39ED, 0x39EE, 0x39EF, 0x39F0, - /* GB+82 31 8A 30 */ 0x39F1, 0x39F2, 0x39F3, 0x39F4, 0x39F5, - /* GB+82 31 8A 35 */ 0x39F6, 0x39F7, 0x39F8, 0x39F9, 0x39FA, - /* GB+82 31 8B 30 */ 0x39FB, 0x39FC, 0x39FD, 0x39FE, 0x39FF, - /* GB+82 31 8B 35 */ 0x3A00, 0x3A01, 0x3A02, 0x3A03, 0x3A04, - /* GB+82 31 8C 30 */ 0x3A05, 0x3A06, 0x3A07, 0x3A08, 0x3A09, - /* GB+82 31 8C 35 */ 0x3A0A, 0x3A0B, 0x3A0C, 0x3A0D, 0x3A0E, - /* GB+82 31 8D 30 */ 0x3A0F, 0x3A10, 0x3A11, 0x3A12, 0x3A13, - /* GB+82 31 8D 35 */ 0x3A14, 0x3A15, 0x3A16, 0x3A17, 0x3A18, - /* GB+82 31 8E 30 */ 0x3A19, 0x3A1A, 0x3A1B, 0x3A1C, 0x3A1D, - /* GB+82 31 8E 35 */ 0x3A1E, 0x3A1F, 0x3A20, 0x3A21, 0x3A22, - /* GB+82 31 8F 30 */ 0x3A23, 0x3A24, 0x3A25, 0x3A26, 0x3A27, - /* GB+82 31 8F 35 */ 0x3A28, 0x3A29, 0x3A2A, 0x3A2B, 0x3A2C, - /* GB+82 31 90 30 */ 0x3A2D, 0x3A2E, 0x3A2F, 0x3A30, 0x3A31, - /* GB+82 31 90 35 */ 0x3A32, 0x3A33, 0x3A34, 0x3A35, 0x3A36, - /* GB+82 31 91 30 */ 0x3A37, 0x3A38, 0x3A39, 0x3A3A, 0x3A3B, - /* GB+82 31 91 35 */ 0x3A3C, 0x3A3D, 0x3A3E, 0x3A3F, 0x3A40, - /* GB+82 31 92 30 */ 0x3A41, 0x3A42, 0x3A43, 0x3A44, 0x3A45, - /* GB+82 31 92 35 */ 0x3A46, 0x3A47, 0x3A48, 0x3A49, 0x3A4A, - /* GB+82 31 93 30 */ 0x3A4B, 0x3A4C, 0x3A4D, 0x3A4E, 0x3A4F, - /* GB+82 31 93 35 */ 0x3A50, 0x3A51, 0x3A52, 0x3A53, 0x3A54, - /* GB+82 31 94 30 */ 0x3A55, 0x3A56, 0x3A57, 0x3A58, 0x3A59, - /* GB+82 31 94 35 */ 0x3A5A, 0x3A5B, 0x3A5C, 0x3A5D, 0x3A5E, - /* GB+82 31 95 30 */ 0x3A5F, 0x3A60, 0x3A61, 0x3A62, 0x3A63, - /* GB+82 31 95 35 */ 0x3A64, 0x3A65, 0x3A66, 0x3A67, 0x3A68, - /* GB+82 31 96 30 */ 0x3A69, 0x3A6A, 0x3A6B, 0x3A6C, 0x3A6D, - /* GB+82 31 96 35 */ 0x3A6E, 0x3A6F, 0x3A70, 0x3A71, 0x3A72, - /* GB+82 31 97 30 */ 0x3A74, 0x3A75, 0x3A76, 0x3A77, 0x3A78, - /* GB+82 31 97 35 */ 0x3A79, 0x3A7A, 0x3A7B, 0x3A7C, 0x3A7D, - /* GB+82 31 98 30 */ 0x3A7E, 0x3A7F, 0x3A80, 0x3A81, 0x3A82, - /* GB+82 31 98 35 */ 0x3A83, 0x3A84, 0x3A85, 0x3A86, 0x3A87, - /* GB+82 31 99 30 */ 0x3A88, 0x3A89, 0x3A8A, 0x3A8B, 0x3A8C, - /* GB+82 31 99 35 */ 0x3A8D, 0x3A8E, 0x3A8F, 0x3A90, 0x3A91, - /* GB+82 31 9A 30 */ 0x3A92, 0x3A93, 0x3A94, 0x3A95, 0x3A96, - /* GB+82 31 9A 35 */ 0x3A97, 0x3A98, 0x3A99, 0x3A9A, 0x3A9B, - /* GB+82 31 9B 30 */ 0x3A9C, 0x3A9D, 0x3A9E, 0x3A9F, 0x3AA0, - /* GB+82 31 9B 35 */ 0x3AA1, 0x3AA2, 0x3AA3, 0x3AA4, 0x3AA5, - /* GB+82 31 9C 30 */ 0x3AA6, 0x3AA7, 0x3AA8, 0x3AA9, 0x3AAA, - /* GB+82 31 9C 35 */ 0x3AAB, 0x3AAC, 0x3AAD, 0x3AAE, 0x3AAF, - /* GB+82 31 9D 30 */ 0x3AB0, 0x3AB1, 0x3AB2, 0x3AB3, 0x3AB4, - /* GB+82 31 9D 35 */ 0x3AB5, 0x3AB6, 0x3AB7, 0x3AB8, 0x3AB9, - /* GB+82 31 9E 30 */ 0x3ABA, 0x3ABB, 0x3ABC, 0x3ABD, 0x3ABE, - /* GB+82 31 9E 35 */ 0x3ABF, 0x3AC0, 0x3AC1, 0x3AC2, 0x3AC3, - /* GB+82 31 9F 30 */ 0x3AC4, 0x3AC5, 0x3AC6, 0x3AC7, 0x3AC8, - /* GB+82 31 9F 35 */ 0x3AC9, 0x3ACA, 0x3ACB, 0x3ACC, 0x3ACD, - /* GB+82 31 A0 30 */ 0x3ACE, 0x3ACF, 0x3AD0, 0x3AD1, 0x3AD2, - /* GB+82 31 A0 35 */ 0x3AD3, 0x3AD4, 0x3AD5, 0x3AD6, 0x3AD7, - /* GB+82 31 A1 30 */ 0x3AD8, 0x3AD9, 0x3ADA, 0x3ADB, 0x3ADC, - /* GB+82 31 A1 35 */ 0x3ADD, 0x3ADE, 0x3ADF, 0x3AE0, 0x3AE1, - /* GB+82 31 A2 30 */ 0x3AE2, 0x3AE3, 0x3AE4, 0x3AE5, 0x3AE6, - /* GB+82 31 A2 35 */ 0x3AE7, 0x3AE8, 0x3AE9, 0x3AEA, 0x3AEB, - /* GB+82 31 A3 30 */ 0x3AEC, 0x3AED, 0x3AEE, 0x3AEF, 0x3AF0, - /* GB+82 31 A3 35 */ 0x3AF1, 0x3AF2, 0x3AF3, 0x3AF4, 0x3AF5, - /* GB+82 31 A4 30 */ 0x3AF6, 0x3AF7, 0x3AF8, 0x3AF9, 0x3AFA, - /* GB+82 31 A4 35 */ 0x3AFB, 0x3AFC, 0x3AFD, 0x3AFE, 0x3AFF, - /* GB+82 31 A5 30 */ 0x3B00, 0x3B01, 0x3B02, 0x3B03, 0x3B04, - /* GB+82 31 A5 35 */ 0x3B05, 0x3B06, 0x3B07, 0x3B08, 0x3B09, - /* GB+82 31 A6 30 */ 0x3B0A, 0x3B0B, 0x3B0C, 0x3B0D, 0x3B0E, - /* GB+82 31 A6 35 */ 0x3B0F, 0x3B10, 0x3B11, 0x3B12, 0x3B13, - /* GB+82 31 A7 30 */ 0x3B14, 0x3B15, 0x3B16, 0x3B17, 0x3B18, - /* GB+82 31 A7 35 */ 0x3B19, 0x3B1A, 0x3B1B, 0x3B1C, 0x3B1D, - /* GB+82 31 A8 30 */ 0x3B1E, 0x3B1F, 0x3B20, 0x3B21, 0x3B22, - /* GB+82 31 A8 35 */ 0x3B23, 0x3B24, 0x3B25, 0x3B26, 0x3B27, - /* GB+82 31 A9 30 */ 0x3B28, 0x3B29, 0x3B2A, 0x3B2B, 0x3B2C, - /* GB+82 31 A9 35 */ 0x3B2D, 0x3B2E, 0x3B2F, 0x3B30, 0x3B31, - /* GB+82 31 AA 30 */ 0x3B32, 0x3B33, 0x3B34, 0x3B35, 0x3B36, - /* GB+82 31 AA 35 */ 0x3B37, 0x3B38, 0x3B39, 0x3B3A, 0x3B3B, - /* GB+82 31 AB 30 */ 0x3B3C, 0x3B3D, 0x3B3E, 0x3B3F, 0x3B40, - /* GB+82 31 AB 35 */ 0x3B41, 0x3B42, 0x3B43, 0x3B44, 0x3B45, - /* GB+82 31 AC 30 */ 0x3B46, 0x3B47, 0x3B48, 0x3B49, 0x3B4A, - /* GB+82 31 AC 35 */ 0x3B4B, 0x3B4C, 0x3B4D, 0x3B4F, 0x3B50, - /* GB+82 31 AD 30 */ 0x3B51, 0x3B52, 0x3B53, 0x3B54, 0x3B55, - /* GB+82 31 AD 35 */ 0x3B56, 0x3B57, 0x3B58, 0x3B59, 0x3B5A, - /* GB+82 31 AE 30 */ 0x3B5B, 0x3B5C, 0x3B5D, 0x3B5E, 0x3B5F, - /* GB+82 31 AE 35 */ 0x3B60, 0x3B61, 0x3B62, 0x3B63, 0x3B64, - /* GB+82 31 AF 30 */ 0x3B65, 0x3B66, 0x3B67, 0x3B68, 0x3B69, - /* GB+82 31 AF 35 */ 0x3B6A, 0x3B6B, 0x3B6C, 0x3B6D, 0x3B6E, - /* GB+82 31 B0 30 */ 0x3B6F, 0x3B70, 0x3B71, 0x3B72, 0x3B73, - /* GB+82 31 B0 35 */ 0x3B74, 0x3B75, 0x3B76, 0x3B77, 0x3B78, - /* GB+82 31 B1 30 */ 0x3B79, 0x3B7A, 0x3B7B, 0x3B7C, 0x3B7D, - /* GB+82 31 B1 35 */ 0x3B7E, 0x3B7F, 0x3B80, 0x3B81, 0x3B82, - /* GB+82 31 B2 30 */ 0x3B83, 0x3B84, 0x3B85, 0x3B86, 0x3B87, - /* GB+82 31 B2 35 */ 0x3B88, 0x3B89, 0x3B8A, 0x3B8B, 0x3B8C, - /* GB+82 31 B3 30 */ 0x3B8D, 0x3B8E, 0x3B8F, 0x3B90, 0x3B91, - /* GB+82 31 B3 35 */ 0x3B92, 0x3B93, 0x3B94, 0x3B95, 0x3B96, - /* GB+82 31 B4 30 */ 0x3B97, 0x3B98, 0x3B99, 0x3B9A, 0x3B9B, - /* GB+82 31 B4 35 */ 0x3B9C, 0x3B9D, 0x3B9E, 0x3B9F, 0x3BA0, - /* GB+82 31 B5 30 */ 0x3BA1, 0x3BA2, 0x3BA3, 0x3BA4, 0x3BA5, - /* GB+82 31 B5 35 */ 0x3BA6, 0x3BA7, 0x3BA8, 0x3BA9, 0x3BAA, - /* GB+82 31 B6 30 */ 0x3BAB, 0x3BAC, 0x3BAD, 0x3BAE, 0x3BAF, - /* GB+82 31 B6 35 */ 0x3BB0, 0x3BB1, 0x3BB2, 0x3BB3, 0x3BB4, - /* GB+82 31 B7 30 */ 0x3BB5, 0x3BB6, 0x3BB7, 0x3BB8, 0x3BB9, - /* GB+82 31 B7 35 */ 0x3BBA, 0x3BBB, 0x3BBC, 0x3BBD, 0x3BBE, - /* GB+82 31 B8 30 */ 0x3BBF, 0x3BC0, 0x3BC1, 0x3BC2, 0x3BC3, - /* GB+82 31 B8 35 */ 0x3BC4, 0x3BC5, 0x3BC6, 0x3BC7, 0x3BC8, - /* GB+82 31 B9 30 */ 0x3BC9, 0x3BCA, 0x3BCB, 0x3BCC, 0x3BCD, - /* GB+82 31 B9 35 */ 0x3BCE, 0x3BCF, 0x3BD0, 0x3BD1, 0x3BD2, - /* GB+82 31 BA 30 */ 0x3BD3, 0x3BD4, 0x3BD5, 0x3BD6, 0x3BD7, - /* GB+82 31 BA 35 */ 0x3BD8, 0x3BD9, 0x3BDA, 0x3BDB, 0x3BDC, - /* GB+82 31 BB 30 */ 0x3BDD, 0x3BDE, 0x3BDF, 0x3BE0, 0x3BE1, - /* GB+82 31 BB 35 */ 0x3BE2, 0x3BE3, 0x3BE4, 0x3BE5, 0x3BE6, - /* GB+82 31 BC 30 */ 0x3BE7, 0x3BE8, 0x3BE9, 0x3BEA, 0x3BEB, - /* GB+82 31 BC 35 */ 0x3BEC, 0x3BED, 0x3BEE, 0x3BEF, 0x3BF0, - /* GB+82 31 BD 30 */ 0x3BF1, 0x3BF2, 0x3BF3, 0x3BF4, 0x3BF5, - /* GB+82 31 BD 35 */ 0x3BF6, 0x3BF7, 0x3BF8, 0x3BF9, 0x3BFA, - /* GB+82 31 BE 30 */ 0x3BFB, 0x3BFC, 0x3BFD, 0x3BFE, 0x3BFF, - /* GB+82 31 BE 35 */ 0x3C00, 0x3C01, 0x3C02, 0x3C03, 0x3C04, - /* GB+82 31 BF 30 */ 0x3C05, 0x3C06, 0x3C07, 0x3C08, 0x3C09, - /* GB+82 31 BF 35 */ 0x3C0A, 0x3C0B, 0x3C0C, 0x3C0D, 0x3C0E, - /* GB+82 31 C0 30 */ 0x3C0F, 0x3C10, 0x3C11, 0x3C12, 0x3C13, - /* GB+82 31 C0 35 */ 0x3C14, 0x3C15, 0x3C16, 0x3C17, 0x3C18, - /* GB+82 31 C1 30 */ 0x3C19, 0x3C1A, 0x3C1B, 0x3C1C, 0x3C1D, - /* GB+82 31 C1 35 */ 0x3C1E, 0x3C1F, 0x3C20, 0x3C21, 0x3C22, - /* GB+82 31 C2 30 */ 0x3C23, 0x3C24, 0x3C25, 0x3C26, 0x3C27, - /* GB+82 31 C2 35 */ 0x3C28, 0x3C29, 0x3C2A, 0x3C2B, 0x3C2C, - /* GB+82 31 C3 30 */ 0x3C2D, 0x3C2E, 0x3C2F, 0x3C30, 0x3C31, - /* GB+82 31 C3 35 */ 0x3C32, 0x3C33, 0x3C34, 0x3C35, 0x3C36, - /* GB+82 31 C4 30 */ 0x3C37, 0x3C38, 0x3C39, 0x3C3A, 0x3C3B, - /* GB+82 31 C4 35 */ 0x3C3C, 0x3C3D, 0x3C3E, 0x3C3F, 0x3C40, - /* GB+82 31 C5 30 */ 0x3C41, 0x3C42, 0x3C43, 0x3C44, 0x3C45, - /* GB+82 31 C5 35 */ 0x3C46, 0x3C47, 0x3C48, 0x3C49, 0x3C4A, - /* GB+82 31 C6 30 */ 0x3C4B, 0x3C4C, 0x3C4D, 0x3C4E, 0x3C4F, - /* GB+82 31 C6 35 */ 0x3C50, 0x3C51, 0x3C52, 0x3C53, 0x3C54, - /* GB+82 31 C7 30 */ 0x3C55, 0x3C56, 0x3C57, 0x3C58, 0x3C59, - /* GB+82 31 C7 35 */ 0x3C5A, 0x3C5B, 0x3C5C, 0x3C5D, 0x3C5E, - /* GB+82 31 C8 30 */ 0x3C5F, 0x3C60, 0x3C61, 0x3C62, 0x3C63, - /* GB+82 31 C8 35 */ 0x3C64, 0x3C65, 0x3C66, 0x3C67, 0x3C68, - /* GB+82 31 C9 30 */ 0x3C69, 0x3C6A, 0x3C6B, 0x3C6C, 0x3C6D, - /* GB+82 31 C9 35 */ 0x3C6F, 0x3C70, 0x3C71, 0x3C72, 0x3C73, - /* GB+82 31 CA 30 */ 0x3C74, 0x3C75, 0x3C76, 0x3C77, 0x3C78, - /* GB+82 31 CA 35 */ 0x3C79, 0x3C7A, 0x3C7B, 0x3C7C, 0x3C7D, - /* GB+82 31 CB 30 */ 0x3C7E, 0x3C7F, 0x3C80, 0x3C81, 0x3C82, - /* GB+82 31 CB 35 */ 0x3C83, 0x3C84, 0x3C85, 0x3C86, 0x3C87, - /* GB+82 31 CC 30 */ 0x3C88, 0x3C89, 0x3C8A, 0x3C8B, 0x3C8C, - /* GB+82 31 CC 35 */ 0x3C8D, 0x3C8E, 0x3C8F, 0x3C90, 0x3C91, - /* GB+82 31 CD 30 */ 0x3C92, 0x3C93, 0x3C94, 0x3C95, 0x3C96, - /* GB+82 31 CD 35 */ 0x3C97, 0x3C98, 0x3C99, 0x3C9A, 0x3C9B, - /* GB+82 31 CE 30 */ 0x3C9C, 0x3C9D, 0x3C9E, 0x3C9F, 0x3CA0, - /* GB+82 31 CE 35 */ 0x3CA1, 0x3CA2, 0x3CA3, 0x3CA4, 0x3CA5, - /* GB+82 31 CF 30 */ 0x3CA6, 0x3CA7, 0x3CA8, 0x3CA9, 0x3CAA, - /* GB+82 31 CF 35 */ 0x3CAB, 0x3CAC, 0x3CAD, 0x3CAE, 0x3CAF, - /* GB+82 31 D0 30 */ 0x3CB0, 0x3CB1, 0x3CB2, 0x3CB3, 0x3CB4, - /* GB+82 31 D0 35 */ 0x3CB5, 0x3CB6, 0x3CB7, 0x3CB8, 0x3CB9, - /* GB+82 31 D1 30 */ 0x3CBA, 0x3CBB, 0x3CBC, 0x3CBD, 0x3CBE, - /* GB+82 31 D1 35 */ 0x3CBF, 0x3CC0, 0x3CC1, 0x3CC2, 0x3CC3, - /* GB+82 31 D2 30 */ 0x3CC4, 0x3CC5, 0x3CC6, 0x3CC7, 0x3CC8, - /* GB+82 31 D2 35 */ 0x3CC9, 0x3CCA, 0x3CCB, 0x3CCC, 0x3CCD, - /* GB+82 31 D3 30 */ 0x3CCE, 0x3CCF, 0x3CD0, 0x3CD1, 0x3CD2, - /* GB+82 31 D3 35 */ 0x3CD3, 0x3CD4, 0x3CD5, 0x3CD6, 0x3CD7, - /* GB+82 31 D4 30 */ 0x3CD8, 0x3CD9, 0x3CDA, 0x3CDB, 0x3CDC, - /* GB+82 31 D4 35 */ 0x3CDD, 0x3CDE, 0x3CDF, - /* Contiguous area: GB+82 32 AF 33 .. GB+82 32 C9 36 */ - /* GB+82 32 AF 33 */ 0x4057, 0x4058, - /* GB+82 32 AF 35 */ 0x4059, 0x405A, 0x405B, 0x405C, 0x405D, - /* GB+82 32 B0 30 */ 0x405E, 0x405F, 0x4060, 0x4061, 0x4062, - /* GB+82 32 B0 35 */ 0x4063, 0x4064, 0x4065, 0x4066, 0x4067, - /* GB+82 32 B1 30 */ 0x4068, 0x4069, 0x406A, 0x406B, 0x406C, - /* GB+82 32 B1 35 */ 0x406D, 0x406E, 0x406F, 0x4070, 0x4071, - /* GB+82 32 B2 30 */ 0x4072, 0x4073, 0x4074, 0x4075, 0x4076, - /* GB+82 32 B2 35 */ 0x4077, 0x4078, 0x4079, 0x407A, 0x407B, - /* GB+82 32 B3 30 */ 0x407C, 0x407D, 0x407E, 0x407F, 0x4080, - /* GB+82 32 B3 35 */ 0x4081, 0x4082, 0x4083, 0x4084, 0x4085, - /* GB+82 32 B4 30 */ 0x4086, 0x4087, 0x4088, 0x4089, 0x408A, - /* GB+82 32 B4 35 */ 0x408B, 0x408C, 0x408D, 0x408E, 0x408F, - /* GB+82 32 B5 30 */ 0x4090, 0x4091, 0x4092, 0x4093, 0x4094, - /* GB+82 32 B5 35 */ 0x4095, 0x4096, 0x4097, 0x4098, 0x4099, - /* GB+82 32 B6 30 */ 0x409A, 0x409B, 0x409C, 0x409D, 0x409E, - /* GB+82 32 B6 35 */ 0x409F, 0x40A0, 0x40A1, 0x40A2, 0x40A3, - /* GB+82 32 B7 30 */ 0x40A4, 0x40A5, 0x40A6, 0x40A7, 0x40A8, - /* GB+82 32 B7 35 */ 0x40A9, 0x40AA, 0x40AB, 0x40AC, 0x40AD, - /* GB+82 32 B8 30 */ 0x40AE, 0x40AF, 0x40B0, 0x40B1, 0x40B2, - /* GB+82 32 B8 35 */ 0x40B3, 0x40B4, 0x40B5, 0x40B6, 0x40B7, - /* GB+82 32 B9 30 */ 0x40B8, 0x40B9, 0x40BA, 0x40BB, 0x40BC, - /* GB+82 32 B9 35 */ 0x40BD, 0x40BE, 0x40BF, 0x40C0, 0x40C1, - /* GB+82 32 BA 30 */ 0x40C2, 0x40C3, 0x40C4, 0x40C5, 0x40C6, - /* GB+82 32 BA 35 */ 0x40C7, 0x40C8, 0x40C9, 0x40CA, 0x40CB, - /* GB+82 32 BB 30 */ 0x40CC, 0x40CD, 0x40CE, 0x40CF, 0x40D0, - /* GB+82 32 BB 35 */ 0x40D1, 0x40D2, 0x40D3, 0x40D4, 0x40D5, - /* GB+82 32 BC 30 */ 0x40D6, 0x40D7, 0x40D8, 0x40D9, 0x40DA, - /* GB+82 32 BC 35 */ 0x40DB, 0x40DC, 0x40DD, 0x40DE, 0x40DF, - /* GB+82 32 BD 30 */ 0x40E0, 0x40E1, 0x40E2, 0x40E3, 0x40E4, - /* GB+82 32 BD 35 */ 0x40E5, 0x40E6, 0x40E7, 0x40E8, 0x40E9, - /* GB+82 32 BE 30 */ 0x40EA, 0x40EB, 0x40EC, 0x40ED, 0x40EE, - /* GB+82 32 BE 35 */ 0x40EF, 0x40F0, 0x40F1, 0x40F2, 0x40F3, - /* GB+82 32 BF 30 */ 0x40F4, 0x40F5, 0x40F6, 0x40F7, 0x40F8, - /* GB+82 32 BF 35 */ 0x40F9, 0x40FA, 0x40FB, 0x40FC, 0x40FD, - /* GB+82 32 C0 30 */ 0x40FE, 0x40FF, 0x4100, 0x4101, 0x4102, - /* GB+82 32 C0 35 */ 0x4103, 0x4104, 0x4105, 0x4106, 0x4107, - /* GB+82 32 C1 30 */ 0x4108, 0x4109, 0x410A, 0x410B, 0x410C, - /* GB+82 32 C1 35 */ 0x410D, 0x410E, 0x410F, 0x4110, 0x4111, - /* GB+82 32 C2 30 */ 0x4112, 0x4113, 0x4114, 0x4115, 0x4116, - /* GB+82 32 C2 35 */ 0x4117, 0x4118, 0x4119, 0x411A, 0x411B, - /* GB+82 32 C3 30 */ 0x411C, 0x411D, 0x411E, 0x411F, 0x4120, - /* GB+82 32 C3 35 */ 0x4121, 0x4122, 0x4123, 0x4124, 0x4125, - /* GB+82 32 C4 30 */ 0x4126, 0x4127, 0x4128, 0x4129, 0x412A, - /* GB+82 32 C4 35 */ 0x412B, 0x412C, 0x412D, 0x412E, 0x412F, - /* GB+82 32 C5 30 */ 0x4130, 0x4131, 0x4132, 0x4133, 0x4134, - /* GB+82 32 C5 35 */ 0x4135, 0x4136, 0x4137, 0x4138, 0x4139, - /* GB+82 32 C6 30 */ 0x413A, 0x413B, 0x413C, 0x413D, 0x413E, - /* GB+82 32 C6 35 */ 0x413F, 0x4140, 0x4141, 0x4142, 0x4143, - /* GB+82 32 C7 30 */ 0x4144, 0x4145, 0x4146, 0x4147, 0x4148, - /* GB+82 32 C7 35 */ 0x4149, 0x414A, 0x414B, 0x414C, 0x414D, - /* GB+82 32 C8 30 */ 0x414E, 0x414F, 0x4150, 0x4151, 0x4152, - /* GB+82 32 C8 35 */ 0x4153, 0x4154, 0x4155, 0x4156, 0x4157, - /* GB+82 32 C9 30 */ 0x4158, 0x4159, 0x415A, 0x415B, 0x415C, - /* GB+82 32 C9 35 */ 0x415D, 0x415E, - /* Contiguous area: GB+82 32 F8 38 .. GB+82 33 A3 38 */ - /* GB+82 32 F8 38 */ 0x4338, 0x4339, - /* GB+82 32 F9 30 */ 0x433A, 0x433B, 0x433C, 0x433D, 0x433E, - /* GB+82 32 F9 35 */ 0x433F, 0x4340, 0x4341, 0x4342, 0x4343, - /* GB+82 32 FA 30 */ 0x4344, 0x4345, 0x4346, 0x4347, 0x4348, - /* GB+82 32 FA 35 */ 0x4349, 0x434A, 0x434B, 0x434C, 0x434D, - /* GB+82 32 FB 30 */ 0x434E, 0x434F, 0x4350, 0x4351, 0x4352, - /* GB+82 32 FB 35 */ 0x4353, 0x4354, 0x4355, 0x4356, 0x4357, - /* GB+82 32 FC 30 */ 0x4358, 0x4359, 0x435A, 0x435B, 0x435C, - /* GB+82 32 FC 35 */ 0x435D, 0x435E, 0x435F, 0x4360, 0x4361, - /* GB+82 32 FD 30 */ 0x4362, 0x4363, 0x4364, 0x4365, 0x4366, - /* GB+82 32 FD 35 */ 0x4367, 0x4368, 0x4369, 0x436A, 0x436B, - /* GB+82 32 FE 30 */ 0x436C, 0x436D, 0x436E, 0x436F, 0x4370, - /* GB+82 32 FE 35 */ 0x4371, 0x4372, 0x4373, 0x4374, 0x4375, - /* GB+82 33 81 30 */ 0x4376, 0x4377, 0x4378, 0x4379, 0x437A, - /* GB+82 33 81 35 */ 0x437B, 0x437C, 0x437D, 0x437E, 0x437F, - /* GB+82 33 82 30 */ 0x4380, 0x4381, 0x4382, 0x4383, 0x4384, - /* GB+82 33 82 35 */ 0x4385, 0x4386, 0x4387, 0x4388, 0x4389, - /* GB+82 33 83 30 */ 0x438A, 0x438B, 0x438C, 0x438D, 0x438E, - /* GB+82 33 83 35 */ 0x438F, 0x4390, 0x4391, 0x4392, 0x4393, - /* GB+82 33 84 30 */ 0x4394, 0x4395, 0x4396, 0x4397, 0x4398, - /* GB+82 33 84 35 */ 0x4399, 0x439A, 0x439B, 0x439C, 0x439D, - /* GB+82 33 85 30 */ 0x439E, 0x439F, 0x43A0, 0x43A1, 0x43A2, - /* GB+82 33 85 35 */ 0x43A3, 0x43A4, 0x43A5, 0x43A6, 0x43A7, - /* GB+82 33 86 30 */ 0x43A8, 0x43A9, 0x43AA, 0x43AB, 0x43AD, - /* GB+82 33 86 35 */ 0x43AE, 0x43AF, 0x43B0, 0x43B2, 0x43B3, - /* GB+82 33 87 30 */ 0x43B4, 0x43B5, 0x43B6, 0x43B7, 0x43B8, - /* GB+82 33 87 35 */ 0x43B9, 0x43BA, 0x43BB, 0x43BC, 0x43BD, - /* GB+82 33 88 30 */ 0x43BE, 0x43BF, 0x43C0, 0x43C1, 0x43C2, - /* GB+82 33 88 35 */ 0x43C3, 0x43C4, 0x43C5, 0x43C6, 0x43C7, - /* GB+82 33 89 30 */ 0x43C8, 0x43C9, 0x43CA, 0x43CB, 0x43CC, - /* GB+82 33 89 35 */ 0x43CD, 0x43CE, 0x43CF, 0x43D0, 0x43D1, - /* GB+82 33 8A 30 */ 0x43D2, 0x43D3, 0x43D4, 0x43D5, 0x43D6, - /* GB+82 33 8A 35 */ 0x43D7, 0x43D8, 0x43D9, 0x43DA, 0x43DB, - /* GB+82 33 8B 30 */ 0x43DC, 0x43DE, 0x43DF, 0x43E0, 0x43E1, - /* GB+82 33 8B 35 */ 0x43E2, 0x43E3, 0x43E4, 0x43E5, 0x43E6, - /* GB+82 33 8C 30 */ 0x43E7, 0x43E8, 0x43E9, 0x43EA, 0x43EB, - /* GB+82 33 8C 35 */ 0x43EC, 0x43ED, 0x43EE, 0x43EF, 0x43F0, - /* GB+82 33 8D 30 */ 0x43F1, 0x43F2, 0x43F3, 0x43F4, 0x43F5, - /* GB+82 33 8D 35 */ 0x43F6, 0x43F7, 0x43F8, 0x43F9, 0x43FA, - /* GB+82 33 8E 30 */ 0x43FB, 0x43FC, 0x43FD, 0x43FE, 0x43FF, - /* GB+82 33 8E 35 */ 0x4400, 0x4401, 0x4402, 0x4403, 0x4404, - /* GB+82 33 8F 30 */ 0x4405, 0x4406, 0x4407, 0x4408, 0x4409, - /* GB+82 33 8F 35 */ 0x440A, 0x440B, 0x440C, 0x440D, 0x440E, - /* GB+82 33 90 30 */ 0x440F, 0x4410, 0x4411, 0x4412, 0x4413, - /* GB+82 33 90 35 */ 0x4414, 0x4415, 0x4416, 0x4417, 0x4418, - /* GB+82 33 91 30 */ 0x4419, 0x441A, 0x441B, 0x441C, 0x441D, - /* GB+82 33 91 35 */ 0x441E, 0x441F, 0x4420, 0x4421, 0x4422, - /* GB+82 33 92 30 */ 0x4423, 0x4424, 0x4425, 0x4426, 0x4427, - /* GB+82 33 92 35 */ 0x4428, 0x4429, 0x442A, 0x442B, 0x442C, - /* GB+82 33 93 30 */ 0x442D, 0x442E, 0x442F, 0x4430, 0x4431, - /* GB+82 33 93 35 */ 0x4432, 0x4433, 0x4434, 0x4435, 0x4436, - /* GB+82 33 94 30 */ 0x4437, 0x4438, 0x4439, 0x443A, 0x443B, - /* GB+82 33 94 35 */ 0x443C, 0x443D, 0x443E, 0x443F, 0x4440, - /* GB+82 33 95 30 */ 0x4441, 0x4442, 0x4443, 0x4444, 0x4445, - /* GB+82 33 95 35 */ 0x4446, 0x4447, 0x4448, 0x4449, 0x444A, - /* GB+82 33 96 30 */ 0x444B, 0x444C, 0x444D, 0x444E, 0x444F, - /* GB+82 33 96 35 */ 0x4450, 0x4451, 0x4452, 0x4453, 0x4454, - /* GB+82 33 97 30 */ 0x4455, 0x4456, 0x4457, 0x4458, 0x4459, - /* GB+82 33 97 35 */ 0x445A, 0x445B, 0x445C, 0x445D, 0x445E, - /* GB+82 33 98 30 */ 0x445F, 0x4460, 0x4461, 0x4462, 0x4463, - /* GB+82 33 98 35 */ 0x4464, 0x4465, 0x4466, 0x4467, 0x4468, - /* GB+82 33 99 30 */ 0x4469, 0x446A, 0x446B, 0x446C, 0x446D, - /* GB+82 33 99 35 */ 0x446E, 0x446F, 0x4470, 0x4471, 0x4472, - /* GB+82 33 9A 30 */ 0x4473, 0x4474, 0x4475, 0x4476, 0x4477, - /* GB+82 33 9A 35 */ 0x4478, 0x4479, 0x447A, 0x447B, 0x447C, - /* GB+82 33 9B 30 */ 0x447D, 0x447E, 0x447F, 0x4480, 0x4481, - /* GB+82 33 9B 35 */ 0x4482, 0x4483, 0x4484, 0x4485, 0x4486, - /* GB+82 33 9C 30 */ 0x4487, 0x4488, 0x4489, 0x448A, 0x448B, - /* GB+82 33 9C 35 */ 0x448C, 0x448D, 0x448E, 0x448F, 0x4490, - /* GB+82 33 9D 30 */ 0x4491, 0x4492, 0x4493, 0x4494, 0x4495, - /* GB+82 33 9D 35 */ 0x4496, 0x4497, 0x4498, 0x4499, 0x449A, - /* GB+82 33 9E 30 */ 0x449B, 0x449C, 0x449D, 0x449E, 0x449F, - /* GB+82 33 9E 35 */ 0x44A0, 0x44A1, 0x44A2, 0x44A3, 0x44A4, - /* GB+82 33 9F 30 */ 0x44A5, 0x44A6, 0x44A7, 0x44A8, 0x44A9, - /* GB+82 33 9F 35 */ 0x44AA, 0x44AB, 0x44AC, 0x44AD, 0x44AE, - /* GB+82 33 A0 30 */ 0x44AF, 0x44B0, 0x44B1, 0x44B2, 0x44B3, - /* GB+82 33 A0 35 */ 0x44B4, 0x44B5, 0x44B6, 0x44B7, 0x44B8, - /* GB+82 33 A1 30 */ 0x44B9, 0x44BA, 0x44BB, 0x44BC, 0x44BD, - /* GB+82 33 A1 35 */ 0x44BE, 0x44BF, 0x44C0, 0x44C1, 0x44C2, - /* GB+82 33 A2 30 */ 0x44C3, 0x44C4, 0x44C5, 0x44C6, 0x44C7, - /* GB+82 33 A2 35 */ 0x44C8, 0x44C9, 0x44CA, 0x44CB, 0x44CC, - /* GB+82 33 A3 30 */ 0x44CD, 0x44CE, 0x44CF, 0x44D0, 0x44D1, - /* GB+82 33 A3 35 */ 0x44D2, 0x44D3, 0x44D4, 0x44D5, - /* Contiguous area: GB+82 33 C9 32 .. GB+82 33 E8 37 */ - /* GB+82 33 C9 32 */ 0x464D, 0x464E, 0x464F, - /* GB+82 33 C9 35 */ 0x4650, 0x4651, 0x4652, 0x4653, 0x4654, - /* GB+82 33 CA 30 */ 0x4655, 0x4656, 0x4657, 0x4658, 0x4659, - /* GB+82 33 CA 35 */ 0x465A, 0x465B, 0x465C, 0x465D, 0x465E, - /* GB+82 33 CB 30 */ 0x465F, 0x4660, 0x4662, 0x4663, 0x4664, - /* GB+82 33 CB 35 */ 0x4665, 0x4666, 0x4667, 0x4668, 0x4669, - /* GB+82 33 CC 30 */ 0x466A, 0x466B, 0x466C, 0x466D, 0x466E, - /* GB+82 33 CC 35 */ 0x466F, 0x4670, 0x4671, 0x4672, 0x4673, - /* GB+82 33 CD 30 */ 0x4674, 0x4675, 0x4676, 0x4677, 0x4678, - /* GB+82 33 CD 35 */ 0x4679, 0x467A, 0x467B, 0x467C, 0x467D, - /* GB+82 33 CE 30 */ 0x467E, 0x467F, 0x4680, 0x4681, 0x4682, - /* GB+82 33 CE 35 */ 0x4683, 0x4684, 0x4685, 0x4686, 0x4687, - /* GB+82 33 CF 30 */ 0x4688, 0x4689, 0x468A, 0x468B, 0x468C, - /* GB+82 33 CF 35 */ 0x468D, 0x468E, 0x468F, 0x4690, 0x4691, - /* GB+82 33 D0 30 */ 0x4692, 0x4693, 0x4694, 0x4695, 0x4696, - /* GB+82 33 D0 35 */ 0x4697, 0x4698, 0x4699, 0x469A, 0x469B, - /* GB+82 33 D1 30 */ 0x469C, 0x469D, 0x469E, 0x469F, 0x46A0, - /* GB+82 33 D1 35 */ 0x46A1, 0x46A2, 0x46A3, 0x46A4, 0x46A5, - /* GB+82 33 D2 30 */ 0x46A6, 0x46A7, 0x46A8, 0x46A9, 0x46AA, - /* GB+82 33 D2 35 */ 0x46AB, 0x46AC, 0x46AD, 0x46AE, 0x46AF, - /* GB+82 33 D3 30 */ 0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46B4, - /* GB+82 33 D3 35 */ 0x46B5, 0x46B6, 0x46B7, 0x46B8, 0x46B9, - /* GB+82 33 D4 30 */ 0x46BA, 0x46BB, 0x46BC, 0x46BD, 0x46BE, - /* GB+82 33 D4 35 */ 0x46BF, 0x46C0, 0x46C1, 0x46C2, 0x46C3, - /* GB+82 33 D5 30 */ 0x46C4, 0x46C5, 0x46C6, 0x46C7, 0x46C8, - /* GB+82 33 D5 35 */ 0x46C9, 0x46CA, 0x46CB, 0x46CC, 0x46CD, - /* GB+82 33 D6 30 */ 0x46CE, 0x46CF, 0x46D0, 0x46D1, 0x46D2, - /* GB+82 33 D6 35 */ 0x46D3, 0x46D4, 0x46D5, 0x46D6, 0x46D7, - /* GB+82 33 D7 30 */ 0x46D8, 0x46D9, 0x46DA, 0x46DB, 0x46DC, - /* GB+82 33 D7 35 */ 0x46DD, 0x46DE, 0x46DF, 0x46E0, 0x46E1, - /* GB+82 33 D8 30 */ 0x46E2, 0x46E3, 0x46E4, 0x46E5, 0x46E6, - /* GB+82 33 D8 35 */ 0x46E7, 0x46E8, 0x46E9, 0x46EA, 0x46EB, - /* GB+82 33 D9 30 */ 0x46EC, 0x46ED, 0x46EE, 0x46EF, 0x46F0, - /* GB+82 33 D9 35 */ 0x46F1, 0x46F2, 0x46F3, 0x46F4, 0x46F5, - /* GB+82 33 DA 30 */ 0x46F6, 0x46F7, 0x46F8, 0x46F9, 0x46FA, - /* GB+82 33 DA 35 */ 0x46FB, 0x46FC, 0x46FD, 0x46FE, 0x46FF, - /* GB+82 33 DB 30 */ 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, - /* GB+82 33 DB 35 */ 0x4705, 0x4706, 0x4707, 0x4708, 0x4709, - /* GB+82 33 DC 30 */ 0x470A, 0x470B, 0x470C, 0x470D, 0x470E, - /* GB+82 33 DC 35 */ 0x470F, 0x4710, 0x4711, 0x4712, 0x4713, - /* GB+82 33 DD 30 */ 0x4714, 0x4715, 0x4716, 0x4717, 0x4718, - /* GB+82 33 DD 35 */ 0x4719, 0x471A, 0x471B, 0x471C, 0x471D, - /* GB+82 33 DE 30 */ 0x471E, 0x471F, 0x4720, 0x4721, 0x4722, - /* GB+82 33 DE 35 */ 0x4724, 0x4725, 0x4726, 0x4727, 0x4728, - /* GB+82 33 DF 30 */ 0x472A, 0x472B, 0x472C, 0x472D, 0x472E, - /* GB+82 33 DF 35 */ 0x472F, 0x4730, 0x4731, 0x4732, 0x4733, - /* GB+82 33 E0 30 */ 0x4734, 0x4735, 0x4736, 0x4737, 0x4738, - /* GB+82 33 E0 35 */ 0x4739, 0x473A, 0x473B, 0x473C, 0x473D, - /* GB+82 33 E1 30 */ 0x473E, 0x473F, 0x4740, 0x4741, 0x4742, - /* GB+82 33 E1 35 */ 0x4743, 0x4744, 0x4745, 0x4746, 0x4747, - /* GB+82 33 E2 30 */ 0x4748, 0x4749, 0x474A, 0x474B, 0x474C, - /* GB+82 33 E2 35 */ 0x474D, 0x474E, 0x474F, 0x4750, 0x4751, - /* GB+82 33 E3 30 */ 0x4752, 0x4753, 0x4754, 0x4755, 0x4756, - /* GB+82 33 E3 35 */ 0x4757, 0x4758, 0x4759, 0x475A, 0x475B, - /* GB+82 33 E4 30 */ 0x475C, 0x475D, 0x475E, 0x475F, 0x4760, - /* GB+82 33 E4 35 */ 0x4761, 0x4762, 0x4763, 0x4764, 0x4765, - /* GB+82 33 E5 30 */ 0x4766, 0x4767, 0x4768, 0x4769, 0x476A, - /* GB+82 33 E5 35 */ 0x476B, 0x476C, 0x476D, 0x476E, 0x476F, - /* GB+82 33 E6 30 */ 0x4770, 0x4771, 0x4772, 0x4773, 0x4774, - /* GB+82 33 E6 35 */ 0x4775, 0x4776, 0x4777, 0x4778, 0x4779, - /* GB+82 33 E7 30 */ 0x477A, 0x477B, 0x477D, 0x477E, 0x477F, - /* GB+82 33 E7 35 */ 0x4780, 0x4781, 0x4782, 0x4783, 0x4784, - /* GB+82 33 E8 30 */ 0x4785, 0x4786, 0x4787, 0x4788, 0x4789, - /* GB+82 33 E8 35 */ 0x478A, 0x478B, 0x478C, - /* Contiguous area: GB+82 34 96 39 .. GB+82 34 A1 30 */ - /* GB+82 34 96 39 */ 0x4948, - /* GB+82 34 97 30 */ 0x4949, 0x494A, 0x494B, 0x494C, 0x494D, - /* GB+82 34 97 35 */ 0x494E, 0x494F, 0x4950, 0x4951, 0x4952, - /* GB+82 34 98 30 */ 0x4953, 0x4954, 0x4955, 0x4956, 0x4957, - /* GB+82 34 98 35 */ 0x4958, 0x4959, 0x495A, 0x495B, 0x495C, - /* GB+82 34 99 30 */ 0x495D, 0x495E, 0x495F, 0x4960, 0x4961, - /* GB+82 34 99 35 */ 0x4962, 0x4963, 0x4964, 0x4965, 0x4966, - /* GB+82 34 9A 30 */ 0x4967, 0x4968, 0x4969, 0x496A, 0x496B, - /* GB+82 34 9A 35 */ 0x496C, 0x496D, 0x496E, 0x496F, 0x4970, - /* GB+82 34 9B 30 */ 0x4971, 0x4972, 0x4973, 0x4974, 0x4975, - /* GB+82 34 9B 35 */ 0x4976, 0x4977, 0x4978, 0x4979, 0x497B, - /* GB+82 34 9C 30 */ 0x497C, 0x497E, 0x497F, 0x4980, 0x4981, - /* GB+82 34 9C 35 */ 0x4984, 0x4987, 0x4988, 0x4989, 0x498A, - /* GB+82 34 9D 30 */ 0x498B, 0x498C, 0x498D, 0x498E, 0x498F, - /* GB+82 34 9D 35 */ 0x4990, 0x4991, 0x4992, 0x4993, 0x4994, - /* GB+82 34 9E 30 */ 0x4995, 0x4996, 0x4997, 0x4998, 0x4999, - /* GB+82 34 9E 35 */ 0x499A, 0x499C, 0x499D, 0x499E, 0x49A0, - /* GB+82 34 9F 30 */ 0x49A1, 0x49A2, 0x49A3, 0x49A4, 0x49A5, - /* GB+82 34 9F 35 */ 0x49A6, 0x49A7, 0x49A8, 0x49A9, 0x49AA, - /* GB+82 34 A0 30 */ 0x49AB, 0x49AC, 0x49AD, 0x49AE, 0x49AF, - /* GB+82 34 A0 35 */ 0x49B0, 0x49B1, 0x49B2, 0x49B3, 0x49B4, - /* GB+82 34 A1 30 */ 0x49B5, - /* Contiguous area: GB+82 34 E7 34 .. GB+82 35 8F 32 */ - /* GB+82 34 E7 34 */ 0x4C78, - /* GB+82 34 E7 35 */ 0x4C79, 0x4C7A, 0x4C7B, 0x4C7C, 0x4C7D, - /* GB+82 34 E8 30 */ 0x4C7E, 0x4C7F, 0x4C80, 0x4C81, 0x4C82, - /* GB+82 34 E8 35 */ 0x4C83, 0x4C84, 0x4C85, 0x4C86, 0x4C87, - /* GB+82 34 E9 30 */ 0x4C88, 0x4C89, 0x4C8A, 0x4C8B, 0x4C8C, - /* GB+82 34 E9 35 */ 0x4C8D, 0x4C8E, 0x4C8F, 0x4C90, 0x4C91, - /* GB+82 34 EA 30 */ 0x4C92, 0x4C93, 0x4C94, 0x4C95, 0x4C96, - /* GB+82 34 EA 35 */ 0x4C97, 0x4C98, 0x4C99, 0x4C9A, 0x4C9B, - /* GB+82 34 EB 30 */ 0x4C9C, 0x4C9D, 0x4C9E, 0x4CA4, 0x4CA5, - /* GB+82 34 EB 35 */ 0x4CA6, 0x4CA7, 0x4CA8, 0x4CA9, 0x4CAA, - /* GB+82 34 EC 30 */ 0x4CAB, 0x4CAC, 0x4CAD, 0x4CAE, 0x4CAF, - /* GB+82 34 EC 35 */ 0x4CB0, 0x4CB1, 0x4CB2, 0x4CB3, 0x4CB4, - /* GB+82 34 ED 30 */ 0x4CB5, 0x4CB6, 0x4CB7, 0x4CB8, 0x4CB9, - /* GB+82 34 ED 35 */ 0x4CBA, 0x4CBB, 0x4CBC, 0x4CBD, 0x4CBE, - /* GB+82 34 EE 30 */ 0x4CBF, 0x4CC0, 0x4CC1, 0x4CC2, 0x4CC3, - /* GB+82 34 EE 35 */ 0x4CC4, 0x4CC5, 0x4CC6, 0x4CC7, 0x4CC8, - /* GB+82 34 EF 30 */ 0x4CC9, 0x4CCA, 0x4CCB, 0x4CCC, 0x4CCD, - /* GB+82 34 EF 35 */ 0x4CCE, 0x4CCF, 0x4CD0, 0x4CD1, 0x4CD2, - /* GB+82 34 F0 30 */ 0x4CD3, 0x4CD4, 0x4CD5, 0x4CD6, 0x4CD7, - /* GB+82 34 F0 35 */ 0x4CD8, 0x4CD9, 0x4CDA, 0x4CDB, 0x4CDC, - /* GB+82 34 F1 30 */ 0x4CDD, 0x4CDE, 0x4CDF, 0x4CE0, 0x4CE1, - /* GB+82 34 F1 35 */ 0x4CE2, 0x4CE3, 0x4CE4, 0x4CE5, 0x4CE6, - /* GB+82 34 F2 30 */ 0x4CE7, 0x4CE8, 0x4CE9, 0x4CEA, 0x4CEB, - /* GB+82 34 F2 35 */ 0x4CEC, 0x4CED, 0x4CEE, 0x4CEF, 0x4CF0, - /* GB+82 34 F3 30 */ 0x4CF1, 0x4CF2, 0x4CF3, 0x4CF4, 0x4CF5, - /* GB+82 34 F3 35 */ 0x4CF6, 0x4CF7, 0x4CF8, 0x4CF9, 0x4CFA, - /* GB+82 34 F4 30 */ 0x4CFB, 0x4CFC, 0x4CFD, 0x4CFE, 0x4CFF, - /* GB+82 34 F4 35 */ 0x4D00, 0x4D01, 0x4D02, 0x4D03, 0x4D04, - /* GB+82 34 F5 30 */ 0x4D05, 0x4D06, 0x4D07, 0x4D08, 0x4D09, - /* GB+82 34 F5 35 */ 0x4D0A, 0x4D0B, 0x4D0C, 0x4D0D, 0x4D0E, - /* GB+82 34 F6 30 */ 0x4D0F, 0x4D10, 0x4D11, 0x4D12, 0x4D1A, - /* GB+82 34 F6 35 */ 0x4D1B, 0x4D1C, 0x4D1D, 0x4D1E, 0x4D1F, - /* GB+82 34 F7 30 */ 0x4D20, 0x4D21, 0x4D22, 0x4D23, 0x4D24, - /* GB+82 34 F7 35 */ 0x4D25, 0x4D26, 0x4D27, 0x4D28, 0x4D29, - /* GB+82 34 F8 30 */ 0x4D2A, 0x4D2B, 0x4D2C, 0x4D2D, 0x4D2E, - /* GB+82 34 F8 35 */ 0x4D2F, 0x4D30, 0x4D31, 0x4D32, 0x4D33, - /* GB+82 34 F9 30 */ 0x4D34, 0x4D35, 0x4D36, 0x4D37, 0x4D38, - /* GB+82 34 F9 35 */ 0x4D39, 0x4D3A, 0x4D3B, 0x4D3C, 0x4D3D, - /* GB+82 34 FA 30 */ 0x4D3E, 0x4D3F, 0x4D40, 0x4D41, 0x4D42, - /* GB+82 34 FA 35 */ 0x4D43, 0x4D44, 0x4D45, 0x4D46, 0x4D47, - /* GB+82 34 FB 30 */ 0x4D48, 0x4D49, 0x4D4A, 0x4D4B, 0x4D4C, - /* GB+82 34 FB 35 */ 0x4D4D, 0x4D4E, 0x4D4F, 0x4D50, 0x4D51, - /* GB+82 34 FC 30 */ 0x4D52, 0x4D53, 0x4D54, 0x4D55, 0x4D56, - /* GB+82 34 FC 35 */ 0x4D57, 0x4D58, 0x4D59, 0x4D5A, 0x4D5B, - /* GB+82 34 FD 30 */ 0x4D5C, 0x4D5D, 0x4D5E, 0x4D5F, 0x4D60, - /* GB+82 34 FD 35 */ 0x4D61, 0x4D62, 0x4D63, 0x4D64, 0x4D65, - /* GB+82 34 FE 30 */ 0x4D66, 0x4D67, 0x4D68, 0x4D69, 0x4D6A, - /* GB+82 34 FE 35 */ 0x4D6B, 0x4D6C, 0x4D6D, 0x4D6E, 0x4D6F, - /* GB+82 35 81 30 */ 0x4D70, 0x4D71, 0x4D72, 0x4D73, 0x4D74, - /* GB+82 35 81 35 */ 0x4D75, 0x4D76, 0x4D77, 0x4D78, 0x4D79, - /* GB+82 35 82 30 */ 0x4D7A, 0x4D7B, 0x4D7C, 0x4D7D, 0x4D7E, - /* GB+82 35 82 35 */ 0x4D7F, 0x4D80, 0x4D81, 0x4D82, 0x4D83, - /* GB+82 35 83 30 */ 0x4D84, 0x4D85, 0x4D86, 0x4D87, 0x4D88, - /* GB+82 35 83 35 */ 0x4D89, 0x4D8A, 0x4D8B, 0x4D8C, 0x4D8D, - /* GB+82 35 84 30 */ 0x4D8E, 0x4D8F, 0x4D90, 0x4D91, 0x4D92, - /* GB+82 35 84 35 */ 0x4D93, 0x4D94, 0x4D95, 0x4D96, 0x4D97, - /* GB+82 35 85 30 */ 0x4D98, 0x4D99, 0x4D9A, 0x4D9B, 0x4D9C, - /* GB+82 35 85 35 */ 0x4D9D, 0x4D9E, 0x4D9F, 0x4DA0, 0x4DA1, - /* GB+82 35 86 30 */ 0x4DA2, 0x4DA3, 0x4DA4, 0x4DA5, 0x4DA6, - /* GB+82 35 86 35 */ 0x4DA7, 0x4DA8, 0x4DA9, 0x4DAA, 0x4DAB, - /* GB+82 35 87 30 */ 0x4DAC, 0x4DAD, 0x4DAF, 0x4DB0, 0x4DB1, - /* GB+82 35 87 35 */ 0x4DB2, 0x4DB3, 0x4DB4, 0x4DB5, 0x4DB6, - /* GB+82 35 88 30 */ 0x4DB7, 0x4DB8, 0x4DB9, 0x4DBA, 0x4DBB, - /* GB+82 35 88 35 */ 0x4DBC, 0x4DBD, 0x4DBE, 0x4DBF, 0x4DC0, - /* GB+82 35 89 30 */ 0x4DC1, 0x4DC2, 0x4DC3, 0x4DC4, 0x4DC5, - /* GB+82 35 89 35 */ 0x4DC6, 0x4DC7, 0x4DC8, 0x4DC9, 0x4DCA, - /* GB+82 35 8A 30 */ 0x4DCB, 0x4DCC, 0x4DCD, 0x4DCE, 0x4DCF, - /* GB+82 35 8A 35 */ 0x4DD0, 0x4DD1, 0x4DD2, 0x4DD3, 0x4DD4, - /* GB+82 35 8B 30 */ 0x4DD5, 0x4DD6, 0x4DD7, 0x4DD8, 0x4DD9, - /* GB+82 35 8B 35 */ 0x4DDA, 0x4DDB, 0x4DDC, 0x4DDD, 0x4DDE, - /* GB+82 35 8C 30 */ 0x4DDF, 0x4DE0, 0x4DE1, 0x4DE2, 0x4DE3, - /* GB+82 35 8C 35 */ 0x4DE4, 0x4DE5, 0x4DE6, 0x4DE7, 0x4DE8, - /* GB+82 35 8D 30 */ 0x4DE9, 0x4DEA, 0x4DEB, 0x4DEC, 0x4DED, - /* GB+82 35 8D 35 */ 0x4DEE, 0x4DEF, 0x4DF0, 0x4DF1, 0x4DF2, - /* GB+82 35 8E 30 */ 0x4DF3, 0x4DF4, 0x4DF5, 0x4DF6, 0x4DF7, - /* GB+82 35 8E 35 */ 0x4DF8, 0x4DF9, 0x4DFA, 0x4DFB, 0x4DFC, - /* GB+82 35 8F 30 */ 0x4DFD, 0x4DFE, 0x4DFF, - /* Contiguous area: GB+83 36 C7 39 .. GB+83 36 CF 39 */ - /* GB+83 36 C7 39 */ 0xE76C, - /* GB+83 36 C8 30 */ 0xE7C8, 0xE7E7, 0xE7E8, 0xE7E9, 0xE7EA, - /* GB+83 36 C8 35 */ 0xE7EB, 0xE7EC, 0xE7ED, 0xE7EE, 0xE7EF, - /* GB+83 36 C9 30 */ 0xE7F0, 0xE7F1, 0xE7F2, 0xE7F3, 0xE815, - /* GB+83 36 C9 35 */ 0xE819, 0xE81A, 0xE81B, 0xE81C, 0xE81D, - /* GB+83 36 CA 30 */ 0xE81F, 0xE820, 0xE821, 0xE822, 0xE823, - /* GB+83 36 CA 35 */ 0xE824, 0xE825, 0xE827, 0xE828, 0xE829, - /* GB+83 36 CB 30 */ 0xE82A, 0xE82D, 0xE82E, 0xE82F, 0xE830, - /* GB+83 36 CB 35 */ 0xE833, 0xE834, 0xE835, 0xE836, 0xE837, - /* GB+83 36 CC 30 */ 0xE838, 0xE839, 0xE83A, 0xE83C, 0xE83D, - /* GB+83 36 CC 35 */ 0xE83E, 0xE83F, 0xE840, 0xE841, 0xE842, - /* GB+83 36 CD 30 */ 0xE844, 0xE845, 0xE846, 0xE847, 0xE848, - /* GB+83 36 CD 35 */ 0xE849, 0xE84A, 0xE84B, 0xE84C, 0xE84D, - /* GB+83 36 CE 30 */ 0xE84E, 0xE84F, 0xE850, 0xE851, 0xE852, - /* GB+83 36 CE 35 */ 0xE853, 0xE856, 0xE857, 0xE858, 0xE859, - /* GB+83 36 CF 30 */ 0xE85A, 0xE85B, 0xE85C, 0xE85D, 0xE85E, - /* GB+83 36 CF 35 */ 0xE85F, 0xE860, 0xE861, 0xE862, 0xE863, - /* Contiguous area: GB+84 30 85 35 .. GB+84 30 9C 37 */ - /* GB+84 30 85 35 */ 0xF92D, 0xF92E, 0xF92F, 0xF930, 0xF931, - /* GB+84 30 86 30 */ 0xF932, 0xF933, 0xF934, 0xF935, 0xF936, - /* GB+84 30 86 35 */ 0xF937, 0xF938, 0xF939, 0xF93A, 0xF93B, - /* GB+84 30 87 30 */ 0xF93C, 0xF93D, 0xF93E, 0xF93F, 0xF940, - /* GB+84 30 87 35 */ 0xF941, 0xF942, 0xF943, 0xF944, 0xF945, - /* GB+84 30 88 30 */ 0xF946, 0xF947, 0xF948, 0xF949, 0xF94A, - /* GB+84 30 88 35 */ 0xF94B, 0xF94C, 0xF94D, 0xF94E, 0xF94F, - /* GB+84 30 89 30 */ 0xF950, 0xF951, 0xF952, 0xF953, 0xF954, - /* GB+84 30 89 35 */ 0xF955, 0xF956, 0xF957, 0xF958, 0xF959, - /* GB+84 30 8A 30 */ 0xF95A, 0xF95B, 0xF95C, 0xF95D, 0xF95E, - /* GB+84 30 8A 35 */ 0xF95F, 0xF960, 0xF961, 0xF962, 0xF963, - /* GB+84 30 8B 30 */ 0xF964, 0xF965, 0xF966, 0xF967, 0xF968, - /* GB+84 30 8B 35 */ 0xF969, 0xF96A, 0xF96B, 0xF96C, 0xF96D, - /* GB+84 30 8C 30 */ 0xF96E, 0xF96F, 0xF970, 0xF971, 0xF972, - /* GB+84 30 8C 35 */ 0xF973, 0xF974, 0xF975, 0xF976, 0xF977, - /* GB+84 30 8D 30 */ 0xF978, 0xF97A, 0xF97B, 0xF97C, 0xF97D, - /* GB+84 30 8D 35 */ 0xF97E, 0xF97F, 0xF980, 0xF981, 0xF982, - /* GB+84 30 8E 30 */ 0xF983, 0xF984, 0xF985, 0xF986, 0xF987, - /* GB+84 30 8E 35 */ 0xF988, 0xF989, 0xF98A, 0xF98B, 0xF98C, - /* GB+84 30 8F 30 */ 0xF98D, 0xF98E, 0xF98F, 0xF990, 0xF991, - /* GB+84 30 8F 35 */ 0xF992, 0xF993, 0xF994, 0xF996, 0xF997, - /* GB+84 30 90 30 */ 0xF998, 0xF999, 0xF99A, 0xF99B, 0xF99C, - /* GB+84 30 90 35 */ 0xF99D, 0xF99E, 0xF99F, 0xF9A0, 0xF9A1, - /* GB+84 30 91 30 */ 0xF9A2, 0xF9A3, 0xF9A4, 0xF9A5, 0xF9A6, - /* GB+84 30 91 35 */ 0xF9A7, 0xF9A8, 0xF9A9, 0xF9AA, 0xF9AB, - /* GB+84 30 92 30 */ 0xF9AC, 0xF9AD, 0xF9AE, 0xF9AF, 0xF9B0, - /* GB+84 30 92 35 */ 0xF9B1, 0xF9B2, 0xF9B3, 0xF9B4, 0xF9B5, - /* GB+84 30 93 30 */ 0xF9B6, 0xF9B7, 0xF9B8, 0xF9B9, 0xF9BA, - /* GB+84 30 93 35 */ 0xF9BB, 0xF9BC, 0xF9BD, 0xF9BE, 0xF9BF, - /* GB+84 30 94 30 */ 0xF9C0, 0xF9C1, 0xF9C2, 0xF9C3, 0xF9C4, - /* GB+84 30 94 35 */ 0xF9C5, 0xF9C6, 0xF9C7, 0xF9C8, 0xF9C9, - /* GB+84 30 95 30 */ 0xF9CA, 0xF9CB, 0xF9CC, 0xF9CD, 0xF9CE, - /* GB+84 30 95 35 */ 0xF9CF, 0xF9D0, 0xF9D1, 0xF9D2, 0xF9D3, - /* GB+84 30 96 30 */ 0xF9D4, 0xF9D5, 0xF9D6, 0xF9D7, 0xF9D8, - /* GB+84 30 96 35 */ 0xF9D9, 0xF9DA, 0xF9DB, 0xF9DC, 0xF9DD, - /* GB+84 30 97 30 */ 0xF9DE, 0xF9DF, 0xF9E0, 0xF9E1, 0xF9E2, - /* GB+84 30 97 35 */ 0xF9E3, 0xF9E4, 0xF9E5, 0xF9E6, 0xF9E8, - /* GB+84 30 98 30 */ 0xF9E9, 0xF9EA, 0xF9EB, 0xF9EC, 0xF9ED, - /* GB+84 30 98 35 */ 0xF9EE, 0xF9EF, 0xF9F0, 0xF9F2, 0xF9F3, - /* GB+84 30 99 30 */ 0xF9F4, 0xF9F5, 0xF9F6, 0xF9F7, 0xF9F8, - /* GB+84 30 99 35 */ 0xF9F9, 0xF9FA, 0xF9FB, 0xF9FC, 0xF9FD, - /* GB+84 30 9A 30 */ 0xF9FE, 0xF9FF, 0xFA00, 0xFA01, 0xFA02, - /* GB+84 30 9A 35 */ 0xFA03, 0xFA04, 0xFA05, 0xFA06, 0xFA07, - /* GB+84 30 9B 30 */ 0xFA08, 0xFA09, 0xFA0A, 0xFA0B, 0xFA10, - /* GB+84 30 9B 35 */ 0xFA12, 0xFA15, 0xFA16, 0xFA17, 0xFA19, - /* GB+84 30 9C 30 */ 0xFA1A, 0xFA1B, 0xFA1C, 0xFA1D, 0xFA1E, - /* GB+84 30 9C 35 */ 0xFA22, 0xFA25, 0xFA26, - /* Contiguous area: GB+84 31 85 38 .. GB+84 31 A2 33 */ - /* GB+84 31 85 38 */ 0xFE32, 0xFE45, - /* GB+84 31 86 30 */ 0xFE46, 0xFE47, 0xFE48, 0xFE53, 0xFE58, - /* GB+84 31 86 35 */ 0xFE67, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F, - /* GB+84 31 87 30 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74, - /* GB+84 31 87 35 */ 0xFE75, 0xFE76, 0xFE77, 0xFE78, 0xFE79, - /* GB+84 31 88 30 */ 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, - /* GB+84 31 88 35 */ 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83, - /* GB+84 31 89 30 */ 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, - /* GB+84 31 89 35 */ 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D, - /* GB+84 31 8A 30 */ 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, - /* GB+84 31 8A 35 */ 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97, - /* GB+84 31 8B 30 */ 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, - /* GB+84 31 8B 35 */ 0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0, 0xFEA1, - /* GB+84 31 8C 30 */ 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, - /* GB+84 31 8C 35 */ 0xFEA7, 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, - /* GB+84 31 8D 30 */ 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0, - /* GB+84 31 8D 35 */ 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, - /* GB+84 31 8E 30 */ 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, 0xFEBA, - /* GB+84 31 8E 35 */ 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, - /* GB+84 31 8F 30 */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, - /* GB+84 31 8F 35 */ 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, - /* GB+84 31 90 30 */ 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE, - /* GB+84 31 90 35 */ 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, - /* GB+84 31 91 30 */ 0xFED4, 0xFED5, 0xFED6, 0xFED7, 0xFED8, - /* GB+84 31 91 35 */ 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, - /* GB+84 31 92 30 */ 0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, - /* GB+84 31 92 35 */ 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7, - /* GB+84 31 93 30 */ 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, - /* GB+84 31 93 35 */ 0xFEED, 0xFEEE, 0xFEEF, 0xFEF0, 0xFEF1, - /* GB+84 31 94 30 */ 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, - /* GB+84 31 94 35 */ 0xFEF7, 0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, - /* GB+84 31 95 30 */ 0xFEFC, 0xFEFD, 0xFEFE, 0xFEFF, 0xFF00, - /* GB+84 31 95 35 */ 0xFF5F, 0xFF60, 0xFF61, 0xFF62, 0xFF63, - /* GB+84 31 96 30 */ 0xFF64, 0xFF65, 0xFF66, 0xFF67, 0xFF68, - /* GB+84 31 96 35 */ 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, - /* GB+84 31 97 30 */ 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72, - /* GB+84 31 97 35 */ 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, - /* GB+84 31 98 30 */ 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, - /* GB+84 31 98 35 */ 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81, - /* GB+84 31 99 30 */ 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, - /* GB+84 31 99 35 */ 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, - /* GB+84 31 9A 30 */ 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90, - /* GB+84 31 9A 35 */ 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, - /* GB+84 31 9B 30 */ 0xFF96, 0xFF97, 0xFF98, 0xFF99, 0xFF9A, - /* GB+84 31 9B 35 */ 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F, - /* GB+84 31 9C 30 */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, - /* GB+84 31 9C 35 */ 0xFFA5, 0xFFA6, 0xFFA7, 0xFFA8, 0xFFA9, - /* GB+84 31 9D 30 */ 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, - /* GB+84 31 9D 35 */ 0xFFAF, 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, - /* GB+84 31 9E 30 */ 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7, 0xFFB8, - /* GB+84 31 9E 35 */ 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, - /* GB+84 31 9F 30 */ 0xFFBE, 0xFFBF, 0xFFC0, 0xFFC1, 0xFFC2, - /* GB+84 31 9F 35 */ 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7, - /* GB+84 31 A0 30 */ 0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, - /* GB+84 31 A0 35 */ 0xFFCD, 0xFFCE, 0xFFCF, 0xFFD0, 0xFFD1, - /* GB+84 31 A1 30 */ 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, - /* GB+84 31 A1 35 */ 0xFFD7, 0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, - /* GB+84 31 A2 30 */ 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF, -}; - - -static const uint16_t REPLACEMENT = 0xfffd; - -static inline bool Is1stByte(unsigned c) -{ - return c >= 0x81 && c <= 0xFE; -} - -static inline bool Is2ndByteIn2Bytes(unsigned c) -{ - return c >= 0x40 && c <= 0xFE && c != 0x7F; -} - -static inline bool Is2ndByteIn4Bytes(unsigned c) -{ - return c >= 0x30 && c <= 0x39; -} - -static inline bool Is3rdByte(unsigned c) -{ - return c >= 0x81 && c <= 0xFE; -} - -static inline bool Is4thByte(unsigned c) -{ - return c >= 0x30 && c <= 0x39; -} - -static inline bool IsUDA1(unsigned a, unsigned b) -{ - return a >= 0xAA && a <= 0xAF && b >= 0xA1 && b <= 0xFE; -} - -static inline bool IsUDA2(unsigned a, unsigned b) -{ - return a >= 0xF8 && a <= 0xFE && b >= 0xA1 && b <= 0xFE; -} - -static inline bool IsUDA3(unsigned a, unsigned b) -{ - return a >= 0xA1 && a <= 0xA7 && b >= 0x40 && b <= 0xA0 && b != 0x7F; -} - -static inline uint16_t ValidChar(unsigned u) -{ - return u != 0 ? static_cast(u) : REPLACEMENT; -} - -static unsigned qt_Gb18030ToUnicode(const uint8_t *gbstr, int& len) { - /* Returns Unicode. */ - unsigned uni; - uint8_t first = *gbstr; - - if (first < 128) { - len = 1; - uni = first; - } - else if (Is1stByte(first) && len >= 2) { - uint8_t second = gbstr[1]; - - if (Is2ndByteIn2Bytes(second)) { - len = 2; - - if (IsUDA1(first, second)) - uni = 0xE000 + (first - 0xAA) * 94 + (second - 0xA1); - else if (IsUDA2(first, second)) - uni = 0xE234 + (first - 0xF8) * 94 + (second - 0xA1); - else if (IsUDA3(first, second)) - uni = 0xE4C6 + (first - 0xA1) * 96 + (second - 0x40) - - ((second >= 0x80) ? 1 : 0); - else { - // Use the mapping table - unsigned i; - - i = (first - 0x81) * 190 + (second - 0x40) - - ((second >= 0x80) ? 1 : 0); - - if (first >= 0xA1 && first <= 0xA7) - i -= (first - 0xA0) * 96; - if (first > 0xA7) - i -= 672; - if (first >= 0xAA && first <= 0xAF) - i -= (first - 0xAA) * 94; - if (first > 0xAF) - i -= 564; - if (first >= 0xF8) - i -= (first - 0xF8) * 94; - - uni = (unsigned)gb18030_2byte_to_ucs[i]; - } - } - else if (Is2ndByteIn4Bytes(second) && len >= 4) { - uint8_t third = gbstr[2], - fourth = gbstr[3]; - - if (Is3rdByte(third) && Is4thByte(fourth)) { - // Valid 4-byte GB18030, whether defined or not - unsigned gb4lin; - indexTbl_t g2u; - - gb4lin = (first - 0x81) * 12600 + (second - 0x30) * 1260 - + (third - 0x81) * 10 + (fourth - 0x30); - - len = 4; - if (gb4lin <= 0x99FB) { - /* GB+81308130 - GB+8431A439 */ - g2u = gb18030_to_ucs_index[gb4lin >> 8]; - - if ((gb4lin & 0xFF) >= g2u.tblBegin && (gb4lin & 0xFF) <= g2u.tblEnd) { - uni = (unsigned)gb18030_4byte_to_ucs[gb4lin - g2u.tblOffset]; - } - else { - uni = g2u.algOffset + (gb4lin & 0xFF); - } - } - else if (gb4lin >= 0x2E248 && gb4lin <= 0x12E247) { - /* GB+90308130 - GB+E3329A35 */ - uni = gb4lin - 0xE248; - } - else { - /* undefined or reserved area */ - len = 1; - uni = REPLACEMENT; - } - } - else { - len = 1; - uni = REPLACEMENT; - } - } - else { - len = 1; - uni = REPLACEMENT; - } - } - else { - len = 1; - uni = REPLACEMENT; - } - return uni; -} - -void -GBTextDecoder::AppendGB18030(std::vector& result, const uint8_t* bytes, size_t length) -{ - uint8_t buf[4]; - int nbuf = 0; -// int invalid = 0; - - result.resize(length); - int unicodeLen = 0; - - for (size_t i = 0; i < length; i++) { - uint8_t ch = bytes[i]; - switch (nbuf) { - case 0: - if (ch < 128) { - // ASCII - result[unicodeLen++] = ch; - } - else if (Is1stByte(ch)) { - // GB18030? - buf[0] = ch; - nbuf = 1; - } - else { - // Invalid - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - } - break; - case 1: - // GB18030 2 bytes - if (Is2ndByteIn2Bytes(ch)) { - buf[1] = ch; - int clen = 2; - unsigned u = qt_Gb18030ToUnicode(buf, clen); - if (clen == 2) { - result[unicodeLen++] = ValidChar(u); - } - else { - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - } - nbuf = 0; - } - else if (Is2ndByteIn4Bytes(ch)) { - buf[1] = ch; - nbuf = 2; - } - else { - // Error - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - nbuf = 0; - } - break; - case 2: - // GB18030 3 bytes - if (Is3rdByte(ch)) { - buf[2] = ch; - nbuf = 3; - } - else { - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - nbuf = 0; - } - break; - case 3: - // GB18030 4 bytes - if (Is4thByte(ch)) { - buf[3] = ch; - int clen = 4; - unsigned u = qt_Gb18030ToUnicode(buf, clen); - if (clen == 4) { - result[unicodeLen++] = ValidChar(u); - } - else { - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - } - } - else { - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - } - nbuf = 0; - break; - } - } - result.resize(unicodeLen); -} - -void -GBTextDecoder::AppendGB2312(std::vector& result, const uint8_t* bytes, size_t length) -{ - uint8_t buf[2]; - int nbuf = 0; -// int invalid = 0; - - result.resize(length); - int unicodeLen = 0; - for (size_t i = 0; i= 0xA1 && ch <= 0xFE) { - // GB2312 1st byte? - buf[0] = ch; - nbuf = 1; - } - else { - // Invalid - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - } - break; - case 1: - // GB2312 2nd byte - if (ch >= 0xA1 && ch <= 0xFE) { - buf[1] = ch; - int clen = 2; - unsigned u = qt_Gb18030ToUnicode(buf, clen); - if (clen == 2) { - result[unicodeLen++] = ValidChar(u); - } - else { - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - } - nbuf = 0; - } - else { - // Error - result[unicodeLen++] = REPLACEMENT; -// ++invalid; - nbuf = 0; - } - break; - } - } - result.resize(unicodeLen); -} diff --git a/core/src/textcodec/GBTextDecoder.h b/core/src/textcodec/GBTextDecoder.h deleted file mode 100644 index 358fd7eaae..0000000000 --- a/core/src/textcodec/GBTextDecoder.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -class GBTextDecoder -{ -public: - static void AppendGB18030(std::vector& utf16, const uint8_t* bytes, size_t length); - static void AppendGB2312(std::vector& utf16, const uint8_t* bytes, size_t length); -}; diff --git a/core/src/textcodec/GBTextEncoder.cpp b/core/src/textcodec/GBTextEncoder.cpp deleted file mode 100644 index 8bbb84826d..0000000000 --- a/core/src/textcodec/GBTextEncoder.cpp +++ /dev/null @@ -1,4061 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "GBTextEncoder.h" -#include "TextUtfEncoding.h" - -struct indexTbl_t -{ - uint8_t tblBegin; - uint8_t tblEnd; - uint16_t tblOffset; - uint16_t algOffset; -}; - -static const indexTbl_t ucs_to_gb18030_index[256] = { - /* 0x00__ */ {0x80, 0xFF, 0x0080, 0x0000}, {0x00, 0xFF, 0x0080, 0x0000}, - /* 0x02__ */ {0x00, 0xFF, 0x0080, 0x0000}, {0x00, 0xFF, 0x0080, 0x0000}, - /* 0x04__ */ {0x00, 0x51, 0x0080, 0x02E2}, {0xFF, 0x00, 0x1C3E, 0x03E2}, - /* 0x06__ */ {0xFF, 0x00, 0x1C3E, 0x04E2}, {0xFF, 0x00, 0x1C3E, 0x05E2}, - /* 0x08__ */ {0xFF, 0x00, 0x1C3E, 0x06E2}, {0xFF, 0x00, 0x1C3E, 0x07E2}, - /* 0x0A__ */ {0xFF, 0x00, 0x1C3E, 0x08E2}, {0xFF, 0x00, 0x1C3E, 0x09E2}, - /* 0x0C__ */ {0xFF, 0x00, 0x1C3E, 0x0AE2}, {0xFF, 0x00, 0x1C3E, 0x0BE2}, - /* 0x0E__ */ {0xFF, 0x00, 0x1C3E, 0x0CE2}, {0xFF, 0x00, 0x1C3E, 0x0DE2}, - /* 0x10__ */ {0xFF, 0x00, 0x1C3E, 0x0EE2}, {0xFF, 0x00, 0x1C3E, 0x0FE2}, - /* 0x12__ */ {0xFF, 0x00, 0x1C3E, 0x10E2}, {0xFF, 0x00, 0x1C3E, 0x11E2}, - /* 0x14__ */ {0xFF, 0x00, 0x1C3E, 0x12E2}, {0xFF, 0x00, 0x1C3E, 0x13E2}, - /* 0x16__ */ {0xFF, 0x00, 0x1C3E, 0x14E2}, {0xFF, 0x00, 0x1C3E, 0x15E2}, - /* 0x18__ */ {0xFF, 0x00, 0x1C3E, 0x16E2}, {0xFF, 0x00, 0x1C3E, 0x17E2}, - /* 0x1A__ */ {0xFF, 0x00, 0x1C3E, 0x18E2}, {0xFF, 0x00, 0x1C3E, 0x19E2}, - /* 0x1C__ */ {0xFF, 0x00, 0x1C3E, 0x1AE2}, {0xFF, 0x00, 0x1C3E, 0x1BE2}, - /* 0x1E__ */ {0xFF, 0x00, 0x1C3E, 0x1CE2}, {0xFF, 0x00, 0x1C3E, 0x1DE2}, - /* 0x20__ */ {0x10, 0xFF, 0x1C3E, 0x1EE2}, {0x00, 0xFF, 0x1C3E, 0x0000}, - /* 0x22__ */ {0x00, 0xFF, 0x1C3E, 0x0000}, {0x00, 0xFF, 0x1C3E, 0x0000}, - /* 0x24__ */ {0x00, 0xFF, 0x1C3E, 0x0000}, {0x00, 0xFF, 0x1C3E, 0x0000}, - /* 0x26__ */ {0x00, 0x42, 0x1C3E, 0x23C0}, {0xFF, 0x00, 0x247C, 0x24C0}, - /* 0x28__ */ {0xFF, 0x00, 0x247C, 0x25C0}, {0xFF, 0x00, 0x247C, 0x26C0}, - /* 0x2A__ */ {0xFF, 0x00, 0x247C, 0x27C0}, {0xFF, 0x00, 0x247C, 0x28C0}, - /* 0x2C__ */ {0xFF, 0x00, 0x247C, 0x29C0}, {0xFF, 0x00, 0x247C, 0x2AC0}, - /* 0x2E__ */ {0x81, 0xFF, 0x247C, 0x2BC0}, {0x00, 0xFF, 0x247C, 0x0000}, - /* 0x30__ */ {0x00, 0xFF, 0x247C, 0x0000}, {0x00, 0xFF, 0x247C, 0x0000}, - /* 0x32__ */ {0x00, 0xFF, 0x247C, 0x0000}, {0x00, 0xFF, 0x247C, 0x0000}, - /* 0x34__ */ {0x00, 0xFF, 0x247C, 0x0000}, {0x00, 0xFF, 0x247C, 0x0000}, - /* 0x36__ */ {0x00, 0x1A, 0x247C, 0x3292}, {0xFF, 0x00, 0x2779, 0x3392}, - /* 0x38__ */ {0xFF, 0x00, 0x2779, 0x3492}, {0x18, 0xFF, 0x2779, 0x3592}, - /* 0x3A__ */ {0x00, 0xFF, 0x2779, 0x0000}, {0x00, 0xFF, 0x2779, 0x0000}, - /* 0x3C__ */ {0x00, 0xE0, 0x2779, 0x3889}, {0xFF, 0x00, 0x2AEE, 0x3989}, - /* 0x3E__ */ {0xFF, 0x00, 0x2AEE, 0x3A89}, {0xFF, 0x00, 0x2AEE, 0x3B89}, - /* 0x40__ */ {0x56, 0xFF, 0x2AEE, 0x3C89}, {0x00, 0x5F, 0x2AEE, 0x3D87}, - /* 0x42__ */ {0xFF, 0x00, 0x2CC5, 0x3E87}, {0x37, 0xFF, 0x2CC5, 0x3F87}, - /* 0x44__ */ {0x00, 0xD6, 0x2CC5, 0x4082}, {0xFF, 0x00, 0x2E3A, 0x4182}, - /* 0x46__ */ {0x4C, 0xFF, 0x2E3A, 0x4282}, {0x00, 0x8D, 0x2E3A, 0x437C}, - /* 0x48__ */ {0xFF, 0x00, 0x2FF3, 0x447C}, {0x47, 0xB7, 0x2FF3, 0x457C}, - /* 0x4A__ */ {0xFF, 0x00, 0x32B2, 0x4671}, {0xFF, 0x00, 0x32B2, 0x4771}, - /* 0x4C__ */ {0x77, 0xFF, 0x32B2, 0x4871}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x4E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x50__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x52__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x54__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x56__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x58__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x5A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x5C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x5E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x60__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x62__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x64__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x66__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x68__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x6A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x6C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x6E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x70__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x72__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x74__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x76__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x78__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x7A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x7C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x7E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x80__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x82__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x84__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x86__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x88__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x8A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x8C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x8E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x90__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x92__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x94__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x96__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x98__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x9A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x9C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000}, - /* 0x9E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xA5, 0x32B2, 0x49BD}, - /* 0xA0__ */ {0xFF, 0x00, 0x6B0C, 0x4ABD}, {0xFF, 0x00, 0x6B0C, 0x4BBD}, - /* 0xA2__ */ {0xFF, 0x00, 0x6B0C, 0x4CBD}, {0xFF, 0x00, 0x6B0C, 0x4DBD}, - /* 0xA4__ */ {0xFF, 0x00, 0x6B0C, 0x4EBD}, {0xFF, 0x00, 0x6B0C, 0x4FBD}, - /* 0xA6__ */ {0xFF, 0x00, 0x6B0C, 0x50BD}, {0xFF, 0x00, 0x6B0C, 0x51BD}, - /* 0xA8__ */ {0xFF, 0x00, 0x6B0C, 0x52BD}, {0xFF, 0x00, 0x6B0C, 0x53BD}, - /* 0xAA__ */ {0xFF, 0x00, 0x6B0C, 0x54BD}, {0xFF, 0x00, 0x6B0C, 0x55BD}, - /* 0xAC__ */ {0xFF, 0x00, 0x6B0C, 0x56BD}, {0xFF, 0x00, 0x6B0C, 0x57BD}, - /* 0xAE__ */ {0xFF, 0x00, 0x6B0C, 0x58BD}, {0xFF, 0x00, 0x6B0C, 0x59BD}, - /* 0xB0__ */ {0xFF, 0x00, 0x6B0C, 0x5ABD}, {0xFF, 0x00, 0x6B0C, 0x5BBD}, - /* 0xB2__ */ {0xFF, 0x00, 0x6B0C, 0x5CBD}, {0xFF, 0x00, 0x6B0C, 0x5DBD}, - /* 0xB4__ */ {0xFF, 0x00, 0x6B0C, 0x5EBD}, {0xFF, 0x00, 0x6B0C, 0x5FBD}, - /* 0xB6__ */ {0xFF, 0x00, 0x6B0C, 0x60BD}, {0xFF, 0x00, 0x6B0C, 0x61BD}, - /* 0xB8__ */ {0xFF, 0x00, 0x6B0C, 0x62BD}, {0xFF, 0x00, 0x6B0C, 0x63BD}, - /* 0xBA__ */ {0xFF, 0x00, 0x6B0C, 0x64BD}, {0xFF, 0x00, 0x6B0C, 0x65BD}, - /* 0xBC__ */ {0xFF, 0x00, 0x6B0C, 0x66BD}, {0xFF, 0x00, 0x6B0C, 0x67BD}, - /* 0xBE__ */ {0xFF, 0x00, 0x6B0C, 0x68BD}, {0xFF, 0x00, 0x6B0C, 0x69BD}, - /* 0xC0__ */ {0xFF, 0x00, 0x6B0C, 0x6ABD}, {0xFF, 0x00, 0x6B0C, 0x6BBD}, - /* 0xC2__ */ {0xFF, 0x00, 0x6B0C, 0x6CBD}, {0xFF, 0x00, 0x6B0C, 0x6DBD}, - /* 0xC4__ */ {0xFF, 0x00, 0x6B0C, 0x6EBD}, {0xFF, 0x00, 0x6B0C, 0x6FBD}, - /* 0xC6__ */ {0xFF, 0x00, 0x6B0C, 0x70BD}, {0xFF, 0x00, 0x6B0C, 0x71BD}, - /* 0xC8__ */ {0xFF, 0x00, 0x6B0C, 0x72BD}, {0xFF, 0x00, 0x6B0C, 0x73BD}, - /* 0xCA__ */ {0xFF, 0x00, 0x6B0C, 0x74BD}, {0xFF, 0x00, 0x6B0C, 0x75BD}, - /* 0xCC__ */ {0xFF, 0x00, 0x6B0C, 0x76BD}, {0xFF, 0x00, 0x6B0C, 0x77BD}, - /* 0xCE__ */ {0xFF, 0x00, 0x6B0C, 0x78BD}, {0xFF, 0x00, 0x6B0C, 0x79BD}, - /* 0xD0__ */ {0xFF, 0x00, 0x6B0C, 0x7ABD}, {0xFF, 0x00, 0x6B0C, 0x7BBD}, - /* 0xD2__ */ {0xFF, 0x00, 0x6B0C, 0x7CBD}, {0xFF, 0x00, 0x6B0C, 0x7DBD}, - /* 0xD4__ */ {0xFF, 0x00, 0x6B0C, 0x7EBD}, {0xFF, 0x00, 0x6B0C, 0x7FBD}, - /* 0xD6__ */ {0xFF, 0x00, 0x6B0C, 0x80BD}, {0xFF, 0x00, 0x6B0C, 0x81BD}, - /* 0xD8__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000}, - /* 0xDA__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000}, - /* 0xDC__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000}, - /* 0xDE__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000}, - /* 0xE0__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0xFF, 0x00, 0x7A72, 0x0000}, - /* 0xE2__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0xFF, 0x00, 0x7A72, 0x0000}, - /* 0xE4__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0xFF, 0x00, 0x7A72, 0x0000}, - /* 0xE6__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0x66, 0xFF, 0x7A72, 0x0000}, - /* 0xE8__ */ {0x00, 0x64, 0x7A72, 0x82A9}, {0xFF, 0x00, 0x8B39, 0x83A9}, - /* 0xEA__ */ {0xFF, 0x00, 0x8B39, 0x84A9}, {0xFF, 0x00, 0x8B39, 0x85A9}, - /* 0xEC__ */ {0xFF, 0x00, 0x8B39, 0x86A9}, {0xFF, 0x00, 0x8B39, 0x87A9}, - /* 0xEE__ */ {0xFF, 0x00, 0x8B39, 0x88A9}, {0xFF, 0x00, 0x8B39, 0x89A9}, - /* 0xF0__ */ {0xFF, 0x00, 0x8B39, 0x8AA9}, {0xFF, 0x00, 0x8B39, 0x8BA9}, - /* 0xF2__ */ {0xFF, 0x00, 0x8B39, 0x8CA9}, {0xFF, 0x00, 0x8B39, 0x8DA9}, - /* 0xF4__ */ {0xFF, 0x00, 0x8B39, 0x8EA9}, {0xFF, 0x00, 0x8B39, 0x8FA9}, - /* 0xF6__ */ {0xFF, 0x00, 0x8B39, 0x90A9}, {0xFF, 0x00, 0x8B39, 0x91A9}, - /* 0xF8__ */ {0xFF, 0x00, 0x8B39, 0x92A9}, {0x2C, 0xFF, 0x8B39, 0x93A9}, - /* 0xFA__ */ {0x00, 0x29, 0x8B39, 0x9494}, {0xFF, 0x00, 0x8F3F, 0x9594}, - /* 0xFC__ */ {0xFF, 0x00, 0x8F3F, 0x9694}, {0xFF, 0x00, 0x8F3F, 0x9794}, - /* 0xFE__ */ {0x30, 0xFF, 0x8F3F, 0x9894}, {0x00, 0xE5, 0x8F3F, 0x98FC}, -}; - -static const uint16_t ucs_to_gb18030[28839] = { - /* Contiguous area: U+0080 .. U+0451 */ - /* U+0080 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - /* U+0088 */ 0x0008, 0x0009, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, - /* U+0090 */ 0x0016, 0x0017, 0x0018, 0x0019, 0x0020, 0x0021, 0x0022, 0x0023, - /* U+0098 */ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x0030, 0x0031, - /* U+00A0 */ 0x0032, 0x0033, 0x0034, 0x0035, 0xA1E8, 0x0036, 0x0037, 0xA1EC, - /* U+00A8 */ 0xA1A7, 0x0038, 0x0039, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, - /* U+00B0 */ 0xA1E3, 0xA1C0, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0xA1A4, - /* U+00B8 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - /* U+00C0 */ 0x0058, 0x0059, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, - /* U+00C8 */ 0x0066, 0x0067, 0x0068, 0x0069, 0x0070, 0x0071, 0x0072, 0x0073, - /* U+00D0 */ 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x0080, 0xA1C1, - /* U+00D8 */ 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, - /* U+00E0 */ 0xA8A4, 0xA8A2, 0x0089, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, - /* U+00E8 */ 0xA8A8, 0xA8A6, 0xA8BA, 0x0095, 0xA8AC, 0xA8AA, 0x0096, 0x0097, - /* U+00F0 */ 0x0098, 0x0099, 0xA8B0, 0xA8AE, 0x00A0, 0x00A1, 0x00A2, 0xA1C2, - /* U+00F8 */ 0x00A3, 0xA8B4, 0xA8B2, 0x00A4, 0xA8B9, 0x00A5, 0x00A6, 0x00A7, - /* U+0100 */ 0x00A8, 0xA8A1, 0x00A9, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, - /* U+0108 */ 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00C0, 0x00C1, 0x00C2, - /* U+0110 */ 0x00C3, 0x00C4, 0x00C5, 0xA8A5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, - /* U+0118 */ 0x00D0, 0x00D1, 0x00D2, 0xA8A7, 0x00D3, 0x00D4, 0x00D5, 0x00D6, - /* U+0120 */ 0x00D7, 0x00D8, 0x00D9, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, - /* U+0128 */ 0x00E5, 0x00E6, 0x00E7, 0xA8A9, 0x00E8, 0x00E9, 0x00F0, 0x00F1, - /* U+0130 */ 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, - /* U+0138 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, - /* U+0140 */ 0x0108, 0x0109, 0x0110, 0x0111, 0xA8BD, 0x0112, 0x0113, 0x0114, - /* U+0148 */ 0xA8BE, 0x0115, 0x0116, 0x0117, 0x0118, 0xA8AD, 0x0119, 0x0120, - /* U+0150 */ 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127, 0x0128, - /* U+0158 */ 0x0129, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, - /* U+0160 */ 0x0137, 0x0138, 0x0139, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, - /* U+0168 */ 0x0145, 0x0146, 0x0147, 0xA8B1, 0x0148, 0x0149, 0x0150, 0x0151, - /* U+0170 */ 0x0152, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, - /* U+0178 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0166, 0x0167, - /* U+0180 */ 0x0168, 0x0169, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, - /* U+0188 */ 0x0176, 0x0177, 0x0178, 0x0179, 0x0180, 0x0181, 0x0182, 0x0183, - /* U+0190 */ 0x0184, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189, 0x0190, 0x0191, - /* U+0198 */ 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 0x0199, - /* U+01A0 */ 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4, 0x01A5, 0x01A6, 0x01A7, - /* U+01A8 */ 0x01A8, 0x01A9, 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5, - /* U+01B0 */ 0x01B6, 0x01B7, 0x01B8, 0x01B9, 0x01C0, 0x01C1, 0x01C2, 0x01C3, - /* U+01B8 */ 0x01C4, 0x01C5, 0x01C6, 0x01C7, 0x01C8, 0x01C9, 0x01D0, 0x01D1, - /* U+01C0 */ 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7, 0x01D8, 0x01D9, - /* U+01C8 */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5, 0xA8A3, 0x01E6, - /* U+01D0 */ 0xA8AB, 0x01E7, 0xA8AF, 0x01E8, 0xA8B3, 0x01E9, 0xA8B5, 0x01F0, - /* U+01D8 */ 0xA8B6, 0x01F1, 0xA8B7, 0x01F2, 0xA8B8, 0x01F3, 0x01F4, 0x01F5, - /* U+01E0 */ 0x01F6, 0x01F7, 0x01F8, 0x01F9, 0x0200, 0x0201, 0x0202, 0x0203, - /* U+01E8 */ 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209, 0x0210, 0x0211, - /* U+01F0 */ 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, - /* U+01F8 */ 0x0220, 0xA8BF, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226, - /* U+0200 */ 0x0227, 0x0228, 0x0229, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, - /* U+0208 */ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x0240, 0x0241, 0x0242, - /* U+0210 */ 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x0250, - /* U+0218 */ 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257, 0x0258, - /* U+0220 */ 0x0259, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, - /* U+0228 */ 0x0267, 0x0268, 0x0269, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, - /* U+0230 */ 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x0280, 0x0281, 0x0282, - /* U+0238 */ 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x0290, - /* U+0240 */ 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 0x0298, - /* U+0248 */ 0x0299, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6, - /* U+0250 */ 0x02A7, 0xA8BB, 0x02A8, 0x02A9, 0x02B0, 0x02B1, 0x02B2, 0x02B3, - /* U+0258 */ 0x02B4, 0x02B5, 0x02B6, 0x02B7, 0x02B8, 0x02B9, 0x02C0, 0x02C1, - /* U+0260 */ 0x02C2, 0xA8C0, 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C7, 0x02C8, - /* U+0268 */ 0x02C9, 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, - /* U+0270 */ 0x02D7, 0x02D8, 0x02D9, 0x02E0, 0x02E1, 0x02E2, 0x02E3, 0x02E4, - /* U+0278 */ 0x02E5, 0x02E6, 0x02E7, 0x02E8, 0x02E9, 0x02F0, 0x02F1, 0x02F2, - /* U+0280 */ 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7, 0x02F8, 0x02F9, 0x0300, - /* U+0288 */ 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, - /* U+0290 */ 0x0309, 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, - /* U+0298 */ 0x0317, 0x0318, 0x0319, 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, - /* U+02A0 */ 0x0325, 0x0326, 0x0327, 0x0328, 0x0329, 0x0330, 0x0331, 0x0332, - /* U+02A8 */ 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x0340, - /* U+02B0 */ 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347, 0x0348, - /* U+02B8 */ 0x0349, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, - /* U+02C0 */ 0x0357, 0x0358, 0x0359, 0x0360, 0x0361, 0x0362, 0x0363, 0xA1A6, - /* U+02C8 */ 0x0364, 0xA1A5, 0xA840, 0xA841, 0x0365, 0x0366, 0x0367, 0x0368, - /* U+02D0 */ 0x0369, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, - /* U+02D8 */ 0x0377, 0xA842, 0x0378, 0x0379, 0x0380, 0x0381, 0x0382, 0x0383, - /* U+02E0 */ 0x0384, 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x0390, 0x0391, - /* U+02E8 */ 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, - /* U+02F0 */ 0x03A0, 0x03A1, 0x03A2, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - /* U+02F8 */ 0x03A8, 0x03A9, 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, - /* U+0300 */ 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03C0, 0x03C1, 0x03C2, 0x03C3, - /* U+0308 */ 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03D0, 0x03D1, - /* U+0310 */ 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, 0x03D8, 0x03D9, - /* U+0318 */ 0x03E0, 0x03E1, 0x03E2, 0x03E3, 0x03E4, 0x03E5, 0x03E6, 0x03E7, - /* U+0320 */ 0x03E8, 0x03E9, 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, - /* U+0328 */ 0x03F6, 0x03F7, 0x03F8, 0x03F9, 0x0400, 0x0401, 0x0402, 0x0403, - /* U+0330 */ 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x0410, 0x0411, - /* U+0338 */ 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, - /* U+0340 */ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, - /* U+0348 */ 0x0428, 0x0429, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, - /* U+0350 */ 0x0436, 0x0437, 0x0438, 0x0439, 0x0440, 0x0441, 0x0442, 0x0443, - /* U+0358 */ 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x0450, 0x0451, - /* U+0360 */ 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, - /* U+0368 */ 0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467, - /* U+0370 */ 0x0468, 0x0469, 0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475, - /* U+0378 */ 0x0476, 0x0477, 0x0478, 0x0479, 0x0480, 0x0481, 0x0482, 0x0483, - /* U+0380 */ 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x0490, 0x0491, - /* U+0388 */ 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, - /* U+0390 */ 0x04A0, 0xA6A1, 0xA6A2, 0xA6A3, 0xA6A4, 0xA6A5, 0xA6A6, 0xA6A7, - /* U+0398 */ 0xA6A8, 0xA6A9, 0xA6AA, 0xA6AB, 0xA6AC, 0xA6AD, 0xA6AE, 0xA6AF, - /* U+03A0 */ 0xA6B0, 0xA6B1, 0x04A1, 0xA6B2, 0xA6B3, 0xA6B4, 0xA6B5, 0xA6B6, - /* U+03A8 */ 0xA6B7, 0xA6B8, 0x04A2, 0x04A3, 0x04A4, 0x04A5, 0x04A6, 0x04A7, - /* U+03B0 */ 0x04A8, 0xA6C1, 0xA6C2, 0xA6C3, 0xA6C4, 0xA6C5, 0xA6C6, 0xA6C7, - /* U+03B8 */ 0xA6C8, 0xA6C9, 0xA6CA, 0xA6CB, 0xA6CC, 0xA6CD, 0xA6CE, 0xA6CF, - /* U+03C0 */ 0xA6D0, 0xA6D1, 0x04A9, 0xA6D2, 0xA6D3, 0xA6D4, 0xA6D5, 0xA6D6, - /* U+03C8 */ 0xA6D7, 0xA6D8, 0x04B0, 0x04B1, 0x04B2, 0x04B3, 0x04B4, 0x04B5, - /* U+03D0 */ 0x04B6, 0x04B7, 0x04B8, 0x04B9, 0x04C0, 0x04C1, 0x04C2, 0x04C3, - /* U+03D8 */ 0x04C4, 0x04C5, 0x04C6, 0x04C7, 0x04C8, 0x04C9, 0x04D0, 0x04D1, - /* U+03E0 */ 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7, 0x04D8, 0x04D9, - /* U+03E8 */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7, - /* U+03F0 */ 0x04E8, 0x04E9, 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, - /* U+03F8 */ 0x04F6, 0x04F7, 0x04F8, 0x04F9, 0x0500, 0x0501, 0x0502, 0x0503, - /* U+0400 */ 0x0504, 0xA7A7, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509, 0x0510, - /* U+0408 */ 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, 0x0518, - /* U+0410 */ 0xA7A1, 0xA7A2, 0xA7A3, 0xA7A4, 0xA7A5, 0xA7A6, 0xA7A8, 0xA7A9, - /* U+0418 */ 0xA7AA, 0xA7AB, 0xA7AC, 0xA7AD, 0xA7AE, 0xA7AF, 0xA7B0, 0xA7B1, - /* U+0420 */ 0xA7B2, 0xA7B3, 0xA7B4, 0xA7B5, 0xA7B6, 0xA7B7, 0xA7B8, 0xA7B9, - /* U+0428 */ 0xA7BA, 0xA7BB, 0xA7BC, 0xA7BD, 0xA7BE, 0xA7BF, 0xA7C0, 0xA7C1, - /* U+0430 */ 0xA7D1, 0xA7D2, 0xA7D3, 0xA7D4, 0xA7D5, 0xA7D6, 0xA7D8, 0xA7D9, - /* U+0438 */ 0xA7DA, 0xA7DB, 0xA7DC, 0xA7DD, 0xA7DE, 0xA7DF, 0xA7E0, 0xA7E1, - /* U+0440 */ 0xA7E2, 0xA7E3, 0xA7E4, 0xA7E5, 0xA7E6, 0xA7E7, 0xA7E8, 0xA7E9, - /* U+0448 */ 0xA7EA, 0xA7EB, 0xA7EC, 0xA7ED, 0xA7EE, 0xA7EF, 0xA7F0, 0xA7F1, - /* U+0450 */ 0x0519, 0xA7D7, - /* Contiguous area: U+2010 .. U+2642 */ - /* U+2010 */ 0xA95C, 0x0A42, 0x0A43, 0xA843, 0xA1AA, 0xA844, 0xA1AC, 0x0A44, - /* U+2018 */ 0xA1AE, 0xA1AF, 0x0A45, 0x0A46, 0xA1B0, 0xA1B1, 0x0A47, 0x0A48, - /* U+2020 */ 0x0A49, 0x0A50, 0x0A51, 0x0A52, 0x0A53, 0xA845, 0xA1AD, 0x0A54, - /* U+2028 */ 0x0A55, 0x0A56, 0x0A57, 0x0A58, 0x0A59, 0x0A60, 0x0A61, 0x0A62, - /* U+2030 */ 0xA1EB, 0x0A63, 0xA1E4, 0xA1E5, 0x0A64, 0xA846, 0x0A65, 0x0A66, - /* U+2038 */ 0x0A67, 0x0A68, 0x0A69, 0xA1F9, 0x0A70, 0x0A71, 0x0A72, 0x0A73, - /* U+2040 */ 0x0A74, 0x0A75, 0x0A76, 0x0A77, 0x0A78, 0x0A79, 0x0A80, 0x0A81, - /* U+2048 */ 0x0A82, 0x0A83, 0x0A84, 0x0A85, 0x0A86, 0x0A87, 0x0A88, 0x0A89, - /* U+2050 */ 0x0A90, 0x0A91, 0x0A92, 0x0A93, 0x0A94, 0x0A95, 0x0A96, 0x0A97, - /* U+2058 */ 0x0A98, 0x0A99, 0x0AA0, 0x0AA1, 0x0AA2, 0x0AA3, 0x0AA4, 0x0AA5, - /* U+2060 */ 0x0AA6, 0x0AA7, 0x0AA8, 0x0AA9, 0x0AB0, 0x0AB1, 0x0AB2, 0x0AB3, - /* U+2068 */ 0x0AB4, 0x0AB5, 0x0AB6, 0x0AB7, 0x0AB8, 0x0AB9, 0x0AC0, 0x0AC1, - /* U+2070 */ 0x0AC2, 0x0AC3, 0x0AC4, 0x0AC5, 0x0AC6, 0x0AC7, 0x0AC8, 0x0AC9, - /* U+2078 */ 0x0AD0, 0x0AD1, 0x0AD2, 0x0AD3, 0x0AD4, 0x0AD5, 0x0AD6, 0x0AD7, - /* U+2080 */ 0x0AD8, 0x0AD9, 0x0AE0, 0x0AE1, 0x0AE2, 0x0AE3, 0x0AE4, 0x0AE5, - /* U+2088 */ 0x0AE6, 0x0AE7, 0x0AE8, 0x0AE9, 0x0AF0, 0x0AF1, 0x0AF2, 0x0AF3, - /* U+2090 */ 0x0AF4, 0x0AF5, 0x0AF6, 0x0AF7, 0x0AF8, 0x0AF9, 0x0B00, 0x0B01, - /* U+2098 */ 0x0B02, 0x0B03, 0x0B04, 0x0B05, 0x0B06, 0x0B07, 0x0B08, 0x0B09, - /* U+20A0 */ 0x0B10, 0x0B11, 0x0B12, 0x0B13, 0x0B14, 0x0B15, 0x0B16, 0x0B17, - /* U+20A8 */ 0x0B18, 0x0B19, 0x0B20, 0x0B21, 0xA2E3, 0x0B22, 0x0B23, 0x0B24, - /* U+20B0 */ 0x0B25, 0x0B26, 0x0B27, 0x0B28, 0x0B29, 0x0B30, 0x0B31, 0x0B32, - /* U+20B8 */ 0x0B33, 0x0B34, 0x0B35, 0x0B36, 0x0B37, 0x0B38, 0x0B39, 0x0B40, - /* U+20C0 */ 0x0B41, 0x0B42, 0x0B43, 0x0B44, 0x0B45, 0x0B46, 0x0B47, 0x0B48, - /* U+20C8 */ 0x0B49, 0x0B50, 0x0B51, 0x0B52, 0x0B53, 0x0B54, 0x0B55, 0x0B56, - /* U+20D0 */ 0x0B57, 0x0B58, 0x0B59, 0x0B60, 0x0B61, 0x0B62, 0x0B63, 0x0B64, - /* U+20D8 */ 0x0B65, 0x0B66, 0x0B67, 0x0B68, 0x0B69, 0x0B70, 0x0B71, 0x0B72, - /* U+20E0 */ 0x0B73, 0x0B74, 0x0B75, 0x0B76, 0x0B77, 0x0B78, 0x0B79, 0x0B80, - /* U+20E8 */ 0x0B81, 0x0B82, 0x0B83, 0x0B84, 0x0B85, 0x0B86, 0x0B87, 0x0B88, - /* U+20F0 */ 0x0B89, 0x0B90, 0x0B91, 0x0B92, 0x0B93, 0x0B94, 0x0B95, 0x0B96, - /* U+20F8 */ 0x0B97, 0x0B98, 0x0B99, 0x0BA0, 0x0BA1, 0x0BA2, 0x0BA3, 0x0BA4, - /* U+2100 */ 0x0BA5, 0x0BA6, 0x0BA7, 0xA1E6, 0x0BA8, 0xA847, 0x0BA9, 0x0BB0, - /* U+2108 */ 0x0BB1, 0xA848, 0x0BB2, 0x0BB3, 0x0BB4, 0x0BB5, 0x0BB6, 0x0BB7, - /* U+2110 */ 0x0BB8, 0x0BB9, 0x0BC0, 0x0BC1, 0x0BC2, 0x0BC3, 0xA1ED, 0x0BC4, - /* U+2118 */ 0x0BC5, 0x0BC6, 0x0BC7, 0x0BC8, 0x0BC9, 0x0BD0, 0x0BD1, 0x0BD2, - /* U+2120 */ 0x0BD3, 0xA959, 0x0BD4, 0x0BD5, 0x0BD6, 0x0BD7, 0x0BD8, 0x0BD9, - /* U+2128 */ 0x0BE0, 0x0BE1, 0x0BE2, 0x0BE3, 0x0BE4, 0x0BE5, 0x0BE6, 0x0BE7, - /* U+2130 */ 0x0BE8, 0x0BE9, 0x0BF0, 0x0BF1, 0x0BF2, 0x0BF3, 0x0BF4, 0x0BF5, - /* U+2138 */ 0x0BF6, 0x0BF7, 0x0BF8, 0x0BF9, 0x0C00, 0x0C01, 0x0C02, 0x0C03, - /* U+2140 */ 0x0C04, 0x0C05, 0x0C06, 0x0C07, 0x0C08, 0x0C09, 0x0C10, 0x0C11, - /* U+2148 */ 0x0C12, 0x0C13, 0x0C14, 0x0C15, 0x0C16, 0x0C17, 0x0C18, 0x0C19, - /* U+2150 */ 0x0C20, 0x0C21, 0x0C22, 0x0C23, 0x0C24, 0x0C25, 0x0C26, 0x0C27, - /* U+2158 */ 0x0C28, 0x0C29, 0x0C30, 0x0C31, 0x0C32, 0x0C33, 0x0C34, 0x0C35, - /* U+2160 */ 0xA2F1, 0xA2F2, 0xA2F3, 0xA2F4, 0xA2F5, 0xA2F6, 0xA2F7, 0xA2F8, - /* U+2168 */ 0xA2F9, 0xA2FA, 0xA2FB, 0xA2FC, 0x0C36, 0x0C37, 0x0C38, 0x0C39, - /* U+2170 */ 0xA2A1, 0xA2A2, 0xA2A3, 0xA2A4, 0xA2A5, 0xA2A6, 0xA2A7, 0xA2A8, - /* U+2178 */ 0xA2A9, 0xA2AA, 0x0C40, 0x0C41, 0x0C42, 0x0C43, 0x0C44, 0x0C45, - /* U+2180 */ 0x0C46, 0x0C47, 0x0C48, 0x0C49, 0x0C50, 0x0C51, 0x0C52, 0x0C53, - /* U+2188 */ 0x0C54, 0x0C55, 0x0C56, 0x0C57, 0x0C58, 0x0C59, 0x0C60, 0x0C61, - /* U+2190 */ 0xA1FB, 0xA1FC, 0xA1FA, 0xA1FD, 0x0C62, 0x0C63, 0xA849, 0xA84A, - /* U+2198 */ 0xA84B, 0xA84C, 0x0C64, 0x0C65, 0x0C66, 0x0C67, 0x0C68, 0x0C69, - /* U+21A0 */ 0x0C70, 0x0C71, 0x0C72, 0x0C73, 0x0C74, 0x0C75, 0x0C76, 0x0C77, - /* U+21A8 */ 0x0C78, 0x0C79, 0x0C80, 0x0C81, 0x0C82, 0x0C83, 0x0C84, 0x0C85, - /* U+21B0 */ 0x0C86, 0x0C87, 0x0C88, 0x0C89, 0x0C90, 0x0C91, 0x0C92, 0x0C93, - /* U+21B8 */ 0x0C94, 0x0C95, 0x0C96, 0x0C97, 0x0C98, 0x0C99, 0x0CA0, 0x0CA1, - /* U+21C0 */ 0x0CA2, 0x0CA3, 0x0CA4, 0x0CA5, 0x0CA6, 0x0CA7, 0x0CA8, 0x0CA9, - /* U+21C8 */ 0x0CB0, 0x0CB1, 0x0CB2, 0x0CB3, 0x0CB4, 0x0CB5, 0x0CB6, 0x0CB7, - /* U+21D0 */ 0x0CB8, 0x0CB9, 0x0CC0, 0x0CC1, 0x0CC2, 0x0CC3, 0x0CC4, 0x0CC5, - /* U+21D8 */ 0x0CC6, 0x0CC7, 0x0CC8, 0x0CC9, 0x0CD0, 0x0CD1, 0x0CD2, 0x0CD3, - /* U+21E0 */ 0x0CD4, 0x0CD5, 0x0CD6, 0x0CD7, 0x0CD8, 0x0CD9, 0x0CE0, 0x0CE1, - /* U+21E8 */ 0x0CE2, 0x0CE3, 0x0CE4, 0x0CE5, 0x0CE6, 0x0CE7, 0x0CE8, 0x0CE9, - /* U+21F0 */ 0x0CF0, 0x0CF1, 0x0CF2, 0x0CF3, 0x0CF4, 0x0CF5, 0x0CF6, 0x0CF7, - /* U+21F8 */ 0x0CF8, 0x0CF9, 0x0D00, 0x0D01, 0x0D02, 0x0D03, 0x0D04, 0x0D05, - /* U+2200 */ 0x0D06, 0x0D07, 0x0D08, 0x0D09, 0x0D10, 0x0D11, 0x0D12, 0x0D13, - /* U+2208 */ 0xA1CA, 0x0D14, 0x0D15, 0x0D16, 0x0D17, 0x0D18, 0x0D19, 0xA1C7, - /* U+2210 */ 0x0D20, 0xA1C6, 0x0D21, 0x0D22, 0x0D23, 0xA84D, 0x0D24, 0x0D25, - /* U+2218 */ 0x0D26, 0x0D27, 0xA1CC, 0x0D28, 0x0D29, 0xA1D8, 0xA1DE, 0xA84E, - /* U+2220 */ 0xA1CF, 0x0D30, 0x0D31, 0xA84F, 0x0D32, 0xA1CE, 0x0D33, 0xA1C4, - /* U+2228 */ 0xA1C5, 0xA1C9, 0xA1C8, 0xA1D2, 0x0D34, 0x0D35, 0xA1D3, 0x0D36, - /* U+2230 */ 0x0D37, 0x0D38, 0x0D39, 0x0D40, 0xA1E0, 0xA1DF, 0xA1C3, 0xA1CB, - /* U+2238 */ 0x0D41, 0x0D42, 0x0D43, 0x0D44, 0x0D45, 0xA1D7, 0x0D46, 0x0D47, - /* U+2240 */ 0x0D48, 0x0D49, 0x0D50, 0x0D51, 0x0D52, 0x0D53, 0x0D54, 0x0D55, - /* U+2248 */ 0xA1D6, 0x0D56, 0x0D57, 0x0D58, 0xA1D5, 0x0D59, 0x0D60, 0x0D61, - /* U+2250 */ 0x0D62, 0x0D63, 0xA850, 0x0D64, 0x0D65, 0x0D66, 0x0D67, 0x0D68, - /* U+2258 */ 0x0D69, 0x0D70, 0x0D71, 0x0D72, 0x0D73, 0x0D74, 0x0D75, 0x0D76, - /* U+2260 */ 0xA1D9, 0xA1D4, 0x0D77, 0x0D78, 0xA1DC, 0xA1DD, 0xA851, 0xA852, - /* U+2268 */ 0x0D79, 0x0D80, 0x0D81, 0x0D82, 0x0D83, 0x0D84, 0xA1DA, 0xA1DB, - /* U+2270 */ 0x0D85, 0x0D86, 0x0D87, 0x0D88, 0x0D89, 0x0D90, 0x0D91, 0x0D92, - /* U+2278 */ 0x0D93, 0x0D94, 0x0D95, 0x0D96, 0x0D97, 0x0D98, 0x0D99, 0x0DA0, - /* U+2280 */ 0x0DA1, 0x0DA2, 0x0DA3, 0x0DA4, 0x0DA5, 0x0DA6, 0x0DA7, 0x0DA8, - /* U+2288 */ 0x0DA9, 0x0DB0, 0x0DB1, 0x0DB2, 0x0DB3, 0x0DB4, 0x0DB5, 0x0DB6, - /* U+2290 */ 0x0DB7, 0x0DB8, 0x0DB9, 0x0DC0, 0x0DC1, 0xA892, 0x0DC2, 0x0DC3, - /* U+2298 */ 0x0DC4, 0xA1D1, 0x0DC5, 0x0DC6, 0x0DC7, 0x0DC8, 0x0DC9, 0x0DD0, - /* U+22A0 */ 0x0DD1, 0x0DD2, 0x0DD3, 0x0DD4, 0x0DD5, 0xA1CD, 0x0DD6, 0x0DD7, - /* U+22A8 */ 0x0DD8, 0x0DD9, 0x0DE0, 0x0DE1, 0x0DE2, 0x0DE3, 0x0DE4, 0x0DE5, - /* U+22B0 */ 0x0DE6, 0x0DE7, 0x0DE8, 0x0DE9, 0x0DF0, 0x0DF1, 0x0DF2, 0x0DF3, - /* U+22B8 */ 0x0DF4, 0x0DF5, 0x0DF6, 0x0DF7, 0x0DF8, 0x0DF9, 0x0E00, 0xA853, - /* U+22C0 */ 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, - /* U+22C8 */ 0x0E09, 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, - /* U+22D0 */ 0x0E17, 0x0E18, 0x0E19, 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, - /* U+22D8 */ 0x0E25, 0x0E26, 0x0E27, 0x0E28, 0x0E29, 0x0E30, 0x0E31, 0x0E32, - /* U+22E0 */ 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E40, - /* U+22E8 */ 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, - /* U+22F0 */ 0x0E49, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, - /* U+22F8 */ 0x0E57, 0x0E58, 0x0E59, 0x0E60, 0x0E61, 0x0E62, 0x0E63, 0x0E64, - /* U+2300 */ 0x0E65, 0x0E66, 0x0E67, 0x0E68, 0x0E69, 0x0E70, 0x0E71, 0x0E72, - /* U+2308 */ 0x0E73, 0x0E74, 0x0E75, 0x0E76, 0x0E77, 0x0E78, 0x0E79, 0x0E80, - /* U+2310 */ 0x0E81, 0x0E82, 0xA1D0, 0x0E83, 0x0E84, 0x0E85, 0x0E86, 0x0E87, - /* U+2318 */ 0x0E88, 0x0E89, 0x0E90, 0x0E91, 0x0E92, 0x0E93, 0x0E94, 0x0E95, - /* U+2320 */ 0x0E96, 0x0E97, 0x0E98, 0x0E99, 0x0EA0, 0x0EA1, 0x0EA2, 0x0EA3, - /* U+2328 */ 0x0EA4, 0x0EA5, 0x0EA6, 0x0EA7, 0x0EA8, 0x0EA9, 0x0EB0, 0x0EB1, - /* U+2330 */ 0x0EB2, 0x0EB3, 0x0EB4, 0x0EB5, 0x0EB6, 0x0EB7, 0x0EB8, 0x0EB9, - /* U+2338 */ 0x0EC0, 0x0EC1, 0x0EC2, 0x0EC3, 0x0EC4, 0x0EC5, 0x0EC6, 0x0EC7, - /* U+2340 */ 0x0EC8, 0x0EC9, 0x0ED0, 0x0ED1, 0x0ED2, 0x0ED3, 0x0ED4, 0x0ED5, - /* U+2348 */ 0x0ED6, 0x0ED7, 0x0ED8, 0x0ED9, 0x0EE0, 0x0EE1, 0x0EE2, 0x0EE3, - /* U+2350 */ 0x0EE4, 0x0EE5, 0x0EE6, 0x0EE7, 0x0EE8, 0x0EE9, 0x0EF0, 0x0EF1, - /* U+2358 */ 0x0EF2, 0x0EF3, 0x0EF4, 0x0EF5, 0x0EF6, 0x0EF7, 0x0EF8, 0x0EF9, - /* U+2360 */ 0x0F00, 0x0F01, 0x0F02, 0x0F03, 0x0F04, 0x0F05, 0x0F06, 0x0F07, - /* U+2368 */ 0x0F08, 0x0F09, 0x0F10, 0x0F11, 0x0F12, 0x0F13, 0x0F14, 0x0F15, - /* U+2370 */ 0x0F16, 0x0F17, 0x0F18, 0x0F19, 0x0F20, 0x0F21, 0x0F22, 0x0F23, - /* U+2378 */ 0x0F24, 0x0F25, 0x0F26, 0x0F27, 0x0F28, 0x0F29, 0x0F30, 0x0F31, - /* U+2380 */ 0x0F32, 0x0F33, 0x0F34, 0x0F35, 0x0F36, 0x0F37, 0x0F38, 0x0F39, - /* U+2388 */ 0x0F40, 0x0F41, 0x0F42, 0x0F43, 0x0F44, 0x0F45, 0x0F46, 0x0F47, - /* U+2390 */ 0x0F48, 0x0F49, 0x0F50, 0x0F51, 0x0F52, 0x0F53, 0x0F54, 0x0F55, - /* U+2398 */ 0x0F56, 0x0F57, 0x0F58, 0x0F59, 0x0F60, 0x0F61, 0x0F62, 0x0F63, - /* U+23A0 */ 0x0F64, 0x0F65, 0x0F66, 0x0F67, 0x0F68, 0x0F69, 0x0F70, 0x0F71, - /* U+23A8 */ 0x0F72, 0x0F73, 0x0F74, 0x0F75, 0x0F76, 0x0F77, 0x0F78, 0x0F79, - /* U+23B0 */ 0x0F80, 0x0F81, 0x0F82, 0x0F83, 0x0F84, 0x0F85, 0x0F86, 0x0F87, - /* U+23B8 */ 0x0F88, 0x0F89, 0x0F90, 0x0F91, 0x0F92, 0x0F93, 0x0F94, 0x0F95, - /* U+23C0 */ 0x0F96, 0x0F97, 0x0F98, 0x0F99, 0x0FA0, 0x0FA1, 0x0FA2, 0x0FA3, - /* U+23C8 */ 0x0FA4, 0x0FA5, 0x0FA6, 0x0FA7, 0x0FA8, 0x0FA9, 0x0FB0, 0x0FB1, - /* U+23D0 */ 0x0FB2, 0x0FB3, 0x0FB4, 0x0FB5, 0x0FB6, 0x0FB7, 0x0FB8, 0x0FB9, - /* U+23D8 */ 0x0FC0, 0x0FC1, 0x0FC2, 0x0FC3, 0x0FC4, 0x0FC5, 0x0FC6, 0x0FC7, - /* U+23E0 */ 0x0FC8, 0x0FC9, 0x0FD0, 0x0FD1, 0x0FD2, 0x0FD3, 0x0FD4, 0x0FD5, - /* U+23E8 */ 0x0FD6, 0x0FD7, 0x0FD8, 0x0FD9, 0x1000, 0x1001, 0x1002, 0x1003, - /* U+23F0 */ 0x1004, 0x1005, 0x1006, 0x1007, 0x1008, 0x1009, 0x1010, 0x1011, - /* U+23F8 */ 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017, 0x1018, 0x1019, - /* U+2400 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, - /* U+2408 */ 0x1028, 0x1029, 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, - /* U+2410 */ 0x1036, 0x1037, 0x1038, 0x1039, 0x1040, 0x1041, 0x1042, 0x1043, - /* U+2418 */ 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049, 0x1050, 0x1051, - /* U+2420 */ 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 0x1058, 0x1059, - /* U+2428 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067, - /* U+2430 */ 0x1068, 0x1069, 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, - /* U+2438 */ 0x1076, 0x1077, 0x1078, 0x1079, 0x1080, 0x1081, 0x1082, 0x1083, - /* U+2440 */ 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, 0x1089, 0x1090, 0x1091, - /* U+2448 */ 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097, 0x1098, 0x1099, - /* U+2450 */ 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x10A4, 0x10A5, 0x10A6, 0x10A7, - /* U+2458 */ 0x10A8, 0x10A9, 0x10B0, 0x10B1, 0x10B2, 0x10B3, 0x10B4, 0x10B5, - /* U+2460 */ 0xA2D9, 0xA2DA, 0xA2DB, 0xA2DC, 0xA2DD, 0xA2DE, 0xA2DF, 0xA2E0, - /* U+2468 */ 0xA2E1, 0xA2E2, 0x10B6, 0x10B7, 0x10B8, 0x10B9, 0x10C0, 0x10C1, - /* U+2470 */ 0x10C2, 0x10C3, 0x10C4, 0x10C5, 0xA2C5, 0xA2C6, 0xA2C7, 0xA2C8, - /* U+2478 */ 0xA2C9, 0xA2CA, 0xA2CB, 0xA2CC, 0xA2CD, 0xA2CE, 0xA2CF, 0xA2D0, - /* U+2480 */ 0xA2D1, 0xA2D2, 0xA2D3, 0xA2D4, 0xA2D5, 0xA2D6, 0xA2D7, 0xA2D8, - /* U+2488 */ 0xA2B1, 0xA2B2, 0xA2B3, 0xA2B4, 0xA2B5, 0xA2B6, 0xA2B7, 0xA2B8, - /* U+2490 */ 0xA2B9, 0xA2BA, 0xA2BB, 0xA2BC, 0xA2BD, 0xA2BE, 0xA2BF, 0xA2C0, - /* U+2498 */ 0xA2C1, 0xA2C2, 0xA2C3, 0xA2C4, 0x10C6, 0x10C7, 0x10C8, 0x10C9, - /* U+24A0 */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7, - /* U+24A8 */ 0x10D8, 0x10D9, 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, - /* U+24B0 */ 0x10E6, 0x10E7, 0x10E8, 0x10E9, 0x10F0, 0x10F1, 0x10F2, 0x10F3, - /* U+24B8 */ 0x10F4, 0x10F5, 0x10F6, 0x10F7, 0x10F8, 0x10F9, 0x1100, 0x1101, - /* U+24C0 */ 0x1102, 0x1103, 0x1104, 0x1105, 0x1106, 0x1107, 0x1108, 0x1109, - /* U+24C8 */ 0x1110, 0x1111, 0x1112, 0x1113, 0x1114, 0x1115, 0x1116, 0x1117, - /* U+24D0 */ 0x1118, 0x1119, 0x1120, 0x1121, 0x1122, 0x1123, 0x1124, 0x1125, - /* U+24D8 */ 0x1126, 0x1127, 0x1128, 0x1129, 0x1130, 0x1131, 0x1132, 0x1133, - /* U+24E0 */ 0x1134, 0x1135, 0x1136, 0x1137, 0x1138, 0x1139, 0x1140, 0x1141, - /* U+24E8 */ 0x1142, 0x1143, 0x1144, 0x1145, 0x1146, 0x1147, 0x1148, 0x1149, - /* U+24F0 */ 0x1150, 0x1151, 0x1152, 0x1153, 0x1154, 0x1155, 0x1156, 0x1157, - /* U+24F8 */ 0x1158, 0x1159, 0x1160, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165, - /* U+2500 */ 0xA9A4, 0xA9A5, 0xA9A6, 0xA9A7, 0xA9A8, 0xA9A9, 0xA9AA, 0xA9AB, - /* U+2508 */ 0xA9AC, 0xA9AD, 0xA9AE, 0xA9AF, 0xA9B0, 0xA9B1, 0xA9B2, 0xA9B3, - /* U+2510 */ 0xA9B4, 0xA9B5, 0xA9B6, 0xA9B7, 0xA9B8, 0xA9B9, 0xA9BA, 0xA9BB, - /* U+2518 */ 0xA9BC, 0xA9BD, 0xA9BE, 0xA9BF, 0xA9C0, 0xA9C1, 0xA9C2, 0xA9C3, - /* U+2520 */ 0xA9C4, 0xA9C5, 0xA9C6, 0xA9C7, 0xA9C8, 0xA9C9, 0xA9CA, 0xA9CB, - /* U+2528 */ 0xA9CC, 0xA9CD, 0xA9CE, 0xA9CF, 0xA9D0, 0xA9D1, 0xA9D2, 0xA9D3, - /* U+2530 */ 0xA9D4, 0xA9D5, 0xA9D6, 0xA9D7, 0xA9D8, 0xA9D9, 0xA9DA, 0xA9DB, - /* U+2538 */ 0xA9DC, 0xA9DD, 0xA9DE, 0xA9DF, 0xA9E0, 0xA9E1, 0xA9E2, 0xA9E3, - /* U+2540 */ 0xA9E4, 0xA9E5, 0xA9E6, 0xA9E7, 0xA9E8, 0xA9E9, 0xA9EA, 0xA9EB, - /* U+2548 */ 0xA9EC, 0xA9ED, 0xA9EE, 0xA9EF, 0x1166, 0x1167, 0x1168, 0x1169, - /* U+2550 */ 0xA854, 0xA855, 0xA856, 0xA857, 0xA858, 0xA859, 0xA85A, 0xA85B, - /* U+2558 */ 0xA85C, 0xA85D, 0xA85E, 0xA85F, 0xA860, 0xA861, 0xA862, 0xA863, - /* U+2560 */ 0xA864, 0xA865, 0xA866, 0xA867, 0xA868, 0xA869, 0xA86A, 0xA86B, - /* U+2568 */ 0xA86C, 0xA86D, 0xA86E, 0xA86F, 0xA870, 0xA871, 0xA872, 0xA873, - /* U+2570 */ 0xA874, 0xA875, 0xA876, 0xA877, 0x1170, 0x1171, 0x1172, 0x1173, - /* U+2578 */ 0x1174, 0x1175, 0x1176, 0x1177, 0x1178, 0x1179, 0x1180, 0x1181, - /* U+2580 */ 0x1182, 0xA878, 0xA879, 0xA87A, 0xA87B, 0xA87C, 0xA87D, 0xA87E, - /* U+2588 */ 0xA880, 0xA881, 0xA882, 0xA883, 0xA884, 0xA885, 0xA886, 0xA887, - /* U+2590 */ 0x1183, 0x1184, 0x1185, 0xA888, 0xA889, 0xA88A, 0x1186, 0x1187, - /* U+2598 */ 0x1188, 0x1189, 0x1190, 0x1191, 0x1192, 0x1193, 0x1194, 0x1195, - /* U+25A0 */ 0xA1F6, 0xA1F5, 0x1196, 0x1197, 0x1198, 0x1199, 0x11A0, 0x11A1, - /* U+25A8 */ 0x11A2, 0x11A3, 0x11A4, 0x11A5, 0x11A6, 0x11A7, 0x11A8, 0x11A9, - /* U+25B0 */ 0x11B0, 0x11B1, 0xA1F8, 0xA1F7, 0x11B2, 0x11B3, 0x11B4, 0x11B5, - /* U+25B8 */ 0x11B6, 0x11B7, 0x11B8, 0x11B9, 0xA88B, 0xA88C, 0x11C0, 0x11C1, - /* U+25C0 */ 0x11C2, 0x11C3, 0x11C4, 0x11C5, 0x11C6, 0x11C7, 0xA1F4, 0xA1F3, - /* U+25C8 */ 0x11C8, 0x11C9, 0x11D0, 0xA1F0, 0x11D1, 0x11D2, 0xA1F2, 0xA1F1, - /* U+25D0 */ 0x11D3, 0x11D4, 0x11D5, 0x11D6, 0x11D7, 0x11D8, 0x11D9, 0x11E0, - /* U+25D8 */ 0x11E1, 0x11E2, 0x11E3, 0x11E4, 0x11E5, 0x11E6, 0x11E7, 0x11E8, - /* U+25E0 */ 0x11E9, 0x11F0, 0xA88D, 0xA88E, 0xA88F, 0xA890, 0x11F1, 0x11F2, - /* U+25E8 */ 0x11F3, 0x11F4, 0x11F5, 0x11F6, 0x11F7, 0x11F8, 0x11F9, 0x1200, - /* U+25F0 */ 0x1201, 0x1202, 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1208, - /* U+25F8 */ 0x1209, 0x1210, 0x1211, 0x1212, 0x1213, 0x1214, 0x1215, 0x1216, - /* U+2600 */ 0x1217, 0x1218, 0x1219, 0x1220, 0x1221, 0xA1EF, 0xA1EE, 0x1222, - /* U+2608 */ 0x1223, 0xA891, 0x1224, 0x1225, 0x1226, 0x1227, 0x1228, 0x1229, - /* U+2610 */ 0x1230, 0x1231, 0x1232, 0x1233, 0x1234, 0x1235, 0x1236, 0x1237, - /* U+2618 */ 0x1238, 0x1239, 0x1240, 0x1241, 0x1242, 0x1243, 0x1244, 0x1245, - /* U+2620 */ 0x1246, 0x1247, 0x1248, 0x1249, 0x1250, 0x1251, 0x1252, 0x1253, - /* U+2628 */ 0x1254, 0x1255, 0x1256, 0x1257, 0x1258, 0x1259, 0x1260, 0x1261, - /* U+2630 */ 0x1262, 0x1263, 0x1264, 0x1265, 0x1266, 0x1267, 0x1268, 0x1269, - /* U+2638 */ 0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1276, 0x1277, - /* U+2640 */ 0xA1E2, 0x1278, 0xA1E1, - /* Contiguous area: U+2E81 .. U+361A */ - /* U+2E81 */ 0xFE50, 0x1FC9, 0x1FD0, 0xFE54, 0x1FD1, 0x1FD2, 0x1FD3, - /* U+2E88 */ 0xFE57, 0x1FD4, 0x1FD5, 0xFE58, 0xFE5D, 0x1FD6, 0x1FD7, 0x1FD8, - /* U+2E90 */ 0x1FD9, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0xFE5E, - /* U+2E98 */ 0x2006, 0x2007, 0x2008, 0x2009, 0x2010, 0x2011, 0x2012, 0x2013, - /* U+2EA0 */ 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, 0x2019, 0x2020, 0xFE6B, - /* U+2EA8 */ 0x2021, 0x2022, 0xFE6E, 0x2023, 0x2024, 0x2025, 0xFE71, 0x2026, - /* U+2EB0 */ 0x2027, 0x2028, 0x2029, 0xFE73, 0x2030, 0x2031, 0xFE74, 0xFE75, - /* U+2EB8 */ 0x2032, 0x2033, 0x2034, 0xFE79, 0x2035, 0x2036, 0x2037, 0x2038, - /* U+2EC0 */ 0x2039, 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, - /* U+2EC8 */ 0x2047, 0x2048, 0xFE84, 0x2049, 0x2050, 0x2051, 0x2052, 0x2053, - /* U+2ED0 */ 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, 0x2059, 0x2060, 0x2061, - /* U+2ED8 */ 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, 0x2069, - /* U+2EE0 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, - /* U+2EE8 */ 0x2078, 0x2079, 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, - /* U+2EF0 */ 0x2086, 0x2087, 0x2088, 0x2089, 0x2090, 0x2091, 0x2092, 0x2093, - /* U+2EF8 */ 0x2094, 0x2095, 0x2096, 0x2097, 0x2098, 0x2099, 0x20A0, 0x20A1, - /* U+2F00 */ 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7, 0x20A8, 0x20A9, - /* U+2F08 */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7, - /* U+2F10 */ 0x20B8, 0x20B9, 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, - /* U+2F18 */ 0x20C6, 0x20C7, 0x20C8, 0x20C9, 0x20D0, 0x20D1, 0x20D2, 0x20D3, - /* U+2F20 */ 0x20D4, 0x20D5, 0x20D6, 0x20D7, 0x20D8, 0x20D9, 0x20E0, 0x20E1, - /* U+2F28 */ 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7, 0x20E8, 0x20E9, - /* U+2F30 */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7, - /* U+2F38 */ 0x20F8, 0x20F9, 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, - /* U+2F40 */ 0x2106, 0x2107, 0x2108, 0x2109, 0x2110, 0x2111, 0x2112, 0x2113, - /* U+2F48 */ 0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x2120, 0x2121, - /* U+2F50 */ 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, 0x2128, 0x2129, - /* U+2F58 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, - /* U+2F60 */ 0x2138, 0x2139, 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, - /* U+2F68 */ 0x2146, 0x2147, 0x2148, 0x2149, 0x2150, 0x2151, 0x2152, 0x2153, - /* U+2F70 */ 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x2160, 0x2161, - /* U+2F78 */ 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, - /* U+2F80 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, - /* U+2F88 */ 0x2178, 0x2179, 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, - /* U+2F90 */ 0x2186, 0x2187, 0x2188, 0x2189, 0x2190, 0x2191, 0x2192, 0x2193, - /* U+2F98 */ 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21A0, 0x21A1, - /* U+2FA0 */ 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7, 0x21A8, 0x21A9, - /* U+2FA8 */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7, - /* U+2FB0 */ 0x21B8, 0x21B9, 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, - /* U+2FB8 */ 0x21C6, 0x21C7, 0x21C8, 0x21C9, 0x21D0, 0x21D1, 0x21D2, 0x21D3, - /* U+2FC0 */ 0x21D4, 0x21D5, 0x21D6, 0x21D7, 0x21D8, 0x21D9, 0x21E0, 0x21E1, - /* U+2FC8 */ 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7, 0x21E8, 0x21E9, - /* U+2FD0 */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7, - /* U+2FD8 */ 0x21F8, 0x21F9, 0x2200, 0x2201, 0x2202, 0x2203, 0x2204, 0x2205, - /* U+2FE0 */ 0x2206, 0x2207, 0x2208, 0x2209, 0x2210, 0x2211, 0x2212, 0x2213, - /* U+2FE8 */ 0x2214, 0x2215, 0x2216, 0x2217, 0x2218, 0x2219, 0x2220, 0x2221, - /* U+2FF0 */ 0xA98A, 0xA98B, 0xA98C, 0xA98D, 0xA98E, 0xA98F, 0xA990, 0xA991, - /* U+2FF8 */ 0xA992, 0xA993, 0xA994, 0xA995, 0x2222, 0x2223, 0x2224, 0x2225, - /* U+3000 */ 0xA1A1, 0xA1A2, 0xA1A3, 0xA1A8, 0x2226, 0xA1A9, 0xA965, 0xA996, - /* U+3008 */ 0xA1B4, 0xA1B5, 0xA1B6, 0xA1B7, 0xA1B8, 0xA1B9, 0xA1BA, 0xA1BB, - /* U+3010 */ 0xA1BE, 0xA1BF, 0xA893, 0xA1FE, 0xA1B2, 0xA1B3, 0xA1BC, 0xA1BD, - /* U+3018 */ 0x2227, 0x2228, 0x2229, 0x2230, 0x2231, 0xA894, 0xA895, 0x2232, - /* U+3020 */ 0x2233, 0xA940, 0xA941, 0xA942, 0xA943, 0xA944, 0xA945, 0xA946, - /* U+3028 */ 0xA947, 0xA948, 0x2234, 0x2235, 0x2236, 0x2237, 0x2238, 0x2239, - /* U+3030 */ 0x2240, 0x2241, 0x2242, 0x2243, 0x2244, 0x2245, 0x2246, 0x2247, - /* U+3038 */ 0x2248, 0x2249, 0x2250, 0x2251, 0x2252, 0x2253, 0xA989, 0x2254, - /* U+3040 */ 0x2255, 0xA4A1, 0xA4A2, 0xA4A3, 0xA4A4, 0xA4A5, 0xA4A6, 0xA4A7, - /* U+3048 */ 0xA4A8, 0xA4A9, 0xA4AA, 0xA4AB, 0xA4AC, 0xA4AD, 0xA4AE, 0xA4AF, - /* U+3050 */ 0xA4B0, 0xA4B1, 0xA4B2, 0xA4B3, 0xA4B4, 0xA4B5, 0xA4B6, 0xA4B7, - /* U+3058 */ 0xA4B8, 0xA4B9, 0xA4BA, 0xA4BB, 0xA4BC, 0xA4BD, 0xA4BE, 0xA4BF, - /* U+3060 */ 0xA4C0, 0xA4C1, 0xA4C2, 0xA4C3, 0xA4C4, 0xA4C5, 0xA4C6, 0xA4C7, - /* U+3068 */ 0xA4C8, 0xA4C9, 0xA4CA, 0xA4CB, 0xA4CC, 0xA4CD, 0xA4CE, 0xA4CF, - /* U+3070 */ 0xA4D0, 0xA4D1, 0xA4D2, 0xA4D3, 0xA4D4, 0xA4D5, 0xA4D6, 0xA4D7, - /* U+3078 */ 0xA4D8, 0xA4D9, 0xA4DA, 0xA4DB, 0xA4DC, 0xA4DD, 0xA4DE, 0xA4DF, - /* U+3080 */ 0xA4E0, 0xA4E1, 0xA4E2, 0xA4E3, 0xA4E4, 0xA4E5, 0xA4E6, 0xA4E7, - /* U+3088 */ 0xA4E8, 0xA4E9, 0xA4EA, 0xA4EB, 0xA4EC, 0xA4ED, 0xA4EE, 0xA4EF, - /* U+3090 */ 0xA4F0, 0xA4F1, 0xA4F2, 0xA4F3, 0x2256, 0x2257, 0x2258, 0x2259, - /* U+3098 */ 0x2260, 0x2261, 0x2262, 0xA961, 0xA962, 0xA966, 0xA967, 0x2263, - /* U+30A0 */ 0x2264, 0xA5A1, 0xA5A2, 0xA5A3, 0xA5A4, 0xA5A5, 0xA5A6, 0xA5A7, - /* U+30A8 */ 0xA5A8, 0xA5A9, 0xA5AA, 0xA5AB, 0xA5AC, 0xA5AD, 0xA5AE, 0xA5AF, - /* U+30B0 */ 0xA5B0, 0xA5B1, 0xA5B2, 0xA5B3, 0xA5B4, 0xA5B5, 0xA5B6, 0xA5B7, - /* U+30B8 */ 0xA5B8, 0xA5B9, 0xA5BA, 0xA5BB, 0xA5BC, 0xA5BD, 0xA5BE, 0xA5BF, - /* U+30C0 */ 0xA5C0, 0xA5C1, 0xA5C2, 0xA5C3, 0xA5C4, 0xA5C5, 0xA5C6, 0xA5C7, - /* U+30C8 */ 0xA5C8, 0xA5C9, 0xA5CA, 0xA5CB, 0xA5CC, 0xA5CD, 0xA5CE, 0xA5CF, - /* U+30D0 */ 0xA5D0, 0xA5D1, 0xA5D2, 0xA5D3, 0xA5D4, 0xA5D5, 0xA5D6, 0xA5D7, - /* U+30D8 */ 0xA5D8, 0xA5D9, 0xA5DA, 0xA5DB, 0xA5DC, 0xA5DD, 0xA5DE, 0xA5DF, - /* U+30E0 */ 0xA5E0, 0xA5E1, 0xA5E2, 0xA5E3, 0xA5E4, 0xA5E5, 0xA5E6, 0xA5E7, - /* U+30E8 */ 0xA5E8, 0xA5E9, 0xA5EA, 0xA5EB, 0xA5EC, 0xA5ED, 0xA5EE, 0xA5EF, - /* U+30F0 */ 0xA5F0, 0xA5F1, 0xA5F2, 0xA5F3, 0xA5F4, 0xA5F5, 0xA5F6, 0x2265, - /* U+30F8 */ 0x2266, 0x2267, 0x2268, 0x2269, 0xA960, 0xA963, 0xA964, 0x2270, - /* U+3100 */ 0x2271, 0x2272, 0x2273, 0x2274, 0x2275, 0xA8C5, 0xA8C6, 0xA8C7, - /* U+3108 */ 0xA8C8, 0xA8C9, 0xA8CA, 0xA8CB, 0xA8CC, 0xA8CD, 0xA8CE, 0xA8CF, - /* U+3110 */ 0xA8D0, 0xA8D1, 0xA8D2, 0xA8D3, 0xA8D4, 0xA8D5, 0xA8D6, 0xA8D7, - /* U+3118 */ 0xA8D8, 0xA8D9, 0xA8DA, 0xA8DB, 0xA8DC, 0xA8DD, 0xA8DE, 0xA8DF, - /* U+3120 */ 0xA8E0, 0xA8E1, 0xA8E2, 0xA8E3, 0xA8E4, 0xA8E5, 0xA8E6, 0xA8E7, - /* U+3128 */ 0xA8E8, 0xA8E9, 0x2276, 0x2277, 0x2278, 0x2279, 0x2280, 0x2281, - /* U+3130 */ 0x2282, 0x2283, 0x2284, 0x2285, 0x2286, 0x2287, 0x2288, 0x2289, - /* U+3138 */ 0x2290, 0x2291, 0x2292, 0x2293, 0x2294, 0x2295, 0x2296, 0x2297, - /* U+3140 */ 0x2298, 0x2299, 0x22A0, 0x22A1, 0x22A2, 0x22A3, 0x22A4, 0x22A5, - /* U+3148 */ 0x22A6, 0x22A7, 0x22A8, 0x22A9, 0x22B0, 0x22B1, 0x22B2, 0x22B3, - /* U+3150 */ 0x22B4, 0x22B5, 0x22B6, 0x22B7, 0x22B8, 0x22B9, 0x22C0, 0x22C1, - /* U+3158 */ 0x22C2, 0x22C3, 0x22C4, 0x22C5, 0x22C6, 0x22C7, 0x22C8, 0x22C9, - /* U+3160 */ 0x22D0, 0x22D1, 0x22D2, 0x22D3, 0x22D4, 0x22D5, 0x22D6, 0x22D7, - /* U+3168 */ 0x22D8, 0x22D9, 0x22E0, 0x22E1, 0x22E2, 0x22E3, 0x22E4, 0x22E5, - /* U+3170 */ 0x22E6, 0x22E7, 0x22E8, 0x22E9, 0x22F0, 0x22F1, 0x22F2, 0x22F3, - /* U+3178 */ 0x22F4, 0x22F5, 0x22F6, 0x22F7, 0x22F8, 0x22F9, 0x2300, 0x2301, - /* U+3180 */ 0x2302, 0x2303, 0x2304, 0x2305, 0x2306, 0x2307, 0x2308, 0x2309, - /* U+3188 */ 0x2310, 0x2311, 0x2312, 0x2313, 0x2314, 0x2315, 0x2316, 0x2317, - /* U+3190 */ 0x2318, 0x2319, 0x2320, 0x2321, 0x2322, 0x2323, 0x2324, 0x2325, - /* U+3198 */ 0x2326, 0x2327, 0x2328, 0x2329, 0x2330, 0x2331, 0x2332, 0x2333, - /* U+31A0 */ 0x2334, 0x2335, 0x2336, 0x2337, 0x2338, 0x2339, 0x2340, 0x2341, - /* U+31A8 */ 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, - /* U+31B0 */ 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, - /* U+31B8 */ 0x2358, 0x2359, 0x2360, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, - /* U+31C0 */ 0x2366, 0x2367, 0x2368, 0x2369, 0x2370, 0x2371, 0x2372, 0x2373, - /* U+31C8 */ 0x2374, 0x2375, 0x2376, 0x2377, 0x2378, 0x2379, 0x2380, 0x2381, - /* U+31D0 */ 0x2382, 0x2383, 0x2384, 0x2385, 0x2386, 0x2387, 0x2388, 0x2389, - /* U+31D8 */ 0x2390, 0x2391, 0x2392, 0x2393, 0x2394, 0x2395, 0x2396, 0x2397, - /* U+31E0 */ 0x2398, 0x2399, 0x23A0, 0x23A1, 0x23A2, 0x23A3, 0x23A4, 0x23A5, - /* U+31E8 */ 0x23A6, 0x23A7, 0x23A8, 0x23A9, 0x23B0, 0x23B1, 0x23B2, 0x23B3, - /* U+31F0 */ 0x23B4, 0x23B5, 0x23B6, 0x23B7, 0x23B8, 0x23B9, 0x23C0, 0x23C1, - /* U+31F8 */ 0x23C2, 0x23C3, 0x23C4, 0x23C5, 0x23C6, 0x23C7, 0x23C8, 0x23C9, - /* U+3200 */ 0x23D0, 0x23D1, 0x23D2, 0x23D3, 0x23D4, 0x23D5, 0x23D6, 0x23D7, - /* U+3208 */ 0x23D8, 0x23D9, 0x23E0, 0x23E1, 0x23E2, 0x23E3, 0x23E4, 0x23E5, - /* U+3210 */ 0x23E6, 0x23E7, 0x23E8, 0x23E9, 0x23F0, 0x23F1, 0x23F2, 0x23F3, - /* U+3218 */ 0x23F4, 0x23F5, 0x23F6, 0x23F7, 0x23F8, 0x23F9, 0x2400, 0x2401, - /* U+3220 */ 0xA2E5, 0xA2E6, 0xA2E7, 0xA2E8, 0xA2E9, 0xA2EA, 0xA2EB, 0xA2EC, - /* U+3228 */ 0xA2ED, 0xA2EE, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407, - /* U+3230 */ 0x2408, 0xA95A, 0x2409, 0x2410, 0x2411, 0x2412, 0x2413, 0x2414, - /* U+3238 */ 0x2415, 0x2416, 0x2417, 0x2418, 0x2419, 0x2420, 0x2421, 0x2422, - /* U+3240 */ 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, 0x2430, - /* U+3248 */ 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, - /* U+3250 */ 0x2439, 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, - /* U+3258 */ 0x2447, 0x2448, 0x2449, 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, - /* U+3260 */ 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, 0x2460, 0x2461, 0x2462, - /* U+3268 */ 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x2470, - /* U+3270 */ 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, - /* U+3278 */ 0x2479, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, - /* U+3280 */ 0x2487, 0x2488, 0x2489, 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, - /* U+3288 */ 0x2495, 0x2496, 0x2497, 0x2498, 0x2499, 0x24A0, 0x24A1, 0x24A2, - /* U+3290 */ 0x24A3, 0x24A4, 0x24A5, 0x24A6, 0x24A7, 0x24A8, 0x24A9, 0x24B0, - /* U+3298 */ 0x24B1, 0x24B2, 0x24B3, 0x24B4, 0x24B5, 0x24B6, 0x24B7, 0x24B8, - /* U+32A0 */ 0x24B9, 0x24C0, 0x24C1, 0xA949, 0x24C2, 0x24C3, 0x24C4, 0x24C5, - /* U+32A8 */ 0x24C6, 0x24C7, 0x24C8, 0x24C9, 0x24D0, 0x24D1, 0x24D2, 0x24D3, - /* U+32B0 */ 0x24D4, 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9, 0x24E0, 0x24E1, - /* U+32B8 */ 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8, 0x24E9, - /* U+32C0 */ 0x24F0, 0x24F1, 0x24F2, 0x24F3, 0x24F4, 0x24F5, 0x24F6, 0x24F7, - /* U+32C8 */ 0x24F8, 0x24F9, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504, 0x2505, - /* U+32D0 */ 0x2506, 0x2507, 0x2508, 0x2509, 0x2510, 0x2511, 0x2512, 0x2513, - /* U+32D8 */ 0x2514, 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x2520, 0x2521, - /* U+32E0 */ 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, - /* U+32E8 */ 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, - /* U+32F0 */ 0x2538, 0x2539, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, - /* U+32F8 */ 0x2546, 0x2547, 0x2548, 0x2549, 0x2550, 0x2551, 0x2552, 0x2553, - /* U+3300 */ 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x2560, 0x2561, - /* U+3308 */ 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, - /* U+3310 */ 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x2577, - /* U+3318 */ 0x2578, 0x2579, 0x2580, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, - /* U+3320 */ 0x2586, 0x2587, 0x2588, 0x2589, 0x2590, 0x2591, 0x2592, 0x2593, - /* U+3328 */ 0x2594, 0x2595, 0x2596, 0x2597, 0x2598, 0x2599, 0x25A0, 0x25A1, - /* U+3330 */ 0x25A2, 0x25A3, 0x25A4, 0x25A5, 0x25A6, 0x25A7, 0x25A8, 0x25A9, - /* U+3338 */ 0x25B0, 0x25B1, 0x25B2, 0x25B3, 0x25B4, 0x25B5, 0x25B6, 0x25B7, - /* U+3340 */ 0x25B8, 0x25B9, 0x25C0, 0x25C1, 0x25C2, 0x25C3, 0x25C4, 0x25C5, - /* U+3348 */ 0x25C6, 0x25C7, 0x25C8, 0x25C9, 0x25D0, 0x25D1, 0x25D2, 0x25D3, - /* U+3350 */ 0x25D4, 0x25D5, 0x25D6, 0x25D7, 0x25D8, 0x25D9, 0x25E0, 0x25E1, - /* U+3358 */ 0x25E2, 0x25E3, 0x25E4, 0x25E5, 0x25E6, 0x25E7, 0x25E8, 0x25E9, - /* U+3360 */ 0x25F0, 0x25F1, 0x25F2, 0x25F3, 0x25F4, 0x25F5, 0x25F6, 0x25F7, - /* U+3368 */ 0x25F8, 0x25F9, 0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x2605, - /* U+3370 */ 0x2606, 0x2607, 0x2608, 0x2609, 0x2610, 0x2611, 0x2612, 0x2613, - /* U+3378 */ 0x2614, 0x2615, 0x2616, 0x2617, 0x2618, 0x2619, 0x2620, 0x2621, - /* U+3380 */ 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627, 0x2628, 0x2629, - /* U+3388 */ 0x2630, 0x2631, 0x2632, 0x2633, 0x2634, 0x2635, 0xA94A, 0xA94B, - /* U+3390 */ 0x2636, 0x2637, 0x2638, 0x2639, 0x2640, 0x2641, 0x2642, 0x2643, - /* U+3398 */ 0x2644, 0x2645, 0x2646, 0x2647, 0xA94C, 0xA94D, 0xA94E, 0x2648, - /* U+33A0 */ 0x2649, 0xA94F, 0x2650, 0x2651, 0x2652, 0x2653, 0x2654, 0x2655, - /* U+33A8 */ 0x2656, 0x2657, 0x2658, 0x2659, 0x2660, 0x2661, 0x2662, 0x2663, - /* U+33B0 */ 0x2664, 0x2665, 0x2666, 0x2667, 0x2668, 0x2669, 0x2670, 0x2671, - /* U+33B8 */ 0x2672, 0x2673, 0x2674, 0x2675, 0x2676, 0x2677, 0x2678, 0x2679, - /* U+33C0 */ 0x2680, 0x2681, 0x2682, 0x2683, 0xA950, 0x2684, 0x2685, 0x2686, - /* U+33C8 */ 0x2687, 0x2688, 0x2689, 0x2690, 0x2691, 0x2692, 0xA951, 0x2693, - /* U+33D0 */ 0x2694, 0xA952, 0xA953, 0x2695, 0x2696, 0xA954, 0x2697, 0x2698, - /* U+33D8 */ 0x2699, 0x26A0, 0x26A1, 0x26A2, 0x26A3, 0x26A4, 0x26A5, 0x26A6, - /* U+33E0 */ 0x26A7, 0x26A8, 0x26A9, 0x26B0, 0x26B1, 0x26B2, 0x26B3, 0x26B4, - /* U+33E8 */ 0x26B5, 0x26B6, 0x26B7, 0x26B8, 0x26B9, 0x26C0, 0x26C1, 0x26C2, - /* U+33F0 */ 0x26C3, 0x26C4, 0x26C5, 0x26C6, 0x26C7, 0x26C8, 0x26C9, 0x26D0, - /* U+33F8 */ 0x26D1, 0x26D2, 0x26D3, 0x26D4, 0x26D5, 0x26D6, 0x26D7, 0x26D8, - /* U+3400 */ 0x26D9, 0x26E0, 0x26E1, 0x26E2, 0x26E3, 0x26E4, 0x26E5, 0x26E6, - /* U+3408 */ 0x26E7, 0x26E8, 0x26E9, 0x26F0, 0x26F1, 0x26F2, 0x26F3, 0x26F4, - /* U+3410 */ 0x26F5, 0x26F6, 0x26F7, 0x26F8, 0x26F9, 0x2700, 0x2701, 0x2702, - /* U+3418 */ 0x2703, 0x2704, 0x2705, 0x2706, 0x2707, 0x2708, 0x2709, 0x2710, - /* U+3420 */ 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, 0x2716, 0x2717, 0x2718, - /* U+3428 */ 0x2719, 0x2720, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, - /* U+3430 */ 0x2727, 0x2728, 0x2729, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, - /* U+3438 */ 0x2735, 0x2736, 0x2737, 0x2738, 0x2739, 0x2740, 0x2741, 0x2742, - /* U+3440 */ 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0xFE56, - /* U+3448 */ 0x2750, 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2757, - /* U+3450 */ 0x2758, 0x2759, 0x2760, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, - /* U+3458 */ 0x2766, 0x2767, 0x2768, 0x2769, 0x2770, 0x2771, 0x2772, 0x2773, - /* U+3460 */ 0x2774, 0x2775, 0x2776, 0x2777, 0x2778, 0x2779, 0x2780, 0x2781, - /* U+3468 */ 0x2782, 0x2783, 0x2784, 0x2785, 0x2786, 0x2787, 0x2788, 0x2789, - /* U+3470 */ 0x2790, 0x2791, 0x2792, 0xFE55, 0x2793, 0x2794, 0x2795, 0x2796, - /* U+3478 */ 0x2797, 0x2798, 0x2799, 0x27A0, 0x27A1, 0x27A2, 0x27A3, 0x27A4, - /* U+3480 */ 0x27A5, 0x27A6, 0x27A7, 0x27A8, 0x27A9, 0x27B0, 0x27B1, 0x27B2, - /* U+3488 */ 0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7, 0x27B8, 0x27B9, 0x27C0, - /* U+3490 */ 0x27C1, 0x27C2, 0x27C3, 0x27C4, 0x27C5, 0x27C6, 0x27C7, 0x27C8, - /* U+3498 */ 0x27C9, 0x27D0, 0x27D1, 0x27D2, 0x27D3, 0x27D4, 0x27D5, 0x27D6, - /* U+34A0 */ 0x27D7, 0x27D8, 0x27D9, 0x3000, 0x3001, 0x3002, 0x3003, 0x3004, - /* U+34A8 */ 0x3005, 0x3006, 0x3007, 0x3008, 0x3009, 0x3010, 0x3011, 0x3012, - /* U+34B0 */ 0x3013, 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x3020, - /* U+34B8 */ 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 0x3028, - /* U+34C0 */ 0x3029, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, - /* U+34C8 */ 0x3037, 0x3038, 0x3039, 0x3040, 0x3041, 0x3042, 0x3043, 0x3044, - /* U+34D0 */ 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x3050, 0x3051, 0x3052, - /* U+34D8 */ 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x3060, - /* U+34E0 */ 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, - /* U+34E8 */ 0x3069, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, - /* U+34F0 */ 0x3077, 0x3078, 0x3079, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, - /* U+34F8 */ 0x3085, 0x3086, 0x3087, 0x3088, 0x3089, 0x3090, 0x3091, 0x3092, - /* U+3500 */ 0x3093, 0x3094, 0x3095, 0x3096, 0x3097, 0x3098, 0x3099, 0x30A0, - /* U+3508 */ 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, - /* U+3510 */ 0x30A9, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, - /* U+3518 */ 0x30B7, 0x30B8, 0x30B9, 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, - /* U+3520 */ 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30D0, 0x30D1, 0x30D2, - /* U+3528 */ 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30E0, - /* U+3530 */ 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, - /* U+3538 */ 0x30E9, 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, - /* U+3540 */ 0x30F7, 0x30F8, 0x30F9, 0x3100, 0x3101, 0x3102, 0x3103, 0x3104, - /* U+3548 */ 0x3105, 0x3106, 0x3107, 0x3108, 0x3109, 0x3110, 0x3111, 0x3112, - /* U+3550 */ 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, 0x3119, 0x3120, - /* U+3558 */ 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, - /* U+3560 */ 0x3129, 0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, - /* U+3568 */ 0x3137, 0x3138, 0x3139, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, - /* U+3570 */ 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x3150, 0x3151, 0x3152, - /* U+3578 */ 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x3160, - /* U+3580 */ 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, 0x3168, - /* U+3588 */ 0x3169, 0x3170, 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176, - /* U+3590 */ 0x3177, 0x3178, 0x3179, 0x3180, 0x3181, 0x3182, 0x3183, 0x3184, - /* U+3598 */ 0x3185, 0x3186, 0x3187, 0x3188, 0x3189, 0x3190, 0xFE5A, 0x3191, - /* U+35A0 */ 0x3192, 0x3193, 0x3194, 0x3195, 0x3196, 0x3197, 0x3198, 0x3199, - /* U+35A8 */ 0x31A0, 0x31A1, 0x31A2, 0x31A3, 0x31A4, 0x31A5, 0x31A6, 0x31A7, - /* U+35B0 */ 0x31A8, 0x31A9, 0x31B0, 0x31B1, 0x31B2, 0x31B3, 0x31B4, 0x31B5, - /* U+35B8 */ 0x31B6, 0x31B7, 0x31B8, 0x31B9, 0x31C0, 0x31C1, 0x31C2, 0x31C3, - /* U+35C0 */ 0x31C4, 0x31C5, 0x31C6, 0x31C7, 0x31C8, 0x31C9, 0x31D0, 0x31D1, - /* U+35C8 */ 0x31D2, 0x31D3, 0x31D4, 0x31D5, 0x31D6, 0x31D7, 0x31D8, 0x31D9, - /* U+35D0 */ 0x31E0, 0x31E1, 0x31E2, 0x31E3, 0x31E4, 0x31E5, 0x31E6, 0x31E7, - /* U+35D8 */ 0x31E8, 0x31E9, 0x31F0, 0x31F1, 0x31F2, 0x31F3, 0x31F4, 0x31F5, - /* U+35E0 */ 0x31F6, 0x31F7, 0x31F8, 0x31F9, 0x3200, 0x3201, 0x3202, 0x3203, - /* U+35E8 */ 0x3204, 0x3205, 0x3206, 0x3207, 0x3208, 0x3209, 0x3210, 0x3211, - /* U+35F0 */ 0x3212, 0x3213, 0x3214, 0x3215, 0x3216, 0x3217, 0x3218, 0x3219, - /* U+35F8 */ 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, - /* U+3600 */ 0x3228, 0x3229, 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, - /* U+3608 */ 0x3236, 0x3237, 0x3238, 0x3239, 0x3240, 0x3241, 0xFE5C, 0x3242, - /* U+3610 */ 0x3243, 0x3244, 0x3245, 0x3246, 0x3247, 0x3248, 0x3249, 0x3250, - /* U+3618 */ 0x3251, 0x3252, 0xFE5B, - /* Contiguous area: U+3918 .. U+3CE0 */ - /* U+3918 */ 0xFE60, 0x3718, 0x3719, 0x3720, 0x3721, 0x3722, 0x3723, 0x3724, - /* U+3920 */ 0x3725, 0x3726, 0x3727, 0x3728, 0x3729, 0x3730, 0x3731, 0x3732, - /* U+3928 */ 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x3740, - /* U+3930 */ 0x3741, 0x3742, 0x3743, 0x3744, 0x3745, 0x3746, 0x3747, 0x3748, - /* U+3938 */ 0x3749, 0x3750, 0x3751, 0x3752, 0x3753, 0x3754, 0x3755, 0x3756, - /* U+3940 */ 0x3757, 0x3758, 0x3759, 0x3760, 0x3761, 0x3762, 0x3763, 0x3764, - /* U+3948 */ 0x3765, 0x3766, 0x3767, 0x3768, 0x3769, 0x3770, 0x3771, 0x3772, - /* U+3950 */ 0x3773, 0x3774, 0x3775, 0x3776, 0x3777, 0x3778, 0x3779, 0x3780, - /* U+3958 */ 0x3781, 0x3782, 0x3783, 0x3784, 0x3785, 0x3786, 0x3787, 0x3788, - /* U+3960 */ 0x3789, 0x3790, 0x3791, 0x3792, 0x3793, 0x3794, 0x3795, 0x3796, - /* U+3968 */ 0x3797, 0x3798, 0x3799, 0x37A0, 0x37A1, 0x37A2, 0xFE5F, 0x37A3, - /* U+3970 */ 0x37A4, 0x37A5, 0x37A6, 0x37A7, 0x37A8, 0x37A9, 0x37B0, 0x37B1, - /* U+3978 */ 0x37B2, 0x37B3, 0x37B4, 0x37B5, 0x37B6, 0x37B7, 0x37B8, 0x37B9, - /* U+3980 */ 0x37C0, 0x37C1, 0x37C2, 0x37C3, 0x37C4, 0x37C5, 0x37C6, 0x37C7, - /* U+3988 */ 0x37C8, 0x37C9, 0x37D0, 0x37D1, 0x37D2, 0x37D3, 0x37D4, 0x37D5, - /* U+3990 */ 0x37D6, 0x37D7, 0x37D8, 0x37D9, 0x3800, 0x3801, 0x3802, 0x3803, - /* U+3998 */ 0x3804, 0x3805, 0x3806, 0x3807, 0x3808, 0x3809, 0x3810, 0x3811, - /* U+39A0 */ 0x3812, 0x3813, 0x3814, 0x3815, 0x3816, 0x3817, 0x3818, 0x3819, - /* U+39A8 */ 0x3820, 0x3821, 0x3822, 0x3823, 0x3824, 0x3825, 0x3826, 0x3827, - /* U+39B0 */ 0x3828, 0x3829, 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, - /* U+39B8 */ 0x3836, 0x3837, 0x3838, 0x3839, 0x3840, 0x3841, 0x3842, 0x3843, - /* U+39C0 */ 0x3844, 0x3845, 0x3846, 0x3847, 0x3848, 0x3849, 0x3850, 0x3851, - /* U+39C8 */ 0x3852, 0x3853, 0x3854, 0x3855, 0x3856, 0x3857, 0x3858, 0xFE62, - /* U+39D0 */ 0xFE65, 0x3859, 0x3860, 0x3861, 0x3862, 0x3863, 0x3864, 0x3865, - /* U+39D8 */ 0x3866, 0x3867, 0x3868, 0x3869, 0x3870, 0x3871, 0x3872, 0xFE63, - /* U+39E0 */ 0x3873, 0x3874, 0x3875, 0x3876, 0x3877, 0x3878, 0x3879, 0x3880, - /* U+39E8 */ 0x3881, 0x3882, 0x3883, 0x3884, 0x3885, 0x3886, 0x3887, 0x3888, - /* U+39F0 */ 0x3889, 0x3890, 0x3891, 0x3892, 0x3893, 0x3894, 0x3895, 0x3896, - /* U+39F8 */ 0x3897, 0x3898, 0x3899, 0x38A0, 0x38A1, 0x38A2, 0x38A3, 0x38A4, - /* U+3A00 */ 0x38A5, 0x38A6, 0x38A7, 0x38A8, 0x38A9, 0x38B0, 0x38B1, 0x38B2, - /* U+3A08 */ 0x38B3, 0x38B4, 0x38B5, 0x38B6, 0x38B7, 0x38B8, 0x38B9, 0x38C0, - /* U+3A10 */ 0x38C1, 0x38C2, 0x38C3, 0x38C4, 0x38C5, 0x38C6, 0x38C7, 0x38C8, - /* U+3A18 */ 0x38C9, 0x38D0, 0x38D1, 0x38D2, 0x38D3, 0x38D4, 0x38D5, 0x38D6, - /* U+3A20 */ 0x38D7, 0x38D8, 0x38D9, 0x38E0, 0x38E1, 0x38E2, 0x38E3, 0x38E4, - /* U+3A28 */ 0x38E5, 0x38E6, 0x38E7, 0x38E8, 0x38E9, 0x38F0, 0x38F1, 0x38F2, - /* U+3A30 */ 0x38F3, 0x38F4, 0x38F5, 0x38F6, 0x38F7, 0x38F8, 0x38F9, 0x3900, - /* U+3A38 */ 0x3901, 0x3902, 0x3903, 0x3904, 0x3905, 0x3906, 0x3907, 0x3908, - /* U+3A40 */ 0x3909, 0x3910, 0x3911, 0x3912, 0x3913, 0x3914, 0x3915, 0x3916, - /* U+3A48 */ 0x3917, 0x3918, 0x3919, 0x3920, 0x3921, 0x3922, 0x3923, 0x3924, - /* U+3A50 */ 0x3925, 0x3926, 0x3927, 0x3928, 0x3929, 0x3930, 0x3931, 0x3932, - /* U+3A58 */ 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939, 0x3940, - /* U+3A60 */ 0x3941, 0x3942, 0x3943, 0x3944, 0x3945, 0x3946, 0x3947, 0x3948, - /* U+3A68 */ 0x3949, 0x3950, 0x3951, 0x3952, 0x3953, 0x3954, 0x3955, 0x3956, - /* U+3A70 */ 0x3957, 0x3958, 0x3959, 0xFE64, 0x3960, 0x3961, 0x3962, 0x3963, - /* U+3A78 */ 0x3964, 0x3965, 0x3966, 0x3967, 0x3968, 0x3969, 0x3970, 0x3971, - /* U+3A80 */ 0x3972, 0x3973, 0x3974, 0x3975, 0x3976, 0x3977, 0x3978, 0x3979, - /* U+3A88 */ 0x3980, 0x3981, 0x3982, 0x3983, 0x3984, 0x3985, 0x3986, 0x3987, - /* U+3A90 */ 0x3988, 0x3989, 0x3990, 0x3991, 0x3992, 0x3993, 0x3994, 0x3995, - /* U+3A98 */ 0x3996, 0x3997, 0x3998, 0x3999, 0x39A0, 0x39A1, 0x39A2, 0x39A3, - /* U+3AA0 */ 0x39A4, 0x39A5, 0x39A6, 0x39A7, 0x39A8, 0x39A9, 0x39B0, 0x39B1, - /* U+3AA8 */ 0x39B2, 0x39B3, 0x39B4, 0x39B5, 0x39B6, 0x39B7, 0x39B8, 0x39B9, - /* U+3AB0 */ 0x39C0, 0x39C1, 0x39C2, 0x39C3, 0x39C4, 0x39C5, 0x39C6, 0x39C7, - /* U+3AB8 */ 0x39C8, 0x39C9, 0x39D0, 0x39D1, 0x39D2, 0x39D3, 0x39D4, 0x39D5, - /* U+3AC0 */ 0x39D6, 0x39D7, 0x39D8, 0x39D9, 0x39E0, 0x39E1, 0x39E2, 0x39E3, - /* U+3AC8 */ 0x39E4, 0x39E5, 0x39E6, 0x39E7, 0x39E8, 0x39E9, 0x39F0, 0x39F1, - /* U+3AD0 */ 0x39F2, 0x39F3, 0x39F4, 0x39F5, 0x39F6, 0x39F7, 0x39F8, 0x39F9, - /* U+3AD8 */ 0x3A00, 0x3A01, 0x3A02, 0x3A03, 0x3A04, 0x3A05, 0x3A06, 0x3A07, - /* U+3AE0 */ 0x3A08, 0x3A09, 0x3A10, 0x3A11, 0x3A12, 0x3A13, 0x3A14, 0x3A15, - /* U+3AE8 */ 0x3A16, 0x3A17, 0x3A18, 0x3A19, 0x3A20, 0x3A21, 0x3A22, 0x3A23, - /* U+3AF0 */ 0x3A24, 0x3A25, 0x3A26, 0x3A27, 0x3A28, 0x3A29, 0x3A30, 0x3A31, - /* U+3AF8 */ 0x3A32, 0x3A33, 0x3A34, 0x3A35, 0x3A36, 0x3A37, 0x3A38, 0x3A39, - /* U+3B00 */ 0x3A40, 0x3A41, 0x3A42, 0x3A43, 0x3A44, 0x3A45, 0x3A46, 0x3A47, - /* U+3B08 */ 0x3A48, 0x3A49, 0x3A50, 0x3A51, 0x3A52, 0x3A53, 0x3A54, 0x3A55, - /* U+3B10 */ 0x3A56, 0x3A57, 0x3A58, 0x3A59, 0x3A60, 0x3A61, 0x3A62, 0x3A63, - /* U+3B18 */ 0x3A64, 0x3A65, 0x3A66, 0x3A67, 0x3A68, 0x3A69, 0x3A70, 0x3A71, - /* U+3B20 */ 0x3A72, 0x3A73, 0x3A74, 0x3A75, 0x3A76, 0x3A77, 0x3A78, 0x3A79, - /* U+3B28 */ 0x3A80, 0x3A81, 0x3A82, 0x3A83, 0x3A84, 0x3A85, 0x3A86, 0x3A87, - /* U+3B30 */ 0x3A88, 0x3A89, 0x3A90, 0x3A91, 0x3A92, 0x3A93, 0x3A94, 0x3A95, - /* U+3B38 */ 0x3A96, 0x3A97, 0x3A98, 0x3A99, 0x3AA0, 0x3AA1, 0x3AA2, 0x3AA3, - /* U+3B40 */ 0x3AA4, 0x3AA5, 0x3AA6, 0x3AA7, 0x3AA8, 0x3AA9, 0x3AB0, 0x3AB1, - /* U+3B48 */ 0x3AB2, 0x3AB3, 0x3AB4, 0x3AB5, 0x3AB6, 0x3AB7, 0xFE68, 0x3AB8, - /* U+3B50 */ 0x3AB9, 0x3AC0, 0x3AC1, 0x3AC2, 0x3AC3, 0x3AC4, 0x3AC5, 0x3AC6, - /* U+3B58 */ 0x3AC7, 0x3AC8, 0x3AC9, 0x3AD0, 0x3AD1, 0x3AD2, 0x3AD3, 0x3AD4, - /* U+3B60 */ 0x3AD5, 0x3AD6, 0x3AD7, 0x3AD8, 0x3AD9, 0x3AE0, 0x3AE1, 0x3AE2, - /* U+3B68 */ 0x3AE3, 0x3AE4, 0x3AE5, 0x3AE6, 0x3AE7, 0x3AE8, 0x3AE9, 0x3AF0, - /* U+3B70 */ 0x3AF1, 0x3AF2, 0x3AF3, 0x3AF4, 0x3AF5, 0x3AF6, 0x3AF7, 0x3AF8, - /* U+3B78 */ 0x3AF9, 0x3B00, 0x3B01, 0x3B02, 0x3B03, 0x3B04, 0x3B05, 0x3B06, - /* U+3B80 */ 0x3B07, 0x3B08, 0x3B09, 0x3B10, 0x3B11, 0x3B12, 0x3B13, 0x3B14, - /* U+3B88 */ 0x3B15, 0x3B16, 0x3B17, 0x3B18, 0x3B19, 0x3B20, 0x3B21, 0x3B22, - /* U+3B90 */ 0x3B23, 0x3B24, 0x3B25, 0x3B26, 0x3B27, 0x3B28, 0x3B29, 0x3B30, - /* U+3B98 */ 0x3B31, 0x3B32, 0x3B33, 0x3B34, 0x3B35, 0x3B36, 0x3B37, 0x3B38, - /* U+3BA0 */ 0x3B39, 0x3B40, 0x3B41, 0x3B42, 0x3B43, 0x3B44, 0x3B45, 0x3B46, - /* U+3BA8 */ 0x3B47, 0x3B48, 0x3B49, 0x3B50, 0x3B51, 0x3B52, 0x3B53, 0x3B54, - /* U+3BB0 */ 0x3B55, 0x3B56, 0x3B57, 0x3B58, 0x3B59, 0x3B60, 0x3B61, 0x3B62, - /* U+3BB8 */ 0x3B63, 0x3B64, 0x3B65, 0x3B66, 0x3B67, 0x3B68, 0x3B69, 0x3B70, - /* U+3BC0 */ 0x3B71, 0x3B72, 0x3B73, 0x3B74, 0x3B75, 0x3B76, 0x3B77, 0x3B78, - /* U+3BC8 */ 0x3B79, 0x3B80, 0x3B81, 0x3B82, 0x3B83, 0x3B84, 0x3B85, 0x3B86, - /* U+3BD0 */ 0x3B87, 0x3B88, 0x3B89, 0x3B90, 0x3B91, 0x3B92, 0x3B93, 0x3B94, - /* U+3BD8 */ 0x3B95, 0x3B96, 0x3B97, 0x3B98, 0x3B99, 0x3BA0, 0x3BA1, 0x3BA2, - /* U+3BE0 */ 0x3BA3, 0x3BA4, 0x3BA5, 0x3BA6, 0x3BA7, 0x3BA8, 0x3BA9, 0x3BB0, - /* U+3BE8 */ 0x3BB1, 0x3BB2, 0x3BB3, 0x3BB4, 0x3BB5, 0x3BB6, 0x3BB7, 0x3BB8, - /* U+3BF0 */ 0x3BB9, 0x3BC0, 0x3BC1, 0x3BC2, 0x3BC3, 0x3BC4, 0x3BC5, 0x3BC6, - /* U+3BF8 */ 0x3BC7, 0x3BC8, 0x3BC9, 0x3BD0, 0x3BD1, 0x3BD2, 0x3BD3, 0x3BD4, - /* U+3C00 */ 0x3BD5, 0x3BD6, 0x3BD7, 0x3BD8, 0x3BD9, 0x3BE0, 0x3BE1, 0x3BE2, - /* U+3C08 */ 0x3BE3, 0x3BE4, 0x3BE5, 0x3BE6, 0x3BE7, 0x3BE8, 0x3BE9, 0x3BF0, - /* U+3C10 */ 0x3BF1, 0x3BF2, 0x3BF3, 0x3BF4, 0x3BF5, 0x3BF6, 0x3BF7, 0x3BF8, - /* U+3C18 */ 0x3BF9, 0x3C00, 0x3C01, 0x3C02, 0x3C03, 0x3C04, 0x3C05, 0x3C06, - /* U+3C20 */ 0x3C07, 0x3C08, 0x3C09, 0x3C10, 0x3C11, 0x3C12, 0x3C13, 0x3C14, - /* U+3C28 */ 0x3C15, 0x3C16, 0x3C17, 0x3C18, 0x3C19, 0x3C20, 0x3C21, 0x3C22, - /* U+3C30 */ 0x3C23, 0x3C24, 0x3C25, 0x3C26, 0x3C27, 0x3C28, 0x3C29, 0x3C30, - /* U+3C38 */ 0x3C31, 0x3C32, 0x3C33, 0x3C34, 0x3C35, 0x3C36, 0x3C37, 0x3C38, - /* U+3C40 */ 0x3C39, 0x3C40, 0x3C41, 0x3C42, 0x3C43, 0x3C44, 0x3C45, 0x3C46, - /* U+3C48 */ 0x3C47, 0x3C48, 0x3C49, 0x3C50, 0x3C51, 0x3C52, 0x3C53, 0x3C54, - /* U+3C50 */ 0x3C55, 0x3C56, 0x3C57, 0x3C58, 0x3C59, 0x3C60, 0x3C61, 0x3C62, - /* U+3C58 */ 0x3C63, 0x3C64, 0x3C65, 0x3C66, 0x3C67, 0x3C68, 0x3C69, 0x3C70, - /* U+3C60 */ 0x3C71, 0x3C72, 0x3C73, 0x3C74, 0x3C75, 0x3C76, 0x3C77, 0x3C78, - /* U+3C68 */ 0x3C79, 0x3C80, 0x3C81, 0x3C82, 0x3C83, 0x3C84, 0xFE69, 0x3C85, - /* U+3C70 */ 0x3C86, 0x3C87, 0x3C88, 0x3C89, 0x3C90, 0x3C91, 0x3C92, 0x3C93, - /* U+3C78 */ 0x3C94, 0x3C95, 0x3C96, 0x3C97, 0x3C98, 0x3C99, 0x3CA0, 0x3CA1, - /* U+3C80 */ 0x3CA2, 0x3CA3, 0x3CA4, 0x3CA5, 0x3CA6, 0x3CA7, 0x3CA8, 0x3CA9, - /* U+3C88 */ 0x3CB0, 0x3CB1, 0x3CB2, 0x3CB3, 0x3CB4, 0x3CB5, 0x3CB6, 0x3CB7, - /* U+3C90 */ 0x3CB8, 0x3CB9, 0x3CC0, 0x3CC1, 0x3CC2, 0x3CC3, 0x3CC4, 0x3CC5, - /* U+3C98 */ 0x3CC6, 0x3CC7, 0x3CC8, 0x3CC9, 0x3CD0, 0x3CD1, 0x3CD2, 0x3CD3, - /* U+3CA0 */ 0x3CD4, 0x3CD5, 0x3CD6, 0x3CD7, 0x3CD8, 0x3CD9, 0x3CE0, 0x3CE1, - /* U+3CA8 */ 0x3CE2, 0x3CE3, 0x3CE4, 0x3CE5, 0x3CE6, 0x3CE7, 0x3CE8, 0x3CE9, - /* U+3CB0 */ 0x3CF0, 0x3CF1, 0x3CF2, 0x3CF3, 0x3CF4, 0x3CF5, 0x3CF6, 0x3CF7, - /* U+3CB8 */ 0x3CF8, 0x3CF9, 0x3D00, 0x3D01, 0x3D02, 0x3D03, 0x3D04, 0x3D05, - /* U+3CC0 */ 0x3D06, 0x3D07, 0x3D08, 0x3D09, 0x3D10, 0x3D11, 0x3D12, 0x3D13, - /* U+3CC8 */ 0x3D14, 0x3D15, 0x3D16, 0x3D17, 0x3D18, 0x3D19, 0x3D20, 0x3D21, - /* U+3CD0 */ 0x3D22, 0x3D23, 0x3D24, 0x3D25, 0x3D26, 0x3D27, 0x3D28, 0x3D29, - /* U+3CD8 */ 0x3D30, 0x3D31, 0x3D32, 0x3D33, 0x3D34, 0x3D35, 0x3D36, 0x3D37, - /* U+3CE0 */ 0xFE6A, - /* Contiguous area: U+4056 .. U+415F */ - /* U+4056 */ 0xFE6F, 0x42E3, - /* U+4058 */ 0x42E4, 0x42E5, 0x42E6, 0x42E7, 0x42E8, 0x42E9, 0x42F0, 0x42F1, - /* U+4060 */ 0x42F2, 0x42F3, 0x42F4, 0x42F5, 0x42F6, 0x42F7, 0x42F8, 0x42F9, - /* U+4068 */ 0x4300, 0x4301, 0x4302, 0x4303, 0x4304, 0x4305, 0x4306, 0x4307, - /* U+4070 */ 0x4308, 0x4309, 0x4310, 0x4311, 0x4312, 0x4313, 0x4314, 0x4315, - /* U+4078 */ 0x4316, 0x4317, 0x4318, 0x4319, 0x4320, 0x4321, 0x4322, 0x4323, - /* U+4080 */ 0x4324, 0x4325, 0x4326, 0x4327, 0x4328, 0x4329, 0x4330, 0x4331, - /* U+4088 */ 0x4332, 0x4333, 0x4334, 0x4335, 0x4336, 0x4337, 0x4338, 0x4339, - /* U+4090 */ 0x4340, 0x4341, 0x4342, 0x4343, 0x4344, 0x4345, 0x4346, 0x4347, - /* U+4098 */ 0x4348, 0x4349, 0x4350, 0x4351, 0x4352, 0x4353, 0x4354, 0x4355, - /* U+40A0 */ 0x4356, 0x4357, 0x4358, 0x4359, 0x4360, 0x4361, 0x4362, 0x4363, - /* U+40A8 */ 0x4364, 0x4365, 0x4366, 0x4367, 0x4368, 0x4369, 0x4370, 0x4371, - /* U+40B0 */ 0x4372, 0x4373, 0x4374, 0x4375, 0x4376, 0x4377, 0x4378, 0x4379, - /* U+40B8 */ 0x4380, 0x4381, 0x4382, 0x4383, 0x4384, 0x4385, 0x4386, 0x4387, - /* U+40C0 */ 0x4388, 0x4389, 0x4390, 0x4391, 0x4392, 0x4393, 0x4394, 0x4395, - /* U+40C8 */ 0x4396, 0x4397, 0x4398, 0x4399, 0x43A0, 0x43A1, 0x43A2, 0x43A3, - /* U+40D0 */ 0x43A4, 0x43A5, 0x43A6, 0x43A7, 0x43A8, 0x43A9, 0x43B0, 0x43B1, - /* U+40D8 */ 0x43B2, 0x43B3, 0x43B4, 0x43B5, 0x43B6, 0x43B7, 0x43B8, 0x43B9, - /* U+40E0 */ 0x43C0, 0x43C1, 0x43C2, 0x43C3, 0x43C4, 0x43C5, 0x43C6, 0x43C7, - /* U+40E8 */ 0x43C8, 0x43C9, 0x43D0, 0x43D1, 0x43D2, 0x43D3, 0x43D4, 0x43D5, - /* U+40F0 */ 0x43D6, 0x43D7, 0x43D8, 0x43D9, 0x43E0, 0x43E1, 0x43E2, 0x43E3, - /* U+40F8 */ 0x43E4, 0x43E5, 0x43E6, 0x43E7, 0x43E8, 0x43E9, 0x43F0, 0x43F1, - /* U+4100 */ 0x43F2, 0x43F3, 0x43F4, 0x43F5, 0x43F6, 0x43F7, 0x43F8, 0x43F9, - /* U+4108 */ 0x4400, 0x4401, 0x4402, 0x4403, 0x4404, 0x4405, 0x4406, 0x4407, - /* U+4110 */ 0x4408, 0x4409, 0x4410, 0x4411, 0x4412, 0x4413, 0x4414, 0x4415, - /* U+4118 */ 0x4416, 0x4417, 0x4418, 0x4419, 0x4420, 0x4421, 0x4422, 0x4423, - /* U+4120 */ 0x4424, 0x4425, 0x4426, 0x4427, 0x4428, 0x4429, 0x4430, 0x4431, - /* U+4128 */ 0x4432, 0x4433, 0x4434, 0x4435, 0x4436, 0x4437, 0x4438, 0x4439, - /* U+4130 */ 0x4440, 0x4441, 0x4442, 0x4443, 0x4444, 0x4445, 0x4446, 0x4447, - /* U+4138 */ 0x4448, 0x4449, 0x4450, 0x4451, 0x4452, 0x4453, 0x4454, 0x4455, - /* U+4140 */ 0x4456, 0x4457, 0x4458, 0x4459, 0x4460, 0x4461, 0x4462, 0x4463, - /* U+4148 */ 0x4464, 0x4465, 0x4466, 0x4467, 0x4468, 0x4469, 0x4470, 0x4471, - /* U+4150 */ 0x4472, 0x4473, 0x4474, 0x4475, 0x4476, 0x4477, 0x4478, 0x4479, - /* U+4158 */ 0x4480, 0x4481, 0x4482, 0x4483, 0x4484, 0x4485, 0x4486, 0xFE70, - /* Contiguous area: U+4337 .. U+44D6 */ - /* U+4337 */ 0xFE72, - /* U+4338 */ 0x4778, 0x4779, 0x4780, 0x4781, 0x4782, 0x4783, 0x4784, 0x4785, - /* U+4340 */ 0x4786, 0x4787, 0x4788, 0x4789, 0x4790, 0x4791, 0x4792, 0x4793, - /* U+4348 */ 0x4794, 0x4795, 0x4796, 0x4797, 0x4798, 0x4799, 0x47A0, 0x47A1, - /* U+4350 */ 0x47A2, 0x47A3, 0x47A4, 0x47A5, 0x47A6, 0x47A7, 0x47A8, 0x47A9, - /* U+4358 */ 0x47B0, 0x47B1, 0x47B2, 0x47B3, 0x47B4, 0x47B5, 0x47B6, 0x47B7, - /* U+4360 */ 0x47B8, 0x47B9, 0x47C0, 0x47C1, 0x47C2, 0x47C3, 0x47C4, 0x47C5, - /* U+4368 */ 0x47C6, 0x47C7, 0x47C8, 0x47C9, 0x47D0, 0x47D1, 0x47D2, 0x47D3, - /* U+4370 */ 0x47D4, 0x47D5, 0x47D6, 0x47D7, 0x47D8, 0x47D9, 0x4800, 0x4801, - /* U+4378 */ 0x4802, 0x4803, 0x4804, 0x4805, 0x4806, 0x4807, 0x4808, 0x4809, - /* U+4380 */ 0x4810, 0x4811, 0x4812, 0x4813, 0x4814, 0x4815, 0x4816, 0x4817, - /* U+4388 */ 0x4818, 0x4819, 0x4820, 0x4821, 0x4822, 0x4823, 0x4824, 0x4825, - /* U+4390 */ 0x4826, 0x4827, 0x4828, 0x4829, 0x4830, 0x4831, 0x4832, 0x4833, - /* U+4398 */ 0x4834, 0x4835, 0x4836, 0x4837, 0x4838, 0x4839, 0x4840, 0x4841, - /* U+43A0 */ 0x4842, 0x4843, 0x4844, 0x4845, 0x4846, 0x4847, 0x4848, 0x4849, - /* U+43A8 */ 0x4850, 0x4851, 0x4852, 0x4853, 0xFE78, 0x4854, 0x4855, 0x4856, - /* U+43B0 */ 0x4857, 0xFE77, 0x4858, 0x4859, 0x4860, 0x4861, 0x4862, 0x4863, - /* U+43B8 */ 0x4864, 0x4865, 0x4866, 0x4867, 0x4868, 0x4869, 0x4870, 0x4871, - /* U+43C0 */ 0x4872, 0x4873, 0x4874, 0x4875, 0x4876, 0x4877, 0x4878, 0x4879, - /* U+43C8 */ 0x4880, 0x4881, 0x4882, 0x4883, 0x4884, 0x4885, 0x4886, 0x4887, - /* U+43D0 */ 0x4888, 0x4889, 0x4890, 0x4891, 0x4892, 0x4893, 0x4894, 0x4895, - /* U+43D8 */ 0x4896, 0x4897, 0x4898, 0x4899, 0x48A0, 0xFE7A, 0x48A1, 0x48A2, - /* U+43E0 */ 0x48A3, 0x48A4, 0x48A5, 0x48A6, 0x48A7, 0x48A8, 0x48A9, 0x48B0, - /* U+43E8 */ 0x48B1, 0x48B2, 0x48B3, 0x48B4, 0x48B5, 0x48B6, 0x48B7, 0x48B8, - /* U+43F0 */ 0x48B9, 0x48C0, 0x48C1, 0x48C2, 0x48C3, 0x48C4, 0x48C5, 0x48C6, - /* U+43F8 */ 0x48C7, 0x48C8, 0x48C9, 0x48D0, 0x48D1, 0x48D2, 0x48D3, 0x48D4, - /* U+4400 */ 0x48D5, 0x48D6, 0x48D7, 0x48D8, 0x48D9, 0x48E0, 0x48E1, 0x48E2, - /* U+4408 */ 0x48E3, 0x48E4, 0x48E5, 0x48E6, 0x48E7, 0x48E8, 0x48E9, 0x48F0, - /* U+4410 */ 0x48F1, 0x48F2, 0x48F3, 0x48F4, 0x48F5, 0x48F6, 0x48F7, 0x48F8, - /* U+4418 */ 0x48F9, 0x4900, 0x4901, 0x4902, 0x4903, 0x4904, 0x4905, 0x4906, - /* U+4420 */ 0x4907, 0x4908, 0x4909, 0x4910, 0x4911, 0x4912, 0x4913, 0x4914, - /* U+4428 */ 0x4915, 0x4916, 0x4917, 0x4918, 0x4919, 0x4920, 0x4921, 0x4922, - /* U+4430 */ 0x4923, 0x4924, 0x4925, 0x4926, 0x4927, 0x4928, 0x4929, 0x4930, - /* U+4438 */ 0x4931, 0x4932, 0x4933, 0x4934, 0x4935, 0x4936, 0x4937, 0x4938, - /* U+4440 */ 0x4939, 0x4940, 0x4941, 0x4942, 0x4943, 0x4944, 0x4945, 0x4946, - /* U+4448 */ 0x4947, 0x4948, 0x4949, 0x4950, 0x4951, 0x4952, 0x4953, 0x4954, - /* U+4450 */ 0x4955, 0x4956, 0x4957, 0x4958, 0x4959, 0x4960, 0x4961, 0x4962, - /* U+4458 */ 0x4963, 0x4964, 0x4965, 0x4966, 0x4967, 0x4968, 0x4969, 0x4970, - /* U+4460 */ 0x4971, 0x4972, 0x4973, 0x4974, 0x4975, 0x4976, 0x4977, 0x4978, - /* U+4468 */ 0x4979, 0x4980, 0x4981, 0x4982, 0x4983, 0x4984, 0x4985, 0x4986, - /* U+4470 */ 0x4987, 0x4988, 0x4989, 0x4990, 0x4991, 0x4992, 0x4993, 0x4994, - /* U+4478 */ 0x4995, 0x4996, 0x4997, 0x4998, 0x4999, 0x49A0, 0x49A1, 0x49A2, - /* U+4480 */ 0x49A3, 0x49A4, 0x49A5, 0x49A6, 0x49A7, 0x49A8, 0x49A9, 0x49B0, - /* U+4488 */ 0x49B1, 0x49B2, 0x49B3, 0x49B4, 0x49B5, 0x49B6, 0x49B7, 0x49B8, - /* U+4490 */ 0x49B9, 0x49C0, 0x49C1, 0x49C2, 0x49C3, 0x49C4, 0x49C5, 0x49C6, - /* U+4498 */ 0x49C7, 0x49C8, 0x49C9, 0x49D0, 0x49D1, 0x49D2, 0x49D3, 0x49D4, - /* U+44A0 */ 0x49D5, 0x49D6, 0x49D7, 0x49D8, 0x49D9, 0x49E0, 0x49E1, 0x49E2, - /* U+44A8 */ 0x49E3, 0x49E4, 0x49E5, 0x49E6, 0x49E7, 0x49E8, 0x49E9, 0x49F0, - /* U+44B0 */ 0x49F1, 0x49F2, 0x49F3, 0x49F4, 0x49F5, 0x49F6, 0x49F7, 0x49F8, - /* U+44B8 */ 0x49F9, 0x4A00, 0x4A01, 0x4A02, 0x4A03, 0x4A04, 0x4A05, 0x4A06, - /* U+44C0 */ 0x4A07, 0x4A08, 0x4A09, 0x4A10, 0x4A11, 0x4A12, 0x4A13, 0x4A14, - /* U+44C8 */ 0x4A15, 0x4A16, 0x4A17, 0x4A18, 0x4A19, 0x4A20, 0x4A21, 0x4A22, - /* U+44D0 */ 0x4A23, 0x4A24, 0x4A25, 0x4A26, 0x4A27, 0x4A28, 0xFE7B, - /* Contiguous area: U+464C .. U+478D */ - /* U+464C */ 0xFE7D, 0x4C82, 0x4C83, 0x4C84, - /* U+4650 */ 0x4C85, 0x4C86, 0x4C87, 0x4C88, 0x4C89, 0x4C90, 0x4C91, 0x4C92, - /* U+4658 */ 0x4C93, 0x4C94, 0x4C95, 0x4C96, 0x4C97, 0x4C98, 0x4C99, 0x4CA0, - /* U+4660 */ 0x4CA1, 0xFE7C, 0x4CA2, 0x4CA3, 0x4CA4, 0x4CA5, 0x4CA6, 0x4CA7, - /* U+4668 */ 0x4CA8, 0x4CA9, 0x4CB0, 0x4CB1, 0x4CB2, 0x4CB3, 0x4CB4, 0x4CB5, - /* U+4670 */ 0x4CB6, 0x4CB7, 0x4CB8, 0x4CB9, 0x4CC0, 0x4CC1, 0x4CC2, 0x4CC3, - /* U+4678 */ 0x4CC4, 0x4CC5, 0x4CC6, 0x4CC7, 0x4CC8, 0x4CC9, 0x4CD0, 0x4CD1, - /* U+4680 */ 0x4CD2, 0x4CD3, 0x4CD4, 0x4CD5, 0x4CD6, 0x4CD7, 0x4CD8, 0x4CD9, - /* U+4688 */ 0x4CE0, 0x4CE1, 0x4CE2, 0x4CE3, 0x4CE4, 0x4CE5, 0x4CE6, 0x4CE7, - /* U+4690 */ 0x4CE8, 0x4CE9, 0x4CF0, 0x4CF1, 0x4CF2, 0x4CF3, 0x4CF4, 0x4CF5, - /* U+4698 */ 0x4CF6, 0x4CF7, 0x4CF8, 0x4CF9, 0x4D00, 0x4D01, 0x4D02, 0x4D03, - /* U+46A0 */ 0x4D04, 0x4D05, 0x4D06, 0x4D07, 0x4D08, 0x4D09, 0x4D10, 0x4D11, - /* U+46A8 */ 0x4D12, 0x4D13, 0x4D14, 0x4D15, 0x4D16, 0x4D17, 0x4D18, 0x4D19, - /* U+46B0 */ 0x4D20, 0x4D21, 0x4D22, 0x4D23, 0x4D24, 0x4D25, 0x4D26, 0x4D27, - /* U+46B8 */ 0x4D28, 0x4D29, 0x4D30, 0x4D31, 0x4D32, 0x4D33, 0x4D34, 0x4D35, - /* U+46C0 */ 0x4D36, 0x4D37, 0x4D38, 0x4D39, 0x4D40, 0x4D41, 0x4D42, 0x4D43, - /* U+46C8 */ 0x4D44, 0x4D45, 0x4D46, 0x4D47, 0x4D48, 0x4D49, 0x4D50, 0x4D51, - /* U+46D0 */ 0x4D52, 0x4D53, 0x4D54, 0x4D55, 0x4D56, 0x4D57, 0x4D58, 0x4D59, - /* U+46D8 */ 0x4D60, 0x4D61, 0x4D62, 0x4D63, 0x4D64, 0x4D65, 0x4D66, 0x4D67, - /* U+46E0 */ 0x4D68, 0x4D69, 0x4D70, 0x4D71, 0x4D72, 0x4D73, 0x4D74, 0x4D75, - /* U+46E8 */ 0x4D76, 0x4D77, 0x4D78, 0x4D79, 0x4D80, 0x4D81, 0x4D82, 0x4D83, - /* U+46F0 */ 0x4D84, 0x4D85, 0x4D86, 0x4D87, 0x4D88, 0x4D89, 0x4D90, 0x4D91, - /* U+46F8 */ 0x4D92, 0x4D93, 0x4D94, 0x4D95, 0x4D96, 0x4D97, 0x4D98, 0x4D99, - /* U+4700 */ 0x4DA0, 0x4DA1, 0x4DA2, 0x4DA3, 0x4DA4, 0x4DA5, 0x4DA6, 0x4DA7, - /* U+4708 */ 0x4DA8, 0x4DA9, 0x4DB0, 0x4DB1, 0x4DB2, 0x4DB3, 0x4DB4, 0x4DB5, - /* U+4710 */ 0x4DB6, 0x4DB7, 0x4DB8, 0x4DB9, 0x4DC0, 0x4DC1, 0x4DC2, 0x4DC3, - /* U+4718 */ 0x4DC4, 0x4DC5, 0x4DC6, 0x4DC7, 0x4DC8, 0x4DC9, 0x4DD0, 0x4DD1, - /* U+4720 */ 0x4DD2, 0x4DD3, 0x4DD4, 0xFE80, 0x4DD5, 0x4DD6, 0x4DD7, 0x4DD8, - /* U+4728 */ 0x4DD9, 0xFE81, 0x4DE0, 0x4DE1, 0x4DE2, 0x4DE3, 0x4DE4, 0x4DE5, - /* U+4730 */ 0x4DE6, 0x4DE7, 0x4DE8, 0x4DE9, 0x4DF0, 0x4DF1, 0x4DF2, 0x4DF3, - /* U+4738 */ 0x4DF4, 0x4DF5, 0x4DF6, 0x4DF7, 0x4DF8, 0x4DF9, 0x4E00, 0x4E01, - /* U+4740 */ 0x4E02, 0x4E03, 0x4E04, 0x4E05, 0x4E06, 0x4E07, 0x4E08, 0x4E09, - /* U+4748 */ 0x4E10, 0x4E11, 0x4E12, 0x4E13, 0x4E14, 0x4E15, 0x4E16, 0x4E17, - /* U+4750 */ 0x4E18, 0x4E19, 0x4E20, 0x4E21, 0x4E22, 0x4E23, 0x4E24, 0x4E25, - /* U+4758 */ 0x4E26, 0x4E27, 0x4E28, 0x4E29, 0x4E30, 0x4E31, 0x4E32, 0x4E33, - /* U+4760 */ 0x4E34, 0x4E35, 0x4E36, 0x4E37, 0x4E38, 0x4E39, 0x4E40, 0x4E41, - /* U+4768 */ 0x4E42, 0x4E43, 0x4E44, 0x4E45, 0x4E46, 0x4E47, 0x4E48, 0x4E49, - /* U+4770 */ 0x4E50, 0x4E51, 0x4E52, 0x4E53, 0x4E54, 0x4E55, 0x4E56, 0x4E57, - /* U+4778 */ 0x4E58, 0x4E59, 0x4E60, 0x4E61, 0xFE82, 0x4E62, 0x4E63, 0x4E64, - /* U+4780 */ 0x4E65, 0x4E66, 0x4E67, 0x4E68, 0x4E69, 0x4E70, 0x4E71, 0x4E72, - /* U+4788 */ 0x4E73, 0x4E74, 0x4E75, 0x4E76, 0x4E77, 0xFE83, - /* Contiguous area: U+4947 .. U+49B7 */ - /* U+4947 */ 0xFE85, - /* U+4948 */ 0x5159, 0x5160, 0x5161, 0x5162, 0x5163, 0x5164, 0x5165, 0x5166, - /* U+4950 */ 0x5167, 0x5168, 0x5169, 0x5170, 0x5171, 0x5172, 0x5173, 0x5174, - /* U+4958 */ 0x5175, 0x5176, 0x5177, 0x5178, 0x5179, 0x5180, 0x5181, 0x5182, - /* U+4960 */ 0x5183, 0x5184, 0x5185, 0x5186, 0x5187, 0x5188, 0x5189, 0x5190, - /* U+4968 */ 0x5191, 0x5192, 0x5193, 0x5194, 0x5195, 0x5196, 0x5197, 0x5198, - /* U+4970 */ 0x5199, 0x51A0, 0x51A1, 0x51A2, 0x51A3, 0x51A4, 0x51A5, 0x51A6, - /* U+4978 */ 0x51A7, 0x51A8, 0xFE86, 0x51A9, 0x51B0, 0xFE87, 0x51B1, 0x51B2, - /* U+4980 */ 0x51B3, 0x51B4, 0xFE88, 0xFE89, 0x51B5, 0xFE8A, 0xFE8B, 0x51B6, - /* U+4988 */ 0x51B7, 0x51B8, 0x51B9, 0x51C0, 0x51C1, 0x51C2, 0x51C3, 0x51C4, - /* U+4990 */ 0x51C5, 0x51C6, 0x51C7, 0x51C8, 0x51C9, 0x51D0, 0x51D1, 0x51D2, - /* U+4998 */ 0x51D3, 0x51D4, 0x51D5, 0xFE8D, 0x51D6, 0x51D7, 0x51D8, 0xFE8C, - /* U+49A0 */ 0x51D9, 0x51E0, 0x51E1, 0x51E2, 0x51E3, 0x51E4, 0x51E5, 0x51E6, - /* U+49A8 */ 0x51E7, 0x51E8, 0x51E9, 0x51F0, 0x51F1, 0x51F2, 0x51F3, 0x51F4, - /* U+49B0 */ 0x51F5, 0x51F6, 0x51F7, 0x51F8, 0x51F9, 0x5200, 0xFE8F, 0xFE8E, - /* Contiguous area: U+4C77 .. U+9FA5 */ - /* U+4C77 */ 0xFE96, - /* U+4C78 */ 0x5664, 0x5665, 0x5666, 0x5667, 0x5668, 0x5669, 0x5670, 0x5671, - /* U+4C80 */ 0x5672, 0x5673, 0x5674, 0x5675, 0x5676, 0x5677, 0x5678, 0x5679, - /* U+4C88 */ 0x5680, 0x5681, 0x5682, 0x5683, 0x5684, 0x5685, 0x5686, 0x5687, - /* U+4C90 */ 0x5688, 0x5689, 0x5690, 0x5691, 0x5692, 0x5693, 0x5694, 0x5695, - /* U+4C98 */ 0x5696, 0x5697, 0x5698, 0x5699, 0x56A0, 0x56A1, 0x56A2, 0xFE93, - /* U+4CA0 */ 0xFE94, 0xFE95, 0xFE97, 0xFE92, 0x56A3, 0x56A4, 0x56A5, 0x56A6, - /* U+4CA8 */ 0x56A7, 0x56A8, 0x56A9, 0x56B0, 0x56B1, 0x56B2, 0x56B3, 0x56B4, - /* U+4CB0 */ 0x56B5, 0x56B6, 0x56B7, 0x56B8, 0x56B9, 0x56C0, 0x56C1, 0x56C2, - /* U+4CB8 */ 0x56C3, 0x56C4, 0x56C5, 0x56C6, 0x56C7, 0x56C8, 0x56C9, 0x56D0, - /* U+4CC0 */ 0x56D1, 0x56D2, 0x56D3, 0x56D4, 0x56D5, 0x56D6, 0x56D7, 0x56D8, - /* U+4CC8 */ 0x56D9, 0x56E0, 0x56E1, 0x56E2, 0x56E3, 0x56E4, 0x56E5, 0x56E6, - /* U+4CD0 */ 0x56E7, 0x56E8, 0x56E9, 0x56F0, 0x56F1, 0x56F2, 0x56F3, 0x56F4, - /* U+4CD8 */ 0x56F5, 0x56F6, 0x56F7, 0x56F8, 0x56F9, 0x5700, 0x5701, 0x5702, - /* U+4CE0 */ 0x5703, 0x5704, 0x5705, 0x5706, 0x5707, 0x5708, 0x5709, 0x5710, - /* U+4CE8 */ 0x5711, 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 0x5718, - /* U+4CF0 */ 0x5719, 0x5720, 0x5721, 0x5722, 0x5723, 0x5724, 0x5725, 0x5726, - /* U+4CF8 */ 0x5727, 0x5728, 0x5729, 0x5730, 0x5731, 0x5732, 0x5733, 0x5734, - /* U+4D00 */ 0x5735, 0x5736, 0x5737, 0x5738, 0x5739, 0x5740, 0x5741, 0x5742, - /* U+4D08 */ 0x5743, 0x5744, 0x5745, 0x5746, 0x5747, 0x5748, 0x5749, 0x5750, - /* U+4D10 */ 0x5751, 0x5752, 0x5753, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, - /* U+4D18 */ 0xFE9D, 0xFE9E, 0x5754, 0x5755, 0x5756, 0x5757, 0x5758, 0x5759, - /* U+4D20 */ 0x5760, 0x5761, 0x5762, 0x5763, 0x5764, 0x5765, 0x5766, 0x5767, - /* U+4D28 */ 0x5768, 0x5769, 0x5770, 0x5771, 0x5772, 0x5773, 0x5774, 0x5775, - /* U+4D30 */ 0x5776, 0x5777, 0x5778, 0x5779, 0x5780, 0x5781, 0x5782, 0x5783, - /* U+4D38 */ 0x5784, 0x5785, 0x5786, 0x5787, 0x5788, 0x5789, 0x5790, 0x5791, - /* U+4D40 */ 0x5792, 0x5793, 0x5794, 0x5795, 0x5796, 0x5797, 0x5798, 0x5799, - /* U+4D48 */ 0x57A0, 0x57A1, 0x57A2, 0x57A3, 0x57A4, 0x57A5, 0x57A6, 0x57A7, - /* U+4D50 */ 0x57A8, 0x57A9, 0x57B0, 0x57B1, 0x57B2, 0x57B3, 0x57B4, 0x57B5, - /* U+4D58 */ 0x57B6, 0x57B7, 0x57B8, 0x57B9, 0x57C0, 0x57C1, 0x57C2, 0x57C3, - /* U+4D60 */ 0x57C4, 0x57C5, 0x57C6, 0x57C7, 0x57C8, 0x57C9, 0x57D0, 0x57D1, - /* U+4D68 */ 0x57D2, 0x57D3, 0x57D4, 0x57D5, 0x57D6, 0x57D7, 0x57D8, 0x57D9, - /* U+4D70 */ 0x5800, 0x5801, 0x5802, 0x5803, 0x5804, 0x5805, 0x5806, 0x5807, - /* U+4D78 */ 0x5808, 0x5809, 0x5810, 0x5811, 0x5812, 0x5813, 0x5814, 0x5815, - /* U+4D80 */ 0x5816, 0x5817, 0x5818, 0x5819, 0x5820, 0x5821, 0x5822, 0x5823, - /* U+4D88 */ 0x5824, 0x5825, 0x5826, 0x5827, 0x5828, 0x5829, 0x5830, 0x5831, - /* U+4D90 */ 0x5832, 0x5833, 0x5834, 0x5835, 0x5836, 0x5837, 0x5838, 0x5839, - /* U+4D98 */ 0x5840, 0x5841, 0x5842, 0x5843, 0x5844, 0x5845, 0x5846, 0x5847, - /* U+4DA0 */ 0x5848, 0x5849, 0x5850, 0x5851, 0x5852, 0x5853, 0x5854, 0x5855, - /* U+4DA8 */ 0x5856, 0x5857, 0x5858, 0x5859, 0x5860, 0x5861, 0xFE9F, 0x5862, - /* U+4DB0 */ 0x5863, 0x5864, 0x5865, 0x5866, 0x5867, 0x5868, 0x5869, 0x5870, - /* U+4DB8 */ 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877, 0x5878, - /* U+4DC0 */ 0x5879, 0x5880, 0x5881, 0x5882, 0x5883, 0x5884, 0x5885, 0x5886, - /* U+4DC8 */ 0x5887, 0x5888, 0x5889, 0x5890, 0x5891, 0x5892, 0x5893, 0x5894, - /* U+4DD0 */ 0x5895, 0x5896, 0x5897, 0x5898, 0x5899, 0x58A0, 0x58A1, 0x58A2, - /* U+4DD8 */ 0x58A3, 0x58A4, 0x58A5, 0x58A6, 0x58A7, 0x58A8, 0x58A9, 0x58B0, - /* U+4DE0 */ 0x58B1, 0x58B2, 0x58B3, 0x58B4, 0x58B5, 0x58B6, 0x58B7, 0x58B8, - /* U+4DE8 */ 0x58B9, 0x58C0, 0x58C1, 0x58C2, 0x58C3, 0x58C4, 0x58C5, 0x58C6, - /* U+4DF0 */ 0x58C7, 0x58C8, 0x58C9, 0x58D0, 0x58D1, 0x58D2, 0x58D3, 0x58D4, - /* U+4DF8 */ 0x58D5, 0x58D6, 0x58D7, 0x58D8, 0x58D9, 0x58E0, 0x58E1, 0x58E2, - /* U+4E00 */ 0xD2BB, 0xB6A1, 0x8140, 0xC6DF, 0x8141, 0x8142, 0x8143, 0xCDF2, - /* U+4E08 */ 0xD5C9, 0xC8FD, 0xC9CF, 0xCFC2, 0xD8A2, 0xB2BB, 0xD3EB, 0x8144, - /* U+4E10 */ 0xD8A4, 0xB3F3, 0x8145, 0xD7A8, 0xC7D2, 0xD8A7, 0xCAC0, 0x8146, - /* U+4E18 */ 0xC7F0, 0xB1FB, 0xD2B5, 0xB4D4, 0xB6AB, 0xCBBF, 0xD8A9, 0x8147, - /* U+4E20 */ 0x8148, 0x8149, 0xB6AA, 0x814A, 0xC1BD, 0xD1CF, 0x814B, 0xC9A5, - /* U+4E28 */ 0xD8AD, 0x814C, 0xB8F6, 0xD1BE, 0xE3DC, 0xD6D0, 0x814D, 0x814E, - /* U+4E30 */ 0xB7E1, 0x814F, 0xB4AE, 0x8150, 0xC1D9, 0x8151, 0xD8BC, 0x8152, - /* U+4E38 */ 0xCDE8, 0xB5A4, 0xCEAA, 0xD6F7, 0x8153, 0xC0F6, 0xBED9, 0xD8AF, - /* U+4E40 */ 0x8154, 0x8155, 0x8156, 0xC4CB, 0x8157, 0xBEC3, 0x8158, 0xD8B1, - /* U+4E48 */ 0xC3B4, 0xD2E5, 0x8159, 0xD6AE, 0xCEDA, 0xD5A7, 0xBAF5, 0xB7A6, - /* U+4E50 */ 0xC0D6, 0x815A, 0xC6B9, 0xC5D2, 0xC7C7, 0x815B, 0xB9D4, 0x815C, - /* U+4E58 */ 0xB3CB, 0xD2D2, 0x815D, 0x815E, 0xD8BF, 0xBEC5, 0xC6F2, 0xD2B2, - /* U+4E60 */ 0xCFB0, 0xCFE7, 0x815F, 0x8160, 0x8161, 0x8162, 0xCAE9, 0x8163, - /* U+4E68 */ 0x8164, 0xD8C0, 0x8165, 0x8166, 0x8167, 0x8168, 0x8169, 0x816A, - /* U+4E70 */ 0xC2F2, 0xC2D2, 0x816B, 0xC8E9, 0x816C, 0x816D, 0x816E, 0x816F, - /* U+4E78 */ 0x8170, 0x8171, 0x8172, 0x8173, 0x8174, 0x8175, 0xC7AC, 0x8176, - /* U+4E80 */ 0x8177, 0x8178, 0x8179, 0x817A, 0x817B, 0x817C, 0xC1CB, 0x817D, - /* U+4E88 */ 0xD3E8, 0xD5F9, 0x817E, 0xCAC2, 0xB6FE, 0xD8A1, 0xD3DA, 0xBFF7, - /* U+4E90 */ 0x8180, 0xD4C6, 0xBBA5, 0xD8C1, 0xCEE5, 0xBEAE, 0x8181, 0x8182, - /* U+4E98 */ 0xD8A8, 0x8183, 0xD1C7, 0xD0A9, 0x8184, 0x8185, 0x8186, 0xD8BD, - /* U+4EA0 */ 0xD9EF, 0xCDF6, 0xBFBA, 0x8187, 0xBDBB, 0xBAA5, 0xD2E0, 0xB2FA, - /* U+4EA8 */ 0xBAE0, 0xC4B6, 0x8188, 0xCFED, 0xBEA9, 0xCDA4, 0xC1C1, 0x8189, - /* U+4EB0 */ 0x818A, 0x818B, 0xC7D7, 0xD9F1, 0x818C, 0xD9F4, 0x818D, 0x818E, - /* U+4EB8 */ 0x818F, 0x8190, 0xC8CB, 0xD8E9, 0x8191, 0x8192, 0x8193, 0xD2DA, - /* U+4EC0 */ 0xCAB2, 0xC8CA, 0xD8EC, 0xD8EA, 0xD8C6, 0xBDF6, 0xC6CD, 0xB3F0, - /* U+4EC8 */ 0x8194, 0xD8EB, 0xBDF1, 0xBDE9, 0x8195, 0xC8D4, 0xB4D3, 0x8196, - /* U+4ED0 */ 0x8197, 0xC2D8, 0x8198, 0xB2D6, 0xD7D0, 0xCACB, 0xCBFB, 0xD5CC, - /* U+4ED8 */ 0xB8B6, 0xCFC9, 0x8199, 0x819A, 0x819B, 0xD9DA, 0xD8F0, 0xC7AA, - /* U+4EE0 */ 0x819C, 0xD8EE, 0x819D, 0xB4FA, 0xC1EE, 0xD2D4, 0x819E, 0x819F, - /* U+4EE8 */ 0xD8ED, 0x81A0, 0xD2C7, 0xD8EF, 0xC3C7, 0x81A1, 0x81A2, 0x81A3, - /* U+4EF0 */ 0xD1F6, 0x81A4, 0xD6D9, 0xD8F2, 0x81A5, 0xD8F5, 0xBCFE, 0xBCDB, - /* U+4EF8 */ 0x81A6, 0x81A7, 0x81A8, 0xC8CE, 0x81A9, 0xB7DD, 0x81AA, 0xB7C2, - /* U+4F00 */ 0x81AB, 0xC6F3, 0x81AC, 0x81AD, 0x81AE, 0x81AF, 0x81B0, 0x81B1, - /* U+4F08 */ 0x81B2, 0xD8F8, 0xD2C1, 0x81B3, 0x81B4, 0xCEE9, 0xBCBF, 0xB7FC, - /* U+4F10 */ 0xB7A5, 0xD0DD, 0x81B5, 0x81B6, 0x81B7, 0x81B8, 0x81B9, 0xD6DA, - /* U+4F18 */ 0xD3C5, 0xBBEF, 0xBBE1, 0xD8F1, 0x81BA, 0x81BB, 0xC9A1, 0xCEB0, - /* U+4F20 */ 0xB4AB, 0x81BC, 0xD8F3, 0x81BD, 0xC9CB, 0xD8F6, 0xC2D7, 0xD8F7, - /* U+4F28 */ 0x81BE, 0x81BF, 0xCEB1, 0xD8F9, 0x81C0, 0x81C1, 0x81C2, 0xB2AE, - /* U+4F30 */ 0xB9C0, 0x81C3, 0xD9A3, 0x81C4, 0xB0E9, 0x81C5, 0xC1E6, 0x81C6, - /* U+4F38 */ 0xC9EC, 0x81C7, 0xCBC5, 0x81C8, 0xCBC6, 0xD9A4, 0x81C9, 0x81CA, - /* U+4F40 */ 0x81CB, 0x81CC, 0x81CD, 0xB5E8, 0x81CE, 0x81CF, 0xB5AB, 0x81D0, - /* U+4F48 */ 0x81D1, 0x81D2, 0x81D3, 0x81D4, 0x81D5, 0xCEBB, 0xB5CD, 0xD7A1, - /* U+4F50 */ 0xD7F4, 0xD3D3, 0x81D6, 0xCCE5, 0x81D7, 0xBACE, 0x81D8, 0xD9A2, - /* U+4F58 */ 0xD9DC, 0xD3E0, 0xD8FD, 0xB7F0, 0xD7F7, 0xD8FE, 0xD8FA, 0xD9A1, - /* U+4F60 */ 0xC4E3, 0x81D9, 0x81DA, 0xD3B6, 0xD8F4, 0xD9DD, 0x81DB, 0xD8FB, - /* U+4F68 */ 0x81DC, 0xC5E5, 0x81DD, 0x81DE, 0xC0D0, 0x81DF, 0x81E0, 0xD1F0, - /* U+4F70 */ 0xB0DB, 0x81E1, 0x81E2, 0xBCD1, 0xD9A6, 0x81E3, 0xD9A5, 0x81E4, - /* U+4F78 */ 0x81E5, 0x81E6, 0x81E7, 0xD9AC, 0xD9AE, 0x81E8, 0xD9AB, 0xCAB9, - /* U+4F80 */ 0x81E9, 0x81EA, 0x81EB, 0xD9A9, 0xD6B6, 0x81EC, 0x81ED, 0x81EE, - /* U+4F88 */ 0xB3DE, 0xD9A8, 0x81EF, 0xC0FD, 0x81F0, 0xCACC, 0x81F1, 0xD9AA, - /* U+4F90 */ 0x81F2, 0xD9A7, 0x81F3, 0x81F4, 0xD9B0, 0x81F5, 0x81F6, 0xB6B1, - /* U+4F98 */ 0x81F7, 0x81F8, 0x81F9, 0xB9A9, 0x81FA, 0xD2C0, 0x81FB, 0x81FC, - /* U+4FA0 */ 0xCFC0, 0x81FD, 0x81FE, 0xC2C2, 0x8240, 0xBDC4, 0xD5EC, 0xB2E0, - /* U+4FA8 */ 0xC7C8, 0xBFEB, 0xD9AD, 0x8241, 0xD9AF, 0x8242, 0xCEEA, 0xBAEE, - /* U+4FB0 */ 0x8243, 0x8244, 0x8245, 0x8246, 0x8247, 0xC7D6, 0x8248, 0x8249, - /* U+4FB8 */ 0x824A, 0x824B, 0x824C, 0x824D, 0x824E, 0x824F, 0x8250, 0xB1E3, - /* U+4FC0 */ 0x8251, 0x8252, 0x8253, 0xB4D9, 0xB6ED, 0xD9B4, 0x8254, 0x8255, - /* U+4FC8 */ 0x8256, 0x8257, 0xBFA1, 0x8258, 0x8259, 0x825A, 0xD9DE, 0xC7CE, - /* U+4FD0 */ 0xC0FE, 0xD9B8, 0x825B, 0x825C, 0x825D, 0x825E, 0x825F, 0xCBD7, - /* U+4FD8 */ 0xB7FD, 0x8260, 0xD9B5, 0x8261, 0xD9B7, 0xB1A3, 0xD3E1, 0xD9B9, - /* U+4FE0 */ 0x8262, 0xD0C5, 0x8263, 0xD9B6, 0x8264, 0x8265, 0xD9B1, 0x8266, - /* U+4FE8 */ 0xD9B2, 0xC1A9, 0xD9B3, 0x8267, 0x8268, 0xBCF3, 0xD0DE, 0xB8A9, - /* U+4FF0 */ 0x8269, 0xBEE3, 0x826A, 0xD9BD, 0x826B, 0x826C, 0x826D, 0x826E, - /* U+4FF8 */ 0xD9BA, 0x826F, 0xB0B3, 0x8270, 0x8271, 0x8272, 0xD9C2, 0x8273, - /* U+5000 */ 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x827A, 0x827B, - /* U+5008 */ 0x827C, 0x827D, 0x827E, 0x8280, 0xD9C4, 0xB1B6, 0x8281, 0xD9BF, - /* U+5010 */ 0x8282, 0x8283, 0xB5B9, 0x8284, 0xBEF3, 0x8285, 0x8286, 0x8287, - /* U+5018 */ 0xCCC8, 0xBAF2, 0xD2D0, 0x8288, 0xD9C3, 0x8289, 0x828A, 0xBDE8, - /* U+5020 */ 0x828B, 0xB3AB, 0x828C, 0x828D, 0x828E, 0xD9C5, 0xBEEB, 0x828F, - /* U+5028 */ 0xD9C6, 0xD9BB, 0xC4DF, 0x8290, 0xD9BE, 0xD9C1, 0xD9C0, 0x8291, - /* U+5030 */ 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, - /* U+5038 */ 0x829A, 0x829B, 0xD5AE, 0x829C, 0xD6B5, 0x829D, 0xC7E3, 0x829E, - /* U+5040 */ 0x829F, 0x82A0, 0x82A1, 0xD9C8, 0x82A2, 0x82A3, 0x82A4, 0xBCD9, - /* U+5048 */ 0xD9CA, 0x82A5, 0x82A6, 0x82A7, 0xD9BC, 0x82A8, 0xD9CB, 0xC6AB, - /* U+5050 */ 0x82A9, 0x82AA, 0x82AB, 0x82AC, 0x82AD, 0xD9C9, 0x82AE, 0x82AF, - /* U+5058 */ 0x82B0, 0x82B1, 0xD7F6, 0x82B2, 0xCDA3, 0x82B3, 0x82B4, 0x82B5, - /* U+5060 */ 0x82B6, 0x82B7, 0x82B8, 0x82B9, 0x82BA, 0xBDA1, 0x82BB, 0x82BC, - /* U+5068 */ 0x82BD, 0x82BE, 0x82BF, 0x82C0, 0xD9CC, 0x82C1, 0x82C2, 0x82C3, - /* U+5070 */ 0x82C4, 0x82C5, 0x82C6, 0x82C7, 0x82C8, 0x82C9, 0xC5BC, 0xCDB5, - /* U+5078 */ 0x82CA, 0x82CB, 0x82CC, 0xD9CD, 0x82CD, 0x82CE, 0xD9C7, 0xB3A5, - /* U+5080 */ 0xBFFE, 0x82CF, 0x82D0, 0x82D1, 0x82D2, 0xB8B5, 0x82D3, 0x82D4, - /* U+5088 */ 0xC0FC, 0x82D5, 0x82D6, 0x82D7, 0x82D8, 0xB0F8, 0x82D9, 0x82DA, - /* U+5090 */ 0x82DB, 0x82DC, 0x82DD, 0x82DE, 0x82DF, 0x82E0, 0x82E1, 0x82E2, - /* U+5098 */ 0x82E3, 0x82E4, 0x82E5, 0x82E6, 0x82E7, 0x82E8, 0x82E9, 0x82EA, - /* U+50A0 */ 0x82EB, 0x82EC, 0x82ED, 0xB4F6, 0x82EE, 0xD9CE, 0x82EF, 0xD9CF, - /* U+50A8 */ 0xB4A2, 0xD9D0, 0x82F0, 0x82F1, 0xB4DF, 0x82F2, 0x82F3, 0x82F4, - /* U+50B0 */ 0x82F5, 0x82F6, 0xB0C1, 0x82F7, 0x82F8, 0x82F9, 0x82FA, 0x82FB, - /* U+50B8 */ 0x82FC, 0x82FD, 0xD9D1, 0xC9B5, 0x82FE, 0x8340, 0x8341, 0x8342, - /* U+50C0 */ 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 0x8348, 0x8349, 0x834A, - /* U+50C8 */ 0x834B, 0x834C, 0x834D, 0x834E, 0x834F, 0x8350, 0x8351, 0xCFF1, - /* U+50D0 */ 0x8352, 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0xD9D2, 0x8358, - /* U+50D8 */ 0x8359, 0x835A, 0xC1C5, 0x835B, 0x835C, 0x835D, 0x835E, 0x835F, - /* U+50E0 */ 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365, 0xD9D6, 0xC9AE, - /* U+50E8 */ 0x8366, 0x8367, 0x8368, 0x8369, 0xD9D5, 0xD9D4, 0xD9D7, 0x836A, - /* U+50F0 */ 0x836B, 0x836C, 0x836D, 0xCBDB, 0x836E, 0xBDA9, 0x836F, 0x8370, - /* U+50F8 */ 0x8371, 0x8372, 0x8373, 0xC6A7, 0x8374, 0x8375, 0x8376, 0x8377, - /* U+5100 */ 0x8378, 0x8379, 0x837A, 0x837B, 0x837C, 0x837D, 0xD9D3, 0xD9D8, - /* U+5108 */ 0x837E, 0x8380, 0x8381, 0xD9D9, 0x8382, 0x8383, 0x8384, 0x8385, - /* U+5110 */ 0x8386, 0x8387, 0xC8E5, 0x8388, 0x8389, 0x838A, 0x838B, 0x838C, - /* U+5118 */ 0x838D, 0x838E, 0x838F, 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, - /* U+5120 */ 0x8395, 0xC0DC, 0x8396, 0x8397, 0x8398, 0x8399, 0x839A, 0x839B, - /* U+5128 */ 0x839C, 0x839D, 0x839E, 0x839F, 0x83A0, 0x83A1, 0x83A2, 0x83A3, - /* U+5130 */ 0x83A4, 0x83A5, 0x83A6, 0x83A7, 0x83A8, 0x83A9, 0x83AA, 0x83AB, - /* U+5138 */ 0x83AC, 0x83AD, 0x83AE, 0x83AF, 0x83B0, 0x83B1, 0x83B2, 0xB6F9, - /* U+5140 */ 0xD8A3, 0xD4CA, 0x83B3, 0xD4AA, 0xD0D6, 0xB3E4, 0xD5D7, 0x83B4, - /* U+5148 */ 0xCFC8, 0xB9E2, 0x83B5, 0xBFCB, 0x83B6, 0xC3E2, 0x83B7, 0x83B8, - /* U+5150 */ 0x83B9, 0xB6D2, 0x83BA, 0x83BB, 0xCDC3, 0xD9EE, 0xD9F0, 0x83BC, - /* U+5158 */ 0x83BD, 0x83BE, 0xB5B3, 0x83BF, 0xB6B5, 0x83C0, 0x83C1, 0x83C2, - /* U+5160 */ 0x83C3, 0x83C4, 0xBEA4, 0x83C5, 0x83C6, 0xC8EB, 0x83C7, 0x83C8, - /* U+5168 */ 0xC8AB, 0x83C9, 0x83CA, 0xB0CB, 0xB9AB, 0xC1F9, 0xD9E2, 0x83CB, - /* U+5170 */ 0xC0BC, 0xB9B2, 0x83CC, 0xB9D8, 0xD0CB, 0xB1F8, 0xC6E4, 0xBEDF, - /* U+5178 */ 0xB5E4, 0xD7C8, 0x83CD, 0xD1F8, 0xBCE6, 0xCADE, 0x83CE, 0x83CF, - /* U+5180 */ 0xBCBD, 0xD9E6, 0xD8E7, 0x83D0, 0x83D1, 0xC4DA, 0x83D2, 0x83D3, - /* U+5188 */ 0xB8D4, 0xC8BD, 0x83D4, 0x83D5, 0xB2E1, 0xD4D9, 0x83D6, 0x83D7, - /* U+5190 */ 0x83D8, 0x83D9, 0xC3B0, 0x83DA, 0x83DB, 0xC3E1, 0xDAA2, 0xC8DF, - /* U+5198 */ 0x83DC, 0xD0B4, 0x83DD, 0xBEFC, 0xC5A9, 0x83DE, 0x83DF, 0x83E0, - /* U+51A0 */ 0xB9DA, 0x83E1, 0xDAA3, 0x83E2, 0xD4A9, 0xDAA4, 0x83E3, 0x83E4, - /* U+51A8 */ 0x83E5, 0x83E6, 0x83E7, 0xD9FB, 0xB6AC, 0x83E8, 0x83E9, 0xB7EB, - /* U+51B0 */ 0xB1F9, 0xD9FC, 0xB3E5, 0xBEF6, 0x83EA, 0xBFF6, 0xD2B1, 0xC0E4, - /* U+51B8 */ 0x83EB, 0x83EC, 0x83ED, 0xB6B3, 0xD9FE, 0xD9FD, 0x83EE, 0x83EF, - /* U+51C0 */ 0xBEBB, 0x83F0, 0x83F1, 0x83F2, 0xC6E0, 0x83F3, 0xD7BC, 0xDAA1, - /* U+51C8 */ 0x83F4, 0xC1B9, 0x83F5, 0xB5F2, 0xC1E8, 0x83F6, 0x83F7, 0xBCF5, - /* U+51D0 */ 0x83F8, 0xB4D5, 0x83F9, 0x83FA, 0x83FB, 0x83FC, 0x83FD, 0x83FE, - /* U+51D8 */ 0x8440, 0x8441, 0x8442, 0xC1DD, 0x8443, 0xC4FD, 0x8444, 0x8445, - /* U+51E0 */ 0xBCB8, 0xB7B2, 0x8446, 0x8447, 0xB7EF, 0x8448, 0x8449, 0x844A, - /* U+51E8 */ 0x844B, 0x844C, 0x844D, 0xD9EC, 0x844E, 0xC6BE, 0x844F, 0xBFAD, - /* U+51F0 */ 0xBBCB, 0x8450, 0x8451, 0xB5CA, 0x8452, 0xDBC9, 0xD0D7, 0x8453, - /* U+51F8 */ 0xCDB9, 0xB0BC, 0xB3F6, 0xBBF7, 0xDBCA, 0xBAAF, 0x8454, 0xD4E4, - /* U+5200 */ 0xB5B6, 0xB5F3, 0xD8D6, 0xC8D0, 0x8455, 0x8456, 0xB7D6, 0xC7D0, - /* U+5208 */ 0xD8D7, 0x8457, 0xBFAF, 0x8458, 0x8459, 0xDBBB, 0xD8D8, 0x845A, - /* U+5210 */ 0x845B, 0xD0CC, 0xBBAE, 0x845C, 0x845D, 0x845E, 0xEBBE, 0xC1D0, - /* U+5218 */ 0xC1F5, 0xD4F2, 0xB8D5, 0xB4B4, 0x845F, 0xB3F5, 0x8460, 0x8461, - /* U+5220 */ 0xC9BE, 0x8462, 0x8463, 0x8464, 0xC5D0, 0x8465, 0x8466, 0x8467, - /* U+5228 */ 0xC5D9, 0xC0FB, 0x8468, 0xB1F0, 0x8469, 0xD8D9, 0xB9CE, 0x846A, - /* U+5230 */ 0xB5BD, 0x846B, 0x846C, 0xD8DA, 0x846D, 0x846E, 0xD6C6, 0xCBA2, - /* U+5238 */ 0xC8AF, 0xC9B2, 0xB4CC, 0xBFCC, 0x846F, 0xB9F4, 0x8470, 0xD8DB, - /* U+5240 */ 0xD8DC, 0xB6E7, 0xBCC1, 0xCCEA, 0x8471, 0x8472, 0x8473, 0x8474, - /* U+5248 */ 0x8475, 0x8476, 0xCFF7, 0x8477, 0xD8DD, 0xC7B0, 0x8478, 0x8479, - /* U+5250 */ 0xB9D0, 0xBDA3, 0x847A, 0x847B, 0xCCDE, 0x847C, 0xC6CA, 0x847D, - /* U+5258 */ 0x847E, 0x8480, 0x8481, 0x8482, 0xD8E0, 0x8483, 0xD8DE, 0x8484, - /* U+5260 */ 0x8485, 0xD8DF, 0x8486, 0x8487, 0x8488, 0xB0FE, 0x8489, 0xBEE7, - /* U+5268 */ 0x848A, 0xCAA3, 0xBCF4, 0x848B, 0x848C, 0x848D, 0x848E, 0xB8B1, - /* U+5270 */ 0x848F, 0x8490, 0xB8EE, 0x8491, 0x8492, 0x8493, 0x8494, 0x8495, - /* U+5278 */ 0x8496, 0x8497, 0x8498, 0x8499, 0x849A, 0xD8E2, 0x849B, 0xBDCB, - /* U+5280 */ 0x849C, 0xD8E4, 0xD8E3, 0x849D, 0x849E, 0x849F, 0x84A0, 0x84A1, - /* U+5288 */ 0xC5FC, 0x84A2, 0x84A3, 0x84A4, 0x84A5, 0x84A6, 0x84A7, 0x84A8, - /* U+5290 */ 0xD8E5, 0x84A9, 0x84AA, 0xD8E6, 0x84AB, 0x84AC, 0x84AD, 0x84AE, - /* U+5298 */ 0x84AF, 0x84B0, 0x84B1, 0xC1A6, 0x84B2, 0xC8B0, 0xB0EC, 0xB9A6, - /* U+52A0 */ 0xBCD3, 0xCEF1, 0xDBBD, 0xC1D3, 0x84B3, 0x84B4, 0x84B5, 0x84B6, - /* U+52A8 */ 0xB6AF, 0xD6FA, 0xC5AC, 0xBDD9, 0xDBBE, 0xDBBF, 0x84B7, 0x84B8, - /* U+52B0 */ 0x84B9, 0xC0F8, 0xBEA2, 0xC0CD, 0x84BA, 0x84BB, 0x84BC, 0x84BD, - /* U+52B8 */ 0x84BE, 0x84BF, 0x84C0, 0x84C1, 0x84C2, 0x84C3, 0xDBC0, 0xCAC6, - /* U+52C0 */ 0x84C4, 0x84C5, 0x84C6, 0xB2AA, 0x84C7, 0x84C8, 0x84C9, 0xD3C2, - /* U+52C8 */ 0x84CA, 0xC3E3, 0x84CB, 0xD1AB, 0x84CC, 0x84CD, 0x84CE, 0x84CF, - /* U+52D0 */ 0xDBC2, 0x84D0, 0xC0D5, 0x84D1, 0x84D2, 0x84D3, 0xDBC3, 0x84D4, - /* U+52D8 */ 0xBFB1, 0x84D5, 0x84D6, 0x84D7, 0x84D8, 0x84D9, 0x84DA, 0xC4BC, - /* U+52E0 */ 0x84DB, 0x84DC, 0x84DD, 0x84DE, 0xC7DA, 0x84DF, 0x84E0, 0x84E1, - /* U+52E8 */ 0x84E2, 0x84E3, 0x84E4, 0x84E5, 0x84E6, 0x84E7, 0x84E8, 0x84E9, - /* U+52F0 */ 0xDBC4, 0x84EA, 0x84EB, 0x84EC, 0x84ED, 0x84EE, 0x84EF, 0x84F0, - /* U+52F8 */ 0x84F1, 0xD9E8, 0xC9D7, 0x84F2, 0x84F3, 0x84F4, 0xB9B4, 0xCEF0, - /* U+5300 */ 0xD4C8, 0x84F5, 0x84F6, 0x84F7, 0x84F8, 0xB0FC, 0xB4D2, 0x84F9, - /* U+5308 */ 0xD0D9, 0x84FA, 0x84FB, 0x84FC, 0x84FD, 0xD9E9, 0x84FE, 0xDECB, - /* U+5310 */ 0xD9EB, 0x8540, 0x8541, 0x8542, 0x8543, 0xD8B0, 0xBBAF, 0xB1B1, - /* U+5318 */ 0x8544, 0xB3D7, 0xD8CE, 0x8545, 0x8546, 0xD4D1, 0x8547, 0x8548, - /* U+5320 */ 0xBDB3, 0xBFEF, 0x8549, 0xCFBB, 0x854A, 0x854B, 0xD8D0, 0x854C, - /* U+5328 */ 0x854D, 0x854E, 0xB7CB, 0x854F, 0x8550, 0x8551, 0xD8D1, 0x8552, - /* U+5330 */ 0x8553, 0x8554, 0x8555, 0x8556, 0x8557, 0x8558, 0x8559, 0x855A, - /* U+5338 */ 0x855B, 0xC6A5, 0xC7F8, 0xD2BD, 0x855C, 0x855D, 0xD8D2, 0xC4E4, - /* U+5340 */ 0x855E, 0xCAAE, 0x855F, 0xC7A7, 0x8560, 0xD8A6, 0x8561, 0xC9FD, - /* U+5348 */ 0xCEE7, 0xBBDC, 0xB0EB, 0x8562, 0x8563, 0x8564, 0xBBAA, 0xD0AD, - /* U+5350 */ 0x8565, 0xB1B0, 0xD7E4, 0xD7BF, 0x8566, 0xB5A5, 0xC2F4, 0xC4CF, - /* U+5358 */ 0x8567, 0x8568, 0xB2A9, 0x8569, 0xB2B7, 0x856A, 0xB1E5, 0xDFB2, - /* U+5360 */ 0xD5BC, 0xBFA8, 0xC2AC, 0xD8D5, 0xC2B1, 0x856B, 0xD8D4, 0xCED4, - /* U+5368 */ 0x856C, 0xDAE0, 0x856D, 0xCEC0, 0x856E, 0x856F, 0xD8B4, 0xC3AE, - /* U+5370 */ 0xD3A1, 0xCEA3, 0x8570, 0xBCB4, 0xC8B4, 0xC2D1, 0x8571, 0xBEED, - /* U+5378 */ 0xD0B6, 0x8572, 0xDAE1, 0x8573, 0x8574, 0x8575, 0x8576, 0xC7E4, - /* U+5380 */ 0x8577, 0x8578, 0xB3A7, 0x8579, 0xB6F2, 0xCCFC, 0xC0FA, 0x857A, - /* U+5388 */ 0x857B, 0xC0F7, 0x857C, 0xD1B9, 0xD1E1, 0xD8C7, 0x857D, 0x857E, - /* U+5390 */ 0x8580, 0x8581, 0x8582, 0x8583, 0x8584, 0xB2DE, 0x8585, 0x8586, - /* U+5398 */ 0xC0E5, 0x8587, 0xBAF1, 0x8588, 0x8589, 0xD8C8, 0x858A, 0xD4AD, - /* U+53A0 */ 0x858B, 0x858C, 0xCFE1, 0xD8C9, 0x858D, 0xD8CA, 0xCFC3, 0x858E, - /* U+53A8 */ 0xB3F8, 0xBEC7, 0x858F, 0x8590, 0x8591, 0x8592, 0xD8CB, 0x8593, - /* U+53B0 */ 0x8594, 0x8595, 0x8596, 0x8597, 0x8598, 0x8599, 0xDBCC, 0x859A, - /* U+53B8 */ 0x859B, 0x859C, 0x859D, 0xC8A5, 0x859E, 0x859F, 0x85A0, 0xCFD8, - /* U+53C0 */ 0x85A1, 0xC8FE, 0xB2CE, 0x85A2, 0x85A3, 0x85A4, 0x85A5, 0x85A6, - /* U+53C8 */ 0xD3D6, 0xB2E6, 0xBCB0, 0xD3D1, 0xCBAB, 0xB7B4, 0x85A7, 0x85A8, - /* U+53D0 */ 0x85A9, 0xB7A2, 0x85AA, 0x85AB, 0xCAE5, 0x85AC, 0xC8A1, 0xCADC, - /* U+53D8 */ 0xB1E4, 0xD0F0, 0x85AD, 0xC5D1, 0x85AE, 0x85AF, 0x85B0, 0xDBC5, - /* U+53E0 */ 0xB5FE, 0x85B1, 0x85B2, 0xBFDA, 0xB9C5, 0xBEE4, 0xC1ED, 0x85B3, - /* U+53E8 */ 0xDFB6, 0xDFB5, 0xD6BB, 0xBDD0, 0xD5D9, 0xB0C8, 0xB6A3, 0xBFC9, - /* U+53F0 */ 0xCCA8, 0xDFB3, 0xCAB7, 0xD3D2, 0x85B4, 0xD8CF, 0xD2B6, 0xBAC5, - /* U+53F8 */ 0xCBBE, 0xCCBE, 0x85B5, 0xDFB7, 0xB5F0, 0xDFB4, 0x85B6, 0x85B7, - /* U+5400 */ 0x85B8, 0xD3F5, 0x85B9, 0xB3D4, 0xB8F7, 0x85BA, 0xDFBA, 0x85BB, - /* U+5408 */ 0xBACF, 0xBCAA, 0xB5F5, 0x85BC, 0xCDAC, 0xC3FB, 0xBAF3, 0xC0F4, - /* U+5410 */ 0xCDC2, 0xCFF2, 0xDFB8, 0xCFC5, 0x85BD, 0xC2C0, 0xDFB9, 0xC2F0, - /* U+5418 */ 0x85BE, 0x85BF, 0x85C0, 0xBEFD, 0x85C1, 0xC1DF, 0xCDCC, 0xD2F7, - /* U+5420 */ 0xB7CD, 0xDFC1, 0x85C2, 0xDFC4, 0x85C3, 0x85C4, 0xB7F1, 0xB0C9, - /* U+5428 */ 0xB6D6, 0xB7D4, 0x85C5, 0xBAAC, 0xCCFD, 0xBFD4, 0xCBB1, 0xC6F4, - /* U+5430 */ 0x85C6, 0xD6A8, 0xDFC5, 0x85C7, 0xCEE2, 0xB3B3, 0x85C8, 0x85C9, - /* U+5438 */ 0xCEFC, 0xB4B5, 0x85CA, 0xCEC7, 0xBAF0, 0x85CB, 0xCEE1, 0x85CC, - /* U+5440 */ 0xD1BD, 0x85CD, 0x85CE, 0xDFC0, 0x85CF, 0x85D0, 0xB4F4, 0x85D1, - /* U+5448 */ 0xB3CA, 0x85D2, 0xB8E6, 0xDFBB, 0x85D3, 0x85D4, 0x85D5, 0x85D6, - /* U+5450 */ 0xC4C5, 0x85D7, 0xDFBC, 0xDFBD, 0xDFBE, 0xC5BB, 0xDFBF, 0xDFC2, - /* U+5458 */ 0xD4B1, 0xDFC3, 0x85D8, 0xC7BA, 0xCED8, 0x85D9, 0x85DA, 0x85DB, - /* U+5460 */ 0x85DC, 0x85DD, 0xC4D8, 0x85DE, 0xDFCA, 0x85DF, 0xDFCF, 0x85E0, - /* U+5468 */ 0xD6DC, 0x85E1, 0x85E2, 0x85E3, 0x85E4, 0x85E5, 0x85E6, 0x85E7, - /* U+5470 */ 0x85E8, 0xDFC9, 0xDFDA, 0xCEB6, 0x85E9, 0xBAC7, 0xDFCE, 0xDFC8, - /* U+5478 */ 0xC5DE, 0x85EA, 0x85EB, 0xC9EB, 0xBAF4, 0xC3FC, 0x85EC, 0x85ED, - /* U+5480 */ 0xBED7, 0x85EE, 0xDFC6, 0x85EF, 0xDFCD, 0x85F0, 0xC5D8, 0x85F1, - /* U+5488 */ 0x85F2, 0x85F3, 0x85F4, 0xD5A6, 0xBACD, 0x85F5, 0xBECC, 0xD3BD, - /* U+5490 */ 0xB8C0, 0x85F6, 0xD6E4, 0x85F7, 0xDFC7, 0xB9BE, 0xBFA7, 0x85F8, - /* U+5498 */ 0x85F9, 0xC1FC, 0xDFCB, 0xDFCC, 0x85FA, 0xDFD0, 0x85FB, 0x85FC, - /* U+54A0 */ 0x85FD, 0x85FE, 0x8640, 0xDFDB, 0xDFE5, 0x8641, 0xDFD7, 0xDFD6, - /* U+54A8 */ 0xD7C9, 0xDFE3, 0xDFE4, 0xE5EB, 0xD2A7, 0xDFD2, 0x8642, 0xBFA9, - /* U+54B0 */ 0x8643, 0xD4DB, 0x8644, 0xBFC8, 0xDFD4, 0x8645, 0x8646, 0x8647, - /* U+54B8 */ 0xCFCC, 0x8648, 0x8649, 0xDFDD, 0x864A, 0xD1CA, 0x864B, 0xDFDE, - /* U+54C0 */ 0xB0A7, 0xC6B7, 0xDFD3, 0x864C, 0xBAE5, 0x864D, 0xB6DF, 0xCDDB, - /* U+54C8 */ 0xB9FE, 0xD4D5, 0x864E, 0x864F, 0xDFDF, 0xCFEC, 0xB0A5, 0xDFE7, - /* U+54D0 */ 0xDFD1, 0xD1C6, 0xDFD5, 0xDFD8, 0xDFD9, 0xDFDC, 0x8650, 0xBBA9, - /* U+54D8 */ 0x8651, 0xDFE0, 0xDFE1, 0x8652, 0xDFE2, 0xDFE6, 0xDFE8, 0xD3B4, - /* U+54E0 */ 0x8653, 0x8654, 0x8655, 0x8656, 0x8657, 0xB8E7, 0xC5B6, 0xDFEA, - /* U+54E8 */ 0xC9DA, 0xC1A8, 0xC4C4, 0x8658, 0x8659, 0xBFDE, 0xCFF8, 0x865A, - /* U+54F0 */ 0x865B, 0x865C, 0xD5DC, 0xDFEE, 0x865D, 0x865E, 0x865F, 0x8660, - /* U+54F8 */ 0x8661, 0x8662, 0xB2B8, 0x8663, 0xBADF, 0xDFEC, 0x8664, 0xDBC1, - /* U+5500 */ 0x8665, 0xD1E4, 0x8666, 0x8667, 0x8668, 0x8669, 0xCBF4, 0xB4BD, - /* U+5508 */ 0x866A, 0xB0A6, 0x866B, 0x866C, 0x866D, 0x866E, 0x866F, 0xDFF1, - /* U+5510 */ 0xCCC6, 0xDFF2, 0x8670, 0x8671, 0xDFED, 0x8672, 0x8673, 0x8674, - /* U+5518 */ 0x8675, 0x8676, 0x8677, 0xDFE9, 0x8678, 0x8679, 0x867A, 0x867B, - /* U+5520 */ 0xDFEB, 0x867C, 0xDFEF, 0xDFF0, 0xBBBD, 0x867D, 0x867E, 0xDFF3, - /* U+5528 */ 0x8680, 0x8681, 0xDFF4, 0x8682, 0xBBA3, 0x8683, 0xCADB, 0xCEA8, - /* U+5530 */ 0xE0A7, 0xB3AA, 0x8684, 0xE0A6, 0x8685, 0x8686, 0x8687, 0xE0A1, - /* U+5538 */ 0x8688, 0x8689, 0x868A, 0x868B, 0xDFFE, 0x868C, 0xCDD9, 0xDFFC, - /* U+5540 */ 0x868D, 0xDFFA, 0x868E, 0xBFD0, 0xD7C4, 0x868F, 0xC9CC, 0x8690, - /* U+5548 */ 0x8691, 0xDFF8, 0xB0A1, 0x8692, 0x8693, 0x8694, 0x8695, 0x8696, - /* U+5550 */ 0xDFFD, 0x8697, 0x8698, 0x8699, 0x869A, 0xDFFB, 0xE0A2, 0x869B, - /* U+5558 */ 0x869C, 0x869D, 0x869E, 0x869F, 0xE0A8, 0x86A0, 0x86A1, 0x86A2, - /* U+5560 */ 0x86A3, 0xB7C8, 0x86A4, 0x86A5, 0xC6A1, 0xC9B6, 0xC0B2, 0xDFF5, - /* U+5568 */ 0x86A6, 0x86A7, 0xC5BE, 0x86A8, 0xD8C4, 0xDFF9, 0xC4F6, 0x86A9, - /* U+5570 */ 0x86AA, 0x86AB, 0x86AC, 0x86AD, 0x86AE, 0xE0A3, 0xE0A4, 0xE0A5, - /* U+5578 */ 0xD0A5, 0x86AF, 0x86B0, 0xE0B4, 0xCCE4, 0x86B1, 0xE0B1, 0x86B2, - /* U+5580 */ 0xBFA6, 0xE0AF, 0xCEB9, 0xE0AB, 0xC9C6, 0x86B3, 0x86B4, 0xC0AE, - /* U+5588 */ 0xE0AE, 0xBAED, 0xBAB0, 0xE0A9, 0x86B5, 0x86B6, 0x86B7, 0xDFF6, - /* U+5590 */ 0x86B8, 0xE0B3, 0x86B9, 0x86BA, 0xE0B8, 0x86BB, 0x86BC, 0x86BD, - /* U+5598 */ 0xB4AD, 0xE0B9, 0x86BE, 0x86BF, 0xCFB2, 0xBAC8, 0x86C0, 0xE0B0, - /* U+55A0 */ 0x86C1, 0x86C2, 0x86C3, 0x86C4, 0x86C5, 0x86C6, 0x86C7, 0xD0FA, - /* U+55A8 */ 0x86C8, 0x86C9, 0x86CA, 0x86CB, 0x86CC, 0x86CD, 0x86CE, 0x86CF, - /* U+55B0 */ 0x86D0, 0xE0AC, 0x86D1, 0xD4FB, 0x86D2, 0xDFF7, 0x86D3, 0xC5E7, - /* U+55B8 */ 0x86D4, 0xE0AD, 0x86D5, 0xD3F7, 0x86D6, 0xE0B6, 0xE0B7, 0x86D7, - /* U+55C0 */ 0x86D8, 0x86D9, 0x86DA, 0x86DB, 0xE0C4, 0xD0E1, 0x86DC, 0x86DD, - /* U+55C8 */ 0x86DE, 0xE0BC, 0x86DF, 0x86E0, 0xE0C9, 0xE0CA, 0x86E1, 0x86E2, - /* U+55D0 */ 0x86E3, 0xE0BE, 0xE0AA, 0xC9A4, 0xE0C1, 0x86E4, 0xE0B2, 0x86E5, - /* U+55D8 */ 0x86E6, 0x86E7, 0x86E8, 0x86E9, 0xCAC8, 0xE0C3, 0x86EA, 0xE0B5, - /* U+55E0 */ 0x86EB, 0xCECB, 0x86EC, 0xCBC3, 0xE0CD, 0xE0C6, 0xE0C2, 0x86ED, - /* U+55E8 */ 0xE0CB, 0x86EE, 0xE0BA, 0xE0BF, 0xE0C0, 0x86EF, 0x86F0, 0xE0C5, - /* U+55F0 */ 0x86F1, 0x86F2, 0xE0C7, 0xE0C8, 0x86F3, 0xE0CC, 0x86F4, 0xE0BB, - /* U+55F8 */ 0x86F5, 0x86F6, 0x86F7, 0x86F8, 0x86F9, 0xCBD4, 0xE0D5, 0x86FA, - /* U+5600 */ 0xE0D6, 0xE0D2, 0x86FB, 0x86FC, 0x86FD, 0x86FE, 0x8740, 0x8741, - /* U+5608 */ 0xE0D0, 0xBCCE, 0x8742, 0x8743, 0xE0D1, 0x8744, 0xB8C2, 0xD8C5, - /* U+5610 */ 0x8745, 0x8746, 0x8747, 0x8748, 0x8749, 0x874A, 0x874B, 0x874C, - /* U+5618 */ 0xD0EA, 0x874D, 0x874E, 0xC2EF, 0x874F, 0x8750, 0xE0CF, 0xE0BD, - /* U+5620 */ 0x8751, 0x8752, 0x8753, 0xE0D4, 0xE0D3, 0x8754, 0x8755, 0xE0D7, - /* U+5628 */ 0x8756, 0x8757, 0x8758, 0x8759, 0xE0DC, 0xE0D8, 0x875A, 0x875B, - /* U+5630 */ 0x875C, 0xD6F6, 0xB3B0, 0x875D, 0xD7EC, 0x875E, 0xCBBB, 0x875F, - /* U+5638 */ 0x8760, 0xE0DA, 0x8761, 0xCEFB, 0x8762, 0x8763, 0x8764, 0xBAD9, - /* U+5640 */ 0x8765, 0x8766, 0x8767, 0x8768, 0x8769, 0x876A, 0x876B, 0x876C, - /* U+5648 */ 0x876D, 0x876E, 0x876F, 0x8770, 0xE0E1, 0xE0DD, 0xD2AD, 0x8771, - /* U+5650 */ 0x8772, 0x8773, 0x8774, 0x8775, 0xE0E2, 0x8776, 0x8777, 0xE0DB, - /* U+5658 */ 0xE0D9, 0xE0DF, 0x8778, 0x8779, 0xE0E0, 0x877A, 0x877B, 0x877C, - /* U+5660 */ 0x877D, 0x877E, 0xE0DE, 0x8780, 0xE0E4, 0x8781, 0x8782, 0x8783, - /* U+5668 */ 0xC6F7, 0xD8AC, 0xD4EB, 0xE0E6, 0xCAC9, 0x8784, 0x8785, 0x8786, - /* U+5670 */ 0x8787, 0xE0E5, 0x8788, 0x8789, 0x878A, 0x878B, 0xB8C1, 0x878C, - /* U+5678 */ 0x878D, 0x878E, 0x878F, 0xE0E7, 0xE0E8, 0x8790, 0x8791, 0x8792, - /* U+5680 */ 0x8793, 0x8794, 0x8795, 0x8796, 0x8797, 0xE0E9, 0xE0E3, 0x8798, - /* U+5688 */ 0x8799, 0x879A, 0x879B, 0x879C, 0x879D, 0x879E, 0xBABF, 0xCCE7, - /* U+5690 */ 0x879F, 0x87A0, 0x87A1, 0xE0EA, 0x87A2, 0x87A3, 0x87A4, 0x87A5, - /* U+5698 */ 0x87A6, 0x87A7, 0x87A8, 0x87A9, 0x87AA, 0x87AB, 0x87AC, 0x87AD, - /* U+56A0 */ 0x87AE, 0x87AF, 0x87B0, 0xCFF9, 0x87B1, 0x87B2, 0x87B3, 0x87B4, - /* U+56A8 */ 0x87B5, 0x87B6, 0x87B7, 0x87B8, 0x87B9, 0x87BA, 0x87BB, 0xE0EB, - /* U+56B0 */ 0x87BC, 0x87BD, 0x87BE, 0x87BF, 0x87C0, 0x87C1, 0x87C2, 0xC8C2, - /* U+56B8 */ 0x87C3, 0x87C4, 0x87C5, 0x87C6, 0xBDC0, 0x87C7, 0x87C8, 0x87C9, - /* U+56C0 */ 0x87CA, 0x87CB, 0x87CC, 0x87CD, 0x87CE, 0x87CF, 0x87D0, 0x87D1, - /* U+56C8 */ 0x87D2, 0x87D3, 0xC4D2, 0x87D4, 0x87D5, 0x87D6, 0x87D7, 0x87D8, - /* U+56D0 */ 0x87D9, 0x87DA, 0x87DB, 0x87DC, 0xE0EC, 0x87DD, 0x87DE, 0xE0ED, - /* U+56D8 */ 0x87DF, 0x87E0, 0xC7F4, 0xCBC4, 0x87E1, 0xE0EE, 0xBBD8, 0xD8B6, - /* U+56E0 */ 0xD2F2, 0xE0EF, 0xCDC5, 0x87E2, 0xB6DA, 0x87E3, 0x87E4, 0x87E5, - /* U+56E8 */ 0x87E6, 0x87E7, 0x87E8, 0xE0F1, 0x87E9, 0xD4B0, 0x87EA, 0x87EB, - /* U+56F0 */ 0xC0A7, 0xB4D1, 0x87EC, 0x87ED, 0xCEA7, 0xE0F0, 0x87EE, 0x87EF, - /* U+56F8 */ 0x87F0, 0xE0F2, 0xB9CC, 0x87F1, 0x87F2, 0xB9FA, 0xCDBC, 0xE0F3, - /* U+5700 */ 0x87F3, 0x87F4, 0x87F5, 0xC6D4, 0xE0F4, 0x87F6, 0xD4B2, 0x87F7, - /* U+5708 */ 0xC8A6, 0xE0F6, 0xE0F5, 0x87F8, 0x87F9, 0x87FA, 0x87FB, 0x87FC, - /* U+5710 */ 0x87FD, 0x87FE, 0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8845, - /* U+5718 */ 0x8846, 0x8847, 0x8848, 0x8849, 0xE0F7, 0x884A, 0x884B, 0xCDC1, - /* U+5720 */ 0x884C, 0x884D, 0x884E, 0xCAA5, 0x884F, 0x8850, 0x8851, 0x8852, - /* U+5728 */ 0xD4DA, 0xDBD7, 0xDBD9, 0x8853, 0xDBD8, 0xB9E7, 0xDBDC, 0xDBDD, - /* U+5730 */ 0xB5D8, 0x8854, 0x8855, 0xDBDA, 0x8856, 0x8857, 0x8858, 0x8859, - /* U+5738 */ 0x885A, 0xDBDB, 0xB3A1, 0xDBDF, 0x885B, 0x885C, 0xBBF8, 0x885D, - /* U+5740 */ 0xD6B7, 0x885E, 0xDBE0, 0x885F, 0x8860, 0x8861, 0x8862, 0xBEF9, - /* U+5748 */ 0x8863, 0x8864, 0xB7BB, 0x8865, 0xDBD0, 0xCCAE, 0xBFB2, 0xBBB5, - /* U+5750 */ 0xD7F8, 0xBFD3, 0x8866, 0x8867, 0x8868, 0x8869, 0x886A, 0xBFE9, - /* U+5758 */ 0x886B, 0x886C, 0xBCE1, 0xCCB3, 0xDBDE, 0xB0D3, 0xCEEB, 0xB7D8, - /* U+5760 */ 0xD7B9, 0xC6C2, 0x886D, 0x886E, 0xC0A4, 0x886F, 0xCCB9, 0x8870, - /* U+5768 */ 0xDBE7, 0xDBE1, 0xC6BA, 0xDBE3, 0x8871, 0xDBE8, 0x8872, 0xC5F7, - /* U+5770 */ 0x8873, 0x8874, 0x8875, 0xDBEA, 0x8876, 0x8877, 0xDBE9, 0xBFC0, - /* U+5778 */ 0x8878, 0x8879, 0x887A, 0xDBE6, 0xDBE5, 0x887B, 0x887C, 0x887D, - /* U+5780 */ 0x887E, 0x8880, 0xB4B9, 0xC0AC, 0xC2A2, 0xDBE2, 0xDBE4, 0x8881, - /* U+5788 */ 0x8882, 0x8883, 0x8884, 0xD0CD, 0xDBED, 0x8885, 0x8886, 0x8887, - /* U+5790 */ 0x8888, 0x8889, 0xC0DD, 0xDBF2, 0x888A, 0x888B, 0x888C, 0x888D, - /* U+5798 */ 0x888E, 0x888F, 0x8890, 0xB6E2, 0x8891, 0x8892, 0x8893, 0x8894, - /* U+57A0 */ 0xDBF3, 0xDBD2, 0xB9B8, 0xD4AB, 0xDBEC, 0x8895, 0xBFD1, 0xDBF0, - /* U+57A8 */ 0x8896, 0xDBD1, 0x8897, 0xB5E6, 0x8898, 0xDBEB, 0xBFE5, 0x8899, - /* U+57B0 */ 0x889A, 0x889B, 0xDBEE, 0x889C, 0xDBF1, 0x889D, 0x889E, 0x889F, - /* U+57B8 */ 0xDBF9, 0x88A0, 0x88A1, 0x88A2, 0x88A3, 0x88A4, 0x88A5, 0x88A6, - /* U+57C0 */ 0x88A7, 0x88A8, 0xB9A1, 0xB0A3, 0x88A9, 0x88AA, 0x88AB, 0x88AC, - /* U+57C8 */ 0x88AD, 0x88AE, 0x88AF, 0xC2F1, 0x88B0, 0x88B1, 0xB3C7, 0xDBEF, - /* U+57D0 */ 0x88B2, 0x88B3, 0xDBF8, 0x88B4, 0xC6D2, 0xDBF4, 0x88B5, 0x88B6, - /* U+57D8 */ 0xDBF5, 0xDBF7, 0xDBF6, 0x88B7, 0x88B8, 0xDBFE, 0x88B9, 0xD3F2, - /* U+57E0 */ 0xB2BA, 0x88BA, 0x88BB, 0x88BC, 0xDBFD, 0x88BD, 0x88BE, 0x88BF, - /* U+57E8 */ 0x88C0, 0x88C1, 0x88C2, 0x88C3, 0x88C4, 0xDCA4, 0x88C5, 0xDBFB, - /* U+57F0 */ 0x88C6, 0x88C7, 0x88C8, 0x88C9, 0xDBFA, 0x88CA, 0x88CB, 0x88CC, - /* U+57F8 */ 0xDBFC, 0xC5E0, 0xBBF9, 0x88CD, 0x88CE, 0xDCA3, 0x88CF, 0x88D0, - /* U+5800 */ 0xDCA5, 0x88D1, 0xCCC3, 0x88D2, 0x88D3, 0x88D4, 0xB6D1, 0xDDC0, - /* U+5808 */ 0x88D5, 0x88D6, 0x88D7, 0xDCA1, 0x88D8, 0xDCA2, 0x88D9, 0x88DA, - /* U+5810 */ 0x88DB, 0xC7B5, 0x88DC, 0x88DD, 0x88DE, 0xB6E9, 0x88DF, 0x88E0, - /* U+5818 */ 0x88E1, 0xDCA7, 0x88E2, 0x88E3, 0x88E4, 0x88E5, 0xDCA6, 0x88E6, - /* U+5820 */ 0xDCA9, 0xB1A4, 0x88E7, 0x88E8, 0xB5CC, 0x88E9, 0x88EA, 0x88EB, - /* U+5828 */ 0x88EC, 0x88ED, 0xBFB0, 0x88EE, 0x88EF, 0x88F0, 0x88F1, 0x88F2, - /* U+5830 */ 0xD1DF, 0x88F3, 0x88F4, 0x88F5, 0x88F6, 0xB6C2, 0x88F7, 0x88F8, - /* U+5838 */ 0x88F9, 0x88FA, 0x88FB, 0x88FC, 0x88FD, 0x88FE, 0x8940, 0x8941, - /* U+5840 */ 0x8942, 0x8943, 0x8944, 0x8945, 0xDCA8, 0x8946, 0x8947, 0x8948, - /* U+5848 */ 0x8949, 0x894A, 0x894B, 0x894C, 0xCBFA, 0xEBF3, 0x894D, 0x894E, - /* U+5850 */ 0x894F, 0xCBDC, 0x8950, 0x8951, 0xCBFE, 0x8952, 0x8953, 0x8954, - /* U+5858 */ 0xCCC1, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, 0xC8FB, 0x895A, - /* U+5860 */ 0x895B, 0x895C, 0x895D, 0x895E, 0x895F, 0xDCAA, 0x8960, 0x8961, - /* U+5868 */ 0x8962, 0x8963, 0x8964, 0xCCEE, 0xDCAB, 0x8965, 0x8966, 0x8967, - /* U+5870 */ 0x8968, 0x8969, 0x896A, 0x896B, 0x896C, 0x896D, 0x896E, 0x896F, - /* U+5878 */ 0x8970, 0x8971, 0x8972, 0x8973, 0x8974, 0x8975, 0xDBD3, 0x8976, - /* U+5880 */ 0xDCAF, 0xDCAC, 0x8977, 0xBEB3, 0x8978, 0xCAFB, 0x8979, 0x897A, - /* U+5888 */ 0x897B, 0xDCAD, 0x897C, 0x897D, 0x897E, 0x8980, 0x8981, 0x8982, - /* U+5890 */ 0x8983, 0x8984, 0xC9CA, 0xC4B9, 0x8985, 0x8986, 0x8987, 0x8988, - /* U+5898 */ 0x8989, 0xC7BD, 0xDCAE, 0x898A, 0x898B, 0x898C, 0xD4F6, 0xD0E6, - /* U+58A0 */ 0x898D, 0x898E, 0x898F, 0x8990, 0x8991, 0x8992, 0x8993, 0x8994, - /* U+58A8 */ 0xC4AB, 0xB6D5, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, 0x899A, - /* U+58B0 */ 0x899B, 0x899C, 0x899D, 0x899E, 0x899F, 0x89A0, 0x89A1, 0x89A2, - /* U+58B8 */ 0x89A3, 0x89A4, 0x89A5, 0x89A6, 0xDBD4, 0x89A7, 0x89A8, 0x89A9, - /* U+58C0 */ 0x89AA, 0xB1DA, 0x89AB, 0x89AC, 0x89AD, 0xDBD5, 0x89AE, 0x89AF, - /* U+58C8 */ 0x89B0, 0x89B1, 0x89B2, 0x89B3, 0x89B4, 0x89B5, 0x89B6, 0x89B7, - /* U+58D0 */ 0x89B8, 0xDBD6, 0x89B9, 0x89BA, 0x89BB, 0xBABE, 0x89BC, 0x89BD, - /* U+58D8 */ 0x89BE, 0x89BF, 0x89C0, 0x89C1, 0x89C2, 0x89C3, 0x89C4, 0x89C5, - /* U+58E0 */ 0x89C6, 0x89C7, 0x89C8, 0x89C9, 0xC8C0, 0x89CA, 0x89CB, 0x89CC, - /* U+58E8 */ 0x89CD, 0x89CE, 0x89CF, 0xCABF, 0xC8C9, 0x89D0, 0xD7B3, 0x89D1, - /* U+58F0 */ 0xC9F9, 0x89D2, 0x89D3, 0xBFC7, 0x89D4, 0x89D5, 0xBAF8, 0x89D6, - /* U+58F8 */ 0x89D7, 0xD2BC, 0x89D8, 0x89D9, 0x89DA, 0x89DB, 0x89DC, 0x89DD, - /* U+5900 */ 0x89DE, 0x89DF, 0xE2BA, 0x89E0, 0xB4A6, 0x89E1, 0x89E2, 0xB1B8, - /* U+5908 */ 0x89E3, 0x89E4, 0x89E5, 0x89E6, 0x89E7, 0xB8B4, 0x89E8, 0xCFC4, - /* U+5910 */ 0x89E9, 0x89EA, 0x89EB, 0x89EC, 0xD9E7, 0xCFA6, 0xCDE2, 0x89ED, - /* U+5918 */ 0x89EE, 0xD9ED, 0xB6E0, 0x89EF, 0xD2B9, 0x89F0, 0x89F1, 0xB9BB, - /* U+5920 */ 0x89F2, 0x89F3, 0x89F4, 0x89F5, 0xE2B9, 0xE2B7, 0x89F6, 0xB4F3, - /* U+5928 */ 0x89F7, 0xCCEC, 0xCCAB, 0xB7F2, 0x89F8, 0xD8B2, 0xD1EB, 0xBABB, - /* U+5930 */ 0x89F9, 0xCAA7, 0x89FA, 0x89FB, 0xCDB7, 0x89FC, 0x89FD, 0xD2C4, - /* U+5938 */ 0xBFE4, 0xBCD0, 0xB6E1, 0x89FE, 0xDEC5, 0x8A40, 0x8A41, 0x8A42, - /* U+5940 */ 0x8A43, 0xDEC6, 0xDBBC, 0x8A44, 0xD1D9, 0x8A45, 0x8A46, 0xC6E6, - /* U+5948 */ 0xC4CE, 0xB7EE, 0x8A47, 0xB7DC, 0x8A48, 0x8A49, 0xBFFC, 0xD7E0, - /* U+5950 */ 0x8A4A, 0xC6F5, 0x8A4B, 0x8A4C, 0xB1BC, 0xDEC8, 0xBDB1, 0xCCD7, - /* U+5958 */ 0xDECA, 0x8A4D, 0xDEC9, 0x8A4E, 0x8A4F, 0x8A50, 0x8A51, 0x8A52, - /* U+5960 */ 0xB5EC, 0x8A53, 0xC9DD, 0x8A54, 0x8A55, 0xB0C2, 0x8A56, 0x8A57, - /* U+5968 */ 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A5E, 0x8A5F, - /* U+5970 */ 0x8A60, 0x8A61, 0x8A62, 0xC5AE, 0xC5AB, 0x8A63, 0xC4CC, 0x8A64, - /* U+5978 */ 0xBCE9, 0xCBFD, 0x8A65, 0x8A66, 0x8A67, 0xBAC3, 0x8A68, 0x8A69, - /* U+5980 */ 0x8A6A, 0xE5F9, 0xC8E7, 0xE5FA, 0xCDFD, 0x8A6B, 0xD7B1, 0xB8BE, - /* U+5988 */ 0xC2E8, 0x8A6C, 0xC8D1, 0x8A6D, 0x8A6E, 0xE5FB, 0x8A6F, 0x8A70, - /* U+5990 */ 0x8A71, 0x8A72, 0xB6CA, 0xBCCB, 0x8A73, 0x8A74, 0xD1FD, 0xE6A1, - /* U+5998 */ 0x8A75, 0xC3EE, 0x8A76, 0x8A77, 0x8A78, 0x8A79, 0xE6A4, 0x8A7A, - /* U+59A0 */ 0x8A7B, 0x8A7C, 0x8A7D, 0xE5FE, 0xE6A5, 0xCDD7, 0x8A7E, 0x8A80, - /* U+59A8 */ 0xB7C1, 0xE5FC, 0xE5FD, 0xE6A3, 0x8A81, 0x8A82, 0xC4DD, 0xE6A8, - /* U+59B0 */ 0x8A83, 0x8A84, 0xE6A7, 0x8A85, 0x8A86, 0x8A87, 0x8A88, 0x8A89, - /* U+59B8 */ 0x8A8A, 0xC3C3, 0x8A8B, 0xC6DE, 0x8A8C, 0x8A8D, 0xE6AA, 0x8A8E, - /* U+59C0 */ 0x8A8F, 0x8A90, 0x8A91, 0x8A92, 0x8A93, 0x8A94, 0xC4B7, 0x8A95, - /* U+59C8 */ 0x8A96, 0x8A97, 0xE6A2, 0xCABC, 0x8A98, 0x8A99, 0x8A9A, 0x8A9B, - /* U+59D0 */ 0xBDE3, 0xB9C3, 0xE6A6, 0xD0D5, 0xCEAF, 0x8A9C, 0x8A9D, 0xE6A9, - /* U+59D8 */ 0xE6B0, 0x8A9E, 0xD2A6, 0x8A9F, 0xBDAA, 0xE6AD, 0x8AA0, 0x8AA1, - /* U+59E0 */ 0x8AA2, 0x8AA3, 0x8AA4, 0xE6AF, 0x8AA5, 0xC0D1, 0x8AA6, 0x8AA7, - /* U+59E8 */ 0xD2CC, 0x8AA8, 0x8AA9, 0x8AAA, 0xBCA7, 0x8AAB, 0x8AAC, 0x8AAD, - /* U+59F0 */ 0x8AAE, 0x8AAF, 0x8AB0, 0x8AB1, 0x8AB2, 0x8AB3, 0x8AB4, 0x8AB5, - /* U+59F8 */ 0x8AB6, 0xE6B1, 0x8AB7, 0xD2F6, 0x8AB8, 0x8AB9, 0x8ABA, 0xD7CB, - /* U+5A00 */ 0x8ABB, 0xCDFE, 0x8ABC, 0xCDDE, 0xC2A6, 0xE6AB, 0xE6AC, 0xBDBF, - /* U+5A08 */ 0xE6AE, 0xE6B3, 0x8ABD, 0x8ABE, 0xE6B2, 0x8ABF, 0x8AC0, 0x8AC1, - /* U+5A10 */ 0x8AC2, 0xE6B6, 0x8AC3, 0xE6B8, 0x8AC4, 0x8AC5, 0x8AC6, 0x8AC7, - /* U+5A18 */ 0xC4EF, 0x8AC8, 0x8AC9, 0x8ACA, 0xC4C8, 0x8ACB, 0x8ACC, 0xBEEA, - /* U+5A20 */ 0xC9EF, 0x8ACD, 0x8ACE, 0xE6B7, 0x8ACF, 0xB6F0, 0x8AD0, 0x8AD1, - /* U+5A28 */ 0x8AD2, 0xC3E4, 0x8AD3, 0x8AD4, 0x8AD5, 0x8AD6, 0x8AD7, 0x8AD8, - /* U+5A30 */ 0x8AD9, 0xD3E9, 0xE6B4, 0x8ADA, 0xE6B5, 0x8ADB, 0xC8A2, 0x8ADC, - /* U+5A38 */ 0x8ADD, 0x8ADE, 0x8ADF, 0x8AE0, 0xE6BD, 0x8AE1, 0x8AE2, 0x8AE3, - /* U+5A40 */ 0xE6B9, 0x8AE4, 0x8AE5, 0x8AE6, 0x8AE7, 0x8AE8, 0xC6C5, 0x8AE9, - /* U+5A48 */ 0x8AEA, 0xCDF1, 0xE6BB, 0x8AEB, 0x8AEC, 0x8AED, 0x8AEE, 0x8AEF, - /* U+5A50 */ 0x8AF0, 0x8AF1, 0x8AF2, 0x8AF3, 0x8AF4, 0xE6BC, 0x8AF5, 0x8AF6, - /* U+5A58 */ 0x8AF7, 0x8AF8, 0xBBE9, 0x8AF9, 0x8AFA, 0x8AFB, 0x8AFC, 0x8AFD, - /* U+5A60 */ 0x8AFE, 0x8B40, 0xE6BE, 0x8B41, 0x8B42, 0x8B43, 0x8B44, 0xE6BA, - /* U+5A68 */ 0x8B45, 0x8B46, 0xC0B7, 0x8B47, 0x8B48, 0x8B49, 0x8B4A, 0x8B4B, - /* U+5A70 */ 0x8B4C, 0x8B4D, 0x8B4E, 0x8B4F, 0xD3A4, 0xE6BF, 0xC9F4, 0xE6C3, - /* U+5A78 */ 0x8B50, 0x8B51, 0xE6C4, 0x8B52, 0x8B53, 0x8B54, 0x8B55, 0xD0F6, - /* U+5A80 */ 0x8B56, 0x8B57, 0x8B58, 0x8B59, 0x8B5A, 0x8B5B, 0x8B5C, 0x8B5D, - /* U+5A88 */ 0x8B5E, 0x8B5F, 0x8B60, 0x8B61, 0x8B62, 0x8B63, 0x8B64, 0x8B65, - /* U+5A90 */ 0x8B66, 0x8B67, 0xC3BD, 0x8B68, 0x8B69, 0x8B6A, 0x8B6B, 0x8B6C, - /* U+5A98 */ 0x8B6D, 0x8B6E, 0xC3C4, 0xE6C2, 0x8B6F, 0x8B70, 0x8B71, 0x8B72, - /* U+5AA0 */ 0x8B73, 0x8B74, 0x8B75, 0x8B76, 0x8B77, 0x8B78, 0x8B79, 0x8B7A, - /* U+5AA8 */ 0x8B7B, 0x8B7C, 0xE6C1, 0x8B7D, 0x8B7E, 0x8B80, 0x8B81, 0x8B82, - /* U+5AB0 */ 0x8B83, 0x8B84, 0xE6C7, 0xCFB1, 0x8B85, 0xEBF4, 0x8B86, 0x8B87, - /* U+5AB8 */ 0xE6CA, 0x8B88, 0x8B89, 0x8B8A, 0x8B8B, 0x8B8C, 0xE6C5, 0x8B8D, - /* U+5AC0 */ 0x8B8E, 0xBCDE, 0xC9A9, 0x8B8F, 0x8B90, 0x8B91, 0x8B92, 0x8B93, - /* U+5AC8 */ 0x8B94, 0xBCB5, 0x8B95, 0x8B96, 0xCFD3, 0x8B97, 0x8B98, 0x8B99, - /* U+5AD0 */ 0x8B9A, 0x8B9B, 0xE6C8, 0x8B9C, 0xE6C9, 0x8B9D, 0xE6CE, 0x8B9E, - /* U+5AD8 */ 0xE6D0, 0x8B9F, 0x8BA0, 0x8BA1, 0xE6D1, 0x8BA2, 0x8BA3, 0x8BA4, - /* U+5AE0 */ 0xE6CB, 0xB5D5, 0x8BA5, 0xE6CC, 0x8BA6, 0x8BA7, 0xE6CF, 0x8BA8, - /* U+5AE8 */ 0x8BA9, 0xC4DB, 0x8BAA, 0xE6C6, 0x8BAB, 0x8BAC, 0x8BAD, 0x8BAE, - /* U+5AF0 */ 0x8BAF, 0xE6CD, 0x8BB0, 0x8BB1, 0x8BB2, 0x8BB3, 0x8BB4, 0x8BB5, - /* U+5AF8 */ 0x8BB6, 0x8BB7, 0x8BB8, 0x8BB9, 0x8BBA, 0x8BBB, 0x8BBC, 0x8BBD, - /* U+5B00 */ 0x8BBE, 0x8BBF, 0x8BC0, 0x8BC1, 0x8BC2, 0x8BC3, 0x8BC4, 0x8BC5, - /* U+5B08 */ 0x8BC6, 0xE6D2, 0x8BC7, 0x8BC8, 0x8BC9, 0x8BCA, 0x8BCB, 0x8BCC, - /* U+5B10 */ 0x8BCD, 0x8BCE, 0x8BCF, 0x8BD0, 0x8BD1, 0x8BD2, 0xE6D4, 0xE6D3, - /* U+5B18 */ 0x8BD3, 0x8BD4, 0x8BD5, 0x8BD6, 0x8BD7, 0x8BD8, 0x8BD9, 0x8BDA, - /* U+5B20 */ 0x8BDB, 0x8BDC, 0x8BDD, 0x8BDE, 0x8BDF, 0x8BE0, 0x8BE1, 0x8BE2, - /* U+5B28 */ 0x8BE3, 0x8BE4, 0x8BE5, 0x8BE6, 0x8BE7, 0x8BE8, 0x8BE9, 0x8BEA, - /* U+5B30 */ 0x8BEB, 0x8BEC, 0xE6D5, 0x8BED, 0xD9F8, 0x8BEE, 0x8BEF, 0xE6D6, - /* U+5B38 */ 0x8BF0, 0x8BF1, 0x8BF2, 0x8BF3, 0x8BF4, 0x8BF5, 0x8BF6, 0x8BF7, - /* U+5B40 */ 0xE6D7, 0x8BF8, 0x8BF9, 0x8BFA, 0x8BFB, 0x8BFC, 0x8BFD, 0x8BFE, - /* U+5B48 */ 0x8C40, 0x8C41, 0x8C42, 0x8C43, 0x8C44, 0x8C45, 0x8C46, 0x8C47, - /* U+5B50 */ 0xD7D3, 0xE6DD, 0x8C48, 0xE6DE, 0xBFD7, 0xD4D0, 0x8C49, 0xD7D6, - /* U+5B58 */ 0xB4E6, 0xCBEF, 0xE6DA, 0xD8C3, 0xD7CE, 0xD0A2, 0x8C4A, 0xC3CF, - /* U+5B60 */ 0x8C4B, 0x8C4C, 0xE6DF, 0xBCBE, 0xB9C2, 0xE6DB, 0xD1A7, 0x8C4D, - /* U+5B68 */ 0x8C4E, 0xBAA2, 0xC2CF, 0x8C4F, 0xD8AB, 0x8C50, 0x8C51, 0x8C52, - /* U+5B70 */ 0xCAEB, 0xE5EE, 0x8C53, 0xE6DC, 0x8C54, 0xB7F5, 0x8C55, 0x8C56, - /* U+5B78 */ 0x8C57, 0x8C58, 0xC8E6, 0x8C59, 0x8C5A, 0xC4F5, 0x8C5B, 0x8C5C, - /* U+5B80 */ 0xE5B2, 0xC4FE, 0x8C5D, 0xCBFC, 0xE5B3, 0xD5AC, 0x8C5E, 0xD3EE, - /* U+5B88 */ 0xCAD8, 0xB0B2, 0x8C5F, 0xCBCE, 0xCDEA, 0x8C60, 0x8C61, 0xBAEA, - /* U+5B90 */ 0x8C62, 0x8C63, 0x8C64, 0xE5B5, 0x8C65, 0xE5B4, 0x8C66, 0xD7DA, - /* U+5B98 */ 0xB9D9, 0xD6E6, 0xB6A8, 0xCDF0, 0xD2CB, 0xB1A6, 0xCAB5, 0x8C67, - /* U+5BA0 */ 0xB3E8, 0xC9F3, 0xBFCD, 0xD0FB, 0xCAD2, 0xE5B6, 0xBBC2, 0x8C68, - /* U+5BA8 */ 0x8C69, 0x8C6A, 0xCFDC, 0xB9AC, 0x8C6B, 0x8C6C, 0x8C6D, 0x8C6E, - /* U+5BB0 */ 0xD4D7, 0x8C6F, 0x8C70, 0xBAA6, 0xD1E7, 0xCFFC, 0xBCD2, 0x8C71, - /* U+5BB8 */ 0xE5B7, 0xC8DD, 0x8C72, 0x8C73, 0x8C74, 0xBFED, 0xB1F6, 0xCBDE, - /* U+5BC0 */ 0x8C75, 0x8C76, 0xBCC5, 0x8C77, 0xBCC4, 0xD2FA, 0xC3DC, 0xBFDC, - /* U+5BC8 */ 0x8C78, 0x8C79, 0x8C7A, 0x8C7B, 0xB8BB, 0x8C7C, 0x8C7D, 0x8C7E, - /* U+5BD0 */ 0xC3C2, 0x8C80, 0xBAAE, 0xD4A2, 0x8C81, 0x8C82, 0x8C83, 0x8C84, - /* U+5BD8 */ 0x8C85, 0x8C86, 0x8C87, 0x8C88, 0x8C89, 0xC7DE, 0xC4AF, 0xB2EC, - /* U+5BE0 */ 0x8C8A, 0xB9D1, 0x8C8B, 0x8C8C, 0xE5BB, 0xC1C8, 0x8C8D, 0x8C8E, - /* U+5BE8 */ 0xD5AF, 0x8C8F, 0x8C90, 0x8C91, 0x8C92, 0x8C93, 0xE5BC, 0x8C94, - /* U+5BF0 */ 0xE5BE, 0x8C95, 0x8C96, 0x8C97, 0x8C98, 0x8C99, 0x8C9A, 0x8C9B, - /* U+5BF8 */ 0xB4E7, 0xB6D4, 0xCBC2, 0xD1B0, 0xB5BC, 0x8C9C, 0x8C9D, 0xCAD9, - /* U+5C00 */ 0x8C9E, 0xB7E2, 0x8C9F, 0x8CA0, 0xC9E4, 0x8CA1, 0xBDAB, 0x8CA2, - /* U+5C08 */ 0x8CA3, 0xCEBE, 0xD7F0, 0x8CA4, 0x8CA5, 0x8CA6, 0x8CA7, 0xD0A1, - /* U+5C10 */ 0x8CA8, 0xC9D9, 0x8CA9, 0x8CAA, 0xB6FB, 0xE6D8, 0xBCE2, 0x8CAB, - /* U+5C18 */ 0xB3BE, 0x8CAC, 0xC9D0, 0x8CAD, 0xE6D9, 0xB3A2, 0x8CAE, 0x8CAF, - /* U+5C20 */ 0x8CB0, 0x8CB1, 0xDECC, 0x8CB2, 0xD3C8, 0xDECD, 0x8CB3, 0xD2A2, - /* U+5C28 */ 0x8CB4, 0x8CB5, 0x8CB6, 0x8CB7, 0xDECE, 0x8CB8, 0x8CB9, 0x8CBA, - /* U+5C30 */ 0x8CBB, 0xBECD, 0x8CBC, 0x8CBD, 0xDECF, 0x8CBE, 0x8CBF, 0x8CC0, - /* U+5C38 */ 0xCAAC, 0xD2FC, 0xB3DF, 0xE5EA, 0xC4E1, 0xBEA1, 0xCEB2, 0xC4F2, - /* U+5C40 */ 0xBED6, 0xC6A8, 0xB2E3, 0x8CC1, 0x8CC2, 0xBED3, 0x8CC3, 0x8CC4, - /* U+5C48 */ 0xC7FC, 0xCCEB, 0xBDEC, 0xCEDD, 0x8CC5, 0x8CC6, 0xCABA, 0xC6C1, - /* U+5C50 */ 0xE5EC, 0xD0BC, 0x8CC7, 0x8CC8, 0x8CC9, 0xD5B9, 0x8CCA, 0x8CCB, - /* U+5C58 */ 0x8CCC, 0xE5ED, 0x8CCD, 0x8CCE, 0x8CCF, 0x8CD0, 0xCAF4, 0x8CD1, - /* U+5C60 */ 0xCDC0, 0xC2C5, 0x8CD2, 0xE5EF, 0x8CD3, 0xC2C4, 0xE5F0, 0x8CD4, - /* U+5C68 */ 0x8CD5, 0x8CD6, 0x8CD7, 0x8CD8, 0x8CD9, 0x8CDA, 0xE5F8, 0xCDCD, - /* U+5C70 */ 0x8CDB, 0xC9BD, 0x8CDC, 0x8CDD, 0x8CDE, 0x8CDF, 0x8CE0, 0x8CE1, - /* U+5C78 */ 0x8CE2, 0xD2D9, 0xE1A8, 0x8CE3, 0x8CE4, 0x8CE5, 0x8CE6, 0xD3EC, - /* U+5C80 */ 0x8CE7, 0xCBEA, 0xC6F1, 0x8CE8, 0x8CE9, 0x8CEA, 0x8CEB, 0x8CEC, - /* U+5C88 */ 0xE1AC, 0x8CED, 0x8CEE, 0x8CEF, 0xE1A7, 0xE1A9, 0x8CF0, 0x8CF1, - /* U+5C90 */ 0xE1AA, 0xE1AF, 0x8CF2, 0x8CF3, 0xB2ED, 0x8CF4, 0xE1AB, 0xB8DA, - /* U+5C98 */ 0xE1AD, 0xE1AE, 0xE1B0, 0xB5BA, 0xE1B1, 0x8CF5, 0x8CF6, 0x8CF7, - /* U+5CA0 */ 0x8CF8, 0x8CF9, 0xE1B3, 0xE1B8, 0x8CFA, 0x8CFB, 0x8CFC, 0x8CFD, - /* U+5CA8 */ 0x8CFE, 0xD1D2, 0x8D40, 0xE1B6, 0xE1B5, 0xC1EB, 0x8D41, 0x8D42, - /* U+5CB0 */ 0x8D43, 0xE1B7, 0x8D44, 0xD4C0, 0x8D45, 0xE1B2, 0x8D46, 0xE1BA, - /* U+5CB8 */ 0xB0B6, 0x8D47, 0x8D48, 0x8D49, 0x8D4A, 0xE1B4, 0x8D4B, 0xBFF9, - /* U+5CC0 */ 0x8D4C, 0xE1B9, 0x8D4D, 0x8D4E, 0xE1BB, 0x8D4F, 0x8D50, 0x8D51, - /* U+5CC8 */ 0x8D52, 0x8D53, 0x8D54, 0xE1BE, 0x8D55, 0x8D56, 0x8D57, 0x8D58, - /* U+5CD0 */ 0x8D59, 0x8D5A, 0xE1BC, 0x8D5B, 0x8D5C, 0x8D5D, 0x8D5E, 0x8D5F, - /* U+5CD8 */ 0x8D60, 0xD6C5, 0x8D61, 0x8D62, 0x8D63, 0x8D64, 0x8D65, 0x8D66, - /* U+5CE0 */ 0x8D67, 0xCFBF, 0x8D68, 0x8D69, 0xE1BD, 0xE1BF, 0xC2CD, 0x8D6A, - /* U+5CE8 */ 0xB6EB, 0x8D6B, 0xD3F8, 0x8D6C, 0x8D6D, 0xC7CD, 0x8D6E, 0x8D6F, - /* U+5CF0 */ 0xB7E5, 0x8D70, 0x8D71, 0x8D72, 0x8D73, 0x8D74, 0x8D75, 0x8D76, - /* U+5CF8 */ 0x8D77, 0x8D78, 0x8D79, 0xBEFE, 0x8D7A, 0x8D7B, 0x8D7C, 0x8D7D, - /* U+5D00 */ 0x8D7E, 0x8D80, 0xE1C0, 0xE1C1, 0x8D81, 0x8D82, 0xE1C7, 0xB3E7, - /* U+5D08 */ 0x8D83, 0x8D84, 0x8D85, 0x8D86, 0x8D87, 0x8D88, 0xC6E9, 0x8D89, - /* U+5D10 */ 0x8D8A, 0x8D8B, 0x8D8C, 0x8D8D, 0xB4DE, 0x8D8E, 0xD1C2, 0x8D8F, - /* U+5D18 */ 0x8D90, 0x8D91, 0x8D92, 0xE1C8, 0x8D93, 0x8D94, 0xE1C6, 0x8D95, - /* U+5D20 */ 0x8D96, 0x8D97, 0x8D98, 0x8D99, 0xE1C5, 0x8D9A, 0xE1C3, 0xE1C2, - /* U+5D28 */ 0x8D9B, 0xB1C0, 0x8D9C, 0x8D9D, 0x8D9E, 0xD5B8, 0xE1C4, 0x8D9F, - /* U+5D30 */ 0x8DA0, 0x8DA1, 0x8DA2, 0x8DA3, 0xE1CB, 0x8DA4, 0x8DA5, 0x8DA6, - /* U+5D38 */ 0x8DA7, 0x8DA8, 0x8DA9, 0x8DAA, 0x8DAB, 0xE1CC, 0xE1CA, 0x8DAC, - /* U+5D40 */ 0x8DAD, 0x8DAE, 0x8DAF, 0x8DB0, 0x8DB1, 0x8DB2, 0x8DB3, 0xEFFA, - /* U+5D48 */ 0x8DB4, 0x8DB5, 0xE1D3, 0xE1D2, 0xC7B6, 0x8DB6, 0x8DB7, 0x8DB8, - /* U+5D50 */ 0x8DB9, 0x8DBA, 0x8DBB, 0x8DBC, 0x8DBD, 0x8DBE, 0x8DBF, 0x8DC0, - /* U+5D58 */ 0xE1C9, 0x8DC1, 0x8DC2, 0xE1CE, 0x8DC3, 0xE1D0, 0x8DC4, 0x8DC5, - /* U+5D60 */ 0x8DC6, 0x8DC7, 0x8DC8, 0x8DC9, 0x8DCA, 0x8DCB, 0x8DCC, 0x8DCD, - /* U+5D68 */ 0x8DCE, 0xE1D4, 0x8DCF, 0xE1D1, 0xE1CD, 0x8DD0, 0x8DD1, 0xE1CF, - /* U+5D70 */ 0x8DD2, 0x8DD3, 0x8DD4, 0x8DD5, 0xE1D5, 0x8DD6, 0x8DD7, 0x8DD8, - /* U+5D78 */ 0x8DD9, 0x8DDA, 0x8DDB, 0x8DDC, 0x8DDD, 0x8DDE, 0x8DDF, 0x8DE0, - /* U+5D80 */ 0x8DE1, 0x8DE2, 0xE1D6, 0x8DE3, 0x8DE4, 0x8DE5, 0x8DE6, 0x8DE7, - /* U+5D88 */ 0x8DE8, 0x8DE9, 0x8DEA, 0x8DEB, 0x8DEC, 0x8DED, 0x8DEE, 0x8DEF, - /* U+5D90 */ 0x8DF0, 0x8DF1, 0x8DF2, 0x8DF3, 0x8DF4, 0x8DF5, 0x8DF6, 0x8DF7, - /* U+5D98 */ 0x8DF8, 0xE1D7, 0x8DF9, 0x8DFA, 0x8DFB, 0xE1D8, 0x8DFC, 0x8DFD, - /* U+5DA0 */ 0x8DFE, 0x8E40, 0x8E41, 0x8E42, 0x8E43, 0x8E44, 0x8E45, 0x8E46, - /* U+5DA8 */ 0x8E47, 0x8E48, 0x8E49, 0x8E4A, 0x8E4B, 0x8E4C, 0x8E4D, 0x8E4E, - /* U+5DB0 */ 0x8E4F, 0x8E50, 0x8E51, 0x8E52, 0x8E53, 0x8E54, 0x8E55, 0xE1DA, - /* U+5DB8 */ 0x8E56, 0x8E57, 0x8E58, 0x8E59, 0x8E5A, 0x8E5B, 0x8E5C, 0x8E5D, - /* U+5DC0 */ 0x8E5E, 0x8E5F, 0x8E60, 0x8E61, 0x8E62, 0xE1DB, 0x8E63, 0x8E64, - /* U+5DC8 */ 0x8E65, 0x8E66, 0x8E67, 0x8E68, 0x8E69, 0xCEA1, 0x8E6A, 0x8E6B, - /* U+5DD0 */ 0x8E6C, 0x8E6D, 0x8E6E, 0x8E6F, 0x8E70, 0x8E71, 0x8E72, 0x8E73, - /* U+5DD8 */ 0x8E74, 0x8E75, 0x8E76, 0xE7DD, 0x8E77, 0xB4A8, 0xD6DD, 0x8E78, - /* U+5DE0 */ 0x8E79, 0xD1B2, 0xB3B2, 0x8E7A, 0x8E7B, 0xB9A4, 0xD7F3, 0xC7C9, - /* U+5DE8 */ 0xBEDE, 0xB9AE, 0x8E7C, 0xCED7, 0x8E7D, 0x8E7E, 0xB2EE, 0xDBCF, - /* U+5DF0 */ 0x8E80, 0xBCBA, 0xD2D1, 0xCBC8, 0xB0CD, 0x8E81, 0x8E82, 0xCFEF, - /* U+5DF8 */ 0x8E83, 0x8E84, 0x8E85, 0x8E86, 0x8E87, 0xD9E3, 0xBDED, 0x8E88, - /* U+5E00 */ 0x8E89, 0xB1D2, 0xCAD0, 0xB2BC, 0x8E8A, 0xCBA7, 0xB7AB, 0x8E8B, - /* U+5E08 */ 0xCAA6, 0x8E8C, 0x8E8D, 0x8E8E, 0xCFA3, 0x8E8F, 0x8E90, 0xE0F8, - /* U+5E10 */ 0xD5CA, 0xE0FB, 0x8E91, 0x8E92, 0xE0FA, 0xC5C1, 0xCCFB, 0x8E93, - /* U+5E18 */ 0xC1B1, 0xE0F9, 0xD6E3, 0xB2AF, 0xD6C4, 0xB5DB, 0x8E94, 0x8E95, - /* U+5E20 */ 0x8E96, 0x8E97, 0x8E98, 0x8E99, 0x8E9A, 0x8E9B, 0xB4F8, 0xD6A1, - /* U+5E28 */ 0x8E9C, 0x8E9D, 0x8E9E, 0x8E9F, 0x8EA0, 0xCFAF, 0xB0EF, 0x8EA1, - /* U+5E30 */ 0x8EA2, 0xE0FC, 0x8EA3, 0x8EA4, 0x8EA5, 0x8EA6, 0x8EA7, 0xE1A1, - /* U+5E38 */ 0xB3A3, 0x8EA8, 0x8EA9, 0xE0FD, 0xE0FE, 0xC3B1, 0x8EAA, 0x8EAB, - /* U+5E40 */ 0x8EAC, 0x8EAD, 0xC3DD, 0x8EAE, 0xE1A2, 0xB7F9, 0x8EAF, 0x8EB0, - /* U+5E48 */ 0x8EB1, 0x8EB2, 0x8EB3, 0x8EB4, 0xBBCF, 0x8EB5, 0x8EB6, 0x8EB7, - /* U+5E50 */ 0x8EB8, 0x8EB9, 0x8EBA, 0x8EBB, 0xE1A3, 0xC4BB, 0x8EBC, 0x8EBD, - /* U+5E58 */ 0x8EBE, 0x8EBF, 0x8EC0, 0xE1A4, 0x8EC1, 0x8EC2, 0xE1A5, 0x8EC3, - /* U+5E60 */ 0x8EC4, 0xE1A6, 0xB4B1, 0x8EC5, 0x8EC6, 0x8EC7, 0x8EC8, 0x8EC9, - /* U+5E68 */ 0x8ECA, 0x8ECB, 0x8ECC, 0x8ECD, 0x8ECE, 0x8ECF, 0x8ED0, 0x8ED1, - /* U+5E70 */ 0x8ED2, 0x8ED3, 0xB8C9, 0xC6BD, 0xC4EA, 0x8ED4, 0xB2A2, 0x8ED5, - /* U+5E78 */ 0xD0D2, 0x8ED6, 0xE7DB, 0xBBC3, 0xD3D7, 0xD3C4, 0x8ED7, 0xB9E3, - /* U+5E80 */ 0xE2CF, 0x8ED8, 0x8ED9, 0x8EDA, 0xD7AF, 0x8EDB, 0xC7EC, 0xB1D3, - /* U+5E88 */ 0x8EDC, 0x8EDD, 0xB4B2, 0xE2D1, 0x8EDE, 0x8EDF, 0x8EE0, 0xD0F2, - /* U+5E90 */ 0xC2AE, 0xE2D0, 0x8EE1, 0xBFE2, 0xD3A6, 0xB5D7, 0xE2D2, 0xB5EA, - /* U+5E98 */ 0x8EE2, 0xC3ED, 0xB8FD, 0x8EE3, 0xB8AE, 0x8EE4, 0xC5D3, 0xB7CF, - /* U+5EA0 */ 0xE2D4, 0x8EE5, 0x8EE6, 0x8EE7, 0x8EE8, 0xE2D3, 0xB6C8, 0xD7F9, - /* U+5EA8 */ 0x8EE9, 0x8EEA, 0x8EEB, 0x8EEC, 0x8EED, 0xCDA5, 0x8EEE, 0x8EEF, - /* U+5EB0 */ 0x8EF0, 0x8EF1, 0x8EF2, 0xE2D8, 0x8EF3, 0xE2D6, 0xCAFC, 0xBFB5, - /* U+5EB8 */ 0xD3B9, 0xE2D5, 0x8EF4, 0x8EF5, 0x8EF6, 0x8EF7, 0xE2D7, 0x8EF8, - /* U+5EC0 */ 0x8EF9, 0x8EFA, 0x8EFB, 0x8EFC, 0x8EFD, 0x8EFE, 0x8F40, 0x8F41, - /* U+5EC8 */ 0x8F42, 0xC1AE, 0xC0C8, 0x8F43, 0x8F44, 0x8F45, 0x8F46, 0x8F47, - /* U+5ED0 */ 0x8F48, 0xE2DB, 0xE2DA, 0xC0AA, 0x8F49, 0x8F4A, 0xC1CE, 0x8F4B, - /* U+5ED8 */ 0x8F4C, 0x8F4D, 0x8F4E, 0xE2DC, 0x8F4F, 0x8F50, 0x8F51, 0x8F52, - /* U+5EE0 */ 0x8F53, 0x8F54, 0x8F55, 0x8F56, 0x8F57, 0x8F58, 0x8F59, 0x8F5A, - /* U+5EE8 */ 0xE2DD, 0x8F5B, 0xE2DE, 0x8F5C, 0x8F5D, 0x8F5E, 0x8F5F, 0x8F60, - /* U+5EF0 */ 0x8F61, 0x8F62, 0x8F63, 0x8F64, 0xDBC8, 0x8F65, 0xD1D3, 0xCDA2, - /* U+5EF8 */ 0x8F66, 0x8F67, 0xBDA8, 0x8F68, 0x8F69, 0x8F6A, 0xDEC3, 0xD8A5, - /* U+5F00 */ 0xBFAA, 0xDBCD, 0xD2EC, 0xC6FA, 0xC5AA, 0x8F6B, 0x8F6C, 0x8F6D, - /* U+5F08 */ 0xDEC4, 0x8F6E, 0xB1D7, 0xDFAE, 0x8F6F, 0x8F70, 0x8F71, 0xCABD, - /* U+5F10 */ 0x8F72, 0xDFB1, 0x8F73, 0xB9AD, 0x8F74, 0xD2FD, 0x8F75, 0xB8A5, - /* U+5F18 */ 0xBAEB, 0x8F76, 0x8F77, 0xB3DA, 0x8F78, 0x8F79, 0x8F7A, 0xB5DC, - /* U+5F20 */ 0xD5C5, 0x8F7B, 0x8F7C, 0x8F7D, 0x8F7E, 0xC3D6, 0xCFD2, 0xBBA1, - /* U+5F28 */ 0x8F80, 0xE5F3, 0xE5F2, 0x8F81, 0x8F82, 0xE5F4, 0x8F83, 0xCDE4, - /* U+5F30 */ 0x8F84, 0xC8F5, 0x8F85, 0x8F86, 0x8F87, 0x8F88, 0x8F89, 0x8F8A, - /* U+5F38 */ 0x8F8B, 0xB5AF, 0xC7BF, 0x8F8C, 0xE5F6, 0x8F8D, 0x8F8E, 0x8F8F, - /* U+5F40 */ 0xECB0, 0x8F90, 0x8F91, 0x8F92, 0x8F93, 0x8F94, 0x8F95, 0x8F96, - /* U+5F48 */ 0x8F97, 0x8F98, 0x8F99, 0x8F9A, 0x8F9B, 0x8F9C, 0x8F9D, 0x8F9E, - /* U+5F50 */ 0xE5E6, 0x8F9F, 0xB9E9, 0xB5B1, 0x8FA0, 0xC2BC, 0xE5E8, 0xE5E7, - /* U+5F58 */ 0xE5E9, 0x8FA1, 0x8FA2, 0x8FA3, 0x8FA4, 0xD2CD, 0x8FA5, 0x8FA6, - /* U+5F60 */ 0x8FA7, 0xE1EA, 0xD0CE, 0x8FA8, 0xCDAE, 0x8FA9, 0xD1E5, 0x8FAA, - /* U+5F68 */ 0x8FAB, 0xB2CA, 0xB1EB, 0x8FAC, 0xB1F2, 0xC5ED, 0x8FAD, 0x8FAE, - /* U+5F70 */ 0xD5C3, 0xD3B0, 0x8FAF, 0xE1DC, 0x8FB0, 0x8FB1, 0x8FB2, 0xE1DD, - /* U+5F78 */ 0x8FB3, 0xD2DB, 0x8FB4, 0xB3B9, 0xB1CB, 0x8FB5, 0x8FB6, 0x8FB7, - /* U+5F80 */ 0xCDF9, 0xD5F7, 0xE1DE, 0x8FB8, 0xBEB6, 0xB4FD, 0x8FB9, 0xE1DF, - /* U+5F88 */ 0xBADC, 0xE1E0, 0xBBB2, 0xC2C9, 0xE1E1, 0x8FBA, 0x8FBB, 0x8FBC, - /* U+5F90 */ 0xD0EC, 0x8FBD, 0xCDBD, 0x8FBE, 0x8FBF, 0xE1E2, 0x8FC0, 0xB5C3, - /* U+5F98 */ 0xC5C7, 0xE1E3, 0x8FC1, 0x8FC2, 0xE1E4, 0x8FC3, 0x8FC4, 0x8FC5, - /* U+5FA0 */ 0x8FC6, 0xD3F9, 0x8FC7, 0x8FC8, 0x8FC9, 0x8FCA, 0x8FCB, 0x8FCC, - /* U+5FA8 */ 0xE1E5, 0x8FCD, 0xD1AD, 0x8FCE, 0x8FCF, 0xE1E6, 0xCEA2, 0x8FD0, - /* U+5FB0 */ 0x8FD1, 0x8FD2, 0x8FD3, 0x8FD4, 0x8FD5, 0xE1E7, 0x8FD6, 0xB5C2, - /* U+5FB8 */ 0x8FD7, 0x8FD8, 0x8FD9, 0x8FDA, 0xE1E8, 0xBBD5, 0x8FDB, 0x8FDC, - /* U+5FC0 */ 0x8FDD, 0x8FDE, 0x8FDF, 0xD0C4, 0xE2E0, 0xB1D8, 0xD2E4, 0x8FE0, - /* U+5FC8 */ 0x8FE1, 0xE2E1, 0x8FE2, 0x8FE3, 0xBCC9, 0xC8CC, 0x8FE4, 0xE2E3, - /* U+5FD0 */ 0xECFE, 0xECFD, 0xDFAF, 0x8FE5, 0x8FE6, 0x8FE7, 0xE2E2, 0xD6BE, - /* U+5FD8 */ 0xCDFC, 0xC3A6, 0x8FE8, 0x8FE9, 0x8FEA, 0xE3C3, 0x8FEB, 0x8FEC, - /* U+5FE0 */ 0xD6D2, 0xE2E7, 0x8FED, 0x8FEE, 0xE2E8, 0x8FEF, 0x8FF0, 0xD3C7, - /* U+5FE8 */ 0x8FF1, 0x8FF2, 0xE2EC, 0xBFEC, 0x8FF3, 0xE2ED, 0xE2E5, 0x8FF4, - /* U+5FF0 */ 0x8FF5, 0xB3C0, 0x8FF6, 0x8FF7, 0x8FF8, 0xC4EE, 0x8FF9, 0x8FFA, - /* U+5FF8 */ 0xE2EE, 0x8FFB, 0x8FFC, 0xD0C3, 0x8FFD, 0xBAF6, 0xE2E9, 0xB7DE, - /* U+6000 */ 0xBBB3, 0xCCAC, 0xCBCB, 0xE2E4, 0xE2E6, 0xE2EA, 0xE2EB, 0x8FFE, - /* U+6008 */ 0x9040, 0x9041, 0xE2F7, 0x9042, 0x9043, 0xE2F4, 0xD4F5, 0xE2F3, - /* U+6010 */ 0x9044, 0x9045, 0xC5AD, 0x9046, 0xD5FA, 0xC5C2, 0xB2C0, 0x9047, - /* U+6018 */ 0x9048, 0xE2EF, 0x9049, 0xE2F2, 0xC1AF, 0xCBBC, 0x904A, 0x904B, - /* U+6020 */ 0xB5A1, 0xE2F9, 0x904C, 0x904D, 0x904E, 0xBCB1, 0xE2F1, 0xD0D4, - /* U+6028 */ 0xD4B9, 0xE2F5, 0xB9D6, 0xE2F6, 0x904F, 0x9050, 0x9051, 0xC7D3, - /* U+6030 */ 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0xE2F0, 0x9057, 0x9058, - /* U+6038 */ 0x9059, 0x905A, 0x905B, 0xD7DC, 0xEDA1, 0x905C, 0x905D, 0xE2F8, - /* U+6040 */ 0x905E, 0xEDA5, 0xE2FE, 0xCAD1, 0x905F, 0x9060, 0x9061, 0x9062, - /* U+6048 */ 0x9063, 0x9064, 0x9065, 0xC1B5, 0x9066, 0xBBD0, 0x9067, 0x9068, - /* U+6050 */ 0xBFD6, 0x9069, 0xBAE3, 0x906A, 0x906B, 0xCBA1, 0x906C, 0x906D, - /* U+6058 */ 0x906E, 0xEDA6, 0xEDA3, 0x906F, 0x9070, 0xEDA2, 0x9071, 0x9072, - /* U+6060 */ 0x9073, 0x9074, 0xBBD6, 0xEDA7, 0xD0F4, 0x9075, 0x9076, 0xEDA4, - /* U+6068 */ 0xBADE, 0xB6F7, 0xE3A1, 0xB6B2, 0xCCF1, 0xB9A7, 0x9077, 0xCFA2, - /* U+6070 */ 0xC7A1, 0x9078, 0x9079, 0xBFD2, 0x907A, 0x907B, 0xB6F1, 0x907C, - /* U+6078 */ 0xE2FA, 0xE2FB, 0xE2FD, 0xE2FC, 0xC4D5, 0xE3A2, 0x907D, 0xD3C1, - /* U+6080 */ 0x907E, 0x9080, 0x9081, 0xE3A7, 0xC7C4, 0x9082, 0x9083, 0x9084, - /* U+6088 */ 0x9085, 0xCFA4, 0x9086, 0x9087, 0xE3A9, 0xBAB7, 0x9088, 0x9089, - /* U+6090 */ 0x908A, 0x908B, 0xE3A8, 0x908C, 0xBBDA, 0x908D, 0xE3A3, 0x908E, - /* U+6098 */ 0x908F, 0x9090, 0xE3A4, 0xE3AA, 0x9091, 0xE3A6, 0x9092, 0xCEF2, - /* U+60A0 */ 0xD3C6, 0x9093, 0x9094, 0xBBBC, 0x9095, 0x9096, 0xD4C3, 0x9097, - /* U+60A8 */ 0xC4FA, 0x9098, 0x9099, 0xEDA8, 0xD0FC, 0xE3A5, 0x909A, 0xC3F5, - /* U+60B0 */ 0x909B, 0xE3AD, 0xB1AF, 0x909C, 0xE3B2, 0x909D, 0x909E, 0x909F, - /* U+60B8 */ 0xBCC2, 0x90A0, 0x90A1, 0xE3AC, 0xB5BF, 0x90A2, 0x90A3, 0x90A4, - /* U+60C0 */ 0x90A5, 0x90A6, 0x90A7, 0x90A8, 0x90A9, 0xC7E9, 0xE3B0, 0x90AA, - /* U+60C8 */ 0x90AB, 0x90AC, 0xBEAA, 0xCDEF, 0x90AD, 0x90AE, 0x90AF, 0x90B0, - /* U+60D0 */ 0x90B1, 0xBBF3, 0x90B2, 0x90B3, 0x90B4, 0xCCE8, 0x90B5, 0x90B6, - /* U+60D8 */ 0xE3AF, 0x90B7, 0xE3B1, 0x90B8, 0xCFA7, 0xE3AE, 0x90B9, 0xCEA9, - /* U+60E0 */ 0xBBDD, 0x90BA, 0x90BB, 0x90BC, 0x90BD, 0x90BE, 0xB5EB, 0xBEE5, - /* U+60E8 */ 0xB2D2, 0xB3CD, 0x90BF, 0xB1B9, 0xE3AB, 0xB2D1, 0xB5AC, 0xB9DF, - /* U+60F0 */ 0xB6E8, 0x90C0, 0x90C1, 0xCFEB, 0xE3B7, 0x90C2, 0xBBCC, 0x90C3, - /* U+60F8 */ 0x90C4, 0xC8C7, 0xD0CA, 0x90C5, 0x90C6, 0x90C7, 0x90C8, 0x90C9, - /* U+6100 */ 0xE3B8, 0xB3EE, 0x90CA, 0x90CB, 0x90CC, 0x90CD, 0xEDA9, 0x90CE, - /* U+6108 */ 0xD3FA, 0xD3E4, 0x90CF, 0x90D0, 0x90D1, 0xEDAA, 0xE3B9, 0xD2E2, - /* U+6110 */ 0x90D2, 0x90D3, 0x90D4, 0x90D5, 0x90D6, 0xE3B5, 0x90D7, 0x90D8, - /* U+6118 */ 0x90D9, 0x90DA, 0xD3DE, 0x90DB, 0x90DC, 0x90DD, 0x90DE, 0xB8D0, - /* U+6120 */ 0xE3B3, 0x90DF, 0x90E0, 0xE3B6, 0xB7DF, 0x90E1, 0xE3B4, 0xC0A2, - /* U+6128 */ 0x90E2, 0x90E3, 0x90E4, 0xE3BA, 0x90E5, 0x90E6, 0x90E7, 0x90E8, - /* U+6130 */ 0x90E9, 0x90EA, 0x90EB, 0x90EC, 0x90ED, 0x90EE, 0x90EF, 0x90F0, - /* U+6138 */ 0x90F1, 0x90F2, 0x90F3, 0x90F4, 0x90F5, 0x90F6, 0x90F7, 0xD4B8, - /* U+6140 */ 0x90F8, 0x90F9, 0x90FA, 0x90FB, 0x90FC, 0x90FD, 0x90FE, 0x9140, - /* U+6148 */ 0xB4C8, 0x9141, 0xE3BB, 0x9142, 0xBBC5, 0x9143, 0xC9F7, 0x9144, - /* U+6150 */ 0x9145, 0xC9E5, 0x9146, 0x9147, 0x9148, 0xC4BD, 0x9149, 0x914A, - /* U+6158 */ 0x914B, 0x914C, 0x914D, 0x914E, 0x914F, 0xEDAB, 0x9150, 0x9151, - /* U+6160 */ 0x9152, 0x9153, 0xC2FD, 0x9154, 0x9155, 0x9156, 0x9157, 0xBBDB, - /* U+6168 */ 0xBFAE, 0x9158, 0x9159, 0x915A, 0x915B, 0x915C, 0x915D, 0x915E, - /* U+6170 */ 0xCEBF, 0x915F, 0x9160, 0x9161, 0x9162, 0xE3BC, 0x9163, 0xBFB6, - /* U+6178 */ 0x9164, 0x9165, 0x9166, 0x9167, 0x9168, 0x9169, 0x916A, 0x916B, - /* U+6180 */ 0x916C, 0x916D, 0x916E, 0x916F, 0x9170, 0x9171, 0x9172, 0x9173, - /* U+6188 */ 0x9174, 0x9175, 0x9176, 0xB1EF, 0x9177, 0x9178, 0xD4F7, 0x9179, - /* U+6190 */ 0x917A, 0x917B, 0x917C, 0x917D, 0xE3BE, 0x917E, 0x9180, 0x9181, - /* U+6198 */ 0x9182, 0x9183, 0x9184, 0x9185, 0x9186, 0xEDAD, 0x9187, 0x9188, - /* U+61A0 */ 0x9189, 0x918A, 0x918B, 0x918C, 0x918D, 0x918E, 0x918F, 0xE3BF, - /* U+61A8 */ 0xBAA9, 0xEDAC, 0x9190, 0x9191, 0xE3BD, 0x9192, 0x9193, 0x9194, - /* U+61B0 */ 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, 0x919A, 0x919B, 0xE3C0, - /* U+61B8 */ 0x919C, 0x919D, 0x919E, 0x919F, 0x91A0, 0x91A1, 0xBAB6, 0x91A2, - /* U+61C0 */ 0x91A3, 0x91A4, 0xB6AE, 0x91A5, 0x91A6, 0x91A7, 0x91A8, 0x91A9, - /* U+61C8 */ 0xD0B8, 0x91AA, 0xB0C3, 0xEDAE, 0x91AB, 0x91AC, 0x91AD, 0x91AE, - /* U+61D0 */ 0x91AF, 0xEDAF, 0xC0C1, 0x91B0, 0xE3C1, 0x91B1, 0x91B2, 0x91B3, - /* U+61D8 */ 0x91B4, 0x91B5, 0x91B6, 0x91B7, 0x91B8, 0x91B9, 0x91BA, 0x91BB, - /* U+61E0 */ 0x91BC, 0x91BD, 0x91BE, 0x91BF, 0x91C0, 0x91C1, 0xC5B3, 0x91C2, - /* U+61E8 */ 0x91C3, 0x91C4, 0x91C5, 0x91C6, 0x91C7, 0x91C8, 0x91C9, 0x91CA, - /* U+61F0 */ 0x91CB, 0x91CC, 0x91CD, 0x91CE, 0x91CF, 0xE3C2, 0x91D0, 0x91D1, - /* U+61F8 */ 0x91D2, 0x91D3, 0x91D4, 0x91D5, 0x91D6, 0x91D7, 0x91D8, 0xDCB2, - /* U+6200 */ 0x91D9, 0x91DA, 0x91DB, 0x91DC, 0x91DD, 0x91DE, 0xEDB0, 0x91DF, - /* U+6208 */ 0xB8EA, 0x91E0, 0xCEEC, 0xEAA7, 0xD0E7, 0xCAF9, 0xC8D6, 0xCFB7, - /* U+6210 */ 0xB3C9, 0xCED2, 0xBDE4, 0x91E1, 0x91E2, 0xE3DE, 0xBBF2, 0xEAA8, - /* U+6218 */ 0xD5BD, 0x91E3, 0xC6DD, 0xEAA9, 0x91E4, 0x91E5, 0x91E6, 0xEAAA, - /* U+6220 */ 0x91E7, 0xEAAC, 0xEAAB, 0x91E8, 0xEAAE, 0xEAAD, 0x91E9, 0x91EA, - /* U+6228 */ 0x91EB, 0x91EC, 0xBDD8, 0x91ED, 0xEAAF, 0x91EE, 0xC2BE, 0x91EF, - /* U+6230 */ 0x91F0, 0x91F1, 0x91F2, 0xB4C1, 0xB4F7, 0x91F3, 0x91F4, 0xBBA7, - /* U+6238 */ 0x91F5, 0x91F6, 0x91F7, 0x91F8, 0x91F9, 0xECE6, 0xECE5, 0xB7BF, - /* U+6240 */ 0xCBF9, 0xB1E2, 0x91FA, 0xECE7, 0x91FB, 0x91FC, 0x91FD, 0xC9C8, - /* U+6248 */ 0xECE8, 0xECE9, 0x91FE, 0xCAD6, 0xDED0, 0xB2C5, 0xD4FA, 0x9240, - /* U+6250 */ 0x9241, 0xC6CB, 0xB0C7, 0xB4F2, 0xC8D3, 0x9242, 0x9243, 0x9244, - /* U+6258 */ 0xCDD0, 0x9245, 0x9246, 0xBFB8, 0x9247, 0x9248, 0x9249, 0x924A, - /* U+6260 */ 0x924B, 0x924C, 0x924D, 0xBFDB, 0x924E, 0x924F, 0xC7A4, 0xD6B4, - /* U+6268 */ 0x9250, 0xC0A9, 0xDED1, 0xC9A8, 0xD1EF, 0xC5A4, 0xB0E7, 0xB3B6, - /* U+6270 */ 0xC8C5, 0x9251, 0x9252, 0xB0E2, 0x9253, 0x9254, 0xB7F6, 0x9255, - /* U+6278 */ 0x9256, 0xC5FA, 0x9257, 0x9258, 0xB6F3, 0x9259, 0xD5D2, 0xB3D0, - /* U+6280 */ 0xBCBC, 0x925A, 0x925B, 0x925C, 0xB3AD, 0x925D, 0x925E, 0x925F, - /* U+6288 */ 0x9260, 0xBEF1, 0xB0D1, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265, - /* U+6290 */ 0x9266, 0xD2D6, 0xCAE3, 0xD7A5, 0x9267, 0xCDB6, 0xB6B6, 0xBFB9, - /* U+6298 */ 0xD5DB, 0x9268, 0xB8A7, 0xC5D7, 0x9269, 0x926A, 0x926B, 0xDED2, - /* U+62A0 */ 0xBFD9, 0xC2D5, 0xC7C0, 0x926C, 0xBBA4, 0xB1A8, 0x926D, 0x926E, - /* U+62A8 */ 0xC5EA, 0x926F, 0x9270, 0xC5FB, 0xCCA7, 0x9271, 0x9272, 0x9273, - /* U+62B0 */ 0x9274, 0xB1A7, 0x9275, 0x9276, 0x9277, 0xB5D6, 0x9278, 0x9279, - /* U+62B8 */ 0x927A, 0xC4A8, 0x927B, 0xDED3, 0xD1BA, 0xB3E9, 0x927C, 0xC3F2, - /* U+62C0 */ 0x927D, 0x927E, 0xB7F7, 0x9280, 0xD6F4, 0xB5A3, 0xB2F0, 0xC4B4, - /* U+62C8 */ 0xC4E9, 0xC0AD, 0xDED4, 0x9281, 0xB0E8, 0xC5C4, 0xC1E0, 0x9282, - /* U+62D0 */ 0xB9D5, 0x9283, 0xBEDC, 0xCDD8, 0xB0CE, 0x9284, 0xCDCF, 0xDED6, - /* U+62D8 */ 0xBED0, 0xD7BE, 0xDED5, 0xD5D0, 0xB0DD, 0x9285, 0x9286, 0xC4E2, - /* U+62E0 */ 0x9287, 0x9288, 0xC2A3, 0xBCF0, 0x9289, 0xD3B5, 0xC0B9, 0xC5A1, - /* U+62E8 */ 0xB2A6, 0xD4F1, 0x928A, 0x928B, 0xC0A8, 0xCAC3, 0xDED7, 0xD5FC, - /* U+62F0 */ 0x928C, 0xB9B0, 0x928D, 0xC8AD, 0xCBA9, 0x928E, 0xDED9, 0xBFBD, - /* U+62F8 */ 0x928F, 0x9290, 0x9291, 0x9292, 0xC6B4, 0xD7A7, 0xCAB0, 0xC4C3, - /* U+6300 */ 0x9293, 0xB3D6, 0xB9D2, 0x9294, 0x9295, 0x9296, 0x9297, 0xD6B8, - /* U+6308 */ 0xEAFC, 0xB0B4, 0x9298, 0x9299, 0x929A, 0x929B, 0xBFE6, 0x929C, - /* U+6310 */ 0x929D, 0xCCF4, 0x929E, 0x929F, 0x92A0, 0x92A1, 0xCDDA, 0x92A2, - /* U+6318 */ 0x92A3, 0x92A4, 0xD6BF, 0xC2CE, 0x92A5, 0xCECE, 0xCCA2, 0xD0AE, - /* U+6320 */ 0xC4D3, 0xB5B2, 0xDED8, 0xD5F5, 0xBCB7, 0xBBD3, 0x92A6, 0x92A7, - /* U+6328 */ 0xB0A4, 0x92A8, 0xC5B2, 0xB4EC, 0x92A9, 0x92AA, 0x92AB, 0xD5F1, - /* U+6330 */ 0x92AC, 0x92AD, 0xEAFD, 0x92AE, 0x92AF, 0x92B0, 0x92B1, 0x92B2, - /* U+6338 */ 0x92B3, 0xDEDA, 0xCDA6, 0x92B4, 0x92B5, 0xCDEC, 0x92B6, 0x92B7, - /* U+6340 */ 0x92B8, 0x92B9, 0xCEE6, 0xDEDC, 0x92BA, 0xCDB1, 0xC0A6, 0x92BB, - /* U+6348 */ 0x92BC, 0xD7BD, 0x92BD, 0xDEDB, 0xB0C6, 0xBAB4, 0xC9D3, 0xC4F3, - /* U+6350 */ 0xBEE8, 0x92BE, 0x92BF, 0x92C0, 0x92C1, 0xB2B6, 0x92C2, 0x92C3, - /* U+6358 */ 0x92C4, 0x92C5, 0x92C6, 0x92C7, 0x92C8, 0x92C9, 0xC0CC, 0xCBF0, - /* U+6360 */ 0x92CA, 0xBCF1, 0xBBBB, 0xB5B7, 0x92CB, 0x92CC, 0x92CD, 0xC5F5, - /* U+6368 */ 0x92CE, 0xDEE6, 0x92CF, 0x92D0, 0x92D1, 0xDEE3, 0xBEDD, 0x92D2, - /* U+6370 */ 0x92D3, 0xDEDF, 0x92D4, 0x92D5, 0x92D6, 0x92D7, 0xB4B7, 0xBDDD, - /* U+6378 */ 0x92D8, 0x92D9, 0xDEE0, 0xC4ED, 0x92DA, 0x92DB, 0x92DC, 0x92DD, - /* U+6380 */ 0xCFC6, 0x92DE, 0xB5E0, 0x92DF, 0x92E0, 0x92E1, 0x92E2, 0xB6DE, - /* U+6388 */ 0xCADA, 0xB5F4, 0xDEE5, 0x92E3, 0xD5C6, 0x92E4, 0xDEE1, 0xCCCD, - /* U+6390 */ 0xC6FE, 0x92E5, 0xC5C5, 0x92E6, 0x92E7, 0x92E8, 0xD2B4, 0x92E9, - /* U+6398 */ 0xBEF2, 0x92EA, 0x92EB, 0x92EC, 0x92ED, 0x92EE, 0x92EF, 0x92F0, - /* U+63A0 */ 0xC2D3, 0x92F1, 0xCCBD, 0xB3B8, 0x92F2, 0xBDD3, 0x92F3, 0xBFD8, - /* U+63A8 */ 0xCDC6, 0xD1DA, 0xB4EB, 0x92F4, 0xDEE4, 0xDEDD, 0xDEE7, 0x92F5, - /* U+63B0 */ 0xEAFE, 0x92F6, 0x92F7, 0xC2B0, 0xDEE2, 0x92F8, 0x92F9, 0xD6C0, - /* U+63B8 */ 0xB5A7, 0x92FA, 0xB2F4, 0x92FB, 0xDEE8, 0x92FC, 0xDEF2, 0x92FD, - /* U+63C0 */ 0x92FE, 0x9340, 0x9341, 0x9342, 0xDEED, 0x9343, 0xDEF1, 0x9344, - /* U+63C8 */ 0x9345, 0xC8E0, 0x9346, 0x9347, 0x9348, 0xD7E1, 0xDEEF, 0xC3E8, - /* U+63D0 */ 0xCCE1, 0x9349, 0xB2E5, 0x934A, 0x934B, 0x934C, 0xD2BE, 0x934D, - /* U+63D8 */ 0x934E, 0x934F, 0x9350, 0x9351, 0x9352, 0x9353, 0xDEEE, 0x9354, - /* U+63E0 */ 0xDEEB, 0xCED5, 0x9355, 0xB4A7, 0x9356, 0x9357, 0x9358, 0x9359, - /* U+63E8 */ 0x935A, 0xBFAB, 0xBEBE, 0x935B, 0x935C, 0xBDD2, 0x935D, 0x935E, - /* U+63F0 */ 0x935F, 0x9360, 0xDEE9, 0x9361, 0xD4AE, 0x9362, 0xDEDE, 0x9363, - /* U+63F8 */ 0xDEEA, 0x9364, 0x9365, 0x9366, 0x9367, 0xC0BF, 0x9368, 0xDEEC, - /* U+6400 */ 0xB2F3, 0xB8E9, 0xC2A7, 0x9369, 0x936A, 0xBDC1, 0x936B, 0x936C, - /* U+6408 */ 0x936D, 0x936E, 0x936F, 0xDEF5, 0xDEF8, 0x9370, 0x9371, 0xB2AB, - /* U+6410 */ 0xB4A4, 0x9372, 0x9373, 0xB4EA, 0xC9A6, 0x9374, 0x9375, 0x9376, - /* U+6418 */ 0x9377, 0x9378, 0x9379, 0xDEF6, 0xCBD1, 0x937A, 0xB8E3, 0x937B, - /* U+6420 */ 0xDEF7, 0xDEFA, 0x937C, 0x937D, 0x937E, 0x9380, 0xDEF9, 0x9381, - /* U+6428 */ 0x9382, 0x9383, 0xCCC2, 0x9384, 0xB0E1, 0xB4EE, 0x9385, 0x9386, - /* U+6430 */ 0x9387, 0x9388, 0x9389, 0x938A, 0xE5BA, 0x938B, 0x938C, 0x938D, - /* U+6438 */ 0x938E, 0x938F, 0xD0AF, 0x9390, 0x9391, 0xB2EB, 0x9392, 0xEBA1, - /* U+6440 */ 0x9393, 0xDEF4, 0x9394, 0x9395, 0xC9E3, 0xDEF3, 0xB0DA, 0xD2A1, - /* U+6448 */ 0xB1F7, 0x9396, 0xCCAF, 0x9397, 0x9398, 0x9399, 0x939A, 0x939B, - /* U+6450 */ 0x939C, 0x939D, 0xDEF0, 0x939E, 0xCBA4, 0x939F, 0x93A0, 0x93A1, - /* U+6458 */ 0xD5AA, 0x93A2, 0x93A3, 0x93A4, 0x93A5, 0x93A6, 0xDEFB, 0x93A7, - /* U+6460 */ 0x93A8, 0x93A9, 0x93AA, 0x93AB, 0x93AC, 0x93AD, 0x93AE, 0xB4DD, - /* U+6468 */ 0x93AF, 0xC4A6, 0x93B0, 0x93B1, 0x93B2, 0xDEFD, 0x93B3, 0x93B4, - /* U+6470 */ 0x93B5, 0x93B6, 0x93B7, 0x93B8, 0x93B9, 0x93BA, 0x93BB, 0x93BC, - /* U+6478 */ 0xC3FE, 0xC4A1, 0xDFA1, 0x93BD, 0x93BE, 0x93BF, 0x93C0, 0x93C1, - /* U+6480 */ 0x93C2, 0x93C3, 0xC1CC, 0x93C4, 0xDEFC, 0xBEEF, 0x93C5, 0xC6B2, - /* U+6488 */ 0x93C6, 0x93C7, 0x93C8, 0x93C9, 0x93CA, 0x93CB, 0x93CC, 0x93CD, - /* U+6490 */ 0x93CE, 0xB3C5, 0xC8F6, 0x93CF, 0x93D0, 0xCBBA, 0xDEFE, 0x93D1, - /* U+6498 */ 0x93D2, 0xDFA4, 0x93D3, 0x93D4, 0x93D5, 0x93D6, 0xD7B2, 0x93D7, - /* U+64A0 */ 0x93D8, 0x93D9, 0x93DA, 0x93DB, 0xB3B7, 0x93DC, 0x93DD, 0x93DE, - /* U+64A8 */ 0x93DF, 0xC1C3, 0x93E0, 0x93E1, 0xC7CB, 0xB2A5, 0xB4E9, 0x93E2, - /* U+64B0 */ 0xD7AB, 0x93E3, 0x93E4, 0x93E5, 0x93E6, 0xC4EC, 0x93E7, 0xDFA2, - /* U+64B8 */ 0xDFA3, 0x93E8, 0xDFA5, 0x93E9, 0xBAB3, 0x93EA, 0x93EB, 0x93EC, - /* U+64C0 */ 0xDFA6, 0x93ED, 0xC0DE, 0x93EE, 0x93EF, 0xC9C3, 0x93F0, 0x93F1, - /* U+64C8 */ 0x93F2, 0x93F3, 0x93F4, 0x93F5, 0x93F6, 0xB2D9, 0xC7E6, 0x93F7, - /* U+64D0 */ 0xDFA7, 0x93F8, 0xC7DC, 0x93F9, 0x93FA, 0x93FB, 0x93FC, 0xDFA8, - /* U+64D8 */ 0xEBA2, 0x93FD, 0x93FE, 0x9440, 0x9441, 0x9442, 0xCBD3, 0x9443, - /* U+64E0 */ 0x9444, 0x9445, 0xDFAA, 0x9446, 0xDFA9, 0x9447, 0xB2C1, 0x9448, - /* U+64E8 */ 0x9449, 0x944A, 0x944B, 0x944C, 0x944D, 0x944E, 0x944F, 0x9450, - /* U+64F0 */ 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, 0x9458, - /* U+64F8 */ 0x9459, 0x945A, 0x945B, 0x945C, 0x945D, 0x945E, 0x945F, 0x9460, - /* U+6500 */ 0xC5CA, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, - /* U+6508 */ 0x9468, 0xDFAB, 0x9469, 0x946A, 0x946B, 0x946C, 0x946D, 0x946E, - /* U+6510 */ 0x946F, 0x9470, 0xD4DC, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, - /* U+6518 */ 0xC8C1, 0x9476, 0x9477, 0x9478, 0x9479, 0x947A, 0x947B, 0x947C, - /* U+6520 */ 0x947D, 0x947E, 0x9480, 0x9481, 0x9482, 0xDFAC, 0x9483, 0x9484, - /* U+6528 */ 0x9485, 0x9486, 0x9487, 0xBEF0, 0x9488, 0x9489, 0xDFAD, 0xD6A7, - /* U+6530 */ 0x948A, 0x948B, 0x948C, 0x948D, 0xEAB7, 0xEBB6, 0xCAD5, 0x948E, - /* U+6538 */ 0xD8FC, 0xB8C4, 0x948F, 0xB9A5, 0x9490, 0x9491, 0xB7C5, 0xD5FE, - /* U+6540 */ 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0xB9CA, 0x9497, 0x9498, - /* U+6548 */ 0xD0A7, 0xF4CD, 0x9499, 0x949A, 0xB5D0, 0x949B, 0x949C, 0xC3F4, - /* U+6550 */ 0x949D, 0xBEC8, 0x949E, 0x949F, 0x94A0, 0xEBB7, 0xB0BD, 0x94A1, - /* U+6558 */ 0x94A2, 0xBDCC, 0x94A3, 0xC1B2, 0x94A4, 0xB1D6, 0xB3A8, 0x94A5, - /* U+6560 */ 0x94A6, 0x94A7, 0xB8D2, 0xC9A2, 0x94A8, 0x94A9, 0xB6D8, 0x94AA, - /* U+6568 */ 0x94AB, 0x94AC, 0x94AD, 0xEBB8, 0xBEB4, 0x94AE, 0x94AF, 0x94B0, - /* U+6570 */ 0xCAFD, 0x94B1, 0xC7C3, 0x94B2, 0xD5FB, 0x94B3, 0x94B4, 0xB7F3, - /* U+6578 */ 0x94B5, 0x94B6, 0x94B7, 0x94B8, 0x94B9, 0x94BA, 0x94BB, 0x94BC, - /* U+6580 */ 0x94BD, 0x94BE, 0x94BF, 0x94C0, 0x94C1, 0x94C2, 0x94C3, 0xCEC4, - /* U+6588 */ 0x94C4, 0x94C5, 0x94C6, 0xD5AB, 0xB1F3, 0x94C7, 0x94C8, 0x94C9, - /* U+6590 */ 0xECB3, 0xB0DF, 0x94CA, 0xECB5, 0x94CB, 0x94CC, 0x94CD, 0xB6B7, - /* U+6598 */ 0x94CE, 0xC1CF, 0x94CF, 0xF5FA, 0xD0B1, 0x94D0, 0x94D1, 0xD5E5, - /* U+65A0 */ 0x94D2, 0xCED3, 0x94D3, 0x94D4, 0xBDEF, 0xB3E2, 0x94D5, 0xB8AB, - /* U+65A8 */ 0x94D6, 0xD5B6, 0x94D7, 0xEDBD, 0x94D8, 0xB6CF, 0x94D9, 0xCBB9, - /* U+65B0 */ 0xD0C2, 0x94DA, 0x94DB, 0x94DC, 0x94DD, 0x94DE, 0x94DF, 0x94E0, - /* U+65B8 */ 0x94E1, 0xB7BD, 0x94E2, 0x94E3, 0xECB6, 0xCAA9, 0x94E4, 0x94E5, - /* U+65C0 */ 0x94E6, 0xC5D4, 0x94E7, 0xECB9, 0xECB8, 0xC2C3, 0xECB7, 0x94E8, - /* U+65C8 */ 0x94E9, 0x94EA, 0x94EB, 0xD0FD, 0xECBA, 0x94EC, 0xECBB, 0xD7E5, - /* U+65D0 */ 0x94ED, 0x94EE, 0xECBC, 0x94EF, 0x94F0, 0x94F1, 0xECBD, 0xC6EC, - /* U+65D8 */ 0x94F2, 0x94F3, 0x94F4, 0x94F5, 0x94F6, 0x94F7, 0x94F8, 0x94F9, - /* U+65E0 */ 0xCEDE, 0x94FA, 0xBCC8, 0x94FB, 0x94FC, 0xC8D5, 0xB5A9, 0xBEC9, - /* U+65E8 */ 0xD6BC, 0xD4E7, 0x94FD, 0x94FE, 0xD1AE, 0xD0F1, 0xEAB8, 0xEAB9, - /* U+65F0 */ 0xEABA, 0xBAB5, 0x9540, 0x9541, 0x9542, 0x9543, 0xCAB1, 0xBFF5, - /* U+65F8 */ 0x9544, 0x9545, 0xCDFA, 0x9546, 0x9547, 0x9548, 0x9549, 0x954A, - /* U+6600 */ 0xEAC0, 0x954B, 0xB0BA, 0xEABE, 0x954C, 0x954D, 0xC0A5, 0x954E, - /* U+6608 */ 0x954F, 0x9550, 0xEABB, 0x9551, 0xB2FD, 0x9552, 0xC3F7, 0xBBE8, - /* U+6610 */ 0x9553, 0x9554, 0x9555, 0xD2D7, 0xCEF4, 0xEABF, 0x9556, 0x9557, - /* U+6618 */ 0x9558, 0xEABC, 0x9559, 0x955A, 0x955B, 0xEAC3, 0x955C, 0xD0C7, - /* U+6620 */ 0xD3B3, 0x955D, 0x955E, 0x955F, 0x9560, 0xB4BA, 0x9561, 0xC3C1, - /* U+6628 */ 0xD7F2, 0x9562, 0x9563, 0x9564, 0x9565, 0xD5D1, 0x9566, 0xCAC7, - /* U+6630 */ 0x9567, 0xEAC5, 0x9568, 0x9569, 0xEAC4, 0xEAC7, 0xEAC6, 0x956A, - /* U+6638 */ 0x956B, 0x956C, 0x956D, 0x956E, 0xD6E7, 0x956F, 0xCFD4, 0x9570, - /* U+6640 */ 0x9571, 0xEACB, 0x9572, 0xBBCE, 0x9573, 0x9574, 0x9575, 0x9576, - /* U+6648 */ 0x9577, 0x9578, 0x9579, 0xBDFA, 0xC9CE, 0x957A, 0x957B, 0xEACC, - /* U+6650 */ 0x957C, 0x957D, 0xC9B9, 0xCFFE, 0xEACA, 0xD4CE, 0xEACD, 0xEACF, - /* U+6658 */ 0x957E, 0x9580, 0xCDED, 0x9581, 0x9582, 0x9583, 0x9584, 0xEAC9, - /* U+6660 */ 0x9585, 0xEACE, 0x9586, 0x9587, 0xCEEE, 0x9588, 0xBBDE, 0x9589, - /* U+6668 */ 0xB3BF, 0x958A, 0x958B, 0x958C, 0x958D, 0x958E, 0xC6D5, 0xBEB0, - /* U+6670 */ 0xCEFA, 0x958F, 0x9590, 0x9591, 0xC7E7, 0x9592, 0xBEA7, 0xEAD0, - /* U+6678 */ 0x9593, 0x9594, 0xD6C7, 0x9595, 0x9596, 0x9597, 0xC1C0, 0x9598, - /* U+6680 */ 0x9599, 0x959A, 0xD4DD, 0x959B, 0xEAD1, 0x959C, 0x959D, 0xCFBE, - /* U+6688 */ 0x959E, 0x959F, 0x95A0, 0x95A1, 0xEAD2, 0x95A2, 0x95A3, 0x95A4, - /* U+6690 */ 0x95A5, 0xCAEE, 0x95A6, 0x95A7, 0x95A8, 0x95A9, 0xC5AF, 0xB0B5, - /* U+6698 */ 0x95AA, 0x95AB, 0x95AC, 0x95AD, 0x95AE, 0xEAD4, 0x95AF, 0x95B0, - /* U+66A0 */ 0x95B1, 0x95B2, 0x95B3, 0x95B4, 0x95B5, 0x95B6, 0x95B7, 0xEAD3, - /* U+66A8 */ 0xF4DF, 0x95B8, 0x95B9, 0x95BA, 0x95BB, 0x95BC, 0xC4BA, 0x95BD, - /* U+66B0 */ 0x95BE, 0x95BF, 0x95C0, 0x95C1, 0xB1A9, 0x95C2, 0x95C3, 0x95C4, - /* U+66B8 */ 0x95C5, 0xE5DF, 0x95C6, 0x95C7, 0x95C8, 0x95C9, 0xEAD5, 0x95CA, - /* U+66C0 */ 0x95CB, 0x95CC, 0x95CD, 0x95CE, 0x95CF, 0x95D0, 0x95D1, 0x95D2, - /* U+66C8 */ 0x95D3, 0x95D4, 0x95D5, 0x95D6, 0x95D7, 0x95D8, 0x95D9, 0x95DA, - /* U+66D0 */ 0x95DB, 0x95DC, 0x95DD, 0x95DE, 0x95DF, 0x95E0, 0x95E1, 0x95E2, - /* U+66D8 */ 0x95E3, 0xCAEF, 0x95E4, 0xEAD6, 0xEAD7, 0xC6D8, 0x95E5, 0x95E6, - /* U+66E0 */ 0x95E7, 0x95E8, 0x95E9, 0x95EA, 0x95EB, 0x95EC, 0xEAD8, 0x95ED, - /* U+66E8 */ 0x95EE, 0xEAD9, 0x95EF, 0x95F0, 0x95F1, 0x95F2, 0x95F3, 0x95F4, - /* U+66F0 */ 0xD4BB, 0x95F5, 0xC7FA, 0xD2B7, 0xB8FC, 0x95F6, 0x95F7, 0xEAC2, - /* U+66F8 */ 0x95F8, 0xB2DC, 0x95F9, 0x95FA, 0xC2FC, 0x95FB, 0xD4F8, 0xCCE6, - /* U+6700 */ 0xD7EE, 0x95FC, 0x95FD, 0x95FE, 0x9640, 0x9641, 0x9642, 0x9643, - /* U+6708 */ 0xD4C2, 0xD3D0, 0xEBC3, 0xC5F3, 0x9644, 0xB7FE, 0x9645, 0x9646, - /* U+6710 */ 0xEBD4, 0x9647, 0x9648, 0x9649, 0xCBB7, 0xEBDE, 0x964A, 0xC0CA, - /* U+6718 */ 0x964B, 0x964C, 0x964D, 0xCDFB, 0x964E, 0xB3AF, 0x964F, 0xC6DA, - /* U+6720 */ 0x9650, 0x9651, 0x9652, 0x9653, 0x9654, 0x9655, 0xEBFC, 0x9656, - /* U+6728 */ 0xC4BE, 0x9657, 0xCEB4, 0xC4A9, 0xB1BE, 0xD4FD, 0x9658, 0xCAF5, - /* U+6730 */ 0x9659, 0xD6EC, 0x965A, 0x965B, 0xC6D3, 0xB6E4, 0x965C, 0x965D, - /* U+6738 */ 0x965E, 0x965F, 0xBBFA, 0x9660, 0x9661, 0xD0E0, 0x9662, 0x9663, - /* U+6740 */ 0xC9B1, 0x9664, 0xD4D3, 0xC8A8, 0x9665, 0x9666, 0xB8CB, 0x9667, - /* U+6748 */ 0xE8BE, 0xC9BC, 0x9668, 0x9669, 0xE8BB, 0x966A, 0xC0EE, 0xD0D3, - /* U+6750 */ 0xB2C4, 0xB4E5, 0x966B, 0xE8BC, 0x966C, 0x966D, 0xD5C8, 0x966E, - /* U+6758 */ 0x966F, 0x9670, 0x9671, 0x9672, 0xB6C5, 0x9673, 0xE8BD, 0xCAF8, - /* U+6760 */ 0xB8DC, 0xCCF5, 0x9674, 0x9675, 0x9676, 0xC0B4, 0x9677, 0x9678, - /* U+6768 */ 0xD1EE, 0xE8BF, 0xE8C2, 0x9679, 0x967A, 0xBABC, 0x967B, 0xB1AD, - /* U+6770 */ 0xBDDC, 0x967C, 0xEABD, 0xE8C3, 0x967D, 0xE8C6, 0x967E, 0xE8CB, - /* U+6778 */ 0x9680, 0x9681, 0x9682, 0x9683, 0xE8CC, 0x9684, 0xCBC9, 0xB0E5, - /* U+6780 */ 0x9685, 0xBCAB, 0x9686, 0x9687, 0xB9B9, 0x9688, 0x9689, 0xE8C1, - /* U+6788 */ 0x968A, 0xCDF7, 0x968B, 0xE8CA, 0x968C, 0x968D, 0x968E, 0x968F, - /* U+6790 */ 0xCEF6, 0x9690, 0x9691, 0x9692, 0x9693, 0xD5ED, 0x9694, 0xC1D6, - /* U+6798 */ 0xE8C4, 0x9695, 0xC3B6, 0x9696, 0xB9FB, 0xD6A6, 0xE8C8, 0x9697, - /* U+67A0 */ 0x9698, 0x9699, 0xCAE0, 0xD4E6, 0x969A, 0xE8C0, 0x969B, 0xE8C5, - /* U+67A8 */ 0xE8C7, 0x969C, 0xC7B9, 0xB7E3, 0x969D, 0xE8C9, 0x969E, 0xBFDD, - /* U+67B0 */ 0xE8D2, 0x969F, 0x96A0, 0xE8D7, 0x96A1, 0xE8D5, 0xBCDC, 0xBCCF, - /* U+67B8 */ 0xE8DB, 0x96A2, 0x96A3, 0x96A4, 0x96A5, 0x96A6, 0x96A7, 0x96A8, - /* U+67C0 */ 0x96A9, 0xE8DE, 0x96AA, 0xE8DA, 0xB1FA, 0x96AB, 0x96AC, 0x96AD, - /* U+67C8 */ 0x96AE, 0x96AF, 0x96B0, 0x96B1, 0x96B2, 0x96B3, 0x96B4, 0xB0D8, - /* U+67D0 */ 0xC4B3, 0xB8CC, 0xC6E2, 0xC8BE, 0xC8E1, 0x96B5, 0x96B6, 0x96B7, - /* U+67D8 */ 0xE8CF, 0xE8D4, 0xE8D6, 0x96B8, 0xB9F1, 0xE8D8, 0xD7F5, 0x96B9, - /* U+67E0 */ 0xC4FB, 0x96BA, 0xE8DC, 0x96BB, 0x96BC, 0xB2E9, 0x96BD, 0x96BE, - /* U+67E8 */ 0x96BF, 0xE8D1, 0x96C0, 0x96C1, 0xBCED, 0x96C2, 0x96C3, 0xBFC2, - /* U+67F0 */ 0xE8CD, 0xD6F9, 0x96C4, 0xC1F8, 0xB2F1, 0x96C5, 0x96C6, 0x96C7, - /* U+67F8 */ 0x96C8, 0x96C9, 0x96CA, 0x96CB, 0x96CC, 0xE8DF, 0x96CD, 0xCAC1, - /* U+6800 */ 0xE8D9, 0x96CE, 0x96CF, 0x96D0, 0x96D1, 0xD5A4, 0x96D2, 0xB1EA, - /* U+6808 */ 0xD5BB, 0xE8CE, 0xE8D0, 0xB6B0, 0xE8D3, 0x96D3, 0xE8DD, 0xC0B8, - /* U+6810 */ 0x96D4, 0xCAF7, 0x96D5, 0xCBA8, 0x96D6, 0x96D7, 0xC6DC, 0xC0F5, - /* U+6818 */ 0x96D8, 0x96D9, 0x96DA, 0x96DB, 0x96DC, 0xE8E9, 0x96DD, 0x96DE, - /* U+6820 */ 0x96DF, 0xD0A3, 0x96E0, 0x96E1, 0x96E2, 0x96E3, 0x96E4, 0x96E5, - /* U+6828 */ 0x96E6, 0xE8F2, 0xD6EA, 0x96E7, 0x96E8, 0x96E9, 0x96EA, 0x96EB, - /* U+6830 */ 0x96EC, 0x96ED, 0xE8E0, 0xE8E1, 0x96EE, 0x96EF, 0x96F0, 0xD1F9, - /* U+6838 */ 0xBACB, 0xB8F9, 0x96F1, 0x96F2, 0xB8F1, 0xD4D4, 0xE8EF, 0x96F3, - /* U+6840 */ 0xE8EE, 0xE8EC, 0xB9F0, 0xCCD2, 0xE8E6, 0xCEA6, 0xBFF2, 0x96F4, - /* U+6848 */ 0xB0B8, 0xE8F1, 0xE8F0, 0x96F5, 0xD7C0, 0x96F6, 0xE8E4, 0x96F7, - /* U+6850 */ 0xCDA9, 0xC9A3, 0x96F8, 0xBBB8, 0xBDDB, 0xE8EA, 0x96F9, 0x96FA, - /* U+6858 */ 0x96FB, 0x96FC, 0x96FD, 0x96FE, 0x9740, 0x9741, 0x9742, 0x9743, - /* U+6860 */ 0xE8E2, 0xE8E3, 0xE8E5, 0xB5B5, 0xE8E7, 0xC7C5, 0xE8EB, 0xE8ED, - /* U+6868 */ 0xBDB0, 0xD7AE, 0x9744, 0xE8F8, 0x9745, 0x9746, 0x9747, 0x9748, - /* U+6870 */ 0x9749, 0x974A, 0x974B, 0x974C, 0xE8F5, 0x974D, 0xCDB0, 0xE8F6, - /* U+6878 */ 0x974E, 0x974F, 0x9750, 0x9751, 0x9752, 0x9753, 0x9754, 0x9755, - /* U+6880 */ 0x9756, 0xC1BA, 0x9757, 0xE8E8, 0x9758, 0xC3B7, 0xB0F0, 0x9759, - /* U+6888 */ 0x975A, 0x975B, 0x975C, 0x975D, 0x975E, 0x975F, 0x9760, 0xE8F4, - /* U+6890 */ 0x9761, 0x9762, 0x9763, 0xE8F7, 0x9764, 0x9765, 0x9766, 0xB9A3, - /* U+6898 */ 0x9767, 0x9768, 0x9769, 0x976A, 0x976B, 0x976C, 0x976D, 0x976E, - /* U+68A0 */ 0x976F, 0x9770, 0xC9D2, 0x9771, 0x9772, 0x9773, 0xC3CE, 0xCEE0, - /* U+68A8 */ 0xC0E6, 0x9774, 0x9775, 0x9776, 0x9777, 0xCBF3, 0x9778, 0xCCDD, - /* U+68B0 */ 0xD0B5, 0x9779, 0x977A, 0xCAE1, 0x977B, 0xE8F3, 0x977C, 0x977D, - /* U+68B8 */ 0x977E, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785, 0x9786, - /* U+68C0 */ 0xBCEC, 0x9787, 0xE8F9, 0x9788, 0x9789, 0x978A, 0x978B, 0x978C, - /* U+68C8 */ 0x978D, 0xC3DE, 0x978E, 0xC6E5, 0x978F, 0xB9F7, 0x9790, 0x9791, - /* U+68D0 */ 0x9792, 0x9793, 0xB0F4, 0x9794, 0x9795, 0xD7D8, 0x9796, 0x9797, - /* U+68D8 */ 0xBCAC, 0x9798, 0xC5EF, 0x9799, 0x979A, 0x979B, 0x979C, 0x979D, - /* U+68E0 */ 0xCCC4, 0x979E, 0x979F, 0xE9A6, 0x97A0, 0x97A1, 0x97A2, 0x97A3, - /* U+68E8 */ 0x97A4, 0x97A5, 0x97A6, 0x97A7, 0x97A8, 0x97A9, 0xC9AD, 0x97AA, - /* U+68F0 */ 0xE9A2, 0xC0E2, 0x97AB, 0x97AC, 0x97AD, 0xBFC3, 0x97AE, 0x97AF, - /* U+68F8 */ 0x97B0, 0xE8FE, 0xB9D7, 0x97B1, 0xE8FB, 0x97B2, 0x97B3, 0x97B4, - /* U+6900 */ 0x97B5, 0xE9A4, 0x97B6, 0x97B7, 0x97B8, 0xD2CE, 0x97B9, 0x97BA, - /* U+6908 */ 0x97BB, 0x97BC, 0x97BD, 0xE9A3, 0x97BE, 0xD6B2, 0xD7B5, 0x97BF, - /* U+6910 */ 0xE9A7, 0x97C0, 0xBDB7, 0x97C1, 0x97C2, 0x97C3, 0x97C4, 0x97C5, - /* U+6918 */ 0x97C6, 0x97C7, 0x97C8, 0x97C9, 0x97CA, 0x97CB, 0x97CC, 0xE8FC, - /* U+6920 */ 0xE8FD, 0x97CD, 0x97CE, 0x97CF, 0xE9A1, 0x97D0, 0x97D1, 0x97D2, - /* U+6928 */ 0x97D3, 0x97D4, 0x97D5, 0x97D6, 0x97D7, 0xCDD6, 0x97D8, 0x97D9, - /* U+6930 */ 0xD2AC, 0x97DA, 0x97DB, 0x97DC, 0xE9B2, 0x97DD, 0x97DE, 0x97DF, - /* U+6938 */ 0x97E0, 0xE9A9, 0x97E1, 0x97E2, 0x97E3, 0xB4AA, 0x97E4, 0xB4BB, - /* U+6940 */ 0x97E5, 0x97E6, 0xE9AB, 0x97E7, 0x97E8, 0x97E9, 0x97EA, 0x97EB, - /* U+6948 */ 0x97EC, 0x97ED, 0x97EE, 0x97EF, 0x97F0, 0x97F1, 0x97F2, 0x97F3, - /* U+6950 */ 0x97F4, 0x97F5, 0x97F6, 0x97F7, 0xD0A8, 0x97F8, 0x97F9, 0xE9A5, - /* U+6958 */ 0x97FA, 0x97FB, 0xB3FE, 0x97FC, 0x97FD, 0xE9AC, 0xC0E3, 0x97FE, - /* U+6960 */ 0xE9AA, 0x9840, 0x9841, 0xE9B9, 0x9842, 0x9843, 0xE9B8, 0x9844, - /* U+6968 */ 0x9845, 0x9846, 0x9847, 0xE9AE, 0x9848, 0x9849, 0xE8FA, 0x984A, - /* U+6970 */ 0x984B, 0xE9A8, 0x984C, 0x984D, 0x984E, 0x984F, 0x9850, 0xBFAC, - /* U+6978 */ 0xE9B1, 0xE9BA, 0x9851, 0x9852, 0xC2A5, 0x9853, 0x9854, 0x9855, - /* U+6980 */ 0xE9AF, 0x9856, 0xB8C5, 0x9857, 0xE9AD, 0x9858, 0xD3DC, 0xE9B4, - /* U+6988 */ 0xE9B5, 0xE9B7, 0x9859, 0x985A, 0x985B, 0xE9C7, 0x985C, 0x985D, - /* U+6990 */ 0x985E, 0x985F, 0x9860, 0x9861, 0xC0C6, 0xE9C5, 0x9862, 0x9863, - /* U+6998 */ 0xE9B0, 0x9864, 0x9865, 0xE9BB, 0xB0F1, 0x9866, 0x9867, 0x9868, - /* U+69A0 */ 0x9869, 0x986A, 0x986B, 0x986C, 0x986D, 0x986E, 0x986F, 0xE9BC, - /* U+69A8 */ 0xD5A5, 0x9870, 0x9871, 0xE9BE, 0x9872, 0xE9BF, 0x9873, 0x9874, - /* U+69B0 */ 0x9875, 0xE9C1, 0x9876, 0x9877, 0xC1F1, 0x9878, 0x9879, 0xC8B6, - /* U+69B8 */ 0x987A, 0x987B, 0x987C, 0xE9BD, 0x987D, 0x987E, 0x9880, 0x9881, - /* U+69C0 */ 0x9882, 0xE9C2, 0x9883, 0x9884, 0x9885, 0x9886, 0x9887, 0x9888, - /* U+69C8 */ 0x9889, 0x988A, 0xE9C3, 0x988B, 0xE9B3, 0x988C, 0xE9B6, 0x988D, - /* U+69D0 */ 0xBBB1, 0x988E, 0x988F, 0x9890, 0xE9C0, 0x9891, 0x9892, 0x9893, - /* U+69D8 */ 0x9894, 0x9895, 0x9896, 0xBCF7, 0x9897, 0x9898, 0x9899, 0xE9C4, - /* U+69E0 */ 0xE9C6, 0x989A, 0x989B, 0x989C, 0x989D, 0x989E, 0x989F, 0x98A0, - /* U+69E8 */ 0x98A1, 0x98A2, 0x98A3, 0x98A4, 0x98A5, 0xE9CA, 0x98A6, 0x98A7, - /* U+69F0 */ 0x98A8, 0x98A9, 0xE9CE, 0x98AA, 0x98AB, 0x98AC, 0x98AD, 0x98AE, - /* U+69F8 */ 0x98AF, 0x98B0, 0x98B1, 0x98B2, 0x98B3, 0xB2DB, 0x98B4, 0xE9C8, - /* U+6A00 */ 0x98B5, 0x98B6, 0x98B7, 0x98B8, 0x98B9, 0x98BA, 0x98BB, 0x98BC, - /* U+6A08 */ 0x98BD, 0x98BE, 0xB7AE, 0x98BF, 0x98C0, 0x98C1, 0x98C2, 0x98C3, - /* U+6A10 */ 0x98C4, 0x98C5, 0x98C6, 0x98C7, 0x98C8, 0x98C9, 0x98CA, 0xE9CB, - /* U+6A18 */ 0xE9CC, 0x98CB, 0x98CC, 0x98CD, 0x98CE, 0x98CF, 0x98D0, 0xD5C1, - /* U+6A20 */ 0x98D1, 0xC4A3, 0x98D2, 0x98D3, 0x98D4, 0x98D5, 0x98D6, 0x98D7, - /* U+6A28 */ 0xE9D8, 0x98D8, 0xBAE1, 0x98D9, 0x98DA, 0x98DB, 0x98DC, 0xE9C9, - /* U+6A30 */ 0x98DD, 0xD3A3, 0x98DE, 0x98DF, 0x98E0, 0xE9D4, 0x98E1, 0x98E2, - /* U+6A38 */ 0x98E3, 0x98E4, 0x98E5, 0x98E6, 0x98E7, 0xE9D7, 0xE9D0, 0x98E8, - /* U+6A40 */ 0x98E9, 0x98EA, 0x98EB, 0x98EC, 0xE9CF, 0x98ED, 0x98EE, 0xC7C1, - /* U+6A48 */ 0x98EF, 0x98F0, 0x98F1, 0x98F2, 0x98F3, 0x98F4, 0x98F5, 0x98F6, - /* U+6A50 */ 0xE9D2, 0x98F7, 0x98F8, 0x98F9, 0x98FA, 0x98FB, 0x98FC, 0x98FD, - /* U+6A58 */ 0xE9D9, 0xB3C8, 0x98FE, 0xE9D3, 0x9940, 0x9941, 0x9942, 0x9943, - /* U+6A60 */ 0x9944, 0xCFF0, 0x9945, 0x9946, 0x9947, 0xE9CD, 0x9948, 0x9949, - /* U+6A68 */ 0x994A, 0x994B, 0x994C, 0x994D, 0x994E, 0x994F, 0x9950, 0x9951, - /* U+6A70 */ 0x9952, 0xB3F7, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957, 0x9958, - /* U+6A78 */ 0x9959, 0xE9D6, 0x995A, 0x995B, 0xE9DA, 0x995C, 0x995D, 0x995E, - /* U+6A80 */ 0xCCB4, 0x995F, 0x9960, 0x9961, 0xCFAD, 0x9962, 0x9963, 0x9964, - /* U+6A88 */ 0x9965, 0x9966, 0x9967, 0x9968, 0x9969, 0x996A, 0xE9D5, 0x996B, - /* U+6A90 */ 0xE9DC, 0xE9DB, 0x996C, 0x996D, 0x996E, 0x996F, 0x9970, 0xE9DE, - /* U+6A98 */ 0x9971, 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977, 0x9978, - /* U+6AA0 */ 0xE9D1, 0x9979, 0x997A, 0x997B, 0x997C, 0x997D, 0x997E, 0x9980, - /* U+6AA8 */ 0x9981, 0xE9DD, 0x9982, 0xE9DF, 0xC3CA, 0x9983, 0x9984, 0x9985, - /* U+6AB0 */ 0x9986, 0x9987, 0x9988, 0x9989, 0x998A, 0x998B, 0x998C, 0x998D, - /* U+6AB8 */ 0x998E, 0x998F, 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, - /* U+6AC0 */ 0x9996, 0x9997, 0x9998, 0x9999, 0x999A, 0x999B, 0x999C, 0x999D, - /* U+6AC8 */ 0x999E, 0x999F, 0x99A0, 0x99A1, 0x99A2, 0x99A3, 0x99A4, 0x99A5, - /* U+6AD0 */ 0x99A6, 0x99A7, 0x99A8, 0x99A9, 0x99AA, 0x99AB, 0x99AC, 0x99AD, - /* U+6AD8 */ 0x99AE, 0x99AF, 0x99B0, 0x99B1, 0x99B2, 0x99B3, 0x99B4, 0x99B5, - /* U+6AE0 */ 0x99B6, 0x99B7, 0x99B8, 0x99B9, 0x99BA, 0x99BB, 0x99BC, 0x99BD, - /* U+6AE8 */ 0x99BE, 0x99BF, 0x99C0, 0x99C1, 0x99C2, 0x99C3, 0x99C4, 0x99C5, - /* U+6AF0 */ 0x99C6, 0x99C7, 0x99C8, 0x99C9, 0x99CA, 0x99CB, 0x99CC, 0x99CD, - /* U+6AF8 */ 0x99CE, 0x99CF, 0x99D0, 0x99D1, 0x99D2, 0x99D3, 0x99D4, 0x99D5, - /* U+6B00 */ 0x99D6, 0x99D7, 0x99D8, 0x99D9, 0x99DA, 0x99DB, 0x99DC, 0x99DD, - /* U+6B08 */ 0x99DE, 0x99DF, 0x99E0, 0x99E1, 0x99E2, 0x99E3, 0x99E4, 0x99E5, - /* U+6B10 */ 0x99E6, 0x99E7, 0x99E8, 0x99E9, 0x99EA, 0x99EB, 0x99EC, 0x99ED, - /* U+6B18 */ 0x99EE, 0x99EF, 0x99F0, 0x99F1, 0x99F2, 0x99F3, 0x99F4, 0x99F5, - /* U+6B20 */ 0xC7B7, 0xB4CE, 0xBBB6, 0xD0C0, 0xECA3, 0x99F6, 0x99F7, 0xC5B7, - /* U+6B28 */ 0x99F8, 0x99F9, 0x99FA, 0x99FB, 0x99FC, 0x99FD, 0x99FE, 0x9A40, - /* U+6B30 */ 0x9A41, 0x9A42, 0xD3FB, 0x9A43, 0x9A44, 0x9A45, 0x9A46, 0xECA4, - /* U+6B38 */ 0x9A47, 0xECA5, 0xC6DB, 0x9A48, 0x9A49, 0x9A4A, 0xBFEE, 0x9A4B, - /* U+6B40 */ 0x9A4C, 0x9A4D, 0x9A4E, 0xECA6, 0x9A4F, 0x9A50, 0xECA7, 0xD0AA, - /* U+6B48 */ 0x9A51, 0xC7B8, 0x9A52, 0x9A53, 0xB8E8, 0x9A54, 0x9A55, 0x9A56, - /* U+6B50 */ 0x9A57, 0x9A58, 0x9A59, 0x9A5A, 0x9A5B, 0x9A5C, 0x9A5D, 0x9A5E, - /* U+6B58 */ 0x9A5F, 0xECA8, 0x9A60, 0x9A61, 0x9A62, 0x9A63, 0x9A64, 0x9A65, - /* U+6B60 */ 0x9A66, 0x9A67, 0xD6B9, 0xD5FD, 0xB4CB, 0xB2BD, 0xCEE4, 0xC6E7, - /* U+6B68 */ 0x9A68, 0x9A69, 0xCDE1, 0x9A6A, 0x9A6B, 0x9A6C, 0x9A6D, 0x9A6E, - /* U+6B70 */ 0x9A6F, 0x9A70, 0x9A71, 0x9A72, 0x9A73, 0x9A74, 0x9A75, 0x9A76, - /* U+6B78 */ 0x9A77, 0xB4F5, 0x9A78, 0xCBC0, 0xBCDF, 0x9A79, 0x9A7A, 0x9A7B, - /* U+6B80 */ 0x9A7C, 0xE9E2, 0xE9E3, 0xD1EA, 0xE9E5, 0x9A7D, 0xB4F9, 0xE9E4, - /* U+6B88 */ 0x9A7E, 0xD1B3, 0xCAE2, 0xB2D0, 0x9A80, 0xE9E8, 0x9A81, 0x9A82, - /* U+6B90 */ 0x9A83, 0x9A84, 0xE9E6, 0xE9E7, 0x9A85, 0x9A86, 0xD6B3, 0x9A87, - /* U+6B98 */ 0x9A88, 0x9A89, 0xE9E9, 0xE9EA, 0x9A8A, 0x9A8B, 0x9A8C, 0x9A8D, - /* U+6BA0 */ 0x9A8E, 0xE9EB, 0x9A8F, 0x9A90, 0x9A91, 0x9A92, 0x9A93, 0x9A94, - /* U+6BA8 */ 0x9A95, 0x9A96, 0xE9EC, 0x9A97, 0x9A98, 0x9A99, 0x9A9A, 0x9A9B, - /* U+6BB0 */ 0x9A9C, 0x9A9D, 0x9A9E, 0xECAF, 0xC5B9, 0xB6CE, 0x9A9F, 0xD2F3, - /* U+6BB8 */ 0x9AA0, 0x9AA1, 0x9AA2, 0x9AA3, 0x9AA4, 0x9AA5, 0x9AA6, 0xB5EE, - /* U+6BC0 */ 0x9AA7, 0xBBD9, 0xECB1, 0x9AA8, 0x9AA9, 0xD2E3, 0x9AAA, 0x9AAB, - /* U+6BC8 */ 0x9AAC, 0x9AAD, 0x9AAE, 0xCEE3, 0x9AAF, 0xC4B8, 0x9AB0, 0xC3BF, - /* U+6BD0 */ 0x9AB1, 0x9AB2, 0xB6BE, 0xD8B9, 0xB1C8, 0xB1CF, 0xB1D1, 0xC5FE, - /* U+6BD8 */ 0x9AB3, 0xB1D0, 0x9AB4, 0xC3AB, 0x9AB5, 0x9AB6, 0x9AB7, 0x9AB8, - /* U+6BE0 */ 0x9AB9, 0xD5B1, 0x9ABA, 0x9ABB, 0x9ABC, 0x9ABD, 0x9ABE, 0x9ABF, - /* U+6BE8 */ 0x9AC0, 0x9AC1, 0xEBA4, 0xBAC1, 0x9AC2, 0x9AC3, 0x9AC4, 0xCCBA, - /* U+6BF0 */ 0x9AC5, 0x9AC6, 0x9AC7, 0xEBA5, 0x9AC8, 0xEBA7, 0x9AC9, 0x9ACA, - /* U+6BF8 */ 0x9ACB, 0xEBA8, 0x9ACC, 0x9ACD, 0x9ACE, 0xEBA6, 0x9ACF, 0x9AD0, - /* U+6C00 */ 0x9AD1, 0x9AD2, 0x9AD3, 0x9AD4, 0x9AD5, 0xEBA9, 0xEBAB, 0xEBAA, - /* U+6C08 */ 0x9AD6, 0x9AD7, 0x9AD8, 0x9AD9, 0x9ADA, 0xEBAC, 0x9ADB, 0xCACF, - /* U+6C10 */ 0xD8B5, 0xC3F1, 0x9ADC, 0xC3A5, 0xC6F8, 0xEBAD, 0xC4CA, 0x9ADD, - /* U+6C18 */ 0xEBAE, 0xEBAF, 0xEBB0, 0xB7D5, 0x9ADE, 0x9ADF, 0x9AE0, 0xB7FA, - /* U+6C20 */ 0x9AE1, 0xEBB1, 0xC7E2, 0x9AE2, 0xEBB3, 0x9AE3, 0xBAA4, 0xD1F5, - /* U+6C28 */ 0xB0B1, 0xEBB2, 0xEBB4, 0x9AE4, 0x9AE5, 0x9AE6, 0xB5AA, 0xC2C8, - /* U+6C30 */ 0xC7E8, 0x9AE7, 0xEBB5, 0x9AE8, 0xCBAE, 0xE3DF, 0x9AE9, 0x9AEA, - /* U+6C38 */ 0xD3C0, 0x9AEB, 0x9AEC, 0x9AED, 0x9AEE, 0xD9DB, 0x9AEF, 0x9AF0, - /* U+6C40 */ 0xCDA1, 0xD6AD, 0xC7F3, 0x9AF1, 0x9AF2, 0x9AF3, 0xD9E0, 0xBBE3, - /* U+6C48 */ 0x9AF4, 0xBABA, 0xE3E2, 0x9AF5, 0x9AF6, 0x9AF7, 0x9AF8, 0x9AF9, - /* U+6C50 */ 0xCFAB, 0x9AFA, 0x9AFB, 0x9AFC, 0xE3E0, 0xC9C7, 0x9AFD, 0xBAB9, - /* U+6C58 */ 0x9AFE, 0x9B40, 0x9B41, 0xD1B4, 0xE3E1, 0xC8EA, 0xB9AF, 0xBDAD, - /* U+6C60 */ 0xB3D8, 0xCEDB, 0x9B42, 0x9B43, 0xCCC0, 0x9B44, 0x9B45, 0x9B46, - /* U+6C68 */ 0xE3E8, 0xE3E9, 0xCDF4, 0x9B47, 0x9B48, 0x9B49, 0x9B4A, 0x9B4B, - /* U+6C70 */ 0xCCAD, 0x9B4C, 0xBCB3, 0x9B4D, 0xE3EA, 0x9B4E, 0xE3EB, 0x9B4F, - /* U+6C78 */ 0x9B50, 0xD0DA, 0x9B51, 0x9B52, 0x9B53, 0xC6FB, 0xB7DA, 0x9B54, - /* U+6C80 */ 0x9B55, 0xC7DF, 0xD2CA, 0xCED6, 0x9B56, 0xE3E4, 0xE3EC, 0x9B57, - /* U+6C88 */ 0xC9F2, 0xB3C1, 0x9B58, 0x9B59, 0xE3E7, 0x9B5A, 0x9B5B, 0xC6E3, - /* U+6C90 */ 0xE3E5, 0x9B5C, 0x9B5D, 0xEDB3, 0xE3E6, 0x9B5E, 0x9B5F, 0x9B60, - /* U+6C98 */ 0x9B61, 0xC9B3, 0x9B62, 0xC5E6, 0x9B63, 0x9B64, 0x9B65, 0xB9B5, - /* U+6CA0 */ 0x9B66, 0xC3BB, 0x9B67, 0xE3E3, 0xC5BD, 0xC1A4, 0xC2D9, 0xB2D7, - /* U+6CA8 */ 0x9B68, 0xE3ED, 0xBBA6, 0xC4AD, 0x9B69, 0xE3F0, 0xBEDA, 0x9B6A, - /* U+6CB0 */ 0x9B6B, 0xE3FB, 0xE3F5, 0xBAD3, 0x9B6C, 0x9B6D, 0x9B6E, 0x9B6F, - /* U+6CB8 */ 0xB7D0, 0xD3CD, 0x9B70, 0xD6CE, 0xD5D3, 0xB9C1, 0xD5B4, 0xD1D8, - /* U+6CC0 */ 0x9B71, 0x9B72, 0x9B73, 0x9B74, 0xD0B9, 0xC7F6, 0x9B75, 0x9B76, - /* U+6CC8 */ 0x9B77, 0xC8AA, 0xB2B4, 0x9B78, 0xC3DA, 0x9B79, 0x9B7A, 0x9B7B, - /* U+6CD0 */ 0xE3EE, 0x9B7C, 0x9B7D, 0xE3FC, 0xE3EF, 0xB7A8, 0xE3F7, 0xE3F4, - /* U+6CD8 */ 0x9B7E, 0x9B80, 0x9B81, 0xB7BA, 0x9B82, 0x9B83, 0xC5A2, 0x9B84, - /* U+6CE0 */ 0xE3F6, 0xC5DD, 0xB2A8, 0xC6FC, 0x9B85, 0xC4E0, 0x9B86, 0x9B87, - /* U+6CE8 */ 0xD7A2, 0x9B88, 0xC0E1, 0xE3F9, 0x9B89, 0x9B8A, 0xE3FA, 0xE3FD, - /* U+6CF0 */ 0xCCA9, 0xE3F3, 0x9B8B, 0xD3BE, 0x9B8C, 0xB1C3, 0xEDB4, 0xE3F1, - /* U+6CF8 */ 0xE3F2, 0x9B8D, 0xE3F8, 0xD0BA, 0xC6C3, 0xD4F3, 0xE3FE, 0x9B8E, - /* U+6D00 */ 0x9B8F, 0xBDE0, 0x9B90, 0x9B91, 0xE4A7, 0x9B92, 0x9B93, 0xE4A6, - /* U+6D08 */ 0x9B94, 0x9B95, 0x9B96, 0xD1F3, 0xE4A3, 0x9B97, 0xE4A9, 0x9B98, - /* U+6D10 */ 0x9B99, 0x9B9A, 0xC8F7, 0x9B9B, 0x9B9C, 0x9B9D, 0x9B9E, 0xCFB4, - /* U+6D18 */ 0x9B9F, 0xE4A8, 0xE4AE, 0xC2E5, 0x9BA0, 0x9BA1, 0xB6B4, 0x9BA2, - /* U+6D20 */ 0x9BA3, 0x9BA4, 0x9BA5, 0x9BA6, 0x9BA7, 0xBDF2, 0x9BA8, 0xE4A2, - /* U+6D28 */ 0x9BA9, 0x9BAA, 0xBAE9, 0xE4AA, 0x9BAB, 0x9BAC, 0xE4AC, 0x9BAD, - /* U+6D30 */ 0x9BAE, 0xB6FD, 0xD6DE, 0xE4B2, 0x9BAF, 0xE4AD, 0x9BB0, 0x9BB1, - /* U+6D38 */ 0x9BB2, 0xE4A1, 0x9BB3, 0xBBEE, 0xCDDD, 0xC7A2, 0xC5C9, 0x9BB4, - /* U+6D40 */ 0x9BB5, 0xC1F7, 0x9BB6, 0xE4A4, 0x9BB7, 0xC7B3, 0xBDAC, 0xBDBD, - /* U+6D48 */ 0xE4A5, 0x9BB8, 0xD7C7, 0xB2E2, 0x9BB9, 0xE4AB, 0xBCC3, 0xE4AF, - /* U+6D50 */ 0x9BBA, 0xBBEB, 0xE4B0, 0xC5A8, 0xE4B1, 0x9BBB, 0x9BBC, 0x9BBD, - /* U+6D58 */ 0x9BBE, 0xD5E3, 0xBFA3, 0x9BBF, 0xE4BA, 0x9BC0, 0xE4B7, 0x9BC1, - /* U+6D60 */ 0xE4BB, 0x9BC2, 0x9BC3, 0xE4BD, 0x9BC4, 0x9BC5, 0xC6D6, 0x9BC6, - /* U+6D68 */ 0x9BC7, 0xBAC6, 0xC0CB, 0x9BC8, 0x9BC9, 0x9BCA, 0xB8A1, 0xE4B4, - /* U+6D70 */ 0x9BCB, 0x9BCC, 0x9BCD, 0x9BCE, 0xD4A1, 0x9BCF, 0x9BD0, 0xBAA3, - /* U+6D78 */ 0xBDFE, 0x9BD1, 0x9BD2, 0x9BD3, 0xE4BC, 0x9BD4, 0x9BD5, 0x9BD6, - /* U+6D80 */ 0x9BD7, 0x9BD8, 0xCDBF, 0x9BD9, 0x9BDA, 0xC4F9, 0x9BDB, 0x9BDC, - /* U+6D88 */ 0xCFFB, 0xC9E6, 0x9BDD, 0x9BDE, 0xD3BF, 0x9BDF, 0xCFD1, 0x9BE0, - /* U+6D90 */ 0x9BE1, 0xE4B3, 0x9BE2, 0xE4B8, 0xE4B9, 0xCCE9, 0x9BE3, 0x9BE4, - /* U+6D98 */ 0x9BE5, 0x9BE6, 0x9BE7, 0xCCCE, 0x9BE8, 0xC0D4, 0xE4B5, 0xC1B0, - /* U+6DA0 */ 0xE4B6, 0xCED0, 0x9BE9, 0xBBC1, 0xB5D3, 0x9BEA, 0xC8F3, 0xBDA7, - /* U+6DA8 */ 0xD5C7, 0xC9AC, 0xB8A2, 0xE4CA, 0x9BEB, 0x9BEC, 0xE4CC, 0xD1C4, - /* U+6DB0 */ 0x9BED, 0x9BEE, 0xD2BA, 0x9BEF, 0x9BF0, 0xBAAD, 0x9BF1, 0x9BF2, - /* U+6DB8 */ 0xBAD4, 0x9BF3, 0x9BF4, 0x9BF5, 0x9BF6, 0x9BF7, 0x9BF8, 0xE4C3, - /* U+6DC0 */ 0xB5ED, 0x9BF9, 0x9BFA, 0x9BFB, 0xD7CD, 0xE4C0, 0xCFFD, 0xE4BF, - /* U+6DC8 */ 0x9BFC, 0x9BFD, 0x9BFE, 0xC1DC, 0xCCCA, 0x9C40, 0x9C41, 0x9C42, - /* U+6DD0 */ 0x9C43, 0xCAE7, 0x9C44, 0x9C45, 0x9C46, 0x9C47, 0xC4D7, 0x9C48, - /* U+6DD8 */ 0xCCD4, 0xE4C8, 0x9C49, 0x9C4A, 0x9C4B, 0xE4C7, 0xE4C1, 0x9C4C, - /* U+6DE0 */ 0xE4C4, 0xB5AD, 0x9C4D, 0x9C4E, 0xD3D9, 0x9C4F, 0xE4C6, 0x9C50, - /* U+6DE8 */ 0x9C51, 0x9C52, 0x9C53, 0xD2F9, 0xB4E3, 0x9C54, 0xBBB4, 0x9C55, - /* U+6DF0 */ 0x9C56, 0xC9EE, 0x9C57, 0xB4BE, 0x9C58, 0x9C59, 0x9C5A, 0xBBEC, - /* U+6DF8 */ 0x9C5B, 0xD1CD, 0x9C5C, 0xCCED, 0xEDB5, 0x9C5D, 0x9C5E, 0x9C5F, - /* U+6E00 */ 0x9C60, 0x9C61, 0x9C62, 0x9C63, 0x9C64, 0xC7E5, 0x9C65, 0x9C66, - /* U+6E08 */ 0x9C67, 0x9C68, 0xD4A8, 0x9C69, 0xE4CB, 0xD7D5, 0xE4C2, 0x9C6A, - /* U+6E10 */ 0xBDA5, 0xE4C5, 0x9C6B, 0x9C6C, 0xD3E6, 0x9C6D, 0xE4C9, 0xC9F8, - /* U+6E18 */ 0x9C6E, 0x9C6F, 0xE4BE, 0x9C70, 0x9C71, 0xD3E5, 0x9C72, 0x9C73, - /* U+6E20 */ 0xC7FE, 0xB6C9, 0x9C74, 0xD4FC, 0xB2B3, 0xE4D7, 0x9C75, 0x9C76, - /* U+6E28 */ 0x9C77, 0xCEC2, 0x9C78, 0xE4CD, 0x9C79, 0xCEBC, 0x9C7A, 0xB8DB, - /* U+6E30 */ 0x9C7B, 0x9C7C, 0xE4D6, 0x9C7D, 0xBFCA, 0x9C7E, 0x9C80, 0x9C81, - /* U+6E38 */ 0xD3CE, 0x9C82, 0xC3EC, 0x9C83, 0x9C84, 0x9C85, 0x9C86, 0x9C87, - /* U+6E40 */ 0x9C88, 0x9C89, 0x9C8A, 0xC5C8, 0xE4D8, 0x9C8B, 0x9C8C, 0x9C8D, - /* U+6E48 */ 0x9C8E, 0x9C8F, 0x9C90, 0x9C91, 0x9C92, 0xCDC4, 0xE4CF, 0x9C93, - /* U+6E50 */ 0x9C94, 0x9C95, 0x9C96, 0xE4D4, 0xE4D5, 0x9C97, 0xBAFE, 0x9C98, - /* U+6E58 */ 0xCFE6, 0x9C99, 0x9C9A, 0xD5BF, 0x9C9B, 0x9C9C, 0x9C9D, 0xE4D2, - /* U+6E60 */ 0x9C9E, 0x9C9F, 0x9CA0, 0x9CA1, 0x9CA2, 0x9CA3, 0x9CA4, 0x9CA5, - /* U+6E68 */ 0x9CA6, 0x9CA7, 0x9CA8, 0xE4D0, 0x9CA9, 0x9CAA, 0xE4CE, 0x9CAB, - /* U+6E70 */ 0x9CAC, 0x9CAD, 0x9CAE, 0x9CAF, 0x9CB0, 0x9CB1, 0x9CB2, 0x9CB3, - /* U+6E78 */ 0x9CB4, 0x9CB5, 0x9CB6, 0x9CB7, 0x9CB8, 0x9CB9, 0xCDE5, 0xCAAA, - /* U+6E80 */ 0x9CBA, 0x9CBB, 0x9CBC, 0xC0A3, 0x9CBD, 0xBDA6, 0xE4D3, 0x9CBE, - /* U+6E88 */ 0x9CBF, 0xB8C8, 0x9CC0, 0x9CC1, 0x9CC2, 0x9CC3, 0x9CC4, 0xE4E7, - /* U+6E90 */ 0xD4B4, 0x9CC5, 0x9CC6, 0x9CC7, 0x9CC8, 0x9CC9, 0x9CCA, 0x9CCB, - /* U+6E98 */ 0xE4DB, 0x9CCC, 0x9CCD, 0x9CCE, 0xC1EF, 0x9CCF, 0x9CD0, 0xE4E9, - /* U+6EA0 */ 0x9CD1, 0x9CD2, 0xD2E7, 0x9CD3, 0x9CD4, 0xE4DF, 0x9CD5, 0xE4E0, - /* U+6EA8 */ 0x9CD6, 0x9CD7, 0xCFAA, 0x9CD8, 0x9CD9, 0x9CDA, 0x9CDB, 0xCBDD, - /* U+6EB0 */ 0x9CDC, 0xE4DA, 0xE4D1, 0x9CDD, 0xE4E5, 0x9CDE, 0xC8DC, 0xE4E3, - /* U+6EB8 */ 0x9CDF, 0x9CE0, 0xC4E7, 0xE4E2, 0x9CE1, 0xE4E1, 0x9CE2, 0x9CE3, - /* U+6EC0 */ 0x9CE4, 0xB3FC, 0xE4E8, 0x9CE5, 0x9CE6, 0x9CE7, 0x9CE8, 0xB5E1, - /* U+6EC8 */ 0x9CE9, 0x9CEA, 0x9CEB, 0xD7CC, 0x9CEC, 0x9CED, 0x9CEE, 0xE4E6, - /* U+6ED0 */ 0x9CEF, 0xBBAC, 0x9CF0, 0xD7D2, 0xCCCF, 0xEBF8, 0x9CF1, 0xE4E4, - /* U+6ED8 */ 0x9CF2, 0x9CF3, 0xB9F6, 0x9CF4, 0x9CF5, 0x9CF6, 0xD6CD, 0xE4D9, - /* U+6EE0 */ 0xE4DC, 0xC2FA, 0xE4DE, 0x9CF7, 0xC2CB, 0xC0C4, 0xC2D0, 0x9CF8, - /* U+6EE8 */ 0xB1F5, 0xCCB2, 0x9CF9, 0x9CFA, 0x9CFB, 0x9CFC, 0x9CFD, 0x9CFE, - /* U+6EF0 */ 0x9D40, 0x9D41, 0x9D42, 0x9D43, 0xB5CE, 0x9D44, 0x9D45, 0x9D46, - /* U+6EF8 */ 0x9D47, 0xE4EF, 0x9D48, 0x9D49, 0x9D4A, 0x9D4B, 0x9D4C, 0x9D4D, - /* U+6F00 */ 0x9D4E, 0x9D4F, 0xC6AF, 0x9D50, 0x9D51, 0x9D52, 0xC6E1, 0x9D53, - /* U+6F08 */ 0x9D54, 0xE4F5, 0x9D55, 0x9D56, 0x9D57, 0x9D58, 0x9D59, 0xC2A9, - /* U+6F10 */ 0x9D5A, 0x9D5B, 0x9D5C, 0xC0EC, 0xD1DD, 0xE4EE, 0x9D5D, 0x9D5E, - /* U+6F18 */ 0x9D5F, 0x9D60, 0x9D61, 0x9D62, 0x9D63, 0x9D64, 0x9D65, 0x9D66, - /* U+6F20 */ 0xC4AE, 0x9D67, 0x9D68, 0x9D69, 0xE4ED, 0x9D6A, 0x9D6B, 0x9D6C, - /* U+6F28 */ 0x9D6D, 0xE4F6, 0xE4F4, 0xC2FE, 0x9D6E, 0xE4DD, 0x9D6F, 0xE4F0, - /* U+6F30 */ 0x9D70, 0xCAFE, 0x9D71, 0xD5C4, 0x9D72, 0x9D73, 0xE4F1, 0x9D74, - /* U+6F38 */ 0x9D75, 0x9D76, 0x9D77, 0x9D78, 0x9D79, 0x9D7A, 0xD1FA, 0x9D7B, - /* U+6F40 */ 0x9D7C, 0x9D7D, 0x9D7E, 0x9D80, 0x9D81, 0x9D82, 0xE4EB, 0xE4EC, - /* U+6F48 */ 0x9D83, 0x9D84, 0x9D85, 0xE4F2, 0x9D86, 0xCEAB, 0x9D87, 0x9D88, - /* U+6F50 */ 0x9D89, 0x9D8A, 0x9D8B, 0x9D8C, 0x9D8D, 0x9D8E, 0x9D8F, 0x9D90, - /* U+6F58 */ 0xC5CB, 0x9D91, 0x9D92, 0x9D93, 0xC7B1, 0x9D94, 0xC2BA, 0x9D95, - /* U+6F60 */ 0x9D96, 0x9D97, 0xE4EA, 0x9D98, 0x9D99, 0x9D9A, 0xC1CA, 0x9D9B, - /* U+6F68 */ 0x9D9C, 0x9D9D, 0x9D9E, 0x9D9F, 0x9DA0, 0xCCB6, 0xB3B1, 0x9DA1, - /* U+6F70 */ 0x9DA2, 0x9DA3, 0xE4FB, 0x9DA4, 0xE4F3, 0x9DA5, 0x9DA6, 0x9DA7, - /* U+6F78 */ 0xE4FA, 0x9DA8, 0xE4FD, 0x9DA9, 0xE4FC, 0x9DAA, 0x9DAB, 0x9DAC, - /* U+6F80 */ 0x9DAD, 0x9DAE, 0x9DAF, 0x9DB0, 0xB3CE, 0x9DB1, 0x9DB2, 0x9DB3, - /* U+6F88 */ 0xB3BA, 0xE4F7, 0x9DB4, 0x9DB5, 0xE4F9, 0xE4F8, 0xC5EC, 0x9DB6, - /* U+6F90 */ 0x9DB7, 0x9DB8, 0x9DB9, 0x9DBA, 0x9DBB, 0x9DBC, 0x9DBD, 0x9DBE, - /* U+6F98 */ 0x9DBF, 0x9DC0, 0x9DC1, 0x9DC2, 0xC0BD, 0x9DC3, 0x9DC4, 0x9DC5, - /* U+6FA0 */ 0x9DC6, 0xD4E8, 0x9DC7, 0x9DC8, 0x9DC9, 0x9DCA, 0x9DCB, 0xE5A2, - /* U+6FA8 */ 0x9DCC, 0x9DCD, 0x9DCE, 0x9DCF, 0x9DD0, 0x9DD1, 0x9DD2, 0x9DD3, - /* U+6FB0 */ 0x9DD4, 0x9DD5, 0x9DD6, 0xB0C4, 0x9DD7, 0x9DD8, 0xE5A4, 0x9DD9, - /* U+6FB8 */ 0x9DDA, 0xE5A3, 0x9DDB, 0x9DDC, 0x9DDD, 0x9DDE, 0x9DDF, 0x9DE0, - /* U+6FC0 */ 0xBCA4, 0x9DE1, 0xE5A5, 0x9DE2, 0x9DE3, 0x9DE4, 0x9DE5, 0x9DE6, - /* U+6FC8 */ 0x9DE7, 0xE5A1, 0x9DE8, 0x9DE9, 0x9DEA, 0x9DEB, 0x9DEC, 0x9DED, - /* U+6FD0 */ 0x9DEE, 0xE4FE, 0xB1F4, 0x9DEF, 0x9DF0, 0x9DF1, 0x9DF2, 0x9DF3, - /* U+6FD8 */ 0x9DF4, 0x9DF5, 0x9DF6, 0x9DF7, 0x9DF8, 0x9DF9, 0xE5A8, 0x9DFA, - /* U+6FE0 */ 0xE5A9, 0xE5A6, 0x9DFB, 0x9DFC, 0x9DFD, 0x9DFE, 0x9E40, 0x9E41, - /* U+6FE8 */ 0x9E42, 0x9E43, 0x9E44, 0x9E45, 0x9E46, 0x9E47, 0xE5A7, 0xE5AA, - /* U+6FF0 */ 0x9E48, 0x9E49, 0x9E4A, 0x9E4B, 0x9E4C, 0x9E4D, 0x9E4E, 0x9E4F, - /* U+6FF8 */ 0x9E50, 0x9E51, 0x9E52, 0x9E53, 0x9E54, 0x9E55, 0x9E56, 0x9E57, - /* U+7000 */ 0x9E58, 0x9E59, 0x9E5A, 0x9E5B, 0x9E5C, 0x9E5D, 0x9E5E, 0x9E5F, - /* U+7008 */ 0x9E60, 0x9E61, 0x9E62, 0x9E63, 0x9E64, 0x9E65, 0x9E66, 0x9E67, - /* U+7010 */ 0x9E68, 0xC6D9, 0x9E69, 0x9E6A, 0x9E6B, 0x9E6C, 0x9E6D, 0x9E6E, - /* U+7018 */ 0x9E6F, 0x9E70, 0xE5AB, 0xE5AD, 0x9E71, 0x9E72, 0x9E73, 0x9E74, - /* U+7020 */ 0x9E75, 0x9E76, 0x9E77, 0xE5AC, 0x9E78, 0x9E79, 0x9E7A, 0x9E7B, - /* U+7028 */ 0x9E7C, 0x9E7D, 0x9E7E, 0x9E80, 0x9E81, 0x9E82, 0x9E83, 0x9E84, - /* U+7030 */ 0x9E85, 0x9E86, 0x9E87, 0x9E88, 0x9E89, 0xE5AF, 0x9E8A, 0x9E8B, - /* U+7038 */ 0x9E8C, 0xE5AE, 0x9E8D, 0x9E8E, 0x9E8F, 0x9E90, 0x9E91, 0x9E92, - /* U+7040 */ 0x9E93, 0x9E94, 0x9E95, 0x9E96, 0x9E97, 0x9E98, 0x9E99, 0x9E9A, - /* U+7048 */ 0x9E9B, 0x9E9C, 0x9E9D, 0x9E9E, 0xB9E0, 0x9E9F, 0x9EA0, 0xE5B0, - /* U+7050 */ 0x9EA1, 0x9EA2, 0x9EA3, 0x9EA4, 0x9EA5, 0x9EA6, 0x9EA7, 0x9EA8, - /* U+7058 */ 0x9EA9, 0x9EAA, 0x9EAB, 0x9EAC, 0x9EAD, 0x9EAE, 0xE5B1, 0x9EAF, - /* U+7060 */ 0x9EB0, 0x9EB1, 0x9EB2, 0x9EB3, 0x9EB4, 0x9EB5, 0x9EB6, 0x9EB7, - /* U+7068 */ 0x9EB8, 0x9EB9, 0x9EBA, 0xBBF0, 0xECE1, 0xC3F0, 0x9EBB, 0xB5C6, - /* U+7070 */ 0xBBD2, 0x9EBC, 0x9EBD, 0x9EBE, 0x9EBF, 0xC1E9, 0xD4EE, 0x9EC0, - /* U+7078 */ 0xBEC4, 0x9EC1, 0x9EC2, 0x9EC3, 0xD7C6, 0x9EC4, 0xD4D6, 0xB2D3, - /* U+7080 */ 0xECBE, 0x9EC5, 0x9EC6, 0x9EC7, 0x9EC8, 0xEAC1, 0x9EC9, 0x9ECA, - /* U+7088 */ 0x9ECB, 0xC2AF, 0xB4B6, 0x9ECC, 0x9ECD, 0x9ECE, 0xD1D7, 0x9ECF, - /* U+7090 */ 0x9ED0, 0x9ED1, 0xB3B4, 0x9ED2, 0xC8B2, 0xBFBB, 0xECC0, 0x9ED3, - /* U+7098 */ 0x9ED4, 0xD6CB, 0x9ED5, 0x9ED6, 0xECBF, 0xECC1, 0x9ED7, 0x9ED8, - /* U+70A0 */ 0x9ED9, 0x9EDA, 0x9EDB, 0x9EDC, 0x9EDD, 0x9EDE, 0x9EDF, 0x9EE0, - /* U+70A8 */ 0x9EE1, 0x9EE2, 0x9EE3, 0xECC5, 0xBEE6, 0xCCBF, 0xC5DA, 0xBEBC, - /* U+70B0 */ 0x9EE4, 0xECC6, 0x9EE5, 0xB1FE, 0x9EE6, 0x9EE7, 0x9EE8, 0xECC4, - /* U+70B8 */ 0xD5A8, 0xB5E3, 0x9EE9, 0xECC2, 0xC1B6, 0xB3E3, 0x9EEA, 0x9EEB, - /* U+70C0 */ 0xECC3, 0xCBB8, 0xC0C3, 0xCCFE, 0x9EEC, 0x9EED, 0x9EEE, 0x9EEF, - /* U+70C8 */ 0xC1D2, 0x9EF0, 0xECC8, 0x9EF1, 0x9EF2, 0x9EF3, 0x9EF4, 0x9EF5, - /* U+70D0 */ 0x9EF6, 0x9EF7, 0x9EF8, 0x9EF9, 0x9EFA, 0x9EFB, 0x9EFC, 0x9EFD, - /* U+70D8 */ 0xBAE6, 0xC0D3, 0x9EFE, 0xD6F2, 0x9F40, 0x9F41, 0x9F42, 0xD1CC, - /* U+70E0 */ 0x9F43, 0x9F44, 0x9F45, 0x9F46, 0xBFBE, 0x9F47, 0xB7B3, 0xC9D5, - /* U+70E8 */ 0xECC7, 0xBBE2, 0x9F48, 0xCCCC, 0xBDFD, 0xC8C8, 0x9F49, 0xCFA9, - /* U+70F0 */ 0x9F4A, 0x9F4B, 0x9F4C, 0x9F4D, 0x9F4E, 0x9F4F, 0x9F50, 0xCDE9, - /* U+70F8 */ 0x9F51, 0xC5EB, 0x9F52, 0x9F53, 0x9F54, 0xB7E9, 0x9F55, 0x9F56, - /* U+7100 */ 0x9F57, 0x9F58, 0x9F59, 0x9F5A, 0x9F5B, 0x9F5C, 0x9F5D, 0x9F5E, - /* U+7108 */ 0x9F5F, 0xD1C9, 0xBAB8, 0x9F60, 0x9F61, 0x9F62, 0x9F63, 0x9F64, - /* U+7110 */ 0xECC9, 0x9F65, 0x9F66, 0xECCA, 0x9F67, 0xBBC0, 0xECCB, 0x9F68, - /* U+7118 */ 0xECE2, 0xB1BA, 0xB7D9, 0x9F69, 0x9F6A, 0x9F6B, 0x9F6C, 0x9F6D, - /* U+7120 */ 0x9F6E, 0x9F6F, 0x9F70, 0x9F71, 0x9F72, 0x9F73, 0xBDB9, 0x9F74, - /* U+7128 */ 0x9F75, 0x9F76, 0x9F77, 0x9F78, 0x9F79, 0x9F7A, 0x9F7B, 0xECCC, - /* U+7130 */ 0xD1E6, 0xECCD, 0x9F7C, 0x9F7D, 0x9F7E, 0x9F80, 0xC8BB, 0x9F81, - /* U+7138 */ 0x9F82, 0x9F83, 0x9F84, 0x9F85, 0x9F86, 0x9F87, 0x9F88, 0x9F89, - /* U+7140 */ 0x9F8A, 0x9F8B, 0x9F8C, 0x9F8D, 0x9F8E, 0xECD1, 0x9F8F, 0x9F90, - /* U+7148 */ 0x9F91, 0x9F92, 0xECD3, 0x9F93, 0xBBCD, 0x9F94, 0xBCE5, 0x9F95, - /* U+7150 */ 0x9F96, 0x9F97, 0x9F98, 0x9F99, 0x9F9A, 0x9F9B, 0x9F9C, 0x9F9D, - /* U+7158 */ 0x9F9E, 0x9F9F, 0x9FA0, 0x9FA1, 0xECCF, 0x9FA2, 0xC9B7, 0x9FA3, - /* U+7160 */ 0x9FA4, 0x9FA5, 0x9FA6, 0x9FA7, 0xC3BA, 0x9FA8, 0xECE3, 0xD5D5, - /* U+7168 */ 0xECD0, 0x9FA9, 0x9FAA, 0x9FAB, 0x9FAC, 0x9FAD, 0xD6F3, 0x9FAE, - /* U+7170 */ 0x9FAF, 0x9FB0, 0xECD2, 0xECCE, 0x9FB1, 0x9FB2, 0x9FB3, 0x9FB4, - /* U+7178 */ 0xECD4, 0x9FB5, 0xECD5, 0x9FB6, 0x9FB7, 0xC9BF, 0x9FB8, 0x9FB9, - /* U+7180 */ 0x9FBA, 0x9FBB, 0x9FBC, 0x9FBD, 0xCFA8, 0x9FBE, 0x9FBF, 0x9FC0, - /* U+7188 */ 0x9FC1, 0x9FC2, 0xD0DC, 0x9FC3, 0x9FC4, 0x9FC5, 0x9FC6, 0xD1AC, - /* U+7190 */ 0x9FC7, 0x9FC8, 0x9FC9, 0x9FCA, 0xC8DB, 0x9FCB, 0x9FCC, 0x9FCD, - /* U+7198 */ 0xECD6, 0xCEF5, 0x9FCE, 0x9FCF, 0x9FD0, 0x9FD1, 0x9FD2, 0xCAEC, - /* U+71A0 */ 0xECDA, 0x9FD3, 0x9FD4, 0x9FD5, 0x9FD6, 0x9FD7, 0x9FD8, 0x9FD9, - /* U+71A8 */ 0xECD9, 0x9FDA, 0x9FDB, 0x9FDC, 0xB0BE, 0x9FDD, 0x9FDE, 0x9FDF, - /* U+71B0 */ 0x9FE0, 0x9FE1, 0x9FE2, 0xECD7, 0x9FE3, 0xECD8, 0x9FE4, 0x9FE5, - /* U+71B8 */ 0x9FE6, 0xECE4, 0x9FE7, 0x9FE8, 0x9FE9, 0x9FEA, 0x9FEB, 0x9FEC, - /* U+71C0 */ 0x9FED, 0x9FEE, 0x9FEF, 0xC8BC, 0x9FF0, 0x9FF1, 0x9FF2, 0x9FF3, - /* U+71C8 */ 0x9FF4, 0x9FF5, 0x9FF6, 0x9FF7, 0x9FF8, 0x9FF9, 0xC1C7, 0x9FFA, - /* U+71D0 */ 0x9FFB, 0x9FFC, 0x9FFD, 0x9FFE, 0xECDC, 0xD1E0, 0xA040, 0xA041, - /* U+71D8 */ 0xA042, 0xA043, 0xA044, 0xA045, 0xA046, 0xA047, 0xA048, 0xA049, - /* U+71E0 */ 0xECDB, 0xA04A, 0xA04B, 0xA04C, 0xA04D, 0xD4EF, 0xA04E, 0xECDD, - /* U+71E8 */ 0xA04F, 0xA050, 0xA051, 0xA052, 0xA053, 0xA054, 0xDBC6, 0xA055, - /* U+71F0 */ 0xA056, 0xA057, 0xA058, 0xA059, 0xA05A, 0xA05B, 0xA05C, 0xA05D, - /* U+71F8 */ 0xA05E, 0xECDE, 0xA05F, 0xA060, 0xA061, 0xA062, 0xA063, 0xA064, - /* U+7200 */ 0xA065, 0xA066, 0xA067, 0xA068, 0xA069, 0xA06A, 0xB1AC, 0xA06B, - /* U+7208 */ 0xA06C, 0xA06D, 0xA06E, 0xA06F, 0xA070, 0xA071, 0xA072, 0xA073, - /* U+7210 */ 0xA074, 0xA075, 0xA076, 0xA077, 0xA078, 0xA079, 0xA07A, 0xA07B, - /* U+7218 */ 0xA07C, 0xA07D, 0xA07E, 0xA080, 0xA081, 0xECDF, 0xA082, 0xA083, - /* U+7220 */ 0xA084, 0xA085, 0xA086, 0xA087, 0xA088, 0xA089, 0xA08A, 0xA08B, - /* U+7228 */ 0xECE0, 0xA08C, 0xD7A6, 0xA08D, 0xC5C0, 0xA08E, 0xA08F, 0xA090, - /* U+7230 */ 0xEBBC, 0xB0AE, 0xA091, 0xA092, 0xA093, 0xBEF4, 0xB8B8, 0xD2AF, - /* U+7238 */ 0xB0D6, 0xB5F9, 0xA094, 0xD8B3, 0xA095, 0xCBAC, 0xA096, 0xE3DD, - /* U+7240 */ 0xA097, 0xA098, 0xA099, 0xA09A, 0xA09B, 0xA09C, 0xA09D, 0xC6AC, - /* U+7248 */ 0xB0E6, 0xA09E, 0xA09F, 0xA0A0, 0xC5C6, 0xEBB9, 0xA0A1, 0xA0A2, - /* U+7250 */ 0xA0A3, 0xA0A4, 0xEBBA, 0xA0A5, 0xA0A6, 0xA0A7, 0xEBBB, 0xA0A8, - /* U+7258 */ 0xA0A9, 0xD1C0, 0xA0AA, 0xC5A3, 0xA0AB, 0xEAF2, 0xA0AC, 0xC4B2, - /* U+7260 */ 0xA0AD, 0xC4B5, 0xC0CE, 0xA0AE, 0xA0AF, 0xA0B0, 0xEAF3, 0xC4C1, - /* U+7268 */ 0xA0B1, 0xCEEF, 0xA0B2, 0xA0B3, 0xA0B4, 0xA0B5, 0xEAF0, 0xEAF4, - /* U+7270 */ 0xA0B6, 0xA0B7, 0xC9FC, 0xA0B8, 0xA0B9, 0xC7A3, 0xA0BA, 0xA0BB, - /* U+7278 */ 0xA0BC, 0xCCD8, 0xCEFE, 0xA0BD, 0xA0BE, 0xA0BF, 0xEAF5, 0xEAF6, - /* U+7280 */ 0xCFAC, 0xC0E7, 0xA0C0, 0xA0C1, 0xEAF7, 0xA0C2, 0xA0C3, 0xA0C4, - /* U+7288 */ 0xA0C5, 0xA0C6, 0xB6BF, 0xEAF8, 0xA0C7, 0xEAF9, 0xA0C8, 0xEAFA, - /* U+7290 */ 0xA0C9, 0xA0CA, 0xEAFB, 0xA0CB, 0xA0CC, 0xA0CD, 0xA0CE, 0xA0CF, - /* U+7298 */ 0xA0D0, 0xA0D1, 0xA0D2, 0xA0D3, 0xA0D4, 0xA0D5, 0xA0D6, 0xEAF1, - /* U+72A0 */ 0xA0D7, 0xA0D8, 0xA0D9, 0xA0DA, 0xA0DB, 0xA0DC, 0xA0DD, 0xA0DE, - /* U+72A8 */ 0xA0DF, 0xA0E0, 0xA0E1, 0xA0E2, 0xC8AE, 0xE1EB, 0xA0E3, 0xB7B8, - /* U+72B0 */ 0xE1EC, 0xA0E4, 0xA0E5, 0xA0E6, 0xE1ED, 0xA0E7, 0xD7B4, 0xE1EE, - /* U+72B8 */ 0xE1EF, 0xD3CC, 0xA0E8, 0xA0E9, 0xA0EA, 0xA0EB, 0xA0EC, 0xA0ED, - /* U+72C0 */ 0xA0EE, 0xE1F1, 0xBFF1, 0xE1F0, 0xB5D2, 0xA0EF, 0xA0F0, 0xA0F1, - /* U+72C8 */ 0xB1B7, 0xA0F2, 0xA0F3, 0xA0F4, 0xA0F5, 0xE1F3, 0xE1F2, 0xA0F6, - /* U+72D0 */ 0xBAFC, 0xA0F7, 0xE1F4, 0xA0F8, 0xA0F9, 0xA0FA, 0xA0FB, 0xB9B7, - /* U+72D8 */ 0xA0FC, 0xBED1, 0xA0FD, 0xA0FE, 0xAA40, 0xAA41, 0xC4FC, 0xAA42, - /* U+72E0 */ 0xBADD, 0xBDC6, 0xAA43, 0xAA44, 0xAA45, 0xAA46, 0xAA47, 0xAA48, - /* U+72E8 */ 0xE1F5, 0xE1F7, 0xAA49, 0xAA4A, 0xB6C0, 0xCFC1, 0xCAA8, 0xE1F6, - /* U+72F0 */ 0xD5F8, 0xD3FC, 0xE1F8, 0xE1FC, 0xE1F9, 0xAA4B, 0xAA4C, 0xE1FA, - /* U+72F8 */ 0xC0EA, 0xAA4D, 0xE1FE, 0xE2A1, 0xC0C7, 0xAA4E, 0xAA4F, 0xAA50, - /* U+7300 */ 0xAA51, 0xE1FB, 0xAA52, 0xE1FD, 0xAA53, 0xAA54, 0xAA55, 0xAA56, - /* U+7308 */ 0xAA57, 0xAA58, 0xE2A5, 0xAA59, 0xAA5A, 0xAA5B, 0xC1D4, 0xAA5C, - /* U+7310 */ 0xAA5D, 0xAA5E, 0xAA5F, 0xE2A3, 0xAA60, 0xE2A8, 0xB2FE, 0xE2A2, - /* U+7318 */ 0xAA61, 0xAA62, 0xAA63, 0xC3CD, 0xB2C2, 0xE2A7, 0xE2A6, 0xAA64, - /* U+7320 */ 0xAA65, 0xE2A4, 0xE2A9, 0xAA66, 0xAA67, 0xE2AB, 0xAA68, 0xAA69, - /* U+7328 */ 0xAA6A, 0xD0C9, 0xD6ED, 0xC3A8, 0xE2AC, 0xAA6B, 0xCFD7, 0xAA6C, - /* U+7330 */ 0xAA6D, 0xE2AE, 0xAA6E, 0xAA6F, 0xBAEF, 0xAA70, 0xAA71, 0xE9E0, - /* U+7338 */ 0xE2AD, 0xE2AA, 0xAA72, 0xAA73, 0xAA74, 0xAA75, 0xBBAB, 0xD4B3, - /* U+7340 */ 0xAA76, 0xAA77, 0xAA78, 0xAA79, 0xAA7A, 0xAA7B, 0xAA7C, 0xAA7D, - /* U+7348 */ 0xAA7E, 0xAA80, 0xAA81, 0xAA82, 0xAA83, 0xE2B0, 0xAA84, 0xAA85, - /* U+7350 */ 0xE2AF, 0xAA86, 0xE9E1, 0xAA87, 0xAA88, 0xAA89, 0xAA8A, 0xE2B1, - /* U+7358 */ 0xAA8B, 0xAA8C, 0xAA8D, 0xAA8E, 0xAA8F, 0xAA90, 0xAA91, 0xAA92, - /* U+7360 */ 0xE2B2, 0xAA93, 0xAA94, 0xAA95, 0xAA96, 0xAA97, 0xAA98, 0xAA99, - /* U+7368 */ 0xAA9A, 0xAA9B, 0xAA9C, 0xAA9D, 0xE2B3, 0xCCA1, 0xAA9E, 0xE2B4, - /* U+7370 */ 0xAA9F, 0xAAA0, 0xAB40, 0xAB41, 0xAB42, 0xAB43, 0xAB44, 0xAB45, - /* U+7378 */ 0xAB46, 0xAB47, 0xAB48, 0xAB49, 0xAB4A, 0xAB4B, 0xE2B5, 0xAB4C, - /* U+7380 */ 0xAB4D, 0xAB4E, 0xAB4F, 0xAB50, 0xD0FE, 0xAB51, 0xAB52, 0xC2CA, - /* U+7388 */ 0xAB53, 0xD3F1, 0xAB54, 0xCDF5, 0xAB55, 0xAB56, 0xE7E0, 0xAB57, - /* U+7390 */ 0xAB58, 0xE7E1, 0xAB59, 0xAB5A, 0xAB5B, 0xAB5C, 0xBEC1, 0xAB5D, - /* U+7398 */ 0xAB5E, 0xAB5F, 0xAB60, 0xC2EA, 0xAB61, 0xAB62, 0xAB63, 0xE7E4, - /* U+73A0 */ 0xAB64, 0xAB65, 0xE7E3, 0xAB66, 0xAB67, 0xAB68, 0xAB69, 0xAB6A, - /* U+73A8 */ 0xAB6B, 0xCDE6, 0xAB6C, 0xC3B5, 0xAB6D, 0xAB6E, 0xE7E2, 0xBBB7, - /* U+73B0 */ 0xCFD6, 0xAB6F, 0xC1E1, 0xE7E9, 0xAB70, 0xAB71, 0xAB72, 0xE7E8, - /* U+73B8 */ 0xAB73, 0xAB74, 0xE7F4, 0xB2A3, 0xAB75, 0xAB76, 0xAB77, 0xAB78, - /* U+73C0 */ 0xE7EA, 0xAB79, 0xE7E6, 0xAB7A, 0xAB7B, 0xAB7C, 0xAB7D, 0xAB7E, - /* U+73C8 */ 0xE7EC, 0xE7EB, 0xC9BA, 0xAB80, 0xAB81, 0xD5E4, 0xAB82, 0xE7E5, - /* U+73D0 */ 0xB7A9, 0xE7E7, 0xAB83, 0xAB84, 0xAB85, 0xAB86, 0xAB87, 0xAB88, - /* U+73D8 */ 0xAB89, 0xE7EE, 0xAB8A, 0xAB8B, 0xAB8C, 0xAB8D, 0xE7F3, 0xAB8E, - /* U+73E0 */ 0xD6E9, 0xAB8F, 0xAB90, 0xAB91, 0xAB92, 0xE7ED, 0xAB93, 0xE7F2, - /* U+73E8 */ 0xAB94, 0xE7F1, 0xAB95, 0xAB96, 0xAB97, 0xB0E0, 0xAB98, 0xAB99, - /* U+73F0 */ 0xAB9A, 0xAB9B, 0xE7F5, 0xAB9C, 0xAB9D, 0xAB9E, 0xAB9F, 0xABA0, - /* U+73F8 */ 0xAC40, 0xAC41, 0xAC42, 0xAC43, 0xAC44, 0xAC45, 0xAC46, 0xAC47, - /* U+7400 */ 0xAC48, 0xAC49, 0xAC4A, 0xC7F2, 0xAC4B, 0xC0C5, 0xC0ED, 0xAC4C, - /* U+7408 */ 0xAC4D, 0xC1F0, 0xE7F0, 0xAC4E, 0xAC4F, 0xAC50, 0xAC51, 0xE7F6, - /* U+7410 */ 0xCBF6, 0xAC52, 0xAC53, 0xAC54, 0xAC55, 0xAC56, 0xAC57, 0xAC58, - /* U+7418 */ 0xAC59, 0xAC5A, 0xE8A2, 0xE8A1, 0xAC5B, 0xAC5C, 0xAC5D, 0xAC5E, - /* U+7420 */ 0xAC5F, 0xAC60, 0xD7C1, 0xAC61, 0xAC62, 0xE7FA, 0xE7F9, 0xAC63, - /* U+7428 */ 0xE7FB, 0xAC64, 0xE7F7, 0xAC65, 0xE7FE, 0xAC66, 0xE7FD, 0xAC67, - /* U+7430 */ 0xE7FC, 0xAC68, 0xAC69, 0xC1D5, 0xC7D9, 0xC5FD, 0xC5C3, 0xAC6A, - /* U+7438 */ 0xAC6B, 0xAC6C, 0xAC6D, 0xAC6E, 0xC7ED, 0xAC6F, 0xAC70, 0xAC71, - /* U+7440 */ 0xAC72, 0xE8A3, 0xAC73, 0xAC74, 0xAC75, 0xAC76, 0xAC77, 0xAC78, - /* U+7448 */ 0xAC79, 0xAC7A, 0xAC7B, 0xAC7C, 0xAC7D, 0xAC7E, 0xAC80, 0xAC81, - /* U+7450 */ 0xAC82, 0xAC83, 0xAC84, 0xAC85, 0xAC86, 0xE8A6, 0xAC87, 0xE8A5, - /* U+7458 */ 0xAC88, 0xE8A7, 0xBAF7, 0xE7F8, 0xE8A4, 0xAC89, 0xC8F0, 0xC9AA, - /* U+7460 */ 0xAC8A, 0xAC8B, 0xAC8C, 0xAC8D, 0xAC8E, 0xAC8F, 0xAC90, 0xAC91, - /* U+7468 */ 0xAC92, 0xAC93, 0xAC94, 0xAC95, 0xAC96, 0xE8A9, 0xAC97, 0xAC98, - /* U+7470 */ 0xB9E5, 0xAC99, 0xAC9A, 0xAC9B, 0xAC9C, 0xAC9D, 0xD1FE, 0xE8A8, - /* U+7478 */ 0xAC9E, 0xAC9F, 0xACA0, 0xAD40, 0xAD41, 0xAD42, 0xE8AA, 0xAD43, - /* U+7480 */ 0xE8AD, 0xE8AE, 0xAD44, 0xC1A7, 0xAD45, 0xAD46, 0xAD47, 0xE8AF, - /* U+7488 */ 0xAD48, 0xAD49, 0xAD4A, 0xE8B0, 0xAD4B, 0xAD4C, 0xE8AC, 0xAD4D, - /* U+7490 */ 0xE8B4, 0xAD4E, 0xAD4F, 0xAD50, 0xAD51, 0xAD52, 0xAD53, 0xAD54, - /* U+7498 */ 0xAD55, 0xAD56, 0xAD57, 0xAD58, 0xE8AB, 0xAD59, 0xE8B1, 0xAD5A, - /* U+74A0 */ 0xAD5B, 0xAD5C, 0xAD5D, 0xAD5E, 0xAD5F, 0xAD60, 0xAD61, 0xE8B5, - /* U+74A8 */ 0xE8B2, 0xE8B3, 0xAD62, 0xAD63, 0xAD64, 0xAD65, 0xAD66, 0xAD67, - /* U+74B0 */ 0xAD68, 0xAD69, 0xAD6A, 0xAD6B, 0xAD6C, 0xAD6D, 0xAD6E, 0xAD6F, - /* U+74B8 */ 0xAD70, 0xAD71, 0xE8B7, 0xAD72, 0xAD73, 0xAD74, 0xAD75, 0xAD76, - /* U+74C0 */ 0xAD77, 0xAD78, 0xAD79, 0xAD7A, 0xAD7B, 0xAD7C, 0xAD7D, 0xAD7E, - /* U+74C8 */ 0xAD80, 0xAD81, 0xAD82, 0xAD83, 0xAD84, 0xAD85, 0xAD86, 0xAD87, - /* U+74D0 */ 0xAD88, 0xAD89, 0xE8B6, 0xAD8A, 0xAD8B, 0xAD8C, 0xAD8D, 0xAD8E, - /* U+74D8 */ 0xAD8F, 0xAD90, 0xAD91, 0xAD92, 0xB9CF, 0xAD93, 0xF0AC, 0xAD94, - /* U+74E0 */ 0xF0AD, 0xAD95, 0xC6B0, 0xB0EA, 0xC8BF, 0xAD96, 0xCDDF, 0xAD97, - /* U+74E8 */ 0xAD98, 0xAD99, 0xAD9A, 0xAD9B, 0xAD9C, 0xAD9D, 0xCECD, 0xEAB1, - /* U+74F0 */ 0xAD9E, 0xAD9F, 0xADA0, 0xAE40, 0xEAB2, 0xAE41, 0xC6BF, 0xB4C9, - /* U+74F8 */ 0xAE42, 0xAE43, 0xAE44, 0xAE45, 0xAE46, 0xAE47, 0xAE48, 0xEAB3, - /* U+7500 */ 0xAE49, 0xAE4A, 0xAE4B, 0xAE4C, 0xD5E7, 0xAE4D, 0xAE4E, 0xAE4F, - /* U+7508 */ 0xAE50, 0xAE51, 0xAE52, 0xAE53, 0xAE54, 0xDDF9, 0xAE55, 0xEAB4, - /* U+7510 */ 0xAE56, 0xEAB5, 0xAE57, 0xEAB6, 0xAE58, 0xAE59, 0xAE5A, 0xAE5B, - /* U+7518 */ 0xB8CA, 0xDFB0, 0xC9F5, 0xAE5C, 0xCCF0, 0xAE5D, 0xAE5E, 0xC9FA, - /* U+7520 */ 0xAE5F, 0xAE60, 0xAE61, 0xAE62, 0xAE63, 0xC9FB, 0xAE64, 0xAE65, - /* U+7528 */ 0xD3C3, 0xCBA6, 0xAE66, 0xB8A6, 0xF0AE, 0xB1C2, 0xAE67, 0xE5B8, - /* U+7530 */ 0xCCEF, 0xD3C9, 0xBCD7, 0xC9EA, 0xAE68, 0xB5E7, 0xAE69, 0xC4D0, - /* U+7538 */ 0xB5E9, 0xAE6A, 0xEEAE, 0xBBAD, 0xAE6B, 0xAE6C, 0xE7DE, 0xAE6D, - /* U+7540 */ 0xEEAF, 0xAE6E, 0xAE6F, 0xAE70, 0xAE71, 0xB3A9, 0xAE72, 0xAE73, - /* U+7548 */ 0xEEB2, 0xAE74, 0xAE75, 0xEEB1, 0xBDE7, 0xAE76, 0xEEB0, 0xCEB7, - /* U+7550 */ 0xAE77, 0xAE78, 0xAE79, 0xAE7A, 0xC5CF, 0xAE7B, 0xAE7C, 0xAE7D, - /* U+7558 */ 0xAE7E, 0xC1F4, 0xDBCE, 0xEEB3, 0xD0F3, 0xAE80, 0xAE81, 0xAE82, - /* U+7560 */ 0xAE83, 0xAE84, 0xAE85, 0xAE86, 0xAE87, 0xC2D4, 0xC6E8, 0xAE88, - /* U+7568 */ 0xAE89, 0xAE8A, 0xB7AC, 0xAE8B, 0xAE8C, 0xAE8D, 0xAE8E, 0xAE8F, - /* U+7570 */ 0xAE90, 0xAE91, 0xEEB4, 0xAE92, 0xB3EB, 0xAE93, 0xAE94, 0xAE95, - /* U+7578 */ 0xBBFB, 0xEEB5, 0xAE96, 0xAE97, 0xAE98, 0xAE99, 0xAE9A, 0xE7DC, - /* U+7580 */ 0xAE9B, 0xAE9C, 0xAE9D, 0xEEB6, 0xAE9E, 0xAE9F, 0xBDAE, 0xAEA0, - /* U+7588 */ 0xAF40, 0xAF41, 0xAF42, 0xF1E2, 0xAF43, 0xAF44, 0xAF45, 0xCAE8, - /* U+7590 */ 0xAF46, 0xD2C9, 0xF0DA, 0xAF47, 0xF0DB, 0xAF48, 0xF0DC, 0xC1C6, - /* U+7598 */ 0xAF49, 0xB8ED, 0xBECE, 0xAF4A, 0xAF4B, 0xF0DE, 0xAF4C, 0xC5B1, - /* U+75A0 */ 0xF0DD, 0xD1F1, 0xAF4D, 0xF0E0, 0xB0CC, 0xBDEA, 0xAF4E, 0xAF4F, - /* U+75A8 */ 0xAF50, 0xAF51, 0xAF52, 0xD2DF, 0xF0DF, 0xAF53, 0xB4AF, 0xB7E8, - /* U+75B0 */ 0xF0E6, 0xF0E5, 0xC6A3, 0xF0E1, 0xF0E2, 0xB4C3, 0xAF54, 0xAF55, - /* U+75B8 */ 0xF0E3, 0xD5EE, 0xAF56, 0xAF57, 0xCCDB, 0xBED2, 0xBCB2, 0xAF58, - /* U+75C0 */ 0xAF59, 0xAF5A, 0xF0E8, 0xF0E7, 0xF0E4, 0xB2A1, 0xAF5B, 0xD6A2, - /* U+75C8 */ 0xD3B8, 0xBEB7, 0xC8AC, 0xAF5C, 0xAF5D, 0xF0EA, 0xAF5E, 0xAF5F, - /* U+75D0 */ 0xAF60, 0xAF61, 0xD1F7, 0xAF62, 0xD6CC, 0xBADB, 0xF0E9, 0xAF63, - /* U+75D8 */ 0xB6BB, 0xAF64, 0xAF65, 0xCDB4, 0xAF66, 0xAF67, 0xC6A6, 0xAF68, - /* U+75E0 */ 0xAF69, 0xAF6A, 0xC1A1, 0xF0EB, 0xF0EE, 0xAF6B, 0xF0ED, 0xF0F0, - /* U+75E8 */ 0xF0EC, 0xAF6C, 0xBBBE, 0xF0EF, 0xAF6D, 0xAF6E, 0xAF6F, 0xAF70, - /* U+75F0 */ 0xCCB5, 0xF0F2, 0xAF71, 0xAF72, 0xB3D5, 0xAF73, 0xAF74, 0xAF75, - /* U+75F8 */ 0xAF76, 0xB1D4, 0xAF77, 0xAF78, 0xF0F3, 0xAF79, 0xAF7A, 0xF0F4, - /* U+7600 */ 0xF0F6, 0xB4E1, 0xAF7B, 0xF0F1, 0xAF7C, 0xF0F7, 0xAF7D, 0xAF7E, - /* U+7608 */ 0xAF80, 0xAF81, 0xF0FA, 0xAF82, 0xF0F8, 0xAF83, 0xAF84, 0xAF85, - /* U+7610 */ 0xF0F5, 0xAF86, 0xAF87, 0xAF88, 0xAF89, 0xF0FD, 0xAF8A, 0xF0F9, - /* U+7618 */ 0xF0FC, 0xF0FE, 0xAF8B, 0xF1A1, 0xAF8C, 0xAF8D, 0xAF8E, 0xCEC1, - /* U+7620 */ 0xF1A4, 0xAF8F, 0xF1A3, 0xAF90, 0xC1F6, 0xF0FB, 0xCADD, 0xAF91, - /* U+7628 */ 0xAF92, 0xB4F1, 0xB1F1, 0xCCB1, 0xAF93, 0xF1A6, 0xAF94, 0xAF95, - /* U+7630 */ 0xF1A7, 0xAF96, 0xAF97, 0xF1AC, 0xD5CE, 0xF1A9, 0xAF98, 0xAF99, - /* U+7638 */ 0xC8B3, 0xAF9A, 0xAF9B, 0xAF9C, 0xF1A2, 0xAF9D, 0xF1AB, 0xF1A8, - /* U+7640 */ 0xF1A5, 0xAF9E, 0xAF9F, 0xF1AA, 0xAFA0, 0xB040, 0xB041, 0xB042, - /* U+7648 */ 0xB043, 0xB044, 0xB045, 0xB046, 0xB0A9, 0xF1AD, 0xB047, 0xB048, - /* U+7650 */ 0xB049, 0xB04A, 0xB04B, 0xB04C, 0xF1AF, 0xB04D, 0xF1B1, 0xB04E, - /* U+7658 */ 0xB04F, 0xB050, 0xB051, 0xB052, 0xF1B0, 0xB053, 0xF1AE, 0xB054, - /* U+7660 */ 0xB055, 0xB056, 0xB057, 0xD1A2, 0xB058, 0xB059, 0xB05A, 0xB05B, - /* U+7668 */ 0xB05C, 0xB05D, 0xB05E, 0xF1B2, 0xB05F, 0xB060, 0xB061, 0xF1B3, - /* U+7670 */ 0xB062, 0xB063, 0xB064, 0xB065, 0xB066, 0xB067, 0xB068, 0xB069, - /* U+7678 */ 0xB9EF, 0xB06A, 0xB06B, 0xB5C7, 0xB06C, 0xB0D7, 0xB0D9, 0xB06D, - /* U+7680 */ 0xB06E, 0xB06F, 0xD4ED, 0xB070, 0xB5C4, 0xB071, 0xBDD4, 0xBBCA, - /* U+7688 */ 0xF0A7, 0xB072, 0xB073, 0xB8DE, 0xB074, 0xB075, 0xF0A8, 0xB076, - /* U+7690 */ 0xB077, 0xB0A8, 0xB078, 0xF0A9, 0xB079, 0xB07A, 0xCDEE, 0xB07B, - /* U+7698 */ 0xB07C, 0xF0AA, 0xB07D, 0xB07E, 0xB080, 0xB081, 0xB082, 0xB083, - /* U+76A0 */ 0xB084, 0xB085, 0xB086, 0xB087, 0xF0AB, 0xB088, 0xB089, 0xB08A, - /* U+76A8 */ 0xB08B, 0xB08C, 0xB08D, 0xB08E, 0xB08F, 0xB090, 0xC6A4, 0xB091, - /* U+76B0 */ 0xB092, 0xD6E5, 0xF1E4, 0xB093, 0xF1E5, 0xB094, 0xB095, 0xB096, - /* U+76B8 */ 0xB097, 0xB098, 0xB099, 0xB09A, 0xB09B, 0xB09C, 0xB09D, 0xC3F3, - /* U+76C0 */ 0xB09E, 0xB09F, 0xD3DB, 0xB0A0, 0xB140, 0xD6D1, 0xC5E8, 0xB141, - /* U+76C8 */ 0xD3AF, 0xB142, 0xD2E6, 0xB143, 0xB144, 0xEEC1, 0xB0BB, 0xD5B5, - /* U+76D0 */ 0xD1CE, 0xBCE0, 0xBAD0, 0xB145, 0xBFF8, 0xB146, 0xB8C7, 0xB5C1, - /* U+76D8 */ 0xC5CC, 0xB147, 0xB148, 0xCAA2, 0xB149, 0xB14A, 0xB14B, 0xC3CB, - /* U+76E0 */ 0xB14C, 0xB14D, 0xB14E, 0xB14F, 0xB150, 0xEEC2, 0xB151, 0xB152, - /* U+76E8 */ 0xB153, 0xB154, 0xB155, 0xB156, 0xB157, 0xB158, 0xC4BF, 0xB6A2, - /* U+76F0 */ 0xB159, 0xEDEC, 0xC3A4, 0xB15A, 0xD6B1, 0xB15B, 0xB15C, 0xB15D, - /* U+76F8 */ 0xCFE0, 0xEDEF, 0xB15E, 0xB15F, 0xC5CE, 0xB160, 0xB6DC, 0xB161, - /* U+7700 */ 0xB162, 0xCAA1, 0xB163, 0xB164, 0xEDED, 0xB165, 0xB166, 0xEDF0, - /* U+7708 */ 0xEDF1, 0xC3BC, 0xB167, 0xBFB4, 0xB168, 0xEDEE, 0xB169, 0xB16A, - /* U+7710 */ 0xB16B, 0xB16C, 0xB16D, 0xB16E, 0xB16F, 0xB170, 0xB171, 0xB172, - /* U+7718 */ 0xB173, 0xEDF4, 0xEDF2, 0xB174, 0xB175, 0xB176, 0xB177, 0xD5E6, - /* U+7720 */ 0xC3DF, 0xB178, 0xEDF3, 0xB179, 0xB17A, 0xB17B, 0xEDF6, 0xB17C, - /* U+7728 */ 0xD5A3, 0xD1A3, 0xB17D, 0xB17E, 0xB180, 0xEDF5, 0xB181, 0xC3D0, - /* U+7730 */ 0xB182, 0xB183, 0xB184, 0xB185, 0xB186, 0xEDF7, 0xBFF4, 0xBEEC, - /* U+7738 */ 0xEDF8, 0xB187, 0xCCF7, 0xB188, 0xD1DB, 0xB189, 0xB18A, 0xB18B, - /* U+7740 */ 0xD7C5, 0xD5F6, 0xB18C, 0xEDFC, 0xB18D, 0xB18E, 0xB18F, 0xEDFB, - /* U+7748 */ 0xB190, 0xB191, 0xB192, 0xB193, 0xB194, 0xB195, 0xB196, 0xB197, - /* U+7750 */ 0xEDF9, 0xEDFA, 0xB198, 0xB199, 0xB19A, 0xB19B, 0xB19C, 0xB19D, - /* U+7758 */ 0xB19E, 0xB19F, 0xEDFD, 0xBEA6, 0xB1A0, 0xB240, 0xB241, 0xB242, - /* U+7760 */ 0xB243, 0xCBAF, 0xEEA1, 0xB6BD, 0xB244, 0xEEA2, 0xC4C0, 0xB245, - /* U+7768 */ 0xEDFE, 0xB246, 0xB247, 0xBDDE, 0xB2C7, 0xB248, 0xB249, 0xB24A, - /* U+7770 */ 0xB24B, 0xB24C, 0xB24D, 0xB24E, 0xB24F, 0xB250, 0xB251, 0xB252, - /* U+7778 */ 0xB253, 0xB6C3, 0xB254, 0xB255, 0xB256, 0xEEA5, 0xD8BA, 0xEEA3, - /* U+7780 */ 0xEEA6, 0xB257, 0xB258, 0xB259, 0xC3E9, 0xB3F2, 0xB25A, 0xB25B, - /* U+7788 */ 0xB25C, 0xB25D, 0xB25E, 0xB25F, 0xEEA7, 0xEEA4, 0xCFB9, 0xB260, - /* U+7790 */ 0xB261, 0xEEA8, 0xC2F7, 0xB262, 0xB263, 0xB264, 0xB265, 0xB266, - /* U+7798 */ 0xB267, 0xB268, 0xB269, 0xB26A, 0xB26B, 0xB26C, 0xB26D, 0xEEA9, - /* U+77A0 */ 0xEEAA, 0xB26E, 0xDEAB, 0xB26F, 0xB270, 0xC6B3, 0xB271, 0xC7C6, - /* U+77A8 */ 0xB272, 0xD6F5, 0xB5C9, 0xB273, 0xCBB2, 0xB274, 0xB275, 0xB276, - /* U+77B0 */ 0xEEAB, 0xB277, 0xB278, 0xCDAB, 0xB279, 0xEEAC, 0xB27A, 0xB27B, - /* U+77B8 */ 0xB27C, 0xB27D, 0xB27E, 0xD5B0, 0xB280, 0xEEAD, 0xB281, 0xF6C4, - /* U+77C0 */ 0xB282, 0xB283, 0xB284, 0xB285, 0xB286, 0xB287, 0xB288, 0xB289, - /* U+77C8 */ 0xB28A, 0xB28B, 0xB28C, 0xB28D, 0xB28E, 0xDBC7, 0xB28F, 0xB290, - /* U+77D0 */ 0xB291, 0xB292, 0xB293, 0xB294, 0xB295, 0xB296, 0xB297, 0xB4A3, - /* U+77D8 */ 0xB298, 0xB299, 0xB29A, 0xC3AC, 0xF1E6, 0xB29B, 0xB29C, 0xB29D, - /* U+77E0 */ 0xB29E, 0xB29F, 0xCAB8, 0xD2D3, 0xB2A0, 0xD6AA, 0xB340, 0xEFF2, - /* U+77E8 */ 0xB341, 0xBED8, 0xB342, 0xBDC3, 0xEFF3, 0xB6CC, 0xB0AB, 0xB343, - /* U+77F0 */ 0xB344, 0xB345, 0xB346, 0xCAAF, 0xB347, 0xB348, 0xEDB6, 0xB349, - /* U+77F8 */ 0xEDB7, 0xB34A, 0xB34B, 0xB34C, 0xB34D, 0xCEF9, 0xB7AF, 0xBFF3, - /* U+7800 */ 0xEDB8, 0xC2EB, 0xC9B0, 0xB34E, 0xB34F, 0xB350, 0xB351, 0xB352, - /* U+7808 */ 0xB353, 0xEDB9, 0xB354, 0xB355, 0xC6F6, 0xBFB3, 0xB356, 0xB357, - /* U+7810 */ 0xB358, 0xEDBC, 0xC5F8, 0xB359, 0xD1D0, 0xB35A, 0xD7A9, 0xEDBA, - /* U+7818 */ 0xEDBB, 0xB35B, 0xD1E2, 0xB35C, 0xEDBF, 0xEDC0, 0xB35D, 0xEDC4, - /* U+7820 */ 0xB35E, 0xB35F, 0xB360, 0xEDC8, 0xB361, 0xEDC6, 0xEDCE, 0xD5E8, - /* U+7828 */ 0xB362, 0xEDC9, 0xB363, 0xB364, 0xEDC7, 0xEDBE, 0xB365, 0xB366, - /* U+7830 */ 0xC5E9, 0xB367, 0xB368, 0xB369, 0xC6C6, 0xB36A, 0xB36B, 0xC9E9, - /* U+7838 */ 0xD4D2, 0xEDC1, 0xEDC2, 0xEDC3, 0xEDC5, 0xB36C, 0xC0F9, 0xB36D, - /* U+7840 */ 0xB4A1, 0xB36E, 0xB36F, 0xB370, 0xB371, 0xB9E8, 0xB372, 0xEDD0, - /* U+7848 */ 0xB373, 0xB374, 0xB375, 0xB376, 0xEDD1, 0xB377, 0xEDCA, 0xB378, - /* U+7850 */ 0xEDCF, 0xB379, 0xCEF8, 0xB37A, 0xB37B, 0xCBB6, 0xEDCC, 0xEDCD, - /* U+7858 */ 0xB37C, 0xB37D, 0xB37E, 0xB380, 0xB381, 0xCFF5, 0xB382, 0xB383, - /* U+7860 */ 0xB384, 0xB385, 0xB386, 0xB387, 0xB388, 0xB389, 0xB38A, 0xB38B, - /* U+7868 */ 0xB38C, 0xB38D, 0xEDD2, 0xC1F2, 0xD3B2, 0xEDCB, 0xC8B7, 0xB38E, - /* U+7870 */ 0xB38F, 0xB390, 0xB391, 0xB392, 0xB393, 0xB394, 0xB395, 0xBCEF, - /* U+7878 */ 0xB396, 0xB397, 0xB398, 0xB399, 0xC5F0, 0xB39A, 0xB39B, 0xB39C, - /* U+7880 */ 0xB39D, 0xB39E, 0xB39F, 0xB3A0, 0xB440, 0xB441, 0xB442, 0xEDD6, - /* U+7888 */ 0xB443, 0xB5EF, 0xB444, 0xB445, 0xC2B5, 0xB0AD, 0xCBE9, 0xB446, - /* U+7890 */ 0xB447, 0xB1AE, 0xB448, 0xEDD4, 0xB449, 0xB44A, 0xB44B, 0xCDEB, - /* U+7898 */ 0xB5E2, 0xB44C, 0xEDD5, 0xEDD3, 0xEDD7, 0xB44D, 0xB44E, 0xB5FA, - /* U+78A0 */ 0xB44F, 0xEDD8, 0xB450, 0xEDD9, 0xB451, 0xEDDC, 0xB452, 0xB1CC, - /* U+78A8 */ 0xB453, 0xB454, 0xB455, 0xB456, 0xB457, 0xB458, 0xB459, 0xB45A, - /* U+78B0 */ 0xC5F6, 0xBCEE, 0xEDDA, 0xCCBC, 0xB2EA, 0xB45B, 0xB45C, 0xB45D, - /* U+78B8 */ 0xB45E, 0xEDDB, 0xB45F, 0xB460, 0xB461, 0xB462, 0xC4EB, 0xB463, - /* U+78C0 */ 0xB464, 0xB4C5, 0xB465, 0xB466, 0xB467, 0xB0F5, 0xB468, 0xB469, - /* U+78C8 */ 0xB46A, 0xEDDF, 0xC0DA, 0xB4E8, 0xB46B, 0xB46C, 0xB46D, 0xB46E, - /* U+78D0 */ 0xC5CD, 0xB46F, 0xB470, 0xB471, 0xEDDD, 0xBFC4, 0xB472, 0xB473, - /* U+78D8 */ 0xB474, 0xEDDE, 0xB475, 0xB476, 0xB477, 0xB478, 0xB479, 0xB47A, - /* U+78E0 */ 0xB47B, 0xB47C, 0xB47D, 0xB47E, 0xB480, 0xB481, 0xB482, 0xB483, - /* U+78E8 */ 0xC4A5, 0xB484, 0xB485, 0xB486, 0xEDE0, 0xB487, 0xB488, 0xB489, - /* U+78F0 */ 0xB48A, 0xB48B, 0xEDE1, 0xB48C, 0xEDE3, 0xB48D, 0xB48E, 0xC1D7, - /* U+78F8 */ 0xB48F, 0xB490, 0xBBC7, 0xB491, 0xB492, 0xB493, 0xB494, 0xB495, - /* U+7900 */ 0xB496, 0xBDB8, 0xB497, 0xB498, 0xB499, 0xEDE2, 0xB49A, 0xB49B, - /* U+7908 */ 0xB49C, 0xB49D, 0xB49E, 0xB49F, 0xB4A0, 0xB540, 0xB541, 0xB542, - /* U+7910 */ 0xB543, 0xB544, 0xB545, 0xEDE4, 0xB546, 0xB547, 0xB548, 0xB549, - /* U+7918 */ 0xB54A, 0xB54B, 0xB54C, 0xB54D, 0xB54E, 0xB54F, 0xEDE6, 0xB550, - /* U+7920 */ 0xB551, 0xB552, 0xB553, 0xB554, 0xEDE5, 0xB555, 0xB556, 0xB557, - /* U+7928 */ 0xB558, 0xB559, 0xB55A, 0xB55B, 0xB55C, 0xB55D, 0xB55E, 0xB55F, - /* U+7930 */ 0xB560, 0xB561, 0xB562, 0xB563, 0xEDE7, 0xB564, 0xB565, 0xB566, - /* U+7938 */ 0xB567, 0xB568, 0xCABE, 0xECEA, 0xC0F1, 0xB569, 0xC9E7, 0xB56A, - /* U+7940 */ 0xECEB, 0xC6EE, 0xB56B, 0xB56C, 0xB56D, 0xB56E, 0xECEC, 0xB56F, - /* U+7948 */ 0xC6ED, 0xECED, 0xB570, 0xB571, 0xB572, 0xB573, 0xB574, 0xB575, - /* U+7950 */ 0xB576, 0xB577, 0xB578, 0xECF0, 0xB579, 0xB57A, 0xD7E6, 0xECF3, - /* U+7958 */ 0xB57B, 0xB57C, 0xECF1, 0xECEE, 0xECEF, 0xD7A3, 0xC9F1, 0xCBEE, - /* U+7960 */ 0xECF4, 0xB57D, 0xECF2, 0xB57E, 0xB580, 0xCFE9, 0xB581, 0xECF6, - /* U+7968 */ 0xC6B1, 0xB582, 0xB583, 0xB584, 0xB585, 0xBCC0, 0xB586, 0xECF5, - /* U+7970 */ 0xB587, 0xB588, 0xB589, 0xB58A, 0xB58B, 0xB58C, 0xB58D, 0xB5BB, - /* U+7978 */ 0xBBF6, 0xB58E, 0xECF7, 0xB58F, 0xB590, 0xB591, 0xB592, 0xB593, - /* U+7980 */ 0xD9F7, 0xBDFB, 0xB594, 0xB595, 0xC2BB, 0xECF8, 0xB596, 0xB597, - /* U+7988 */ 0xB598, 0xB599, 0xECF9, 0xB59A, 0xB59B, 0xB59C, 0xB59D, 0xB8A3, - /* U+7990 */ 0xB59E, 0xB59F, 0xB5A0, 0xB640, 0xB641, 0xB642, 0xB643, 0xB644, - /* U+7998 */ 0xB645, 0xB646, 0xECFA, 0xB647, 0xB648, 0xB649, 0xB64A, 0xB64B, - /* U+79A0 */ 0xB64C, 0xB64D, 0xB64E, 0xB64F, 0xB650, 0xB651, 0xB652, 0xECFB, - /* U+79A8 */ 0xB653, 0xB654, 0xB655, 0xB656, 0xB657, 0xB658, 0xB659, 0xB65A, - /* U+79B0 */ 0xB65B, 0xB65C, 0xB65D, 0xECFC, 0xB65E, 0xB65F, 0xB660, 0xB661, - /* U+79B8 */ 0xB662, 0xD3ED, 0xD8AE, 0xC0EB, 0xB663, 0xC7DD, 0xBACC, 0xB664, - /* U+79C0 */ 0xD0E3, 0xCBBD, 0xB665, 0xCDBA, 0xB666, 0xB667, 0xB8D1, 0xB668, - /* U+79C8 */ 0xB669, 0xB1FC, 0xB66A, 0xC7EF, 0xB66B, 0xD6D6, 0xB66C, 0xB66D, - /* U+79D0 */ 0xB66E, 0xBFC6, 0xC3EB, 0xB66F, 0xB670, 0xEFF5, 0xB671, 0xB672, - /* U+79D8 */ 0xC3D8, 0xB673, 0xB674, 0xB675, 0xB676, 0xB677, 0xB678, 0xD7E2, - /* U+79E0 */ 0xB679, 0xB67A, 0xB67B, 0xEFF7, 0xB3D3, 0xB67C, 0xC7D8, 0xD1ED, - /* U+79E8 */ 0xB67D, 0xD6C8, 0xB67E, 0xEFF8, 0xB680, 0xEFF6, 0xB681, 0xBBFD, - /* U+79F0 */ 0xB3C6, 0xB682, 0xB683, 0xB684, 0xB685, 0xB686, 0xB687, 0xB688, - /* U+79F8 */ 0xBDD5, 0xB689, 0xB68A, 0xD2C6, 0xB68B, 0xBBE0, 0xB68C, 0xB68D, - /* U+7A00 */ 0xCFA1, 0xB68E, 0xEFFC, 0xEFFB, 0xB68F, 0xB690, 0xEFF9, 0xB691, - /* U+7A08 */ 0xB692, 0xB693, 0xB694, 0xB3CC, 0xB695, 0xC9D4, 0xCBB0, 0xB696, - /* U+7A10 */ 0xB697, 0xB698, 0xB699, 0xB69A, 0xEFFE, 0xB69B, 0xB69C, 0xB0DE, - /* U+7A18 */ 0xB69D, 0xB69E, 0xD6C9, 0xB69F, 0xB6A0, 0xB740, 0xEFFD, 0xB741, - /* U+7A20 */ 0xB3ED, 0xB742, 0xB743, 0xF6D5, 0xB744, 0xB745, 0xB746, 0xB747, - /* U+7A28 */ 0xB748, 0xB749, 0xB74A, 0xB74B, 0xB74C, 0xB74D, 0xB74E, 0xB74F, - /* U+7A30 */ 0xB750, 0xB751, 0xB752, 0xCEC8, 0xB753, 0xB754, 0xB755, 0xF0A2, - /* U+7A38 */ 0xB756, 0xF0A1, 0xB757, 0xB5BE, 0xBCDA, 0xBBFC, 0xB758, 0xB8E5, - /* U+7A40 */ 0xB759, 0xB75A, 0xB75B, 0xB75C, 0xB75D, 0xB75E, 0xC4C2, 0xB75F, - /* U+7A48 */ 0xB760, 0xB761, 0xB762, 0xB763, 0xB764, 0xB765, 0xB766, 0xB767, - /* U+7A50 */ 0xB768, 0xF0A3, 0xB769, 0xB76A, 0xB76B, 0xB76C, 0xB76D, 0xCBEB, - /* U+7A58 */ 0xB76E, 0xB76F, 0xB770, 0xB771, 0xB772, 0xB773, 0xB774, 0xB775, - /* U+7A60 */ 0xB776, 0xB777, 0xB778, 0xB779, 0xB77A, 0xB77B, 0xB77C, 0xB77D, - /* U+7A68 */ 0xB77E, 0xB780, 0xB781, 0xB782, 0xB783, 0xB784, 0xB785, 0xB786, - /* U+7A70 */ 0xF0A6, 0xB787, 0xB788, 0xB789, 0xD1A8, 0xB78A, 0xBEBF, 0xC7EE, - /* U+7A78 */ 0xF1B6, 0xF1B7, 0xBFD5, 0xB78B, 0xB78C, 0xB78D, 0xB78E, 0xB4A9, - /* U+7A80 */ 0xF1B8, 0xCDBB, 0xB78F, 0xC7D4, 0xD5AD, 0xB790, 0xF1B9, 0xB791, - /* U+7A88 */ 0xF1BA, 0xB792, 0xB793, 0xB794, 0xB795, 0xC7CF, 0xB796, 0xB797, - /* U+7A90 */ 0xB798, 0xD2A4, 0xD6CF, 0xB799, 0xB79A, 0xF1BB, 0xBDD1, 0xB4B0, - /* U+7A98 */ 0xBEBD, 0xB79B, 0xB79C, 0xB79D, 0xB4DC, 0xCED1, 0xB79E, 0xBFDF, - /* U+7AA0 */ 0xF1BD, 0xB79F, 0xB7A0, 0xB840, 0xB841, 0xBFFA, 0xF1BC, 0xB842, - /* U+7AA8 */ 0xF1BF, 0xB843, 0xB844, 0xB845, 0xF1BE, 0xF1C0, 0xB846, 0xB847, - /* U+7AB0 */ 0xB848, 0xB849, 0xB84A, 0xF1C1, 0xB84B, 0xB84C, 0xB84D, 0xB84E, - /* U+7AB8 */ 0xB84F, 0xB850, 0xB851, 0xB852, 0xB853, 0xB854, 0xB855, 0xC1FE, - /* U+7AC0 */ 0xB856, 0xB857, 0xB858, 0xB859, 0xB85A, 0xB85B, 0xB85C, 0xB85D, - /* U+7AC8 */ 0xB85E, 0xB85F, 0xB860, 0xC1A2, 0xB861, 0xB862, 0xB863, 0xB864, - /* U+7AD0 */ 0xB865, 0xB866, 0xB867, 0xB868, 0xB869, 0xB86A, 0xCAFA, 0xB86B, - /* U+7AD8 */ 0xB86C, 0xD5BE, 0xB86D, 0xB86E, 0xB86F, 0xB870, 0xBEBA, 0xBEB9, - /* U+7AE0 */ 0xD5C2, 0xB871, 0xB872, 0xBFA2, 0xB873, 0xCDAF, 0xF1B5, 0xB874, - /* U+7AE8 */ 0xB875, 0xB876, 0xB877, 0xB878, 0xB879, 0xBDDF, 0xB87A, 0xB6CB, - /* U+7AF0 */ 0xB87B, 0xB87C, 0xB87D, 0xB87E, 0xB880, 0xB881, 0xB882, 0xB883, - /* U+7AF8 */ 0xB884, 0xD6F1, 0xF3C3, 0xB885, 0xB886, 0xF3C4, 0xB887, 0xB8CD, - /* U+7B00 */ 0xB888, 0xB889, 0xB88A, 0xF3C6, 0xF3C7, 0xB88B, 0xB0CA, 0xB88C, - /* U+7B08 */ 0xF3C5, 0xB88D, 0xF3C9, 0xCBF1, 0xB88E, 0xB88F, 0xB890, 0xF3CB, - /* U+7B10 */ 0xB891, 0xD0A6, 0xB892, 0xB893, 0xB1CA, 0xF3C8, 0xB894, 0xB895, - /* U+7B18 */ 0xB896, 0xF3CF, 0xB897, 0xB5D1, 0xB898, 0xB899, 0xF3D7, 0xB89A, - /* U+7B20 */ 0xF3D2, 0xB89B, 0xB89C, 0xB89D, 0xF3D4, 0xF3D3, 0xB7FB, 0xB89E, - /* U+7B28 */ 0xB1BF, 0xB89F, 0xF3CE, 0xF3CA, 0xB5DA, 0xB8A0, 0xF3D0, 0xB940, - /* U+7B30 */ 0xB941, 0xF3D1, 0xB942, 0xF3D5, 0xB943, 0xB944, 0xB945, 0xB946, - /* U+7B38 */ 0xF3CD, 0xB947, 0xBCE3, 0xB948, 0xC1FD, 0xB949, 0xF3D6, 0xB94A, - /* U+7B40 */ 0xB94B, 0xB94C, 0xB94D, 0xB94E, 0xB94F, 0xF3DA, 0xB950, 0xF3CC, - /* U+7B48 */ 0xB951, 0xB5C8, 0xB952, 0xBDEE, 0xF3DC, 0xB953, 0xB954, 0xB7A4, - /* U+7B50 */ 0xBFF0, 0xD6FE, 0xCDB2, 0xB955, 0xB4F0, 0xB956, 0xB2DF, 0xB957, - /* U+7B58 */ 0xF3D8, 0xB958, 0xF3D9, 0xC9B8, 0xB959, 0xF3DD, 0xB95A, 0xB95B, - /* U+7B60 */ 0xF3DE, 0xB95C, 0xF3E1, 0xB95D, 0xB95E, 0xB95F, 0xB960, 0xB961, - /* U+7B68 */ 0xB962, 0xB963, 0xB964, 0xB965, 0xB966, 0xB967, 0xF3DF, 0xB968, - /* U+7B70 */ 0xB969, 0xF3E3, 0xF3E2, 0xB96A, 0xB96B, 0xF3DB, 0xB96C, 0xBFEA, - /* U+7B78 */ 0xB96D, 0xB3EF, 0xB96E, 0xF3E0, 0xB96F, 0xB970, 0xC7A9, 0xB971, - /* U+7B80 */ 0xBCF2, 0xB972, 0xB973, 0xB974, 0xB975, 0xF3EB, 0xB976, 0xB977, - /* U+7B88 */ 0xB978, 0xB979, 0xB97A, 0xB97B, 0xB97C, 0xB9BF, 0xB97D, 0xB97E, - /* U+7B90 */ 0xF3E4, 0xB980, 0xB981, 0xB982, 0xB2AD, 0xBBFE, 0xB983, 0xCBE3, - /* U+7B98 */ 0xB984, 0xB985, 0xB986, 0xB987, 0xF3ED, 0xF3E9, 0xB988, 0xB989, - /* U+7BA0 */ 0xB98A, 0xB9DC, 0xF3EE, 0xB98B, 0xB98C, 0xB98D, 0xF3E5, 0xF3E6, - /* U+7BA8 */ 0xF3EA, 0xC2E1, 0xF3EC, 0xF3EF, 0xF3E8, 0xBCFD, 0xB98E, 0xB98F, - /* U+7BB0 */ 0xB990, 0xCFE4, 0xB991, 0xB992, 0xF3F0, 0xB993, 0xB994, 0xB995, - /* U+7BB8 */ 0xF3E7, 0xB996, 0xB997, 0xB998, 0xB999, 0xB99A, 0xB99B, 0xB99C, - /* U+7BC0 */ 0xB99D, 0xF3F2, 0xB99E, 0xB99F, 0xB9A0, 0xBA40, 0xD7AD, 0xC6AA, - /* U+7BC8 */ 0xBA41, 0xBA42, 0xBA43, 0xBA44, 0xF3F3, 0xBA45, 0xBA46, 0xBA47, - /* U+7BD0 */ 0xBA48, 0xF3F1, 0xBA49, 0xC2A8, 0xBA4A, 0xBA4B, 0xBA4C, 0xBA4D, - /* U+7BD8 */ 0xBA4E, 0xB8DD, 0xF3F5, 0xBA4F, 0xBA50, 0xF3F4, 0xBA51, 0xBA52, - /* U+7BE0 */ 0xBA53, 0xB4DB, 0xBA54, 0xBA55, 0xBA56, 0xF3F6, 0xF3F7, 0xBA57, - /* U+7BE8 */ 0xBA58, 0xBA59, 0xF3F8, 0xBA5A, 0xBA5B, 0xBA5C, 0xC0BA, 0xBA5D, - /* U+7BF0 */ 0xBA5E, 0xC0E9, 0xBA5F, 0xBA60, 0xBA61, 0xBA62, 0xBA63, 0xC5F1, - /* U+7BF8 */ 0xBA64, 0xBA65, 0xBA66, 0xBA67, 0xF3FB, 0xBA68, 0xF3FA, 0xBA69, - /* U+7C00 */ 0xBA6A, 0xBA6B, 0xBA6C, 0xBA6D, 0xBA6E, 0xBA6F, 0xBA70, 0xB4D8, - /* U+7C08 */ 0xBA71, 0xBA72, 0xBA73, 0xF3FE, 0xF3F9, 0xBA74, 0xBA75, 0xF3FC, - /* U+7C10 */ 0xBA76, 0xBA77, 0xBA78, 0xBA79, 0xBA7A, 0xBA7B, 0xF3FD, 0xBA7C, - /* U+7C18 */ 0xBA7D, 0xBA7E, 0xBA80, 0xBA81, 0xBA82, 0xBA83, 0xBA84, 0xF4A1, - /* U+7C20 */ 0xBA85, 0xBA86, 0xBA87, 0xBA88, 0xBA89, 0xBA8A, 0xF4A3, 0xBBC9, - /* U+7C28 */ 0xBA8B, 0xBA8C, 0xF4A2, 0xBA8D, 0xBA8E, 0xBA8F, 0xBA90, 0xBA91, - /* U+7C30 */ 0xBA92, 0xBA93, 0xBA94, 0xBA95, 0xBA96, 0xBA97, 0xBA98, 0xBA99, - /* U+7C38 */ 0xF4A4, 0xBA9A, 0xBA9B, 0xBA9C, 0xBA9D, 0xBA9E, 0xBA9F, 0xB2BE, - /* U+7C40 */ 0xF4A6, 0xF4A5, 0xBAA0, 0xBB40, 0xBB41, 0xBB42, 0xBB43, 0xBB44, - /* U+7C48 */ 0xBB45, 0xBB46, 0xBB47, 0xBB48, 0xBB49, 0xBCAE, 0xBB4A, 0xBB4B, - /* U+7C50 */ 0xBB4C, 0xBB4D, 0xBB4E, 0xBB4F, 0xBB50, 0xBB51, 0xBB52, 0xBB53, - /* U+7C58 */ 0xBB54, 0xBB55, 0xBB56, 0xBB57, 0xBB58, 0xBB59, 0xBB5A, 0xBB5B, - /* U+7C60 */ 0xBB5C, 0xBB5D, 0xBB5E, 0xBB5F, 0xBB60, 0xBB61, 0xBB62, 0xBB63, - /* U+7C68 */ 0xBB64, 0xBB65, 0xBB66, 0xBB67, 0xBB68, 0xBB69, 0xBB6A, 0xBB6B, - /* U+7C70 */ 0xBB6C, 0xBB6D, 0xBB6E, 0xC3D7, 0xD9E1, 0xBB6F, 0xBB70, 0xBB71, - /* U+7C78 */ 0xBB72, 0xBB73, 0xBB74, 0xC0E0, 0xF4CC, 0xD7D1, 0xBB75, 0xBB76, - /* U+7C80 */ 0xBB77, 0xBB78, 0xBB79, 0xBB7A, 0xBB7B, 0xBB7C, 0xBB7D, 0xBB7E, - /* U+7C88 */ 0xBB80, 0xB7DB, 0xBB81, 0xBB82, 0xBB83, 0xBB84, 0xBB85, 0xBB86, - /* U+7C90 */ 0xBB87, 0xF4CE, 0xC1A3, 0xBB88, 0xBB89, 0xC6C9, 0xBB8A, 0xB4D6, - /* U+7C98 */ 0xD5B3, 0xBB8B, 0xBB8C, 0xBB8D, 0xF4D0, 0xF4CF, 0xF4D1, 0xCBDA, - /* U+7CA0 */ 0xBB8E, 0xBB8F, 0xF4D2, 0xBB90, 0xD4C1, 0xD6E0, 0xBB91, 0xBB92, - /* U+7CA8 */ 0xBB93, 0xBB94, 0xB7E0, 0xBB95, 0xBB96, 0xBB97, 0xC1B8, 0xBB98, - /* U+7CB0 */ 0xBB99, 0xC1BB, 0xF4D3, 0xBEAC, 0xBB9A, 0xBB9B, 0xBB9C, 0xBB9D, - /* U+7CB8 */ 0xBB9E, 0xB4E2, 0xBB9F, 0xBBA0, 0xF4D4, 0xF4D5, 0xBEAB, 0xBC40, - /* U+7CC0 */ 0xBC41, 0xF4D6, 0xBC42, 0xBC43, 0xBC44, 0xF4DB, 0xBC45, 0xF4D7, - /* U+7CC8 */ 0xF4DA, 0xBC46, 0xBAFD, 0xBC47, 0xF4D8, 0xF4D9, 0xBC48, 0xBC49, - /* U+7CD0 */ 0xBC4A, 0xBC4B, 0xBC4C, 0xBC4D, 0xBC4E, 0xB8E2, 0xCCC7, 0xF4DC, - /* U+7CD8 */ 0xBC4F, 0xB2DA, 0xBC50, 0xBC51, 0xC3D3, 0xBC52, 0xBC53, 0xD4E3, - /* U+7CE0 */ 0xBFB7, 0xBC54, 0xBC55, 0xBC56, 0xBC57, 0xBC58, 0xBC59, 0xBC5A, - /* U+7CE8 */ 0xF4DD, 0xBC5B, 0xBC5C, 0xBC5D, 0xBC5E, 0xBC5F, 0xBC60, 0xC5B4, - /* U+7CF0 */ 0xBC61, 0xBC62, 0xBC63, 0xBC64, 0xBC65, 0xBC66, 0xBC67, 0xBC68, - /* U+7CF8 */ 0xF4E9, 0xBC69, 0xBC6A, 0xCFB5, 0xBC6B, 0xBC6C, 0xBC6D, 0xBC6E, - /* U+7D00 */ 0xBC6F, 0xBC70, 0xBC71, 0xBC72, 0xBC73, 0xBC74, 0xBC75, 0xBC76, - /* U+7D08 */ 0xBC77, 0xBC78, 0xCEC9, 0xBC79, 0xBC7A, 0xBC7B, 0xBC7C, 0xBC7D, - /* U+7D10 */ 0xBC7E, 0xBC80, 0xBC81, 0xBC82, 0xBC83, 0xBC84, 0xBC85, 0xBC86, - /* U+7D18 */ 0xBC87, 0xBC88, 0xBC89, 0xBC8A, 0xBC8B, 0xBC8C, 0xBC8D, 0xBC8E, - /* U+7D20 */ 0xCBD8, 0xBC8F, 0xCBF7, 0xBC90, 0xBC91, 0xBC92, 0xBC93, 0xBDF4, - /* U+7D28 */ 0xBC94, 0xBC95, 0xBC96, 0xD7CF, 0xBC97, 0xBC98, 0xBC99, 0xC0DB, - /* U+7D30 */ 0xBC9A, 0xBC9B, 0xBC9C, 0xBC9D, 0xBC9E, 0xBC9F, 0xBCA0, 0xBD40, - /* U+7D38 */ 0xBD41, 0xBD42, 0xBD43, 0xBD44, 0xBD45, 0xBD46, 0xBD47, 0xBD48, - /* U+7D40 */ 0xBD49, 0xBD4A, 0xBD4B, 0xBD4C, 0xBD4D, 0xBD4E, 0xBD4F, 0xBD50, - /* U+7D48 */ 0xBD51, 0xBD52, 0xBD53, 0xBD54, 0xBD55, 0xBD56, 0xBD57, 0xBD58, - /* U+7D50 */ 0xBD59, 0xBD5A, 0xBD5B, 0xBD5C, 0xBD5D, 0xBD5E, 0xBD5F, 0xBD60, - /* U+7D58 */ 0xBD61, 0xBD62, 0xBD63, 0xBD64, 0xBD65, 0xBD66, 0xBD67, 0xBD68, - /* U+7D60 */ 0xBD69, 0xBD6A, 0xBD6B, 0xBD6C, 0xBD6D, 0xBD6E, 0xBD6F, 0xBD70, - /* U+7D68 */ 0xBD71, 0xBD72, 0xBD73, 0xBD74, 0xBD75, 0xBD76, 0xD0F5, 0xBD77, - /* U+7D70 */ 0xBD78, 0xBD79, 0xBD7A, 0xBD7B, 0xBD7C, 0xBD7D, 0xBD7E, 0xF4EA, - /* U+7D78 */ 0xBD80, 0xBD81, 0xBD82, 0xBD83, 0xBD84, 0xBD85, 0xBD86, 0xBD87, - /* U+7D80 */ 0xBD88, 0xBD89, 0xBD8A, 0xBD8B, 0xBD8C, 0xBD8D, 0xBD8E, 0xBD8F, - /* U+7D88 */ 0xBD90, 0xBD91, 0xBD92, 0xBD93, 0xBD94, 0xBD95, 0xBD96, 0xBD97, - /* U+7D90 */ 0xBD98, 0xBD99, 0xBD9A, 0xBD9B, 0xBD9C, 0xBD9D, 0xBD9E, 0xBD9F, - /* U+7D98 */ 0xBDA0, 0xBE40, 0xBE41, 0xBE42, 0xBE43, 0xBE44, 0xBE45, 0xBE46, - /* U+7DA0 */ 0xBE47, 0xBE48, 0xBE49, 0xBE4A, 0xBE4B, 0xBE4C, 0xF4EB, 0xBE4D, - /* U+7DA8 */ 0xBE4E, 0xBE4F, 0xBE50, 0xBE51, 0xBE52, 0xBE53, 0xF4EC, 0xBE54, - /* U+7DB0 */ 0xBE55, 0xBE56, 0xBE57, 0xBE58, 0xBE59, 0xBE5A, 0xBE5B, 0xBE5C, - /* U+7DB8 */ 0xBE5D, 0xBE5E, 0xBE5F, 0xBE60, 0xBE61, 0xBE62, 0xBE63, 0xBE64, - /* U+7DC0 */ 0xBE65, 0xBE66, 0xBE67, 0xBE68, 0xBE69, 0xBE6A, 0xBE6B, 0xBE6C, - /* U+7DC8 */ 0xBE6D, 0xBE6E, 0xBE6F, 0xBE70, 0xBE71, 0xBE72, 0xBE73, 0xBE74, - /* U+7DD0 */ 0xBE75, 0xBE76, 0xBE77, 0xBE78, 0xBE79, 0xBE7A, 0xBE7B, 0xBE7C, - /* U+7DD8 */ 0xBE7D, 0xBE7E, 0xBE80, 0xBE81, 0xBE82, 0xBE83, 0xBE84, 0xBE85, - /* U+7DE0 */ 0xBE86, 0xBE87, 0xBE88, 0xBE89, 0xBE8A, 0xBE8B, 0xBE8C, 0xBE8D, - /* U+7DE8 */ 0xBE8E, 0xBE8F, 0xBE90, 0xBE91, 0xBE92, 0xBE93, 0xBE94, 0xBE95, - /* U+7DF0 */ 0xBE96, 0xBE97, 0xBE98, 0xBE99, 0xBE9A, 0xBE9B, 0xBE9C, 0xBE9D, - /* U+7DF8 */ 0xBE9E, 0xBE9F, 0xBEA0, 0xBF40, 0xBF41, 0xBF42, 0xBF43, 0xBF44, - /* U+7E00 */ 0xBF45, 0xBF46, 0xBF47, 0xBF48, 0xBF49, 0xBF4A, 0xBF4B, 0xBF4C, - /* U+7E08 */ 0xBF4D, 0xBF4E, 0xBF4F, 0xBF50, 0xBF51, 0xBF52, 0xBF53, 0xBF54, - /* U+7E10 */ 0xBF55, 0xBF56, 0xBF57, 0xBF58, 0xBF59, 0xBF5A, 0xBF5B, 0xBF5C, - /* U+7E18 */ 0xBF5D, 0xBF5E, 0xBF5F, 0xBF60, 0xBF61, 0xBF62, 0xBF63, 0xBF64, - /* U+7E20 */ 0xBF65, 0xBF66, 0xBF67, 0xBF68, 0xBF69, 0xBF6A, 0xBF6B, 0xBF6C, - /* U+7E28 */ 0xBF6D, 0xBF6E, 0xBF6F, 0xBF70, 0xBF71, 0xBF72, 0xBF73, 0xBF74, - /* U+7E30 */ 0xBF75, 0xBF76, 0xBF77, 0xBF78, 0xBF79, 0xBF7A, 0xBF7B, 0xBF7C, - /* U+7E38 */ 0xBF7D, 0xBF7E, 0xBF80, 0xF7E3, 0xBF81, 0xBF82, 0xBF83, 0xBF84, - /* U+7E40 */ 0xBF85, 0xB7B1, 0xBF86, 0xBF87, 0xBF88, 0xBF89, 0xBF8A, 0xF4ED, - /* U+7E48 */ 0xBF8B, 0xBF8C, 0xBF8D, 0xBF8E, 0xBF8F, 0xBF90, 0xBF91, 0xBF92, - /* U+7E50 */ 0xBF93, 0xBF94, 0xBF95, 0xBF96, 0xBF97, 0xBF98, 0xBF99, 0xBF9A, - /* U+7E58 */ 0xBF9B, 0xBF9C, 0xBF9D, 0xBF9E, 0xBF9F, 0xBFA0, 0xC040, 0xC041, - /* U+7E60 */ 0xC042, 0xC043, 0xC044, 0xC045, 0xC046, 0xC047, 0xC048, 0xC049, - /* U+7E68 */ 0xC04A, 0xC04B, 0xC04C, 0xC04D, 0xC04E, 0xC04F, 0xC050, 0xC051, - /* U+7E70 */ 0xC052, 0xC053, 0xC054, 0xC055, 0xC056, 0xC057, 0xC058, 0xC059, - /* U+7E78 */ 0xC05A, 0xC05B, 0xC05C, 0xC05D, 0xC05E, 0xC05F, 0xC060, 0xC061, - /* U+7E80 */ 0xC062, 0xC063, 0xD7EB, 0xC064, 0xC065, 0xC066, 0xC067, 0xC068, - /* U+7E88 */ 0xC069, 0xC06A, 0xC06B, 0xC06C, 0xC06D, 0xC06E, 0xC06F, 0xC070, - /* U+7E90 */ 0xC071, 0xC072, 0xC073, 0xC074, 0xC075, 0xC076, 0xC077, 0xC078, - /* U+7E98 */ 0xC079, 0xC07A, 0xC07B, 0xF4EE, 0xC07C, 0xC07D, 0xC07E, 0xE6F9, - /* U+7EA0 */ 0xBEC0, 0xE6FA, 0xBAEC, 0xE6FB, 0xCFCB, 0xE6FC, 0xD4BC, 0xBCB6, - /* U+7EA8 */ 0xE6FD, 0xE6FE, 0xBCCD, 0xC8D2, 0xCEB3, 0xE7A1, 0xC080, 0xB4BF, - /* U+7EB0 */ 0xE7A2, 0xC9B4, 0xB8D9, 0xC4C9, 0xC081, 0xD7DD, 0xC2DA, 0xB7D7, - /* U+7EB8 */ 0xD6BD, 0xCEC6, 0xB7C4, 0xC082, 0xC083, 0xC5A6, 0xE7A3, 0xCFDF, - /* U+7EC0 */ 0xE7A4, 0xE7A5, 0xE7A6, 0xC1B7, 0xD7E9, 0xC9F0, 0xCFB8, 0xD6AF, - /* U+7EC8 */ 0xD6D5, 0xE7A7, 0xB0ED, 0xE7A8, 0xE7A9, 0xC9DC, 0xD2EF, 0xBEAD, - /* U+7ED0 */ 0xE7AA, 0xB0F3, 0xC8DE, 0xBDE1, 0xE7AB, 0xC8C6, 0xC084, 0xE7AC, - /* U+7ED8 */ 0xBBE6, 0xB8F8, 0xD1A4, 0xE7AD, 0xC2E7, 0xBEF8, 0xBDCA, 0xCDB3, - /* U+7EE0 */ 0xE7AE, 0xE7AF, 0xBEEE, 0xD0E5, 0xC085, 0xCBE7, 0xCCD0, 0xBCCC, - /* U+7EE8 */ 0xE7B0, 0xBCA8, 0xD0F7, 0xE7B1, 0xC086, 0xD0F8, 0xE7B2, 0xE7B3, - /* U+7EF0 */ 0xB4C2, 0xE7B4, 0xE7B5, 0xC9FE, 0xCEAC, 0xC3E0, 0xE7B7, 0xB1C1, - /* U+7EF8 */ 0xB3F1, 0xC087, 0xE7B8, 0xE7B9, 0xD7DB, 0xD5C0, 0xE7BA, 0xC2CC, - /* U+7F00 */ 0xD7BA, 0xE7BB, 0xE7BC, 0xE7BD, 0xBCEA, 0xC3E5, 0xC0C2, 0xE7BE, - /* U+7F08 */ 0xE7BF, 0xBCA9, 0xC088, 0xE7C0, 0xE7C1, 0xE7B6, 0xB6D0, 0xE7C2, - /* U+7F10 */ 0xC089, 0xE7C3, 0xE7C4, 0xBBBA, 0xB5DE, 0xC2C6, 0xB1E0, 0xE7C5, - /* U+7F18 */ 0xD4B5, 0xE7C6, 0xB8BF, 0xE7C8, 0xE7C7, 0xB7EC, 0xC08A, 0xE7C9, - /* U+7F20 */ 0xB2F8, 0xE7CA, 0xE7CB, 0xE7CC, 0xE7CD, 0xE7CE, 0xE7CF, 0xE7D0, - /* U+7F28 */ 0xD3A7, 0xCBF5, 0xE7D1, 0xE7D2, 0xE7D3, 0xE7D4, 0xC9C9, 0xE7D5, - /* U+7F30 */ 0xE7D6, 0xE7D7, 0xE7D8, 0xE7D9, 0xBDC9, 0xE7DA, 0xF3BE, 0xC08B, - /* U+7F38 */ 0xB8D7, 0xC08C, 0xC8B1, 0xC08D, 0xC08E, 0xC08F, 0xC090, 0xC091, - /* U+7F40 */ 0xC092, 0xC093, 0xF3BF, 0xC094, 0xF3C0, 0xF3C1, 0xC095, 0xC096, - /* U+7F48 */ 0xC097, 0xC098, 0xC099, 0xC09A, 0xC09B, 0xC09C, 0xC09D, 0xC09E, - /* U+7F50 */ 0xB9DE, 0xCDF8, 0xC09F, 0xC0A0, 0xD8E8, 0xBAB1, 0xC140, 0xC2DE, - /* U+7F58 */ 0xEEB7, 0xC141, 0xB7A3, 0xC142, 0xC143, 0xC144, 0xC145, 0xEEB9, - /* U+7F60 */ 0xC146, 0xEEB8, 0xB0D5, 0xC147, 0xC148, 0xC149, 0xC14A, 0xC14B, - /* U+7F68 */ 0xEEBB, 0xD5D6, 0xD7EF, 0xC14C, 0xC14D, 0xC14E, 0xD6C3, 0xC14F, - /* U+7F70 */ 0xC150, 0xEEBD, 0xCAF0, 0xC151, 0xEEBC, 0xC152, 0xC153, 0xC154, - /* U+7F78 */ 0xC155, 0xEEBE, 0xC156, 0xC157, 0xC158, 0xC159, 0xEEC0, 0xC15A, - /* U+7F80 */ 0xC15B, 0xEEBF, 0xC15C, 0xC15D, 0xC15E, 0xC15F, 0xC160, 0xC161, - /* U+7F88 */ 0xC162, 0xC163, 0xD1F2, 0xC164, 0xC7BC, 0xC165, 0xC3C0, 0xC166, - /* U+7F90 */ 0xC167, 0xC168, 0xC169, 0xC16A, 0xB8E1, 0xC16B, 0xC16C, 0xC16D, - /* U+7F98 */ 0xC16E, 0xC16F, 0xC1E7, 0xC170, 0xC171, 0xF4C6, 0xD0DF, 0xF4C7, - /* U+7FA0 */ 0xC172, 0xCFDB, 0xC173, 0xC174, 0xC8BA, 0xC175, 0xC176, 0xF4C8, - /* U+7FA8 */ 0xC177, 0xC178, 0xC179, 0xC17A, 0xC17B, 0xC17C, 0xC17D, 0xF4C9, - /* U+7FB0 */ 0xF4CA, 0xC17E, 0xF4CB, 0xC180, 0xC181, 0xC182, 0xC183, 0xC184, - /* U+7FB8 */ 0xD9FA, 0xB8FE, 0xC185, 0xC186, 0xE5F1, 0xD3F0, 0xC187, 0xF4E0, - /* U+7FC0 */ 0xC188, 0xCECC, 0xC189, 0xC18A, 0xC18B, 0xB3E1, 0xC18C, 0xC18D, - /* U+7FC8 */ 0xC18E, 0xC18F, 0xF1B4, 0xC190, 0xD2EE, 0xC191, 0xF4E1, 0xC192, - /* U+7FD0 */ 0xC193, 0xC194, 0xC195, 0xC196, 0xCFE8, 0xF4E2, 0xC197, 0xC198, - /* U+7FD8 */ 0xC7CC, 0xC199, 0xC19A, 0xC19B, 0xC19C, 0xC19D, 0xC19E, 0xB5D4, - /* U+7FE0 */ 0xB4E4, 0xF4E4, 0xC19F, 0xC1A0, 0xC240, 0xF4E3, 0xF4E5, 0xC241, - /* U+7FE8 */ 0xC242, 0xF4E6, 0xC243, 0xC244, 0xC245, 0xC246, 0xF4E7, 0xC247, - /* U+7FF0 */ 0xBAB2, 0xB0BF, 0xC248, 0xF4E8, 0xC249, 0xC24A, 0xC24B, 0xC24C, - /* U+7FF8 */ 0xC24D, 0xC24E, 0xC24F, 0xB7AD, 0xD2ED, 0xC250, 0xC251, 0xC252, - /* U+8000 */ 0xD2AB, 0xC0CF, 0xC253, 0xBFBC, 0xEBA3, 0xD5DF, 0xEAC8, 0xC254, - /* U+8008 */ 0xC255, 0xC256, 0xC257, 0xF1F3, 0xB6F8, 0xCBA3, 0xC258, 0xC259, - /* U+8010 */ 0xC4CD, 0xC25A, 0xF1E7, 0xC25B, 0xF1E8, 0xB8FB, 0xF1E9, 0xBAC4, - /* U+8018 */ 0xD4C5, 0xB0D2, 0xC25C, 0xC25D, 0xF1EA, 0xC25E, 0xC25F, 0xC260, - /* U+8020 */ 0xF1EB, 0xC261, 0xF1EC, 0xC262, 0xC263, 0xF1ED, 0xF1EE, 0xF1EF, - /* U+8028 */ 0xF1F1, 0xF1F0, 0xC5D5, 0xC264, 0xC265, 0xC266, 0xC267, 0xC268, - /* U+8030 */ 0xC269, 0xF1F2, 0xC26A, 0xB6FA, 0xC26B, 0xF1F4, 0xD2AE, 0xDEC7, - /* U+8038 */ 0xCBCA, 0xC26C, 0xC26D, 0xB3DC, 0xC26E, 0xB5A2, 0xC26F, 0xB9A2, - /* U+8040 */ 0xC270, 0xC271, 0xC4F4, 0xF1F5, 0xC272, 0xC273, 0xF1F6, 0xC274, - /* U+8048 */ 0xC275, 0xC276, 0xC1C4, 0xC1FB, 0xD6B0, 0xF1F7, 0xC277, 0xC278, - /* U+8050 */ 0xC279, 0xC27A, 0xF1F8, 0xC27B, 0xC1AA, 0xC27C, 0xC27D, 0xC27E, - /* U+8058 */ 0xC6B8, 0xC280, 0xBEDB, 0xC281, 0xC282, 0xC283, 0xC284, 0xC285, - /* U+8060 */ 0xC286, 0xC287, 0xC288, 0xC289, 0xC28A, 0xC28B, 0xC28C, 0xC28D, - /* U+8068 */ 0xC28E, 0xF1F9, 0xB4CF, 0xC28F, 0xC290, 0xC291, 0xC292, 0xC293, - /* U+8070 */ 0xC294, 0xF1FA, 0xC295, 0xC296, 0xC297, 0xC298, 0xC299, 0xC29A, - /* U+8078 */ 0xC29B, 0xC29C, 0xC29D, 0xC29E, 0xC29F, 0xC2A0, 0xC340, 0xEDB2, - /* U+8080 */ 0xEDB1, 0xC341, 0xC342, 0xCBE0, 0xD2DE, 0xC343, 0xCBC1, 0xD5D8, - /* U+8088 */ 0xC344, 0xC8E2, 0xC345, 0xC0DF, 0xBCA1, 0xC346, 0xC347, 0xC348, - /* U+8090 */ 0xC349, 0xC34A, 0xC34B, 0xEBC1, 0xC34C, 0xC34D, 0xD0A4, 0xC34E, - /* U+8098 */ 0xD6E2, 0xC34F, 0xB6C7, 0xB8D8, 0xEBC0, 0xB8CE, 0xC350, 0xEBBF, - /* U+80A0 */ 0xB3A6, 0xB9C9, 0xD6AB, 0xC351, 0xB7F4, 0xB7CA, 0xC352, 0xC353, - /* U+80A8 */ 0xC354, 0xBCE7, 0xB7BE, 0xEBC6, 0xC355, 0xEBC7, 0xB0B9, 0xBFCF, - /* U+80B0 */ 0xC356, 0xEBC5, 0xD3FD, 0xC357, 0xEBC8, 0xC358, 0xC359, 0xEBC9, - /* U+80B8 */ 0xC35A, 0xC35B, 0xB7CE, 0xC35C, 0xEBC2, 0xEBC4, 0xC9F6, 0xD6D7, - /* U+80C0 */ 0xD5CD, 0xD0B2, 0xEBCF, 0xCEB8, 0xEBD0, 0xC35D, 0xB5A8, 0xC35E, - /* U+80C8 */ 0xC35F, 0xC360, 0xC361, 0xC362, 0xB1B3, 0xEBD2, 0xCCA5, 0xC363, - /* U+80D0 */ 0xC364, 0xC365, 0xC366, 0xC367, 0xC368, 0xC369, 0xC5D6, 0xEBD3, - /* U+80D8 */ 0xC36A, 0xEBD1, 0xC5DF, 0xEBCE, 0xCAA4, 0xEBD5, 0xB0FB, 0xC36B, - /* U+80E0 */ 0xC36C, 0xBAFA, 0xC36D, 0xC36E, 0xD8B7, 0xF1E3, 0xC36F, 0xEBCA, - /* U+80E8 */ 0xEBCB, 0xEBCC, 0xEBCD, 0xEBD6, 0xE6C0, 0xEBD9, 0xC370, 0xBFE8, - /* U+80F0 */ 0xD2C8, 0xEBD7, 0xEBDC, 0xB8EC, 0xEBD8, 0xC371, 0xBDBA, 0xC372, - /* U+80F8 */ 0xD0D8, 0xC373, 0xB0B7, 0xC374, 0xEBDD, 0xC4DC, 0xC375, 0xC376, - /* U+8100 */ 0xC377, 0xC378, 0xD6AC, 0xC379, 0xC37A, 0xC37B, 0xB4E0, 0xC37C, - /* U+8108 */ 0xC37D, 0xC2F6, 0xBCB9, 0xC37E, 0xC380, 0xEBDA, 0xEBDB, 0xD4E0, - /* U+8110 */ 0xC6EA, 0xC4D4, 0xEBDF, 0xC5A7, 0xD9F5, 0xC381, 0xB2B1, 0xC382, - /* U+8118 */ 0xEBE4, 0xC383, 0xBDC5, 0xC384, 0xC385, 0xC386, 0xEBE2, 0xC387, - /* U+8120 */ 0xC388, 0xC389, 0xC38A, 0xC38B, 0xC38C, 0xC38D, 0xC38E, 0xC38F, - /* U+8128 */ 0xC390, 0xC391, 0xC392, 0xC393, 0xEBE3, 0xC394, 0xC395, 0xB8AC, - /* U+8130 */ 0xC396, 0xCDD1, 0xEBE5, 0xC397, 0xC398, 0xC399, 0xEBE1, 0xC39A, - /* U+8138 */ 0xC1B3, 0xC39B, 0xC39C, 0xC39D, 0xC39E, 0xC39F, 0xC6A2, 0xC3A0, - /* U+8140 */ 0xC440, 0xC441, 0xC442, 0xC443, 0xC444, 0xC445, 0xCCF3, 0xC446, - /* U+8148 */ 0xEBE6, 0xC447, 0xC0B0, 0xD2B8, 0xEBE7, 0xC448, 0xC449, 0xC44A, - /* U+8150 */ 0xB8AF, 0xB8AD, 0xC44B, 0xEBE8, 0xC7BB, 0xCDF3, 0xC44C, 0xC44D, - /* U+8158 */ 0xC44E, 0xEBEA, 0xEBEB, 0xC44F, 0xC450, 0xC451, 0xC452, 0xC453, - /* U+8160 */ 0xEBED, 0xC454, 0xC455, 0xC456, 0xC457, 0xD0C8, 0xC458, 0xEBF2, - /* U+8168 */ 0xC459, 0xEBEE, 0xC45A, 0xC45B, 0xC45C, 0xEBF1, 0xC8F9, 0xC45D, - /* U+8170 */ 0xD1FC, 0xEBEC, 0xC45E, 0xC45F, 0xEBE9, 0xC460, 0xC461, 0xC462, - /* U+8178 */ 0xC463, 0xB8B9, 0xCFD9, 0xC4E5, 0xEBEF, 0xEBF0, 0xCCDA, 0xCDC8, - /* U+8180 */ 0xB0F2, 0xC464, 0xEBF6, 0xC465, 0xC466, 0xC467, 0xC468, 0xC469, - /* U+8188 */ 0xEBF5, 0xC46A, 0xB2B2, 0xC46B, 0xC46C, 0xC46D, 0xC46E, 0xB8E0, - /* U+8190 */ 0xC46F, 0xEBF7, 0xC470, 0xC471, 0xC472, 0xC473, 0xC474, 0xC475, - /* U+8198 */ 0xB1EC, 0xC476, 0xC477, 0xCCC5, 0xC4A4, 0xCFA5, 0xC478, 0xC479, - /* U+81A0 */ 0xC47A, 0xC47B, 0xC47C, 0xEBF9, 0xC47D, 0xC47E, 0xECA2, 0xC480, - /* U+81A8 */ 0xC5F2, 0xC481, 0xEBFA, 0xC482, 0xC483, 0xC484, 0xC485, 0xC486, - /* U+81B0 */ 0xC487, 0xC488, 0xC489, 0xC9C5, 0xC48A, 0xC48B, 0xC48C, 0xC48D, - /* U+81B8 */ 0xC48E, 0xC48F, 0xE2DF, 0xEBFE, 0xC490, 0xC491, 0xC492, 0xC493, - /* U+81C0 */ 0xCDCE, 0xECA1, 0xB1DB, 0xD3B7, 0xC494, 0xC495, 0xD2DC, 0xC496, - /* U+81C8 */ 0xC497, 0xC498, 0xEBFD, 0xC499, 0xEBFB, 0xC49A, 0xC49B, 0xC49C, - /* U+81D0 */ 0xC49D, 0xC49E, 0xC49F, 0xC4A0, 0xC540, 0xC541, 0xC542, 0xC543, - /* U+81D8 */ 0xC544, 0xC545, 0xC546, 0xC547, 0xC548, 0xC549, 0xC54A, 0xC54B, - /* U+81E0 */ 0xC54C, 0xC54D, 0xC54E, 0xB3BC, 0xC54F, 0xC550, 0xC551, 0xEAB0, - /* U+81E8 */ 0xC552, 0xC553, 0xD7D4, 0xC554, 0xF4AB, 0xB3F4, 0xC555, 0xC556, - /* U+81F0 */ 0xC557, 0xC558, 0xC559, 0xD6C1, 0xD6C2, 0xC55A, 0xC55B, 0xC55C, - /* U+81F8 */ 0xC55D, 0xC55E, 0xC55F, 0xD5E9, 0xBECA, 0xC560, 0xF4A7, 0xC561, - /* U+8200 */ 0xD2A8, 0xF4A8, 0xF4A9, 0xC562, 0xF4AA, 0xBECB, 0xD3DF, 0xC563, - /* U+8208 */ 0xC564, 0xC565, 0xC566, 0xC567, 0xC9E0, 0xC9E1, 0xC568, 0xC569, - /* U+8210 */ 0xF3C2, 0xC56A, 0xCAE6, 0xC56B, 0xCCF2, 0xC56C, 0xC56D, 0xC56E, - /* U+8218 */ 0xC56F, 0xC570, 0xC571, 0xE2B6, 0xCBB4, 0xC572, 0xCEE8, 0xD6DB, - /* U+8220 */ 0xC573, 0xF4AD, 0xF4AE, 0xF4AF, 0xC574, 0xC575, 0xC576, 0xC577, - /* U+8228 */ 0xF4B2, 0xC578, 0xBABD, 0xF4B3, 0xB0E3, 0xF4B0, 0xC579, 0xF4B1, - /* U+8230 */ 0xBDA2, 0xB2D5, 0xC57A, 0xF4B6, 0xF4B7, 0xB6E6, 0xB2B0, 0xCFCF, - /* U+8238 */ 0xF4B4, 0xB4AC, 0xC57B, 0xF4B5, 0xC57C, 0xC57D, 0xF4B8, 0xC57E, - /* U+8240 */ 0xC580, 0xC581, 0xC582, 0xC583, 0xF4B9, 0xC584, 0xC585, 0xCDA7, - /* U+8248 */ 0xC586, 0xF4BA, 0xC587, 0xF4BB, 0xC588, 0xC589, 0xC58A, 0xF4BC, - /* U+8250 */ 0xC58B, 0xC58C, 0xC58D, 0xC58E, 0xC58F, 0xC590, 0xC591, 0xC592, - /* U+8258 */ 0xCBD2, 0xC593, 0xF4BD, 0xC594, 0xC595, 0xC596, 0xC597, 0xF4BE, - /* U+8260 */ 0xC598, 0xC599, 0xC59A, 0xC59B, 0xC59C, 0xC59D, 0xC59E, 0xC59F, - /* U+8268 */ 0xF4BF, 0xC5A0, 0xC640, 0xC641, 0xC642, 0xC643, 0xF4DE, 0xC1BC, - /* U+8270 */ 0xBCE8, 0xC644, 0xC9AB, 0xD1DE, 0xE5F5, 0xC645, 0xC646, 0xC647, - /* U+8278 */ 0xC648, 0xDCB3, 0xD2D5, 0xC649, 0xC64A, 0xDCB4, 0xB0AC, 0xDCB5, - /* U+8280 */ 0xC64B, 0xC64C, 0xBDDA, 0xC64D, 0xDCB9, 0xC64E, 0xC64F, 0xC650, - /* U+8288 */ 0xD8C2, 0xC651, 0xDCB7, 0xD3F3, 0xC652, 0xC9D6, 0xDCBA, 0xDCB6, - /* U+8290 */ 0xC653, 0xDCBB, 0xC3A2, 0xC654, 0xC655, 0xC656, 0xC657, 0xDCBC, - /* U+8298 */ 0xDCC5, 0xDCBD, 0xC658, 0xC659, 0xCEDF, 0xD6A5, 0xC65A, 0xDCCF, - /* U+82A0 */ 0xC65B, 0xDCCD, 0xC65C, 0xC65D, 0xDCD2, 0xBDE6, 0xC2AB, 0xC65E, - /* U+82A8 */ 0xDCB8, 0xDCCB, 0xDCCE, 0xDCBE, 0xB7D2, 0xB0C5, 0xDCC7, 0xD0BE, - /* U+82B0 */ 0xDCC1, 0xBBA8, 0xC65F, 0xB7BC, 0xDCCC, 0xC660, 0xC661, 0xDCC6, - /* U+82B8 */ 0xDCBF, 0xC7DB, 0xC662, 0xC663, 0xC664, 0xD1BF, 0xDCC0, 0xC665, - /* U+82C0 */ 0xC666, 0xDCCA, 0xC667, 0xC668, 0xDCD0, 0xC669, 0xC66A, 0xCEAD, - /* U+82C8 */ 0xDCC2, 0xC66B, 0xDCC3, 0xDCC8, 0xDCC9, 0xB2D4, 0xDCD1, 0xCBD5, - /* U+82D0 */ 0xC66C, 0xD4B7, 0xDCDB, 0xDCDF, 0xCCA6, 0xDCE6, 0xC66D, 0xC3E7, - /* U+82D8 */ 0xDCDC, 0xC66E, 0xC66F, 0xBFC1, 0xDCD9, 0xC670, 0xB0FA, 0xB9B6, - /* U+82E0 */ 0xDCE5, 0xDCD3, 0xC671, 0xDCC4, 0xDCD6, 0xC8F4, 0xBFE0, 0xC672, - /* U+82E8 */ 0xC673, 0xC674, 0xC675, 0xC9BB, 0xC676, 0xC677, 0xC678, 0xB1BD, - /* U+82F0 */ 0xC679, 0xD3A2, 0xC67A, 0xC67B, 0xDCDA, 0xC67C, 0xC67D, 0xDCD5, - /* U+82F8 */ 0xC67E, 0xC6BB, 0xC680, 0xDCDE, 0xC681, 0xC682, 0xC683, 0xC684, - /* U+8300 */ 0xC685, 0xD7C2, 0xC3AF, 0xB7B6, 0xC7D1, 0xC3A9, 0xDCE2, 0xDCD8, - /* U+8308 */ 0xDCEB, 0xDCD4, 0xC686, 0xC687, 0xDCDD, 0xC688, 0xBEA5, 0xDCD7, - /* U+8310 */ 0xC689, 0xDCE0, 0xC68A, 0xC68B, 0xDCE3, 0xDCE4, 0xC68C, 0xDCF8, - /* U+8318 */ 0xC68D, 0xC68E, 0xDCE1, 0xDDA2, 0xDCE7, 0xC68F, 0xC690, 0xC691, - /* U+8320 */ 0xC692, 0xC693, 0xC694, 0xC695, 0xC696, 0xC697, 0xC698, 0xBCEB, - /* U+8328 */ 0xB4C4, 0xC699, 0xC69A, 0xC3A3, 0xB2E7, 0xDCFA, 0xC69B, 0xDCF2, - /* U+8330 */ 0xC69C, 0xDCEF, 0xC69D, 0xDCFC, 0xDCEE, 0xD2F0, 0xB2E8, 0xC69E, - /* U+8338 */ 0xC8D7, 0xC8E3, 0xDCFB, 0xC69F, 0xDCED, 0xC6A0, 0xC740, 0xC741, - /* U+8340 */ 0xDCF7, 0xC742, 0xC743, 0xDCF5, 0xC744, 0xC745, 0xBEA3, 0xDCF4, - /* U+8348 */ 0xC746, 0xB2DD, 0xC747, 0xC748, 0xC749, 0xC74A, 0xC74B, 0xDCF3, - /* U+8350 */ 0xBCF6, 0xDCE8, 0xBBC4, 0xC74C, 0xC0F3, 0xC74D, 0xC74E, 0xC74F, - /* U+8358 */ 0xC750, 0xC751, 0xBCD4, 0xDCE9, 0xDCEA, 0xC752, 0xDCF1, 0xDCF6, - /* U+8360 */ 0xDCF9, 0xB5B4, 0xC753, 0xC8D9, 0xBBE7, 0xDCFE, 0xDCFD, 0xD3AB, - /* U+8368 */ 0xDDA1, 0xDDA3, 0xDDA5, 0xD2F1, 0xDDA4, 0xDDA6, 0xDDA7, 0xD2A9, - /* U+8370 */ 0xC754, 0xC755, 0xC756, 0xC757, 0xC758, 0xC759, 0xC75A, 0xBAC9, - /* U+8378 */ 0xDDA9, 0xC75B, 0xC75C, 0xDDB6, 0xDDB1, 0xDDB4, 0xC75D, 0xC75E, - /* U+8380 */ 0xC75F, 0xC760, 0xC761, 0xC762, 0xC763, 0xDDB0, 0xC6CE, 0xC764, - /* U+8388 */ 0xC765, 0xC0F2, 0xC766, 0xC767, 0xC768, 0xC769, 0xC9AF, 0xC76A, - /* U+8390 */ 0xC76B, 0xC76C, 0xDCEC, 0xDDAE, 0xC76D, 0xC76E, 0xC76F, 0xC770, - /* U+8398 */ 0xDDB7, 0xC771, 0xC772, 0xDCF0, 0xDDAF, 0xC773, 0xDDB8, 0xC774, - /* U+83A0 */ 0xDDAC, 0xC775, 0xC776, 0xC777, 0xC778, 0xC779, 0xC77A, 0xC77B, - /* U+83A8 */ 0xDDB9, 0xDDB3, 0xDDAD, 0xC4AA, 0xC77C, 0xC77D, 0xC77E, 0xC780, - /* U+83B0 */ 0xDDA8, 0xC0B3, 0xC1AB, 0xDDAA, 0xDDAB, 0xC781, 0xDDB2, 0xBBF1, - /* U+83B8 */ 0xDDB5, 0xD3A8, 0xDDBA, 0xC782, 0xDDBB, 0xC3A7, 0xC783, 0xC784, - /* U+83C0 */ 0xDDD2, 0xDDBC, 0xC785, 0xC786, 0xC787, 0xDDD1, 0xC788, 0xB9BD, - /* U+83C8 */ 0xC789, 0xC78A, 0xBED5, 0xC78B, 0xBEFA, 0xC78C, 0xC78D, 0xBACA, - /* U+83D0 */ 0xC78E, 0xC78F, 0xC790, 0xC791, 0xDDCA, 0xC792, 0xDDC5, 0xC793, - /* U+83D8 */ 0xDDBF, 0xC794, 0xC795, 0xC796, 0xB2CB, 0xDDC3, 0xC797, 0xDDCB, - /* U+83E0 */ 0xB2A4, 0xDDD5, 0xC798, 0xC799, 0xC79A, 0xDDBE, 0xC79B, 0xC79C, - /* U+83E8 */ 0xC79D, 0xC6D0, 0xDDD0, 0xC79E, 0xC79F, 0xC7A0, 0xC840, 0xC841, - /* U+83F0 */ 0xDDD4, 0xC1E2, 0xB7C6, 0xC842, 0xC843, 0xC844, 0xC845, 0xC846, - /* U+83F8 */ 0xDDCE, 0xDDCF, 0xC847, 0xC848, 0xC849, 0xDDC4, 0xC84A, 0xC84B, - /* U+8400 */ 0xC84C, 0xDDBD, 0xC84D, 0xDDCD, 0xCCD1, 0xC84E, 0xDDC9, 0xC84F, - /* U+8408 */ 0xC850, 0xC851, 0xC852, 0xDDC2, 0xC3C8, 0xC6BC, 0xCEAE, 0xDDCC, - /* U+8410 */ 0xC853, 0xDDC8, 0xC854, 0xC855, 0xC856, 0xC857, 0xC858, 0xC859, - /* U+8418 */ 0xDDC1, 0xC85A, 0xC85B, 0xC85C, 0xDDC6, 0xC2DC, 0xC85D, 0xC85E, - /* U+8420 */ 0xC85F, 0xC860, 0xC861, 0xC862, 0xD3A9, 0xD3AA, 0xDDD3, 0xCFF4, - /* U+8428 */ 0xC8F8, 0xC863, 0xC864, 0xC865, 0xC866, 0xC867, 0xC868, 0xC869, - /* U+8430 */ 0xC86A, 0xDDE6, 0xC86B, 0xC86C, 0xC86D, 0xC86E, 0xC86F, 0xC870, - /* U+8438 */ 0xDDC7, 0xC871, 0xC872, 0xC873, 0xDDE0, 0xC2E4, 0xC874, 0xC875, - /* U+8440 */ 0xC876, 0xC877, 0xC878, 0xC879, 0xC87A, 0xC87B, 0xDDE1, 0xC87C, - /* U+8448 */ 0xC87D, 0xC87E, 0xC880, 0xC881, 0xC882, 0xC883, 0xC884, 0xC885, - /* U+8450 */ 0xC886, 0xDDD7, 0xC887, 0xC888, 0xC889, 0xC88A, 0xC88B, 0xD6F8, - /* U+8458 */ 0xC88C, 0xDDD9, 0xDDD8, 0xB8F0, 0xDDD6, 0xC88D, 0xC88E, 0xC88F, - /* U+8460 */ 0xC890, 0xC6CF, 0xC891, 0xB6AD, 0xC892, 0xC893, 0xC894, 0xC895, - /* U+8468 */ 0xC896, 0xDDE2, 0xC897, 0xBAF9, 0xD4E1, 0xDDE7, 0xC898, 0xC899, - /* U+8470 */ 0xC89A, 0xB4D0, 0xC89B, 0xDDDA, 0xC89C, 0xBFFB, 0xDDE3, 0xC89D, - /* U+8478 */ 0xDDDF, 0xC89E, 0xDDDD, 0xC89F, 0xC8A0, 0xC940, 0xC941, 0xC942, - /* U+8480 */ 0xC943, 0xC944, 0xB5D9, 0xC945, 0xC946, 0xC947, 0xC948, 0xDDDB, - /* U+8488 */ 0xDDDC, 0xDDDE, 0xC949, 0xBDAF, 0xDDE4, 0xC94A, 0xDDE5, 0xC94B, - /* U+8490 */ 0xC94C, 0xC94D, 0xC94E, 0xC94F, 0xC950, 0xC951, 0xC952, 0xDDF5, - /* U+8498 */ 0xC953, 0xC3C9, 0xC954, 0xC955, 0xCBE2, 0xC956, 0xC957, 0xC958, - /* U+84A0 */ 0xC959, 0xDDF2, 0xC95A, 0xC95B, 0xC95C, 0xC95D, 0xC95E, 0xC95F, - /* U+84A8 */ 0xC960, 0xC961, 0xC962, 0xC963, 0xC964, 0xC965, 0xC966, 0xD8E1, - /* U+84B0 */ 0xC967, 0xC968, 0xC6D1, 0xC969, 0xDDF4, 0xC96A, 0xC96B, 0xC96C, - /* U+84B8 */ 0xD5F4, 0xDDF3, 0xDDF0, 0xC96D, 0xC96E, 0xDDEC, 0xC96F, 0xDDEF, - /* U+84C0 */ 0xC970, 0xDDE8, 0xC971, 0xC972, 0xD0EE, 0xC973, 0xC974, 0xC975, - /* U+84C8 */ 0xC976, 0xC8D8, 0xDDEE, 0xC977, 0xC978, 0xDDE9, 0xC979, 0xC97A, - /* U+84D0 */ 0xDDEA, 0xCBF2, 0xC97B, 0xDDED, 0xC97C, 0xC97D, 0xB1CD, 0xC97E, - /* U+84D8 */ 0xC980, 0xC981, 0xC982, 0xC983, 0xC984, 0xC0B6, 0xC985, 0xBCBB, - /* U+84E0 */ 0xDDF1, 0xC986, 0xC987, 0xDDF7, 0xC988, 0xDDF6, 0xDDEB, 0xC989, - /* U+84E8 */ 0xC98A, 0xC98B, 0xC98C, 0xC98D, 0xC5EE, 0xC98E, 0xC98F, 0xC990, - /* U+84F0 */ 0xDDFB, 0xC991, 0xC992, 0xC993, 0xC994, 0xC995, 0xC996, 0xC997, - /* U+84F8 */ 0xC998, 0xC999, 0xC99A, 0xC99B, 0xDEA4, 0xC99C, 0xC99D, 0xDEA3, - /* U+8500 */ 0xC99E, 0xC99F, 0xC9A0, 0xCA40, 0xCA41, 0xCA42, 0xCA43, 0xCA44, - /* U+8508 */ 0xCA45, 0xCA46, 0xCA47, 0xCA48, 0xDDF8, 0xCA49, 0xCA4A, 0xCA4B, - /* U+8510 */ 0xCA4C, 0xC3EF, 0xCA4D, 0xC2FB, 0xCA4E, 0xCA4F, 0xCA50, 0xD5E1, - /* U+8518 */ 0xCA51, 0xCA52, 0xCEB5, 0xCA53, 0xCA54, 0xCA55, 0xCA56, 0xDDFD, - /* U+8520 */ 0xCA57, 0xB2CC, 0xCA58, 0xCA59, 0xCA5A, 0xCA5B, 0xCA5C, 0xCA5D, - /* U+8528 */ 0xCA5E, 0xCA5F, 0xCA60, 0xC4E8, 0xCADF, 0xCA61, 0xCA62, 0xCA63, - /* U+8530 */ 0xCA64, 0xCA65, 0xCA66, 0xCA67, 0xCA68, 0xCA69, 0xCA6A, 0xC7BE, - /* U+8538 */ 0xDDFA, 0xDDFC, 0xDDFE, 0xDEA2, 0xB0AA, 0xB1CE, 0xCA6B, 0xCA6C, - /* U+8540 */ 0xCA6D, 0xCA6E, 0xCA6F, 0xDEAC, 0xCA70, 0xCA71, 0xCA72, 0xCA73, - /* U+8548 */ 0xDEA6, 0xBDB6, 0xC8EF, 0xCA74, 0xCA75, 0xCA76, 0xCA77, 0xCA78, - /* U+8550 */ 0xCA79, 0xCA7A, 0xCA7B, 0xCA7C, 0xCA7D, 0xCA7E, 0xDEA1, 0xCA80, - /* U+8558 */ 0xCA81, 0xDEA5, 0xCA82, 0xCA83, 0xCA84, 0xCA85, 0xDEA9, 0xCA86, - /* U+8560 */ 0xCA87, 0xCA88, 0xCA89, 0xCA8A, 0xDEA8, 0xCA8B, 0xCA8C, 0xCA8D, - /* U+8568 */ 0xDEA7, 0xCA8E, 0xCA8F, 0xCA90, 0xCA91, 0xCA92, 0xCA93, 0xCA94, - /* U+8570 */ 0xCA95, 0xCA96, 0xDEAD, 0xCA97, 0xD4CC, 0xCA98, 0xCA99, 0xCA9A, - /* U+8578 */ 0xCA9B, 0xDEB3, 0xDEAA, 0xDEAE, 0xCA9C, 0xCA9D, 0xC0D9, 0xCA9E, - /* U+8580 */ 0xCA9F, 0xCAA0, 0xCB40, 0xCB41, 0xB1A1, 0xDEB6, 0xCB42, 0xDEB1, - /* U+8588 */ 0xCB43, 0xCB44, 0xCB45, 0xCB46, 0xCB47, 0xCB48, 0xCB49, 0xDEB2, - /* U+8590 */ 0xCB4A, 0xCB4B, 0xCB4C, 0xCB4D, 0xCB4E, 0xCB4F, 0xCB50, 0xCB51, - /* U+8598 */ 0xCB52, 0xCB53, 0xCB54, 0xD1A6, 0xDEB5, 0xCB55, 0xCB56, 0xCB57, - /* U+85A0 */ 0xCB58, 0xCB59, 0xCB5A, 0xCB5B, 0xDEAF, 0xCB5C, 0xCB5D, 0xCB5E, - /* U+85A8 */ 0xDEB0, 0xCB5F, 0xD0BD, 0xCB60, 0xCB61, 0xCB62, 0xDEB4, 0xCAED, - /* U+85B0 */ 0xDEB9, 0xCB63, 0xCB64, 0xCB65, 0xCB66, 0xCB67, 0xCB68, 0xDEB8, - /* U+85B8 */ 0xCB69, 0xDEB7, 0xCB6A, 0xCB6B, 0xCB6C, 0xCB6D, 0xCB6E, 0xCB6F, - /* U+85C0 */ 0xCB70, 0xDEBB, 0xCB71, 0xCB72, 0xCB73, 0xCB74, 0xCB75, 0xCB76, - /* U+85C8 */ 0xCB77, 0xBDE5, 0xCB78, 0xCB79, 0xCB7A, 0xCB7B, 0xCB7C, 0xB2D8, - /* U+85D0 */ 0xC3EA, 0xCB7D, 0xCB7E, 0xDEBA, 0xCB80, 0xC5BA, 0xCB81, 0xCB82, - /* U+85D8 */ 0xCB83, 0xCB84, 0xCB85, 0xCB86, 0xDEBC, 0xCB87, 0xCB88, 0xCB89, - /* U+85E0 */ 0xCB8A, 0xCB8B, 0xCB8C, 0xCB8D, 0xCCD9, 0xCB8E, 0xCB8F, 0xCB90, - /* U+85E8 */ 0xCB91, 0xB7AA, 0xCB92, 0xCB93, 0xCB94, 0xCB95, 0xCB96, 0xCB97, - /* U+85F0 */ 0xCB98, 0xCB99, 0xCB9A, 0xCB9B, 0xCB9C, 0xCB9D, 0xCB9E, 0xCB9F, - /* U+85F8 */ 0xCBA0, 0xCC40, 0xCC41, 0xD4E5, 0xCC42, 0xCC43, 0xCC44, 0xDEBD, - /* U+8600 */ 0xCC45, 0xCC46, 0xCC47, 0xCC48, 0xCC49, 0xDEBF, 0xCC4A, 0xCC4B, - /* U+8608 */ 0xCC4C, 0xCC4D, 0xCC4E, 0xCC4F, 0xCC50, 0xCC51, 0xCC52, 0xCC53, - /* U+8610 */ 0xCC54, 0xC4A2, 0xCC55, 0xCC56, 0xCC57, 0xCC58, 0xDEC1, 0xCC59, - /* U+8618 */ 0xCC5A, 0xCC5B, 0xCC5C, 0xCC5D, 0xCC5E, 0xCC5F, 0xCC60, 0xCC61, - /* U+8620 */ 0xCC62, 0xCC63, 0xCC64, 0xCC65, 0xCC66, 0xCC67, 0xCC68, 0xDEBE, - /* U+8628 */ 0xCC69, 0xDEC0, 0xCC6A, 0xCC6B, 0xCC6C, 0xCC6D, 0xCC6E, 0xCC6F, - /* U+8630 */ 0xCC70, 0xCC71, 0xCC72, 0xCC73, 0xCC74, 0xCC75, 0xCC76, 0xCC77, - /* U+8638 */ 0xD5BA, 0xCC78, 0xCC79, 0xCC7A, 0xDEC2, 0xCC7B, 0xCC7C, 0xCC7D, - /* U+8640 */ 0xCC7E, 0xCC80, 0xCC81, 0xCC82, 0xCC83, 0xCC84, 0xCC85, 0xCC86, - /* U+8648 */ 0xCC87, 0xCC88, 0xCC89, 0xCC8A, 0xCC8B, 0xF2AE, 0xBBA2, 0xC2B2, - /* U+8650 */ 0xC5B0, 0xC2C7, 0xCC8C, 0xCC8D, 0xF2AF, 0xCC8E, 0xCC8F, 0xCC90, - /* U+8658 */ 0xCC91, 0xCC92, 0xD0E9, 0xCC93, 0xCC94, 0xCC95, 0xD3DD, 0xCC96, - /* U+8660 */ 0xCC97, 0xCC98, 0xEBBD, 0xCC99, 0xCC9A, 0xCC9B, 0xCC9C, 0xCC9D, - /* U+8668 */ 0xCC9E, 0xCC9F, 0xCCA0, 0xB3E6, 0xF2B0, 0xCD40, 0xF2B1, 0xCD41, - /* U+8670 */ 0xCD42, 0xCAAD, 0xCD43, 0xCD44, 0xCD45, 0xCD46, 0xCD47, 0xCD48, - /* U+8678 */ 0xCD49, 0xBAE7, 0xF2B3, 0xF2B5, 0xF2B4, 0xCBE4, 0xCFBA, 0xF2B2, - /* U+8680 */ 0xCAB4, 0xD2CF, 0xC2EC, 0xCD4A, 0xCD4B, 0xCD4C, 0xCD4D, 0xCD4E, - /* U+8688 */ 0xCD4F, 0xCD50, 0xCEC3, 0xF2B8, 0xB0F6, 0xF2B7, 0xCD51, 0xCD52, - /* U+8690 */ 0xCD53, 0xCD54, 0xCD55, 0xF2BE, 0xCD56, 0xB2CF, 0xCD57, 0xCD58, - /* U+8698 */ 0xCD59, 0xCD5A, 0xCD5B, 0xCD5C, 0xD1C1, 0xF2BA, 0xCD5D, 0xCD5E, - /* U+86A0 */ 0xCD5F, 0xCD60, 0xCD61, 0xF2BC, 0xD4E9, 0xCD62, 0xCD63, 0xF2BB, - /* U+86A8 */ 0xF2B6, 0xF2BF, 0xF2BD, 0xCD64, 0xF2B9, 0xCD65, 0xCD66, 0xF2C7, - /* U+86B0 */ 0xF2C4, 0xF2C6, 0xCD67, 0xCD68, 0xF2CA, 0xF2C2, 0xF2C0, 0xCD69, - /* U+86B8 */ 0xCD6A, 0xCD6B, 0xF2C5, 0xCD6C, 0xCD6D, 0xCD6E, 0xCD6F, 0xCD70, - /* U+86C0 */ 0xD6FB, 0xCD71, 0xCD72, 0xCD73, 0xF2C1, 0xCD74, 0xC7F9, 0xC9DF, - /* U+86C8 */ 0xCD75, 0xF2C8, 0xB9C6, 0xB5B0, 0xCD76, 0xCD77, 0xF2C3, 0xF2C9, - /* U+86D0 */ 0xF2D0, 0xF2D6, 0xCD78, 0xCD79, 0xBBD7, 0xCD7A, 0xCD7B, 0xCD7C, - /* U+86D8 */ 0xF2D5, 0xCDDC, 0xCD7D, 0xD6EB, 0xCD7E, 0xCD80, 0xF2D2, 0xF2D4, - /* U+86E0 */ 0xCD81, 0xCD82, 0xCD83, 0xCD84, 0xB8F2, 0xCD85, 0xCD86, 0xCD87, - /* U+86E8 */ 0xCD88, 0xF2CB, 0xCD89, 0xCD8A, 0xCD8B, 0xF2CE, 0xC2F9, 0xCD8C, - /* U+86F0 */ 0xD5DD, 0xF2CC, 0xF2CD, 0xF2CF, 0xF2D3, 0xCD8D, 0xCD8E, 0xCD8F, - /* U+86F8 */ 0xF2D9, 0xD3BC, 0xCD90, 0xCD91, 0xCD92, 0xCD93, 0xB6EA, 0xCD94, - /* U+8700 */ 0xCAF1, 0xCD95, 0xB7E4, 0xF2D7, 0xCD96, 0xCD97, 0xCD98, 0xF2D8, - /* U+8708 */ 0xF2DA, 0xF2DD, 0xF2DB, 0xCD99, 0xCD9A, 0xF2DC, 0xCD9B, 0xCD9C, - /* U+8710 */ 0xCD9D, 0xCD9E, 0xD1D1, 0xF2D1, 0xCD9F, 0xCDC9, 0xCDA0, 0xCECF, - /* U+8718 */ 0xD6A9, 0xCE40, 0xF2E3, 0xCE41, 0xC3DB, 0xCE42, 0xF2E0, 0xCE43, - /* U+8720 */ 0xCE44, 0xC0AF, 0xF2EC, 0xF2DE, 0xCE45, 0xF2E1, 0xCE46, 0xCE47, - /* U+8728 */ 0xCE48, 0xF2E8, 0xCE49, 0xCE4A, 0xCE4B, 0xCE4C, 0xF2E2, 0xCE4D, - /* U+8730 */ 0xCE4E, 0xF2E7, 0xCE4F, 0xCE50, 0xF2E6, 0xCE51, 0xCE52, 0xF2E9, - /* U+8738 */ 0xCE53, 0xCE54, 0xCE55, 0xF2DF, 0xCE56, 0xCE57, 0xF2E4, 0xF2EA, - /* U+8740 */ 0xCE58, 0xCE59, 0xCE5A, 0xCE5B, 0xCE5C, 0xCE5D, 0xCE5E, 0xD3AC, - /* U+8748 */ 0xF2E5, 0xB2F5, 0xCE5F, 0xCE60, 0xF2F2, 0xCE61, 0xD0AB, 0xCE62, - /* U+8750 */ 0xCE63, 0xCE64, 0xCE65, 0xF2F5, 0xCE66, 0xCE67, 0xCE68, 0xBBC8, - /* U+8758 */ 0xCE69, 0xF2F9, 0xCE6A, 0xCE6B, 0xCE6C, 0xCE6D, 0xCE6E, 0xCE6F, - /* U+8760 */ 0xF2F0, 0xCE70, 0xCE71, 0xF2F6, 0xF2F8, 0xF2FA, 0xCE72, 0xCE73, - /* U+8768 */ 0xCE74, 0xCE75, 0xCE76, 0xCE77, 0xCE78, 0xCE79, 0xF2F3, 0xCE7A, - /* U+8770 */ 0xF2F1, 0xCE7B, 0xCE7C, 0xCE7D, 0xBAFB, 0xCE7E, 0xB5FB, 0xCE80, - /* U+8778 */ 0xCE81, 0xCE82, 0xCE83, 0xF2EF, 0xF2F7, 0xF2ED, 0xF2EE, 0xCE84, - /* U+8780 */ 0xCE85, 0xCE86, 0xF2EB, 0xF3A6, 0xCE87, 0xF3A3, 0xCE88, 0xCE89, - /* U+8788 */ 0xF3A2, 0xCE8A, 0xCE8B, 0xF2F4, 0xCE8C, 0xC8DA, 0xCE8D, 0xCE8E, - /* U+8790 */ 0xCE8F, 0xCE90, 0xCE91, 0xF2FB, 0xCE92, 0xCE93, 0xCE94, 0xF3A5, - /* U+8798 */ 0xCE95, 0xCE96, 0xCE97, 0xCE98, 0xCE99, 0xCE9A, 0xCE9B, 0xC3F8, - /* U+87A0 */ 0xCE9C, 0xCE9D, 0xCE9E, 0xCE9F, 0xCEA0, 0xCF40, 0xCF41, 0xCF42, - /* U+87A8 */ 0xF2FD, 0xCF43, 0xCF44, 0xF3A7, 0xF3A9, 0xF3A4, 0xCF45, 0xF2FC, - /* U+87B0 */ 0xCF46, 0xCF47, 0xCF48, 0xF3AB, 0xCF49, 0xF3AA, 0xCF4A, 0xCF4B, - /* U+87B8 */ 0xCF4C, 0xCF4D, 0xC2DD, 0xCF4E, 0xCF4F, 0xF3AE, 0xCF50, 0xCF51, - /* U+87C0 */ 0xF3B0, 0xCF52, 0xCF53, 0xCF54, 0xCF55, 0xCF56, 0xF3A1, 0xCF57, - /* U+87C8 */ 0xCF58, 0xCF59, 0xF3B1, 0xF3AC, 0xCF5A, 0xCF5B, 0xCF5C, 0xCF5D, - /* U+87D0 */ 0xCF5E, 0xF3AF, 0xF2FE, 0xF3AD, 0xCF5F, 0xCF60, 0xCF61, 0xCF62, - /* U+87D8 */ 0xCF63, 0xCF64, 0xCF65, 0xF3B2, 0xCF66, 0xCF67, 0xCF68, 0xCF69, - /* U+87E0 */ 0xF3B4, 0xCF6A, 0xCF6B, 0xCF6C, 0xCF6D, 0xF3A8, 0xCF6E, 0xCF6F, - /* U+87E8 */ 0xCF70, 0xCF71, 0xF3B3, 0xCF72, 0xCF73, 0xCF74, 0xF3B5, 0xCF75, - /* U+87F0 */ 0xCF76, 0xCF77, 0xCF78, 0xCF79, 0xCF7A, 0xCF7B, 0xCF7C, 0xCF7D, - /* U+87F8 */ 0xCF7E, 0xD0B7, 0xCF80, 0xCF81, 0xCF82, 0xCF83, 0xF3B8, 0xCF84, - /* U+8800 */ 0xCF85, 0xCF86, 0xCF87, 0xD9F9, 0xCF88, 0xCF89, 0xCF8A, 0xCF8B, - /* U+8808 */ 0xCF8C, 0xCF8D, 0xF3B9, 0xCF8E, 0xCF8F, 0xCF90, 0xCF91, 0xCF92, - /* U+8810 */ 0xCF93, 0xCF94, 0xCF95, 0xF3B7, 0xCF96, 0xC8E4, 0xF3B6, 0xCF97, - /* U+8818 */ 0xCF98, 0xCF99, 0xCF9A, 0xF3BA, 0xCF9B, 0xCF9C, 0xCF9D, 0xCF9E, - /* U+8820 */ 0xCF9F, 0xF3BB, 0xB4C0, 0xCFA0, 0xD040, 0xD041, 0xD042, 0xD043, - /* U+8828 */ 0xD044, 0xD045, 0xD046, 0xD047, 0xD048, 0xD049, 0xD04A, 0xD04B, - /* U+8830 */ 0xD04C, 0xD04D, 0xEEC3, 0xD04E, 0xD04F, 0xD050, 0xD051, 0xD052, - /* U+8838 */ 0xD053, 0xF3BC, 0xD054, 0xD055, 0xF3BD, 0xD056, 0xD057, 0xD058, - /* U+8840 */ 0xD1AA, 0xD059, 0xD05A, 0xD05B, 0xF4AC, 0xD0C6, 0xD05C, 0xD05D, - /* U+8848 */ 0xD05E, 0xD05F, 0xD060, 0xD061, 0xD0D0, 0xD1DC, 0xD062, 0xD063, - /* U+8850 */ 0xD064, 0xD065, 0xD066, 0xD067, 0xCFCE, 0xD068, 0xD069, 0xBDD6, - /* U+8858 */ 0xD06A, 0xD1C3, 0xD06B, 0xD06C, 0xD06D, 0xD06E, 0xD06F, 0xD070, - /* U+8860 */ 0xD071, 0xBAE2, 0xE1E9, 0xD2C2, 0xF1C2, 0xB2B9, 0xD072, 0xD073, - /* U+8868 */ 0xB1ED, 0xF1C3, 0xD074, 0xC9C0, 0xB3C4, 0xD075, 0xD9F2, 0xD076, - /* U+8870 */ 0xCBA5, 0xD077, 0xF1C4, 0xD078, 0xD079, 0xD07A, 0xD07B, 0xD6D4, - /* U+8878 */ 0xD07C, 0xD07D, 0xD07E, 0xD080, 0xD081, 0xF1C5, 0xF4C0, 0xF1C6, - /* U+8880 */ 0xD082, 0xD4AC, 0xF1C7, 0xD083, 0xB0C0, 0xF4C1, 0xD084, 0xD085, - /* U+8888 */ 0xF4C2, 0xD086, 0xD087, 0xB4FC, 0xD088, 0xC5DB, 0xD089, 0xD08A, - /* U+8890 */ 0xD08B, 0xD08C, 0xCCBB, 0xD08D, 0xD08E, 0xD08F, 0xD0E4, 0xD090, - /* U+8898 */ 0xD091, 0xD092, 0xD093, 0xD094, 0xCDE0, 0xD095, 0xD096, 0xD097, - /* U+88A0 */ 0xD098, 0xD099, 0xF1C8, 0xD09A, 0xD9F3, 0xD09B, 0xD09C, 0xD09D, - /* U+88A8 */ 0xD09E, 0xD09F, 0xD0A0, 0xB1BB, 0xD140, 0xCFAE, 0xD141, 0xD142, - /* U+88B0 */ 0xD143, 0xB8A4, 0xD144, 0xD145, 0xD146, 0xD147, 0xD148, 0xF1CA, - /* U+88B8 */ 0xD149, 0xD14A, 0xD14B, 0xD14C, 0xF1CB, 0xD14D, 0xD14E, 0xD14F, - /* U+88C0 */ 0xD150, 0xB2C3, 0xC1D1, 0xD151, 0xD152, 0xD7B0, 0xF1C9, 0xD153, - /* U+88C8 */ 0xD154, 0xF1CC, 0xD155, 0xD156, 0xD157, 0xD158, 0xF1CE, 0xD159, - /* U+88D0 */ 0xD15A, 0xD15B, 0xD9F6, 0xD15C, 0xD2E1, 0xD4A3, 0xD15D, 0xD15E, - /* U+88D8 */ 0xF4C3, 0xC8B9, 0xD15F, 0xD160, 0xD161, 0xD162, 0xD163, 0xF4C4, - /* U+88E0 */ 0xD164, 0xD165, 0xF1CD, 0xF1CF, 0xBFE3, 0xF1D0, 0xD166, 0xD167, - /* U+88E8 */ 0xF1D4, 0xD168, 0xD169, 0xD16A, 0xD16B, 0xD16C, 0xD16D, 0xD16E, - /* U+88F0 */ 0xF1D6, 0xF1D1, 0xD16F, 0xC9D1, 0xC5E1, 0xD170, 0xD171, 0xD172, - /* U+88F8 */ 0xC2E3, 0xB9FC, 0xD173, 0xD174, 0xF1D3, 0xD175, 0xF1D5, 0xD176, - /* U+8900 */ 0xD177, 0xD178, 0xB9D3, 0xD179, 0xD17A, 0xD17B, 0xD17C, 0xD17D, - /* U+8908 */ 0xD17E, 0xD180, 0xF1DB, 0xD181, 0xD182, 0xD183, 0xD184, 0xD185, - /* U+8910 */ 0xBAD6, 0xD186, 0xB0FD, 0xF1D9, 0xD187, 0xD188, 0xD189, 0xD18A, - /* U+8918 */ 0xD18B, 0xF1D8, 0xF1D2, 0xF1DA, 0xD18C, 0xD18D, 0xD18E, 0xD18F, - /* U+8920 */ 0xD190, 0xF1D7, 0xD191, 0xD192, 0xD193, 0xC8EC, 0xD194, 0xD195, - /* U+8928 */ 0xD196, 0xD197, 0xCDCA, 0xF1DD, 0xD198, 0xD199, 0xD19A, 0xD19B, - /* U+8930 */ 0xE5BD, 0xD19C, 0xD19D, 0xD19E, 0xF1DC, 0xD19F, 0xF1DE, 0xD1A0, - /* U+8938 */ 0xD240, 0xD241, 0xD242, 0xD243, 0xD244, 0xD245, 0xD246, 0xD247, - /* U+8940 */ 0xD248, 0xF1DF, 0xD249, 0xD24A, 0xCFE5, 0xD24B, 0xD24C, 0xD24D, - /* U+8948 */ 0xD24E, 0xD24F, 0xD250, 0xD251, 0xD252, 0xD253, 0xD254, 0xD255, - /* U+8950 */ 0xD256, 0xD257, 0xD258, 0xD259, 0xD25A, 0xD25B, 0xD25C, 0xD25D, - /* U+8958 */ 0xD25E, 0xD25F, 0xD260, 0xD261, 0xD262, 0xD263, 0xF4C5, 0xBDF3, - /* U+8960 */ 0xD264, 0xD265, 0xD266, 0xD267, 0xD268, 0xD269, 0xF1E0, 0xD26A, - /* U+8968 */ 0xD26B, 0xD26C, 0xD26D, 0xD26E, 0xD26F, 0xD270, 0xD271, 0xD272, - /* U+8970 */ 0xD273, 0xD274, 0xD275, 0xD276, 0xD277, 0xD278, 0xD279, 0xD27A, - /* U+8978 */ 0xD27B, 0xD27C, 0xD27D, 0xF1E1, 0xD27E, 0xD280, 0xD281, 0xCEF7, - /* U+8980 */ 0xD282, 0xD2AA, 0xD283, 0xF1FB, 0xD284, 0xD285, 0xB8B2, 0xD286, - /* U+8988 */ 0xD287, 0xD288, 0xD289, 0xD28A, 0xD28B, 0xD28C, 0xD28D, 0xD28E, - /* U+8990 */ 0xD28F, 0xD290, 0xD291, 0xD292, 0xD293, 0xD294, 0xD295, 0xD296, - /* U+8998 */ 0xD297, 0xD298, 0xD299, 0xD29A, 0xD29B, 0xD29C, 0xD29D, 0xD29E, - /* U+89A0 */ 0xD29F, 0xD2A0, 0xD340, 0xD341, 0xD342, 0xD343, 0xD344, 0xD345, - /* U+89A8 */ 0xD346, 0xD347, 0xD348, 0xD349, 0xD34A, 0xD34B, 0xD34C, 0xD34D, - /* U+89B0 */ 0xD34E, 0xD34F, 0xD350, 0xD351, 0xD352, 0xD353, 0xD354, 0xD355, - /* U+89B8 */ 0xD356, 0xD357, 0xD358, 0xD359, 0xD35A, 0xD35B, 0xD35C, 0xD35D, - /* U+89C0 */ 0xD35E, 0xBCFB, 0xB9DB, 0xD35F, 0xB9E6, 0xC3D9, 0xCAD3, 0xEAE8, - /* U+89C8 */ 0xC0C0, 0xBEF5, 0xEAE9, 0xEAEA, 0xEAEB, 0xD360, 0xEAEC, 0xEAED, - /* U+89D0 */ 0xEAEE, 0xEAEF, 0xBDC7, 0xD361, 0xD362, 0xD363, 0xF5FB, 0xD364, - /* U+89D8 */ 0xD365, 0xD366, 0xF5FD, 0xD367, 0xF5FE, 0xD368, 0xF5FC, 0xD369, - /* U+89E0 */ 0xD36A, 0xD36B, 0xD36C, 0xBDE2, 0xD36D, 0xF6A1, 0xB4A5, 0xD36E, - /* U+89E8 */ 0xD36F, 0xD370, 0xD371, 0xF6A2, 0xD372, 0xD373, 0xD374, 0xF6A3, - /* U+89F0 */ 0xD375, 0xD376, 0xD377, 0xECB2, 0xD378, 0xD379, 0xD37A, 0xD37B, - /* U+89F8 */ 0xD37C, 0xD37D, 0xD37E, 0xD380, 0xD381, 0xD382, 0xD383, 0xD384, - /* U+8A00 */ 0xD1D4, 0xD385, 0xD386, 0xD387, 0xD388, 0xD389, 0xD38A, 0xD9EA, - /* U+8A08 */ 0xD38B, 0xD38C, 0xD38D, 0xD38E, 0xD38F, 0xD390, 0xD391, 0xD392, - /* U+8A10 */ 0xD393, 0xD394, 0xD395, 0xD396, 0xD397, 0xD398, 0xD399, 0xD39A, - /* U+8A18 */ 0xD39B, 0xD39C, 0xD39D, 0xD39E, 0xD39F, 0xD3A0, 0xD440, 0xD441, - /* U+8A20 */ 0xD442, 0xD443, 0xD444, 0xD445, 0xD446, 0xD447, 0xD448, 0xD449, - /* U+8A28 */ 0xD44A, 0xD44B, 0xD44C, 0xD44D, 0xD44E, 0xD44F, 0xD450, 0xD451, - /* U+8A30 */ 0xD452, 0xD453, 0xD454, 0xD455, 0xD456, 0xD457, 0xD458, 0xD459, - /* U+8A38 */ 0xD45A, 0xD45B, 0xD45C, 0xD45D, 0xD45E, 0xD45F, 0xF6A4, 0xD460, - /* U+8A40 */ 0xD461, 0xD462, 0xD463, 0xD464, 0xD465, 0xD466, 0xD467, 0xD468, - /* U+8A48 */ 0xEEBA, 0xD469, 0xD46A, 0xD46B, 0xD46C, 0xD46D, 0xD46E, 0xD46F, - /* U+8A50 */ 0xD470, 0xD471, 0xD472, 0xD473, 0xD474, 0xD475, 0xD476, 0xD477, - /* U+8A58 */ 0xD478, 0xD479, 0xD47A, 0xD47B, 0xD47C, 0xD47D, 0xD47E, 0xD480, - /* U+8A60 */ 0xD481, 0xD482, 0xD483, 0xD484, 0xD485, 0xD486, 0xD487, 0xD488, - /* U+8A68 */ 0xD489, 0xD48A, 0xD48B, 0xD48C, 0xD48D, 0xD48E, 0xD48F, 0xD490, - /* U+8A70 */ 0xD491, 0xD492, 0xD493, 0xD494, 0xD495, 0xD496, 0xD497, 0xD498, - /* U+8A78 */ 0xD499, 0xD5B2, 0xD49A, 0xD49B, 0xD49C, 0xD49D, 0xD49E, 0xD49F, - /* U+8A80 */ 0xD4A0, 0xD540, 0xD541, 0xD542, 0xD543, 0xD544, 0xD545, 0xD546, - /* U+8A88 */ 0xD547, 0xD3FE, 0xCCDC, 0xD548, 0xD549, 0xD54A, 0xD54B, 0xD54C, - /* U+8A90 */ 0xD54D, 0xD54E, 0xD54F, 0xCAC4, 0xD550, 0xD551, 0xD552, 0xD553, - /* U+8A98 */ 0xD554, 0xD555, 0xD556, 0xD557, 0xD558, 0xD559, 0xD55A, 0xD55B, - /* U+8AA0 */ 0xD55C, 0xD55D, 0xD55E, 0xD55F, 0xD560, 0xD561, 0xD562, 0xD563, - /* U+8AA8 */ 0xD564, 0xD565, 0xD566, 0xD567, 0xD568, 0xD569, 0xD56A, 0xD56B, - /* U+8AB0 */ 0xD56C, 0xD56D, 0xD56E, 0xD56F, 0xD570, 0xD571, 0xD572, 0xD573, - /* U+8AB8 */ 0xD574, 0xD575, 0xD576, 0xD577, 0xD578, 0xD579, 0xD57A, 0xD57B, - /* U+8AC0 */ 0xD57C, 0xD57D, 0xD57E, 0xD580, 0xD581, 0xD582, 0xD583, 0xD584, - /* U+8AC8 */ 0xD585, 0xD586, 0xD587, 0xD588, 0xD589, 0xD58A, 0xD58B, 0xD58C, - /* U+8AD0 */ 0xD58D, 0xD58E, 0xD58F, 0xD590, 0xD591, 0xD592, 0xD593, 0xD594, - /* U+8AD8 */ 0xD595, 0xD596, 0xD597, 0xD598, 0xD599, 0xD59A, 0xD59B, 0xD59C, - /* U+8AE0 */ 0xD59D, 0xD59E, 0xD59F, 0xD5A0, 0xD640, 0xD641, 0xD642, 0xD643, - /* U+8AE8 */ 0xD644, 0xD645, 0xD646, 0xD647, 0xD648, 0xD649, 0xD64A, 0xD64B, - /* U+8AF0 */ 0xD64C, 0xD64D, 0xD64E, 0xD64F, 0xD650, 0xD651, 0xD652, 0xD653, - /* U+8AF8 */ 0xD654, 0xD655, 0xD656, 0xD657, 0xD658, 0xD659, 0xD65A, 0xD65B, - /* U+8B00 */ 0xD65C, 0xD65D, 0xD65E, 0xD65F, 0xD660, 0xD661, 0xD662, 0xE5C0, - /* U+8B08 */ 0xD663, 0xD664, 0xD665, 0xD666, 0xD667, 0xD668, 0xD669, 0xD66A, - /* U+8B10 */ 0xD66B, 0xD66C, 0xD66D, 0xD66E, 0xD66F, 0xD670, 0xD671, 0xD672, - /* U+8B18 */ 0xD673, 0xD674, 0xD675, 0xD676, 0xD677, 0xD678, 0xD679, 0xD67A, - /* U+8B20 */ 0xD67B, 0xD67C, 0xD67D, 0xD67E, 0xD680, 0xD681, 0xF6A5, 0xD682, - /* U+8B28 */ 0xD683, 0xD684, 0xD685, 0xD686, 0xD687, 0xD688, 0xD689, 0xD68A, - /* U+8B30 */ 0xD68B, 0xD68C, 0xD68D, 0xD68E, 0xD68F, 0xD690, 0xD691, 0xD692, - /* U+8B38 */ 0xD693, 0xD694, 0xD695, 0xD696, 0xD697, 0xD698, 0xD699, 0xD69A, - /* U+8B40 */ 0xD69B, 0xD69C, 0xD69D, 0xD69E, 0xD69F, 0xD6A0, 0xD740, 0xD741, - /* U+8B48 */ 0xD742, 0xD743, 0xD744, 0xD745, 0xD746, 0xD747, 0xD748, 0xD749, - /* U+8B50 */ 0xD74A, 0xD74B, 0xD74C, 0xD74D, 0xD74E, 0xD74F, 0xD750, 0xD751, - /* U+8B58 */ 0xD752, 0xD753, 0xD754, 0xD755, 0xD756, 0xD757, 0xD758, 0xD759, - /* U+8B60 */ 0xD75A, 0xD75B, 0xD75C, 0xD75D, 0xD75E, 0xD75F, 0xBEAF, 0xD760, - /* U+8B68 */ 0xD761, 0xD762, 0xD763, 0xD764, 0xC6A9, 0xD765, 0xD766, 0xD767, - /* U+8B70 */ 0xD768, 0xD769, 0xD76A, 0xD76B, 0xD76C, 0xD76D, 0xD76E, 0xD76F, - /* U+8B78 */ 0xD770, 0xD771, 0xD772, 0xD773, 0xD774, 0xD775, 0xD776, 0xD777, - /* U+8B80 */ 0xD778, 0xD779, 0xD77A, 0xD77B, 0xD77C, 0xD77D, 0xD77E, 0xD780, - /* U+8B88 */ 0xD781, 0xD782, 0xD783, 0xD784, 0xD785, 0xD786, 0xD787, 0xD788, - /* U+8B90 */ 0xD789, 0xD78A, 0xD78B, 0xD78C, 0xD78D, 0xD78E, 0xD78F, 0xD790, - /* U+8B98 */ 0xD791, 0xD792, 0xD793, 0xD794, 0xD795, 0xD796, 0xD797, 0xD798, - /* U+8BA0 */ 0xDAA5, 0xBCC6, 0xB6A9, 0xB8BC, 0xC8CF, 0xBCA5, 0xDAA6, 0xDAA7, - /* U+8BA8 */ 0xCCD6, 0xC8C3, 0xDAA8, 0xC6FD, 0xD799, 0xD1B5, 0xD2E9, 0xD1B6, - /* U+8BB0 */ 0xBCC7, 0xD79A, 0xBDB2, 0xBBE4, 0xDAA9, 0xDAAA, 0xD1C8, 0xDAAB, - /* U+8BB8 */ 0xD0ED, 0xB6EF, 0xC2DB, 0xD79B, 0xCBCF, 0xB7ED, 0xC9E8, 0xB7C3, - /* U+8BC0 */ 0xBEF7, 0xD6A4, 0xDAAC, 0xDAAD, 0xC6C0, 0xD7E7, 0xCAB6, 0xD79C, - /* U+8BC8 */ 0xD5A9, 0xCBDF, 0xD5EF, 0xDAAE, 0xD6DF, 0xB4CA, 0xDAB0, 0xDAAF, - /* U+8BD0 */ 0xD79D, 0xD2EB, 0xDAB1, 0xDAB2, 0xDAB3, 0xCAD4, 0xDAB4, 0xCAAB, - /* U+8BD8 */ 0xDAB5, 0xDAB6, 0xB3CF, 0xD6EF, 0xDAB7, 0xBBB0, 0xB5AE, 0xDAB8, - /* U+8BE0 */ 0xDAB9, 0xB9EE, 0xD1AF, 0xD2E8, 0xDABA, 0xB8C3, 0xCFEA, 0xB2EF, - /* U+8BE8 */ 0xDABB, 0xDABC, 0xD79E, 0xBDEB, 0xCEDC, 0xD3EF, 0xDABD, 0xCEF3, - /* U+8BF0 */ 0xDABE, 0xD3D5, 0xBBE5, 0xDABF, 0xCBB5, 0xCBD0, 0xDAC0, 0xC7EB, - /* U+8BF8 */ 0xD6EE, 0xDAC1, 0xC5B5, 0xB6C1, 0xDAC2, 0xB7CC, 0xBFCE, 0xDAC3, - /* U+8C00 */ 0xDAC4, 0xCBAD, 0xDAC5, 0xB5F7, 0xDAC6, 0xC1C2, 0xD7BB, 0xDAC7, - /* U+8C08 */ 0xCCB8, 0xD79F, 0xD2EA, 0xC4B1, 0xDAC8, 0xB5FD, 0xBBD1, 0xDAC9, - /* U+8C10 */ 0xD0B3, 0xDACA, 0xDACB, 0xCEBD, 0xDACC, 0xDACD, 0xDACE, 0xB2F7, - /* U+8C18 */ 0xDAD1, 0xDACF, 0xD1E8, 0xDAD0, 0xC3D5, 0xDAD2, 0xD7A0, 0xDAD3, - /* U+8C20 */ 0xDAD4, 0xDAD5, 0xD0BB, 0xD2A5, 0xB0F9, 0xDAD6, 0xC7AB, 0xDAD7, - /* U+8C28 */ 0xBDF7, 0xC3A1, 0xDAD8, 0xDAD9, 0xC3FD, 0xCCB7, 0xDADA, 0xDADB, - /* U+8C30 */ 0xC0BE, 0xC6D7, 0xDADC, 0xDADD, 0xC7B4, 0xDADE, 0xDADF, 0xB9C8, - /* U+8C38 */ 0xD840, 0xD841, 0xD842, 0xD843, 0xD844, 0xD845, 0xD846, 0xD847, - /* U+8C40 */ 0xD848, 0xBBED, 0xD849, 0xD84A, 0xD84B, 0xD84C, 0xB6B9, 0xF4F8, - /* U+8C48 */ 0xD84D, 0xF4F9, 0xD84E, 0xD84F, 0xCDE3, 0xD850, 0xD851, 0xD852, - /* U+8C50 */ 0xD853, 0xD854, 0xD855, 0xD856, 0xD857, 0xF5B9, 0xD858, 0xD859, - /* U+8C58 */ 0xD85A, 0xD85B, 0xEBE0, 0xD85C, 0xD85D, 0xD85E, 0xD85F, 0xD860, - /* U+8C60 */ 0xD861, 0xCFF3, 0xBBBF, 0xD862, 0xD863, 0xD864, 0xD865, 0xD866, - /* U+8C68 */ 0xD867, 0xD868, 0xBAC0, 0xD4A5, 0xD869, 0xD86A, 0xD86B, 0xD86C, - /* U+8C70 */ 0xD86D, 0xD86E, 0xD86F, 0xE1D9, 0xD870, 0xD871, 0xD872, 0xD873, - /* U+8C78 */ 0xF5F4, 0xB1AA, 0xB2F2, 0xD874, 0xD875, 0xD876, 0xD877, 0xD878, - /* U+8C80 */ 0xD879, 0xD87A, 0xF5F5, 0xD87B, 0xD87C, 0xF5F7, 0xD87D, 0xD87E, - /* U+8C88 */ 0xD880, 0xBAD1, 0xF5F6, 0xD881, 0xC3B2, 0xD882, 0xD883, 0xD884, - /* U+8C90 */ 0xD885, 0xD886, 0xD887, 0xD888, 0xF5F9, 0xD889, 0xD88A, 0xD88B, - /* U+8C98 */ 0xF5F8, 0xD88C, 0xD88D, 0xD88E, 0xD88F, 0xD890, 0xD891, 0xD892, - /* U+8CA0 */ 0xD893, 0xD894, 0xD895, 0xD896, 0xD897, 0xD898, 0xD899, 0xD89A, - /* U+8CA8 */ 0xD89B, 0xD89C, 0xD89D, 0xD89E, 0xD89F, 0xD8A0, 0xD940, 0xD941, - /* U+8CB0 */ 0xD942, 0xD943, 0xD944, 0xD945, 0xD946, 0xD947, 0xD948, 0xD949, - /* U+8CB8 */ 0xD94A, 0xD94B, 0xD94C, 0xD94D, 0xD94E, 0xD94F, 0xD950, 0xD951, - /* U+8CC0 */ 0xD952, 0xD953, 0xD954, 0xD955, 0xD956, 0xD957, 0xD958, 0xD959, - /* U+8CC8 */ 0xD95A, 0xD95B, 0xD95C, 0xD95D, 0xD95E, 0xD95F, 0xD960, 0xD961, - /* U+8CD0 */ 0xD962, 0xD963, 0xD964, 0xD965, 0xD966, 0xD967, 0xD968, 0xD969, - /* U+8CD8 */ 0xD96A, 0xD96B, 0xD96C, 0xD96D, 0xD96E, 0xD96F, 0xD970, 0xD971, - /* U+8CE0 */ 0xD972, 0xD973, 0xD974, 0xD975, 0xD976, 0xD977, 0xD978, 0xD979, - /* U+8CE8 */ 0xD97A, 0xD97B, 0xD97C, 0xD97D, 0xD97E, 0xD980, 0xD981, 0xD982, - /* U+8CF0 */ 0xD983, 0xD984, 0xD985, 0xD986, 0xD987, 0xD988, 0xD989, 0xD98A, - /* U+8CF8 */ 0xD98B, 0xD98C, 0xD98D, 0xD98E, 0xD98F, 0xD990, 0xD991, 0xD992, - /* U+8D00 */ 0xD993, 0xD994, 0xD995, 0xD996, 0xD997, 0xD998, 0xD999, 0xD99A, - /* U+8D08 */ 0xD99B, 0xD99C, 0xD99D, 0xD99E, 0xD99F, 0xD9A0, 0xDA40, 0xDA41, - /* U+8D10 */ 0xDA42, 0xDA43, 0xDA44, 0xDA45, 0xDA46, 0xDA47, 0xDA48, 0xDA49, - /* U+8D18 */ 0xDA4A, 0xDA4B, 0xDA4C, 0xDA4D, 0xDA4E, 0xB1B4, 0xD5EA, 0xB8BA, - /* U+8D20 */ 0xDA4F, 0xB9B1, 0xB2C6, 0xD4F0, 0xCFCD, 0xB0DC, 0xD5CB, 0xBBF5, - /* U+8D28 */ 0xD6CA, 0xB7B7, 0xCCB0, 0xC6B6, 0xB1E1, 0xB9BA, 0xD6FC, 0xB9E1, - /* U+8D30 */ 0xB7A1, 0xBCFA, 0xEADA, 0xEADB, 0xCCF9, 0xB9F3, 0xEADC, 0xB4FB, - /* U+8D38 */ 0xC3B3, 0xB7D1, 0xBAD8, 0xEADD, 0xD4F4, 0xEADE, 0xBCD6, 0xBBDF, - /* U+8D40 */ 0xEADF, 0xC1DE, 0xC2B8, 0xD4DF, 0xD7CA, 0xEAE0, 0xEAE1, 0xEAE4, - /* U+8D48 */ 0xEAE2, 0xEAE3, 0xC9DE, 0xB8B3, 0xB6C4, 0xEAE5, 0xCAEA, 0xC9CD, - /* U+8D50 */ 0xB4CD, 0xDA50, 0xDA51, 0xE2D9, 0xC5E2, 0xEAE6, 0xC0B5, 0xDA52, - /* U+8D58 */ 0xD7B8, 0xEAE7, 0xD7AC, 0xC8FC, 0xD8D3, 0xD8CD, 0xD4DE, 0xDA53, - /* U+8D60 */ 0xD4F9, 0xC9C4, 0xD3AE, 0xB8D3, 0xB3E0, 0xDA54, 0xC9E2, 0xF4F6, - /* U+8D68 */ 0xDA55, 0xDA56, 0xDA57, 0xBAD5, 0xDA58, 0xF4F7, 0xDA59, 0xDA5A, - /* U+8D70 */ 0xD7DF, 0xDA5B, 0xDA5C, 0xF4F1, 0xB8B0, 0xD5D4, 0xB8CF, 0xC6F0, - /* U+8D78 */ 0xDA5D, 0xDA5E, 0xDA5F, 0xDA60, 0xDA61, 0xDA62, 0xDA63, 0xDA64, - /* U+8D80 */ 0xDA65, 0xB3C3, 0xDA66, 0xDA67, 0xF4F2, 0xB3AC, 0xDA68, 0xDA69, - /* U+8D88 */ 0xDA6A, 0xDA6B, 0xD4BD, 0xC7F7, 0xDA6C, 0xDA6D, 0xDA6E, 0xDA6F, - /* U+8D90 */ 0xDA70, 0xF4F4, 0xDA71, 0xDA72, 0xF4F3, 0xDA73, 0xDA74, 0xDA75, - /* U+8D98 */ 0xDA76, 0xDA77, 0xDA78, 0xDA79, 0xDA7A, 0xDA7B, 0xDA7C, 0xCCCB, - /* U+8DA0 */ 0xDA7D, 0xDA7E, 0xDA80, 0xC8A4, 0xDA81, 0xDA82, 0xDA83, 0xDA84, - /* U+8DA8 */ 0xDA85, 0xDA86, 0xDA87, 0xDA88, 0xDA89, 0xDA8A, 0xDA8B, 0xDA8C, - /* U+8DB0 */ 0xDA8D, 0xF4F5, 0xDA8E, 0xD7E3, 0xC5BF, 0xF5C0, 0xDA8F, 0xDA90, - /* U+8DB8 */ 0xF5BB, 0xDA91, 0xF5C3, 0xDA92, 0xF5C2, 0xDA93, 0xD6BA, 0xF5C1, - /* U+8DC0 */ 0xDA94, 0xDA95, 0xDA96, 0xD4BE, 0xF5C4, 0xDA97, 0xF5CC, 0xDA98, - /* U+8DC8 */ 0xDA99, 0xDA9A, 0xDA9B, 0xB0CF, 0xB5F8, 0xDA9C, 0xF5C9, 0xF5CA, - /* U+8DD0 */ 0xDA9D, 0xC5DC, 0xDA9E, 0xDA9F, 0xDAA0, 0xDB40, 0xF5C5, 0xF5C6, - /* U+8DD8 */ 0xDB41, 0xDB42, 0xF5C7, 0xF5CB, 0xDB43, 0xBEE0, 0xF5C8, 0xB8FA, - /* U+8DE0 */ 0xDB44, 0xDB45, 0xDB46, 0xF5D0, 0xF5D3, 0xDB47, 0xDB48, 0xDB49, - /* U+8DE8 */ 0xBFE7, 0xDB4A, 0xB9F2, 0xF5BC, 0xF5CD, 0xDB4B, 0xDB4C, 0xC2B7, - /* U+8DF0 */ 0xDB4D, 0xDB4E, 0xDB4F, 0xCCF8, 0xDB50, 0xBCF9, 0xDB51, 0xF5CE, - /* U+8DF8 */ 0xF5CF, 0xF5D1, 0xB6E5, 0xF5D2, 0xDB52, 0xF5D5, 0xDB53, 0xDB54, - /* U+8E00 */ 0xDB55, 0xDB56, 0xDB57, 0xDB58, 0xDB59, 0xF5BD, 0xDB5A, 0xDB5B, - /* U+8E08 */ 0xDB5C, 0xF5D4, 0xD3BB, 0xDB5D, 0xB3EC, 0xDB5E, 0xDB5F, 0xCCA4, - /* U+8E10 */ 0xDB60, 0xDB61, 0xDB62, 0xDB63, 0xF5D6, 0xDB64, 0xDB65, 0xDB66, - /* U+8E18 */ 0xDB67, 0xDB68, 0xDB69, 0xDB6A, 0xDB6B, 0xF5D7, 0xBEE1, 0xF5D8, - /* U+8E20 */ 0xDB6C, 0xDB6D, 0xCCDF, 0xF5DB, 0xDB6E, 0xDB6F, 0xDB70, 0xDB71, - /* U+8E28 */ 0xDB72, 0xB2C8, 0xD7D9, 0xDB73, 0xF5D9, 0xDB74, 0xF5DA, 0xF5DC, - /* U+8E30 */ 0xDB75, 0xF5E2, 0xDB76, 0xDB77, 0xDB78, 0xF5E0, 0xDB79, 0xDB7A, - /* U+8E38 */ 0xDB7B, 0xF5DF, 0xF5DD, 0xDB7C, 0xDB7D, 0xF5E1, 0xDB7E, 0xDB80, - /* U+8E40 */ 0xF5DE, 0xF5E4, 0xF5E5, 0xDB81, 0xCCE3, 0xDB82, 0xDB83, 0xE5BF, - /* U+8E48 */ 0xB5B8, 0xF5E3, 0xF5E8, 0xCCA3, 0xDB84, 0xDB85, 0xDB86, 0xDB87, - /* U+8E50 */ 0xDB88, 0xF5E6, 0xF5E7, 0xDB89, 0xDB8A, 0xDB8B, 0xDB8C, 0xDB8D, - /* U+8E58 */ 0xDB8E, 0xF5BE, 0xDB8F, 0xDB90, 0xDB91, 0xDB92, 0xDB93, 0xDB94, - /* U+8E60 */ 0xDB95, 0xDB96, 0xDB97, 0xDB98, 0xDB99, 0xDB9A, 0xB1C4, 0xDB9B, - /* U+8E68 */ 0xDB9C, 0xF5BF, 0xDB9D, 0xDB9E, 0xB5C5, 0xB2E4, 0xDB9F, 0xF5EC, - /* U+8E70 */ 0xF5E9, 0xDBA0, 0xB6D7, 0xDC40, 0xF5ED, 0xDC41, 0xF5EA, 0xDC42, - /* U+8E78 */ 0xDC43, 0xDC44, 0xDC45, 0xDC46, 0xF5EB, 0xDC47, 0xDC48, 0xB4DA, - /* U+8E80 */ 0xDC49, 0xD4EA, 0xDC4A, 0xDC4B, 0xDC4C, 0xF5EE, 0xDC4D, 0xB3F9, - /* U+8E88 */ 0xDC4E, 0xDC4F, 0xDC50, 0xDC51, 0xDC52, 0xDC53, 0xDC54, 0xF5EF, - /* U+8E90 */ 0xF5F1, 0xDC55, 0xDC56, 0xDC57, 0xF5F0, 0xDC58, 0xDC59, 0xDC5A, - /* U+8E98 */ 0xDC5B, 0xDC5C, 0xDC5D, 0xDC5E, 0xF5F2, 0xDC5F, 0xF5F3, 0xDC60, - /* U+8EA0 */ 0xDC61, 0xDC62, 0xDC63, 0xDC64, 0xDC65, 0xDC66, 0xDC67, 0xDC68, - /* U+8EA8 */ 0xDC69, 0xDC6A, 0xDC6B, 0xC9ED, 0xB9AA, 0xDC6C, 0xDC6D, 0xC7FB, - /* U+8EB0 */ 0xDC6E, 0xDC6F, 0xB6E3, 0xDC70, 0xDC71, 0xDC72, 0xDC73, 0xDC74, - /* U+8EB8 */ 0xDC75, 0xDC76, 0xCCC9, 0xDC77, 0xDC78, 0xDC79, 0xDC7A, 0xDC7B, - /* U+8EC0 */ 0xDC7C, 0xDC7D, 0xDC7E, 0xDC80, 0xDC81, 0xDC82, 0xDC83, 0xDC84, - /* U+8EC8 */ 0xDC85, 0xDC86, 0xDC87, 0xDC88, 0xDC89, 0xDC8A, 0xEAA6, 0xDC8B, - /* U+8ED0 */ 0xDC8C, 0xDC8D, 0xDC8E, 0xDC8F, 0xDC90, 0xDC91, 0xDC92, 0xDC93, - /* U+8ED8 */ 0xDC94, 0xDC95, 0xDC96, 0xDC97, 0xDC98, 0xDC99, 0xDC9A, 0xDC9B, - /* U+8EE0 */ 0xDC9C, 0xDC9D, 0xDC9E, 0xDC9F, 0xDCA0, 0xDD40, 0xDD41, 0xDD42, - /* U+8EE8 */ 0xDD43, 0xDD44, 0xDD45, 0xDD46, 0xDD47, 0xDD48, 0xDD49, 0xDD4A, - /* U+8EF0 */ 0xDD4B, 0xDD4C, 0xDD4D, 0xDD4E, 0xDD4F, 0xDD50, 0xDD51, 0xDD52, - /* U+8EF8 */ 0xDD53, 0xDD54, 0xDD55, 0xDD56, 0xDD57, 0xDD58, 0xDD59, 0xDD5A, - /* U+8F00 */ 0xDD5B, 0xDD5C, 0xDD5D, 0xDD5E, 0xDD5F, 0xDD60, 0xDD61, 0xDD62, - /* U+8F08 */ 0xDD63, 0xDD64, 0xDD65, 0xDD66, 0xDD67, 0xDD68, 0xDD69, 0xDD6A, - /* U+8F10 */ 0xDD6B, 0xDD6C, 0xDD6D, 0xDD6E, 0xDD6F, 0xDD70, 0xDD71, 0xDD72, - /* U+8F18 */ 0xDD73, 0xDD74, 0xDD75, 0xDD76, 0xDD77, 0xDD78, 0xDD79, 0xDD7A, - /* U+8F20 */ 0xDD7B, 0xDD7C, 0xDD7D, 0xDD7E, 0xDD80, 0xDD81, 0xDD82, 0xDD83, - /* U+8F28 */ 0xDD84, 0xDD85, 0xDD86, 0xDD87, 0xDD88, 0xDD89, 0xDD8A, 0xDD8B, - /* U+8F30 */ 0xDD8C, 0xDD8D, 0xDD8E, 0xDD8F, 0xDD90, 0xDD91, 0xDD92, 0xDD93, - /* U+8F38 */ 0xDD94, 0xDD95, 0xDD96, 0xDD97, 0xDD98, 0xDD99, 0xDD9A, 0xDD9B, - /* U+8F40 */ 0xDD9C, 0xDD9D, 0xDD9E, 0xDD9F, 0xDDA0, 0xDE40, 0xDE41, 0xDE42, - /* U+8F48 */ 0xDE43, 0xDE44, 0xDE45, 0xDE46, 0xDE47, 0xDE48, 0xDE49, 0xDE4A, - /* U+8F50 */ 0xDE4B, 0xDE4C, 0xDE4D, 0xDE4E, 0xDE4F, 0xDE50, 0xDE51, 0xDE52, - /* U+8F58 */ 0xDE53, 0xDE54, 0xDE55, 0xDE56, 0xDE57, 0xDE58, 0xDE59, 0xDE5A, - /* U+8F60 */ 0xDE5B, 0xDE5C, 0xDE5D, 0xDE5E, 0xDE5F, 0xDE60, 0xB3B5, 0xD4FE, - /* U+8F68 */ 0xB9EC, 0xD0F9, 0xDE61, 0xE9ED, 0xD7AA, 0xE9EE, 0xC2D6, 0xC8ED, - /* U+8F70 */ 0xBAE4, 0xE9EF, 0xE9F0, 0xE9F1, 0xD6E1, 0xE9F2, 0xE9F3, 0xE9F5, - /* U+8F78 */ 0xE9F4, 0xE9F6, 0xE9F7, 0xC7E1, 0xE9F8, 0xD4D8, 0xE9F9, 0xBDCE, - /* U+8F80 */ 0xDE62, 0xE9FA, 0xE9FB, 0xBDCF, 0xE9FC, 0xB8A8, 0xC1BE, 0xE9FD, - /* U+8F88 */ 0xB1B2, 0xBBD4, 0xB9F5, 0xE9FE, 0xDE63, 0xEAA1, 0xEAA2, 0xEAA3, - /* U+8F90 */ 0xB7F8, 0xBCAD, 0xDE64, 0xCAE4, 0xE0CE, 0xD4AF, 0xCFBD, 0xD5B7, - /* U+8F98 */ 0xEAA4, 0xD5DE, 0xEAA5, 0xD0C1, 0xB9BC, 0xDE65, 0xB4C7, 0xB1D9, - /* U+8FA0 */ 0xDE66, 0xDE67, 0xDE68, 0xC0B1, 0xDE69, 0xDE6A, 0xDE6B, 0xDE6C, - /* U+8FA8 */ 0xB1E6, 0xB1E7, 0xDE6D, 0xB1E8, 0xDE6E, 0xDE6F, 0xDE70, 0xDE71, - /* U+8FB0 */ 0xB3BD, 0xC8E8, 0xDE72, 0xDE73, 0xDE74, 0xDE75, 0xE5C1, 0xDE76, - /* U+8FB8 */ 0xDE77, 0xB1DF, 0xDE78, 0xDE79, 0xDE7A, 0xC1C9, 0xB4EF, 0xDE7B, - /* U+8FC0 */ 0xDE7C, 0xC7A8, 0xD3D8, 0xDE7D, 0xC6F9, 0xD1B8, 0xDE7E, 0xB9FD, - /* U+8FC8 */ 0xC2F5, 0xDE80, 0xDE81, 0xDE82, 0xDE83, 0xDE84, 0xD3AD, 0xDE85, - /* U+8FD0 */ 0xD4CB, 0xBDFC, 0xDE86, 0xE5C2, 0xB7B5, 0xE5C3, 0xDE87, 0xDE88, - /* U+8FD8 */ 0xBBB9, 0xD5E2, 0xDE89, 0xBDF8, 0xD4B6, 0xCEA5, 0xC1AC, 0xB3D9, - /* U+8FE0 */ 0xDE8A, 0xDE8B, 0xCCF6, 0xDE8C, 0xE5C6, 0xE5C4, 0xE5C8, 0xDE8D, - /* U+8FE8 */ 0xE5CA, 0xE5C7, 0xB5CF, 0xC6C8, 0xDE8E, 0xB5FC, 0xE5C5, 0xDE8F, - /* U+8FF0 */ 0xCAF6, 0xDE90, 0xDE91, 0xE5C9, 0xDE92, 0xDE93, 0xDE94, 0xC3D4, - /* U+8FF8 */ 0xB1C5, 0xBCA3, 0xDE95, 0xDE96, 0xDE97, 0xD7B7, 0xDE98, 0xDE99, - /* U+9000 */ 0xCDCB, 0xCBCD, 0xCACA, 0xCCD3, 0xE5CC, 0xE5CB, 0xC4E6, 0xDE9A, - /* U+9008 */ 0xDE9B, 0xD1A1, 0xD1B7, 0xE5CD, 0xDE9C, 0xE5D0, 0xDE9D, 0xCDB8, - /* U+9010 */ 0xD6F0, 0xE5CF, 0xB5DD, 0xDE9E, 0xCDBE, 0xDE9F, 0xE5D1, 0xB6BA, - /* U+9018 */ 0xDEA0, 0xDF40, 0xCDA8, 0xB9E4, 0xDF41, 0xCAC5, 0xB3D1, 0xCBD9, - /* U+9020 */ 0xD4EC, 0xE5D2, 0xB7EA, 0xDF42, 0xDF43, 0xDF44, 0xE5CE, 0xDF45, - /* U+9028 */ 0xDF46, 0xDF47, 0xDF48, 0xDF49, 0xDF4A, 0xE5D5, 0xB4FE, 0xE5D6, - /* U+9030 */ 0xDF4B, 0xDF4C, 0xDF4D, 0xDF4E, 0xDF4F, 0xE5D3, 0xE5D4, 0xDF50, - /* U+9038 */ 0xD2DD, 0xDF51, 0xDF52, 0xC2DF, 0xB1C6, 0xDF53, 0xD3E2, 0xDF54, - /* U+9040 */ 0xDF55, 0xB6DD, 0xCBEC, 0xDF56, 0xE5D7, 0xDF57, 0xDF58, 0xD3F6, - /* U+9048 */ 0xDF59, 0xDF5A, 0xDF5B, 0xDF5C, 0xDF5D, 0xB1E9, 0xDF5E, 0xB6F4, - /* U+9050 */ 0xE5DA, 0xE5D8, 0xE5D9, 0xB5C0, 0xDF5F, 0xDF60, 0xDF61, 0xD2C5, - /* U+9058 */ 0xE5DC, 0xDF62, 0xDF63, 0xE5DE, 0xDF64, 0xDF65, 0xDF66, 0xDF67, - /* U+9060 */ 0xDF68, 0xDF69, 0xE5DD, 0xC7B2, 0xDF6A, 0xD2A3, 0xDF6B, 0xDF6C, - /* U+9068 */ 0xE5DB, 0xDF6D, 0xDF6E, 0xDF6F, 0xDF70, 0xD4E2, 0xD5DA, 0xDF71, - /* U+9070 */ 0xDF72, 0xDF73, 0xDF74, 0xDF75, 0xE5E0, 0xD7F1, 0xDF76, 0xDF77, - /* U+9078 */ 0xDF78, 0xDF79, 0xDF7A, 0xDF7B, 0xDF7C, 0xE5E1, 0xDF7D, 0xB1DC, - /* U+9080 */ 0xD1FB, 0xDF7E, 0xE5E2, 0xE5E4, 0xDF80, 0xDF81, 0xDF82, 0xDF83, - /* U+9088 */ 0xE5E3, 0xDF84, 0xDF85, 0xE5E5, 0xDF86, 0xDF87, 0xDF88, 0xDF89, - /* U+9090 */ 0xDF8A, 0xD2D8, 0xDF8B, 0xB5CB, 0xDF8C, 0xE7DF, 0xDF8D, 0xDAF5, - /* U+9098 */ 0xDF8E, 0xDAF8, 0xDF8F, 0xDAF6, 0xDF90, 0xDAF7, 0xDF91, 0xDF92, - /* U+90A0 */ 0xDF93, 0xDAFA, 0xD0CF, 0xC4C7, 0xDF94, 0xDF95, 0xB0EE, 0xDF96, - /* U+90A8 */ 0xDF97, 0xDF98, 0xD0B0, 0xDF99, 0xDAF9, 0xDF9A, 0xD3CA, 0xBAAA, - /* U+90B0 */ 0xDBA2, 0xC7F1, 0xDF9B, 0xDAFC, 0xDAFB, 0xC9DB, 0xDAFD, 0xDF9C, - /* U+90B8 */ 0xDBA1, 0xD7DE, 0xDAFE, 0xC1DA, 0xDF9D, 0xDF9E, 0xDBA5, 0xDF9F, - /* U+90C0 */ 0xDFA0, 0xD3F4, 0xE040, 0xE041, 0xDBA7, 0xDBA4, 0xE042, 0xDBA8, - /* U+90C8 */ 0xE043, 0xE044, 0xBDBC, 0xE045, 0xE046, 0xE047, 0xC0C9, 0xDBA3, - /* U+90D0 */ 0xDBA6, 0xD6A3, 0xE048, 0xDBA9, 0xE049, 0xE04A, 0xE04B, 0xDBAD, - /* U+90D8 */ 0xE04C, 0xE04D, 0xE04E, 0xDBAE, 0xDBAC, 0xBAC2, 0xE04F, 0xE050, - /* U+90E0 */ 0xE051, 0xBFA4, 0xDBAB, 0xE052, 0xE053, 0xE054, 0xDBAA, 0xD4C7, - /* U+90E8 */ 0xB2BF, 0xE055, 0xE056, 0xDBAF, 0xE057, 0xB9F9, 0xE058, 0xDBB0, - /* U+90F0 */ 0xE059, 0xE05A, 0xE05B, 0xE05C, 0xB3BB, 0xE05D, 0xE05E, 0xE05F, - /* U+90F8 */ 0xB5A6, 0xE060, 0xE061, 0xE062, 0xE063, 0xB6BC, 0xDBB1, 0xE064, - /* U+9100 */ 0xE065, 0xE066, 0xB6F5, 0xE067, 0xDBB2, 0xE068, 0xE069, 0xE06A, - /* U+9108 */ 0xE06B, 0xE06C, 0xE06D, 0xE06E, 0xE06F, 0xE070, 0xE071, 0xE072, - /* U+9110 */ 0xE073, 0xE074, 0xE075, 0xE076, 0xE077, 0xE078, 0xE079, 0xE07A, - /* U+9118 */ 0xE07B, 0xB1C9, 0xE07C, 0xE07D, 0xE07E, 0xE080, 0xDBB4, 0xE081, - /* U+9120 */ 0xE082, 0xE083, 0xDBB3, 0xDBB5, 0xE084, 0xE085, 0xE086, 0xE087, - /* U+9128 */ 0xE088, 0xE089, 0xE08A, 0xE08B, 0xE08C, 0xE08D, 0xE08E, 0xDBB7, - /* U+9130 */ 0xE08F, 0xDBB6, 0xE090, 0xE091, 0xE092, 0xE093, 0xE094, 0xE095, - /* U+9138 */ 0xE096, 0xDBB8, 0xE097, 0xE098, 0xE099, 0xE09A, 0xE09B, 0xE09C, - /* U+9140 */ 0xE09D, 0xE09E, 0xE09F, 0xDBB9, 0xE0A0, 0xE140, 0xDBBA, 0xE141, - /* U+9148 */ 0xE142, 0xD3CF, 0xF4FA, 0xC7F5, 0xD7C3, 0xC5E4, 0xF4FC, 0xF4FD, - /* U+9150 */ 0xF4FB, 0xE143, 0xBEC6, 0xE144, 0xE145, 0xE146, 0xE147, 0xD0EF, - /* U+9158 */ 0xE148, 0xE149, 0xB7D3, 0xE14A, 0xE14B, 0xD4CD, 0xCCAA, 0xE14C, - /* U+9160 */ 0xE14D, 0xF5A2, 0xF5A1, 0xBAA8, 0xF4FE, 0xCBD6, 0xE14E, 0xE14F, - /* U+9168 */ 0xE150, 0xF5A4, 0xC0D2, 0xE151, 0xB3EA, 0xE152, 0xCDAA, 0xF5A5, - /* U+9170 */ 0xF5A3, 0xBDB4, 0xF5A8, 0xE153, 0xF5A9, 0xBDCD, 0xC3B8, 0xBFE1, - /* U+9178 */ 0xCBE1, 0xF5AA, 0xE154, 0xE155, 0xE156, 0xF5A6, 0xF5A7, 0xC4F0, - /* U+9180 */ 0xE157, 0xE158, 0xE159, 0xE15A, 0xE15B, 0xF5AC, 0xE15C, 0xB4BC, - /* U+9188 */ 0xE15D, 0xD7ED, 0xE15E, 0xB4D7, 0xF5AB, 0xF5AE, 0xE15F, 0xE160, - /* U+9190 */ 0xF5AD, 0xF5AF, 0xD0D1, 0xE161, 0xE162, 0xE163, 0xE164, 0xE165, - /* U+9198 */ 0xE166, 0xE167, 0xC3D1, 0xC8A9, 0xE168, 0xE169, 0xE16A, 0xE16B, - /* U+91A0 */ 0xE16C, 0xE16D, 0xF5B0, 0xF5B1, 0xE16E, 0xE16F, 0xE170, 0xE171, - /* U+91A8 */ 0xE172, 0xE173, 0xF5B2, 0xE174, 0xE175, 0xF5B3, 0xF5B4, 0xF5B5, - /* U+91B0 */ 0xE176, 0xE177, 0xE178, 0xE179, 0xF5B7, 0xF5B6, 0xE17A, 0xE17B, - /* U+91B8 */ 0xE17C, 0xE17D, 0xF5B8, 0xE17E, 0xE180, 0xE181, 0xE182, 0xE183, - /* U+91C0 */ 0xE184, 0xE185, 0xE186, 0xE187, 0xE188, 0xE189, 0xE18A, 0xB2C9, - /* U+91C8 */ 0xE18B, 0xD3D4, 0xCACD, 0xE18C, 0xC0EF, 0xD6D8, 0xD2B0, 0xC1BF, - /* U+91D0 */ 0xE18D, 0xBDF0, 0xE18E, 0xE18F, 0xE190, 0xE191, 0xE192, 0xE193, - /* U+91D8 */ 0xE194, 0xE195, 0xE196, 0xE197, 0xB8AA, 0xE198, 0xE199, 0xE19A, - /* U+91E0 */ 0xE19B, 0xE19C, 0xE19D, 0xE19E, 0xE19F, 0xE1A0, 0xE240, 0xE241, - /* U+91E8 */ 0xE242, 0xE243, 0xE244, 0xE245, 0xE246, 0xE247, 0xE248, 0xE249, - /* U+91F0 */ 0xE24A, 0xE24B, 0xE24C, 0xE24D, 0xE24E, 0xE24F, 0xE250, 0xE251, - /* U+91F8 */ 0xE252, 0xE253, 0xE254, 0xE255, 0xE256, 0xE257, 0xE258, 0xE259, - /* U+9200 */ 0xE25A, 0xE25B, 0xE25C, 0xE25D, 0xE25E, 0xE25F, 0xE260, 0xE261, - /* U+9208 */ 0xE262, 0xE263, 0xE264, 0xE265, 0xE266, 0xE267, 0xE268, 0xE269, - /* U+9210 */ 0xE26A, 0xE26B, 0xE26C, 0xE26D, 0xE26E, 0xE26F, 0xE270, 0xE271, - /* U+9218 */ 0xE272, 0xE273, 0xE274, 0xE275, 0xE276, 0xE277, 0xE278, 0xE279, - /* U+9220 */ 0xE27A, 0xE27B, 0xE27C, 0xE27D, 0xE27E, 0xE280, 0xE281, 0xE282, - /* U+9228 */ 0xE283, 0xE284, 0xE285, 0xE286, 0xE287, 0xE288, 0xE289, 0xE28A, - /* U+9230 */ 0xE28B, 0xE28C, 0xE28D, 0xE28E, 0xE28F, 0xE290, 0xE291, 0xE292, - /* U+9238 */ 0xE293, 0xE294, 0xE295, 0xE296, 0xE297, 0xE298, 0xE299, 0xE29A, - /* U+9240 */ 0xE29B, 0xE29C, 0xE29D, 0xE29E, 0xE29F, 0xE2A0, 0xE340, 0xE341, - /* U+9248 */ 0xE342, 0xE343, 0xE344, 0xE345, 0xE346, 0xE347, 0xE348, 0xE349, - /* U+9250 */ 0xE34A, 0xE34B, 0xE34C, 0xE34D, 0xE34E, 0xE34F, 0xE350, 0xE351, - /* U+9258 */ 0xE352, 0xE353, 0xE354, 0xE355, 0xE356, 0xE357, 0xE358, 0xE359, - /* U+9260 */ 0xE35A, 0xE35B, 0xE35C, 0xE35D, 0xE35E, 0xE35F, 0xE360, 0xE361, - /* U+9268 */ 0xE362, 0xE363, 0xE364, 0xE365, 0xE366, 0xE367, 0xE368, 0xE369, - /* U+9270 */ 0xE36A, 0xE36B, 0xE36C, 0xE36D, 0xBCF8, 0xE36E, 0xE36F, 0xE370, - /* U+9278 */ 0xE371, 0xE372, 0xE373, 0xE374, 0xE375, 0xE376, 0xE377, 0xE378, - /* U+9280 */ 0xE379, 0xE37A, 0xE37B, 0xE37C, 0xE37D, 0xE37E, 0xE380, 0xE381, - /* U+9288 */ 0xE382, 0xE383, 0xE384, 0xE385, 0xE386, 0xE387, 0xF6C6, 0xE388, - /* U+9290 */ 0xE389, 0xE38A, 0xE38B, 0xE38C, 0xE38D, 0xE38E, 0xE38F, 0xE390, - /* U+9298 */ 0xE391, 0xE392, 0xE393, 0xE394, 0xE395, 0xE396, 0xE397, 0xE398, - /* U+92A0 */ 0xE399, 0xE39A, 0xE39B, 0xE39C, 0xE39D, 0xE39E, 0xE39F, 0xE3A0, - /* U+92A8 */ 0xE440, 0xE441, 0xE442, 0xE443, 0xE444, 0xE445, 0xF6C7, 0xE446, - /* U+92B0 */ 0xE447, 0xE448, 0xE449, 0xE44A, 0xE44B, 0xE44C, 0xE44D, 0xE44E, - /* U+92B8 */ 0xE44F, 0xE450, 0xE451, 0xE452, 0xE453, 0xE454, 0xE455, 0xE456, - /* U+92C0 */ 0xE457, 0xE458, 0xE459, 0xE45A, 0xE45B, 0xE45C, 0xE45D, 0xE45E, - /* U+92C8 */ 0xF6C8, 0xE45F, 0xE460, 0xE461, 0xE462, 0xE463, 0xE464, 0xE465, - /* U+92D0 */ 0xE466, 0xE467, 0xE468, 0xE469, 0xE46A, 0xE46B, 0xE46C, 0xE46D, - /* U+92D8 */ 0xE46E, 0xE46F, 0xE470, 0xE471, 0xE472, 0xE473, 0xE474, 0xE475, - /* U+92E0 */ 0xE476, 0xE477, 0xE478, 0xE479, 0xE47A, 0xE47B, 0xE47C, 0xE47D, - /* U+92E8 */ 0xE47E, 0xE480, 0xE481, 0xE482, 0xE483, 0xE484, 0xE485, 0xE486, - /* U+92F0 */ 0xE487, 0xE488, 0xE489, 0xE48A, 0xE48B, 0xE48C, 0xE48D, 0xE48E, - /* U+92F8 */ 0xE48F, 0xE490, 0xE491, 0xE492, 0xE493, 0xE494, 0xE495, 0xE496, - /* U+9300 */ 0xE497, 0xE498, 0xE499, 0xE49A, 0xE49B, 0xE49C, 0xE49D, 0xE49E, - /* U+9308 */ 0xE49F, 0xE4A0, 0xE540, 0xE541, 0xE542, 0xE543, 0xE544, 0xE545, - /* U+9310 */ 0xE546, 0xE547, 0xE548, 0xE549, 0xE54A, 0xE54B, 0xE54C, 0xE54D, - /* U+9318 */ 0xE54E, 0xE54F, 0xE550, 0xE551, 0xE552, 0xE553, 0xE554, 0xE555, - /* U+9320 */ 0xE556, 0xE557, 0xE558, 0xE559, 0xE55A, 0xE55B, 0xE55C, 0xE55D, - /* U+9328 */ 0xE55E, 0xE55F, 0xE560, 0xE561, 0xE562, 0xE563, 0xE564, 0xE565, - /* U+9330 */ 0xE566, 0xE567, 0xE568, 0xE569, 0xE56A, 0xE56B, 0xE56C, 0xE56D, - /* U+9338 */ 0xE56E, 0xE56F, 0xE570, 0xE571, 0xE572, 0xE573, 0xF6C9, 0xE574, - /* U+9340 */ 0xE575, 0xE576, 0xE577, 0xE578, 0xE579, 0xE57A, 0xE57B, 0xE57C, - /* U+9348 */ 0xE57D, 0xE57E, 0xE580, 0xE581, 0xE582, 0xE583, 0xE584, 0xE585, - /* U+9350 */ 0xE586, 0xE587, 0xE588, 0xE589, 0xE58A, 0xE58B, 0xE58C, 0xE58D, - /* U+9358 */ 0xE58E, 0xE58F, 0xE590, 0xE591, 0xE592, 0xE593, 0xE594, 0xE595, - /* U+9360 */ 0xE596, 0xE597, 0xE598, 0xE599, 0xE59A, 0xE59B, 0xE59C, 0xE59D, - /* U+9368 */ 0xE59E, 0xE59F, 0xF6CA, 0xE5A0, 0xE640, 0xE641, 0xE642, 0xE643, - /* U+9370 */ 0xE644, 0xE645, 0xE646, 0xE647, 0xE648, 0xE649, 0xE64A, 0xE64B, - /* U+9378 */ 0xE64C, 0xE64D, 0xE64E, 0xE64F, 0xE650, 0xE651, 0xE652, 0xE653, - /* U+9380 */ 0xE654, 0xE655, 0xE656, 0xE657, 0xE658, 0xE659, 0xE65A, 0xE65B, - /* U+9388 */ 0xE65C, 0xE65D, 0xE65E, 0xE65F, 0xE660, 0xE661, 0xE662, 0xF6CC, - /* U+9390 */ 0xE663, 0xE664, 0xE665, 0xE666, 0xE667, 0xE668, 0xE669, 0xE66A, - /* U+9398 */ 0xE66B, 0xE66C, 0xE66D, 0xE66E, 0xE66F, 0xE670, 0xE671, 0xE672, - /* U+93A0 */ 0xE673, 0xE674, 0xE675, 0xE676, 0xE677, 0xE678, 0xE679, 0xE67A, - /* U+93A8 */ 0xE67B, 0xE67C, 0xE67D, 0xE67E, 0xE680, 0xE681, 0xE682, 0xE683, - /* U+93B0 */ 0xE684, 0xE685, 0xE686, 0xE687, 0xE688, 0xE689, 0xE68A, 0xE68B, - /* U+93B8 */ 0xE68C, 0xE68D, 0xE68E, 0xE68F, 0xE690, 0xE691, 0xE692, 0xE693, - /* U+93C0 */ 0xE694, 0xE695, 0xE696, 0xE697, 0xE698, 0xE699, 0xE69A, 0xE69B, - /* U+93C8 */ 0xE69C, 0xE69D, 0xF6CB, 0xE69E, 0xE69F, 0xE6A0, 0xE740, 0xE741, - /* U+93D0 */ 0xE742, 0xE743, 0xE744, 0xE745, 0xE746, 0xE747, 0xF7E9, 0xE748, - /* U+93D8 */ 0xE749, 0xE74A, 0xE74B, 0xE74C, 0xE74D, 0xE74E, 0xE74F, 0xE750, - /* U+93E0 */ 0xE751, 0xE752, 0xE753, 0xE754, 0xE755, 0xE756, 0xE757, 0xE758, - /* U+93E8 */ 0xE759, 0xE75A, 0xE75B, 0xE75C, 0xE75D, 0xE75E, 0xE75F, 0xE760, - /* U+93F0 */ 0xE761, 0xE762, 0xE763, 0xE764, 0xE765, 0xE766, 0xE767, 0xE768, - /* U+93F8 */ 0xE769, 0xE76A, 0xE76B, 0xE76C, 0xE76D, 0xE76E, 0xE76F, 0xE770, - /* U+9400 */ 0xE771, 0xE772, 0xE773, 0xE774, 0xE775, 0xE776, 0xE777, 0xE778, - /* U+9408 */ 0xE779, 0xE77A, 0xE77B, 0xE77C, 0xE77D, 0xE77E, 0xE780, 0xE781, - /* U+9410 */ 0xE782, 0xE783, 0xE784, 0xE785, 0xE786, 0xE787, 0xE788, 0xE789, - /* U+9418 */ 0xE78A, 0xE78B, 0xE78C, 0xE78D, 0xE78E, 0xE78F, 0xE790, 0xE791, - /* U+9420 */ 0xE792, 0xE793, 0xE794, 0xE795, 0xE796, 0xE797, 0xE798, 0xE799, - /* U+9428 */ 0xE79A, 0xE79B, 0xE79C, 0xE79D, 0xE79E, 0xE79F, 0xE7A0, 0xE840, - /* U+9430 */ 0xE841, 0xE842, 0xE843, 0xE844, 0xE845, 0xE846, 0xE847, 0xE848, - /* U+9438 */ 0xE849, 0xE84A, 0xE84B, 0xE84C, 0xE84D, 0xE84E, 0xF6CD, 0xE84F, - /* U+9440 */ 0xE850, 0xE851, 0xE852, 0xE853, 0xE854, 0xE855, 0xE856, 0xE857, - /* U+9448 */ 0xE858, 0xE859, 0xE85A, 0xE85B, 0xE85C, 0xE85D, 0xE85E, 0xE85F, - /* U+9450 */ 0xE860, 0xE861, 0xE862, 0xE863, 0xE864, 0xE865, 0xE866, 0xE867, - /* U+9458 */ 0xE868, 0xE869, 0xE86A, 0xE86B, 0xE86C, 0xE86D, 0xE86E, 0xE86F, - /* U+9460 */ 0xE870, 0xE871, 0xE872, 0xE873, 0xE874, 0xE875, 0xE876, 0xE877, - /* U+9468 */ 0xE878, 0xE879, 0xE87A, 0xF6CE, 0xE87B, 0xE87C, 0xE87D, 0xE87E, - /* U+9470 */ 0xE880, 0xE881, 0xE882, 0xE883, 0xE884, 0xE885, 0xE886, 0xE887, - /* U+9478 */ 0xE888, 0xE889, 0xE88A, 0xE88B, 0xE88C, 0xE88D, 0xE88E, 0xE88F, - /* U+9480 */ 0xE890, 0xE891, 0xE892, 0xE893, 0xE894, 0xEEC4, 0xEEC5, 0xEEC6, - /* U+9488 */ 0xD5EB, 0xB6A4, 0xEEC8, 0xEEC7, 0xEEC9, 0xEECA, 0xC7A5, 0xEECB, - /* U+9490 */ 0xEECC, 0xE895, 0xB7B0, 0xB5F6, 0xEECD, 0xEECF, 0xE896, 0xEECE, - /* U+9498 */ 0xE897, 0xB8C6, 0xEED0, 0xEED1, 0xEED2, 0xB6DB, 0xB3AE, 0xD6D3, - /* U+94A0 */ 0xC4C6, 0xB1B5, 0xB8D6, 0xEED3, 0xEED4, 0xD4BF, 0xC7D5, 0xBEFB, - /* U+94A8 */ 0xCED9, 0xB9B3, 0xEED6, 0xEED5, 0xEED8, 0xEED7, 0xC5A5, 0xEED9, - /* U+94B0 */ 0xEEDA, 0xC7AE, 0xEEDB, 0xC7AF, 0xEEDC, 0xB2A7, 0xEEDD, 0xEEDE, - /* U+94B8 */ 0xEEDF, 0xEEE0, 0xEEE1, 0xD7EA, 0xEEE2, 0xEEE3, 0xBCD8, 0xEEE4, - /* U+94C0 */ 0xD3CB, 0xCCFA, 0xB2AC, 0xC1E5, 0xEEE5, 0xC7A6, 0xC3AD, 0xE898, - /* U+94C8 */ 0xEEE6, 0xEEE7, 0xEEE8, 0xEEE9, 0xEEEA, 0xEEEB, 0xEEEC, 0xE899, - /* U+94D0 */ 0xEEED, 0xEEEE, 0xEEEF, 0xE89A, 0xE89B, 0xEEF0, 0xEEF1, 0xEEF2, - /* U+94D8 */ 0xEEF4, 0xEEF3, 0xE89C, 0xEEF5, 0xCDAD, 0xC2C1, 0xEEF6, 0xEEF7, - /* U+94E0 */ 0xEEF8, 0xD5A1, 0xEEF9, 0xCFB3, 0xEEFA, 0xEEFB, 0xE89D, 0xEEFC, - /* U+94E8 */ 0xEEFD, 0xEFA1, 0xEEFE, 0xEFA2, 0xB8F5, 0xC3FA, 0xEFA3, 0xEFA4, - /* U+94F0 */ 0xBDC2, 0xD2BF, 0xB2F9, 0xEFA5, 0xEFA6, 0xEFA7, 0xD2F8, 0xEFA8, - /* U+94F8 */ 0xD6FD, 0xEFA9, 0xC6CC, 0xE89E, 0xEFAA, 0xEFAB, 0xC1B4, 0xEFAC, - /* U+9500 */ 0xCFFA, 0xCBF8, 0xEFAE, 0xEFAD, 0xB3FA, 0xB9F8, 0xEFAF, 0xEFB0, - /* U+9508 */ 0xD0E2, 0xEFB1, 0xEFB2, 0xB7E6, 0xD0BF, 0xEFB3, 0xEFB4, 0xEFB5, - /* U+9510 */ 0xC8F1, 0xCCE0, 0xEFB6, 0xEFB7, 0xEFB8, 0xEFB9, 0xEFBA, 0xD5E0, - /* U+9518 */ 0xEFBB, 0xB4ED, 0xC3AA, 0xEFBC, 0xE89F, 0xEFBD, 0xEFBE, 0xEFBF, - /* U+9520 */ 0xE8A0, 0xCEFD, 0xEFC0, 0xC2E0, 0xB4B8, 0xD7B6, 0xBDF5, 0xE940, - /* U+9528 */ 0xCFC7, 0xEFC3, 0xEFC1, 0xEFC2, 0xEFC4, 0xB6A7, 0xBCFC, 0xBEE2, - /* U+9530 */ 0xC3CC, 0xEFC5, 0xEFC6, 0xE941, 0xEFC7, 0xEFCF, 0xEFC8, 0xEFC9, - /* U+9538 */ 0xEFCA, 0xC7C2, 0xEFF1, 0xB6CD, 0xEFCB, 0xE942, 0xEFCC, 0xEFCD, - /* U+9540 */ 0xB6C6, 0xC3BE, 0xEFCE, 0xE943, 0xEFD0, 0xEFD1, 0xEFD2, 0xD5F2, - /* U+9548 */ 0xE944, 0xEFD3, 0xC4F7, 0xE945, 0xEFD4, 0xC4F8, 0xEFD5, 0xEFD6, - /* U+9550 */ 0xB8E4, 0xB0F7, 0xEFD7, 0xEFD8, 0xEFD9, 0xE946, 0xEFDA, 0xEFDB, - /* U+9558 */ 0xEFDC, 0xEFDD, 0xE947, 0xEFDE, 0xBEB5, 0xEFE1, 0xEFDF, 0xEFE0, - /* U+9560 */ 0xE948, 0xEFE2, 0xEFE3, 0xC1CD, 0xEFE4, 0xEFE5, 0xEFE6, 0xEFE7, - /* U+9568 */ 0xEFE8, 0xEFE9, 0xEFEA, 0xEFEB, 0xEFEC, 0xC0D8, 0xE949, 0xEFED, - /* U+9570 */ 0xC1AD, 0xEFEE, 0xEFEF, 0xEFF0, 0xE94A, 0xE94B, 0xCFE2, 0xE94C, - /* U+9578 */ 0xE94D, 0xE94E, 0xE94F, 0xE950, 0xE951, 0xE952, 0xE953, 0xB3A4, - /* U+9580 */ 0xE954, 0xE955, 0xE956, 0xE957, 0xE958, 0xE959, 0xE95A, 0xE95B, - /* U+9588 */ 0xE95C, 0xE95D, 0xE95E, 0xE95F, 0xE960, 0xE961, 0xE962, 0xE963, - /* U+9590 */ 0xE964, 0xE965, 0xE966, 0xE967, 0xE968, 0xE969, 0xE96A, 0xE96B, - /* U+9598 */ 0xE96C, 0xE96D, 0xE96E, 0xE96F, 0xE970, 0xE971, 0xE972, 0xE973, - /* U+95A0 */ 0xE974, 0xE975, 0xE976, 0xE977, 0xE978, 0xE979, 0xE97A, 0xE97B, - /* U+95A8 */ 0xE97C, 0xE97D, 0xE97E, 0xE980, 0xE981, 0xE982, 0xE983, 0xE984, - /* U+95B0 */ 0xE985, 0xE986, 0xE987, 0xE988, 0xE989, 0xE98A, 0xE98B, 0xE98C, - /* U+95B8 */ 0xE98D, 0xE98E, 0xE98F, 0xE990, 0xE991, 0xE992, 0xE993, 0xE994, - /* U+95C0 */ 0xE995, 0xE996, 0xE997, 0xE998, 0xE999, 0xE99A, 0xE99B, 0xE99C, - /* U+95C8 */ 0xE99D, 0xE99E, 0xE99F, 0xE9A0, 0xEA40, 0xEA41, 0xEA42, 0xEA43, - /* U+95D0 */ 0xEA44, 0xEA45, 0xEA46, 0xEA47, 0xEA48, 0xEA49, 0xEA4A, 0xEA4B, - /* U+95D8 */ 0xEA4C, 0xEA4D, 0xEA4E, 0xEA4F, 0xEA50, 0xEA51, 0xEA52, 0xEA53, - /* U+95E0 */ 0xEA54, 0xEA55, 0xEA56, 0xEA57, 0xEA58, 0xEA59, 0xEA5A, 0xEA5B, - /* U+95E8 */ 0xC3C5, 0xE3C5, 0xC9C1, 0xE3C6, 0xEA5C, 0xB1D5, 0xCECA, 0xB4B3, - /* U+95F0 */ 0xC8F2, 0xE3C7, 0xCFD0, 0xE3C8, 0xBCE4, 0xE3C9, 0xE3CA, 0xC3C6, - /* U+95F8 */ 0xD5A2, 0xC4D6, 0xB9EB, 0xCEC5, 0xE3CB, 0xC3F6, 0xE3CC, 0xEA5D, - /* U+9600 */ 0xB7A7, 0xB8F3, 0xBAD2, 0xE3CD, 0xE3CE, 0xD4C4, 0xE3CF, 0xEA5E, - /* U+9608 */ 0xE3D0, 0xD1CB, 0xE3D1, 0xE3D2, 0xE3D3, 0xE3D4, 0xD1D6, 0xE3D5, - /* U+9610 */ 0xB2FB, 0xC0BB, 0xE3D6, 0xEA5F, 0xC0AB, 0xE3D7, 0xE3D8, 0xE3D9, - /* U+9618 */ 0xEA60, 0xE3DA, 0xE3DB, 0xEA61, 0xB8B7, 0xDAE2, 0xEA62, 0xB6D3, - /* U+9620 */ 0xEA63, 0xDAE4, 0xDAE3, 0xEA64, 0xEA65, 0xEA66, 0xEA67, 0xEA68, - /* U+9628 */ 0xEA69, 0xEA6A, 0xDAE6, 0xEA6B, 0xEA6C, 0xEA6D, 0xC8EE, 0xEA6E, - /* U+9630 */ 0xEA6F, 0xDAE5, 0xB7C0, 0xD1F4, 0xD2F5, 0xD5F3, 0xBDD7, 0xEA70, - /* U+9638 */ 0xEA71, 0xEA72, 0xEA73, 0xD7E8, 0xDAE8, 0xDAE7, 0xEA74, 0xB0A2, - /* U+9640 */ 0xCDD3, 0xEA75, 0xDAE9, 0xEA76, 0xB8BD, 0xBCCA, 0xC2BD, 0xC2A4, - /* U+9648 */ 0xB3C2, 0xDAEA, 0xEA77, 0xC2AA, 0xC4B0, 0xBDB5, 0xEA78, 0xEA79, - /* U+9650 */ 0xCFDE, 0xEA7A, 0xEA7B, 0xEA7C, 0xDAEB, 0xC9C2, 0xEA7D, 0xEA7E, - /* U+9658 */ 0xEA80, 0xEA81, 0xEA82, 0xB1DD, 0xEA83, 0xEA84, 0xEA85, 0xDAEC, - /* U+9660 */ 0xEA86, 0xB6B8, 0xD4BA, 0xEA87, 0xB3FD, 0xEA88, 0xEA89, 0xDAED, - /* U+9668 */ 0xD4C9, 0xCFD5, 0xC5E3, 0xEA8A, 0xDAEE, 0xEA8B, 0xEA8C, 0xEA8D, - /* U+9670 */ 0xEA8E, 0xEA8F, 0xDAEF, 0xEA90, 0xDAF0, 0xC1EA, 0xCCD5, 0xCFDD, - /* U+9678 */ 0xEA91, 0xEA92, 0xEA93, 0xEA94, 0xEA95, 0xEA96, 0xEA97, 0xEA98, - /* U+9680 */ 0xEA99, 0xEA9A, 0xEA9B, 0xEA9C, 0xEA9D, 0xD3E7, 0xC2A1, 0xEA9E, - /* U+9688 */ 0xDAF1, 0xEA9F, 0xEAA0, 0xCBE5, 0xEB40, 0xDAF2, 0xEB41, 0xCBE6, - /* U+9690 */ 0xD2FE, 0xEB42, 0xEB43, 0xEB44, 0xB8F4, 0xEB45, 0xEB46, 0xDAF3, - /* U+9698 */ 0xB0AF, 0xCFB6, 0xEB47, 0xEB48, 0xD5CF, 0xEB49, 0xEB4A, 0xEB4B, - /* U+96A0 */ 0xEB4C, 0xEB4D, 0xEB4E, 0xEB4F, 0xEB50, 0xEB51, 0xEB52, 0xCBED, - /* U+96A8 */ 0xEB53, 0xEB54, 0xEB55, 0xEB56, 0xEB57, 0xEB58, 0xEB59, 0xEB5A, - /* U+96B0 */ 0xDAF4, 0xEB5B, 0xEB5C, 0xE3C4, 0xEB5D, 0xEB5E, 0xC1A5, 0xEB5F, - /* U+96B8 */ 0xEB60, 0xF6BF, 0xEB61, 0xEB62, 0xF6C0, 0xF6C1, 0xC4D1, 0xEB63, - /* U+96C0 */ 0xC8B8, 0xD1E3, 0xEB64, 0xEB65, 0xD0DB, 0xD1C5, 0xBCAF, 0xB9CD, - /* U+96C8 */ 0xEB66, 0xEFF4, 0xEB67, 0xEB68, 0xB4C6, 0xD3BA, 0xF6C2, 0xB3FB, - /* U+96D0 */ 0xEB69, 0xEB6A, 0xF6C3, 0xEB6B, 0xEB6C, 0xB5F1, 0xEB6D, 0xEB6E, - /* U+96D8 */ 0xEB6F, 0xEB70, 0xEB71, 0xEB72, 0xEB73, 0xEB74, 0xEB75, 0xEB76, - /* U+96E0 */ 0xF6C5, 0xEB77, 0xEB78, 0xEB79, 0xEB7A, 0xEB7B, 0xEB7C, 0xEB7D, - /* U+96E8 */ 0xD3EA, 0xF6A7, 0xD1A9, 0xEB7E, 0xEB80, 0xEB81, 0xEB82, 0xF6A9, - /* U+96F0 */ 0xEB83, 0xEB84, 0xEB85, 0xF6A8, 0xEB86, 0xEB87, 0xC1E3, 0xC0D7, - /* U+96F8 */ 0xEB88, 0xB1A2, 0xEB89, 0xEB8A, 0xEB8B, 0xEB8C, 0xCEED, 0xEB8D, - /* U+9700 */ 0xD0E8, 0xF6AB, 0xEB8E, 0xEB8F, 0xCFF6, 0xEB90, 0xF6AA, 0xD5F0, - /* U+9708 */ 0xF6AC, 0xC3B9, 0xEB91, 0xEB92, 0xEB93, 0xBBF4, 0xF6AE, 0xF6AD, - /* U+9710 */ 0xEB94, 0xEB95, 0xEB96, 0xC4DE, 0xEB97, 0xEB98, 0xC1D8, 0xEB99, - /* U+9718 */ 0xEB9A, 0xEB9B, 0xEB9C, 0xEB9D, 0xCBAA, 0xEB9E, 0xCFBC, 0xEB9F, - /* U+9720 */ 0xEBA0, 0xEC40, 0xEC41, 0xEC42, 0xEC43, 0xEC44, 0xEC45, 0xEC46, - /* U+9728 */ 0xEC47, 0xEC48, 0xF6AF, 0xEC49, 0xEC4A, 0xF6B0, 0xEC4B, 0xEC4C, - /* U+9730 */ 0xF6B1, 0xEC4D, 0xC2B6, 0xEC4E, 0xEC4F, 0xEC50, 0xEC51, 0xEC52, - /* U+9738 */ 0xB0D4, 0xC5F9, 0xEC53, 0xEC54, 0xEC55, 0xEC56, 0xF6B2, 0xEC57, - /* U+9740 */ 0xEC58, 0xEC59, 0xEC5A, 0xEC5B, 0xEC5C, 0xEC5D, 0xEC5E, 0xEC5F, - /* U+9748 */ 0xEC60, 0xEC61, 0xEC62, 0xEC63, 0xEC64, 0xEC65, 0xEC66, 0xEC67, - /* U+9750 */ 0xEC68, 0xEC69, 0xC7E0, 0xF6A6, 0xEC6A, 0xEC6B, 0xBEB8, 0xEC6C, - /* U+9758 */ 0xEC6D, 0xBEB2, 0xEC6E, 0xB5E5, 0xEC6F, 0xEC70, 0xB7C7, 0xEC71, - /* U+9760 */ 0xBFBF, 0xC3D2, 0xC3E6, 0xEC72, 0xEC73, 0xD8CC, 0xEC74, 0xEC75, - /* U+9768 */ 0xEC76, 0xB8EF, 0xEC77, 0xEC78, 0xEC79, 0xEC7A, 0xEC7B, 0xEC7C, - /* U+9770 */ 0xEC7D, 0xEC7E, 0xEC80, 0xBDF9, 0xD1A5, 0xEC81, 0xB0D0, 0xEC82, - /* U+9778 */ 0xEC83, 0xEC84, 0xEC85, 0xEC86, 0xF7B0, 0xEC87, 0xEC88, 0xEC89, - /* U+9780 */ 0xEC8A, 0xEC8B, 0xEC8C, 0xEC8D, 0xEC8E, 0xF7B1, 0xEC8F, 0xEC90, - /* U+9788 */ 0xEC91, 0xEC92, 0xEC93, 0xD0AC, 0xEC94, 0xB0B0, 0xEC95, 0xEC96, - /* U+9790 */ 0xEC97, 0xF7B2, 0xF7B3, 0xEC98, 0xF7B4, 0xEC99, 0xEC9A, 0xEC9B, - /* U+9798 */ 0xC7CA, 0xEC9C, 0xEC9D, 0xEC9E, 0xEC9F, 0xECA0, 0xED40, 0xED41, - /* U+97A0 */ 0xBECF, 0xED42, 0xED43, 0xF7B7, 0xED44, 0xED45, 0xED46, 0xED47, - /* U+97A8 */ 0xED48, 0xED49, 0xED4A, 0xF7B6, 0xED4B, 0xB1DE, 0xED4C, 0xF7B5, - /* U+97B0 */ 0xED4D, 0xED4E, 0xF7B8, 0xED4F, 0xF7B9, 0xED50, 0xED51, 0xED52, - /* U+97B8 */ 0xED53, 0xED54, 0xED55, 0xED56, 0xED57, 0xED58, 0xED59, 0xED5A, - /* U+97C0 */ 0xED5B, 0xED5C, 0xED5D, 0xED5E, 0xED5F, 0xED60, 0xED61, 0xED62, - /* U+97C8 */ 0xED63, 0xED64, 0xED65, 0xED66, 0xED67, 0xED68, 0xED69, 0xED6A, - /* U+97D0 */ 0xED6B, 0xED6C, 0xED6D, 0xED6E, 0xED6F, 0xED70, 0xED71, 0xED72, - /* U+97D8 */ 0xED73, 0xED74, 0xED75, 0xED76, 0xED77, 0xED78, 0xED79, 0xED7A, - /* U+97E0 */ 0xED7B, 0xED7C, 0xED7D, 0xED7E, 0xED80, 0xED81, 0xCEA4, 0xC8CD, - /* U+97E8 */ 0xED82, 0xBAAB, 0xE8B8, 0xE8B9, 0xE8BA, 0xBEC2, 0xED83, 0xED84, - /* U+97F0 */ 0xED85, 0xED86, 0xED87, 0xD2F4, 0xED88, 0xD4CF, 0xC9D8, 0xED89, - /* U+97F8 */ 0xED8A, 0xED8B, 0xED8C, 0xED8D, 0xED8E, 0xED8F, 0xED90, 0xED91, - /* U+9800 */ 0xED92, 0xED93, 0xED94, 0xED95, 0xED96, 0xED97, 0xED98, 0xED99, - /* U+9808 */ 0xED9A, 0xED9B, 0xED9C, 0xED9D, 0xED9E, 0xED9F, 0xEDA0, 0xEE40, - /* U+9810 */ 0xEE41, 0xEE42, 0xEE43, 0xEE44, 0xEE45, 0xEE46, 0xEE47, 0xEE48, - /* U+9818 */ 0xEE49, 0xEE4A, 0xEE4B, 0xEE4C, 0xEE4D, 0xEE4E, 0xEE4F, 0xEE50, - /* U+9820 */ 0xEE51, 0xEE52, 0xEE53, 0xEE54, 0xEE55, 0xEE56, 0xEE57, 0xEE58, - /* U+9828 */ 0xEE59, 0xEE5A, 0xEE5B, 0xEE5C, 0xEE5D, 0xEE5E, 0xEE5F, 0xEE60, - /* U+9830 */ 0xEE61, 0xEE62, 0xEE63, 0xEE64, 0xEE65, 0xEE66, 0xEE67, 0xEE68, - /* U+9838 */ 0xEE69, 0xEE6A, 0xEE6B, 0xEE6C, 0xEE6D, 0xEE6E, 0xEE6F, 0xEE70, - /* U+9840 */ 0xEE71, 0xEE72, 0xEE73, 0xEE74, 0xEE75, 0xEE76, 0xEE77, 0xEE78, - /* U+9848 */ 0xEE79, 0xEE7A, 0xEE7B, 0xEE7C, 0xEE7D, 0xEE7E, 0xEE80, 0xEE81, - /* U+9850 */ 0xEE82, 0xEE83, 0xEE84, 0xEE85, 0xEE86, 0xEE87, 0xEE88, 0xEE89, - /* U+9858 */ 0xEE8A, 0xEE8B, 0xEE8C, 0xEE8D, 0xEE8E, 0xEE8F, 0xEE90, 0xEE91, - /* U+9860 */ 0xEE92, 0xEE93, 0xEE94, 0xEE95, 0xEE96, 0xEE97, 0xEE98, 0xEE99, - /* U+9868 */ 0xEE9A, 0xEE9B, 0xEE9C, 0xEE9D, 0xEE9E, 0xEE9F, 0xEEA0, 0xEF40, - /* U+9870 */ 0xEF41, 0xEF42, 0xEF43, 0xEF44, 0xEF45, 0xD2B3, 0xB6A5, 0xC7EA, - /* U+9878 */ 0xF1FC, 0xCFEE, 0xCBB3, 0xD0EB, 0xE7EF, 0xCDE7, 0xB9CB, 0xB6D9, - /* U+9880 */ 0xF1FD, 0xB0E4, 0xCBCC, 0xF1FE, 0xD4A4, 0xC2AD, 0xC1EC, 0xC6C4, - /* U+9888 */ 0xBEB1, 0xF2A1, 0xBCD5, 0xEF46, 0xF2A2, 0xF2A3, 0xEF47, 0xF2A4, - /* U+9890 */ 0xD2C3, 0xC6B5, 0xEF48, 0xCDC7, 0xF2A5, 0xEF49, 0xD3B1, 0xBFC5, - /* U+9898 */ 0xCCE2, 0xEF4A, 0xF2A6, 0xF2A7, 0xD1D5, 0xB6EE, 0xF2A8, 0xF2A9, - /* U+98A0 */ 0xB5DF, 0xF2AA, 0xF2AB, 0xEF4B, 0xB2FC, 0xF2AC, 0xF2AD, 0xC8A7, - /* U+98A8 */ 0xEF4C, 0xEF4D, 0xEF4E, 0xEF4F, 0xEF50, 0xEF51, 0xEF52, 0xEF53, - /* U+98B0 */ 0xEF54, 0xEF55, 0xEF56, 0xEF57, 0xEF58, 0xEF59, 0xEF5A, 0xEF5B, - /* U+98B8 */ 0xEF5C, 0xEF5D, 0xEF5E, 0xEF5F, 0xEF60, 0xEF61, 0xEF62, 0xEF63, - /* U+98C0 */ 0xEF64, 0xEF65, 0xEF66, 0xEF67, 0xEF68, 0xEF69, 0xEF6A, 0xEF6B, - /* U+98C8 */ 0xEF6C, 0xEF6D, 0xEF6E, 0xEF6F, 0xEF70, 0xEF71, 0xB7E7, 0xEF72, - /* U+98D0 */ 0xEF73, 0xECA9, 0xECAA, 0xECAB, 0xEF74, 0xECAC, 0xEF75, 0xEF76, - /* U+98D8 */ 0xC6AE, 0xECAD, 0xECAE, 0xEF77, 0xEF78, 0xEF79, 0xB7C9, 0xCAB3, - /* U+98E0 */ 0xEF7A, 0xEF7B, 0xEF7C, 0xEF7D, 0xEF7E, 0xEF80, 0xEF81, 0xE2B8, - /* U+98E8 */ 0xF7CF, 0xEF82, 0xEF83, 0xEF84, 0xEF85, 0xEF86, 0xEF87, 0xEF88, - /* U+98F0 */ 0xEF89, 0xEF8A, 0xEF8B, 0xEF8C, 0xEF8D, 0xEF8E, 0xEF8F, 0xEF90, - /* U+98F8 */ 0xEF91, 0xEF92, 0xEF93, 0xEF94, 0xEF95, 0xEF96, 0xEF97, 0xEF98, - /* U+9900 */ 0xEF99, 0xEF9A, 0xEF9B, 0xEF9C, 0xEF9D, 0xEF9E, 0xEF9F, 0xEFA0, - /* U+9908 */ 0xF040, 0xF041, 0xF042, 0xF043, 0xF044, 0xF7D0, 0xF045, 0xF046, - /* U+9910 */ 0xB2CD, 0xF047, 0xF048, 0xF049, 0xF04A, 0xF04B, 0xF04C, 0xF04D, - /* U+9918 */ 0xF04E, 0xF04F, 0xF050, 0xF051, 0xF052, 0xF053, 0xF054, 0xF055, - /* U+9920 */ 0xF056, 0xF057, 0xF058, 0xF059, 0xF05A, 0xF05B, 0xF05C, 0xF05D, - /* U+9928 */ 0xF05E, 0xF05F, 0xF060, 0xF061, 0xF062, 0xF063, 0xF7D1, 0xF064, - /* U+9930 */ 0xF065, 0xF066, 0xF067, 0xF068, 0xF069, 0xF06A, 0xF06B, 0xF06C, - /* U+9938 */ 0xF06D, 0xF06E, 0xF06F, 0xF070, 0xF071, 0xF072, 0xF073, 0xF074, - /* U+9940 */ 0xF075, 0xF076, 0xF077, 0xF078, 0xF079, 0xF07A, 0xF07B, 0xF07C, - /* U+9948 */ 0xF07D, 0xF07E, 0xF080, 0xF081, 0xF082, 0xF083, 0xF084, 0xF085, - /* U+9950 */ 0xF086, 0xF087, 0xF088, 0xF089, 0xF7D3, 0xF7D2, 0xF08A, 0xF08B, - /* U+9958 */ 0xF08C, 0xF08D, 0xF08E, 0xF08F, 0xF090, 0xF091, 0xF092, 0xF093, - /* U+9960 */ 0xF094, 0xF095, 0xF096, 0xE2BB, 0xF097, 0xBCA2, 0xF098, 0xE2BC, - /* U+9968 */ 0xE2BD, 0xE2BE, 0xE2BF, 0xE2C0, 0xE2C1, 0xB7B9, 0xD2FB, 0xBDA4, - /* U+9970 */ 0xCACE, 0xB1A5, 0xCBC7, 0xF099, 0xE2C2, 0xB6FC, 0xC8C4, 0xE2C3, - /* U+9978 */ 0xF09A, 0xF09B, 0xBDC8, 0xF09C, 0xB1FD, 0xE2C4, 0xF09D, 0xB6F6, - /* U+9980 */ 0xE2C5, 0xC4D9, 0xF09E, 0xF09F, 0xE2C6, 0xCFDA, 0xB9DD, 0xE2C7, - /* U+9988 */ 0xC0A1, 0xF0A0, 0xE2C8, 0xB2F6, 0xF140, 0xE2C9, 0xF141, 0xC1F3, - /* U+9990 */ 0xE2CA, 0xE2CB, 0xC2F8, 0xE2CC, 0xE2CD, 0xE2CE, 0xCAD7, 0xD8B8, - /* U+9998 */ 0xD9E5, 0xCFE3, 0xF142, 0xF143, 0xF144, 0xF145, 0xF146, 0xF147, - /* U+99A0 */ 0xF148, 0xF149, 0xF14A, 0xF14B, 0xF14C, 0xF0A5, 0xF14D, 0xF14E, - /* U+99A8 */ 0xDCB0, 0xF14F, 0xF150, 0xF151, 0xF152, 0xF153, 0xF154, 0xF155, - /* U+99B0 */ 0xF156, 0xF157, 0xF158, 0xF159, 0xF15A, 0xF15B, 0xF15C, 0xF15D, - /* U+99B8 */ 0xF15E, 0xF15F, 0xF160, 0xF161, 0xF162, 0xF163, 0xF164, 0xF165, - /* U+99C0 */ 0xF166, 0xF167, 0xF168, 0xF169, 0xF16A, 0xF16B, 0xF16C, 0xF16D, - /* U+99C8 */ 0xF16E, 0xF16F, 0xF170, 0xF171, 0xF172, 0xF173, 0xF174, 0xF175, - /* U+99D0 */ 0xF176, 0xF177, 0xF178, 0xF179, 0xF17A, 0xF17B, 0xF17C, 0xF17D, - /* U+99D8 */ 0xF17E, 0xF180, 0xF181, 0xF182, 0xF183, 0xF184, 0xF185, 0xF186, - /* U+99E0 */ 0xF187, 0xF188, 0xF189, 0xF18A, 0xF18B, 0xF18C, 0xF18D, 0xF18E, - /* U+99E8 */ 0xF18F, 0xF190, 0xF191, 0xF192, 0xF193, 0xF194, 0xF195, 0xF196, - /* U+99F0 */ 0xF197, 0xF198, 0xF199, 0xF19A, 0xF19B, 0xF19C, 0xF19D, 0xF19E, - /* U+99F8 */ 0xF19F, 0xF1A0, 0xF240, 0xF241, 0xF242, 0xF243, 0xF244, 0xF245, - /* U+9A00 */ 0xF246, 0xF247, 0xF248, 0xF249, 0xF24A, 0xF24B, 0xF24C, 0xF24D, - /* U+9A08 */ 0xF24E, 0xF24F, 0xF250, 0xF251, 0xF252, 0xF253, 0xF254, 0xF255, - /* U+9A10 */ 0xF256, 0xF257, 0xF258, 0xF259, 0xF25A, 0xF25B, 0xF25C, 0xF25D, - /* U+9A18 */ 0xF25E, 0xF25F, 0xF260, 0xF261, 0xF262, 0xF263, 0xF264, 0xF265, - /* U+9A20 */ 0xF266, 0xF267, 0xF268, 0xF269, 0xF26A, 0xF26B, 0xF26C, 0xF26D, - /* U+9A28 */ 0xF26E, 0xF26F, 0xF270, 0xF271, 0xF272, 0xF273, 0xF274, 0xF275, - /* U+9A30 */ 0xF276, 0xF277, 0xF278, 0xF279, 0xF27A, 0xF27B, 0xF27C, 0xF27D, - /* U+9A38 */ 0xF27E, 0xF280, 0xF281, 0xF282, 0xF283, 0xF284, 0xF285, 0xF286, - /* U+9A40 */ 0xF287, 0xF288, 0xF289, 0xF28A, 0xF28B, 0xF28C, 0xF28D, 0xF28E, - /* U+9A48 */ 0xF28F, 0xF290, 0xF291, 0xF292, 0xF293, 0xF294, 0xF295, 0xF296, - /* U+9A50 */ 0xF297, 0xF298, 0xF299, 0xF29A, 0xF29B, 0xF29C, 0xF29D, 0xF29E, - /* U+9A58 */ 0xF29F, 0xF2A0, 0xF340, 0xF341, 0xF342, 0xF343, 0xF344, 0xF345, - /* U+9A60 */ 0xF346, 0xF347, 0xF348, 0xF349, 0xF34A, 0xF34B, 0xF34C, 0xF34D, - /* U+9A68 */ 0xF34E, 0xF34F, 0xF350, 0xF351, 0xC2ED, 0xD4A6, 0xCDD4, 0xD1B1, - /* U+9A70 */ 0xB3DB, 0xC7FD, 0xF352, 0xB2B5, 0xC2BF, 0xE6E0, 0xCABB, 0xE6E1, - /* U+9A78 */ 0xE6E2, 0xBED4, 0xE6E3, 0xD7A4, 0xCDD5, 0xE6E5, 0xBCDD, 0xE6E4, - /* U+9A80 */ 0xE6E6, 0xE6E7, 0xC2EE, 0xF353, 0xBDBE, 0xE6E8, 0xC2E6, 0xBAA7, - /* U+9A88 */ 0xE6E9, 0xF354, 0xE6EA, 0xB3D2, 0xD1E9, 0xF355, 0xF356, 0xBFA5, - /* U+9A90 */ 0xE6EB, 0xC6EF, 0xE6EC, 0xE6ED, 0xF357, 0xF358, 0xE6EE, 0xC6AD, - /* U+9A98 */ 0xE6EF, 0xF359, 0xC9A7, 0xE6F0, 0xE6F1, 0xE6F2, 0xE5B9, 0xE6F3, - /* U+9AA0 */ 0xE6F4, 0xC2E2, 0xE6F5, 0xE6F6, 0xD6E8, 0xE6F7, 0xF35A, 0xE6F8, - /* U+9AA8 */ 0xB9C7, 0xF35B, 0xF35C, 0xF35D, 0xF35E, 0xF35F, 0xF360, 0xF361, - /* U+9AB0 */ 0xF7BB, 0xF7BA, 0xF362, 0xF363, 0xF364, 0xF365, 0xF7BE, 0xF7BC, - /* U+9AB8 */ 0xBAA1, 0xF366, 0xF7BF, 0xF367, 0xF7C0, 0xF368, 0xF369, 0xF36A, - /* U+9AC0 */ 0xF7C2, 0xF7C1, 0xF7C4, 0xF36B, 0xF36C, 0xF7C3, 0xF36D, 0xF36E, - /* U+9AC8 */ 0xF36F, 0xF370, 0xF371, 0xF7C5, 0xF7C6, 0xF372, 0xF373, 0xF374, - /* U+9AD0 */ 0xF375, 0xF7C7, 0xF376, 0xCBE8, 0xF377, 0xF378, 0xF379, 0xF37A, - /* U+9AD8 */ 0xB8DF, 0xF37B, 0xF37C, 0xF37D, 0xF37E, 0xF380, 0xF381, 0xF7D4, - /* U+9AE0 */ 0xF382, 0xF7D5, 0xF383, 0xF384, 0xF385, 0xF386, 0xF7D6, 0xF387, - /* U+9AE8 */ 0xF388, 0xF389, 0xF38A, 0xF7D8, 0xF38B, 0xF7DA, 0xF38C, 0xF7D7, - /* U+9AF0 */ 0xF38D, 0xF38E, 0xF38F, 0xF390, 0xF391, 0xF392, 0xF393, 0xF394, - /* U+9AF8 */ 0xF395, 0xF7DB, 0xF396, 0xF7D9, 0xF397, 0xF398, 0xF399, 0xF39A, - /* U+9B00 */ 0xF39B, 0xF39C, 0xF39D, 0xD7D7, 0xF39E, 0xF39F, 0xF3A0, 0xF440, - /* U+9B08 */ 0xF7DC, 0xF441, 0xF442, 0xF443, 0xF444, 0xF445, 0xF446, 0xF7DD, - /* U+9B10 */ 0xF447, 0xF448, 0xF449, 0xF7DE, 0xF44A, 0xF44B, 0xF44C, 0xF44D, - /* U+9B18 */ 0xF44E, 0xF44F, 0xF450, 0xF451, 0xF452, 0xF453, 0xF454, 0xF7DF, - /* U+9B20 */ 0xF455, 0xF456, 0xF457, 0xF7E0, 0xF458, 0xF459, 0xF45A, 0xF45B, - /* U+9B28 */ 0xF45C, 0xF45D, 0xF45E, 0xF45F, 0xF460, 0xF461, 0xF462, 0xDBCB, - /* U+9B30 */ 0xF463, 0xF464, 0xD8AA, 0xF465, 0xF466, 0xF467, 0xF468, 0xF469, - /* U+9B38 */ 0xF46A, 0xF46B, 0xF46C, 0xE5F7, 0xB9ED, 0xF46D, 0xF46E, 0xF46F, - /* U+9B40 */ 0xF470, 0xBFFD, 0xBBEA, 0xF7C9, 0xC6C7, 0xF7C8, 0xF471, 0xF7CA, - /* U+9B48 */ 0xF7CC, 0xF7CB, 0xF472, 0xF473, 0xF474, 0xF7CD, 0xF475, 0xCEBA, - /* U+9B50 */ 0xF476, 0xF7CE, 0xF477, 0xF478, 0xC4A7, 0xF479, 0xF47A, 0xF47B, - /* U+9B58 */ 0xF47C, 0xF47D, 0xF47E, 0xF480, 0xF481, 0xF482, 0xF483, 0xF484, - /* U+9B60 */ 0xF485, 0xF486, 0xF487, 0xF488, 0xF489, 0xF48A, 0xF48B, 0xF48C, - /* U+9B68 */ 0xF48D, 0xF48E, 0xF48F, 0xF490, 0xF491, 0xF492, 0xF493, 0xF494, - /* U+9B70 */ 0xF495, 0xF496, 0xF497, 0xF498, 0xF499, 0xF49A, 0xF49B, 0xF49C, - /* U+9B78 */ 0xF49D, 0xF49E, 0xF49F, 0xF4A0, 0xF540, 0xF541, 0xF542, 0xF543, - /* U+9B80 */ 0xF544, 0xF545, 0xF546, 0xF547, 0xF548, 0xF549, 0xF54A, 0xF54B, - /* U+9B88 */ 0xF54C, 0xF54D, 0xF54E, 0xF54F, 0xF550, 0xF551, 0xF552, 0xF553, - /* U+9B90 */ 0xF554, 0xF555, 0xF556, 0xF557, 0xF558, 0xF559, 0xF55A, 0xF55B, - /* U+9B98 */ 0xF55C, 0xF55D, 0xF55E, 0xF55F, 0xF560, 0xF561, 0xF562, 0xF563, - /* U+9BA0 */ 0xF564, 0xF565, 0xF566, 0xF567, 0xF568, 0xF569, 0xF56A, 0xF56B, - /* U+9BA8 */ 0xF56C, 0xF56D, 0xF56E, 0xF56F, 0xF570, 0xF571, 0xF572, 0xF573, - /* U+9BB0 */ 0xF574, 0xF575, 0xF576, 0xF577, 0xF578, 0xF579, 0xF57A, 0xF57B, - /* U+9BB8 */ 0xF57C, 0xF57D, 0xF57E, 0xF580, 0xF581, 0xF582, 0xF583, 0xF584, - /* U+9BC0 */ 0xF585, 0xF586, 0xF587, 0xF588, 0xF589, 0xF58A, 0xF58B, 0xF58C, - /* U+9BC8 */ 0xF58D, 0xF58E, 0xF58F, 0xF590, 0xF591, 0xF592, 0xF593, 0xF594, - /* U+9BD0 */ 0xF595, 0xF596, 0xF597, 0xF598, 0xF599, 0xF59A, 0xF59B, 0xF59C, - /* U+9BD8 */ 0xF59D, 0xF59E, 0xF59F, 0xF5A0, 0xF640, 0xF641, 0xF642, 0xF643, - /* U+9BE0 */ 0xF644, 0xF645, 0xF646, 0xF647, 0xF648, 0xF649, 0xF64A, 0xF64B, - /* U+9BE8 */ 0xF64C, 0xF64D, 0xF64E, 0xF64F, 0xF650, 0xF651, 0xF652, 0xF653, - /* U+9BF0 */ 0xF654, 0xF655, 0xF656, 0xF657, 0xF658, 0xF659, 0xF65A, 0xF65B, - /* U+9BF8 */ 0xF65C, 0xF65D, 0xF65E, 0xF65F, 0xF660, 0xF661, 0xF662, 0xF663, - /* U+9C00 */ 0xF664, 0xF665, 0xF666, 0xF667, 0xF668, 0xF669, 0xF66A, 0xF66B, - /* U+9C08 */ 0xF66C, 0xF66D, 0xF66E, 0xF66F, 0xF670, 0xF671, 0xF672, 0xF673, - /* U+9C10 */ 0xF674, 0xF675, 0xF676, 0xF677, 0xF678, 0xF679, 0xF67A, 0xF67B, - /* U+9C18 */ 0xF67C, 0xF67D, 0xF67E, 0xF680, 0xF681, 0xF682, 0xF683, 0xF684, - /* U+9C20 */ 0xF685, 0xF686, 0xF687, 0xF688, 0xF689, 0xF68A, 0xF68B, 0xF68C, - /* U+9C28 */ 0xF68D, 0xF68E, 0xF68F, 0xF690, 0xF691, 0xF692, 0xF693, 0xF694, - /* U+9C30 */ 0xF695, 0xF696, 0xF697, 0xF698, 0xF699, 0xF69A, 0xF69B, 0xF69C, - /* U+9C38 */ 0xF69D, 0xF69E, 0xF69F, 0xF6A0, 0xF740, 0xF741, 0xF742, 0xF743, - /* U+9C40 */ 0xF744, 0xF745, 0xF746, 0xF747, 0xF748, 0xF749, 0xF74A, 0xF74B, - /* U+9C48 */ 0xF74C, 0xF74D, 0xF74E, 0xF74F, 0xF750, 0xF751, 0xF752, 0xF753, - /* U+9C50 */ 0xF754, 0xF755, 0xF756, 0xF757, 0xF758, 0xF759, 0xF75A, 0xF75B, - /* U+9C58 */ 0xF75C, 0xF75D, 0xF75E, 0xF75F, 0xF760, 0xF761, 0xF762, 0xF763, - /* U+9C60 */ 0xF764, 0xF765, 0xF766, 0xF767, 0xF768, 0xF769, 0xF76A, 0xF76B, - /* U+9C68 */ 0xF76C, 0xF76D, 0xF76E, 0xF76F, 0xF770, 0xF771, 0xF772, 0xF773, - /* U+9C70 */ 0xF774, 0xF775, 0xF776, 0xF777, 0xF778, 0xF779, 0xF77A, 0xF77B, - /* U+9C78 */ 0xF77C, 0xF77D, 0xF77E, 0xF780, 0xD3E3, 0xF781, 0xF782, 0xF6CF, - /* U+9C80 */ 0xF783, 0xC2B3, 0xF6D0, 0xF784, 0xF785, 0xF6D1, 0xF6D2, 0xF6D3, - /* U+9C88 */ 0xF6D4, 0xF786, 0xF787, 0xF6D6, 0xF788, 0xB1AB, 0xF6D7, 0xF789, - /* U+9C90 */ 0xF6D8, 0xF6D9, 0xF6DA, 0xF78A, 0xF6DB, 0xF6DC, 0xF78B, 0xF78C, - /* U+9C98 */ 0xF78D, 0xF78E, 0xF6DD, 0xF6DE, 0xCFCA, 0xF78F, 0xF6DF, 0xF6E0, - /* U+9CA0 */ 0xF6E1, 0xF6E2, 0xF6E3, 0xF6E4, 0xC0F0, 0xF6E5, 0xF6E6, 0xF6E7, - /* U+9CA8 */ 0xF6E8, 0xF6E9, 0xF790, 0xF6EA, 0xF791, 0xF6EB, 0xF6EC, 0xF792, - /* U+9CB0 */ 0xF6ED, 0xF6EE, 0xF6EF, 0xF6F0, 0xF6F1, 0xF6F2, 0xF6F3, 0xF6F4, - /* U+9CB8 */ 0xBEA8, 0xF793, 0xF6F5, 0xF6F6, 0xF6F7, 0xF6F8, 0xF794, 0xF795, - /* U+9CC0 */ 0xF796, 0xF797, 0xF798, 0xC8FA, 0xF6F9, 0xF6FA, 0xF6FB, 0xF6FC, - /* U+9CC8 */ 0xF799, 0xF79A, 0xF6FD, 0xF6FE, 0xF7A1, 0xF7A2, 0xF7A3, 0xF7A4, - /* U+9CD0 */ 0xF7A5, 0xF79B, 0xF79C, 0xF7A6, 0xF7A7, 0xF7A8, 0xB1EE, 0xF7A9, - /* U+9CD8 */ 0xF7AA, 0xF7AB, 0xF79D, 0xF79E, 0xF7AC, 0xF7AD, 0xC1DB, 0xF7AE, - /* U+9CE0 */ 0xF79F, 0xF7A0, 0xF7AF, 0xF840, 0xF841, 0xF842, 0xF843, 0xF844, - /* U+9CE8 */ 0xF845, 0xF846, 0xF847, 0xF848, 0xF849, 0xF84A, 0xF84B, 0xF84C, - /* U+9CF0 */ 0xF84D, 0xF84E, 0xF84F, 0xF850, 0xF851, 0xF852, 0xF853, 0xF854, - /* U+9CF8 */ 0xF855, 0xF856, 0xF857, 0xF858, 0xF859, 0xF85A, 0xF85B, 0xF85C, - /* U+9D00 */ 0xF85D, 0xF85E, 0xF85F, 0xF860, 0xF861, 0xF862, 0xF863, 0xF864, - /* U+9D08 */ 0xF865, 0xF866, 0xF867, 0xF868, 0xF869, 0xF86A, 0xF86B, 0xF86C, - /* U+9D10 */ 0xF86D, 0xF86E, 0xF86F, 0xF870, 0xF871, 0xF872, 0xF873, 0xF874, - /* U+9D18 */ 0xF875, 0xF876, 0xF877, 0xF878, 0xF879, 0xF87A, 0xF87B, 0xF87C, - /* U+9D20 */ 0xF87D, 0xF87E, 0xF880, 0xF881, 0xF882, 0xF883, 0xF884, 0xF885, - /* U+9D28 */ 0xF886, 0xF887, 0xF888, 0xF889, 0xF88A, 0xF88B, 0xF88C, 0xF88D, - /* U+9D30 */ 0xF88E, 0xF88F, 0xF890, 0xF891, 0xF892, 0xF893, 0xF894, 0xF895, - /* U+9D38 */ 0xF896, 0xF897, 0xF898, 0xF899, 0xF89A, 0xF89B, 0xF89C, 0xF89D, - /* U+9D40 */ 0xF89E, 0xF89F, 0xF8A0, 0xF940, 0xF941, 0xF942, 0xF943, 0xF944, - /* U+9D48 */ 0xF945, 0xF946, 0xF947, 0xF948, 0xF949, 0xF94A, 0xF94B, 0xF94C, - /* U+9D50 */ 0xF94D, 0xF94E, 0xF94F, 0xF950, 0xF951, 0xF952, 0xF953, 0xF954, - /* U+9D58 */ 0xF955, 0xF956, 0xF957, 0xF958, 0xF959, 0xF95A, 0xF95B, 0xF95C, - /* U+9D60 */ 0xF95D, 0xF95E, 0xF95F, 0xF960, 0xF961, 0xF962, 0xF963, 0xF964, - /* U+9D68 */ 0xF965, 0xF966, 0xF967, 0xF968, 0xF969, 0xF96A, 0xF96B, 0xF96C, - /* U+9D70 */ 0xF96D, 0xF96E, 0xF96F, 0xF970, 0xF971, 0xF972, 0xF973, 0xF974, - /* U+9D78 */ 0xF975, 0xF976, 0xF977, 0xF978, 0xF979, 0xF97A, 0xF97B, 0xF97C, - /* U+9D80 */ 0xF97D, 0xF97E, 0xF980, 0xF981, 0xF982, 0xF983, 0xF984, 0xF985, - /* U+9D88 */ 0xF986, 0xF987, 0xF988, 0xF989, 0xF98A, 0xF98B, 0xF98C, 0xF98D, - /* U+9D90 */ 0xF98E, 0xF98F, 0xF990, 0xF991, 0xF992, 0xF993, 0xF994, 0xF995, - /* U+9D98 */ 0xF996, 0xF997, 0xF998, 0xF999, 0xF99A, 0xF99B, 0xF99C, 0xF99D, - /* U+9DA0 */ 0xF99E, 0xF99F, 0xF9A0, 0xFA40, 0xFA41, 0xFA42, 0xFA43, 0xFA44, - /* U+9DA8 */ 0xFA45, 0xFA46, 0xFA47, 0xFA48, 0xFA49, 0xFA4A, 0xFA4B, 0xFA4C, - /* U+9DB0 */ 0xFA4D, 0xFA4E, 0xFA4F, 0xFA50, 0xFA51, 0xFA52, 0xFA53, 0xFA54, - /* U+9DB8 */ 0xFA55, 0xFA56, 0xFA57, 0xFA58, 0xFA59, 0xFA5A, 0xFA5B, 0xFA5C, - /* U+9DC0 */ 0xFA5D, 0xFA5E, 0xFA5F, 0xFA60, 0xFA61, 0xFA62, 0xFA63, 0xFA64, - /* U+9DC8 */ 0xFA65, 0xFA66, 0xFA67, 0xFA68, 0xFA69, 0xFA6A, 0xFA6B, 0xFA6C, - /* U+9DD0 */ 0xFA6D, 0xFA6E, 0xFA6F, 0xFA70, 0xFA71, 0xFA72, 0xFA73, 0xFA74, - /* U+9DD8 */ 0xFA75, 0xFA76, 0xFA77, 0xFA78, 0xFA79, 0xFA7A, 0xFA7B, 0xFA7C, - /* U+9DE0 */ 0xFA7D, 0xFA7E, 0xFA80, 0xFA81, 0xFA82, 0xFA83, 0xFA84, 0xFA85, - /* U+9DE8 */ 0xFA86, 0xFA87, 0xFA88, 0xFA89, 0xFA8A, 0xFA8B, 0xFA8C, 0xFA8D, - /* U+9DF0 */ 0xFA8E, 0xFA8F, 0xFA90, 0xFA91, 0xFA92, 0xFA93, 0xFA94, 0xFA95, - /* U+9DF8 */ 0xFA96, 0xFA97, 0xFA98, 0xFA99, 0xFA9A, 0xFA9B, 0xFA9C, 0xFA9D, - /* U+9E00 */ 0xFA9E, 0xFA9F, 0xFAA0, 0xFB40, 0xFB41, 0xFB42, 0xFB43, 0xFB44, - /* U+9E08 */ 0xFB45, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C, - /* U+9E10 */ 0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, - /* U+9E18 */ 0xFB55, 0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xC4F1, - /* U+9E20 */ 0xF0AF, 0xBCA6, 0xF0B0, 0xC3F9, 0xFB5C, 0xC5B8, 0xD1BB, 0xFB5D, - /* U+9E28 */ 0xF0B1, 0xF0B2, 0xF0B3, 0xF0B4, 0xF0B5, 0xD1BC, 0xFB5E, 0xD1EC, - /* U+9E30 */ 0xFB5F, 0xF0B7, 0xF0B6, 0xD4A7, 0xFB60, 0xCDD2, 0xF0B8, 0xF0BA, - /* U+9E38 */ 0xF0B9, 0xF0BB, 0xF0BC, 0xFB61, 0xFB62, 0xB8EB, 0xF0BD, 0xBAE8, - /* U+9E40 */ 0xFB63, 0xF0BE, 0xF0BF, 0xBEE9, 0xF0C0, 0xB6EC, 0xF0C1, 0xF0C2, - /* U+9E48 */ 0xF0C3, 0xF0C4, 0xC8B5, 0xF0C5, 0xF0C6, 0xFB64, 0xF0C7, 0xC5F4, - /* U+9E50 */ 0xFB65, 0xF0C8, 0xFB66, 0xFB67, 0xFB68, 0xF0C9, 0xFB69, 0xF0CA, - /* U+9E58 */ 0xF7BD, 0xFB6A, 0xF0CB, 0xF0CC, 0xF0CD, 0xFB6B, 0xF0CE, 0xFB6C, - /* U+9E60 */ 0xFB6D, 0xFB6E, 0xFB6F, 0xF0CF, 0xBAD7, 0xFB70, 0xF0D0, 0xF0D1, - /* U+9E68 */ 0xF0D2, 0xF0D3, 0xF0D4, 0xF0D5, 0xF0D6, 0xF0D8, 0xFB71, 0xFB72, - /* U+9E70 */ 0xD3A5, 0xF0D7, 0xFB73, 0xF0D9, 0xFB74, 0xFB75, 0xFB76, 0xFB77, - /* U+9E78 */ 0xFB78, 0xFB79, 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xF5BA, 0xC2B9, - /* U+9E80 */ 0xFB7E, 0xFB80, 0xF7E4, 0xFB81, 0xFB82, 0xFB83, 0xFB84, 0xF7E5, - /* U+9E88 */ 0xF7E6, 0xFB85, 0xFB86, 0xF7E7, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, - /* U+9E90 */ 0xFB8B, 0xFB8C, 0xF7E8, 0xC2B4, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, - /* U+9E98 */ 0xFB91, 0xFB92, 0xFB93, 0xFB94, 0xFB95, 0xF7EA, 0xFB96, 0xF7EB, - /* U+9EA0 */ 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xC2F3, 0xFB9D, - /* U+9EA8 */ 0xFB9E, 0xFB9F, 0xFBA0, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, - /* U+9EB0 */ 0xFC45, 0xFC46, 0xFC47, 0xFC48, 0xF4F0, 0xFC49, 0xFC4A, 0xFC4B, - /* U+9EB8 */ 0xF4EF, 0xFC4C, 0xFC4D, 0xC2E9, 0xFC4E, 0xF7E1, 0xF7E2, 0xFC4F, - /* U+9EC0 */ 0xFC50, 0xFC51, 0xFC52, 0xFC53, 0xBBC6, 0xFC54, 0xFC55, 0xFC56, - /* U+9EC8 */ 0xFC57, 0xD9E4, 0xFC58, 0xFC59, 0xFC5A, 0xCAF2, 0xC0E8, 0xF0A4, - /* U+9ED0 */ 0xFC5B, 0xBADA, 0xFC5C, 0xFC5D, 0xC7AD, 0xFC5E, 0xFC5F, 0xFC60, - /* U+9ED8 */ 0xC4AC, 0xFC61, 0xFC62, 0xF7EC, 0xF7ED, 0xF7EE, 0xFC63, 0xF7F0, - /* U+9EE0 */ 0xF7EF, 0xFC64, 0xF7F1, 0xFC65, 0xFC66, 0xF7F4, 0xFC67, 0xF7F3, - /* U+9EE8 */ 0xFC68, 0xF7F2, 0xF7F5, 0xFC69, 0xFC6A, 0xFC6B, 0xFC6C, 0xF7F6, - /* U+9EF0 */ 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74, - /* U+9EF8 */ 0xFC75, 0xEDE9, 0xFC76, 0xEDEA, 0xEDEB, 0xFC77, 0xF6BC, 0xFC78, - /* U+9F00 */ 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D, 0xFC7E, 0xFC80, 0xFC81, - /* U+9F08 */ 0xFC82, 0xFC83, 0xFC84, 0xF6BD, 0xFC85, 0xF6BE, 0xB6A6, 0xFC86, - /* U+9F10 */ 0xD8BE, 0xFC87, 0xFC88, 0xB9C4, 0xFC89, 0xFC8A, 0xFC8B, 0xD8BB, - /* U+9F18 */ 0xFC8C, 0xDCB1, 0xFC8D, 0xFC8E, 0xFC8F, 0xFC90, 0xFC91, 0xFC92, - /* U+9F20 */ 0xCAF3, 0xFC93, 0xF7F7, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98, - /* U+9F28 */ 0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xF7F8, 0xFC9D, 0xFC9E, 0xF7F9, - /* U+9F30 */ 0xFC9F, 0xFCA0, 0xFD40, 0xFD41, 0xFD42, 0xFD43, 0xFD44, 0xF7FB, - /* U+9F38 */ 0xFD45, 0xF7FA, 0xFD46, 0xB1C7, 0xFD47, 0xF7FC, 0xF7FD, 0xFD48, - /* U+9F40 */ 0xFD49, 0xFD4A, 0xFD4B, 0xFD4C, 0xF7FE, 0xFD4D, 0xFD4E, 0xFD4F, - /* U+9F48 */ 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55, 0xFD56, 0xFD57, - /* U+9F50 */ 0xC6EB, 0xECB4, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, - /* U+9F58 */ 0xFD5E, 0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, - /* U+9F60 */ 0xFD66, 0xFD67, 0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, - /* U+9F68 */ 0xFD6E, 0xFD6F, 0xFD70, 0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, - /* U+9F70 */ 0xFD76, 0xFD77, 0xFD78, 0xFD79, 0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, - /* U+9F78 */ 0xFD7E, 0xFD80, 0xFD81, 0xFD82, 0xFD83, 0xFD84, 0xFD85, 0xB3DD, - /* U+9F80 */ 0xF6B3, 0xFD86, 0xFD87, 0xF6B4, 0xC1E4, 0xF6B5, 0xF6B6, 0xF6B7, - /* U+9F88 */ 0xF6B8, 0xF6B9, 0xF6BA, 0xC8A3, 0xF6BB, 0xFD88, 0xFD89, 0xFD8A, - /* U+9F90 */ 0xFD8B, 0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD90, 0xFD91, 0xFD92, - /* U+9F98 */ 0xFD93, 0xC1FA, 0xB9A8, 0xEDE8, 0xFD94, 0xFD95, 0xFD96, 0xB9EA, - /* U+9FA0 */ 0xD9DF, 0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, - /* Contiguous area: U+E766 .. U+E864 */ - /* U+E766 */ 0xA2AB, 0xA2AC, - /* U+E768 */ 0xA2AD, 0xA2AE, 0xA2AF, 0xA2B0, 0x6469, 0xA2E4, 0xA2EF, 0xA2F0, - /* U+E770 */ 0xA2FD, 0xA2FE, 0xA4F4, 0xA4F5, 0xA4F6, 0xA4F7, 0xA4F8, 0xA4F9, - /* U+E778 */ 0xA4FA, 0xA4FB, 0xA4FC, 0xA4FD, 0xA4FE, 0xA5F7, 0xA5F8, 0xA5F9, - /* U+E780 */ 0xA5FA, 0xA5FB, 0xA5FC, 0xA5FD, 0xA5FE, 0xA6B9, 0xA6BA, 0xA6BB, - /* U+E788 */ 0xA6BC, 0xA6BD, 0xA6BE, 0xA6BF, 0xA6C0, 0xA6D9, 0xA6DA, 0xA6DB, - /* U+E790 */ 0xA6DC, 0xA6DD, 0xA6DE, 0xA6DF, 0xA6EC, 0xA6ED, 0xA6F3, 0xA6F6, - /* U+E798 */ 0xA6F7, 0xA6F8, 0xA6F9, 0xA6FA, 0xA6FB, 0xA6FC, 0xA6FD, 0xA6FE, - /* U+E7A0 */ 0xA7C2, 0xA7C3, 0xA7C4, 0xA7C5, 0xA7C6, 0xA7C7, 0xA7C8, 0xA7C9, - /* U+E7A8 */ 0xA7CA, 0xA7CB, 0xA7CC, 0xA7CD, 0xA7CE, 0xA7CF, 0xA7D0, 0xA7F2, - /* U+E7B0 */ 0xA7F3, 0xA7F4, 0xA7F5, 0xA7F6, 0xA7F7, 0xA7F8, 0xA7F9, 0xA7FA, - /* U+E7B8 */ 0xA7FB, 0xA7FC, 0xA7FD, 0xA7FE, 0xA896, 0xA897, 0xA898, 0xA899, - /* U+E7C0 */ 0xA89A, 0xA89B, 0xA89C, 0xA89D, 0xA89E, 0xA89F, 0xA8A0, 0xA8BC, - /* U+E7C8 */ 0x6470, 0xA8C1, 0xA8C2, 0xA8C3, 0xA8C4, 0xA8EA, 0xA8EB, 0xA8EC, - /* U+E7D0 */ 0xA8ED, 0xA8EE, 0xA8EF, 0xA8F0, 0xA8F1, 0xA8F2, 0xA8F3, 0xA8F4, - /* U+E7D8 */ 0xA8F5, 0xA8F6, 0xA8F7, 0xA8F8, 0xA8F9, 0xA8FA, 0xA8FB, 0xA8FC, - /* U+E7E0 */ 0xA8FD, 0xA8FE, 0xA958, 0xA95B, 0xA95D, 0xA95E, 0xA95F, 0x6471, - /* U+E7E8 */ 0x6472, 0x6473, 0x6474, 0x6475, 0x6476, 0x6477, 0x6478, 0x6479, - /* U+E7F0 */ 0x6480, 0x6481, 0x6482, 0x6483, 0xA997, 0xA998, 0xA999, 0xA99A, - /* U+E7F8 */ 0xA99B, 0xA99C, 0xA99D, 0xA99E, 0xA99F, 0xA9A0, 0xA9A1, 0xA9A2, - /* U+E800 */ 0xA9A3, 0xA9F0, 0xA9F1, 0xA9F2, 0xA9F3, 0xA9F4, 0xA9F5, 0xA9F6, - /* U+E808 */ 0xA9F7, 0xA9F8, 0xA9F9, 0xA9FA, 0xA9FB, 0xA9FC, 0xA9FD, 0xA9FE, - /* U+E810 */ 0xD7FA, 0xD7FB, 0xD7FC, 0xD7FD, 0xD7FE, 0x6484, 0xFE51, 0xFE52, - /* U+E818 */ 0xFE53, 0x6485, 0x6486, 0x6487, 0x6488, 0x6489, 0xFE59, 0x6490, - /* U+E820 */ 0x6491, 0x6492, 0x6493, 0x6494, 0x6495, 0x6496, 0xFE61, 0x6497, - /* U+E828 */ 0x6498, 0x6499, 0x64A0, 0xFE66, 0xFE67, 0x64A1, 0x64A2, 0x64A3, - /* U+E830 */ 0x64A4, 0xFE6C, 0xFE6D, 0x64A5, 0x64A6, 0x64A7, 0x64A8, 0x64A9, - /* U+E838 */ 0x64B0, 0x64B1, 0x64B2, 0xFE76, 0x64B3, 0x64B4, 0x64B5, 0x64B6, - /* U+E840 */ 0x64B7, 0x64B8, 0x64B9, 0xFE7E, 0x64C0, 0x64C1, 0x64C2, 0x64C3, - /* U+E848 */ 0x64C4, 0x64C5, 0x64C6, 0x64C7, 0x64C8, 0x64C9, 0x64D0, 0x64D1, - /* U+E850 */ 0x64D2, 0x64D3, 0x64D4, 0x64D5, 0xFE90, 0xFE91, 0x64D6, 0x64D7, - /* U+E858 */ 0x64D8, 0x64D9, 0x64E0, 0x64E1, 0x64E2, 0x64E3, 0x64E4, 0x64E5, - /* U+E860 */ 0x64E6, 0x64E7, 0x64E8, 0x64E9, 0xFEA0, - /* Contiguous area: U+F92C .. U+FA29 */ - /* U+F92C */ 0xFD9C, 0x7045, 0x7046, 0x7047, - /* U+F930 */ 0x7048, 0x7049, 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, - /* U+F938 */ 0x7056, 0x7057, 0x7058, 0x7059, 0x7060, 0x7061, 0x7062, 0x7063, - /* U+F940 */ 0x7064, 0x7065, 0x7066, 0x7067, 0x7068, 0x7069, 0x7070, 0x7071, - /* U+F948 */ 0x7072, 0x7073, 0x7074, 0x7075, 0x7076, 0x7077, 0x7078, 0x7079, - /* U+F950 */ 0x7080, 0x7081, 0x7082, 0x7083, 0x7084, 0x7085, 0x7086, 0x7087, - /* U+F958 */ 0x7088, 0x7089, 0x7090, 0x7091, 0x7092, 0x7093, 0x7094, 0x7095, - /* U+F960 */ 0x7096, 0x7097, 0x7098, 0x7099, 0x70A0, 0x70A1, 0x70A2, 0x70A3, - /* U+F968 */ 0x70A4, 0x70A5, 0x70A6, 0x70A7, 0x70A8, 0x70A9, 0x70B0, 0x70B1, - /* U+F970 */ 0x70B2, 0x70B3, 0x70B4, 0x70B5, 0x70B6, 0x70B7, 0x70B8, 0x70B9, - /* U+F978 */ 0x70C0, 0xFD9D, 0x70C1, 0x70C2, 0x70C3, 0x70C4, 0x70C5, 0x70C6, - /* U+F980 */ 0x70C7, 0x70C8, 0x70C9, 0x70D0, 0x70D1, 0x70D2, 0x70D3, 0x70D4, - /* U+F988 */ 0x70D5, 0x70D6, 0x70D7, 0x70D8, 0x70D9, 0x70E0, 0x70E1, 0x70E2, - /* U+F990 */ 0x70E3, 0x70E4, 0x70E5, 0x70E6, 0x70E7, 0xFD9E, 0x70E8, 0x70E9, - /* U+F998 */ 0x70F0, 0x70F1, 0x70F2, 0x70F3, 0x70F4, 0x70F5, 0x70F6, 0x70F7, - /* U+F9A0 */ 0x70F8, 0x70F9, 0x7100, 0x7101, 0x7102, 0x7103, 0x7104, 0x7105, - /* U+F9A8 */ 0x7106, 0x7107, 0x7108, 0x7109, 0x7110, 0x7111, 0x7112, 0x7113, - /* U+F9B0 */ 0x7114, 0x7115, 0x7116, 0x7117, 0x7118, 0x7119, 0x7120, 0x7121, - /* U+F9B8 */ 0x7122, 0x7123, 0x7124, 0x7125, 0x7126, 0x7127, 0x7128, 0x7129, - /* U+F9C0 */ 0x7130, 0x7131, 0x7132, 0x7133, 0x7134, 0x7135, 0x7136, 0x7137, - /* U+F9C8 */ 0x7138, 0x7139, 0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7145, - /* U+F9D0 */ 0x7146, 0x7147, 0x7148, 0x7149, 0x7150, 0x7151, 0x7152, 0x7153, - /* U+F9D8 */ 0x7154, 0x7155, 0x7156, 0x7157, 0x7158, 0x7159, 0x7160, 0x7161, - /* U+F9E0 */ 0x7162, 0x7163, 0x7164, 0x7165, 0x7166, 0x7167, 0x7168, 0xFD9F, - /* U+F9E8 */ 0x7169, 0x7170, 0x7171, 0x7172, 0x7173, 0x7174, 0x7175, 0x7176, - /* U+F9F0 */ 0x7177, 0xFDA0, 0x7178, 0x7179, 0x7180, 0x7181, 0x7182, 0x7183, - /* U+F9F8 */ 0x7184, 0x7185, 0x7186, 0x7187, 0x7188, 0x7189, 0x7190, 0x7191, - /* U+FA00 */ 0x7192, 0x7193, 0x7194, 0x7195, 0x7196, 0x7197, 0x7198, 0x7199, - /* U+FA08 */ 0x71A0, 0x71A1, 0x71A2, 0x71A3, 0xFE40, 0xFE41, 0xFE42, 0xFE43, - /* U+FA10 */ 0x71A4, 0xFE44, 0x71A5, 0xFE45, 0xFE46, 0x71A6, 0x71A7, 0x71A8, - /* U+FA18 */ 0xFE47, 0x71A9, 0x71B0, 0x71B1, 0x71B2, 0x71B3, 0x71B4, 0xFE48, - /* U+FA20 */ 0xFE49, 0xFE4A, 0x71B5, 0xFE4B, 0xFE4C, 0x71B6, 0x71B7, 0xFE4D, - /* U+FA28 */ 0xFE4E, 0xFE4F, - /* Contiguous area: U+FE30 .. U+FFE5 */ - /* U+FE30 */ 0xA955, 0xA6F2, 0x7848, 0xA6F4, 0xA6F5, 0xA6E0, 0xA6E1, 0xA6F0, - /* U+FE38 */ 0xA6F1, 0xA6E2, 0xA6E3, 0xA6EE, 0xA6EF, 0xA6E6, 0xA6E7, 0xA6E4, - /* U+FE40 */ 0xA6E5, 0xA6E8, 0xA6E9, 0xA6EA, 0xA6EB, 0x7849, 0x7850, 0x7851, - /* U+FE48 */ 0x7852, 0xA968, 0xA969, 0xA96A, 0xA96B, 0xA96C, 0xA96D, 0xA96E, - /* U+FE50 */ 0xA96F, 0xA970, 0xA971, 0x7853, 0xA972, 0xA973, 0xA974, 0xA975, - /* U+FE58 */ 0x7854, 0xA976, 0xA977, 0xA978, 0xA979, 0xA97A, 0xA97B, 0xA97C, - /* U+FE60 */ 0xA97D, 0xA97E, 0xA980, 0xA981, 0xA982, 0xA983, 0xA984, 0x7855, - /* U+FE68 */ 0xA985, 0xA986, 0xA987, 0xA988, 0x7856, 0x7857, 0x7858, 0x7859, - /* U+FE70 */ 0x7860, 0x7861, 0x7862, 0x7863, 0x7864, 0x7865, 0x7866, 0x7867, - /* U+FE78 */ 0x7868, 0x7869, 0x7870, 0x7871, 0x7872, 0x7873, 0x7874, 0x7875, - /* U+FE80 */ 0x7876, 0x7877, 0x7878, 0x7879, 0x7880, 0x7881, 0x7882, 0x7883, - /* U+FE88 */ 0x7884, 0x7885, 0x7886, 0x7887, 0x7888, 0x7889, 0x7890, 0x7891, - /* U+FE90 */ 0x7892, 0x7893, 0x7894, 0x7895, 0x7896, 0x7897, 0x7898, 0x7899, - /* U+FE98 */ 0x78A0, 0x78A1, 0x78A2, 0x78A3, 0x78A4, 0x78A5, 0x78A6, 0x78A7, - /* U+FEA0 */ 0x78A8, 0x78A9, 0x78B0, 0x78B1, 0x78B2, 0x78B3, 0x78B4, 0x78B5, - /* U+FEA8 */ 0x78B6, 0x78B7, 0x78B8, 0x78B9, 0x78C0, 0x78C1, 0x78C2, 0x78C3, - /* U+FEB0 */ 0x78C4, 0x78C5, 0x78C6, 0x78C7, 0x78C8, 0x78C9, 0x78D0, 0x78D1, - /* U+FEB8 */ 0x78D2, 0x78D3, 0x78D4, 0x78D5, 0x78D6, 0x78D7, 0x78D8, 0x78D9, - /* U+FEC0 */ 0x78E0, 0x78E1, 0x78E2, 0x78E3, 0x78E4, 0x78E5, 0x78E6, 0x78E7, - /* U+FEC8 */ 0x78E8, 0x78E9, 0x78F0, 0x78F1, 0x78F2, 0x78F3, 0x78F4, 0x78F5, - /* U+FED0 */ 0x78F6, 0x78F7, 0x78F8, 0x78F9, 0x7900, 0x7901, 0x7902, 0x7903, - /* U+FED8 */ 0x7904, 0x7905, 0x7906, 0x7907, 0x7908, 0x7909, 0x7910, 0x7911, - /* U+FEE0 */ 0x7912, 0x7913, 0x7914, 0x7915, 0x7916, 0x7917, 0x7918, 0x7919, - /* U+FEE8 */ 0x7920, 0x7921, 0x7922, 0x7923, 0x7924, 0x7925, 0x7926, 0x7927, - /* U+FEF0 */ 0x7928, 0x7929, 0x7930, 0x7931, 0x7932, 0x7933, 0x7934, 0x7935, - /* U+FEF8 */ 0x7936, 0x7937, 0x7938, 0x7939, 0x7940, 0x7941, 0x7942, 0x7943, - /* U+FF00 */ 0x7944, 0xA3A1, 0xA3A2, 0xA3A3, 0xA1E7, 0xA3A5, 0xA3A6, 0xA3A7, - /* U+FF08 */ 0xA3A8, 0xA3A9, 0xA3AA, 0xA3AB, 0xA3AC, 0xA3AD, 0xA3AE, 0xA3AF, - /* U+FF10 */ 0xA3B0, 0xA3B1, 0xA3B2, 0xA3B3, 0xA3B4, 0xA3B5, 0xA3B6, 0xA3B7, - /* U+FF18 */ 0xA3B8, 0xA3B9, 0xA3BA, 0xA3BB, 0xA3BC, 0xA3BD, 0xA3BE, 0xA3BF, - /* U+FF20 */ 0xA3C0, 0xA3C1, 0xA3C2, 0xA3C3, 0xA3C4, 0xA3C5, 0xA3C6, 0xA3C7, - /* U+FF28 */ 0xA3C8, 0xA3C9, 0xA3CA, 0xA3CB, 0xA3CC, 0xA3CD, 0xA3CE, 0xA3CF, - /* U+FF30 */ 0xA3D0, 0xA3D1, 0xA3D2, 0xA3D3, 0xA3D4, 0xA3D5, 0xA3D6, 0xA3D7, - /* U+FF38 */ 0xA3D8, 0xA3D9, 0xA3DA, 0xA3DB, 0xA3DC, 0xA3DD, 0xA3DE, 0xA3DF, - /* U+FF40 */ 0xA3E0, 0xA3E1, 0xA3E2, 0xA3E3, 0xA3E4, 0xA3E5, 0xA3E6, 0xA3E7, - /* U+FF48 */ 0xA3E8, 0xA3E9, 0xA3EA, 0xA3EB, 0xA3EC, 0xA3ED, 0xA3EE, 0xA3EF, - /* U+FF50 */ 0xA3F0, 0xA3F1, 0xA3F2, 0xA3F3, 0xA3F4, 0xA3F5, 0xA3F6, 0xA3F7, - /* U+FF58 */ 0xA3F8, 0xA3F9, 0xA3FA, 0xA3FB, 0xA3FC, 0xA3FD, 0xA1AB, 0x7945, - /* U+FF60 */ 0x7946, 0x7947, 0x7948, 0x7949, 0x7950, 0x7951, 0x7952, 0x7953, - /* U+FF68 */ 0x7954, 0x7955, 0x7956, 0x7957, 0x7958, 0x7959, 0x7960, 0x7961, - /* U+FF70 */ 0x7962, 0x7963, 0x7964, 0x7965, 0x7966, 0x7967, 0x7968, 0x7969, - /* U+FF78 */ 0x7970, 0x7971, 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7977, - /* U+FF80 */ 0x7978, 0x7979, 0x7980, 0x7981, 0x7982, 0x7983, 0x7984, 0x7985, - /* U+FF88 */ 0x7986, 0x7987, 0x7988, 0x7989, 0x7990, 0x7991, 0x7992, 0x7993, - /* U+FF90 */ 0x7994, 0x7995, 0x7996, 0x7997, 0x7998, 0x7999, 0x79A0, 0x79A1, - /* U+FF98 */ 0x79A2, 0x79A3, 0x79A4, 0x79A5, 0x79A6, 0x79A7, 0x79A8, 0x79A9, - /* U+FFA0 */ 0x79B0, 0x79B1, 0x79B2, 0x79B3, 0x79B4, 0x79B5, 0x79B6, 0x79B7, - /* U+FFA8 */ 0x79B8, 0x79B9, 0x79C0, 0x79C1, 0x79C2, 0x79C3, 0x79C4, 0x79C5, - /* U+FFB0 */ 0x79C6, 0x79C7, 0x79C8, 0x79C9, 0x79D0, 0x79D1, 0x79D2, 0x79D3, - /* U+FFB8 */ 0x79D4, 0x79D5, 0x79D6, 0x79D7, 0x79D8, 0x79D9, 0x79E0, 0x79E1, - /* U+FFC0 */ 0x79E2, 0x79E3, 0x79E4, 0x79E5, 0x79E6, 0x79E7, 0x79E8, 0x79E9, - /* U+FFC8 */ 0x79F0, 0x79F1, 0x79F2, 0x79F3, 0x79F4, 0x79F5, 0x79F6, 0x79F7, - /* U+FFD0 */ 0x79F8, 0x79F9, 0x7A00, 0x7A01, 0x7A02, 0x7A03, 0x7A04, 0x7A05, - /* U+FFD8 */ 0x7A06, 0x7A07, 0x7A08, 0x7A09, 0x7A10, 0x7A11, 0x7A12, 0x7A13, - /* U+FFE0 */ 0xA1E9, 0xA1EA, 0xA956, 0xA3FE, 0xA957, 0xA3A4, -}; - -static inline bool InRange(unsigned c, unsigned lower, unsigned upper) -{ - return c >= lower && c <= upper; -} - -static inline unsigned gb4lin_to_gb(unsigned gb4lin) -{ - unsigned a, b, c, d; - a = 0x81 + gb4lin / 12600; - b = 0x30 + (gb4lin / 1260) % 10; - c = 0x81 + (gb4lin / 10) % 126; - d = 0x30 + gb4lin % 10; - return ((a << 24) | (b << 16) | (c << 8) | d); -} - -static int qt_UnicodeToGb18030(unsigned uni, uint8_t *gbchar) { - /* Returns the bytesize of the GB18030 character. */ - unsigned gb, gb4lin; - indexTbl_t u2g; - - if (uni < 0x80) { - *gbchar = (uint8_t)uni; - return 1; - } - else if (uni <= 0xD7FF || InRange(uni, 0xE766, 0xFFFF)) { - u2g = ucs_to_gb18030_index[uni >> 8]; - - if ((uint8_t)(uni & 0xFF) >= u2g.tblBegin && (uint8_t)(uni & 0xFF) <= u2g.tblEnd) { - // Use mapping table (2-byte or 4-byte GB18030) - unsigned tblEntry; - - tblEntry = ucs_to_gb18030[uni - u2g.tblOffset]; - - if (tblEntry > 0x8000) { - // 2-byte GB18030 - gb = tblEntry; - } - else { - // 4-byte GB18030 stored in a special compact format - uint8_t a, b; - a = 0x81; - b = 0x30 + (tblEntry >> 11); - if (tblEntry >= 0x7000) { - a += 3; - b -= 14; - } - else if (tblEntry >= 0x6000) { - a += 2; - b -= 6; - } - else if (tblEntry >= 0x3000) { - a += 1; - b -= 6; - } - else if (b >= 0x31) { - b += 5; - } - gbchar[0] = a; - gbchar[1] = b; - gbchar[2] = 0x81 + ((tblEntry >> 4) & 0x7F); - gbchar[3] = 0x30 + (tblEntry & 0xF); - return 4; - } - } - else { - // 4-byte GB18030 calculated algorithmically - gb4lin = u2g.algOffset + (uni & 0xFF); - // Yikes, my index table could not cover all the bases... - if (InRange(uni, 0x49B8, 0x49FF)) - gb4lin -= 11; - gb = gb4lin_to_gb(gb4lin); - } - } - else if (InRange(uni, 0xE000, 0xE765)) { - // User-defined areas in GB18030 (2-byte) - if (uni <= 0xE233) - gb = 0xAAA1 + (((uni - 0xE000) / 94) << 8) + (uni - 0xE000) % 94; - else if (uni <= 0xE4C5) - gb = 0xF8A1 + (((uni - 0xE234) / 94) << 8) + (uni - 0xE234) % 94; - else { - gb = 0xA140 + (((uni - 0xE4C6) / 96) << 8) + (uni - 0xE4C6) % 96; - // Skip the gap at 0x7F - if ((gb & 0xFF) >= 0x7F) - gb++; - } - } - else if (InRange(uni, 0x10000, 0x10FFFF)) { - // Qt 3.x does not support beyond BMP yet, but what the heck... - // (U+10000 = GB+90308130) to (U+10FFFF = GB+E3329A35) - gb = gb4lin_to_gb(0x1E248 + uni); - } - else { - // Surrogate area and other undefined/reserved areas (discard) - *gbchar = 0; - return 0; - } - - if (gb <= 0xFFFF) { - gbchar[0] = (uint8_t)((gb >> 8) & 0xFF); - gbchar[1] = (uint8_t)(gb & 0xFF); - return 2; - } - else { - gbchar[0] = (uint8_t)((gb >> 24) & 0xFF); - gbchar[1] = (uint8_t)((gb >> 16) & 0xFF); - gbchar[2] = (uint8_t)((gb >> 8) & 0xFF); - gbchar[3] = (uint8_t)(gb & 0xFF); - return 4; - } -} - -static int qt_UnicodeToGbk(unsigned uni, uint8_t *gbchar) { - /* Returns the bytesize of the GBK character. */ - /* Intended for improving performance of GB2312 and GBK functions. */ - unsigned gb; - indexTbl_t u2g; - - if (uni < 0x80) { - *gbchar = (uint8_t)uni; - return 1; - } - else if (uni <= 0xD7FF || InRange(uni, 0xE766, 0xFFFF)) { - u2g = ucs_to_gb18030_index[uni >> 8]; - - if ((uint8_t)(uni & 0xFF) >= u2g.tblBegin && (uint8_t)(uni & 0xFF) <= u2g.tblEnd) { - // Use mapping table (2-byte GBK or 4-byte GB18030) - unsigned tblEntry; - - tblEntry = ucs_to_gb18030[uni - u2g.tblOffset]; - - if (tblEntry > 0x8000) { - // GBK - gb = tblEntry; - } - else { - // 4-byte GB18030 stored in a special compact format (discard) - *gbchar = 0; - return 0; - } - } - else { - // 4-byte GB18030 calculated algorithmically (discard) - *gbchar = 0; - return 0; - } - } - else if (InRange(uni, 0xE000, 0xE765)) { - // User-defined areas in GB18030 (2-byte) - if (uni <= 0xE233) - gb = 0xAAA1 + (((uni - 0xE000) / 94) << 8) + (uni - 0xE000) % 94; - else if (uni <= 0xE4C5) - gb = 0xF8A1 + (((uni - 0xE234) / 94) << 8) + (uni - 0xE234) % 94; - else { - gb = 0xA140 + (((uni - 0xE4C6) / 96) << 8) + (uni - 0xE4C6) % 96; - // Skip the gap at 0x7F - if ((gb & 0xFF) >= 0x7F) - gb++; - } - } - else { - // Surrogate area and other undefined/reserved areas (discard) - *gbchar = 0; - return 0; - } - - gbchar[0] = (uint8_t)((gb >> 8) & 0xFF); - gbchar[1] = (uint8_t)(gb & 0xFF); - return 2; -} - -void GBTextEncoder::EncodeGB18030(const std::wstring& str, std::string& bytes) -{ - static const char replacement = '?'; - unsigned high = 0; -// int invalid = 0; - - bytes.resize(4 * str.length() + 1); - int index = 0; - - uint8_t buf[4]; - for (size_t i = 0; i < str.length(); ++i) { - unsigned ch = str[i]; - int len; - if (high > 0) { - if (ZXing::TextUtfEncoding::IsUtf16LowSurrogate(ch)) { - // valid surrogate pair - ++i; - unsigned u = ZXing::TextUtfEncoding::CodePointFromUtf16Surrogates(high, ch); - len = qt_UnicodeToGb18030(u, buf); - if (len >= 2) { - for (int j = 0; j(ch); - } - else if (ZXing::TextUtfEncoding::IsUtf16HighSurrogate(ch)) { - // surrogates area. check for correct encoding - // we need at least one more character, first the high surrogate, then the low one - high = ch; - } - else if ((len = qt_UnicodeToGb18030(ch, buf)) >= 2) { - for (int j = 0; j(ch); - } - else if ((qt_UnicodeToGbk(ch, buf) == 2) && - (buf[0] >= 0xA1) && (buf[1] >= 0xA1)) { - bytes[index++] = buf[0]; - bytes[index++] = buf[1]; - } - else { - // Error - bytes[index++] = replacement; - //++invalid; - } - } - bytes.resize(index); -} diff --git a/core/src/textcodec/GBTextEncoder.h b/core/src/textcodec/GBTextEncoder.h deleted file mode 100644 index 38d171e903..0000000000 --- a/core/src/textcodec/GBTextEncoder.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -class GBTextEncoder -{ -public: - static void EncodeGB18030(const std::wstring& str, std::string& bytes); - static void EncodeGB2312(const std::wstring& str, std::string& bytes); -}; diff --git a/core/src/textcodec/JPTextDecoder.cpp b/core/src/textcodec/JPTextDecoder.cpp deleted file mode 100644 index 22874a4961..0000000000 --- a/core/src/textcodec/JPTextDecoder.cpp +++ /dev/null @@ -1,2775 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Most of the code here was originally written by Serika Kurusugawa -// a.k.a. Junji Takagi, and is included in Qt with the author's permission, -// and the grateful thanks of the Qt team. - -#include "JPTextDecoder.h" - -/* -* This data is derived from Unicode 1.1, -* JIS X 0208 (1990) to Unicode mapping table version 0.9 . -* (In addition NEC Vendor Defined Char included) -*/ -static unsigned short const jisx0208_to_unicode[] = { - /* 0x2121 - 0x217e */ - 0x3000, 0x3001, 0x3002, 0xff0c, 0xff0e, 0x30fb, 0xff1a, - 0xff1b, 0xff1f, 0xff01, 0x309b, 0x309c, 0x00b4, 0xff40, 0x00a8, - 0xff3e, 0xffe3, 0xff3f, 0x30fd, 0x30fe, 0x309d, 0x309e, 0x3003, - 0x4edd, 0x3005, 0x3006, 0x3007, 0x30fc, 0x2015, 0x2010, 0xff0f, - 0x005c, 0x301c, 0x2016, 0xff5c, 0x2026, 0x2025, 0x2018, 0x2019, - 0x201c, 0x201d, 0xff08, 0xff09, 0x3014, 0x3015, 0xff3b, 0xff3d, - 0xff5b, 0xff5d, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, - 0x300e, 0x300f, 0x3010, 0x3011, 0xff0b, 0xff0d, 0x00b1, 0x00d7, - 0x00f7, 0xff1d, 0x2260, 0xff1c, 0xff1e, 0x2266, 0x2267, 0x221e, - 0x2234, 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xffe5, - 0xff04, 0x00a2, 0x00a3, 0xff05, 0xff03, 0xff06, 0xff0a, 0xff20, - 0x00a7, 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, - /* 0x2221 - 0x227e */ - 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, - 0x203b, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, 0x2283, - 0x222a, 0x2229, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2227, 0x2228, 0x00ac, 0x21d2, 0x21d4, 0x2200, - 0x2203, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2220, 0x22a5, 0x2312, 0x2202, - 0x2207, 0x2261, 0x2252, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, - 0x2235, 0x222b, 0x222c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x212b, 0x2030, 0x266f, 0x266d, 0x266a, 0x2020, - 0x2021, 0x00b6, 0x0000, 0x0000, 0x0000, 0x0000, 0x25ef, - /* 0x2321 - 0x237e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xff10, 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, - 0xff18, 0xff19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, - 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, - 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, - 0xff38, 0xff39, 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, - 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, - 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, - 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2421 - 0x247e */ - 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, - 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, - 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, - 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, - 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, - 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, - 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, - 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, - 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, - 0x3088, 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, - 0x3090, 0x3091, 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2521 - 0x257e */ - 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, - 0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, - 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, - 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, - 0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, - 0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, - 0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, - 0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, - 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, - 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, - 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2621 - 0x267e */ - 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, - 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, - 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, - 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, - 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, - 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2721 - 0x277e */ - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, - 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, - 0x041e, 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, - 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, - 0x042e, 0x042f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, - 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, - 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, - 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, - 0x044e, 0x044f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2821 - 0x287e */ - 0x2500, 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, - 0x252c, 0x2524, 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, - 0x251b, 0x2517, 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, - 0x252f, 0x2528, 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, - 0x2542, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2921 - 0x297e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2a21 - 0x2a7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2b21 - 0x2b7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2c21 - 0x2c7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2d21 - 0x2d7e */ - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, - 0x2467, 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, - 0x246f, 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, - 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x0000, - 0x3349, 0x3314, 0x3322, 0x334d, 0x3318, 0x3327, 0x3303, 0x3336, - 0x3351, 0x3357, 0x330d, 0x3326, 0x3323, 0x332b, 0x334a, 0x333b, - 0x339c, 0x339d, 0x339e, 0x338e, 0x338f, 0x33c4, 0x33a1, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x337b, - 0x301d, 0x301f, 0x2116, 0x33cd, 0x2121, 0x32a4, 0x32a5, 0x32a6, - 0x32a7, 0x32a8, 0x3231, 0x3232, 0x3239, 0x337e, 0x337d, 0x337c, - 0x2252, 0x2261, 0x222b, 0x222e, 0x2211, 0x221a, 0x22a5, 0x2220, - 0x221f, 0x22bf, 0x2235, 0x2229, 0x222a, 0x0000, 0x0000, - /* 0x2e21 - 0x2e7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2f21 - 0x2f7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x3021 - 0x307e */ - 0x4e9c, 0x5516, 0x5a03, 0x963f, 0x54c0, 0x611b, 0x6328, - 0x59f6, 0x9022, 0x8475, 0x831c, 0x7a50, 0x60aa, 0x63e1, 0x6e25, - 0x65ed, 0x8466, 0x82a6, 0x9bf5, 0x6893, 0x5727, 0x65a1, 0x6271, - 0x5b9b, 0x59d0, 0x867b, 0x98f4, 0x7d62, 0x7dbe, 0x9b8e, 0x6216, - 0x7c9f, 0x88b7, 0x5b89, 0x5eb5, 0x6309, 0x6697, 0x6848, 0x95c7, - 0x978d, 0x674f, 0x4ee5, 0x4f0a, 0x4f4d, 0x4f9d, 0x5049, 0x56f2, - 0x5937, 0x59d4, 0x5a01, 0x5c09, 0x60df, 0x610f, 0x6170, 0x6613, - 0x6905, 0x70ba, 0x754f, 0x7570, 0x79fb, 0x7dad, 0x7def, 0x80c3, - 0x840e, 0x8863, 0x8b02, 0x9055, 0x907a, 0x533b, 0x4e95, 0x4ea5, - 0x57df, 0x80b2, 0x90c1, 0x78ef, 0x4e00, 0x58f1, 0x6ea2, 0x9038, - 0x7a32, 0x8328, 0x828b, 0x9c2f, 0x5141, 0x5370, 0x54bd, 0x54e1, - 0x56e0, 0x59fb, 0x5f15, 0x98f2, 0x6deb, 0x80e4, 0x852d, - /* 0x3121 - 0x317e */ - 0x9662, 0x9670, 0x96a0, 0x97fb, 0x540b, 0x53f3, 0x5b87, - 0x70cf, 0x7fbd, 0x8fc2, 0x96e8, 0x536f, 0x9d5c, 0x7aba, 0x4e11, - 0x7893, 0x81fc, 0x6e26, 0x5618, 0x5504, 0x6b1d, 0x851a, 0x9c3b, - 0x59e5, 0x53a9, 0x6d66, 0x74dc, 0x958f, 0x5642, 0x4e91, 0x904b, - 0x96f2, 0x834f, 0x990c, 0x53e1, 0x55b6, 0x5b30, 0x5f71, 0x6620, - 0x66f3, 0x6804, 0x6c38, 0x6cf3, 0x6d29, 0x745b, 0x76c8, 0x7a4e, - 0x9834, 0x82f1, 0x885b, 0x8a60, 0x92ed, 0x6db2, 0x75ab, 0x76ca, - 0x99c5, 0x60a6, 0x8b01, 0x8d8a, 0x95b2, 0x698e, 0x53ad, 0x5186, - 0x5712, 0x5830, 0x5944, 0x5bb4, 0x5ef6, 0x6028, 0x63a9, 0x63f4, - 0x6cbf, 0x6f14, 0x708e, 0x7114, 0x7159, 0x71d5, 0x733f, 0x7e01, - 0x8276, 0x82d1, 0x8597, 0x9060, 0x925b, 0x9d1b, 0x5869, 0x65bc, - 0x6c5a, 0x7525, 0x51f9, 0x592e, 0x5965, 0x5f80, 0x5fdc, - /* 0x3221 - 0x327e */ - 0x62bc, 0x65fa, 0x6a2a, 0x6b27, 0x6bb4, 0x738b, 0x7fc1, - 0x8956, 0x9d2c, 0x9d0e, 0x9ec4, 0x5ca1, 0x6c96, 0x837b, 0x5104, - 0x5c4b, 0x61b6, 0x81c6, 0x6876, 0x7261, 0x4e59, 0x4ffa, 0x5378, - 0x6069, 0x6e29, 0x7a4f, 0x97f3, 0x4e0b, 0x5316, 0x4eee, 0x4f55, - 0x4f3d, 0x4fa1, 0x4f73, 0x52a0, 0x53ef, 0x5609, 0x590f, 0x5ac1, - 0x5bb6, 0x5be1, 0x79d1, 0x6687, 0x679c, 0x67b6, 0x6b4c, 0x6cb3, - 0x706b, 0x73c2, 0x798d, 0x79be, 0x7a3c, 0x7b87, 0x82b1, 0x82db, - 0x8304, 0x8377, 0x83ef, 0x83d3, 0x8766, 0x8ab2, 0x5629, 0x8ca8, - 0x8fe6, 0x904e, 0x971e, 0x868a, 0x4fc4, 0x5ce8, 0x6211, 0x7259, - 0x753b, 0x81e5, 0x82bd, 0x86fe, 0x8cc0, 0x96c5, 0x9913, 0x99d5, - 0x4ecb, 0x4f1a, 0x89e3, 0x56de, 0x584a, 0x58ca, 0x5efb, 0x5feb, - 0x602a, 0x6094, 0x6062, 0x61d0, 0x6212, 0x62d0, 0x6539, - /* 0x3321 - 0x337e */ - 0x9b41, 0x6666, 0x68b0, 0x6d77, 0x7070, 0x754c, 0x7686, - 0x7d75, 0x82a5, 0x87f9, 0x958b, 0x968e, 0x8c9d, 0x51f1, 0x52be, - 0x5916, 0x54b3, 0x5bb3, 0x5d16, 0x6168, 0x6982, 0x6daf, 0x788d, - 0x84cb, 0x8857, 0x8a72, 0x93a7, 0x9ab8, 0x6d6c, 0x99a8, 0x86d9, - 0x57a3, 0x67ff, 0x86ce, 0x920e, 0x5283, 0x5687, 0x5404, 0x5ed3, - 0x62e1, 0x64b9, 0x683c, 0x6838, 0x6bbb, 0x7372, 0x78ba, 0x7a6b, - 0x899a, 0x89d2, 0x8d6b, 0x8f03, 0x90ed, 0x95a3, 0x9694, 0x9769, - 0x5b66, 0x5cb3, 0x697d, 0x984d, 0x984e, 0x639b, 0x7b20, 0x6a2b, - 0x6a7f, 0x68b6, 0x9c0d, 0x6f5f, 0x5272, 0x559d, 0x6070, 0x62ec, - 0x6d3b, 0x6e07, 0x6ed1, 0x845b, 0x8910, 0x8f44, 0x4e14, 0x9c39, - 0x53f6, 0x691b, 0x6a3a, 0x9784, 0x682a, 0x515c, 0x7ac3, 0x84b2, - 0x91dc, 0x938c, 0x565b, 0x9d28, 0x6822, 0x8305, 0x8431, - /* 0x3421 - 0x347e */ - 0x7ca5, 0x5208, 0x82c5, 0x74e6, 0x4e7e, 0x4f83, 0x51a0, - 0x5bd2, 0x520a, 0x52d8, 0x52e7, 0x5dfb, 0x559a, 0x582a, 0x59e6, - 0x5b8c, 0x5b98, 0x5bdb, 0x5e72, 0x5e79, 0x60a3, 0x611f, 0x6163, - 0x61be, 0x63db, 0x6562, 0x67d1, 0x6853, 0x68fa, 0x6b3e, 0x6b53, - 0x6c57, 0x6f22, 0x6f97, 0x6f45, 0x74b0, 0x7518, 0x76e3, 0x770b, - 0x7aff, 0x7ba1, 0x7c21, 0x7de9, 0x7f36, 0x7ff0, 0x809d, 0x8266, - 0x839e, 0x89b3, 0x8acc, 0x8cab, 0x9084, 0x9451, 0x9593, 0x9591, - 0x95a2, 0x9665, 0x97d3, 0x9928, 0x8218, 0x4e38, 0x542b, 0x5cb8, - 0x5dcc, 0x73a9, 0x764c, 0x773c, 0x5ca9, 0x7feb, 0x8d0b, 0x96c1, - 0x9811, 0x9854, 0x9858, 0x4f01, 0x4f0e, 0x5371, 0x559c, 0x5668, - 0x57fa, 0x5947, 0x5b09, 0x5bc4, 0x5c90, 0x5e0c, 0x5e7e, 0x5fcc, - 0x63ee, 0x673a, 0x65d7, 0x65e2, 0x671f, 0x68cb, 0x68c4, - /* 0x3521 - 0x357e */ - 0x6a5f, 0x5e30, 0x6bc5, 0x6c17, 0x6c7d, 0x757f, 0x7948, - 0x5b63, 0x7a00, 0x7d00, 0x5fbd, 0x898f, 0x8a18, 0x8cb4, 0x8d77, - 0x8ecc, 0x8f1d, 0x98e2, 0x9a0e, 0x9b3c, 0x4e80, 0x507d, 0x5100, - 0x5993, 0x5b9c, 0x622f, 0x6280, 0x64ec, 0x6b3a, 0x72a0, 0x7591, - 0x7947, 0x7fa9, 0x87fb, 0x8abc, 0x8b70, 0x63ac, 0x83ca, 0x97a0, - 0x5409, 0x5403, 0x55ab, 0x6854, 0x6a58, 0x8a70, 0x7827, 0x6775, - 0x9ecd, 0x5374, 0x5ba2, 0x811a, 0x8650, 0x9006, 0x4e18, 0x4e45, - 0x4ec7, 0x4f11, 0x53ca, 0x5438, 0x5bae, 0x5f13, 0x6025, 0x6551, - 0x673d, 0x6c42, 0x6c72, 0x6ce3, 0x7078, 0x7403, 0x7a76, 0x7aae, - 0x7b08, 0x7d1a, 0x7cfe, 0x7d66, 0x65e7, 0x725b, 0x53bb, 0x5c45, - 0x5de8, 0x62d2, 0x62e0, 0x6319, 0x6e20, 0x865a, 0x8a31, 0x8ddd, - 0x92f8, 0x6f01, 0x79a6, 0x9b5a, 0x4ea8, 0x4eab, 0x4eac, - /* 0x3621 - 0x367e */ - 0x4f9b, 0x4fa0, 0x50d1, 0x5147, 0x7af6, 0x5171, 0x51f6, - 0x5354, 0x5321, 0x537f, 0x53eb, 0x55ac, 0x5883, 0x5ce1, 0x5f37, - 0x5f4a, 0x602f, 0x6050, 0x606d, 0x631f, 0x6559, 0x6a4b, 0x6cc1, - 0x72c2, 0x72ed, 0x77ef, 0x80f8, 0x8105, 0x8208, 0x854e, 0x90f7, - 0x93e1, 0x97ff, 0x9957, 0x9a5a, 0x4ef0, 0x51dd, 0x5c2d, 0x6681, - 0x696d, 0x5c40, 0x66f2, 0x6975, 0x7389, 0x6850, 0x7c81, 0x50c5, - 0x52e4, 0x5747, 0x5dfe, 0x9326, 0x65a4, 0x6b23, 0x6b3d, 0x7434, - 0x7981, 0x79bd, 0x7b4b, 0x7dca, 0x82b9, 0x83cc, 0x887f, 0x895f, - 0x8b39, 0x8fd1, 0x91d1, 0x541f, 0x9280, 0x4e5d, 0x5036, 0x53e5, - 0x533a, 0x72d7, 0x7396, 0x77e9, 0x82e6, 0x8eaf, 0x99c6, 0x99c8, - 0x99d2, 0x5177, 0x611a, 0x865e, 0x55b0, 0x7a7a, 0x5076, 0x5bd3, - 0x9047, 0x9685, 0x4e32, 0x6adb, 0x91e7, 0x5c51, 0x5c48, - /* 0x3721 - 0x377e */ - 0x6398, 0x7a9f, 0x6c93, 0x9774, 0x8f61, 0x7aaa, 0x718a, - 0x9688, 0x7c82, 0x6817, 0x7e70, 0x6851, 0x936c, 0x52f2, 0x541b, - 0x85ab, 0x8a13, 0x7fa4, 0x8ecd, 0x90e1, 0x5366, 0x8888, 0x7941, - 0x4fc2, 0x50be, 0x5211, 0x5144, 0x5553, 0x572d, 0x73ea, 0x578b, - 0x5951, 0x5f62, 0x5f84, 0x6075, 0x6176, 0x6167, 0x61a9, 0x63b2, - 0x643a, 0x656c, 0x666f, 0x6842, 0x6e13, 0x7566, 0x7a3d, 0x7cfb, - 0x7d4c, 0x7d99, 0x7e4b, 0x7f6b, 0x830e, 0x834a, 0x86cd, 0x8a08, - 0x8a63, 0x8b66, 0x8efd, 0x981a, 0x9d8f, 0x82b8, 0x8fce, 0x9be8, - 0x5287, 0x621f, 0x6483, 0x6fc0, 0x9699, 0x6841, 0x5091, 0x6b20, - 0x6c7a, 0x6f54, 0x7a74, 0x7d50, 0x8840, 0x8a23, 0x6708, 0x4ef6, - 0x5039, 0x5026, 0x5065, 0x517c, 0x5238, 0x5263, 0x55a7, 0x570f, - 0x5805, 0x5acc, 0x5efa, 0x61b2, 0x61f8, 0x62f3, 0x6372, - /* 0x3821 - 0x387e */ - 0x691c, 0x6a29, 0x727d, 0x72ac, 0x732e, 0x7814, 0x786f, - 0x7d79, 0x770c, 0x80a9, 0x898b, 0x8b19, 0x8ce2, 0x8ed2, 0x9063, - 0x9375, 0x967a, 0x9855, 0x9a13, 0x9e78, 0x5143, 0x539f, 0x53b3, - 0x5e7b, 0x5f26, 0x6e1b, 0x6e90, 0x7384, 0x73fe, 0x7d43, 0x8237, - 0x8a00, 0x8afa, 0x9650, 0x4e4e, 0x500b, 0x53e4, 0x547c, 0x56fa, - 0x59d1, 0x5b64, 0x5df1, 0x5eab, 0x5f27, 0x6238, 0x6545, 0x67af, - 0x6e56, 0x72d0, 0x7cca, 0x88b4, 0x80a1, 0x80e1, 0x83f0, 0x864e, - 0x8a87, 0x8de8, 0x9237, 0x96c7, 0x9867, 0x9f13, 0x4e94, 0x4e92, - 0x4f0d, 0x5348, 0x5449, 0x543e, 0x5a2f, 0x5f8c, 0x5fa1, 0x609f, - 0x68a7, 0x6a8e, 0x745a, 0x7881, 0x8a9e, 0x8aa4, 0x8b77, 0x9190, - 0x4e5e, 0x9bc9, 0x4ea4, 0x4f7c, 0x4faf, 0x5019, 0x5016, 0x5149, - 0x516c, 0x529f, 0x52b9, 0x52fe, 0x539a, 0x53e3, 0x5411, - /* 0x3921 - 0x397e */ - 0x540e, 0x5589, 0x5751, 0x57a2, 0x597d, 0x5b54, 0x5b5d, - 0x5b8f, 0x5de5, 0x5de7, 0x5df7, 0x5e78, 0x5e83, 0x5e9a, 0x5eb7, - 0x5f18, 0x6052, 0x614c, 0x6297, 0x62d8, 0x63a7, 0x653b, 0x6602, - 0x6643, 0x66f4, 0x676d, 0x6821, 0x6897, 0x69cb, 0x6c5f, 0x6d2a, - 0x6d69, 0x6e2f, 0x6e9d, 0x7532, 0x7687, 0x786c, 0x7a3f, 0x7ce0, - 0x7d05, 0x7d18, 0x7d5e, 0x7db1, 0x8015, 0x8003, 0x80af, 0x80b1, - 0x8154, 0x818f, 0x822a, 0x8352, 0x884c, 0x8861, 0x8b1b, 0x8ca2, - 0x8cfc, 0x90ca, 0x9175, 0x9271, 0x783f, 0x92fc, 0x95a4, 0x964d, - 0x9805, 0x9999, 0x9ad8, 0x9d3b, 0x525b, 0x52ab, 0x53f7, 0x5408, - 0x58d5, 0x62f7, 0x6fe0, 0x8c6a, 0x8f5f, 0x9eb9, 0x514b, 0x523b, - 0x544a, 0x56fd, 0x7a40, 0x9177, 0x9d60, 0x9ed2, 0x7344, 0x6f09, - 0x8170, 0x7511, 0x5ffd, 0x60da, 0x9aa8, 0x72db, 0x8fbc, - /* 0x3a21 - 0x3a7e */ - 0x6b64, 0x9803, 0x4eca, 0x56f0, 0x5764, 0x58be, 0x5a5a, - 0x6068, 0x61c7, 0x660f, 0x6606, 0x6839, 0x68b1, 0x6df7, 0x75d5, - 0x7d3a, 0x826e, 0x9b42, 0x4e9b, 0x4f50, 0x53c9, 0x5506, 0x5d6f, - 0x5de6, 0x5dee, 0x67fb, 0x6c99, 0x7473, 0x7802, 0x8a50, 0x9396, - 0x88df, 0x5750, 0x5ea7, 0x632b, 0x50b5, 0x50ac, 0x518d, 0x6700, - 0x54c9, 0x585e, 0x59bb, 0x5bb0, 0x5f69, 0x624d, 0x63a1, 0x683d, - 0x6b73, 0x6e08, 0x707d, 0x91c7, 0x7280, 0x7815, 0x7826, 0x796d, - 0x658e, 0x7d30, 0x83dc, 0x88c1, 0x8f09, 0x969b, 0x5264, 0x5728, - 0x6750, 0x7f6a, 0x8ca1, 0x51b4, 0x5742, 0x962a, 0x583a, 0x698a, - 0x80b4, 0x54b2, 0x5d0e, 0x57fc, 0x7895, 0x9dfa, 0x4f5c, 0x524a, - 0x548b, 0x643e, 0x6628, 0x6714, 0x67f5, 0x7a84, 0x7b56, 0x7d22, - 0x932f, 0x685c, 0x9bad, 0x7b39, 0x5319, 0x518a, 0x5237, - /* 0x3b21 - 0x3b7e */ - 0x5bdf, 0x62f6, 0x64ae, 0x64e6, 0x672d, 0x6bba, 0x85a9, - 0x96d1, 0x7690, 0x9bd6, 0x634c, 0x9306, 0x9bab, 0x76bf, 0x6652, - 0x4e09, 0x5098, 0x53c2, 0x5c71, 0x60e8, 0x6492, 0x6563, 0x685f, - 0x71e6, 0x73ca, 0x7523, 0x7b97, 0x7e82, 0x8695, 0x8b83, 0x8cdb, - 0x9178, 0x9910, 0x65ac, 0x66ab, 0x6b8b, 0x4ed5, 0x4ed4, 0x4f3a, - 0x4f7f, 0x523a, 0x53f8, 0x53f2, 0x55e3, 0x56db, 0x58eb, 0x59cb, - 0x59c9, 0x59ff, 0x5b50, 0x5c4d, 0x5e02, 0x5e2b, 0x5fd7, 0x601d, - 0x6307, 0x652f, 0x5b5c, 0x65af, 0x65bd, 0x65e8, 0x679d, 0x6b62, - 0x6b7b, 0x6c0f, 0x7345, 0x7949, 0x79c1, 0x7cf8, 0x7d19, 0x7d2b, - 0x80a2, 0x8102, 0x81f3, 0x8996, 0x8a5e, 0x8a69, 0x8a66, 0x8a8c, - 0x8aee, 0x8cc7, 0x8cdc, 0x96cc, 0x98fc, 0x6b6f, 0x4e8b, 0x4f3c, - 0x4f8d, 0x5150, 0x5b57, 0x5bfa, 0x6148, 0x6301, 0x6642, - /* 0x3c21 - 0x3c7e */ - 0x6b21, 0x6ecb, 0x6cbb, 0x723e, 0x74bd, 0x75d4, 0x78c1, - 0x793a, 0x800c, 0x8033, 0x81ea, 0x8494, 0x8f9e, 0x6c50, 0x9e7f, - 0x5f0f, 0x8b58, 0x9d2b, 0x7afa, 0x8ef8, 0x5b8d, 0x96eb, 0x4e03, - 0x53f1, 0x57f7, 0x5931, 0x5ac9, 0x5ba4, 0x6089, 0x6e7f, 0x6f06, - 0x75be, 0x8cea, 0x5b9f, 0x8500, 0x7be0, 0x5072, 0x67f4, 0x829d, - 0x5c61, 0x854a, 0x7e1e, 0x820e, 0x5199, 0x5c04, 0x6368, 0x8d66, - 0x659c, 0x716e, 0x793e, 0x7d17, 0x8005, 0x8b1d, 0x8eca, 0x906e, - 0x86c7, 0x90aa, 0x501f, 0x52fa, 0x5c3a, 0x6753, 0x707c, 0x7235, - 0x914c, 0x91c8, 0x932b, 0x82e5, 0x5bc2, 0x5f31, 0x60f9, 0x4e3b, - 0x53d6, 0x5b88, 0x624b, 0x6731, 0x6b8a, 0x72e9, 0x73e0, 0x7a2e, - 0x816b, 0x8da3, 0x9152, 0x9996, 0x5112, 0x53d7, 0x546a, 0x5bff, - 0x6388, 0x6a39, 0x7dac, 0x9700, 0x56da, 0x53ce, 0x5468, - /* 0x3d21 - 0x3d7e */ - 0x5b97, 0x5c31, 0x5dde, 0x4fee, 0x6101, 0x62fe, 0x6d32, - 0x79c0, 0x79cb, 0x7d42, 0x7e4d, 0x7fd2, 0x81ed, 0x821f, 0x8490, - 0x8846, 0x8972, 0x8b90, 0x8e74, 0x8f2f, 0x9031, 0x914b, 0x916c, - 0x96c6, 0x919c, 0x4ec0, 0x4f4f, 0x5145, 0x5341, 0x5f93, 0x620e, - 0x67d4, 0x6c41, 0x6e0b, 0x7363, 0x7e26, 0x91cd, 0x9283, 0x53d4, - 0x5919, 0x5bbf, 0x6dd1, 0x795d, 0x7e2e, 0x7c9b, 0x587e, 0x719f, - 0x51fa, 0x8853, 0x8ff0, 0x4fca, 0x5cfb, 0x6625, 0x77ac, 0x7ae3, - 0x821c, 0x99ff, 0x51c6, 0x5faa, 0x65ec, 0x696f, 0x6b89, 0x6df3, - 0x6e96, 0x6f64, 0x76fe, 0x7d14, 0x5de1, 0x9075, 0x9187, 0x9806, - 0x51e6, 0x521d, 0x6240, 0x6691, 0x66d9, 0x6e1a, 0x5eb6, 0x7dd2, - 0x7f72, 0x66f8, 0x85af, 0x85f7, 0x8af8, 0x52a9, 0x53d9, 0x5973, - 0x5e8f, 0x5f90, 0x6055, 0x92e4, 0x9664, 0x50b7, 0x511f, - /* 0x3e21 - 0x3e7e */ - 0x52dd, 0x5320, 0x5347, 0x53ec, 0x54e8, 0x5546, 0x5531, - 0x5617, 0x5968, 0x59be, 0x5a3c, 0x5bb5, 0x5c06, 0x5c0f, 0x5c11, - 0x5c1a, 0x5e84, 0x5e8a, 0x5ee0, 0x5f70, 0x627f, 0x6284, 0x62db, - 0x638c, 0x6377, 0x6607, 0x660c, 0x662d, 0x6676, 0x677e, 0x68a2, - 0x6a1f, 0x6a35, 0x6cbc, 0x6d88, 0x6e09, 0x6e58, 0x713c, 0x7126, - 0x7167, 0x75c7, 0x7701, 0x785d, 0x7901, 0x7965, 0x79f0, 0x7ae0, - 0x7b11, 0x7ca7, 0x7d39, 0x8096, 0x83d6, 0x848b, 0x8549, 0x885d, - 0x88f3, 0x8a1f, 0x8a3c, 0x8a54, 0x8a73, 0x8c61, 0x8cde, 0x91a4, - 0x9266, 0x937e, 0x9418, 0x969c, 0x9798, 0x4e0a, 0x4e08, 0x4e1e, - 0x4e57, 0x5197, 0x5270, 0x57ce, 0x5834, 0x58cc, 0x5b22, 0x5e38, - 0x60c5, 0x64fe, 0x6761, 0x6756, 0x6d44, 0x72b6, 0x7573, 0x7a63, - 0x84b8, 0x8b72, 0x91b8, 0x9320, 0x5631, 0x57f4, 0x98fe, - /* 0x3f21 - 0x3f7e */ - 0x62ed, 0x690d, 0x6b96, 0x71ed, 0x7e54, 0x8077, 0x8272, - 0x89e6, 0x98df, 0x8755, 0x8fb1, 0x5c3b, 0x4f38, 0x4fe1, 0x4fb5, - 0x5507, 0x5a20, 0x5bdd, 0x5be9, 0x5fc3, 0x614e, 0x632f, 0x65b0, - 0x664b, 0x68ee, 0x699b, 0x6d78, 0x6df1, 0x7533, 0x75b9, 0x771f, - 0x795e, 0x79e6, 0x7d33, 0x81e3, 0x82af, 0x85aa, 0x89aa, 0x8a3a, - 0x8eab, 0x8f9b, 0x9032, 0x91dd, 0x9707, 0x4eba, 0x4ec1, 0x5203, - 0x5875, 0x58ec, 0x5c0b, 0x751a, 0x5c3d, 0x814e, 0x8a0a, 0x8fc5, - 0x9663, 0x976d, 0x7b25, 0x8acf, 0x9808, 0x9162, 0x56f3, 0x53a8, - 0x9017, 0x5439, 0x5782, 0x5e25, 0x63a8, 0x6c34, 0x708a, 0x7761, - 0x7c8b, 0x7fe0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968f, - 0x745e, 0x9ac4, 0x5d07, 0x5d69, 0x6570, 0x67a2, 0x8da8, 0x96db, - 0x636e, 0x6749, 0x6919, 0x83c5, 0x9817, 0x96c0, 0x88fe, - /* 0x4021 - 0x407e */ - 0x6f84, 0x647a, 0x5bf8, 0x4e16, 0x702c, 0x755d, 0x662f, - 0x51c4, 0x5236, 0x52e2, 0x59d3, 0x5f81, 0x6027, 0x6210, 0x653f, - 0x6574, 0x661f, 0x6674, 0x68f2, 0x6816, 0x6b63, 0x6e05, 0x7272, - 0x751f, 0x76db, 0x7cbe, 0x8056, 0x58f0, 0x88fd, 0x897f, 0x8aa0, - 0x8a93, 0x8acb, 0x901d, 0x9192, 0x9752, 0x9759, 0x6589, 0x7a0e, - 0x8106, 0x96bb, 0x5e2d, 0x60dc, 0x621a, 0x65a5, 0x6614, 0x6790, - 0x77f3, 0x7a4d, 0x7c4d, 0x7e3e, 0x810a, 0x8cac, 0x8d64, 0x8de1, - 0x8e5f, 0x78a9, 0x5207, 0x62d9, 0x63a5, 0x6442, 0x6298, 0x8a2d, - 0x7a83, 0x7bc0, 0x8aac, 0x96ea, 0x7d76, 0x820c, 0x8749, 0x4ed9, - 0x5148, 0x5343, 0x5360, 0x5ba3, 0x5c02, 0x5c16, 0x5ddd, 0x6226, - 0x6247, 0x64b0, 0x6813, 0x6834, 0x6cc9, 0x6d45, 0x6d17, 0x67d3, - 0x6f5c, 0x714e, 0x717d, 0x65cb, 0x7a7f, 0x7bad, 0x7dda, - /* 0x4121 - 0x417e */ - 0x7e4a, 0x7fa8, 0x817a, 0x821b, 0x8239, 0x85a6, 0x8a6e, - 0x8cce, 0x8df5, 0x9078, 0x9077, 0x92ad, 0x9291, 0x9583, 0x9bae, - 0x524d, 0x5584, 0x6f38, 0x7136, 0x5168, 0x7985, 0x7e55, 0x81b3, - 0x7cce, 0x564c, 0x5851, 0x5ca8, 0x63aa, 0x66fe, 0x66fd, 0x695a, - 0x72d9, 0x758f, 0x758e, 0x790e, 0x7956, 0x79df, 0x7c97, 0x7d20, - 0x7d44, 0x8607, 0x8a34, 0x963b, 0x9061, 0x9f20, 0x50e7, 0x5275, - 0x53cc, 0x53e2, 0x5009, 0x55aa, 0x58ee, 0x594f, 0x723d, 0x5b8b, - 0x5c64, 0x531d, 0x60e3, 0x60f3, 0x635c, 0x6383, 0x633f, 0x63bb, - 0x64cd, 0x65e9, 0x66f9, 0x5de3, 0x69cd, 0x69fd, 0x6f15, 0x71e5, - 0x4e89, 0x75e9, 0x76f8, 0x7a93, 0x7cdf, 0x7dcf, 0x7d9c, 0x8061, - 0x8349, 0x8358, 0x846c, 0x84bc, 0x85fb, 0x88c5, 0x8d70, 0x9001, - 0x906d, 0x9397, 0x971c, 0x9a12, 0x50cf, 0x5897, 0x618e, - /* 0x4221 - 0x427e */ - 0x81d3, 0x8535, 0x8d08, 0x9020, 0x4fc3, 0x5074, 0x5247, - 0x5373, 0x606f, 0x6349, 0x675f, 0x6e2c, 0x8db3, 0x901f, 0x4fd7, - 0x5c5e, 0x8cca, 0x65cf, 0x7d9a, 0x5352, 0x8896, 0x5176, 0x63c3, - 0x5b58, 0x5b6b, 0x5c0a, 0x640d, 0x6751, 0x905c, 0x4ed6, 0x591a, - 0x592a, 0x6c70, 0x8a51, 0x553e, 0x5815, 0x59a5, 0x60f0, 0x6253, - 0x67c1, 0x8235, 0x6955, 0x9640, 0x99c4, 0x9a28, 0x4f53, 0x5806, - 0x5bfe, 0x8010, 0x5cb1, 0x5e2f, 0x5f85, 0x6020, 0x614b, 0x6234, - 0x66ff, 0x6cf0, 0x6ede, 0x80ce, 0x817f, 0x82d4, 0x888b, 0x8cb8, - 0x9000, 0x902e, 0x968a, 0x9edb, 0x9bdb, 0x4ee3, 0x53f0, 0x5927, - 0x7b2c, 0x918d, 0x984c, 0x9df9, 0x6edd, 0x7027, 0x5353, 0x5544, - 0x5b85, 0x6258, 0x629e, 0x62d3, 0x6ca2, 0x6fef, 0x7422, 0x8a17, - 0x9438, 0x6fc1, 0x8afe, 0x8338, 0x51e7, 0x86f8, 0x53ea, - /* 0x4321 - 0x437e */ - 0x53e9, 0x4f46, 0x9054, 0x8fb0, 0x596a, 0x8131, 0x5dfd, - 0x7aea, 0x8fbf, 0x68da, 0x8c37, 0x72f8, 0x9c48, 0x6a3d, 0x8ab0, - 0x4e39, 0x5358, 0x5606, 0x5766, 0x62c5, 0x63a2, 0x65e6, 0x6b4e, - 0x6de1, 0x6e5b, 0x70ad, 0x77ed, 0x7aef, 0x7baa, 0x7dbb, 0x803d, - 0x80c6, 0x86cb, 0x8a95, 0x935b, 0x56e3, 0x58c7, 0x5f3e, 0x65ad, - 0x6696, 0x6a80, 0x6bb5, 0x7537, 0x8ac7, 0x5024, 0x77e5, 0x5730, - 0x5f1b, 0x6065, 0x667a, 0x6c60, 0x75f4, 0x7a1a, 0x7f6e, 0x81f4, - 0x8718, 0x9045, 0x99b3, 0x7bc9, 0x755c, 0x7af9, 0x7b51, 0x84c4, - 0x9010, 0x79e9, 0x7a92, 0x8336, 0x5ae1, 0x7740, 0x4e2d, 0x4ef2, - 0x5b99, 0x5fe0, 0x62bd, 0x663c, 0x67f1, 0x6ce8, 0x866b, 0x8877, - 0x8a3b, 0x914e, 0x92f3, 0x99d0, 0x6a17, 0x7026, 0x732a, 0x82e7, - 0x8457, 0x8caf, 0x4e01, 0x5146, 0x51cb, 0x558b, 0x5bf5, - /* 0x4421 - 0x447e */ - 0x5e16, 0x5e33, 0x5e81, 0x5f14, 0x5f35, 0x5f6b, 0x5fb4, - 0x61f2, 0x6311, 0x66a2, 0x671d, 0x6f6e, 0x7252, 0x753a, 0x773a, - 0x8074, 0x8139, 0x8178, 0x8776, 0x8abf, 0x8adc, 0x8d85, 0x8df3, - 0x929a, 0x9577, 0x9802, 0x9ce5, 0x52c5, 0x6357, 0x76f4, 0x6715, - 0x6c88, 0x73cd, 0x8cc3, 0x93ae, 0x9673, 0x6d25, 0x589c, 0x690e, - 0x69cc, 0x8ffd, 0x939a, 0x75db, 0x901a, 0x585a, 0x6802, 0x63b4, - 0x69fb, 0x4f43, 0x6f2c, 0x67d8, 0x8fbb, 0x8526, 0x7db4, 0x9354, - 0x693f, 0x6f70, 0x576a, 0x58f7, 0x5b2c, 0x7d2c, 0x722a, 0x540a, - 0x91e3, 0x9db4, 0x4ead, 0x4f4e, 0x505c, 0x5075, 0x5243, 0x8c9e, - 0x5448, 0x5824, 0x5b9a, 0x5e1d, 0x5e95, 0x5ead, 0x5ef7, 0x5f1f, - 0x608c, 0x62b5, 0x633a, 0x63d0, 0x68af, 0x6c40, 0x7887, 0x798e, - 0x7a0b, 0x7de0, 0x8247, 0x8a02, 0x8ae6, 0x8e44, 0x9013, - /* 0x4521 - 0x457e */ - 0x90b8, 0x912d, 0x91d8, 0x9f0e, 0x6ce5, 0x6458, 0x64e2, - 0x6575, 0x6ef4, 0x7684, 0x7b1b, 0x9069, 0x93d1, 0x6eba, 0x54f2, - 0x5fb9, 0x64a4, 0x8f4d, 0x8fed, 0x9244, 0x5178, 0x586b, 0x5929, - 0x5c55, 0x5e97, 0x6dfb, 0x7e8f, 0x751c, 0x8cbc, 0x8ee2, 0x985b, - 0x70b9, 0x4f1d, 0x6bbf, 0x6fb1, 0x7530, 0x96fb, 0x514e, 0x5410, - 0x5835, 0x5857, 0x59ac, 0x5c60, 0x5f92, 0x6597, 0x675c, 0x6e21, - 0x767b, 0x83df, 0x8ced, 0x9014, 0x90fd, 0x934d, 0x7825, 0x783a, - 0x52aa, 0x5ea6, 0x571f, 0x5974, 0x6012, 0x5012, 0x515a, 0x51ac, - 0x51cd, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5b95, 0x5cf6, - 0x5d8b, 0x60bc, 0x6295, 0x642d, 0x6771, 0x6843, 0x68bc, 0x68df, - 0x76d7, 0x6dd8, 0x6e6f, 0x6d9b, 0x706f, 0x71c8, 0x5f53, 0x75d8, - 0x7977, 0x7b49, 0x7b54, 0x7b52, 0x7cd6, 0x7d71, 0x5230, - /* 0x4621 - 0x467e */ - 0x8463, 0x8569, 0x85e4, 0x8a0e, 0x8b04, 0x8c46, 0x8e0f, - 0x9003, 0x900f, 0x9419, 0x9676, 0x982d, 0x9a30, 0x95d8, 0x50cd, - 0x52d5, 0x540c, 0x5802, 0x5c0e, 0x61a7, 0x649e, 0x6d1e, 0x77b3, - 0x7ae5, 0x80f4, 0x8404, 0x9053, 0x9285, 0x5ce0, 0x9d07, 0x533f, - 0x5f97, 0x5fb3, 0x6d9c, 0x7279, 0x7763, 0x79bf, 0x7be4, 0x6bd2, - 0x72ec, 0x8aad, 0x6803, 0x6a61, 0x51f8, 0x7a81, 0x6934, 0x5c4a, - 0x9cf6, 0x82eb, 0x5bc5, 0x9149, 0x701e, 0x5678, 0x5c6f, 0x60c7, - 0x6566, 0x6c8c, 0x8c5a, 0x9041, 0x9813, 0x5451, 0x66c7, 0x920d, - 0x5948, 0x90a3, 0x5185, 0x4e4d, 0x51ea, 0x8599, 0x8b0e, 0x7058, - 0x637a, 0x934b, 0x6962, 0x99b4, 0x7e04, 0x7577, 0x5357, 0x6960, - 0x8edf, 0x96e3, 0x6c5d, 0x4e8c, 0x5c3c, 0x5f10, 0x8fe9, 0x5302, - 0x8cd1, 0x8089, 0x8679, 0x5eff, 0x65e5, 0x4e73, 0x5165, - /* 0x4721 - 0x477e */ - 0x5982, 0x5c3f, 0x97ee, 0x4efb, 0x598a, 0x5fcd, 0x8a8d, - 0x6fe1, 0x79b0, 0x7962, 0x5be7, 0x8471, 0x732b, 0x71b1, 0x5e74, - 0x5ff5, 0x637b, 0x649a, 0x71c3, 0x7c98, 0x4e43, 0x5efc, 0x4e4b, - 0x57dc, 0x56a2, 0x60a9, 0x6fc3, 0x7d0d, 0x80fd, 0x8133, 0x81bf, - 0x8fb2, 0x8997, 0x86a4, 0x5df4, 0x628a, 0x64ad, 0x8987, 0x6777, - 0x6ce2, 0x6d3e, 0x7436, 0x7834, 0x5a46, 0x7f75, 0x82ad, 0x99ac, - 0x4ff3, 0x5ec3, 0x62dd, 0x6392, 0x6557, 0x676f, 0x76c3, 0x724c, - 0x80cc, 0x80ba, 0x8f29, 0x914d, 0x500d, 0x57f9, 0x5a92, 0x6885, - 0x6973, 0x7164, 0x72fd, 0x8cb7, 0x58f2, 0x8ce0, 0x966a, 0x9019, - 0x877f, 0x79e4, 0x77e7, 0x8429, 0x4f2f, 0x5265, 0x535a, 0x62cd, - 0x67cf, 0x6cca, 0x767d, 0x7b94, 0x7c95, 0x8236, 0x8584, 0x8feb, - 0x66dd, 0x6f20, 0x7206, 0x7e1b, 0x83ab, 0x99c1, 0x9ea6, - /* 0x4821 - 0x487e */ - 0x51fd, 0x7bb1, 0x7872, 0x7bb8, 0x8087, 0x7b48, 0x6ae8, - 0x5e61, 0x808c, 0x7551, 0x7560, 0x516b, 0x9262, 0x6e8c, 0x767a, - 0x9197, 0x9aea, 0x4f10, 0x7f70, 0x629c, 0x7b4f, 0x95a5, 0x9ce9, - 0x567a, 0x5859, 0x86e4, 0x96bc, 0x4f34, 0x5224, 0x534a, 0x53cd, - 0x53db, 0x5e06, 0x642c, 0x6591, 0x677f, 0x6c3e, 0x6c4e, 0x7248, - 0x72af, 0x73ed, 0x7554, 0x7e41, 0x822c, 0x85e9, 0x8ca9, 0x7bc4, - 0x91c6, 0x7169, 0x9812, 0x98ef, 0x633d, 0x6669, 0x756a, 0x76e4, - 0x78d0, 0x8543, 0x86ee, 0x532a, 0x5351, 0x5426, 0x5983, 0x5e87, - 0x5f7c, 0x60b2, 0x6249, 0x6279, 0x62ab, 0x6590, 0x6bd4, 0x6ccc, - 0x75b2, 0x76ae, 0x7891, 0x79d8, 0x7dcb, 0x7f77, 0x80a5, 0x88ab, - 0x8ab9, 0x8cbb, 0x907f, 0x975e, 0x98db, 0x6a0b, 0x7c38, 0x5099, - 0x5c3e, 0x5fae, 0x6787, 0x6bd8, 0x7435, 0x7709, 0x7f8e, - /* 0x4921 - 0x497e */ - 0x9f3b, 0x67ca, 0x7a17, 0x5339, 0x758b, 0x9aed, 0x5f66, - 0x819d, 0x83f1, 0x8098, 0x5f3c, 0x5fc5, 0x7562, 0x7b46, 0x903c, - 0x6867, 0x59eb, 0x5a9b, 0x7d10, 0x767e, 0x8b2c, 0x4ff5, 0x5f6a, - 0x6a19, 0x6c37, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8a55, 0x8c79, - 0x5edf, 0x63cf, 0x75c5, 0x79d2, 0x82d7, 0x9328, 0x92f2, 0x849c, - 0x86ed, 0x9c2d, 0x54c1, 0x5f6c, 0x658c, 0x6d5c, 0x7015, 0x8ca7, - 0x8cd3, 0x983b, 0x654f, 0x74f6, 0x4e0d, 0x4ed8, 0x57e0, 0x592b, - 0x5a66, 0x5bcc, 0x51a8, 0x5e03, 0x5e9c, 0x6016, 0x6276, 0x6577, - 0x65a7, 0x666e, 0x6d6e, 0x7236, 0x7b26, 0x8150, 0x819a, 0x8299, - 0x8b5c, 0x8ca0, 0x8ce6, 0x8d74, 0x961c, 0x9644, 0x4fae, 0x64ab, - 0x6b66, 0x821e, 0x8461, 0x856a, 0x90e8, 0x5c01, 0x6953, 0x98a8, - 0x847a, 0x8557, 0x4f0f, 0x526f, 0x5fa9, 0x5e45, 0x670d, - /* 0x4a21 - 0x4a7e */ - 0x798f, 0x8179, 0x8907, 0x8986, 0x6df5, 0x5f17, 0x6255, - 0x6cb8, 0x4ecf, 0x7269, 0x9b92, 0x5206, 0x543b, 0x5674, 0x58b3, - 0x61a4, 0x626e, 0x711a, 0x596e, 0x7c89, 0x7cde, 0x7d1b, 0x96f0, - 0x6587, 0x805e, 0x4e19, 0x4f75, 0x5175, 0x5840, 0x5e63, 0x5e73, - 0x5f0a, 0x67c4, 0x4e26, 0x853d, 0x9589, 0x965b, 0x7c73, 0x9801, - 0x50fb, 0x58c1, 0x7656, 0x78a7, 0x5225, 0x77a5, 0x8511, 0x7b86, - 0x504f, 0x5909, 0x7247, 0x7bc7, 0x7de8, 0x8fba, 0x8fd4, 0x904d, - 0x4fbf, 0x52c9, 0x5a29, 0x5f01, 0x97ad, 0x4fdd, 0x8217, 0x92ea, - 0x5703, 0x6355, 0x6b69, 0x752b, 0x88dc, 0x8f14, 0x7a42, 0x52df, - 0x5893, 0x6155, 0x620a, 0x66ae, 0x6bcd, 0x7c3f, 0x83e9, 0x5023, - 0x4ff8, 0x5305, 0x5446, 0x5831, 0x5949, 0x5b9d, 0x5cf0, 0x5cef, - 0x5d29, 0x5e96, 0x62b1, 0x6367, 0x653e, 0x65b9, 0x670b, - /* 0x4b21 - 0x4b7e */ - 0x6cd5, 0x6ce1, 0x70f9, 0x7832, 0x7e2b, 0x80de, 0x82b3, - 0x840c, 0x84ec, 0x8702, 0x8912, 0x8a2a, 0x8c4a, 0x90a6, 0x92d2, - 0x98fd, 0x9cf3, 0x9d6c, 0x4e4f, 0x4ea1, 0x508d, 0x5256, 0x574a, - 0x59a8, 0x5e3d, 0x5fd8, 0x5fd9, 0x623f, 0x66b4, 0x671b, 0x67d0, - 0x68d2, 0x5192, 0x7d21, 0x80aa, 0x81a8, 0x8b00, 0x8c8c, 0x8cbf, - 0x927e, 0x9632, 0x5420, 0x982c, 0x5317, 0x50d5, 0x535c, 0x58a8, - 0x64b2, 0x6734, 0x7267, 0x7766, 0x7a46, 0x91e6, 0x52c3, 0x6ca1, - 0x6b86, 0x5800, 0x5e4c, 0x5954, 0x672c, 0x7ffb, 0x51e1, 0x76c6, - 0x6469, 0x78e8, 0x9b54, 0x9ebb, 0x57cb, 0x59b9, 0x6627, 0x679a, - 0x6bce, 0x54e9, 0x69d9, 0x5e55, 0x819c, 0x6795, 0x9baa, 0x67fe, - 0x9c52, 0x685d, 0x4ea6, 0x4fe3, 0x53c8, 0x62b9, 0x672b, 0x6cab, - 0x8fc4, 0x4fad, 0x7e6d, 0x9ebf, 0x4e07, 0x6162, 0x6e80, - /* 0x4c21 - 0x4c7e */ - 0x6f2b, 0x8513, 0x5473, 0x672a, 0x9b45, 0x5df3, 0x7b95, - 0x5cac, 0x5bc6, 0x871c, 0x6e4a, 0x84d1, 0x7a14, 0x8108, 0x5999, - 0x7c8d, 0x6c11, 0x7720, 0x52d9, 0x5922, 0x7121, 0x725f, 0x77db, - 0x9727, 0x9d61, 0x690b, 0x5a7f, 0x5a18, 0x51a5, 0x540d, 0x547d, - 0x660e, 0x76df, 0x8ff7, 0x9298, 0x9cf4, 0x59ea, 0x725d, 0x6ec5, - 0x514d, 0x68c9, 0x7dbf, 0x7dec, 0x9762, 0x9eba, 0x6478, 0x6a21, - 0x8302, 0x5984, 0x5b5f, 0x6bdb, 0x731b, 0x76f2, 0x7db2, 0x8017, - 0x8499, 0x5132, 0x6728, 0x9ed9, 0x76ee, 0x6762, 0x52ff, 0x9905, - 0x5c24, 0x623b, 0x7c7e, 0x8cb0, 0x554f, 0x60b6, 0x7d0b, 0x9580, - 0x5301, 0x4e5f, 0x51b6, 0x591c, 0x723a, 0x8036, 0x91ce, 0x5f25, - 0x77e2, 0x5384, 0x5f79, 0x7d04, 0x85ac, 0x8a33, 0x8e8d, 0x9756, - 0x67f3, 0x85ae, 0x9453, 0x6109, 0x6108, 0x6cb9, 0x7652, - /* 0x4d21 - 0x4d7e */ - 0x8aed, 0x8f38, 0x552f, 0x4f51, 0x512a, 0x52c7, 0x53cb, - 0x5ba5, 0x5e7d, 0x60a0, 0x6182, 0x63d6, 0x6709, 0x67da, 0x6e67, - 0x6d8c, 0x7336, 0x7337, 0x7531, 0x7950, 0x88d5, 0x8a98, 0x904a, - 0x9091, 0x90f5, 0x96c4, 0x878d, 0x5915, 0x4e88, 0x4f59, 0x4e0e, - 0x8a89, 0x8f3f, 0x9810, 0x50ad, 0x5e7c, 0x5996, 0x5bb9, 0x5eb8, - 0x63da, 0x63fa, 0x64c1, 0x66dc, 0x694a, 0x69d8, 0x6d0b, 0x6eb6, - 0x7194, 0x7528, 0x7aaf, 0x7f8a, 0x8000, 0x8449, 0x84c9, 0x8981, - 0x8b21, 0x8e0a, 0x9065, 0x967d, 0x990a, 0x617e, 0x6291, 0x6b32, - 0x6c83, 0x6d74, 0x7fcc, 0x7ffc, 0x6dc0, 0x7f85, 0x87ba, 0x88f8, - 0x6765, 0x83b1, 0x983c, 0x96f7, 0x6d1b, 0x7d61, 0x843d, 0x916a, - 0x4e71, 0x5375, 0x5d50, 0x6b04, 0x6feb, 0x85cd, 0x862d, 0x89a7, - 0x5229, 0x540f, 0x5c65, 0x674e, 0x68a8, 0x7406, 0x7483, - /* 0x4e21 - 0x4e7e */ - 0x75e2, 0x88cf, 0x88e1, 0x91cc, 0x96e2, 0x9678, 0x5f8b, - 0x7387, 0x7acb, 0x844e, 0x63a0, 0x7565, 0x5289, 0x6d41, 0x6e9c, - 0x7409, 0x7559, 0x786b, 0x7c92, 0x9686, 0x7adc, 0x9f8d, 0x4fb6, - 0x616e, 0x65c5, 0x865c, 0x4e86, 0x4eae, 0x50da, 0x4e21, 0x51cc, - 0x5bee, 0x6599, 0x6881, 0x6dbc, 0x731f, 0x7642, 0x77ad, 0x7a1c, - 0x7ce7, 0x826f, 0x8ad2, 0x907c, 0x91cf, 0x9675, 0x9818, 0x529b, - 0x7dd1, 0x502b, 0x5398, 0x6797, 0x6dcb, 0x71d0, 0x7433, 0x81e8, - 0x8f2a, 0x96a3, 0x9c57, 0x9e9f, 0x7460, 0x5841, 0x6d99, 0x7d2f, - 0x985e, 0x4ee4, 0x4f36, 0x4f8b, 0x51b7, 0x52b1, 0x5dba, 0x601c, - 0x73b2, 0x793c, 0x82d3, 0x9234, 0x96b7, 0x96f6, 0x970a, 0x9e97, - 0x9f62, 0x66a6, 0x6b74, 0x5217, 0x52a3, 0x70c8, 0x88c2, 0x5ec9, - 0x604b, 0x6190, 0x6f23, 0x7149, 0x7c3e, 0x7df4, 0x806f, - /* 0x4f21 - 0x4f7e */ - 0x84ee, 0x9023, 0x932c, 0x5442, 0x9b6f, 0x6ad3, 0x7089, - 0x8cc2, 0x8def, 0x9732, 0x52b4, 0x5a41, 0x5eca, 0x5f04, 0x6717, - 0x697c, 0x6994, 0x6d6a, 0x6f0f, 0x7262, 0x72fc, 0x7bed, 0x8001, - 0x807e, 0x874b, 0x90ce, 0x516d, 0x9e93, 0x7984, 0x808b, 0x9332, - 0x8ad6, 0x502d, 0x548c, 0x8a71, 0x6b6a, 0x8cc4, 0x8107, 0x60d1, - 0x67a0, 0x9df2, 0x4e99, 0x4e98, 0x9c10, 0x8a6b, 0x85c1, 0x8568, - 0x6900, 0x6e7e, 0x7897, 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x5021 - 0x507e */ - 0x5f0c, 0x4e10, 0x4e15, 0x4e2a, 0x4e31, 0x4e36, 0x4e3c, - 0x4e3f, 0x4e42, 0x4e56, 0x4e58, 0x4e82, 0x4e85, 0x8c6b, 0x4e8a, - 0x8212, 0x5f0d, 0x4e8e, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea2, 0x4eb0, - 0x4eb3, 0x4eb6, 0x4ece, 0x4ecd, 0x4ec4, 0x4ec6, 0x4ec2, 0x4ed7, - 0x4ede, 0x4eed, 0x4edf, 0x4ef7, 0x4f09, 0x4f5a, 0x4f30, 0x4f5b, - 0x4f5d, 0x4f57, 0x4f47, 0x4f76, 0x4f88, 0x4f8f, 0x4f98, 0x4f7b, - 0x4f69, 0x4f70, 0x4f91, 0x4f6f, 0x4f86, 0x4f96, 0x5118, 0x4fd4, - 0x4fdf, 0x4fce, 0x4fd8, 0x4fdb, 0x4fd1, 0x4fda, 0x4fd0, 0x4fe4, - 0x4fe5, 0x501a, 0x5028, 0x5014, 0x502a, 0x5025, 0x5005, 0x4f1c, - 0x4ff6, 0x5021, 0x5029, 0x502c, 0x4ffe, 0x4fef, 0x5011, 0x5006, - 0x5043, 0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505a, 0x5056, - 0x506c, 0x5078, 0x5080, 0x509a, 0x5085, 0x50b4, 0x50b2, - /* 0x5121 - 0x517e */ - 0x50c9, 0x50ca, 0x50b3, 0x50c2, 0x50d6, 0x50de, 0x50e5, - 0x50ed, 0x50e3, 0x50ee, 0x50f9, 0x50f5, 0x5109, 0x5101, 0x5102, - 0x5116, 0x5115, 0x5114, 0x511a, 0x5121, 0x513a, 0x5137, 0x513c, - 0x513b, 0x513f, 0x5140, 0x5152, 0x514c, 0x5154, 0x5162, 0x7af8, - 0x5169, 0x516a, 0x516e, 0x5180, 0x5182, 0x56d8, 0x518c, 0x5189, - 0x518f, 0x5191, 0x5193, 0x5195, 0x5196, 0x51a4, 0x51a6, 0x51a2, - 0x51a9, 0x51aa, 0x51ab, 0x51b3, 0x51b1, 0x51b2, 0x51b0, 0x51b5, - 0x51bd, 0x51c5, 0x51c9, 0x51db, 0x51e0, 0x8655, 0x51e9, 0x51ed, - 0x51f0, 0x51f5, 0x51fe, 0x5204, 0x520b, 0x5214, 0x520e, 0x5227, - 0x522a, 0x522e, 0x5233, 0x5239, 0x524f, 0x5244, 0x524b, 0x524c, - 0x525e, 0x5254, 0x526a, 0x5274, 0x5269, 0x5273, 0x527f, 0x527d, - 0x528d, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8fa8, - /* 0x5221 - 0x527e */ - 0x8fa7, 0x52ac, 0x52ad, 0x52bc, 0x52b5, 0x52c1, 0x52cd, - 0x52d7, 0x52de, 0x52e3, 0x52e6, 0x98ed, 0x52e0, 0x52f3, 0x52f5, - 0x52f8, 0x52f9, 0x5306, 0x5308, 0x7538, 0x530d, 0x5310, 0x530f, - 0x5315, 0x531a, 0x5323, 0x532f, 0x5331, 0x5333, 0x5338, 0x5340, - 0x5346, 0x5345, 0x4e17, 0x5349, 0x534d, 0x51d6, 0x535e, 0x5369, - 0x536e, 0x5918, 0x537b, 0x5377, 0x5382, 0x5396, 0x53a0, 0x53a6, - 0x53a5, 0x53ae, 0x53b0, 0x53b6, 0x53c3, 0x7c12, 0x96d9, 0x53df, - 0x66fc, 0x71ee, 0x53ee, 0x53e8, 0x53ed, 0x53fa, 0x5401, 0x543d, - 0x5440, 0x542c, 0x542d, 0x543c, 0x542e, 0x5436, 0x5429, 0x541d, - 0x544e, 0x548f, 0x5475, 0x548e, 0x545f, 0x5471, 0x5477, 0x5470, - 0x5492, 0x547b, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54c7, - 0x54a2, 0x54b8, 0x54a5, 0x54ac, 0x54c4, 0x54c8, 0x54a8, - /* 0x5321 - 0x537e */ - 0x54ab, 0x54c2, 0x54a4, 0x54be, 0x54bc, 0x54d8, 0x54e5, - 0x54e6, 0x550f, 0x5514, 0x54fd, 0x54ee, 0x54ed, 0x54fa, 0x54e2, - 0x5539, 0x5540, 0x5563, 0x554c, 0x552e, 0x555c, 0x5545, 0x5556, - 0x5557, 0x5538, 0x5533, 0x555d, 0x5599, 0x5580, 0x54af, 0x558a, - 0x559f, 0x557b, 0x557e, 0x5598, 0x559e, 0x55ae, 0x557c, 0x5583, - 0x55a9, 0x5587, 0x55a8, 0x55da, 0x55c5, 0x55df, 0x55c4, 0x55dc, - 0x55e4, 0x55d4, 0x5614, 0x55f7, 0x5616, 0x55fe, 0x55fd, 0x561b, - 0x55f9, 0x564e, 0x5650, 0x71df, 0x5634, 0x5636, 0x5632, 0x5638, - 0x566b, 0x5664, 0x562f, 0x566c, 0x566a, 0x5686, 0x5680, 0x568a, - 0x56a0, 0x5694, 0x568f, 0x56a5, 0x56ae, 0x56b6, 0x56b4, 0x56c2, - 0x56bc, 0x56c1, 0x56c3, 0x56c0, 0x56c8, 0x56ce, 0x56d1, 0x56d3, - 0x56d7, 0x56ee, 0x56f9, 0x5700, 0x56ff, 0x5704, 0x5709, - /* 0x5421 - 0x547e */ - 0x5708, 0x570b, 0x570d, 0x5713, 0x5718, 0x5716, 0x55c7, - 0x571c, 0x5726, 0x5737, 0x5738, 0x574e, 0x573b, 0x5740, 0x574f, - 0x5769, 0x57c0, 0x5788, 0x5761, 0x577f, 0x5789, 0x5793, 0x57a0, - 0x57b3, 0x57a4, 0x57aa, 0x57b0, 0x57c3, 0x57c6, 0x57d4, 0x57d2, - 0x57d3, 0x580a, 0x57d6, 0x57e3, 0x580b, 0x5819, 0x581d, 0x5872, - 0x5821, 0x5862, 0x584b, 0x5870, 0x6bc0, 0x5852, 0x583d, 0x5879, - 0x5885, 0x58b9, 0x589f, 0x58ab, 0x58ba, 0x58de, 0x58bb, 0x58b8, - 0x58ae, 0x58c5, 0x58d3, 0x58d1, 0x58d7, 0x58d9, 0x58d8, 0x58e5, - 0x58dc, 0x58e4, 0x58df, 0x58ef, 0x58fa, 0x58f9, 0x58fb, 0x58fc, - 0x58fd, 0x5902, 0x590a, 0x5910, 0x591b, 0x68a6, 0x5925, 0x592c, - 0x592d, 0x5932, 0x5938, 0x593e, 0x7ad2, 0x5955, 0x5950, 0x594e, - 0x595a, 0x5958, 0x5962, 0x5960, 0x5967, 0x596c, 0x5969, - /* 0x5521 - 0x557e */ - 0x5978, 0x5981, 0x599d, 0x4f5e, 0x4fab, 0x59a3, 0x59b2, - 0x59c6, 0x59e8, 0x59dc, 0x598d, 0x59d9, 0x59da, 0x5a25, 0x5a1f, - 0x5a11, 0x5a1c, 0x5a09, 0x5a1a, 0x5a40, 0x5a6c, 0x5a49, 0x5a35, - 0x5a36, 0x5a62, 0x5a6a, 0x5a9a, 0x5abc, 0x5abe, 0x5acb, 0x5ac2, - 0x5abd, 0x5ae3, 0x5ad7, 0x5ae6, 0x5ae9, 0x5ad6, 0x5afa, 0x5afb, - 0x5b0c, 0x5b0b, 0x5b16, 0x5b32, 0x5ad0, 0x5b2a, 0x5b36, 0x5b3e, - 0x5b43, 0x5b45, 0x5b40, 0x5b51, 0x5b55, 0x5b5a, 0x5b5b, 0x5b65, - 0x5b69, 0x5b70, 0x5b73, 0x5b75, 0x5b78, 0x6588, 0x5b7a, 0x5b80, - 0x5b83, 0x5ba6, 0x5bb8, 0x5bc3, 0x5bc7, 0x5bc9, 0x5bd4, 0x5bd0, - 0x5be4, 0x5be6, 0x5be2, 0x5bde, 0x5be5, 0x5beb, 0x5bf0, 0x5bf6, - 0x5bf3, 0x5c05, 0x5c07, 0x5c08, 0x5c0d, 0x5c13, 0x5c20, 0x5c22, - 0x5c28, 0x5c38, 0x5c39, 0x5c41, 0x5c46, 0x5c4e, 0x5c53, - /* 0x5621 - 0x567e */ - 0x5c50, 0x5c4f, 0x5b71, 0x5c6c, 0x5c6e, 0x4e62, 0x5c76, - 0x5c79, 0x5c8c, 0x5c91, 0x5c94, 0x599b, 0x5cab, 0x5cbb, 0x5cb6, - 0x5cbc, 0x5cb7, 0x5cc5, 0x5cbe, 0x5cc7, 0x5cd9, 0x5ce9, 0x5cfd, - 0x5cfa, 0x5ced, 0x5d8c, 0x5cea, 0x5d0b, 0x5d15, 0x5d17, 0x5d5c, - 0x5d1f, 0x5d1b, 0x5d11, 0x5d14, 0x5d22, 0x5d1a, 0x5d19, 0x5d18, - 0x5d4c, 0x5d52, 0x5d4e, 0x5d4b, 0x5d6c, 0x5d73, 0x5d76, 0x5d87, - 0x5d84, 0x5d82, 0x5da2, 0x5d9d, 0x5dac, 0x5dae, 0x5dbd, 0x5d90, - 0x5db7, 0x5dbc, 0x5dc9, 0x5dcd, 0x5dd3, 0x5dd2, 0x5dd6, 0x5ddb, - 0x5deb, 0x5df2, 0x5df5, 0x5e0b, 0x5e1a, 0x5e19, 0x5e11, 0x5e1b, - 0x5e36, 0x5e37, 0x5e44, 0x5e43, 0x5e40, 0x5e4e, 0x5e57, 0x5e54, - 0x5e5f, 0x5e62, 0x5e64, 0x5e47, 0x5e75, 0x5e76, 0x5e7a, 0x9ebc, - 0x5e7f, 0x5ea0, 0x5ec1, 0x5ec2, 0x5ec8, 0x5ed0, 0x5ecf, - /* 0x5721 - 0x577e */ - 0x5ed6, 0x5ee3, 0x5edd, 0x5eda, 0x5edb, 0x5ee2, 0x5ee1, - 0x5ee8, 0x5ee9, 0x5eec, 0x5ef1, 0x5ef3, 0x5ef0, 0x5ef4, 0x5ef8, - 0x5efe, 0x5f03, 0x5f09, 0x5f5d, 0x5f5c, 0x5f0b, 0x5f11, 0x5f16, - 0x5f29, 0x5f2d, 0x5f38, 0x5f41, 0x5f48, 0x5f4c, 0x5f4e, 0x5f2f, - 0x5f51, 0x5f56, 0x5f57, 0x5f59, 0x5f61, 0x5f6d, 0x5f73, 0x5f77, - 0x5f83, 0x5f82, 0x5f7f, 0x5f8a, 0x5f88, 0x5f91, 0x5f87, 0x5f9e, - 0x5f99, 0x5f98, 0x5fa0, 0x5fa8, 0x5fad, 0x5fbc, 0x5fd6, 0x5ffb, - 0x5fe4, 0x5ff8, 0x5ff1, 0x5fdd, 0x60b3, 0x5fff, 0x6021, 0x6060, - 0x6019, 0x6010, 0x6029, 0x600e, 0x6031, 0x601b, 0x6015, 0x602b, - 0x6026, 0x600f, 0x603a, 0x605a, 0x6041, 0x606a, 0x6077, 0x605f, - 0x604a, 0x6046, 0x604d, 0x6063, 0x6043, 0x6064, 0x6042, 0x606c, - 0x606b, 0x6059, 0x6081, 0x608d, 0x60e7, 0x6083, 0x609a, - /* 0x5821 - 0x587e */ - 0x6084, 0x609b, 0x6096, 0x6097, 0x6092, 0x60a7, 0x608b, - 0x60e1, 0x60b8, 0x60e0, 0x60d3, 0x60b4, 0x5ff0, 0x60bd, 0x60c6, - 0x60b5, 0x60d8, 0x614d, 0x6115, 0x6106, 0x60f6, 0x60f7, 0x6100, - 0x60f4, 0x60fa, 0x6103, 0x6121, 0x60fb, 0x60f1, 0x610d, 0x610e, - 0x6147, 0x613e, 0x6128, 0x6127, 0x614a, 0x613f, 0x613c, 0x612c, - 0x6134, 0x613d, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, - 0x615a, 0x616b, 0x6174, 0x616f, 0x6165, 0x6171, 0x615f, 0x615d, - 0x6153, 0x6175, 0x6199, 0x6196, 0x6187, 0x61ac, 0x6194, 0x619a, - 0x618a, 0x6191, 0x61ab, 0x61ae, 0x61cc, 0x61ca, 0x61c9, 0x61f7, - 0x61c8, 0x61c3, 0x61c6, 0x61ba, 0x61cb, 0x7f79, 0x61cd, 0x61e6, - 0x61e3, 0x61f6, 0x61fa, 0x61f4, 0x61ff, 0x61fd, 0x61fc, 0x61fe, - 0x6200, 0x6208, 0x6209, 0x620d, 0x620c, 0x6214, 0x621b, - /* 0x5921 - 0x597e */ - 0x621e, 0x6221, 0x622a, 0x622e, 0x6230, 0x6232, 0x6233, - 0x6241, 0x624e, 0x625e, 0x6263, 0x625b, 0x6260, 0x6268, 0x627c, - 0x6282, 0x6289, 0x627e, 0x6292, 0x6293, 0x6296, 0x62d4, 0x6283, - 0x6294, 0x62d7, 0x62d1, 0x62bb, 0x62cf, 0x62ff, 0x62c6, 0x64d4, - 0x62c8, 0x62dc, 0x62cc, 0x62ca, 0x62c2, 0x62c7, 0x629b, 0x62c9, - 0x630c, 0x62ee, 0x62f1, 0x6327, 0x6302, 0x6308, 0x62ef, 0x62f5, - 0x6350, 0x633e, 0x634d, 0x641c, 0x634f, 0x6396, 0x638e, 0x6380, - 0x63ab, 0x6376, 0x63a3, 0x638f, 0x6389, 0x639f, 0x63b5, 0x636b, - 0x6369, 0x63be, 0x63e9, 0x63c0, 0x63c6, 0x63e3, 0x63c9, 0x63d2, - 0x63f6, 0x63c4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, - 0x651d, 0x6417, 0x6428, 0x640f, 0x6467, 0x646f, 0x6476, 0x644e, - 0x652a, 0x6495, 0x6493, 0x64a5, 0x64a9, 0x6488, 0x64bc, - /* 0x5a21 - 0x5a7e */ - 0x64da, 0x64d2, 0x64c5, 0x64c7, 0x64bb, 0x64d8, 0x64c2, - 0x64f1, 0x64e7, 0x8209, 0x64e0, 0x64e1, 0x62ac, 0x64e3, 0x64ef, - 0x652c, 0x64f6, 0x64f4, 0x64f2, 0x64fa, 0x6500, 0x64fd, 0x6518, - 0x651c, 0x6505, 0x6524, 0x6523, 0x652b, 0x6534, 0x6535, 0x6537, - 0x6536, 0x6538, 0x754b, 0x6548, 0x6556, 0x6555, 0x654d, 0x6558, - 0x655e, 0x655d, 0x6572, 0x6578, 0x6582, 0x6583, 0x8b8a, 0x659b, - 0x659f, 0x65ab, 0x65b7, 0x65c3, 0x65c6, 0x65c1, 0x65c4, 0x65cc, - 0x65d2, 0x65db, 0x65d9, 0x65e0, 0x65e1, 0x65f1, 0x6772, 0x660a, - 0x6603, 0x65fb, 0x6773, 0x6635, 0x6636, 0x6634, 0x661c, 0x664f, - 0x6644, 0x6649, 0x6641, 0x665e, 0x665d, 0x6664, 0x6667, 0x6668, - 0x665f, 0x6662, 0x6670, 0x6683, 0x6688, 0x668e, 0x6689, 0x6684, - 0x6698, 0x669d, 0x66c1, 0x66b9, 0x66c9, 0x66be, 0x66bc, - /* 0x5b21 - 0x5b7e */ - 0x66c4, 0x66b8, 0x66d6, 0x66da, 0x66e0, 0x663f, 0x66e6, - 0x66e9, 0x66f0, 0x66f5, 0x66f7, 0x670f, 0x6716, 0x671e, 0x6726, - 0x6727, 0x9738, 0x672e, 0x673f, 0x6736, 0x6741, 0x6738, 0x6737, - 0x6746, 0x675e, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, - 0x67a9, 0x677c, 0x676a, 0x678c, 0x678b, 0x67a6, 0x67a1, 0x6785, - 0x67b7, 0x67ef, 0x67b4, 0x67ec, 0x67b3, 0x67e9, 0x67b8, 0x67e4, - 0x67de, 0x67dd, 0x67e2, 0x67ee, 0x67b9, 0x67ce, 0x67c6, 0x67e7, - 0x6a9c, 0x681e, 0x6846, 0x6829, 0x6840, 0x684d, 0x6832, 0x684e, - 0x68b3, 0x682b, 0x6859, 0x6863, 0x6877, 0x687f, 0x689f, 0x688f, - 0x68ad, 0x6894, 0x689d, 0x689b, 0x6883, 0x6aae, 0x68b9, 0x6874, - 0x68b5, 0x68a0, 0x68ba, 0x690f, 0x688d, 0x687e, 0x6901, 0x68ca, - 0x6908, 0x68d8, 0x6922, 0x6926, 0x68e1, 0x690c, 0x68cd, - /* 0x5c21 - 0x5c7e */ - 0x68d4, 0x68e7, 0x68d5, 0x6936, 0x6912, 0x6904, 0x68d7, - 0x68e3, 0x6925, 0x68f9, 0x68e0, 0x68ef, 0x6928, 0x692a, 0x691a, - 0x6923, 0x6921, 0x68c6, 0x6979, 0x6977, 0x695c, 0x6978, 0x696b, - 0x6954, 0x697e, 0x696e, 0x6939, 0x6974, 0x693d, 0x6959, 0x6930, - 0x6961, 0x695e, 0x695d, 0x6981, 0x696a, 0x69b2, 0x69ae, 0x69d0, - 0x69bf, 0x69c1, 0x69d3, 0x69be, 0x69ce, 0x5be8, 0x69ca, 0x69dd, - 0x69bb, 0x69c3, 0x69a7, 0x6a2e, 0x6991, 0x69a0, 0x699c, 0x6995, - 0x69b4, 0x69de, 0x69e8, 0x6a02, 0x6a1b, 0x69ff, 0x6b0a, 0x69f9, - 0x69f2, 0x69e7, 0x6a05, 0x69b1, 0x6a1e, 0x69ed, 0x6a14, 0x69eb, - 0x6a0a, 0x6a12, 0x6ac1, 0x6a23, 0x6a13, 0x6a44, 0x6a0c, 0x6a72, - 0x6a36, 0x6a78, 0x6a47, 0x6a62, 0x6a59, 0x6a66, 0x6a48, 0x6a38, - 0x6a22, 0x6a90, 0x6a8d, 0x6aa0, 0x6a84, 0x6aa2, 0x6aa3, - /* 0x5d21 - 0x5d7e */ - 0x6a97, 0x8617, 0x6abb, 0x6ac3, 0x6ac2, 0x6ab8, 0x6ab3, - 0x6aac, 0x6ade, 0x6ad1, 0x6adf, 0x6aaa, 0x6ada, 0x6aea, 0x6afb, - 0x6b05, 0x8616, 0x6afa, 0x6b12, 0x6b16, 0x9b31, 0x6b1f, 0x6b38, - 0x6b37, 0x76dc, 0x6b39, 0x98ee, 0x6b47, 0x6b43, 0x6b49, 0x6b50, - 0x6b59, 0x6b54, 0x6b5b, 0x6b5f, 0x6b61, 0x6b78, 0x6b79, 0x6b7f, - 0x6b80, 0x6b84, 0x6b83, 0x6b8d, 0x6b98, 0x6b95, 0x6b9e, 0x6ba4, - 0x6baa, 0x6bab, 0x6baf, 0x6bb2, 0x6bb1, 0x6bb3, 0x6bb7, 0x6bbc, - 0x6bc6, 0x6bcb, 0x6bd3, 0x6bdf, 0x6bec, 0x6beb, 0x6bf3, 0x6bef, - 0x9ebe, 0x6c08, 0x6c13, 0x6c14, 0x6c1b, 0x6c24, 0x6c23, 0x6c5e, - 0x6c55, 0x6c62, 0x6c6a, 0x6c82, 0x6c8d, 0x6c9a, 0x6c81, 0x6c9b, - 0x6c7e, 0x6c68, 0x6c73, 0x6c92, 0x6c90, 0x6cc4, 0x6cf1, 0x6cd3, - 0x6cbd, 0x6cd7, 0x6cc5, 0x6cdd, 0x6cae, 0x6cb1, 0x6cbe, - /* 0x5e21 - 0x5e7e */ - 0x6cba, 0x6cdb, 0x6cef, 0x6cd9, 0x6cea, 0x6d1f, 0x884d, - 0x6d36, 0x6d2b, 0x6d3d, 0x6d38, 0x6d19, 0x6d35, 0x6d33, 0x6d12, - 0x6d0c, 0x6d63, 0x6d93, 0x6d64, 0x6d5a, 0x6d79, 0x6d59, 0x6d8e, - 0x6d95, 0x6fe4, 0x6d85, 0x6df9, 0x6e15, 0x6e0a, 0x6db5, 0x6dc7, - 0x6de6, 0x6db8, 0x6dc6, 0x6dec, 0x6dde, 0x6dcc, 0x6de8, 0x6dd2, - 0x6dc5, 0x6dfa, 0x6dd9, 0x6de4, 0x6dd5, 0x6dea, 0x6dee, 0x6e2d, - 0x6e6e, 0x6e2e, 0x6e19, 0x6e72, 0x6e5f, 0x6e3e, 0x6e23, 0x6e6b, - 0x6e2b, 0x6e76, 0x6e4d, 0x6e1f, 0x6e43, 0x6e3a, 0x6e4e, 0x6e24, - 0x6eff, 0x6e1d, 0x6e38, 0x6e82, 0x6eaa, 0x6e98, 0x6ec9, 0x6eb7, - 0x6ed3, 0x6ebd, 0x6eaf, 0x6ec4, 0x6eb2, 0x6ed4, 0x6ed5, 0x6e8f, - 0x6ea5, 0x6ec2, 0x6e9f, 0x6f41, 0x6f11, 0x704c, 0x6eec, 0x6ef8, - 0x6efe, 0x6f3f, 0x6ef2, 0x6f31, 0x6eef, 0x6f32, 0x6ecc, - /* 0x5f21 - 0x5f7e */ - 0x6f3e, 0x6f13, 0x6ef7, 0x6f86, 0x6f7a, 0x6f78, 0x6f81, - 0x6f80, 0x6f6f, 0x6f5b, 0x6ff3, 0x6f6d, 0x6f82, 0x6f7c, 0x6f58, - 0x6f8e, 0x6f91, 0x6fc2, 0x6f66, 0x6fb3, 0x6fa3, 0x6fa1, 0x6fa4, - 0x6fb9, 0x6fc6, 0x6faa, 0x6fdf, 0x6fd5, 0x6fec, 0x6fd4, 0x6fd8, - 0x6ff1, 0x6fee, 0x6fdb, 0x7009, 0x700b, 0x6ffa, 0x7011, 0x7001, - 0x700f, 0x6ffe, 0x701b, 0x701a, 0x6f74, 0x701d, 0x7018, 0x701f, - 0x7030, 0x703e, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70af, - 0x70f1, 0x70ac, 0x70b8, 0x70b3, 0x70ae, 0x70df, 0x70cb, 0x70dd, - 0x70d9, 0x7109, 0x70fd, 0x711c, 0x7119, 0x7165, 0x7155, 0x7188, - 0x7166, 0x7162, 0x714c, 0x7156, 0x716c, 0x718f, 0x71fb, 0x7184, - 0x7195, 0x71a8, 0x71ac, 0x71d7, 0x71b9, 0x71be, 0x71d2, 0x71c9, - 0x71d4, 0x71ce, 0x71e0, 0x71ec, 0x71e7, 0x71f5, 0x71fc, - /* 0x6021 - 0x607e */ - 0x71f9, 0x71ff, 0x720d, 0x7210, 0x721b, 0x7228, 0x722d, - 0x722c, 0x7230, 0x7232, 0x723b, 0x723c, 0x723f, 0x7240, 0x7246, - 0x724b, 0x7258, 0x7274, 0x727e, 0x7282, 0x7281, 0x7287, 0x7292, - 0x7296, 0x72a2, 0x72a7, 0x72b9, 0x72b2, 0x72c3, 0x72c6, 0x72c4, - 0x72ce, 0x72d2, 0x72e2, 0x72e0, 0x72e1, 0x72f9, 0x72f7, 0x500f, - 0x7317, 0x730a, 0x731c, 0x7316, 0x731d, 0x7334, 0x732f, 0x7329, - 0x7325, 0x733e, 0x734e, 0x734f, 0x9ed8, 0x7357, 0x736a, 0x7368, - 0x7370, 0x7378, 0x7375, 0x737b, 0x737a, 0x73c8, 0x73b3, 0x73ce, - 0x73bb, 0x73c0, 0x73e5, 0x73ee, 0x73de, 0x74a2, 0x7405, 0x746f, - 0x7425, 0x73f8, 0x7432, 0x743a, 0x7455, 0x743f, 0x745f, 0x7459, - 0x7441, 0x745c, 0x7469, 0x7470, 0x7463, 0x746a, 0x7476, 0x747e, - 0x748b, 0x749e, 0x74a7, 0x74ca, 0x74cf, 0x74d4, 0x73f1, - /* 0x6121 - 0x617e */ - 0x74e0, 0x74e3, 0x74e7, 0x74e9, 0x74ee, 0x74f2, 0x74f0, - 0x74f1, 0x74f8, 0x74f7, 0x7504, 0x7503, 0x7505, 0x750c, 0x750e, - 0x750d, 0x7515, 0x7513, 0x751e, 0x7526, 0x752c, 0x753c, 0x7544, - 0x754d, 0x754a, 0x7549, 0x755b, 0x7546, 0x755a, 0x7569, 0x7564, - 0x7567, 0x756b, 0x756d, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, - 0x758a, 0x7589, 0x7582, 0x7594, 0x759a, 0x759d, 0x75a5, 0x75a3, - 0x75c2, 0x75b3, 0x75c3, 0x75b5, 0x75bd, 0x75b8, 0x75bc, 0x75b1, - 0x75cd, 0x75ca, 0x75d2, 0x75d9, 0x75e3, 0x75de, 0x75fe, 0x75ff, - 0x75fc, 0x7601, 0x75f0, 0x75fa, 0x75f2, 0x75f3, 0x760b, 0x760d, - 0x7609, 0x761f, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, - 0x7630, 0x763b, 0x7647, 0x7648, 0x7646, 0x765c, 0x7658, 0x7661, - 0x7662, 0x7668, 0x7669, 0x766a, 0x7667, 0x766c, 0x7670, - /* 0x6221 - 0x627e */ - 0x7672, 0x7676, 0x7678, 0x767c, 0x7680, 0x7683, 0x7688, - 0x768b, 0x768e, 0x7696, 0x7693, 0x7699, 0x769a, 0x76b0, 0x76b4, - 0x76b8, 0x76b9, 0x76ba, 0x76c2, 0x76cd, 0x76d6, 0x76d2, 0x76de, - 0x76e1, 0x76e5, 0x76e7, 0x76ea, 0x862f, 0x76fb, 0x7708, 0x7707, - 0x7704, 0x7729, 0x7724, 0x771e, 0x7725, 0x7726, 0x771b, 0x7737, - 0x7738, 0x7747, 0x775a, 0x7768, 0x776b, 0x775b, 0x7765, 0x777f, - 0x777e, 0x7779, 0x778e, 0x778b, 0x7791, 0x77a0, 0x779e, 0x77b0, - 0x77b6, 0x77b9, 0x77bf, 0x77bc, 0x77bd, 0x77bb, 0x77c7, 0x77cd, - 0x77d7, 0x77da, 0x77dc, 0x77e3, 0x77ee, 0x77fc, 0x780c, 0x7812, - 0x7926, 0x7820, 0x792a, 0x7845, 0x788e, 0x7874, 0x7886, 0x787c, - 0x789a, 0x788c, 0x78a3, 0x78b5, 0x78aa, 0x78af, 0x78d1, 0x78c6, - 0x78cb, 0x78d4, 0x78be, 0x78bc, 0x78c5, 0x78ca, 0x78ec, - /* 0x6321 - 0x637e */ - 0x78e7, 0x78da, 0x78fd, 0x78f4, 0x7907, 0x7912, 0x7911, - 0x7919, 0x792c, 0x792b, 0x7940, 0x7960, 0x7957, 0x795f, 0x795a, - 0x7955, 0x7953, 0x797a, 0x797f, 0x798a, 0x799d, 0x79a7, 0x9f4b, - 0x79aa, 0x79ae, 0x79b3, 0x79b9, 0x79ba, 0x79c9, 0x79d5, 0x79e7, - 0x79ec, 0x79e1, 0x79e3, 0x7a08, 0x7a0d, 0x7a18, 0x7a19, 0x7a20, - 0x7a1f, 0x7980, 0x7a31, 0x7a3b, 0x7a3e, 0x7a37, 0x7a43, 0x7a57, - 0x7a49, 0x7a61, 0x7a62, 0x7a69, 0x9f9d, 0x7a70, 0x7a79, 0x7a7d, - 0x7a88, 0x7a97, 0x7a95, 0x7a98, 0x7a96, 0x7aa9, 0x7ac8, 0x7ab0, - 0x7ab6, 0x7ac5, 0x7ac4, 0x7abf, 0x9083, 0x7ac7, 0x7aca, 0x7acd, - 0x7acf, 0x7ad5, 0x7ad3, 0x7ad9, 0x7ada, 0x7add, 0x7ae1, 0x7ae2, - 0x7ae6, 0x7aed, 0x7af0, 0x7b02, 0x7b0f, 0x7b0a, 0x7b06, 0x7b33, - 0x7b18, 0x7b19, 0x7b1e, 0x7b35, 0x7b28, 0x7b36, 0x7b50, - /* 0x6421 - 0x647e */ - 0x7b7a, 0x7b04, 0x7b4d, 0x7b0b, 0x7b4c, 0x7b45, 0x7b75, - 0x7b65, 0x7b74, 0x7b67, 0x7b70, 0x7b71, 0x7b6c, 0x7b6e, 0x7b9d, - 0x7b98, 0x7b9f, 0x7b8d, 0x7b9c, 0x7b9a, 0x7b8b, 0x7b92, 0x7b8f, - 0x7b5d, 0x7b99, 0x7bcb, 0x7bc1, 0x7bcc, 0x7bcf, 0x7bb4, 0x7bc6, - 0x7bdd, 0x7be9, 0x7c11, 0x7c14, 0x7be6, 0x7be5, 0x7c60, 0x7c00, - 0x7c07, 0x7c13, 0x7bf3, 0x7bf7, 0x7c17, 0x7c0d, 0x7bf6, 0x7c23, - 0x7c27, 0x7c2a, 0x7c1f, 0x7c37, 0x7c2b, 0x7c3d, 0x7c4c, 0x7c43, - 0x7c54, 0x7c4f, 0x7c40, 0x7c50, 0x7c58, 0x7c5f, 0x7c64, 0x7c56, - 0x7c65, 0x7c6c, 0x7c75, 0x7c83, 0x7c90, 0x7ca4, 0x7cad, 0x7ca2, - 0x7cab, 0x7ca1, 0x7ca8, 0x7cb3, 0x7cb2, 0x7cb1, 0x7cae, 0x7cb9, - 0x7cbd, 0x7cc0, 0x7cc5, 0x7cc2, 0x7cd8, 0x7cd2, 0x7cdc, 0x7ce2, - 0x9b3b, 0x7cef, 0x7cf2, 0x7cf4, 0x7cf6, 0x7cfa, 0x7d06, - /* 0x6521 - 0x657e */ - 0x7d02, 0x7d1c, 0x7d15, 0x7d0a, 0x7d45, 0x7d4b, 0x7d2e, - 0x7d32, 0x7d3f, 0x7d35, 0x7d46, 0x7d73, 0x7d56, 0x7d4e, 0x7d72, - 0x7d68, 0x7d6e, 0x7d4f, 0x7d63, 0x7d93, 0x7d89, 0x7d5b, 0x7d8f, - 0x7d7d, 0x7d9b, 0x7dba, 0x7dae, 0x7da3, 0x7db5, 0x7dc7, 0x7dbd, - 0x7dab, 0x7e3d, 0x7da2, 0x7daf, 0x7ddc, 0x7db8, 0x7d9f, 0x7db0, - 0x7dd8, 0x7ddd, 0x7de4, 0x7dde, 0x7dfb, 0x7df2, 0x7de1, 0x7e05, - 0x7e0a, 0x7e23, 0x7e21, 0x7e12, 0x7e31, 0x7e1f, 0x7e09, 0x7e0b, - 0x7e22, 0x7e46, 0x7e66, 0x7e3b, 0x7e35, 0x7e39, 0x7e43, 0x7e37, - 0x7e32, 0x7e3a, 0x7e67, 0x7e5d, 0x7e56, 0x7e5e, 0x7e59, 0x7e5a, - 0x7e79, 0x7e6a, 0x7e69, 0x7e7c, 0x7e7b, 0x7e83, 0x7dd5, 0x7e7d, - 0x8fae, 0x7e7f, 0x7e88, 0x7e89, 0x7e8c, 0x7e92, 0x7e90, 0x7e93, - 0x7e94, 0x7e96, 0x7e8e, 0x7e9b, 0x7e9c, 0x7f38, 0x7f3a, - /* 0x6621 - 0x667e */ - 0x7f45, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f50, 0x7f51, 0x7f55, - 0x7f54, 0x7f58, 0x7f5f, 0x7f60, 0x7f68, 0x7f69, 0x7f67, 0x7f78, - 0x7f82, 0x7f86, 0x7f83, 0x7f88, 0x7f87, 0x7f8c, 0x7f94, 0x7f9e, - 0x7f9d, 0x7f9a, 0x7fa3, 0x7faf, 0x7fb2, 0x7fb9, 0x7fae, 0x7fb6, - 0x7fb8, 0x8b71, 0x7fc5, 0x7fc6, 0x7fca, 0x7fd5, 0x7fd4, 0x7fe1, - 0x7fe6, 0x7fe9, 0x7ff3, 0x7ff9, 0x98dc, 0x8006, 0x8004, 0x800b, - 0x8012, 0x8018, 0x8019, 0x801c, 0x8021, 0x8028, 0x803f, 0x803b, - 0x804a, 0x8046, 0x8052, 0x8058, 0x805a, 0x805f, 0x8062, 0x8068, - 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807d, 0x807f, 0x8084, - 0x8086, 0x8085, 0x809b, 0x8093, 0x809a, 0x80ad, 0x5190, 0x80ac, - 0x80db, 0x80e5, 0x80d9, 0x80dd, 0x80c4, 0x80da, 0x80d6, 0x8109, - 0x80ef, 0x80f1, 0x811b, 0x8129, 0x8123, 0x812f, 0x814b, - /* 0x6721 - 0x677e */ - 0x968b, 0x8146, 0x813e, 0x8153, 0x8151, 0x80fc, 0x8171, - 0x816e, 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818a, 0x8180, - 0x8182, 0x81a0, 0x8195, 0x81a4, 0x81a3, 0x815f, 0x8193, 0x81a9, - 0x81b0, 0x81b5, 0x81be, 0x81b8, 0x81bd, 0x81c0, 0x81c2, 0x81ba, - 0x81c9, 0x81cd, 0x81d1, 0x81d9, 0x81d8, 0x81c8, 0x81da, 0x81df, - 0x81e0, 0x81e7, 0x81fa, 0x81fb, 0x81fe, 0x8201, 0x8202, 0x8205, - 0x8207, 0x820a, 0x820d, 0x8210, 0x8216, 0x8229, 0x822b, 0x8238, - 0x8233, 0x8240, 0x8259, 0x8258, 0x825d, 0x825a, 0x825f, 0x8264, - 0x8262, 0x8268, 0x826a, 0x826b, 0x822e, 0x8271, 0x8277, 0x8278, - 0x827e, 0x828d, 0x8292, 0x82ab, 0x829f, 0x82bb, 0x82ac, 0x82e1, - 0x82e3, 0x82df, 0x82d2, 0x82f4, 0x82f3, 0x82fa, 0x8393, 0x8303, - 0x82fb, 0x82f9, 0x82de, 0x8306, 0x82dc, 0x8309, 0x82d9, - /* 0x6821 - 0x687e */ - 0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, - 0x8350, 0x8345, 0x832f, 0x832b, 0x8317, 0x8318, 0x8385, 0x839a, - 0x83aa, 0x839f, 0x83a2, 0x8396, 0x8323, 0x838e, 0x8387, 0x838a, - 0x837c, 0x83b5, 0x8373, 0x8375, 0x83a0, 0x8389, 0x83a8, 0x83f4, - 0x8413, 0x83eb, 0x83ce, 0x83fd, 0x8403, 0x83d8, 0x840b, 0x83c1, - 0x83f7, 0x8407, 0x83e0, 0x83f2, 0x840d, 0x8422, 0x8420, 0x83bd, - 0x8438, 0x8506, 0x83fb, 0x846d, 0x842a, 0x843c, 0x855a, 0x8484, - 0x8477, 0x846b, 0x84ad, 0x846e, 0x8482, 0x8469, 0x8446, 0x842c, - 0x846f, 0x8479, 0x8435, 0x84ca, 0x8462, 0x84b9, 0x84bf, 0x849f, - 0x84d9, 0x84cd, 0x84bb, 0x84da, 0x84d0, 0x84c1, 0x84c6, 0x84d6, - 0x84a1, 0x8521, 0x84ff, 0x84f4, 0x8517, 0x8518, 0x852c, 0x851f, - 0x8515, 0x8514, 0x84fc, 0x8540, 0x8563, 0x8558, 0x8548, - /* 0x6921 - 0x697e */ - 0x8541, 0x8602, 0x854b, 0x8555, 0x8580, 0x85a4, 0x8588, - 0x8591, 0x858a, 0x85a8, 0x856d, 0x8594, 0x859b, 0x85ea, 0x8587, - 0x859c, 0x8577, 0x857e, 0x8590, 0x85c9, 0x85ba, 0x85cf, 0x85b9, - 0x85d0, 0x85d5, 0x85dd, 0x85e5, 0x85dc, 0x85f9, 0x860a, 0x8613, - 0x860b, 0x85fe, 0x85fa, 0x8606, 0x8622, 0x861a, 0x8630, 0x863f, - 0x864d, 0x4e55, 0x8654, 0x865f, 0x8667, 0x8671, 0x8693, 0x86a3, - 0x86a9, 0x86aa, 0x868b, 0x868c, 0x86b6, 0x86af, 0x86c4, 0x86c6, - 0x86b0, 0x86c9, 0x8823, 0x86ab, 0x86d4, 0x86de, 0x86e9, 0x86ec, - 0x86df, 0x86db, 0x86ef, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, - 0x86fb, 0x8711, 0x8709, 0x870d, 0x86f9, 0x870a, 0x8734, 0x873f, - 0x8737, 0x873b, 0x8725, 0x8729, 0x871a, 0x8760, 0x875f, 0x8778, - 0x874c, 0x874e, 0x8774, 0x8757, 0x8768, 0x876e, 0x8759, - /* 0x6a21 - 0x6a7e */ - 0x8753, 0x8763, 0x876a, 0x8805, 0x87a2, 0x879f, 0x8782, - 0x87af, 0x87cb, 0x87bd, 0x87c0, 0x87d0, 0x96d6, 0x87ab, 0x87c4, - 0x87b3, 0x87c7, 0x87c6, 0x87bb, 0x87ef, 0x87f2, 0x87e0, 0x880f, - 0x880d, 0x87fe, 0x87f6, 0x87f7, 0x880e, 0x87d2, 0x8811, 0x8816, - 0x8815, 0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883b, - 0x8844, 0x8842, 0x8852, 0x8859, 0x885e, 0x8862, 0x886b, 0x8881, - 0x887e, 0x889e, 0x8875, 0x887d, 0x88b5, 0x8872, 0x8882, 0x8897, - 0x8892, 0x88ae, 0x8899, 0x88a2, 0x888d, 0x88a4, 0x88b0, 0x88bf, - 0x88b1, 0x88c3, 0x88c4, 0x88d4, 0x88d8, 0x88d9, 0x88dd, 0x88f9, - 0x8902, 0x88fc, 0x88f4, 0x88e8, 0x88f2, 0x8904, 0x890c, 0x890a, - 0x8913, 0x8943, 0x891e, 0x8925, 0x892a, 0x892b, 0x8941, 0x8944, - 0x893b, 0x8936, 0x8938, 0x894c, 0x891d, 0x8960, 0x895e, - /* 0x6b21 - 0x6b7e */ - 0x8966, 0x8964, 0x896d, 0x896a, 0x896f, 0x8974, 0x8977, - 0x897e, 0x8983, 0x8988, 0x898a, 0x8993, 0x8998, 0x89a1, 0x89a9, - 0x89a6, 0x89ac, 0x89af, 0x89b2, 0x89ba, 0x89bd, 0x89bf, 0x89c0, - 0x89da, 0x89dc, 0x89dd, 0x89e7, 0x89f4, 0x89f8, 0x8a03, 0x8a16, - 0x8a10, 0x8a0c, 0x8a1b, 0x8a1d, 0x8a25, 0x8a36, 0x8a41, 0x8a5b, - 0x8a52, 0x8a46, 0x8a48, 0x8a7c, 0x8a6d, 0x8a6c, 0x8a62, 0x8a85, - 0x8a82, 0x8a84, 0x8aa8, 0x8aa1, 0x8a91, 0x8aa5, 0x8aa6, 0x8a9a, - 0x8aa3, 0x8ac4, 0x8acd, 0x8ac2, 0x8ada, 0x8aeb, 0x8af3, 0x8ae7, - 0x8ae4, 0x8af1, 0x8b14, 0x8ae0, 0x8ae2, 0x8af7, 0x8ade, 0x8adb, - 0x8b0c, 0x8b07, 0x8b1a, 0x8ae1, 0x8b16, 0x8b10, 0x8b17, 0x8b20, - 0x8b33, 0x97ab, 0x8b26, 0x8b2b, 0x8b3e, 0x8b28, 0x8b41, 0x8b4c, - 0x8b4f, 0x8b4e, 0x8b49, 0x8b56, 0x8b5b, 0x8b5a, 0x8b6b, - /* 0x6c21 - 0x6c7e */ - 0x8b5f, 0x8b6c, 0x8b6f, 0x8b74, 0x8b7d, 0x8b80, 0x8b8c, - 0x8b8e, 0x8b92, 0x8b93, 0x8b96, 0x8b99, 0x8b9a, 0x8c3a, 0x8c41, - 0x8c3f, 0x8c48, 0x8c4c, 0x8c4e, 0x8c50, 0x8c55, 0x8c62, 0x8c6c, - 0x8c78, 0x8c7a, 0x8c82, 0x8c89, 0x8c85, 0x8c8a, 0x8c8d, 0x8c8e, - 0x8c94, 0x8c7c, 0x8c98, 0x621d, 0x8cad, 0x8caa, 0x8cbd, 0x8cb2, - 0x8cb3, 0x8cae, 0x8cb6, 0x8cc8, 0x8cc1, 0x8ce4, 0x8ce3, 0x8cda, - 0x8cfd, 0x8cfa, 0x8cfb, 0x8d04, 0x8d05, 0x8d0a, 0x8d07, 0x8d0f, - 0x8d0d, 0x8d10, 0x9f4e, 0x8d13, 0x8ccd, 0x8d14, 0x8d16, 0x8d67, - 0x8d6d, 0x8d71, 0x8d73, 0x8d81, 0x8d99, 0x8dc2, 0x8dbe, 0x8dba, - 0x8dcf, 0x8dda, 0x8dd6, 0x8dcc, 0x8ddb, 0x8dcb, 0x8dea, 0x8deb, - 0x8ddf, 0x8de3, 0x8dfc, 0x8e08, 0x8e09, 0x8dff, 0x8e1d, 0x8e1e, - 0x8e10, 0x8e1f, 0x8e42, 0x8e35, 0x8e30, 0x8e34, 0x8e4a, - /* 0x6d21 - 0x6d7e */ - 0x8e47, 0x8e49, 0x8e4c, 0x8e50, 0x8e48, 0x8e59, 0x8e64, - 0x8e60, 0x8e2a, 0x8e63, 0x8e55, 0x8e76, 0x8e72, 0x8e7c, 0x8e81, - 0x8e87, 0x8e85, 0x8e84, 0x8e8b, 0x8e8a, 0x8e93, 0x8e91, 0x8e94, - 0x8e99, 0x8eaa, 0x8ea1, 0x8eac, 0x8eb0, 0x8ec6, 0x8eb1, 0x8ebe, - 0x8ec5, 0x8ec8, 0x8ecb, 0x8edb, 0x8ee3, 0x8efc, 0x8efb, 0x8eeb, - 0x8efe, 0x8f0a, 0x8f05, 0x8f15, 0x8f12, 0x8f19, 0x8f13, 0x8f1c, - 0x8f1f, 0x8f1b, 0x8f0c, 0x8f26, 0x8f33, 0x8f3b, 0x8f39, 0x8f45, - 0x8f42, 0x8f3e, 0x8f4c, 0x8f49, 0x8f46, 0x8f4e, 0x8f57, 0x8f5c, - 0x8f62, 0x8f63, 0x8f64, 0x8f9c, 0x8f9f, 0x8fa3, 0x8fad, 0x8faf, - 0x8fb7, 0x8fda, 0x8fe5, 0x8fe2, 0x8fea, 0x8fef, 0x9087, 0x8ff4, - 0x9005, 0x8ff9, 0x8ffa, 0x9011, 0x9015, 0x9021, 0x900d, 0x901e, - 0x9016, 0x900b, 0x9027, 0x9036, 0x9035, 0x9039, 0x8ff8, - /* 0x6e21 - 0x6e7e */ - 0x904f, 0x9050, 0x9051, 0x9052, 0x900e, 0x9049, 0x903e, - 0x9056, 0x9058, 0x905e, 0x9068, 0x906f, 0x9076, 0x96a8, 0x9072, - 0x9082, 0x907d, 0x9081, 0x9080, 0x908a, 0x9089, 0x908f, 0x90a8, - 0x90af, 0x90b1, 0x90b5, 0x90e2, 0x90e4, 0x6248, 0x90db, 0x9102, - 0x9112, 0x9119, 0x9132, 0x9130, 0x914a, 0x9156, 0x9158, 0x9163, - 0x9165, 0x9169, 0x9173, 0x9172, 0x918b, 0x9189, 0x9182, 0x91a2, - 0x91ab, 0x91af, 0x91aa, 0x91b5, 0x91b4, 0x91ba, 0x91c0, 0x91c1, - 0x91c9, 0x91cb, 0x91d0, 0x91d6, 0x91df, 0x91e1, 0x91db, 0x91fc, - 0x91f5, 0x91f6, 0x921e, 0x91ff, 0x9214, 0x922c, 0x9215, 0x9211, - 0x925e, 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923f, - 0x924b, 0x9250, 0x929c, 0x9296, 0x9293, 0x929b, 0x925a, 0x92cf, - 0x92b9, 0x92b7, 0x92e9, 0x930f, 0x92fa, 0x9344, 0x932e, - /* 0x6f21 - 0x6f7e */ - 0x9319, 0x9322, 0x931a, 0x9323, 0x933a, 0x9335, 0x933b, - 0x935c, 0x9360, 0x937c, 0x936e, 0x9356, 0x93b0, 0x93ac, 0x93ad, - 0x9394, 0x93b9, 0x93d6, 0x93d7, 0x93e8, 0x93e5, 0x93d8, 0x93c3, - 0x93dd, 0x93d0, 0x93c8, 0x93e4, 0x941a, 0x9414, 0x9413, 0x9403, - 0x9407, 0x9410, 0x9436, 0x942b, 0x9435, 0x9421, 0x943a, 0x9441, - 0x9452, 0x9444, 0x945b, 0x9460, 0x9462, 0x945e, 0x946a, 0x9229, - 0x9470, 0x9475, 0x9477, 0x947d, 0x945a, 0x947c, 0x947e, 0x9481, - 0x947f, 0x9582, 0x9587, 0x958a, 0x9594, 0x9596, 0x9598, 0x9599, - 0x95a0, 0x95a8, 0x95a7, 0x95ad, 0x95bc, 0x95bb, 0x95b9, 0x95be, - 0x95ca, 0x6ff6, 0x95c3, 0x95cd, 0x95cc, 0x95d5, 0x95d4, 0x95d6, - 0x95dc, 0x95e1, 0x95e5, 0x95e2, 0x9621, 0x9628, 0x962e, 0x962f, - 0x9642, 0x964c, 0x964f, 0x964b, 0x9677, 0x965c, 0x965e, - /* 0x7021 - 0x707e */ - 0x965d, 0x965f, 0x9666, 0x9672, 0x966c, 0x968d, 0x9698, - 0x9695, 0x9697, 0x96aa, 0x96a7, 0x96b1, 0x96b2, 0x96b0, 0x96b4, - 0x96b6, 0x96b8, 0x96b9, 0x96ce, 0x96cb, 0x96c9, 0x96cd, 0x894d, - 0x96dc, 0x970d, 0x96d5, 0x96f9, 0x9704, 0x9706, 0x9708, 0x9713, - 0x970e, 0x9711, 0x970f, 0x9716, 0x9719, 0x9724, 0x972a, 0x9730, - 0x9739, 0x973d, 0x973e, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, - 0x975c, 0x9760, 0x9764, 0x9766, 0x9768, 0x52d2, 0x976b, 0x9771, - 0x9779, 0x9785, 0x977c, 0x9781, 0x977a, 0x9786, 0x978b, 0x978f, - 0x9790, 0x979c, 0x97a8, 0x97a6, 0x97a3, 0x97b3, 0x97b4, 0x97c3, - 0x97c6, 0x97c8, 0x97cb, 0x97dc, 0x97ed, 0x9f4f, 0x97f2, 0x7adf, - 0x97f6, 0x97f5, 0x980f, 0x980c, 0x9838, 0x9824, 0x9821, 0x9837, - 0x983d, 0x9846, 0x984f, 0x984b, 0x986b, 0x986f, 0x9870, - /* 0x7121 - 0x717e */ - 0x9871, 0x9874, 0x9873, 0x98aa, 0x98af, 0x98b1, 0x98b6, - 0x98c4, 0x98c3, 0x98c6, 0x98e9, 0x98eb, 0x9903, 0x9909, 0x9912, - 0x9914, 0x9918, 0x9921, 0x991d, 0x991e, 0x9924, 0x9920, 0x992c, - 0x992e, 0x993d, 0x993e, 0x9942, 0x9949, 0x9945, 0x9950, 0x994b, - 0x9951, 0x9952, 0x994c, 0x9955, 0x9997, 0x9998, 0x99a5, 0x99ad, - 0x99ae, 0x99bc, 0x99df, 0x99db, 0x99dd, 0x99d8, 0x99d1, 0x99ed, - 0x99ee, 0x99f1, 0x99f2, 0x99fb, 0x99f8, 0x9a01, 0x9a0f, 0x9a05, - 0x99e2, 0x9a19, 0x9a2b, 0x9a37, 0x9a45, 0x9a42, 0x9a40, 0x9a43, - 0x9a3e, 0x9a55, 0x9a4d, 0x9a5b, 0x9a57, 0x9a5f, 0x9a62, 0x9a65, - 0x9a64, 0x9a69, 0x9a6b, 0x9a6a, 0x9aad, 0x9ab0, 0x9abc, 0x9ac0, - 0x9acf, 0x9ad1, 0x9ad3, 0x9ad4, 0x9ade, 0x9adf, 0x9ae2, 0x9ae3, - 0x9ae6, 0x9aef, 0x9aeb, 0x9aee, 0x9af4, 0x9af1, 0x9af7, - /* 0x7221 - 0x727e */ - 0x9afb, 0x9b06, 0x9b18, 0x9b1a, 0x9b1f, 0x9b22, 0x9b23, - 0x9b25, 0x9b27, 0x9b28, 0x9b29, 0x9b2a, 0x9b2e, 0x9b2f, 0x9b32, - 0x9b44, 0x9b43, 0x9b4f, 0x9b4d, 0x9b4e, 0x9b51, 0x9b58, 0x9b74, - 0x9b93, 0x9b83, 0x9b91, 0x9b96, 0x9b97, 0x9b9f, 0x9ba0, 0x9ba8, - 0x9bb4, 0x9bc0, 0x9bca, 0x9bb9, 0x9bc6, 0x9bcf, 0x9bd1, 0x9bd2, - 0x9be3, 0x9be2, 0x9be4, 0x9bd4, 0x9be1, 0x9c3a, 0x9bf2, 0x9bf1, - 0x9bf0, 0x9c15, 0x9c14, 0x9c09, 0x9c13, 0x9c0c, 0x9c06, 0x9c08, - 0x9c12, 0x9c0a, 0x9c04, 0x9c2e, 0x9c1b, 0x9c25, 0x9c24, 0x9c21, - 0x9c30, 0x9c47, 0x9c32, 0x9c46, 0x9c3e, 0x9c5a, 0x9c60, 0x9c67, - 0x9c76, 0x9c78, 0x9ce7, 0x9cec, 0x9cf0, 0x9d09, 0x9d08, 0x9ceb, - 0x9d03, 0x9d06, 0x9d2a, 0x9d26, 0x9daf, 0x9d23, 0x9d1f, 0x9d44, - 0x9d15, 0x9d12, 0x9d41, 0x9d3f, 0x9d3e, 0x9d46, 0x9d48, - /* 0x7321 - 0x737e */ - 0x9d5d, 0x9d5e, 0x9d64, 0x9d51, 0x9d50, 0x9d59, 0x9d72, - 0x9d89, 0x9d87, 0x9dab, 0x9d6f, 0x9d7a, 0x9d9a, 0x9da4, 0x9da9, - 0x9db2, 0x9dc4, 0x9dc1, 0x9dbb, 0x9db8, 0x9dba, 0x9dc6, 0x9dcf, - 0x9dc2, 0x9dd9, 0x9dd3, 0x9df8, 0x9de6, 0x9ded, 0x9def, 0x9dfd, - 0x9e1a, 0x9e1b, 0x9e1e, 0x9e75, 0x9e79, 0x9e7d, 0x9e81, 0x9e88, - 0x9e8b, 0x9e8c, 0x9e92, 0x9e95, 0x9e91, 0x9e9d, 0x9ea5, 0x9ea9, - 0x9eb8, 0x9eaa, 0x9ead, 0x9761, 0x9ecc, 0x9ece, 0x9ecf, 0x9ed0, - 0x9ed4, 0x9edc, 0x9ede, 0x9edd, 0x9ee0, 0x9ee5, 0x9ee8, 0x9eef, - 0x9ef4, 0x9ef6, 0x9ef7, 0x9ef9, 0x9efb, 0x9efc, 0x9efd, 0x9f07, - 0x9f08, 0x76b7, 0x9f15, 0x9f21, 0x9f2c, 0x9f3e, 0x9f4a, 0x9f52, - 0x9f54, 0x9f63, 0x9f5f, 0x9f60, 0x9f61, 0x9f66, 0x9f67, 0x9f6c, - 0x9f6a, 0x9f77, 0x9f72, 0x9f76, 0x9f95, 0x9f9c, 0x9fa0, - /* 0x7421 - 0x747e */ - 0x582f, 0x69c7, 0x9059, 0x7464, 0x51dc, 0x7199, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7521 - 0x757e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7621 - 0x767e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7721 - 0x777e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7821 - 0x787e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7921 - 0x797e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7a21 - 0x7a7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7b21 - 0x7b7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7c21 - 0x7c7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7d21 - 0x7d7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7e21 - 0x7e7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/* -* This data is derived from Unicode 1.1, -* JIS X 0212 (1990) to Unicode mapping table version 0.9 . -* (In addition IBM Vendor Defined Char included) -*/ -static unsigned short const jisx0212_to_unicode[] = { - /* 0x2121 - 0x217e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2221 - 0x227e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02d8, - 0x02c7, 0x00b8, 0x02d9, 0x02dd, 0x00af, 0x02db, 0x02da, 0x007e, - 0x0384, 0x0385, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x00a1, 0x00a6, 0x00bf, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x00ba, 0x00aa, 0x00a9, 0x00ae, 0x2122, - 0x00a4, 0x2116, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2321 - 0x237e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2421 - 0x247e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2521 - 0x257e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2621 - 0x267e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, - 0x0000, 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0000, - 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, - 0x03c2, 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, - /* 0x2721 - 0x277e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, - 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x040e, 0x040f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, - 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045e, 0x045f, - /* 0x2821 - 0x287e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2921 - 0x297e */ - 0x00c6, 0x0110, 0x0000, 0x0126, 0x0000, 0x0132, 0x0000, - 0x0141, 0x013f, 0x0000, 0x014a, 0x00d8, 0x0152, 0x0000, 0x0166, - 0x00de, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138, - 0x0142, 0x0140, 0x0149, 0x014b, 0x00f8, 0x0153, 0x00df, 0x0167, - 0x00fe, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2a21 - 0x2a7e */ - 0x00c1, 0x00c0, 0x00c4, 0x00c2, 0x0102, 0x01cd, 0x0100, - 0x0104, 0x00c5, 0x00c3, 0x0106, 0x0108, 0x010c, 0x00c7, 0x010a, - 0x010e, 0x00c9, 0x00c8, 0x00cb, 0x00ca, 0x011a, 0x0116, 0x0112, - 0x0118, 0x0000, 0x011c, 0x011e, 0x0122, 0x0120, 0x0124, 0x00cd, - 0x00cc, 0x00cf, 0x00ce, 0x01cf, 0x0130, 0x012a, 0x012e, 0x0128, - 0x0134, 0x0136, 0x0139, 0x013d, 0x013b, 0x0143, 0x0147, 0x0145, - 0x00d1, 0x00d3, 0x00d2, 0x00d6, 0x00d4, 0x01d1, 0x0150, 0x014c, - 0x00d5, 0x0154, 0x0158, 0x0156, 0x015a, 0x015c, 0x0160, 0x015e, - 0x0164, 0x0162, 0x00da, 0x00d9, 0x00dc, 0x00db, 0x016c, 0x01d3, - 0x0170, 0x016a, 0x0172, 0x016e, 0x0168, 0x01d7, 0x01db, 0x01d9, - 0x01d5, 0x0174, 0x00dd, 0x0178, 0x0176, 0x0179, 0x017d, 0x017b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2b21 - 0x2b7e */ - 0x00e1, 0x00e0, 0x00e4, 0x00e2, 0x0103, 0x01ce, 0x0101, - 0x0105, 0x00e5, 0x00e3, 0x0107, 0x0109, 0x010d, 0x00e7, 0x010b, - 0x010f, 0x00e9, 0x00e8, 0x00eb, 0x00ea, 0x011b, 0x0117, 0x0113, - 0x0119, 0x01f5, 0x011d, 0x011f, 0x0000, 0x0121, 0x0125, 0x00ed, - 0x00ec, 0x00ef, 0x00ee, 0x01d0, 0x0000, 0x012b, 0x012f, 0x0129, - 0x0135, 0x0137, 0x013a, 0x013e, 0x013c, 0x0144, 0x0148, 0x0146, - 0x00f1, 0x00f3, 0x00f2, 0x00f6, 0x00f4, 0x01d2, 0x0151, 0x014d, - 0x00f5, 0x0155, 0x0159, 0x0157, 0x015b, 0x015d, 0x0161, 0x015f, - 0x0165, 0x0163, 0x00fa, 0x00f9, 0x00fc, 0x00fb, 0x016d, 0x01d4, - 0x0171, 0x016b, 0x0173, 0x016f, 0x0169, 0x01d8, 0x01dc, 0x01da, - 0x01d6, 0x0175, 0x00fd, 0x00ff, 0x0177, 0x017a, 0x017e, 0x017c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2c21 - 0x2c7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2d21 - 0x2d7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2e21 - 0x2e7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x2f21 - 0x2f7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x3021 - 0x307e */ - 0x4e02, 0x4e04, 0x4e05, 0x4e0c, 0x4e12, 0x4e1f, 0x4e23, - 0x4e24, 0x4e28, 0x4e2b, 0x4e2e, 0x4e2f, 0x4e30, 0x4e35, 0x4e40, - 0x4e41, 0x4e44, 0x4e47, 0x4e51, 0x4e5a, 0x4e5c, 0x4e63, 0x4e68, - 0x4e69, 0x4e74, 0x4e75, 0x4e79, 0x4e7f, 0x4e8d, 0x4e96, 0x4e97, - 0x4e9d, 0x4eaf, 0x4eb9, 0x4ec3, 0x4ed0, 0x4eda, 0x4edb, 0x4ee0, - 0x4ee1, 0x4ee2, 0x4ee8, 0x4eef, 0x4ef1, 0x4ef3, 0x4ef5, 0x4efd, - 0x4efe, 0x4eff, 0x4f00, 0x4f02, 0x4f03, 0x4f08, 0x4f0b, 0x4f0c, - 0x4f12, 0x4f15, 0x4f16, 0x4f17, 0x4f19, 0x4f2e, 0x4f31, 0x4f60, - 0x4f33, 0x4f35, 0x4f37, 0x4f39, 0x4f3b, 0x4f3e, 0x4f40, 0x4f42, - 0x4f48, 0x4f49, 0x4f4b, 0x4f4c, 0x4f52, 0x4f54, 0x4f56, 0x4f58, - 0x4f5f, 0x4f63, 0x4f6a, 0x4f6c, 0x4f6e, 0x4f71, 0x4f77, 0x4f78, - 0x4f79, 0x4f7a, 0x4f7d, 0x4f7e, 0x4f81, 0x4f82, 0x4f84, - /* 0x3121 - 0x317e */ - 0x4f85, 0x4f89, 0x4f8a, 0x4f8c, 0x4f8e, 0x4f90, 0x4f92, - 0x4f93, 0x4f94, 0x4f97, 0x4f99, 0x4f9a, 0x4f9e, 0x4f9f, 0x4fb2, - 0x4fb7, 0x4fb9, 0x4fbb, 0x4fbc, 0x4fbd, 0x4fbe, 0x4fc0, 0x4fc1, - 0x4fc5, 0x4fc6, 0x4fc8, 0x4fc9, 0x4fcb, 0x4fcc, 0x4fcd, 0x4fcf, - 0x4fd2, 0x4fdc, 0x4fe0, 0x4fe2, 0x4ff0, 0x4ff2, 0x4ffc, 0x4ffd, - 0x4fff, 0x5000, 0x5001, 0x5004, 0x5007, 0x500a, 0x500c, 0x500e, - 0x5010, 0x5013, 0x5017, 0x5018, 0x501b, 0x501c, 0x501d, 0x501e, - 0x5022, 0x5027, 0x502e, 0x5030, 0x5032, 0x5033, 0x5035, 0x5040, - 0x5041, 0x5042, 0x5045, 0x5046, 0x504a, 0x504c, 0x504e, 0x5051, - 0x5052, 0x5053, 0x5057, 0x5059, 0x505f, 0x5060, 0x5062, 0x5063, - 0x5066, 0x5067, 0x506a, 0x506d, 0x5070, 0x5071, 0x503b, 0x5081, - 0x5083, 0x5084, 0x5086, 0x508a, 0x508e, 0x508f, 0x5090, - /* 0x3221 - 0x327e */ - 0x5092, 0x5093, 0x5094, 0x5096, 0x509b, 0x509c, 0x509e, - 0x509f, 0x50a0, 0x50a1, 0x50a2, 0x50aa, 0x50af, 0x50b0, 0x50b9, - 0x50ba, 0x50bd, 0x50c0, 0x50c3, 0x50c4, 0x50c7, 0x50cc, 0x50ce, - 0x50d0, 0x50d3, 0x50d4, 0x50d8, 0x50dc, 0x50dd, 0x50df, 0x50e2, - 0x50e4, 0x50e6, 0x50e8, 0x50e9, 0x50ef, 0x50f1, 0x50f6, 0x50fa, - 0x50fe, 0x5103, 0x5106, 0x5107, 0x5108, 0x510b, 0x510c, 0x510d, - 0x510e, 0x50f2, 0x5110, 0x5117, 0x5119, 0x511b, 0x511c, 0x511d, - 0x511e, 0x5123, 0x5127, 0x5128, 0x512c, 0x512d, 0x512f, 0x5131, - 0x5133, 0x5134, 0x5135, 0x5138, 0x5139, 0x5142, 0x514a, 0x514f, - 0x5153, 0x5155, 0x5157, 0x5158, 0x515f, 0x5164, 0x5166, 0x517e, - 0x5183, 0x5184, 0x518b, 0x518e, 0x5198, 0x519d, 0x51a1, 0x51a3, - 0x51ad, 0x51b8, 0x51ba, 0x51bc, 0x51be, 0x51bf, 0x51c2, - /* 0x3321 - 0x337e */ - 0x51c8, 0x51cf, 0x51d1, 0x51d2, 0x51d3, 0x51d5, 0x51d8, - 0x51de, 0x51e2, 0x51e5, 0x51ee, 0x51f2, 0x51f3, 0x51f4, 0x51f7, - 0x5201, 0x5202, 0x5205, 0x5212, 0x5213, 0x5215, 0x5216, 0x5218, - 0x5222, 0x5228, 0x5231, 0x5232, 0x5235, 0x523c, 0x5245, 0x5249, - 0x5255, 0x5257, 0x5258, 0x525a, 0x525c, 0x525f, 0x5260, 0x5261, - 0x5266, 0x526e, 0x5277, 0x5278, 0x5279, 0x5280, 0x5282, 0x5285, - 0x528a, 0x528c, 0x5293, 0x5295, 0x5296, 0x5297, 0x5298, 0x529a, - 0x529c, 0x52a4, 0x52a5, 0x52a6, 0x52a7, 0x52af, 0x52b0, 0x52b6, - 0x52b7, 0x52b8, 0x52ba, 0x52bb, 0x52bd, 0x52c0, 0x52c4, 0x52c6, - 0x52c8, 0x52cc, 0x52cf, 0x52d1, 0x52d4, 0x52d6, 0x52db, 0x52dc, - 0x52e1, 0x52e5, 0x52e8, 0x52e9, 0x52ea, 0x52ec, 0x52f0, 0x52f1, - 0x52f4, 0x52f6, 0x52f7, 0x5300, 0x5303, 0x530a, 0x530b, - /* 0x3421 - 0x347e */ - 0x530c, 0x5311, 0x5313, 0x5318, 0x531b, 0x531c, 0x531e, - 0x531f, 0x5325, 0x5327, 0x5328, 0x5329, 0x532b, 0x532c, 0x532d, - 0x5330, 0x5332, 0x5335, 0x533c, 0x533d, 0x533e, 0x5342, 0x534c, - 0x534b, 0x5359, 0x535b, 0x5361, 0x5363, 0x5365, 0x536c, 0x536d, - 0x5372, 0x5379, 0x537e, 0x5383, 0x5387, 0x5388, 0x538e, 0x5393, - 0x5394, 0x5399, 0x539d, 0x53a1, 0x53a4, 0x53aa, 0x53ab, 0x53af, - 0x53b2, 0x53b4, 0x53b5, 0x53b7, 0x53b8, 0x53ba, 0x53bd, 0x53c0, - 0x53c5, 0x53cf, 0x53d2, 0x53d3, 0x53d5, 0x53da, 0x53dd, 0x53de, - 0x53e0, 0x53e6, 0x53e7, 0x53f5, 0x5402, 0x5413, 0x541a, 0x5421, - 0x5427, 0x5428, 0x542a, 0x542f, 0x5431, 0x5434, 0x5435, 0x5443, - 0x5444, 0x5447, 0x544d, 0x544f, 0x545e, 0x5462, 0x5464, 0x5466, - 0x5467, 0x5469, 0x546b, 0x546d, 0x546e, 0x5474, 0x547f, - /* 0x3521 - 0x357e */ - 0x5481, 0x5483, 0x5485, 0x5488, 0x5489, 0x548d, 0x5491, - 0x5495, 0x5496, 0x549c, 0x549f, 0x54a1, 0x54a6, 0x54a7, 0x54a9, - 0x54aa, 0x54ad, 0x54ae, 0x54b1, 0x54b7, 0x54b9, 0x54ba, 0x54bb, - 0x54bf, 0x54c6, 0x54ca, 0x54cd, 0x54ce, 0x54e0, 0x54ea, 0x54ec, - 0x54ef, 0x54f6, 0x54fc, 0x54fe, 0x54ff, 0x5500, 0x5501, 0x5505, - 0x5508, 0x5509, 0x550c, 0x550d, 0x550e, 0x5515, 0x552a, 0x552b, - 0x5532, 0x5535, 0x5536, 0x553b, 0x553c, 0x553d, 0x5541, 0x5547, - 0x5549, 0x554a, 0x554d, 0x5550, 0x5551, 0x5558, 0x555a, 0x555b, - 0x555e, 0x5560, 0x5561, 0x5564, 0x5566, 0x557f, 0x5581, 0x5582, - 0x5586, 0x5588, 0x558e, 0x558f, 0x5591, 0x5592, 0x5593, 0x5594, - 0x5597, 0x55a3, 0x55a4, 0x55ad, 0x55b2, 0x55bf, 0x55c1, 0x55c3, - 0x55c6, 0x55c9, 0x55cb, 0x55cc, 0x55ce, 0x55d1, 0x55d2, - /* 0x3621 - 0x367e */ - 0x55d3, 0x55d7, 0x55d8, 0x55db, 0x55de, 0x55e2, 0x55e9, - 0x55f6, 0x55ff, 0x5605, 0x5608, 0x560a, 0x560d, 0x560e, 0x560f, - 0x5610, 0x5611, 0x5612, 0x5619, 0x562c, 0x5630, 0x5633, 0x5635, - 0x5637, 0x5639, 0x563b, 0x563c, 0x563d, 0x563f, 0x5640, 0x5641, - 0x5643, 0x5644, 0x5646, 0x5649, 0x564b, 0x564d, 0x564f, 0x5654, - 0x565e, 0x5660, 0x5661, 0x5662, 0x5663, 0x5666, 0x5669, 0x566d, - 0x566f, 0x5671, 0x5672, 0x5675, 0x5684, 0x5685, 0x5688, 0x568b, - 0x568c, 0x5695, 0x5699, 0x569a, 0x569d, 0x569e, 0x569f, 0x56a6, - 0x56a7, 0x56a8, 0x56a9, 0x56ab, 0x56ac, 0x56ad, 0x56b1, 0x56b3, - 0x56b7, 0x56be, 0x56c5, 0x56c9, 0x56ca, 0x56cb, 0x56cf, 0x56d0, - 0x56cc, 0x56cd, 0x56d9, 0x56dc, 0x56dd, 0x56df, 0x56e1, 0x56e4, - 0x56e5, 0x56e6, 0x56e7, 0x56e8, 0x56f1, 0x56eb, 0x56ed, - /* 0x3721 - 0x377e */ - 0x56f6, 0x56f7, 0x5701, 0x5702, 0x5707, 0x570a, 0x570c, - 0x5711, 0x5715, 0x571a, 0x571b, 0x571d, 0x5720, 0x5722, 0x5723, - 0x5724, 0x5725, 0x5729, 0x572a, 0x572c, 0x572e, 0x572f, 0x5733, - 0x5734, 0x573d, 0x573e, 0x573f, 0x5745, 0x5746, 0x574c, 0x574d, - 0x5752, 0x5762, 0x5765, 0x5767, 0x5768, 0x576b, 0x576d, 0x576e, - 0x576f, 0x5770, 0x5771, 0x5773, 0x5774, 0x5775, 0x5777, 0x5779, - 0x577a, 0x577b, 0x577c, 0x577e, 0x5781, 0x5783, 0x578c, 0x5794, - 0x5797, 0x5799, 0x579a, 0x579c, 0x579d, 0x579e, 0x579f, 0x57a1, - 0x5795, 0x57a7, 0x57a8, 0x57a9, 0x57ac, 0x57b8, 0x57bd, 0x57c7, - 0x57c8, 0x57cc, 0x57cf, 0x57d5, 0x57dd, 0x57de, 0x57e4, 0x57e6, - 0x57e7, 0x57e9, 0x57ed, 0x57f0, 0x57f5, 0x57f6, 0x57f8, 0x57fd, - 0x57fe, 0x57ff, 0x5803, 0x5804, 0x5808, 0x5809, 0x57e1, - /* 0x3821 - 0x387e */ - 0x580c, 0x580d, 0x581b, 0x581e, 0x581f, 0x5820, 0x5826, - 0x5827, 0x582d, 0x5832, 0x5839, 0x583f, 0x5849, 0x584c, 0x584d, - 0x584f, 0x5850, 0x5855, 0x585f, 0x5861, 0x5864, 0x5867, 0x5868, - 0x5878, 0x587c, 0x587f, 0x5880, 0x5881, 0x5887, 0x5888, 0x5889, - 0x588a, 0x588c, 0x588d, 0x588f, 0x5890, 0x5894, 0x5896, 0x589d, - 0x58a0, 0x58a1, 0x58a2, 0x58a6, 0x58a9, 0x58b1, 0x58b2, 0x58c4, - 0x58bc, 0x58c2, 0x58c8, 0x58cd, 0x58ce, 0x58d0, 0x58d2, 0x58d4, - 0x58d6, 0x58da, 0x58dd, 0x58e1, 0x58e2, 0x58e9, 0x58f3, 0x5905, - 0x5906, 0x590b, 0x590c, 0x5912, 0x5913, 0x5914, 0x8641, 0x591d, - 0x5921, 0x5923, 0x5924, 0x5928, 0x592f, 0x5930, 0x5933, 0x5935, - 0x5936, 0x593f, 0x5943, 0x5946, 0x5952, 0x5953, 0x5959, 0x595b, - 0x595d, 0x595e, 0x595f, 0x5961, 0x5963, 0x596b, 0x596d, - /* 0x3921 - 0x397e */ - 0x596f, 0x5972, 0x5975, 0x5976, 0x5979, 0x597b, 0x597c, - 0x598b, 0x598c, 0x598e, 0x5992, 0x5995, 0x5997, 0x599f, 0x59a4, - 0x59a7, 0x59ad, 0x59ae, 0x59af, 0x59b0, 0x59b3, 0x59b7, 0x59ba, - 0x59bc, 0x59c1, 0x59c3, 0x59c4, 0x59c8, 0x59ca, 0x59cd, 0x59d2, - 0x59dd, 0x59de, 0x59df, 0x59e3, 0x59e4, 0x59e7, 0x59ee, 0x59ef, - 0x59f1, 0x59f2, 0x59f4, 0x59f7, 0x5a00, 0x5a04, 0x5a0c, 0x5a0d, - 0x5a0e, 0x5a12, 0x5a13, 0x5a1e, 0x5a23, 0x5a24, 0x5a27, 0x5a28, - 0x5a2a, 0x5a2d, 0x5a30, 0x5a44, 0x5a45, 0x5a47, 0x5a48, 0x5a4c, - 0x5a50, 0x5a55, 0x5a5e, 0x5a63, 0x5a65, 0x5a67, 0x5a6d, 0x5a77, - 0x5a7a, 0x5a7b, 0x5a7e, 0x5a8b, 0x5a90, 0x5a93, 0x5a96, 0x5a99, - 0x5a9c, 0x5a9e, 0x5a9f, 0x5aa0, 0x5aa2, 0x5aa7, 0x5aac, 0x5ab1, - 0x5ab2, 0x5ab3, 0x5ab5, 0x5ab8, 0x5aba, 0x5abb, 0x5abf, - /* 0x3a21 - 0x3a7e */ - 0x5ac4, 0x5ac6, 0x5ac8, 0x5acf, 0x5ada, 0x5adc, 0x5ae0, - 0x5ae5, 0x5aea, 0x5aee, 0x5af5, 0x5af6, 0x5afd, 0x5b00, 0x5b01, - 0x5b08, 0x5b17, 0x5b34, 0x5b19, 0x5b1b, 0x5b1d, 0x5b21, 0x5b25, - 0x5b2d, 0x5b38, 0x5b41, 0x5b4b, 0x5b4c, 0x5b52, 0x5b56, 0x5b5e, - 0x5b68, 0x5b6e, 0x5b6f, 0x5b7c, 0x5b7d, 0x5b7e, 0x5b7f, 0x5b81, - 0x5b84, 0x5b86, 0x5b8a, 0x5b8e, 0x5b90, 0x5b91, 0x5b93, 0x5b94, - 0x5b96, 0x5ba8, 0x5ba9, 0x5bac, 0x5bad, 0x5baf, 0x5bb1, 0x5bb2, - 0x5bb7, 0x5bba, 0x5bbc, 0x5bc0, 0x5bc1, 0x5bcd, 0x5bcf, 0x5bd6, - 0x5bd7, 0x5bd8, 0x5bd9, 0x5bda, 0x5be0, 0x5bef, 0x5bf1, 0x5bf4, - 0x5bfd, 0x5c0c, 0x5c17, 0x5c1e, 0x5c1f, 0x5c23, 0x5c26, 0x5c29, - 0x5c2b, 0x5c2c, 0x5c2e, 0x5c30, 0x5c32, 0x5c35, 0x5c36, 0x5c59, - 0x5c5a, 0x5c5c, 0x5c62, 0x5c63, 0x5c67, 0x5c68, 0x5c69, - /* 0x3b21 - 0x3b7e */ - 0x5c6d, 0x5c70, 0x5c74, 0x5c75, 0x5c7a, 0x5c7b, 0x5c7c, - 0x5c7d, 0x5c87, 0x5c88, 0x5c8a, 0x5c8f, 0x5c92, 0x5c9d, 0x5c9f, - 0x5ca0, 0x5ca2, 0x5ca3, 0x5ca6, 0x5caa, 0x5cb2, 0x5cb4, 0x5cb5, - 0x5cba, 0x5cc9, 0x5ccb, 0x5cd2, 0x5cdd, 0x5cd7, 0x5cee, 0x5cf1, - 0x5cf2, 0x5cf4, 0x5d01, 0x5d06, 0x5d0d, 0x5d12, 0x5d2b, 0x5d23, - 0x5d24, 0x5d26, 0x5d27, 0x5d31, 0x5d34, 0x5d39, 0x5d3d, 0x5d3f, - 0x5d42, 0x5d43, 0x5d46, 0x5d48, 0x5d55, 0x5d51, 0x5d59, 0x5d4a, - 0x5d5f, 0x5d60, 0x5d61, 0x5d62, 0x5d64, 0x5d6a, 0x5d6d, 0x5d70, - 0x5d79, 0x5d7a, 0x5d7e, 0x5d7f, 0x5d81, 0x5d83, 0x5d88, 0x5d8a, - 0x5d92, 0x5d93, 0x5d94, 0x5d95, 0x5d99, 0x5d9b, 0x5d9f, 0x5da0, - 0x5da7, 0x5dab, 0x5db0, 0x5db4, 0x5db8, 0x5db9, 0x5dc3, 0x5dc7, - 0x5dcb, 0x5dd0, 0x5dce, 0x5dd8, 0x5dd9, 0x5de0, 0x5de4, - /* 0x3c21 - 0x3c7e */ - 0x5de9, 0x5df8, 0x5df9, 0x5e00, 0x5e07, 0x5e0d, 0x5e12, - 0x5e14, 0x5e15, 0x5e18, 0x5e1f, 0x5e20, 0x5e2e, 0x5e28, 0x5e32, - 0x5e35, 0x5e3e, 0x5e4b, 0x5e50, 0x5e49, 0x5e51, 0x5e56, 0x5e58, - 0x5e5b, 0x5e5c, 0x5e5e, 0x5e68, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, - 0x5e6e, 0x5e70, 0x5e80, 0x5e8b, 0x5e8e, 0x5ea2, 0x5ea4, 0x5ea5, - 0x5ea8, 0x5eaa, 0x5eac, 0x5eb1, 0x5eb3, 0x5ebd, 0x5ebe, 0x5ebf, - 0x5ec6, 0x5ecc, 0x5ecb, 0x5ece, 0x5ed1, 0x5ed2, 0x5ed4, 0x5ed5, - 0x5edc, 0x5ede, 0x5ee5, 0x5eeb, 0x5f02, 0x5f06, 0x5f07, 0x5f08, - 0x5f0e, 0x5f19, 0x5f1c, 0x5f1d, 0x5f21, 0x5f22, 0x5f23, 0x5f24, - 0x5f28, 0x5f2b, 0x5f2c, 0x5f2e, 0x5f30, 0x5f34, 0x5f36, 0x5f3b, - 0x5f3d, 0x5f3f, 0x5f40, 0x5f44, 0x5f45, 0x5f47, 0x5f4d, 0x5f50, - 0x5f54, 0x5f58, 0x5f5b, 0x5f60, 0x5f63, 0x5f64, 0x5f67, - /* 0x3d21 - 0x3d7e */ - 0x5f6f, 0x5f72, 0x5f74, 0x5f75, 0x5f78, 0x5f7a, 0x5f7d, - 0x5f7e, 0x5f89, 0x5f8d, 0x5f8f, 0x5f96, 0x5f9c, 0x5f9d, 0x5fa2, - 0x5fa7, 0x5fab, 0x5fa4, 0x5fac, 0x5faf, 0x5fb0, 0x5fb1, 0x5fb8, - 0x5fc4, 0x5fc7, 0x5fc8, 0x5fc9, 0x5fcb, 0x5fd0, 0x5fd1, 0x5fd2, - 0x5fd3, 0x5fd4, 0x5fde, 0x5fe1, 0x5fe2, 0x5fe8, 0x5fe9, 0x5fea, - 0x5fec, 0x5fed, 0x5fee, 0x5fef, 0x5ff2, 0x5ff3, 0x5ff6, 0x5ffa, - 0x5ffc, 0x6007, 0x600a, 0x600d, 0x6013, 0x6014, 0x6017, 0x6018, - 0x601a, 0x601f, 0x6024, 0x602d, 0x6033, 0x6035, 0x6040, 0x6047, - 0x6048, 0x6049, 0x604c, 0x6051, 0x6054, 0x6056, 0x6057, 0x605d, - 0x6061, 0x6067, 0x6071, 0x607e, 0x607f, 0x6082, 0x6086, 0x6088, - 0x608a, 0x608e, 0x6091, 0x6093, 0x6095, 0x6098, 0x609d, 0x609e, - 0x60a2, 0x60a4, 0x60a5, 0x60a8, 0x60b0, 0x60b1, 0x60b7, - /* 0x3e21 - 0x3e7e */ - 0x60bb, 0x60be, 0x60c2, 0x60c4, 0x60c8, 0x60c9, 0x60ca, - 0x60cb, 0x60ce, 0x60cf, 0x60d4, 0x60d5, 0x60d9, 0x60db, 0x60dd, - 0x60de, 0x60e2, 0x60e5, 0x60f2, 0x60f5, 0x60f8, 0x60fc, 0x60fd, - 0x6102, 0x6107, 0x610a, 0x610c, 0x6110, 0x6111, 0x6112, 0x6113, - 0x6114, 0x6116, 0x6117, 0x6119, 0x611c, 0x611e, 0x6122, 0x612a, - 0x612b, 0x6130, 0x6131, 0x6135, 0x6136, 0x6137, 0x6139, 0x6141, - 0x6145, 0x6146, 0x6149, 0x615e, 0x6160, 0x616c, 0x6172, 0x6178, - 0x617b, 0x617c, 0x617f, 0x6180, 0x6181, 0x6183, 0x6184, 0x618b, - 0x618d, 0x6192, 0x6193, 0x6197, 0x6198, 0x619c, 0x619d, 0x619f, - 0x61a0, 0x61a5, 0x61a8, 0x61aa, 0x61ad, 0x61b8, 0x61b9, 0x61bc, - 0x61c0, 0x61c1, 0x61c2, 0x61ce, 0x61cf, 0x61d5, 0x61dc, 0x61dd, - 0x61de, 0x61df, 0x61e1, 0x61e2, 0x61e7, 0x61e9, 0x61e5, - /* 0x3f21 - 0x3f7e */ - 0x61ec, 0x61ed, 0x61ef, 0x6201, 0x6203, 0x6204, 0x6207, - 0x6213, 0x6215, 0x621c, 0x6220, 0x6222, 0x6223, 0x6227, 0x6229, - 0x622b, 0x6239, 0x623d, 0x6242, 0x6243, 0x6244, 0x6246, 0x624c, - 0x6250, 0x6251, 0x6252, 0x6254, 0x6256, 0x625a, 0x625c, 0x6264, - 0x626d, 0x626f, 0x6273, 0x627a, 0x627d, 0x628d, 0x628e, 0x628f, - 0x6290, 0x62a6, 0x62a8, 0x62b3, 0x62b6, 0x62b7, 0x62ba, 0x62be, - 0x62bf, 0x62c4, 0x62ce, 0x62d5, 0x62d6, 0x62da, 0x62ea, 0x62f2, - 0x62f4, 0x62fc, 0x62fd, 0x6303, 0x6304, 0x630a, 0x630b, 0x630d, - 0x6310, 0x6313, 0x6316, 0x6318, 0x6329, 0x632a, 0x632d, 0x6335, - 0x6336, 0x6339, 0x633c, 0x6341, 0x6342, 0x6343, 0x6344, 0x6346, - 0x634a, 0x634b, 0x634e, 0x6352, 0x6353, 0x6354, 0x6358, 0x635b, - 0x6365, 0x6366, 0x636c, 0x636d, 0x6371, 0x6374, 0x6375, - /* 0x4021 - 0x407e */ - 0x6378, 0x637c, 0x637d, 0x637f, 0x6382, 0x6384, 0x6387, - 0x638a, 0x6390, 0x6394, 0x6395, 0x6399, 0x639a, 0x639e, 0x63a4, - 0x63a6, 0x63ad, 0x63ae, 0x63af, 0x63bd, 0x63c1, 0x63c5, 0x63c8, - 0x63ce, 0x63d1, 0x63d3, 0x63d4, 0x63d5, 0x63dc, 0x63e0, 0x63e5, - 0x63ea, 0x63ec, 0x63f2, 0x63f3, 0x63f5, 0x63f8, 0x63f9, 0x6409, - 0x640a, 0x6410, 0x6412, 0x6414, 0x6418, 0x641e, 0x6420, 0x6422, - 0x6424, 0x6425, 0x6429, 0x642a, 0x642f, 0x6430, 0x6435, 0x643d, - 0x643f, 0x644b, 0x644f, 0x6451, 0x6452, 0x6453, 0x6454, 0x645a, - 0x645b, 0x645c, 0x645d, 0x645f, 0x6460, 0x6461, 0x6463, 0x646d, - 0x6473, 0x6474, 0x647b, 0x647d, 0x6485, 0x6487, 0x648f, 0x6490, - 0x6491, 0x6498, 0x6499, 0x649b, 0x649d, 0x649f, 0x64a1, 0x64a3, - 0x64a6, 0x64a8, 0x64ac, 0x64b3, 0x64bd, 0x64be, 0x64bf, - /* 0x4121 - 0x417e */ - 0x64c4, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64ce, 0x64d0, - 0x64d1, 0x64d5, 0x64d7, 0x64e4, 0x64e5, 0x64e9, 0x64ea, 0x64ed, - 0x64f0, 0x64f5, 0x64f7, 0x64fb, 0x64ff, 0x6501, 0x6504, 0x6508, - 0x6509, 0x650a, 0x650f, 0x6513, 0x6514, 0x6516, 0x6519, 0x651b, - 0x651e, 0x651f, 0x6522, 0x6526, 0x6529, 0x652e, 0x6531, 0x653a, - 0x653c, 0x653d, 0x6543, 0x6547, 0x6549, 0x6550, 0x6552, 0x6554, - 0x655f, 0x6560, 0x6567, 0x656b, 0x657a, 0x657d, 0x6581, 0x6585, - 0x658a, 0x6592, 0x6595, 0x6598, 0x659d, 0x65a0, 0x65a3, 0x65a6, - 0x65ae, 0x65b2, 0x65b3, 0x65b4, 0x65bf, 0x65c2, 0x65c8, 0x65c9, - 0x65ce, 0x65d0, 0x65d4, 0x65d6, 0x65d8, 0x65df, 0x65f0, 0x65f2, - 0x65f4, 0x65f5, 0x65f9, 0x65fe, 0x65ff, 0x6600, 0x6604, 0x6608, - 0x6609, 0x660d, 0x6611, 0x6612, 0x6615, 0x6616, 0x661d, - /* 0x4221 - 0x427e */ - 0x661e, 0x6621, 0x6622, 0x6623, 0x6624, 0x6626, 0x6629, - 0x662a, 0x662b, 0x662c, 0x662e, 0x6630, 0x6631, 0x6633, 0x6639, - 0x6637, 0x6640, 0x6645, 0x6646, 0x664a, 0x664c, 0x6651, 0x664e, - 0x6657, 0x6658, 0x6659, 0x665b, 0x665c, 0x6660, 0x6661, 0x66fb, - 0x666a, 0x666b, 0x666c, 0x667e, 0x6673, 0x6675, 0x667f, 0x6677, - 0x6678, 0x6679, 0x667b, 0x6680, 0x667c, 0x668b, 0x668c, 0x668d, - 0x6690, 0x6692, 0x6699, 0x669a, 0x669b, 0x669c, 0x669f, 0x66a0, - 0x66a4, 0x66ad, 0x66b1, 0x66b2, 0x66b5, 0x66bb, 0x66bf, 0x66c0, - 0x66c2, 0x66c3, 0x66c8, 0x66cc, 0x66ce, 0x66cf, 0x66d4, 0x66db, - 0x66df, 0x66e8, 0x66eb, 0x66ec, 0x66ee, 0x66fa, 0x6705, 0x6707, - 0x670e, 0x6713, 0x6719, 0x671c, 0x6720, 0x6722, 0x6733, 0x673e, - 0x6745, 0x6747, 0x6748, 0x674c, 0x6754, 0x6755, 0x675d, - /* 0x4321 - 0x437e */ - 0x6766, 0x676c, 0x676e, 0x6774, 0x6776, 0x677b, 0x6781, - 0x6784, 0x678e, 0x678f, 0x6791, 0x6793, 0x6796, 0x6798, 0x6799, - 0x679b, 0x67b0, 0x67b1, 0x67b2, 0x67b5, 0x67bb, 0x67bc, 0x67bd, - 0x67f9, 0x67c0, 0x67c2, 0x67c3, 0x67c5, 0x67c8, 0x67c9, 0x67d2, - 0x67d7, 0x67d9, 0x67dc, 0x67e1, 0x67e6, 0x67f0, 0x67f2, 0x67f6, - 0x67f7, 0x6852, 0x6814, 0x6819, 0x681d, 0x681f, 0x6828, 0x6827, - 0x682c, 0x682d, 0x682f, 0x6830, 0x6831, 0x6833, 0x683b, 0x683f, - 0x6844, 0x6845, 0x684a, 0x684c, 0x6855, 0x6857, 0x6858, 0x685b, - 0x686b, 0x686e, 0x686f, 0x6870, 0x6871, 0x6872, 0x6875, 0x6879, - 0x687a, 0x687b, 0x687c, 0x6882, 0x6884, 0x6886, 0x6888, 0x6896, - 0x6898, 0x689a, 0x689c, 0x68a1, 0x68a3, 0x68a5, 0x68a9, 0x68aa, - 0x68ae, 0x68b2, 0x68bb, 0x68c5, 0x68c8, 0x68cc, 0x68cf, - /* 0x4421 - 0x447e */ - 0x68d0, 0x68d1, 0x68d3, 0x68d6, 0x68d9, 0x68dc, 0x68dd, - 0x68e5, 0x68e8, 0x68ea, 0x68eb, 0x68ec, 0x68ed, 0x68f0, 0x68f1, - 0x68f5, 0x68f6, 0x68fb, 0x68fc, 0x68fd, 0x6906, 0x6909, 0x690a, - 0x6910, 0x6911, 0x6913, 0x6916, 0x6917, 0x6931, 0x6933, 0x6935, - 0x6938, 0x693b, 0x6942, 0x6945, 0x6949, 0x694e, 0x6957, 0x695b, - 0x6963, 0x6964, 0x6965, 0x6966, 0x6968, 0x6969, 0x696c, 0x6970, - 0x6971, 0x6972, 0x697a, 0x697b, 0x697f, 0x6980, 0x698d, 0x6992, - 0x6996, 0x6998, 0x69a1, 0x69a5, 0x69a6, 0x69a8, 0x69ab, 0x69ad, - 0x69af, 0x69b7, 0x69b8, 0x69ba, 0x69bc, 0x69c5, 0x69c8, 0x69d1, - 0x69d6, 0x69d7, 0x69e2, 0x69e5, 0x69ee, 0x69ef, 0x69f1, 0x69f3, - 0x69f5, 0x69fe, 0x6a00, 0x6a01, 0x6a03, 0x6a0f, 0x6a11, 0x6a15, - 0x6a1a, 0x6a1d, 0x6a20, 0x6a24, 0x6a28, 0x6a30, 0x6a32, - /* 0x4521 - 0x457e */ - 0x6a34, 0x6a37, 0x6a3b, 0x6a3e, 0x6a3f, 0x6a45, 0x6a46, - 0x6a49, 0x6a4a, 0x6a4e, 0x6a50, 0x6a51, 0x6a52, 0x6a55, 0x6a56, - 0x6a5b, 0x6a64, 0x6a67, 0x6a6a, 0x6a71, 0x6a73, 0x6a7e, 0x6a81, - 0x6a83, 0x6a86, 0x6a87, 0x6a89, 0x6a8b, 0x6a91, 0x6a9b, 0x6a9d, - 0x6a9e, 0x6a9f, 0x6aa5, 0x6aab, 0x6aaf, 0x6ab0, 0x6ab1, 0x6ab4, - 0x6abd, 0x6abe, 0x6abf, 0x6ac6, 0x6ac9, 0x6ac8, 0x6acc, 0x6ad0, - 0x6ad4, 0x6ad5, 0x6ad6, 0x6adc, 0x6add, 0x6ae4, 0x6ae7, 0x6aec, - 0x6af0, 0x6af1, 0x6af2, 0x6afc, 0x6afd, 0x6b02, 0x6b03, 0x6b06, - 0x6b07, 0x6b09, 0x6b0f, 0x6b10, 0x6b11, 0x6b17, 0x6b1b, 0x6b1e, - 0x6b24, 0x6b28, 0x6b2b, 0x6b2c, 0x6b2f, 0x6b35, 0x6b36, 0x6b3b, - 0x6b3f, 0x6b46, 0x6b4a, 0x6b4d, 0x6b52, 0x6b56, 0x6b58, 0x6b5d, - 0x6b60, 0x6b67, 0x6b6b, 0x6b6e, 0x6b70, 0x6b75, 0x6b7d, - /* 0x4621 - 0x467e */ - 0x6b7e, 0x6b82, 0x6b85, 0x6b97, 0x6b9b, 0x6b9f, 0x6ba0, - 0x6ba2, 0x6ba3, 0x6ba8, 0x6ba9, 0x6bac, 0x6bad, 0x6bae, 0x6bb0, - 0x6bb8, 0x6bb9, 0x6bbd, 0x6bbe, 0x6bc3, 0x6bc4, 0x6bc9, 0x6bcc, - 0x6bd6, 0x6bda, 0x6be1, 0x6be3, 0x6be6, 0x6be7, 0x6bee, 0x6bf1, - 0x6bf7, 0x6bf9, 0x6bff, 0x6c02, 0x6c04, 0x6c05, 0x6c09, 0x6c0d, - 0x6c0e, 0x6c10, 0x6c12, 0x6c19, 0x6c1f, 0x6c26, 0x6c27, 0x6c28, - 0x6c2c, 0x6c2e, 0x6c33, 0x6c35, 0x6c36, 0x6c3a, 0x6c3b, 0x6c3f, - 0x6c4a, 0x6c4b, 0x6c4d, 0x6c4f, 0x6c52, 0x6c54, 0x6c59, 0x6c5b, - 0x6c5c, 0x6c6b, 0x6c6d, 0x6c6f, 0x6c74, 0x6c76, 0x6c78, 0x6c79, - 0x6c7b, 0x6c85, 0x6c86, 0x6c87, 0x6c89, 0x6c94, 0x6c95, 0x6c97, - 0x6c98, 0x6c9c, 0x6c9f, 0x6cb0, 0x6cb2, 0x6cb4, 0x6cc2, 0x6cc6, - 0x6ccd, 0x6ccf, 0x6cd0, 0x6cd1, 0x6cd2, 0x6cd4, 0x6cd6, - /* 0x4721 - 0x477e */ - 0x6cda, 0x6cdc, 0x6ce0, 0x6ce7, 0x6ce9, 0x6ceb, 0x6cec, - 0x6cee, 0x6cf2, 0x6cf4, 0x6d04, 0x6d07, 0x6d0a, 0x6d0e, 0x6d0f, - 0x6d11, 0x6d13, 0x6d1a, 0x6d26, 0x6d27, 0x6d28, 0x6c67, 0x6d2e, - 0x6d2f, 0x6d31, 0x6d39, 0x6d3c, 0x6d3f, 0x6d57, 0x6d5e, 0x6d5f, - 0x6d61, 0x6d65, 0x6d67, 0x6d6f, 0x6d70, 0x6d7c, 0x6d82, 0x6d87, - 0x6d91, 0x6d92, 0x6d94, 0x6d96, 0x6d97, 0x6d98, 0x6daa, 0x6dac, - 0x6db4, 0x6db7, 0x6db9, 0x6dbd, 0x6dbf, 0x6dc4, 0x6dc8, 0x6dca, - 0x6dce, 0x6dcf, 0x6dd6, 0x6ddb, 0x6ddd, 0x6ddf, 0x6de0, 0x6de2, - 0x6de5, 0x6de9, 0x6def, 0x6df0, 0x6df4, 0x6df6, 0x6dfc, 0x6e00, - 0x6e04, 0x6e1e, 0x6e22, 0x6e27, 0x6e32, 0x6e36, 0x6e39, 0x6e3b, - 0x6e3c, 0x6e44, 0x6e45, 0x6e48, 0x6e49, 0x6e4b, 0x6e4f, 0x6e51, - 0x6e52, 0x6e53, 0x6e54, 0x6e57, 0x6e5c, 0x6e5d, 0x6e5e, - /* 0x4821 - 0x487e */ - 0x6e62, 0x6e63, 0x6e68, 0x6e73, 0x6e7b, 0x6e7d, 0x6e8d, - 0x6e93, 0x6e99, 0x6ea0, 0x6ea7, 0x6ead, 0x6eae, 0x6eb1, 0x6eb3, - 0x6ebb, 0x6ebf, 0x6ec0, 0x6ec1, 0x6ec3, 0x6ec7, 0x6ec8, 0x6eca, - 0x6ecd, 0x6ece, 0x6ecf, 0x6eeb, 0x6eed, 0x6eee, 0x6ef9, 0x6efb, - 0x6efd, 0x6f04, 0x6f08, 0x6f0a, 0x6f0c, 0x6f0d, 0x6f16, 0x6f18, - 0x6f1a, 0x6f1b, 0x6f26, 0x6f29, 0x6f2a, 0x6f2f, 0x6f30, 0x6f33, - 0x6f36, 0x6f3b, 0x6f3c, 0x6f2d, 0x6f4f, 0x6f51, 0x6f52, 0x6f53, - 0x6f57, 0x6f59, 0x6f5a, 0x6f5d, 0x6f5e, 0x6f61, 0x6f62, 0x6f68, - 0x6f6c, 0x6f7d, 0x6f7e, 0x6f83, 0x6f87, 0x6f88, 0x6f8b, 0x6f8c, - 0x6f8d, 0x6f90, 0x6f92, 0x6f93, 0x6f94, 0x6f96, 0x6f9a, 0x6f9f, - 0x6fa0, 0x6fa5, 0x6fa6, 0x6fa7, 0x6fa8, 0x6fae, 0x6faf, 0x6fb0, - 0x6fb5, 0x6fb6, 0x6fbc, 0x6fc5, 0x6fc7, 0x6fc8, 0x6fca, - /* 0x4921 - 0x497e */ - 0x6fda, 0x6fde, 0x6fe8, 0x6fe9, 0x6ff0, 0x6ff5, 0x6ff9, - 0x6ffc, 0x6ffd, 0x7000, 0x7005, 0x7006, 0x7007, 0x700d, 0x7017, - 0x7020, 0x7023, 0x702f, 0x7034, 0x7037, 0x7039, 0x703c, 0x7043, - 0x7044, 0x7048, 0x7049, 0x704a, 0x704b, 0x7054, 0x7055, 0x705d, - 0x705e, 0x704e, 0x7064, 0x7065, 0x706c, 0x706e, 0x7075, 0x7076, - 0x707e, 0x7081, 0x7085, 0x7086, 0x7094, 0x7095, 0x7096, 0x7097, - 0x7098, 0x709b, 0x70a4, 0x70ab, 0x70b0, 0x70b1, 0x70b4, 0x70b7, - 0x70ca, 0x70d1, 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d8, 0x70dc, - 0x70e4, 0x70fa, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x710b, - 0x710c, 0x710f, 0x711e, 0x7120, 0x712b, 0x712d, 0x712f, 0x7130, - 0x7131, 0x7138, 0x7141, 0x7145, 0x7146, 0x7147, 0x714a, 0x714b, - 0x7150, 0x7152, 0x7157, 0x715a, 0x715c, 0x715e, 0x7160, - /* 0x4a21 - 0x4a7e */ - 0x7168, 0x7179, 0x7180, 0x7185, 0x7187, 0x718c, 0x7192, - 0x719a, 0x719b, 0x71a0, 0x71a2, 0x71af, 0x71b0, 0x71b2, 0x71b3, - 0x71ba, 0x71bf, 0x71c0, 0x71c1, 0x71c4, 0x71cb, 0x71cc, 0x71d3, - 0x71d6, 0x71d9, 0x71da, 0x71dc, 0x71f8, 0x71fe, 0x7200, 0x7207, - 0x7208, 0x7209, 0x7213, 0x7217, 0x721a, 0x721d, 0x721f, 0x7224, - 0x722b, 0x722f, 0x7234, 0x7238, 0x7239, 0x7241, 0x7242, 0x7243, - 0x7245, 0x724e, 0x724f, 0x7250, 0x7253, 0x7255, 0x7256, 0x725a, - 0x725c, 0x725e, 0x7260, 0x7263, 0x7268, 0x726b, 0x726e, 0x726f, - 0x7271, 0x7277, 0x7278, 0x727b, 0x727c, 0x727f, 0x7284, 0x7289, - 0x728d, 0x728e, 0x7293, 0x729b, 0x72a8, 0x72ad, 0x72ae, 0x72b1, - 0x72b4, 0x72be, 0x72c1, 0x72c7, 0x72c9, 0x72cc, 0x72d5, 0x72d6, - 0x72d8, 0x72df, 0x72e5, 0x72f3, 0x72f4, 0x72fa, 0x72fb, - /* 0x4b21 - 0x4b7e */ - 0x72fe, 0x7302, 0x7304, 0x7305, 0x7307, 0x730b, 0x730d, - 0x7312, 0x7313, 0x7318, 0x7319, 0x731e, 0x7322, 0x7324, 0x7327, - 0x7328, 0x732c, 0x7331, 0x7332, 0x7335, 0x733a, 0x733b, 0x733d, - 0x7343, 0x734d, 0x7350, 0x7352, 0x7356, 0x7358, 0x735d, 0x735e, - 0x735f, 0x7360, 0x7366, 0x7367, 0x7369, 0x736b, 0x736c, 0x736e, - 0x736f, 0x7371, 0x7377, 0x7379, 0x737c, 0x7380, 0x7381, 0x7383, - 0x7385, 0x7386, 0x738e, 0x7390, 0x7393, 0x7395, 0x7397, 0x7398, - 0x739c, 0x739e, 0x739f, 0x73a0, 0x73a2, 0x73a5, 0x73a6, 0x73aa, - 0x73ab, 0x73ad, 0x73b5, 0x73b7, 0x73b9, 0x73bc, 0x73bd, 0x73bf, - 0x73c5, 0x73c6, 0x73c9, 0x73cb, 0x73cc, 0x73cf, 0x73d2, 0x73d3, - 0x73d6, 0x73d9, 0x73dd, 0x73e1, 0x73e3, 0x73e6, 0x73e7, 0x73e9, - 0x73f4, 0x73f5, 0x73f7, 0x73f9, 0x73fa, 0x73fb, 0x73fd, - /* 0x4c21 - 0x4c7e */ - 0x73ff, 0x7400, 0x7401, 0x7404, 0x7407, 0x740a, 0x7411, - 0x741a, 0x741b, 0x7424, 0x7426, 0x7428, 0x7429, 0x742a, 0x742b, - 0x742c, 0x742d, 0x742e, 0x742f, 0x7430, 0x7431, 0x7439, 0x7440, - 0x7443, 0x7444, 0x7446, 0x7447, 0x744b, 0x744d, 0x7451, 0x7452, - 0x7457, 0x745d, 0x7462, 0x7466, 0x7467, 0x7468, 0x746b, 0x746d, - 0x746e, 0x7471, 0x7472, 0x7480, 0x7481, 0x7485, 0x7486, 0x7487, - 0x7489, 0x748f, 0x7490, 0x7491, 0x7492, 0x7498, 0x7499, 0x749a, - 0x749c, 0x749f, 0x74a0, 0x74a1, 0x74a3, 0x74a6, 0x74a8, 0x74a9, - 0x74aa, 0x74ab, 0x74ae, 0x74af, 0x74b1, 0x74b2, 0x74b5, 0x74b9, - 0x74bb, 0x74bf, 0x74c8, 0x74c9, 0x74cc, 0x74d0, 0x74d3, 0x74d8, - 0x74da, 0x74db, 0x74de, 0x74df, 0x74e4, 0x74e8, 0x74ea, 0x74eb, - 0x74ef, 0x74f4, 0x74fa, 0x74fb, 0x74fc, 0x74ff, 0x7506, - /* 0x4d21 - 0x4d7e */ - 0x7512, 0x7516, 0x7517, 0x7520, 0x7521, 0x7524, 0x7527, - 0x7529, 0x752a, 0x752f, 0x7536, 0x7539, 0x753d, 0x753e, 0x753f, - 0x7540, 0x7543, 0x7547, 0x7548, 0x754e, 0x7550, 0x7552, 0x7557, - 0x755e, 0x755f, 0x7561, 0x756f, 0x7571, 0x7579, 0x757a, 0x757b, - 0x757c, 0x757d, 0x757e, 0x7581, 0x7585, 0x7590, 0x7592, 0x7593, - 0x7595, 0x7599, 0x759c, 0x75a2, 0x75a4, 0x75b4, 0x75ba, 0x75bf, - 0x75c0, 0x75c1, 0x75c4, 0x75c6, 0x75cc, 0x75ce, 0x75cf, 0x75d7, - 0x75dc, 0x75df, 0x75e0, 0x75e1, 0x75e4, 0x75e7, 0x75ec, 0x75ee, - 0x75ef, 0x75f1, 0x75f9, 0x7600, 0x7602, 0x7603, 0x7604, 0x7607, - 0x7608, 0x760a, 0x760c, 0x760f, 0x7612, 0x7613, 0x7615, 0x7616, - 0x7619, 0x761b, 0x761c, 0x761d, 0x761e, 0x7623, 0x7625, 0x7626, - 0x7629, 0x762d, 0x7632, 0x7633, 0x7635, 0x7638, 0x7639, - /* 0x4e21 - 0x4e7e */ - 0x763a, 0x763c, 0x764a, 0x7640, 0x7641, 0x7643, 0x7644, - 0x7645, 0x7649, 0x764b, 0x7655, 0x7659, 0x765f, 0x7664, 0x7665, - 0x766d, 0x766e, 0x766f, 0x7671, 0x7674, 0x7681, 0x7685, 0x768c, - 0x768d, 0x7695, 0x769b, 0x769c, 0x769d, 0x769f, 0x76a0, 0x76a2, - 0x76a3, 0x76a4, 0x76a5, 0x76a6, 0x76a7, 0x76a8, 0x76aa, 0x76ad, - 0x76bd, 0x76c1, 0x76c5, 0x76c9, 0x76cb, 0x76cc, 0x76ce, 0x76d4, - 0x76d9, 0x76e0, 0x76e6, 0x76e8, 0x76ec, 0x76f0, 0x76f1, 0x76f6, - 0x76f9, 0x76fc, 0x7700, 0x7706, 0x770a, 0x770e, 0x7712, 0x7714, - 0x7715, 0x7717, 0x7719, 0x771a, 0x771c, 0x7722, 0x7728, 0x772d, - 0x772e, 0x772f, 0x7734, 0x7735, 0x7736, 0x7739, 0x773d, 0x773e, - 0x7742, 0x7745, 0x7746, 0x774a, 0x774d, 0x774e, 0x774f, 0x7752, - 0x7756, 0x7757, 0x775c, 0x775e, 0x775f, 0x7760, 0x7762, - /* 0x4f21 - 0x4f7e */ - 0x7764, 0x7767, 0x776a, 0x776c, 0x7770, 0x7772, 0x7773, - 0x7774, 0x777a, 0x777d, 0x7780, 0x7784, 0x778c, 0x778d, 0x7794, - 0x7795, 0x7796, 0x779a, 0x779f, 0x77a2, 0x77a7, 0x77aa, 0x77ae, - 0x77af, 0x77b1, 0x77b5, 0x77be, 0x77c3, 0x77c9, 0x77d1, 0x77d2, - 0x77d5, 0x77d9, 0x77de, 0x77df, 0x77e0, 0x77e4, 0x77e6, 0x77ea, - 0x77ec, 0x77f0, 0x77f1, 0x77f4, 0x77f8, 0x77fb, 0x7805, 0x7806, - 0x7809, 0x780d, 0x780e, 0x7811, 0x781d, 0x7821, 0x7822, 0x7823, - 0x782d, 0x782e, 0x7830, 0x7835, 0x7837, 0x7843, 0x7844, 0x7847, - 0x7848, 0x784c, 0x784e, 0x7852, 0x785c, 0x785e, 0x7860, 0x7861, - 0x7863, 0x7864, 0x7868, 0x786a, 0x786e, 0x787a, 0x787e, 0x788a, - 0x788f, 0x7894, 0x7898, 0x78a1, 0x789d, 0x789e, 0x789f, 0x78a4, - 0x78a8, 0x78ac, 0x78ad, 0x78b0, 0x78b1, 0x78b2, 0x78b3, - /* 0x5021 - 0x507e */ - 0x78bb, 0x78bd, 0x78bf, 0x78c7, 0x78c8, 0x78c9, 0x78cc, - 0x78ce, 0x78d2, 0x78d3, 0x78d5, 0x78d6, 0x78e4, 0x78db, 0x78df, - 0x78e0, 0x78e1, 0x78e6, 0x78ea, 0x78f2, 0x78f3, 0x7900, 0x78f6, - 0x78f7, 0x78fa, 0x78fb, 0x78ff, 0x7906, 0x790c, 0x7910, 0x791a, - 0x791c, 0x791e, 0x791f, 0x7920, 0x7925, 0x7927, 0x7929, 0x792d, - 0x7931, 0x7934, 0x7935, 0x793b, 0x793d, 0x793f, 0x7944, 0x7945, - 0x7946, 0x794a, 0x794b, 0x794f, 0x7951, 0x7954, 0x7958, 0x795b, - 0x795c, 0x7967, 0x7969, 0x796b, 0x7972, 0x7979, 0x797b, 0x797c, - 0x797e, 0x798b, 0x798c, 0x7991, 0x7993, 0x7994, 0x7995, 0x7996, - 0x7998, 0x799b, 0x799c, 0x79a1, 0x79a8, 0x79a9, 0x79ab, 0x79af, - 0x79b1, 0x79b4, 0x79b8, 0x79bb, 0x79c2, 0x79c4, 0x79c7, 0x79c8, - 0x79ca, 0x79cf, 0x79d4, 0x79d6, 0x79da, 0x79dd, 0x79de, - /* 0x5121 - 0x517e */ - 0x79e0, 0x79e2, 0x79e5, 0x79ea, 0x79eb, 0x79ed, 0x79f1, - 0x79f8, 0x79fc, 0x7a02, 0x7a03, 0x7a07, 0x7a09, 0x7a0a, 0x7a0c, - 0x7a11, 0x7a15, 0x7a1b, 0x7a1e, 0x7a21, 0x7a27, 0x7a2b, 0x7a2d, - 0x7a2f, 0x7a30, 0x7a34, 0x7a35, 0x7a38, 0x7a39, 0x7a3a, 0x7a44, - 0x7a45, 0x7a47, 0x7a48, 0x7a4c, 0x7a55, 0x7a56, 0x7a59, 0x7a5c, - 0x7a5d, 0x7a5f, 0x7a60, 0x7a65, 0x7a67, 0x7a6a, 0x7a6d, 0x7a75, - 0x7a78, 0x7a7e, 0x7a80, 0x7a82, 0x7a85, 0x7a86, 0x7a8a, 0x7a8b, - 0x7a90, 0x7a91, 0x7a94, 0x7a9e, 0x7aa0, 0x7aa3, 0x7aac, 0x7ab3, - 0x7ab5, 0x7ab9, 0x7abb, 0x7abc, 0x7ac6, 0x7ac9, 0x7acc, 0x7ace, - 0x7ad1, 0x7adb, 0x7ae8, 0x7ae9, 0x7aeb, 0x7aec, 0x7af1, 0x7af4, - 0x7afb, 0x7afd, 0x7afe, 0x7b07, 0x7b14, 0x7b1f, 0x7b23, 0x7b27, - 0x7b29, 0x7b2a, 0x7b2b, 0x7b2d, 0x7b2e, 0x7b2f, 0x7b30, - /* 0x5221 - 0x527e */ - 0x7b31, 0x7b34, 0x7b3d, 0x7b3f, 0x7b40, 0x7b41, 0x7b47, - 0x7b4e, 0x7b55, 0x7b60, 0x7b64, 0x7b66, 0x7b69, 0x7b6a, 0x7b6d, - 0x7b6f, 0x7b72, 0x7b73, 0x7b77, 0x7b84, 0x7b89, 0x7b8e, 0x7b90, - 0x7b91, 0x7b96, 0x7b9b, 0x7b9e, 0x7ba0, 0x7ba5, 0x7bac, 0x7baf, - 0x7bb0, 0x7bb2, 0x7bb5, 0x7bb6, 0x7bba, 0x7bbb, 0x7bbc, 0x7bbd, - 0x7bc2, 0x7bc5, 0x7bc8, 0x7bca, 0x7bd4, 0x7bd6, 0x7bd7, 0x7bd9, - 0x7bda, 0x7bdb, 0x7be8, 0x7bea, 0x7bf2, 0x7bf4, 0x7bf5, 0x7bf8, - 0x7bf9, 0x7bfa, 0x7bfc, 0x7bfe, 0x7c01, 0x7c02, 0x7c03, 0x7c04, - 0x7c06, 0x7c09, 0x7c0b, 0x7c0c, 0x7c0e, 0x7c0f, 0x7c19, 0x7c1b, - 0x7c20, 0x7c25, 0x7c26, 0x7c28, 0x7c2c, 0x7c31, 0x7c33, 0x7c34, - 0x7c36, 0x7c39, 0x7c3a, 0x7c46, 0x7c4a, 0x7c55, 0x7c51, 0x7c52, - 0x7c53, 0x7c59, 0x7c5a, 0x7c5b, 0x7c5c, 0x7c5d, 0x7c5e, - /* 0x5321 - 0x537e */ - 0x7c61, 0x7c63, 0x7c67, 0x7c69, 0x7c6d, 0x7c6e, 0x7c70, - 0x7c72, 0x7c79, 0x7c7c, 0x7c7d, 0x7c86, 0x7c87, 0x7c8f, 0x7c94, - 0x7c9e, 0x7ca0, 0x7ca6, 0x7cb0, 0x7cb6, 0x7cb7, 0x7cba, 0x7cbb, - 0x7cbc, 0x7cbf, 0x7cc4, 0x7cc7, 0x7cc8, 0x7cc9, 0x7ccd, 0x7ccf, - 0x7cd3, 0x7cd4, 0x7cd5, 0x7cd7, 0x7cd9, 0x7cda, 0x7cdd, 0x7ce6, - 0x7ce9, 0x7ceb, 0x7cf5, 0x7d03, 0x7d07, 0x7d08, 0x7d09, 0x7d0f, - 0x7d11, 0x7d12, 0x7d13, 0x7d16, 0x7d1d, 0x7d1e, 0x7d23, 0x7d26, - 0x7d2a, 0x7d2d, 0x7d31, 0x7d3c, 0x7d3d, 0x7d3e, 0x7d40, 0x7d41, - 0x7d47, 0x7d48, 0x7d4d, 0x7d51, 0x7d53, 0x7d57, 0x7d59, 0x7d5a, - 0x7d5c, 0x7d5d, 0x7d65, 0x7d67, 0x7d6a, 0x7d70, 0x7d78, 0x7d7a, - 0x7d7b, 0x7d7f, 0x7d81, 0x7d82, 0x7d83, 0x7d85, 0x7d86, 0x7d88, - 0x7d8b, 0x7d8c, 0x7d8d, 0x7d91, 0x7d96, 0x7d97, 0x7d9d, - /* 0x5421 - 0x547e */ - 0x7d9e, 0x7da6, 0x7da7, 0x7daa, 0x7db3, 0x7db6, 0x7db7, - 0x7db9, 0x7dc2, 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dcc, 0x7dcd, - 0x7dce, 0x7dd7, 0x7dd9, 0x7e00, 0x7de2, 0x7de5, 0x7de6, 0x7dea, - 0x7deb, 0x7ded, 0x7df1, 0x7df5, 0x7df6, 0x7df9, 0x7dfa, 0x7e08, - 0x7e10, 0x7e11, 0x7e15, 0x7e17, 0x7e1c, 0x7e1d, 0x7e20, 0x7e27, - 0x7e28, 0x7e2c, 0x7e2d, 0x7e2f, 0x7e33, 0x7e36, 0x7e3f, 0x7e44, - 0x7e45, 0x7e47, 0x7e4e, 0x7e50, 0x7e52, 0x7e58, 0x7e5f, 0x7e61, - 0x7e62, 0x7e65, 0x7e6b, 0x7e6e, 0x7e6f, 0x7e73, 0x7e78, 0x7e7e, - 0x7e81, 0x7e86, 0x7e87, 0x7e8a, 0x7e8d, 0x7e91, 0x7e95, 0x7e98, - 0x7e9a, 0x7e9d, 0x7e9e, 0x7f3c, 0x7f3b, 0x7f3d, 0x7f3e, 0x7f3f, - 0x7f43, 0x7f44, 0x7f47, 0x7f4f, 0x7f52, 0x7f53, 0x7f5b, 0x7f5c, - 0x7f5d, 0x7f61, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f6d, - /* 0x5521 - 0x557e */ - 0x7f71, 0x7f7d, 0x7f7e, 0x7f7f, 0x7f80, 0x7f8b, 0x7f8d, - 0x7f8f, 0x7f90, 0x7f91, 0x7f96, 0x7f97, 0x7f9c, 0x7fa1, 0x7fa2, - 0x7fa6, 0x7faa, 0x7fad, 0x7fb4, 0x7fbc, 0x7fbf, 0x7fc0, 0x7fc3, - 0x7fc8, 0x7fce, 0x7fcf, 0x7fdb, 0x7fdf, 0x7fe3, 0x7fe5, 0x7fe8, - 0x7fec, 0x7fee, 0x7fef, 0x7ff2, 0x7ffa, 0x7ffd, 0x7ffe, 0x7fff, - 0x8007, 0x8008, 0x800a, 0x800d, 0x800e, 0x800f, 0x8011, 0x8013, - 0x8014, 0x8016, 0x801d, 0x801e, 0x801f, 0x8020, 0x8024, 0x8026, - 0x802c, 0x802e, 0x8030, 0x8034, 0x8035, 0x8037, 0x8039, 0x803a, - 0x803c, 0x803e, 0x8040, 0x8044, 0x8060, 0x8064, 0x8066, 0x806d, - 0x8071, 0x8075, 0x8081, 0x8088, 0x808e, 0x809c, 0x809e, 0x80a6, - 0x80a7, 0x80ab, 0x80b8, 0x80b9, 0x80c8, 0x80cd, 0x80cf, 0x80d2, - 0x80d4, 0x80d5, 0x80d7, 0x80d8, 0x80e0, 0x80ed, 0x80ee, - /* 0x5621 - 0x567e */ - 0x80f0, 0x80f2, 0x80f3, 0x80f6, 0x80f9, 0x80fa, 0x80fe, - 0x8103, 0x810b, 0x8116, 0x8117, 0x8118, 0x811c, 0x811e, 0x8120, - 0x8124, 0x8127, 0x812c, 0x8130, 0x8135, 0x813a, 0x813c, 0x8145, - 0x8147, 0x814a, 0x814c, 0x8152, 0x8157, 0x8160, 0x8161, 0x8167, - 0x8168, 0x8169, 0x816d, 0x816f, 0x8177, 0x8181, 0x8190, 0x8184, - 0x8185, 0x8186, 0x818b, 0x818e, 0x8196, 0x8198, 0x819b, 0x819e, - 0x81a2, 0x81ae, 0x81b2, 0x81b4, 0x81bb, 0x81cb, 0x81c3, 0x81c5, - 0x81ca, 0x81ce, 0x81cf, 0x81d5, 0x81d7, 0x81db, 0x81dd, 0x81de, - 0x81e1, 0x81e4, 0x81eb, 0x81ec, 0x81f0, 0x81f1, 0x81f2, 0x81f5, - 0x81f6, 0x81f8, 0x81f9, 0x81fd, 0x81ff, 0x8200, 0x8203, 0x820f, - 0x8213, 0x8214, 0x8219, 0x821a, 0x821d, 0x8221, 0x8222, 0x8228, - 0x8232, 0x8234, 0x823a, 0x8243, 0x8244, 0x8245, 0x8246, - /* 0x5721 - 0x577e */ - 0x824b, 0x824e, 0x824f, 0x8251, 0x8256, 0x825c, 0x8260, - 0x8263, 0x8267, 0x826d, 0x8274, 0x827b, 0x827d, 0x827f, 0x8280, - 0x8281, 0x8283, 0x8284, 0x8287, 0x8289, 0x828a, 0x828e, 0x8291, - 0x8294, 0x8296, 0x8298, 0x829a, 0x829b, 0x82a0, 0x82a1, 0x82a3, - 0x82a4, 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ae, 0x82b0, 0x82b2, - 0x82b4, 0x82b7, 0x82ba, 0x82bc, 0x82be, 0x82bf, 0x82c6, 0x82d0, - 0x82d5, 0x82da, 0x82e0, 0x82e2, 0x82e4, 0x82e8, 0x82ea, 0x82ed, - 0x82ef, 0x82f6, 0x82f7, 0x82fd, 0x82fe, 0x8300, 0x8301, 0x8307, - 0x8308, 0x830a, 0x830b, 0x8354, 0x831b, 0x831d, 0x831e, 0x831f, - 0x8321, 0x8322, 0x832c, 0x832d, 0x832e, 0x8330, 0x8333, 0x8337, - 0x833a, 0x833c, 0x833d, 0x8342, 0x8343, 0x8344, 0x8347, 0x834d, - 0x834e, 0x8351, 0x8355, 0x8356, 0x8357, 0x8370, 0x8378, - /* 0x5821 - 0x587e */ - 0x837d, 0x837f, 0x8380, 0x8382, 0x8384, 0x8386, 0x838d, - 0x8392, 0x8394, 0x8395, 0x8398, 0x8399, 0x839b, 0x839c, 0x839d, - 0x83a6, 0x83a7, 0x83a9, 0x83ac, 0x83be, 0x83bf, 0x83c0, 0x83c7, - 0x83c9, 0x83cf, 0x83d0, 0x83d1, 0x83d4, 0x83dd, 0x8353, 0x83e8, - 0x83ea, 0x83f6, 0x83f8, 0x83f9, 0x83fc, 0x8401, 0x8406, 0x840a, - 0x840f, 0x8411, 0x8415, 0x8419, 0x83ad, 0x842f, 0x8439, 0x8445, - 0x8447, 0x8448, 0x844a, 0x844d, 0x844f, 0x8451, 0x8452, 0x8456, - 0x8458, 0x8459, 0x845a, 0x845c, 0x8460, 0x8464, 0x8465, 0x8467, - 0x846a, 0x8470, 0x8473, 0x8474, 0x8476, 0x8478, 0x847c, 0x847d, - 0x8481, 0x8485, 0x8492, 0x8493, 0x8495, 0x849e, 0x84a6, 0x84a8, - 0x84a9, 0x84aa, 0x84af, 0x84b1, 0x84b4, 0x84ba, 0x84bd, 0x84be, - 0x84c0, 0x84c2, 0x84c7, 0x84c8, 0x84cc, 0x84cf, 0x84d3, - /* 0x5921 - 0x597e */ - 0x84dc, 0x84e7, 0x84ea, 0x84ef, 0x84f0, 0x84f1, 0x84f2, - 0x84f7, 0x8532, 0x84fa, 0x84fb, 0x84fd, 0x8502, 0x8503, 0x8507, - 0x850c, 0x850e, 0x8510, 0x851c, 0x851e, 0x8522, 0x8523, 0x8524, - 0x8525, 0x8527, 0x852a, 0x852b, 0x852f, 0x8533, 0x8534, 0x8536, - 0x853f, 0x8546, 0x854f, 0x8550, 0x8551, 0x8552, 0x8553, 0x8556, - 0x8559, 0x855c, 0x855d, 0x855e, 0x855f, 0x8560, 0x8561, 0x8562, - 0x8564, 0x856b, 0x856f, 0x8579, 0x857a, 0x857b, 0x857d, 0x857f, - 0x8581, 0x8585, 0x8586, 0x8589, 0x858b, 0x858c, 0x858f, 0x8593, - 0x8598, 0x859d, 0x859f, 0x85a0, 0x85a2, 0x85a5, 0x85a7, 0x85b4, - 0x85b6, 0x85b7, 0x85b8, 0x85bc, 0x85bd, 0x85be, 0x85bf, 0x85c2, - 0x85c7, 0x85ca, 0x85cb, 0x85ce, 0x85ad, 0x85d8, 0x85da, 0x85df, - 0x85e0, 0x85e6, 0x85e8, 0x85ed, 0x85f3, 0x85f6, 0x85fc, - /* 0x5a21 - 0x5a7e */ - 0x85ff, 0x8600, 0x8604, 0x8605, 0x860d, 0x860e, 0x8610, - 0x8611, 0x8612, 0x8618, 0x8619, 0x861b, 0x861e, 0x8621, 0x8627, - 0x8629, 0x8636, 0x8638, 0x863a, 0x863c, 0x863d, 0x8640, 0x8642, - 0x8646, 0x8652, 0x8653, 0x8656, 0x8657, 0x8658, 0x8659, 0x865d, - 0x8660, 0x8661, 0x8662, 0x8663, 0x8664, 0x8669, 0x866c, 0x866f, - 0x8675, 0x8676, 0x8677, 0x867a, 0x868d, 0x8691, 0x8696, 0x8698, - 0x869a, 0x869c, 0x86a1, 0x86a6, 0x86a7, 0x86a8, 0x86ad, 0x86b1, - 0x86b3, 0x86b4, 0x86b5, 0x86b7, 0x86b8, 0x86b9, 0x86bf, 0x86c0, - 0x86c1, 0x86c3, 0x86c5, 0x86d1, 0x86d2, 0x86d5, 0x86d7, 0x86da, - 0x86dc, 0x86e0, 0x86e3, 0x86e5, 0x86e7, 0x8688, 0x86fa, 0x86fc, - 0x86fd, 0x8704, 0x8705, 0x8707, 0x870b, 0x870e, 0x870f, 0x8710, - 0x8713, 0x8714, 0x8719, 0x871e, 0x871f, 0x8721, 0x8723, - /* 0x5b21 - 0x5b7e */ - 0x8728, 0x872e, 0x872f, 0x8731, 0x8732, 0x8739, 0x873a, - 0x873c, 0x873d, 0x873e, 0x8740, 0x8743, 0x8745, 0x874d, 0x8758, - 0x875d, 0x8761, 0x8764, 0x8765, 0x876f, 0x8771, 0x8772, 0x877b, - 0x8783, 0x8784, 0x8785, 0x8786, 0x8787, 0x8788, 0x8789, 0x878b, - 0x878c, 0x8790, 0x8793, 0x8795, 0x8797, 0x8798, 0x8799, 0x879e, - 0x87a0, 0x87a3, 0x87a7, 0x87ac, 0x87ad, 0x87ae, 0x87b1, 0x87b5, - 0x87be, 0x87bf, 0x87c1, 0x87c8, 0x87c9, 0x87ca, 0x87ce, 0x87d5, - 0x87d6, 0x87d9, 0x87da, 0x87dc, 0x87df, 0x87e2, 0x87e3, 0x87e4, - 0x87ea, 0x87eb, 0x87ed, 0x87f1, 0x87f3, 0x87f8, 0x87fa, 0x87ff, - 0x8801, 0x8803, 0x8806, 0x8809, 0x880a, 0x880b, 0x8810, 0x8819, - 0x8812, 0x8813, 0x8814, 0x8818, 0x881a, 0x881b, 0x881c, 0x881e, - 0x881f, 0x8828, 0x882d, 0x882e, 0x8830, 0x8832, 0x8835, - /* 0x5c21 - 0x5c7e */ - 0x883a, 0x883c, 0x8841, 0x8843, 0x8845, 0x8848, 0x8849, - 0x884a, 0x884b, 0x884e, 0x8851, 0x8855, 0x8856, 0x8858, 0x885a, - 0x885c, 0x885f, 0x8860, 0x8864, 0x8869, 0x8871, 0x8879, 0x887b, - 0x8880, 0x8898, 0x889a, 0x889b, 0x889c, 0x889f, 0x88a0, 0x88a8, - 0x88aa, 0x88ba, 0x88bd, 0x88be, 0x88c0, 0x88ca, 0x88cb, 0x88cc, - 0x88cd, 0x88ce, 0x88d1, 0x88d2, 0x88d3, 0x88db, 0x88de, 0x88e7, - 0x88ef, 0x88f0, 0x88f1, 0x88f5, 0x88f7, 0x8901, 0x8906, 0x890d, - 0x890e, 0x890f, 0x8915, 0x8916, 0x8918, 0x8919, 0x891a, 0x891c, - 0x8920, 0x8926, 0x8927, 0x8928, 0x8930, 0x8931, 0x8932, 0x8935, - 0x8939, 0x893a, 0x893e, 0x8940, 0x8942, 0x8945, 0x8946, 0x8949, - 0x894f, 0x8952, 0x8957, 0x895a, 0x895b, 0x895c, 0x8961, 0x8962, - 0x8963, 0x896b, 0x896e, 0x8970, 0x8973, 0x8975, 0x897a, - /* 0x5d21 - 0x5d7e */ - 0x897b, 0x897c, 0x897d, 0x8989, 0x898d, 0x8990, 0x8994, - 0x8995, 0x899b, 0x899c, 0x899f, 0x89a0, 0x89a5, 0x89b0, 0x89b4, - 0x89b5, 0x89b6, 0x89b7, 0x89bc, 0x89d4, 0x89d5, 0x89d6, 0x89d7, - 0x89d8, 0x89e5, 0x89e9, 0x89eb, 0x89ed, 0x89f1, 0x89f3, 0x89f6, - 0x89f9, 0x89fd, 0x89ff, 0x8a04, 0x8a05, 0x8a07, 0x8a0f, 0x8a11, - 0x8a12, 0x8a14, 0x8a15, 0x8a1e, 0x8a20, 0x8a22, 0x8a24, 0x8a26, - 0x8a2b, 0x8a2c, 0x8a2f, 0x8a35, 0x8a37, 0x8a3d, 0x8a3e, 0x8a40, - 0x8a43, 0x8a45, 0x8a47, 0x8a49, 0x8a4d, 0x8a4e, 0x8a53, 0x8a56, - 0x8a57, 0x8a58, 0x8a5c, 0x8a5d, 0x8a61, 0x8a65, 0x8a67, 0x8a75, - 0x8a76, 0x8a77, 0x8a79, 0x8a7a, 0x8a7b, 0x8a7e, 0x8a7f, 0x8a80, - 0x8a83, 0x8a86, 0x8a8b, 0x8a8f, 0x8a90, 0x8a92, 0x8a96, 0x8a97, - 0x8a99, 0x8a9f, 0x8aa7, 0x8aa9, 0x8aae, 0x8aaf, 0x8ab3, - /* 0x5e21 - 0x5e7e */ - 0x8ab6, 0x8ab7, 0x8abb, 0x8abe, 0x8ac3, 0x8ac6, 0x8ac8, - 0x8ac9, 0x8aca, 0x8ad1, 0x8ad3, 0x8ad4, 0x8ad5, 0x8ad7, 0x8add, - 0x8adf, 0x8aec, 0x8af0, 0x8af4, 0x8af5, 0x8af6, 0x8afc, 0x8aff, - 0x8b05, 0x8b06, 0x8b0b, 0x8b11, 0x8b1c, 0x8b1e, 0x8b1f, 0x8b0a, - 0x8b2d, 0x8b30, 0x8b37, 0x8b3c, 0x8b42, 0x8b43, 0x8b44, 0x8b45, - 0x8b46, 0x8b48, 0x8b52, 0x8b53, 0x8b54, 0x8b59, 0x8b4d, 0x8b5e, - 0x8b63, 0x8b6d, 0x8b76, 0x8b78, 0x8b79, 0x8b7c, 0x8b7e, 0x8b81, - 0x8b84, 0x8b85, 0x8b8b, 0x8b8d, 0x8b8f, 0x8b94, 0x8b95, 0x8b9c, - 0x8b9e, 0x8b9f, 0x8c38, 0x8c39, 0x8c3d, 0x8c3e, 0x8c45, 0x8c47, - 0x8c49, 0x8c4b, 0x8c4f, 0x8c51, 0x8c53, 0x8c54, 0x8c57, 0x8c58, - 0x8c5b, 0x8c5d, 0x8c59, 0x8c63, 0x8c64, 0x8c66, 0x8c68, 0x8c69, - 0x8c6d, 0x8c73, 0x8c75, 0x8c76, 0x8c7b, 0x8c7e, 0x8c86, - /* 0x5f21 - 0x5f7e */ - 0x8c87, 0x8c8b, 0x8c90, 0x8c92, 0x8c93, 0x8c99, 0x8c9b, - 0x8c9c, 0x8ca4, 0x8cb9, 0x8cba, 0x8cc5, 0x8cc6, 0x8cc9, 0x8ccb, - 0x8ccf, 0x8cd6, 0x8cd5, 0x8cd9, 0x8cdd, 0x8ce1, 0x8ce8, 0x8cec, - 0x8cef, 0x8cf0, 0x8cf2, 0x8cf5, 0x8cf7, 0x8cf8, 0x8cfe, 0x8cff, - 0x8d01, 0x8d03, 0x8d09, 0x8d12, 0x8d17, 0x8d1b, 0x8d65, 0x8d69, - 0x8d6c, 0x8d6e, 0x8d7f, 0x8d82, 0x8d84, 0x8d88, 0x8d8d, 0x8d90, - 0x8d91, 0x8d95, 0x8d9e, 0x8d9f, 0x8da0, 0x8da6, 0x8dab, 0x8dac, - 0x8daf, 0x8db2, 0x8db5, 0x8db7, 0x8db9, 0x8dbb, 0x8dc0, 0x8dc5, - 0x8dc6, 0x8dc7, 0x8dc8, 0x8dca, 0x8dce, 0x8dd1, 0x8dd4, 0x8dd5, - 0x8dd7, 0x8dd9, 0x8de4, 0x8de5, 0x8de7, 0x8dec, 0x8df0, 0x8dbc, - 0x8df1, 0x8df2, 0x8df4, 0x8dfd, 0x8e01, 0x8e04, 0x8e05, 0x8e06, - 0x8e0b, 0x8e11, 0x8e14, 0x8e16, 0x8e20, 0x8e21, 0x8e22, - /* 0x6021 - 0x607e */ - 0x8e23, 0x8e26, 0x8e27, 0x8e31, 0x8e33, 0x8e36, 0x8e37, - 0x8e38, 0x8e39, 0x8e3d, 0x8e40, 0x8e41, 0x8e4b, 0x8e4d, 0x8e4e, - 0x8e4f, 0x8e54, 0x8e5b, 0x8e5c, 0x8e5d, 0x8e5e, 0x8e61, 0x8e62, - 0x8e69, 0x8e6c, 0x8e6d, 0x8e6f, 0x8e70, 0x8e71, 0x8e79, 0x8e7a, - 0x8e7b, 0x8e82, 0x8e83, 0x8e89, 0x8e90, 0x8e92, 0x8e95, 0x8e9a, - 0x8e9b, 0x8e9d, 0x8e9e, 0x8ea2, 0x8ea7, 0x8ea9, 0x8ead, 0x8eae, - 0x8eb3, 0x8eb5, 0x8eba, 0x8ebb, 0x8ec0, 0x8ec1, 0x8ec3, 0x8ec4, - 0x8ec7, 0x8ecf, 0x8ed1, 0x8ed4, 0x8edc, 0x8ee8, 0x8eee, 0x8ef0, - 0x8ef1, 0x8ef7, 0x8ef9, 0x8efa, 0x8eed, 0x8f00, 0x8f02, 0x8f07, - 0x8f08, 0x8f0f, 0x8f10, 0x8f16, 0x8f17, 0x8f18, 0x8f1e, 0x8f20, - 0x8f21, 0x8f23, 0x8f25, 0x8f27, 0x8f28, 0x8f2c, 0x8f2d, 0x8f2e, - 0x8f34, 0x8f35, 0x8f36, 0x8f37, 0x8f3a, 0x8f40, 0x8f41, - /* 0x6121 - 0x617e */ - 0x8f43, 0x8f47, 0x8f4f, 0x8f51, 0x8f52, 0x8f53, 0x8f54, - 0x8f55, 0x8f58, 0x8f5d, 0x8f5e, 0x8f65, 0x8f9d, 0x8fa0, 0x8fa1, - 0x8fa4, 0x8fa5, 0x8fa6, 0x8fb5, 0x8fb6, 0x8fb8, 0x8fbe, 0x8fc0, - 0x8fc1, 0x8fc6, 0x8fca, 0x8fcb, 0x8fcd, 0x8fd0, 0x8fd2, 0x8fd3, - 0x8fd5, 0x8fe0, 0x8fe3, 0x8fe4, 0x8fe8, 0x8fee, 0x8ff1, 0x8ff5, - 0x8ff6, 0x8ffb, 0x8ffe, 0x9002, 0x9004, 0x9008, 0x900c, 0x9018, - 0x901b, 0x9028, 0x9029, 0x902f, 0x902a, 0x902c, 0x902d, 0x9033, - 0x9034, 0x9037, 0x903f, 0x9043, 0x9044, 0x904c, 0x905b, 0x905d, - 0x9062, 0x9066, 0x9067, 0x906c, 0x9070, 0x9074, 0x9079, 0x9085, - 0x9088, 0x908b, 0x908c, 0x908e, 0x9090, 0x9095, 0x9097, 0x9098, - 0x9099, 0x909b, 0x90a0, 0x90a1, 0x90a2, 0x90a5, 0x90b0, 0x90b2, - 0x90b3, 0x90b4, 0x90b6, 0x90bd, 0x90cc, 0x90be, 0x90c3, - /* 0x6221 - 0x627e */ - 0x90c4, 0x90c5, 0x90c7, 0x90c8, 0x90d5, 0x90d7, 0x90d8, - 0x90d9, 0x90dc, 0x90dd, 0x90df, 0x90e5, 0x90d2, 0x90f6, 0x90eb, - 0x90ef, 0x90f0, 0x90f4, 0x90fe, 0x90ff, 0x9100, 0x9104, 0x9105, - 0x9106, 0x9108, 0x910d, 0x9110, 0x9114, 0x9116, 0x9117, 0x9118, - 0x911a, 0x911c, 0x911e, 0x9120, 0x9125, 0x9122, 0x9123, 0x9127, - 0x9129, 0x912e, 0x912f, 0x9131, 0x9134, 0x9136, 0x9137, 0x9139, - 0x913a, 0x913c, 0x913d, 0x9143, 0x9147, 0x9148, 0x914f, 0x9153, - 0x9157, 0x9159, 0x915a, 0x915b, 0x9161, 0x9164, 0x9167, 0x916d, - 0x9174, 0x9179, 0x917a, 0x917b, 0x9181, 0x9183, 0x9185, 0x9186, - 0x918a, 0x918e, 0x9191, 0x9193, 0x9194, 0x9195, 0x9198, 0x919e, - 0x91a1, 0x91a6, 0x91a8, 0x91ac, 0x91ad, 0x91ae, 0x91b0, 0x91b1, - 0x91b2, 0x91b3, 0x91b6, 0x91bb, 0x91bc, 0x91bd, 0x91bf, - /* 0x6321 - 0x637e */ - 0x91c2, 0x91c3, 0x91c5, 0x91d3, 0x91d4, 0x91d7, 0x91d9, - 0x91da, 0x91de, 0x91e4, 0x91e5, 0x91e9, 0x91ea, 0x91ec, 0x91ed, - 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f7, 0x91f9, 0x91fb, 0x91fd, - 0x9200, 0x9201, 0x9204, 0x9205, 0x9206, 0x9207, 0x9209, 0x920a, - 0x920c, 0x9210, 0x9212, 0x9213, 0x9216, 0x9218, 0x921c, 0x921d, - 0x9223, 0x9224, 0x9225, 0x9226, 0x9228, 0x922e, 0x922f, 0x9230, - 0x9233, 0x9235, 0x9236, 0x9238, 0x9239, 0x923a, 0x923c, 0x923e, - 0x9240, 0x9242, 0x9243, 0x9246, 0x9247, 0x924a, 0x924d, 0x924e, - 0x924f, 0x9251, 0x9258, 0x9259, 0x925c, 0x925d, 0x9260, 0x9261, - 0x9265, 0x9267, 0x9268, 0x9269, 0x926e, 0x926f, 0x9270, 0x9275, - 0x9276, 0x9277, 0x9278, 0x9279, 0x927b, 0x927c, 0x927d, 0x927f, - 0x9288, 0x9289, 0x928a, 0x928d, 0x928e, 0x9292, 0x9297, - /* 0x6421 - 0x647e */ - 0x9299, 0x929f, 0x92a0, 0x92a4, 0x92a5, 0x92a7, 0x92a8, - 0x92ab, 0x92af, 0x92b2, 0x92b6, 0x92b8, 0x92ba, 0x92bb, 0x92bc, - 0x92bd, 0x92bf, 0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c5, 0x92c6, - 0x92c7, 0x92c8, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92d0, 0x92d3, - 0x92d5, 0x92d7, 0x92d8, 0x92d9, 0x92dc, 0x92dd, 0x92df, 0x92e0, - 0x92e1, 0x92e3, 0x92e5, 0x92e7, 0x92e8, 0x92ec, 0x92ee, 0x92f0, - 0x92f9, 0x92fb, 0x92ff, 0x9300, 0x9302, 0x9308, 0x930d, 0x9311, - 0x9314, 0x9315, 0x931c, 0x931d, 0x931e, 0x931f, 0x9321, 0x9324, - 0x9325, 0x9327, 0x9329, 0x932a, 0x9333, 0x9334, 0x9336, 0x9337, - 0x9347, 0x9348, 0x9349, 0x9350, 0x9351, 0x9352, 0x9355, 0x9357, - 0x9358, 0x935a, 0x935e, 0x9364, 0x9365, 0x9367, 0x9369, 0x936a, - 0x936d, 0x936f, 0x9370, 0x9371, 0x9373, 0x9374, 0x9376, - /* 0x6521 - 0x657e */ - 0x937a, 0x937d, 0x937f, 0x9380, 0x9381, 0x9382, 0x9388, - 0x938a, 0x938b, 0x938d, 0x938f, 0x9392, 0x9395, 0x9398, 0x939b, - 0x939e, 0x93a1, 0x93a3, 0x93a4, 0x93a6, 0x93a8, 0x93ab, 0x93b4, - 0x93b5, 0x93b6, 0x93ba, 0x93a9, 0x93c1, 0x93c4, 0x93c5, 0x93c6, - 0x93c7, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93d3, 0x93d9, - 0x93dc, 0x93de, 0x93df, 0x93e2, 0x93e6, 0x93e7, 0x93f9, 0x93f7, - 0x93f8, 0x93fa, 0x93fb, 0x93fd, 0x9401, 0x9402, 0x9404, 0x9408, - 0x9409, 0x940d, 0x940e, 0x940f, 0x9415, 0x9416, 0x9417, 0x941f, - 0x942e, 0x942f, 0x9431, 0x9432, 0x9433, 0x9434, 0x943b, 0x943f, - 0x943d, 0x9443, 0x9445, 0x9448, 0x944a, 0x944c, 0x9455, 0x9459, - 0x945c, 0x945f, 0x9461, 0x9463, 0x9468, 0x946b, 0x946d, 0x946e, - 0x946f, 0x9471, 0x9472, 0x9484, 0x9483, 0x9578, 0x9579, - /* 0x6621 - 0x667e */ - 0x957e, 0x9584, 0x9588, 0x958c, 0x958d, 0x958e, 0x959d, - 0x959e, 0x959f, 0x95a1, 0x95a6, 0x95a9, 0x95ab, 0x95ac, 0x95b4, - 0x95b6, 0x95ba, 0x95bd, 0x95bf, 0x95c6, 0x95c8, 0x95c9, 0x95cb, - 0x95d0, 0x95d1, 0x95d2, 0x95d3, 0x95d9, 0x95da, 0x95dd, 0x95de, - 0x95df, 0x95e0, 0x95e4, 0x95e6, 0x961d, 0x961e, 0x9622, 0x9624, - 0x9625, 0x9626, 0x962c, 0x9631, 0x9633, 0x9637, 0x9638, 0x9639, - 0x963a, 0x963c, 0x963d, 0x9641, 0x9652, 0x9654, 0x9656, 0x9657, - 0x9658, 0x9661, 0x966e, 0x9674, 0x967b, 0x967c, 0x967e, 0x967f, - 0x9681, 0x9682, 0x9683, 0x9684, 0x9689, 0x9691, 0x9696, 0x969a, - 0x969d, 0x969f, 0x96a4, 0x96a5, 0x96a6, 0x96a9, 0x96ae, 0x96af, - 0x96b3, 0x96ba, 0x96ca, 0x96d2, 0x5db2, 0x96d8, 0x96da, 0x96dd, - 0x96de, 0x96df, 0x96e9, 0x96ef, 0x96f1, 0x96fa, 0x9702, - /* 0x6721 - 0x677e */ - 0x9703, 0x9705, 0x9709, 0x971a, 0x971b, 0x971d, 0x9721, - 0x9722, 0x9723, 0x9728, 0x9731, 0x9733, 0x9741, 0x9743, 0x974a, - 0x974e, 0x974f, 0x9755, 0x9757, 0x9758, 0x975a, 0x975b, 0x9763, - 0x9767, 0x976a, 0x976e, 0x9773, 0x9776, 0x9777, 0x9778, 0x977b, - 0x977d, 0x977f, 0x9780, 0x9789, 0x9795, 0x9796, 0x9797, 0x9799, - 0x979a, 0x979e, 0x979f, 0x97a2, 0x97ac, 0x97ae, 0x97b1, 0x97b2, - 0x97b5, 0x97b6, 0x97b8, 0x97b9, 0x97ba, 0x97bc, 0x97be, 0x97bf, - 0x97c1, 0x97c4, 0x97c5, 0x97c7, 0x97c9, 0x97ca, 0x97cc, 0x97cd, - 0x97ce, 0x97d0, 0x97d1, 0x97d4, 0x97d7, 0x97d8, 0x97d9, 0x97dd, - 0x97de, 0x97e0, 0x97db, 0x97e1, 0x97e4, 0x97ef, 0x97f1, 0x97f4, - 0x97f7, 0x97f8, 0x97fa, 0x9807, 0x980a, 0x9819, 0x980d, 0x980e, - 0x9814, 0x9816, 0x981c, 0x981e, 0x9820, 0x9823, 0x9826, - /* 0x6821 - 0x687e */ - 0x982b, 0x982e, 0x982f, 0x9830, 0x9832, 0x9833, 0x9835, - 0x9825, 0x983e, 0x9844, 0x9847, 0x984a, 0x9851, 0x9852, 0x9853, - 0x9856, 0x9857, 0x9859, 0x985a, 0x9862, 0x9863, 0x9865, 0x9866, - 0x986a, 0x986c, 0x98ab, 0x98ad, 0x98ae, 0x98b0, 0x98b4, 0x98b7, - 0x98b8, 0x98ba, 0x98bb, 0x98bf, 0x98c2, 0x98c5, 0x98c8, 0x98cc, - 0x98e1, 0x98e3, 0x98e5, 0x98e6, 0x98e7, 0x98ea, 0x98f3, 0x98f6, - 0x9902, 0x9907, 0x9908, 0x9911, 0x9915, 0x9916, 0x9917, 0x991a, - 0x991b, 0x991c, 0x991f, 0x9922, 0x9926, 0x9927, 0x992b, 0x9931, - 0x9932, 0x9933, 0x9934, 0x9935, 0x9939, 0x993a, 0x993b, 0x993c, - 0x9940, 0x9941, 0x9946, 0x9947, 0x9948, 0x994d, 0x994e, 0x9954, - 0x9958, 0x9959, 0x995b, 0x995c, 0x995e, 0x995f, 0x9960, 0x999b, - 0x999d, 0x999f, 0x99a6, 0x99b0, 0x99b1, 0x99b2, 0x99b5, - /* 0x6921 - 0x697e */ - 0x99b9, 0x99ba, 0x99bd, 0x99bf, 0x99c3, 0x99c9, 0x99d3, - 0x99d4, 0x99d9, 0x99da, 0x99dc, 0x99de, 0x99e7, 0x99ea, 0x99eb, - 0x99ec, 0x99f0, 0x99f4, 0x99f5, 0x99f9, 0x99fd, 0x99fe, 0x9a02, - 0x9a03, 0x9a04, 0x9a0b, 0x9a0c, 0x9a10, 0x9a11, 0x9a16, 0x9a1e, - 0x9a20, 0x9a22, 0x9a23, 0x9a24, 0x9a27, 0x9a2d, 0x9a2e, 0x9a33, - 0x9a35, 0x9a36, 0x9a38, 0x9a47, 0x9a41, 0x9a44, 0x9a4a, 0x9a4b, - 0x9a4c, 0x9a4e, 0x9a51, 0x9a54, 0x9a56, 0x9a5d, 0x9aaa, 0x9aac, - 0x9aae, 0x9aaf, 0x9ab2, 0x9ab4, 0x9ab5, 0x9ab6, 0x9ab9, 0x9abb, - 0x9abe, 0x9abf, 0x9ac1, 0x9ac3, 0x9ac6, 0x9ac8, 0x9ace, 0x9ad0, - 0x9ad2, 0x9ad5, 0x9ad6, 0x9ad7, 0x9adb, 0x9adc, 0x9ae0, 0x9ae4, - 0x9ae5, 0x9ae7, 0x9ae9, 0x9aec, 0x9af2, 0x9af3, 0x9af5, 0x9af9, - 0x9afa, 0x9afd, 0x9aff, 0x9b00, 0x9b01, 0x9b02, 0x9b03, - /* 0x6a21 - 0x6a7e */ - 0x9b04, 0x9b05, 0x9b08, 0x9b09, 0x9b0b, 0x9b0c, 0x9b0d, - 0x9b0e, 0x9b10, 0x9b12, 0x9b16, 0x9b19, 0x9b1b, 0x9b1c, 0x9b20, - 0x9b26, 0x9b2b, 0x9b2d, 0x9b33, 0x9b34, 0x9b35, 0x9b37, 0x9b39, - 0x9b3a, 0x9b3d, 0x9b48, 0x9b4b, 0x9b4c, 0x9b55, 0x9b56, 0x9b57, - 0x9b5b, 0x9b5e, 0x9b61, 0x9b63, 0x9b65, 0x9b66, 0x9b68, 0x9b6a, - 0x9b6b, 0x9b6c, 0x9b6d, 0x9b6e, 0x9b73, 0x9b75, 0x9b77, 0x9b78, - 0x9b79, 0x9b7f, 0x9b80, 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b89, - 0x9b8a, 0x9b8b, 0x9b8d, 0x9b8f, 0x9b90, 0x9b94, 0x9b9a, 0x9b9d, - 0x9b9e, 0x9ba6, 0x9ba7, 0x9ba9, 0x9bac, 0x9bb0, 0x9bb1, 0x9bb2, - 0x9bb7, 0x9bb8, 0x9bbb, 0x9bbc, 0x9bbe, 0x9bbf, 0x9bc1, 0x9bc7, - 0x9bc8, 0x9bce, 0x9bd0, 0x9bd7, 0x9bd8, 0x9bdd, 0x9bdf, 0x9be5, - 0x9be7, 0x9bea, 0x9beb, 0x9bef, 0x9bf3, 0x9bf7, 0x9bf8, - /* 0x6b21 - 0x6b7e */ - 0x9bf9, 0x9bfa, 0x9bfd, 0x9bff, 0x9c00, 0x9c02, 0x9c0b, - 0x9c0f, 0x9c11, 0x9c16, 0x9c18, 0x9c19, 0x9c1a, 0x9c1c, 0x9c1e, - 0x9c22, 0x9c23, 0x9c26, 0x9c27, 0x9c28, 0x9c29, 0x9c2a, 0x9c31, - 0x9c35, 0x9c36, 0x9c37, 0x9c3d, 0x9c41, 0x9c43, 0x9c44, 0x9c45, - 0x9c49, 0x9c4a, 0x9c4e, 0x9c4f, 0x9c50, 0x9c53, 0x9c54, 0x9c56, - 0x9c58, 0x9c5b, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c63, 0x9c69, 0x9c6a, - 0x9c5c, 0x9c6b, 0x9c68, 0x9c6e, 0x9c70, 0x9c72, 0x9c75, 0x9c77, - 0x9c7b, 0x9ce6, 0x9cf2, 0x9cf7, 0x9cf9, 0x9d0b, 0x9d02, 0x9d11, - 0x9d17, 0x9d18, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d2f, 0x9d30, 0x9d32, - 0x9d33, 0x9d34, 0x9d3a, 0x9d3c, 0x9d45, 0x9d3d, 0x9d42, 0x9d43, - 0x9d47, 0x9d4a, 0x9d53, 0x9d54, 0x9d5f, 0x9d63, 0x9d62, 0x9d65, - 0x9d69, 0x9d6a, 0x9d6b, 0x9d70, 0x9d76, 0x9d77, 0x9d7b, - /* 0x6c21 - 0x6c7e */ - 0x9d7c, 0x9d7e, 0x9d83, 0x9d84, 0x9d86, 0x9d8a, 0x9d8d, - 0x9d8e, 0x9d92, 0x9d93, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9da1, - 0x9daa, 0x9dac, 0x9dae, 0x9db1, 0x9db5, 0x9db9, 0x9dbc, 0x9dbf, - 0x9dc3, 0x9dc7, 0x9dc9, 0x9dca, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, - 0x9dda, 0x9dde, 0x9ddf, 0x9de0, 0x9de5, 0x9de7, 0x9de9, 0x9deb, - 0x9dee, 0x9df0, 0x9df3, 0x9df4, 0x9dfe, 0x9e0a, 0x9e02, 0x9e07, - 0x9e0e, 0x9e10, 0x9e11, 0x9e12, 0x9e15, 0x9e16, 0x9e19, 0x9e1c, - 0x9e1d, 0x9e7a, 0x9e7b, 0x9e7c, 0x9e80, 0x9e82, 0x9e83, 0x9e84, - 0x9e85, 0x9e87, 0x9e8e, 0x9e8f, 0x9e96, 0x9e98, 0x9e9b, 0x9e9e, - 0x9ea4, 0x9ea8, 0x9eac, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb3, 0x9eb4, - 0x9eb5, 0x9ec6, 0x9ec8, 0x9ecb, 0x9ed5, 0x9edf, 0x9ee4, 0x9ee7, - 0x9eec, 0x9eed, 0x9eee, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef5, - /* 0x6d21 - 0x6d7e */ - 0x9ef8, 0x9eff, 0x9f02, 0x9f03, 0x9f09, 0x9f0f, 0x9f10, - 0x9f11, 0x9f12, 0x9f14, 0x9f16, 0x9f17, 0x9f19, 0x9f1a, 0x9f1b, - 0x9f1f, 0x9f22, 0x9f26, 0x9f2a, 0x9f2b, 0x9f2f, 0x9f31, 0x9f32, - 0x9f34, 0x9f37, 0x9f39, 0x9f3a, 0x9f3c, 0x9f3d, 0x9f3f, 0x9f41, - 0x9f43, 0x9f44, 0x9f45, 0x9f46, 0x9f47, 0x9f53, 0x9f55, 0x9f56, - 0x9f57, 0x9f58, 0x9f5a, 0x9f5d, 0x9f5e, 0x9f68, 0x9f69, 0x9f6d, - 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, 0x9f73, 0x9f75, 0x9f7a, 0x9f7d, - 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f94, 0x9f96, 0x9f97, 0x9f9e, - 0x9fa1, 0x9fa2, 0x9fa3, 0x9fa5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x6e21 - 0x6e7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x6f21 - 0x6f7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7021 - 0x707e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7121 - 0x717e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7221 - 0x727e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7321 - 0x737e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, - 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x2160, 0x2161, - /* 0x7421 - 0x747e */ - 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, - 0x2169, 0xff07, 0xff02, 0x3231, 0x2116, 0x2121, 0x70bb, 0x4efc, - 0x50f4, 0x51ec, 0x5307, 0x5324, 0xfa0e, 0x548a, 0x5759, 0xfa0f, - 0xfa10, 0x589e, 0x5bec, 0x5cf5, 0x5d53, 0xfa11, 0x5fb7, 0x6085, - 0x6120, 0x654e, 0x663b, 0x6665, 0xfa12, 0xf929, 0x6801, 0xfa13, - 0xfa14, 0x6a6b, 0x6ae2, 0x6df8, 0x6df2, 0x7028, 0xfa15, 0xfa16, - 0x7501, 0x7682, 0x769e, 0xfa17, 0x7930, 0xfa18, 0xfa19, 0xfa1a, - 0xfa1b, 0x7ae7, 0xfa1c, 0xfa1d, 0x7da0, 0x7dd6, 0xfa1e, 0x8362, - 0xfa1f, 0x85b0, 0xfa20, 0xfa21, 0x8807, 0xfa22, 0x8b7f, 0x8cf4, - 0x8d76, 0xfa23, 0xfa24, 0xfa25, 0x90de, 0xfa26, 0x9115, 0xfa27, - 0xfa28, 0x9592, 0xf9dc, 0xfa29, 0x973b, 0x974d, 0x9751, 0xfa2a, - 0xfa2b, 0xfa2c, 0x999e, 0x9ad9, 0x9b72, 0xfa2d, 0x9ed1, - /* 0x7521 - 0x757e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7621 - 0x767e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7721 - 0x777e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7821 - 0x787e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7921 - 0x797e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7a21 - 0x7a7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7b21 - 0x7b7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7c21 - 0x7c7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7d21 - 0x7d7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x7e21 - 0x7e7e */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static const uint16_t REPLACEMENT = 0xfffd; - -static inline uint16_t ValidChar(unsigned u) -{ - return u != 0 ? static_cast(u) : REPLACEMENT; -} - -static inline bool IsKana(unsigned c) -{ - return c >= 0xa1 && c <= 0xdf; -} - -static inline bool IsSjisChar1(unsigned c) -{ - return (c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc); -} - -static inline bool IsSjisChar2(unsigned c) -{ - return c >= 0x40 && c != 0x7f && c <= 0xfc; -} - -static inline bool IsUserDefinedChar1(unsigned c) -{ - return c >= 0xf0 && c <= 0xfc; -} - -static inline unsigned jisx0208ToUnicode11(unsigned h, unsigned l) -{ - if ((0x0021 <= h) && (h <= 0x007e) && (0x0021 <= l) && (l <= 0x007e)) { - return jisx0208_to_unicode[(h - 0x0021) * 0x005e + (l - 0x0021)]; - } - return 0x0000; -} - -unsigned inline jisx0208ToUnicode(unsigned h, unsigned l) -{ - if ((h == 0x21) && (l == 0x40)) { - return 0xff3c; - } - return jisx0208ToUnicode11(h, l); -} - -unsigned jisx0208ToUnicode(unsigned jis) -{ - return jisx0208ToUnicode((jis & 0xff00) >> 8, (jis & 0x00ff)); -} - -static inline unsigned jisx0212ToUnicode11(unsigned h, unsigned l) -{ - if ((0x0021 <= h) && (h <= 0x007e) && (0x0021 <= l) && (l <= 0x007e)) { - return jisx0212_to_unicode[(h - 0x0021) * 0x005e + (l - 0x0021)]; - } - return 0x0000; -} - -unsigned inline jisx0212ToUnicode(unsigned h, unsigned l) -{ - if ((h == 0x22) && (l == 0x37)) { - return 0xff5e; - } - return jisx0212ToUnicode11(h, l); -} - -/* -* This function is derived from Unicode 1.1, -* JIS X 0201 (1976) to Unicode mapping table version 0.9 . -*/ - -#define JISX0201_YEN_SIGN 0x005c -#define UNICODE_YEN_SIGN 0x00a5 - -#define JISX0201_OVERLINE 0x007e -#define UNICODE_OVERLINE 0x203e - -static inline unsigned jisx0201ToUnicode(unsigned h, unsigned l) -{ - if (h == 0) { - if (l < 0x80) { - if (l == JISX0201_YEN_SIGN) { - return UNICODE_YEN_SIGN; - } - else if (l == JISX0201_OVERLINE) { - return UNICODE_OVERLINE; - } - else { - return l; - } - } - else if ((0xa1 <= l) && (l <= 0x00df)) { - return 0xff61 + l - 0x00a1; - } - } - return 0x0000; -} - -static inline unsigned jisx0201ToUnicode(unsigned jis) -{ - return jisx0201ToUnicode((jis & 0xff00) >> 8, (jis & 0x00ff)); -} - -static unsigned sjisToJisx0208(unsigned h, unsigned l) -{ - if ((((0x81 <= h) && (h <= 0x9f)) || ((0xe0 <= h) && (h <= 0xef))) && - ((0x40 <= l) && (l != 0x7f) && (l <= 0xfc))) { - if (l < 0x9f) { - return (((h << 1) - ((h <= 0x9f) ? 0x00e1 : 0x0161)) << 8) | - (l - ((l <= 0x7f) ? 0x1f : 0x20)); - } - else { - return (((h << 1) - ((h <= 0x9f) ? 0x00e1 : 0x0161) + 1) << 8) | - (l - 0x7e); - } - } - return 0x0000; -} - -static inline unsigned sjisToUnicode(unsigned h, unsigned l) -{ - if (h == 0) { - return jisx0201ToUnicode(h, l); - } - else if (IsSjisChar1(h) && IsSjisChar2(l)) { - return jisx0208ToUnicode(sjisToJisx0208(h, l)); - } - return 0x0000; -} - -void -JPTextDecoder::AppendShiftJIS(std::vector& result, const uint8_t* bytes, size_t length) -{ - uint8_t buf[1] = { 0 }; - int nbuf = 0; -// int invalid = 0; - unsigned u = 0; - for (size_t i = 0; i= 0xa1 && c <= 0xfe; -} - -void -JPTextDecoder::AppendEUCJP(std::vector& result, const uint8_t* bytes, size_t length) -{ - static const uint8_t Ss2 = 0x8e; // Single Shift 2 - static const uint8_t Ss3 = 0x8f; // Single Shift 3 - - uint8_t buf[2] = { 0, 0 }; - int nbuf = 0; -// int invalid = 0; - - for (size_t i = 0; i -#include -#include - -class JPTextDecoder -{ -public: - static void AppendShiftJIS(std::vector& utf16, const uint8_t* bytes, size_t length); - static void AppendEUCJP(std::vector& utf16, const uint8_t* bytes, size_t length); -}; diff --git a/core/src/textcodec/JPTextEncoder.cpp b/core/src/textcodec/JPTextEncoder.cpp deleted file mode 100644 index d909ad666f..0000000000 --- a/core/src/textcodec/JPTextEncoder.cpp +++ /dev/null @@ -1,2218 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Most of the code here was originally written by Serika Kurusugawa -// a.k.a. Junji Takagi, and is included in Qt with the author's permission, -// and the grateful thanks of the Qt team. - -#include "JPTextEncoder.h" - -#include - -/* -* This data is derived from Unicode 1.1, -* JIS X 0208 (1990) to Unicode mapping table version 0.9 . -* (In addition NEC Vendor Defined Char included) -*/ -static const uint16_t unicode_to_jisx0208_00[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2140, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2171, 0x2172, 0x0000, 0x0000, 0x0000, 0x2178, 0x212f, 0x0000, 0x0000, 0x0000, 0x224c, 0x0000, 0x0000, 0x0000, - 0x216b, 0x215e, 0x0000, 0x0000, 0x212d, 0x0000, 0x2279, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x215f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2160, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_03[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627, 0x2628, 0x2629, 0x262a, 0x262b, 0x262c, 0x262d, 0x262e, 0x262f, - 0x2630, 0x2631, 0x0000, 0x2632, 0x2633, 0x2634, 0x2635, 0x2636, 0x2637, 0x2638, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, 0x2646, 0x2647, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, 0x264e, 0x264f, - 0x2650, 0x2651, 0x0000, 0x2652, 0x2653, 0x2654, 0x2655, 0x2656, 0x2657, 0x2658, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_04[256] = { - 0x0000, 0x2727, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2728, 0x2729, 0x272a, 0x272b, 0x272c, 0x272d, 0x272e, 0x272f, 0x2730, 0x2731, - 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738, 0x2739, 0x273a, 0x273b, 0x273c, 0x273d, 0x273e, 0x273f, 0x2740, 0x2741, - 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2758, 0x2759, 0x275a, 0x275b, 0x275c, 0x275d, 0x275e, 0x275f, 0x2760, 0x2761, - 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, 0x276d, 0x276e, 0x276f, 0x2770, 0x2771, - 0x0000, 0x2757, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_20[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x213e, 0x0000, 0x0000, 0x0000, 0x0000, 0x213d, 0x2142, 0x0000, 0x2146, 0x2147, 0x0000, 0x0000, 0x2148, 0x2149, 0x0000, 0x0000, - 0x2277, 0x2278, 0x0000, 0x0000, 0x0000, 0x2145, 0x2144, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2273, 0x0000, 0x216c, 0x216d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2228, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_21[256] = { - 0x0000, 0x0000, 0x0000, 0x216e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d62, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2d64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2272, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2d35, 0x2d36, 0x2d37, 0x2d38, 0x2d39, 0x2d3a, 0x2d3b, 0x2d3c, 0x2d3d, 0x2d3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x222b, 0x222c, 0x222a, 0x222d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x224d, 0x0000, 0x224e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_22[256] = { - 0x224f, 0x0000, 0x225f, 0x2250, 0x0000, 0x0000, 0x0000, 0x2260, 0x223a, 0x0000, 0x0000, 0x223b, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2d74, 0x215d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2265, 0x0000, 0x0000, 0x2267, 0x2167, 0x2d78, - 0x225c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x224a, 0x224b, 0x2241, 0x2240, 0x2269, 0x226a, 0x0000, 0x2d73, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2168, 0x2268, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2266, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2262, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2162, 0x2261, 0x0000, 0x0000, 0x0000, 0x0000, 0x2165, 0x2166, 0x0000, 0x0000, 0x2263, 0x2264, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x223e, 0x223f, 0x0000, 0x0000, 0x223c, 0x223d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x225d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d79, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_23[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x225e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_24[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, 0x2d26, 0x2d27, 0x2d28, 0x2d29, 0x2d2a, 0x2d2b, 0x2d2c, 0x2d2d, 0x2d2e, 0x2d2f, 0x2d30, - 0x2d31, 0x2d32, 0x2d33, 0x2d34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_25[256] = { - 0x2821, 0x282c, 0x2822, 0x282d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2823, 0x0000, 0x0000, 0x282e, - 0x2824, 0x0000, 0x0000, 0x282f, 0x2826, 0x0000, 0x0000, 0x2831, 0x2825, 0x0000, 0x0000, 0x2830, 0x2827, 0x283c, 0x0000, 0x0000, - 0x2837, 0x0000, 0x0000, 0x2832, 0x2829, 0x283e, 0x0000, 0x0000, 0x2839, 0x0000, 0x0000, 0x2834, 0x2828, 0x0000, 0x0000, 0x2838, - 0x283d, 0x0000, 0x0000, 0x2833, 0x282a, 0x0000, 0x0000, 0x283a, 0x283f, 0x0000, 0x0000, 0x2835, 0x282b, 0x0000, 0x0000, 0x283b, - 0x0000, 0x0000, 0x2840, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2836, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2223, 0x2222, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2225, 0x2224, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2227, 0x2226, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2221, 0x217e, 0x0000, 0x0000, 0x0000, 0x217b, 0x0000, 0x0000, 0x217d, 0x217c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x227e, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_26[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x217a, 0x2179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x216a, 0x0000, 0x2169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2276, 0x0000, 0x0000, 0x2275, 0x0000, 0x2274, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_30[256] = { - 0x2121, 0x2122, 0x2123, 0x2137, 0x0000, 0x2139, 0x213a, 0x213b, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, - 0x215a, 0x215b, 0x2229, 0x222e, 0x214c, 0x214d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2141, 0x2d60, 0x0000, 0x2d61, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, - 0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439, 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, - 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, - 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, - 0x2470, 0x2471, 0x2472, 0x2473, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x212b, 0x212c, 0x2135, 0x2136, 0x0000, - 0x0000, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, 0x252d, 0x252e, 0x252f, - 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, 0x253d, 0x253e, 0x253f, - 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, 0x254f, - 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, 0x255f, - 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, 0x256f, - 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x0000, 0x0000, 0x0000, 0x0000, 0x2126, 0x213c, 0x2133, 0x2134, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_32[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2d6a, 0x2d6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d6c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2d65, 0x2d66, 0x2d67, 0x2d68, 0x2d69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_33[256] = { - 0x0000, 0x0000, 0x0000, 0x2d46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d4a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2d41, 0x0000, 0x0000, 0x0000, 0x2d44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2d42, 0x2d4c, 0x0000, 0x0000, 0x2d4b, 0x2d45, 0x0000, 0x0000, 0x0000, 0x2d4d, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d47, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d4f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d40, 0x2d4e, 0x0000, 0x0000, 0x2d43, 0x0000, 0x0000, - 0x0000, 0x2d48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d5f, 0x2d6f, 0x2d6e, 0x2d6d, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d53, 0x2d54, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d50, 0x2d51, 0x2d52, 0x0000, - 0x0000, 0x2d56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2d55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d63, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_4e[256] = { - 0x306c, 0x437a, 0x0000, 0x3c37, 0x0000, 0x0000, 0x0000, 0x4b7c, 0x3e66, 0x3b30, 0x3e65, 0x323c, 0x0000, 0x4954, 0x4d3f, 0x0000, - 0x5022, 0x312f, 0x0000, 0x0000, 0x336e, 0x5023, 0x4024, 0x5242, 0x3556, 0x4a3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e67, 0x0000, - 0x0000, 0x4e3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a42, 0x0000, 0x0000, 0x0000, 0x5024, 0x0000, 0x0000, 0x4366, 0x0000, 0x0000, - 0x0000, 0x5025, 0x367a, 0x0000, 0x0000, 0x0000, 0x5026, 0x0000, 0x345d, 0x4330, 0x0000, 0x3c67, 0x5027, 0x0000, 0x0000, 0x5028, - 0x0000, 0x0000, 0x5029, 0x4735, 0x0000, 0x3557, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4737, 0x0000, 0x4663, 0x3843, 0x4b33, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6949, 0x502a, 0x3e68, 0x502b, 0x3235, 0x0000, 0x0000, 0x0000, 0x3665, 0x3870, 0x4c69, - 0x0000, 0x0000, 0x5626, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4d70, 0x0000, 0x467d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3425, 0x0000, - 0x3535, 0x0000, 0x502c, 0x0000, 0x0000, 0x502d, 0x4e3b, 0x0000, 0x4d3d, 0x4168, 0x502f, 0x3b76, 0x4673, 0x0000, 0x5032, 0x0000, - 0x0000, 0x313e, 0x385f, 0x0000, 0x385e, 0x3066, 0x0000, 0x0000, 0x4f4b, 0x4f4a, 0x0000, 0x3a33, 0x3021, 0x0000, 0x5033, 0x5034, - 0x5035, 0x4b34, 0x5036, 0x0000, 0x3872, 0x3067, 0x4b72, 0x0000, 0x357c, 0x0000, 0x0000, 0x357d, 0x357e, 0x4462, 0x4e3c, 0x0000, - 0x5037, 0x0000, 0x0000, 0x5038, 0x0000, 0x0000, 0x5039, 0x0000, 0x0000, 0x0000, 0x3f4d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3d3a, 0x3f4e, 0x503e, 0x0000, 0x503c, 0x0000, 0x503d, 0x3558, 0x0000, 0x0000, 0x3a23, 0x3270, 0x0000, 0x503b, 0x503a, 0x4a29, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3b46, 0x3b45, 0x423e, 0x503f, 0x4955, 0x4067, 0x0000, 0x0000, 0x0000, 0x2138, 0x5040, 0x5042, - 0x0000, 0x0000, 0x0000, 0x4265, 0x4e61, 0x304a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5041, 0x323e, 0x0000, - 0x3644, 0x0000, 0x4367, 0x0000, 0x0000, 0x0000, 0x376f, 0x5043, 0x0000, 0x0000, 0x0000, 0x4724, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_4f[256] = { - 0x0000, 0x346b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5044, 0x304b, 0x0000, 0x0000, 0x3860, 0x346c, 0x497a, - 0x4832, 0x3559, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3271, 0x0000, 0x5067, 0x4541, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x476c, - 0x5046, 0x0000, 0x0000, 0x0000, 0x483c, 0x0000, 0x4e62, 0x0000, 0x3f2d, 0x0000, 0x3b47, 0x0000, 0x3b77, 0x3240, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4451, 0x0000, 0x0000, 0x4322, 0x504a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x304c, 0x4463, 0x3d3b, - 0x3a34, 0x4d24, 0x0000, 0x424e, 0x0000, 0x323f, 0x0000, 0x5049, 0x0000, 0x4d3e, 0x5045, 0x5047, 0x3a6e, 0x5048, 0x5524, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5050, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5053, - 0x5051, 0x0000, 0x0000, 0x3242, 0x0000, 0x4a3b, 0x504b, 0x0000, 0x0000, 0x0000, 0x0000, 0x504f, 0x3873, 0x0000, 0x0000, 0x3b48, - 0x0000, 0x0000, 0x0000, 0x3426, 0x0000, 0x0000, 0x5054, 0x0000, 0x504c, 0x0000, 0x0000, 0x4e63, 0x0000, 0x3b78, 0x0000, 0x504d, - 0x0000, 0x5052, 0x0000, 0x0000, 0x0000, 0x0000, 0x5055, 0x0000, 0x504e, 0x0000, 0x0000, 0x3621, 0x0000, 0x304d, 0x0000, 0x0000, - 0x3622, 0x3241, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5525, 0x0000, 0x4b79, 0x496e, 0x3874, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f2f, 0x4e37, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a58, - 0x0000, 0x0000, 0x3738, 0x4225, 0x3264, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d53, 0x0000, 0x0000, 0x0000, 0x5059, 0x0000, - 0x505e, 0x505c, 0x0000, 0x0000, 0x5057, 0x0000, 0x0000, 0x422f, 0x505a, 0x0000, 0x505d, 0x505b, 0x0000, 0x4a5d, 0x0000, 0x5058, - 0x0000, 0x3f2e, 0x0000, 0x4b73, 0x505f, 0x5060, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d24, 0x506d, - 0x0000, 0x0000, 0x0000, 0x4750, 0x0000, 0x4936, 0x5068, 0x0000, 0x4a70, 0x0000, 0x3236, 0x0000, 0x0000, 0x0000, 0x506c, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_50[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5066, 0x506f, 0x0000, 0x0000, 0x4152, 0x0000, 0x3844, 0x0000, 0x475c, 0x0000, 0x6047, - 0x0000, 0x506e, 0x455d, 0x0000, 0x5063, 0x0000, 0x3876, 0x0000, 0x0000, 0x3875, 0x5061, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c5a, - 0x0000, 0x5069, 0x0000, 0x4a6f, 0x434d, 0x5065, 0x3771, 0x0000, 0x5062, 0x506a, 0x5064, 0x4e51, 0x506b, 0x4f41, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3666, 0x0000, 0x0000, 0x3770, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5070, 0x0000, 0x0000, 0x0000, 0x5071, 0x5075, 0x304e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a50, - 0x5074, 0x0000, 0x0000, 0x0000, 0x0000, 0x5073, 0x5077, 0x0000, 0x0000, 0x0000, 0x5076, 0x0000, 0x4464, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3772, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5078, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3c45, 0x0000, 0x4226, 0x4465, 0x3676, 0x0000, 0x5079, 0x0000, 0x0000, 0x0000, 0x0000, 0x3536, 0x0000, 0x0000, - 0x507a, 0x0000, 0x0000, 0x0000, 0x0000, 0x507c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b35, 0x0000, 0x0000, - 0x0000, 0x3766, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b31, 0x4877, 0x507b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a45, 0x4d43, 0x0000, 0x0000, - 0x0000, 0x0000, 0x507e, 0x5123, 0x507d, 0x3a44, 0x0000, 0x3d7d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3739, 0x0000, - 0x0000, 0x0000, 0x5124, 0x0000, 0x0000, 0x364f, 0x0000, 0x0000, 0x0000, 0x5121, 0x5122, 0x0000, 0x0000, 0x462f, 0x0000, 0x417c, - 0x0000, 0x3623, 0x0000, 0x0000, 0x0000, 0x4b4d, 0x5125, 0x0000, 0x0000, 0x0000, 0x4e3d, 0x0000, 0x0000, 0x0000, 0x5126, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5129, 0x0000, 0x5127, 0x0000, 0x414e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5128, 0x512a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x512c, 0x0000, 0x0000, 0x0000, 0x512b, 0x0000, 0x4a48, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_51[256] = { - 0x3537, 0x512e, 0x512f, 0x0000, 0x322f, 0x0000, 0x0000, 0x0000, 0x0000, 0x512d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3c74, 0x0000, 0x5132, 0x5131, 0x5130, 0x0000, 0x5056, 0x0000, 0x5133, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d7e, - 0x0000, 0x5134, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4c59, 0x0000, 0x0000, 0x0000, 0x0000, 0x5136, 0x0000, 0x0000, 0x5135, 0x5138, 0x5137, 0x0000, 0x0000, 0x5139, - 0x513a, 0x3074, 0x0000, 0x3835, 0x373b, 0x3d3c, 0x437b, 0x3624, 0x4068, 0x3877, 0x0000, 0x396e, 0x513c, 0x4c48, 0x4546, 0x0000, - 0x3b79, 0x0000, 0x513b, 0x0000, 0x513d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x455e, 0x0000, 0x3375, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x513e, 0x0000, 0x0000, 0x467e, 0x0000, 0x0000, 0x4134, 0x5140, 0x5141, 0x482c, 0x3878, 0x4f3b, 0x5142, 0x0000, - 0x0000, 0x3626, 0x0000, 0x0000, 0x0000, 0x4a3c, 0x4236, 0x3671, 0x4535, 0x0000, 0x0000, 0x0000, 0x3773, 0x0000, 0x0000, 0x0000, - 0x5143, 0x0000, 0x5144, 0x0000, 0x0000, 0x4662, 0x315f, 0x0000, 0x0000, 0x5147, 0x3a7d, 0x0000, 0x5146, 0x3a46, 0x0000, 0x5148, - 0x666e, 0x5149, 0x4b41, 0x514a, 0x0000, 0x514b, 0x514c, 0x3e69, 0x0000, 0x3c4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3427, 0x0000, 0x514f, 0x0000, 0x514d, 0x4c3d, 0x514e, 0x0000, 0x495a, 0x5150, 0x5151, 0x5152, 0x455f, 0x0000, 0x0000, 0x0000, - 0x5156, 0x5154, 0x5155, 0x5153, 0x3a63, 0x5157, 0x4c6a, 0x4e64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5158, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4028, 0x5159, 0x3d5a, 0x0000, 0x0000, 0x515a, 0x0000, 0x437c, 0x4e3f, 0x4560, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5245, 0x0000, 0x0000, 0x0000, 0x0000, 0x515b, 0x7425, 0x3645, 0x0000, 0x0000, - 0x515c, 0x4b5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d68, 0x427c, 0x0000, 0x515e, 0x4664, 0x0000, 0x0000, 0x515f, 0x0000, 0x0000, - 0x5160, 0x332e, 0x0000, 0x0000, 0x0000, 0x5161, 0x3627, 0x0000, 0x464c, 0x317a, 0x3d50, 0x0000, 0x0000, 0x4821, 0x5162, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_52[256] = { - 0x4561, 0x0000, 0x0000, 0x3f4f, 0x5163, 0x0000, 0x4a2c, 0x405a, 0x3422, 0x0000, 0x3429, 0x5164, 0x0000, 0x0000, 0x5166, 0x0000, - 0x0000, 0x373a, 0x0000, 0x0000, 0x5165, 0x0000, 0x0000, 0x4e73, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d69, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x483d, 0x4a4c, 0x0000, 0x5167, 0x0000, 0x4d78, 0x5168, 0x0000, 0x0000, 0x0000, 0x5169, 0x0000, - 0x457e, 0x0000, 0x0000, 0x516a, 0x0000, 0x0000, 0x4029, 0x3a7e, 0x3774, 0x516b, 0x3b49, 0x396f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4466, 0x516d, 0x0000, 0x0000, 0x4227, 0x0000, 0x0000, 0x3a6f, 0x516e, 0x516f, 0x4130, 0x0000, 0x516c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5171, 0x0000, 0x4b36, 0x0000, 0x0000, 0x0000, 0x0000, 0x3964, 0x0000, 0x0000, 0x5170, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3775, 0x3a5e, 0x476d, 0x0000, 0x0000, 0x0000, 0x5174, 0x5172, 0x0000, 0x0000, 0x0000, 0x0000, 0x497b, - 0x3e6a, 0x517b, 0x3364, 0x5175, 0x5173, 0x414f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5177, 0x0000, 0x5176, - 0x0000, 0x0000, 0x0000, 0x3344, 0x0000, 0x0000, 0x0000, 0x3760, 0x517c, 0x4e2d, 0x0000, 0x0000, 0x0000, 0x5178, 0x0000, 0x0000, - 0x0000, 0x517d, 0x517a, 0x0000, 0x5179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e4f, 0x0000, 0x0000, 0x0000, 0x3879, - 0x3243, 0x0000, 0x0000, 0x4e74, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d75, 0x4558, 0x3965, 0x5222, 0x5223, 0x0000, 0x0000, - 0x0000, 0x4e65, 0x0000, 0x0000, 0x4f2b, 0x5225, 0x0000, 0x0000, 0x0000, 0x387a, 0x0000, 0x0000, 0x5224, 0x0000, 0x332f, 0x0000, - 0x0000, 0x5226, 0x0000, 0x4b56, 0x0000, 0x443c, 0x0000, 0x4d26, 0x0000, 0x4a59, 0x0000, 0x0000, 0x0000, 0x5227, 0x0000, 0x0000, - 0x0000, 0x0000, 0x7055, 0x0000, 0x0000, 0x4630, 0x0000, 0x5228, 0x342a, 0x4c33, 0x0000, 0x0000, 0x0000, 0x3e21, 0x5229, 0x4a67, - 0x522d, 0x0000, 0x402a, 0x522a, 0x3650, 0x0000, 0x522b, 0x342b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x372e, 0x522e, 0x0000, 0x522f, 0x0000, 0x0000, 0x5230, 0x5231, 0x3c5b, 0x0000, 0x0000, 0x0000, 0x387b, 0x4c5e, -}; - -static const uint16_t unicode_to_jisx0208_53[256] = { - 0x0000, 0x4c68, 0x4677, 0x0000, 0x0000, 0x4a71, 0x5232, 0x0000, 0x5233, 0x0000, 0x0000, 0x0000, 0x0000, 0x5235, 0x0000, 0x5237, - 0x5236, 0x0000, 0x0000, 0x0000, 0x0000, 0x5238, 0x323d, 0x4b4c, 0x0000, 0x3a7c, 0x5239, 0x0000, 0x0000, 0x4159, 0x0000, 0x0000, - 0x3e22, 0x3629, 0x0000, 0x523a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x485b, 0x0000, 0x0000, 0x0000, 0x0000, 0x523b, - 0x0000, 0x523c, 0x0000, 0x523d, 0x0000, 0x0000, 0x0000, 0x0000, 0x523e, 0x4924, 0x3668, 0x3065, 0x0000, 0x0000, 0x0000, 0x463f, - 0x523f, 0x3d3d, 0x0000, 0x4069, 0x0000, 0x5241, 0x5240, 0x3e23, 0x3861, 0x5243, 0x483e, 0x0000, 0x0000, 0x5244, 0x0000, 0x0000, - 0x0000, 0x485c, 0x4234, 0x426e, 0x3628, 0x0000, 0x0000, 0x466e, 0x4331, 0x0000, 0x476e, 0x0000, 0x4b4e, 0x0000, 0x5246, 0x0000, - 0x406a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3735, 0x0000, 0x0000, 0x5247, 0x0000, 0x0000, 0x0000, 0x0000, 0x5248, 0x312c, - 0x3075, 0x346d, 0x0000, 0x4228, 0x3551, 0x4d71, 0x0000, 0x524b, 0x3237, 0x0000, 0x0000, 0x524a, 0x0000, 0x0000, 0x0000, 0x362a, - 0x0000, 0x0000, 0x524c, 0x0000, 0x4c71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x524d, 0x0000, 0x4e52, 0x0000, 0x387c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3836, - 0x524e, 0x0000, 0x0000, 0x0000, 0x0000, 0x5250, 0x524f, 0x0000, 0x3f5f, 0x3139, 0x0000, 0x0000, 0x0000, 0x315e, 0x5251, 0x0000, - 0x5252, 0x0000, 0x0000, 0x3837, 0x0000, 0x0000, 0x5253, 0x0000, 0x0000, 0x0000, 0x0000, 0x356e, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3b32, 0x5254, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b74, 0x3a35, 0x355a, 0x4d27, 0x4150, 0x483f, 0x3c7d, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3d47, 0x0000, 0x3c68, 0x3c75, 0x0000, 0x3d76, 0x0000, 0x4840, 0x0000, 0x0000, 0x0000, 0x5257, - 0x0000, 0x3143, 0x4151, 0x387d, 0x3845, 0x3667, 0x0000, 0x0000, 0x525b, 0x4321, 0x427e, 0x362b, 0x3e24, 0x525c, 0x525a, 0x3244, - 0x4266, 0x3c38, 0x3b4b, 0x3126, 0x0000, 0x0000, 0x3370, 0x3966, 0x3b4a, 0x0000, 0x525d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_54[256] = { - 0x0000, 0x525e, 0x0000, 0x3549, 0x3346, 0x0000, 0x0000, 0x0000, 0x3967, 0x3548, 0x445f, 0x3125, 0x4631, 0x4c3e, 0x3921, 0x4d79, - 0x4547, 0x387e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x372f, 0x0000, 0x5267, 0x0000, 0x3663, - 0x4b4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x485d, 0x0000, 0x0000, 0x5266, 0x0000, 0x345e, 0x5261, 0x5262, 0x5264, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5265, 0x0000, 0x355b, 0x3f61, 0x0000, 0x4a2d, 0x5263, 0x525f, 0x3863, 0x0000, - 0x5260, 0x0000, 0x4f24, 0x0000, 0x0000, 0x0000, 0x4a72, 0x0000, 0x4468, 0x3862, 0x3970, 0x0000, 0x0000, 0x0000, 0x5268, 0x0000, - 0x0000, 0x465d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x526c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c7e, 0x0000, 0x3c76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x526f, 0x526d, 0x0000, 0x4c23, 0x0000, 0x526a, 0x5273, 0x526e, 0x0000, 0x0000, 0x0000, 0x5271, 0x3846, 0x4c3f, 0x0000, 0x0000, - 0x5272, 0x0000, 0x0000, 0x0000, 0x5274, 0x0000, 0x5276, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a70, 0x4f42, 0x0000, 0x526b, 0x5269, - 0x5275, 0x0000, 0x5270, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5278, 0x0000, 0x5323, 0x527a, 0x0000, 0x0000, 0x527e, 0x0000, 0x0000, 0x5321, 0x527b, 0x0000, 0x0000, 0x533e, - 0x0000, 0x0000, 0x3a69, 0x3331, 0x0000, 0x0000, 0x0000, 0x0000, 0x5279, 0x0000, 0x0000, 0x0000, 0x5325, 0x3076, 0x5324, 0x0000, - 0x3025, 0x494a, 0x5322, 0x0000, 0x527c, 0x0000, 0x0000, 0x5277, 0x527d, 0x3a48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5326, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3077, 0x532f, 0x0000, 0x0000, 0x5327, 0x5328, 0x0000, 0x3e25, 0x4b69, 0x0000, 0x0000, 0x0000, 0x532d, 0x532c, 0x0000, - 0x0000, 0x0000, 0x452f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x532e, 0x0000, 0x0000, 0x532b, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_55[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x3134, 0x0000, 0x3a36, 0x3f30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5329, - 0x4562, 0x0000, 0x0000, 0x0000, 0x532a, 0x0000, 0x3022, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5334, 0x4d23, - 0x0000, 0x3e27, 0x0000, 0x533a, 0x0000, 0x0000, 0x0000, 0x0000, 0x5339, 0x5330, 0x0000, 0x0000, 0x0000, 0x0000, 0x4243, 0x0000, - 0x5331, 0x0000, 0x0000, 0x0000, 0x426f, 0x5336, 0x3e26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5333, 0x0000, 0x0000, 0x4c64, - 0x0000, 0x0000, 0x0000, 0x373c, 0x0000, 0x0000, 0x5337, 0x5338, 0x0000, 0x0000, 0x0000, 0x0000, 0x5335, 0x533b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5332, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5341, 0x5346, 0x0000, 0x5342, 0x0000, - 0x533d, 0x0000, 0x0000, 0x5347, 0x4131, 0x0000, 0x0000, 0x5349, 0x0000, 0x3922, 0x533f, 0x437d, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5343, 0x533c, 0x342d, 0x0000, 0x346e, 0x3365, 0x5344, 0x5340, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3776, 0x534a, 0x5348, 0x4153, 0x354a, 0x362c, 0x0000, 0x5345, 0x0000, - 0x3674, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3144, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x534e, 0x534c, 0x0000, 0x5427, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5351, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x534b, 0x0000, 0x534f, 0x0000, 0x0000, 0x534d, - 0x0000, 0x0000, 0x0000, 0x3b4c, 0x5350, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5353, 0x0000, 0x5358, 0x0000, 0x0000, 0x0000, 0x5356, 0x5355, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_56[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4332, 0x0000, 0x0000, 0x3245, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5352, 0x0000, 0x5354, 0x3e28, 0x3133, 0x0000, 0x0000, 0x5357, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x325e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5362, - 0x0000, 0x3e7c, 0x535e, 0x0000, 0x535c, 0x0000, 0x535d, 0x0000, 0x535f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x313d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4139, 0x0000, 0x5359, 0x0000, - 0x535a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x337a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5361, 0x0000, 0x0000, 0x0000, 0x346f, 0x0000, 0x5364, 0x5360, 0x5363, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4a2e, 0x0000, 0x0000, 0x0000, 0x4655, 0x0000, 0x4838, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5366, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5365, 0x3345, 0x0000, 0x0000, 0x5367, 0x0000, 0x0000, 0x0000, 0x0000, 0x536a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5369, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5368, 0x0000, 0x4739, 0x0000, 0x0000, 0x536b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x536c, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x536e, 0x0000, 0x536d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5370, 0x0000, 0x0000, 0x0000, - 0x5373, 0x5371, 0x536f, 0x5372, 0x0000, 0x0000, 0x0000, 0x0000, 0x5374, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5375, 0x0000, - 0x0000, 0x5376, 0x0000, 0x5377, 0x0000, 0x0000, 0x0000, 0x5378, 0x5145, 0x0000, 0x3c7c, 0x3b4d, 0x0000, 0x0000, 0x3273, 0x0000, - 0x3078, 0x0000, 0x0000, 0x4344, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5379, 0x0000, - 0x3a24, 0x0000, 0x304f, 0x3f5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x537a, 0x3847, 0x0000, 0x0000, 0x3971, 0x0000, 0x537c, -}; - -static const uint16_t unicode_to_jisx0208_57[256] = { - 0x537b, 0x0000, 0x0000, 0x4a60, 0x537d, 0x0000, 0x0000, 0x0000, 0x5421, 0x537e, 0x0000, 0x5422, 0x0000, 0x5423, 0x0000, 0x3777, - 0x0000, 0x0000, 0x3160, 0x5424, 0x0000, 0x0000, 0x5426, 0x0000, 0x5425, 0x0000, 0x0000, 0x0000, 0x5428, 0x0000, 0x0000, 0x455a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5429, 0x3035, 0x3a5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x373d, 0x0000, 0x0000, - 0x434f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x542a, 0x542b, 0x0000, 0x0000, 0x542d, 0x0000, 0x0000, 0x0000, 0x0000, - 0x542e, 0x0000, 0x3a64, 0x0000, 0x0000, 0x0000, 0x0000, 0x3651, 0x0000, 0x0000, 0x4b37, 0x0000, 0x0000, 0x0000, 0x542c, 0x542f, - 0x3a41, 0x3923, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5433, 0x0000, 0x0000, 0x3a25, 0x0000, 0x4333, 0x0000, 0x0000, 0x5430, 0x445a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5434, - 0x0000, 0x0000, 0x3f62, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5432, 0x5435, 0x0000, 0x373f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5436, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5437, 0x0000, 0x3924, 0x3340, 0x5439, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x543a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x543b, 0x0000, 0x0000, 0x5438, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5431, 0x0000, 0x0000, 0x543c, 0x0000, 0x0000, 0x543d, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b64, 0x0000, 0x0000, 0x3e6b, 0x0000, - 0x0000, 0x0000, 0x543f, 0x5440, 0x543e, 0x0000, 0x5442, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4738, 0x0000, 0x0000, 0x3068, - 0x4956, 0x0000, 0x0000, 0x5443, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3e7d, 0x0000, 0x0000, 0x3c39, 0x0000, 0x475d, 0x3470, 0x0000, 0x3a6b, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_58[256] = { - 0x4b59, 0x0000, 0x4632, 0x0000, 0x0000, 0x3778, 0x424f, 0x0000, 0x0000, 0x0000, 0x5441, 0x5444, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4244, 0x0000, 0x0000, 0x0000, 0x5445, 0x0000, 0x0000, 0x0000, 0x5446, 0x0000, 0x0000, - 0x0000, 0x5448, 0x0000, 0x0000, 0x4469, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x342e, 0x0000, 0x0000, 0x0000, 0x0000, 0x7421, - 0x3161, 0x4a73, 0x0000, 0x0000, 0x3e6c, 0x4548, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a66, 0x0000, 0x0000, 0x544e, 0x0000, 0x0000, - 0x4a3d, 0x4e5d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3274, 0x544a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x413a, 0x544d, 0x0000, 0x4563, 0x0000, 0x0000, 0x4549, 0x4564, 0x4839, 0x444d, 0x0000, 0x0000, 0x0000, 0x3a49, 0x0000, - 0x0000, 0x0000, 0x5449, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3176, 0x0000, 0x4536, 0x0000, 0x0000, 0x0000, 0x0000, - 0x544b, 0x0000, 0x5447, 0x0000, 0x0000, 0x3f50, 0x0000, 0x0000, 0x0000, 0x544f, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d4e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x362d, 0x0000, 0x5450, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4a68, 0x0000, 0x0000, 0x0000, 0x417d, 0x0000, 0x0000, 0x0000, 0x0000, 0x4446, 0x0000, 0x0000, 0x5452, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b4f, 0x0000, 0x0000, 0x5453, 0x0000, 0x0000, 0x5458, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4a2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x5457, 0x5451, 0x5454, 0x5456, 0x0000, 0x0000, 0x3a26, 0x0000, - 0x0000, 0x4a49, 0x0000, 0x0000, 0x0000, 0x5459, 0x0000, 0x4345, 0x0000, 0x0000, 0x3275, 0x0000, 0x3e6d, 0x0000, 0x0000, 0x0000, - 0x0000, 0x545b, 0x0000, 0x545a, 0x0000, 0x3968, 0x0000, 0x545c, 0x545e, 0x545d, 0x0000, 0x0000, 0x5460, 0x0000, 0x5455, 0x5462, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5461, 0x545f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b4e, 0x3f51, 0x0000, 0x4154, 0x5463, - 0x403c, 0x306d, 0x4764, 0x0000, 0x0000, 0x0000, 0x0000, 0x445b, 0x0000, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_59[256] = { - 0x0000, 0x0000, 0x5469, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a51, 0x546a, 0x0000, 0x0000, 0x0000, 0x0000, 0x3246, - 0x546b, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d3c, 0x3330, 0x0000, 0x5249, 0x3d48, 0x423f, 0x546c, 0x4c6b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4c34, 0x0000, 0x0000, 0x546e, 0x0000, 0x4267, 0x0000, 0x4537, 0x4240, 0x4957, 0x546f, 0x5470, 0x317b, 0x0000, - 0x0000, 0x3c3a, 0x5471, 0x0000, 0x0000, 0x0000, 0x0000, 0x3050, 0x5472, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5473, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3162, 0x0000, 0x0000, 0x3471, 0x4660, 0x4a74, 0x0000, 0x0000, 0x0000, 0x0000, 0x5477, 0x4155, - 0x5476, 0x3740, 0x0000, 0x0000, 0x4b5b, 0x5475, 0x0000, 0x4565, 0x5479, 0x0000, 0x5478, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x547b, 0x0000, 0x547a, 0x0000, 0x0000, 0x317c, 0x0000, 0x547c, 0x3e29, 0x547e, 0x4325, 0x0000, 0x547d, 0x0000, 0x4a33, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3d77, 0x455b, 0x0000, 0x0000, 0x0000, 0x5521, 0x0000, 0x0000, 0x0000, 0x0000, 0x3925, 0x0000, 0x0000, - 0x0000, 0x5522, 0x4721, 0x485e, 0x4c51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4725, 0x0000, 0x0000, 0x552b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3538, 0x0000, 0x0000, 0x4d45, 0x0000, 0x0000, 0x4c2f, 0x0000, 0x562c, 0x0000, 0x5523, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5526, 0x0000, 0x4245, 0x0000, 0x0000, 0x4b38, 0x0000, 0x0000, 0x0000, 0x454a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5527, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b65, 0x0000, 0x3a4a, 0x0000, 0x0000, 0x3e2a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5528, 0x0000, 0x0000, 0x3b50, 0x0000, 0x3b4f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3039, 0x3848, 0x0000, 0x402b, 0x3051, 0x0000, 0x0000, 0x0000, 0x0000, 0x552c, 0x552d, 0x0000, 0x552a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3138, 0x342f, 0x0000, 0x5529, 0x0000, 0x4c45, 0x4931, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3028, 0x0000, 0x0000, 0x0000, 0x0000, 0x3079, 0x0000, 0x0000, 0x0000, 0x3b51, -}; - -static const uint16_t unicode_to_jisx0208_5a[256] = { - 0x0000, 0x3052, 0x0000, 0x3023, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5532, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5530, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c3c, 0x0000, 0x5533, 0x0000, 0x5531, 0x0000, 0x0000, 0x552f, - 0x3f31, 0x0000, 0x0000, 0x0000, 0x0000, 0x552e, 0x0000, 0x0000, 0x0000, 0x4a5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3864, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5537, 0x5538, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e2b, 0x0000, 0x0000, 0x0000, - 0x5534, 0x4f2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x474c, 0x0000, 0x0000, 0x5536, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5539, 0x0000, 0x0000, 0x0000, 0x4958, 0x0000, 0x0000, 0x0000, 0x553a, 0x0000, 0x5535, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c3b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x475e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x553b, 0x4932, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x553c, 0x5540, 0x553d, 0x0000, - 0x0000, 0x3247, 0x553f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c3b, 0x0000, 0x553e, 0x3779, 0x0000, 0x0000, 0x0000, - 0x554c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5545, 0x5542, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4364, 0x0000, 0x5541, 0x0000, 0x0000, 0x5543, 0x0000, 0x0000, 0x5544, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5546, 0x5547, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_5b[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3472, 0x0000, 0x5549, 0x5548, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x554a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3e6e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x554d, 0x0000, 0x445c, 0x0000, 0x0000, 0x0000, - 0x3145, 0x0000, 0x554b, 0x0000, 0x0000, 0x0000, 0x554e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x554f, 0x0000, - 0x5552, 0x0000, 0x0000, 0x5550, 0x0000, 0x5551, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3b52, 0x5553, 0x0000, 0x0000, 0x3926, 0x5554, 0x0000, 0x3b7a, 0x4238, 0x0000, 0x5555, 0x5556, 0x3b5a, 0x3927, 0x0000, 0x4c52, - 0x0000, 0x0000, 0x0000, 0x3528, 0x3849, 0x5557, 0x3358, 0x0000, 0x0000, 0x5558, 0x0000, 0x4239, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5559, 0x5623, 0x0000, 0x555a, 0x0000, 0x555b, 0x0000, 0x0000, 0x555c, 0x0000, 0x555e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x555f, 0x0000, 0x0000, 0x5560, 0x0000, 0x4270, 0x0000, 0x3127, 0x3c69, 0x3042, 0x0000, 0x4157, 0x3430, 0x3c35, 0x0000, 0x3928, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4566, 0x0000, 0x3d21, 0x3431, 0x4368, 0x446a, 0x3038, 0x3539, 0x4a75, 0x0000, 0x3c42, - 0x0000, 0x0000, 0x3552, 0x406b, 0x3c3c, 0x4d28, 0x5561, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x355c, 0x0000, - 0x3a4b, 0x0000, 0x0000, 0x3332, 0x3163, 0x3e2c, 0x3248, 0x0000, 0x5562, 0x4d46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d49, - 0x0000, 0x0000, 0x3c64, 0x5563, 0x3473, 0x4652, 0x4c29, 0x5564, 0x0000, 0x5565, 0x0000, 0x0000, 0x4959, 0x0000, 0x0000, 0x0000, - 0x5567, 0x0000, 0x3428, 0x3677, 0x5566, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3432, 0x0000, 0x3f32, 0x556b, 0x3b21, - 0x0000, 0x3249, 0x556a, 0x0000, 0x5568, 0x556c, 0x5569, 0x472b, 0x5c4d, 0x3f33, 0x0000, 0x556d, 0x0000, 0x0000, 0x4e40, 0x0000, - 0x556e, 0x0000, 0x0000, 0x5570, 0x0000, 0x437e, 0x556f, 0x0000, 0x4023, 0x0000, 0x3b7b, 0x0000, 0x0000, 0x0000, 0x4250, 0x3c77, -}; - -static const uint16_t unicode_to_jisx0208_5c[256] = { - 0x0000, 0x4975, 0x406c, 0x0000, 0x3c4d, 0x5571, 0x3e2d, 0x5572, 0x5573, 0x3053, 0x423a, 0x3f52, 0x0000, 0x5574, 0x4633, 0x3e2e, - 0x0000, 0x3e2f, 0x0000, 0x5575, 0x0000, 0x0000, 0x406d, 0x0000, 0x0000, 0x0000, 0x3e30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5576, 0x0000, 0x5577, 0x0000, 0x4c60, 0x0000, 0x0000, 0x0000, 0x5578, 0x0000, 0x0000, 0x0000, 0x0000, 0x3646, 0x0000, 0x0000, - 0x0000, 0x3d22, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5579, 0x557a, 0x3c5c, 0x3f2c, 0x4674, 0x3f54, 0x4878, 0x4722, - 0x3649, 0x557b, 0x0000, 0x0000, 0x0000, 0x356f, 0x557c, 0x0000, 0x367e, 0x0000, 0x464f, 0x3230, 0x0000, 0x3b53, 0x557d, 0x5622, - 0x5621, 0x367d, 0x0000, 0x557e, 0x0000, 0x4538, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4230, 0x0000, - 0x454b, 0x3c48, 0x0000, 0x0000, 0x4158, 0x4d7a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5624, 0x0000, 0x5625, 0x4656, - 0x0000, 0x3b33, 0x0000, 0x0000, 0x0000, 0x0000, 0x5627, 0x0000, 0x0000, 0x5628, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5629, 0x0000, 0x0000, 0x0000, - 0x3474, 0x562a, 0x0000, 0x0000, 0x562b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x322c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x413b, 0x3464, 0x0000, 0x562d, 0x4c28, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4252, 0x0000, 0x3359, 0x0000, 0x0000, 0x562f, 0x5631, 0x345f, 0x0000, 0x0000, 0x562e, 0x5630, 0x0000, 0x5633, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5632, 0x0000, 0x5634, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5635, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x463d, 0x362e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3265, 0x5636, 0x563b, 0x0000, 0x0000, 0x5639, 0x0000, 0x4a77, - 0x4a76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4567, 0x0000, 0x0000, 0x0000, 0x5638, 0x3d54, 0x0000, 0x5637, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_5d[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f72, 0x0000, 0x0000, 0x0000, 0x563c, 0x0000, 0x0000, 0x3a6a, 0x0000, - 0x0000, 0x5642, 0x0000, 0x0000, 0x5643, 0x563d, 0x3333, 0x563e, 0x5647, 0x5646, 0x5645, 0x5641, 0x0000, 0x0000, 0x0000, 0x5640, - 0x0000, 0x0000, 0x5644, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x564b, 0x5648, 0x0000, 0x564a, 0x0000, - 0x4d72, 0x0000, 0x5649, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x563f, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f73, 0x0000, 0x0000, 0x564c, 0x0000, 0x0000, 0x3a37, - 0x0000, 0x0000, 0x0000, 0x564d, 0x0000, 0x0000, 0x564e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5651, 0x0000, 0x5650, 0x0000, 0x0000, 0x564f, 0x0000, 0x0000, 0x0000, 0x4568, 0x563a, 0x0000, 0x0000, 0x0000, - 0x5657, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5653, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5654, 0x0000, 0x5655, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5658, 0x0000, 0x0000, 0x4e66, 0x0000, 0x5659, 0x5656, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x565a, 0x0000, 0x0000, 0x3460, 0x565b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x565d, 0x565c, 0x0000, 0x0000, 0x565e, 0x0000, 0x0000, 0x0000, 0x0000, 0x565f, 0x0000, 0x406e, 0x3d23, 0x0000, - 0x0000, 0x3d64, 0x0000, 0x4163, 0x0000, 0x3929, 0x3a38, 0x392a, 0x3570, 0x0000, 0x0000, 0x5660, 0x0000, 0x0000, 0x3a39, 0x0000, - 0x0000, 0x384a, 0x5661, 0x4c26, 0x4743, 0x5662, 0x0000, 0x392b, 0x0000, 0x0000, 0x0000, 0x342c, 0x0000, 0x4327, 0x3652, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_5e[256] = { - 0x0000, 0x0000, 0x3b54, 0x495b, 0x0000, 0x0000, 0x4841, 0x0000, 0x0000, 0x0000, 0x0000, 0x5663, 0x3475, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5666, 0x0000, 0x0000, 0x0000, 0x0000, 0x4421, 0x0000, 0x0000, 0x5665, 0x5664, 0x5667, 0x0000, 0x446b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b55, 0x0000, 0x404a, 0x0000, 0x4253, - 0x3522, 0x0000, 0x0000, 0x4422, 0x0000, 0x0000, 0x5668, 0x5669, 0x3e6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b39, 0x0000, 0x0000, - 0x566c, 0x0000, 0x0000, 0x566b, 0x566a, 0x497d, 0x0000, 0x5673, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b5a, 0x0000, 0x566d, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x566f, 0x4b6b, 0x0000, 0x566e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5670, - 0x0000, 0x4828, 0x5671, 0x4a3e, 0x5672, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3433, 0x4a3f, 0x472f, 0x5674, 0x5675, 0x0000, 0x392c, 0x3434, 0x5676, 0x3838, 0x4d44, 0x4d29, 0x3476, 0x5678, - 0x0000, 0x4423, 0x0000, 0x392d, 0x3e31, 0x0000, 0x0000, 0x485f, 0x0000, 0x0000, 0x3e32, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d78, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x446c, 0x4a79, 0x4539, 0x0000, 0x0000, 0x392e, 0x0000, 0x495c, 0x0000, 0x0000, 0x0000, - 0x5679, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4559, 0x3a42, 0x0000, 0x0000, 0x0000, 0x384b, 0x0000, 0x446d, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3043, 0x3d6e, 0x392f, 0x4d47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x567a, 0x567b, 0x4751, 0x0000, 0x0000, 0x0000, 0x0000, 0x567c, 0x4e77, 0x4f2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x567e, - 0x567d, 0x0000, 0x0000, 0x3347, 0x0000, 0x0000, 0x5721, 0x0000, 0x0000, 0x0000, 0x5724, 0x5725, 0x0000, 0x5723, 0x0000, 0x4940, - 0x3e33, 0x5727, 0x5726, 0x5722, 0x0000, 0x0000, 0x0000, 0x0000, 0x5728, 0x5729, 0x0000, 0x0000, 0x572a, 0x0000, 0x0000, 0x0000, - 0x572d, 0x572b, 0x0000, 0x572c, 0x572e, 0x0000, 0x3164, 0x446e, 0x572f, 0x0000, 0x377a, 0x3276, 0x4736, 0x0000, 0x5730, 0x467b, -}; - -static const uint16_t unicode_to_jisx0208_5f[256] = { - 0x0000, 0x4a5b, 0x0000, 0x5731, 0x4f2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x5732, 0x4a40, 0x5735, 0x5021, 0x5031, 0x0000, 0x3c30, - 0x4675, 0x5736, 0x0000, 0x355d, 0x4424, 0x307a, 0x5737, 0x4a26, 0x3930, 0x0000, 0x0000, 0x4350, 0x0000, 0x0000, 0x0000, 0x446f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c6f, 0x3839, 0x384c, 0x0000, 0x5738, 0x0000, 0x0000, 0x0000, 0x5739, 0x0000, 0x573f, - 0x0000, 0x3c65, 0x0000, 0x0000, 0x0000, 0x4425, 0x0000, 0x362f, 0x573a, 0x0000, 0x0000, 0x0000, 0x492b, 0x0000, 0x4346, 0x0000, - 0x0000, 0x573b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x573c, 0x0000, 0x3630, 0x0000, 0x573d, 0x0000, 0x573e, 0x0000, - 0x0000, 0x5740, 0x0000, 0x4576, 0x0000, 0x0000, 0x5741, 0x5742, 0x0000, 0x5743, 0x0000, 0x0000, 0x5734, 0x5733, 0x0000, 0x0000, - 0x0000, 0x5744, 0x3741, 0x0000, 0x0000, 0x0000, 0x4927, 0x0000, 0x0000, 0x3a4c, 0x4937, 0x4426, 0x494b, 0x5745, 0x0000, 0x0000, - 0x3e34, 0x3146, 0x0000, 0x5746, 0x0000, 0x0000, 0x0000, 0x5747, 0x0000, 0x4c72, 0x0000, 0x0000, 0x4860, 0x0000, 0x0000, 0x574a, - 0x317d, 0x402c, 0x5749, 0x5748, 0x3742, 0x4254, 0x0000, 0x574e, 0x574c, 0x0000, 0x574b, 0x4e27, 0x3865, 0x0000, 0x0000, 0x0000, - 0x3d79, 0x574d, 0x454c, 0x3d3e, 0x0000, 0x0000, 0x0000, 0x4640, 0x5751, 0x5750, 0x0000, 0x0000, 0x0000, 0x0000, 0x574f, 0x0000, - 0x5752, 0x3866, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5753, 0x497c, 0x3d5b, 0x0000, 0x0000, 0x5754, 0x4879, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4641, 0x4427, 0x0000, 0x0000, 0x0000, 0x0000, 0x4530, 0x0000, 0x0000, 0x5755, 0x352b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3f34, 0x0000, 0x492c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3477, 0x4726, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5756, 0x3b56, 0x4b3a, 0x4b3b, 0x0000, 0x0000, 0x317e, 0x575b, 0x0000, 0x0000, - 0x4369, 0x0000, 0x0000, 0x0000, 0x5758, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3277, 0x0000, 0x0000, 0x0000, 0x0000, - 0x582d, 0x575a, 0x0000, 0x0000, 0x0000, 0x4730, 0x0000, 0x0000, 0x5759, 0x0000, 0x0000, 0x5757, 0x0000, 0x397a, 0x0000, 0x575d, -}; - -static const uint16_t unicode_to_jisx0208_60[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5763, 0x5769, - 0x5761, 0x0000, 0x455c, 0x0000, 0x0000, 0x5766, 0x495d, 0x0000, 0x0000, 0x5760, 0x0000, 0x5765, 0x4e67, 0x3b57, 0x0000, 0x0000, - 0x4255, 0x575e, 0x0000, 0x0000, 0x0000, 0x355e, 0x5768, 0x402d, 0x3165, 0x5762, 0x3278, 0x5767, 0x0000, 0x0000, 0x0000, 0x3631, - 0x0000, 0x5764, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x576a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x576c, 0x5776, 0x5774, 0x0000, 0x0000, 0x5771, 0x0000, 0x0000, 0x0000, 0x5770, 0x4e78, 0x0000, 0x5772, 0x0000, 0x0000, - 0x3632, 0x0000, 0x3931, 0x0000, 0x0000, 0x3d7a, 0x0000, 0x0000, 0x0000, 0x5779, 0x576b, 0x0000, 0x0000, 0x0000, 0x0000, 0x576f, - 0x575f, 0x0000, 0x327a, 0x5773, 0x5775, 0x4351, 0x0000, 0x0000, 0x3a28, 0x3238, 0x576d, 0x5778, 0x5777, 0x3633, 0x0000, 0x4229, - 0x3366, 0x0000, 0x0000, 0x0000, 0x0000, 0x3743, 0x0000, 0x576e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x577a, 0x0000, 0x577d, 0x5821, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c3d, 0x0000, 0x5827, 0x4470, 0x577b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5825, 0x0000, 0x3279, 0x0000, 0x5823, 0x5824, 0x0000, 0x0000, 0x577e, 0x5822, 0x0000, 0x0000, 0x0000, 0x3867, - 0x4d2a, 0x0000, 0x0000, 0x3435, 0x0000, 0x0000, 0x3159, 0x5826, 0x0000, 0x473a, 0x302d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4861, 0x575c, 0x582c, 0x5830, 0x4c65, 0x0000, 0x5829, 0x0000, 0x0000, 0x0000, 0x4569, 0x582e, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e70, 0x582f, 0x4657, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4f47, 0x0000, 0x582b, 0x0000, 0x0000, 0x0000, 0x0000, 0x5831, 0x0000, 0x397b, 0x0000, 0x404b, 0x0000, 0x0000, 0x3054, - 0x582a, 0x5828, 0x0000, 0x415a, 0x0000, 0x0000, 0x0000, 0x577c, 0x3b34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4246, 0x583d, 0x0000, 0x415b, 0x5838, 0x0000, 0x5835, 0x5836, 0x0000, 0x3c66, 0x5839, 0x583c, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_61[256] = { - 0x5837, 0x3d25, 0x0000, 0x583a, 0x0000, 0x0000, 0x5834, 0x0000, 0x4c7c, 0x4c7b, 0x0000, 0x0000, 0x0000, 0x583e, 0x583f, 0x3055, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5833, 0x0000, 0x0000, 0x0000, 0x0000, 0x3672, 0x3026, 0x0000, 0x0000, 0x0000, 0x3436, - 0x0000, 0x583b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5843, 0x5842, 0x0000, 0x0000, 0x0000, 0x5847, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5848, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5846, 0x5849, 0x5841, 0x5845, - 0x0000, 0x0000, 0x584a, 0x0000, 0x584b, 0x0000, 0x0000, 0x5840, 0x3b7c, 0x0000, 0x5844, 0x4256, 0x3932, 0x5832, 0x3f35, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5858, 0x0000, 0x4a69, 0x0000, 0x0000, 0x584e, 0x584f, 0x5850, 0x0000, 0x0000, 0x5857, 0x0000, 0x5856, - 0x0000, 0x0000, 0x4b7d, 0x3437, 0x0000, 0x5854, 0x0000, 0x3745, 0x3334, 0x0000, 0x0000, 0x5851, 0x0000, 0x0000, 0x4e38, 0x5853, - 0x3056, 0x5855, 0x0000, 0x584c, 0x5852, 0x5859, 0x3744, 0x584d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d5d, 0x0000, - 0x0000, 0x0000, 0x4d2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x585c, 0x0000, 0x0000, 0x5860, 0x0000, 0x0000, 0x0000, 0x417e, 0x0000, - 0x4e79, 0x5861, 0x0000, 0x0000, 0x585e, 0x0000, 0x585b, 0x0000, 0x0000, 0x585a, 0x585f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4a30, 0x0000, 0x0000, 0x4634, 0x0000, 0x3746, 0x0000, 0x5862, 0x585d, 0x0000, 0x5863, 0x0000, - 0x0000, 0x0000, 0x377b, 0x0000, 0x0000, 0x0000, 0x3231, 0x0000, 0x0000, 0x0000, 0x586b, 0x0000, 0x0000, 0x0000, 0x3438, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5869, 0x0000, 0x0000, 0x586a, 0x3a29, 0x5868, 0x5866, 0x5865, 0x586c, 0x5864, 0x586e, 0x0000, 0x0000, - 0x327b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5870, 0x0000, 0x0000, 0x586f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4428, 0x0000, 0x5873, 0x0000, 0x5871, 0x5867, 0x377c, 0x0000, 0x5872, 0x0000, 0x5876, 0x5875, 0x5877, 0x5874, -}; - -static const uint16_t unicode_to_jisx0208_62[256] = { - 0x5878, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5879, 0x587a, 0x4a6a, 0x0000, 0x587c, 0x587b, 0x3d3f, 0x0000, - 0x402e, 0x3266, 0x327c, 0x0000, 0x587d, 0x0000, 0x303f, 0x0000, 0x0000, 0x0000, 0x404c, 0x587e, 0x0000, 0x6c43, 0x5921, 0x3761, - 0x0000, 0x5922, 0x0000, 0x0000, 0x0000, 0x0000, 0x406f, 0x0000, 0x0000, 0x0000, 0x5923, 0x0000, 0x0000, 0x0000, 0x5924, 0x353a, - 0x5925, 0x0000, 0x5926, 0x5927, 0x4257, 0x0000, 0x0000, 0x0000, 0x384d, 0x0000, 0x0000, 0x4c61, 0x0000, 0x0000, 0x0000, 0x4b3c, - 0x3d6a, 0x5928, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4070, 0x6e3d, 0x4862, 0x0000, 0x3c6a, 0x0000, 0x3a4d, 0x5929, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4247, 0x0000, 0x4a27, 0x0000, 0x0000, 0x4271, 0x0000, 0x0000, 0x592c, 0x0000, 0x0000, 0x592a, 0x0000, - 0x592d, 0x0000, 0x0000, 0x592b, 0x0000, 0x0000, 0x0000, 0x0000, 0x592e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a31, 0x0000, - 0x0000, 0x3037, 0x0000, 0x0000, 0x0000, 0x0000, 0x495e, 0x0000, 0x0000, 0x4863, 0x0000, 0x0000, 0x592f, 0x0000, 0x5932, 0x3e35, - 0x353b, 0x0000, 0x5930, 0x5937, 0x3e36, 0x0000, 0x0000, 0x0000, 0x0000, 0x5931, 0x4744, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4d5e, 0x5933, 0x5934, 0x5938, 0x456a, 0x5935, 0x3933, 0x405e, 0x0000, 0x0000, 0x5946, 0x4834, 0x0000, 0x4272, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4864, 0x5a2d, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4a7a, 0x0000, 0x0000, 0x0000, 0x4471, 0x0000, 0x0000, 0x0000, 0x4b75, 0x0000, 0x593b, 0x3221, 0x436a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5944, 0x0000, 0x0000, 0x4334, 0x593e, 0x5945, 0x5940, 0x5947, 0x5943, 0x0000, 0x5942, 0x476f, 0x0000, 0x593c, - 0x327d, 0x593a, 0x3571, 0x4273, 0x5936, 0x0000, 0x0000, 0x5939, 0x3934, 0x405b, 0x0000, 0x3e37, 0x5941, 0x4752, 0x0000, 0x0000, - 0x3572, 0x3348, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3367, 0x3f21, 0x5949, 0x594e, - 0x0000, 0x594a, 0x0000, 0x377d, 0x0000, 0x594f, 0x3b22, 0x3969, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d26, 0x593d, -}; - -static const uint16_t unicode_to_jisx0208_63[256] = { - 0x0000, 0x3b7d, 0x594c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b58, 0x594d, 0x3044, 0x0000, 0x0000, 0x5948, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4429, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3573, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3634, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x594b, 0x3027, 0x0000, 0x0000, 0x3a43, 0x0000, 0x0000, 0x0000, 0x3f36, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4472, 0x0000, 0x0000, 0x4854, 0x5951, 0x415e, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x422a, 0x0000, 0x0000, 0x3b2b, 0x5952, 0x0000, 0x5954, - 0x5950, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a61, 0x0000, 0x443d, 0x0000, 0x0000, 0x0000, 0x0000, 0x415c, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a7b, 0x3c4e, 0x5960, 0x0000, 0x595f, 0x0000, 0x0000, 0x3f78, 0x0000, - 0x0000, 0x0000, 0x377e, 0x0000, 0x0000, 0x0000, 0x5959, 0x3e39, 0x0000, 0x0000, 0x4668, 0x4731, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5957, 0x0000, 0x0000, 0x415d, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c78, 0x595c, 0x0000, 0x0000, 0x3e38, 0x0000, 0x5956, 0x595b, - 0x0000, 0x0000, 0x4753, 0x0000, 0x0000, 0x0000, 0x5955, 0x0000, 0x3721, 0x0000, 0x0000, 0x335d, 0x0000, 0x0000, 0x0000, 0x595d, - 0x4e2b, 0x3a4e, 0x4335, 0x595a, 0x0000, 0x405c, 0x0000, 0x3935, 0x3f64, 0x3166, 0x413c, 0x5958, 0x3545, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3747, 0x0000, 0x444f, 0x595e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x415f, 0x0000, 0x0000, 0x5961, 0x0000, - 0x5963, 0x0000, 0x0000, 0x4237, 0x5969, 0x0000, 0x5964, 0x0000, 0x0000, 0x5966, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4941, - 0x4473, 0x0000, 0x5967, 0x0000, 0x0000, 0x0000, 0x4d2c, 0x0000, 0x0000, 0x0000, 0x4d48, 0x3439, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x302e, 0x0000, 0x5965, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5962, 0x0000, 0x0000, 0x0000, 0x0000, 0x3478, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3167, 0x0000, 0x5968, 0x0000, 0x0000, 0x0000, 0x4d49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_64[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x596c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x423b, 0x0000, 0x5973, - 0x0000, 0x0000, 0x0000, 0x596d, 0x0000, 0x0000, 0x596a, 0x5971, 0x0000, 0x0000, 0x0000, 0x0000, 0x5953, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x596e, 0x0000, 0x5972, 0x0000, 0x0000, 0x0000, 0x4842, 0x456b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x596b, 0x0000, 0x596f, 0x0000, 0x0000, 0x0000, 0x3748, 0x0000, 0x0000, 0x0000, 0x3a71, 0x0000, - 0x0000, 0x0000, 0x405d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5977, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4526, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5974, 0x0000, 0x4b60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5975, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5976, 0x0000, 0x4c4e, 0x0000, 0x4022, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3762, 0x0000, 0x0000, 0x0000, 0x0000, 0x597d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3b35, 0x597a, 0x0000, 0x5979, 0x0000, 0x0000, 0x0000, 0x0000, 0x4732, 0x0000, 0x0000, 0x0000, 0x4635, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4531, 0x597b, 0x0000, 0x0000, 0x0000, 0x597c, 0x0000, 0x496f, 0x0000, 0x4745, 0x3b23, 0x0000, - 0x4071, 0x0000, 0x4b50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3349, 0x0000, 0x5a25, 0x597e, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4d4a, 0x5a27, 0x0000, 0x0000, 0x5a23, 0x0000, 0x5a24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4160, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5a22, 0x0000, 0x593f, 0x0000, 0x0000, 0x0000, 0x5a26, 0x0000, 0x5a21, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5a2b, 0x5a2c, 0x4527, 0x5a2e, 0x0000, 0x0000, 0x3b24, 0x5a29, 0x0000, 0x0000, 0x0000, 0x0000, 0x353c, 0x0000, 0x0000, 0x5a2f, - 0x0000, 0x5a28, 0x5a33, 0x0000, 0x5a32, 0x0000, 0x5a31, 0x0000, 0x0000, 0x0000, 0x5a34, 0x0000, 0x0000, 0x5a36, 0x3e71, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_65[256] = { - 0x5a35, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a39, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a37, 0x0000, 0x0000, 0x0000, 0x5a38, 0x5970, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5a3b, 0x5a3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5978, 0x5a3c, 0x5a30, 0x0000, 0x0000, 0x3b59, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5a3d, 0x5a3e, 0x5a40, 0x5a3f, 0x5a41, 0x327e, 0x0000, 0x3936, 0x0000, 0x0000, 0x4a7c, 0x402f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x384e, 0x0000, 0x0000, 0x5a43, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a46, 0x0000, 0x4952, - 0x0000, 0x355f, 0x0000, 0x0000, 0x0000, 0x5a45, 0x5a44, 0x4754, 0x5a47, 0x3635, 0x0000, 0x0000, 0x0000, 0x5a49, 0x5a48, 0x0000, - 0x0000, 0x0000, 0x343a, 0x3b36, 0x0000, 0x0000, 0x4658, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3749, 0x0000, 0x0000, 0x0000, - 0x3f74, 0x0000, 0x5a4a, 0x0000, 0x4030, 0x4528, 0x0000, 0x495f, 0x5a4b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5a4c, 0x5a4d, 0x0000, 0x0000, 0x0000, 0x4a38, 0x555d, 0x4046, 0x0000, 0x0000, 0x494c, 0x0000, 0x3a58, 0x0000, - 0x4865, 0x4843, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x454d, 0x0000, 0x4e41, 0x0000, 0x5a4f, 0x3c50, 0x0000, 0x0000, 0x5a50, - 0x0000, 0x3036, 0x0000, 0x0000, 0x3654, 0x404d, 0x0000, 0x4960, 0x0000, 0x0000, 0x0000, 0x5a51, 0x3b42, 0x4347, 0x0000, 0x3b5b, - 0x3f37, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a52, 0x0000, 0x4a7d, 0x0000, 0x0000, 0x3177, 0x3b5c, 0x0000, 0x0000, - 0x0000, 0x5a55, 0x0000, 0x5a53, 0x5a56, 0x4e39, 0x5a54, 0x0000, 0x0000, 0x0000, 0x0000, 0x407b, 0x5a57, 0x0000, 0x0000, 0x4232, - 0x0000, 0x0000, 0x5a58, 0x0000, 0x0000, 0x0000, 0x0000, 0x347a, 0x0000, 0x5a5a, 0x0000, 0x5a59, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5a5b, 0x5a5c, 0x347b, 0x0000, 0x0000, 0x467c, 0x4336, 0x356c, 0x3b5d, 0x4161, 0x0000, 0x0000, 0x3d5c, 0x3030, 0x0000, 0x0000, - 0x0000, 0x5a5d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3222, 0x5a61, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_66[256] = { - 0x0000, 0x0000, 0x3937, 0x5a60, 0x0000, 0x0000, 0x3a2b, 0x3e3a, 0x0000, 0x0000, 0x5a5f, 0x0000, 0x3e3b, 0x0000, 0x4c40, 0x3a2a, - 0x0000, 0x0000, 0x0000, 0x3057, 0x404e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a66, 0x0000, 0x0000, 0x4031, - 0x3147, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d55, 0x0000, 0x4b66, 0x3a72, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e3c, 0x0000, 0x4027, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5a65, 0x5a63, 0x5a64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x436b, 0x0000, 0x0000, 0x5b26, - 0x0000, 0x5a6a, 0x3b7e, 0x3938, 0x5a68, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a69, 0x0000, 0x3f38, 0x0000, 0x0000, 0x0000, 0x5a67, - 0x0000, 0x0000, 0x3b2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a6c, 0x5a6b, 0x5a70, - 0x0000, 0x0000, 0x5a71, 0x0000, 0x5a6d, 0x0000, 0x3322, 0x5a6e, 0x5a6f, 0x4855, 0x0000, 0x0000, 0x0000, 0x0000, 0x4961, 0x374a, - 0x5a72, 0x0000, 0x0000, 0x0000, 0x4032, 0x0000, 0x3e3d, 0x0000, 0x0000, 0x0000, 0x4352, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3647, 0x0000, 0x5a73, 0x5a77, 0x0000, 0x0000, 0x324b, 0x5a74, 0x5a76, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a75, 0x0000, - 0x0000, 0x3d6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x4348, 0x3045, 0x5a78, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a79, 0x0000, 0x0000, - 0x0000, 0x0000, 0x442a, 0x0000, 0x0000, 0x0000, 0x4e71, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b43, 0x0000, 0x0000, 0x4a6b, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4b3d, 0x0000, 0x0000, 0x0000, 0x5b22, 0x5a7b, 0x0000, 0x0000, 0x5a7e, 0x0000, 0x5a7d, 0x0000, - 0x0000, 0x5a7a, 0x0000, 0x0000, 0x5b21, 0x0000, 0x0000, 0x465e, 0x0000, 0x5a7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b23, 0x0000, 0x0000, 0x3d6c, 0x5b24, 0x0000, 0x4d4b, 0x4778, 0x0000, 0x0000, - 0x5b25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b27, 0x0000, 0x0000, 0x5b28, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5b29, 0x0000, 0x364a, 0x3148, 0x3939, 0x5b2a, 0x0000, 0x5b2b, 0x3d71, 0x4162, 0x0000, 0x0000, 0x5258, 0x413e, 0x413d, 0x4258, -}; - -static const uint16_t unicode_to_jisx0208_67[256] = { - 0x3a47, 0x0000, 0x0000, 0x5072, 0x0000, 0x0000, 0x0000, 0x0000, 0x376e, 0x4d2d, 0x0000, 0x4a7e, 0x0000, 0x497e, 0x0000, 0x5b2c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3a73, 0x443f, 0x5b2d, 0x4f2f, 0x0000, 0x0000, 0x0000, 0x4b3e, 0x0000, 0x442b, 0x5b2e, 0x347c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b2f, 0x5b30, 0x4c5a, 0x0000, 0x4c24, 0x4b76, 0x4b5c, 0x3b25, 0x5b32, 0x0000, - 0x0000, 0x3c6b, 0x0000, 0x0000, 0x4b51, 0x0000, 0x5b34, 0x5b37, 0x5b36, 0x0000, 0x3479, 0x0000, 0x0000, 0x3560, 0x0000, 0x5b33, - 0x0000, 0x5b35, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b38, 0x0000, 0x0000, 0x3f79, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d7b, 0x3049, - 0x3a60, 0x423c, 0x0000, 0x3c5d, 0x0000, 0x0000, 0x3e73, 0x0000, 0x0000, 0x5b3b, 0x0000, 0x0000, 0x454e, 0x0000, 0x5b39, 0x422b, - 0x5b3a, 0x3e72, 0x4c5d, 0x5b3c, 0x5b3d, 0x4d68, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b42, 0x0000, 0x0000, 0x393a, 0x0000, 0x4755, - 0x5b3f, 0x456c, 0x5a5e, 0x5a62, 0x0000, 0x354f, 0x0000, 0x4747, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b41, 0x0000, 0x3e3e, 0x4844, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b47, 0x0000, 0x487a, 0x0000, 0x5b3e, 0x0000, 0x5b44, 0x5b43, 0x0000, 0x0000, 0x0000, - 0x404f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b6d, 0x0000, 0x4e53, 0x0000, 0x0000, 0x4b67, 0x0000, 0x324c, 0x3b5e, 0x0000, 0x0000, - 0x4f48, 0x5b46, 0x3f75, 0x0000, 0x0000, 0x0000, 0x5b45, 0x0000, 0x0000, 0x5b40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x384f, - 0x0000, 0x0000, 0x0000, 0x5b4c, 0x5b4a, 0x0000, 0x324d, 0x5b48, 0x5b4e, 0x5b54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4248, 0x0000, 0x0000, 0x4a41, 0x0000, 0x5b56, 0x0000, 0x0000, 0x0000, 0x4922, 0x0000, 0x0000, 0x0000, 0x5b55, 0x4770, - 0x4b3f, 0x343b, 0x0000, 0x4077, 0x3d40, 0x0000, 0x0000, 0x0000, 0x4453, 0x0000, 0x4d2e, 0x0000, 0x0000, 0x5b51, 0x5b50, 0x0000, - 0x0000, 0x0000, 0x5b52, 0x0000, 0x5b4f, 0x0000, 0x0000, 0x5b57, 0x0000, 0x5b4d, 0x0000, 0x0000, 0x5b4b, 0x0000, 0x5b53, 0x5b49, - 0x0000, 0x436c, 0x0000, 0x4c78, 0x3c46, 0x3a74, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a3a, 0x0000, 0x0000, 0x4b6f, 0x3341, -}; - -static const uint16_t unicode_to_jisx0208_68[256] = { - 0x0000, 0x0000, 0x444e, 0x464a, 0x3149, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4072, 0x0000, 0x0000, 0x4034, 0x372a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b59, 0x0000, - 0x0000, 0x393b, 0x337c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b5b, 0x3374, 0x5b61, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5b5e, 0x0000, 0x4073, 0x0000, 0x0000, 0x0000, 0x334b, 0x3a2c, 0x0000, 0x0000, 0x334a, 0x3a4f, 0x0000, 0x0000, - 0x5b5c, 0x3765, 0x374b, 0x456d, 0x0000, 0x0000, 0x5b5a, 0x0000, 0x3046, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b5d, 0x5b5f, 0x0000, - 0x364d, 0x372c, 0x0000, 0x343c, 0x354b, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b62, 0x0000, 0x0000, 0x3a79, 0x4b71, 0x0000, 0x3b37, - 0x0000, 0x0000, 0x0000, 0x5b63, 0x0000, 0x0000, 0x0000, 0x4930, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5b6f, 0x0000, 0x3233, 0x5b64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b75, 0x5b65, - 0x0000, 0x4e42, 0x0000, 0x5b6c, 0x0000, 0x475f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b74, 0x0000, 0x5b67, - 0x0000, 0x0000, 0x0000, 0x3034, 0x5b69, 0x0000, 0x0000, 0x393c, 0x0000, 0x0000, 0x0000, 0x5b6b, 0x0000, 0x5b6a, 0x0000, 0x5b66, - 0x5b71, 0x0000, 0x3e3f, 0x0000, 0x0000, 0x0000, 0x546d, 0x3868, 0x4d7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b68, 0x0000, 0x4474, - 0x3323, 0x3a2d, 0x0000, 0x5b60, 0x0000, 0x5b70, 0x3361, 0x0000, 0x0000, 0x5b6e, 0x5b72, 0x0000, 0x456e, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x347e, 0x0000, 0x5c32, 0x0000, 0x0000, 0x4c49, 0x5b77, 0x347d, 0x0000, 0x5b7e, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4b40, 0x0000, 0x5c21, 0x5c23, 0x0000, 0x5c27, 0x5b79, 0x0000, 0x432a, 0x0000, 0x0000, 0x0000, 0x0000, 0x456f, - 0x5c2b, 0x5b7c, 0x0000, 0x5c28, 0x0000, 0x0000, 0x0000, 0x5c22, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f39, 0x5c2c, - 0x0000, 0x0000, 0x4033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c2a, 0x343d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_69[256] = { - 0x4f50, 0x5b76, 0x0000, 0x0000, 0x5c26, 0x3058, 0x0000, 0x0000, 0x5b78, 0x0000, 0x0000, 0x4c3a, 0x5b7d, 0x3f22, 0x4447, 0x5b73, - 0x0000, 0x0000, 0x5c25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f7a, 0x5c2f, 0x3371, 0x3821, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5c31, 0x5b7a, 0x5c30, 0x0000, 0x5c29, 0x5b7b, 0x0000, 0x5c2d, 0x0000, 0x5c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x5c3f, 0x0000, 0x0000, 0x0000, 0x464e, 0x0000, 0x5c24, 0x0000, 0x0000, 0x5c3b, 0x0000, 0x0000, 0x0000, 0x5c3d, 0x0000, 0x4458, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4976, 0x5c38, 0x424a, 0x0000, 0x0000, 0x0000, 0x5c3e, 0x413f, 0x0000, 0x5c35, 0x5c42, 0x5c41, 0x0000, - 0x466f, 0x5c40, 0x466a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c44, 0x5c37, 0x0000, 0x3648, 0x5c3a, 0x3d5d, - 0x0000, 0x0000, 0x0000, 0x4760, 0x5c3c, 0x364b, 0x0000, 0x5c34, 0x5c36, 0x5c33, 0x0000, 0x0000, 0x4f30, 0x335a, 0x5c39, 0x0000, - 0x0000, 0x5c43, 0x3335, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a67, 0x0000, 0x0000, 0x0000, 0x315d, 0x0000, - 0x0000, 0x5c54, 0x0000, 0x0000, 0x4f31, 0x5c57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f3a, 0x5c56, 0x0000, 0x0000, 0x0000, - 0x5c55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c46, 0x0000, - 0x0000, 0x5c63, 0x5c45, 0x0000, 0x5c58, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c50, 0x0000, 0x0000, 0x5c4b, 0x5c48, - 0x0000, 0x5c49, 0x0000, 0x5c51, 0x0000, 0x0000, 0x0000, 0x7422, 0x0000, 0x0000, 0x5c4e, 0x393d, 0x4448, 0x4164, 0x5c4c, 0x0000, - 0x5c47, 0x0000, 0x0000, 0x5c4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d4d, 0x4b6a, 0x0000, 0x0000, 0x0000, 0x5c4f, 0x5c59, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c61, 0x5c5a, 0x0000, 0x0000, 0x5c67, 0x0000, 0x5c65, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5c60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c5f, 0x0000, 0x4450, 0x0000, 0x4165, 0x0000, 0x5c5d, -}; - -static const uint16_t unicode_to_jisx0208_6a[256] = { - 0x0000, 0x0000, 0x5c5b, 0x0000, 0x0000, 0x5c62, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c68, 0x4875, 0x5c6e, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5c69, 0x5c6c, 0x5c66, 0x0000, 0x0000, 0x4374, 0x0000, 0x4938, 0x0000, 0x5c5c, 0x0000, 0x0000, 0x5c64, 0x3e40, - 0x0000, 0x4c4f, 0x5c78, 0x5c6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3822, 0x3223, 0x335f, 0x0000, 0x0000, 0x5c53, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e41, 0x5c70, 0x0000, 0x5c77, 0x3c79, 0x3372, 0x0000, 0x0000, 0x432e, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5c6d, 0x0000, 0x0000, 0x5c72, 0x5c76, 0x0000, 0x0000, 0x3636, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x354c, 0x5c74, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3521, - 0x0000, 0x464b, 0x5c73, 0x0000, 0x0000, 0x0000, 0x5c75, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5c6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3360, - 0x4349, 0x0000, 0x0000, 0x0000, 0x5c7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c7a, 0x3869, 0x0000, - 0x5c79, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d21, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b58, 0x0000, 0x0000, 0x0000, - 0x5c7b, 0x0000, 0x5c7d, 0x5c7e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d2c, 0x0000, 0x5d28, 0x0000, 0x5b6d, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5d27, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d26, 0x0000, 0x0000, 0x5d23, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5c6a, 0x5d25, 0x5d24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5d2a, 0x0000, 0x4f26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d2d, 0x367b, 0x0000, 0x0000, 0x5d29, 0x5d2b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4827, 0x0000, 0x5d2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d32, 0x5d2f, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_6b[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x4d73, 0x5d30, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5d33, 0x0000, 0x0000, 0x0000, 0x5d34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3135, 0x0000, 0x5d36, - 0x3767, 0x3c21, 0x0000, 0x3655, 0x0000, 0x0000, 0x0000, 0x3224, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4d5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d38, 0x5d37, 0x5d3a, 0x353d, 0x0000, 0x0000, 0x3656, 0x343e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5d3d, 0x0000, 0x0000, 0x0000, 0x5d3c, 0x0000, 0x5d3e, 0x0000, 0x0000, 0x324e, 0x0000, 0x4337, 0x0000, - 0x5d3f, 0x0000, 0x0000, 0x343f, 0x5d41, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d40, 0x0000, 0x5d42, 0x0000, 0x0000, 0x0000, 0x5d43, - 0x0000, 0x5d44, 0x3b5f, 0x4035, 0x3a21, 0x0000, 0x4970, 0x0000, 0x0000, 0x4a62, 0x4f44, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b75, - 0x0000, 0x0000, 0x0000, 0x3a50, 0x4e72, 0x0000, 0x0000, 0x0000, 0x5d45, 0x5d46, 0x0000, 0x3b60, 0x0000, 0x0000, 0x0000, 0x5d47, - 0x5d48, 0x0000, 0x0000, 0x5d4a, 0x5d49, 0x0000, 0x4b58, 0x0000, 0x0000, 0x3d5e, 0x3c6c, 0x3b44, 0x0000, 0x5d4b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d4d, 0x3f23, 0x0000, 0x5d4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d4e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5d4f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d50, 0x5d51, 0x0000, 0x0000, 0x0000, 0x5d52, - 0x0000, 0x5d54, 0x5d53, 0x5d55, 0x3225, 0x434a, 0x0000, 0x5d56, 0x0000, 0x0000, 0x3b26, 0x334c, 0x5d57, 0x0000, 0x0000, 0x4542, - 0x544c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3523, 0x5d58, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d59, 0x0000, 0x4a6c, 0x4b68, 0x0000, - 0x0000, 0x0000, 0x4647, 0x5d5a, 0x4866, 0x0000, 0x0000, 0x0000, 0x487b, 0x0000, 0x0000, 0x4c53, 0x0000, 0x0000, 0x0000, 0x5d5b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d5d, 0x5d5c, 0x0000, 0x0000, 0x5d5f, - 0x0000, 0x0000, 0x0000, 0x5d5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_6c[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b61, - 0x0000, 0x4c31, 0x0000, 0x5d62, 0x5d63, 0x0000, 0x0000, 0x3524, 0x0000, 0x0000, 0x0000, 0x5d64, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5d66, 0x5d65, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3f65, 0x0000, 0x0000, 0x4939, 0x314a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4845, 0x0000, - 0x4475, 0x3d41, 0x3561, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4846, 0x0000, - 0x3c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d68, 0x0000, 0x3440, 0x0000, 0x0000, 0x3178, 0x0000, 0x0000, 0x4672, 0x5d67, 0x393e, - 0x4353, 0x0000, 0x5d69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d71, 0x0000, 0x5d6a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4241, 0x0000, 0x3562, 0x5d72, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3768, 0x0000, 0x0000, 0x3525, 0x5d70, 0x0000, - 0x0000, 0x5d6e, 0x5d6b, 0x4d60, 0x0000, 0x0000, 0x0000, 0x0000, 0x4440, 0x0000, 0x0000, 0x0000, 0x4659, 0x5d6c, 0x0000, 0x0000, - 0x5d74, 0x0000, 0x5d73, 0x3723, 0x0000, 0x0000, 0x322d, 0x0000, 0x0000, 0x3a3b, 0x5d6d, 0x5d6f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4b57, 0x4274, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b77, 0x0000, 0x0000, 0x5d7c, 0x0000, - 0x0000, 0x5d7d, 0x0000, 0x324f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a28, 0x4c7d, 0x5e21, 0x3c23, 0x3e42, 0x5d78, 0x5d7e, 0x3168, - 0x0000, 0x3637, 0x0000, 0x0000, 0x5d75, 0x5d7a, 0x0000, 0x0000, 0x0000, 0x4074, 0x4771, 0x0000, 0x4867, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5d77, 0x0000, 0x4b21, 0x0000, 0x5d79, 0x0000, 0x5e24, 0x0000, 0x5e22, 0x0000, 0x5d7b, 0x0000, 0x0000, - 0x0000, 0x4b22, 0x4748, 0x3563, 0x0000, 0x4525, 0x0000, 0x0000, 0x436d, 0x0000, 0x5e25, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e23, - 0x4259, 0x5d76, 0x0000, 0x314b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_6d[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d4e, 0x5e30, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5e2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4076, 0x0000, 0x5e2c, 0x0000, 0x4d6c, 0x0000, 0x0000, 0x4636, 0x5e26, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4445, 0x0000, 0x0000, 0x0000, 0x314c, 0x393f, 0x5e29, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3d27, 0x5e2e, 0x0000, 0x5e2d, 0x5e28, 0x0000, 0x5e2b, 0x0000, 0x0000, 0x3368, 0x0000, 0x5e2a, 0x4749, 0x0000, - 0x0000, 0x4e2e, 0x0000, 0x0000, 0x3e74, 0x4075, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e36, 0x5e34, 0x0000, 0x494d, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5e31, 0x5e33, 0x0000, 0x313a, 0x0000, 0x0000, 0x3940, 0x4f32, 0x0000, 0x333d, 0x0000, 0x4962, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4d61, 0x0000, 0x0000, 0x3324, 0x3f3b, 0x5e35, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e3a, 0x0000, 0x0000, 0x3e43, 0x0000, 0x0000, 0x0000, 0x4d30, 0x0000, 0x5e37, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5e32, 0x0000, 0x5e38, 0x0000, 0x0000, 0x0000, 0x4e5e, 0x0000, 0x4573, 0x4642, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3336, - 0x0000, 0x0000, 0x3155, 0x0000, 0x0000, 0x5e3e, 0x0000, 0x0000, 0x5e41, 0x0000, 0x0000, 0x0000, 0x4e43, 0x0000, 0x0000, 0x0000, - 0x4d64, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e48, 0x5e42, 0x5e3f, 0x0000, 0x0000, 0x0000, 0x4e54, 0x5e45, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3d4a, 0x5e47, 0x0000, 0x0000, 0x5e4c, 0x0000, 0x0000, 0x4571, 0x5e4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e44, 0x0000, - 0x0000, 0x4338, 0x0000, 0x0000, 0x5e4b, 0x0000, 0x5e40, 0x0000, 0x5e46, 0x0000, 0x5e4d, 0x307c, 0x5e43, 0x0000, 0x5e4e, 0x0000, - 0x0000, 0x3f3c, 0x0000, 0x3d5f, 0x0000, 0x4a25, 0x0000, 0x3a2e, 0x0000, 0x5e3b, 0x5e49, 0x453a, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_6e[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4036, 0x0000, 0x3369, 0x3a51, 0x3e44, 0x5e3d, 0x3d42, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x374c, 0x0000, 0x5e3c, 0x0000, 0x0000, 0x0000, 0x5e52, 0x3d6d, 0x383a, 0x0000, 0x5e61, 0x0000, 0x5e5b, - 0x3574, 0x454f, 0x0000, 0x5e56, 0x5e5f, 0x302f, 0x3132, 0x0000, 0x0000, 0x3239, 0x0000, 0x5e58, 0x422c, 0x5e4f, 0x5e51, 0x3941, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e62, 0x0000, 0x5e5d, 0x0000, 0x0000, 0x0000, 0x5e55, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5e5c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c2b, 0x0000, 0x0000, 0x5e5a, 0x5e5e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3850, 0x0000, 0x3e45, 0x0000, 0x0000, 0x4339, 0x0000, 0x0000, 0x0000, 0x5e54, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d2f, 0x0000, 0x0000, 0x0000, 0x5e57, 0x0000, 0x0000, 0x5e50, 0x4572, - 0x0000, 0x0000, 0x5e53, 0x0000, 0x0000, 0x0000, 0x5e59, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f51, 0x3c3e, - 0x4b7e, 0x0000, 0x5e63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x482e, 0x0000, 0x0000, 0x5e6f, - 0x383b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d60, 0x0000, 0x5e65, 0x0000, 0x0000, 0x0000, 0x4e2f, 0x3942, 0x0000, 0x5e72, - 0x0000, 0x0000, 0x306e, 0x0000, 0x0000, 0x5e70, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e64, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e6a, - 0x0000, 0x0000, 0x5e6c, 0x0000, 0x0000, 0x0000, 0x4d4f, 0x5e67, 0x0000, 0x0000, 0x452e, 0x0000, 0x0000, 0x5e69, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5e71, 0x0000, 0x5e6b, 0x4c47, 0x0000, 0x0000, 0x0000, 0x5e66, 0x0000, 0x3c22, 0x5e7e, 0x0000, 0x0000, 0x0000, - 0x0000, 0x336a, 0x0000, 0x5e68, 0x5e6d, 0x5e6e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x426c, 0x425a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e76, 0x0000, 0x0000, 0x5e7c, - 0x0000, 0x0000, 0x5e7a, 0x0000, 0x4529, 0x0000, 0x0000, 0x5f23, 0x5e77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e78, 0x5e60, -}; - -static const uint16_t unicode_to_jisx0208_6f[256] = { - 0x0000, 0x3579, 0x493a, 0x0000, 0x0000, 0x0000, 0x3c3f, 0x0000, 0x0000, 0x3977, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f33, - 0x0000, 0x5e74, 0x0000, 0x5f22, 0x3169, 0x4166, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4779, 0x0000, 0x3441, 0x4e7a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c21, 0x4452, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5e7b, 0x5e7d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4132, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f21, 0x5e79, - 0x0000, 0x5e73, 0x0000, 0x0000, 0x0000, 0x3443, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3769, 0x0000, 0x0000, 0x0000, 0x5f2f, 0x0000, 0x0000, 0x5f2a, 0x4078, 0x0000, 0x0000, 0x3363, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3d61, 0x0000, 0x5f33, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f2c, 0x442c, 0x5f29, - 0x4459, 0x0000, 0x0000, 0x0000, 0x5f4c, 0x0000, 0x0000, 0x0000, 0x5f26, 0x0000, 0x5f25, 0x0000, 0x5f2e, 0x0000, 0x0000, 0x0000, - 0x5f28, 0x5f27, 0x5f2d, 0x0000, 0x4021, 0x0000, 0x5f24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f30, 0x0000, - 0x0000, 0x5f31, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3442, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5f36, 0x0000, 0x5f35, 0x5f37, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4543, 0x0000, 0x5f34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3763, 0x4279, 0x5f32, 0x473b, 0x0000, 0x0000, 0x5f39, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5f3e, 0x5f3c, 0x0000, 0x0000, 0x5f3f, 0x0000, 0x0000, 0x5f42, 0x0000, 0x0000, 0x0000, 0x5f3b, - 0x396a, 0x4728, 0x0000, 0x0000, 0x5e39, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d74, 0x5f3d, 0x0000, 0x5f41, 0x4275, - 0x0000, 0x5f40, 0x0000, 0x5f2b, 0x0000, 0x0000, 0x6f69, 0x0000, 0x0000, 0x0000, 0x5f45, 0x0000, 0x0000, 0x0000, 0x5f49, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_70[256] = { - 0x0000, 0x5f47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f43, 0x0000, 0x5f44, 0x0000, 0x0000, 0x0000, 0x5f48, - 0x0000, 0x5f46, 0x0000, 0x0000, 0x0000, 0x494e, 0x0000, 0x0000, 0x5f4e, 0x0000, 0x5f4b, 0x5f4a, 0x0000, 0x5f4d, 0x4654, 0x5f4f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4375, 0x426d, 0x0000, 0x0000, 0x0000, 0x0000, 0x4025, 0x0000, 0x0000, 0x0000, - 0x5f50, 0x0000, 0x5f52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f51, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e75, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5f53, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4667, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5f54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3250, 0x0000, 0x0000, 0x0000, 0x4574, - 0x3325, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3564, 0x0000, 0x0000, 0x0000, 0x3c5e, 0x3a52, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f27, 0x3f66, 0x0000, 0x0000, 0x0000, 0x316a, 0x0000, - 0x0000, 0x0000, 0x5f56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f59, 0x433a, 0x5f5c, 0x5f57, - 0x0000, 0x0000, 0x0000, 0x5f5b, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f5a, 0x4540, 0x3059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e75, 0x0000, 0x0000, 0x5f5e, 0x0000, 0x0000, 0x0000, 0x3128, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f60, 0x0000, 0x0000, 0x0000, 0x5f5f, 0x0000, 0x5f5d, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x5f58, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b23, 0x0000, 0x0000, 0x0000, 0x5f62, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_71[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x316b, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f64, 0x4a32, 0x0000, 0x5f63, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4c35, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4133, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e46, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e7b, 0x0000, 0x0000, 0x5f6a, 0x0000, 0x4079, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f66, 0x5f6b, 0x0000, 0x0000, 0x316c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x5f69, 0x0000, 0x4761, 0x5f65, 0x5f68, 0x3e48, 0x0000, 0x4851, 0x0000, 0x0000, 0x5f6c, 0x0000, 0x3c51, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x407a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5f6f, 0x0000, 0x0000, 0x0000, 0x5f67, 0x0000, 0x3727, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f6d, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4d50, 0x5f70, 0x0000, 0x0000, 0x0000, 0x7426, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d4f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f71, 0x0000, 0x0000, 0x0000, 0x5f72, 0x0000, 0x0000, 0x0000, - 0x0000, 0x472e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f74, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f75, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4733, 0x0000, 0x0000, 0x0000, 0x0000, 0x4575, 0x5f77, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f79, 0x0000, - 0x4e55, 0x0000, 0x5f76, 0x0000, 0x5f78, 0x316d, 0x0000, 0x5f73, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x535b, - 0x5f7a, 0x0000, 0x0000, 0x0000, 0x0000, 0x4167, 0x3b38, 0x5f7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f7b, 0x3f24, 0x5259, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f7d, 0x0000, 0x0000, 0x0000, 0x6021, 0x0000, 0x5f6e, 0x5f7e, 0x0000, 0x0000, 0x6022, -}; - -static const uint16_t unicode_to_jisx0208_72[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x477a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6023, 0x0000, 0x0000, - 0x6024, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6025, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6026, 0x0000, 0x445e, 0x0000, 0x6028, 0x6027, 0x0000, 0x0000, - 0x6029, 0x0000, 0x602a, 0x0000, 0x0000, 0x3c5f, 0x4963, 0x0000, 0x0000, 0x0000, 0x4c6c, 0x602b, 0x602c, 0x4156, 0x3c24, 0x602d, - 0x602e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x602f, 0x4a52, 0x4847, 0x0000, 0x0000, 0x6030, 0x4757, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x442d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6031, 0x3267, 0x0000, 0x356d, 0x0000, 0x4c46, 0x0000, 0x4c36, - 0x0000, 0x3234, 0x4f34, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b52, 0x0000, 0x4a2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4037, 0x0000, 0x6032, 0x0000, 0x0000, 0x0000, 0x0000, 0x4643, 0x0000, 0x0000, 0x0000, 0x3823, 0x6033, 0x0000, - 0x3a54, 0x6035, 0x6034, 0x0000, 0x0000, 0x0000, 0x0000, 0x6036, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6037, 0x0000, 0x0000, 0x0000, 0x6038, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x353e, 0x0000, 0x6039, 0x0000, 0x0000, 0x0000, 0x0000, 0x603a, 0x0000, 0x0000, 0x0000, 0x0000, 0x3824, 0x0000, 0x0000, 0x4848, - 0x0000, 0x0000, 0x603c, 0x0000, 0x0000, 0x0000, 0x3e75, 0x0000, 0x0000, 0x603b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3638, 0x603d, 0x603f, 0x0000, 0x603e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6040, 0x0000, - 0x3851, 0x0000, 0x6041, 0x0000, 0x0000, 0x0000, 0x0000, 0x3669, 0x0000, 0x4140, 0x0000, 0x397d, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6043, 0x6044, 0x6042, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c6d, 0x0000, 0x0000, 0x4648, 0x3639, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6046, 0x432c, 0x6045, 0x0000, 0x0000, 0x4f35, 0x4762, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_73[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x604b, 0x6048, 0x0000, 0x0000, 0x0000, 0x4c54, 0x604a, 0x604c, 0x0000, 0x4e44, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6050, 0x0000, 0x0000, 0x0000, 0x604f, 0x4376, 0x472d, 0x0000, 0x0000, 0x3825, 0x604e, - 0x0000, 0x0000, 0x0000, 0x0000, 0x604d, 0x0000, 0x4d31, 0x4d32, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6051, 0x316e, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3976, 0x3b62, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6052, 0x6053, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6055, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3d43, 0x0000, 0x0000, 0x0000, 0x0000, 0x6057, 0x0000, 0x6056, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6058, 0x0000, 0x334d, 0x0000, 0x0000, 0x605a, 0x0000, 0x0000, 0x6059, 0x0000, 0x605c, 0x605b, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x383c, 0x0000, 0x0000, 0x4e28, 0x0000, 0x364c, 0x0000, 0x3226, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x366a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3461, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4e68, 0x605e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6060, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6061, 0x0000, 0x3251, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x605d, 0x0000, 0x3b39, 0x0000, 0x0000, 0x4441, 0x605f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6064, 0x0000, - 0x3c6e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6062, 0x0000, 0x0000, 0x0000, 0x0000, 0x373e, 0x0000, 0x0000, 0x4849, 0x6063, 0x0000, - 0x0000, 0x607e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x383d, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_74[256] = { - 0x0000, 0x0000, 0x0000, 0x3565, 0x0000, 0x6066, 0x4d7d, 0x0000, 0x0000, 0x4e30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4276, 0x0000, 0x0000, 0x6068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x606a, 0x4e56, 0x3657, 0x487c, 0x474a, 0x0000, 0x0000, 0x0000, 0x606b, 0x0000, 0x0000, 0x0000, 0x0000, 0x606d, - 0x0000, 0x6070, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x606c, 0x0000, 0x0000, 0x0000, 0x606f, 0x386a, 0x314d, 0x6071, 0x0000, 0x3f70, 0x606e, - 0x4e5c, 0x0000, 0x0000, 0x6074, 0x7424, 0x0000, 0x0000, 0x0000, 0x0000, 0x6072, 0x6075, 0x0000, 0x0000, 0x0000, 0x0000, 0x6067, - 0x6073, 0x0000, 0x0000, 0x3a3c, 0x0000, 0x0000, 0x6076, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6077, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4d7e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6078, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6079, 0x0000, - 0x0000, 0x0000, 0x6065, 0x0000, 0x0000, 0x0000, 0x0000, 0x607a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c25, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x607b, 0x0000, 0x0000, 0x0000, 0x0000, 0x607c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x607d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x313b, 0x0000, 0x0000, 0x0000, - 0x6121, 0x0000, 0x493b, 0x6122, 0x0000, 0x0000, 0x3424, 0x6123, 0x0000, 0x6124, 0x0000, 0x0000, 0x0000, 0x0000, 0x6125, 0x0000, - 0x6127, 0x6128, 0x6126, 0x0000, 0x0000, 0x0000, 0x4953, 0x612a, 0x6129, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_75[256] = { - 0x0000, 0x0000, 0x0000, 0x612c, 0x612b, 0x612d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x612e, 0x6130, 0x612f, 0x0000, - 0x0000, 0x3979, 0x0000, 0x6132, 0x0000, 0x6131, 0x0000, 0x0000, 0x3445, 0x0000, 0x3f53, 0x0000, 0x453c, 0x0000, 0x6133, 0x4038, - 0x0000, 0x0000, 0x0000, 0x3b3a, 0x0000, 0x3179, 0x6134, 0x0000, 0x4d51, 0x0000, 0x0000, 0x4a63, 0x6135, 0x0000, 0x0000, 0x0000, - 0x4544, 0x4d33, 0x3943, 0x3f3d, 0x0000, 0x0000, 0x0000, 0x434b, 0x5234, 0x0000, 0x442e, 0x3268, 0x6136, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6137, 0x0000, 0x613c, 0x0000, 0x0000, 0x613a, 0x6139, 0x5a42, 0x3326, 0x6138, 0x0000, 0x305a, - 0x0000, 0x482a, 0x0000, 0x0000, 0x484a, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e31, 0x613d, 0x613b, 0x435c, 0x4026, 0x0000, 0x0000, - 0x482b, 0x0000, 0x492d, 0x0000, 0x613f, 0x4e2c, 0x374d, 0x6140, 0x0000, 0x613e, 0x4856, 0x6141, 0x0000, 0x6142, 0x0000, 0x0000, - 0x305b, 0x0000, 0x0000, 0x3e76, 0x6147, 0x0000, 0x6144, 0x466d, 0x6143, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3526, - 0x0000, 0x0000, 0x614a, 0x0000, 0x0000, 0x0000, 0x6145, 0x6146, 0x0000, 0x6149, 0x6148, 0x4925, 0x0000, 0x0000, 0x4142, 0x4141, - 0x0000, 0x353f, 0x0000, 0x0000, 0x614b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x614c, 0x0000, 0x0000, 0x614d, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x614f, 0x0000, 0x614e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3156, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6157, 0x4868, 0x6151, 0x0000, 0x6153, 0x0000, 0x0000, 0x6155, 0x3f3e, 0x0000, 0x0000, 0x6156, 0x6154, 0x3c40, 0x0000, - 0x0000, 0x0000, 0x6150, 0x6152, 0x0000, 0x4942, 0x0000, 0x3e49, 0x0000, 0x0000, 0x6159, 0x0000, 0x0000, 0x6158, 0x0000, 0x0000, - 0x0000, 0x0000, 0x615a, 0x0000, 0x3c26, 0x3a2f, 0x0000, 0x0000, 0x4577, 0x615b, 0x0000, 0x444b, 0x0000, 0x0000, 0x615d, 0x0000, - 0x0000, 0x0000, 0x4e21, 0x615c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6162, 0x0000, 0x6164, 0x6165, 0x4354, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6163, 0x0000, 0x6160, 0x0000, 0x615e, 0x615f, -}; - -static const uint16_t unicode_to_jisx0208_76[256] = { - 0x0000, 0x6161, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6168, 0x0000, 0x6166, 0x0000, 0x6167, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6169, - 0x616b, 0x616c, 0x616d, 0x0000, 0x616e, 0x0000, 0x0000, 0x616a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6170, 0x0000, 0x0000, 0x0000, 0x616f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6171, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4e45, 0x0000, 0x0000, 0x0000, 0x6174, 0x6172, 0x6173, 0x0000, 0x0000, 0x0000, 0x3462, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4c7e, 0x0000, 0x0000, 0x0000, 0x4a4a, 0x0000, 0x6176, 0x0000, 0x0000, 0x0000, 0x6175, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6177, 0x6178, 0x0000, 0x0000, 0x0000, 0x0000, 0x617c, 0x6179, 0x617a, 0x617b, 0x0000, 0x617d, 0x0000, 0x0000, 0x0000, - 0x617e, 0x0000, 0x6221, 0x0000, 0x0000, 0x0000, 0x6222, 0x0000, 0x6223, 0x0000, 0x482f, 0x4550, 0x6224, 0x4772, 0x4934, 0x0000, - 0x6225, 0x0000, 0x0000, 0x6226, 0x452a, 0x0000, 0x3327, 0x3944, 0x6227, 0x0000, 0x0000, 0x6228, 0x0000, 0x0000, 0x6229, 0x0000, - 0x3b29, 0x0000, 0x0000, 0x622b, 0x0000, 0x0000, 0x622a, 0x0000, 0x0000, 0x622c, 0x622d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4869, 0x0000, - 0x622e, 0x0000, 0x0000, 0x0000, 0x622f, 0x0000, 0x0000, 0x7369, 0x6230, 0x6231, 0x6232, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b2e, - 0x0000, 0x0000, 0x6233, 0x4756, 0x0000, 0x0000, 0x4b5f, 0x0000, 0x314e, 0x0000, 0x3157, 0x0000, 0x0000, 0x6234, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6236, 0x0000, 0x0000, 0x0000, 0x6235, 0x4570, 0x0000, 0x0000, 0x0000, 0x4039, 0x5d39, 0x0000, 0x6237, 0x4c41, - 0x0000, 0x6238, 0x0000, 0x3446, 0x4857, 0x6239, 0x0000, 0x623a, 0x0000, 0x0000, 0x623b, 0x0000, 0x0000, 0x0000, 0x4c5c, 0x0000, - 0x0000, 0x0000, 0x4c55, 0x0000, 0x443e, 0x0000, 0x0000, 0x0000, 0x416a, 0x0000, 0x0000, 0x623d, 0x0000, 0x0000, 0x3d62, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_77[256] = { - 0x0000, 0x3e4a, 0x0000, 0x0000, 0x6240, 0x0000, 0x0000, 0x623f, 0x623e, 0x487d, 0x0000, 0x3447, 0x3829, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6246, 0x0000, 0x0000, 0x6243, 0x3f3f, - 0x4c32, 0x0000, 0x0000, 0x0000, 0x6242, 0x6244, 0x6245, 0x0000, 0x0000, 0x6241, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6247, 0x6248, 0x0000, 0x442f, 0x0000, 0x3463, 0x0000, 0x0000, 0x0000, - 0x4365, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6249, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x624a, 0x624d, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3f67, 0x0000, 0x4644, 0x0000, 0x624e, 0x4b53, 0x0000, 0x624b, 0x0000, 0x0000, 0x624c, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6251, 0x0000, 0x0000, 0x0000, 0x0000, 0x6250, 0x624f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6253, 0x0000, 0x0000, 0x6252, 0x0000, - 0x0000, 0x6254, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6256, 0x0000, - 0x6255, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a4d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d56, 0x4e46, 0x0000, 0x0000, - 0x6257, 0x0000, 0x0000, 0x4637, 0x0000, 0x0000, 0x6258, 0x0000, 0x0000, 0x6259, 0x0000, 0x625d, 0x625b, 0x625c, 0x0000, 0x625a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x625e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x625f, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6260, 0x0000, 0x0000, 0x6261, 0x4c37, 0x6262, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4c70, 0x6263, 0x0000, 0x434e, 0x0000, 0x476a, 0x0000, 0x366b, 0x0000, 0x0000, 0x0000, 0x433b, 0x6264, 0x363a, - 0x0000, 0x0000, 0x0000, 0x4050, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6265, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_78[256] = { - 0x0000, 0x0000, 0x3a3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6266, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6267, 0x0000, 0x3826, 0x3a55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6269, 0x0000, 0x0000, 0x0000, 0x0000, 0x4556, 0x3a56, 0x354e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4b24, 0x0000, 0x474b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4557, 0x0000, 0x0000, 0x0000, 0x0000, 0x395c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x626b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e4b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e32, 0x3945, 0x0000, 0x0000, 0x3827, - 0x0000, 0x0000, 0x4823, 0x0000, 0x626d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x626f, 0x0000, 0x0000, 0x0000, - 0x0000, 0x386b, 0x0000, 0x0000, 0x0000, 0x0000, 0x626e, 0x4476, 0x0000, 0x0000, 0x0000, 0x0000, 0x6271, 0x3337, 0x626c, 0x0000, - 0x0000, 0x486a, 0x0000, 0x3130, 0x0000, 0x3a6c, 0x0000, 0x4f52, 0x0000, 0x0000, 0x6270, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6272, 0x0000, 0x0000, 0x0000, 0x4a4b, 0x0000, 0x4059, 0x6274, 0x0000, 0x0000, 0x0000, 0x0000, 0x6275, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6273, 0x0000, 0x0000, 0x0000, 0x0000, 0x334e, 0x0000, 0x627b, 0x0000, 0x627a, 0x0000, - 0x0000, 0x3c27, 0x0000, 0x0000, 0x0000, 0x627c, 0x6277, 0x0000, 0x0000, 0x0000, 0x627d, 0x6278, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4858, 0x6276, 0x0000, 0x0000, 0x6279, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6322, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6321, 0x4b61, 0x0000, 0x0000, 0x0000, 0x627e, 0x0000, 0x0000, 0x306b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6324, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6323, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_79[256] = { - 0x0000, 0x3e4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6325, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4143, 0x0000, - 0x0000, 0x6327, 0x6326, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6328, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6268, 0x0000, 0x0000, 0x0000, 0x626a, 0x632a, 0x6329, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c28, 0x0000, 0x4e69, 0x0000, 0x3c52, 0x0000, - 0x632b, 0x3737, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3540, 0x3527, 0x3b63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4d34, 0x0000, 0x0000, 0x6331, 0x0000, 0x6330, 0x4144, 0x632d, 0x0000, 0x0000, 0x632f, 0x0000, 0x0000, 0x3d4b, 0x3f40, 0x632e, - 0x632c, 0x0000, 0x472a, 0x0000, 0x0000, 0x3e4d, 0x0000, 0x0000, 0x493c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a57, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4578, 0x0000, 0x0000, 0x6332, 0x0000, 0x0000, 0x0000, 0x0000, 0x6333, - 0x6349, 0x3658, 0x0000, 0x0000, 0x4f3d, 0x4135, 0x0000, 0x0000, 0x0000, 0x0000, 0x6334, 0x0000, 0x0000, 0x3252, 0x4477, 0x4a21, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6335, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x357a, 0x6336, 0x0000, 0x0000, 0x6338, 0x0000, 0x0000, 0x0000, 0x6339, 0x0000, - 0x4729, 0x0000, 0x0000, 0x633a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x633b, 0x633c, 0x0000, 0x0000, 0x3659, 0x3253, 0x4645, - 0x3d28, 0x3b64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x633d, 0x0000, 0x3d29, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x324a, 0x4943, 0x0000, 0x0000, 0x633e, 0x0000, 0x0000, 0x486b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4145, - 0x0000, 0x6341, 0x0000, 0x6342, 0x4769, 0x0000, 0x3f41, 0x633f, 0x0000, 0x4361, 0x0000, 0x0000, 0x6340, 0x0000, 0x0000, 0x0000, - 0x3e4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x305c, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_7a[256] = { - 0x3529, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6343, 0x0000, 0x0000, 0x4478, 0x0000, 0x6344, 0x4047, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4c2d, 0x0000, 0x0000, 0x4923, 0x6345, 0x6346, 0x4355, 0x0000, 0x4e47, 0x0000, 0x0000, 0x6348, - 0x6347, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c6f, 0x0000, - 0x0000, 0x634a, 0x3070, 0x0000, 0x0000, 0x0000, 0x0000, 0x634d, 0x0000, 0x0000, 0x0000, 0x634b, 0x3254, 0x374e, 0x634c, 0x3946, - 0x3972, 0x0000, 0x4a66, 0x634e, 0x0000, 0x0000, 0x4b54, 0x0000, 0x0000, 0x6350, 0x0000, 0x0000, 0x0000, 0x4051, 0x314f, 0x323a, - 0x302c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x634f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6351, 0x6352, 0x3e77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6353, 0x0000, 0x334f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6355, 0x0000, 0x0000, 0x0000, 0x376a, 0x0000, 0x3566, 0x0000, 0x0000, 0x6356, 0x3675, 0x0000, 0x0000, 0x6357, 0x0000, 0x407c, - 0x0000, 0x464d, 0x0000, 0x4060, 0x3a75, 0x0000, 0x0000, 0x0000, 0x6358, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4362, 0x416b, 0x0000, 0x635a, 0x635c, 0x6359, 0x635b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3722, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x635d, 0x3726, 0x0000, 0x0000, 0x0000, 0x3567, 0x4d52, - 0x635f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6360, 0x0000, 0x0000, 0x0000, 0x312e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6363, - 0x0000, 0x0000, 0x0000, 0x3376, 0x6362, 0x6361, 0x0000, 0x6365, 0x635e, 0x0000, 0x6366, 0x4e29, 0x0000, 0x6367, 0x0000, 0x6368, - 0x0000, 0x0000, 0x5474, 0x636a, 0x0000, 0x6369, 0x0000, 0x0000, 0x0000, 0x636b, 0x636c, 0x0000, 0x4e35, 0x636d, 0x0000, 0x706f, - 0x3e4f, 0x636e, 0x636f, 0x3d57, 0x0000, 0x4638, 0x6370, 0x0000, 0x0000, 0x0000, 0x4328, 0x0000, 0x0000, 0x6371, 0x0000, 0x433c, - 0x6372, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3625, 0x0000, 0x513f, 0x435d, 0x3c33, 0x0000, 0x0000, 0x0000, 0x0000, 0x3448, -}; - -static const uint16_t unicode_to_jisx0208_7b[256] = { - 0x0000, 0x0000, 0x6373, 0x0000, 0x6422, 0x0000, 0x6376, 0x0000, 0x3568, 0x0000, 0x6375, 0x6424, 0x0000, 0x0000, 0x0000, 0x6374, - 0x0000, 0x3e50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6378, 0x6379, 0x0000, 0x452b, 0x0000, 0x0000, 0x637a, 0x0000, - 0x335e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f5a, 0x4964, 0x0000, 0x637c, 0x0000, 0x0000, 0x0000, 0x4268, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6377, 0x0000, 0x637b, 0x637d, 0x0000, 0x0000, 0x3a7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6426, 0x492e, 0x0000, 0x4826, 0x4579, 0x0000, 0x365a, 0x6425, 0x6423, 0x0000, 0x4835, - 0x637e, 0x435e, 0x457b, 0x0000, 0x457a, 0x0000, 0x3a76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6438, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6428, 0x0000, 0x642a, 0x0000, 0x0000, 0x0000, 0x0000, 0x642d, 0x0000, 0x642e, 0x0000, - 0x642b, 0x642c, 0x0000, 0x0000, 0x6429, 0x6427, 0x0000, 0x0000, 0x0000, 0x0000, 0x6421, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a4f, 0x3255, 0x0000, 0x0000, 0x0000, 0x6435, 0x0000, 0x6432, 0x0000, 0x6437, - 0x0000, 0x0000, 0x6436, 0x0000, 0x4773, 0x4c27, 0x0000, 0x3b3b, 0x6430, 0x6439, 0x6434, 0x0000, 0x6433, 0x642f, 0x0000, 0x6431, - 0x0000, 0x3449, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x433d, 0x0000, 0x0000, 0x407d, 0x0000, 0x0000, - 0x0000, 0x4822, 0x0000, 0x0000, 0x643e, 0x0000, 0x0000, 0x0000, 0x4824, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4061, 0x643b, 0x0000, 0x0000, 0x484f, 0x0000, 0x643f, 0x4a53, 0x0000, 0x435b, 0x0000, 0x643a, 0x643c, 0x0000, 0x0000, 0x643d, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6440, 0x0000, 0x0000, - 0x3c44, 0x0000, 0x0000, 0x0000, 0x4646, 0x6445, 0x6444, 0x0000, 0x0000, 0x6441, 0x0000, 0x0000, 0x0000, 0x4f36, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x644a, 0x0000, 0x0000, 0x644e, 0x644b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_7c[256] = { - 0x6447, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6448, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x644d, 0x0000, 0x0000, - 0x0000, 0x6442, 0x5255, 0x6449, 0x6443, 0x0000, 0x0000, 0x644c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6452, - 0x0000, 0x344a, 0x0000, 0x644f, 0x0000, 0x0000, 0x0000, 0x6450, 0x0000, 0x0000, 0x6451, 0x6454, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6453, 0x4876, 0x0000, 0x0000, 0x0000, 0x0000, 0x6455, 0x4e7c, 0x4a6d, - 0x645a, 0x0000, 0x0000, 0x6457, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6456, 0x4052, 0x0000, 0x6459, - 0x645b, 0x0000, 0x0000, 0x0000, 0x6458, 0x0000, 0x645f, 0x0000, 0x645c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x645d, - 0x6446, 0x0000, 0x0000, 0x0000, 0x645e, 0x6460, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6461, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4a46, 0x0000, 0x6462, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c62, 0x0000, - 0x0000, 0x364e, 0x3729, 0x6463, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a34, 0x0000, 0x3f68, 0x0000, 0x4c30, 0x0000, 0x0000, - 0x6464, 0x0000, 0x4e33, 0x0000, 0x0000, 0x4774, 0x0000, 0x4146, 0x4734, 0x0000, 0x0000, 0x3d4d, 0x0000, 0x0000, 0x0000, 0x3040, - 0x0000, 0x6469, 0x6467, 0x0000, 0x6465, 0x3421, 0x0000, 0x3e51, 0x646a, 0x0000, 0x0000, 0x6468, 0x0000, 0x6466, 0x646e, 0x0000, - 0x0000, 0x646d, 0x646c, 0x646b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x646f, 0x0000, 0x0000, 0x0000, 0x6470, 0x403a, 0x0000, - 0x6471, 0x0000, 0x6473, 0x0000, 0x0000, 0x6472, 0x0000, 0x0000, 0x0000, 0x0000, 0x3852, 0x0000, 0x0000, 0x0000, 0x4138, 0x0000, - 0x0000, 0x0000, 0x6475, 0x0000, 0x0000, 0x0000, 0x457c, 0x0000, 0x6474, 0x0000, 0x0000, 0x0000, 0x6476, 0x0000, 0x4a35, 0x416c, - 0x3947, 0x0000, 0x6477, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6479, - 0x0000, 0x0000, 0x647a, 0x0000, 0x647b, 0x0000, 0x647c, 0x0000, 0x3b65, 0x0000, 0x647d, 0x374f, 0x0000, 0x0000, 0x356a, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_7d[256] = { - 0x352a, 0x0000, 0x6521, 0x0000, 0x4c73, 0x3948, 0x647e, 0x0000, 0x0000, 0x0000, 0x6524, 0x4c66, 0x0000, 0x473c, 0x0000, 0x0000, - 0x4933, 0x0000, 0x0000, 0x0000, 0x3d63, 0x6523, 0x0000, 0x3c53, 0x3949, 0x3b66, 0x3569, 0x4a36, 0x6522, 0x0000, 0x0000, 0x0000, - 0x4147, 0x4b42, 0x3a77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b67, 0x445d, 0x0000, 0x6527, 0x4e5f, - 0x3a59, 0x0000, 0x6528, 0x3f42, 0x0000, 0x652a, 0x0000, 0x0000, 0x0000, 0x3e52, 0x3a30, 0x0000, 0x0000, 0x0000, 0x0000, 0x6529, - 0x0000, 0x0000, 0x3d2a, 0x383e, 0x4148, 0x6525, 0x652b, 0x0000, 0x0000, 0x0000, 0x0000, 0x6526, 0x3750, 0x0000, 0x652e, 0x6532, - 0x376b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x652d, 0x0000, 0x0000, 0x0000, 0x0000, 0x6536, 0x0000, 0x0000, 0x394a, 0x0000, - 0x0000, 0x4d6d, 0x303c, 0x6533, 0x0000, 0x0000, 0x356b, 0x0000, 0x6530, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6531, 0x0000, - 0x0000, 0x457d, 0x652f, 0x652c, 0x0000, 0x3328, 0x4064, 0x0000, 0x0000, 0x3828, 0x0000, 0x0000, 0x0000, 0x6538, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6535, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6537, - 0x0000, 0x0000, 0x0000, 0x6534, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3751, 0x4233, 0x6539, 0x416e, 0x0000, 0x0000, 0x6546, - 0x0000, 0x0000, 0x6542, 0x653c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6540, 0x3c7a, 0x305d, 0x653b, 0x6543, - 0x6547, 0x394b, 0x4c56, 0x0000, 0x4456, 0x653d, 0x0000, 0x0000, 0x6545, 0x0000, 0x653a, 0x433e, 0x0000, 0x653f, 0x303d, 0x4c4a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x653e, 0x0000, 0x0000, 0x365b, 0x486c, 0x0000, 0x0000, 0x0000, 0x416d, - 0x0000, 0x4e50, 0x3d6f, 0x0000, 0x0000, 0x656e, 0x0000, 0x0000, 0x6548, 0x0000, 0x407e, 0x0000, 0x6544, 0x6549, 0x654b, 0x0000, - 0x4479, 0x654e, 0x0000, 0x0000, 0x654a, 0x0000, 0x0000, 0x0000, 0x4a54, 0x344b, 0x0000, 0x0000, 0x4c4b, 0x0000, 0x0000, 0x305e, - 0x0000, 0x0000, 0x654d, 0x0000, 0x4e7d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x654c, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_7e[256] = { - 0x0000, 0x316f, 0x0000, 0x0000, 0x466c, 0x654f, 0x0000, 0x0000, 0x0000, 0x6556, 0x6550, 0x6557, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6553, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x477b, 0x0000, 0x0000, 0x3c4a, 0x6555, - 0x0000, 0x6552, 0x6558, 0x6551, 0x0000, 0x0000, 0x3d44, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b25, 0x0000, 0x0000, 0x3d4c, 0x0000, - 0x0000, 0x6554, 0x6560, 0x0000, 0x0000, 0x655c, 0x0000, 0x655f, 0x0000, 0x655d, 0x6561, 0x655b, 0x0000, 0x6541, 0x4053, 0x0000, - 0x0000, 0x484b, 0x0000, 0x655e, 0x0000, 0x0000, 0x6559, 0x0000, 0x0000, 0x0000, 0x4121, 0x3752, 0x0000, 0x3d2b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3f25, 0x4136, 0x6564, 0x0000, 0x0000, 0x6566, 0x6567, 0x0000, 0x0000, 0x6563, 0x6565, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x655a, 0x6562, 0x0000, 0x656a, 0x6569, 0x0000, 0x0000, 0x4b7a, 0x0000, 0x0000, - 0x372b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6568, 0x0000, 0x656c, 0x656b, 0x656f, 0x0000, 0x6571, - 0x0000, 0x0000, 0x3b3c, 0x656d, 0x0000, 0x0000, 0x0000, 0x0000, 0x6572, 0x6573, 0x0000, 0x0000, 0x6574, 0x0000, 0x657a, 0x453b, - 0x6576, 0x0000, 0x6575, 0x6577, 0x6578, 0x0000, 0x6579, 0x0000, 0x0000, 0x0000, 0x0000, 0x657b, 0x657c, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_7f[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x344c, 0x0000, 0x657d, 0x0000, 0x657e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6621, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6622, 0x6623, 0x6624, 0x0000, - 0x6625, 0x6626, 0x0000, 0x0000, 0x6628, 0x6627, 0x0000, 0x0000, 0x6629, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x662a, - 0x662b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x662e, 0x662c, 0x662d, 0x3a61, 0x3753, 0x0000, 0x0000, 0x4356, 0x0000, - 0x4833, 0x0000, 0x3d70, 0x0000, 0x0000, 0x474d, 0x0000, 0x486d, 0x662f, 0x586d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6630, 0x6632, 0x0000, 0x4d65, 0x6631, 0x6634, 0x6633, 0x0000, 0x4d53, 0x0000, 0x6635, 0x0000, 0x487e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6636, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6639, 0x0000, 0x0000, 0x6638, 0x6637, 0x0000, - 0x0000, 0x0000, 0x0000, 0x663a, 0x3732, 0x0000, 0x0000, 0x0000, 0x4122, 0x3541, 0x0000, 0x0000, 0x0000, 0x0000, 0x663e, 0x663b, - 0x0000, 0x0000, 0x663c, 0x0000, 0x0000, 0x0000, 0x663f, 0x0000, 0x6640, 0x663d, 0x0000, 0x0000, 0x0000, 0x3129, 0x0000, 0x0000, - 0x0000, 0x3227, 0x0000, 0x0000, 0x0000, 0x6642, 0x6643, 0x0000, 0x0000, 0x0000, 0x6644, 0x0000, 0x4d62, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3d2c, 0x0000, 0x6646, 0x6645, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3f69, 0x6647, 0x0000, 0x0000, 0x0000, 0x0000, 0x6648, 0x0000, 0x0000, 0x6649, 0x0000, 0x3465, 0x0000, 0x0000, 0x0000, 0x0000, - 0x344d, 0x0000, 0x0000, 0x664a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x664b, 0x0000, 0x4b5d, 0x4d63, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_80[256] = { - 0x4d54, 0x4f37, 0x0000, 0x394d, 0x664e, 0x3c54, 0x664d, 0x0000, 0x0000, 0x0000, 0x0000, 0x664f, 0x3c29, 0x0000, 0x0000, 0x0000, - 0x4251, 0x0000, 0x6650, 0x0000, 0x0000, 0x394c, 0x0000, 0x4c57, 0x6651, 0x6652, 0x0000, 0x0000, 0x6653, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6654, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6655, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3c2a, 0x0000, 0x0000, 0x4c6d, 0x0000, 0x0000, 0x0000, 0x0000, 0x6657, 0x0000, 0x433f, 0x0000, 0x6656, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6659, 0x0000, 0x0000, 0x0000, 0x6658, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x665a, 0x0000, 0x0000, 0x0000, 0x403b, 0x0000, 0x665b, 0x0000, 0x665c, 0x0000, 0x0000, 0x0000, 0x4a39, 0x665d, - 0x0000, 0x416f, 0x665e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x665f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e7e, - 0x6662, 0x0000, 0x6661, 0x6660, 0x4430, 0x0000, 0x6663, 0x3f26, 0x0000, 0x6664, 0x0000, 0x0000, 0x0000, 0x6665, 0x4f38, 0x6666, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6667, 0x6669, 0x6668, 0x4825, 0x0000, 0x4679, 0x0000, 0x4f3e, 0x4829, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x666b, 0x0000, 0x0000, 0x3e53, 0x0000, 0x492a, 0x0000, 0x666c, 0x666a, 0x0000, 0x344e, 0x0000, 0x0000, - 0x0000, 0x3854, 0x3b68, 0x0000, 0x0000, 0x486e, 0x0000, 0x0000, 0x0000, 0x382a, 0x4b43, 0x0000, 0x666f, 0x666d, 0x0000, 0x394e, - 0x0000, 0x394f, 0x3069, 0x0000, 0x3a68, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4759, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x305f, 0x6674, 0x0000, 0x4340, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4758, 0x0000, 0x425b, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6676, 0x0000, 0x0000, 0x6672, 0x6675, 0x6670, 0x0000, 0x6673, 0x4b26, 0x0000, - 0x0000, 0x3855, 0x0000, 0x0000, 0x307d, 0x6671, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6678, - 0x0000, 0x6679, 0x0000, 0x0000, 0x4639, 0x0000, 0x0000, 0x0000, 0x363b, 0x0000, 0x0000, 0x0000, 0x6726, 0x473d, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_81[256] = { - 0x0000, 0x0000, 0x3b69, 0x0000, 0x0000, 0x363c, 0x4048, 0x4f46, 0x4c2e, 0x6677, 0x4054, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3553, 0x667a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x667c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x667b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x667d, - 0x0000, 0x4326, 0x0000, 0x473e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4431, 0x0000, 0x0000, 0x0000, 0x0000, 0x6723, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6722, 0x0000, 0x0000, 0x0000, 0x0000, 0x667e, 0x0000, 0x0000, 0x3f55, 0x0000, - 0x4965, 0x6725, 0x0000, 0x6724, 0x3950, 0x4f53, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6735, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6729, 0x672a, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c70, 0x0000, 0x0000, 0x6728, 0x0000, - 0x3978, 0x6727, 0x0000, 0x0000, 0x672b, 0x0000, 0x0000, 0x0000, 0x4432, 0x4a22, 0x4123, 0x0000, 0x0000, 0x0000, 0x0000, 0x425c, - 0x672f, 0x0000, 0x6730, 0x672c, 0x0000, 0x0000, 0x0000, 0x0000, 0x672d, 0x0000, 0x672e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3951, - 0x0000, 0x0000, 0x0000, 0x6736, 0x0000, 0x6732, 0x0000, 0x0000, 0x0000, 0x0000, 0x4966, 0x0000, 0x4b6c, 0x4928, 0x0000, 0x0000, - 0x6731, 0x0000, 0x0000, 0x6734, 0x6733, 0x0000, 0x0000, 0x0000, 0x4b44, 0x6737, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6738, 0x0000, 0x0000, 0x4137, 0x0000, 0x6739, 0x0000, 0x0000, 0x673b, 0x0000, 0x673f, 0x0000, 0x0000, 0x673c, 0x673a, 0x473f, - 0x673d, 0x0000, 0x673e, 0x0000, 0x0000, 0x0000, 0x3232, 0x0000, 0x6745, 0x6740, 0x0000, 0x0000, 0x0000, 0x6741, 0x0000, 0x0000, - 0x0000, 0x6742, 0x0000, 0x4221, 0x0000, 0x0000, 0x0000, 0x0000, 0x6744, 0x6743, 0x6746, 0x0000, 0x0000, 0x0000, 0x0000, 0x6747, - 0x6748, 0x0000, 0x0000, 0x3f43, 0x0000, 0x3269, 0x0000, 0x6749, 0x4e57, 0x0000, 0x3c2b, 0x0000, 0x0000, 0x3d2d, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3b6a, 0x4357, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x674a, 0x674b, 0x3131, 0x0000, 0x674c, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_82[256] = { - 0x0000, 0x674d, 0x674e, 0x0000, 0x0000, 0x674f, 0x0000, 0x6750, 0x363d, 0x5a2a, 0x6751, 0x0000, 0x4065, 0x6752, 0x3c4b, 0x0000, - 0x6753, 0x0000, 0x5030, 0x0000, 0x0000, 0x0000, 0x6754, 0x4a5e, 0x345c, 0x0000, 0x0000, 0x4124, 0x3d58, 0x0000, 0x4971, 0x3d2e, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6755, 0x3952, 0x6756, 0x484c, 0x0000, 0x6764, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6758, 0x0000, 0x4249, 0x4775, 0x383f, 0x6757, 0x4125, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6759, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x447a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x675b, 0x675a, 0x675d, 0x0000, 0x0000, 0x675c, 0x0000, 0x675e, - 0x0000, 0x0000, 0x6760, 0x0000, 0x675f, 0x0000, 0x344f, 0x0000, 0x6761, 0x0000, 0x6762, 0x6763, 0x0000, 0x0000, 0x3a31, 0x4e49, - 0x0000, 0x6765, 0x3f27, 0x0000, 0x0000, 0x0000, 0x3170, 0x6766, 0x6767, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6768, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3072, 0x0000, 0x6769, 0x0000, 0x0000, - 0x0000, 0x0000, 0x676a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4967, 0x0000, 0x0000, 0x0000, 0x3c47, 0x0000, 0x676c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3329, 0x3032, 0x0000, 0x0000, 0x0000, 0x0000, 0x676b, 0x676e, 0x474e, 0x0000, 0x3f44, - 0x0000, 0x3256, 0x0000, 0x4b27, 0x0000, 0x0000, 0x0000, 0x0000, 0x375d, 0x365c, 0x0000, 0x676d, 0x0000, 0x326a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3423, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3171, 0x6772, 0x4e6a, 0x425d, 0x0000, 0x0000, 0x4944, 0x0000, 0x677e, 0x0000, 0x3257, 0x677c, 0x0000, 0x677a, 0x6771, - 0x0000, 0x676f, 0x0000, 0x6770, 0x0000, 0x3c63, 0x366c, 0x4377, 0x0000, 0x0000, 0x0000, 0x4651, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3151, 0x0000, 0x6774, 0x6773, 0x0000, 0x0000, 0x0000, 0x0000, 0x6779, 0x6775, 0x6778, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_83[256] = { - 0x0000, 0x0000, 0x4c50, 0x6777, 0x3258, 0x337d, 0x677b, 0x0000, 0x0000, 0x677d, 0x0000, 0x0000, 0x0000, 0x0000, 0x3754, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6823, 0x682c, 0x682d, 0x0000, 0x0000, 0x0000, 0x302b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6834, 0x0000, 0x0000, 0x0000, 0x0000, 0x3071, 0x0000, 0x0000, 0x682b, 0x0000, 0x0000, 0x0000, 0x682a, - 0x0000, 0x6825, 0x6824, 0x0000, 0x6822, 0x6821, 0x4363, 0x0000, 0x427b, 0x6827, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6826, 0x0000, 0x0000, 0x0000, 0x0000, 0x6829, 0x0000, 0x0000, 0x0000, 0x4170, 0x3755, 0x0000, 0x0000, 0x0000, 0x0000, 0x3141, - 0x6828, 0x0000, 0x3953, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4171, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x683a, 0x0000, 0x683b, 0x0000, 0x3259, 0x0000, 0x0000, 0x0000, 0x322e, 0x6838, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x682e, 0x0000, 0x6836, 0x0000, 0x683d, 0x6837, 0x0000, 0x0000, 0x0000, 0x6835, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6776, 0x0000, 0x0000, 0x6833, 0x0000, 0x0000, 0x0000, 0x682f, 0x0000, 0x0000, 0x0000, 0x3450, 0x6831, - 0x683c, 0x0000, 0x6832, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x683e, 0x0000, 0x6830, 0x477c, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4d69, 0x0000, 0x0000, 0x0000, 0x6839, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x684f, 0x0000, 0x0000, - 0x0000, 0x6847, 0x0000, 0x0000, 0x0000, 0x3f7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x3546, 0x0000, 0x365d, 0x0000, 0x6842, 0x0000, - 0x0000, 0x0000, 0x0000, 0x325b, 0x0000, 0x0000, 0x3e54, 0x0000, 0x6845, 0x0000, 0x0000, 0x0000, 0x3a5a, 0x0000, 0x0000, 0x4551, - 0x684a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a6e, 0x0000, 0x6841, 0x0000, 0x0000, 0x0000, 0x325a, - 0x3856, 0x4929, 0x684b, 0x0000, 0x683f, 0x0000, 0x0000, 0x6848, 0x0000, 0x0000, 0x0000, 0x6852, 0x0000, 0x6843, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_84[256] = { - 0x0000, 0x0000, 0x0000, 0x6844, 0x463a, 0x0000, 0x0000, 0x6849, 0x0000, 0x0000, 0x0000, 0x6846, 0x4b28, 0x684c, 0x3060, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6840, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x684e, 0x0000, 0x684d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x476b, 0x6854, 0x0000, 0x685f, 0x0000, 0x0000, 0x0000, - 0x0000, 0x337e, 0x0000, 0x0000, 0x0000, 0x6862, 0x0000, 0x0000, 0x6850, 0x0000, 0x0000, 0x0000, 0x6855, 0x4d6e, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x685e, 0x0000, 0x0000, 0x4d55, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e2a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4378, 0x0000, 0x0000, 0x0000, 0x336b, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4972, 0x6864, 0x4621, 0x0000, 0x0000, 0x3031, 0x0000, 0x0000, 0x685d, 0x0000, 0x6859, 0x4172, 0x6853, 0x685b, 0x6860, - 0x0000, 0x472c, 0x0000, 0x0000, 0x0000, 0x302a, 0x0000, 0x6858, 0x0000, 0x6861, 0x4978, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x685c, 0x0000, 0x6857, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e55, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3d2f, 0x0000, 0x0000, 0x0000, 0x3c2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c58, 0x0000, 0x0000, 0x4947, 0x0000, 0x0000, 0x6867, - 0x0000, 0x6870, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x685a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3377, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e78, 0x6865, 0x0000, 0x686a, 0x4173, 0x0000, 0x0000, 0x6866, - 0x0000, 0x686d, 0x0000, 0x0000, 0x435f, 0x0000, 0x686e, 0x0000, 0x0000, 0x4d56, 0x6863, 0x3338, 0x0000, 0x6869, 0x0000, 0x0000, - 0x686c, 0x4c2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x686f, 0x0000, 0x0000, 0x6868, 0x686b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b29, 0x0000, 0x4f21, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6873, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x687a, 0x0000, 0x0000, 0x6872, -}; - -static const uint16_t unicode_to_jisx0208_85[256] = { - 0x3c43, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6851, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4a4e, 0x0000, 0x4c22, 0x6879, 0x6878, 0x0000, 0x6874, 0x6875, 0x0000, 0x3136, 0x0000, 0x0000, 0x0000, 0x0000, 0x6877, - 0x0000, 0x6871, 0x0000, 0x0000, 0x0000, 0x0000, 0x4455, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6876, 0x307e, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4222, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a43, 0x0000, 0x0000, - 0x687b, 0x6921, 0x0000, 0x4859, 0x0000, 0x0000, 0x0000, 0x0000, 0x687e, 0x3e56, 0x3c49, 0x6923, 0x0000, 0x0000, 0x363e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6924, 0x0000, 0x4979, 0x687d, 0x0000, 0x6856, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x687c, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f4f, 0x4622, 0x4973, 0x0000, 0x0000, 0x692b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6931, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6932, 0x0000, - 0x6925, 0x0000, 0x0000, 0x0000, 0x4776, 0x0000, 0x0000, 0x692f, 0x6927, 0x0000, 0x6929, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6933, 0x6928, 0x0000, 0x0000, 0x692c, 0x0000, 0x0000, 0x3172, 0x0000, 0x4665, 0x0000, 0x692d, 0x6930, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6926, 0x0000, 0x4126, 0x0000, 0x692a, 0x3b27, 0x3f45, 0x3730, 0x4c74, 0x0000, 0x4c79, 0x3d72, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6937, 0x6935, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x4f4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6934, 0x0000, 0x0000, 0x0000, 0x4d75, 0x0000, 0x6936, - 0x6938, 0x0000, 0x0000, 0x0000, 0x0000, 0x6939, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x693c, 0x693a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4623, 0x693b, 0x0000, 0x0000, 0x0000, 0x484d, 0x692e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d73, 0x0000, 0x693d, 0x6942, 0x4174, 0x0000, 0x0000, 0x6941, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_86[256] = { - 0x0000, 0x0000, 0x6922, 0x0000, 0x0000, 0x0000, 0x6943, 0x4149, 0x0000, 0x0000, 0x693e, 0x6940, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x693f, 0x0000, 0x0000, 0x5d31, 0x5d22, 0x0000, 0x0000, 0x6945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6944, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d76, 0x0000, 0x623c, - 0x6946, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6947, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6948, 0x3857, 0x0000, - 0x3554, 0x0000, 0x0000, 0x0000, 0x694a, 0x515d, 0x0000, 0x0000, 0x0000, 0x0000, 0x3575, 0x0000, 0x4e3a, 0x0000, 0x3673, 0x694b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x694c, 0x0000, 0x0000, 0x0000, 0x436e, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x694d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x467a, 0x0000, 0x303a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3263, 0x6952, 0x6953, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x694e, 0x0000, 0x3b3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x694f, 0x4742, 0x0000, 0x0000, 0x0000, 0x0000, 0x6950, 0x6951, 0x695b, 0x0000, 0x0000, 0x0000, 0x6955, - 0x6958, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6954, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6956, 0x0000, 0x6957, 0x3c58, 0x0000, 0x6959, 0x0000, 0x4341, 0x0000, 0x3756, 0x3342, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x695c, 0x0000, 0x0000, 0x0000, 0x0000, 0x333f, 0x0000, 0x6961, 0x0000, 0x0000, 0x695d, 0x6960, - 0x0000, 0x0000, 0x0000, 0x0000, 0x483a, 0x0000, 0x0000, 0x0000, 0x0000, 0x695e, 0x0000, 0x0000, 0x695f, 0x4948, 0x485a, 0x6962, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x427d, 0x696c, 0x0000, 0x6968, 0x0000, 0x0000, 0x326b, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_87[256] = { - 0x6966, 0x0000, 0x4b2a, 0x6967, 0x0000, 0x0000, 0x6964, 0x0000, 0x6965, 0x696a, 0x696d, 0x0000, 0x0000, 0x696b, 0x0000, 0x0000, - 0x0000, 0x6969, 0x6963, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4358, 0x0000, 0x6974, 0x0000, 0x4c2a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6972, 0x0000, 0x0000, 0x0000, 0x6973, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x696e, 0x0000, 0x0000, 0x6970, 0x0000, 0x0000, 0x0000, 0x6971, 0x0000, 0x0000, 0x0000, 0x696f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4066, 0x0000, 0x4f39, 0x6978, 0x0000, 0x6979, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6a21, 0x0000, 0x3f2a, 0x0000, 0x697b, 0x0000, 0x697e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6976, - 0x6975, 0x0000, 0x0000, 0x6a22, 0x0000, 0x0000, 0x325c, 0x0000, 0x697c, 0x0000, 0x6a23, 0x0000, 0x0000, 0x0000, 0x697d, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x697a, 0x0000, 0x4433, 0x0000, 0x6977, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4768, - 0x0000, 0x0000, 0x6a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d3b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a26, - 0x0000, 0x0000, 0x6a25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a2e, 0x0000, 0x0000, 0x0000, 0x6a28, - 0x0000, 0x0000, 0x0000, 0x6a30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d66, 0x6a33, 0x0000, 0x6a2a, 0x0000, 0x0000, - 0x6a2b, 0x0000, 0x0000, 0x0000, 0x6a2f, 0x0000, 0x6a32, 0x6a31, 0x0000, 0x0000, 0x0000, 0x6a29, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6a2c, 0x0000, 0x6a3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6a36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a34, - 0x0000, 0x0000, 0x6a35, 0x0000, 0x0000, 0x0000, 0x6a3a, 0x6a3b, 0x0000, 0x332a, 0x0000, 0x3542, 0x0000, 0x0000, 0x6a39, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_88[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a38, 0x6a3c, 0x6a37, - 0x0000, 0x6a3e, 0x0000, 0x0000, 0x0000, 0x6a40, 0x6a3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6a42, 0x6a41, 0x695a, 0x0000, 0x0000, 0x0000, 0x6a46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6a43, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a44, 0x0000, 0x0000, 0x6a45, 0x0000, 0x6a47, 0x0000, 0x0000, 0x0000, 0x0000, - 0x376c, 0x0000, 0x6a49, 0x0000, 0x6a48, 0x0000, 0x3d30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3954, 0x5e27, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6a4a, 0x3d51, 0x0000, 0x0000, 0x0000, 0x3339, 0x0000, 0x6a4b, 0x0000, 0x3152, 0x0000, 0x3e57, 0x6a4c, 0x0000, - 0x0000, 0x3955, 0x6a4d, 0x3061, 0x0000, 0x0000, 0x0000, 0x0000, 0x493d, 0x0000, 0x0000, 0x6a4e, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3f6a, 0x0000, 0x6a55, 0x0000, 0x0000, 0x6a52, 0x0000, 0x436f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a53, 0x6a50, 0x365e, - 0x0000, 0x6a4f, 0x6a56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3736, 0x0000, 0x0000, 0x425e, 0x0000, 0x6a5c, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6a58, 0x0000, 0x0000, 0x0000, 0x4235, 0x6a57, 0x0000, 0x6a5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a51, 0x0000, - 0x0000, 0x0000, 0x6a5b, 0x0000, 0x6a5d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x486f, 0x0000, 0x0000, 0x6a59, 0x0000, - 0x6a5e, 0x6a60, 0x0000, 0x0000, 0x3853, 0x6a54, 0x0000, 0x3041, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a5f, - 0x0000, 0x3a5b, 0x4e76, 0x6a61, 0x6a62, 0x4175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e22, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6a63, 0x4d35, 0x0000, 0x0000, 0x6a64, 0x6a65, 0x0000, 0x0000, 0x4a64, 0x6a66, 0x0000, 0x3a40, - 0x0000, 0x4e23, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6a6c, 0x3e58, 0x6a6a, 0x0000, 0x0000, 0x0000, 0x4d67, 0x6a67, 0x0000, 0x0000, 0x6a69, 0x403d, 0x3f7e, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_89[256] = { - 0x0000, 0x0000, 0x6a68, 0x0000, 0x6a6d, 0x0000, 0x0000, 0x4a23, 0x0000, 0x0000, 0x6a6f, 0x0000, 0x6a6e, 0x0000, 0x0000, 0x0000, - 0x336c, 0x0000, 0x4b2b, 0x6a70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a7c, 0x6a72, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a73, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a74, 0x6a75, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a79, 0x0000, 0x6a7a, 0x0000, 0x0000, 0x6a78, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6a76, 0x0000, 0x6a71, 0x6a77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a7b, 0x7037, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3228, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a7e, 0x365f, - 0x6a7d, 0x0000, 0x0000, 0x0000, 0x6b22, 0x0000, 0x6b21, 0x0000, 0x0000, 0x0000, 0x6b24, 0x0000, 0x0000, 0x6b23, 0x0000, 0x6b25, - 0x0000, 0x0000, 0x3d31, 0x0000, 0x6b26, 0x0000, 0x0000, 0x6b27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b28, 0x403e, - 0x0000, 0x4d57, 0x0000, 0x6b29, 0x0000, 0x0000, 0x4a24, 0x4746, 0x6b2a, 0x0000, 0x6b2b, 0x382b, 0x0000, 0x0000, 0x0000, 0x352c, - 0x0000, 0x0000, 0x0000, 0x6b2c, 0x0000, 0x0000, 0x3b6b, 0x4741, 0x6b2d, 0x0000, 0x3350, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6b2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b30, 0x4d77, 0x0000, 0x6b2f, 0x3f46, 0x0000, 0x6b31, 0x0000, 0x0000, 0x6b32, - 0x0000, 0x0000, 0x6b33, 0x3451, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b34, 0x0000, 0x0000, 0x6b35, 0x0000, 0x6b36, - 0x6b37, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3351, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b38, 0x0000, 0x6b39, 0x6b3a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3272, 0x0000, 0x0000, 0x3f28, 0x6b3b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6b3c, 0x0000, 0x0000, 0x0000, 0x6b3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_8a[256] = { - 0x3840, 0x0000, 0x447b, 0x6b3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3757, 0x0000, 0x3f56, 0x0000, 0x6b41, 0x0000, 0x4624, 0x0000, - 0x6b40, 0x0000, 0x0000, 0x3731, 0x0000, 0x0000, 0x6b3f, 0x4277, 0x352d, 0x0000, 0x0000, 0x6b42, 0x0000, 0x6b43, 0x0000, 0x3e59, - 0x0000, 0x0000, 0x0000, 0x376d, 0x0000, 0x6b44, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b2c, 0x0000, 0x0000, 0x405f, 0x0000, 0x0000, - 0x0000, 0x3576, 0x0000, 0x4c75, 0x414a, 0x0000, 0x6b45, 0x0000, 0x0000, 0x0000, 0x3f47, 0x4370, 0x3e5a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6b46, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b49, 0x0000, 0x6b4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3a3e, 0x4242, 0x6b48, 0x0000, 0x3e5b, 0x493e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b47, 0x0000, 0x0000, 0x3b6c, 0x0000, - 0x3153, 0x0000, 0x6b4e, 0x3758, 0x0000, 0x0000, 0x3b6e, 0x0000, 0x0000, 0x3b6d, 0x0000, 0x4f4d, 0x6b4d, 0x6b4c, 0x4127, 0x0000, - 0x354d, 0x4f43, 0x333a, 0x3e5c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b4b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6b50, 0x0000, 0x6b51, 0x6b4f, 0x0000, 0x3858, 0x0000, 0x4d40, 0x0000, 0x0000, 0x3b6f, 0x4727, 0x0000, 0x0000, - 0x0000, 0x6b54, 0x0000, 0x4040, 0x0000, 0x4342, 0x0000, 0x0000, 0x4d36, 0x0000, 0x6b57, 0x0000, 0x0000, 0x0000, 0x386c, 0x0000, - 0x403f, 0x6b53, 0x0000, 0x6b58, 0x386d, 0x6b55, 0x6b56, 0x0000, 0x6b52, 0x0000, 0x0000, 0x0000, 0x4062, 0x4649, 0x0000, 0x0000, - 0x432f, 0x0000, 0x325d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4870, 0x0000, 0x0000, 0x3543, 0x0000, 0x0000, 0x4434, - 0x0000, 0x0000, 0x6b5b, 0x0000, 0x6b59, 0x0000, 0x0000, 0x434c, 0x0000, 0x0000, 0x0000, 0x4041, 0x3452, 0x6b5a, 0x0000, 0x3f5b, - 0x0000, 0x0000, 0x4e4a, 0x0000, 0x0000, 0x0000, 0x4f40, 0x0000, 0x0000, 0x0000, 0x6b5c, 0x6b67, 0x4435, 0x0000, 0x6b66, 0x0000, - 0x6b63, 0x6b6b, 0x6b64, 0x0000, 0x6b60, 0x0000, 0x447c, 0x6b5f, 0x0000, 0x0000, 0x0000, 0x6b5d, 0x0000, 0x4d21, 0x3b70, 0x0000, - 0x0000, 0x6b61, 0x0000, 0x6b5e, 0x0000, 0x0000, 0x0000, 0x6b65, 0x3d74, 0x0000, 0x3841, 0x0000, 0x0000, 0x0000, 0x427a, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_8b[256] = { - 0x4b45, 0x315a, 0x3062, 0x0000, 0x4625, 0x0000, 0x0000, 0x6b69, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b68, 0x0000, 0x4666, 0x0000, - 0x6b6d, 0x0000, 0x0000, 0x0000, 0x6b62, 0x0000, 0x6b6c, 0x6b6e, 0x0000, 0x382c, 0x6b6a, 0x3956, 0x0000, 0x3c55, 0x0000, 0x0000, - 0x6b6f, 0x4d58, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b72, 0x0000, 0x6b75, 0x0000, 0x0000, 0x6b73, 0x4935, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6b70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3660, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b74, 0x0000, - 0x0000, 0x6b76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b7a, 0x0000, 0x0000, 0x6b77, 0x0000, 0x6b79, 0x6b78, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b7b, 0x0000, 0x3c31, 0x0000, 0x6b7d, 0x6b7c, 0x4968, 0x0000, 0x0000, 0x6c21, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3759, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b7e, 0x6c22, 0x0000, 0x0000, 0x6c23, - 0x3544, 0x6641, 0x3e79, 0x0000, 0x6c24, 0x0000, 0x0000, 0x386e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c25, 0x0000, 0x0000, - 0x6c26, 0x0000, 0x0000, 0x3b3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a4e, 0x0000, 0x6c27, 0x0000, 0x6c28, 0x0000, - 0x3d32, 0x0000, 0x6c29, 0x6c2a, 0x0000, 0x0000, 0x6c2b, 0x0000, 0x0000, 0x6c2c, 0x6c2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_8c[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x432b, 0x0000, 0x0000, 0x6c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c30, - 0x0000, 0x6c2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4626, 0x0000, 0x6c31, 0x0000, 0x4b2d, 0x0000, 0x6c32, 0x0000, 0x6c33, 0x0000, - 0x6c34, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c35, 0x0000, 0x0000, 0x0000, 0x0000, 0x465a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3e5d, 0x6c36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x396b, 0x502e, 0x6c37, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c38, 0x493f, 0x6c39, 0x0000, 0x6c41, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6c3a, 0x0000, 0x0000, 0x6c3c, 0x0000, 0x0000, 0x0000, 0x6c3b, 0x6c3d, 0x0000, 0x4b46, 0x6c3e, 0x6c3f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6c40, 0x0000, 0x0000, 0x0000, 0x6c42, 0x0000, 0x0000, 0x0000, 0x0000, 0x332d, 0x4467, 0x0000, - 0x4969, 0x3a62, 0x3957, 0x0000, 0x0000, 0x0000, 0x0000, 0x494f, 0x325f, 0x484e, 0x6c45, 0x3453, 0x4055, 0x6c44, 0x6c49, 0x4379, - 0x4c63, 0x0000, 0x6c47, 0x6c48, 0x352e, 0x0000, 0x6c4a, 0x4763, 0x425f, 0x0000, 0x0000, 0x4871, 0x453d, 0x6c46, 0x0000, 0x4b47, - 0x326c, 0x6c4c, 0x4f28, 0x4442, 0x4f45, 0x0000, 0x0000, 0x3b71, 0x6c4b, 0x0000, 0x4231, 0x0000, 0x0000, 0x6c5c, 0x4128, 0x0000, - 0x0000, 0x4678, 0x0000, 0x4950, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c4f, 0x3b3f, 0x3b72, 0x0000, 0x3e5e, 0x0000, - 0x4765, 0x0000, 0x382d, 0x6c4e, 0x6c4d, 0x0000, 0x496a, 0x0000, 0x0000, 0x0000, 0x3c41, 0x0000, 0x0000, 0x4552, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c51, 0x6c52, 0x3958, 0x6c50, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_8d[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x6c53, 0x6c54, 0x0000, 0x6c56, 0x4223, 0x0000, 0x6c55, 0x3466, 0x0000, 0x6c58, 0x0000, 0x6c57, - 0x6c59, 0x0000, 0x0000, 0x6c5b, 0x6c5d, 0x0000, 0x6c5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4056, 0x0000, 0x3c4f, 0x6c5f, 0x0000, 0x0000, 0x0000, 0x3352, 0x0000, 0x6c60, 0x0000, 0x0000, - 0x4176, 0x6c61, 0x0000, 0x6c62, 0x496b, 0x0000, 0x0000, 0x352f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6c63, 0x0000, 0x0000, 0x0000, 0x4436, 0x0000, 0x0000, 0x0000, 0x0000, 0x315b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3c71, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x422d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c67, 0x0000, 0x0000, 0x0000, 0x6c66, 0x0000, - 0x0000, 0x0000, 0x6c65, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c6d, 0x6c6b, 0x0000, 0x0000, 0x6c68, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c6a, 0x0000, 0x0000, 0x0000, 0x6c69, 0x6c6c, 0x0000, 0x3577, 0x0000, 0x6c70, - 0x0000, 0x4057, 0x0000, 0x6c71, 0x0000, 0x0000, 0x0000, 0x0000, 0x3859, 0x0000, 0x6c6e, 0x6c6f, 0x0000, 0x0000, 0x0000, 0x4f29, - 0x0000, 0x0000, 0x0000, 0x4437, 0x0000, 0x4129, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c72, 0x0000, 0x0000, 0x6c75, -}; - -static const uint16_t unicode_to_jisx0208_8e[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c73, 0x6c74, 0x4d59, 0x0000, 0x0000, 0x0000, 0x0000, 0x4627, - 0x6c78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c76, 0x6c77, 0x6c79, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d29, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6c7c, 0x0000, 0x0000, 0x0000, 0x6c7d, 0x6c7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6c7a, 0x0000, 0x447d, 0x0000, 0x0000, 0x6d21, 0x6d25, 0x6d22, 0x6c7e, 0x0000, 0x6d23, 0x0000, 0x0000, 0x0000, - 0x6d24, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d2b, 0x0000, 0x0000, 0x0000, 0x6d26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4058, - 0x6d28, 0x0000, 0x0000, 0x6d2a, 0x6d27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6d2d, 0x0000, 0x3d33, 0x0000, 0x6d2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d2e, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6d2f, 0x0000, 0x0000, 0x6d32, 0x6d31, 0x0000, 0x6d30, 0x0000, 0x0000, 0x6d34, 0x6d33, 0x0000, 0x4c76, 0x0000, 0x0000, - 0x0000, 0x6d36, 0x0000, 0x6d35, 0x6d37, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6d3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d39, 0x3f48, 0x6d3b, 0x0000, 0x0000, 0x366d, - 0x6d3c, 0x6d3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d3f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d40, 0x6d3d, 0x0000, 0x6d41, 0x0000, 0x3c56, 0x6d42, 0x3530, 0x3733, 0x0000, 0x0000, - 0x0000, 0x0000, 0x382e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d43, 0x0000, 0x0000, 0x0000, 0x4670, - 0x0000, 0x0000, 0x453e, 0x6d44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d47, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c34, 0x0000, 0x0000, 0x6d46, 0x6d45, 0x375a, 0x6d48, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_8f[256] = { - 0x0000, 0x0000, 0x0000, 0x3353, 0x0000, 0x6d4a, 0x0000, 0x0000, 0x0000, 0x3a5c, 0x6d49, 0x0000, 0x6d52, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6d4c, 0x6d4e, 0x4a65, 0x6d4b, 0x0000, 0x0000, 0x0000, 0x6d4d, 0x0000, 0x6d51, 0x6d4f, 0x3531, 0x0000, 0x6d50, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d53, 0x0000, 0x0000, 0x475a, 0x4e58, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d34, - 0x0000, 0x0000, 0x0000, 0x6d54, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d22, 0x6d56, 0x0000, 0x6d55, 0x0000, 0x0000, 0x6d59, 0x4d41, - 0x0000, 0x0000, 0x6d58, 0x0000, 0x336d, 0x6d57, 0x6d5c, 0x0000, 0x0000, 0x6d5b, 0x0000, 0x0000, 0x6d5a, 0x4532, 0x6d5d, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d5f, 0x0000, 0x0000, 0x396c, - 0x0000, 0x3725, 0x6d60, 0x6d61, 0x6d62, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f49, 0x6d63, 0x0000, 0x3c2d, 0x6d64, - 0x0000, 0x0000, 0x0000, 0x6d65, 0x0000, 0x0000, 0x0000, 0x5221, 0x517e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d66, 0x6570, 0x6d67, - 0x4324, 0x3f2b, 0x4740, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d68, 0x0000, 0x0000, 0x4a55, 0x4454, 0x397e, 0x0000, 0x0000, 0x4329, - 0x0000, 0x0000, 0x312a, 0x0000, 0x4b78, 0x3f57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x375e, 0x0000, - 0x0000, 0x3661, 0x0000, 0x0000, 0x4a56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6d6b, 0x0000, 0x0000, 0x6d6a, 0x3260, 0x0000, 0x0000, 0x4676, 0x6d6c, 0x4777, 0x0000, 0x4533, 0x0000, 0x6d6d, - 0x3d52, 0x0000, 0x0000, 0x0000, 0x6d6f, 0x0000, 0x0000, 0x4c42, 0x6d7e, 0x6d71, 0x6d72, 0x0000, 0x0000, 0x4449, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_90[256] = { - 0x4260, 0x4177, 0x0000, 0x4628, 0x0000, 0x6d70, 0x3555, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d79, 0x0000, 0x6d76, 0x6e25, 0x4629, - 0x4360, 0x6d73, 0x0000, 0x447e, 0x4553, 0x6d74, 0x6d78, 0x3f60, 0x0000, 0x4767, 0x444c, 0x0000, 0x0000, 0x4042, 0x6d77, 0x422e, - 0x4224, 0x6d75, 0x3029, 0x4f22, 0x0000, 0x0000, 0x0000, 0x6d7a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4261, 0x0000, - 0x0000, 0x3d35, 0x3f4a, 0x0000, 0x0000, 0x6d7c, 0x6d7b, 0x0000, 0x306f, 0x6d7d, 0x0000, 0x0000, 0x492f, 0x0000, 0x6e27, 0x0000, - 0x0000, 0x465b, 0x3f6b, 0x0000, 0x0000, 0x4359, 0x0000, 0x3678, 0x0000, 0x6e26, 0x4d37, 0x313f, 0x0000, 0x4a57, 0x3261, 0x6e21, - 0x6e22, 0x6e23, 0x6e24, 0x463b, 0x4323, 0x3063, 0x6e28, 0x0000, 0x6e29, 0x7423, 0x0000, 0x0000, 0x423d, 0x0000, 0x6e2a, 0x0000, - 0x3173, 0x414c, 0x0000, 0x382f, 0x0000, 0x4d5a, 0x0000, 0x0000, 0x6e2b, 0x452c, 0x0000, 0x0000, 0x0000, 0x4178, 0x3c57, 0x6e2c, - 0x0000, 0x0000, 0x6e2f, 0x0000, 0x0000, 0x3d65, 0x6e2d, 0x412b, 0x412a, 0x0000, 0x3064, 0x0000, 0x4e4b, 0x6e31, 0x0000, 0x4872, - 0x6e33, 0x6e32, 0x6e30, 0x6364, 0x3454, 0x0000, 0x0000, 0x6d6e, 0x0000, 0x6e35, 0x6e34, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e36, - 0x0000, 0x4d38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4661, 0x0000, 0x0000, 0x4b2e, 0x0000, 0x6e37, 0x0000, 0x3c59, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e38, - 0x0000, 0x6e39, 0x0000, 0x0000, 0x0000, 0x6e3a, 0x0000, 0x0000, 0x4521, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x306a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3959, 0x0000, 0x0000, 0x0000, 0x4f3a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e3e, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3734, 0x6e3b, 0x0000, 0x6e3c, 0x0000, 0x0000, 0x0000, 0x4974, 0x0000, 0x0000, 0x0000, 0x0000, 0x3354, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d39, 0x0000, 0x363f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4554, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_91[256] = { - 0x0000, 0x0000, 0x6e3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6e40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e41, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4522, 0x0000, 0x0000, - 0x6e43, 0x0000, 0x6e42, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4653, 0x6e44, 0x3d36, 0x3c60, 0x475b, 0x4371, 0x0000, - 0x0000, 0x0000, 0x3c72, 0x0000, 0x3f6c, 0x0000, 0x6e45, 0x0000, 0x6e46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3f5d, 0x6e47, 0x0000, 0x6e48, 0x0000, 0x0000, 0x0000, 0x6e49, 0x4d6f, 0x0000, 0x3d37, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6e4b, 0x6e4a, 0x0000, 0x395a, 0x0000, 0x3973, 0x3b40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6e4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d66, 0x0000, 0x6e4d, 0x0000, 0x6e4c, 0x0000, 0x4269, 0x0000, 0x0000, - 0x386f, 0x0000, 0x4043, 0x0000, 0x0000, 0x0000, 0x0000, 0x4830, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d39, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x6e4f, 0x0000, 0x3e5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e52, 0x6e50, 0x0000, 0x0000, 0x0000, 0x6e51, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6e54, 0x6e53, 0x0000, 0x0000, 0x3e7a, 0x0000, 0x6e55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6e56, 0x6e57, 0x0000, 0x0000, 0x0000, 0x0000, 0x4850, 0x3a53, 0x3c61, 0x6e58, 0x0000, 0x6e59, 0x4e24, 0x3d45, 0x4c6e, 0x4e4c, - 0x6e5a, 0x3662, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e5b, 0x0000, 0x4523, 0x0000, 0x0000, 0x6e5e, 0x3378, 0x3f4b, 0x0000, 0x6e5c, - 0x0000, 0x6e5d, 0x0000, 0x4460, 0x0000, 0x0000, 0x4b55, 0x367c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e60, 0x6e61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e5f, 0x0000, 0x0000, 0x6e63, -}; - -static const uint16_t unicode_to_jisx0208_92[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x465f, 0x3343, 0x0000, - 0x0000, 0x6e67, 0x0000, 0x0000, 0x6e64, 0x6e66, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e62, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f4f, 0x0000, 0x0000, 0x6e65, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4e6b, 0x0000, 0x0000, 0x385a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e6f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4534, 0x6e6a, 0x0000, 0x0000, 0x6e6d, 0x6e6b, 0x0000, 0x6e70, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6e71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e69, 0x0000, 0x0000, 0x6e76, 0x3174, 0x0000, 0x0000, 0x6e68, 0x0000, - 0x0000, 0x0000, 0x482d, 0x0000, 0x6e6c, 0x0000, 0x3e60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x395b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b48, 0x0000, - 0x3664, 0x0000, 0x0000, 0x3d46, 0x0000, 0x463c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x412d, 0x0000, 0x6e74, 0x0000, 0x6e6e, 0x6e73, 0x0000, 0x4c43, 0x0000, 0x4438, 0x6e75, 0x6e72, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x412c, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e79, 0x0000, 0x6e78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e77, - 0x0000, 0x0000, 0x4b2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3d7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e7a, 0x4a5f, 0x0000, 0x0000, 0x3154, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4946, 0x4372, 0x0000, 0x0000, 0x0000, 0x0000, 0x3578, 0x0000, 0x6e7c, 0x0000, 0x395d, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_93[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e7b, - 0x3f6d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f6e, 0x6f21, 0x6f23, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3e7b, 0x0000, 0x6f22, 0x6f24, 0x0000, 0x0000, 0x3653, 0x0000, 0x4945, 0x0000, 0x0000, 0x3c62, 0x4f23, 0x0000, 0x6e7e, 0x3a78, - 0x0000, 0x0000, 0x4f3f, 0x0000, 0x0000, 0x6f26, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f25, 0x6f27, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6e7d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4669, 0x0000, 0x4555, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x4457, 0x0000, 0x6f2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x4343, 0x6f28, 0x0000, 0x0000, 0x0000, - 0x6f29, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x372d, 0x0000, 0x6f2b, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3830, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f2a, 0x0000, 0x3e61, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3379, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6f30, 0x0000, 0x3a3f, 0x4179, 0x0000, 0x0000, 0x444a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x333b, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f2e, 0x6f2f, 0x4443, 0x0000, - 0x6f2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f31, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6f37, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6f39, 0x452d, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f32, 0x6f33, 0x6f36, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f38, 0x0000, 0x0000, - 0x0000, 0x3640, 0x0000, 0x0000, 0x6f3b, 0x6f35, 0x0000, 0x0000, 0x6f34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_94[256] = { - 0x0000, 0x0000, 0x0000, 0x6f3f, 0x0000, 0x0000, 0x0000, 0x6f40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6f41, 0x0000, 0x0000, 0x6f3e, 0x6f3d, 0x0000, 0x0000, 0x0000, 0x3e62, 0x462a, 0x6f3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6f45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f43, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f44, 0x6f42, 0x0000, 0x4278, 0x0000, 0x6f46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6f47, 0x0000, 0x0000, 0x6f49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3455, 0x6f48, 0x4c7a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f54, 0x6f4a, 0x0000, 0x0000, 0x6f4d, 0x0000, - 0x6f4b, 0x0000, 0x6f4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6f50, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f51, 0x0000, 0x6f52, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f55, 0x6f53, 0x6f56, 0x6f58, - 0x0000, 0x6f57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_95[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4439, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4c67, 0x0000, 0x6f59, 0x412e, 0x0000, 0x0000, 0x0000, 0x6f5a, 0x0000, 0x4a44, 0x6f5b, 0x332b, 0x0000, 0x0000, 0x0000, 0x313c, - 0x0000, 0x3457, 0x0000, 0x3456, 0x6f5c, 0x0000, 0x6f5d, 0x0000, 0x6f5e, 0x6f5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x6f60, 0x0000, 0x3458, 0x3355, 0x395e, 0x4836, 0x0000, 0x6f62, 0x6f61, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f63, 0x0000, 0x0000, - 0x0000, 0x0000, 0x315c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f66, 0x0000, 0x6f65, 0x6f64, 0x0000, 0x6f67, 0x0000, - 0x0000, 0x0000, 0x0000, 0x6f6a, 0x0000, 0x0000, 0x0000, 0x3047, 0x0000, 0x0000, 0x6f68, 0x0000, 0x6f6c, 0x6f6b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6f6e, 0x6f6d, 0x6f6f, 0x0000, 0x462e, 0x0000, 0x0000, 0x0000, 0x6f70, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6f71, 0x6f73, 0x0000, 0x0000, 0x6f72, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_96[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x496c, 0x0000, 0x0000, 0x0000, - 0x0000, 0x6f74, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f75, 0x0000, 0x3a65, 0x0000, 0x0000, 0x0000, 0x6f76, 0x6f77, - 0x0000, 0x0000, 0x4b49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x414b, 0x0000, 0x0000, 0x0000, 0x3024, - 0x424b, 0x0000, 0x6f78, 0x0000, 0x496d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f7b, 0x6f79, 0x395f, 0x0000, 0x6f7a, - 0x3842, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a45, 0x6f7d, 0x7021, 0x6f7e, 0x7022, - 0x0000, 0x0000, 0x3121, 0x3f58, 0x3d7c, 0x3459, 0x7023, 0x0000, 0x0000, 0x0000, 0x4766, 0x0000, 0x7025, 0x0000, 0x0000, 0x0000, - 0x3122, 0x0000, 0x7024, 0x4444, 0x0000, 0x4e4d, 0x462b, 0x6f7c, 0x4e26, 0x0000, 0x3831, 0x0000, 0x0000, 0x4d5b, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3679, 0x4e34, 0x0000, 0x3728, 0x0000, 0x4262, 0x6721, 0x0000, 0x7026, 0x332c, 0x3f6f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3356, 0x7028, 0x0000, 0x7029, 0x7027, 0x3764, 0x0000, 0x3a5d, 0x3e63, 0x0000, 0x0000, 0x0000, - 0x3123, 0x0000, 0x0000, 0x4e59, 0x0000, 0x0000, 0x0000, 0x702b, 0x6e2e, 0x0000, 0x702a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x702e, 0x702c, 0x702d, 0x0000, 0x702f, 0x0000, 0x7030, 0x4e6c, 0x7031, 0x7032, 0x0000, 0x4049, 0x483b, 0x0000, 0x0000, 0x0000, - 0x3f7d, 0x3467, 0x0000, 0x0000, 0x4d3a, 0x326d, 0x3d38, 0x385b, 0x0000, 0x7035, 0x0000, 0x7034, 0x3b73, 0x7036, 0x7033, 0x0000, - 0x0000, 0x3b28, 0x0000, 0x0000, 0x0000, 0x703a, 0x6a2d, 0x0000, 0x0000, 0x5256, 0x0000, 0x3f77, 0x7038, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4e25, 0x4671, 0x0000, 0x0000, 0x0000, 0x0000, 0x312b, 0x0000, 0x4063, 0x3c36, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4a37, 0x0000, 0x3140, 0x0000, 0x0000, 0x0000, 0x4e6d, 0x4d6b, 0x0000, 0x703b, 0x0000, 0x4545, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_97[256] = { - 0x3c7b, 0x0000, 0x0000, 0x0000, 0x703c, 0x0000, 0x703d, 0x3f4c, 0x703e, 0x0000, 0x4e6e, 0x0000, 0x0000, 0x7039, 0x7040, 0x7042, - 0x0000, 0x7041, 0x0000, 0x703f, 0x0000, 0x0000, 0x7043, 0x0000, 0x0000, 0x7044, 0x0000, 0x0000, 0x417a, 0x0000, 0x3262, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x7045, 0x0000, 0x0000, 0x4c38, 0x0000, 0x0000, 0x7046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x7047, 0x0000, 0x4f2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b31, 0x7048, 0x0000, 0x0000, 0x0000, 0x7049, 0x704a, 0x0000, - 0x0000, 0x0000, 0x704e, 0x0000, 0x704b, 0x0000, 0x704c, 0x0000, 0x704d, 0x704f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4044, 0x0000, 0x0000, 0x0000, 0x4c77, 0x0000, 0x0000, 0x4045, 0x0000, 0x0000, 0x7050, 0x0000, 0x4873, 0x0000, - 0x7051, 0x7353, 0x4c4c, 0x0000, 0x7052, 0x0000, 0x7053, 0x0000, 0x7054, 0x3357, 0x0000, 0x7056, 0x0000, 0x3f59, 0x0000, 0x0000, - 0x0000, 0x7057, 0x0000, 0x0000, 0x3724, 0x0000, 0x0000, 0x0000, 0x0000, 0x7058, 0x705c, 0x0000, 0x705a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x705b, 0x0000, 0x0000, 0x3373, 0x7059, 0x705d, 0x0000, 0x0000, 0x0000, 0x0000, 0x705e, 0x0000, 0x3048, 0x0000, 0x705f, - 0x7060, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e64, 0x0000, 0x0000, 0x0000, 0x7061, 0x0000, 0x0000, 0x0000, - 0x3547, 0x0000, 0x0000, 0x7064, 0x0000, 0x0000, 0x7063, 0x0000, 0x7062, 0x0000, 0x0000, 0x6b71, 0x0000, 0x4a5c, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x7065, 0x7066, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x7067, 0x0000, 0x0000, 0x7068, 0x0000, 0x7069, 0x0000, 0x0000, 0x706a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x345a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x706b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x706c, 0x4723, 0x0000, - 0x0000, 0x0000, 0x706e, 0x323b, 0x0000, 0x7071, 0x7070, 0x0000, 0x0000, 0x0000, 0x0000, 0x3124, 0x0000, 0x0000, 0x0000, 0x3641, -}; - -static const uint16_t unicode_to_jisx0208_98[256] = { - 0x0000, 0x4a47, 0x443a, 0x3a22, 0x0000, 0x3960, 0x3d67, 0x0000, 0x3f5c, 0x0000, 0x0000, 0x0000, 0x7073, 0x0000, 0x0000, 0x7072, - 0x4d42, 0x3468, 0x4852, 0x465c, 0x0000, 0x0000, 0x0000, 0x3f7c, 0x4e4e, 0x0000, 0x375b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x7076, 0x0000, 0x0000, 0x7075, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b4b, 0x462c, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3150, 0x0000, 0x0000, 0x7077, 0x7074, 0x0000, 0x0000, 0x4951, 0x4d6a, 0x7078, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7079, 0x0000, 0x0000, 0x0000, 0x0000, 0x707b, 0x426a, 0x335b, 0x335c, 0x707a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3469, 0x3832, 0x0000, 0x0000, 0x346a, 0x0000, 0x0000, 0x453f, 0x0000, 0x0000, 0x4e60, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x385c, 0x0000, 0x0000, 0x0000, 0x707c, 0x0000, 0x0000, 0x0000, 0x707d, - 0x707e, 0x7121, 0x0000, 0x7123, 0x7122, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4977, 0x0000, 0x7124, 0x0000, 0x0000, 0x0000, 0x0000, 0x7125, - 0x0000, 0x7126, 0x0000, 0x0000, 0x0000, 0x0000, 0x7127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x7129, 0x7128, 0x0000, 0x712a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4874, 0x664c, 0x0000, 0x0000, 0x3f29, - 0x0000, 0x0000, 0x3532, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x712b, 0x0000, 0x712c, 0x0000, 0x522c, 0x5d3b, 0x4853, - 0x0000, 0x0000, 0x307b, 0x0000, 0x303b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b74, 0x4b30, 0x3e7e, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_99[256] = { - 0x0000, 0x0000, 0x0000, 0x712d, 0x0000, 0x4c5f, 0x0000, 0x0000, 0x0000, 0x712e, 0x4d5c, 0x0000, 0x3142, 0x0000, 0x0000, 0x0000, - 0x3b41, 0x0000, 0x712f, 0x326e, 0x7130, 0x0000, 0x0000, 0x0000, 0x7131, 0x0000, 0x0000, 0x0000, 0x0000, 0x7133, 0x7134, 0x0000, - 0x7136, 0x7132, 0x0000, 0x0000, 0x7135, 0x0000, 0x0000, 0x0000, 0x345b, 0x0000, 0x0000, 0x0000, 0x7137, 0x0000, 0x7138, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7139, 0x713a, 0x0000, - 0x0000, 0x0000, 0x713b, 0x0000, 0x0000, 0x713d, 0x0000, 0x0000, 0x0000, 0x713c, 0x0000, 0x713f, 0x7142, 0x0000, 0x0000, 0x0000, - 0x713e, 0x7140, 0x7141, 0x0000, 0x0000, 0x7143, 0x0000, 0x3642, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c73, 0x7144, 0x7145, 0x3961, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7146, 0x0000, 0x0000, 0x333e, 0x0000, 0x0000, 0x0000, 0x474f, 0x7147, 0x7148, 0x0000, - 0x0000, 0x0000, 0x0000, 0x435a, 0x466b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7149, 0x0000, 0x0000, 0x0000, - 0x0000, 0x477d, 0x0000, 0x0000, 0x424c, 0x3158, 0x366e, 0x0000, 0x366f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x4373, 0x714e, 0x3670, 0x0000, 0x0000, 0x326f, 0x0000, 0x0000, 0x714d, 0x0000, 0x0000, 0x714b, 0x0000, 0x714c, 0x0000, 0x714a, - 0x0000, 0x0000, 0x7158, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x714f, 0x7150, 0x0000, - 0x0000, 0x7151, 0x7152, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7154, 0x0000, 0x0000, 0x7153, 0x0000, 0x0000, 0x0000, 0x3d59, -}; - -static const uint16_t unicode_to_jisx0208_9a[256] = { - 0x0000, 0x7155, 0x0000, 0x0000, 0x0000, 0x7157, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3533, 0x7156, - 0x0000, 0x0000, 0x417b, 0x3833, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7159, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x424d, 0x0000, 0x0000, 0x715a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x462d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x715b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7160, 0x0000, - 0x715e, 0x0000, 0x715d, 0x715f, 0x0000, 0x715c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7162, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7161, 0x0000, 0x7164, 0x0000, 0x0000, 0x3643, 0x7163, 0x0000, 0x0000, 0x0000, 0x7165, - 0x0000, 0x0000, 0x7166, 0x0000, 0x7168, 0x7167, 0x0000, 0x0000, 0x0000, 0x7169, 0x716b, 0x716a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x397c, 0x0000, 0x0000, 0x0000, 0x0000, 0x716c, 0x0000, 0x0000, - 0x716d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x333c, 0x0000, 0x0000, 0x0000, 0x716e, 0x0000, 0x0000, 0x0000, - 0x716f, 0x0000, 0x0000, 0x0000, 0x3f71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7170, - 0x0000, 0x7171, 0x0000, 0x7172, 0x7173, 0x0000, 0x0000, 0x0000, 0x3962, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7174, 0x7175, - 0x0000, 0x0000, 0x7176, 0x7177, 0x0000, 0x0000, 0x7178, 0x0000, 0x0000, 0x0000, 0x4831, 0x717a, 0x0000, 0x4926, 0x717b, 0x7179, - 0x0000, 0x717d, 0x0000, 0x0000, 0x717c, 0x0000, 0x0000, 0x717e, 0x0000, 0x0000, 0x0000, 0x7221, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_9b[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7222, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7223, 0x0000, 0x7224, 0x0000, 0x0000, 0x0000, 0x0000, 0x7225, - 0x0000, 0x0000, 0x7226, 0x7227, 0x0000, 0x7228, 0x0000, 0x7229, 0x722a, 0x722b, 0x722c, 0x0000, 0x0000, 0x0000, 0x722d, 0x722e, - 0x0000, 0x5d35, 0x722f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6478, 0x3534, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3321, 0x3a32, 0x7231, 0x7230, 0x4c25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7233, 0x7234, 0x7232, - 0x0000, 0x7235, 0x0000, 0x0000, 0x4b62, 0x0000, 0x0000, 0x0000, 0x7236, 0x0000, 0x357b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f25, - 0x0000, 0x0000, 0x0000, 0x0000, 0x7237, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x7239, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x303e, 0x0000, - 0x0000, 0x723a, 0x4a2b, 0x7238, 0x0000, 0x0000, 0x723b, 0x723c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x723d, - 0x723e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x723f, 0x0000, 0x4b6e, 0x3b2d, 0x0000, 0x3a7a, 0x412f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x7240, 0x0000, 0x0000, 0x0000, 0x0000, 0x7243, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x7241, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7244, 0x0000, 0x0000, 0x3871, 0x7242, 0x0000, 0x0000, 0x0000, 0x0000, 0x7245, - 0x0000, 0x7246, 0x7247, 0x0000, 0x724b, 0x0000, 0x3b2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x4264, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x724c, 0x7249, 0x7248, 0x724a, 0x0000, 0x0000, 0x0000, 0x375f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x7250, 0x724f, 0x724e, 0x0000, 0x0000, 0x3033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_9c[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x725a, 0x0000, 0x7256, 0x0000, 0x7257, 0x7253, 0x7259, 0x0000, 0x7255, 0x3362, 0x0000, 0x0000, - 0x4f4c, 0x0000, 0x7258, 0x7254, 0x7252, 0x7251, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x725c, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x725f, 0x0000, 0x0000, 0x725e, 0x725d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4949, 0x725b, 0x3073, - 0x7260, 0x0000, 0x7262, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x336f, 0x724d, 0x3137, 0x0000, 0x0000, 0x7264, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7263, 0x7261, 0x432d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x4b70, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e5a, 0x0000, 0x0000, 0x7265, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x7266, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7267, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7268, 0x0000, 0x7269, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x443b, 0x0000, 0x726a, 0x0000, 0x4837, 0x0000, 0x726f, 0x726b, 0x0000, 0x0000, 0x0000, - 0x726c, 0x0000, 0x0000, 0x4b31, 0x4c44, 0x0000, 0x4650, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_9d[256] = { - 0x0000, 0x0000, 0x0000, 0x7270, 0x0000, 0x0000, 0x7271, 0x463e, 0x726e, 0x726d, 0x0000, 0x0000, 0x0000, 0x0000, 0x322a, 0x0000, - 0x0000, 0x0000, 0x7279, 0x0000, 0x0000, 0x7278, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3175, 0x0000, 0x0000, 0x0000, 0x7276, - 0x0000, 0x0000, 0x0000, 0x7275, 0x0000, 0x0000, 0x7273, 0x0000, 0x337b, 0x0000, 0x7272, 0x3c32, 0x3229, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3963, 0x0000, 0x0000, 0x727c, 0x727b, - 0x0000, 0x727a, 0x0000, 0x0000, 0x7277, 0x0000, 0x727d, 0x0000, 0x727e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x7325, 0x7324, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7326, 0x0000, 0x0000, 0x312d, 0x7321, 0x7322, 0x0000, - 0x3974, 0x4c39, 0x0000, 0x0000, 0x7323, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b32, 0x0000, 0x0000, 0x732b, - 0x0000, 0x0000, 0x7327, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x732c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7329, 0x0000, 0x7328, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x375c, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x732d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x732e, 0x0000, 0x0000, 0x0000, 0x0000, 0x732f, 0x0000, 0x732a, 0x0000, 0x0000, 0x0000, 0x7274, - 0x0000, 0x0000, 0x7330, 0x0000, 0x4461, 0x0000, 0x0000, 0x0000, 0x7334, 0x0000, 0x7335, 0x7333, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x7332, 0x7338, 0x0000, 0x7331, 0x0000, 0x7336, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7337, - 0x0000, 0x0000, 0x0000, 0x733a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7339, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x733c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x733d, 0x0000, 0x733e, - 0x0000, 0x0000, 0x4f49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x733b, 0x426b, 0x3a6d, 0x0000, 0x0000, 0x733f, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_9e[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7340, 0x7341, 0x0000, 0x0000, 0x7342, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7343, 0x0000, 0x0000, 0x3834, 0x7344, 0x0000, 0x0000, 0x0000, 0x7345, 0x0000, 0x3c2f, - 0x0000, 0x7346, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7347, 0x0000, 0x0000, 0x7348, 0x7349, 0x0000, 0x0000, 0x0000, - 0x0000, 0x734c, 0x734a, 0x4f3c, 0x0000, 0x734b, 0x0000, 0x4e6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x734d, 0x0000, 0x4e5b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x734e, 0x477e, 0x0000, 0x0000, 0x734f, 0x7351, 0x0000, 0x0000, 0x7352, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7350, 0x396d, 0x4c4d, 0x4b63, 0x5677, 0x0000, 0x5d60, 0x4b7b, - 0x0000, 0x0000, 0x0000, 0x0000, 0x322b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7354, 0x3550, 0x7355, 0x7356, - 0x7357, 0x0000, 0x3975, 0x0000, 0x7358, 0x0000, 0x0000, 0x0000, 0x6054, 0x4c5b, 0x0000, 0x4263, 0x7359, 0x735b, 0x735a, 0x0000, - 0x735c, 0x0000, 0x0000, 0x0000, 0x0000, 0x735d, 0x0000, 0x0000, 0x735e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x735f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x7360, 0x0000, 0x7361, 0x7362, 0x0000, 0x7363, 0x0000, 0x7364, 0x7365, 0x7366, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_9f[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7367, 0x7368, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4524, 0x0000, - 0x0000, 0x0000, 0x0000, 0x385d, 0x0000, 0x736a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x414d, 0x736b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x736c, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4921, 0x0000, 0x0000, 0x736d, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x736e, 0x6337, 0x0000, 0x0000, 0x6c5a, 0x706d, - 0x0000, 0x0000, 0x736f, 0x0000, 0x7370, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7372, - 0x7373, 0x7374, 0x4e70, 0x7371, 0x0000, 0x0000, 0x7375, 0x7376, 0x0000, 0x0000, 0x7378, 0x0000, 0x7377, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x737a, 0x0000, 0x0000, 0x0000, 0x737b, 0x7379, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e36, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x737c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x737d, 0x6354, 0x0000, 0x0000, - 0x737e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const uint16_t unicode_to_jisx0208_ff[256] = { - 0x0000, 0x212a, 0x2149, 0x2174, 0x2170, 0x2173, 0x2175, 0x216d, 0x214a, 0x214b, 0x2176, 0x215c, 0x2124, 0x213e, 0x2125, 0x213f, - 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129, - 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f, - 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, 0x2358, 0x2359, 0x235a, 0x214e, 0x2140, 0x214f, 0x2130, 0x2132, - 0x212e, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f, - 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, 0x2378, 0x2379, 0x237a, 0x2150, 0x2143, 0x2151, 0x2141, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x2131, 0x0000, 0x216f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - - -static const uint16_t * const unicode_to_jisx0208_map[0x100] = { - /* 0x00XX - 0x0fXX */ - unicode_to_jisx0208_00, - 0, 0, - unicode_to_jisx0208_03, - unicode_to_jisx0208_04, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10XX - 0x1fXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x20XX - 0x2fXX */ - unicode_to_jisx0208_20, - unicode_to_jisx0208_21, - unicode_to_jisx0208_22, - unicode_to_jisx0208_23, - unicode_to_jisx0208_24, - unicode_to_jisx0208_25, - unicode_to_jisx0208_26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x30XX - 0x3fXX */ - unicode_to_jisx0208_30, - 0, - unicode_to_jisx0208_32, - unicode_to_jisx0208_33, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x40XX - 0x4fXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - unicode_to_jisx0208_4e, - unicode_to_jisx0208_4f, - /* 0x50XX - 0x5fXX */ - unicode_to_jisx0208_50, - unicode_to_jisx0208_51, - unicode_to_jisx0208_52, - unicode_to_jisx0208_53, - unicode_to_jisx0208_54, - unicode_to_jisx0208_55, - unicode_to_jisx0208_56, - unicode_to_jisx0208_57, - unicode_to_jisx0208_58, - unicode_to_jisx0208_59, - unicode_to_jisx0208_5a, - unicode_to_jisx0208_5b, - unicode_to_jisx0208_5c, - unicode_to_jisx0208_5d, - unicode_to_jisx0208_5e, - unicode_to_jisx0208_5f, - /* 0x60XX - 0x6fXX */ - unicode_to_jisx0208_60, - unicode_to_jisx0208_61, - unicode_to_jisx0208_62, - unicode_to_jisx0208_63, - unicode_to_jisx0208_64, - unicode_to_jisx0208_65, - unicode_to_jisx0208_66, - unicode_to_jisx0208_67, - unicode_to_jisx0208_68, - unicode_to_jisx0208_69, - unicode_to_jisx0208_6a, - unicode_to_jisx0208_6b, - unicode_to_jisx0208_6c, - unicode_to_jisx0208_6d, - unicode_to_jisx0208_6e, - unicode_to_jisx0208_6f, - /* 0x70XX - 0x7fXX */ - unicode_to_jisx0208_70, - unicode_to_jisx0208_71, - unicode_to_jisx0208_72, - unicode_to_jisx0208_73, - unicode_to_jisx0208_74, - unicode_to_jisx0208_75, - unicode_to_jisx0208_76, - unicode_to_jisx0208_77, - unicode_to_jisx0208_78, - unicode_to_jisx0208_79, - unicode_to_jisx0208_7a, - unicode_to_jisx0208_7b, - unicode_to_jisx0208_7c, - unicode_to_jisx0208_7d, - unicode_to_jisx0208_7e, - unicode_to_jisx0208_7f, - /* 0x80XX - 0x8fXX */ - unicode_to_jisx0208_80, - unicode_to_jisx0208_81, - unicode_to_jisx0208_82, - unicode_to_jisx0208_83, - unicode_to_jisx0208_84, - unicode_to_jisx0208_85, - unicode_to_jisx0208_86, - unicode_to_jisx0208_87, - unicode_to_jisx0208_88, - unicode_to_jisx0208_89, - unicode_to_jisx0208_8a, - unicode_to_jisx0208_8b, - unicode_to_jisx0208_8c, - unicode_to_jisx0208_8d, - unicode_to_jisx0208_8e, - unicode_to_jisx0208_8f, - /* 0x90XX - 0x9fXX */ - unicode_to_jisx0208_90, - unicode_to_jisx0208_91, - unicode_to_jisx0208_92, - unicode_to_jisx0208_93, - unicode_to_jisx0208_94, - unicode_to_jisx0208_95, - unicode_to_jisx0208_96, - unicode_to_jisx0208_97, - unicode_to_jisx0208_98, - unicode_to_jisx0208_99, - unicode_to_jisx0208_9a, - unicode_to_jisx0208_9b, - unicode_to_jisx0208_9c, - unicode_to_jisx0208_9d, - unicode_to_jisx0208_9e, - unicode_to_jisx0208_9f, - /* 0xa0XX - 0xafXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xb0XX - 0xbfXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xc0XX - 0xcfXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xd0XX - 0xdfXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xe0XX - 0xefXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xf0XX - 0xffXX */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - unicode_to_jisx0208_ff, -}; - -static inline bool IsKana(unsigned c) -{ - return c >= 0xa1 && c <= 0xdf; -} - -static inline bool IsLatin(unsigned c) -{ - return /*(c) >= 0x00 &&*/ c <= 0x7f; -} - -/* -* This function is derived from Unicode 1.1, -* JIS X 0201 (1976) to Unicode mapping table version 0.9 . -*/ - -#define JISX0201_YEN_SIGN 0x005c -#define UNICODE_YEN_SIGN 0x00a5 - -#define JISX0201_OVERLINE 0x007e -#define UNICODE_OVERLINE 0x203e - -static inline unsigned Hi(unsigned c) -{ - return (c >> 8) & 0xff; -} - -static inline unsigned Lo(unsigned c) -{ - return c & 0xff; -} - -/* -* This function is derived from Unicode 1.1, -* JIS X 0201 (1976) to Unicode mapping table version 0.9 . -*/ - -static unsigned unicode11ToJisx0201(unsigned h, unsigned l) -{ - if ((h == 0x00) && (l < 0x80)) { - if ((l == JISX0201_YEN_SIGN) || - (l == JISX0201_OVERLINE)) { - return 0x0000; - } - return l; - } - else if ((h == 0x00) && (l == 0xa5)) { - return JISX0201_YEN_SIGN; - } - else if ((h == 0x20) && (l == 0x3e)) { - return JISX0201_OVERLINE; - } - else if ((h == 0xff) && (0x61 <= l) && (l <= 0x9f)) { - return 0x00a1 + l - 0x61; - } - return 0x0000; -} - -static unsigned unicodeToJisx0201Latin(unsigned h, unsigned l) -{ - unsigned jis = unicode11ToJisx0201(h, l); - if (IsLatin(jis)) { - return jis; - } - return 0x0000; -} - -static unsigned unicodeToJisx0201Kana(unsigned h, unsigned l) -{ - unsigned jis = unicode11ToJisx0201(h, l); - if (IsKana(jis)) { - return jis; - } - return 0x0000; -} - -static unsigned unicodeToJisx0201(unsigned h, unsigned l) -{ - unsigned jis; - if ((jis = unicodeToJisx0201Latin(h, l)) != 0) { - return jis; - } - else if ((jis = unicodeToJisx0201Kana(h, l)) != 0) { - return jis; - } - return 0x0000; -} - -static unsigned unicodeToJisx0208(unsigned h, unsigned l) -{ - if ((h == 0x00) && (l == 0x5c)) { - return 0x0000; - } - - uint16_t const *table; - table = unicode_to_jisx0208_map[h]; - if (table != 0) { - return table[l]; - } - return 0x0000; -} - - -static unsigned jisx0208ToSjis(unsigned h, unsigned l) -{ - if ((0x0021 <= h) && (h <= 0x007e) && (0x0021 <= l) && (l <= 0x007e)) { - return ((((h - 1) >> 1) + ((h <= 0x5e) ? 0x71 : 0xb1)) << 8) | - (l + ((h & 1) ? ((l < 0x60) ? 0x1f : 0x20) : 0x7e)); - } - return 0x0000; -} - -/*! -\internal -*/ -unsigned unicodeToJisx0212(unsigned h, unsigned l) -{ - if ((h == 0x00) && (l == 0x7e)) { - return 0x0000; - } - if ((h == 0xff) && (l == 0x5e)) { - return 0x2237; - } - return unicodeToJisx0208(h, l); -} - -static unsigned unicodeToSjis(unsigned h, unsigned l) -{ - unsigned jis; - if ((jis = unicodeToJisx0201(h, l)) != 0x0000) { - return jis; - } - else if ((jis = unicodeToJisx0208(h, l)) != 0x0000) { - return jisx0208ToSjis(Hi(jis), Lo(jis)); - } - else if ((jis = unicodeToJisx0212(h, l)) != 0x0000) { - return 0x0000; - } - return 0x0000; -} - -void -JPTextEncoder::EncodeShiftJIS(const std::wstring& str, std::string& bytes) -{ - static const char replacement = '?'; - //int invalid = 0; - bytes.resize(2 * str.length() + 1); - int index = 0; - for (wchar_t ch : str) { - unsigned j; - if (ch < 0x80) { - // ASCII - bytes[index++] = static_cast(ch); - } else if ((j = unicodeToJisx0201(Hi(ch), Lo(ch))) != 0) { - // JIS X 0201 Latin or JIS X 0201 Kana - bytes[index++] = static_cast(j); - } else if ((j = unicodeToSjis(Hi(ch), Lo(ch))) != 0) { - // JIS X 0208 - bytes[index++] = static_cast(j >> 8); - bytes[index++] = static_cast(j & 0xff); - } else if ((j = unicodeToJisx0212(Hi(ch), Lo(ch))) != 0) { - // JIS X 0212 (can't be encoded in ShiftJIS !) - bytes[index++] = static_cast(0x81); // white square - bytes[index++] = static_cast(0xa0); // white square - } else { - // Error - bytes[index++] = replacement; - //++invalid; - } - } - bytes.resize(index); -} - -void -JPTextEncoder::EncodeEUCJP(const std::wstring& str, std::string& bytes) -{ - static const char replacement = '?'; - static const uint8_t Ss2 = 0x8e; // Single Shift 2 - static const uint8_t Ss3 = 0x8f; // Single Shift 3 - - //int invalid = 0; - - bytes.resize(3 * str.length() + 1); - int index = 0; - for (wchar_t ch : str) { - unsigned j; - if (ch < 0x80) { - // ASCII - bytes[index++] = static_cast(ch); - } - else if ((j = unicodeToJisx0201(Hi(ch), Lo(ch))) != 0) { - if (j < 0x80) { - // JIS X 0201 Latin ? - bytes[index++] = static_cast(j); - } - else { - // JIS X 0201 Kana - bytes[index++] = Ss2; - bytes[index++] = static_cast(j); - } - } - else if ((j = unicodeToJisx0208(Hi(ch), Lo(ch))) != 0) { - // JIS X 0208 - bytes[index++] = static_cast((j >> 8) | 0x80); - bytes[index++] = static_cast((j & 0xff) | 0x80); - } - else if ((j = unicodeToJisx0212(Hi(ch), Lo(ch))) != 0) { - // JIS X 0212 - bytes[index++] = Ss3; - bytes[index++] = static_cast((j >> 8) | 0x80); - bytes[index++] = static_cast((j & 0xff) | 0x80); - } - else { - // Error - bytes[index++] = replacement; - //++invalid; - } - } - bytes.resize(index); -} diff --git a/core/src/textcodec/JPTextEncoder.h b/core/src/textcodec/JPTextEncoder.h deleted file mode 100644 index 053efe7c0c..0000000000 --- a/core/src/textcodec/JPTextEncoder.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Most of the code here was originally written by Serika Kurusugawa -// a.k.a. Junji Takagi, and is included in Qt with the author's permission, -// and the grateful thanks of the Qt team. - -/* - * Copyright (C) 1999 Serika Kurusugawa, All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -class JPTextEncoder -{ -public: - static void EncodeShiftJIS(const std::wstring& str, std::string& bytes); - static void EncodeEUCJP(const std::wstring& str, std::string& bytes); -}; diff --git a/core/src/textcodec/KRHangulMapping.cpp b/core/src/textcodec/KRHangulMapping.cpp deleted file mode 100644 index 478b8789d2..0000000000 --- a/core/src/textcodec/KRHangulMapping.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Most of the cp949 code was originally written by Joon-Kyu Park, and is included -// in Qt with the author's permission and the grateful thanks of the Qt team. - -#include "KRHangulMapping.h" - -/* Table including ksc5601 hangul to unicode */ -const uint16_t ksc5601_hangul_to_unicode[2350] = -{ - 0xac00, 0xac01, 0xac04, 0xac07, 0xac08, 0xac09, 0xac0a, 0xac10, 0xac11, 0xac12, 0xac13, 0xac14, 0xac15, 0xac16, 0xac17, 0xac19, - 0xac1a, 0xac1b, 0xac1c, 0xac1d, 0xac20, 0xac24, 0xac2c, 0xac2d, 0xac2f, 0xac30, 0xac31, 0xac38, 0xac39, 0xac3c, 0xac40, 0xac4b, - 0xac4d, 0xac54, 0xac58, 0xac5c, 0xac70, 0xac71, 0xac74, 0xac77, 0xac78, 0xac7a, 0xac80, 0xac81, 0xac83, 0xac84, 0xac85, 0xac86, - 0xac89, 0xac8a, 0xac8b, 0xac8c, 0xac90, 0xac94, 0xac9c, 0xac9d, 0xac9f, 0xaca0, 0xaca1, 0xaca8, 0xaca9, 0xacaa, 0xacac, 0xacaf, - 0xacb0, 0xacb8, 0xacb9, 0xacbb, 0xacbc, 0xacbd, 0xacc1, 0xacc4, 0xacc8, 0xaccc, 0xacd5, 0xacd7, 0xace0, 0xace1, 0xace4, 0xace7, - 0xace8, 0xacea, 0xacec, 0xacef, 0xacf0, 0xacf1, 0xacf3, 0xacf5, 0xacf6, 0xacfc, 0xacfd, 0xad00, 0xad04, 0xad06, 0xad0c, 0xad0d, - 0xad0f, 0xad11, 0xad18, 0xad1c, 0xad20, 0xad29, 0xad2c, 0xad2d, 0xad34, 0xad35, 0xad38, 0xad3c, 0xad44, 0xad45, 0xad47, 0xad49, - 0xad50, 0xad54, 0xad58, 0xad61, 0xad63, 0xad6c, 0xad6d, 0xad70, 0xad73, 0xad74, 0xad75, 0xad76, 0xad7b, 0xad7c, 0xad7d, 0xad7f, - 0xad81, 0xad82, 0xad88, 0xad89, 0xad8c, 0xad90, 0xad9c, 0xad9d, 0xada4, 0xadb7, 0xadc0, 0xadc1, 0xadc4, 0xadc8, 0xadd0, 0xadd1, - 0xadd3, 0xaddc, 0xade0, 0xade4, 0xadf8, 0xadf9, 0xadfc, 0xadff, 0xae00, 0xae01, 0xae08, 0xae09, 0xae0b, 0xae0d, 0xae14, 0xae30, - 0xae31, 0xae34, 0xae37, 0xae38, 0xae3a, 0xae40, 0xae41, 0xae43, 0xae45, 0xae46, 0xae4a, 0xae4c, 0xae4d, 0xae4e, 0xae50, 0xae54, - 0xae56, 0xae5c, 0xae5d, 0xae5f, 0xae60, 0xae61, 0xae65, 0xae68, 0xae69, 0xae6c, 0xae70, 0xae78, 0xae79, 0xae7b, 0xae7c, 0xae7d, - 0xae84, 0xae85, 0xae8c, 0xaebc, 0xaebd, 0xaebe, 0xaec0, 0xaec4, 0xaecc, 0xaecd, 0xaecf, 0xaed0, 0xaed1, 0xaed8, 0xaed9, 0xaedc, - 0xaee8, 0xaeeb, 0xaeed, 0xaef4, 0xaef8, 0xaefc, 0xaf07, 0xaf08, 0xaf0d, 0xaf10, 0xaf2c, 0xaf2d, 0xaf30, 0xaf32, 0xaf34, 0xaf3c, - 0xaf3d, 0xaf3f, 0xaf41, 0xaf42, 0xaf43, 0xaf48, 0xaf49, 0xaf50, 0xaf5c, 0xaf5d, 0xaf64, 0xaf65, 0xaf79, 0xaf80, 0xaf84, 0xaf88, - 0xaf90, 0xaf91, 0xaf95, 0xaf9c, 0xafb8, 0xafb9, 0xafbc, 0xafc0, 0xafc7, 0xafc8, 0xafc9, 0xafcb, 0xafcd, 0xafce, 0xafd4, 0xafdc, - 0xafe8, 0xafe9, 0xaff0, 0xaff1, 0xaff4, 0xaff8, 0xb000, 0xb001, 0xb004, 0xb00c, 0xb010, 0xb014, 0xb01c, 0xb01d, 0xb028, 0xb044, - 0xb045, 0xb048, 0xb04a, 0xb04c, 0xb04e, 0xb053, 0xb054, 0xb055, 0xb057, 0xb059, 0xb05d, 0xb07c, 0xb07d, 0xb080, 0xb084, 0xb08c, - 0xb08d, 0xb08f, 0xb091, 0xb098, 0xb099, 0xb09a, 0xb09c, 0xb09f, 0xb0a0, 0xb0a1, 0xb0a2, 0xb0a8, 0xb0a9, 0xb0ab, 0xb0ac, 0xb0ad, - 0xb0ae, 0xb0af, 0xb0b1, 0xb0b3, 0xb0b4, 0xb0b5, 0xb0b8, 0xb0bc, 0xb0c4, 0xb0c5, 0xb0c7, 0xb0c8, 0xb0c9, 0xb0d0, 0xb0d1, 0xb0d4, - 0xb0d8, 0xb0e0, 0xb0e5, 0xb108, 0xb109, 0xb10b, 0xb10c, 0xb110, 0xb112, 0xb113, 0xb118, 0xb119, 0xb11b, 0xb11c, 0xb11d, 0xb123, - 0xb124, 0xb125, 0xb128, 0xb12c, 0xb134, 0xb135, 0xb137, 0xb138, 0xb139, 0xb140, 0xb141, 0xb144, 0xb148, 0xb150, 0xb151, 0xb154, - 0xb155, 0xb158, 0xb15c, 0xb160, 0xb178, 0xb179, 0xb17c, 0xb180, 0xb182, 0xb188, 0xb189, 0xb18b, 0xb18d, 0xb192, 0xb193, 0xb194, - 0xb198, 0xb19c, 0xb1a8, 0xb1cc, 0xb1d0, 0xb1d4, 0xb1dc, 0xb1dd, 0xb1df, 0xb1e8, 0xb1e9, 0xb1ec, 0xb1f0, 0xb1f9, 0xb1fb, 0xb1fd, - 0xb204, 0xb205, 0xb208, 0xb20b, 0xb20c, 0xb214, 0xb215, 0xb217, 0xb219, 0xb220, 0xb234, 0xb23c, 0xb258, 0xb25c, 0xb260, 0xb268, - 0xb269, 0xb274, 0xb275, 0xb27c, 0xb284, 0xb285, 0xb289, 0xb290, 0xb291, 0xb294, 0xb298, 0xb299, 0xb29a, 0xb2a0, 0xb2a1, 0xb2a3, - 0xb2a5, 0xb2a6, 0xb2aa, 0xb2ac, 0xb2b0, 0xb2b4, 0xb2c8, 0xb2c9, 0xb2cc, 0xb2d0, 0xb2d2, 0xb2d8, 0xb2d9, 0xb2db, 0xb2dd, 0xb2e2, - 0xb2e4, 0xb2e5, 0xb2e6, 0xb2e8, 0xb2eb, 0xb2ec, 0xb2ed, 0xb2ee, 0xb2ef, 0xb2f3, 0xb2f4, 0xb2f5, 0xb2f7, 0xb2f8, 0xb2f9, 0xb2fa, - 0xb2fb, 0xb2ff, 0xb300, 0xb301, 0xb304, 0xb308, 0xb310, 0xb311, 0xb313, 0xb314, 0xb315, 0xb31c, 0xb354, 0xb355, 0xb356, 0xb358, - 0xb35b, 0xb35c, 0xb35e, 0xb35f, 0xb364, 0xb365, 0xb367, 0xb369, 0xb36b, 0xb36e, 0xb370, 0xb371, 0xb374, 0xb378, 0xb380, 0xb381, - 0xb383, 0xb384, 0xb385, 0xb38c, 0xb390, 0xb394, 0xb3a0, 0xb3a1, 0xb3a8, 0xb3ac, 0xb3c4, 0xb3c5, 0xb3c8, 0xb3cb, 0xb3cc, 0xb3ce, - 0xb3d0, 0xb3d4, 0xb3d5, 0xb3d7, 0xb3d9, 0xb3db, 0xb3dd, 0xb3e0, 0xb3e4, 0xb3e8, 0xb3fc, 0xb410, 0xb418, 0xb41c, 0xb420, 0xb428, - 0xb429, 0xb42b, 0xb434, 0xb450, 0xb451, 0xb454, 0xb458, 0xb460, 0xb461, 0xb463, 0xb465, 0xb46c, 0xb480, 0xb488, 0xb49d, 0xb4a4, - 0xb4a8, 0xb4ac, 0xb4b5, 0xb4b7, 0xb4b9, 0xb4c0, 0xb4c4, 0xb4c8, 0xb4d0, 0xb4d5, 0xb4dc, 0xb4dd, 0xb4e0, 0xb4e3, 0xb4e4, 0xb4e6, - 0xb4ec, 0xb4ed, 0xb4ef, 0xb4f1, 0xb4f8, 0xb514, 0xb515, 0xb518, 0xb51b, 0xb51c, 0xb524, 0xb525, 0xb527, 0xb528, 0xb529, 0xb52a, - 0xb530, 0xb531, 0xb534, 0xb538, 0xb540, 0xb541, 0xb543, 0xb544, 0xb545, 0xb54b, 0xb54c, 0xb54d, 0xb550, 0xb554, 0xb55c, 0xb55d, - 0xb55f, 0xb560, 0xb561, 0xb5a0, 0xb5a1, 0xb5a4, 0xb5a8, 0xb5aa, 0xb5ab, 0xb5b0, 0xb5b1, 0xb5b3, 0xb5b4, 0xb5b5, 0xb5bb, 0xb5bc, - 0xb5bd, 0xb5c0, 0xb5c4, 0xb5cc, 0xb5cd, 0xb5cf, 0xb5d0, 0xb5d1, 0xb5d8, 0xb5ec, 0xb610, 0xb611, 0xb614, 0xb618, 0xb625, 0xb62c, - 0xb634, 0xb648, 0xb664, 0xb668, 0xb69c, 0xb69d, 0xb6a0, 0xb6a4, 0xb6ab, 0xb6ac, 0xb6b1, 0xb6d4, 0xb6f0, 0xb6f4, 0xb6f8, 0xb700, - 0xb701, 0xb705, 0xb728, 0xb729, 0xb72c, 0xb72f, 0xb730, 0xb738, 0xb739, 0xb73b, 0xb744, 0xb748, 0xb74c, 0xb754, 0xb755, 0xb760, - 0xb764, 0xb768, 0xb770, 0xb771, 0xb773, 0xb775, 0xb77c, 0xb77d, 0xb780, 0xb784, 0xb78c, 0xb78d, 0xb78f, 0xb790, 0xb791, 0xb792, - 0xb796, 0xb797, 0xb798, 0xb799, 0xb79c, 0xb7a0, 0xb7a8, 0xb7a9, 0xb7ab, 0xb7ac, 0xb7ad, 0xb7b4, 0xb7b5, 0xb7b8, 0xb7c7, 0xb7c9, - 0xb7ec, 0xb7ed, 0xb7f0, 0xb7f4, 0xb7fc, 0xb7fd, 0xb7ff, 0xb800, 0xb801, 0xb807, 0xb808, 0xb809, 0xb80c, 0xb810, 0xb818, 0xb819, - 0xb81b, 0xb81d, 0xb824, 0xb825, 0xb828, 0xb82c, 0xb834, 0xb835, 0xb837, 0xb838, 0xb839, 0xb840, 0xb844, 0xb851, 0xb853, 0xb85c, - 0xb85d, 0xb860, 0xb864, 0xb86c, 0xb86d, 0xb86f, 0xb871, 0xb878, 0xb87c, 0xb88d, 0xb8a8, 0xb8b0, 0xb8b4, 0xb8b8, 0xb8c0, 0xb8c1, - 0xb8c3, 0xb8c5, 0xb8cc, 0xb8d0, 0xb8d4, 0xb8dd, 0xb8df, 0xb8e1, 0xb8e8, 0xb8e9, 0xb8ec, 0xb8f0, 0xb8f8, 0xb8f9, 0xb8fb, 0xb8fd, - 0xb904, 0xb918, 0xb920, 0xb93c, 0xb93d, 0xb940, 0xb944, 0xb94c, 0xb94f, 0xb951, 0xb958, 0xb959, 0xb95c, 0xb960, 0xb968, 0xb969, - 0xb96b, 0xb96d, 0xb974, 0xb975, 0xb978, 0xb97c, 0xb984, 0xb985, 0xb987, 0xb989, 0xb98a, 0xb98d, 0xb98e, 0xb9ac, 0xb9ad, 0xb9b0, - 0xb9b4, 0xb9bc, 0xb9bd, 0xb9bf, 0xb9c1, 0xb9c8, 0xb9c9, 0xb9cc, 0xb9ce, 0xb9cf, 0xb9d0, 0xb9d1, 0xb9d2, 0xb9d8, 0xb9d9, 0xb9db, - 0xb9dd, 0xb9de, 0xb9e1, 0xb9e3, 0xb9e4, 0xb9e5, 0xb9e8, 0xb9ec, 0xb9f4, 0xb9f5, 0xb9f7, 0xb9f8, 0xb9f9, 0xb9fa, 0xba00, 0xba01, - 0xba08, 0xba15, 0xba38, 0xba39, 0xba3c, 0xba40, 0xba42, 0xba48, 0xba49, 0xba4b, 0xba4d, 0xba4e, 0xba53, 0xba54, 0xba55, 0xba58, - 0xba5c, 0xba64, 0xba65, 0xba67, 0xba68, 0xba69, 0xba70, 0xba71, 0xba74, 0xba78, 0xba83, 0xba84, 0xba85, 0xba87, 0xba8c, 0xbaa8, - 0xbaa9, 0xbaab, 0xbaac, 0xbab0, 0xbab2, 0xbab8, 0xbab9, 0xbabb, 0xbabd, 0xbac4, 0xbac8, 0xbad8, 0xbad9, 0xbafc, 0xbb00, 0xbb04, - 0xbb0d, 0xbb0f, 0xbb11, 0xbb18, 0xbb1c, 0xbb20, 0xbb29, 0xbb2b, 0xbb34, 0xbb35, 0xbb36, 0xbb38, 0xbb3b, 0xbb3c, 0xbb3d, 0xbb3e, - 0xbb44, 0xbb45, 0xbb47, 0xbb49, 0xbb4d, 0xbb4f, 0xbb50, 0xbb54, 0xbb58, 0xbb61, 0xbb63, 0xbb6c, 0xbb88, 0xbb8c, 0xbb90, 0xbba4, - 0xbba8, 0xbbac, 0xbbb4, 0xbbb7, 0xbbc0, 0xbbc4, 0xbbc8, 0xbbd0, 0xbbd3, 0xbbf8, 0xbbf9, 0xbbfc, 0xbbff, 0xbc00, 0xbc02, 0xbc08, - 0xbc09, 0xbc0b, 0xbc0c, 0xbc0d, 0xbc0f, 0xbc11, 0xbc14, 0xbc15, 0xbc16, 0xbc17, 0xbc18, 0xbc1b, 0xbc1c, 0xbc1d, 0xbc1e, 0xbc1f, - 0xbc24, 0xbc25, 0xbc27, 0xbc29, 0xbc2d, 0xbc30, 0xbc31, 0xbc34, 0xbc38, 0xbc40, 0xbc41, 0xbc43, 0xbc44, 0xbc45, 0xbc49, 0xbc4c, - 0xbc4d, 0xbc50, 0xbc5d, 0xbc84, 0xbc85, 0xbc88, 0xbc8b, 0xbc8c, 0xbc8e, 0xbc94, 0xbc95, 0xbc97, 0xbc99, 0xbc9a, 0xbca0, 0xbca1, - 0xbca4, 0xbca7, 0xbca8, 0xbcb0, 0xbcb1, 0xbcb3, 0xbcb4, 0xbcb5, 0xbcbc, 0xbcbd, 0xbcc0, 0xbcc4, 0xbccd, 0xbccf, 0xbcd0, 0xbcd1, - 0xbcd5, 0xbcd8, 0xbcdc, 0xbcf4, 0xbcf5, 0xbcf6, 0xbcf8, 0xbcfc, 0xbd04, 0xbd05, 0xbd07, 0xbd09, 0xbd10, 0xbd14, 0xbd24, 0xbd2c, - 0xbd40, 0xbd48, 0xbd49, 0xbd4c, 0xbd50, 0xbd58, 0xbd59, 0xbd64, 0xbd68, 0xbd80, 0xbd81, 0xbd84, 0xbd87, 0xbd88, 0xbd89, 0xbd8a, - 0xbd90, 0xbd91, 0xbd93, 0xbd95, 0xbd99, 0xbd9a, 0xbd9c, 0xbda4, 0xbdb0, 0xbdb8, 0xbdd4, 0xbdd5, 0xbdd8, 0xbddc, 0xbde9, 0xbdf0, - 0xbdf4, 0xbdf8, 0xbe00, 0xbe03, 0xbe05, 0xbe0c, 0xbe0d, 0xbe10, 0xbe14, 0xbe1c, 0xbe1d, 0xbe1f, 0xbe44, 0xbe45, 0xbe48, 0xbe4c, - 0xbe4e, 0xbe54, 0xbe55, 0xbe57, 0xbe59, 0xbe5a, 0xbe5b, 0xbe60, 0xbe61, 0xbe64, 0xbe68, 0xbe6a, 0xbe70, 0xbe71, 0xbe73, 0xbe74, - 0xbe75, 0xbe7b, 0xbe7c, 0xbe7d, 0xbe80, 0xbe84, 0xbe8c, 0xbe8d, 0xbe8f, 0xbe90, 0xbe91, 0xbe98, 0xbe99, 0xbea8, 0xbed0, 0xbed1, - 0xbed4, 0xbed7, 0xbed8, 0xbee0, 0xbee3, 0xbee4, 0xbee5, 0xbeec, 0xbf01, 0xbf08, 0xbf09, 0xbf18, 0xbf19, 0xbf1b, 0xbf1c, 0xbf1d, - 0xbf40, 0xbf41, 0xbf44, 0xbf48, 0xbf50, 0xbf51, 0xbf55, 0xbf94, 0xbfb0, 0xbfc5, 0xbfcc, 0xbfcd, 0xbfd0, 0xbfd4, 0xbfdc, 0xbfdf, - 0xbfe1, 0xc03c, 0xc051, 0xc058, 0xc05c, 0xc060, 0xc068, 0xc069, 0xc090, 0xc091, 0xc094, 0xc098, 0xc0a0, 0xc0a1, 0xc0a3, 0xc0a5, - 0xc0ac, 0xc0ad, 0xc0af, 0xc0b0, 0xc0b3, 0xc0b4, 0xc0b5, 0xc0b6, 0xc0bc, 0xc0bd, 0xc0bf, 0xc0c0, 0xc0c1, 0xc0c5, 0xc0c8, 0xc0c9, - 0xc0cc, 0xc0d0, 0xc0d8, 0xc0d9, 0xc0db, 0xc0dc, 0xc0dd, 0xc0e4, 0xc0e5, 0xc0e8, 0xc0ec, 0xc0f4, 0xc0f5, 0xc0f7, 0xc0f9, 0xc100, - 0xc104, 0xc108, 0xc110, 0xc115, 0xc11c, 0xc11d, 0xc11e, 0xc11f, 0xc120, 0xc123, 0xc124, 0xc126, 0xc127, 0xc12c, 0xc12d, 0xc12f, - 0xc130, 0xc131, 0xc136, 0xc138, 0xc139, 0xc13c, 0xc140, 0xc148, 0xc149, 0xc14b, 0xc14c, 0xc14d, 0xc154, 0xc155, 0xc158, 0xc15c, - 0xc164, 0xc165, 0xc167, 0xc168, 0xc169, 0xc170, 0xc174, 0xc178, 0xc185, 0xc18c, 0xc18d, 0xc18e, 0xc190, 0xc194, 0xc196, 0xc19c, - 0xc19d, 0xc19f, 0xc1a1, 0xc1a5, 0xc1a8, 0xc1a9, 0xc1ac, 0xc1b0, 0xc1bd, 0xc1c4, 0xc1c8, 0xc1cc, 0xc1d4, 0xc1d7, 0xc1d8, 0xc1e0, - 0xc1e4, 0xc1e8, 0xc1f0, 0xc1f1, 0xc1f3, 0xc1fc, 0xc1fd, 0xc200, 0xc204, 0xc20c, 0xc20d, 0xc20f, 0xc211, 0xc218, 0xc219, 0xc21c, - 0xc21f, 0xc220, 0xc228, 0xc229, 0xc22b, 0xc22d, 0xc22f, 0xc231, 0xc232, 0xc234, 0xc248, 0xc250, 0xc251, 0xc254, 0xc258, 0xc260, - 0xc265, 0xc26c, 0xc26d, 0xc270, 0xc274, 0xc27c, 0xc27d, 0xc27f, 0xc281, 0xc288, 0xc289, 0xc290, 0xc298, 0xc29b, 0xc29d, 0xc2a4, - 0xc2a5, 0xc2a8, 0xc2ac, 0xc2ad, 0xc2b4, 0xc2b5, 0xc2b7, 0xc2b9, 0xc2dc, 0xc2dd, 0xc2e0, 0xc2e3, 0xc2e4, 0xc2eb, 0xc2ec, 0xc2ed, - 0xc2ef, 0xc2f1, 0xc2f6, 0xc2f8, 0xc2f9, 0xc2fb, 0xc2fc, 0xc300, 0xc308, 0xc309, 0xc30c, 0xc30d, 0xc313, 0xc314, 0xc315, 0xc318, - 0xc31c, 0xc324, 0xc325, 0xc328, 0xc329, 0xc345, 0xc368, 0xc369, 0xc36c, 0xc370, 0xc372, 0xc378, 0xc379, 0xc37c, 0xc37d, 0xc384, - 0xc388, 0xc38c, 0xc3c0, 0xc3d8, 0xc3d9, 0xc3dc, 0xc3df, 0xc3e0, 0xc3e2, 0xc3e8, 0xc3e9, 0xc3ed, 0xc3f4, 0xc3f5, 0xc3f8, 0xc408, - 0xc410, 0xc424, 0xc42c, 0xc430, 0xc434, 0xc43c, 0xc43d, 0xc448, 0xc464, 0xc465, 0xc468, 0xc46c, 0xc474, 0xc475, 0xc479, 0xc480, - 0xc494, 0xc49c, 0xc4b8, 0xc4bc, 0xc4e9, 0xc4f0, 0xc4f1, 0xc4f4, 0xc4f8, 0xc4fa, 0xc4ff, 0xc500, 0xc501, 0xc50c, 0xc510, 0xc514, - 0xc51c, 0xc528, 0xc529, 0xc52c, 0xc530, 0xc538, 0xc539, 0xc53b, 0xc53d, 0xc544, 0xc545, 0xc548, 0xc549, 0xc54a, 0xc54c, 0xc54d, - 0xc54e, 0xc553, 0xc554, 0xc555, 0xc557, 0xc558, 0xc559, 0xc55d, 0xc55e, 0xc560, 0xc561, 0xc564, 0xc568, 0xc570, 0xc571, 0xc573, - 0xc574, 0xc575, 0xc57c, 0xc57d, 0xc580, 0xc584, 0xc587, 0xc58c, 0xc58d, 0xc58f, 0xc591, 0xc595, 0xc597, 0xc598, 0xc59c, 0xc5a0, - 0xc5a9, 0xc5b4, 0xc5b5, 0xc5b8, 0xc5b9, 0xc5bb, 0xc5bc, 0xc5bd, 0xc5be, 0xc5c4, 0xc5c5, 0xc5c6, 0xc5c7, 0xc5c8, 0xc5c9, 0xc5ca, - 0xc5cc, 0xc5ce, 0xc5d0, 0xc5d1, 0xc5d4, 0xc5d8, 0xc5e0, 0xc5e1, 0xc5e3, 0xc5e5, 0xc5ec, 0xc5ed, 0xc5ee, 0xc5f0, 0xc5f4, 0xc5f6, - 0xc5f7, 0xc5fc, 0xc5fd, 0xc5fe, 0xc5ff, 0xc600, 0xc601, 0xc605, 0xc606, 0xc607, 0xc608, 0xc60c, 0xc610, 0xc618, 0xc619, 0xc61b, - 0xc61c, 0xc624, 0xc625, 0xc628, 0xc62c, 0xc62d, 0xc62e, 0xc630, 0xc633, 0xc634, 0xc635, 0xc637, 0xc639, 0xc63b, 0xc640, 0xc641, - 0xc644, 0xc648, 0xc650, 0xc651, 0xc653, 0xc654, 0xc655, 0xc65c, 0xc65d, 0xc660, 0xc66c, 0xc66f, 0xc671, 0xc678, 0xc679, 0xc67c, - 0xc680, 0xc688, 0xc689, 0xc68b, 0xc68d, 0xc694, 0xc695, 0xc698, 0xc69c, 0xc6a4, 0xc6a5, 0xc6a7, 0xc6a9, 0xc6b0, 0xc6b1, 0xc6b4, - 0xc6b8, 0xc6b9, 0xc6ba, 0xc6c0, 0xc6c1, 0xc6c3, 0xc6c5, 0xc6cc, 0xc6cd, 0xc6d0, 0xc6d4, 0xc6dc, 0xc6dd, 0xc6e0, 0xc6e1, 0xc6e8, - 0xc6e9, 0xc6ec, 0xc6f0, 0xc6f8, 0xc6f9, 0xc6fd, 0xc704, 0xc705, 0xc708, 0xc70c, 0xc714, 0xc715, 0xc717, 0xc719, 0xc720, 0xc721, - 0xc724, 0xc728, 0xc730, 0xc731, 0xc733, 0xc735, 0xc737, 0xc73c, 0xc73d, 0xc740, 0xc744, 0xc74a, 0xc74c, 0xc74d, 0xc74f, 0xc751, - 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc75c, 0xc760, 0xc768, 0xc76b, 0xc774, 0xc775, 0xc778, 0xc77c, 0xc77d, - 0xc77e, 0xc783, 0xc784, 0xc785, 0xc787, 0xc788, 0xc789, 0xc78a, 0xc78e, 0xc790, 0xc791, 0xc794, 0xc796, 0xc797, 0xc798, 0xc79a, - 0xc7a0, 0xc7a1, 0xc7a3, 0xc7a4, 0xc7a5, 0xc7a6, 0xc7ac, 0xc7ad, 0xc7b0, 0xc7b4, 0xc7bc, 0xc7bd, 0xc7bf, 0xc7c0, 0xc7c1, 0xc7c8, - 0xc7c9, 0xc7cc, 0xc7ce, 0xc7d0, 0xc7d8, 0xc7dd, 0xc7e4, 0xc7e8, 0xc7ec, 0xc800, 0xc801, 0xc804, 0xc808, 0xc80a, 0xc810, 0xc811, - 0xc813, 0xc815, 0xc816, 0xc81c, 0xc81d, 0xc820, 0xc824, 0xc82c, 0xc82d, 0xc82f, 0xc831, 0xc838, 0xc83c, 0xc840, 0xc848, 0xc849, - 0xc84c, 0xc84d, 0xc854, 0xc870, 0xc871, 0xc874, 0xc878, 0xc87a, 0xc880, 0xc881, 0xc883, 0xc885, 0xc886, 0xc887, 0xc88b, 0xc88c, - 0xc88d, 0xc894, 0xc89d, 0xc89f, 0xc8a1, 0xc8a8, 0xc8bc, 0xc8bd, 0xc8c4, 0xc8c8, 0xc8cc, 0xc8d4, 0xc8d5, 0xc8d7, 0xc8d9, 0xc8e0, - 0xc8e1, 0xc8e4, 0xc8f5, 0xc8fc, 0xc8fd, 0xc900, 0xc904, 0xc905, 0xc906, 0xc90c, 0xc90d, 0xc90f, 0xc911, 0xc918, 0xc92c, 0xc934, - 0xc950, 0xc951, 0xc954, 0xc958, 0xc960, 0xc961, 0xc963, 0xc96c, 0xc970, 0xc974, 0xc97c, 0xc988, 0xc989, 0xc98c, 0xc990, 0xc998, - 0xc999, 0xc99b, 0xc99d, 0xc9c0, 0xc9c1, 0xc9c4, 0xc9c7, 0xc9c8, 0xc9ca, 0xc9d0, 0xc9d1, 0xc9d3, 0xc9d5, 0xc9d6, 0xc9d9, 0xc9da, - 0xc9dc, 0xc9dd, 0xc9e0, 0xc9e2, 0xc9e4, 0xc9e7, 0xc9ec, 0xc9ed, 0xc9ef, 0xc9f0, 0xc9f1, 0xc9f8, 0xc9f9, 0xc9fc, 0xca00, 0xca08, - 0xca09, 0xca0b, 0xca0c, 0xca0d, 0xca14, 0xca18, 0xca29, 0xca4c, 0xca4d, 0xca50, 0xca54, 0xca5c, 0xca5d, 0xca5f, 0xca60, 0xca61, - 0xca68, 0xca7d, 0xca84, 0xca98, 0xcabc, 0xcabd, 0xcac0, 0xcac4, 0xcacc, 0xcacd, 0xcacf, 0xcad1, 0xcad3, 0xcad8, 0xcad9, 0xcae0, - 0xcaec, 0xcaf4, 0xcb08, 0xcb10, 0xcb14, 0xcb18, 0xcb20, 0xcb21, 0xcb41, 0xcb48, 0xcb49, 0xcb4c, 0xcb50, 0xcb58, 0xcb59, 0xcb5d, - 0xcb64, 0xcb78, 0xcb79, 0xcb9c, 0xcbb8, 0xcbd4, 0xcbe4, 0xcbe7, 0xcbe9, 0xcc0c, 0xcc0d, 0xcc10, 0xcc14, 0xcc1c, 0xcc1d, 0xcc21, - 0xcc22, 0xcc27, 0xcc28, 0xcc29, 0xcc2c, 0xcc2e, 0xcc30, 0xcc38, 0xcc39, 0xcc3b, 0xcc3c, 0xcc3d, 0xcc3e, 0xcc44, 0xcc45, 0xcc48, - 0xcc4c, 0xcc54, 0xcc55, 0xcc57, 0xcc58, 0xcc59, 0xcc60, 0xcc64, 0xcc66, 0xcc68, 0xcc70, 0xcc75, 0xcc98, 0xcc99, 0xcc9c, 0xcca0, - 0xcca8, 0xcca9, 0xccab, 0xccac, 0xccad, 0xccb4, 0xccb5, 0xccb8, 0xccbc, 0xccc4, 0xccc5, 0xccc7, 0xccc9, 0xccd0, 0xccd4, 0xcce4, - 0xccec, 0xccf0, 0xcd01, 0xcd08, 0xcd09, 0xcd0c, 0xcd10, 0xcd18, 0xcd19, 0xcd1b, 0xcd1d, 0xcd24, 0xcd28, 0xcd2c, 0xcd39, 0xcd5c, - 0xcd60, 0xcd64, 0xcd6c, 0xcd6d, 0xcd6f, 0xcd71, 0xcd78, 0xcd88, 0xcd94, 0xcd95, 0xcd98, 0xcd9c, 0xcda4, 0xcda5, 0xcda7, 0xcda9, - 0xcdb0, 0xcdc4, 0xcdcc, 0xcdd0, 0xcde8, 0xcdec, 0xcdf0, 0xcdf8, 0xcdf9, 0xcdfb, 0xcdfd, 0xce04, 0xce08, 0xce0c, 0xce14, 0xce19, - 0xce20, 0xce21, 0xce24, 0xce28, 0xce30, 0xce31, 0xce33, 0xce35, 0xce58, 0xce59, 0xce5c, 0xce5f, 0xce60, 0xce61, 0xce68, 0xce69, - 0xce6b, 0xce6d, 0xce74, 0xce75, 0xce78, 0xce7c, 0xce84, 0xce85, 0xce87, 0xce89, 0xce90, 0xce91, 0xce94, 0xce98, 0xcea0, 0xcea1, - 0xcea3, 0xcea4, 0xcea5, 0xceac, 0xcead, 0xcec1, 0xcee4, 0xcee5, 0xcee8, 0xceeb, 0xceec, 0xcef4, 0xcef5, 0xcef7, 0xcef8, 0xcef9, - 0xcf00, 0xcf01, 0xcf04, 0xcf08, 0xcf10, 0xcf11, 0xcf13, 0xcf15, 0xcf1c, 0xcf20, 0xcf24, 0xcf2c, 0xcf2d, 0xcf2f, 0xcf30, 0xcf31, - 0xcf38, 0xcf54, 0xcf55, 0xcf58, 0xcf5c, 0xcf64, 0xcf65, 0xcf67, 0xcf69, 0xcf70, 0xcf71, 0xcf74, 0xcf78, 0xcf80, 0xcf85, 0xcf8c, - 0xcfa1, 0xcfa8, 0xcfb0, 0xcfc4, 0xcfe0, 0xcfe1, 0xcfe4, 0xcfe8, 0xcff0, 0xcff1, 0xcff3, 0xcff5, 0xcffc, 0xd000, 0xd004, 0xd011, - 0xd018, 0xd02d, 0xd034, 0xd035, 0xd038, 0xd03c, 0xd044, 0xd045, 0xd047, 0xd049, 0xd050, 0xd054, 0xd058, 0xd060, 0xd06c, 0xd06d, - 0xd070, 0xd074, 0xd07c, 0xd07d, 0xd081, 0xd0a4, 0xd0a5, 0xd0a8, 0xd0ac, 0xd0b4, 0xd0b5, 0xd0b7, 0xd0b9, 0xd0c0, 0xd0c1, 0xd0c4, - 0xd0c8, 0xd0c9, 0xd0d0, 0xd0d1, 0xd0d3, 0xd0d4, 0xd0d5, 0xd0dc, 0xd0dd, 0xd0e0, 0xd0e4, 0xd0ec, 0xd0ed, 0xd0ef, 0xd0f0, 0xd0f1, - 0xd0f8, 0xd10d, 0xd130, 0xd131, 0xd134, 0xd138, 0xd13a, 0xd140, 0xd141, 0xd143, 0xd144, 0xd145, 0xd14c, 0xd14d, 0xd150, 0xd154, - 0xd15c, 0xd15d, 0xd15f, 0xd161, 0xd168, 0xd16c, 0xd17c, 0xd184, 0xd188, 0xd1a0, 0xd1a1, 0xd1a4, 0xd1a8, 0xd1b0, 0xd1b1, 0xd1b3, - 0xd1b5, 0xd1ba, 0xd1bc, 0xd1c0, 0xd1d8, 0xd1f4, 0xd1f8, 0xd207, 0xd209, 0xd210, 0xd22c, 0xd22d, 0xd230, 0xd234, 0xd23c, 0xd23d, - 0xd23f, 0xd241, 0xd248, 0xd25c, 0xd264, 0xd280, 0xd281, 0xd284, 0xd288, 0xd290, 0xd291, 0xd295, 0xd29c, 0xd2a0, 0xd2a4, 0xd2ac, - 0xd2b1, 0xd2b8, 0xd2b9, 0xd2bc, 0xd2bf, 0xd2c0, 0xd2c2, 0xd2c8, 0xd2c9, 0xd2cb, 0xd2d4, 0xd2d8, 0xd2dc, 0xd2e4, 0xd2e5, 0xd2f0, - 0xd2f1, 0xd2f4, 0xd2f8, 0xd300, 0xd301, 0xd303, 0xd305, 0xd30c, 0xd30d, 0xd30e, 0xd310, 0xd314, 0xd316, 0xd31c, 0xd31d, 0xd31f, - 0xd320, 0xd321, 0xd325, 0xd328, 0xd329, 0xd32c, 0xd330, 0xd338, 0xd339, 0xd33b, 0xd33c, 0xd33d, 0xd344, 0xd345, 0xd37c, 0xd37d, - 0xd380, 0xd384, 0xd38c, 0xd38d, 0xd38f, 0xd390, 0xd391, 0xd398, 0xd399, 0xd39c, 0xd3a0, 0xd3a8, 0xd3a9, 0xd3ab, 0xd3ad, 0xd3b4, - 0xd3b8, 0xd3bc, 0xd3c4, 0xd3c5, 0xd3c8, 0xd3c9, 0xd3d0, 0xd3d8, 0xd3e1, 0xd3e3, 0xd3ec, 0xd3ed, 0xd3f0, 0xd3f4, 0xd3fc, 0xd3fd, - 0xd3ff, 0xd401, 0xd408, 0xd41d, 0xd440, 0xd444, 0xd45c, 0xd460, 0xd464, 0xd46d, 0xd46f, 0xd478, 0xd479, 0xd47c, 0xd47f, 0xd480, - 0xd482, 0xd488, 0xd489, 0xd48b, 0xd48d, 0xd494, 0xd4a9, 0xd4cc, 0xd4d0, 0xd4d4, 0xd4dc, 0xd4df, 0xd4e8, 0xd4ec, 0xd4f0, 0xd4f8, - 0xd4fb, 0xd4fd, 0xd504, 0xd508, 0xd50c, 0xd514, 0xd515, 0xd517, 0xd53c, 0xd53d, 0xd540, 0xd544, 0xd54c, 0xd54d, 0xd54f, 0xd551, - 0xd558, 0xd559, 0xd55c, 0xd560, 0xd565, 0xd568, 0xd569, 0xd56b, 0xd56d, 0xd574, 0xd575, 0xd578, 0xd57c, 0xd584, 0xd585, 0xd587, - 0xd588, 0xd589, 0xd590, 0xd5a5, 0xd5c8, 0xd5c9, 0xd5cc, 0xd5d0, 0xd5d2, 0xd5d8, 0xd5d9, 0xd5db, 0xd5dd, 0xd5e4, 0xd5e5, 0xd5e8, - 0xd5ec, 0xd5f4, 0xd5f5, 0xd5f7, 0xd5f9, 0xd600, 0xd601, 0xd604, 0xd608, 0xd610, 0xd611, 0xd613, 0xd614, 0xd615, 0xd61c, 0xd620, - 0xd624, 0xd62d, 0xd638, 0xd639, 0xd63c, 0xd640, 0xd645, 0xd648, 0xd649, 0xd64b, 0xd64d, 0xd651, 0xd654, 0xd655, 0xd658, 0xd65c, - 0xd667, 0xd669, 0xd670, 0xd671, 0xd674, 0xd683, 0xd685, 0xd68c, 0xd68d, 0xd690, 0xd694, 0xd69d, 0xd69f, 0xd6a1, 0xd6a8, 0xd6ac, - 0xd6b0, 0xd6b9, 0xd6bb, 0xd6c4, 0xd6c5, 0xd6c8, 0xd6cc, 0xd6d1, 0xd6d4, 0xd6d7, 0xd6d9, 0xd6e0, 0xd6e4, 0xd6e8, 0xd6f0, 0xd6f5, - 0xd6fc, 0xd6fd, 0xd700, 0xd704, 0xd711, 0xd718, 0xd719, 0xd71c, 0xd720, 0xd728, 0xd729, 0xd72b, 0xd72d, 0xd734, 0xd735, 0xd738, - 0xd73c, 0xd744, 0xd747, 0xd749, 0xd750, 0xd751, 0xd754, 0xd756, 0xd757, 0xd758, 0xd759, 0xd760, 0xd761, 0xd763, 0xd765, 0xd769, - 0xd76c, 0xd770, 0xd774, 0xd77c, 0xd77d, 0xd781, 0xd788, 0xd789, 0xd78c, 0xd790, 0xd798, 0xd799, 0xd79b, 0xd79d -}; diff --git a/core/src/textcodec/KRHangulMapping.h b/core/src/textcodec/KRHangulMapping.h deleted file mode 100644 index 044b3d5d57..0000000000 --- a/core/src/textcodec/KRHangulMapping.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -/* Table including ksc5601 hangul to unicode */ -extern const uint16_t ksc5601_hangul_to_unicode[2350]; \ No newline at end of file diff --git a/core/src/textcodec/KRTextDecoder.cpp b/core/src/textcodec/KRTextDecoder.cpp deleted file mode 100644 index dcbc0646ac..0000000000 --- a/core/src/textcodec/KRTextDecoder.cpp +++ /dev/null @@ -1,1097 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Most of the cp949 code was originally written by Joon-Kyu Park, and is included -// in Qt with the author's permission and the grateful thanks of the Qt team. - -#include "KRTextDecoder.h" -#include "KRHangulMapping.h" - -static const uint16_t cp949_icode_to_unicode[8822] = { - 0xac02, 0xac03, 0xac05, 0xac06, 0xac0b, 0xac0c, 0xac0d, 0xac0e, 0xac0f, 0xac18, 0xac1e, 0xac1f, 0xac21, 0xac22, 0xac23, 0xac25, - 0xac26, 0xac27, 0xac28, 0xac29, 0xac2a, 0xac2b, 0xac2e, 0xac32, 0xac33, 0xac34, 0xac35, 0xac36, 0xac37, 0xac3a, 0xac3b, 0xac3d, - 0xac3e, 0xac3f, 0xac41, 0xac42, 0xac43, 0xac44, 0xac45, 0xac46, 0xac47, 0xac48, 0xac49, 0xac4a, 0xac4c, 0xac4e, 0xac4f, 0xac50, - 0xac51, 0xac52, 0xac53, 0xac55, 0xac56, 0xac57, 0xac59, 0xac5a, 0xac5b, 0xac5d, 0xac5e, 0xac5f, 0xac60, 0xac61, 0xac62, 0xac63, - 0xac64, 0xac65, 0xac66, 0xac67, 0xac68, 0xac69, 0xac6a, 0xac6b, 0xac6c, 0xac6d, 0xac6e, 0xac6f, 0xac72, 0xac73, 0xac75, 0xac76, - 0xac79, 0xac7b, 0xac7c, 0xac7d, 0xac7e, 0xac7f, 0xac82, 0xac87, 0xac88, 0xac8d, 0xac8e, 0xac8f, 0xac91, 0xac92, 0xac93, 0xac95, - 0xac96, 0xac97, 0xac98, 0xac99, 0xac9a, 0xac9b, 0xac9e, 0xaca2, 0xaca3, 0xaca4, 0xaca5, 0xaca6, 0xaca7, 0xacab, 0xacad, 0xacae, - 0xacb1, 0xacb2, 0xacb3, 0xacb4, 0xacb5, 0xacb6, 0xacb7, 0xacba, 0xacbe, 0xacbf, 0xacc0, 0xacc2, 0xacc3, 0xacc5, 0xacc6, 0xacc7, - 0xacc9, 0xacca, 0xaccb, 0xaccd, 0xacce, 0xaccf, 0xacd0, 0xacd1, 0xacd2, 0xacd3, 0xacd4, 0xacd6, 0xacd8, 0xacd9, 0xacda, 0xacdb, - 0xacdc, 0xacdd, 0xacde, 0xacdf, 0xace2, 0xace3, 0xace5, 0xace6, 0xace9, 0xaceb, 0xaced, 0xacee, 0xacf2, 0xacf4, 0xacf7, 0xacf8, - 0xacf9, 0xacfa, 0xacfb, 0xacfe, 0xacff, 0xad01, 0xad02, 0xad03, 0xad05, 0xad07, 0xad08, 0xad09, 0xad0a, 0xad0b, 0xad0e, 0xad10, - 0xad12, 0xad13, 0xad14, 0xad15, 0xad16, 0xad17, 0xad19, 0xad1a, 0xad1b, 0xad1d, 0xad1e, 0xad1f, 0xad21, 0xad22, 0xad23, 0xad24, - 0xad25, 0xad26, 0xad27, 0xad28, 0xad2a, 0xad2b, 0xad2e, 0xad2f, 0xad30, 0xad31, 0xad32, 0xad33, 0xad36, 0xad37, 0xad39, 0xad3a, - 0xad3b, 0xad3d, 0xad3e, 0xad3f, 0xad40, 0xad41, 0xad42, 0xad43, 0xad46, 0xad48, 0xad4a, 0xad4b, 0xad4c, 0xad4d, 0xad4e, 0xad4f, - 0xad51, 0xad52, 0xad53, 0xad55, 0xad56, 0xad57, 0xad59, 0xad5a, 0xad5b, 0xad5c, 0xad5d, 0xad5e, 0xad5f, 0xad60, 0xad62, 0xad64, - 0xad65, 0xad66, 0xad67, 0xad68, 0xad69, 0xad6a, 0xad6b, 0xad6e, 0xad6f, 0xad71, 0xad72, 0xad77, 0xad78, 0xad79, 0xad7a, 0xad7e, - 0xad80, 0xad83, 0xad84, 0xad85, 0xad86, 0xad87, 0xad8a, 0xad8b, 0xad8d, 0xad8e, 0xad8f, 0xad91, 0xad92, 0xad93, 0xad94, 0xad95, - 0xad96, 0xad97, 0xad98, 0xad99, 0xad9a, 0xad9b, 0xad9e, 0xad9f, 0xada0, 0xada1, 0xada2, 0xada3, 0xada5, 0xada6, 0xada7, 0xada8, - 0xada9, 0xadaa, 0xadab, 0xadac, 0xadad, 0xadae, 0xadaf, 0xadb0, 0xadb1, 0xadb2, 0xadb3, 0xadb4, 0xadb5, 0xadb6, 0xadb8, 0xadb9, - 0xadba, 0xadbb, 0xadbc, 0xadbd, 0xadbe, 0xadbf, 0xadc2, 0xadc3, 0xadc5, 0xadc6, 0xadc7, 0xadc9, 0xadca, 0xadcb, 0xadcc, 0xadcd, - 0xadce, 0xadcf, 0xadd2, 0xadd4, 0xadd5, 0xadd6, 0xadd7, 0xadd8, 0xadd9, 0xadda, 0xaddb, 0xaddd, 0xadde, 0xaddf, 0xade1, 0xade2, - 0xade3, 0xade5, 0xade6, 0xade7, 0xade8, 0xade9, 0xadea, 0xadeb, 0xadec, 0xaded, 0xadee, 0xadef, 0xadf0, 0xadf1, 0xadf2, 0xadf3, - 0xadf4, 0xadf5, 0xadf6, 0xadf7, 0xadfa, 0xadfb, 0xadfd, 0xadfe, 0xae02, 0xae03, 0xae04, 0xae05, 0xae06, 0xae07, 0xae0a, 0xae0c, - 0xae0e, 0xae0f, 0xae10, 0xae11, 0xae12, 0xae13, 0xae15, 0xae16, 0xae17, 0xae18, 0xae19, 0xae1a, 0xae1b, 0xae1c, 0xae1d, 0xae1e, - 0xae1f, 0xae20, 0xae21, 0xae22, 0xae23, 0xae24, 0xae25, 0xae26, 0xae27, 0xae28, 0xae29, 0xae2a, 0xae2b, 0xae2c, 0xae2d, 0xae2e, - 0xae2f, 0xae32, 0xae33, 0xae35, 0xae36, 0xae39, 0xae3b, 0xae3c, 0xae3d, 0xae3e, 0xae3f, 0xae42, 0xae44, 0xae47, 0xae48, 0xae49, - 0xae4b, 0xae4f, 0xae51, 0xae52, 0xae53, 0xae55, 0xae57, 0xae58, 0xae59, 0xae5a, 0xae5b, 0xae5e, 0xae62, 0xae63, 0xae64, 0xae66, - 0xae67, 0xae6a, 0xae6b, 0xae6d, 0xae6e, 0xae6f, 0xae71, 0xae72, 0xae73, 0xae74, 0xae75, 0xae76, 0xae77, 0xae7a, 0xae7e, 0xae7f, - 0xae80, 0xae81, 0xae82, 0xae83, 0xae86, 0xae87, 0xae88, 0xae89, 0xae8a, 0xae8b, 0xae8d, 0xae8e, 0xae8f, 0xae90, 0xae91, 0xae92, - 0xae93, 0xae94, 0xae95, 0xae96, 0xae97, 0xae98, 0xae99, 0xae9a, 0xae9b, 0xae9c, 0xae9d, 0xae9e, 0xae9f, 0xaea0, 0xaea1, 0xaea2, - 0xaea3, 0xaea4, 0xaea5, 0xaea6, 0xaea7, 0xaea8, 0xaea9, 0xaeaa, 0xaeab, 0xaeac, 0xaead, 0xaeae, 0xaeaf, 0xaeb0, 0xaeb1, 0xaeb2, - 0xaeb3, 0xaeb4, 0xaeb5, 0xaeb6, 0xaeb7, 0xaeb8, 0xaeb9, 0xaeba, 0xaebb, 0xaebf, 0xaec1, 0xaec2, 0xaec3, 0xaec5, 0xaec6, 0xaec7, - 0xaec8, 0xaec9, 0xaeca, 0xaecb, 0xaece, 0xaed2, 0xaed3, 0xaed4, 0xaed5, 0xaed6, 0xaed7, 0xaeda, 0xaedb, 0xaedd, 0xaede, 0xaedf, - 0xaee0, 0xaee1, 0xaee2, 0xaee3, 0xaee4, 0xaee5, 0xaee6, 0xaee7, 0xaee9, 0xaeea, 0xaeec, 0xaeee, 0xaeef, 0xaef0, 0xaef1, 0xaef2, - 0xaef3, 0xaef5, 0xaef6, 0xaef7, 0xaef9, 0xaefa, 0xaefb, 0xaefd, 0xaefe, 0xaeff, 0xaf00, 0xaf01, 0xaf02, 0xaf03, 0xaf04, 0xaf05, - 0xaf06, 0xaf09, 0xaf0a, 0xaf0b, 0xaf0c, 0xaf0e, 0xaf0f, 0xaf11, 0xaf12, 0xaf13, 0xaf14, 0xaf15, 0xaf16, 0xaf17, 0xaf18, 0xaf19, - 0xaf1a, 0xaf1b, 0xaf1c, 0xaf1d, 0xaf1e, 0xaf1f, 0xaf20, 0xaf21, 0xaf22, 0xaf23, 0xaf24, 0xaf25, 0xaf26, 0xaf27, 0xaf28, 0xaf29, - 0xaf2a, 0xaf2b, 0xaf2e, 0xaf2f, 0xaf31, 0xaf33, 0xaf35, 0xaf36, 0xaf37, 0xaf38, 0xaf39, 0xaf3a, 0xaf3b, 0xaf3e, 0xaf40, 0xaf44, - 0xaf45, 0xaf46, 0xaf47, 0xaf4a, 0xaf4b, 0xaf4c, 0xaf4d, 0xaf4e, 0xaf4f, 0xaf51, 0xaf52, 0xaf53, 0xaf54, 0xaf55, 0xaf56, 0xaf57, - 0xaf58, 0xaf59, 0xaf5a, 0xaf5b, 0xaf5e, 0xaf5f, 0xaf60, 0xaf61, 0xaf62, 0xaf63, 0xaf66, 0xaf67, 0xaf68, 0xaf69, 0xaf6a, 0xaf6b, - 0xaf6c, 0xaf6d, 0xaf6e, 0xaf6f, 0xaf70, 0xaf71, 0xaf72, 0xaf73, 0xaf74, 0xaf75, 0xaf76, 0xaf77, 0xaf78, 0xaf7a, 0xaf7b, 0xaf7c, - 0xaf7d, 0xaf7e, 0xaf7f, 0xaf81, 0xaf82, 0xaf83, 0xaf85, 0xaf86, 0xaf87, 0xaf89, 0xaf8a, 0xaf8b, 0xaf8c, 0xaf8d, 0xaf8e, 0xaf8f, - 0xaf92, 0xaf93, 0xaf94, 0xaf96, 0xaf97, 0xaf98, 0xaf99, 0xaf9a, 0xaf9b, 0xaf9d, 0xaf9e, 0xaf9f, 0xafa0, 0xafa1, 0xafa2, 0xafa3, - 0xafa4, 0xafa5, 0xafa6, 0xafa7, 0xafa8, 0xafa9, 0xafaa, 0xafab, 0xafac, 0xafad, 0xafae, 0xafaf, 0xafb0, 0xafb1, 0xafb2, 0xafb3, - 0xafb4, 0xafb5, 0xafb6, 0xafb7, 0xafba, 0xafbb, 0xafbd, 0xafbe, 0xafbf, 0xafc1, 0xafc2, 0xafc3, 0xafc4, 0xafc5, 0xafc6, 0xafca, - 0xafcc, 0xafcf, 0xafd0, 0xafd1, 0xafd2, 0xafd3, 0xafd5, 0xafd6, 0xafd7, 0xafd8, 0xafd9, 0xafda, 0xafdb, 0xafdd, 0xafde, 0xafdf, - 0xafe0, 0xafe1, 0xafe2, 0xafe3, 0xafe4, 0xafe5, 0xafe6, 0xafe7, 0xafea, 0xafeb, 0xafec, 0xafed, 0xafee, 0xafef, 0xaff2, 0xaff3, - 0xaff5, 0xaff6, 0xaff7, 0xaff9, 0xaffa, 0xaffb, 0xaffc, 0xaffd, 0xaffe, 0xafff, 0xb002, 0xb003, 0xb005, 0xb006, 0xb007, 0xb008, - 0xb009, 0xb00a, 0xb00b, 0xb00d, 0xb00e, 0xb00f, 0xb011, 0xb012, 0xb013, 0xb015, 0xb016, 0xb017, 0xb018, 0xb019, 0xb01a, 0xb01b, - 0xb01e, 0xb01f, 0xb020, 0xb021, 0xb022, 0xb023, 0xb024, 0xb025, 0xb026, 0xb027, 0xb029, 0xb02a, 0xb02b, 0xb02c, 0xb02d, 0xb02e, - 0xb02f, 0xb030, 0xb031, 0xb032, 0xb033, 0xb034, 0xb035, 0xb036, 0xb037, 0xb038, 0xb039, 0xb03a, 0xb03b, 0xb03c, 0xb03d, 0xb03e, - 0xb03f, 0xb040, 0xb041, 0xb042, 0xb043, 0xb046, 0xb047, 0xb049, 0xb04b, 0xb04d, 0xb04f, 0xb050, 0xb051, 0xb052, 0xb056, 0xb058, - 0xb05a, 0xb05b, 0xb05c, 0xb05e, 0xb05f, 0xb060, 0xb061, 0xb062, 0xb063, 0xb064, 0xb065, 0xb066, 0xb067, 0xb068, 0xb069, 0xb06a, - 0xb06b, 0xb06c, 0xb06d, 0xb06e, 0xb06f, 0xb070, 0xb071, 0xb072, 0xb073, 0xb074, 0xb075, 0xb076, 0xb077, 0xb078, 0xb079, 0xb07a, - 0xb07b, 0xb07e, 0xb07f, 0xb081, 0xb082, 0xb083, 0xb085, 0xb086, 0xb087, 0xb088, 0xb089, 0xb08a, 0xb08b, 0xb08e, 0xb090, 0xb092, - 0xb093, 0xb094, 0xb095, 0xb096, 0xb097, 0xb09b, 0xb09d, 0xb09e, 0xb0a3, 0xb0a4, 0xb0a5, 0xb0a6, 0xb0a7, 0xb0aa, 0xb0b0, 0xb0b2, - 0xb0b6, 0xb0b7, 0xb0b9, 0xb0ba, 0xb0bb, 0xb0bd, 0xb0be, 0xb0bf, 0xb0c0, 0xb0c1, 0xb0c2, 0xb0c3, 0xb0c6, 0xb0ca, 0xb0cb, 0xb0cc, - 0xb0cd, 0xb0ce, 0xb0cf, 0xb0d2, 0xb0d3, 0xb0d5, 0xb0d6, 0xb0d7, 0xb0d9, 0xb0da, 0xb0db, 0xb0dc, 0xb0dd, 0xb0de, 0xb0df, 0xb0e1, - 0xb0e2, 0xb0e3, 0xb0e4, 0xb0e6, 0xb0e7, 0xb0e8, 0xb0e9, 0xb0ea, 0xb0eb, 0xb0ec, 0xb0ed, 0xb0ee, 0xb0ef, 0xb0f0, 0xb0f1, 0xb0f2, - 0xb0f3, 0xb0f4, 0xb0f5, 0xb0f6, 0xb0f7, 0xb0f8, 0xb0f9, 0xb0fa, 0xb0fb, 0xb0fc, 0xb0fd, 0xb0fe, 0xb0ff, 0xb100, 0xb101, 0xb102, - 0xb103, 0xb104, 0xb105, 0xb106, 0xb107, 0xb10a, 0xb10d, 0xb10e, 0xb10f, 0xb111, 0xb114, 0xb115, 0xb116, 0xb117, 0xb11a, 0xb11e, - 0xb11f, 0xb120, 0xb121, 0xb122, 0xb126, 0xb127, 0xb129, 0xb12a, 0xb12b, 0xb12d, 0xb12e, 0xb12f, 0xb130, 0xb131, 0xb132, 0xb133, - 0xb136, 0xb13a, 0xb13b, 0xb13c, 0xb13d, 0xb13e, 0xb13f, 0xb142, 0xb143, 0xb145, 0xb146, 0xb147, 0xb149, 0xb14a, 0xb14b, 0xb14c, - 0xb14d, 0xb14e, 0xb14f, 0xb152, 0xb153, 0xb156, 0xb157, 0xb159, 0xb15a, 0xb15b, 0xb15d, 0xb15e, 0xb15f, 0xb161, 0xb162, 0xb163, - 0xb164, 0xb165, 0xb166, 0xb167, 0xb168, 0xb169, 0xb16a, 0xb16b, 0xb16c, 0xb16d, 0xb16e, 0xb16f, 0xb170, 0xb171, 0xb172, 0xb173, - 0xb174, 0xb175, 0xb176, 0xb177, 0xb17a, 0xb17b, 0xb17d, 0xb17e, 0xb17f, 0xb181, 0xb183, 0xb184, 0xb185, 0xb186, 0xb187, 0xb18a, - 0xb18c, 0xb18e, 0xb18f, 0xb190, 0xb191, 0xb195, 0xb196, 0xb197, 0xb199, 0xb19a, 0xb19b, 0xb19d, 0xb19e, 0xb19f, 0xb1a0, 0xb1a1, - 0xb1a2, 0xb1a3, 0xb1a4, 0xb1a5, 0xb1a6, 0xb1a7, 0xb1a9, 0xb1aa, 0xb1ab, 0xb1ac, 0xb1ad, 0xb1ae, 0xb1af, 0xb1b0, 0xb1b1, 0xb1b2, - 0xb1b3, 0xb1b4, 0xb1b5, 0xb1b6, 0xb1b7, 0xb1b8, 0xb1b9, 0xb1ba, 0xb1bb, 0xb1bc, 0xb1bd, 0xb1be, 0xb1bf, 0xb1c0, 0xb1c1, 0xb1c2, - 0xb1c3, 0xb1c4, 0xb1c5, 0xb1c6, 0xb1c7, 0xb1c8, 0xb1c9, 0xb1ca, 0xb1cb, 0xb1cd, 0xb1ce, 0xb1cf, 0xb1d1, 0xb1d2, 0xb1d3, 0xb1d5, - 0xb1d6, 0xb1d7, 0xb1d8, 0xb1d9, 0xb1da, 0xb1db, 0xb1de, 0xb1e0, 0xb1e1, 0xb1e2, 0xb1e3, 0xb1e4, 0xb1e5, 0xb1e6, 0xb1e7, 0xb1ea, - 0xb1eb, 0xb1ed, 0xb1ee, 0xb1ef, 0xb1f1, 0xb1f2, 0xb1f3, 0xb1f4, 0xb1f5, 0xb1f6, 0xb1f7, 0xb1f8, 0xb1fa, 0xb1fc, 0xb1fe, 0xb1ff, - 0xb200, 0xb201, 0xb202, 0xb203, 0xb206, 0xb207, 0xb209, 0xb20a, 0xb20d, 0xb20e, 0xb20f, 0xb210, 0xb211, 0xb212, 0xb213, 0xb216, - 0xb218, 0xb21a, 0xb21b, 0xb21c, 0xb21d, 0xb21e, 0xb21f, 0xb221, 0xb222, 0xb223, 0xb224, 0xb225, 0xb226, 0xb227, 0xb228, 0xb229, - 0xb22a, 0xb22b, 0xb22c, 0xb22d, 0xb22e, 0xb22f, 0xb230, 0xb231, 0xb232, 0xb233, 0xb235, 0xb236, 0xb237, 0xb238, 0xb239, 0xb23a, - 0xb23b, 0xb23d, 0xb23e, 0xb23f, 0xb240, 0xb241, 0xb242, 0xb243, 0xb244, 0xb245, 0xb246, 0xb247, 0xb248, 0xb249, 0xb24a, 0xb24b, - 0xb24c, 0xb24d, 0xb24e, 0xb24f, 0xb250, 0xb251, 0xb252, 0xb253, 0xb254, 0xb255, 0xb256, 0xb257, 0xb259, 0xb25a, 0xb25b, 0xb25d, - 0xb25e, 0xb25f, 0xb261, 0xb262, 0xb263, 0xb264, 0xb265, 0xb266, 0xb267, 0xb26a, 0xb26b, 0xb26c, 0xb26d, 0xb26e, 0xb26f, 0xb270, - 0xb271, 0xb272, 0xb273, 0xb276, 0xb277, 0xb278, 0xb279, 0xb27a, 0xb27b, 0xb27d, 0xb27e, 0xb27f, 0xb280, 0xb281, 0xb282, 0xb283, - 0xb286, 0xb287, 0xb288, 0xb28a, 0xb28b, 0xb28c, 0xb28d, 0xb28e, 0xb28f, 0xb292, 0xb293, 0xb295, 0xb296, 0xb297, 0xb29b, 0xb29c, - 0xb29d, 0xb29e, 0xb29f, 0xb2a2, 0xb2a4, 0xb2a7, 0xb2a8, 0xb2a9, 0xb2ab, 0xb2ad, 0xb2ae, 0xb2af, 0xb2b1, 0xb2b2, 0xb2b3, 0xb2b5, - 0xb2b6, 0xb2b7, 0xb2b8, 0xb2b9, 0xb2ba, 0xb2bb, 0xb2bc, 0xb2bd, 0xb2be, 0xb2bf, 0xb2c0, 0xb2c1, 0xb2c2, 0xb2c3, 0xb2c4, 0xb2c5, - 0xb2c6, 0xb2c7, 0xb2ca, 0xb2cb, 0xb2cd, 0xb2ce, 0xb2cf, 0xb2d1, 0xb2d3, 0xb2d4, 0xb2d5, 0xb2d6, 0xb2d7, 0xb2da, 0xb2dc, 0xb2de, - 0xb2df, 0xb2e0, 0xb2e1, 0xb2e3, 0xb2e7, 0xb2e9, 0xb2ea, 0xb2f0, 0xb2f1, 0xb2f2, 0xb2f6, 0xb2fc, 0xb2fd, 0xb2fe, 0xb302, 0xb303, - 0xb305, 0xb306, 0xb307, 0xb309, 0xb30a, 0xb30b, 0xb30c, 0xb30d, 0xb30e, 0xb30f, 0xb312, 0xb316, 0xb317, 0xb318, 0xb319, 0xb31a, - 0xb31b, 0xb31d, 0xb31e, 0xb31f, 0xb320, 0xb321, 0xb322, 0xb323, 0xb324, 0xb325, 0xb326, 0xb327, 0xb328, 0xb329, 0xb32a, 0xb32b, - 0xb32c, 0xb32d, 0xb32e, 0xb32f, 0xb330, 0xb331, 0xb332, 0xb333, 0xb334, 0xb335, 0xb336, 0xb337, 0xb338, 0xb339, 0xb33a, 0xb33b, - 0xb33c, 0xb33d, 0xb33e, 0xb33f, 0xb340, 0xb341, 0xb342, 0xb343, 0xb344, 0xb345, 0xb346, 0xb347, 0xb348, 0xb349, 0xb34a, 0xb34b, - 0xb34c, 0xb34d, 0xb34e, 0xb34f, 0xb350, 0xb351, 0xb352, 0xb353, 0xb357, 0xb359, 0xb35a, 0xb35d, 0xb360, 0xb361, 0xb362, 0xb363, - 0xb366, 0xb368, 0xb36a, 0xb36c, 0xb36d, 0xb36f, 0xb372, 0xb373, 0xb375, 0xb376, 0xb377, 0xb379, 0xb37a, 0xb37b, 0xb37c, 0xb37d, - 0xb37e, 0xb37f, 0xb382, 0xb386, 0xb387, 0xb388, 0xb389, 0xb38a, 0xb38b, 0xb38d, 0xb38e, 0xb38f, 0xb391, 0xb392, 0xb393, 0xb395, - 0xb396, 0xb397, 0xb398, 0xb399, 0xb39a, 0xb39b, 0xb39c, 0xb39d, 0xb39e, 0xb39f, 0xb3a2, 0xb3a3, 0xb3a4, 0xb3a5, 0xb3a6, 0xb3a7, - 0xb3a9, 0xb3aa, 0xb3ab, 0xb3ad, 0xb3ae, 0xb3af, 0xb3b0, 0xb3b1, 0xb3b2, 0xb3b3, 0xb3b4, 0xb3b5, 0xb3b6, 0xb3b7, 0xb3b8, 0xb3b9, - 0xb3ba, 0xb3bb, 0xb3bc, 0xb3bd, 0xb3be, 0xb3bf, 0xb3c0, 0xb3c1, 0xb3c2, 0xb3c3, 0xb3c6, 0xb3c7, 0xb3c9, 0xb3ca, 0xb3cd, 0xb3cf, - 0xb3d1, 0xb3d2, 0xb3d3, 0xb3d6, 0xb3d8, 0xb3da, 0xb3dc, 0xb3de, 0xb3df, 0xb3e1, 0xb3e2, 0xb3e3, 0xb3e5, 0xb3e6, 0xb3e7, 0xb3e9, - 0xb3ea, 0xb3eb, 0xb3ec, 0xb3ed, 0xb3ee, 0xb3ef, 0xb3f0, 0xb3f1, 0xb3f2, 0xb3f3, 0xb3f4, 0xb3f5, 0xb3f6, 0xb3f7, 0xb3f8, 0xb3f9, - 0xb3fa, 0xb3fb, 0xb3fd, 0xb3fe, 0xb3ff, 0xb400, 0xb401, 0xb402, 0xb403, 0xb404, 0xb405, 0xb406, 0xb407, 0xb408, 0xb409, 0xb40a, - 0xb40b, 0xb40c, 0xb40d, 0xb40e, 0xb40f, 0xb411, 0xb412, 0xb413, 0xb414, 0xb415, 0xb416, 0xb417, 0xb419, 0xb41a, 0xb41b, 0xb41d, - 0xb41e, 0xb41f, 0xb421, 0xb422, 0xb423, 0xb424, 0xb425, 0xb426, 0xb427, 0xb42a, 0xb42c, 0xb42d, 0xb42e, 0xb42f, 0xb430, 0xb431, - 0xb432, 0xb433, 0xb435, 0xb436, 0xb437, 0xb438, 0xb439, 0xb43a, 0xb43b, 0xb43c, 0xb43d, 0xb43e, 0xb43f, 0xb440, 0xb441, 0xb442, - 0xb443, 0xb444, 0xb445, 0xb446, 0xb447, 0xb448, 0xb449, 0xb44a, 0xb44b, 0xb44c, 0xb44d, 0xb44e, 0xb44f, 0xb452, 0xb453, 0xb455, - 0xb456, 0xb457, 0xb459, 0xb45a, 0xb45b, 0xb45c, 0xb45d, 0xb45e, 0xb45f, 0xb462, 0xb464, 0xb466, 0xb467, 0xb468, 0xb469, 0xb46a, - 0xb46b, 0xb46d, 0xb46e, 0xb46f, 0xb470, 0xb471, 0xb472, 0xb473, 0xb474, 0xb475, 0xb476, 0xb477, 0xb478, 0xb479, 0xb47a, 0xb47b, - 0xb47c, 0xb47d, 0xb47e, 0xb47f, 0xb481, 0xb482, 0xb483, 0xb484, 0xb485, 0xb486, 0xb487, 0xb489, 0xb48a, 0xb48b, 0xb48c, 0xb48d, - 0xb48e, 0xb48f, 0xb490, 0xb491, 0xb492, 0xb493, 0xb494, 0xb495, 0xb496, 0xb497, 0xb498, 0xb499, 0xb49a, 0xb49b, 0xb49c, 0xb49e, - 0xb49f, 0xb4a0, 0xb4a1, 0xb4a2, 0xb4a3, 0xb4a5, 0xb4a6, 0xb4a7, 0xb4a9, 0xb4aa, 0xb4ab, 0xb4ad, 0xb4ae, 0xb4af, 0xb4b0, 0xb4b1, - 0xb4b2, 0xb4b3, 0xb4b4, 0xb4b6, 0xb4b8, 0xb4ba, 0xb4bb, 0xb4bc, 0xb4bd, 0xb4be, 0xb4bf, 0xb4c1, 0xb4c2, 0xb4c3, 0xb4c5, 0xb4c6, - 0xb4c7, 0xb4c9, 0xb4ca, 0xb4cb, 0xb4cc, 0xb4cd, 0xb4ce, 0xb4cf, 0xb4d1, 0xb4d2, 0xb4d3, 0xb4d4, 0xb4d6, 0xb4d7, 0xb4d8, 0xb4d9, - 0xb4da, 0xb4db, 0xb4de, 0xb4df, 0xb4e1, 0xb4e2, 0xb4e5, 0xb4e7, 0xb4e8, 0xb4e9, 0xb4ea, 0xb4eb, 0xb4ee, 0xb4f0, 0xb4f2, 0xb4f3, - 0xb4f4, 0xb4f5, 0xb4f6, 0xb4f7, 0xb4f9, 0xb4fa, 0xb4fb, 0xb4fc, 0xb4fd, 0xb4fe, 0xb4ff, 0xb500, 0xb501, 0xb502, 0xb503, 0xb504, - 0xb505, 0xb506, 0xb507, 0xb508, 0xb509, 0xb50a, 0xb50b, 0xb50c, 0xb50d, 0xb50e, 0xb50f, 0xb510, 0xb511, 0xb512, 0xb513, 0xb516, - 0xb517, 0xb519, 0xb51a, 0xb51d, 0xb51e, 0xb51f, 0xb520, 0xb521, 0xb522, 0xb523, 0xb526, 0xb52b, 0xb52c, 0xb52d, 0xb52e, 0xb52f, - 0xb532, 0xb533, 0xb535, 0xb536, 0xb537, 0xb539, 0xb53a, 0xb53b, 0xb53c, 0xb53d, 0xb53e, 0xb53f, 0xb542, 0xb546, 0xb547, 0xb548, - 0xb549, 0xb54a, 0xb54e, 0xb54f, 0xb551, 0xb552, 0xb553, 0xb555, 0xb556, 0xb557, 0xb558, 0xb559, 0xb55a, 0xb55b, 0xb55e, 0xb562, - 0xb563, 0xb564, 0xb565, 0xb566, 0xb567, 0xb568, 0xb569, 0xb56a, 0xb56b, 0xb56c, 0xb56d, 0xb56e, 0xb56f, 0xb570, 0xb571, 0xb572, - 0xb573, 0xb574, 0xb575, 0xb576, 0xb577, 0xb578, 0xb579, 0xb57a, 0xb57b, 0xb57c, 0xb57d, 0xb57e, 0xb57f, 0xb580, 0xb581, 0xb582, - 0xb583, 0xb584, 0xb585, 0xb586, 0xb587, 0xb588, 0xb589, 0xb58a, 0xb58b, 0xb58c, 0xb58d, 0xb58e, 0xb58f, 0xb590, 0xb591, 0xb592, - 0xb593, 0xb594, 0xb595, 0xb596, 0xb597, 0xb598, 0xb599, 0xb59a, 0xb59b, 0xb59c, 0xb59d, 0xb59e, 0xb59f, 0xb5a2, 0xb5a3, 0xb5a5, - 0xb5a6, 0xb5a7, 0xb5a9, 0xb5ac, 0xb5ad, 0xb5ae, 0xb5af, 0xb5b2, 0xb5b6, 0xb5b7, 0xb5b8, 0xb5b9, 0xb5ba, 0xb5be, 0xb5bf, 0xb5c1, - 0xb5c2, 0xb5c3, 0xb5c5, 0xb5c6, 0xb5c7, 0xb5c8, 0xb5c9, 0xb5ca, 0xb5cb, 0xb5ce, 0xb5d2, 0xb5d3, 0xb5d4, 0xb5d5, 0xb5d6, 0xb5d7, - 0xb5d9, 0xb5da, 0xb5db, 0xb5dc, 0xb5dd, 0xb5de, 0xb5df, 0xb5e0, 0xb5e1, 0xb5e2, 0xb5e3, 0xb5e4, 0xb5e5, 0xb5e6, 0xb5e7, 0xb5e8, - 0xb5e9, 0xb5ea, 0xb5eb, 0xb5ed, 0xb5ee, 0xb5ef, 0xb5f0, 0xb5f1, 0xb5f2, 0xb5f3, 0xb5f4, 0xb5f5, 0xb5f6, 0xb5f7, 0xb5f8, 0xb5f9, - 0xb5fa, 0xb5fb, 0xb5fc, 0xb5fd, 0xb5fe, 0xb5ff, 0xb600, 0xb601, 0xb602, 0xb603, 0xb604, 0xb605, 0xb606, 0xb607, 0xb608, 0xb609, - 0xb60a, 0xb60b, 0xb60c, 0xb60d, 0xb60e, 0xb60f, 0xb612, 0xb613, 0xb615, 0xb616, 0xb617, 0xb619, 0xb61a, 0xb61b, 0xb61c, 0xb61d, - 0xb61e, 0xb61f, 0xb620, 0xb621, 0xb622, 0xb623, 0xb624, 0xb626, 0xb627, 0xb628, 0xb629, 0xb62a, 0xb62b, 0xb62d, 0xb62e, 0xb62f, - 0xb630, 0xb631, 0xb632, 0xb633, 0xb635, 0xb636, 0xb637, 0xb638, 0xb639, 0xb63a, 0xb63b, 0xb63c, 0xb63d, 0xb63e, 0xb63f, 0xb640, - 0xb641, 0xb642, 0xb643, 0xb644, 0xb645, 0xb646, 0xb647, 0xb649, 0xb64a, 0xb64b, 0xb64c, 0xb64d, 0xb64e, 0xb64f, 0xb650, 0xb651, - 0xb652, 0xb653, 0xb654, 0xb655, 0xb656, 0xb657, 0xb658, 0xb659, 0xb65a, 0xb65b, 0xb65c, 0xb65d, 0xb65e, 0xb65f, 0xb660, 0xb661, - 0xb662, 0xb663, 0xb665, 0xb666, 0xb667, 0xb669, 0xb66a, 0xb66b, 0xb66c, 0xb66d, 0xb66e, 0xb66f, 0xb670, 0xb671, 0xb672, 0xb673, - 0xb674, 0xb675, 0xb676, 0xb677, 0xb678, 0xb679, 0xb67a, 0xb67b, 0xb67c, 0xb67d, 0xb67e, 0xb67f, 0xb680, 0xb681, 0xb682, 0xb683, - 0xb684, 0xb685, 0xb686, 0xb687, 0xb688, 0xb689, 0xb68a, 0xb68b, 0xb68c, 0xb68d, 0xb68e, 0xb68f, 0xb690, 0xb691, 0xb692, 0xb693, - 0xb694, 0xb695, 0xb696, 0xb697, 0xb698, 0xb699, 0xb69a, 0xb69b, 0xb69e, 0xb69f, 0xb6a1, 0xb6a2, 0xb6a3, 0xb6a5, 0xb6a6, 0xb6a7, - 0xb6a8, 0xb6a9, 0xb6aa, 0xb6ad, 0xb6ae, 0xb6af, 0xb6b0, 0xb6b2, 0xb6b3, 0xb6b4, 0xb6b5, 0xb6b6, 0xb6b7, 0xb6b8, 0xb6b9, 0xb6ba, - 0xb6bb, 0xb6bc, 0xb6bd, 0xb6be, 0xb6bf, 0xb6c0, 0xb6c1, 0xb6c2, 0xb6c3, 0xb6c4, 0xb6c5, 0xb6c6, 0xb6c7, 0xb6c8, 0xb6c9, 0xb6ca, - 0xb6cb, 0xb6cc, 0xb6cd, 0xb6ce, 0xb6cf, 0xb6d0, 0xb6d1, 0xb6d2, 0xb6d3, 0xb6d5, 0xb6d6, 0xb6d7, 0xb6d8, 0xb6d9, 0xb6da, 0xb6db, - 0xb6dc, 0xb6dd, 0xb6de, 0xb6df, 0xb6e0, 0xb6e1, 0xb6e2, 0xb6e3, 0xb6e4, 0xb6e5, 0xb6e6, 0xb6e7, 0xb6e8, 0xb6e9, 0xb6ea, 0xb6eb, - 0xb6ec, 0xb6ed, 0xb6ee, 0xb6ef, 0xb6f1, 0xb6f2, 0xb6f3, 0xb6f5, 0xb6f6, 0xb6f7, 0xb6f9, 0xb6fa, 0xb6fb, 0xb6fc, 0xb6fd, 0xb6fe, - 0xb6ff, 0xb702, 0xb703, 0xb704, 0xb706, 0xb707, 0xb708, 0xb709, 0xb70a, 0xb70b, 0xb70c, 0xb70d, 0xb70e, 0xb70f, 0xb710, 0xb711, - 0xb712, 0xb713, 0xb714, 0xb715, 0xb716, 0xb717, 0xb718, 0xb719, 0xb71a, 0xb71b, 0xb71c, 0xb71d, 0xb71e, 0xb71f, 0xb720, 0xb721, - 0xb722, 0xb723, 0xb724, 0xb725, 0xb726, 0xb727, 0xb72a, 0xb72b, 0xb72d, 0xb72e, 0xb731, 0xb732, 0xb733, 0xb734, 0xb735, 0xb736, - 0xb737, 0xb73a, 0xb73c, 0xb73d, 0xb73e, 0xb73f, 0xb740, 0xb741, 0xb742, 0xb743, 0xb745, 0xb746, 0xb747, 0xb749, 0xb74a, 0xb74b, - 0xb74d, 0xb74e, 0xb74f, 0xb750, 0xb751, 0xb752, 0xb753, 0xb756, 0xb757, 0xb758, 0xb759, 0xb75a, 0xb75b, 0xb75c, 0xb75d, 0xb75e, - 0xb75f, 0xb761, 0xb762, 0xb763, 0xb765, 0xb766, 0xb767, 0xb769, 0xb76a, 0xb76b, 0xb76c, 0xb76d, 0xb76e, 0xb76f, 0xb772, 0xb774, - 0xb776, 0xb777, 0xb778, 0xb779, 0xb77a, 0xb77b, 0xb77e, 0xb77f, 0xb781, 0xb782, 0xb783, 0xb785, 0xb786, 0xb787, 0xb788, 0xb789, - 0xb78a, 0xb78b, 0xb78e, 0xb793, 0xb794, 0xb795, 0xb79a, 0xb79b, 0xb79d, 0xb79e, 0xb79f, 0xb7a1, 0xb7a2, 0xb7a3, 0xb7a4, 0xb7a5, - 0xb7a6, 0xb7a7, 0xb7aa, 0xb7ae, 0xb7af, 0xb7b0, 0xb7b1, 0xb7b2, 0xb7b3, 0xb7b6, 0xb7b7, 0xb7b9, 0xb7ba, 0xb7bb, 0xb7bc, 0xb7bd, - 0xb7be, 0xb7bf, 0xb7c0, 0xb7c1, 0xb7c2, 0xb7c3, 0xb7c4, 0xb7c5, 0xb7c6, 0xb7c8, 0xb7ca, 0xb7cb, 0xb7cc, 0xb7cd, 0xb7ce, 0xb7cf, - 0xb7d0, 0xb7d1, 0xb7d2, 0xb7d3, 0xb7d4, 0xb7d5, 0xb7d6, 0xb7d7, 0xb7d8, 0xb7d9, 0xb7da, 0xb7db, 0xb7dc, 0xb7dd, 0xb7de, 0xb7df, - 0xb7e0, 0xb7e1, 0xb7e2, 0xb7e3, 0xb7e4, 0xb7e5, 0xb7e6, 0xb7e7, 0xb7e8, 0xb7e9, 0xb7ea, 0xb7eb, 0xb7ee, 0xb7ef, 0xb7f1, 0xb7f2, - 0xb7f3, 0xb7f5, 0xb7f6, 0xb7f7, 0xb7f8, 0xb7f9, 0xb7fa, 0xb7fb, 0xb7fe, 0xb802, 0xb803, 0xb804, 0xb805, 0xb806, 0xb80a, 0xb80b, - 0xb80d, 0xb80e, 0xb80f, 0xb811, 0xb812, 0xb813, 0xb814, 0xb815, 0xb816, 0xb817, 0xb81a, 0xb81c, 0xb81e, 0xb81f, 0xb820, 0xb821, - 0xb822, 0xb823, 0xb826, 0xb827, 0xb829, 0xb82a, 0xb82b, 0xb82d, 0xb82e, 0xb82f, 0xb830, 0xb831, 0xb832, 0xb833, 0xb836, 0xb83a, - 0xb83b, 0xb83c, 0xb83d, 0xb83e, 0xb83f, 0xb841, 0xb842, 0xb843, 0xb845, 0xb846, 0xb847, 0xb848, 0xb849, 0xb84a, 0xb84b, 0xb84c, - 0xb84d, 0xb84e, 0xb84f, 0xb850, 0xb852, 0xb854, 0xb855, 0xb856, 0xb857, 0xb858, 0xb859, 0xb85a, 0xb85b, 0xb85e, 0xb85f, 0xb861, - 0xb862, 0xb863, 0xb865, 0xb866, 0xb867, 0xb868, 0xb869, 0xb86a, 0xb86b, 0xb86e, 0xb870, 0xb872, 0xb873, 0xb874, 0xb875, 0xb876, - 0xb877, 0xb879, 0xb87a, 0xb87b, 0xb87d, 0xb87e, 0xb87f, 0xb880, 0xb881, 0xb882, 0xb883, 0xb884, 0xb885, 0xb886, 0xb887, 0xb888, - 0xb889, 0xb88a, 0xb88b, 0xb88c, 0xb88e, 0xb88f, 0xb890, 0xb891, 0xb892, 0xb893, 0xb894, 0xb895, 0xb896, 0xb897, 0xb898, 0xb899, - 0xb89a, 0xb89b, 0xb89c, 0xb89d, 0xb89e, 0xb89f, 0xb8a0, 0xb8a1, 0xb8a2, 0xb8a3, 0xb8a4, 0xb8a5, 0xb8a6, 0xb8a7, 0xb8a9, 0xb8aa, - 0xb8ab, 0xb8ac, 0xb8ad, 0xb8ae, 0xb8af, 0xb8b1, 0xb8b2, 0xb8b3, 0xb8b5, 0xb8b6, 0xb8b7, 0xb8b9, 0xb8ba, 0xb8bb, 0xb8bc, 0xb8bd, - 0xb8be, 0xb8bf, 0xb8c2, 0xb8c4, 0xb8c6, 0xb8c7, 0xb8c8, 0xb8c9, 0xb8ca, 0xb8cb, 0xb8cd, 0xb8ce, 0xb8cf, 0xb8d1, 0xb8d2, 0xb8d3, - 0xb8d5, 0xb8d6, 0xb8d7, 0xb8d8, 0xb8d9, 0xb8da, 0xb8db, 0xb8dc, 0xb8de, 0xb8e0, 0xb8e2, 0xb8e3, 0xb8e4, 0xb8e5, 0xb8e6, 0xb8e7, - 0xb8ea, 0xb8eb, 0xb8ed, 0xb8ee, 0xb8ef, 0xb8f1, 0xb8f2, 0xb8f3, 0xb8f4, 0xb8f5, 0xb8f6, 0xb8f7, 0xb8fa, 0xb8fc, 0xb8fe, 0xb8ff, - 0xb900, 0xb901, 0xb902, 0xb903, 0xb905, 0xb906, 0xb907, 0xb908, 0xb909, 0xb90a, 0xb90b, 0xb90c, 0xb90d, 0xb90e, 0xb90f, 0xb910, - 0xb911, 0xb912, 0xb913, 0xb914, 0xb915, 0xb916, 0xb917, 0xb919, 0xb91a, 0xb91b, 0xb91c, 0xb91d, 0xb91e, 0xb91f, 0xb921, 0xb922, - 0xb923, 0xb924, 0xb925, 0xb926, 0xb927, 0xb928, 0xb929, 0xb92a, 0xb92b, 0xb92c, 0xb92d, 0xb92e, 0xb92f, 0xb930, 0xb931, 0xb932, - 0xb933, 0xb934, 0xb935, 0xb936, 0xb937, 0xb938, 0xb939, 0xb93a, 0xb93b, 0xb93e, 0xb93f, 0xb941, 0xb942, 0xb943, 0xb945, 0xb946, - 0xb947, 0xb948, 0xb949, 0xb94a, 0xb94b, 0xb94d, 0xb94e, 0xb950, 0xb952, 0xb953, 0xb954, 0xb955, 0xb956, 0xb957, 0xb95a, 0xb95b, - 0xb95d, 0xb95e, 0xb95f, 0xb961, 0xb962, 0xb963, 0xb964, 0xb965, 0xb966, 0xb967, 0xb96a, 0xb96c, 0xb96e, 0xb96f, 0xb970, 0xb971, - 0xb972, 0xb973, 0xb976, 0xb977, 0xb979, 0xb97a, 0xb97b, 0xb97d, 0xb97e, 0xb97f, 0xb980, 0xb981, 0xb982, 0xb983, 0xb986, 0xb988, - 0xb98b, 0xb98c, 0xb98f, 0xb990, 0xb991, 0xb992, 0xb993, 0xb994, 0xb995, 0xb996, 0xb997, 0xb998, 0xb999, 0xb99a, 0xb99b, 0xb99c, - 0xb99d, 0xb99e, 0xb99f, 0xb9a0, 0xb9a1, 0xb9a2, 0xb9a3, 0xb9a4, 0xb9a5, 0xb9a6, 0xb9a7, 0xb9a8, 0xb9a9, 0xb9aa, 0xb9ab, 0xb9ae, - 0xb9af, 0xb9b1, 0xb9b2, 0xb9b3, 0xb9b5, 0xb9b6, 0xb9b7, 0xb9b8, 0xb9b9, 0xb9ba, 0xb9bb, 0xb9be, 0xb9c0, 0xb9c2, 0xb9c3, 0xb9c4, - 0xb9c5, 0xb9c6, 0xb9c7, 0xb9ca, 0xb9cb, 0xb9cd, 0xb9d3, 0xb9d4, 0xb9d5, 0xb9d6, 0xb9d7, 0xb9da, 0xb9dc, 0xb9df, 0xb9e0, 0xb9e2, - 0xb9e6, 0xb9e7, 0xb9e9, 0xb9ea, 0xb9eb, 0xb9ed, 0xb9ee, 0xb9ef, 0xb9f0, 0xb9f1, 0xb9f2, 0xb9f3, 0xb9f6, 0xb9fb, 0xb9fc, 0xb9fd, - 0xb9fe, 0xb9ff, 0xba02, 0xba03, 0xba04, 0xba05, 0xba06, 0xba07, 0xba09, 0xba0a, 0xba0b, 0xba0c, 0xba0d, 0xba0e, 0xba0f, 0xba10, - 0xba11, 0xba12, 0xba13, 0xba14, 0xba16, 0xba17, 0xba18, 0xba19, 0xba1a, 0xba1b, 0xba1c, 0xba1d, 0xba1e, 0xba1f, 0xba20, 0xba21, - 0xba22, 0xba23, 0xba24, 0xba25, 0xba26, 0xba27, 0xba28, 0xba29, 0xba2a, 0xba2b, 0xba2c, 0xba2d, 0xba2e, 0xba2f, 0xba30, 0xba31, - 0xba32, 0xba33, 0xba34, 0xba35, 0xba36, 0xba37, 0xba3a, 0xba3b, 0xba3d, 0xba3e, 0xba3f, 0xba41, 0xba43, 0xba44, 0xba45, 0xba46, - 0xba47, 0xba4a, 0xba4c, 0xba4f, 0xba50, 0xba51, 0xba52, 0xba56, 0xba57, 0xba59, 0xba5a, 0xba5b, 0xba5d, 0xba5e, 0xba5f, 0xba60, - 0xba61, 0xba62, 0xba63, 0xba66, 0xba6a, 0xba6b, 0xba6c, 0xba6d, 0xba6e, 0xba6f, 0xba72, 0xba73, 0xba75, 0xba76, 0xba77, 0xba79, - 0xba7a, 0xba7b, 0xba7c, 0xba7d, 0xba7e, 0xba7f, 0xba80, 0xba81, 0xba82, 0xba86, 0xba88, 0xba89, 0xba8a, 0xba8b, 0xba8d, 0xba8e, - 0xba8f, 0xba90, 0xba91, 0xba92, 0xba93, 0xba94, 0xba95, 0xba96, 0xba97, 0xba98, 0xba99, 0xba9a, 0xba9b, 0xba9c, 0xba9d, 0xba9e, - 0xba9f, 0xbaa0, 0xbaa1, 0xbaa2, 0xbaa3, 0xbaa4, 0xbaa5, 0xbaa6, 0xbaa7, 0xbaaa, 0xbaad, 0xbaae, 0xbaaf, 0xbab1, 0xbab3, 0xbab4, - 0xbab5, 0xbab6, 0xbab7, 0xbaba, 0xbabc, 0xbabe, 0xbabf, 0xbac0, 0xbac1, 0xbac2, 0xbac3, 0xbac5, 0xbac6, 0xbac7, 0xbac9, 0xbaca, - 0xbacb, 0xbacc, 0xbacd, 0xbace, 0xbacf, 0xbad0, 0xbad1, 0xbad2, 0xbad3, 0xbad4, 0xbad5, 0xbad6, 0xbad7, 0xbada, 0xbadb, 0xbadc, - 0xbadd, 0xbade, 0xbadf, 0xbae0, 0xbae1, 0xbae2, 0xbae3, 0xbae4, 0xbae5, 0xbae6, 0xbae7, 0xbae8, 0xbae9, 0xbaea, 0xbaeb, 0xbaec, - 0xbaed, 0xbaee, 0xbaef, 0xbaf0, 0xbaf1, 0xbaf2, 0xbaf3, 0xbaf4, 0xbaf5, 0xbaf6, 0xbaf7, 0xbaf8, 0xbaf9, 0xbafa, 0xbafb, 0xbafd, - 0xbafe, 0xbaff, 0xbb01, 0xbb02, 0xbb03, 0xbb05, 0xbb06, 0xbb07, 0xbb08, 0xbb09, 0xbb0a, 0xbb0b, 0xbb0c, 0xbb0e, 0xbb10, 0xbb12, - 0xbb13, 0xbb14, 0xbb15, 0xbb16, 0xbb17, 0xbb19, 0xbb1a, 0xbb1b, 0xbb1d, 0xbb1e, 0xbb1f, 0xbb21, 0xbb22, 0xbb23, 0xbb24, 0xbb25, - 0xbb26, 0xbb27, 0xbb28, 0xbb2a, 0xbb2c, 0xbb2d, 0xbb2e, 0xbb2f, 0xbb30, 0xbb31, 0xbb32, 0xbb33, 0xbb37, 0xbb39, 0xbb3a, 0xbb3f, - 0xbb40, 0xbb41, 0xbb42, 0xbb43, 0xbb46, 0xbb48, 0xbb4a, 0xbb4b, 0xbb4c, 0xbb4e, 0xbb51, 0xbb52, 0xbb53, 0xbb55, 0xbb56, 0xbb57, - 0xbb59, 0xbb5a, 0xbb5b, 0xbb5c, 0xbb5d, 0xbb5e, 0xbb5f, 0xbb60, 0xbb62, 0xbb64, 0xbb65, 0xbb66, 0xbb67, 0xbb68, 0xbb69, 0xbb6a, - 0xbb6b, 0xbb6d, 0xbb6e, 0xbb6f, 0xbb70, 0xbb71, 0xbb72, 0xbb73, 0xbb74, 0xbb75, 0xbb76, 0xbb77, 0xbb78, 0xbb79, 0xbb7a, 0xbb7b, - 0xbb7c, 0xbb7d, 0xbb7e, 0xbb7f, 0xbb80, 0xbb81, 0xbb82, 0xbb83, 0xbb84, 0xbb85, 0xbb86, 0xbb87, 0xbb89, 0xbb8a, 0xbb8b, 0xbb8d, - 0xbb8e, 0xbb8f, 0xbb91, 0xbb92, 0xbb93, 0xbb94, 0xbb95, 0xbb96, 0xbb97, 0xbb98, 0xbb99, 0xbb9a, 0xbb9b, 0xbb9c, 0xbb9d, 0xbb9e, - 0xbb9f, 0xbba0, 0xbba1, 0xbba2, 0xbba3, 0xbba5, 0xbba6, 0xbba7, 0xbba9, 0xbbaa, 0xbbab, 0xbbad, 0xbbae, 0xbbaf, 0xbbb0, 0xbbb1, - 0xbbb2, 0xbbb3, 0xbbb5, 0xbbb6, 0xbbb8, 0xbbb9, 0xbbba, 0xbbbb, 0xbbbc, 0xbbbd, 0xbbbe, 0xbbbf, 0xbbc1, 0xbbc2, 0xbbc3, 0xbbc5, - 0xbbc6, 0xbbc7, 0xbbc9, 0xbbca, 0xbbcb, 0xbbcc, 0xbbcd, 0xbbce, 0xbbcf, 0xbbd1, 0xbbd2, 0xbbd4, 0xbbd5, 0xbbd6, 0xbbd7, 0xbbd8, - 0xbbd9, 0xbbda, 0xbbdb, 0xbbdc, 0xbbdd, 0xbbde, 0xbbdf, 0xbbe0, 0xbbe1, 0xbbe2, 0xbbe3, 0xbbe4, 0xbbe5, 0xbbe6, 0xbbe7, 0xbbe8, - 0xbbe9, 0xbbea, 0xbbeb, 0xbbec, 0xbbed, 0xbbee, 0xbbef, 0xbbf0, 0xbbf1, 0xbbf2, 0xbbf3, 0xbbf4, 0xbbf5, 0xbbf6, 0xbbf7, 0xbbfa, - 0xbbfb, 0xbbfd, 0xbbfe, 0xbc01, 0xbc03, 0xbc04, 0xbc05, 0xbc06, 0xbc07, 0xbc0a, 0xbc0e, 0xbc10, 0xbc12, 0xbc13, 0xbc19, 0xbc1a, - 0xbc20, 0xbc21, 0xbc22, 0xbc23, 0xbc26, 0xbc28, 0xbc2a, 0xbc2b, 0xbc2c, 0xbc2e, 0xbc2f, 0xbc32, 0xbc33, 0xbc35, 0xbc36, 0xbc37, - 0xbc39, 0xbc3a, 0xbc3b, 0xbc3c, 0xbc3d, 0xbc3e, 0xbc3f, 0xbc42, 0xbc46, 0xbc47, 0xbc48, 0xbc4a, 0xbc4b, 0xbc4e, 0xbc4f, 0xbc51, - 0xbc52, 0xbc53, 0xbc54, 0xbc55, 0xbc56, 0xbc57, 0xbc58, 0xbc59, 0xbc5a, 0xbc5b, 0xbc5c, 0xbc5e, 0xbc5f, 0xbc60, 0xbc61, 0xbc62, - 0xbc63, 0xbc64, 0xbc65, 0xbc66, 0xbc67, 0xbc68, 0xbc69, 0xbc6a, 0xbc6b, 0xbc6c, 0xbc6d, 0xbc6e, 0xbc6f, 0xbc70, 0xbc71, 0xbc72, - 0xbc73, 0xbc74, 0xbc75, 0xbc76, 0xbc77, 0xbc78, 0xbc79, 0xbc7a, 0xbc7b, 0xbc7c, 0xbc7d, 0xbc7e, 0xbc7f, 0xbc80, 0xbc81, 0xbc82, - 0xbc83, 0xbc86, 0xbc87, 0xbc89, 0xbc8a, 0xbc8d, 0xbc8f, 0xbc90, 0xbc91, 0xbc92, 0xbc93, 0xbc96, 0xbc98, 0xbc9b, 0xbc9c, 0xbc9d, - 0xbc9e, 0xbc9f, 0xbca2, 0xbca3, 0xbca5, 0xbca6, 0xbca9, 0xbcaa, 0xbcab, 0xbcac, 0xbcad, 0xbcae, 0xbcaf, 0xbcb2, 0xbcb6, 0xbcb7, - 0xbcb8, 0xbcb9, 0xbcba, 0xbcbb, 0xbcbe, 0xbcbf, 0xbcc1, 0xbcc2, 0xbcc3, 0xbcc5, 0xbcc6, 0xbcc7, 0xbcc8, 0xbcc9, 0xbcca, 0xbccb, - 0xbccc, 0xbcce, 0xbcd2, 0xbcd3, 0xbcd4, 0xbcd6, 0xbcd7, 0xbcd9, 0xbcda, 0xbcdb, 0xbcdd, 0xbcde, 0xbcdf, 0xbce0, 0xbce1, 0xbce2, - 0xbce3, 0xbce4, 0xbce5, 0xbce6, 0xbce7, 0xbce8, 0xbce9, 0xbcea, 0xbceb, 0xbcec, 0xbced, 0xbcee, 0xbcef, 0xbcf0, 0xbcf1, 0xbcf2, - 0xbcf3, 0xbcf7, 0xbcf9, 0xbcfa, 0xbcfb, 0xbcfd, 0xbcfe, 0xbcff, 0xbd00, 0xbd01, 0xbd02, 0xbd03, 0xbd06, 0xbd08, 0xbd0a, 0xbd0b, - 0xbd0c, 0xbd0d, 0xbd0e, 0xbd0f, 0xbd11, 0xbd12, 0xbd13, 0xbd15, 0xbd16, 0xbd17, 0xbd18, 0xbd19, 0xbd1a, 0xbd1b, 0xbd1c, 0xbd1d, - 0xbd1e, 0xbd1f, 0xbd20, 0xbd21, 0xbd22, 0xbd23, 0xbd25, 0xbd26, 0xbd27, 0xbd28, 0xbd29, 0xbd2a, 0xbd2b, 0xbd2d, 0xbd2e, 0xbd2f, - 0xbd30, 0xbd31, 0xbd32, 0xbd33, 0xbd34, 0xbd35, 0xbd36, 0xbd37, 0xbd38, 0xbd39, 0xbd3a, 0xbd3b, 0xbd3c, 0xbd3d, 0xbd3e, 0xbd3f, - 0xbd41, 0xbd42, 0xbd43, 0xbd44, 0xbd45, 0xbd46, 0xbd47, 0xbd4a, 0xbd4b, 0xbd4d, 0xbd4e, 0xbd4f, 0xbd51, 0xbd52, 0xbd53, 0xbd54, - 0xbd55, 0xbd56, 0xbd57, 0xbd5a, 0xbd5b, 0xbd5c, 0xbd5d, 0xbd5e, 0xbd5f, 0xbd60, 0xbd61, 0xbd62, 0xbd63, 0xbd65, 0xbd66, 0xbd67, - 0xbd69, 0xbd6a, 0xbd6b, 0xbd6c, 0xbd6d, 0xbd6e, 0xbd6f, 0xbd70, 0xbd71, 0xbd72, 0xbd73, 0xbd74, 0xbd75, 0xbd76, 0xbd77, 0xbd78, - 0xbd79, 0xbd7a, 0xbd7b, 0xbd7c, 0xbd7d, 0xbd7e, 0xbd7f, 0xbd82, 0xbd83, 0xbd85, 0xbd86, 0xbd8b, 0xbd8c, 0xbd8d, 0xbd8e, 0xbd8f, - 0xbd92, 0xbd94, 0xbd96, 0xbd97, 0xbd98, 0xbd9b, 0xbd9d, 0xbd9e, 0xbd9f, 0xbda0, 0xbda1, 0xbda2, 0xbda3, 0xbda5, 0xbda6, 0xbda7, - 0xbda8, 0xbda9, 0xbdaa, 0xbdab, 0xbdac, 0xbdad, 0xbdae, 0xbdaf, 0xbdb1, 0xbdb2, 0xbdb3, 0xbdb4, 0xbdb5, 0xbdb6, 0xbdb7, 0xbdb9, - 0xbdba, 0xbdbb, 0xbdbc, 0xbdbd, 0xbdbe, 0xbdbf, 0xbdc0, 0xbdc1, 0xbdc2, 0xbdc3, 0xbdc4, 0xbdc5, 0xbdc6, 0xbdc7, 0xbdc8, 0xbdc9, - 0xbdca, 0xbdcb, 0xbdcc, 0xbdcd, 0xbdce, 0xbdcf, 0xbdd0, 0xbdd1, 0xbdd2, 0xbdd3, 0xbdd6, 0xbdd7, 0xbdd9, 0xbdda, 0xbddb, 0xbddd, - 0xbdde, 0xbddf, 0xbde0, 0xbde1, 0xbde2, 0xbde3, 0xbde4, 0xbde5, 0xbde6, 0xbde7, 0xbde8, 0xbdea, 0xbdeb, 0xbdec, 0xbded, 0xbdee, - 0xbdef, 0xbdf1, 0xbdf2, 0xbdf3, 0xbdf5, 0xbdf6, 0xbdf7, 0xbdf9, 0xbdfa, 0xbdfb, 0xbdfc, 0xbdfd, 0xbdfe, 0xbdff, 0xbe01, 0xbe02, - 0xbe04, 0xbe06, 0xbe07, 0xbe08, 0xbe09, 0xbe0a, 0xbe0b, 0xbe0e, 0xbe0f, 0xbe11, 0xbe12, 0xbe13, 0xbe15, 0xbe16, 0xbe17, 0xbe18, - 0xbe19, 0xbe1a, 0xbe1b, 0xbe1e, 0xbe20, 0xbe21, 0xbe22, 0xbe23, 0xbe24, 0xbe25, 0xbe26, 0xbe27, 0xbe28, 0xbe29, 0xbe2a, 0xbe2b, - 0xbe2c, 0xbe2d, 0xbe2e, 0xbe2f, 0xbe30, 0xbe31, 0xbe32, 0xbe33, 0xbe34, 0xbe35, 0xbe36, 0xbe37, 0xbe38, 0xbe39, 0xbe3a, 0xbe3b, - 0xbe3c, 0xbe3d, 0xbe3e, 0xbe3f, 0xbe40, 0xbe41, 0xbe42, 0xbe43, 0xbe46, 0xbe47, 0xbe49, 0xbe4a, 0xbe4b, 0xbe4d, 0xbe4f, 0xbe50, - 0xbe51, 0xbe52, 0xbe53, 0xbe56, 0xbe58, 0xbe5c, 0xbe5d, 0xbe5e, 0xbe5f, 0xbe62, 0xbe63, 0xbe65, 0xbe66, 0xbe67, 0xbe69, 0xbe6b, - 0xbe6c, 0xbe6d, 0xbe6e, 0xbe6f, 0xbe72, 0xbe76, 0xbe77, 0xbe78, 0xbe79, 0xbe7a, 0xbe7e, 0xbe7f, 0xbe81, 0xbe82, 0xbe83, 0xbe85, - 0xbe86, 0xbe87, 0xbe88, 0xbe89, 0xbe8a, 0xbe8b, 0xbe8e, 0xbe92, 0xbe93, 0xbe94, 0xbe95, 0xbe96, 0xbe97, 0xbe9a, 0xbe9b, 0xbe9c, - 0xbe9d, 0xbe9e, 0xbe9f, 0xbea0, 0xbea1, 0xbea2, 0xbea3, 0xbea4, 0xbea5, 0xbea6, 0xbea7, 0xbea9, 0xbeaa, 0xbeab, 0xbeac, 0xbead, - 0xbeae, 0xbeaf, 0xbeb0, 0xbeb1, 0xbeb2, 0xbeb3, 0xbeb4, 0xbeb5, 0xbeb6, 0xbeb7, 0xbeb8, 0xbeb9, 0xbeba, 0xbebb, 0xbebc, 0xbebd, - 0xbebe, 0xbebf, 0xbec0, 0xbec1, 0xbec2, 0xbec3, 0xbec4, 0xbec5, 0xbec6, 0xbec7, 0xbec8, 0xbec9, 0xbeca, 0xbecb, 0xbecc, 0xbecd, - 0xbece, 0xbecf, 0xbed2, 0xbed3, 0xbed5, 0xbed6, 0xbed9, 0xbeda, 0xbedb, 0xbedc, 0xbedd, 0xbede, 0xbedf, 0xbee1, 0xbee2, 0xbee6, - 0xbee7, 0xbee8, 0xbee9, 0xbeea, 0xbeeb, 0xbeed, 0xbeee, 0xbeef, 0xbef0, 0xbef1, 0xbef2, 0xbef3, 0xbef4, 0xbef5, 0xbef6, 0xbef7, - 0xbef8, 0xbef9, 0xbefa, 0xbefb, 0xbefc, 0xbefd, 0xbefe, 0xbeff, 0xbf00, 0xbf02, 0xbf03, 0xbf04, 0xbf05, 0xbf06, 0xbf07, 0xbf0a, - 0xbf0b, 0xbf0c, 0xbf0d, 0xbf0e, 0xbf0f, 0xbf10, 0xbf11, 0xbf12, 0xbf13, 0xbf14, 0xbf15, 0xbf16, 0xbf17, 0xbf1a, 0xbf1e, 0xbf1f, - 0xbf20, 0xbf21, 0xbf22, 0xbf23, 0xbf24, 0xbf25, 0xbf26, 0xbf27, 0xbf28, 0xbf29, 0xbf2a, 0xbf2b, 0xbf2c, 0xbf2d, 0xbf2e, 0xbf2f, - 0xbf30, 0xbf31, 0xbf32, 0xbf33, 0xbf34, 0xbf35, 0xbf36, 0xbf37, 0xbf38, 0xbf39, 0xbf3a, 0xbf3b, 0xbf3c, 0xbf3d, 0xbf3e, 0xbf3f, - 0xbf42, 0xbf43, 0xbf45, 0xbf46, 0xbf47, 0xbf49, 0xbf4a, 0xbf4b, 0xbf4c, 0xbf4d, 0xbf4e, 0xbf4f, 0xbf52, 0xbf53, 0xbf54, 0xbf56, - 0xbf57, 0xbf58, 0xbf59, 0xbf5a, 0xbf5b, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf5f, 0xbf60, 0xbf61, 0xbf62, 0xbf63, 0xbf64, 0xbf65, 0xbf66, - 0xbf67, 0xbf68, 0xbf69, 0xbf6a, 0xbf6b, 0xbf6c, 0xbf6d, 0xbf6e, 0xbf6f, 0xbf70, 0xbf71, 0xbf72, 0xbf73, 0xbf74, 0xbf75, 0xbf76, - 0xbf77, 0xbf78, 0xbf79, 0xbf7a, 0xbf7b, 0xbf7c, 0xbf7d, 0xbf7e, 0xbf7f, 0xbf80, 0xbf81, 0xbf82, 0xbf83, 0xbf84, 0xbf85, 0xbf86, - 0xbf87, 0xbf88, 0xbf89, 0xbf8a, 0xbf8b, 0xbf8c, 0xbf8d, 0xbf8e, 0xbf8f, 0xbf90, 0xbf91, 0xbf92, 0xbf93, 0xbf95, 0xbf96, 0xbf97, - 0xbf98, 0xbf99, 0xbf9a, 0xbf9b, 0xbf9c, 0xbf9d, 0xbf9e, 0xbf9f, 0xbfa0, 0xbfa1, 0xbfa2, 0xbfa3, 0xbfa4, 0xbfa5, 0xbfa6, 0xbfa7, - 0xbfa8, 0xbfa9, 0xbfaa, 0xbfab, 0xbfac, 0xbfad, 0xbfae, 0xbfaf, 0xbfb1, 0xbfb2, 0xbfb3, 0xbfb4, 0xbfb5, 0xbfb6, 0xbfb7, 0xbfb8, - 0xbfb9, 0xbfba, 0xbfbb, 0xbfbc, 0xbfbd, 0xbfbe, 0xbfbf, 0xbfc0, 0xbfc1, 0xbfc2, 0xbfc3, 0xbfc4, 0xbfc6, 0xbfc7, 0xbfc8, 0xbfc9, - 0xbfca, 0xbfcb, 0xbfce, 0xbfcf, 0xbfd1, 0xbfd2, 0xbfd3, 0xbfd5, 0xbfd6, 0xbfd7, 0xbfd8, 0xbfd9, 0xbfda, 0xbfdb, 0xbfdd, 0xbfde, - 0xbfe0, 0xbfe2, 0xbfe3, 0xbfe4, 0xbfe5, 0xbfe6, 0xbfe7, 0xbfe8, 0xbfe9, 0xbfea, 0xbfeb, 0xbfec, 0xbfed, 0xbfee, 0xbfef, 0xbff0, - 0xbff1, 0xbff2, 0xbff3, 0xbff4, 0xbff5, 0xbff6, 0xbff7, 0xbff8, 0xbff9, 0xbffa, 0xbffb, 0xbffc, 0xbffd, 0xbffe, 0xbfff, 0xc000, - 0xc001, 0xc002, 0xc003, 0xc004, 0xc005, 0xc006, 0xc007, 0xc008, 0xc009, 0xc00a, 0xc00b, 0xc00c, 0xc00d, 0xc00e, 0xc00f, 0xc010, - 0xc011, 0xc012, 0xc013, 0xc014, 0xc015, 0xc016, 0xc017, 0xc018, 0xc019, 0xc01a, 0xc01b, 0xc01c, 0xc01d, 0xc01e, 0xc01f, 0xc020, - 0xc021, 0xc022, 0xc023, 0xc024, 0xc025, 0xc026, 0xc027, 0xc028, 0xc029, 0xc02a, 0xc02b, 0xc02c, 0xc02d, 0xc02e, 0xc02f, 0xc030, - 0xc031, 0xc032, 0xc033, 0xc034, 0xc035, 0xc036, 0xc037, 0xc038, 0xc039, 0xc03a, 0xc03b, 0xc03d, 0xc03e, 0xc03f, 0xc040, 0xc041, - 0xc042, 0xc043, 0xc044, 0xc045, 0xc046, 0xc047, 0xc048, 0xc049, 0xc04a, 0xc04b, 0xc04c, 0xc04d, 0xc04e, 0xc04f, 0xc050, 0xc052, - 0xc053, 0xc054, 0xc055, 0xc056, 0xc057, 0xc059, 0xc05a, 0xc05b, 0xc05d, 0xc05e, 0xc05f, 0xc061, 0xc062, 0xc063, 0xc064, 0xc065, - 0xc066, 0xc067, 0xc06a, 0xc06b, 0xc06c, 0xc06d, 0xc06e, 0xc06f, 0xc070, 0xc071, 0xc072, 0xc073, 0xc074, 0xc075, 0xc076, 0xc077, - 0xc078, 0xc079, 0xc07a, 0xc07b, 0xc07c, 0xc07d, 0xc07e, 0xc07f, 0xc080, 0xc081, 0xc082, 0xc083, 0xc084, 0xc085, 0xc086, 0xc087, - 0xc088, 0xc089, 0xc08a, 0xc08b, 0xc08c, 0xc08d, 0xc08e, 0xc08f, 0xc092, 0xc093, 0xc095, 0xc096, 0xc097, 0xc099, 0xc09a, 0xc09b, - 0xc09c, 0xc09d, 0xc09e, 0xc09f, 0xc0a2, 0xc0a4, 0xc0a6, 0xc0a7, 0xc0a8, 0xc0a9, 0xc0aa, 0xc0ab, 0xc0ae, 0xc0b1, 0xc0b2, 0xc0b7, - 0xc0b8, 0xc0b9, 0xc0ba, 0xc0bb, 0xc0be, 0xc0c2, 0xc0c3, 0xc0c4, 0xc0c6, 0xc0c7, 0xc0ca, 0xc0cb, 0xc0cd, 0xc0ce, 0xc0cf, 0xc0d1, - 0xc0d2, 0xc0d3, 0xc0d4, 0xc0d5, 0xc0d6, 0xc0d7, 0xc0da, 0xc0de, 0xc0df, 0xc0e0, 0xc0e1, 0xc0e2, 0xc0e3, 0xc0e6, 0xc0e7, 0xc0e9, - 0xc0ea, 0xc0eb, 0xc0ed, 0xc0ee, 0xc0ef, 0xc0f0, 0xc0f1, 0xc0f2, 0xc0f3, 0xc0f6, 0xc0f8, 0xc0fa, 0xc0fb, 0xc0fc, 0xc0fd, 0xc0fe, - 0xc0ff, 0xc101, 0xc102, 0xc103, 0xc105, 0xc106, 0xc107, 0xc109, 0xc10a, 0xc10b, 0xc10c, 0xc10d, 0xc10e, 0xc10f, 0xc111, 0xc112, - 0xc113, 0xc114, 0xc116, 0xc117, 0xc118, 0xc119, 0xc11a, 0xc11b, 0xc121, 0xc122, 0xc125, 0xc128, 0xc129, 0xc12a, 0xc12b, 0xc12e, - 0xc132, 0xc133, 0xc134, 0xc135, 0xc137, 0xc13a, 0xc13b, 0xc13d, 0xc13e, 0xc13f, 0xc141, 0xc142, 0xc143, 0xc144, 0xc145, 0xc146, - 0xc147, 0xc14a, 0xc14e, 0xc14f, 0xc150, 0xc151, 0xc152, 0xc153, 0xc156, 0xc157, 0xc159, 0xc15a, 0xc15b, 0xc15d, 0xc15e, 0xc15f, - 0xc160, 0xc161, 0xc162, 0xc163, 0xc166, 0xc16a, 0xc16b, 0xc16c, 0xc16d, 0xc16e, 0xc16f, 0xc171, 0xc172, 0xc173, 0xc175, 0xc176, - 0xc177, 0xc179, 0xc17a, 0xc17b, 0xc17c, 0xc17d, 0xc17e, 0xc17f, 0xc180, 0xc181, 0xc182, 0xc183, 0xc184, 0xc186, 0xc187, 0xc188, - 0xc189, 0xc18a, 0xc18b, 0xc18f, 0xc191, 0xc192, 0xc193, 0xc195, 0xc197, 0xc198, 0xc199, 0xc19a, 0xc19b, 0xc19e, 0xc1a0, 0xc1a2, - 0xc1a3, 0xc1a4, 0xc1a6, 0xc1a7, 0xc1aa, 0xc1ab, 0xc1ad, 0xc1ae, 0xc1af, 0xc1b1, 0xc1b2, 0xc1b3, 0xc1b4, 0xc1b5, 0xc1b6, 0xc1b7, - 0xc1b8, 0xc1b9, 0xc1ba, 0xc1bb, 0xc1bc, 0xc1be, 0xc1bf, 0xc1c0, 0xc1c1, 0xc1c2, 0xc1c3, 0xc1c5, 0xc1c6, 0xc1c7, 0xc1c9, 0xc1ca, - 0xc1cb, 0xc1cd, 0xc1ce, 0xc1cf, 0xc1d0, 0xc1d1, 0xc1d2, 0xc1d3, 0xc1d5, 0xc1d6, 0xc1d9, 0xc1da, 0xc1db, 0xc1dc, 0xc1dd, 0xc1de, - 0xc1df, 0xc1e1, 0xc1e2, 0xc1e3, 0xc1e5, 0xc1e6, 0xc1e7, 0xc1e9, 0xc1ea, 0xc1eb, 0xc1ec, 0xc1ed, 0xc1ee, 0xc1ef, 0xc1f2, 0xc1f4, - 0xc1f5, 0xc1f6, 0xc1f7, 0xc1f8, 0xc1f9, 0xc1fa, 0xc1fb, 0xc1fe, 0xc1ff, 0xc201, 0xc202, 0xc203, 0xc205, 0xc206, 0xc207, 0xc208, - 0xc209, 0xc20a, 0xc20b, 0xc20e, 0xc210, 0xc212, 0xc213, 0xc214, 0xc215, 0xc216, 0xc217, 0xc21a, 0xc21b, 0xc21d, 0xc21e, 0xc221, - 0xc222, 0xc223, 0xc224, 0xc225, 0xc226, 0xc227, 0xc22a, 0xc22c, 0xc22e, 0xc230, 0xc233, 0xc235, 0xc236, 0xc237, 0xc238, 0xc239, - 0xc23a, 0xc23b, 0xc23c, 0xc23d, 0xc23e, 0xc23f, 0xc240, 0xc241, 0xc242, 0xc243, 0xc244, 0xc245, 0xc246, 0xc247, 0xc249, 0xc24a, - 0xc24b, 0xc24c, 0xc24d, 0xc24e, 0xc24f, 0xc252, 0xc253, 0xc255, 0xc256, 0xc257, 0xc259, 0xc25a, 0xc25b, 0xc25c, 0xc25d, 0xc25e, - 0xc25f, 0xc261, 0xc262, 0xc263, 0xc264, 0xc266, 0xc267, 0xc268, 0xc269, 0xc26a, 0xc26b, 0xc26e, 0xc26f, 0xc271, 0xc272, 0xc273, - 0xc275, 0xc276, 0xc277, 0xc278, 0xc279, 0xc27a, 0xc27b, 0xc27e, 0xc280, 0xc282, 0xc283, 0xc284, 0xc285, 0xc286, 0xc287, 0xc28a, - 0xc28b, 0xc28c, 0xc28d, 0xc28e, 0xc28f, 0xc291, 0xc292, 0xc293, 0xc294, 0xc295, 0xc296, 0xc297, 0xc299, 0xc29a, 0xc29c, 0xc29e, - 0xc29f, 0xc2a0, 0xc2a1, 0xc2a2, 0xc2a3, 0xc2a6, 0xc2a7, 0xc2a9, 0xc2aa, 0xc2ab, 0xc2ae, 0xc2af, 0xc2b0, 0xc2b1, 0xc2b2, 0xc2b3, - 0xc2b6, 0xc2b8, 0xc2ba, 0xc2bb, 0xc2bc, 0xc2bd, 0xc2be, 0xc2bf, 0xc2c0, 0xc2c1, 0xc2c2, 0xc2c3, 0xc2c4, 0xc2c5, 0xc2c6, 0xc2c7, - 0xc2c8, 0xc2c9, 0xc2ca, 0xc2cb, 0xc2cc, 0xc2cd, 0xc2ce, 0xc2cf, 0xc2d0, 0xc2d1, 0xc2d2, 0xc2d3, 0xc2d4, 0xc2d5, 0xc2d6, 0xc2d7, - 0xc2d8, 0xc2d9, 0xc2da, 0xc2db, 0xc2de, 0xc2df, 0xc2e1, 0xc2e2, 0xc2e5, 0xc2e6, 0xc2e7, 0xc2e8, 0xc2e9, 0xc2ea, 0xc2ee, 0xc2f0, - 0xc2f2, 0xc2f3, 0xc2f4, 0xc2f5, 0xc2f7, 0xc2fa, 0xc2fd, 0xc2fe, 0xc2ff, 0xc301, 0xc302, 0xc303, 0xc304, 0xc305, 0xc306, 0xc307, - 0xc30a, 0xc30b, 0xc30e, 0xc30f, 0xc310, 0xc311, 0xc312, 0xc316, 0xc317, 0xc319, 0xc31a, 0xc31b, 0xc31d, 0xc31e, 0xc31f, 0xc320, - 0xc321, 0xc322, 0xc323, 0xc326, 0xc327, 0xc32a, 0xc32b, 0xc32c, 0xc32d, 0xc32e, 0xc32f, 0xc330, 0xc331, 0xc332, 0xc333, 0xc334, - 0xc335, 0xc336, 0xc337, 0xc338, 0xc339, 0xc33a, 0xc33b, 0xc33c, 0xc33d, 0xc33e, 0xc33f, 0xc340, 0xc341, 0xc342, 0xc343, 0xc344, - 0xc346, 0xc347, 0xc348, 0xc349, 0xc34a, 0xc34b, 0xc34c, 0xc34d, 0xc34e, 0xc34f, 0xc350, 0xc351, 0xc352, 0xc353, 0xc354, 0xc355, - 0xc356, 0xc357, 0xc358, 0xc359, 0xc35a, 0xc35b, 0xc35c, 0xc35d, 0xc35e, 0xc35f, 0xc360, 0xc361, 0xc362, 0xc363, 0xc364, 0xc365, - 0xc366, 0xc367, 0xc36a, 0xc36b, 0xc36d, 0xc36e, 0xc36f, 0xc371, 0xc373, 0xc374, 0xc375, 0xc376, 0xc377, 0xc37a, 0xc37b, 0xc37e, - 0xc37f, 0xc380, 0xc381, 0xc382, 0xc383, 0xc385, 0xc386, 0xc387, 0xc389, 0xc38a, 0xc38b, 0xc38d, 0xc38e, 0xc38f, 0xc390, 0xc391, - 0xc392, 0xc393, 0xc394, 0xc395, 0xc396, 0xc397, 0xc398, 0xc399, 0xc39a, 0xc39b, 0xc39c, 0xc39d, 0xc39e, 0xc39f, 0xc3a0, 0xc3a1, - 0xc3a2, 0xc3a3, 0xc3a4, 0xc3a5, 0xc3a6, 0xc3a7, 0xc3a8, 0xc3a9, 0xc3aa, 0xc3ab, 0xc3ac, 0xc3ad, 0xc3ae, 0xc3af, 0xc3b0, 0xc3b1, - 0xc3b2, 0xc3b3, 0xc3b4, 0xc3b5, 0xc3b6, 0xc3b7, 0xc3b8, 0xc3b9, 0xc3ba, 0xc3bb, 0xc3bc, 0xc3bd, 0xc3be, 0xc3bf, 0xc3c1, 0xc3c2, - 0xc3c3, 0xc3c4, 0xc3c5, 0xc3c6, 0xc3c7, 0xc3c8, 0xc3c9, 0xc3ca, 0xc3cb, 0xc3cc, 0xc3cd, 0xc3ce, 0xc3cf, 0xc3d0, 0xc3d1, 0xc3d2, - 0xc3d3, 0xc3d4, 0xc3d5, 0xc3d6, 0xc3d7, 0xc3da, 0xc3db, 0xc3dd, 0xc3de, 0xc3e1, 0xc3e3, 0xc3e4, 0xc3e5, 0xc3e6, 0xc3e7, 0xc3ea, - 0xc3eb, 0xc3ec, 0xc3ee, 0xc3ef, 0xc3f0, 0xc3f1, 0xc3f2, 0xc3f3, 0xc3f6, 0xc3f7, 0xc3f9, 0xc3fa, 0xc3fb, 0xc3fc, 0xc3fd, 0xc3fe, - 0xc3ff, 0xc400, 0xc401, 0xc402, 0xc403, 0xc404, 0xc405, 0xc406, 0xc407, 0xc409, 0xc40a, 0xc40b, 0xc40c, 0xc40d, 0xc40e, 0xc40f, - 0xc411, 0xc412, 0xc413, 0xc414, 0xc415, 0xc416, 0xc417, 0xc418, 0xc419, 0xc41a, 0xc41b, 0xc41c, 0xc41d, 0xc41e, 0xc41f, 0xc420, - 0xc421, 0xc422, 0xc423, 0xc425, 0xc426, 0xc427, 0xc428, 0xc429, 0xc42a, 0xc42b, 0xc42d, 0xc42e, 0xc42f, 0xc431, 0xc432, 0xc433, - 0xc435, 0xc436, 0xc437, 0xc438, 0xc439, 0xc43a, 0xc43b, 0xc43e, 0xc43f, 0xc440, 0xc441, 0xc442, 0xc443, 0xc444, 0xc445, 0xc446, - 0xc447, 0xc449, 0xc44a, 0xc44b, 0xc44c, 0xc44d, 0xc44e, 0xc44f, 0xc450, 0xc451, 0xc452, 0xc453, 0xc454, 0xc455, 0xc456, 0xc457, - 0xc458, 0xc459, 0xc45a, 0xc45b, 0xc45c, 0xc45d, 0xc45e, 0xc45f, 0xc460, 0xc461, 0xc462, 0xc463, 0xc466, 0xc467, 0xc469, 0xc46a, - 0xc46b, 0xc46d, 0xc46e, 0xc46f, 0xc470, 0xc471, 0xc472, 0xc473, 0xc476, 0xc477, 0xc478, 0xc47a, 0xc47b, 0xc47c, 0xc47d, 0xc47e, - 0xc47f, 0xc481, 0xc482, 0xc483, 0xc484, 0xc485, 0xc486, 0xc487, 0xc488, 0xc489, 0xc48a, 0xc48b, 0xc48c, 0xc48d, 0xc48e, 0xc48f, - 0xc490, 0xc491, 0xc492, 0xc493, 0xc495, 0xc496, 0xc497, 0xc498, 0xc499, 0xc49a, 0xc49b, 0xc49d, 0xc49e, 0xc49f, 0xc4a0, 0xc4a1, - 0xc4a2, 0xc4a3, 0xc4a4, 0xc4a5, 0xc4a6, 0xc4a7, 0xc4a8, 0xc4a9, 0xc4aa, 0xc4ab, 0xc4ac, 0xc4ad, 0xc4ae, 0xc4af, 0xc4b0, 0xc4b1, - 0xc4b2, 0xc4b3, 0xc4b4, 0xc4b5, 0xc4b6, 0xc4b7, 0xc4b9, 0xc4ba, 0xc4bb, 0xc4bd, 0xc4be, 0xc4bf, 0xc4c0, 0xc4c1, 0xc4c2, 0xc4c3, - 0xc4c4, 0xc4c5, 0xc4c6, 0xc4c7, 0xc4c8, 0xc4c9, 0xc4ca, 0xc4cb, 0xc4cc, 0xc4cd, 0xc4ce, 0xc4cf, 0xc4d0, 0xc4d1, 0xc4d2, 0xc4d3, - 0xc4d4, 0xc4d5, 0xc4d6, 0xc4d7, 0xc4d8, 0xc4d9, 0xc4da, 0xc4db, 0xc4dc, 0xc4dd, 0xc4de, 0xc4df, 0xc4e0, 0xc4e1, 0xc4e2, 0xc4e3, - 0xc4e4, 0xc4e5, 0xc4e6, 0xc4e7, 0xc4e8, 0xc4ea, 0xc4eb, 0xc4ec, 0xc4ed, 0xc4ee, 0xc4ef, 0xc4f2, 0xc4f3, 0xc4f5, 0xc4f6, 0xc4f7, - 0xc4f9, 0xc4fb, 0xc4fc, 0xc4fd, 0xc4fe, 0xc502, 0xc503, 0xc504, 0xc505, 0xc506, 0xc507, 0xc508, 0xc509, 0xc50a, 0xc50b, 0xc50d, - 0xc50e, 0xc50f, 0xc511, 0xc512, 0xc513, 0xc515, 0xc516, 0xc517, 0xc518, 0xc519, 0xc51a, 0xc51b, 0xc51d, 0xc51e, 0xc51f, 0xc520, - 0xc521, 0xc522, 0xc523, 0xc524, 0xc525, 0xc526, 0xc527, 0xc52a, 0xc52b, 0xc52d, 0xc52e, 0xc52f, 0xc531, 0xc532, 0xc533, 0xc534, - 0xc535, 0xc536, 0xc537, 0xc53a, 0xc53c, 0xc53e, 0xc53f, 0xc540, 0xc541, 0xc542, 0xc543, 0xc546, 0xc547, 0xc54b, 0xc54f, 0xc550, - 0xc551, 0xc552, 0xc556, 0xc55a, 0xc55b, 0xc55c, 0xc55f, 0xc562, 0xc563, 0xc565, 0xc566, 0xc567, 0xc569, 0xc56a, 0xc56b, 0xc56c, - 0xc56d, 0xc56e, 0xc56f, 0xc572, 0xc576, 0xc577, 0xc578, 0xc579, 0xc57a, 0xc57b, 0xc57e, 0xc57f, 0xc581, 0xc582, 0xc583, 0xc585, - 0xc586, 0xc588, 0xc589, 0xc58a, 0xc58b, 0xc58e, 0xc590, 0xc592, 0xc593, 0xc594, 0xc596, 0xc599, 0xc59a, 0xc59b, 0xc59d, 0xc59e, - 0xc59f, 0xc5a1, 0xc5a2, 0xc5a3, 0xc5a4, 0xc5a5, 0xc5a6, 0xc5a7, 0xc5a8, 0xc5aa, 0xc5ab, 0xc5ac, 0xc5ad, 0xc5ae, 0xc5af, 0xc5b0, - 0xc5b1, 0xc5b2, 0xc5b3, 0xc5b6, 0xc5b7, 0xc5ba, 0xc5bf, 0xc5c0, 0xc5c1, 0xc5c2, 0xc5c3, 0xc5cb, 0xc5cd, 0xc5cf, 0xc5d2, 0xc5d3, - 0xc5d5, 0xc5d6, 0xc5d7, 0xc5d9, 0xc5da, 0xc5db, 0xc5dc, 0xc5dd, 0xc5de, 0xc5df, 0xc5e2, 0xc5e4, 0xc5e6, 0xc5e7, 0xc5e8, 0xc5e9, - 0xc5ea, 0xc5eb, 0xc5ef, 0xc5f1, 0xc5f2, 0xc5f3, 0xc5f5, 0xc5f8, 0xc5f9, 0xc5fa, 0xc5fb, 0xc602, 0xc603, 0xc604, 0xc609, 0xc60a, - 0xc60b, 0xc60d, 0xc60e, 0xc60f, 0xc611, 0xc612, 0xc613, 0xc614, 0xc615, 0xc616, 0xc617, 0xc61a, 0xc61d, 0xc61e, 0xc61f, 0xc620, - 0xc621, 0xc622, 0xc623, 0xc626, 0xc627, 0xc629, 0xc62a, 0xc62b, 0xc62f, 0xc631, 0xc632, 0xc636, 0xc638, 0xc63a, 0xc63c, 0xc63d, - 0xc63e, 0xc63f, 0xc642, 0xc643, 0xc645, 0xc646, 0xc647, 0xc649, 0xc64a, 0xc64b, 0xc64c, 0xc64d, 0xc64e, 0xc64f, 0xc652, 0xc656, - 0xc657, 0xc658, 0xc659, 0xc65a, 0xc65b, 0xc65e, 0xc65f, 0xc661, 0xc662, 0xc663, 0xc664, 0xc665, 0xc666, 0xc667, 0xc668, 0xc669, - 0xc66a, 0xc66b, 0xc66d, 0xc66e, 0xc670, 0xc672, 0xc673, 0xc674, 0xc675, 0xc676, 0xc677, 0xc67a, 0xc67b, 0xc67d, 0xc67e, 0xc67f, - 0xc681, 0xc682, 0xc683, 0xc684, 0xc685, 0xc686, 0xc687, 0xc68a, 0xc68c, 0xc68e, 0xc68f, 0xc690, 0xc691, 0xc692, 0xc693, 0xc696, - 0xc697, 0xc699, 0xc69a, 0xc69b, 0xc69d, 0xc69e, 0xc69f, 0xc6a0, 0xc6a1, 0xc6a2, 0xc6a3, 0xc6a6, 0xc6a8, 0xc6aa, 0xc6ab, 0xc6ac, - 0xc6ad, 0xc6ae, 0xc6af, 0xc6b2, 0xc6b3, 0xc6b5, 0xc6b6, 0xc6b7, 0xc6bb, 0xc6bc, 0xc6bd, 0xc6be, 0xc6bf, 0xc6c2, 0xc6c4, 0xc6c6, - 0xc6c7, 0xc6c8, 0xc6c9, 0xc6ca, 0xc6cb, 0xc6ce, 0xc6cf, 0xc6d1, 0xc6d2, 0xc6d3, 0xc6d5, 0xc6d6, 0xc6d7, 0xc6d8, 0xc6d9, 0xc6da, - 0xc6db, 0xc6de, 0xc6df, 0xc6e2, 0xc6e3, 0xc6e4, 0xc6e5, 0xc6e6, 0xc6e7, 0xc6ea, 0xc6eb, 0xc6ed, 0xc6ee, 0xc6ef, 0xc6f1, 0xc6f2, - 0xc6f3, 0xc6f4, 0xc6f5, 0xc6f6, 0xc6f7, 0xc6fa, 0xc6fb, 0xc6fc, 0xc6fe, 0xc6ff, 0xc700, 0xc701, 0xc702, 0xc703, 0xc706, 0xc707, - 0xc709, 0xc70a, 0xc70b, 0xc70d, 0xc70e, 0xc70f, 0xc710, 0xc711, 0xc712, 0xc713, 0xc716, 0xc718, 0xc71a, 0xc71b, 0xc71c, 0xc71d, - 0xc71e, 0xc71f, 0xc722, 0xc723, 0xc725, 0xc726, 0xc727, 0xc729, 0xc72a, 0xc72b, 0xc72c, 0xc72d, 0xc72e, 0xc72f, 0xc732, 0xc734, - 0xc736, 0xc738, 0xc739, 0xc73a, 0xc73b, 0xc73e, 0xc73f, 0xc741, 0xc742, 0xc743, 0xc745, 0xc746, 0xc747, 0xc748, 0xc749, 0xc74b, - 0xc74e, 0xc750, 0xc759, 0xc75a, 0xc75b, 0xc75d, 0xc75e, 0xc75f, 0xc761, 0xc762, 0xc763, 0xc764, 0xc765, 0xc766, 0xc767, 0xc769, - 0xc76a, 0xc76c, 0xc76d, 0xc76e, 0xc76f, 0xc770, 0xc771, 0xc772, 0xc773, 0xc776, 0xc777, 0xc779, 0xc77a, 0xc77b, 0xc77f, 0xc780, - 0xc781, 0xc782, 0xc786, 0xc78b, 0xc78c, 0xc78d, 0xc78f, 0xc792, 0xc793, 0xc795, 0xc799, 0xc79b, 0xc79c, 0xc79d, 0xc79e, 0xc79f, - 0xc7a2, 0xc7a7, 0xc7a8, 0xc7a9, 0xc7aa, 0xc7ab, 0xc7ae, 0xc7af, 0xc7b1, 0xc7b2, 0xc7b3, 0xc7b5, 0xc7b6, 0xc7b7, 0xc7b8, 0xc7b9, - 0xc7ba, 0xc7bb, 0xc7be, 0xc7c2, 0xc7c3, 0xc7c4, 0xc7c5, 0xc7c6, 0xc7c7, 0xc7ca, 0xc7cb, 0xc7cd, 0xc7cf, 0xc7d1, 0xc7d2, 0xc7d3, - 0xc7d4, 0xc7d5, 0xc7d6, 0xc7d7, 0xc7d9, 0xc7da, 0xc7db, 0xc7dc, 0xc7de, 0xc7df, 0xc7e0, 0xc7e1, 0xc7e2, 0xc7e3, 0xc7e5, 0xc7e6, - 0xc7e7, 0xc7e9, 0xc7ea, 0xc7eb, 0xc7ed, 0xc7ee, 0xc7ef, 0xc7f0, 0xc7f1, 0xc7f2, 0xc7f3, 0xc7f4, 0xc7f5, 0xc7f6, 0xc7f7, 0xc7f8, - 0xc7f9, 0xc7fa, 0xc7fb, 0xc7fc, 0xc7fd, 0xc7fe, 0xc7ff, 0xc802, 0xc803, 0xc805, 0xc806, 0xc807, 0xc809, 0xc80b, 0xc80c, 0xc80d, - 0xc80e, 0xc80f, 0xc812, 0xc814, 0xc817, 0xc818, 0xc819, 0xc81a, 0xc81b, 0xc81e, 0xc81f, 0xc821, 0xc822, 0xc823, 0xc825, 0xc826, - 0xc827, 0xc828, 0xc829, 0xc82a, 0xc82b, 0xc82e, 0xc830, 0xc832, 0xc833, 0xc834, 0xc835, 0xc836, 0xc837, 0xc839, 0xc83a, 0xc83b, - 0xc83d, 0xc83e, 0xc83f, 0xc841, 0xc842, 0xc843, 0xc844, 0xc845, 0xc846, 0xc847, 0xc84a, 0xc84b, 0xc84e, 0xc84f, 0xc850, 0xc851, - 0xc852, 0xc853, 0xc855, 0xc856, 0xc857, 0xc858, 0xc859, 0xc85a, 0xc85b, 0xc85c, 0xc85d, 0xc85e, 0xc85f, 0xc860, 0xc861, 0xc862, - 0xc863, 0xc864, 0xc865, 0xc866, 0xc867, 0xc868, 0xc869, 0xc86a, 0xc86b, 0xc86c, 0xc86d, 0xc86e, 0xc86f, 0xc872, 0xc873, 0xc875, - 0xc876, 0xc877, 0xc879, 0xc87b, 0xc87c, 0xc87d, 0xc87e, 0xc87f, 0xc882, 0xc884, 0xc888, 0xc889, 0xc88a, 0xc88e, 0xc88f, 0xc890, - 0xc891, 0xc892, 0xc893, 0xc895, 0xc896, 0xc897, 0xc898, 0xc899, 0xc89a, 0xc89b, 0xc89c, 0xc89e, 0xc8a0, 0xc8a2, 0xc8a3, 0xc8a4, - 0xc8a5, 0xc8a6, 0xc8a7, 0xc8a9, 0xc8aa, 0xc8ab, 0xc8ac, 0xc8ad, 0xc8ae, 0xc8af, 0xc8b0, 0xc8b1, 0xc8b2, 0xc8b3, 0xc8b4, 0xc8b5, - 0xc8b6, 0xc8b7, 0xc8b8, 0xc8b9, 0xc8ba, 0xc8bb, 0xc8be, 0xc8bf, 0xc8c0, 0xc8c1, 0xc8c2, 0xc8c3, 0xc8c5, 0xc8c6, 0xc8c7, 0xc8c9, - 0xc8ca, 0xc8cb, 0xc8cd, 0xc8ce, 0xc8cf, 0xc8d0, 0xc8d1, 0xc8d2, 0xc8d3, 0xc8d6, 0xc8d8, 0xc8da, 0xc8db, 0xc8dc, 0xc8dd, 0xc8de, - 0xc8df, 0xc8e2, 0xc8e3, 0xc8e5, 0xc8e6, 0xc8e7, 0xc8e8, 0xc8e9, 0xc8ea, 0xc8eb, 0xc8ec, 0xc8ed, 0xc8ee, 0xc8ef, 0xc8f0, 0xc8f1, - 0xc8f2, 0xc8f3, 0xc8f4, 0xc8f6, 0xc8f7, 0xc8f8, 0xc8f9, 0xc8fa, 0xc8fb, 0xc8fe, 0xc8ff, 0xc901, 0xc902, 0xc903, 0xc907, 0xc908, - 0xc909, 0xc90a, 0xc90b, 0xc90e, 0xc910, 0xc912, 0xc913, 0xc914, 0xc915, 0xc916, 0xc917, 0xc919, 0xc91a, 0xc91b, 0xc91c, 0xc91d, - 0xc91e, 0xc91f, 0xc920, 0xc921, 0xc922, 0xc923, 0xc924, 0xc925, 0xc926, 0xc927, 0xc928, 0xc929, 0xc92a, 0xc92b, 0xc92d, 0xc92e, - 0xc92f, 0xc930, 0xc931, 0xc932, 0xc933, 0xc935, 0xc936, 0xc937, 0xc938, 0xc939, 0xc93a, 0xc93b, 0xc93c, 0xc93d, 0xc93e, 0xc93f, - 0xc940, 0xc941, 0xc942, 0xc943, 0xc944, 0xc945, 0xc946, 0xc947, 0xc948, 0xc949, 0xc94a, 0xc94b, 0xc94c, 0xc94d, 0xc94e, 0xc94f, - 0xc952, 0xc953, 0xc955, 0xc956, 0xc957, 0xc959, 0xc95a, 0xc95b, 0xc95c, 0xc95d, 0xc95e, 0xc95f, 0xc962, 0xc964, 0xc965, 0xc966, - 0xc967, 0xc968, 0xc969, 0xc96a, 0xc96b, 0xc96d, 0xc96e, 0xc96f, 0xc971, 0xc972, 0xc973, 0xc975, 0xc976, 0xc977, 0xc978, 0xc979, - 0xc97a, 0xc97b, 0xc97d, 0xc97e, 0xc97f, 0xc980, 0xc981, 0xc982, 0xc983, 0xc984, 0xc985, 0xc986, 0xc987, 0xc98a, 0xc98b, 0xc98d, - 0xc98e, 0xc98f, 0xc991, 0xc992, 0xc993, 0xc994, 0xc995, 0xc996, 0xc997, 0xc99a, 0xc99c, 0xc99e, 0xc99f, 0xc9a0, 0xc9a1, 0xc9a2, - 0xc9a3, 0xc9a4, 0xc9a5, 0xc9a6, 0xc9a7, 0xc9a8, 0xc9a9, 0xc9aa, 0xc9ab, 0xc9ac, 0xc9ad, 0xc9ae, 0xc9af, 0xc9b0, 0xc9b1, 0xc9b2, - 0xc9b3, 0xc9b4, 0xc9b5, 0xc9b6, 0xc9b7, 0xc9b8, 0xc9b9, 0xc9ba, 0xc9bb, 0xc9bc, 0xc9bd, 0xc9be, 0xc9bf, 0xc9c2, 0xc9c3, 0xc9c5, - 0xc9c6, 0xc9c9, 0xc9cb, 0xc9cc, 0xc9cd, 0xc9ce, 0xc9cf, 0xc9d2, 0xc9d4, 0xc9d7, 0xc9d8, 0xc9db, 0xc9de, 0xc9df, 0xc9e1, 0xc9e3, - 0xc9e5, 0xc9e6, 0xc9e8, 0xc9e9, 0xc9ea, 0xc9eb, 0xc9ee, 0xc9f2, 0xc9f3, 0xc9f4, 0xc9f5, 0xc9f6, 0xc9f7, 0xc9fa, 0xc9fb, 0xc9fd, - 0xc9fe, 0xc9ff, 0xca01, 0xca02, 0xca03, 0xca04, 0xca05, 0xca06, 0xca07, 0xca0a, 0xca0e, 0xca0f, 0xca10, 0xca11, 0xca12, 0xca13, - 0xca15, 0xca16, 0xca17, 0xca19, 0xca1a, 0xca1b, 0xca1c, 0xca1d, 0xca1e, 0xca1f, 0xca20, 0xca21, 0xca22, 0xca23, 0xca24, 0xca25, - 0xca26, 0xca27, 0xca28, 0xca2a, 0xca2b, 0xca2c, 0xca2d, 0xca2e, 0xca2f, 0xca30, 0xca31, 0xca32, 0xca33, 0xca34, 0xca35, 0xca36, - 0xca37, 0xca38, 0xca39, 0xca3a, 0xca3b, 0xca3c, 0xca3d, 0xca3e, 0xca3f, 0xca40, 0xca41, 0xca42, 0xca43, 0xca44, 0xca45, 0xca46, - 0xca47, 0xca48, 0xca49, 0xca4a, 0xca4b, 0xca4e, 0xca4f, 0xca51, 0xca52, 0xca53, 0xca55, 0xca56, 0xca57, 0xca58, 0xca59, 0xca5a, - 0xca5b, 0xca5e, 0xca62, 0xca63, 0xca64, 0xca65, 0xca66, 0xca67, 0xca69, 0xca6a, 0xca6b, 0xca6c, 0xca6d, 0xca6e, 0xca6f, 0xca70, - 0xca71, 0xca72, 0xca73, 0xca74, 0xca75, 0xca76, 0xca77, 0xca78, 0xca79, 0xca7a, 0xca7b, 0xca7c, 0xca7e, 0xca7f, 0xca80, 0xca81, - 0xca82, 0xca83, 0xca85, 0xca86, 0xca87, 0xca88, 0xca89, 0xca8a, 0xca8b, 0xca8c, 0xca8d, 0xca8e, 0xca8f, 0xca90, 0xca91, 0xca92, - 0xca93, 0xca94, 0xca95, 0xca96, 0xca97, 0xca99, 0xca9a, 0xca9b, 0xca9c, 0xca9d, 0xca9e, 0xca9f, 0xcaa0, 0xcaa1, 0xcaa2, 0xcaa3, - 0xcaa4, 0xcaa5, 0xcaa6, 0xcaa7, 0xcaa8, 0xcaa9, 0xcaaa, 0xcaab, 0xcaac, 0xcaad, 0xcaae, 0xcaaf, 0xcab0, 0xcab1, 0xcab2, 0xcab3, - 0xcab4, 0xcab5, 0xcab6, 0xcab7, 0xcab8, 0xcab9, 0xcaba, 0xcabb, 0xcabe, 0xcabf, 0xcac1, 0xcac2, 0xcac3, 0xcac5, 0xcac6, 0xcac7, - 0xcac8, 0xcac9, 0xcaca, 0xcacb, 0xcace, 0xcad0, 0xcad2, 0xcad4, 0xcad5, 0xcad6, 0xcad7, 0xcada, 0xcadb, 0xcadc, 0xcadd, 0xcade, - 0xcadf, 0xcae1, 0xcae2, 0xcae3, 0xcae4, 0xcae5, 0xcae6, 0xcae7, 0xcae8, 0xcae9, 0xcaea, 0xcaeb, 0xcaed, 0xcaee, 0xcaef, 0xcaf0, - 0xcaf1, 0xcaf2, 0xcaf3, 0xcaf5, 0xcaf6, 0xcaf7, 0xcaf8, 0xcaf9, 0xcafa, 0xcafb, 0xcafc, 0xcafd, 0xcafe, 0xcaff, 0xcb00, 0xcb01, - 0xcb02, 0xcb03, 0xcb04, 0xcb05, 0xcb06, 0xcb07, 0xcb09, 0xcb0a, 0xcb0b, 0xcb0c, 0xcb0d, 0xcb0e, 0xcb0f, 0xcb11, 0xcb12, 0xcb13, - 0xcb15, 0xcb16, 0xcb17, 0xcb19, 0xcb1a, 0xcb1b, 0xcb1c, 0xcb1d, 0xcb1e, 0xcb1f, 0xcb22, 0xcb23, 0xcb24, 0xcb25, 0xcb26, 0xcb27, - 0xcb28, 0xcb29, 0xcb2a, 0xcb2b, 0xcb2c, 0xcb2d, 0xcb2e, 0xcb2f, 0xcb30, 0xcb31, 0xcb32, 0xcb33, 0xcb34, 0xcb35, 0xcb36, 0xcb37, - 0xcb38, 0xcb39, 0xcb3a, 0xcb3b, 0xcb3c, 0xcb3d, 0xcb3e, 0xcb3f, 0xcb40, 0xcb42, 0xcb43, 0xcb44, 0xcb45, 0xcb46, 0xcb47, 0xcb4a, - 0xcb4b, 0xcb4d, 0xcb4e, 0xcb4f, 0xcb51, 0xcb52, 0xcb53, 0xcb54, 0xcb55, 0xcb56, 0xcb57, 0xcb5a, 0xcb5b, 0xcb5c, 0xcb5e, 0xcb5f, - 0xcb60, 0xcb61, 0xcb62, 0xcb63, 0xcb65, 0xcb66, 0xcb67, 0xcb68, 0xcb69, 0xcb6a, 0xcb6b, 0xcb6c, 0xcb6d, 0xcb6e, 0xcb6f, 0xcb70, - 0xcb71, 0xcb72, 0xcb73, 0xcb74, 0xcb75, 0xcb76, 0xcb77, 0xcb7a, 0xcb7b, 0xcb7c, 0xcb7d, 0xcb7e, 0xcb7f, 0xcb80, 0xcb81, 0xcb82, - 0xcb83, 0xcb84, 0xcb85, 0xcb86, 0xcb87, 0xcb88, 0xcb89, 0xcb8a, 0xcb8b, 0xcb8c, 0xcb8d, 0xcb8e, 0xcb8f, 0xcb90, 0xcb91, 0xcb92, - 0xcb93, 0xcb94, 0xcb95, 0xcb96, 0xcb97, 0xcb98, 0xcb99, 0xcb9a, 0xcb9b, 0xcb9d, 0xcb9e, 0xcb9f, 0xcba0, 0xcba1, 0xcba2, 0xcba3, - 0xcba4, 0xcba5, 0xcba6, 0xcba7, 0xcba8, 0xcba9, 0xcbaa, 0xcbab, 0xcbac, 0xcbad, 0xcbae, 0xcbaf, 0xcbb0, 0xcbb1, 0xcbb2, 0xcbb3, - 0xcbb4, 0xcbb5, 0xcbb6, 0xcbb7, 0xcbb9, 0xcbba, 0xcbbb, 0xcbbc, 0xcbbd, 0xcbbe, 0xcbbf, 0xcbc0, 0xcbc1, 0xcbc2, 0xcbc3, 0xcbc4, - 0xcbc5, 0xcbc6, 0xcbc7, 0xcbc8, 0xcbc9, 0xcbca, 0xcbcb, 0xcbcc, 0xcbcd, 0xcbce, 0xcbcf, 0xcbd0, 0xcbd1, 0xcbd2, 0xcbd3, 0xcbd5, - 0xcbd6, 0xcbd7, 0xcbd8, 0xcbd9, 0xcbda, 0xcbdb, 0xcbdc, 0xcbdd, 0xcbde, 0xcbdf, 0xcbe0, 0xcbe1, 0xcbe2, 0xcbe3, 0xcbe5, 0xcbe6, - 0xcbe8, 0xcbea, 0xcbeb, 0xcbec, 0xcbed, 0xcbee, 0xcbef, 0xcbf0, 0xcbf1, 0xcbf2, 0xcbf3, 0xcbf4, 0xcbf5, 0xcbf6, 0xcbf7, 0xcbf8, - 0xcbf9, 0xcbfa, 0xcbfb, 0xcbfc, 0xcbfd, 0xcbfe, 0xcbff, 0xcc00, 0xcc01, 0xcc02, 0xcc03, 0xcc04, 0xcc05, 0xcc06, 0xcc07, 0xcc08, - 0xcc09, 0xcc0a, 0xcc0b, 0xcc0e, 0xcc0f, 0xcc11, 0xcc12, 0xcc13, 0xcc15, 0xcc16, 0xcc17, 0xcc18, 0xcc19, 0xcc1a, 0xcc1b, 0xcc1e, - 0xcc1f, 0xcc20, 0xcc23, 0xcc24, 0xcc25, 0xcc26, 0xcc2a, 0xcc2b, 0xcc2d, 0xcc2f, 0xcc31, 0xcc32, 0xcc33, 0xcc34, 0xcc35, 0xcc36, - 0xcc37, 0xcc3a, 0xcc3f, 0xcc40, 0xcc41, 0xcc42, 0xcc43, 0xcc46, 0xcc47, 0xcc49, 0xcc4a, 0xcc4b, 0xcc4d, 0xcc4e, 0xcc4f, 0xcc50, - 0xcc51, 0xcc52, 0xcc53, 0xcc56, 0xcc5a, 0xcc5b, 0xcc5c, 0xcc5d, 0xcc5e, 0xcc5f, 0xcc61, 0xcc62, 0xcc63, 0xcc65, 0xcc67, 0xcc69, - 0xcc6a, 0xcc6b, 0xcc6c, 0xcc6d, 0xcc6e, 0xcc6f, 0xcc71, 0xcc72, 0xcc73, 0xcc74, 0xcc76, 0xcc77, 0xcc78, 0xcc79, 0xcc7a, 0xcc7b, - 0xcc7c, 0xcc7d, 0xcc7e, 0xcc7f, 0xcc80, 0xcc81, 0xcc82, 0xcc83, 0xcc84, 0xcc85, 0xcc86, 0xcc87, 0xcc88, 0xcc89, 0xcc8a, 0xcc8b, - 0xcc8c, 0xcc8d, 0xcc8e, 0xcc8f, 0xcc90, 0xcc91, 0xcc92, 0xcc93, 0xcc94, 0xcc95, 0xcc96, 0xcc97, 0xcc9a, 0xcc9b, 0xcc9d, 0xcc9e, - 0xcc9f, 0xcca1, 0xcca2, 0xcca3, 0xcca4, 0xcca5, 0xcca6, 0xcca7, 0xccaa, 0xccae, 0xccaf, 0xccb0, 0xccb1, 0xccb2, 0xccb3, 0xccb6, - 0xccb7, 0xccb9, 0xccba, 0xccbb, 0xccbd, 0xccbe, 0xccbf, 0xccc0, 0xccc1, 0xccc2, 0xccc3, 0xccc6, 0xccc8, 0xccca, 0xcccb, 0xcccc, - 0xcccd, 0xccce, 0xcccf, 0xccd1, 0xccd2, 0xccd3, 0xccd5, 0xccd6, 0xccd7, 0xccd8, 0xccd9, 0xccda, 0xccdb, 0xccdc, 0xccdd, 0xccde, - 0xccdf, 0xcce0, 0xcce1, 0xcce2, 0xcce3, 0xcce5, 0xcce6, 0xcce7, 0xcce8, 0xcce9, 0xccea, 0xcceb, 0xcced, 0xccee, 0xccef, 0xccf1, - 0xccf2, 0xccf3, 0xccf4, 0xccf5, 0xccf6, 0xccf7, 0xccf8, 0xccf9, 0xccfa, 0xccfb, 0xccfc, 0xccfd, 0xccfe, 0xccff, 0xcd00, 0xcd02, - 0xcd03, 0xcd04, 0xcd05, 0xcd06, 0xcd07, 0xcd0a, 0xcd0b, 0xcd0d, 0xcd0e, 0xcd0f, 0xcd11, 0xcd12, 0xcd13, 0xcd14, 0xcd15, 0xcd16, - 0xcd17, 0xcd1a, 0xcd1c, 0xcd1e, 0xcd1f, 0xcd20, 0xcd21, 0xcd22, 0xcd23, 0xcd25, 0xcd26, 0xcd27, 0xcd29, 0xcd2a, 0xcd2b, 0xcd2d, - 0xcd2e, 0xcd2f, 0xcd30, 0xcd31, 0xcd32, 0xcd33, 0xcd34, 0xcd35, 0xcd36, 0xcd37, 0xcd38, 0xcd3a, 0xcd3b, 0xcd3c, 0xcd3d, 0xcd3e, - 0xcd3f, 0xcd40, 0xcd41, 0xcd42, 0xcd43, 0xcd44, 0xcd45, 0xcd46, 0xcd47, 0xcd48, 0xcd49, 0xcd4a, 0xcd4b, 0xcd4c, 0xcd4d, 0xcd4e, - 0xcd4f, 0xcd50, 0xcd51, 0xcd52, 0xcd53, 0xcd54, 0xcd55, 0xcd56, 0xcd57, 0xcd58, 0xcd59, 0xcd5a, 0xcd5b, 0xcd5d, 0xcd5e, 0xcd5f, - 0xcd61, 0xcd62, 0xcd63, 0xcd65, 0xcd66, 0xcd67, 0xcd68, 0xcd69, 0xcd6a, 0xcd6b, 0xcd6e, 0xcd70, 0xcd72, 0xcd73, 0xcd74, 0xcd75, - 0xcd76, 0xcd77, 0xcd79, 0xcd7a, 0xcd7b, 0xcd7c, 0xcd7d, 0xcd7e, 0xcd7f, 0xcd80, 0xcd81, 0xcd82, 0xcd83, 0xcd84, 0xcd85, 0xcd86, - 0xcd87, 0xcd89, 0xcd8a, 0xcd8b, 0xcd8c, 0xcd8d, 0xcd8e, 0xcd8f, 0xcd90, 0xcd91, 0xcd92, 0xcd93, 0xcd96, 0xcd97, 0xcd99, 0xcd9a, - 0xcd9b, 0xcd9d, 0xcd9e, 0xcd9f, 0xcda0, 0xcda1, 0xcda2, 0xcda3, 0xcda6, 0xcda8, 0xcdaa, 0xcdab, 0xcdac, 0xcdad, 0xcdae, 0xcdaf, - 0xcdb1, 0xcdb2, 0xcdb3, 0xcdb4, 0xcdb5, 0xcdb6, 0xcdb7, 0xcdb8, 0xcdb9, 0xcdba, 0xcdbb, 0xcdbc, 0xcdbd, 0xcdbe, 0xcdbf, 0xcdc0, - 0xcdc1, 0xcdc2, 0xcdc3, 0xcdc5, 0xcdc6, 0xcdc7, 0xcdc8, 0xcdc9, 0xcdca, 0xcdcb, 0xcdcd, 0xcdce, 0xcdcf, 0xcdd1, 0xcdd2, 0xcdd3, - 0xcdd4, 0xcdd5, 0xcdd6, 0xcdd7, 0xcdd8, 0xcdd9, 0xcdda, 0xcddb, 0xcddc, 0xcddd, 0xcdde, 0xcddf, 0xcde0, 0xcde1, 0xcde2, 0xcde3, - 0xcde4, 0xcde5, 0xcde6, 0xcde7, 0xcde9, 0xcdea, 0xcdeb, 0xcded, 0xcdee, 0xcdef, 0xcdf1, 0xcdf2, 0xcdf3, 0xcdf4, 0xcdf5, 0xcdf6, - 0xcdf7, 0xcdfa, 0xcdfc, 0xcdfe, 0xcdff, 0xce00, 0xce01, 0xce02, 0xce03, 0xce05, 0xce06, 0xce07, 0xce09, 0xce0a, 0xce0b, 0xce0d, - 0xce0e, 0xce0f, 0xce10, 0xce11, 0xce12, 0xce13, 0xce15, 0xce16, 0xce17, 0xce18, 0xce1a, 0xce1b, 0xce1c, 0xce1d, 0xce1e, 0xce1f, - 0xce22, 0xce23, 0xce25, 0xce26, 0xce27, 0xce29, 0xce2a, 0xce2b, 0xce2c, 0xce2d, 0xce2e, 0xce2f, 0xce32, 0xce34, 0xce36, 0xce37, - 0xce38, 0xce39, 0xce3a, 0xce3b, 0xce3c, 0xce3d, 0xce3e, 0xce3f, 0xce40, 0xce41, 0xce42, 0xce43, 0xce44, 0xce45, 0xce46, 0xce47, - 0xce48, 0xce49, 0xce4a, 0xce4b, 0xce4c, 0xce4d, 0xce4e, 0xce4f, 0xce50, 0xce51, 0xce52, 0xce53, 0xce54, 0xce55, 0xce56, 0xce57, - 0xce5a, 0xce5b, 0xce5d, 0xce5e, 0xce62, 0xce63, 0xce64, 0xce65, 0xce66, 0xce67, 0xce6a, 0xce6c, 0xce6e, 0xce6f, 0xce70, 0xce71, - 0xce72, 0xce73, 0xce76, 0xce77, 0xce79, 0xce7a, 0xce7b, 0xce7d, 0xce7e, 0xce7f, 0xce80, 0xce81, 0xce82, 0xce83, 0xce86, 0xce88, - 0xce8a, 0xce8b, 0xce8c, 0xce8d, 0xce8e, 0xce8f, 0xce92, 0xce93, 0xce95, 0xce96, 0xce97, 0xce99, 0xce9a, 0xce9b, 0xce9c, 0xce9d, - 0xce9e, 0xce9f, 0xcea2, 0xcea6, 0xcea7, 0xcea8, 0xcea9, 0xceaa, 0xceab, 0xceae, 0xceaf, 0xceb0, 0xceb1, 0xceb2, 0xceb3, 0xceb4, - 0xceb5, 0xceb6, 0xceb7, 0xceb8, 0xceb9, 0xceba, 0xcebb, 0xcebc, 0xcebd, 0xcebe, 0xcebf, 0xcec0, 0xcec2, 0xcec3, 0xcec4, 0xcec5, - 0xcec6, 0xcec7, 0xcec8, 0xcec9, 0xceca, 0xcecb, 0xcecc, 0xcecd, 0xcece, 0xcecf, 0xced0, 0xced1, 0xced2, 0xced3, 0xced4, 0xced5, - 0xced6, 0xced7, 0xced8, 0xced9, 0xceda, 0xcedb, 0xcedc, 0xcedd, 0xcede, 0xcedf, 0xcee0, 0xcee1, 0xcee2, 0xcee3, 0xcee6, 0xcee7, - 0xcee9, 0xceea, 0xceed, 0xceee, 0xceef, 0xcef0, 0xcef1, 0xcef2, 0xcef3, 0xcef6, 0xcefa, 0xcefb, 0xcefc, 0xcefd, 0xcefe, 0xceff, - 0xcf02, 0xcf03, 0xcf05, 0xcf06, 0xcf07, 0xcf09, 0xcf0a, 0xcf0b, 0xcf0c, 0xcf0d, 0xcf0e, 0xcf0f, 0xcf12, 0xcf14, 0xcf16, 0xcf17, - 0xcf18, 0xcf19, 0xcf1a, 0xcf1b, 0xcf1d, 0xcf1e, 0xcf1f, 0xcf21, 0xcf22, 0xcf23, 0xcf25, 0xcf26, 0xcf27, 0xcf28, 0xcf29, 0xcf2a, - 0xcf2b, 0xcf2e, 0xcf32, 0xcf33, 0xcf34, 0xcf35, 0xcf36, 0xcf37, 0xcf39, 0xcf3a, 0xcf3b, 0xcf3c, 0xcf3d, 0xcf3e, 0xcf3f, 0xcf40, - 0xcf41, 0xcf42, 0xcf43, 0xcf44, 0xcf45, 0xcf46, 0xcf47, 0xcf48, 0xcf49, 0xcf4a, 0xcf4b, 0xcf4c, 0xcf4d, 0xcf4e, 0xcf4f, 0xcf50, - 0xcf51, 0xcf52, 0xcf53, 0xcf56, 0xcf57, 0xcf59, 0xcf5a, 0xcf5b, 0xcf5d, 0xcf5e, 0xcf5f, 0xcf60, 0xcf61, 0xcf62, 0xcf63, 0xcf66, - 0xcf68, 0xcf6a, 0xcf6b, 0xcf6c, 0xcf6d, 0xcf6e, 0xcf6f, 0xcf72, 0xcf73, 0xcf75, 0xcf76, 0xcf77, 0xcf79, 0xcf7a, 0xcf7b, 0xcf7c, - 0xcf7d, 0xcf7e, 0xcf7f, 0xcf81, 0xcf82, 0xcf83, 0xcf84, 0xcf86, 0xcf87, 0xcf88, 0xcf89, 0xcf8a, 0xcf8b, 0xcf8d, 0xcf8e, 0xcf8f, - 0xcf90, 0xcf91, 0xcf92, 0xcf93, 0xcf94, 0xcf95, 0xcf96, 0xcf97, 0xcf98, 0xcf99, 0xcf9a, 0xcf9b, 0xcf9c, 0xcf9d, 0xcf9e, 0xcf9f, - 0xcfa0, 0xcfa2, 0xcfa3, 0xcfa4, 0xcfa5, 0xcfa6, 0xcfa7, 0xcfa9, 0xcfaa, 0xcfab, 0xcfac, 0xcfad, 0xcfae, 0xcfaf, 0xcfb1, 0xcfb2, - 0xcfb3, 0xcfb4, 0xcfb5, 0xcfb6, 0xcfb7, 0xcfb8, 0xcfb9, 0xcfba, 0xcfbb, 0xcfbc, 0xcfbd, 0xcfbe, 0xcfbf, 0xcfc0, 0xcfc1, 0xcfc2, - 0xcfc3, 0xcfc5, 0xcfc6, 0xcfc7, 0xcfc8, 0xcfc9, 0xcfca, 0xcfcb, 0xcfcc, 0xcfcd, 0xcfce, 0xcfcf, 0xcfd0, 0xcfd1, 0xcfd2, 0xcfd3, - 0xcfd4, 0xcfd5, 0xcfd6, 0xcfd7, 0xcfd8, 0xcfd9, 0xcfda, 0xcfdb, 0xcfdc, 0xcfdd, 0xcfde, 0xcfdf, 0xcfe2, 0xcfe3, 0xcfe5, 0xcfe6, - 0xcfe7, 0xcfe9, 0xcfea, 0xcfeb, 0xcfec, 0xcfed, 0xcfee, 0xcfef, 0xcff2, 0xcff4, 0xcff6, 0xcff7, 0xcff8, 0xcff9, 0xcffa, 0xcffb, - 0xcffd, 0xcffe, 0xcfff, 0xd001, 0xd002, 0xd003, 0xd005, 0xd006, 0xd007, 0xd008, 0xd009, 0xd00a, 0xd00b, 0xd00c, 0xd00d, 0xd00e, - 0xd00f, 0xd010, 0xd012, 0xd013, 0xd014, 0xd015, 0xd016, 0xd017, 0xd019, 0xd01a, 0xd01b, 0xd01c, 0xd01d, 0xd01e, 0xd01f, 0xd020, - 0xd021, 0xd022, 0xd023, 0xd024, 0xd025, 0xd026, 0xd027, 0xd028, 0xd029, 0xd02a, 0xd02b, 0xd02c, 0xd02e, 0xd02f, 0xd030, 0xd031, - 0xd032, 0xd033, 0xd036, 0xd037, 0xd039, 0xd03a, 0xd03b, 0xd03d, 0xd03e, 0xd03f, 0xd040, 0xd041, 0xd042, 0xd043, 0xd046, 0xd048, - 0xd04a, 0xd04b, 0xd04c, 0xd04d, 0xd04e, 0xd04f, 0xd051, 0xd052, 0xd053, 0xd055, 0xd056, 0xd057, 0xd059, 0xd05a, 0xd05b, 0xd05c, - 0xd05d, 0xd05e, 0xd05f, 0xd061, 0xd062, 0xd063, 0xd064, 0xd065, 0xd066, 0xd067, 0xd068, 0xd069, 0xd06a, 0xd06b, 0xd06e, 0xd06f, - 0xd071, 0xd072, 0xd073, 0xd075, 0xd076, 0xd077, 0xd078, 0xd079, 0xd07a, 0xd07b, 0xd07e, 0xd07f, 0xd080, 0xd082, 0xd083, 0xd084, - 0xd085, 0xd086, 0xd087, 0xd088, 0xd089, 0xd08a, 0xd08b, 0xd08c, 0xd08d, 0xd08e, 0xd08f, 0xd090, 0xd091, 0xd092, 0xd093, 0xd094, - 0xd095, 0xd096, 0xd097, 0xd098, 0xd099, 0xd09a, 0xd09b, 0xd09c, 0xd09d, 0xd09e, 0xd09f, 0xd0a0, 0xd0a1, 0xd0a2, 0xd0a3, 0xd0a6, - 0xd0a7, 0xd0a9, 0xd0aa, 0xd0ab, 0xd0ad, 0xd0ae, 0xd0af, 0xd0b0, 0xd0b1, 0xd0b2, 0xd0b3, 0xd0b6, 0xd0b8, 0xd0ba, 0xd0bb, 0xd0bc, - 0xd0bd, 0xd0be, 0xd0bf, 0xd0c2, 0xd0c3, 0xd0c5, 0xd0c6, 0xd0c7, 0xd0ca, 0xd0cb, 0xd0cc, 0xd0cd, 0xd0ce, 0xd0cf, 0xd0d2, 0xd0d6, - 0xd0d7, 0xd0d8, 0xd0d9, 0xd0da, 0xd0db, 0xd0de, 0xd0df, 0xd0e1, 0xd0e2, 0xd0e3, 0xd0e5, 0xd0e6, 0xd0e7, 0xd0e8, 0xd0e9, 0xd0ea, - 0xd0eb, 0xd0ee, 0xd0f2, 0xd0f3, 0xd0f4, 0xd0f5, 0xd0f6, 0xd0f7, 0xd0f9, 0xd0fa, 0xd0fb, 0xd0fc, 0xd0fd, 0xd0fe, 0xd0ff, 0xd100, - 0xd101, 0xd102, 0xd103, 0xd104, 0xd105, 0xd106, 0xd107, 0xd108, 0xd109, 0xd10a, 0xd10b, 0xd10c, 0xd10e, 0xd10f, 0xd110, 0xd111, - 0xd112, 0xd113, 0xd114, 0xd115, 0xd116, 0xd117, 0xd118, 0xd119, 0xd11a, 0xd11b, 0xd11c, 0xd11d, 0xd11e, 0xd11f, 0xd120, 0xd121, - 0xd122, 0xd123, 0xd124, 0xd125, 0xd126, 0xd127, 0xd128, 0xd129, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, 0xd12f, 0xd132, 0xd133, - 0xd135, 0xd136, 0xd137, 0xd139, 0xd13b, 0xd13c, 0xd13d, 0xd13e, 0xd13f, 0xd142, 0xd146, 0xd147, 0xd148, 0xd149, 0xd14a, 0xd14b, - 0xd14e, 0xd14f, 0xd151, 0xd152, 0xd153, 0xd155, 0xd156, 0xd157, 0xd158, 0xd159, 0xd15a, 0xd15b, 0xd15e, 0xd160, 0xd162, 0xd163, - 0xd164, 0xd165, 0xd166, 0xd167, 0xd169, 0xd16a, 0xd16b, 0xd16d, 0xd16e, 0xd16f, 0xd170, 0xd171, 0xd172, 0xd173, 0xd174, 0xd175, - 0xd176, 0xd177, 0xd178, 0xd179, 0xd17a, 0xd17b, 0xd17d, 0xd17e, 0xd17f, 0xd180, 0xd181, 0xd182, 0xd183, 0xd185, 0xd186, 0xd187, - 0xd189, 0xd18a, 0xd18b, 0xd18c, 0xd18d, 0xd18e, 0xd18f, 0xd190, 0xd191, 0xd192, 0xd193, 0xd194, 0xd195, 0xd196, 0xd197, 0xd198, - 0xd199, 0xd19a, 0xd19b, 0xd19c, 0xd19d, 0xd19e, 0xd19f, 0xd1a2, 0xd1a3, 0xd1a5, 0xd1a6, 0xd1a7, 0xd1a9, 0xd1aa, 0xd1ab, 0xd1ac, - 0xd1ad, 0xd1ae, 0xd1af, 0xd1b2, 0xd1b4, 0xd1b6, 0xd1b7, 0xd1b8, 0xd1b9, 0xd1bb, 0xd1bd, 0xd1be, 0xd1bf, 0xd1c1, 0xd1c2, 0xd1c3, - 0xd1c4, 0xd1c5, 0xd1c6, 0xd1c7, 0xd1c8, 0xd1c9, 0xd1ca, 0xd1cb, 0xd1cc, 0xd1cd, 0xd1ce, 0xd1cf, 0xd1d0, 0xd1d1, 0xd1d2, 0xd1d3, - 0xd1d4, 0xd1d5, 0xd1d6, 0xd1d7, 0xd1d9, 0xd1da, 0xd1db, 0xd1dc, 0xd1dd, 0xd1de, 0xd1df, 0xd1e0, 0xd1e1, 0xd1e2, 0xd1e3, 0xd1e4, - 0xd1e5, 0xd1e6, 0xd1e7, 0xd1e8, 0xd1e9, 0xd1ea, 0xd1eb, 0xd1ec, 0xd1ed, 0xd1ee, 0xd1ef, 0xd1f0, 0xd1f1, 0xd1f2, 0xd1f3, 0xd1f5, - 0xd1f6, 0xd1f7, 0xd1f9, 0xd1fa, 0xd1fb, 0xd1fc, 0xd1fd, 0xd1fe, 0xd1ff, 0xd200, 0xd201, 0xd202, 0xd203, 0xd204, 0xd205, 0xd206, - 0xd208, 0xd20a, 0xd20b, 0xd20c, 0xd20d, 0xd20e, 0xd20f, 0xd211, 0xd212, 0xd213, 0xd214, 0xd215, 0xd216, 0xd217, 0xd218, 0xd219, - 0xd21a, 0xd21b, 0xd21c, 0xd21d, 0xd21e, 0xd21f, 0xd220, 0xd221, 0xd222, 0xd223, 0xd224, 0xd225, 0xd226, 0xd227, 0xd228, 0xd229, - 0xd22a, 0xd22b, 0xd22e, 0xd22f, 0xd231, 0xd232, 0xd233, 0xd235, 0xd236, 0xd237, 0xd238, 0xd239, 0xd23a, 0xd23b, 0xd23e, 0xd240, - 0xd242, 0xd243, 0xd244, 0xd245, 0xd246, 0xd247, 0xd249, 0xd24a, 0xd24b, 0xd24c, 0xd24d, 0xd24e, 0xd24f, 0xd250, 0xd251, 0xd252, - 0xd253, 0xd254, 0xd255, 0xd256, 0xd257, 0xd258, 0xd259, 0xd25a, 0xd25b, 0xd25d, 0xd25e, 0xd25f, 0xd260, 0xd261, 0xd262, 0xd263, - 0xd265, 0xd266, 0xd267, 0xd268, 0xd269, 0xd26a, 0xd26b, 0xd26c, 0xd26d, 0xd26e, 0xd26f, 0xd270, 0xd271, 0xd272, 0xd273, 0xd274, - 0xd275, 0xd276, 0xd277, 0xd278, 0xd279, 0xd27a, 0xd27b, 0xd27c, 0xd27d, 0xd27e, 0xd27f, 0xd282, 0xd283, 0xd285, 0xd286, 0xd287, - 0xd289, 0xd28a, 0xd28b, 0xd28c, 0xd28d, 0xd28e, 0xd28f, 0xd292, 0xd293, 0xd294, 0xd296, 0xd297, 0xd298, 0xd299, 0xd29a, 0xd29b, - 0xd29d, 0xd29e, 0xd29f, 0xd2a1, 0xd2a2, 0xd2a3, 0xd2a5, 0xd2a6, 0xd2a7, 0xd2a8, 0xd2a9, 0xd2aa, 0xd2ab, 0xd2ad, 0xd2ae, 0xd2af, - 0xd2b0, 0xd2b2, 0xd2b3, 0xd2b4, 0xd2b5, 0xd2b6, 0xd2b7, 0xd2ba, 0xd2bb, 0xd2bd, 0xd2be, 0xd2c1, 0xd2c3, 0xd2c4, 0xd2c5, 0xd2c6, - 0xd2c7, 0xd2ca, 0xd2cc, 0xd2cd, 0xd2ce, 0xd2cf, 0xd2d0, 0xd2d1, 0xd2d2, 0xd2d3, 0xd2d5, 0xd2d6, 0xd2d7, 0xd2d9, 0xd2da, 0xd2db, - 0xd2dd, 0xd2de, 0xd2df, 0xd2e0, 0xd2e1, 0xd2e2, 0xd2e3, 0xd2e6, 0xd2e7, 0xd2e8, 0xd2e9, 0xd2ea, 0xd2eb, 0xd2ec, 0xd2ed, 0xd2ee, - 0xd2ef, 0xd2f2, 0xd2f3, 0xd2f5, 0xd2f6, 0xd2f7, 0xd2f9, 0xd2fa, 0xd2fb, 0xd2fc, 0xd2fd, 0xd2fe, 0xd2ff, 0xd302, 0xd304, 0xd306, - 0xd307, 0xd308, 0xd309, 0xd30a, 0xd30b, 0xd30f, 0xd311, 0xd312, 0xd313, 0xd315, 0xd317, 0xd318, 0xd319, 0xd31a, 0xd31b, 0xd31e, - 0xd322, 0xd323, 0xd324, 0xd326, 0xd327, 0xd32a, 0xd32b, 0xd32d, 0xd32e, 0xd32f, 0xd331, 0xd332, 0xd333, 0xd334, 0xd335, 0xd336, - 0xd337, 0xd33a, 0xd33e, 0xd33f, 0xd340, 0xd341, 0xd342, 0xd343, 0xd346, 0xd347, 0xd348, 0xd349, 0xd34a, 0xd34b, 0xd34c, 0xd34d, - 0xd34e, 0xd34f, 0xd350, 0xd351, 0xd352, 0xd353, 0xd354, 0xd355, 0xd356, 0xd357, 0xd358, 0xd359, 0xd35a, 0xd35b, 0xd35c, 0xd35d, - 0xd35e, 0xd35f, 0xd360, 0xd361, 0xd362, 0xd363, 0xd364, 0xd365, 0xd366, 0xd367, 0xd368, 0xd369, 0xd36a, 0xd36b, 0xd36c, 0xd36d, - 0xd36e, 0xd36f, 0xd370, 0xd371, 0xd372, 0xd373, 0xd374, 0xd375, 0xd376, 0xd377, 0xd378, 0xd379, 0xd37a, 0xd37b, 0xd37e, 0xd37f, - 0xd381, 0xd382, 0xd383, 0xd385, 0xd386, 0xd387, 0xd388, 0xd389, 0xd38a, 0xd38b, 0xd38e, 0xd392, 0xd393, 0xd394, 0xd395, 0xd396, - 0xd397, 0xd39a, 0xd39b, 0xd39d, 0xd39e, 0xd39f, 0xd3a1, 0xd3a2, 0xd3a3, 0xd3a4, 0xd3a5, 0xd3a6, 0xd3a7, 0xd3aa, 0xd3ac, 0xd3ae, - 0xd3af, 0xd3b0, 0xd3b1, 0xd3b2, 0xd3b3, 0xd3b5, 0xd3b6, 0xd3b7, 0xd3b9, 0xd3ba, 0xd3bb, 0xd3bd, 0xd3be, 0xd3bf, 0xd3c0, 0xd3c1, - 0xd3c2, 0xd3c3, 0xd3c6, 0xd3c7, 0xd3ca, 0xd3cb, 0xd3cc, 0xd3cd, 0xd3ce, 0xd3cf, 0xd3d1, 0xd3d2, 0xd3d3, 0xd3d4, 0xd3d5, 0xd3d6, - 0xd3d7, 0xd3d9, 0xd3da, 0xd3db, 0xd3dc, 0xd3dd, 0xd3de, 0xd3df, 0xd3e0, 0xd3e2, 0xd3e4, 0xd3e5, 0xd3e6, 0xd3e7, 0xd3e8, 0xd3e9, - 0xd3ea, 0xd3eb, 0xd3ee, 0xd3ef, 0xd3f1, 0xd3f2, 0xd3f3, 0xd3f5, 0xd3f6, 0xd3f7, 0xd3f8, 0xd3f9, 0xd3fa, 0xd3fb, 0xd3fe, 0xd400, - 0xd402, 0xd403, 0xd404, 0xd405, 0xd406, 0xd407, 0xd409, 0xd40a, 0xd40b, 0xd40c, 0xd40d, 0xd40e, 0xd40f, 0xd410, 0xd411, 0xd412, - 0xd413, 0xd414, 0xd415, 0xd416, 0xd417, 0xd418, 0xd419, 0xd41a, 0xd41b, 0xd41c, 0xd41e, 0xd41f, 0xd420, 0xd421, 0xd422, 0xd423, - 0xd424, 0xd425, 0xd426, 0xd427, 0xd428, 0xd429, 0xd42a, 0xd42b, 0xd42c, 0xd42d, 0xd42e, 0xd42f, 0xd430, 0xd431, 0xd432, 0xd433, - 0xd434, 0xd435, 0xd436, 0xd437, 0xd438, 0xd439, 0xd43a, 0xd43b, 0xd43c, 0xd43d, 0xd43e, 0xd43f, 0xd441, 0xd442, 0xd443, 0xd445, - 0xd446, 0xd447, 0xd448, 0xd449, 0xd44a, 0xd44b, 0xd44c, 0xd44d, 0xd44e, 0xd44f, 0xd450, 0xd451, 0xd452, 0xd453, 0xd454, 0xd455, - 0xd456, 0xd457, 0xd458, 0xd459, 0xd45a, 0xd45b, 0xd45d, 0xd45e, 0xd45f, 0xd461, 0xd462, 0xd463, 0xd465, 0xd466, 0xd467, 0xd468, - 0xd469, 0xd46a, 0xd46b, 0xd46c, 0xd46e, 0xd470, 0xd471, 0xd472, 0xd473, 0xd474, 0xd475, 0xd476, 0xd477, 0xd47a, 0xd47b, 0xd47d, - 0xd47e, 0xd481, 0xd483, 0xd484, 0xd485, 0xd486, 0xd487, 0xd48a, 0xd48c, 0xd48e, 0xd48f, 0xd490, 0xd491, 0xd492, 0xd493, 0xd495, - 0xd496, 0xd497, 0xd498, 0xd499, 0xd49a, 0xd49b, 0xd49c, 0xd49d, 0xd49e, 0xd49f, 0xd4a0, 0xd4a1, 0xd4a2, 0xd4a3, 0xd4a4, 0xd4a5, - 0xd4a6, 0xd4a7, 0xd4a8, 0xd4aa, 0xd4ab, 0xd4ac, 0xd4ad, 0xd4ae, 0xd4af, 0xd4b0, 0xd4b1, 0xd4b2, 0xd4b3, 0xd4b4, 0xd4b5, 0xd4b6, - 0xd4b7, 0xd4b8, 0xd4b9, 0xd4ba, 0xd4bb, 0xd4bc, 0xd4bd, 0xd4be, 0xd4bf, 0xd4c0, 0xd4c1, 0xd4c2, 0xd4c3, 0xd4c4, 0xd4c5, 0xd4c6, - 0xd4c7, 0xd4c8, 0xd4c9, 0xd4ca, 0xd4cb, 0xd4cd, 0xd4ce, 0xd4cf, 0xd4d1, 0xd4d2, 0xd4d3, 0xd4d5, 0xd4d6, 0xd4d7, 0xd4d8, 0xd4d9, - 0xd4da, 0xd4db, 0xd4dd, 0xd4de, 0xd4e0, 0xd4e1, 0xd4e2, 0xd4e3, 0xd4e4, 0xd4e5, 0xd4e6, 0xd4e7, 0xd4e9, 0xd4ea, 0xd4eb, 0xd4ed, - 0xd4ee, 0xd4ef, 0xd4f1, 0xd4f2, 0xd4f3, 0xd4f4, 0xd4f5, 0xd4f6, 0xd4f7, 0xd4f9, 0xd4fa, 0xd4fc, 0xd4fe, 0xd4ff, 0xd500, 0xd501, - 0xd502, 0xd503, 0xd505, 0xd506, 0xd507, 0xd509, 0xd50a, 0xd50b, 0xd50d, 0xd50e, 0xd50f, 0xd510, 0xd511, 0xd512, 0xd513, 0xd516, - 0xd518, 0xd519, 0xd51a, 0xd51b, 0xd51c, 0xd51d, 0xd51e, 0xd51f, 0xd520, 0xd521, 0xd522, 0xd523, 0xd524, 0xd525, 0xd526, 0xd527, - 0xd528, 0xd529, 0xd52a, 0xd52b, 0xd52c, 0xd52d, 0xd52e, 0xd52f, 0xd530, 0xd531, 0xd532, 0xd533, 0xd534, 0xd535, 0xd536, 0xd537, - 0xd538, 0xd539, 0xd53a, 0xd53b, 0xd53e, 0xd53f, 0xd541, 0xd542, 0xd543, 0xd545, 0xd546, 0xd547, 0xd548, 0xd549, 0xd54a, 0xd54b, - 0xd54e, 0xd550, 0xd552, 0xd553, 0xd554, 0xd555, 0xd556, 0xd557, 0xd55a, 0xd55b, 0xd55d, 0xd55e, 0xd55f, 0xd561, 0xd562, 0xd563, - 0xd564, 0xd566, 0xd567, 0xd56a, 0xd56c, 0xd56e, 0xd56f, 0xd570, 0xd571, 0xd572, 0xd573, 0xd576, 0xd577, 0xd579, 0xd57a, 0xd57b, - 0xd57d, 0xd57e, 0xd57f, 0xd580, 0xd581, 0xd582, 0xd583, 0xd586, 0xd58a, 0xd58b, 0xd58c, 0xd58d, 0xd58e, 0xd58f, 0xd591, 0xd592, - 0xd593, 0xd594, 0xd595, 0xd596, 0xd597, 0xd598, 0xd599, 0xd59a, 0xd59b, 0xd59c, 0xd59d, 0xd59e, 0xd59f, 0xd5a0, 0xd5a1, 0xd5a2, - 0xd5a3, 0xd5a4, 0xd5a6, 0xd5a7, 0xd5a8, 0xd5a9, 0xd5aa, 0xd5ab, 0xd5ac, 0xd5ad, 0xd5ae, 0xd5af, 0xd5b0, 0xd5b1, 0xd5b2, 0xd5b3, - 0xd5b4, 0xd5b5, 0xd5b6, 0xd5b7, 0xd5b8, 0xd5b9, 0xd5ba, 0xd5bb, 0xd5bc, 0xd5bd, 0xd5be, 0xd5bf, 0xd5c0, 0xd5c1, 0xd5c2, 0xd5c3, - 0xd5c4, 0xd5c5, 0xd5c6, 0xd5c7, 0xd5ca, 0xd5cb, 0xd5cd, 0xd5ce, 0xd5cf, 0xd5d1, 0xd5d3, 0xd5d4, 0xd5d5, 0xd5d6, 0xd5d7, 0xd5da, - 0xd5dc, 0xd5de, 0xd5df, 0xd5e0, 0xd5e1, 0xd5e2, 0xd5e3, 0xd5e6, 0xd5e7, 0xd5e9, 0xd5ea, 0xd5eb, 0xd5ed, 0xd5ee, 0xd5ef, 0xd5f0, - 0xd5f1, 0xd5f2, 0xd5f3, 0xd5f6, 0xd5f8, 0xd5fa, 0xd5fb, 0xd5fc, 0xd5fd, 0xd5fe, 0xd5ff, 0xd602, 0xd603, 0xd605, 0xd606, 0xd607, - 0xd609, 0xd60a, 0xd60b, 0xd60c, 0xd60d, 0xd60e, 0xd60f, 0xd612, 0xd616, 0xd617, 0xd618, 0xd619, 0xd61a, 0xd61b, 0xd61d, 0xd61e, - 0xd61f, 0xd621, 0xd622, 0xd623, 0xd625, 0xd626, 0xd627, 0xd628, 0xd629, 0xd62a, 0xd62b, 0xd62c, 0xd62e, 0xd62f, 0xd630, 0xd631, - 0xd632, 0xd633, 0xd634, 0xd635, 0xd636, 0xd637, 0xd63a, 0xd63b, 0xd63d, 0xd63e, 0xd63f, 0xd641, 0xd642, 0xd643, 0xd644, 0xd646, - 0xd647, 0xd64a, 0xd64c, 0xd64e, 0xd64f, 0xd650, 0xd652, 0xd653, 0xd656, 0xd657, 0xd659, 0xd65a, 0xd65b, 0xd65d, 0xd65e, 0xd65f, - 0xd660, 0xd661, 0xd662, 0xd663, 0xd664, 0xd665, 0xd666, 0xd668, 0xd66a, 0xd66b, 0xd66c, 0xd66d, 0xd66e, 0xd66f, 0xd672, 0xd673, - 0xd675, 0xd676, 0xd677, 0xd678, 0xd679, 0xd67a, 0xd67b, 0xd67c, 0xd67d, 0xd67e, 0xd67f, 0xd680, 0xd681, 0xd682, 0xd684, 0xd686, - 0xd687, 0xd688, 0xd689, 0xd68a, 0xd68b, 0xd68e, 0xd68f, 0xd691, 0xd692, 0xd693, 0xd695, 0xd696, 0xd697, 0xd698, 0xd699, 0xd69a, - 0xd69b, 0xd69c, 0xd69e, 0xd6a0, 0xd6a2, 0xd6a3, 0xd6a4, 0xd6a5, 0xd6a6, 0xd6a7, 0xd6a9, 0xd6aa, 0xd6ab, 0xd6ad, 0xd6ae, 0xd6af, - 0xd6b1, 0xd6b2, 0xd6b3, 0xd6b4, 0xd6b5, 0xd6b6, 0xd6b7, 0xd6b8, 0xd6ba, 0xd6bc, 0xd6bd, 0xd6be, 0xd6bf, 0xd6c0, 0xd6c1, 0xd6c2, - 0xd6c3, 0xd6c6, 0xd6c7, 0xd6c9, 0xd6ca, 0xd6cb, 0xd6cd, 0xd6ce, 0xd6cf, 0xd6d0, 0xd6d2, 0xd6d3, 0xd6d5, 0xd6d6, 0xd6d8, 0xd6da, - 0xd6db, 0xd6dc, 0xd6dd, 0xd6de, 0xd6df, 0xd6e1, 0xd6e2, 0xd6e3, 0xd6e5, 0xd6e6, 0xd6e7, 0xd6e9, 0xd6ea, 0xd6eb, 0xd6ec, 0xd6ed, - 0xd6ee, 0xd6ef, 0xd6f1, 0xd6f2, 0xd6f3, 0xd6f4, 0xd6f6, 0xd6f7, 0xd6f8, 0xd6f9, 0xd6fa, 0xd6fb, 0xd6fe, 0xd6ff, 0xd701, 0xd702, - 0xd703, 0xd705, 0xd706, 0xd707, 0xd708, 0xd709, 0xd70a, 0xd70b, 0xd70c, 0xd70d, 0xd70e, 0xd70f, 0xd710, 0xd712, 0xd713, 0xd714, - 0xd715, 0xd716, 0xd717, 0xd71a, 0xd71b, 0xd71d, 0xd71e, 0xd71f, 0xd721, 0xd722, 0xd723, 0xd724, 0xd725, 0xd726, 0xd727, 0xd72a, - 0xd72c, 0xd72e, 0xd72f, 0xd730, 0xd731, 0xd732, 0xd733, 0xd736, 0xd737, 0xd739, 0xd73a, 0xd73b, 0xd73d, 0xd73e, 0xd73f, 0xd740, - 0xd741, 0xd742, 0xd743, 0xd745, 0xd746, 0xd748, 0xd74a, 0xd74b, 0xd74c, 0xd74d, 0xd74e, 0xd74f, 0xd752, 0xd753, 0xd755, 0xd75a, - 0xd75b, 0xd75c, 0xd75d, 0xd75e, 0xd75f, 0xd762, 0xd764, 0xd766, 0xd767, 0xd768, 0xd76a, 0xd76b, 0xd76d, 0xd76e, 0xd76f, 0xd771, - 0xd772, 0xd773, 0xd775, 0xd776, 0xd777, 0xd778, 0xd779, 0xd77a, 0xd77b, 0xd77e, 0xd77f, 0xd780, 0xd782, 0xd783, 0xd784, 0xd785, - 0xd786, 0xd787, 0xd78a, 0xd78b, 0xd78d, 0xd78e, 0xd78f, 0xd791, 0xd792, 0xd793, 0xd794, 0xd795, 0xd796, 0xd797, 0xd79a, 0xd79c, - 0xd79e, 0xd79f, 0xd7a0, 0xd7a1, 0xd7a2, 0xd7a3, -}; - -static const uint16_t ksc5601_hanja_to_unicode[4888] = -{ - 0x4f3d, 0x4f73, 0x5047, 0x50f9, 0x52a0, 0x53ef, 0x5475, 0x54e5, 0x5609, 0x5ac1, 0x5bb6, 0x6687, 0x67b6, 0x67b7, 0x67ef, 0x6b4c, - 0x73c2, 0x75c2, 0x7a3c, 0x82db, 0x8304, 0x8857, 0x8888, 0x8a36, 0x8cc8, 0x8dcf, 0x8efb, 0x8fe6, 0x99d5, 0x523b, 0x5374, 0x5404, - 0x606a, 0x6164, 0x6bbc, 0x73cf, 0x811a, 0x89ba, 0x89d2, 0x95a3, 0x4f83, 0x520a, 0x58be, 0x5978, 0x59e6, 0x5e72, 0x5e79, 0x61c7, - 0x63c0, 0x6746, 0x67ec, 0x687f, 0x6f97, 0x764e, 0x770b, 0x78f5, 0x7a08, 0x7aff, 0x7c21, 0x809d, 0x826e, 0x8271, 0x8aeb, 0x9593, - 0x4e6b, 0x559d, 0x66f7, 0x6e34, 0x78a3, 0x7aed, 0x845b, 0x8910, 0x874e, 0x97a8, 0x52d8, 0x574e, 0x582a, 0x5d4c, 0x611f, 0x61be, - 0x6221, 0x6562, 0x67d1, 0x6a44, 0x6e1b, 0x7518, 0x75b3, 0x76e3, 0x77b0, 0x7d3a, 0x90af, 0x9451, 0x9452, 0x9f95, 0x5323, 0x5cac, - 0x7532, 0x80db, 0x9240, 0x9598, 0x525b, 0x5808, 0x59dc, 0x5ca1, 0x5d17, 0x5eb7, 0x5f3a, 0x5f4a, 0x6177, 0x6c5f, 0x757a, 0x7586, - 0x7ce0, 0x7d73, 0x7db1, 0x7f8c, 0x8154, 0x8221, 0x8591, 0x8941, 0x8b1b, 0x92fc, 0x964d, 0x9c47, 0x4ecb, 0x4ef7, 0x500b, 0x51f1, - 0x584f, 0x6137, 0x613e, 0x6168, 0x6539, 0x69ea, 0x6f11, 0x75a5, 0x7686, 0x76d6, 0x7b87, 0x82a5, 0x84cb, 0xf900, 0x93a7, 0x958b, - 0x5580, 0x5ba2, 0x5751, 0xf901, 0x7cb3, 0x7fb9, 0x91b5, 0x5028, 0x53bb, 0x5c45, 0x5de8, 0x62d2, 0x636e, 0x64da, 0x64e7, 0x6e20, - 0x70ac, 0x795b, 0x8ddd, 0x8e1e, 0xf902, 0x907d, 0x9245, 0x92f8, 0x4e7e, 0x4ef6, 0x5065, 0x5dfe, 0x5efa, 0x6106, 0x6957, 0x8171, - 0x8654, 0x8e47, 0x9375, 0x9a2b, 0x4e5e, 0x5091, 0x6770, 0x6840, 0x5109, 0x528d, 0x5292, 0x6aa2, 0x77bc, 0x9210, 0x9ed4, 0x52ab, - 0x602f, 0x8ff2, 0x5048, 0x61a9, 0x63ed, 0x64ca, 0x683c, 0x6a84, 0x6fc0, 0x8188, 0x89a1, 0x9694, 0x5805, 0x727d, 0x72ac, 0x7504, - 0x7d79, 0x7e6d, 0x80a9, 0x898b, 0x8b74, 0x9063, 0x9d51, 0x6289, 0x6c7a, 0x6f54, 0x7d50, 0x7f3a, 0x8a23, 0x517c, 0x614a, 0x7b9d, - 0x8b19, 0x9257, 0x938c, 0x4eac, 0x4fd3, 0x501e, 0x50be, 0x5106, 0x52c1, 0x52cd, 0x537f, 0x5770, 0x5883, 0x5e9a, 0x5f91, 0x6176, - 0x61ac, 0x64ce, 0x656c, 0x666f, 0x66bb, 0x66f4, 0x6897, 0x6d87, 0x7085, 0x70f1, 0x749f, 0x74a5, 0x74ca, 0x75d9, 0x786c, 0x78ec, - 0x7adf, 0x7af6, 0x7d45, 0x7d93, 0x8015, 0x803f, 0x811b, 0x8396, 0x8b66, 0x8f15, 0x9015, 0x93e1, 0x9803, 0x9838, 0x9a5a, 0x9be8, - 0x4fc2, 0x5553, 0x583a, 0x5951, 0x5b63, 0x5c46, 0x60b8, 0x6212, 0x6842, 0x68b0, 0x68e8, 0x6eaa, 0x754c, 0x7678, 0x78ce, 0x7a3d, - 0x7cfb, 0x7e6b, 0x7e7c, 0x8a08, 0x8aa1, 0x8c3f, 0x968e, 0x9dc4, 0x53e4, 0x53e9, 0x544a, 0x5471, 0x56fa, 0x59d1, 0x5b64, 0x5c3b, - 0x5eab, 0x62f7, 0x6537, 0x6545, 0x6572, 0x66a0, 0x67af, 0x69c1, 0x6cbd, 0x75fc, 0x7690, 0x777e, 0x7a3f, 0x7f94, 0x8003, 0x80a1, - 0x818f, 0x82e6, 0x82fd, 0x83f0, 0x85c1, 0x8831, 0x88b4, 0x8aa5, 0xf903, 0x8f9c, 0x932e, 0x96c7, 0x9867, 0x9ad8, 0x9f13, 0x54ed, - 0x659b, 0x66f2, 0x688f, 0x7a40, 0x8c37, 0x9d60, 0x56f0, 0x5764, 0x5d11, 0x6606, 0x68b1, 0x68cd, 0x6efe, 0x7428, 0x889e, 0x9be4, - 0x6c68, 0xf904, 0x9aa8, 0x4f9b, 0x516c, 0x5171, 0x529f, 0x5b54, 0x5de5, 0x6050, 0x606d, 0x62f1, 0x63a7, 0x653b, 0x73d9, 0x7a7a, - 0x86a3, 0x8ca2, 0x978f, 0x4e32, 0x5be1, 0x6208, 0x679c, 0x74dc, 0x79d1, 0x83d3, 0x8a87, 0x8ab2, 0x8de8, 0x904e, 0x934b, 0x9846, - 0x5ed3, 0x69e8, 0x85ff, 0x90ed, 0xf905, 0x51a0, 0x5b98, 0x5bec, 0x6163, 0x68fa, 0x6b3e, 0x704c, 0x742f, 0x74d8, 0x7ba1, 0x7f50, - 0x83c5, 0x89c0, 0x8cab, 0x95dc, 0x9928, 0x522e, 0x605d, 0x62ec, 0x9002, 0x4f8a, 0x5149, 0x5321, 0x58d9, 0x5ee3, 0x66e0, 0x6d38, - 0x709a, 0x72c2, 0x73d6, 0x7b50, 0x80f1, 0x945b, 0x5366, 0x639b, 0x7f6b, 0x4e56, 0x5080, 0x584a, 0x58de, 0x602a, 0x6127, 0x62d0, - 0x69d0, 0x9b41, 0x5b8f, 0x7d18, 0x80b1, 0x8f5f, 0x4ea4, 0x50d1, 0x54ac, 0x55ac, 0x5b0c, 0x5da0, 0x5de7, 0x652a, 0x654e, 0x6821, - 0x6a4b, 0x72e1, 0x768e, 0x77ef, 0x7d5e, 0x7ff9, 0x81a0, 0x854e, 0x86df, 0x8f03, 0x8f4e, 0x90ca, 0x9903, 0x9a55, 0x9bab, 0x4e18, - 0x4e45, 0x4e5d, 0x4ec7, 0x4ff1, 0x5177, 0x52fe, 0x5340, 0x53e3, 0x53e5, 0x548e, 0x5614, 0x5775, 0x57a2, 0x5bc7, 0x5d87, 0x5ed0, - 0x61fc, 0x62d8, 0x6551, 0x67b8, 0x67e9, 0x69cb, 0x6b50, 0x6bc6, 0x6bec, 0x6c42, 0x6e9d, 0x7078, 0x72d7, 0x7396, 0x7403, 0x77bf, - 0x77e9, 0x7a76, 0x7d7f, 0x8009, 0x81fc, 0x8205, 0x820a, 0x82df, 0x8862, 0x8b33, 0x8cfc, 0x8ec0, 0x9011, 0x90b1, 0x9264, 0x92b6, - 0x99d2, 0x9a45, 0x9ce9, 0x9dd7, 0x9f9c, 0x570b, 0x5c40, 0x83ca, 0x97a0, 0x97ab, 0x9eb4, 0x541b, 0x7a98, 0x7fa4, 0x88d9, 0x8ecd, - 0x90e1, 0x5800, 0x5c48, 0x6398, 0x7a9f, 0x5bae, 0x5f13, 0x7a79, 0x7aae, 0x828e, 0x8eac, 0x5026, 0x5238, 0x52f8, 0x5377, 0x5708, - 0x62f3, 0x6372, 0x6b0a, 0x6dc3, 0x7737, 0x53a5, 0x7357, 0x8568, 0x8e76, 0x95d5, 0x673a, 0x6ac3, 0x6f70, 0x8a6d, 0x8ecc, 0x994b, - 0xf906, 0x6677, 0x6b78, 0x8cb4, 0x9b3c, 0xf907, 0x53eb, 0x572d, 0x594e, 0x63c6, 0x69fb, 0x73ea, 0x7845, 0x7aba, 0x7ac5, 0x7cfe, - 0x8475, 0x898f, 0x8d73, 0x9035, 0x95a8, 0x52fb, 0x5747, 0x7547, 0x7b60, 0x83cc, 0x921e, 0xf908, 0x6a58, 0x514b, 0x524b, 0x5287, - 0x621f, 0x68d8, 0x6975, 0x9699, 0x50c5, 0x52a4, 0x52e4, 0x61c3, 0x65a4, 0x6839, 0x69ff, 0x747e, 0x7b4b, 0x82b9, 0x83eb, 0x89b2, - 0x8b39, 0x8fd1, 0x9949, 0xf909, 0x4eca, 0x5997, 0x64d2, 0x6611, 0x6a8e, 0x7434, 0x7981, 0x79bd, 0x82a9, 0x887e, 0x887f, 0x895f, - 0xf90a, 0x9326, 0x4f0b, 0x53ca, 0x6025, 0x6271, 0x6c72, 0x7d1a, 0x7d66, 0x4e98, 0x5162, 0x77dc, 0x80af, 0x4f01, 0x4f0e, 0x5176, - 0x5180, 0x55dc, 0x5668, 0x573b, 0x57fa, 0x57fc, 0x5914, 0x5947, 0x5993, 0x5bc4, 0x5c90, 0x5d0e, 0x5df1, 0x5e7e, 0x5fcc, 0x6280, - 0x65d7, 0x65e3, 0x671e, 0x671f, 0x675e, 0x68cb, 0x68c4, 0x6a5f, 0x6b3a, 0x6c23, 0x6c7d, 0x6c82, 0x6dc7, 0x7398, 0x7426, 0x742a, - 0x7482, 0x74a3, 0x7578, 0x757f, 0x7881, 0x78ef, 0x7941, 0x7947, 0x7948, 0x797a, 0x7b95, 0x7d00, 0x7dba, 0x7f88, 0x8006, 0x802d, - 0x808c, 0x8a18, 0x8b4f, 0x8c48, 0x8d77, 0x9321, 0x9324, 0x98e2, 0x9951, 0x9a0e, 0x9a0f, 0x9a65, 0x9e92, 0x7dca, 0x4f76, 0x5409, - 0x62ee, 0x6854, 0x91d1, 0x55ab, 0x513a, 0xf90b, 0xf90c, 0x5a1c, 0x61e6, 0xf90d, 0x62cf, 0x62ff, 0xf90e, 0xf90f, 0xf910, 0xf911, - 0xf912, 0xf913, 0x90a3, 0xf914, 0xf915, 0xf916, 0xf917, 0xf918, 0x8afe, 0xf919, 0xf91a, 0xf91b, 0xf91c, 0x6696, 0xf91d, 0x7156, - 0xf91e, 0xf91f, 0x96e3, 0xf920, 0x634f, 0x637a, 0x5357, 0xf921, 0x678f, 0x6960, 0x6e73, 0xf922, 0x7537, 0xf923, 0xf924, 0xf925, - 0x7d0d, 0xf926, 0xf927, 0x8872, 0x56ca, 0x5a18, 0xf928, 0xf929, 0xf92a, 0xf92b, 0xf92c, 0x4e43, 0xf92d, 0x5167, 0x5948, 0x67f0, - 0x8010, 0xf92e, 0x5973, 0x5e74, 0x649a, 0x79ca, 0x5ff5, 0x606c, 0x62c8, 0x637b, 0x5be7, 0x5bd7, 0x52aa, 0xf92f, 0x5974, 0x5f29, - 0x6012, 0xf930, 0xf931, 0xf932, 0x7459, 0xf933, 0xf934, 0xf935, 0xf936, 0xf937, 0xf938, 0x99d1, 0xf939, 0xf93a, 0xf93b, 0xf93c, - 0xf93d, 0xf93e, 0xf93f, 0xf940, 0xf941, 0xf942, 0xf943, 0x6fc3, 0xf944, 0xf945, 0x81bf, 0x8fb2, 0x60f1, 0xf946, 0xf947, 0x8166, - 0xf948, 0xf949, 0x5c3f, 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e, 0xf94f, 0xf950, 0xf951, 0x5ae9, 0x8a25, 0x677b, 0x7d10, 0xf952, - 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0x80fd, 0xf958, 0xf959, 0x5c3c, 0x6ce5, 0x533f, 0x6eba, 0x591a, 0x8336, 0x4e39, 0x4eb6, - 0x4f46, 0x55ae, 0x5718, 0x58c7, 0x5f56, 0x65b7, 0x65e6, 0x6a80, 0x6bb5, 0x6e4d, 0x77ed, 0x7aef, 0x7c1e, 0x7dde, 0x86cb, 0x8892, - 0x9132, 0x935b, 0x64bb, 0x6fbe, 0x737a, 0x75b8, 0x9054, 0x5556, 0x574d, 0x61ba, 0x64d4, 0x66c7, 0x6de1, 0x6e5b, 0x6f6d, 0x6fb9, - 0x75f0, 0x8043, 0x81bd, 0x8541, 0x8983, 0x8ac7, 0x8b5a, 0x931f, 0x6c93, 0x7553, 0x7b54, 0x8e0f, 0x905d, 0x5510, 0x5802, 0x5858, - 0x5e62, 0x6207, 0x649e, 0x68e0, 0x7576, 0x7cd6, 0x87b3, 0x9ee8, 0x4ee3, 0x5788, 0x576e, 0x5927, 0x5c0d, 0x5cb1, 0x5e36, 0x5f85, - 0x6234, 0x64e1, 0x73b3, 0x81fa, 0x888b, 0x8cb8, 0x968a, 0x9edb, 0x5b85, 0x5fb7, 0x60b3, 0x5012, 0x5200, 0x5230, 0x5716, 0x5835, - 0x5857, 0x5c0e, 0x5c60, 0x5cf6, 0x5d8b, 0x5ea6, 0x5f92, 0x60bc, 0x6311, 0x6389, 0x6417, 0x6843, 0x68f9, 0x6ac2, 0x6dd8, 0x6e21, - 0x6ed4, 0x6fe4, 0x71fe, 0x76dc, 0x7779, 0x79b1, 0x7a3b, 0x8404, 0x89a9, 0x8ced, 0x8df3, 0x8e48, 0x9003, 0x9014, 0x9053, 0x90fd, - 0x934d, 0x9676, 0x97dc, 0x6bd2, 0x7006, 0x7258, 0x72a2, 0x7368, 0x7763, 0x79bf, 0x7be4, 0x7e9b, 0x8b80, 0x58a9, 0x60c7, 0x6566, - 0x65fd, 0x66be, 0x6c8c, 0x711e, 0x71c9, 0x8c5a, 0x9813, 0x4e6d, 0x7a81, 0x4edd, 0x51ac, 0x51cd, 0x52d5, 0x540c, 0x61a7, 0x6771, - 0x6850, 0x68df, 0x6d1e, 0x6f7c, 0x75bc, 0x77b3, 0x7ae5, 0x80f4, 0x8463, 0x9285, 0x515c, 0x6597, 0x675c, 0x6793, 0x75d8, 0x7ac7, - 0x8373, 0xf95a, 0x8c46, 0x9017, 0x982d, 0x5c6f, 0x81c0, 0x829a, 0x9041, 0x906f, 0x920d, 0x5f97, 0x5d9d, 0x6a59, 0x71c8, 0x767b, - 0x7b49, 0x85e4, 0x8b04, 0x9127, 0x9a30, 0x5587, 0x61f6, 0xf95b, 0x7669, 0x7f85, 0x863f, 0x87ba, 0x88f8, 0x908f, 0xf95c, 0x6d1b, - 0x70d9, 0x73de, 0x7d61, 0x843d, 0xf95d, 0x916a, 0x99f1, 0xf95e, 0x4e82, 0x5375, 0x6b04, 0x6b12, 0x703e, 0x721b, 0x862d, 0x9e1e, - 0x524c, 0x8fa3, 0x5d50, 0x64e5, 0x652c, 0x6b16, 0x6feb, 0x7c43, 0x7e9c, 0x85cd, 0x8964, 0x89bd, 0x62c9, 0x81d8, 0x881f, 0x5eca, - 0x6717, 0x6d6a, 0x72fc, 0x7405, 0x746f, 0x8782, 0x90de, 0x4f86, 0x5d0d, 0x5fa0, 0x840a, 0x51b7, 0x63a0, 0x7565, 0x4eae, 0x5006, - 0x5169, 0x51c9, 0x6881, 0x6a11, 0x7cae, 0x7cb1, 0x7ce7, 0x826f, 0x8ad2, 0x8f1b, 0x91cf, 0x4fb6, 0x5137, 0x52f5, 0x5442, 0x5eec, - 0x616e, 0x623e, 0x65c5, 0x6ada, 0x6ffe, 0x792a, 0x85dc, 0x8823, 0x95ad, 0x9a62, 0x9a6a, 0x9e97, 0x9ece, 0x529b, 0x66c6, 0x6b77, - 0x701d, 0x792b, 0x8f62, 0x9742, 0x6190, 0x6200, 0x6523, 0x6f23, 0x7149, 0x7489, 0x7df4, 0x806f, 0x84ee, 0x8f26, 0x9023, 0x934a, - 0x51bd, 0x5217, 0x52a3, 0x6d0c, 0x70c8, 0x88c2, 0x5ec9, 0x6582, 0x6bae, 0x6fc2, 0x7c3e, 0x7375, 0x4ee4, 0x4f36, 0x56f9, 0xf95f, - 0x5cba, 0x5dba, 0x601c, 0x73b2, 0x7b2d, 0x7f9a, 0x7fce, 0x8046, 0x901e, 0x9234, 0x96f6, 0x9748, 0x9818, 0x9f61, 0x4f8b, 0x6fa7, - 0x79ae, 0x91b4, 0x96b7, 0x52de, 0xf960, 0x6488, 0x64c4, 0x6ad3, 0x6f5e, 0x7018, 0x7210, 0x76e7, 0x8001, 0x8606, 0x865c, 0x8def, - 0x8f05, 0x9732, 0x9b6f, 0x9dfa, 0x9e75, 0x788c, 0x797f, 0x7da0, 0x83c9, 0x9304, 0x9e7f, 0x9e93, 0x8ad6, 0x58df, 0x5f04, 0x6727, - 0x7027, 0x74cf, 0x7c60, 0x807e, 0x5121, 0x7028, 0x7262, 0x78ca, 0x8cc2, 0x8cda, 0x8cf4, 0x96f7, 0x4e86, 0x50da, 0x5bee, 0x5ed6, - 0x6599, 0x71ce, 0x7642, 0x77ad, 0x804a, 0x84fc, 0x907c, 0x9b27, 0x9f8d, 0x58d8, 0x5a41, 0x5c62, 0x6a13, 0x6dda, 0x6f0f, 0x763b, - 0x7d2f, 0x7e37, 0x851e, 0x8938, 0x93e4, 0x964b, 0x5289, 0x65d2, 0x67f3, 0x69b4, 0x6d41, 0x6e9c, 0x700f, 0x7409, 0x7460, 0x7559, - 0x7624, 0x786b, 0x8b2c, 0x985e, 0x516d, 0x622e, 0x9678, 0x4f96, 0x502b, 0x5d19, 0x6dea, 0x7db8, 0x8f2a, 0x5f8b, 0x6144, 0x6817, - 0xf961, 0x9686, 0x52d2, 0x808b, 0x51dc, 0x51cc, 0x695e, 0x7a1c, 0x7dbe, 0x83f1, 0x9675, 0x4fda, 0x5229, 0x5398, 0x540f, 0x550e, - 0x5c65, 0x60a7, 0x674e, 0x68a8, 0x6d6c, 0x7281, 0x72f8, 0x7406, 0x7483, 0xf962, 0x75e2, 0x7c6c, 0x7f79, 0x7fb8, 0x8389, 0x88cf, - 0x88e1, 0x91cc, 0x91d0, 0x96e2, 0x9bc9, 0x541d, 0x6f7e, 0x71d0, 0x7498, 0x85fa, 0x8eaa, 0x96a3, 0x9c57, 0x9e9f, 0x6797, 0x6dcb, - 0x7433, 0x81e8, 0x9716, 0x782c, 0x7acb, 0x7b20, 0x7c92, 0x6469, 0x746a, 0x75f2, 0x78bc, 0x78e8, 0x99ac, 0x9b54, 0x9ebb, 0x5bde, - 0x5e55, 0x6f20, 0x819c, 0x83ab, 0x9088, 0x4e07, 0x534d, 0x5a29, 0x5dd2, 0x5f4e, 0x6162, 0x633d, 0x6669, 0x66fc, 0x6eff, 0x6f2b, - 0x7063, 0x779e, 0x842c, 0x8513, 0x883b, 0x8f13, 0x9945, 0x9c3b, 0x551c, 0x62b9, 0x672b, 0x6cab, 0x8309, 0x896a, 0x977a, 0x4ea1, - 0x5984, 0x5fd8, 0x5fd9, 0x671b, 0x7db2, 0x7f54, 0x8292, 0x832b, 0x83bd, 0x8f1e, 0x9099, 0x57cb, 0x59b9, 0x5a92, 0x5bd0, 0x6627, - 0x679a, 0x6885, 0x6bcf, 0x7164, 0x7f75, 0x8cb7, 0x8ce3, 0x9081, 0x9b45, 0x8108, 0x8c8a, 0x964c, 0x9a40, 0x9ea5, 0x5b5f, 0x6c13, - 0x731b, 0x76f2, 0x76df, 0x840c, 0x51aa, 0x8993, 0x514d, 0x5195, 0x52c9, 0x68c9, 0x6c94, 0x7704, 0x7720, 0x7dbf, 0x7dec, 0x9762, - 0x9eb5, 0x6ec5, 0x8511, 0x51a5, 0x540d, 0x547d, 0x660e, 0x669d, 0x6927, 0x6e9f, 0x76bf, 0x7791, 0x8317, 0x84c2, 0x879f, 0x9169, - 0x9298, 0x9cf4, 0x8882, 0x4fae, 0x5192, 0x52df, 0x59c6, 0x5e3d, 0x6155, 0x6478, 0x6479, 0x66ae, 0x67d0, 0x6a21, 0x6bcd, 0x6bdb, - 0x725f, 0x7261, 0x7441, 0x7738, 0x77db, 0x8017, 0x82bc, 0x8305, 0x8b00, 0x8b28, 0x8c8c, 0x6728, 0x6c90, 0x7267, 0x76ee, 0x7766, - 0x7a46, 0x9da9, 0x6b7f, 0x6c92, 0x5922, 0x6726, 0x8499, 0x536f, 0x5893, 0x5999, 0x5edf, 0x63cf, 0x6634, 0x6773, 0x6e3a, 0x732b, - 0x7ad7, 0x82d7, 0x9328, 0x52d9, 0x5deb, 0x61ae, 0x61cb, 0x620a, 0x62c7, 0x64ab, 0x65e0, 0x6959, 0x6b66, 0x6bcb, 0x7121, 0x73f7, - 0x755d, 0x7e46, 0x821e, 0x8302, 0x856a, 0x8aa3, 0x8cbf, 0x9727, 0x9d61, 0x58a8, 0x9ed8, 0x5011, 0x520e, 0x543b, 0x554f, 0x6587, - 0x6c76, 0x7d0a, 0x7d0b, 0x805e, 0x868a, 0x9580, 0x96ef, 0x52ff, 0x6c95, 0x7269, 0x5473, 0x5a9a, 0x5c3e, 0x5d4b, 0x5f4c, 0x5fae, - 0x672a, 0x68b6, 0x6963, 0x6e3c, 0x6e44, 0x7709, 0x7c73, 0x7f8e, 0x8587, 0x8b0e, 0x8ff7, 0x9761, 0x9ef4, 0x5cb7, 0x60b6, 0x610d, - 0x61ab, 0x654f, 0x65fb, 0x65fc, 0x6c11, 0x6cef, 0x739f, 0x73c9, 0x7de1, 0x9594, 0x5bc6, 0x871c, 0x8b10, 0x525d, 0x535a, 0x62cd, - 0x640f, 0x64b2, 0x6734, 0x6a38, 0x6cca, 0x73c0, 0x749e, 0x7b94, 0x7c95, 0x7e1b, 0x818a, 0x8236, 0x8584, 0x8feb, 0x96f9, 0x99c1, - 0x4f34, 0x534a, 0x53cd, 0x53db, 0x62cc, 0x642c, 0x6500, 0x6591, 0x69c3, 0x6cee, 0x6f58, 0x73ed, 0x7554, 0x7622, 0x76e4, 0x76fc, - 0x78d0, 0x78fb, 0x792c, 0x7d46, 0x822c, 0x87e0, 0x8fd4, 0x9812, 0x98ef, 0x52c3, 0x62d4, 0x64a5, 0x6e24, 0x6f51, 0x767c, 0x8dcb, - 0x91b1, 0x9262, 0x9aee, 0x9b43, 0x5023, 0x508d, 0x574a, 0x59a8, 0x5c28, 0x5e47, 0x5f77, 0x623f, 0x653e, 0x65b9, 0x65c1, 0x6609, - 0x678b, 0x699c, 0x6ec2, 0x78c5, 0x7d21, 0x80aa, 0x8180, 0x822b, 0x82b3, 0x84a1, 0x868c, 0x8a2a, 0x8b17, 0x90a6, 0x9632, 0x9f90, - 0x500d, 0x4ff3, 0xf963, 0x57f9, 0x5f98, 0x62dc, 0x6392, 0x676f, 0x6e43, 0x7119, 0x76c3, 0x80cc, 0x80da, 0x88f4, 0x88f5, 0x8919, - 0x8ce0, 0x8f29, 0x914d, 0x966a, 0x4f2f, 0x4f70, 0x5e1b, 0x67cf, 0x6822, 0x767d, 0x767e, 0x9b44, 0x5e61, 0x6a0a, 0x7169, 0x71d4, - 0x756a, 0xf964, 0x7e41, 0x8543, 0x85e9, 0x98dc, 0x4f10, 0x7b4f, 0x7f70, 0x95a5, 0x51e1, 0x5e06, 0x68b5, 0x6c3e, 0x6c4e, 0x6cdb, - 0x72af, 0x7bc4, 0x8303, 0x6cd5, 0x743a, 0x50fb, 0x5288, 0x58c1, 0x64d8, 0x6a97, 0x74a7, 0x7656, 0x78a7, 0x8617, 0x95e2, 0x9739, - 0xf965, 0x535e, 0x5f01, 0x8b8a, 0x8fa8, 0x8faf, 0x908a, 0x5225, 0x77a5, 0x9c49, 0x9f08, 0x4e19, 0x5002, 0x5175, 0x5c5b, 0x5e77, - 0x661e, 0x663a, 0x67c4, 0x68c5, 0x70b3, 0x7501, 0x75c5, 0x79c9, 0x7add, 0x8f27, 0x9920, 0x9a08, 0x4fdd, 0x5821, 0x5831, 0x5bf6, - 0x666e, 0x6b65, 0x6d11, 0x6e7a, 0x6f7d, 0x73e4, 0x752b, 0x83e9, 0x88dc, 0x8913, 0x8b5c, 0x8f14, 0x4f0f, 0x50d5, 0x5310, 0x535c, - 0x5b93, 0x5fa9, 0x670d, 0x798f, 0x8179, 0x832f, 0x8514, 0x8907, 0x8986, 0x8f39, 0x8f3b, 0x99a5, 0x9c12, 0x672c, 0x4e76, 0x4ff8, - 0x5949, 0x5c01, 0x5cef, 0x5cf0, 0x6367, 0x68d2, 0x70fd, 0x71a2, 0x742b, 0x7e2b, 0x84ec, 0x8702, 0x9022, 0x92d2, 0x9cf3, 0x4e0d, - 0x4ed8, 0x4fef, 0x5085, 0x5256, 0x526f, 0x5426, 0x5490, 0x57e0, 0x592b, 0x5a66, 0x5b5a, 0x5b75, 0x5bcc, 0x5e9c, 0xf966, 0x6276, - 0x6577, 0x65a7, 0x6d6e, 0x6ea5, 0x7236, 0x7b26, 0x7c3f, 0x7f36, 0x8150, 0x8151, 0x819a, 0x8240, 0x8299, 0x83a9, 0x8a03, 0x8ca0, - 0x8ce6, 0x8cfb, 0x8d74, 0x8dba, 0x90e8, 0x91dc, 0x961c, 0x9644, 0x99d9, 0x9ce7, 0x5317, 0x5206, 0x5429, 0x5674, 0x58b3, 0x5954, - 0x596e, 0x5fff, 0x61a4, 0x626e, 0x6610, 0x6c7e, 0x711a, 0x76c6, 0x7c89, 0x7cde, 0x7d1b, 0x82ac, 0x8cc1, 0x96f0, 0xf967, 0x4f5b, - 0x5f17, 0x5f7f, 0x62c2, 0x5d29, 0x670b, 0x68da, 0x787c, 0x7e43, 0x9d6c, 0x4e15, 0x5099, 0x5315, 0x532a, 0x5351, 0x5983, 0x5a62, - 0x5e87, 0x60b2, 0x618a, 0x6249, 0x6279, 0x6590, 0x6787, 0x69a7, 0x6bd4, 0x6bd6, 0x6bd7, 0x6bd8, 0x6cb8, 0xf968, 0x7435, 0x75fa, - 0x7812, 0x7891, 0x79d5, 0x79d8, 0x7c83, 0x7dcb, 0x7fe1, 0x80a5, 0x813e, 0x81c2, 0x83f2, 0x871a, 0x88e8, 0x8ab9, 0x8b6c, 0x8cbb, - 0x9119, 0x975e, 0x98db, 0x9f3b, 0x56ac, 0x5b2a, 0x5f6c, 0x658c, 0x6ab3, 0x6baf, 0x6d5c, 0x6ff1, 0x7015, 0x725d, 0x73ad, 0x8ca7, - 0x8cd3, 0x983b, 0x6191, 0x6c37, 0x8058, 0x9a01, 0x4e4d, 0x4e8b, 0x4e9b, 0x4ed5, 0x4f3a, 0x4f3c, 0x4f7f, 0x4fdf, 0x50ff, 0x53f2, - 0x53f8, 0x5506, 0x55e3, 0x56db, 0x58eb, 0x5962, 0x5a11, 0x5beb, 0x5bfa, 0x5c04, 0x5df3, 0x5e2b, 0x5f99, 0x601d, 0x6368, 0x659c, - 0x65af, 0x67f6, 0x67fb, 0x68ad, 0x6b7b, 0x6c99, 0x6cd7, 0x6e23, 0x7009, 0x7345, 0x7802, 0x793e, 0x7940, 0x7960, 0x79c1, 0x7be9, - 0x7d17, 0x7d72, 0x8086, 0x820d, 0x838e, 0x84d1, 0x86c7, 0x88df, 0x8a50, 0x8a5e, 0x8b1d, 0x8cdc, 0x8d66, 0x8fad, 0x90aa, 0x98fc, - 0x99df, 0x9e9d, 0x524a, 0xf969, 0x6714, 0xf96a, 0x5098, 0x522a, 0x5c71, 0x6563, 0x6c55, 0x73ca, 0x7523, 0x759d, 0x7b97, 0x849c, - 0x9178, 0x9730, 0x4e77, 0x6492, 0x6bba, 0x715e, 0x85a9, 0x4e09, 0xf96b, 0x6749, 0x68ee, 0x6e17, 0x829f, 0x8518, 0x886b, 0x63f7, - 0x6f81, 0x9212, 0x98af, 0x4e0a, 0x50b7, 0x50cf, 0x511f, 0x5546, 0x55aa, 0x5617, 0x5b40, 0x5c19, 0x5ce0, 0x5e38, 0x5e8a, 0x5ea0, - 0x5ec2, 0x60f3, 0x6851, 0x6a61, 0x6e58, 0x723d, 0x7240, 0x72c0, 0x76f8, 0x7965, 0x7bb1, 0x7fd4, 0x88f3, 0x89f4, 0x8a73, 0x8c61, - 0x8cde, 0x971c, 0x585e, 0x74bd, 0x8cfd, 0x55c7, 0xf96c, 0x7a61, 0x7d22, 0x8272, 0x7272, 0x751f, 0x7525, 0xf96d, 0x7b19, 0x5885, - 0x58fb, 0x5dbc, 0x5e8f, 0x5eb6, 0x5f90, 0x6055, 0x6292, 0x637f, 0x654d, 0x6691, 0x66d9, 0x66f8, 0x6816, 0x68f2, 0x7280, 0x745e, - 0x7b6e, 0x7d6e, 0x7dd6, 0x7f72, 0x80e5, 0x8212, 0x85af, 0x897f, 0x8a93, 0x901d, 0x92e4, 0x9ecd, 0x9f20, 0x5915, 0x596d, 0x5e2d, - 0x60dc, 0x6614, 0x6673, 0x6790, 0x6c50, 0x6dc5, 0x6f5f, 0x77f3, 0x78a9, 0x84c6, 0x91cb, 0x932b, 0x4ed9, 0x50ca, 0x5148, 0x5584, - 0x5b0b, 0x5ba3, 0x6247, 0x657e, 0x65cb, 0x6e32, 0x717d, 0x7401, 0x7444, 0x7487, 0x74bf, 0x766c, 0x79aa, 0x7dda, 0x7e55, 0x7fa8, - 0x817a, 0x81b3, 0x8239, 0x861a, 0x87ec, 0x8a75, 0x8de3, 0x9078, 0x9291, 0x9425, 0x994d, 0x9bae, 0x5368, 0x5c51, 0x6954, 0x6cc4, - 0x6d29, 0x6e2b, 0x820c, 0x859b, 0x893b, 0x8a2d, 0x8aaa, 0x96ea, 0x9f67, 0x5261, 0x66b9, 0x6bb2, 0x7e96, 0x87fe, 0x8d0d, 0x9583, - 0x965d, 0x651d, 0x6d89, 0x71ee, 0xf96e, 0x57ce, 0x59d3, 0x5bac, 0x6027, 0x60fa, 0x6210, 0x661f, 0x665f, 0x7329, 0x73f9, 0x76db, - 0x7701, 0x7b6c, 0x8056, 0x8072, 0x8165, 0x8aa0, 0x9192, 0x4e16, 0x52e2, 0x6b72, 0x6d17, 0x7a05, 0x7b39, 0x7d30, 0xf96f, 0x8cb0, - 0x53ec, 0x562f, 0x5851, 0x5bb5, 0x5c0f, 0x5c11, 0x5de2, 0x6240, 0x6383, 0x6414, 0x662d, 0x68b3, 0x6cbc, 0x6d88, 0x6eaf, 0x701f, - 0x70a4, 0x71d2, 0x7526, 0x758f, 0x758e, 0x7619, 0x7b11, 0x7be0, 0x7c2b, 0x7d20, 0x7d39, 0x852c, 0x856d, 0x8607, 0x8a34, 0x900d, - 0x9061, 0x90b5, 0x92b7, 0x97f6, 0x9a37, 0x4fd7, 0x5c6c, 0x675f, 0x6d91, 0x7c9f, 0x7e8c, 0x8b16, 0x8d16, 0x901f, 0x5b6b, 0x5dfd, - 0x640d, 0x84c0, 0x905c, 0x98e1, 0x7387, 0x5b8b, 0x609a, 0x677e, 0x6dde, 0x8a1f, 0x8aa6, 0x9001, 0x980c, 0x5237, 0xf970, 0x7051, - 0x788e, 0x9396, 0x8870, 0x91d7, 0x4fee, 0x53d7, 0x55fd, 0x56da, 0x5782, 0x58fd, 0x5ac2, 0x5b88, 0x5cab, 0x5cc0, 0x5e25, 0x6101, - 0x620d, 0x624b, 0x6388, 0x641c, 0x6536, 0x6578, 0x6a39, 0x6b8a, 0x6c34, 0x6d19, 0x6f31, 0x71e7, 0x72e9, 0x7378, 0x7407, 0x74b2, - 0x7626, 0x7761, 0x79c0, 0x7a57, 0x7aea, 0x7cb9, 0x7d8f, 0x7dac, 0x7e61, 0x7f9e, 0x8129, 0x8331, 0x8490, 0x84da, 0x85ea, 0x8896, - 0x8ab0, 0x8b90, 0x8f38, 0x9042, 0x9083, 0x916c, 0x9296, 0x92b9, 0x968b, 0x96a7, 0x96a8, 0x96d6, 0x9700, 0x9808, 0x9996, 0x9ad3, - 0x9b1a, 0x53d4, 0x587e, 0x5919, 0x5b70, 0x5bbf, 0x6dd1, 0x6f5a, 0x719f, 0x7421, 0x74b9, 0x8085, 0x83fd, 0x5de1, 0x5f87, 0x5faa, - 0x6042, 0x65ec, 0x6812, 0x696f, 0x6a53, 0x6b89, 0x6d35, 0x6df3, 0x73e3, 0x76fe, 0x77ac, 0x7b4d, 0x7d14, 0x8123, 0x821c, 0x8340, - 0x84f4, 0x8563, 0x8a62, 0x8ac4, 0x9187, 0x931e, 0x9806, 0x99b4, 0x620c, 0x8853, 0x8ff0, 0x9265, 0x5d07, 0x5d27, 0x5d69, 0x745f, - 0x819d, 0x8768, 0x6fd5, 0x62fe, 0x7fd2, 0x8936, 0x8972, 0x4e1e, 0x4e58, 0x50e7, 0x52dd, 0x5347, 0x627f, 0x6607, 0x7e69, 0x8805, - 0x965e, 0x4f8d, 0x5319, 0x5636, 0x59cb, 0x5aa4, 0x5c38, 0x5c4e, 0x5c4d, 0x5e02, 0x5f11, 0x6043, 0x65bd, 0x662f, 0x6642, 0x67be, - 0x67f4, 0x731c, 0x77e2, 0x793a, 0x7fc5, 0x8494, 0x84cd, 0x8996, 0x8a66, 0x8a69, 0x8ae1, 0x8c55, 0x8c7a, 0x57f4, 0x5bd4, 0x5f0f, - 0x606f, 0x62ed, 0x690d, 0x6b96, 0x6e5c, 0x7184, 0x7bd2, 0x8755, 0x8b58, 0x8efe, 0x98df, 0x98fe, 0x4f38, 0x4f81, 0x4fe1, 0x547b, - 0x5a20, 0x5bb8, 0x613c, 0x65b0, 0x6668, 0x71fc, 0x7533, 0x795e, 0x7d33, 0x814e, 0x81e3, 0x8398, 0x85aa, 0x85ce, 0x8703, 0x8a0a, - 0x8eab, 0x8f9b, 0xf971, 0x8fc5, 0x5931, 0x5ba4, 0x5be6, 0x6089, 0x5be9, 0x5c0b, 0x5fc3, 0x6c81, 0xf972, 0x6df1, 0x700b, 0x751a, - 0x82af, 0x8af6, 0x4ec0, 0x5341, 0xf973, 0x96d9, 0x6c0f, 0x4e9e, 0x4fc4, 0x5152, 0x555e, 0x5a25, 0x5ce8, 0x6211, 0x7259, 0x82bd, - 0x83aa, 0x86fe, 0x8859, 0x8a1d, 0x963f, 0x96c5, 0x9913, 0x9d09, 0x9d5d, 0x580a, 0x5cb3, 0x5dbd, 0x5e44, 0x60e1, 0x6115, 0x63e1, - 0x6a02, 0x6e25, 0x9102, 0x9354, 0x984e, 0x9c10, 0x9f77, 0x5b89, 0x5cb8, 0x6309, 0x664f, 0x6848, 0x773c, 0x96c1, 0x978d, 0x9854, - 0x9b9f, 0x65a1, 0x8b01, 0x8ecb, 0x95bc, 0x5535, 0x5ca9, 0x5dd6, 0x5eb5, 0x6697, 0x764c, 0x83f4, 0x95c7, 0x58d3, 0x62bc, 0x72ce, - 0x9d28, 0x4ef0, 0x592e, 0x600f, 0x663b, 0x6b83, 0x79e7, 0x9d26, 0x5393, 0x54c0, 0x57c3, 0x5d16, 0x611b, 0x66d6, 0x6daf, 0x788d, - 0x827e, 0x9698, 0x9744, 0x5384, 0x627c, 0x6396, 0x6db2, 0x7e0a, 0x814b, 0x984d, 0x6afb, 0x7f4c, 0x9daf, 0x9e1a, 0x4e5f, 0x503b, - 0x51b6, 0x591c, 0x60f9, 0x63f6, 0x6930, 0x723a, 0x8036, 0xf974, 0x91ce, 0x5f31, 0xf975, 0xf976, 0x7d04, 0x82e5, 0x846f, 0x84bb, - 0x85e5, 0x8e8d, 0xf977, 0x4f6f, 0xf978, 0xf979, 0x58e4, 0x5b43, 0x6059, 0x63da, 0x6518, 0x656d, 0x6698, 0xf97a, 0x694a, 0x6a23, - 0x6d0b, 0x7001, 0x716c, 0x75d2, 0x760d, 0x79b3, 0x7a70, 0xf97b, 0x7f8a, 0xf97c, 0x8944, 0xf97d, 0x8b93, 0x91c0, 0x967d, 0xf97e, - 0x990a, 0x5704, 0x5fa1, 0x65bc, 0x6f01, 0x7600, 0x79a6, 0x8a9e, 0x99ad, 0x9b5a, 0x9f6c, 0x5104, 0x61b6, 0x6291, 0x6a8d, 0x81c6, - 0x5043, 0x5830, 0x5f66, 0x7109, 0x8a00, 0x8afa, 0x5b7c, 0x8616, 0x4ffa, 0x513c, 0x56b4, 0x5944, 0x63a9, 0x6df9, 0x5daa, 0x696d, - 0x5186, 0x4e88, 0x4f59, 0xf97f, 0xf980, 0xf981, 0x5982, 0xf982, 0xf983, 0x6b5f, 0x6c5d, 0xf984, 0x74b5, 0x7916, 0xf985, 0x8207, - 0x8245, 0x8339, 0x8f3f, 0x8f5d, 0xf986, 0x9918, 0xf987, 0xf988, 0xf989, 0x4ea6, 0xf98a, 0x57df, 0x5f79, 0x6613, 0xf98b, 0xf98c, - 0x75ab, 0x7e79, 0x8b6f, 0xf98d, 0x9006, 0x9a5b, 0x56a5, 0x5827, 0x59f8, 0x5a1f, 0x5bb4, 0xf98e, 0x5ef6, 0xf98f, 0xf990, 0x6350, - 0x633b, 0xf991, 0x693d, 0x6c87, 0x6cbf, 0x6d8e, 0x6d93, 0x6df5, 0x6f14, 0xf992, 0x70df, 0x7136, 0x7159, 0xf993, 0x71c3, 0x71d5, - 0xf994, 0x784f, 0x786f, 0xf995, 0x7b75, 0x7de3, 0xf996, 0x7e2f, 0xf997, 0x884d, 0x8edf, 0xf998, 0xf999, 0xf99a, 0x925b, 0xf99b, - 0x9cf6, 0xf99c, 0xf99d, 0xf99e, 0x6085, 0x6d85, 0xf99f, 0x71b1, 0xf9a0, 0xf9a1, 0x95b1, 0x53ad, 0xf9a2, 0xf9a3, 0xf9a4, 0x67d3, - 0xf9a5, 0x708e, 0x7130, 0x7430, 0x8276, 0x82d2, 0xf9a6, 0x95bb, 0x9ae5, 0x9e7d, 0x66c4, 0xf9a7, 0x71c1, 0x8449, 0xf9a8, 0xf9a9, - 0x584b, 0xf9aa, 0xf9ab, 0x5db8, 0x5f71, 0xf9ac, 0x6620, 0x668e, 0x6979, 0x69ae, 0x6c38, 0x6cf3, 0x6e36, 0x6f41, 0x6fda, 0x701b, - 0x702f, 0x7150, 0x71df, 0x7370, 0xf9ad, 0x745b, 0xf9ae, 0x74d4, 0x76c8, 0x7a4e, 0x7e93, 0xf9af, 0xf9b0, 0x82f1, 0x8a60, 0x8fce, - 0xf9b1, 0x9348, 0xf9b2, 0x9719, 0xf9b3, 0xf9b4, 0x4e42, 0x502a, 0xf9b5, 0x5208, 0x53e1, 0x66f3, 0x6c6d, 0x6fca, 0x730a, 0x777f, - 0x7a62, 0x82ae, 0x85dd, 0x8602, 0xf9b6, 0x88d4, 0x8a63, 0x8b7d, 0x8c6b, 0xf9b7, 0x92b3, 0xf9b8, 0x9713, 0x9810, 0x4e94, 0x4f0d, - 0x4fc9, 0x50b2, 0x5348, 0x543e, 0x5433, 0x55da, 0x5862, 0x58ba, 0x5967, 0x5a1b, 0x5be4, 0x609f, 0xf9b9, 0x61ca, 0x6556, 0x65ff, - 0x6664, 0x68a7, 0x6c5a, 0x6fb3, 0x70cf, 0x71ac, 0x7352, 0x7b7d, 0x8708, 0x8aa4, 0x9c32, 0x9f07, 0x5c4b, 0x6c83, 0x7344, 0x7389, - 0x923a, 0x6eab, 0x7465, 0x761f, 0x7a69, 0x7e15, 0x860a, 0x5140, 0x58c5, 0x64c1, 0x74ee, 0x7515, 0x7670, 0x7fc1, 0x9095, 0x96cd, - 0x9954, 0x6e26, 0x74e6, 0x7aa9, 0x7aaa, 0x81e5, 0x86d9, 0x8778, 0x8a1b, 0x5a49, 0x5b8c, 0x5b9b, 0x68a1, 0x6900, 0x6d63, 0x73a9, - 0x7413, 0x742c, 0x7897, 0x7de9, 0x7feb, 0x8118, 0x8155, 0x839e, 0x8c4c, 0x962e, 0x9811, 0x66f0, 0x5f80, 0x65fa, 0x6789, 0x6c6a, - 0x738b, 0x502d, 0x5a03, 0x6b6a, 0x77ee, 0x5916, 0x5d6c, 0x5dcd, 0x7325, 0x754f, 0xf9ba, 0xf9bb, 0x50e5, 0x51f9, 0x582f, 0x592d, - 0x5996, 0x59da, 0x5be5, 0xf9bc, 0xf9bd, 0x5da2, 0x62d7, 0x6416, 0x6493, 0x64fe, 0xf9be, 0x66dc, 0xf9bf, 0x6a48, 0xf9c0, 0x71ff, - 0x7464, 0xf9c1, 0x7a88, 0x7aaf, 0x7e47, 0x7e5e, 0x8000, 0x8170, 0xf9c2, 0x87ef, 0x8981, 0x8b20, 0x9059, 0xf9c3, 0x9080, 0x9952, - 0x617e, 0x6b32, 0x6d74, 0x7e1f, 0x8925, 0x8fb1, 0x4fd1, 0x50ad, 0x5197, 0x52c7, 0x57c7, 0x5889, 0x5bb9, 0x5eb8, 0x6142, 0x6995, - 0x6d8c, 0x6e67, 0x6eb6, 0x7194, 0x7462, 0x7528, 0x752c, 0x8073, 0x8338, 0x84c9, 0x8e0a, 0x9394, 0x93de, 0xf9c4, 0x4e8e, 0x4f51, - 0x5076, 0x512a, 0x53c8, 0x53cb, 0x53f3, 0x5b87, 0x5bd3, 0x5c24, 0x611a, 0x6182, 0x65f4, 0x725b, 0x7397, 0x7440, 0x76c2, 0x7950, - 0x7991, 0x79b9, 0x7d06, 0x7fbd, 0x828b, 0x85d5, 0x865e, 0x8fc2, 0x9047, 0x90f5, 0x91ea, 0x9685, 0x96e8, 0x96e9, 0x52d6, 0x5f67, - 0x65ed, 0x6631, 0x682f, 0x715c, 0x7a36, 0x90c1, 0x980a, 0x4e91, 0xf9c5, 0x6a52, 0x6b9e, 0x6f90, 0x7189, 0x8018, 0x82b8, 0x8553, - 0x904b, 0x9695, 0x96f2, 0x97fb, 0x851a, 0x9b31, 0x4e90, 0x718a, 0x96c4, 0x5143, 0x539f, 0x54e1, 0x5713, 0x5712, 0x57a3, 0x5a9b, - 0x5ac4, 0x5bc3, 0x6028, 0x613f, 0x63f4, 0x6c85, 0x6d39, 0x6e72, 0x6e90, 0x7230, 0x733f, 0x7457, 0x82d1, 0x8881, 0x8f45, 0x9060, - 0xf9c6, 0x9662, 0x9858, 0x9d1b, 0x6708, 0x8d8a, 0x925e, 0x4f4d, 0x5049, 0x50de, 0x5371, 0x570d, 0x59d4, 0x5a01, 0x5c09, 0x6170, - 0x6690, 0x6e2d, 0x7232, 0x744b, 0x7def, 0x80c3, 0x840e, 0x8466, 0x853f, 0x875f, 0x885b, 0x8918, 0x8b02, 0x9055, 0x97cb, 0x9b4f, - 0x4e73, 0x4f91, 0x5112, 0x516a, 0xf9c7, 0x552f, 0x55a9, 0x5b7a, 0x5ba5, 0x5e7c, 0x5e7d, 0x5ebe, 0x60a0, 0x60df, 0x6108, 0x6109, - 0x63c4, 0x6538, 0x6709, 0xf9c8, 0x67d4, 0x67da, 0xf9c9, 0x6961, 0x6962, 0x6cb9, 0x6d27, 0xf9ca, 0x6e38, 0xf9cb, 0x6fe1, 0x7336, - 0x7337, 0xf9cc, 0x745c, 0x7531, 0xf9cd, 0x7652, 0xf9ce, 0xf9cf, 0x7dad, 0x81fe, 0x8438, 0x88d5, 0x8a98, 0x8adb, 0x8aed, 0x8e30, - 0x8e42, 0x904a, 0x903e, 0x907a, 0x9149, 0x91c9, 0x936e, 0xf9d0, 0xf9d1, 0x5809, 0xf9d2, 0x6bd3, 0x8089, 0x80b2, 0xf9d3, 0xf9d4, - 0x5141, 0x596b, 0x5c39, 0xf9d5, 0xf9d6, 0x6f64, 0x73a7, 0x80e4, 0x8d07, 0xf9d7, 0x9217, 0x958f, 0xf9d8, 0xf9d9, 0xf9da, 0xf9db, - 0x807f, 0x620e, 0x701c, 0x7d68, 0x878d, 0xf9dc, 0x57a0, 0x6069, 0x6147, 0x6bb7, 0x8abe, 0x9280, 0x96b1, 0x4e59, 0x541f, 0x6deb, - 0x852d, 0x9670, 0x97f3, 0x98ee, 0x63d6, 0x6ce3, 0x9091, 0x51dd, 0x61c9, 0x81ba, 0x9df9, 0x4f9d, 0x501a, 0x5100, 0x5b9c, 0x610f, - 0x61ff, 0x64ec, 0x6905, 0x6bc5, 0x7591, 0x77e3, 0x7fa9, 0x8264, 0x858f, 0x87fb, 0x8863, 0x8abc, 0x8b70, 0x91ab, 0x4e8c, 0x4ee5, - 0x4f0a, 0xf9dd, 0xf9de, 0x5937, 0x59e8, 0xf9df, 0x5df2, 0x5f1b, 0x5f5b, 0x6021, 0xf9e0, 0xf9e1, 0xf9e2, 0xf9e3, 0x723e, 0x73e5, - 0xf9e4, 0x7570, 0x75cd, 0xf9e5, 0x79fb, 0xf9e6, 0x800c, 0x8033, 0x8084, 0x82e1, 0x8351, 0xf9e7, 0xf9e8, 0x8cbd, 0x8cb3, 0x9087, - 0xf9e9, 0xf9ea, 0x98f4, 0x990c, 0xf9eb, 0xf9ec, 0x7037, 0x76ca, 0x7fca, 0x7fcc, 0x7ffc, 0x8b1a, 0x4eba, 0x4ec1, 0x5203, 0x5370, - 0xf9ed, 0x54bd, 0x56e0, 0x59fb, 0x5bc5, 0x5f15, 0x5fcd, 0x6e6e, 0xf9ee, 0xf9ef, 0x7d6a, 0x8335, 0xf9f0, 0x8693, 0x8a8d, 0xf9f1, - 0x976d, 0x9777, 0xf9f2, 0xf9f3, 0x4e00, 0x4f5a, 0x4f7e, 0x58f9, 0x65e5, 0x6ea2, 0x9038, 0x93b0, 0x99b9, 0x4efb, 0x58ec, 0x598a, - 0x59d9, 0x6041, 0xf9f4, 0xf9f5, 0x7a14, 0xf9f6, 0x834f, 0x8cc3, 0x5165, 0x5344, 0xf9f7, 0xf9f8, 0xf9f9, 0x4ecd, 0x5269, 0x5b55, - 0x82bf, 0x4ed4, 0x523a, 0x54a8, 0x59c9, 0x59ff, 0x5b50, 0x5b57, 0x5b5c, 0x6063, 0x6148, 0x6ecb, 0x7099, 0x716e, 0x7386, 0x74f7, - 0x75b5, 0x78c1, 0x7d2b, 0x8005, 0x81ea, 0x8328, 0x8517, 0x85c9, 0x8aee, 0x8cc7, 0x96cc, 0x4f5c, 0x52fa, 0x56bc, 0x65ab, 0x6628, - 0x707c, 0x70b8, 0x7235, 0x7dbd, 0x828d, 0x914c, 0x96c0, 0x9d72, 0x5b71, 0x68e7, 0x6b98, 0x6f7a, 0x76de, 0x5c91, 0x66ab, 0x6f5b, - 0x7bb4, 0x7c2a, 0x8836, 0x96dc, 0x4e08, 0x4ed7, 0x5320, 0x5834, 0x58bb, 0x58ef, 0x596c, 0x5c07, 0x5e33, 0x5e84, 0x5f35, 0x638c, - 0x66b2, 0x6756, 0x6a1f, 0x6aa3, 0x6b0c, 0x6f3f, 0x7246, 0xf9fa, 0x7350, 0x748b, 0x7ae0, 0x7ca7, 0x8178, 0x81df, 0x81e7, 0x838a, - 0x846c, 0x8523, 0x8594, 0x85cf, 0x88dd, 0x8d13, 0x91ac, 0x9577, 0x969c, 0x518d, 0x54c9, 0x5728, 0x5bb0, 0x624d, 0x6750, 0x683d, - 0x6893, 0x6e3d, 0x6ed3, 0x707d, 0x7e21, 0x88c1, 0x8ca1, 0x8f09, 0x9f4b, 0x9f4e, 0x722d, 0x7b8f, 0x8acd, 0x931a, 0x4f47, 0x4f4e, - 0x5132, 0x5480, 0x59d0, 0x5e95, 0x62b5, 0x6775, 0x696e, 0x6a17, 0x6cae, 0x6e1a, 0x72d9, 0x732a, 0x75bd, 0x7bb8, 0x7d35, 0x82e7, - 0x83f9, 0x8457, 0x85f7, 0x8a5b, 0x8caf, 0x8e87, 0x9019, 0x90b8, 0x96ce, 0x9f5f, 0x52e3, 0x540a, 0x5ae1, 0x5bc2, 0x6458, 0x6575, - 0x6ef4, 0x72c4, 0xf9fb, 0x7684, 0x7a4d, 0x7b1b, 0x7c4d, 0x7e3e, 0x7fdf, 0x837b, 0x8b2b, 0x8cca, 0x8d64, 0x8de1, 0x8e5f, 0x8fea, - 0x8ff9, 0x9069, 0x93d1, 0x4f43, 0x4f7a, 0x50b3, 0x5168, 0x5178, 0x524d, 0x526a, 0x5861, 0x587c, 0x5960, 0x5c08, 0x5c55, 0x5edb, - 0x609b, 0x6230, 0x6813, 0x6bbf, 0x6c08, 0x6fb1, 0x714e, 0x7420, 0x7530, 0x7538, 0x7551, 0x7672, 0x7b4c, 0x7b8b, 0x7bad, 0x7bc6, - 0x7e8f, 0x8a6e, 0x8f3e, 0x8f49, 0x923f, 0x9293, 0x9322, 0x942b, 0x96fb, 0x985a, 0x986b, 0x991e, 0x5207, 0x622a, 0x6298, 0x6d59, - 0x7664, 0x7aca, 0x7bc0, 0x7d76, 0x5360, 0x5cbe, 0x5e97, 0x6f38, 0x70b9, 0x7c98, 0x9711, 0x9b8e, 0x9ede, 0x63a5, 0x647a, 0x8776, - 0x4e01, 0x4e95, 0x4ead, 0x505c, 0x5075, 0x5448, 0x59c3, 0x5b9a, 0x5e40, 0x5ead, 0x5ef7, 0x5f81, 0x60c5, 0x633a, 0x653f, 0x6574, - 0x65cc, 0x6676, 0x6678, 0x67fe, 0x6968, 0x6a89, 0x6b63, 0x6c40, 0x6dc0, 0x6de8, 0x6e1f, 0x6e5e, 0x701e, 0x70a1, 0x738e, 0x73fd, - 0x753a, 0x775b, 0x7887, 0x798e, 0x7a0b, 0x7a7d, 0x7cbe, 0x7d8e, 0x8247, 0x8a02, 0x8aea, 0x8c9e, 0x912d, 0x914a, 0x91d8, 0x9266, - 0x92cc, 0x9320, 0x9706, 0x9756, 0x975c, 0x9802, 0x9f0e, 0x5236, 0x5291, 0x557c, 0x5824, 0x5e1d, 0x5f1f, 0x608c, 0x63d0, 0x68af, - 0x6fdf, 0x796d, 0x7b2c, 0x81cd, 0x85ba, 0x88fd, 0x8af8, 0x8e44, 0x918d, 0x9664, 0x969b, 0x973d, 0x984c, 0x9f4a, 0x4fce, 0x5146, - 0x51cb, 0x52a9, 0x5632, 0x5f14, 0x5f6b, 0x63aa, 0x64cd, 0x65e9, 0x6641, 0x66fa, 0x66f9, 0x671d, 0x689d, 0x68d7, 0x69fd, 0x6f15, - 0x6f6e, 0x7167, 0x71e5, 0x722a, 0x74aa, 0x773a, 0x7956, 0x795a, 0x79df, 0x7a20, 0x7a95, 0x7c97, 0x7cdf, 0x7d44, 0x7e70, 0x8087, - 0x85fb, 0x86a4, 0x8a54, 0x8abf, 0x8d99, 0x8e81, 0x9020, 0x906d, 0x91e3, 0x963b, 0x96d5, 0x9ce5, 0x65cf, 0x7c07, 0x8db3, 0x93c3, - 0x5b58, 0x5c0a, 0x5352, 0x62d9, 0x731d, 0x5027, 0x5b97, 0x5f9e, 0x60b0, 0x616b, 0x68d5, 0x6dd9, 0x742e, 0x7a2e, 0x7d42, 0x7d9c, - 0x7e31, 0x816b, 0x8e2a, 0x8e35, 0x937e, 0x9418, 0x4f50, 0x5750, 0x5de6, 0x5ea7, 0x632b, 0x7f6a, 0x4e3b, 0x4f4f, 0x4f8f, 0x505a, - 0x59dd, 0x80c4, 0x546a, 0x5468, 0x55fe, 0x594f, 0x5b99, 0x5dde, 0x5eda, 0x665d, 0x6731, 0x67f1, 0x682a, 0x6ce8, 0x6d32, 0x6e4a, - 0x6f8d, 0x70b7, 0x73e0, 0x7587, 0x7c4c, 0x7d02, 0x7d2c, 0x7da2, 0x821f, 0x86db, 0x8a3b, 0x8a85, 0x8d70, 0x8e8a, 0x8f33, 0x9031, - 0x914e, 0x9152, 0x9444, 0x99d0, 0x7af9, 0x7ca5, 0x4fca, 0x5101, 0x51c6, 0x57c8, 0x5bef, 0x5cfb, 0x6659, 0x6a3d, 0x6d5a, 0x6e96, - 0x6fec, 0x710c, 0x756f, 0x7ae3, 0x8822, 0x9021, 0x9075, 0x96cb, 0x99ff, 0x8301, 0x4e2d, 0x4ef2, 0x8846, 0x91cd, 0x537d, 0x6adb, - 0x696b, 0x6c41, 0x847a, 0x589e, 0x618e, 0x66fe, 0x62ef, 0x70dd, 0x7511, 0x75c7, 0x7e52, 0x84b8, 0x8b49, 0x8d08, 0x4e4b, 0x53ea, - 0x54ab, 0x5730, 0x5740, 0x5fd7, 0x6301, 0x6307, 0x646f, 0x652f, 0x65e8, 0x667a, 0x679d, 0x67b3, 0x6b62, 0x6c60, 0x6c9a, 0x6f2c, - 0x77e5, 0x7825, 0x7949, 0x7957, 0x7d19, 0x80a2, 0x8102, 0x81f3, 0x829d, 0x82b7, 0x8718, 0x8a8c, 0xf9fc, 0x8d04, 0x8dbe, 0x9072, - 0x76f4, 0x7a19, 0x7a37, 0x7e54, 0x8077, 0x5507, 0x55d4, 0x5875, 0x632f, 0x6422, 0x6649, 0x664b, 0x686d, 0x699b, 0x6b84, 0x6d25, - 0x6eb1, 0x73cd, 0x7468, 0x74a1, 0x755b, 0x75b9, 0x76e1, 0x771e, 0x778b, 0x79e6, 0x7e09, 0x7e1d, 0x81fb, 0x852f, 0x8897, 0x8a3a, - 0x8cd1, 0x8eeb, 0x8fb0, 0x9032, 0x93ad, 0x9663, 0x9673, 0x9707, 0x4f84, 0x53f1, 0x59ea, 0x5ac9, 0x5e19, 0x684e, 0x74c6, 0x75be, - 0x79e9, 0x7a92, 0x81a3, 0x86ed, 0x8cea, 0x8dcc, 0x8fed, 0x659f, 0x6715, 0xf9fd, 0x57f7, 0x6f57, 0x7ddd, 0x8f2f, 0x93f6, 0x96c6, - 0x5fb5, 0x61f2, 0x6f84, 0x4e14, 0x4f98, 0x501f, 0x53c9, 0x55df, 0x5d6f, 0x5dee, 0x6b21, 0x6b64, 0x78cb, 0x7b9a, 0xf9fe, 0x8e49, - 0x8eca, 0x906e, 0x6349, 0x643e, 0x7740, 0x7a84, 0x932f, 0x947f, 0x9f6a, 0x64b0, 0x6faf, 0x71e6, 0x74a8, 0x74da, 0x7ac4, 0x7c12, - 0x7e82, 0x7cb2, 0x7e98, 0x8b9a, 0x8d0a, 0x947d, 0x9910, 0x994c, 0x5239, 0x5bdf, 0x64e6, 0x672d, 0x7d2e, 0x50ed, 0x53c3, 0x5879, - 0x6158, 0x6159, 0x61fa, 0x65ac, 0x7ad9, 0x8b92, 0x8b96, 0x5009, 0x5021, 0x5275, 0x5531, 0x5a3c, 0x5ee0, 0x5f70, 0x6134, 0x655e, - 0x660c, 0x6636, 0x66a2, 0x69cd, 0x6ec4, 0x6f32, 0x7316, 0x7621, 0x7a93, 0x8139, 0x8259, 0x83d6, 0x84bc, 0x50b5, 0x57f0, 0x5bc0, - 0x5be8, 0x5f69, 0x63a1, 0x7826, 0x7db5, 0x83dc, 0x8521, 0x91c7, 0x91f5, 0x518a, 0x67f5, 0x7b56, 0x8cac, 0x51c4, 0x59bb, 0x60bd, - 0x8655, 0x501c, 0xf9ff, 0x5254, 0x5c3a, 0x617d, 0x621a, 0x62d3, 0x64f2, 0x65a5, 0x6ecc, 0x7620, 0x810a, 0x8e60, 0x965f, 0x96bb, - 0x4edf, 0x5343, 0x5598, 0x5929, 0x5ddd, 0x64c5, 0x6cc9, 0x6dfa, 0x7394, 0x7a7f, 0x821b, 0x85a6, 0x8ce4, 0x8e10, 0x9077, 0x91e7, - 0x95e1, 0x9621, 0x97c6, 0x51f8, 0x54f2, 0x5586, 0x5fb9, 0x64a4, 0x6f88, 0x7db4, 0x8f1f, 0x8f4d, 0x9435, 0x50c9, 0x5c16, 0x6cbe, - 0x6dfb, 0x751b, 0x77bb, 0x7c3d, 0x7c64, 0x8a79, 0x8ac2, 0x581e, 0x59be, 0x5e16, 0x6377, 0x7252, 0x758a, 0x776b, 0x8adc, 0x8cbc, - 0x8f12, 0x5ef3, 0x6674, 0x6df8, 0x807d, 0x83c1, 0x8acb, 0x9751, 0x9bd6, 0xfa00, 0x5243, 0x66ff, 0x6d95, 0x6eef, 0x7de0, 0x8ae6, - 0x902e, 0x905e, 0x9ad4, 0x521d, 0x527f, 0x54e8, 0x6194, 0x6284, 0x62db, 0x68a2, 0x6912, 0x695a, 0x6a35, 0x7092, 0x7126, 0x785d, - 0x7901, 0x790e, 0x79d2, 0x7a0d, 0x8096, 0x8278, 0x82d5, 0x8349, 0x8549, 0x8c82, 0x8d85, 0x9162, 0x918b, 0x91ae, 0x4fc3, 0x56d1, - 0x71ed, 0x77d7, 0x8700, 0x89f8, 0x5bf8, 0x5fd6, 0x6751, 0x90a8, 0x53e2, 0x585a, 0x5bf5, 0x60a4, 0x6181, 0x6460, 0x7e3d, 0x8070, - 0x8525, 0x9283, 0x64ae, 0x50ac, 0x5d14, 0x6700, 0x589c, 0x62bd, 0x63a8, 0x690e, 0x6978, 0x6a1e, 0x6e6b, 0x76ba, 0x79cb, 0x82bb, - 0x8429, 0x8acf, 0x8da8, 0x8ffd, 0x9112, 0x914b, 0x919c, 0x9310, 0x9318, 0x939a, 0x96db, 0x9a36, 0x9c0d, 0x4e11, 0x755c, 0x795d, - 0x7afa, 0x7b51, 0x7bc9, 0x7e2e, 0x84c4, 0x8e59, 0x8e74, 0x8ef8, 0x9010, 0x6625, 0x693f, 0x7443, 0x51fa, 0x672e, 0x9edc, 0x5145, - 0x5fe0, 0x6c96, 0x87f2, 0x885d, 0x8877, 0x60b4, 0x81b5, 0x8403, 0x8d05, 0x53d6, 0x5439, 0x5634, 0x5a36, 0x5c31, 0x708a, 0x7fe0, - 0x805a, 0x8106, 0x81ed, 0x8da3, 0x9189, 0x9a5f, 0x9df2, 0x5074, 0x4ec4, 0x53a0, 0x60fb, 0x6e2c, 0x5c64, 0x4f88, 0x5024, 0x55e4, - 0x5cd9, 0x5e5f, 0x6065, 0x6894, 0x6cbb, 0x6dc4, 0x71be, 0x75d4, 0x75f4, 0x7661, 0x7a1a, 0x7a49, 0x7dc7, 0x7dfb, 0x7f6e, 0x81f4, - 0x86a9, 0x8f1c, 0x96c9, 0x99b3, 0x9f52, 0x5247, 0x52c5, 0x98ed, 0x89aa, 0x4e03, 0x67d2, 0x6f06, 0x4fb5, 0x5be2, 0x6795, 0x6c88, - 0x6d78, 0x741b, 0x7827, 0x91dd, 0x937c, 0x87c4, 0x79e4, 0x7a31, 0x5feb, 0x4ed6, 0x54a4, 0x553e, 0x58ae, 0x59a5, 0x60f0, 0x6253, - 0x62d6, 0x6736, 0x6955, 0x8235, 0x9640, 0x99b1, 0x99dd, 0x502c, 0x5353, 0x5544, 0x577c, 0xfa01, 0x6258, 0xfa02, 0x64e2, 0x666b, - 0x67dd, 0x6fc1, 0x6fef, 0x7422, 0x7438, 0x8a17, 0x9438, 0x5451, 0x5606, 0x5766, 0x5f48, 0x619a, 0x6b4e, 0x7058, 0x70ad, 0x7dbb, - 0x8a95, 0x596a, 0x812b, 0x63a2, 0x7708, 0x803d, 0x8caa, 0x5854, 0x642d, 0x69bb, 0x5b95, 0x5e11, 0x6e6f, 0xfa03, 0x8569, 0x514c, - 0x53f0, 0x592a, 0x6020, 0x614b, 0x6b86, 0x6c70, 0x6cf0, 0x7b1e, 0x80ce, 0x82d4, 0x8dc6, 0x90b0, 0x98b1, 0xfa04, 0x64c7, 0x6fa4, - 0x6491, 0x6504, 0x514e, 0x5410, 0x571f, 0x8a0e, 0x615f, 0x6876, 0xfa05, 0x75db, 0x7b52, 0x7d71, 0x901a, 0x5806, 0x69cc, 0x817f, - 0x892a, 0x9000, 0x9839, 0x5078, 0x5957, 0x59ac, 0x6295, 0x900f, 0x9b2a, 0x615d, 0x7279, 0x95d6, 0x5761, 0x5a46, 0x5df4, 0x628a, - 0x64ad, 0x64fa, 0x6777, 0x6ce2, 0x6d3e, 0x722c, 0x7436, 0x7834, 0x7f77, 0x82ad, 0x8ddb, 0x9817, 0x5224, 0x5742, 0x677f, 0x7248, - 0x74e3, 0x8ca9, 0x8fa6, 0x9211, 0x962a, 0x516b, 0x53ed, 0x634c, 0x4f69, 0x5504, 0x6096, 0x6557, 0x6c9b, 0x6d7f, 0x724c, 0x72fd, - 0x7a17, 0x8987, 0x8c9d, 0x5f6d, 0x6f8e, 0x70f9, 0x81a8, 0x610e, 0x4fbf, 0x504f, 0x6241, 0x7247, 0x7bc7, 0x7de8, 0x7fe9, 0x904d, - 0x97ad, 0x9a19, 0x8cb6, 0x576a, 0x5e73, 0x67b0, 0x840d, 0x8a55, 0x5420, 0x5b16, 0x5e63, 0x5ee2, 0x5f0a, 0x6583, 0x80ba, 0x853d, - 0x9589, 0x965b, 0x4f48, 0x5305, 0x530d, 0x530f, 0x5486, 0x54fa, 0x5703, 0x5e03, 0x6016, 0x629b, 0x62b1, 0x6355, 0xfa06, 0x6ce1, - 0x6d66, 0x75b1, 0x7832, 0x80de, 0x812f, 0x82de, 0x8461, 0x84b2, 0x888d, 0x8912, 0x900b, 0x92ea, 0x98fd, 0x9b91, 0x5e45, 0x66b4, - 0x66dd, 0x7011, 0x7206, 0xfa07, 0x4ff5, 0x527d, 0x5f6a, 0x6153, 0x6753, 0x6a19, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8c79, 0x98c7, - 0x98c4, 0x9a43, 0x54c1, 0x7a1f, 0x6953, 0x8af7, 0x8c4a, 0x98a8, 0x99ae, 0x5f7c, 0x62ab, 0x75b2, 0x76ae, 0x88ab, 0x907f, 0x9642, - 0x5339, 0x5f3c, 0x5fc5, 0x6ccc, 0x73cc, 0x7562, 0x758b, 0x7b46, 0x82fe, 0x999d, 0x4e4f, 0x903c, 0x4e0b, 0x4f55, 0x53a6, 0x590f, - 0x5ec8, 0x6630, 0x6cb3, 0x7455, 0x8377, 0x8766, 0x8cc0, 0x9050, 0x971e, 0x9c15, 0x58d1, 0x5b78, 0x8650, 0x8b14, 0x9db4, 0x5bd2, - 0x6068, 0x608d, 0x65f1, 0x6c57, 0x6f22, 0x6fa3, 0x701a, 0x7f55, 0x7ff0, 0x9591, 0x9592, 0x9650, 0x97d3, 0x5272, 0x8f44, 0x51fd, - 0x542b, 0x54b8, 0x5563, 0x558a, 0x6abb, 0x6db5, 0x7dd8, 0x8266, 0x929c, 0x9677, 0x9e79, 0x5408, 0x54c8, 0x76d2, 0x86e4, 0x95a4, - 0x95d4, 0x965c, 0x4ea2, 0x4f09, 0x59ee, 0x5ae6, 0x5df7, 0x6052, 0x6297, 0x676d, 0x6841, 0x6c86, 0x6e2f, 0x7f38, 0x809b, 0x822a, - 0xfa08, 0xfa09, 0x9805, 0x4ea5, 0x5055, 0x54b3, 0x5793, 0x595a, 0x5b69, 0x5bb3, 0x61c8, 0x6977, 0x6d77, 0x7023, 0x87f9, 0x89e3, - 0x8a72, 0x8ae7, 0x9082, 0x99ed, 0x9ab8, 0x52be, 0x6838, 0x5016, 0x5e78, 0x674f, 0x8347, 0x884c, 0x4eab, 0x5411, 0x56ae, 0x73e6, - 0x9115, 0x97ff, 0x9909, 0x9957, 0x9999, 0x5653, 0x589f, 0x865b, 0x8a31, 0x61b2, 0x6af6, 0x737b, 0x8ed2, 0x6b47, 0x96aa, 0x9a57, - 0x5955, 0x7200, 0x8d6b, 0x9769, 0x4fd4, 0x5cf4, 0x5f26, 0x61f8, 0x665b, 0x6ceb, 0x70ab, 0x7384, 0x73b9, 0x73fe, 0x7729, 0x774d, - 0x7d43, 0x7d62, 0x7e23, 0x8237, 0x8852, 0xfa0a, 0x8ce2, 0x9249, 0x986f, 0x5b51, 0x7a74, 0x8840, 0x9801, 0x5acc, 0x4fe0, 0x5354, - 0x593e, 0x5cfd, 0x633e, 0x6d79, 0x72f9, 0x8105, 0x8107, 0x83a2, 0x92cf, 0x9830, 0x4ea8, 0x5144, 0x5211, 0x578b, 0x5f62, 0x6cc2, - 0x6ece, 0x7005, 0x7050, 0x70af, 0x7192, 0x73e9, 0x7469, 0x834a, 0x87a2, 0x8861, 0x9008, 0x90a2, 0x93a3, 0x99a8, 0x516e, 0x5f57, - 0x60e0, 0x6167, 0x66b3, 0x8559, 0x8e4a, 0x91af, 0x978b, 0x4e4e, 0x4e92, 0x547c, 0x58d5, 0x58fa, 0x597d, 0x5cb5, 0x5f27, 0x6236, - 0x6248, 0x660a, 0x6667, 0x6beb, 0x6d69, 0x6dcf, 0x6e56, 0x6ef8, 0x6f94, 0x6fe0, 0x6fe9, 0x705d, 0x72d0, 0x7425, 0x745a, 0x74e0, - 0x7693, 0x795c, 0x7cca, 0x7e1e, 0x80e1, 0x82a6, 0x846b, 0x84bf, 0x864e, 0x865f, 0x8774, 0x8b77, 0x8c6a, 0x93ac, 0x9800, 0x9865, - 0x60d1, 0x6216, 0x9177, 0x5a5a, 0x660f, 0x6df7, 0x6e3e, 0x743f, 0x9b42, 0x5ffd, 0x60da, 0x7b0f, 0x54c4, 0x5f18, 0x6c5e, 0x6cd3, - 0x6d2a, 0x70d8, 0x7d05, 0x8679, 0x8a0c, 0x9d3b, 0x5316, 0x548c, 0x5b05, 0x6a3a, 0x706b, 0x7575, 0x798d, 0x79be, 0x82b1, 0x83ef, - 0x8a71, 0x8b41, 0x8ca8, 0x9774, 0xfa0b, 0x64f4, 0x652b, 0x78ba, 0x78bb, 0x7a6b, 0x4e38, 0x559a, 0x5950, 0x5ba6, 0x5e7b, 0x60a3, - 0x63db, 0x6b61, 0x6665, 0x6853, 0x6e19, 0x7165, 0x74b0, 0x7d08, 0x9084, 0x9a69, 0x9c25, 0x6d3b, 0x6ed1, 0x733e, 0x8c41, 0x95ca, - 0x51f0, 0x5e4c, 0x5fa8, 0x604d, 0x60f6, 0x6130, 0x614c, 0x6643, 0x6644, 0x69a5, 0x6cc1, 0x6e5f, 0x6ec9, 0x6f62, 0x714c, 0x749c, - 0x7687, 0x7bc1, 0x7c27, 0x8352, 0x8757, 0x9051, 0x968d, 0x9ec3, 0x532f, 0x56de, 0x5efb, 0x5f8a, 0x6062, 0x6094, 0x61f7, 0x6666, - 0x6703, 0x6a9c, 0x6dee, 0x6fae, 0x7070, 0x736a, 0x7e6a, 0x81be, 0x8334, 0x86d4, 0x8aa8, 0x8cc4, 0x5283, 0x7372, 0x5b96, 0x6a6b, - 0x9404, 0x54ee, 0x5686, 0x5b5d, 0x6548, 0x6585, 0x66c9, 0x689f, 0x6d8d, 0x6dc6, 0x723b, 0x80b4, 0x9175, 0x9a4d, 0x4faf, 0x5019, - 0x539a, 0x540e, 0x543c, 0x5589, 0x55c5, 0x5e3f, 0x5f8c, 0x673d, 0x7166, 0x73dd, 0x9005, 0x52db, 0x52f3, 0x5864, 0x58ce, 0x7104, - 0x718f, 0x71fb, 0x85b0, 0x8a13, 0x6688, 0x85a8, 0x55a7, 0x6684, 0x714a, 0x8431, 0x5349, 0x5599, 0x6bc1, 0x5f59, 0x5fbd, 0x63ee, - 0x6689, 0x7147, 0x8af1, 0x8f1d, 0x9ebe, 0x4f11, 0x643a, 0x70cb, 0x7566, 0x8667, 0x6064, 0x8b4e, 0x9df8, 0x5147, 0x51f6, 0x5308, - 0x6d36, 0x80f8, 0x9ed1, 0x6615, 0x6b23, 0x7098, 0x75d5, 0x5403, 0x5c79, 0x7d07, 0x8a16, 0x6b20, 0x6b3d, 0x6b46, 0x5438, 0x6070, - 0x6d3d, 0x7fd5, 0x8208, 0x50d6, 0x51de, 0x559c, 0x566b, 0x56cd, 0x59ec, 0x5b09, 0x5e0c, 0x6199, 0x6198, 0x6231, 0x665e, 0x66e6, - 0x7199, 0x71b9, 0x71ba, 0x72a7, 0x79a7, 0x7a00, 0x7fb2, 0x8a70, -}; - -/* Table including ksc5601 symbol to unicode */ -static const uint16_t ksc5601_symbol_to_unicode[1115] = -{ - 0x3000, 0x3001, 0x3002, 0x00b7, 0x2025, 0x2026, 0x00a8, 0x3003, 0x00ad, 0x2015, 0x2225, 0xff3c, 0x223c, 0x2018, 0x2019, 0x201c, - 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e, 0x300f, 0x3010, 0x3011, 0x00b1, 0x00d7, 0x00f7, - 0x2260, 0x2264, 0x2265, 0x221e, 0x2234, 0x00b0, 0x2032, 0x2033, 0x2103, 0x212b, 0xffe0, 0xffe1, 0xffe5, 0x2642, 0x2640, 0x2220, - 0x22a5, 0x2312, 0x2202, 0x2207, 0x2261, 0x2252, 0x00a7, 0x203b, 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1, - 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x2192, 0x2190, 0x2191, 0x2193, 0x2194, 0x3013, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, - 0x2235, 0x222b, 0x222c, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, 0x2283, 0x222a, 0x2229, 0x2227, 0x2228, 0xffe2, 0x21d2, 0x21d4, - 0x2200, 0x2203, 0x00b4, 0xff5e, 0x02c7, 0x02d8, 0x02dd, 0x02da, 0x02d9, 0x00b8, 0x02db, 0x00a1, 0x00bf, 0x02d0, 0x222e, 0x2211, - 0x220f, 0x00a4, 0x2109, 0x2030, 0x25c1, 0x25c0, 0x25b7, 0x25b6, 0x2664, 0x2660, 0x2661, 0x2665, 0x2667, 0x2663, 0x2299, 0x25c8, - 0x25a3, 0x25d0, 0x25d1, 0x2592, 0x25a4, 0x25a5, 0x25a8, 0x25a7, 0x25a6, 0x25a9, 0x2668, 0x260f, 0x260e, 0x261c, 0x261e, 0x00b6, - 0x2020, 0x2021, 0x2195, 0x2197, 0x2199, 0x2196, 0x2198, 0x266d, 0x2669, 0x266a, 0x266c, 0x327f, 0x321c, 0x2116, 0x33c7, 0x2122, - 0x33c2, 0x33d8, 0x2121, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff01, 0xff02, 0xff03, 0xff04, - 0xff05, 0xff06, 0xff07, 0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10, 0xff11, 0xff12, 0xff13, 0xff14, - 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 0xff20, 0xff21, 0xff22, 0xff23, 0xff24, - 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, - 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0xff3b, 0xffe6, 0xff3d, 0xff3e, 0xff3f, 0xff40, 0xff41, 0xff42, 0xff43, 0xff44, - 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, - 0xff55, 0xff56, 0xff57, 0xff58, 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xffe3, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, - 0x3137, 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, - 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, - 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, - 0x3167, 0x3168, 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e, 0x316f, 0x3170, 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176, - 0x3177, 0x3178, 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, 0x317e, 0x317f, 0x3180, 0x3181, 0x3182, 0x3183, 0x3184, 0x3185, 0x3186, - 0x3187, 0x3188, 0x3189, 0x318a, 0x318b, 0x318c, 0x318d, 0x318e, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, - 0x2178, 0x2179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, - 0x2169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, - 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, - 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2500, 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, 0x2524, 0x2534, - 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, 0x2517, 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, 0x2528, 0x2537, - 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, 0x2512, 0x2511, 0x251a, 0x2519, 0x2516, 0x2515, 0x250e, 0x250d, 0x251e, 0x251f, - 0x2521, 0x2522, 0x2526, 0x2527, 0x2529, 0x252a, 0x252d, 0x252e, 0x2531, 0x2532, 0x2535, 0x2536, 0x2539, 0x253a, 0x253d, 0x253e, - 0x2540, 0x2541, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3395, 0x3396, 0x3397, 0x2113, 0x3398, 0x33c4, 0x33a3, 0x33a4, 0x33a5, 0x33a6, 0x3399, 0x339a, - 0x339b, 0x339c, 0x339d, 0x339e, 0x339f, 0x33a0, 0x33a1, 0x33a2, 0x33ca, 0x338d, 0x338e, 0x338f, 0x33cf, 0x3388, 0x3389, 0x33c8, - 0x33a7, 0x33a8, 0x33b0, 0x33b1, 0x33b2, 0x33b3, 0x33b4, 0x33b5, 0x33b6, 0x33b7, 0x33b8, 0x33b9, 0x3380, 0x3381, 0x3382, 0x3383, - 0x3384, 0x33ba, 0x33bb, 0x33bc, 0x33bd, 0x33be, 0x33bf, 0x3390, 0x3391, 0x3392, 0x3393, 0x3394, 0x2126, 0x33c0, 0x33c1, 0x338a, - 0x338b, 0x338c, 0x33d6, 0x33c5, 0x33ad, 0x33ae, 0x33af, 0x33db, 0x33a9, 0x33aa, 0x33ab, 0x33ac, 0x33dd, 0x33d0, 0x33d3, 0x33c3, - 0x33c9, 0x33dc, 0x33c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x00c6, 0x00d0, 0x00aa, 0x0126, 0x0000, 0x0132, 0x0000, 0x013f, 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, - 0x014a, 0x0000, 0x3260, 0x3261, 0x3262, 0x3263, 0x3264, 0x3265, 0x3266, 0x3267, 0x3268, 0x3269, 0x326a, 0x326b, 0x326c, 0x326d, - 0x326e, 0x326f, 0x3270, 0x3271, 0x3272, 0x3273, 0x3274, 0x3275, 0x3276, 0x3277, 0x3278, 0x3279, 0x327a, 0x327b, 0x24d0, 0x24d1, - 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, - 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, - 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x00bd, 0x2153, 0x2154, 0x00bc, 0x00be, 0x215b, 0x215c, 0x215d, 0x215e, - 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138, 0x0140, 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x0149, - 0x3200, 0x3201, 0x3202, 0x3203, 0x3204, 0x3205, 0x3206, 0x3207, 0x3208, 0x3209, 0x320a, 0x320b, 0x320c, 0x320d, 0x320e, 0x320f, - 0x3210, 0x3211, 0x3212, 0x3213, 0x3214, 0x3215, 0x3216, 0x3217, 0x3218, 0x3219, 0x321a, 0x321b, 0x249c, 0x249d, 0x249e, 0x249f, - 0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5, 0x24a6, 0x24a7, 0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad, 0x24ae, 0x24af, - 0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, - 0x247e, 0x247f, 0x2480, 0x2481, 0x2482, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x207f, 0x2081, 0x2082, 0x2083, 0x2084, 0x3041, 0x3042, - 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, 0x3051, 0x3052, - 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, 0x3061, 0x3062, - 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, 0x3071, 0x3072, - 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, 0x3081, 0x3082, - 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, 0x3091, 0x3092, - 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x30a1, 0x30a2, 0x30a3, 0x30a4, - 0x30a5, 0x30a6, 0x30a7, 0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, - 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4, - 0x30c5, 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4, - 0x30d5, 0x30d6, 0x30d7, 0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, - 0x30e5, 0x30e6, 0x30e7, 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, - 0x30f5, 0x30f6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, - 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, - 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, - 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, - 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, -}; - -static const uint16_t REPLACEMENT = 0xfffd; - -static inline bool IsEucChar(unsigned c) -{ - return c >= 0xa1 && c <= 0xfe; -} - -static inline bool IsCP949Char(unsigned c) -{ - return c >= 0x81 && c <= 0xa0; -} - -static inline uint16_t ValidChar(unsigned u) -{ - return u != 0 ? static_cast(u) : REPLACEMENT; -} - -static uint16_t ksc2unicode(unsigned code) -{ - int ch1 = code >> 8; - int ch2 = code & 0x00ff; - int idx; - - if (ch1 < 0x80 || (ch1 - 0x80) <= 0x20 || (ch1 - 0x80) >= 0x7e - || (ch1 - 0x80) == 0x49) - return 0; - - if (ch2 < 0x80 || (ch2 - 0x80) <= 0x20 || (ch2 - 0x80) >= 0x7f) - return 0; - - idx = (ch1 - 0x80 - 0x21) * 94 + (ch2 - 0x80 - 0x21); - - /* Hangul : row 16 - row 40 : 1410 = 15 * 94 , - 3760 = 40 * 94 */ - if (idx >= 1410 && idx < 1410 + 2350) - return ksc5601_hangul_to_unicode[idx - 1410]; - - else if (idx >= 3854) - /* Hanja : row 42 - row 93 : 3854 = 94 * (42-1) */ - return ksc5601_hanja_to_unicode[idx - 3854]; - - else if (idx <= 1114) - return ksc5601_symbol_to_unicode[idx]; - - return 0; -} - -void -KRTextDecoder::AppendEucKr(std::vector& result, const uint8_t* bytes, size_t length) -{ - uint8_t buf[2] = { 0, 0 }; - int nbuf = 0; -// int invalid = 0; - - for (size_t i = 0; i= 8822) { - result.push_back(REPLACEMENT); -// ++invalid; - break; - } - else - result.push_back(ValidChar(cp949_icode_to_unicode[internal_code])); - } - nbuf = 0; - break; - } - } -} diff --git a/core/src/textcodec/KRTextDecoder.h b/core/src/textcodec/KRTextDecoder.h deleted file mode 100644 index 33d79031b1..0000000000 --- a/core/src/textcodec/KRTextDecoder.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -class KRTextDecoder -{ -public: - static void AppendEucKr(std::vector& utf16, const uint8_t* bytes, size_t length); -}; diff --git a/core/src/textcodec/KRTextEncoder.cpp b/core/src/textcodec/KRTextEncoder.cpp deleted file mode 100644 index f472089fcd..0000000000 --- a/core/src/textcodec/KRTextEncoder.cpp +++ /dev/null @@ -1,731 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Most of the cp949 code was originally written by Joon-Kyu Park, and is included -// in Qt with the author's permission and the grateful thanks of the Qt team. - -#include "KRTextEncoder.h" -#include "KRHangulMapping.h" - -struct Mapping -{ - uint16_t unicode; - uint16_t kscode; -}; - - -/* Map Table including unicode to ksc5601 symbol */ -static const Mapping unicode_to_ksc5601_symbol[986] = { - {0x4e00,0x6c69}, {0x4e01,0x6f4b}, {0x4e03,0x7652}, {0x4e07,0x5832}, {0x4e08,0x6d5b}, {0x4e09,0x5f32}, {0x4e0a,0x5f3e}, {0x4e0b,0x793b}, {0x4e0d,0x5c74}, {0x4e11,0x7564}, - {0x4e14,0x7326}, {0x4e15,0x5d60}, {0x4e16,0x6126}, {0x4e18,0x4e78}, {0x4e19,0x5c30}, {0x4e1e,0x632a}, {0x4e2d,0x7169}, {0x4e32,0x4d7a}, {0x4e38,0x7c2f}, {0x4e39,0x5321}, - {0x4e3b,0x712b}, {0x4e42,0x6751}, {0x4e43,0x522c}, {0x4e45,0x4e79}, {0x4e4b,0x717d}, {0x4e4d,0x5e3f}, {0x4e4e,0x7b3a}, {0x4e4f,0x7939}, {0x4e56,0x4e52}, {0x4e58,0x632b}, - {0x4e59,0x6b60}, {0x4e5d,0x4e7a}, {0x4e5e,0x4b77}, {0x4e5f,0x6525}, {0x4e6b,0x4a61}, {0x4e6d,0x544c}, {0x4e73,0x6a61}, {0x4e76,0x5c63}, {0x4e77,0x5f2d}, {0x4e7e,0x4b6b}, - {0x4e82,0x552f}, {0x4e86,0x5675}, {0x4e88,0x6578}, {0x4e8b,0x5e40}, {0x4e8c,0x6c23}, {0x4e8e,0x694d}, {0x4e90,0x6a27}, {0x4e91,0x6976}, {0x4e92,0x7b3b}, {0x4e94,0x6769}, - {0x4e95,0x6f4c}, {0x4e98,0x5066}, {0x4e9b,0x5e41}, {0x4e9e,0x642c}, {0x4ea1,0x584c}, {0x4ea2,0x7971}, {0x4ea4,0x4e5f}, {0x4ea5,0x7a24}, {0x4ea6,0x6632}, {0x4ea8,0x7a7b}, - {0x4eab,0x7a3d}, {0x4eac,0x4c48}, {0x4ead,0x6f4d}, {0x4eae,0x5555}, {0x4eb6,0x5322}, {0x4eba,0x6c51}, {0x4ec0,0x6427}, {0x4ec1,0x6c52}, {0x4ec4,0x7631}, {0x4ec7,0x4e7b}, - {0x4eca,0x5051}, {0x4ecb,0x4b3f}, {0x4ecd,0x6d24}, {0x4ed4,0x6d28}, {0x4ed5,0x5e42}, {0x4ed6,0x7662}, {0x4ed7,0x6d5c}, {0x4ed8,0x5c75}, {0x4ed9,0x6039}, {0x4edd,0x544e}, - {0x4edf,0x7435}, {0x4ee3,0x535b}, {0x4ee4,0x5635}, {0x4ee5,0x6c24}, {0x4ef0,0x6466}, {0x4ef2,0x716a}, {0x4ef6,0x4b6c}, {0x4ef7,0x4b40}, {0x4efb,0x6c72}, {0x4f01,0x506a}, - {0x4f09,0x7972}, {0x4f0a,0x6c25}, {0x4f0b,0x505f}, {0x4f0d,0x676a}, {0x4f0e,0x506b}, {0x4f0f,0x5c51}, {0x4f10,0x5b69}, {0x4f11,0x7d4c}, {0x4f2f,0x5b57}, {0x4f34,0x5a61}, - {0x4f36,0x5636}, {0x4f38,0x635f}, {0x4f3a,0x5e43}, {0x4f3c,0x5e44}, {0x4f3d,0x4a21}, {0x4f43,0x6e6c}, {0x4f46,0x5323}, {0x4f47,0x6e37}, {0x4f48,0x784f}, {0x4f4d,0x6a48}, - {0x4f4e,0x6e38}, {0x4f4f,0x712c}, {0x4f50,0x7125}, {0x4f51,0x694e}, {0x4f55,0x793c}, {0x4f59,0x6579}, {0x4f5a,0x6c6a}, {0x4f5b,0x5d56}, {0x4f5c,0x6d42}, {0x4f69,0x7825}, - {0x4f6f,0x653a}, {0x4f70,0x5b58}, {0x4f73,0x4a22}, {0x4f76,0x514d}, {0x4f7a,0x6e6d}, {0x4f7e,0x6c6b}, {0x4f7f,0x5e45}, {0x4f81,0x6360}, {0x4f83,0x4a49}, {0x4f84,0x7269}, - {0x4f86,0x554e}, {0x4f88,0x7636}, {0x4f8a,0x4e42}, {0x4f8b,0x5647}, {0x4f8d,0x6334}, {0x4f8f,0x712d}, {0x4f91,0x6a62}, {0x4f96,0x5742}, {0x4f98,0x7327}, {0x4f9b,0x4d6a}, - {0x4f9d,0x6b6e}, {0x4fae,0x5932}, {0x4faf,0x7d25}, {0x4fb5,0x7655}, {0x4fb6,0x5562}, {0x4fbf,0x7835}, {0x4fc2,0x4c75}, {0x4fc3,0x7535}, {0x4fc4,0x642d}, {0x4fc9,0x676b}, - {0x4fca,0x7155}, {0x4fce,0x703b}, {0x4fd1,0x6935}, {0x4fd3,0x4c49}, {0x4fd4,0x7a55}, {0x4fd7,0x6154}, {0x4fda,0x5756}, {0x4fdd,0x5c41}, {0x4fdf,0x5e46}, {0x4fe0,0x7a6f}, - {0x4fe1,0x6361}, {0x4fee,0x6173}, {0x4fef,0x5c76}, {0x4ff1,0x4e7c}, {0x4ff3,0x5b44}, {0x4ff5,0x7871}, {0x4ff8,0x5c64}, {0x4ffa,0x656f}, {0x5002,0x5c31}, {0x5006,0x5556}, - {0x5009,0x735a}, {0x500b,0x4b41}, {0x500d,0x5b43}, {0x5011,0x597a}, {0x5012,0x536e}, {0x5016,0x7a38}, {0x5019,0x7d26}, {0x501a,0x6b6f}, {0x501c,0x7426}, {0x501e,0x4c4a}, - {0x501f,0x7328}, {0x5021,0x735b}, {0x5023,0x5b27}, {0x5024,0x7637}, {0x5026,0x4f66}, {0x5027,0x7072}, {0x5028,0x4b5a}, {0x502a,0x6752}, {0x502b,0x5743}, {0x502c,0x7670}, - {0x502d,0x685e}, {0x503b,0x6526}, {0x5043,0x6567}, {0x5047,0x4a23}, {0x5048,0x4c27}, {0x5049,0x6a49}, {0x504f,0x7836}, {0x5055,0x7a25}, {0x505a,0x712e}, {0x505c,0x6f4e}, - {0x5065,0x4b6d}, {0x5074,0x7630}, {0x5075,0x6f4f}, {0x5076,0x694f}, {0x5078,0x775e}, {0x5080,0x4e53}, {0x5085,0x5c77}, {0x508d,0x5b28}, {0x5091,0x4b78}, {0x5098,0x5f21}, - {0x5099,0x5d61}, {0x50ac,0x754a}, {0x50ad,0x6936}, {0x50b2,0x676c}, {0x50b3,0x6e6e}, {0x50b5,0x7370}, {0x50b7,0x5f3f}, {0x50be,0x4c4b}, {0x50c5,0x5041}, {0x50c9,0x7452}, - {0x50ca,0x603a}, {0x50cf,0x5f40}, {0x50d1,0x4e60}, {0x50d5,0x5c52}, {0x50d6,0x7d6a}, {0x50da,0x5676}, {0x50de,0x6a4a}, {0x50e5,0x6869}, {0x50e7,0x632c}, {0x50ed,0x7350}, - {0x50f9,0x4a24}, {0x50fb,0x5b78}, {0x50ff,0x5e47}, {0x5100,0x6b70}, {0x5101,0x7156}, {0x5104,0x6562}, {0x5106,0x4c4c}, {0x5109,0x4b7b}, {0x5112,0x6a63}, {0x511f,0x5f41}, - {0x5121,0x566d}, {0x512a,0x6950}, {0x5132,0x6e39}, {0x5137,0x5563}, {0x513a,0x5153}, {0x513c,0x6570}, {0x5140,0x6834}, {0x5141,0x6b43}, {0x5143,0x6a2a}, {0x5144,0x7a7c}, - {0x5145,0x7576}, {0x5146,0x703c}, {0x5147,0x7d54}, {0x5148,0x603b}, {0x5149,0x4e43}, {0x514b,0x503a}, {0x514c,0x773a}, {0x514d,0x5873}, {0x514e,0x774d}, {0x5152,0x642e}, - {0x515c,0x545f}, {0x5162,0x5067}, {0x5165,0x6c7d}, {0x5167,0x522e}, {0x5168,0x6e6f}, {0x5169,0x5557}, {0x516a,0x6a64}, {0x516b,0x7822}, {0x516c,0x4d6b}, {0x516d,0x573f}, - {0x516e,0x7b31}, {0x5171,0x4d6c}, {0x5175,0x5c32}, {0x5176,0x506c}, {0x5177,0x4e7d}, {0x5178,0x6e70}, {0x517c,0x4c42}, {0x5180,0x506d}, {0x5186,0x6577}, {0x518a,0x737c}, - {0x518d,0x6e22}, {0x5192,0x5933}, {0x5195,0x5874}, {0x5197,0x6937}, {0x51a0,0x4e2e}, {0x51a5,0x5922}, {0x51aa,0x5871}, {0x51ac,0x544f}, {0x51b6,0x6527}, {0x51b7,0x5552}, - {0x51bd,0x5629}, {0x51c4,0x7422}, {0x51c6,0x7157}, {0x51c9,0x5558}, {0x51cb,0x703d}, {0x51cc,0x5750}, {0x51cd,0x5450}, {0x51dc,0x574f}, {0x51dd,0x6b6a}, {0x51de,0x7d6b}, - {0x51e1,0x5b6d}, {0x51f0,0x7c45}, {0x51f1,0x4b42}, {0x51f6,0x7d55}, {0x51f8,0x7448}, {0x51f9,0x686a}, {0x51fa,0x7573}, {0x51fd,0x795e}, {0x5200,0x536f}, {0x5203,0x6c53}, - {0x5206,0x5d42}, {0x5207,0x6f37}, {0x5208,0x6754}, {0x520a,0x4a4a}, {0x520e,0x597b}, {0x5211,0x7a7d}, {0x5217,0x562a}, {0x521d,0x7478}, {0x5224,0x7777}, {0x5225,0x5c2c}, - {0x5229,0x5757}, {0x522a,0x5f22}, {0x522e,0x4e3e}, {0x5230,0x5370}, {0x5236,0x7024}, {0x5237,0x616c}, {0x5238,0x4f67}, {0x5239,0x734b}, {0x523a,0x6d29}, {0x523b,0x4a3e}, - {0x5243,0x746f}, {0x5247,0x764e}, {0x524a,0x5e7b}, {0x524b,0x503b}, {0x524c,0x5537}, {0x524d,0x6e71}, {0x5254,0x7428}, {0x5256,0x5c78}, {0x525b,0x4b27}, {0x525d,0x5a4e}, - {0x5261,0x6066}, {0x5269,0x6d25}, {0x526a,0x6e72}, {0x526f,0x5c79}, {0x5272,0x795c}, {0x5275,0x735c}, {0x527d,0x7872}, {0x527f,0x7479}, {0x5283,0x7c71}, {0x5287,0x503c}, - {0x5288,0x5b79}, {0x5289,0x5731}, {0x528d,0x4b7c}, {0x5291,0x7025}, {0x5292,0x4b7d}, {0x529b,0x5574}, {0x529f,0x4d6d}, {0x52a0,0x4a25}, {0x52a3,0x562b}, {0x52a4,0x5042}, - {0x52a9,0x703e}, {0x52aa,0x523d}, {0x52ab,0x4c24}, {0x52be,0x7a36}, {0x52c1,0x4c4d}, {0x52c3,0x5a7a}, {0x52c5,0x764f}, {0x52c7,0x6938}, {0x52c9,0x5875}, {0x52cd,0x4c4e}, - {0x52d2,0x574d}, {0x52d5,0x5451}, {0x52d6,0x696d}, {0x52d8,0x4a6b}, {0x52d9,0x5962}, {0x52db,0x7d32}, {0x52dd,0x632d}, {0x52de,0x564c}, {0x52df,0x5934}, {0x52e2,0x6127}, - {0x52e3,0x6e53}, {0x52e4,0x5043}, {0x52f3,0x7d33}, {0x52f5,0x5564}, {0x52f8,0x4f68}, {0x52fa,0x6d43}, {0x52fb,0x5032}, {0x52fe,0x4e7e}, {0x52ff,0x5a28}, {0x5305,0x7850}, - {0x5308,0x7d56}, {0x530d,0x7851}, {0x530f,0x7852}, {0x5310,0x5c53}, {0x5315,0x5d62}, {0x5316,0x7b79}, {0x5317,0x5d41}, {0x5319,0x6335}, {0x5320,0x6d5d}, {0x5321,0x4e44}, - {0x5323,0x4b21}, {0x532a,0x5d63}, {0x532f,0x7c5d}, {0x5339,0x792f}, {0x533f,0x527b}, {0x5340,0x4f21}, {0x5341,0x6428}, {0x5343,0x7436}, {0x5344,0x6c7e}, {0x5347,0x632e}, - {0x5348,0x676d}, {0x5349,0x7d41}, {0x534a,0x5a62}, {0x534d,0x5833}, {0x5351,0x5d64}, {0x5352,0x706f}, {0x5353,0x7671}, {0x5354,0x7a70}, {0x5357,0x5175}, {0x535a,0x5a4f}, - {0x535c,0x5c54}, {0x535e,0x5c26}, {0x5360,0x6f3f}, {0x5366,0x4e4f}, {0x5368,0x6059}, {0x536f,0x5956}, {0x5370,0x6c54}, {0x5371,0x6a4b}, {0x5374,0x4a3f}, {0x5375,0x5530}, - {0x5377,0x4f69}, {0x537d,0x716d}, {0x537f,0x4c4f}, {0x5384,0x6478}, {0x5393,0x646d}, {0x5398,0x5758}, {0x539a,0x7d27}, {0x539f,0x6a2b}, {0x53a0,0x7632}, {0x53a5,0x4f70}, - {0x53a6,0x793d}, {0x53ad,0x6674}, {0x53bb,0x4b5b}, {0x53c3,0x7351}, {0x53c8,0x6951}, {0x53c9,0x7329}, {0x53ca,0x5060}, {0x53cb,0x6952}, {0x53cd,0x5a63}, {0x53d4,0x6252}, - {0x53d6,0x7622}, {0x53d7,0x6174}, {0x53db,0x5a64}, {0x53e1,0x6755}, {0x53e2,0x753f}, {0x53e3,0x4f22}, {0x53e4,0x4d2f}, {0x53e5,0x4f23}, {0x53e9,0x4d30}, {0x53ea,0x717e}, - {0x53eb,0x5023}, {0x53ec,0x612f}, {0x53ed,0x7823}, {0x53ef,0x4a26}, {0x53f0,0x773b}, {0x53f1,0x726a}, {0x53f2,0x5e48}, {0x53f3,0x6953}, {0x53f8,0x5e49}, {0x5403,0x7d5e}, - {0x5404,0x4a40}, {0x5408,0x796a}, {0x5409,0x514e}, {0x540a,0x6e54}, {0x540c,0x5452}, {0x540d,0x5923}, {0x540e,0x7d28}, {0x540f,0x5759}, {0x5410,0x774e}, {0x5411,0x7a3e}, - {0x541b,0x4f56}, {0x541d,0x5770}, {0x541f,0x6b61}, {0x5420,0x7845}, {0x5426,0x5c7a}, {0x5429,0x5d43}, {0x542b,0x795f}, {0x5433,0x676f}, {0x5438,0x7d65}, {0x5439,0x7623}, - {0x543b,0x597c}, {0x543c,0x7d29}, {0x543e,0x676e}, {0x5442,0x5565}, {0x5448,0x6f50}, {0x544a,0x4d31}, {0x5451,0x7722}, {0x5468,0x7132}, {0x546a,0x7131}, {0x5471,0x4d32}, - {0x5473,0x5a2b}, {0x5475,0x4a27}, {0x547b,0x6362}, {0x547c,0x7b3c}, {0x547d,0x5924}, {0x5480,0x6e3a}, {0x5486,0x7853}, {0x548c,0x7b7a}, {0x548e,0x4f24}, {0x5490,0x5c7b}, - {0x54a4,0x7663}, {0x54a8,0x6d2a}, {0x54ab,0x7221}, {0x54ac,0x4e61}, {0x54b3,0x7a26}, {0x54b8,0x7960}, {0x54bd,0x6c56}, {0x54c0,0x646e}, {0x54c1,0x7921}, {0x54c4,0x7b6f}, - {0x54c8,0x796b}, {0x54c9,0x6e23}, {0x54e1,0x6a2c}, {0x54e5,0x4a28}, {0x54e8,0x747a}, {0x54ed,0x4d56}, {0x54ee,0x7c76}, {0x54f2,0x7449}, {0x54fa,0x7854}, {0x5504,0x7826}, - {0x5506,0x5e4a}, {0x5507,0x7246}, {0x550e,0x575a}, {0x5510,0x5350}, {0x551c,0x5845}, {0x552f,0x6a66}, {0x5531,0x735d}, {0x5535,0x645a}, {0x553e,0x7664}, {0x5544,0x7672}, - {0x5546,0x5f42}, {0x554f,0x597d}, {0x5553,0x4c76}, {0x5556,0x533a}, {0x555e,0x642f}, {0x5563,0x7961}, {0x557c,0x7026}, {0x5580,0x4b53}, {0x5584,0x603c}, {0x5586,0x744a}, - {0x5587,0x547a}, {0x5589,0x7d2a}, {0x558a,0x7962}, {0x5598,0x7437}, {0x5599,0x7d42}, {0x559a,0x7c30}, {0x559c,0x7d6c}, {0x559d,0x4a62}, {0x55a7,0x7d3d}, {0x55a9,0x6a67}, - {0x55aa,0x5f43}, {0x55ab,0x5152}, {0x55ac,0x4e62}, {0x55ae,0x5324}, {0x55c5,0x7d2b}, {0x55c7,0x5f60}, {0x55d4,0x7247}, {0x55da,0x6770}, {0x55dc,0x506e}, {0x55df,0x732a}, - {0x55e3,0x5e4b}, {0x55e4,0x7638}, {0x55fd,0x6175}, {0x55fe,0x7133}, {0x5606,0x7723}, {0x5609,0x4a29}, {0x5614,0x4f25}, {0x5617,0x5f44}, {0x562f,0x6130}, {0x5632,0x703f}, - {0x5634,0x7624}, {0x5636,0x6336}, {0x5653,0x7a46}, {0x5668,0x506f}, {0x566b,0x7d6d}, {0x5674,0x5d44}, {0x5686,0x7c77}, {0x56a5,0x663f}, {0x56ac,0x5e2d}, {0x56ae,0x7a3f}, - {0x56b4,0x6571}, {0x56bc,0x6d44}, {0x56ca,0x5225}, {0x56cd,0x7d6e}, {0x56d1,0x7536}, {0x56da,0x6176}, {0x56db,0x5e4c}, {0x56de,0x7c5e}, {0x56e0,0x6c57}, {0x56f0,0x4d5d}, - {0x56f9,0x5637}, {0x56fa,0x4d33}, {0x5703,0x7855}, {0x5704,0x6558}, {0x5708,0x4f6a}, {0x570b,0x4f50}, {0x570d,0x6a4c}, {0x5712,0x6a2e}, {0x5713,0x6a2d}, {0x5716,0x5371}, - {0x5718,0x5325}, {0x571f,0x774f}, {0x5728,0x6e24}, {0x572d,0x5024}, {0x5730,0x7222}, {0x573b,0x5070}, {0x5740,0x7223}, {0x5742,0x7778}, {0x5747,0x5033}, {0x574a,0x5b29}, - {0x574d,0x533b}, {0x574e,0x4a6c}, {0x5750,0x7126}, {0x5751,0x4b55}, {0x5761,0x7767}, {0x5764,0x4d5e}, {0x5766,0x7724}, {0x576a,0x7840}, {0x576e,0x535d}, {0x5770,0x4c50}, - {0x5775,0x4f26}, {0x577c,0x7673}, {0x5782,0x6177}, {0x5788,0x535c}, {0x578b,0x7a7e}, {0x5793,0x7a27}, {0x57a0,0x6b59}, {0x57a2,0x4f27}, {0x57a3,0x6a2f}, {0x57c3,0x646f}, - {0x57c7,0x6939}, {0x57c8,0x7158}, {0x57cb,0x5858}, {0x57ce,0x6072}, {0x57df,0x6634}, {0x57e0,0x5c7c}, {0x57f0,0x7371}, {0x57f4,0x6350}, {0x57f7,0x727b}, {0x57f9,0x5b46}, - {0x57fa,0x5071}, {0x57fc,0x5072}, {0x5800,0x4f5c}, {0x5802,0x5351}, {0x5805,0x4c31}, {0x5806,0x7758}, {0x5808,0x4b28}, {0x5809,0x6b3c}, {0x580a,0x643e}, {0x581e,0x745c}, - {0x5821,0x5c42}, {0x5824,0x7027}, {0x5827,0x6640}, {0x582a,0x4a6d}, {0x582f,0x686b}, {0x5830,0x6568}, {0x5831,0x5c43}, {0x5834,0x6d5e}, {0x5835,0x5372}, {0x583a,0x4c77}, - {0x584a,0x4e54}, {0x584b,0x672b}, {0x584f,0x4b43}, {0x5851,0x6131}, {0x5854,0x7732}, {0x5857,0x5373}, {0x5858,0x5352}, {0x585a,0x7540}, {0x585e,0x5f5d}, {0x5861,0x6e73}, - {0x5862,0x6771}, {0x5864,0x7d34}, {0x5875,0x7248}, {0x5879,0x7352}, {0x587c,0x6e74}, {0x587e,0x6253}, {0x5883,0x4c51}, {0x5885,0x5f6a}, {0x5889,0x693a}, {0x5893,0x5957}, - {0x589c,0x754d}, {0x589e,0x7172}, {0x589f,0x7a47}, {0x58a8,0x5978}, {0x58a9,0x5442}, {0x58ae,0x7665}, {0x58b3,0x5d45}, {0x58ba,0x6772}, {0x58bb,0x6d5f}, {0x58be,0x4a4b}, - {0x58c1,0x5b7a}, {0x58c5,0x6835}, {0x58c7,0x5326}, {0x58ce,0x7d35}, {0x58d1,0x7949}, {0x58d3,0x6462}, {0x58d5,0x7b3d}, {0x58d8,0x5724}, {0x58d9,0x4e45}, {0x58de,0x4e55}, - {0x58df,0x5666}, {0x58e4,0x653d}, {0x58eb,0x5e4d}, {0x58ec,0x6c73}, {0x58ef,0x6d60}, {0x58f9,0x6c6c}, {0x58fa,0x7b3e}, {0x58fb,0x5f6b}, {0x58fd,0x6178}, {0x590f,0x793e}, - {0x5914,0x5073}, {0x5915,0x602a}, {0x5916,0x6862}, {0x5919,0x6254}, {0x591a,0x527d}, {0x591c,0x6528}, {0x5922,0x5953}, {0x5927,0x535e}, {0x5929,0x7438}, {0x592a,0x773c}, - {0x592b,0x5c7d}, {0x592d,0x686c}, {0x592e,0x6467}, {0x5931,0x6377}, {0x5937,0x6c28}, {0x593e,0x7a71}, {0x5944,0x6572}, {0x5947,0x5074}, {0x5948,0x522f}, {0x5949,0x5c65}, - {0x594e,0x5025}, {0x594f,0x7134}, {0x5950,0x7c31}, {0x5951,0x4c78}, {0x5954,0x5d46}, {0x5955,0x7a51}, {0x5957,0x775f}, {0x595a,0x7a28}, {0x5960,0x6e75}, {0x5962,0x5e4e}, - {0x5967,0x6773}, {0x596a,0x772c}, {0x596b,0x6b44}, {0x596c,0x6d61}, {0x596d,0x602b}, {0x596e,0x5d47}, {0x5973,0x5233}, {0x5974,0x523f}, {0x5978,0x4a4c}, {0x597d,0x7b3f}, - {0x5982,0x657d}, {0x5983,0x5d65}, {0x5984,0x584d}, {0x598a,0x6c74}, {0x5993,0x5075}, {0x5996,0x686d}, {0x5997,0x5052}, {0x5999,0x5958}, {0x59a5,0x7666}, {0x59a8,0x5b2a}, - {0x59ac,0x7760}, {0x59b9,0x5859}, {0x59bb,0x7423}, {0x59be,0x745d}, {0x59c3,0x6f51}, {0x59c6,0x5935}, {0x59c9,0x6d2b}, {0x59cb,0x6337}, {0x59d0,0x6e3b}, {0x59d1,0x4d34}, - {0x59d3,0x6073}, {0x59d4,0x6a4d}, {0x59d9,0x6c75}, {0x59da,0x686e}, {0x59dc,0x4b29}, {0x59dd,0x712f}, {0x59e6,0x4a4d}, {0x59e8,0x6c29}, {0x59ea,0x726b}, {0x59ec,0x7d6f}, - {0x59ee,0x7973}, {0x59f8,0x6641}, {0x59fb,0x6c58}, {0x59ff,0x6d2c}, {0x5a01,0x6a4e}, {0x5a03,0x685f}, {0x5a11,0x5e4f}, {0x5a18,0x5226}, {0x5a1b,0x6774}, {0x5a1c,0x5156}, - {0x5a1f,0x6642}, {0x5a20,0x6363}, {0x5a25,0x6430}, {0x5a29,0x5834}, {0x5a36,0x7625}, {0x5a3c,0x735e}, {0x5a41,0x5725}, {0x5a46,0x7768}, {0x5a49,0x6846}, {0x5a5a,0x7b66}, - {0x5a62,0x5d66}, {0x5a66,0x5c7e}, {0x5a92,0x585a}, {0x5a9a,0x5a2c}, {0x5a9b,0x6a30}, {0x5aa4,0x6338}, {0x5ac1,0x4a2a}, {0x5ac2,0x6179}, {0x5ac4,0x6a31}, {0x5ac9,0x726c}, - {0x5acc,0x7a6e}, {0x5ae1,0x6e55}, {0x5ae6,0x7974}, {0x5ae9,0x526c}, {0x5b05,0x7b7b}, {0x5b09,0x7d70}, {0x5b0b,0x603d}, {0x5b0c,0x4e63}, {0x5b16,0x7846}, {0x5b2a,0x5e2e}, - {0x5b40,0x5f45}, {0x5b43,0x653e}, {0x5b50,0x6d2d}, {0x5b51,0x7a6a}, {0x5b54,0x4d6e}, {0x5b55,0x6d26}, {0x5b57,0x6d2e}, {0x5b58,0x706d}, {0x5b5a,0x5d21}, {0x5b5c,0x6d2f}, - {0x5b5d,0x7c78}, {0x5b5f,0x586b}, {0x5b63,0x4c79}, {0x5b64,0x4d35}, {0x5b69,0x7a29}, {0x5b6b,0x615d}, {0x5b70,0x6255}, {0x5b71,0x6d4f}, {0x5b75,0x5d22}, {0x5b78,0x794a}, - {0x5b7a,0x6a68}, {0x5b7c,0x656d}, {0x5b85,0x536b}, {0x5b87,0x6954}, {0x5b88,0x617a}, {0x5b89,0x644c}, {0x5b8b,0x6164}, {0x5b8c,0x6847}, {0x5b8f,0x4e5b}, {0x5b93,0x5c55}, - {0x5b95,0x7735}, {0x5b96,0x7c73}, {0x5b97,0x7073}, {0x5b98,0x4e2f}, {0x5b99,0x7135}, {0x5b9a,0x6f52}, {0x5b9b,0x6848}, {0x5b9c,0x6b71}, {0x5ba2,0x4b54}, {0x5ba3,0x603e}, - {0x5ba4,0x6378}, {0x5ba5,0x6a69}, {0x5ba6,0x7c32}, {0x5bac,0x6074}, {0x5bae,0x4f60}, {0x5bb0,0x6e25}, {0x5bb3,0x7a2a}, {0x5bb4,0x6643}, {0x5bb5,0x6132}, {0x5bb6,0x4a2b}, - {0x5bb8,0x6364}, {0x5bb9,0x693b}, {0x5bbf,0x6256}, {0x5bc0,0x7372}, {0x5bc2,0x6e56}, {0x5bc3,0x6a32}, {0x5bc4,0x5076}, {0x5bc5,0x6c59}, {0x5bc6,0x5a4b}, {0x5bc7,0x4f28}, - {0x5bcc,0x5d23}, {0x5bd0,0x585b}, {0x5bd2,0x794e}, {0x5bd3,0x6955}, {0x5bd4,0x6351}, {0x5bd7,0x523c}, {0x5bde,0x582c}, {0x5bdf,0x734c}, {0x5be1,0x4d7b}, {0x5be2,0x7656}, - {0x5be4,0x6775}, {0x5be5,0x686f}, {0x5be6,0x6379}, {0x5be7,0x523b}, {0x5be8,0x7373}, {0x5be9,0x637b}, {0x5beb,0x5e50}, {0x5bec,0x4e30}, {0x5bee,0x5677}, {0x5bef,0x7159}, - {0x5bf5,0x7541}, {0x5bf6,0x5c44}, {0x5bf8,0x753b}, {0x5bfa,0x5e51}, {0x5c01,0x5c66}, {0x5c04,0x5e52}, {0x5c07,0x6d62}, {0x5c08,0x6e76}, {0x5c09,0x6a4f}, {0x5c0a,0x706e}, - {0x5c0b,0x637c}, {0x5c0d,0x535f}, {0x5c0e,0x5374}, {0x5c0f,0x6133}, {0x5c11,0x6134}, {0x5c16,0x7453}, {0x5c19,0x5f46}, {0x5c24,0x6956}, {0x5c28,0x5b2b}, {0x5c31,0x7626}, - {0x5c38,0x6339}, {0x5c39,0x6b45}, {0x5c3a,0x7429}, {0x5c3b,0x4d36}, {0x5c3c,0x5279}, {0x5c3e,0x5a2d}, {0x5c3f,0x5263}, {0x5c40,0x4f51}, {0x5c45,0x4b5c}, {0x5c46,0x4c7a}, - {0x5c48,0x4f5d}, {0x5c4b,0x6829}, {0x5c4d,0x633b}, {0x5c4e,0x633a}, {0x5c51,0x605a}, {0x5c55,0x6e77}, {0x5c5b,0x5c33}, {0x5c60,0x5375}, {0x5c62,0x5726}, {0x5c64,0x7635}, - {0x5c65,0x575b}, {0x5c6c,0x6155}, {0x5c6f,0x546a}, {0x5c71,0x5f23}, {0x5c79,0x7d5f}, {0x5c90,0x5077}, {0x5c91,0x6d54}, {0x5ca1,0x4b2a}, {0x5ca9,0x645b}, {0x5cab,0x617b}, - {0x5cac,0x4b22}, {0x5cb1,0x5360}, {0x5cb3,0x643f}, {0x5cb5,0x7b40}, {0x5cb7,0x5a3e}, {0x5cb8,0x644d}, {0x5cba,0x5639}, {0x5cbe,0x6f40}, {0x5cc0,0x617c}, {0x5cd9,0x7639}, - {0x5ce0,0x5f47}, {0x5ce8,0x6431}, {0x5cef,0x5c67}, {0x5cf0,0x5c68}, {0x5cf4,0x7a56}, {0x5cf6,0x5376}, {0x5cfb,0x715a}, {0x5cfd,0x7a72}, {0x5d07,0x627d}, {0x5d0d,0x554f}, - {0x5d0e,0x5078}, {0x5d11,0x4d5f}, {0x5d14,0x754b}, {0x5d16,0x6470}, {0x5d17,0x4b2b}, {0x5d19,0x5744}, -}; - - -/* Map Table including unicode to ksc5601 hanja */ -static const Mapping unicode_to_ksc5601_hanja[4888] = { - {0x4e00,0x6c69}, {0x4e01,0x6f4b}, {0x4e03,0x7652}, {0x4e07,0x5832}, {0x4e08,0x6d5b}, {0x4e09,0x5f32}, {0x4e0a,0x5f3e}, {0x4e0b,0x793b}, {0x4e0d,0x5c74}, {0x4e11,0x7564}, - {0x4e14,0x7326}, {0x4e15,0x5d60}, {0x4e16,0x6126}, {0x4e18,0x4e78}, {0x4e19,0x5c30}, {0x4e1e,0x632a}, {0x4e2d,0x7169}, {0x4e32,0x4d7a}, {0x4e38,0x7c2f}, {0x4e39,0x5321}, - {0x4e3b,0x712b}, {0x4e42,0x6751}, {0x4e43,0x522c}, {0x4e45,0x4e79}, {0x4e4b,0x717d}, {0x4e4d,0x5e3f}, {0x4e4e,0x7b3a}, {0x4e4f,0x7939}, {0x4e56,0x4e52}, {0x4e58,0x632b}, - {0x4e59,0x6b60}, {0x4e5d,0x4e7a}, {0x4e5e,0x4b77}, {0x4e5f,0x6525}, {0x4e6b,0x4a61}, {0x4e6d,0x544c}, {0x4e73,0x6a61}, {0x4e76,0x5c63}, {0x4e77,0x5f2d}, {0x4e7e,0x4b6b}, - {0x4e82,0x552f}, {0x4e86,0x5675}, {0x4e88,0x6578}, {0x4e8b,0x5e40}, {0x4e8c,0x6c23}, {0x4e8e,0x694d}, {0x4e90,0x6a27}, {0x4e91,0x6976}, {0x4e92,0x7b3b}, {0x4e94,0x6769}, - {0x4e95,0x6f4c}, {0x4e98,0x5066}, {0x4e9b,0x5e41}, {0x4e9e,0x642c}, {0x4ea1,0x584c}, {0x4ea2,0x7971}, {0x4ea4,0x4e5f}, {0x4ea5,0x7a24}, {0x4ea6,0x6632}, {0x4ea8,0x7a7b}, - {0x4eab,0x7a3d}, {0x4eac,0x4c48}, {0x4ead,0x6f4d}, {0x4eae,0x5555}, {0x4eb6,0x5322}, {0x4eba,0x6c51}, {0x4ec0,0x6427}, {0x4ec1,0x6c52}, {0x4ec4,0x7631}, {0x4ec7,0x4e7b}, - {0x4eca,0x5051}, {0x4ecb,0x4b3f}, {0x4ecd,0x6d24}, {0x4ed4,0x6d28}, {0x4ed5,0x5e42}, {0x4ed6,0x7662}, {0x4ed7,0x6d5c}, {0x4ed8,0x5c75}, {0x4ed9,0x6039}, {0x4edd,0x544e}, - {0x4edf,0x7435}, {0x4ee3,0x535b}, {0x4ee4,0x5635}, {0x4ee5,0x6c24}, {0x4ef0,0x6466}, {0x4ef2,0x716a}, {0x4ef6,0x4b6c}, {0x4ef7,0x4b40}, {0x4efb,0x6c72}, {0x4f01,0x506a}, - {0x4f09,0x7972}, {0x4f0a,0x6c25}, {0x4f0b,0x505f}, {0x4f0d,0x676a}, {0x4f0e,0x506b}, {0x4f0f,0x5c51}, {0x4f10,0x5b69}, {0x4f11,0x7d4c}, {0x4f2f,0x5b57}, {0x4f34,0x5a61}, - {0x4f36,0x5636}, {0x4f38,0x635f}, {0x4f3a,0x5e43}, {0x4f3c,0x5e44}, {0x4f3d,0x4a21}, {0x4f43,0x6e6c}, {0x4f46,0x5323}, {0x4f47,0x6e37}, {0x4f48,0x784f}, {0x4f4d,0x6a48}, - {0x4f4e,0x6e38}, {0x4f4f,0x712c}, {0x4f50,0x7125}, {0x4f51,0x694e}, {0x4f55,0x793c}, {0x4f59,0x6579}, {0x4f5a,0x6c6a}, {0x4f5b,0x5d56}, {0x4f5c,0x6d42}, {0x4f69,0x7825}, - {0x4f6f,0x653a}, {0x4f70,0x5b58}, {0x4f73,0x4a22}, {0x4f76,0x514d}, {0x4f7a,0x6e6d}, {0x4f7e,0x6c6b}, {0x4f7f,0x5e45}, {0x4f81,0x6360}, {0x4f83,0x4a49}, {0x4f84,0x7269}, - {0x4f86,0x554e}, {0x4f88,0x7636}, {0x4f8a,0x4e42}, {0x4f8b,0x5647}, {0x4f8d,0x6334}, {0x4f8f,0x712d}, {0x4f91,0x6a62}, {0x4f96,0x5742}, {0x4f98,0x7327}, {0x4f9b,0x4d6a}, - {0x4f9d,0x6b6e}, {0x4fae,0x5932}, {0x4faf,0x7d25}, {0x4fb5,0x7655}, {0x4fb6,0x5562}, {0x4fbf,0x7835}, {0x4fc2,0x4c75}, {0x4fc3,0x7535}, {0x4fc4,0x642d}, {0x4fc9,0x676b}, - {0x4fca,0x7155}, {0x4fce,0x703b}, {0x4fd1,0x6935}, {0x4fd3,0x4c49}, {0x4fd4,0x7a55}, {0x4fd7,0x6154}, {0x4fda,0x5756}, {0x4fdd,0x5c41}, {0x4fdf,0x5e46}, {0x4fe0,0x7a6f}, - {0x4fe1,0x6361}, {0x4fee,0x6173}, {0x4fef,0x5c76}, {0x4ff1,0x4e7c}, {0x4ff3,0x5b44}, {0x4ff5,0x7871}, {0x4ff8,0x5c64}, {0x4ffa,0x656f}, {0x5002,0x5c31}, {0x5006,0x5556}, - {0x5009,0x735a}, {0x500b,0x4b41}, {0x500d,0x5b43}, {0x5011,0x597a}, {0x5012,0x536e}, {0x5016,0x7a38}, {0x5019,0x7d26}, {0x501a,0x6b6f}, {0x501c,0x7426}, {0x501e,0x4c4a}, - {0x501f,0x7328}, {0x5021,0x735b}, {0x5023,0x5b27}, {0x5024,0x7637}, {0x5026,0x4f66}, {0x5027,0x7072}, {0x5028,0x4b5a}, {0x502a,0x6752}, {0x502b,0x5743}, {0x502c,0x7670}, - {0x502d,0x685e}, {0x503b,0x6526}, {0x5043,0x6567}, {0x5047,0x4a23}, {0x5048,0x4c27}, {0x5049,0x6a49}, {0x504f,0x7836}, {0x5055,0x7a25}, {0x505a,0x712e}, {0x505c,0x6f4e}, - {0x5065,0x4b6d}, {0x5074,0x7630}, {0x5075,0x6f4f}, {0x5076,0x694f}, {0x5078,0x775e}, {0x5080,0x4e53}, {0x5085,0x5c77}, {0x508d,0x5b28}, {0x5091,0x4b78}, {0x5098,0x5f21}, - {0x5099,0x5d61}, {0x50ac,0x754a}, {0x50ad,0x6936}, {0x50b2,0x676c}, {0x50b3,0x6e6e}, {0x50b5,0x7370}, {0x50b7,0x5f3f}, {0x50be,0x4c4b}, {0x50c5,0x5041}, {0x50c9,0x7452}, - {0x50ca,0x603a}, {0x50cf,0x5f40}, {0x50d1,0x4e60}, {0x50d5,0x5c52}, {0x50d6,0x7d6a}, {0x50da,0x5676}, {0x50de,0x6a4a}, {0x50e5,0x6869}, {0x50e7,0x632c}, {0x50ed,0x7350}, - {0x50f9,0x4a24}, {0x50fb,0x5b78}, {0x50ff,0x5e47}, {0x5100,0x6b70}, {0x5101,0x7156}, {0x5104,0x6562}, {0x5106,0x4c4c}, {0x5109,0x4b7b}, {0x5112,0x6a63}, {0x511f,0x5f41}, - {0x5121,0x566d}, {0x512a,0x6950}, {0x5132,0x6e39}, {0x5137,0x5563}, {0x513a,0x5153}, {0x513c,0x6570}, {0x5140,0x6834}, {0x5141,0x6b43}, {0x5143,0x6a2a}, {0x5144,0x7a7c}, - {0x5145,0x7576}, {0x5146,0x703c}, {0x5147,0x7d54}, {0x5148,0x603b}, {0x5149,0x4e43}, {0x514b,0x503a}, {0x514c,0x773a}, {0x514d,0x5873}, {0x514e,0x774d}, {0x5152,0x642e}, - {0x515c,0x545f}, {0x5162,0x5067}, {0x5165,0x6c7d}, {0x5167,0x522e}, {0x5168,0x6e6f}, {0x5169,0x5557}, {0x516a,0x6a64}, {0x516b,0x7822}, {0x516c,0x4d6b}, {0x516d,0x573f}, - {0x516e,0x7b31}, {0x5171,0x4d6c}, {0x5175,0x5c32}, {0x5176,0x506c}, {0x5177,0x4e7d}, {0x5178,0x6e70}, {0x517c,0x4c42}, {0x5180,0x506d}, {0x5186,0x6577}, {0x518a,0x737c}, - {0x518d,0x6e22}, {0x5192,0x5933}, {0x5195,0x5874}, {0x5197,0x6937}, {0x51a0,0x4e2e}, {0x51a5,0x5922}, {0x51aa,0x5871}, {0x51ac,0x544f}, {0x51b6,0x6527}, {0x51b7,0x5552}, - {0x51bd,0x5629}, {0x51c4,0x7422}, {0x51c6,0x7157}, {0x51c9,0x5558}, {0x51cb,0x703d}, {0x51cc,0x5750}, {0x51cd,0x5450}, {0x51dc,0x574f}, {0x51dd,0x6b6a}, {0x51de,0x7d6b}, - {0x51e1,0x5b6d}, {0x51f0,0x7c45}, {0x51f1,0x4b42}, {0x51f6,0x7d55}, {0x51f8,0x7448}, {0x51f9,0x686a}, {0x51fa,0x7573}, {0x51fd,0x795e}, {0x5200,0x536f}, {0x5203,0x6c53}, - {0x5206,0x5d42}, {0x5207,0x6f37}, {0x5208,0x6754}, {0x520a,0x4a4a}, {0x520e,0x597b}, {0x5211,0x7a7d}, {0x5217,0x562a}, {0x521d,0x7478}, {0x5224,0x7777}, {0x5225,0x5c2c}, - {0x5229,0x5757}, {0x522a,0x5f22}, {0x522e,0x4e3e}, {0x5230,0x5370}, {0x5236,0x7024}, {0x5237,0x616c}, {0x5238,0x4f67}, {0x5239,0x734b}, {0x523a,0x6d29}, {0x523b,0x4a3e}, - {0x5243,0x746f}, {0x5247,0x764e}, {0x524a,0x5e7b}, {0x524b,0x503b}, {0x524c,0x5537}, {0x524d,0x6e71}, {0x5254,0x7428}, {0x5256,0x5c78}, {0x525b,0x4b27}, {0x525d,0x5a4e}, - {0x5261,0x6066}, {0x5269,0x6d25}, {0x526a,0x6e72}, {0x526f,0x5c79}, {0x5272,0x795c}, {0x5275,0x735c}, {0x527d,0x7872}, {0x527f,0x7479}, {0x5283,0x7c71}, {0x5287,0x503c}, - {0x5288,0x5b79}, {0x5289,0x5731}, {0x528d,0x4b7c}, {0x5291,0x7025}, {0x5292,0x4b7d}, {0x529b,0x5574}, {0x529f,0x4d6d}, {0x52a0,0x4a25}, {0x52a3,0x562b}, {0x52a4,0x5042}, - {0x52a9,0x703e}, {0x52aa,0x523d}, {0x52ab,0x4c24}, {0x52be,0x7a36}, {0x52c1,0x4c4d}, {0x52c3,0x5a7a}, {0x52c5,0x764f}, {0x52c7,0x6938}, {0x52c9,0x5875}, {0x52cd,0x4c4e}, - {0x52d2,0x574d}, {0x52d5,0x5451}, {0x52d6,0x696d}, {0x52d8,0x4a6b}, {0x52d9,0x5962}, {0x52db,0x7d32}, {0x52dd,0x632d}, {0x52de,0x564c}, {0x52df,0x5934}, {0x52e2,0x6127}, - {0x52e3,0x6e53}, {0x52e4,0x5043}, {0x52f3,0x7d33}, {0x52f5,0x5564}, {0x52f8,0x4f68}, {0x52fa,0x6d43}, {0x52fb,0x5032}, {0x52fe,0x4e7e}, {0x52ff,0x5a28}, {0x5305,0x7850}, - {0x5308,0x7d56}, {0x530d,0x7851}, {0x530f,0x7852}, {0x5310,0x5c53}, {0x5315,0x5d62}, {0x5316,0x7b79}, {0x5317,0x5d41}, {0x5319,0x6335}, {0x5320,0x6d5d}, {0x5321,0x4e44}, - {0x5323,0x4b21}, {0x532a,0x5d63}, {0x532f,0x7c5d}, {0x5339,0x792f}, {0x533f,0x527b}, {0x5340,0x4f21}, {0x5341,0x6428}, {0x5343,0x7436}, {0x5344,0x6c7e}, {0x5347,0x632e}, - {0x5348,0x676d}, {0x5349,0x7d41}, {0x534a,0x5a62}, {0x534d,0x5833}, {0x5351,0x5d64}, {0x5352,0x706f}, {0x5353,0x7671}, {0x5354,0x7a70}, {0x5357,0x5175}, {0x535a,0x5a4f}, - {0x535c,0x5c54}, {0x535e,0x5c26}, {0x5360,0x6f3f}, {0x5366,0x4e4f}, {0x5368,0x6059}, {0x536f,0x5956}, {0x5370,0x6c54}, {0x5371,0x6a4b}, {0x5374,0x4a3f}, {0x5375,0x5530}, - {0x5377,0x4f69}, {0x537d,0x716d}, {0x537f,0x4c4f}, {0x5384,0x6478}, {0x5393,0x646d}, {0x5398,0x5758}, {0x539a,0x7d27}, {0x539f,0x6a2b}, {0x53a0,0x7632}, {0x53a5,0x4f70}, - {0x53a6,0x793d}, {0x53ad,0x6674}, {0x53bb,0x4b5b}, {0x53c3,0x7351}, {0x53c8,0x6951}, {0x53c9,0x7329}, {0x53ca,0x5060}, {0x53cb,0x6952}, {0x53cd,0x5a63}, {0x53d4,0x6252}, - {0x53d6,0x7622}, {0x53d7,0x6174}, {0x53db,0x5a64}, {0x53e1,0x6755}, {0x53e2,0x753f}, {0x53e3,0x4f22}, {0x53e4,0x4d2f}, {0x53e5,0x4f23}, {0x53e9,0x4d30}, {0x53ea,0x717e}, - {0x53eb,0x5023}, {0x53ec,0x612f}, {0x53ed,0x7823}, {0x53ef,0x4a26}, {0x53f0,0x773b}, {0x53f1,0x726a}, {0x53f2,0x5e48}, {0x53f3,0x6953}, {0x53f8,0x5e49}, {0x5403,0x7d5e}, - {0x5404,0x4a40}, {0x5408,0x796a}, {0x5409,0x514e}, {0x540a,0x6e54}, {0x540c,0x5452}, {0x540d,0x5923}, {0x540e,0x7d28}, {0x540f,0x5759}, {0x5410,0x774e}, {0x5411,0x7a3e}, - {0x541b,0x4f56}, {0x541d,0x5770}, {0x541f,0x6b61}, {0x5420,0x7845}, {0x5426,0x5c7a}, {0x5429,0x5d43}, {0x542b,0x795f}, {0x5433,0x676f}, {0x5438,0x7d65}, {0x5439,0x7623}, - {0x543b,0x597c}, {0x543c,0x7d29}, {0x543e,0x676e}, {0x5442,0x5565}, {0x5448,0x6f50}, {0x544a,0x4d31}, {0x5451,0x7722}, {0x5468,0x7132}, {0x546a,0x7131}, {0x5471,0x4d32}, - {0x5473,0x5a2b}, {0x5475,0x4a27}, {0x547b,0x6362}, {0x547c,0x7b3c}, {0x547d,0x5924}, {0x5480,0x6e3a}, {0x5486,0x7853}, {0x548c,0x7b7a}, {0x548e,0x4f24}, {0x5490,0x5c7b}, - {0x54a4,0x7663}, {0x54a8,0x6d2a}, {0x54ab,0x7221}, {0x54ac,0x4e61}, {0x54b3,0x7a26}, {0x54b8,0x7960}, {0x54bd,0x6c56}, {0x54c0,0x646e}, {0x54c1,0x7921}, {0x54c4,0x7b6f}, - {0x54c8,0x796b}, {0x54c9,0x6e23}, {0x54e1,0x6a2c}, {0x54e5,0x4a28}, {0x54e8,0x747a}, {0x54ed,0x4d56}, {0x54ee,0x7c76}, {0x54f2,0x7449}, {0x54fa,0x7854}, {0x5504,0x7826}, - {0x5506,0x5e4a}, {0x5507,0x7246}, {0x550e,0x575a}, {0x5510,0x5350}, {0x551c,0x5845}, {0x552f,0x6a66}, {0x5531,0x735d}, {0x5535,0x645a}, {0x553e,0x7664}, {0x5544,0x7672}, - {0x5546,0x5f42}, {0x554f,0x597d}, {0x5553,0x4c76}, {0x5556,0x533a}, {0x555e,0x642f}, {0x5563,0x7961}, {0x557c,0x7026}, {0x5580,0x4b53}, {0x5584,0x603c}, {0x5586,0x744a}, - {0x5587,0x547a}, {0x5589,0x7d2a}, {0x558a,0x7962}, {0x5598,0x7437}, {0x5599,0x7d42}, {0x559a,0x7c30}, {0x559c,0x7d6c}, {0x559d,0x4a62}, {0x55a7,0x7d3d}, {0x55a9,0x6a67}, - {0x55aa,0x5f43}, {0x55ab,0x5152}, {0x55ac,0x4e62}, {0x55ae,0x5324}, {0x55c5,0x7d2b}, {0x55c7,0x5f60}, {0x55d4,0x7247}, {0x55da,0x6770}, {0x55dc,0x506e}, {0x55df,0x732a}, - {0x55e3,0x5e4b}, {0x55e4,0x7638}, {0x55fd,0x6175}, {0x55fe,0x7133}, {0x5606,0x7723}, {0x5609,0x4a29}, {0x5614,0x4f25}, {0x5617,0x5f44}, {0x562f,0x6130}, {0x5632,0x703f}, - {0x5634,0x7624}, {0x5636,0x6336}, {0x5653,0x7a46}, {0x5668,0x506f}, {0x566b,0x7d6d}, {0x5674,0x5d44}, {0x5686,0x7c77}, {0x56a5,0x663f}, {0x56ac,0x5e2d}, {0x56ae,0x7a3f}, - {0x56b4,0x6571}, {0x56bc,0x6d44}, {0x56ca,0x5225}, {0x56cd,0x7d6e}, {0x56d1,0x7536}, {0x56da,0x6176}, {0x56db,0x5e4c}, {0x56de,0x7c5e}, {0x56e0,0x6c57}, {0x56f0,0x4d5d}, - {0x56f9,0x5637}, {0x56fa,0x4d33}, {0x5703,0x7855}, {0x5704,0x6558}, {0x5708,0x4f6a}, {0x570b,0x4f50}, {0x570d,0x6a4c}, {0x5712,0x6a2e}, {0x5713,0x6a2d}, {0x5716,0x5371}, - {0x5718,0x5325}, {0x571f,0x774f}, {0x5728,0x6e24}, {0x572d,0x5024}, {0x5730,0x7222}, {0x573b,0x5070}, {0x5740,0x7223}, {0x5742,0x7778}, {0x5747,0x5033}, {0x574a,0x5b29}, - {0x574d,0x533b}, {0x574e,0x4a6c}, {0x5750,0x7126}, {0x5751,0x4b55}, {0x5761,0x7767}, {0x5764,0x4d5e}, {0x5766,0x7724}, {0x576a,0x7840}, {0x576e,0x535d}, {0x5770,0x4c50}, - {0x5775,0x4f26}, {0x577c,0x7673}, {0x5782,0x6177}, {0x5788,0x535c}, {0x578b,0x7a7e}, {0x5793,0x7a27}, {0x57a0,0x6b59}, {0x57a2,0x4f27}, {0x57a3,0x6a2f}, {0x57c3,0x646f}, - {0x57c7,0x6939}, {0x57c8,0x7158}, {0x57cb,0x5858}, {0x57ce,0x6072}, {0x57df,0x6634}, {0x57e0,0x5c7c}, {0x57f0,0x7371}, {0x57f4,0x6350}, {0x57f7,0x727b}, {0x57f9,0x5b46}, - {0x57fa,0x5071}, {0x57fc,0x5072}, {0x5800,0x4f5c}, {0x5802,0x5351}, {0x5805,0x4c31}, {0x5806,0x7758}, {0x5808,0x4b28}, {0x5809,0x6b3c}, {0x580a,0x643e}, {0x581e,0x745c}, - {0x5821,0x5c42}, {0x5824,0x7027}, {0x5827,0x6640}, {0x582a,0x4a6d}, {0x582f,0x686b}, {0x5830,0x6568}, {0x5831,0x5c43}, {0x5834,0x6d5e}, {0x5835,0x5372}, {0x583a,0x4c77}, - {0x584a,0x4e54}, {0x584b,0x672b}, {0x584f,0x4b43}, {0x5851,0x6131}, {0x5854,0x7732}, {0x5857,0x5373}, {0x5858,0x5352}, {0x585a,0x7540}, {0x585e,0x5f5d}, {0x5861,0x6e73}, - {0x5862,0x6771}, {0x5864,0x7d34}, {0x5875,0x7248}, {0x5879,0x7352}, {0x587c,0x6e74}, {0x587e,0x6253}, {0x5883,0x4c51}, {0x5885,0x5f6a}, {0x5889,0x693a}, {0x5893,0x5957}, - {0x589c,0x754d}, {0x589e,0x7172}, {0x589f,0x7a47}, {0x58a8,0x5978}, {0x58a9,0x5442}, {0x58ae,0x7665}, {0x58b3,0x5d45}, {0x58ba,0x6772}, {0x58bb,0x6d5f}, {0x58be,0x4a4b}, - {0x58c1,0x5b7a}, {0x58c5,0x6835}, {0x58c7,0x5326}, {0x58ce,0x7d35}, {0x58d1,0x7949}, {0x58d3,0x6462}, {0x58d5,0x7b3d}, {0x58d8,0x5724}, {0x58d9,0x4e45}, {0x58de,0x4e55}, - {0x58df,0x5666}, {0x58e4,0x653d}, {0x58eb,0x5e4d}, {0x58ec,0x6c73}, {0x58ef,0x6d60}, {0x58f9,0x6c6c}, {0x58fa,0x7b3e}, {0x58fb,0x5f6b}, {0x58fd,0x6178}, {0x590f,0x793e}, - {0x5914,0x5073}, {0x5915,0x602a}, {0x5916,0x6862}, {0x5919,0x6254}, {0x591a,0x527d}, {0x591c,0x6528}, {0x5922,0x5953}, {0x5927,0x535e}, {0x5929,0x7438}, {0x592a,0x773c}, - {0x592b,0x5c7d}, {0x592d,0x686c}, {0x592e,0x6467}, {0x5931,0x6377}, {0x5937,0x6c28}, {0x593e,0x7a71}, {0x5944,0x6572}, {0x5947,0x5074}, {0x5948,0x522f}, {0x5949,0x5c65}, - {0x594e,0x5025}, {0x594f,0x7134}, {0x5950,0x7c31}, {0x5951,0x4c78}, {0x5954,0x5d46}, {0x5955,0x7a51}, {0x5957,0x775f}, {0x595a,0x7a28}, {0x5960,0x6e75}, {0x5962,0x5e4e}, - {0x5967,0x6773}, {0x596a,0x772c}, {0x596b,0x6b44}, {0x596c,0x6d61}, {0x596d,0x602b}, {0x596e,0x5d47}, {0x5973,0x5233}, {0x5974,0x523f}, {0x5978,0x4a4c}, {0x597d,0x7b3f}, - {0x5982,0x657d}, {0x5983,0x5d65}, {0x5984,0x584d}, {0x598a,0x6c74}, {0x5993,0x5075}, {0x5996,0x686d}, {0x5997,0x5052}, {0x5999,0x5958}, {0x59a5,0x7666}, {0x59a8,0x5b2a}, - {0x59ac,0x7760}, {0x59b9,0x5859}, {0x59bb,0x7423}, {0x59be,0x745d}, {0x59c3,0x6f51}, {0x59c6,0x5935}, {0x59c9,0x6d2b}, {0x59cb,0x6337}, {0x59d0,0x6e3b}, {0x59d1,0x4d34}, - {0x59d3,0x6073}, {0x59d4,0x6a4d}, {0x59d9,0x6c75}, {0x59da,0x686e}, {0x59dc,0x4b29}, {0x59dd,0x712f}, {0x59e6,0x4a4d}, {0x59e8,0x6c29}, {0x59ea,0x726b}, {0x59ec,0x7d6f}, - {0x59ee,0x7973}, {0x59f8,0x6641}, {0x59fb,0x6c58}, {0x59ff,0x6d2c}, {0x5a01,0x6a4e}, {0x5a03,0x685f}, {0x5a11,0x5e4f}, {0x5a18,0x5226}, {0x5a1b,0x6774}, {0x5a1c,0x5156}, - {0x5a1f,0x6642}, {0x5a20,0x6363}, {0x5a25,0x6430}, {0x5a29,0x5834}, {0x5a36,0x7625}, {0x5a3c,0x735e}, {0x5a41,0x5725}, {0x5a46,0x7768}, {0x5a49,0x6846}, {0x5a5a,0x7b66}, - {0x5a62,0x5d66}, {0x5a66,0x5c7e}, {0x5a92,0x585a}, {0x5a9a,0x5a2c}, {0x5a9b,0x6a30}, {0x5aa4,0x6338}, {0x5ac1,0x4a2a}, {0x5ac2,0x6179}, {0x5ac4,0x6a31}, {0x5ac9,0x726c}, - {0x5acc,0x7a6e}, {0x5ae1,0x6e55}, {0x5ae6,0x7974}, {0x5ae9,0x526c}, {0x5b05,0x7b7b}, {0x5b09,0x7d70}, {0x5b0b,0x603d}, {0x5b0c,0x4e63}, {0x5b16,0x7846}, {0x5b2a,0x5e2e}, - {0x5b40,0x5f45}, {0x5b43,0x653e}, {0x5b50,0x6d2d}, {0x5b51,0x7a6a}, {0x5b54,0x4d6e}, {0x5b55,0x6d26}, {0x5b57,0x6d2e}, {0x5b58,0x706d}, {0x5b5a,0x5d21}, {0x5b5c,0x6d2f}, - {0x5b5d,0x7c78}, {0x5b5f,0x586b}, {0x5b63,0x4c79}, {0x5b64,0x4d35}, {0x5b69,0x7a29}, {0x5b6b,0x615d}, {0x5b70,0x6255}, {0x5b71,0x6d4f}, {0x5b75,0x5d22}, {0x5b78,0x794a}, - {0x5b7a,0x6a68}, {0x5b7c,0x656d}, {0x5b85,0x536b}, {0x5b87,0x6954}, {0x5b88,0x617a}, {0x5b89,0x644c}, {0x5b8b,0x6164}, {0x5b8c,0x6847}, {0x5b8f,0x4e5b}, {0x5b93,0x5c55}, - {0x5b95,0x7735}, {0x5b96,0x7c73}, {0x5b97,0x7073}, {0x5b98,0x4e2f}, {0x5b99,0x7135}, {0x5b9a,0x6f52}, {0x5b9b,0x6848}, {0x5b9c,0x6b71}, {0x5ba2,0x4b54}, {0x5ba3,0x603e}, - {0x5ba4,0x6378}, {0x5ba5,0x6a69}, {0x5ba6,0x7c32}, {0x5bac,0x6074}, {0x5bae,0x4f60}, {0x5bb0,0x6e25}, {0x5bb3,0x7a2a}, {0x5bb4,0x6643}, {0x5bb5,0x6132}, {0x5bb6,0x4a2b}, - {0x5bb8,0x6364}, {0x5bb9,0x693b}, {0x5bbf,0x6256}, {0x5bc0,0x7372}, {0x5bc2,0x6e56}, {0x5bc3,0x6a32}, {0x5bc4,0x5076}, {0x5bc5,0x6c59}, {0x5bc6,0x5a4b}, {0x5bc7,0x4f28}, - {0x5bcc,0x5d23}, {0x5bd0,0x585b}, {0x5bd2,0x794e}, {0x5bd3,0x6955}, {0x5bd4,0x6351}, {0x5bd7,0x523c}, {0x5bde,0x582c}, {0x5bdf,0x734c}, {0x5be1,0x4d7b}, {0x5be2,0x7656}, - {0x5be4,0x6775}, {0x5be5,0x686f}, {0x5be6,0x6379}, {0x5be7,0x523b}, {0x5be8,0x7373}, {0x5be9,0x637b}, {0x5beb,0x5e50}, {0x5bec,0x4e30}, {0x5bee,0x5677}, {0x5bef,0x7159}, - {0x5bf5,0x7541}, {0x5bf6,0x5c44}, {0x5bf8,0x753b}, {0x5bfa,0x5e51}, {0x5c01,0x5c66}, {0x5c04,0x5e52}, {0x5c07,0x6d62}, {0x5c08,0x6e76}, {0x5c09,0x6a4f}, {0x5c0a,0x706e}, - {0x5c0b,0x637c}, {0x5c0d,0x535f}, {0x5c0e,0x5374}, {0x5c0f,0x6133}, {0x5c11,0x6134}, {0x5c16,0x7453}, {0x5c19,0x5f46}, {0x5c24,0x6956}, {0x5c28,0x5b2b}, {0x5c31,0x7626}, - {0x5c38,0x6339}, {0x5c39,0x6b45}, {0x5c3a,0x7429}, {0x5c3b,0x4d36}, {0x5c3c,0x5279}, {0x5c3e,0x5a2d}, {0x5c3f,0x5263}, {0x5c40,0x4f51}, {0x5c45,0x4b5c}, {0x5c46,0x4c7a}, - {0x5c48,0x4f5d}, {0x5c4b,0x6829}, {0x5c4d,0x633b}, {0x5c4e,0x633a}, {0x5c51,0x605a}, {0x5c55,0x6e77}, {0x5c5b,0x5c33}, {0x5c60,0x5375}, {0x5c62,0x5726}, {0x5c64,0x7635}, - {0x5c65,0x575b}, {0x5c6c,0x6155}, {0x5c6f,0x546a}, {0x5c71,0x5f23}, {0x5c79,0x7d5f}, {0x5c90,0x5077}, {0x5c91,0x6d54}, {0x5ca1,0x4b2a}, {0x5ca9,0x645b}, {0x5cab,0x617b}, - {0x5cac,0x4b22}, {0x5cb1,0x5360}, {0x5cb3,0x643f}, {0x5cb5,0x7b40}, {0x5cb7,0x5a3e}, {0x5cb8,0x644d}, {0x5cba,0x5639}, {0x5cbe,0x6f40}, {0x5cc0,0x617c}, {0x5cd9,0x7639}, - {0x5ce0,0x5f47}, {0x5ce8,0x6431}, {0x5cef,0x5c67}, {0x5cf0,0x5c68}, {0x5cf4,0x7a56}, {0x5cf6,0x5376}, {0x5cfb,0x715a}, {0x5cfd,0x7a72}, {0x5d07,0x627d}, {0x5d0d,0x554f}, - {0x5d0e,0x5078}, {0x5d11,0x4d5f}, {0x5d14,0x754b}, {0x5d16,0x6470}, {0x5d17,0x4b2b}, {0x5d19,0x5744}, {0x5d27,0x627e}, {0x5d29,0x5d5a}, {0x5d4b,0x5a2e}, {0x5d4c,0x4a6e}, - {0x5d50,0x5539}, {0x5d69,0x6321}, {0x5d6c,0x6863}, {0x5d6f,0x732b}, {0x5d87,0x4f29}, {0x5d8b,0x5377}, {0x5d9d,0x5471}, {0x5da0,0x4e64}, {0x5da2,0x6872}, {0x5daa,0x6575}, - {0x5db8,0x672e}, {0x5dba,0x563a}, {0x5dbc,0x5f6c}, {0x5dbd,0x6440}, {0x5dcd,0x6864}, {0x5dd2,0x5835}, {0x5dd6,0x645c}, {0x5ddd,0x7439}, {0x5dde,0x7136}, {0x5de1,0x625e}, - {0x5de2,0x6135}, {0x5de5,0x4d6f}, {0x5de6,0x7127}, {0x5de7,0x4e65}, {0x5de8,0x4b5d}, {0x5deb,0x5963}, {0x5dee,0x732c}, {0x5df1,0x5079}, {0x5df2,0x6c2b}, {0x5df3,0x5e53}, - {0x5df4,0x7769}, {0x5df7,0x7975}, {0x5dfd,0x615e}, {0x5dfe,0x4b6e}, {0x5e02,0x633c}, {0x5e03,0x7856}, {0x5e06,0x5b6e}, {0x5e0c,0x7d71}, {0x5e11,0x7736}, {0x5e16,0x745e}, - {0x5e19,0x726d}, {0x5e1b,0x5b59}, {0x5e1d,0x7028}, {0x5e25,0x617d}, {0x5e2b,0x5e54}, {0x5e2d,0x602c}, {0x5e33,0x6d63}, {0x5e36,0x5361}, {0x5e38,0x5f48}, {0x5e3d,0x5936}, - {0x5e3f,0x7d2c}, {0x5e40,0x6f53}, {0x5e44,0x6441}, {0x5e45,0x786b}, {0x5e47,0x5b2c}, {0x5e4c,0x7c46}, {0x5e55,0x582d}, {0x5e5f,0x763a}, {0x5e61,0x5b5f}, {0x5e62,0x5353}, - {0x5e63,0x7847}, {0x5e72,0x4a4e}, {0x5e73,0x7841}, {0x5e74,0x5234}, {0x5e77,0x5c34}, {0x5e78,0x7a39}, {0x5e79,0x4a4f}, {0x5e7b,0x7c33}, {0x5e7c,0x6a6a}, {0x5e7d,0x6a6b}, - {0x5e7e,0x507a}, {0x5e84,0x6d64}, {0x5e87,0x5d67}, {0x5e8a,0x5f49}, {0x5e8f,0x5f6d}, {0x5e95,0x6e3c}, {0x5e97,0x6f41}, {0x5e9a,0x4c52}, {0x5e9c,0x5d24}, {0x5ea0,0x5f4a}, - {0x5ea6,0x5378}, {0x5ea7,0x7128}, {0x5eab,0x4d37}, {0x5ead,0x6f54}, {0x5eb5,0x645d}, {0x5eb6,0x5f6e}, {0x5eb7,0x4b2c}, {0x5eb8,0x693c}, {0x5ebe,0x6a6c}, {0x5ec2,0x5f4b}, - {0x5ec8,0x793f}, {0x5ec9,0x562f}, {0x5eca,0x5546}, {0x5ed0,0x4f2a}, {0x5ed3,0x4e29}, {0x5ed6,0x5678}, {0x5eda,0x7137}, {0x5edb,0x6e78}, {0x5edf,0x5959}, {0x5ee0,0x735f}, - {0x5ee2,0x7848}, {0x5ee3,0x4e46}, {0x5eec,0x5566}, {0x5ef3,0x7466}, {0x5ef6,0x6645}, {0x5ef7,0x6f55}, {0x5efa,0x4b6f}, {0x5efb,0x7c5f}, {0x5f01,0x5c27}, {0x5f04,0x5667}, - {0x5f0a,0x7849}, {0x5f0f,0x6352}, {0x5f11,0x633d}, {0x5f13,0x4f61}, {0x5f14,0x7040}, {0x5f15,0x6c5a}, {0x5f17,0x5d57}, {0x5f18,0x7b70}, {0x5f1b,0x6c2c}, {0x5f1f,0x7029}, - {0x5f26,0x7a57}, {0x5f27,0x7b41}, {0x5f29,0x5240}, {0x5f31,0x6530}, {0x5f35,0x6d65}, {0x5f3a,0x4b2d}, {0x5f3c,0x7930}, {0x5f48,0x7725}, {0x5f4a,0x4b2e}, {0x5f4c,0x5a2f}, - {0x5f4e,0x5836}, {0x5f56,0x5327}, {0x5f57,0x7b32}, {0x5f59,0x7d44}, {0x5f5b,0x6c2d}, {0x5f62,0x7b21}, {0x5f66,0x6569}, {0x5f67,0x696e}, {0x5f69,0x7374}, {0x5f6a,0x7873}, - {0x5f6b,0x7041}, {0x5f6c,0x5e2f}, {0x5f6d,0x7830}, {0x5f70,0x7360}, {0x5f71,0x672f}, {0x5f77,0x5b2d}, {0x5f79,0x6635}, {0x5f7c,0x7928}, {0x5f7f,0x5d58}, {0x5f80,0x6859}, - {0x5f81,0x6f56}, {0x5f85,0x5362}, {0x5f87,0x625f}, {0x5f8a,0x7c60}, {0x5f8b,0x5748}, {0x5f8c,0x7d2d}, {0x5f90,0x5f6f}, {0x5f91,0x4c53}, {0x5f92,0x5379}, {0x5f97,0x5470}, - {0x5f98,0x5b47}, {0x5f99,0x5e55}, {0x5f9e,0x7074}, {0x5fa0,0x5550}, {0x5fa1,0x6559}, {0x5fa8,0x7c47}, {0x5fa9,0x5c56}, {0x5faa,0x6260}, {0x5fae,0x5a30}, {0x5fb5,0x7323}, - {0x5fb7,0x536c}, {0x5fb9,0x744b}, {0x5fbd,0x7d45}, {0x5fc3,0x637d}, {0x5fc5,0x7931}, {0x5fcc,0x507b}, {0x5fcd,0x6c5b}, {0x5fd6,0x753c}, {0x5fd7,0x7224}, {0x5fd8,0x584e}, - {0x5fd9,0x584f}, {0x5fe0,0x7577}, {0x5feb,0x7661}, {0x5ff5,0x5237}, {0x5ffd,0x7b6c}, {0x5fff,0x5d48}, {0x600f,0x6468}, {0x6012,0x5241}, {0x6016,0x7857}, {0x601c,0x563b}, - {0x601d,0x5e56}, {0x6020,0x773d}, {0x6021,0x6c2e}, {0x6025,0x5061}, {0x6027,0x6075}, {0x6028,0x6a33}, {0x602a,0x4e56}, {0x602f,0x4c25}, {0x6041,0x6c76}, {0x6042,0x6261}, - {0x6043,0x633e}, {0x604d,0x7c48}, {0x6050,0x4d70}, {0x6052,0x7976}, {0x6055,0x5f70}, {0x6059,0x653f}, {0x605d,0x4e3f}, {0x6062,0x7c61}, {0x6063,0x6d30}, {0x6064,0x7d51}, - {0x6065,0x763b}, {0x6068,0x794f}, {0x6069,0x6b5a}, {0x606a,0x4a41}, {0x606c,0x5238}, {0x606d,0x4d71}, {0x606f,0x6353}, {0x6070,0x7d66}, {0x6085,0x666d}, {0x6089,0x637a}, - {0x608c,0x702a}, {0x608d,0x7950}, {0x6094,0x7c62}, {0x6096,0x7827}, {0x609a,0x6165}, {0x609b,0x6e79}, {0x609f,0x6776}, {0x60a0,0x6a6d}, {0x60a3,0x7c34}, {0x60a4,0x7542}, - {0x60a7,0x575c}, {0x60b0,0x7075}, {0x60b2,0x5d68}, {0x60b3,0x536d}, {0x60b4,0x757c}, {0x60b6,0x5a3f}, {0x60b8,0x4c7b}, {0x60bc,0x537a}, {0x60bd,0x7424}, {0x60c5,0x6f57}, - {0x60c7,0x5443}, {0x60d1,0x7b63}, {0x60da,0x7b6d}, {0x60dc,0x602d}, {0x60df,0x6a6e}, {0x60e0,0x7b33}, {0x60e1,0x6442}, {0x60f0,0x7667}, {0x60f1,0x525d}, {0x60f3,0x5f4c}, - {0x60f6,0x7c49}, {0x60f9,0x6529}, {0x60fa,0x6076}, {0x60fb,0x7633}, {0x6101,0x617e}, {0x6106,0x4b70}, {0x6108,0x6a6f}, {0x6109,0x6a70}, {0x610d,0x5a40}, {0x610e,0x7834}, - {0x610f,0x6b72}, {0x6115,0x6443}, {0x611a,0x6957}, {0x611b,0x6471}, {0x611f,0x4a6f}, {0x6127,0x4e57}, {0x6130,0x7c4a}, {0x6134,0x7361}, {0x6137,0x4b44}, {0x613c,0x6365}, - {0x613e,0x4b45}, {0x613f,0x6a34}, {0x6142,0x693d}, {0x6144,0x5749}, {0x6147,0x6b5b}, {0x6148,0x6d31}, {0x614a,0x4c43}, {0x614b,0x773e}, {0x614c,0x7c4b}, {0x6153,0x7874}, - {0x6155,0x5937}, {0x6158,0x7353}, {0x6159,0x7354}, {0x615d,0x7764}, {0x615f,0x7751}, {0x6162,0x5837}, {0x6163,0x4e31}, {0x6164,0x4a42}, {0x6167,0x7b34}, {0x6168,0x4b46}, - {0x616b,0x7076}, {0x616e,0x5567}, {0x6170,0x6a50}, {0x6176,0x4c54}, {0x6177,0x4b2f}, {0x617d,0x742a}, {0x617e,0x692f}, {0x6181,0x7543}, {0x6182,0x6958}, {0x618a,0x5d69}, - {0x618e,0x7173}, {0x6190,0x557b}, {0x6191,0x5e3b}, {0x6194,0x747b}, {0x6198,0x7d73}, {0x6199,0x7d72}, {0x619a,0x7726}, {0x61a4,0x5d49}, {0x61a7,0x5453}, {0x61a9,0x4c28}, - {0x61ab,0x5a41}, {0x61ac,0x4c55}, {0x61ae,0x5964}, {0x61b2,0x7a4a}, {0x61b6,0x6563}, {0x61ba,0x533c}, {0x61be,0x4a70}, {0x61c3,0x5044}, {0x61c7,0x4a50}, {0x61c8,0x7a2b}, - {0x61c9,0x6b6b}, {0x61ca,0x6778}, {0x61cb,0x5965}, {0x61e6,0x5157}, {0x61f2,0x7324}, {0x61f6,0x547b}, {0x61f7,0x7c63}, {0x61f8,0x7a58}, {0x61fa,0x7355}, {0x61fc,0x4f2b}, - {0x61ff,0x6b73}, {0x6200,0x557c}, {0x6207,0x5354}, {0x6208,0x4d7c}, {0x620a,0x5966}, {0x620c,0x6279}, {0x620d,0x6221}, {0x620e,0x6b54}, {0x6210,0x6077}, {0x6211,0x6432}, - {0x6212,0x4c7c}, {0x6216,0x7b64}, {0x621a,0x742b}, {0x621f,0x503d}, {0x6221,0x4a71}, {0x622a,0x6f38}, {0x622e,0x5740}, {0x6230,0x6e7a}, {0x6231,0x7d74}, {0x6234,0x5363}, - {0x6236,0x7b42}, {0x623e,0x5568}, {0x623f,0x5b2e}, {0x6240,0x6136}, {0x6241,0x7837}, {0x6247,0x603f}, {0x6248,0x7b43}, {0x6249,0x5d6a}, {0x624b,0x6222}, {0x624d,0x6e26}, - {0x6253,0x7668}, {0x6258,0x7675}, {0x626e,0x5d4a}, {0x6271,0x5062}, {0x6276,0x5d26}, {0x6279,0x5d6b}, {0x627c,0x6479}, {0x627f,0x632f}, {0x6280,0x507c}, {0x6284,0x747c}, - {0x6289,0x4c3c}, {0x628a,0x776a}, {0x6291,0x6564}, {0x6292,0x5f71}, {0x6295,0x7761}, {0x6297,0x7977}, {0x6298,0x6f39}, {0x629b,0x7858}, {0x62ab,0x7929}, {0x62b1,0x7859}, - {0x62b5,0x6e3d}, {0x62b9,0x5846}, {0x62bc,0x6463}, {0x62bd,0x754e}, {0x62c2,0x5d59}, {0x62c7,0x5967}, {0x62c8,0x5239}, {0x62c9,0x5543}, {0x62cc,0x5a65}, {0x62cd,0x5a50}, - {0x62cf,0x5159}, {0x62d0,0x4e58}, {0x62d2,0x4b5e}, {0x62d3,0x742c}, {0x62d4,0x5a7b}, {0x62d6,0x7669}, {0x62d7,0x6873}, {0x62d8,0x4f2c}, {0x62d9,0x7070}, {0x62db,0x747d}, - {0x62dc,0x5b48}, {0x62ec,0x4e40}, {0x62ed,0x6354}, {0x62ee,0x514f}, {0x62ef,0x7175}, {0x62f1,0x4d72}, {0x62f3,0x4f6b}, {0x62f7,0x4d38}, {0x62fe,0x6326}, {0x62ff,0x515a}, - {0x6301,0x7225}, {0x6307,0x7226}, {0x6309,0x644e}, {0x6311,0x537b}, {0x632b,0x7129}, {0x632f,0x7249}, {0x633a,0x6f58}, {0x633b,0x6649}, {0x633d,0x5838}, {0x633e,0x7a73}, - {0x6349,0x7335}, {0x634c,0x7824}, {0x634f,0x5173}, {0x6350,0x6648}, {0x6355,0x785a}, {0x6367,0x5c69}, {0x6368,0x5e57}, {0x636e,0x4b5f}, {0x6372,0x4f6c}, {0x6377,0x745f}, - {0x637a,0x5174}, {0x637b,0x523a}, {0x637f,0x5f72}, {0x6383,0x6137}, {0x6388,0x6223}, {0x6389,0x537c}, {0x638c,0x6d66}, {0x6392,0x5b49}, {0x6396,0x647a}, {0x6398,0x4f5e}, - {0x639b,0x4e50}, {0x63a0,0x5553}, {0x63a1,0x7375}, {0x63a2,0x772e}, {0x63a5,0x6f48}, {0x63a7,0x4d73}, {0x63a8,0x754f}, {0x63a9,0x6573}, {0x63aa,0x7042}, {0x63c0,0x4a51}, - {0x63c4,0x6a71}, {0x63c6,0x5026}, {0x63cf,0x595a}, {0x63d0,0x702b}, {0x63d6,0x6b67}, {0x63da,0x6540}, {0x63db,0x7c35}, {0x63e1,0x6444}, {0x63ed,0x4c29}, {0x63ee,0x7d46}, - {0x63f4,0x6a35}, {0x63f6,0x652a}, {0x63f7,0x5f3a}, {0x640d,0x615f}, {0x640f,0x5a51}, {0x6414,0x6138}, {0x6416,0x6874}, {0x6417,0x537d}, {0x641c,0x6224}, {0x6422,0x724a}, - {0x642c,0x5a66}, {0x642d,0x7733}, {0x643a,0x7d4d}, {0x643e,0x7336}, {0x6458,0x6e57}, {0x6460,0x7544}, {0x6469,0x5824}, {0x646f,0x7227}, {0x6478,0x5938}, {0x6479,0x5939}, - {0x647a,0x6f49}, {0x6488,0x564e}, {0x6491,0x774b}, {0x6492,0x5f2e}, {0x6493,0x6875}, {0x649a,0x5235}, {0x649e,0x5355}, {0x64a4,0x744c}, {0x64a5,0x5a7c}, {0x64ab,0x5968}, - {0x64ad,0x776b}, {0x64ae,0x7549}, {0x64b0,0x733c}, {0x64b2,0x5a52}, {0x64bb,0x5335}, {0x64c1,0x6836}, {0x64c4,0x564f}, {0x64c5,0x743a}, {0x64c7,0x7749}, {0x64ca,0x4c2a}, - {0x64cd,0x7043}, {0x64ce,0x4c56}, {0x64d2,0x5053}, {0x64d4,0x533d}, {0x64d8,0x5b7b}, {0x64da,0x4b60}, {0x64e1,0x5364}, {0x64e2,0x7677}, {0x64e5,0x553a}, {0x64e6,0x734d}, - {0x64e7,0x4b61}, {0x64ec,0x6b74}, {0x64f2,0x742d}, {0x64f4,0x7c2a}, {0x64fa,0x776c}, {0x64fe,0x6876}, {0x6500,0x5a67}, {0x6504,0x774c}, {0x6518,0x6541}, {0x651d,0x606e}, - {0x6523,0x557d}, {0x652a,0x4e66}, {0x652b,0x7c2b}, {0x652c,0x553b}, {0x652f,0x7228}, {0x6536,0x6225}, {0x6537,0x4d39}, {0x6538,0x6a72}, {0x6539,0x4b47}, {0x653b,0x4d74}, - {0x653e,0x5b2f}, {0x653f,0x6f59}, {0x6545,0x4d3a}, {0x6548,0x7c79}, {0x654d,0x5f73}, {0x654e,0x4e67}, {0x654f,0x5a42}, {0x6551,0x4f2d}, {0x6556,0x6779}, {0x6557,0x7828}, - {0x655e,0x7362}, {0x6562,0x4a72}, {0x6563,0x5f24}, {0x6566,0x5444}, {0x656c,0x4c57}, {0x656d,0x6542}, {0x6572,0x4d3b}, {0x6574,0x6f5a}, {0x6575,0x6e58}, {0x6577,0x5d27}, - {0x6578,0x6226}, {0x657e,0x6040}, {0x6582,0x5630}, {0x6583,0x784a}, {0x6585,0x7c7a}, {0x6587,0x597e}, {0x658c,0x5e30}, {0x6590,0x5d6c}, {0x6591,0x5a68}, {0x6597,0x5460}, - {0x6599,0x5679}, {0x659b,0x4d57}, {0x659c,0x5e58}, {0x659f,0x7278}, {0x65a1,0x6456}, {0x65a4,0x5045}, {0x65a5,0x742e}, {0x65a7,0x5d28}, {0x65ab,0x6d45}, {0x65ac,0x7356}, - {0x65af,0x5e59}, {0x65b0,0x6366}, {0x65b7,0x5328}, {0x65b9,0x5b30}, {0x65bc,0x655a}, {0x65bd,0x633f}, {0x65c1,0x5b31}, {0x65c5,0x5569}, {0x65cb,0x6041}, {0x65cc,0x6f5b}, - {0x65cf,0x7069}, {0x65d2,0x5732}, {0x65d7,0x507d}, {0x65e0,0x5969}, {0x65e3,0x507e}, {0x65e5,0x6c6d}, {0x65e6,0x5329}, {0x65e8,0x7229}, {0x65e9,0x7044}, {0x65ec,0x6262}, - {0x65ed,0x696f}, {0x65f1,0x7951}, {0x65f4,0x6959}, {0x65fa,0x685a}, {0x65fb,0x5a43}, {0x65fc,0x5a44}, {0x65fd,0x5445}, {0x65ff,0x677a}, {0x6606,0x4d60}, {0x6607,0x6330}, - {0x6609,0x5b32}, {0x660a,0x7b44}, {0x660c,0x7363}, {0x660e,0x5925}, {0x660f,0x7b67}, {0x6610,0x5d4b}, {0x6611,0x5054}, {0x6613,0x6636}, {0x6614,0x602e}, {0x6615,0x7d5a}, - {0x661e,0x5c35}, {0x661f,0x6078}, {0x6620,0x6731}, {0x6625,0x7570}, {0x6627,0x585c}, {0x6628,0x6d46}, {0x662d,0x6139}, {0x662f,0x6340}, {0x6630,0x7940}, {0x6631,0x6970}, - {0x6634,0x595b}, {0x6636,0x7364}, {0x663a,0x5c36}, {0x663b,0x6469}, {0x6641,0x7045}, {0x6642,0x6341}, {0x6643,0x7c4c}, {0x6644,0x7c4d}, {0x6649,0x724b}, {0x664b,0x724c}, - {0x664f,0x644f}, {0x6659,0x715b}, {0x665b,0x7a59}, {0x665d,0x7138}, {0x665e,0x7d75}, {0x665f,0x6079}, {0x6664,0x677b}, {0x6665,0x7c37}, {0x6666,0x7c64}, {0x6667,0x7b45}, - {0x6668,0x6367}, {0x6669,0x5839}, {0x666b,0x7678}, {0x666e,0x5c45}, {0x666f,0x4c58}, {0x6673,0x602f}, {0x6674,0x7467}, {0x6676,0x6f5c}, {0x6677,0x4f7c}, {0x6678,0x6f5d}, - {0x667a,0x722a}, {0x6684,0x7d3e}, {0x6687,0x4a2c}, {0x6688,0x7d3b}, {0x6689,0x7d47}, {0x668e,0x6732}, {0x6690,0x6a51}, {0x6691,0x5f74}, {0x6696,0x516c}, {0x6697,0x645e}, - {0x6698,0x6543}, {0x669d,0x5926}, {0x66a0,0x4d3c}, {0x66a2,0x7365}, {0x66ab,0x6d55}, {0x66ae,0x593a}, {0x66b2,0x6d67}, {0x66b3,0x7b35}, {0x66b4,0x786c}, {0x66b9,0x6067}, - {0x66bb,0x4c59}, {0x66be,0x5446}, {0x66c4,0x6725}, {0x66c6,0x5575}, {0x66c7,0x533e}, {0x66c9,0x7c7b}, {0x66d6,0x6472}, {0x66d9,0x5f75}, {0x66dc,0x6878}, {0x66dd,0x786d}, - {0x66e0,0x4e47}, {0x66e6,0x7d76}, {0x66f0,0x6858}, {0x66f2,0x4d58}, {0x66f3,0x6756}, {0x66f4,0x4c5a}, {0x66f7,0x4a63}, {0x66f8,0x5f76}, {0x66f9,0x7047}, {0x66fa,0x7046}, - {0x66fc,0x583a}, {0x66fe,0x7174}, {0x66ff,0x7470}, {0x6700,0x754c}, {0x6703,0x7c65}, {0x6708,0x6a45}, {0x6709,0x6a73}, {0x670b,0x5d5b}, {0x670d,0x5c57}, {0x6714,0x5e7d}, - {0x6715,0x7279}, {0x6717,0x5547}, {0x671b,0x5850}, {0x671d,0x7048}, {0x671e,0x5121}, {0x671f,0x5122}, {0x6726,0x5954}, {0x6727,0x5668}, {0x6728,0x594a}, {0x672a,0x5a31}, - {0x672b,0x5847}, {0x672c,0x5c62}, {0x672d,0x734e}, {0x672e,0x7574}, {0x6731,0x7139}, {0x6734,0x5a53}, {0x6736,0x766a}, {0x673a,0x4f75}, {0x673d,0x7d2e}, {0x6746,0x4a52}, - {0x6749,0x5f34}, {0x674e,0x575d}, {0x674f,0x7a3a}, {0x6750,0x6e27}, {0x6751,0x753d}, {0x6753,0x7875}, {0x6756,0x6d68}, {0x675c,0x5461}, {0x675e,0x5123}, {0x675f,0x6156}, - {0x676d,0x7978}, {0x676f,0x5b4a}, {0x6770,0x4b79}, {0x6771,0x5454}, {0x6773,0x595c}, {0x6775,0x6e3e}, {0x6777,0x776d}, {0x677b,0x526e}, {0x677e,0x6166}, {0x677f,0x7779}, - {0x6787,0x5d6d}, {0x6789,0x685b}, {0x678b,0x5b33}, {0x678f,0x5177}, {0x6790,0x6030}, {0x6793,0x5462}, {0x6795,0x7657}, {0x6797,0x5779}, {0x679a,0x585d}, {0x679c,0x4d7d}, - {0x679d,0x722b}, {0x67af,0x4d3d}, {0x67b0,0x7842}, {0x67b3,0x722c}, {0x67b6,0x4a2d}, {0x67b7,0x4a2e}, {0x67b8,0x4f2e}, {0x67be,0x6342}, {0x67c4,0x5c37}, {0x67cf,0x5b5a}, - {0x67d0,0x593b}, {0x67d1,0x4a73}, {0x67d2,0x7653}, {0x67d3,0x6678}, {0x67d4,0x6a75}, {0x67da,0x6a76}, {0x67dd,0x7679}, {0x67e9,0x4f2f}, {0x67ec,0x4a53}, {0x67ef,0x4a2f}, - {0x67f0,0x5230}, {0x67f1,0x713a}, {0x67f3,0x5733}, {0x67f4,0x6343}, {0x67f5,0x737d}, {0x67f6,0x5e5a}, {0x67fb,0x5e5b}, {0x67fe,0x6f5e}, {0x6812,0x6263}, {0x6813,0x6e7b}, - {0x6816,0x5f77}, {0x6817,0x574a}, {0x6821,0x4e68}, {0x6822,0x5b5b}, {0x682a,0x713b}, {0x682f,0x6971}, {0x6838,0x7a37}, {0x6839,0x5046}, {0x683c,0x4c2b}, {0x683d,0x6e28}, - {0x6840,0x4b7a}, {0x6841,0x7979}, {0x6842,0x4c7d}, {0x6843,0x537e}, {0x6848,0x6450}, {0x684e,0x726e}, {0x6850,0x5455}, {0x6851,0x5f4d}, {0x6853,0x7c38}, {0x6854,0x5150}, - {0x686d,0x724d}, {0x6876,0x7752}, {0x687f,0x4a54}, {0x6881,0x5559}, {0x6885,0x585e}, {0x688f,0x4d59}, {0x6893,0x6e29}, {0x6894,0x763c}, {0x6897,0x4c5b}, {0x689d,0x7049}, - {0x689f,0x7c7c}, {0x68a1,0x6849}, {0x68a2,0x747e}, {0x68a7,0x677c}, {0x68a8,0x575e}, {0x68ad,0x5e5c}, {0x68af,0x702c}, {0x68b0,0x4c7e}, {0x68b1,0x4d61}, {0x68b3,0x613a}, - {0x68b5,0x5b6f}, {0x68b6,0x5a32}, {0x68c4,0x5125}, {0x68c5,0x5c38}, {0x68c9,0x5876}, {0x68cb,0x5124}, {0x68cd,0x4d62}, {0x68d2,0x5c6a}, {0x68d5,0x7077}, {0x68d7,0x704a}, - {0x68d8,0x503e}, {0x68da,0x5d5c}, {0x68df,0x5456}, {0x68e0,0x5356}, {0x68e7,0x6d50}, {0x68e8,0x4d21}, {0x68ee,0x5f35}, {0x68f2,0x5f78}, {0x68f9,0x5421}, {0x68fa,0x4e32}, - {0x6900,0x684a}, {0x6905,0x6b75}, {0x690d,0x6355}, {0x690e,0x7550}, {0x6912,0x7521}, {0x6927,0x5927}, {0x6930,0x652b}, {0x693d,0x664b}, {0x693f,0x7571}, {0x694a,0x6545}, - {0x6953,0x7923}, {0x6954,0x605b}, {0x6955,0x766b}, {0x6957,0x4b71}, {0x6959,0x596a}, {0x695a,0x7522}, {0x695e,0x5751}, {0x6960,0x5178}, {0x6961,0x6a78}, {0x6962,0x6a79}, - {0x6963,0x5a33}, {0x6968,0x6f5f}, {0x696b,0x716f}, {0x696d,0x6576}, {0x696e,0x6e3f}, {0x696f,0x6264}, {0x6975,0x503f}, {0x6977,0x7a2c}, {0x6978,0x7551}, {0x6979,0x6733}, - {0x6995,0x693e}, {0x699b,0x724e}, {0x699c,0x5b34}, {0x69a5,0x7c4e}, {0x69a7,0x5d6e}, {0x69ae,0x6734}, {0x69b4,0x5734}, {0x69bb,0x7734}, {0x69c1,0x4d3e}, {0x69c3,0x5a69}, - {0x69cb,0x4f30}, {0x69cc,0x7759}, {0x69cd,0x7366}, {0x69d0,0x4e59}, {0x69e8,0x4e2a}, {0x69ea,0x4b48}, {0x69fb,0x5027}, {0x69fd,0x704b}, {0x69ff,0x5047}, {0x6a02,0x6445}, - {0x6a0a,0x5b60}, {0x6a11,0x555a}, {0x6a13,0x5727}, {0x6a17,0x6e40}, {0x6a19,0x7876}, {0x6a1e,0x7552}, {0x6a1f,0x6d69}, {0x6a21,0x593c}, {0x6a23,0x6546}, {0x6a35,0x7523}, - {0x6a38,0x5a54}, {0x6a39,0x6227}, {0x6a3a,0x7b7c}, {0x6a3d,0x715c}, {0x6a44,0x4a74}, {0x6a48,0x687a}, {0x6a4b,0x4e69}, {0x6a52,0x6978}, {0x6a53,0x6265}, {0x6a58,0x5039}, - {0x6a59,0x5472}, {0x6a5f,0x5126}, {0x6a61,0x5f4e}, {0x6a6b,0x7c74}, {0x6a80,0x532a}, {0x6a84,0x4c2c}, {0x6a89,0x6f60}, {0x6a8d,0x6565}, {0x6a8e,0x5055}, {0x6a97,0x5b7c}, - {0x6a9c,0x7c66}, {0x6aa2,0x4b7e}, {0x6aa3,0x6d6a}, {0x6ab3,0x5e31}, {0x6abb,0x7963}, {0x6ac2,0x5422}, {0x6ac3,0x4f76}, {0x6ad3,0x5650}, {0x6ada,0x556a}, {0x6adb,0x716e}, - {0x6af6,0x7a4b}, {0x6afb,0x6521}, {0x6b04,0x5531}, {0x6b0a,0x4f6d}, {0x6b0c,0x6d6b}, {0x6b12,0x5532}, {0x6b16,0x553c}, {0x6b20,0x7d62}, {0x6b21,0x732d}, {0x6b23,0x7d5b}, - {0x6b32,0x6930}, {0x6b3a,0x5127}, {0x6b3d,0x7d63}, {0x6b3e,0x4e33}, {0x6b46,0x7d64}, {0x6b47,0x7a4e}, {0x6b4c,0x4a30}, {0x6b4e,0x7727}, {0x6b50,0x4f31}, {0x6b5f,0x6622}, - {0x6b61,0x7c36}, {0x6b62,0x722d}, {0x6b63,0x6f61}, {0x6b64,0x732e}, {0x6b65,0x5c46}, {0x6b66,0x596b}, {0x6b6a,0x6860}, {0x6b72,0x6128}, {0x6b77,0x5576}, {0x6b78,0x4f7d}, - {0x6b7b,0x5e5d}, {0x6b7f,0x5951}, {0x6b83,0x646a}, {0x6b84,0x724f}, {0x6b86,0x773f}, {0x6b89,0x6266}, {0x6b8a,0x6228}, {0x6b96,0x6356}, {0x6b98,0x6d51}, {0x6b9e,0x6979}, - {0x6bae,0x5631}, {0x6baf,0x5e32}, {0x6bb2,0x6068}, {0x6bb5,0x532b}, {0x6bb7,0x6b5c}, {0x6bba,0x5f2f}, {0x6bbc,0x4a43}, {0x6bbf,0x6e7c}, {0x6bc1,0x7d43}, {0x6bc5,0x6b76}, - {0x6bc6,0x4f32}, {0x6bcb,0x596c}, {0x6bcd,0x593d}, {0x6bcf,0x585f}, {0x6bd2,0x5438}, {0x6bd3,0x6b3e}, {0x6bd4,0x5d6f}, {0x6bd6,0x5d70}, {0x6bd7,0x5d71}, {0x6bd8,0x5d72}, - {0x6bdb,0x593e}, {0x6beb,0x7b46}, {0x6bec,0x4f33}, {0x6c08,0x6e7d}, {0x6c0f,0x642b}, {0x6c11,0x5a45}, {0x6c13,0x586c}, {0x6c23,0x5128}, {0x6c34,0x6229}, {0x6c37,0x5e3c}, - {0x6c38,0x6735}, {0x6c3e,0x5b70}, {0x6c40,0x6f62}, {0x6c41,0x7170}, {0x6c42,0x4f34}, {0x6c4e,0x5b71}, {0x6c50,0x6031}, {0x6c55,0x5f25}, {0x6c57,0x7952}, {0x6c5a,0x677d}, - {0x6c5d,0x6623}, {0x6c5e,0x7b71}, {0x6c5f,0x4b30}, {0x6c60,0x722e}, {0x6c68,0x4d67}, {0x6c6a,0x685c}, {0x6c6d,0x6757}, {0x6c70,0x7740}, {0x6c72,0x5063}, {0x6c76,0x5a21}, - {0x6c7a,0x4c3d}, {0x6c7d,0x5129}, {0x6c7e,0x5d4c}, {0x6c81,0x637e}, {0x6c82,0x512a}, {0x6c83,0x682a}, {0x6c85,0x6a36}, {0x6c86,0x797a}, {0x6c87,0x664c}, {0x6c88,0x7658}, - {0x6c8c,0x5447}, {0x6c90,0x594b}, {0x6c92,0x5952}, {0x6c93,0x534b}, {0x6c94,0x5877}, {0x6c95,0x5a29}, {0x6c96,0x7578}, {0x6c99,0x5e5e}, {0x6c9a,0x722f}, {0x6c9b,0x7829}, - {0x6cab,0x5848}, {0x6cae,0x6e41}, {0x6cb3,0x7941}, {0x6cb8,0x5d73}, {0x6cb9,0x6a7a}, {0x6cbb,0x763d}, {0x6cbc,0x613b}, {0x6cbd,0x4d3f}, {0x6cbe,0x7454}, {0x6cbf,0x664d}, - {0x6cc1,0x7c4f}, {0x6cc2,0x7b22}, {0x6cc4,0x605c}, {0x6cc9,0x743b}, {0x6cca,0x5a55}, {0x6ccc,0x7932}, {0x6cd3,0x7b72}, {0x6cd5,0x5b76}, {0x6cd7,0x5e5f}, {0x6cdb,0x5b72}, - {0x6ce1,0x785c}, {0x6ce2,0x776e}, {0x6ce3,0x6b68}, {0x6ce5,0x527a}, {0x6ce8,0x713c}, {0x6ceb,0x7a5a}, {0x6cee,0x5a6a}, {0x6cef,0x5a46}, {0x6cf0,0x7741}, {0x6cf3,0x6736}, - {0x6d0b,0x6547}, {0x6d0c,0x562c}, {0x6d11,0x5c47}, {0x6d17,0x6129}, {0x6d19,0x622a}, {0x6d1b,0x5526}, {0x6d1e,0x5457}, {0x6d25,0x7250}, {0x6d27,0x6a7b}, {0x6d29,0x605d}, - {0x6d2a,0x7b73}, {0x6d32,0x713d}, {0x6d35,0x6267}, {0x6d36,0x7d57}, {0x6d38,0x4e48}, {0x6d39,0x6a37}, {0x6d3b,0x7c40}, {0x6d3d,0x7d67}, {0x6d3e,0x776f}, {0x6d41,0x5735}, - {0x6d59,0x6f3a}, {0x6d5a,0x715d}, {0x6d5c,0x5e33}, {0x6d63,0x684b}, {0x6d66,0x785d}, {0x6d69,0x7b47}, {0x6d6a,0x5548}, {0x6d6c,0x575f}, {0x6d6e,0x5d29}, {0x6d74,0x6931}, - {0x6d77,0x7a2d}, {0x6d78,0x7659}, {0x6d79,0x7a74}, {0x6d7f,0x782a}, {0x6d85,0x666e}, {0x6d87,0x4c5c}, {0x6d88,0x613c}, {0x6d89,0x606f}, {0x6d8c,0x693f}, {0x6d8d,0x7c7d}, - {0x6d8e,0x664e}, {0x6d91,0x6157}, {0x6d93,0x664f}, {0x6d95,0x7471}, {0x6daf,0x6473}, {0x6db2,0x647b}, {0x6db5,0x7964}, {0x6dc0,0x6f63}, {0x6dc3,0x4f6e}, {0x6dc4,0x763e}, - {0x6dc5,0x6032}, {0x6dc6,0x7c7e}, {0x6dc7,0x512b}, {0x6dcb,0x577a}, {0x6dcf,0x7b48}, {0x6dd1,0x6257}, {0x6dd8,0x5423}, {0x6dd9,0x7078}, {0x6dda,0x5728}, {0x6dde,0x6167}, - {0x6de1,0x533f}, {0x6de8,0x6f64}, {0x6dea,0x5745}, {0x6deb,0x6b62}, {0x6dee,0x7c67}, {0x6df1,0x6422}, {0x6df3,0x6268}, {0x6df5,0x6650}, {0x6df7,0x7b68}, {0x6df8,0x7468}, - {0x6df9,0x6574}, {0x6dfa,0x743c}, {0x6dfb,0x7455}, {0x6e17,0x5f36}, {0x6e19,0x7c39}, {0x6e1a,0x6e42}, {0x6e1b,0x4a75}, {0x6e1f,0x6f65}, {0x6e20,0x4b62}, {0x6e21,0x5424}, - {0x6e23,0x5e60}, {0x6e24,0x5a7d}, {0x6e25,0x6446}, {0x6e26,0x683e}, {0x6e2b,0x605e}, {0x6e2c,0x7634}, {0x6e2d,0x6a52}, {0x6e2f,0x797b}, {0x6e32,0x6042}, {0x6e34,0x4a64}, - {0x6e36,0x6737}, {0x6e38,0x6a7d}, {0x6e3a,0x595d}, {0x6e3c,0x5a34}, {0x6e3d,0x6e2a}, {0x6e3e,0x7b69}, {0x6e43,0x5b4b}, {0x6e44,0x5a35}, {0x6e4a,0x713e}, {0x6e4d,0x532c}, - {0x6e56,0x7b49}, {0x6e58,0x5f4f}, {0x6e5b,0x5340}, {0x6e5c,0x6357}, {0x6e5e,0x6f66}, {0x6e5f,0x7c50}, {0x6e67,0x6940}, {0x6e6b,0x7553}, {0x6e6e,0x6c5c}, {0x6e6f,0x7737}, - {0x6e72,0x6a38}, {0x6e73,0x5179}, {0x6e7a,0x5c48}, {0x6e90,0x6a39}, {0x6e96,0x715e}, {0x6e9c,0x5736}, {0x6e9d,0x4f35}, {0x6e9f,0x5928}, {0x6ea2,0x6c6e}, {0x6ea5,0x5d2a}, - {0x6eaa,0x4d22}, {0x6eab,0x682e}, {0x6eaf,0x613d}, {0x6eb1,0x7251}, {0x6eb6,0x6941}, {0x6eba,0x527c}, {0x6ec2,0x5b35}, {0x6ec4,0x7367}, {0x6ec5,0x587e}, {0x6ec9,0x7c51}, - {0x6ecb,0x6d32}, {0x6ecc,0x742f}, {0x6ece,0x7b23}, {0x6ed1,0x7c41}, {0x6ed3,0x6e2b}, {0x6ed4,0x5425}, {0x6eef,0x7472}, {0x6ef4,0x6e59}, {0x6ef8,0x7b4a}, {0x6efe,0x4d63}, - {0x6eff,0x583b}, {0x6f01,0x655b}, {0x6f02,0x7877}, {0x6f06,0x7654}, {0x6f0f,0x5729}, {0x6f11,0x4b49}, {0x6f14,0x6651}, {0x6f15,0x704c}, {0x6f20,0x582e}, {0x6f22,0x7953}, - {0x6f23,0x557e}, {0x6f2b,0x583c}, {0x6f2c,0x7230}, {0x6f31,0x622b}, {0x6f32,0x7368}, {0x6f38,0x6f42}, {0x6f3f,0x6d6c}, {0x6f41,0x6738}, {0x6f51,0x5a7e}, {0x6f54,0x4c3e}, - {0x6f57,0x727c}, {0x6f58,0x5a6b}, {0x6f5a,0x6258}, {0x6f5b,0x6d56}, {0x6f5e,0x5651}, {0x6f5f,0x6033}, {0x6f62,0x7c52}, {0x6f64,0x6b48}, {0x6f6d,0x5341}, {0x6f6e,0x704d}, - {0x6f70,0x4f77}, {0x6f7a,0x6d52}, {0x6f7c,0x5458}, {0x6f7d,0x5c49}, {0x6f7e,0x5771}, {0x6f81,0x5f3b}, {0x6f84,0x7325}, {0x6f88,0x744d}, {0x6f8d,0x713f}, {0x6f8e,0x7831}, - {0x6f90,0x697a}, {0x6f94,0x7b4b}, {0x6f97,0x4a55}, {0x6fa3,0x7954}, {0x6fa4,0x774a}, {0x6fa7,0x5648}, {0x6fae,0x7c68}, {0x6faf,0x733d}, {0x6fb1,0x6e7e}, {0x6fb3,0x677e}, - {0x6fb9,0x5342}, {0x6fbe,0x5336}, {0x6fc0,0x4c2d}, {0x6fc1,0x767a}, {0x6fc2,0x5632}, {0x6fc3,0x5258}, {0x6fca,0x6758}, {0x6fd5,0x6325}, {0x6fda,0x6739}, {0x6fdf,0x702d}, - {0x6fe0,0x7b4c}, {0x6fe1,0x6b21}, {0x6fe4,0x5426}, {0x6fe9,0x7b4d}, {0x6feb,0x553d}, {0x6fec,0x715f}, {0x6fef,0x767b}, {0x6ff1,0x5e34}, {0x6ffe,0x556b}, {0x7001,0x6548}, - {0x7005,0x7b24}, {0x7006,0x5439}, {0x7009,0x5e61}, {0x700b,0x6423}, {0x700f,0x5737}, {0x7011,0x786e}, {0x7015,0x5e35}, {0x7018,0x5652}, {0x701a,0x7955}, {0x701b,0x673a}, - {0x701c,0x6b55}, {0x701d,0x5577}, {0x701e,0x6f67}, {0x701f,0x613e}, {0x7023,0x7a2e}, {0x7027,0x5669}, {0x7028,0x566e}, {0x702f,0x673b}, {0x7037,0x6c4b}, {0x703e,0x5533}, - {0x704c,0x4e34}, {0x7050,0x7b25}, {0x7051,0x616e}, {0x7058,0x7728}, {0x705d,0x7b4e}, {0x7063,0x583d}, {0x706b,0x7b7d}, {0x7070,0x7c69}, {0x7078,0x4f36}, {0x707c,0x6d47}, - {0x707d,0x6e2c}, {0x7085,0x4c5d}, {0x708a,0x7627}, {0x708e,0x667a}, {0x7092,0x7524}, {0x7098,0x7d5c}, {0x7099,0x6d33}, {0x709a,0x4e49}, {0x70a1,0x6f68}, {0x70a4,0x613f}, - {0x70ab,0x7a5b}, {0x70ac,0x4b63}, {0x70ad,0x7729}, {0x70af,0x7b26}, {0x70b3,0x5c39}, {0x70b7,0x7140}, {0x70b8,0x6d48}, {0x70b9,0x6f43}, {0x70c8,0x562d}, {0x70cb,0x7d4e}, - {0x70cf,0x6821}, {0x70d8,0x7b74}, {0x70d9,0x5527}, {0x70dd,0x7176}, {0x70df,0x6653}, {0x70f1,0x4c5e}, {0x70f9,0x7832}, {0x70fd,0x5c6b}, {0x7104,0x7d36}, {0x7109,0x656a}, - {0x710c,0x7160}, {0x7119,0x5b4c}, {0x711a,0x5d4d}, {0x711e,0x5448}, {0x7121,0x596d}, {0x7126,0x7525}, {0x7130,0x667b}, {0x7136,0x6654}, {0x7147,0x7d48}, {0x7149,0x5621}, - {0x714a,0x7d3f}, {0x714c,0x7c53}, {0x714e,0x6f21}, {0x7150,0x673c}, {0x7156,0x516e}, {0x7159,0x6655}, {0x715c,0x6972}, {0x715e,0x5f30}, {0x7164,0x5860}, {0x7165,0x7c3a}, - {0x7166,0x7d2f}, {0x7167,0x704e}, {0x7169,0x5b61}, {0x716c,0x6549}, {0x716e,0x6d34}, {0x717d,0x6043}, {0x7184,0x6358}, {0x7189,0x697b}, {0x718a,0x6a28}, {0x718f,0x7d37}, - {0x7192,0x7b27}, {0x7194,0x6942}, {0x7199,0x7d77}, {0x719f,0x6259}, {0x71a2,0x5c6c}, {0x71ac,0x6822}, {0x71b1,0x6670}, {0x71b9,0x7d78}, {0x71ba,0x7d79}, {0x71be,0x763f}, - {0x71c1,0x6727}, {0x71c3,0x6657}, {0x71c8,0x5473}, {0x71c9,0x5449}, {0x71ce,0x567a}, {0x71d0,0x5772}, {0x71d2,0x6140}, {0x71d4,0x5b62}, {0x71d5,0x6658}, {0x71df,0x673d}, - {0x71e5,0x704f}, {0x71e6,0x733e}, {0x71e7,0x622c}, {0x71ed,0x7537}, {0x71ee,0x6070}, {0x71fb,0x7d38}, {0x71fc,0x6368}, {0x71fe,0x5427}, {0x71ff,0x687c}, {0x7200,0x7a52}, - {0x7206,0x786f}, {0x7210,0x5653}, {0x721b,0x5534}, {0x722a,0x7050}, {0x722c,0x7770}, {0x722d,0x6e33}, {0x7230,0x6a3a}, {0x7232,0x6a53}, {0x7235,0x6d49}, {0x7236,0x5d2b}, - {0x723a,0x652c}, {0x723b,0x7d21}, {0x723d,0x5f50}, {0x723e,0x6c33}, {0x7240,0x5f51}, {0x7246,0x6d6d}, {0x7247,0x7838}, {0x7248,0x777a}, {0x724c,0x782b}, {0x7252,0x7460}, - {0x7258,0x543a}, {0x7259,0x6433}, {0x725b,0x695a}, {0x725d,0x5e36}, {0x725f,0x593f}, {0x7261,0x5940}, {0x7262,0x566f}, {0x7267,0x594c}, {0x7269,0x5a2a}, {0x7272,0x5f65}, - {0x7279,0x7765}, {0x727d,0x4c32}, {0x7280,0x5f79}, {0x7281,0x5760}, {0x72a2,0x543b}, {0x72a7,0x7d7a}, {0x72ac,0x4c33}, {0x72af,0x5b73}, {0x72c0,0x5f52}, {0x72c2,0x4e4a}, - {0x72c4,0x6e5a}, {0x72ce,0x6464}, {0x72d0,0x7b4f}, {0x72d7,0x4f37}, {0x72d9,0x6e43}, {0x72e1,0x4e6a}, {0x72e9,0x622d}, {0x72f8,0x5761}, {0x72f9,0x7a75}, {0x72fc,0x5549}, - {0x72fd,0x782c}, {0x730a,0x6759}, {0x7316,0x7369}, {0x731b,0x586d}, {0x731c,0x6344}, {0x731d,0x7071}, {0x7325,0x6865}, {0x7329,0x607a}, {0x732a,0x6e44}, {0x732b,0x595e}, - {0x7336,0x6b22}, {0x7337,0x6b23}, {0x733e,0x7c42}, {0x733f,0x6a3b}, {0x7344,0x682b}, {0x7345,0x5e62}, {0x7350,0x6d6f}, {0x7352,0x6823}, {0x7357,0x4f71}, {0x7368,0x543c}, - {0x736a,0x7c6a}, {0x7370,0x673e}, {0x7372,0x7c72}, {0x7375,0x5634}, {0x7378,0x622e}, {0x737a,0x5337}, {0x737b,0x7a4c}, {0x7384,0x7a5c}, {0x7386,0x6d35}, {0x7387,0x6163}, - {0x7389,0x682c}, {0x738b,0x685d}, {0x738e,0x6f69}, {0x7394,0x743d}, {0x7396,0x4f38}, {0x7397,0x695b}, {0x7398,0x512c}, {0x739f,0x5a47}, {0x73a7,0x6b49}, {0x73a9,0x684c}, - {0x73ad,0x5e37}, {0x73b2,0x563c}, {0x73b3,0x5365}, {0x73b9,0x7a5d}, {0x73c0,0x5a56}, {0x73c2,0x4a31}, {0x73c9,0x5a48}, {0x73ca,0x5f26}, {0x73cc,0x7933}, {0x73cd,0x7252}, - {0x73cf,0x4a44}, {0x73d6,0x4e4b}, {0x73d9,0x4d75}, {0x73dd,0x7d30}, {0x73de,0x5528}, {0x73e0,0x7141}, {0x73e3,0x6269}, {0x73e4,0x5c4a}, {0x73e5,0x6c34}, {0x73e6,0x7a40}, - {0x73e9,0x7b28}, {0x73ea,0x5028}, {0x73ed,0x5a6c}, {0x73f7,0x596e}, {0x73f9,0x607b}, {0x73fd,0x6f6a}, {0x73fe,0x7a5e}, {0x7401,0x6044}, {0x7403,0x4f39}, {0x7405,0x554a}, - {0x7406,0x5762}, {0x7407,0x622f}, {0x7409,0x5738}, {0x7413,0x684d}, {0x741b,0x765a}, {0x7420,0x6f22}, {0x7421,0x625a}, {0x7422,0x767c}, {0x7425,0x7b50}, {0x7426,0x512d}, - {0x7428,0x4d64}, {0x742a,0x512e}, {0x742b,0x5c6d}, {0x742c,0x684e}, {0x742e,0x7079}, {0x742f,0x4e35}, {0x7430,0x667c}, {0x7433,0x577b}, {0x7434,0x5056}, {0x7435,0x5d75}, - {0x7436,0x7771}, {0x7438,0x767d}, {0x743a,0x5b77}, {0x743f,0x7b6a}, {0x7440,0x695c}, {0x7441,0x5941}, {0x7443,0x7572}, {0x7444,0x6045}, {0x744b,0x6a54}, {0x7455,0x7942}, - {0x7457,0x6a3c}, {0x7459,0x5245}, {0x745a,0x7b51}, {0x745b,0x6740}, {0x745c,0x6b25}, {0x745e,0x5f7a}, {0x745f,0x6322}, {0x7460,0x5739}, {0x7462,0x6943}, {0x7464,0x687d}, - {0x7465,0x682f}, {0x7468,0x7253}, {0x7469,0x7b29}, {0x746a,0x5825}, {0x746f,0x554b}, {0x747e,0x5048}, {0x7482,0x512f}, {0x7483,0x5763}, {0x7487,0x6046}, {0x7489,0x5622}, - {0x748b,0x6d70}, {0x7498,0x5773}, {0x749c,0x7c54}, {0x749e,0x5a57}, {0x749f,0x4c5f}, {0x74a1,0x7254}, {0x74a3,0x5130}, {0x74a5,0x4c60}, {0x74a7,0x5b7d}, {0x74a8,0x733f}, - {0x74aa,0x7051}, {0x74b0,0x7c3b}, {0x74b2,0x6230}, {0x74b5,0x6625}, {0x74b9,0x625b}, {0x74bd,0x5f5e}, {0x74bf,0x6047}, {0x74c6,0x726f}, {0x74ca,0x4c61}, {0x74cf,0x566a}, - {0x74d4,0x6742}, {0x74d8,0x4e36}, {0x74da,0x7340}, {0x74dc,0x4d7e}, {0x74e0,0x7b52}, {0x74e2,0x7878}, {0x74e3,0x777b}, {0x74e6,0x683f}, {0x74ee,0x6837}, {0x74f7,0x6d36}, - {0x7501,0x5c3a}, {0x7504,0x4c34}, {0x7511,0x7177}, {0x7515,0x6838}, {0x7518,0x4a76}, {0x751a,0x6424}, {0x751b,0x7456}, {0x751f,0x5f66}, {0x7523,0x5f27}, {0x7525,0x5f67}, - {0x7526,0x6141}, {0x7528,0x6944}, {0x752b,0x5c4b}, {0x752c,0x6945}, {0x7530,0x6f23}, {0x7531,0x6b26}, {0x7532,0x4b23}, {0x7533,0x6369}, {0x7537,0x517b}, {0x7538,0x6f24}, - {0x753a,0x6f6b}, {0x7547,0x5034}, {0x754c,0x4d23}, {0x754f,0x6866}, {0x7551,0x6f25}, {0x7553,0x534c}, {0x7554,0x5a6d}, {0x7559,0x573a}, {0x755b,0x7255}, {0x755c,0x7565}, - {0x755d,0x596f}, {0x7562,0x7934}, {0x7565,0x5554}, {0x7566,0x7d4f}, {0x756a,0x5b63}, {0x756f,0x7161}, {0x7570,0x6c36}, {0x7575,0x7b7e}, {0x7576,0x5357}, {0x7578,0x5131}, - {0x757a,0x4b31}, {0x757f,0x5132}, {0x7586,0x4b32}, {0x7587,0x7142}, {0x758a,0x7461}, {0x758b,0x7935}, {0x758e,0x6143}, {0x758f,0x6142}, {0x7591,0x6b77}, {0x759d,0x5f28}, - {0x75a5,0x4b4a}, {0x75ab,0x6639}, {0x75b1,0x785e}, {0x75b2,0x792a}, {0x75b3,0x4a77}, {0x75b5,0x6d37}, {0x75b8,0x5338}, {0x75b9,0x7256}, {0x75bc,0x5459}, {0x75bd,0x6e45}, - {0x75be,0x7270}, {0x75c2,0x4a32}, {0x75c5,0x5c3b}, {0x75c7,0x7178}, {0x75cd,0x6c37}, {0x75d2,0x654a}, {0x75d4,0x7640}, {0x75d5,0x7d5d}, {0x75d8,0x5463}, {0x75d9,0x4c62}, - {0x75db,0x7754}, {0x75e2,0x5765}, {0x75f0,0x5343}, {0x75f2,0x5826}, {0x75f4,0x7641}, {0x75fa,0x5d76}, {0x75fc,0x4d40}, {0x7600,0x655c}, {0x760d,0x654b}, {0x7619,0x6144}, - {0x761f,0x6830}, {0x7620,0x7430}, {0x7621,0x736a}, {0x7622,0x5a6e}, {0x7624,0x573b}, {0x7626,0x6231}, {0x763b,0x572a}, {0x7642,0x567b}, {0x764c,0x645f}, {0x764e,0x4a56}, - {0x7652,0x6b28}, {0x7656,0x5b7e}, {0x7661,0x7642}, {0x7664,0x6f3b}, {0x7669,0x547d}, {0x766c,0x6048}, {0x7670,0x6839}, {0x7672,0x6f26}, {0x7678,0x4d24}, {0x767b,0x5474}, - {0x767c,0x5b21}, {0x767d,0x5b5c}, {0x767e,0x5b5d}, {0x7684,0x6e5c}, {0x7686,0x4b4b}, {0x7687,0x7c55}, {0x768e,0x4e6b}, {0x7690,0x4d41}, {0x7693,0x7b53}, {0x76ae,0x792b}, - {0x76ba,0x7554}, {0x76bf,0x5929}, {0x76c2,0x695d}, {0x76c3,0x5b4d}, {0x76c6,0x5d4e}, {0x76c8,0x6743}, {0x76ca,0x6c4c}, {0x76d2,0x796c}, {0x76d6,0x4b4c}, {0x76db,0x607c}, - {0x76dc,0x5428}, {0x76de,0x6d53}, {0x76df,0x586f}, {0x76e1,0x7257}, {0x76e3,0x4a78}, {0x76e4,0x5a6f}, {0x76e7,0x5654}, {0x76ee,0x594d}, {0x76f2,0x586e}, {0x76f4,0x7241}, - {0x76f8,0x5f53}, {0x76fc,0x5a70}, {0x76fe,0x626a}, {0x7701,0x607d}, {0x7704,0x5878}, {0x7708,0x772f}, {0x7709,0x5a36}, {0x770b,0x4a57}, {0x771e,0x7258}, {0x7720,0x5879}, - {0x7729,0x7a5f}, {0x7737,0x4f6f}, {0x7738,0x5942}, {0x773a,0x7052}, {0x773c,0x6451}, {0x7740,0x7337}, {0x774d,0x7a60}, {0x775b,0x6f6c}, {0x7761,0x6232}, {0x7763,0x543d}, - {0x7766,0x594e}, {0x776b,0x7462}, {0x7779,0x5429}, {0x777e,0x4d42}, {0x777f,0x675a}, {0x778b,0x7259}, {0x7791,0x592a}, {0x779e,0x583e}, {0x77a5,0x5c2d}, {0x77ac,0x626b}, - {0x77ad,0x567c}, {0x77b0,0x4a79}, {0x77b3,0x545a}, {0x77bb,0x7457}, {0x77bc,0x4c21}, {0x77bf,0x4f3a}, {0x77d7,0x7538}, {0x77db,0x5943}, {0x77dc,0x5068}, {0x77e2,0x6345}, - {0x77e3,0x6b78}, {0x77e5,0x7231}, {0x77e9,0x4f3b}, {0x77ed,0x532d}, {0x77ee,0x6861}, {0x77ef,0x4e6c}, {0x77f3,0x6034}, {0x7802,0x5e63}, {0x7812,0x5d77}, {0x7825,0x7232}, - {0x7826,0x7376}, {0x7827,0x765b}, {0x782c,0x577e}, {0x7832,0x785f}, {0x7834,0x7772}, {0x7845,0x5029}, {0x784f,0x665a}, {0x785d,0x7526}, {0x786b,0x573c}, {0x786c,0x4c63}, - {0x786f,0x665b}, {0x787c,0x5d5d}, {0x7881,0x5133}, {0x7887,0x6f6d}, {0x788c,0x565e}, {0x788d,0x6474}, {0x788e,0x616f}, {0x7891,0x5d78}, {0x7897,0x684f}, {0x78a3,0x4a65}, - {0x78a7,0x5c21}, {0x78a9,0x6035}, {0x78ba,0x7c2c}, {0x78bb,0x7c2d}, {0x78bc,0x5827}, {0x78c1,0x6d38}, {0x78c5,0x5b36}, {0x78ca,0x5670}, {0x78cb,0x732f}, {0x78ce,0x4d25}, - {0x78d0,0x5a71}, {0x78e8,0x5828}, {0x78ec,0x4c64}, {0x78ef,0x5134}, {0x78f5,0x4a58}, {0x78fb,0x5a72}, {0x7901,0x7527}, {0x790e,0x7528}, {0x7916,0x6626}, {0x792a,0x556c}, - {0x792b,0x5578}, {0x792c,0x5a73}, {0x793a,0x6346}, {0x793e,0x5e64}, {0x7940,0x5e65}, {0x7941,0x5135}, {0x7947,0x5136}, {0x7948,0x5137}, {0x7949,0x7233}, {0x7950,0x695e}, - {0x7956,0x7053}, {0x7957,0x7234}, {0x795a,0x7054}, {0x795b,0x4b64}, {0x795c,0x7b54}, {0x795d,0x7566}, {0x795e,0x636a}, {0x7960,0x5e66}, {0x7965,0x5f54}, {0x7968,0x7879}, - {0x796d,0x702e}, {0x797a,0x5138}, {0x797f,0x565f}, {0x7981,0x5057}, {0x798d,0x7c21}, {0x798e,0x6f6e}, {0x798f,0x5c58}, {0x7991,0x695f}, {0x79a6,0x655d}, {0x79a7,0x7d7b}, - {0x79aa,0x6049}, {0x79ae,0x5649}, {0x79b1,0x542a}, {0x79b3,0x654c}, {0x79b9,0x6960}, {0x79bd,0x5058}, {0x79be,0x7c22}, {0x79bf,0x543e}, {0x79c0,0x6233}, {0x79c1,0x5e67}, - {0x79c9,0x5c3c}, {0x79ca,0x5236}, {0x79cb,0x7555}, {0x79d1,0x4e21}, {0x79d2,0x7529}, {0x79d5,0x5d79}, {0x79d8,0x5d7a}, {0x79df,0x7055}, {0x79e4,0x765f}, {0x79e6,0x725a}, - {0x79e7,0x646b}, {0x79e9,0x7271}, {0x79fb,0x6c39}, {0x7a00,0x7d7c}, {0x7a05,0x612a}, {0x7a08,0x4a59}, {0x7a0b,0x6f6f}, {0x7a0d,0x752a}, {0x7a14,0x6c79}, {0x7a17,0x782d}, - {0x7a19,0x7242}, {0x7a1a,0x7643}, {0x7a1c,0x5752}, {0x7a1f,0x7922}, {0x7a20,0x7056}, {0x7a2e,0x707a}, {0x7a31,0x7660}, {0x7a36,0x6973}, {0x7a37,0x7243}, {0x7a3b,0x542b}, - {0x7a3c,0x4a33}, {0x7a3d,0x4d26}, {0x7a3f,0x4d43}, {0x7a40,0x4d5a}, {0x7a46,0x594f}, {0x7a49,0x7644}, {0x7a4d,0x6e5d}, {0x7a4e,0x6744}, {0x7a57,0x6234}, {0x7a61,0x5f62}, - {0x7a62,0x675b}, {0x7a69,0x6831}, {0x7a6b,0x7c2e}, {0x7a70,0x654d}, {0x7a74,0x7a6b}, {0x7a76,0x4f3c}, {0x7a79,0x4f62}, {0x7a7a,0x4d76}, {0x7a7d,0x6f70}, {0x7a7f,0x743e}, - {0x7a81,0x544d}, {0x7a84,0x7338}, {0x7a88,0x6921}, {0x7a92,0x7272}, {0x7a93,0x736b}, {0x7a95,0x7057}, {0x7a98,0x4f57}, {0x7a9f,0x4f5f}, {0x7aa9,0x6840}, {0x7aaa,0x6841}, - {0x7aae,0x4f63}, {0x7aaf,0x6922}, {0x7aba,0x502a}, {0x7ac4,0x7341}, {0x7ac5,0x502b}, {0x7ac7,0x5464}, {0x7aca,0x6f3c}, {0x7acb,0x5821}, {0x7ad7,0x595f}, {0x7ad9,0x7357}, - {0x7add,0x5c3d}, {0x7adf,0x4c65}, {0x7ae0,0x6d71}, {0x7ae3,0x7162}, {0x7ae5,0x545b}, {0x7aea,0x6235}, {0x7aed,0x4a66}, {0x7aef,0x532e}, {0x7af6,0x4c66}, {0x7af9,0x7153}, - {0x7afa,0x7567}, {0x7aff,0x4a5a}, {0x7b0f,0x7b6e}, {0x7b11,0x6145}, {0x7b19,0x5f69}, {0x7b1b,0x6e5e}, {0x7b1e,0x7742}, {0x7b20,0x5822}, {0x7b26,0x5d2c}, {0x7b2c,0x702f}, - {0x7b2d,0x563d}, {0x7b39,0x612b}, {0x7b46,0x7936}, {0x7b49,0x5475}, {0x7b4b,0x5049}, {0x7b4c,0x6f27}, {0x7b4d,0x626c}, {0x7b4f,0x5b6a}, {0x7b50,0x4e4c}, {0x7b51,0x7568}, - {0x7b52,0x7755}, {0x7b54,0x534d}, {0x7b56,0x737e}, {0x7b60,0x5035}, {0x7b6c,0x607e}, {0x7b6e,0x5f7b}, {0x7b75,0x665d}, {0x7b7d,0x6824}, {0x7b87,0x4b4d}, {0x7b8b,0x6f28}, - {0x7b8f,0x6e34}, {0x7b94,0x5a58}, {0x7b95,0x5139}, {0x7b97,0x5f29}, {0x7b9a,0x7330}, {0x7b9d,0x4c44}, {0x7ba1,0x4e37}, {0x7bad,0x6f29}, {0x7bb1,0x5f55}, {0x7bb4,0x6d57}, - {0x7bb8,0x6e46}, {0x7bc0,0x6f3d}, {0x7bc1,0x7c56}, {0x7bc4,0x5b74}, {0x7bc6,0x6f2a}, {0x7bc7,0x7839}, {0x7bc9,0x7569}, {0x7bd2,0x6359}, {0x7be0,0x6146}, {0x7be4,0x543f}, - {0x7be9,0x5e68}, {0x7c07,0x706a}, {0x7c12,0x7342}, {0x7c1e,0x532f}, {0x7c21,0x4a5b}, {0x7c27,0x7c57}, {0x7c2a,0x6d58}, {0x7c2b,0x6147}, {0x7c3d,0x7458}, {0x7c3e,0x5633}, - {0x7c3f,0x5d2d}, {0x7c43,0x553e}, {0x7c4c,0x7143}, {0x7c4d,0x6e5f}, {0x7c60,0x566b}, {0x7c64,0x7459}, {0x7c6c,0x5766}, {0x7c73,0x5a37}, {0x7c83,0x5d7b}, {0x7c89,0x5d4f}, - {0x7c92,0x5823}, {0x7c95,0x5a59}, {0x7c97,0x7058}, {0x7c98,0x6f44}, {0x7c9f,0x6158}, {0x7ca5,0x7154}, {0x7ca7,0x6d72}, {0x7cae,0x555b}, {0x7cb1,0x555c}, {0x7cb2,0x7344}, - {0x7cb3,0x4b57}, {0x7cb9,0x6236}, {0x7cbe,0x6f71}, {0x7cca,0x7b55}, {0x7cd6,0x5358}, {0x7cde,0x5d50}, {0x7cdf,0x7059}, {0x7ce0,0x4b33}, {0x7ce7,0x555d}, {0x7cfb,0x4d27}, - {0x7cfe,0x502c}, {0x7d00,0x513a}, {0x7d02,0x7144}, {0x7d04,0x6533}, {0x7d05,0x7b75}, {0x7d06,0x6961}, {0x7d07,0x7d60}, {0x7d08,0x7c3c}, {0x7d0a,0x5a22}, {0x7d0b,0x5a23}, - {0x7d0d,0x5221}, {0x7d10,0x526f}, {0x7d14,0x626d}, {0x7d17,0x5e69}, {0x7d18,0x4e5c}, {0x7d19,0x7235}, {0x7d1a,0x5064}, {0x7d1b,0x5d51}, {0x7d20,0x6148}, {0x7d21,0x5b37}, - {0x7d22,0x5f63}, {0x7d2b,0x6d39}, {0x7d2c,0x7145}, {0x7d2e,0x734f}, {0x7d2f,0x572b}, {0x7d30,0x612c}, {0x7d33,0x636b}, {0x7d35,0x6e47}, {0x7d39,0x6149}, {0x7d3a,0x4a7a}, - {0x7d42,0x707b}, {0x7d43,0x7a61}, {0x7d44,0x705a}, {0x7d45,0x4c67}, {0x7d46,0x5a74}, {0x7d50,0x4c3f}, {0x7d5e,0x4e6d}, {0x7d61,0x5529}, {0x7d62,0x7a62}, {0x7d66,0x5065}, - {0x7d68,0x6b56}, {0x7d6a,0x6c5f}, {0x7d6e,0x5f7c}, {0x7d71,0x7756}, {0x7d72,0x5e6a}, {0x7d73,0x4b34}, {0x7d76,0x6f3e}, {0x7d79,0x4c35}, {0x7d7f,0x4f3d}, {0x7d8e,0x6f72}, - {0x7d8f,0x6237}, {0x7d93,0x4c68}, {0x7d9c,0x707c}, {0x7da0,0x5660}, {0x7da2,0x7146}, {0x7dac,0x6238}, {0x7dad,0x6b2b}, {0x7db1,0x4b35}, {0x7db2,0x5851}, {0x7db4,0x744e}, - {0x7db5,0x7377}, {0x7db8,0x5746}, {0x7dba,0x513b}, {0x7dbb,0x772a}, {0x7dbd,0x6d4a}, {0x7dbe,0x5753}, {0x7dbf,0x587a}, {0x7dc7,0x7645}, {0x7dca,0x514c}, {0x7dcb,0x5d7c}, - {0x7dd6,0x5f7d}, {0x7dd8,0x7965}, {0x7dda,0x604a}, {0x7ddd,0x727d}, {0x7dde,0x5330}, {0x7de0,0x7473}, {0x7de1,0x5a49}, {0x7de3,0x665e}, {0x7de8,0x783a}, {0x7de9,0x6850}, - {0x7dec,0x587b}, {0x7def,0x6a55}, {0x7df4,0x5623}, {0x7dfb,0x7646}, {0x7e09,0x725b}, {0x7e0a,0x647c}, {0x7e15,0x6832}, {0x7e1b,0x5a5a}, {0x7e1d,0x725c}, {0x7e1e,0x7b56}, - {0x7e1f,0x6932}, {0x7e21,0x6e2d}, {0x7e23,0x7a63}, {0x7e2b,0x5c6e}, {0x7e2e,0x756a}, {0x7e2f,0x6660}, {0x7e31,0x707d}, {0x7e37,0x572c}, {0x7e3d,0x7545}, {0x7e3e,0x6e60}, - {0x7e41,0x5b65}, {0x7e43,0x5d5e}, {0x7e46,0x5970}, {0x7e47,0x6923}, {0x7e52,0x7179}, {0x7e54,0x7244}, {0x7e55,0x604b}, {0x7e5e,0x6924}, {0x7e61,0x6239}, {0x7e69,0x6331}, - {0x7e6a,0x7c6b}, {0x7e6b,0x4d28}, {0x7e6d,0x4c36}, {0x7e70,0x705b}, {0x7e79,0x663a}, {0x7e7c,0x4d29}, {0x7e82,0x7343}, {0x7e8c,0x6159}, {0x7e8f,0x6f2b}, {0x7e93,0x6745}, - {0x7e96,0x6069}, {0x7e98,0x7345}, {0x7e9b,0x5440}, {0x7e9c,0x553f}, {0x7f36,0x5d2e}, {0x7f38,0x797c}, {0x7f3a,0x4c40}, {0x7f4c,0x6522}, {0x7f50,0x4e38}, {0x7f54,0x5852}, - {0x7f55,0x7956}, {0x7f6a,0x712a}, {0x7f6b,0x4e51}, {0x7f6e,0x7647}, {0x7f70,0x5b6b}, {0x7f72,0x5f7e}, {0x7f75,0x5861}, {0x7f77,0x7773}, {0x7f79,0x5767}, {0x7f85,0x547e}, - {0x7f88,0x513c}, {0x7f8a,0x654f}, {0x7f8c,0x4b36}, {0x7f8e,0x5a38}, {0x7f94,0x4d44}, {0x7f9a,0x563e}, {0x7f9e,0x623a}, {0x7fa4,0x4f58}, {0x7fa8,0x604c}, {0x7fa9,0x6b79}, - {0x7fb2,0x7d7d}, {0x7fb8,0x5768}, {0x7fb9,0x4b58}, {0x7fbd,0x6962}, {0x7fc1,0x683a}, {0x7fc5,0x6347}, {0x7fca,0x6c4d}, {0x7fcc,0x6c4e}, {0x7fce,0x563f}, {0x7fd2,0x6327}, - {0x7fd4,0x5f56}, {0x7fd5,0x7d68}, {0x7fdf,0x6e61}, {0x7fe0,0x7628}, {0x7fe1,0x5d7d}, {0x7fe9,0x783b}, {0x7feb,0x6851}, {0x7ff0,0x7957}, {0x7ff9,0x4e6e}, {0x7ffc,0x6c4f}, - {0x8000,0x6925}, {0x8001,0x5655}, {0x8003,0x4d45}, {0x8005,0x6d3a}, {0x8006,0x513d}, {0x8009,0x4f3e}, {0x800c,0x6c3b}, {0x8010,0x5231}, {0x8015,0x4c69}, {0x8017,0x5944}, - {0x8018,0x697c}, {0x802d,0x513e}, {0x8033,0x6c3c}, {0x8036,0x652d}, {0x803d,0x7730}, {0x803f,0x4c6a}, {0x8043,0x5344}, {0x8046,0x5640}, {0x804a,0x567d}, {0x8056,0x6121}, - {0x8058,0x5e3d}, {0x805a,0x7629}, {0x805e,0x5a24}, {0x806f,0x5624}, {0x8070,0x7546}, {0x8072,0x6122}, {0x8073,0x6946}, {0x8077,0x7245}, {0x807d,0x7469}, {0x807e,0x566c}, - {0x807f,0x6b53}, {0x8084,0x6c3d}, {0x8085,0x625c}, {0x8086,0x5e6b}, {0x8087,0x705c}, {0x8089,0x6b3f}, {0x808b,0x574e}, {0x808c,0x513f}, {0x8096,0x752b}, {0x809b,0x797d}, - {0x809d,0x4a5c}, {0x80a1,0x4d46}, {0x80a2,0x7236}, {0x80a5,0x5d7e}, {0x80a9,0x4c37}, {0x80aa,0x5b38}, {0x80af,0x5069}, {0x80b1,0x4e5d}, {0x80b2,0x6b40}, {0x80b4,0x7d22}, - {0x80ba,0x784b}, {0x80c3,0x6a56}, {0x80c4,0x7130}, {0x80cc,0x5b4e}, {0x80ce,0x7743}, {0x80da,0x5b4f}, {0x80db,0x4b24}, {0x80de,0x7860}, {0x80e1,0x7b57}, {0x80e4,0x6b4a}, - {0x80e5,0x6021}, {0x80f1,0x4e4d}, {0x80f4,0x545c}, {0x80f8,0x7d58}, {0x80fd,0x5276}, {0x8102,0x7237}, {0x8105,0x7a76}, {0x8106,0x762a}, {0x8107,0x7a77}, {0x8108,0x5866}, - {0x810a,0x7431}, {0x8118,0x6852}, {0x811a,0x4a45}, {0x811b,0x4c6b}, {0x8123,0x626e}, {0x8129,0x623b}, {0x812b,0x772d}, {0x812f,0x7861}, {0x8139,0x736c}, {0x813e,0x5e21}, - {0x814b,0x647d}, {0x814e,0x636c}, {0x8150,0x5d2f}, {0x8151,0x5d30}, {0x8154,0x4b37}, {0x8155,0x6853}, {0x8165,0x6123}, {0x8166,0x5260}, {0x816b,0x707e}, {0x8170,0x6926}, - {0x8171,0x4b72}, {0x8178,0x6d73}, {0x8179,0x5c59}, {0x817a,0x604d}, {0x817f,0x775a}, {0x8180,0x5b39}, {0x8188,0x4c2e}, {0x818a,0x5a5b}, {0x818f,0x4d47}, {0x819a,0x5d31}, - {0x819c,0x582f}, {0x819d,0x6323}, {0x81a0,0x4e6f}, {0x81a3,0x7273}, {0x81a8,0x7833}, {0x81b3,0x604e}, {0x81b5,0x757d}, {0x81ba,0x6b6c}, {0x81bd,0x5345}, {0x81be,0x7c6c}, - {0x81bf,0x525b}, {0x81c0,0x546b}, {0x81c2,0x5e22}, {0x81c6,0x6566}, {0x81cd,0x7030}, {0x81d8,0x5544}, {0x81df,0x6d74}, {0x81e3,0x636d}, {0x81e5,0x6842}, {0x81e7,0x6d75}, - {0x81e8,0x577c}, {0x81ea,0x6d3b}, {0x81ed,0x762b}, {0x81f3,0x7238}, {0x81f4,0x7648}, {0x81fa,0x5366}, {0x81fb,0x725d}, {0x81fc,0x4f3f}, {0x81fe,0x6b2c}, {0x8205,0x4f40}, - {0x8207,0x6628}, {0x8208,0x7d69}, {0x820a,0x4f41}, {0x820c,0x605f}, {0x820d,0x5e6c}, {0x8212,0x6022}, {0x821b,0x743f}, {0x821c,0x626f}, {0x821e,0x5971}, {0x821f,0x7147}, - {0x8221,0x4b38}, {0x822a,0x797e}, {0x822b,0x5b3a}, {0x822c,0x5a75}, {0x8235,0x766c}, {0x8236,0x5a5c}, {0x8237,0x7a64}, {0x8239,0x604f}, {0x8240,0x5d32}, {0x8245,0x6629}, - {0x8247,0x6f73}, {0x8259,0x736d}, {0x8264,0x6b7a}, {0x8266,0x7966}, {0x826e,0x4a5d}, {0x826f,0x555e}, {0x8271,0x4a5e}, {0x8272,0x5f64}, {0x8276,0x667d}, {0x8278,0x752c}, - {0x827e,0x6475}, {0x828b,0x6963}, {0x828d,0x6d4b}, {0x828e,0x4f64}, {0x8292,0x5853}, {0x8299,0x5d33}, {0x829a,0x546c}, {0x829d,0x7239}, {0x829f,0x5f37}, {0x82a5,0x4b4e}, - {0x82a6,0x7b58}, {0x82a9,0x5059}, {0x82ac,0x5d52}, {0x82ad,0x7774}, {0x82ae,0x675c}, {0x82af,0x6425}, {0x82b1,0x7c23}, {0x82b3,0x5b3b}, {0x82b7,0x723a}, {0x82b8,0x697d}, - {0x82b9,0x504a}, {0x82bb,0x7556}, {0x82bc,0x5945}, {0x82bd,0x6434}, {0x82bf,0x6d27}, {0x82d1,0x6a3d}, {0x82d2,0x667e}, {0x82d4,0x7744}, {0x82d5,0x752d}, {0x82d7,0x5960}, - {0x82db,0x4a34}, {0x82de,0x7862}, {0x82df,0x4f42}, {0x82e1,0x6c3e}, {0x82e5,0x6534}, {0x82e6,0x4d48}, {0x82e7,0x6e48}, {0x82f1,0x6748}, {0x82fd,0x4d49}, {0x82fe,0x7937}, - {0x8301,0x7168}, {0x8302,0x5972}, {0x8303,0x5b75}, {0x8304,0x4a35}, {0x8305,0x5946}, {0x8309,0x5849}, {0x8317,0x592b}, {0x8328,0x6d3c}, {0x832b,0x5854}, {0x832f,0x5c5a}, - {0x8331,0x623c}, {0x8334,0x7c6d}, {0x8335,0x6c60}, {0x8336,0x527e}, {0x8338,0x6947}, {0x8339,0x662a}, {0x8340,0x6270}, {0x8347,0x7a3b}, {0x8349,0x752e}, {0x834a,0x7b2a}, - {0x834f,0x6c7b}, {0x8351,0x6c3f}, {0x8352,0x7c58}, {0x8373,0x5465}, {0x8377,0x7943}, {0x837b,0x6e62}, {0x8389,0x5769}, {0x838a,0x6d76}, {0x838e,0x5e6d}, {0x8396,0x4c6c}, - {0x8398,0x636e}, {0x839e,0x6854}, {0x83a2,0x7a78}, {0x83a9,0x5d34}, {0x83aa,0x6435}, {0x83ab,0x5830}, {0x83bd,0x5855}, {0x83c1,0x746a}, {0x83c5,0x4e39}, {0x83c9,0x5661}, - {0x83ca,0x4f52}, {0x83cc,0x5036}, {0x83d3,0x4e22}, {0x83d6,0x736e}, {0x83dc,0x7378}, {0x83e9,0x5c4c}, {0x83eb,0x504b}, {0x83ef,0x7c24}, {0x83f0,0x4d4a}, {0x83f1,0x5754}, - {0x83f2,0x5e23}, {0x83f4,0x6460}, {0x83f9,0x6e49}, {0x83fd,0x625d}, {0x8403,0x757e}, {0x8404,0x542c}, {0x840a,0x5551}, {0x840c,0x5870}, {0x840d,0x7843}, {0x840e,0x6a57}, - {0x8429,0x7557}, {0x842c,0x583f}, {0x8431,0x7d40}, {0x8438,0x6b2d}, {0x843d,0x552a}, {0x8449,0x6728}, {0x8457,0x6e4a}, {0x845b,0x4a67}, {0x8461,0x7863}, {0x8463,0x545d}, - {0x8466,0x6a58}, {0x846b,0x7b59}, {0x846c,0x6d77}, {0x846f,0x6535}, {0x8475,0x502d}, {0x847a,0x7171}, {0x8490,0x623d}, {0x8494,0x6348}, {0x8499,0x5955}, {0x849c,0x5f2a}, - {0x84a1,0x5b3c}, {0x84b2,0x7864}, {0x84b8,0x717a}, {0x84bb,0x6536}, {0x84bc,0x736f}, {0x84bf,0x7b5a}, {0x84c0,0x6160}, {0x84c2,0x592c}, {0x84c4,0x756b}, {0x84c6,0x6036}, - {0x84c9,0x6948}, {0x84cb,0x4b4f}, {0x84cd,0x6349}, {0x84d1,0x5e6e}, {0x84da,0x623e}, {0x84ec,0x5c6f}, {0x84ee,0x5625}, {0x84f4,0x6271}, {0x84fc,0x567e}, {0x8511,0x5921}, - {0x8513,0x5840}, {0x8514,0x5c5b}, {0x8517,0x6d3d}, {0x8518,0x5f38}, {0x851a,0x6a25}, {0x851e,0x572d}, {0x8521,0x7379}, {0x8523,0x6d78}, {0x8525,0x7547}, {0x852c,0x614a}, - {0x852d,0x6b63}, {0x852f,0x725e}, {0x853d,0x784c}, {0x853f,0x6a59}, {0x8541,0x5346}, {0x8543,0x5b66}, {0x8549,0x752f}, {0x854e,0x4e70}, {0x8553,0x697e}, {0x8559,0x7b36}, - {0x8563,0x6272}, {0x8568,0x4f72}, {0x8569,0x7739}, {0x856a,0x5973}, {0x856d,0x614b}, {0x8584,0x5a5d}, {0x8587,0x5a39}, {0x858f,0x6b7b}, {0x8591,0x4b39}, {0x8594,0x6d79}, - {0x859b,0x6060}, {0x85a6,0x7440}, {0x85a8,0x7d3c}, {0x85a9,0x5f31}, {0x85aa,0x636f}, {0x85af,0x6023}, {0x85b0,0x7d39}, {0x85ba,0x7031}, {0x85c1,0x4d4b}, {0x85c9,0x6d3e}, - {0x85cd,0x5540}, {0x85ce,0x6370}, {0x85cf,0x6d7a}, {0x85d5,0x6964}, {0x85dc,0x556d}, {0x85dd,0x675d}, {0x85e4,0x5476}, {0x85e5,0x6537}, {0x85e9,0x5b67}, {0x85ea,0x623f}, - {0x85f7,0x6e4b}, {0x85fa,0x5774}, {0x85fb,0x705d}, {0x85ff,0x4e2b}, {0x8602,0x675e}, {0x8606,0x5656}, {0x8607,0x614c}, {0x860a,0x6833}, {0x8616,0x656e}, {0x8617,0x5c22}, - {0x861a,0x6050}, {0x862d,0x5535}, {0x863f,0x5521}, {0x864e,0x7b5b}, {0x8650,0x794b}, {0x8654,0x4b73}, {0x8655,0x7425}, {0x865b,0x7a48}, {0x865c,0x5657}, {0x865e,0x6965}, - {0x865f,0x7b5c}, {0x8667,0x7d50}, {0x8679,0x7b76}, {0x868a,0x5a25}, {0x868c,0x5b3d}, {0x8693,0x6c62}, {0x86a3,0x4d77}, {0x86a4,0x705e}, {0x86a9,0x7649}, {0x86c7,0x5e6f}, - {0x86cb,0x5331}, {0x86d4,0x7c6e}, {0x86d9,0x6843}, {0x86db,0x7148}, {0x86df,0x4e71}, {0x86e4,0x796d}, {0x86ed,0x7274}, {0x86fe,0x6436}, {0x8700,0x7539}, {0x8702,0x5c70}, - {0x8703,0x6371}, {0x8708,0x6825}, {0x8718,0x723b}, {0x871a,0x5e24}, {0x871c,0x5a4c}, {0x874e,0x4a69}, {0x8755,0x635a}, {0x8757,0x7c59}, {0x875f,0x6a5a}, {0x8766,0x7944}, - {0x8768,0x6324}, {0x8774,0x7b5d}, {0x8776,0x6f4a}, {0x8778,0x6844}, {0x8782,0x554c}, {0x878d,0x6b57}, {0x879f,0x592d}, {0x87a2,0x7b2b}, {0x87b3,0x5359}, {0x87ba,0x5522}, - {0x87c4,0x765e}, {0x87e0,0x5a76}, {0x87ec,0x6051}, {0x87ef,0x6928}, {0x87f2,0x7579}, {0x87f9,0x7a2f}, {0x87fb,0x6b7c}, {0x87fe,0x606a}, {0x8805,0x6332}, {0x881f,0x5545}, - {0x8822,0x7163}, {0x8823,0x556e}, {0x8831,0x4d4c}, {0x8836,0x6d59}, {0x883b,0x5841}, {0x8840,0x7a6c}, {0x8846,0x716b}, {0x884c,0x7a3c}, {0x884d,0x6662}, {0x8852,0x7a65}, - {0x8853,0x627a}, {0x8857,0x4a36}, {0x8859,0x6437}, {0x885b,0x6a5b}, {0x885d,0x757a}, {0x8861,0x7b2c}, {0x8862,0x4f43}, {0x8863,0x6b7d}, {0x8868,0x787a}, {0x886b,0x5f39}, - {0x8870,0x6171}, {0x8872,0x5224}, {0x8877,0x757b}, {0x887e,0x505a}, {0x887f,0x505b}, {0x8881,0x6a3e}, {0x8882,0x5931}, {0x8888,0x4a37}, {0x888b,0x5367}, {0x888d,0x7865}, - {0x8892,0x5332}, {0x8896,0x6240}, {0x8897,0x725f}, {0x889e,0x4d65}, {0x88ab,0x792c}, {0x88b4,0x4d4d}, {0x88c1,0x6e2e}, {0x88c2,0x562e}, {0x88cf,0x576a}, {0x88d4,0x6760}, - {0x88d5,0x6b2e}, {0x88d9,0x4f59}, {0x88dc,0x5c4d}, {0x88dd,0x6d7b}, {0x88df,0x5e70}, {0x88e1,0x576b}, {0x88e8,0x5e25}, {0x88f3,0x5f57}, {0x88f4,0x5b50}, {0x88f5,0x5b51}, - {0x88f8,0x5523}, {0x88fd,0x7032}, {0x8907,0x5c5c}, {0x8910,0x4a68}, {0x8912,0x7866}, {0x8913,0x5c4e}, {0x8918,0x6a5c}, {0x8919,0x5b52}, {0x8925,0x6933}, {0x892a,0x775b}, - {0x8936,0x6328}, {0x8938,0x572e}, {0x893b,0x6061}, {0x8941,0x4b3a}, {0x8944,0x6551}, {0x895f,0x505c}, {0x8964,0x5541}, {0x896a,0x584a}, {0x8972,0x6329}, {0x897f,0x6024}, - {0x8981,0x6929}, {0x8983,0x5347}, {0x8986,0x5c5d}, {0x8987,0x782e}, {0x898b,0x4c38}, {0x898f,0x502e}, {0x8993,0x5872}, {0x8996,0x634a}, {0x89a1,0x4c2f}, {0x89a9,0x542d}, - {0x89aa,0x7651}, {0x89b2,0x504c}, {0x89ba,0x4a46}, {0x89bd,0x5542}, {0x89c0,0x4e3a}, {0x89d2,0x4a47}, {0x89e3,0x7a30}, {0x89f4,0x5f58}, {0x89f8,0x753a}, {0x8a00,0x656b}, - {0x8a02,0x6f74}, {0x8a03,0x5d35}, {0x8a08,0x4d2a}, {0x8a0a,0x6372}, {0x8a0c,0x7b77}, {0x8a0e,0x7750}, {0x8a13,0x7d3a}, {0x8a16,0x7d61}, {0x8a17,0x767e}, {0x8a18,0x5140}, - {0x8a1b,0x6845}, {0x8a1d,0x6438}, {0x8a1f,0x6168}, {0x8a23,0x4c41}, {0x8a25,0x526d}, {0x8a2a,0x5b3e}, {0x8a2d,0x6062}, {0x8a31,0x7a49}, {0x8a34,0x614d}, {0x8a36,0x4a38}, - {0x8a3a,0x7260}, {0x8a3b,0x7149}, {0x8a50,0x5e71}, {0x8a54,0x705f}, {0x8a55,0x7844}, {0x8a5b,0x6e4c}, {0x8a5e,0x5e72}, {0x8a60,0x6749}, {0x8a62,0x6273}, {0x8a63,0x6761}, - {0x8a66,0x634b}, {0x8a69,0x634c}, {0x8a6d,0x4f78}, {0x8a6e,0x6f2c}, {0x8a70,0x7d7e}, {0x8a71,0x7c25}, {0x8a72,0x7a31}, {0x8a73,0x5f59}, {0x8a75,0x6052}, {0x8a79,0x745a}, - {0x8a85,0x714a}, {0x8a87,0x4e23}, {0x8a8c,0x723c}, {0x8a8d,0x6c63}, {0x8a93,0x6025}, {0x8a95,0x772b}, {0x8a98,0x6b2f}, {0x8a9e,0x655e}, {0x8aa0,0x6124}, {0x8aa1,0x4d2b}, - {0x8aa3,0x5974}, {0x8aa4,0x6826}, {0x8aa5,0x4d4e}, {0x8aa6,0x6169}, {0x8aa8,0x7c6f}, {0x8aaa,0x6063}, {0x8ab0,0x6241}, {0x8ab2,0x4e24}, {0x8ab9,0x5e26}, {0x8abc,0x6b7e}, - {0x8abe,0x6b5d}, {0x8abf,0x7060}, {0x8ac2,0x745b}, {0x8ac4,0x6274}, {0x8ac7,0x5348}, {0x8acb,0x746b}, {0x8acd,0x6e35}, {0x8acf,0x7558}, {0x8ad2,0x555f}, {0x8ad6,0x5665}, - {0x8adb,0x6b30}, {0x8adc,0x7463}, {0x8ae1,0x634d}, {0x8ae6,0x7474}, {0x8ae7,0x7a32}, {0x8aea,0x6f75}, {0x8aeb,0x4a5f}, {0x8aed,0x6b31}, {0x8aee,0x6d3f}, {0x8af1,0x7d49}, - {0x8af6,0x6426}, {0x8af7,0x7924}, {0x8af8,0x7033}, {0x8afa,0x656c}, {0x8afe,0x5167}, {0x8b00,0x5947}, {0x8b01,0x6457}, {0x8b02,0x6a5d}, {0x8b04,0x5477}, {0x8b0e,0x5a3a}, - {0x8b10,0x5a4d}, {0x8b14,0x794c}, {0x8b16,0x615a}, {0x8b17,0x5b3f}, {0x8b19,0x4c45}, {0x8b1a,0x6c50}, {0x8b1b,0x4b3b}, {0x8b1d,0x5e73}, {0x8b20,0x692a}, {0x8b28,0x5948}, - {0x8b2b,0x6e63}, {0x8b2c,0x573d}, {0x8b33,0x4f44}, {0x8b39,0x504d}, {0x8b41,0x7c26}, {0x8b49,0x717b}, {0x8b4e,0x7d52}, {0x8b4f,0x5141}, {0x8b58,0x635b}, {0x8b5a,0x5349}, - {0x8b5c,0x5c4f}, {0x8b66,0x4c6d}, {0x8b6c,0x5e27}, {0x8b6f,0x663b}, {0x8b70,0x6c21}, {0x8b74,0x4c39}, {0x8b77,0x7b5e}, {0x8b7d,0x6762}, {0x8b80,0x5441}, {0x8b8a,0x5c28}, - {0x8b90,0x6242}, {0x8b92,0x7358}, {0x8b93,0x6553}, {0x8b96,0x7359}, {0x8b9a,0x7346}, {0x8c37,0x4d5b}, {0x8c3f,0x4d2c}, {0x8c41,0x7c43}, {0x8c46,0x5467}, {0x8c48,0x5142}, - {0x8c4a,0x7925}, {0x8c4c,0x6855}, {0x8c55,0x634e}, {0x8c5a,0x544a}, {0x8c61,0x5f5a}, {0x8c6a,0x7b5f}, {0x8c6b,0x6763}, {0x8c79,0x787b}, {0x8c7a,0x634f}, {0x8c82,0x7530}, - {0x8c8a,0x5867}, {0x8c8c,0x5949}, {0x8c9d,0x782f}, {0x8c9e,0x6f76}, {0x8ca0,0x5d36}, {0x8ca1,0x6e2f}, {0x8ca2,0x4d78}, {0x8ca7,0x5e38}, {0x8ca8,0x7c27}, {0x8ca9,0x777c}, - {0x8caa,0x7731}, {0x8cab,0x4e3b}, {0x8cac,0x7421}, {0x8caf,0x6e4d}, {0x8cb0,0x612e}, {0x8cb3,0x6c43}, {0x8cb4,0x4f7e}, {0x8cb6,0x783f}, {0x8cb7,0x5862}, {0x8cb8,0x5368}, - {0x8cbb,0x5e28}, {0x8cbc,0x7464}, {0x8cbd,0x6c42}, {0x8cbf,0x5975}, {0x8cc0,0x7945}, {0x8cc1,0x5d53}, {0x8cc2,0x5671}, {0x8cc3,0x6c7c}, {0x8cc4,0x7c70}, {0x8cc7,0x6d40}, - {0x8cc8,0x4a39}, {0x8cca,0x6e64}, {0x8cd1,0x7261}, {0x8cd3,0x5e39}, {0x8cda,0x5672}, {0x8cdc,0x5e74}, {0x8cde,0x5f5b}, {0x8ce0,0x5b53}, {0x8ce2,0x7a67}, {0x8ce3,0x5863}, - {0x8ce4,0x7441}, {0x8ce6,0x5d37}, {0x8cea,0x7275}, {0x8ced,0x542e}, {0x8cf4,0x5673}, {0x8cfb,0x5d38}, {0x8cfc,0x4f45}, {0x8cfd,0x5f5f}, {0x8d04,0x723e}, {0x8d05,0x7621}, - {0x8d07,0x6b4b}, {0x8d08,0x717c}, {0x8d0a,0x7347}, {0x8d0d,0x606b}, {0x8d13,0x6d7c}, {0x8d16,0x615b}, {0x8d64,0x6e65}, {0x8d66,0x5e75}, {0x8d6b,0x7a53}, {0x8d70,0x714b}, - {0x8d73,0x502f}, {0x8d74,0x5d39}, {0x8d77,0x5143}, {0x8d85,0x7531}, {0x8d8a,0x6a46}, {0x8d99,0x7061}, {0x8da3,0x762c}, {0x8da8,0x7559}, {0x8db3,0x706b}, {0x8dba,0x5d3a}, - {0x8dbe,0x723f}, {0x8dc6,0x7745}, {0x8dcb,0x5b22}, {0x8dcc,0x7276}, {0x8dcf,0x4a3a}, {0x8ddb,0x7775}, {0x8ddd,0x4b65}, {0x8de1,0x6e66}, {0x8de3,0x6053}, {0x8de8,0x4e25}, - {0x8def,0x5658}, {0x8df3,0x542f}, {0x8e0a,0x6949}, {0x8e0f,0x534e}, {0x8e10,0x7442}, {0x8e1e,0x4b66}, {0x8e2a,0x7121}, {0x8e30,0x6b32}, {0x8e35,0x7122}, {0x8e42,0x6b33}, - {0x8e44,0x7034}, {0x8e47,0x4b74}, {0x8e48,0x5430}, {0x8e49,0x7332}, {0x8e4a,0x7b37}, {0x8e59,0x756c}, {0x8e5f,0x6e67}, {0x8e60,0x7432}, {0x8e74,0x756d}, {0x8e76,0x4f73}, - {0x8e81,0x7062}, {0x8e87,0x6e4e}, {0x8e8a,0x714c}, {0x8e8d,0x6538}, {0x8eaa,0x5775}, {0x8eab,0x6373}, {0x8eac,0x4f65}, {0x8ec0,0x4f46}, {0x8eca,0x7333}, {0x8ecb,0x6458}, - {0x8ecc,0x4f79}, {0x8ecd,0x4f5a}, {0x8ed2,0x7a4d}, {0x8edf,0x6663}, {0x8eeb,0x7262}, {0x8ef8,0x756e}, {0x8efb,0x4a3b}, {0x8efe,0x635c}, {0x8f03,0x4e72}, {0x8f05,0x5659}, - {0x8f09,0x6e30}, {0x8f12,0x7465}, {0x8f13,0x5842}, {0x8f14,0x5c50}, {0x8f15,0x4c6e}, {0x8f1b,0x5560}, {0x8f1c,0x764a}, {0x8f1d,0x7d4a}, {0x8f1e,0x5856}, {0x8f1f,0x744f}, - {0x8f26,0x5626}, {0x8f27,0x5c3e}, {0x8f29,0x5b54}, {0x8f2a,0x5747}, {0x8f2f,0x727e}, {0x8f33,0x714d}, {0x8f38,0x6243}, {0x8f39,0x5c5e}, {0x8f3b,0x5c5f}, {0x8f3e,0x6f2d}, - {0x8f3f,0x662b}, {0x8f44,0x795d}, {0x8f45,0x6a3f}, {0x8f49,0x6f2e}, {0x8f4d,0x7450}, {0x8f4e,0x4e73}, {0x8f5d,0x662c}, {0x8f5f,0x4e5e}, {0x8f62,0x5579}, {0x8f9b,0x6374}, - {0x8f9c,0x4d50}, {0x8fa3,0x5538}, {0x8fa6,0x777d}, {0x8fa8,0x5c29}, {0x8fad,0x5e76}, {0x8faf,0x5c2a}, {0x8fb0,0x7263}, {0x8fb1,0x6934}, {0x8fb2,0x525c}, {0x8fc2,0x6966}, - {0x8fc5,0x6376}, {0x8fce,0x674a}, {0x8fd1,0x504e}, {0x8fd4,0x5a77}, {0x8fe6,0x4a3c}, {0x8fea,0x6e68}, {0x8feb,0x5a5e}, {0x8fed,0x7277}, {0x8ff0,0x627b}, {0x8ff2,0x4c26}, - {0x8ff7,0x5a3b}, {0x8ff9,0x6e69}, {0x8ffd,0x755a}, {0x9000,0x775c}, {0x9001,0x616a}, {0x9002,0x4e41}, {0x9003,0x5431}, {0x9005,0x7d31}, {0x9006,0x663d}, {0x9008,0x7b2d}, - {0x900b,0x7867}, {0x900d,0x614e}, {0x900f,0x7762}, {0x9010,0x756f}, {0x9011,0x4f47}, {0x9014,0x5432}, {0x9015,0x4c6f}, {0x9017,0x5468}, {0x9019,0x6e4f}, {0x901a,0x7757}, - {0x901d,0x6026}, {0x901e,0x5641}, {0x901f,0x615c}, {0x9020,0x7063}, {0x9021,0x7164}, {0x9022,0x5c71}, {0x9023,0x5627}, {0x902e,0x7475}, {0x9031,0x714e}, {0x9032,0x7264}, - {0x9035,0x5030}, {0x9038,0x6c6f}, {0x903c,0x793a}, {0x903e,0x6b35}, {0x9041,0x546d}, {0x9042,0x6244}, {0x9047,0x6967}, {0x904a,0x6b34}, {0x904b,0x6a21}, {0x904d,0x783c}, - {0x904e,0x4e26}, {0x9050,0x7946}, {0x9051,0x7c5a}, {0x9053,0x5433}, {0x9054,0x5339}, {0x9055,0x6a5e}, {0x9059,0x692b}, {0x905c,0x6161}, {0x905d,0x534f}, {0x905e,0x7476}, - {0x9060,0x6a40}, {0x9061,0x614f}, {0x9063,0x4c3a}, {0x9069,0x6e6a}, {0x906d,0x7064}, {0x906e,0x7334}, {0x906f,0x546e}, {0x9072,0x7240}, {0x9075,0x7165}, {0x9077,0x7443}, - {0x9078,0x6054}, {0x907a,0x6b36}, {0x907c,0x5721}, {0x907d,0x4b68}, {0x907f,0x792d}, {0x9080,0x692d}, {0x9081,0x5864}, {0x9082,0x7a33}, {0x9083,0x6245}, {0x9084,0x7c3d}, - {0x9087,0x6c44}, {0x9088,0x5831}, {0x908a,0x5c2b}, {0x908f,0x5524}, {0x9091,0x6b69}, {0x9095,0x683b}, {0x9099,0x5857}, {0x90a2,0x7b2e}, {0x90a3,0x5161}, {0x90a6,0x5b40}, - {0x90a8,0x753e}, {0x90aa,0x5e77}, {0x90af,0x4a7b}, {0x90b0,0x7746}, {0x90b1,0x4f48}, {0x90b5,0x6150}, {0x90b8,0x6e50}, {0x90c1,0x6974}, {0x90ca,0x4e74}, {0x90de,0x554d}, - {0x90e1,0x4f5b}, {0x90e8,0x5d3b}, {0x90ed,0x4e2c}, {0x90f5,0x6968}, {0x90fd,0x5434}, {0x9102,0x6447}, {0x9112,0x755b}, {0x9115,0x7a41}, {0x9119,0x5e29}, {0x9127,0x5478}, - {0x912d,0x6f77}, {0x9132,0x5333}, {0x9149,0x6b37}, {0x914a,0x6f78}, {0x914b,0x755c}, {0x914c,0x6d4c}, {0x914d,0x5b55}, {0x914e,0x714f}, {0x9152,0x7150}, {0x9162,0x7532}, - {0x9169,0x592e}, {0x916a,0x552c}, {0x916c,0x6246}, {0x9175,0x7d23}, {0x9177,0x7b65}, {0x9178,0x5f2b}, {0x9187,0x6275}, {0x9189,0x762d}, {0x918b,0x7533}, {0x918d,0x7035}, - {0x9192,0x6125}, {0x919c,0x755d}, {0x91ab,0x6c22}, {0x91ac,0x6d7d}, {0x91ae,0x7534}, {0x91af,0x7b38}, {0x91b1,0x5b23}, {0x91b4,0x564a}, {0x91b5,0x4b59}, {0x91c0,0x6554}, - {0x91c7,0x737a}, {0x91c9,0x6b38}, {0x91cb,0x6037}, {0x91cc,0x576c}, {0x91cd,0x716c}, {0x91ce,0x652f}, {0x91cf,0x5561}, {0x91d0,0x576d}, {0x91d1,0x5151}, {0x91d7,0x6172}, - {0x91d8,0x6f79}, {0x91dc,0x5d3c}, {0x91dd,0x765c}, {0x91e3,0x7065}, {0x91e7,0x7444}, {0x91ea,0x6969}, {0x91f5,0x737b}, {0x920d,0x546f}, {0x9210,0x4c22}, {0x9211,0x777e}, - {0x9212,0x5f3c}, {0x9217,0x6b4d}, {0x921e,0x5037}, {0x9234,0x5642}, {0x923a,0x682d}, {0x923f,0x6f2f}, {0x9240,0x4b25}, {0x9245,0x4b69}, {0x9249,0x7a68}, {0x9257,0x4c46}, - {0x925b,0x6667}, {0x925e,0x6a47}, {0x9262,0x5b24}, {0x9264,0x4f49}, {0x9265,0x627c}, {0x9266,0x6f7a}, {0x9280,0x6b5e}, {0x9283,0x7548}, {0x9285,0x545e}, {0x9291,0x6055}, - {0x9293,0x6f30}, {0x9296,0x6247}, {0x9298,0x592f}, {0x929c,0x7967}, {0x92b3,0x6765}, {0x92b6,0x4f4a}, {0x92b7,0x6151}, {0x92b9,0x6248}, {0x92cc,0x6f7b}, {0x92cf,0x7a79}, - {0x92d2,0x5c72}, {0x92e4,0x6027}, {0x92ea,0x7868}, {0x92f8,0x4b6a}, {0x92fc,0x4b3c}, {0x9304,0x5662}, {0x9310,0x755e}, {0x9318,0x755f}, {0x931a,0x6e36}, {0x931e,0x6276}, - {0x931f,0x534a}, {0x9320,0x6f7c}, {0x9321,0x5144}, {0x9322,0x6f31}, {0x9324,0x5145}, {0x9326,0x505e}, {0x9328,0x5961}, {0x932b,0x6038}, {0x932e,0x4d51}, {0x932f,0x7339}, - {0x9348,0x674c}, {0x934a,0x5628}, {0x934b,0x4e27}, {0x934d,0x5435}, {0x9354,0x6448}, {0x935b,0x5334}, {0x936e,0x6b39}, {0x9375,0x4b75}, {0x937c,0x765d}, {0x937e,0x7123}, - {0x938c,0x4c47}, {0x9394,0x694a}, {0x9396,0x6170}, {0x939a,0x7560}, {0x93a3,0x7b2f}, {0x93a7,0x4b51}, {0x93ac,0x7b60}, {0x93ad,0x7265}, {0x93b0,0x6c70}, {0x93c3,0x706c}, - {0x93d1,0x6e6b}, {0x93de,0x694b}, {0x93e1,0x4c70}, {0x93e4,0x572f}, {0x93f6,0x7321}, {0x9404,0x7c75}, {0x9418,0x7124}, {0x9425,0x6056}, {0x942b,0x6f32}, {0x9435,0x7451}, - {0x9438,0x7721}, {0x9444,0x7151}, {0x9451,0x4a7c}, {0x9452,0x4a7d}, {0x945b,0x4e4e}, {0x947d,0x7348}, {0x947f,0x733a}, {0x9577,0x6d7e}, {0x9580,0x5a26}, {0x9583,0x606c}, - {0x9589,0x784d}, {0x958b,0x4b52}, {0x958f,0x6b4e}, {0x9591,0x7958}, {0x9592,0x7959}, {0x9593,0x4a60}, {0x9594,0x5a4a}, {0x9598,0x4b26}, {0x95a3,0x4a48}, {0x95a4,0x796e}, - {0x95a5,0x5b6c}, {0x95a8,0x5031}, {0x95ad,0x556f}, {0x95b1,0x6673}, {0x95bb,0x6722}, {0x95bc,0x6459}, {0x95c7,0x6461}, {0x95ca,0x7c44}, {0x95d4,0x796f}, {0x95d5,0x4f74}, - {0x95d6,0x7766}, {0x95dc,0x4e3c}, {0x95e1,0x7445}, {0x95e2,0x5c23}, {0x961c,0x5d3d}, {0x9621,0x7446}, {0x962a,0x7821}, {0x962e,0x6856}, {0x9632,0x5b41}, {0x963b,0x7066}, - {0x963f,0x6439}, {0x9640,0x766d}, {0x9642,0x792e}, {0x9644,0x5d3e}, {0x964b,0x5730}, {0x964c,0x5868}, {0x964d,0x4b3d}, {0x9650,0x795a}, {0x965b,0x784e}, {0x965c,0x7970}, - {0x965d,0x606d}, {0x965e,0x6333}, {0x965f,0x7433}, {0x9662,0x6a42}, {0x9663,0x7266}, {0x9664,0x7036}, {0x966a,0x5b56}, {0x9670,0x6b64}, {0x9673,0x7267}, {0x9675,0x5755}, - {0x9676,0x5436}, {0x9677,0x7968}, {0x9678,0x5741}, {0x967d,0x6555}, {0x9685,0x696a}, {0x9686,0x574c}, {0x968a,0x5369}, {0x968b,0x6249}, {0x968d,0x7c5b}, {0x968e,0x4d2d}, - {0x9694,0x4c30}, {0x9695,0x6a22}, {0x9698,0x6476}, {0x9699,0x5040}, {0x969b,0x7037}, {0x969c,0x6e21}, {0x96a3,0x5776}, {0x96a7,0x624a}, {0x96a8,0x624b}, {0x96aa,0x7a4f}, - {0x96b1,0x6b5f}, {0x96b7,0x564b}, {0x96bb,0x7434}, {0x96c0,0x6d4d}, {0x96c1,0x6452}, {0x96c4,0x6a29}, {0x96c5,0x643a}, {0x96c6,0x7322}, {0x96c7,0x4d52}, {0x96c9,0x764b}, - {0x96cb,0x7166}, {0x96cc,0x6d41}, {0x96cd,0x683c}, {0x96ce,0x6e51}, {0x96d5,0x7067}, {0x96d6,0x624c}, {0x96d9,0x642a}, {0x96db,0x7561}, {0x96dc,0x6d5a}, {0x96e2,0x576e}, - {0x96e3,0x5171}, {0x96e8,0x696b}, {0x96e9,0x696c}, {0x96ea,0x6064}, {0x96ef,0x5a27}, {0x96f0,0x5d54}, {0x96f2,0x6a23}, {0x96f6,0x5643}, {0x96f7,0x5674}, {0x96f9,0x5a5f}, - {0x96fb,0x6f33}, {0x9700,0x624d}, {0x9706,0x6f7d}, {0x9707,0x7268}, {0x9711,0x6f45}, {0x9713,0x6767}, {0x9716,0x577d}, {0x9719,0x674e}, {0x971c,0x5f5c}, {0x971e,0x7947}, - {0x9727,0x5976}, {0x9730,0x5f2c}, {0x9732,0x565a}, {0x9739,0x5c24}, {0x973d,0x7038}, {0x9742,0x557a}, {0x9744,0x6477}, {0x9748,0x5644}, {0x9751,0x746c}, {0x9756,0x6f7e}, - {0x975c,0x7021}, {0x975e,0x5e2a}, {0x9761,0x5a3c}, {0x9762,0x587c}, {0x9769,0x7a54}, {0x976d,0x6c65}, {0x9774,0x7c28}, {0x9777,0x6c66}, {0x977a,0x584b}, {0x978b,0x7b39}, - {0x978d,0x6453}, {0x978f,0x4d79}, {0x97a0,0x4f53}, {0x97a8,0x4a6a}, {0x97ab,0x4f54}, {0x97ad,0x783d}, {0x97c6,0x7447}, {0x97cb,0x6a5f}, {0x97d3,0x795b}, {0x97dc,0x5437}, - {0x97f3,0x6b65}, {0x97f6,0x6152}, {0x97fb,0x6a24}, {0x97ff,0x7a42}, {0x9800,0x7b61}, {0x9801,0x7a6d}, {0x9802,0x7022}, {0x9803,0x4c71}, {0x9805,0x7a23}, {0x9806,0x6277}, - {0x9808,0x624e}, {0x980a,0x6975}, {0x980c,0x616b}, {0x9810,0x6768}, {0x9811,0x6857}, {0x9812,0x5a78}, {0x9813,0x544b}, {0x9817,0x7776}, {0x9818,0x5645}, {0x982d,0x5469}, - {0x9830,0x7a7a}, {0x9838,0x4c72}, {0x9839,0x775d}, {0x983b,0x5e3a}, {0x9846,0x4e28}, {0x984c,0x7039}, {0x984d,0x647e}, {0x984e,0x6449}, {0x9854,0x6454}, {0x9858,0x6a43}, - {0x985a,0x6f34}, {0x985e,0x573e}, {0x9865,0x7b62}, {0x9867,0x4d53}, {0x986b,0x6f35}, {0x986f,0x7a69}, {0x98a8,0x7926}, {0x98af,0x5f3d}, {0x98b1,0x7747}, {0x98c4,0x787d}, - {0x98c7,0x787c}, {0x98db,0x5e2b}, {0x98dc,0x5b68}, {0x98df,0x635d}, {0x98e1,0x6162}, {0x98e2,0x5146}, {0x98ed,0x7650}, {0x98ee,0x6b66}, {0x98ef,0x5a79}, {0x98f4,0x6c47}, - {0x98fc,0x5e78}, {0x98fd,0x7869}, {0x98fe,0x635e}, {0x9903,0x4e75}, {0x9909,0x7a43}, {0x990a,0x6557}, {0x990c,0x6c48}, {0x9910,0x7349}, {0x9913,0x643b}, {0x9918,0x662e}, - {0x991e,0x6f36}, {0x9920,0x5c3f}, {0x9928,0x4e3d}, {0x9945,0x5843}, {0x9949,0x504f}, {0x994b,0x4f7a}, {0x994c,0x734a}, {0x994d,0x6057}, {0x9951,0x5147}, {0x9952,0x692e}, - {0x9954,0x683d}, {0x9957,0x7a44}, {0x9996,0x624f}, {0x9999,0x7a45}, {0x999d,0x7938}, {0x99a5,0x5c60}, {0x99a8,0x7b30}, {0x99ac,0x5829}, {0x99ad,0x655f}, {0x99ae,0x7927}, - {0x99b1,0x766e}, {0x99b3,0x764c}, {0x99b4,0x6278}, {0x99b9,0x6c71}, {0x99c1,0x5a60}, {0x99d0,0x7152}, {0x99d1,0x524c}, {0x99d2,0x4f4b}, {0x99d5,0x4a3d}, {0x99d9,0x5d3f}, - {0x99dd,0x766f}, {0x99df,0x5e79}, {0x99ed,0x7a34}, {0x99f1,0x552d}, {0x99ff,0x7167}, {0x9a01,0x5e3e}, {0x9a08,0x5c40}, {0x9a0e,0x5148}, {0x9a0f,0x5149}, {0x9a19,0x783e}, - {0x9a2b,0x4b76}, {0x9a30,0x5479}, {0x9a36,0x7562}, {0x9a37,0x6153}, {0x9a40,0x5869}, {0x9a43,0x787e}, {0x9a45,0x4f4c}, {0x9a4d,0x7d24}, {0x9a55,0x4e76}, {0x9a57,0x7a50}, - {0x9a5a,0x4c73}, {0x9a5b,0x663e}, {0x9a5f,0x762e}, {0x9a62,0x5570}, {0x9a65,0x514a}, {0x9a69,0x7c3e}, {0x9a6a,0x5571}, {0x9aa8,0x4d69}, {0x9ab8,0x7a35}, {0x9ad3,0x6250}, - {0x9ad4,0x7477}, {0x9ad8,0x4d54}, {0x9ae5,0x6723}, {0x9aee,0x5b25}, {0x9b1a,0x6251}, {0x9b27,0x5722}, {0x9b2a,0x7763}, {0x9b31,0x6a26}, {0x9b3c,0x5021}, {0x9b41,0x4e5a}, - {0x9b42,0x7b6b}, {0x9b43,0x5b26}, {0x9b44,0x5b5e}, {0x9b45,0x5865}, {0x9b4f,0x6a60}, {0x9b54,0x582a}, {0x9b5a,0x6560}, {0x9b6f,0x565b}, {0x9b8e,0x6f46}, {0x9b91,0x786a}, - {0x9b9f,0x6455}, {0x9bab,0x4e77}, {0x9bae,0x6058}, {0x9bc9,0x576f}, {0x9bd6,0x746d}, {0x9be4,0x4d66}, {0x9be8,0x4c74}, {0x9c0d,0x7563}, {0x9c10,0x644a}, {0x9c12,0x5c61}, - {0x9c15,0x7948}, {0x9c25,0x7c3f}, {0x9c32,0x6827}, {0x9c3b,0x5844}, {0x9c47,0x4b3e}, {0x9c49,0x5c2e}, {0x9c57,0x5777}, {0x9ce5,0x7068}, {0x9ce7,0x5d40}, {0x9ce9,0x4f4d}, - {0x9cf3,0x5c73}, {0x9cf4,0x5930}, {0x9cf6,0x6669}, {0x9d09,0x643c}, {0x9d1b,0x6a44}, {0x9d26,0x646c}, {0x9d28,0x6465}, {0x9d3b,0x7b78}, {0x9d51,0x4c3b}, {0x9d5d,0x643d}, - {0x9d60,0x4d5c}, {0x9d61,0x5977}, {0x9d6c,0x5d5f}, {0x9d72,0x6d4e}, {0x9da9,0x5950}, {0x9daf,0x6523}, {0x9db4,0x794d}, {0x9dc4,0x4d2e}, {0x9dd7,0x4f4e}, {0x9df2,0x762f}, - {0x9df8,0x7d53}, {0x9df9,0x6b6d}, {0x9dfa,0x565c}, {0x9e1a,0x6524}, {0x9e1e,0x5536}, {0x9e75,0x565d}, {0x9e79,0x7969}, {0x9e7d,0x6724}, {0x9e7f,0x5663}, {0x9e92,0x514b}, - {0x9e93,0x5664}, {0x9e97,0x5572}, {0x9e9d,0x5e7a}, {0x9e9f,0x5778}, {0x9ea5,0x586a}, {0x9eb4,0x4f55}, {0x9eb5,0x587d}, {0x9ebb,0x582b}, {0x9ebe,0x7d4b}, {0x9ec3,0x7c5c}, - {0x9ecd,0x6028}, {0x9ece,0x5573}, {0x9ed1,0x7d59}, {0x9ed4,0x4c23}, {0x9ed8,0x5979}, {0x9edb,0x536a}, {0x9edc,0x7575}, {0x9ede,0x6f47}, {0x9ee8,0x535a}, {0x9ef4,0x5a3d}, - {0x9f07,0x6828}, {0x9f08,0x5c2f}, {0x9f0e,0x7023}, {0x9f13,0x4d55}, {0x9f20,0x6029}, {0x9f3b,0x5e2c}, {0x9f4a,0x703a}, {0x9f4b,0x6e31}, {0x9f4e,0x6e32}, {0x9f52,0x764d}, - {0x9f5f,0x6e52}, {0x9f61,0x5646}, {0x9f67,0x6065}, {0x9f6a,0x733b}, {0x9f6c,0x6561}, {0x9f77,0x644b}, {0x9f8d,0x5723}, {0x9f90,0x5b42}, {0x9f95,0x4a7e}, {0x9f9c,0x4f4f}, - {0xf900,0x4b50}, {0xf901,0x4b56}, {0xf902,0x4b67}, {0xf903,0x4d4f}, {0xf904,0x4d68}, {0xf905,0x4e2d}, {0xf906,0x4f7b}, {0xf907,0x5022}, {0xf908,0x5038}, {0xf909,0x5050}, - {0xf90a,0x505d}, {0xf90b,0x5154}, {0xf90c,0x5155}, {0xf90d,0x5158}, {0xf90e,0x515b}, {0xf90f,0x515c}, {0xf910,0x515d}, {0xf911,0x515e}, {0xf912,0x515f}, {0xf913,0x5160}, - {0xf914,0x5162}, {0xf915,0x5163}, {0xf916,0x5164}, {0xf917,0x5165}, {0xf918,0x5166}, {0xf919,0x5168}, {0xf91a,0x5169}, {0xf91b,0x516a}, {0xf91c,0x516b}, {0xf91d,0x516d}, - {0xf91e,0x516f}, {0xf91f,0x5170}, {0xf920,0x5172}, {0xf921,0x5176}, {0xf922,0x517a}, {0xf923,0x517c}, {0xf924,0x517d}, {0xf925,0x517e}, {0xf926,0x5222}, {0xf927,0x5223}, - {0xf928,0x5227}, {0xf929,0x5228}, {0xf92a,0x5229}, {0xf92b,0x522a}, {0xf92c,0x522b}, {0xf92d,0x522d}, {0xf92e,0x5232}, {0xf92f,0x523e}, {0xf930,0x5242}, {0xf931,0x5243}, - {0xf932,0x5244}, {0xf933,0x5246}, {0xf934,0x5247}, {0xf935,0x5248}, {0xf936,0x5249}, {0xf937,0x524a}, {0xf938,0x524b}, {0xf939,0x524d}, {0xf93a,0x524e}, {0xf93b,0x524f}, - {0xf93c,0x5250}, {0xf93d,0x5251}, {0xf93e,0x5252}, {0xf93f,0x5253}, {0xf940,0x5254}, {0xf941,0x5255}, {0xf942,0x5256}, {0xf943,0x5257}, {0xf944,0x5259}, {0xf945,0x525a}, - {0xf946,0x525e}, {0xf947,0x525f}, {0xf948,0x5261}, {0xf949,0x5262}, {0xf94a,0x5264}, {0xf94b,0x5265}, {0xf94c,0x5266}, {0xf94d,0x5267}, {0xf94e,0x5268}, {0xf94f,0x5269}, - {0xf950,0x526a}, {0xf951,0x526b}, {0xf952,0x5270}, {0xf953,0x5271}, {0xf954,0x5272}, {0xf955,0x5273}, {0xf956,0x5274}, {0xf957,0x5275}, {0xf958,0x5277}, {0xf959,0x5278}, - {0xf95a,0x5466}, {0xf95b,0x547c}, {0xf95c,0x5525}, {0xf95d,0x552b}, {0xf95e,0x552e}, {0xf95f,0x5638}, {0xf960,0x564d}, {0xf961,0x574b}, {0xf962,0x5764}, {0xf963,0x5b45}, - {0xf964,0x5b64}, {0xf965,0x5c25}, {0xf966,0x5d25}, {0xf967,0x5d55}, {0xf968,0x5d74}, {0xf969,0x5e7c}, {0xf96a,0x5e7e}, {0xf96b,0x5f33}, {0xf96c,0x5f61}, {0xf96d,0x5f68}, - {0xf96e,0x6071}, {0xf96f,0x612d}, {0xf970,0x616d}, {0xf971,0x6375}, {0xf972,0x6421}, {0xf973,0x6429}, {0xf974,0x652e}, {0xf975,0x6531}, {0xf976,0x6532}, {0xf977,0x6539}, - {0xf978,0x653b}, {0xf979,0x653c}, {0xf97a,0x6544}, {0xf97b,0x654e}, {0xf97c,0x6550}, {0xf97d,0x6552}, {0xf97e,0x6556}, {0xf97f,0x657a}, {0xf980,0x657b}, {0xf981,0x657c}, - {0xf982,0x657e}, {0xf983,0x6621}, {0xf984,0x6624}, {0xf985,0x6627}, {0xf986,0x662d}, {0xf987,0x662f}, {0xf988,0x6630}, {0xf989,0x6631}, {0xf98a,0x6633}, {0xf98b,0x6637}, - {0xf98c,0x6638}, {0xf98d,0x663c}, {0xf98e,0x6644}, {0xf98f,0x6646}, {0xf990,0x6647}, {0xf991,0x664a}, {0xf992,0x6652}, {0xf993,0x6656}, {0xf994,0x6659}, {0xf995,0x665c}, - {0xf996,0x665f}, {0xf997,0x6661}, {0xf998,0x6664}, {0xf999,0x6665}, {0xf99a,0x6666}, {0xf99b,0x6668}, {0xf99c,0x666a}, {0xf99d,0x666b}, {0xf99e,0x666c}, {0xf99f,0x666f}, - {0xf9a0,0x6671}, {0xf9a1,0x6672}, {0xf9a2,0x6675}, {0xf9a3,0x6676}, {0xf9a4,0x6677}, {0xf9a5,0x6679}, {0xf9a6,0x6721}, {0xf9a7,0x6726}, {0xf9a8,0x6729}, {0xf9a9,0x672a}, - {0xf9aa,0x672c}, {0xf9ab,0x672d}, {0xf9ac,0x6730}, {0xf9ad,0x673f}, {0xf9ae,0x6741}, {0xf9af,0x6746}, {0xf9b0,0x6747}, {0xf9b1,0x674b}, {0xf9b2,0x674d}, {0xf9b3,0x674f}, - {0xf9b4,0x6750}, {0xf9b5,0x6753}, {0xf9b6,0x675f}, {0xf9b7,0x6764}, {0xf9b8,0x6766}, {0xf9b9,0x6777}, {0xf9ba,0x6867}, {0xf9bb,0x6868}, {0xf9bc,0x6870}, {0xf9bd,0x6871}, - {0xf9be,0x6877}, {0xf9bf,0x6879}, {0xf9c0,0x687b}, {0xf9c1,0x687e}, {0xf9c2,0x6927}, {0xf9c3,0x692c}, {0xf9c4,0x694c}, {0xf9c5,0x6977}, {0xf9c6,0x6a41}, {0xf9c7,0x6a65}, - {0xf9c8,0x6a74}, {0xf9c9,0x6a77}, {0xf9ca,0x6a7c}, {0xf9cb,0x6a7e}, {0xf9cc,0x6b24}, {0xf9cd,0x6b27}, {0xf9ce,0x6b29}, {0xf9cf,0x6b2a}, {0xf9d0,0x6b3a}, {0xf9d1,0x6b3b}, - {0xf9d2,0x6b3d}, {0xf9d3,0x6b41}, {0xf9d4,0x6b42}, {0xf9d5,0x6b46}, {0xf9d6,0x6b47}, {0xf9d7,0x6b4c}, {0xf9d8,0x6b4f}, {0xf9d9,0x6b50}, {0xf9da,0x6b51}, {0xf9db,0x6b52}, - {0xf9dc,0x6b58}, {0xf9dd,0x6c26}, {0xf9de,0x6c27}, {0xf9df,0x6c2a}, {0xf9e0,0x6c2f}, {0xf9e1,0x6c30}, {0xf9e2,0x6c31}, {0xf9e3,0x6c32}, {0xf9e4,0x6c35}, {0xf9e5,0x6c38}, - {0xf9e6,0x6c3a}, {0xf9e7,0x6c40}, {0xf9e8,0x6c41}, {0xf9e9,0x6c45}, {0xf9ea,0x6c46}, {0xf9eb,0x6c49}, {0xf9ec,0x6c4a}, {0xf9ed,0x6c55}, {0xf9ee,0x6c5d}, {0xf9ef,0x6c5e}, - {0xf9f0,0x6c61}, {0xf9f1,0x6c64}, {0xf9f2,0x6c67}, {0xf9f3,0x6c68}, {0xf9f4,0x6c77}, {0xf9f5,0x6c78}, {0xf9f6,0x6c7a}, {0xf9f7,0x6d21}, {0xf9f8,0x6d22}, {0xf9f9,0x6d23}, - {0xf9fa,0x6d6e}, {0xf9fb,0x6e5b}, {0xf9fc,0x723d}, {0xf9fd,0x727a}, {0xf9fe,0x7331}, {0xf9ff,0x7427}, {0xfa00,0x746e}, {0xfa01,0x7674}, {0xfa02,0x7676}, {0xfa03,0x7738}, - {0xfa04,0x7748}, {0xfa05,0x7753}, {0xfa06,0x785b}, {0xfa07,0x7870}, {0xfa08,0x7a21}, {0xfa09,0x7a22}, {0xfa0a,0x7a66}, {0xfa0b,0x7c29}, -}; - -static uint16_t unicode2ksc(unsigned unicode) -{ - unsigned lo, hi, mid, c2; - uint8_t s[2]; - - lo = mid = c2 = 0; - - if (unicode >= 0xac00 && unicode <= 0xd7a3) { - // Hangul - hi = 2349; - - while (lo <= hi) { // binary search - mid = (lo + hi) / 2; - c2 = ksc5601_hangul_to_unicode[mid]; - if (unicode < c2) - hi = mid - 1; - else if (unicode > c2) - lo = mid + 1; - else { // unicode == c2 - s[0] = (mid / 94) + 0x30; - s[1] = (mid % 94) + 0x21; - - return ((s[0] << 8) | s[1]); - } - } - } - else if ((unicode >= 0x4e00 && unicode <= 0x9fff) - || (unicode >= 0xf900 && unicode <= 0xfa0b)) { - // Hanja - hi = 4887; - - while (lo <= hi) { // binary search - mid = (lo + hi) / 2; - c2 = unicode_to_ksc5601_hanja[mid].unicode; - if (unicode < c2) - hi = mid - 1; - else if (unicode > c2) - lo = mid + 1; - else { // unicode == c2 - return unicode_to_ksc5601_hanja[mid].kscode; - } - } - } - else { - // Symbol - hi = 985; - - while (lo <= hi) { // binary search - mid = (lo + hi) / 2; - c2 = unicode_to_ksc5601_symbol[mid].unicode; - if (unicode < c2) - hi = mid - 1; - else if (unicode > c2) - lo = mid + 1; - else { // unicode == c2 - return unicode_to_ksc5601_symbol[mid].kscode; - } - } - } - return 0; -} - -void KRTextEncoder::EncodeEucKr(const std::wstring& str, std::string& bytes) -{ - static const char replacement = '?'; - //int invalid = 0; - - bytes.resize(2 * str.length() + 1); - int index = 0; - for (wchar_t ch : str) { - unsigned j; - if (ch < 0x80) { - // ASCII - bytes[index++] = static_cast(ch); - } - else if ((j = unicode2ksc(ch))) { - // KSC 5601 - bytes[index++] = static_cast((j >> 8) | 0x80); - bytes[index++] = static_cast((j & 0xff) | 0x80); - } - else { - // Error - bytes[index++] = replacement; - //++invalid; - } - } - bytes.resize(index); -} \ No newline at end of file diff --git a/core/src/textcodec/KRTextEncoder.h b/core/src/textcodec/KRTextEncoder.h deleted file mode 100644 index 05c5f6b524..0000000000 --- a/core/src/textcodec/KRTextEncoder.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -class KRTextEncoder -{ -public: - static void EncodeEucKr(const std::wstring& str, std::string& bytes); -}; diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index 5276c4e7f5..2034bec4e5 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -66,7 +66,7 @@ TEST(TextDecoderTest, AppendISO8859Range80_9F) CharacterSet::ISO8859_1, CharacterSet::ISO8859_2, CharacterSet::ISO8859_3, CharacterSet::ISO8859_4, CharacterSet::ISO8859_5, CharacterSet::ISO8859_6, CharacterSet::ISO8859_7, CharacterSet::ISO8859_8, CharacterSet::ISO8859_7, CharacterSet::ISO8859_8, CharacterSet::ISO8859_9, CharacterSet::ISO8859_10, - // CharacterSet::ISO8859_11 extended with 9 CP874 codepoints in 0x80-9F range + CharacterSet::ISO8859_11, // extended with 9 CP874 codepoints in 0x80-9F range CharacterSet::ISO8859_13, CharacterSet::ISO8859_14, CharacterSet::ISO8859_15, CharacterSet::ISO8859_16 }; @@ -75,12 +75,6 @@ TEST(TextDecoderTest, AppendISO8859Range80_9F) TextDecoder::Append(str, data, sizeof(data), iso); EXPECT_THAT(str, ElementsAreArray(data, sizeof(data))) << "iso: " << static_cast(iso); } - - // CharacterSet::ISO8859_11 - note maps non-defined to U+FFFD - std::wstring str; - TextDecoder::Append(str, data, sizeof(data), CharacterSet::ISO8859_11); - EXPECT_EQ(str, L"\u20AC\uFFFD\uFFFD\uFFFD\uFFFD\u2026\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" - L"\uFFFD\u2018\u2019\u201C\u201D\u2022\u2013\u2014\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD"); } TEST(TextDecoderTest, AppendShift_JIS) @@ -94,14 +88,14 @@ TEST(TextDecoderTest, AppendShift_JIS) EXPECT_EQ(ToUtf8(str), "\\"); // "¥" ditto } - { - // Shift JIS 0x815F goes to U+FF3C (full width reverse solidus i.e. backslash) - static const uint8_t data[] = { 0x81, 0x5F }; - std::wstring str; - TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); - EXPECT_EQ(str, L"\uFF3C"); - EXPECT_EQ(ToUtf8(str), "\"); - } +// { +// // Shift JIS 0x815F goes to U+FF3C (full width reverse solidus i.e. backslash) +// static const uint8_t data[] = { 0x81, 0x5F }; +// std::wstring str; +// TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); +// EXPECT_EQ(str, L"\uFF3C"); +// EXPECT_EQ(ToUtf8(str), "\"); +// } { // Shift JIS 0xA5 (Yen sign in ISO/IEC 8859-1) goes to U+FF65 (half-width katakana middle dot) @@ -122,24 +116,24 @@ TEST(TextDecoderTest, AppendShift_JIS) } { - static const uint8_t data[] = { 'a', 0x83, 0xC0, 'c', 0x84, 0x47, 0xA5, 0xBF, 0x81, 0x5F, 0x93, 0x5F, + static const uint8_t data[] = { 'a', 0x83, 0xC0, 'c', 0x84, 0x47, 0xA5, 0xBF, 0x93, 0x5F, 0xE4, 0xAA, 0x83, 0x65 }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::Shift_JIS); - EXPECT_EQ(str, L"a\u03B2c\u0416\uFF65\uFF7F\uFF3C\u70B9\u8317\u30C6"); - EXPECT_EQ(ToUtf8(str), "aβcЖ・ソ\点茗テ"); + EXPECT_EQ(str, L"a\u03B2c\u0416\uFF65\uFF7F\u70B9\u8317\u30C6"); + EXPECT_EQ(ToUtf8(str), "aβcЖ・ソ点茗テ"); } } TEST(TextDecoderTest, AppendBig5) { - { - static const uint8_t data[] = { 0xA1, 0x5A }; // Drawings box light left in Big5-2003; not in original Big5 - std::wstring str; - TextDecoder::Append(str, data, sizeof(data), CharacterSet::Big5); - EXPECT_EQ(str, L"\u2574"); - EXPECT_EQ(ToUtf8(str), "╴"); - } +// { +// static const uint8_t data[] = { 0xA1, 0x5A }; // Drawings box light left in Big5-2003; not in original Big5 +// std::wstring str; +// TextDecoder::Append(str, data, sizeof(data), CharacterSet::Big5); +// EXPECT_EQ(str, L"\u2574"); +// EXPECT_EQ(ToUtf8(str), "╴"); +// } { static const uint8_t data[] = { 0xA1, 0x56 }; // En dash U+2013 in Big5, horizontal bar U+2015 in Big5-2003 @@ -161,11 +155,11 @@ TEST(TextDecoderTest, AppendBig5) TEST(TextDecoderTest, AppendGB2312) { { - static const uint8_t data[] = { 'a', 0xA6, 0xC2, 'c', 0xA1, 0xA4, 0xA1, 0xAA, 0xA8, 0xA6, 'Z' }; + static const uint8_t data[] = { 'a', 0xB0, 0xA1 }; std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::GB2312); - EXPECT_EQ(str, L"a\u03B2c\u00B7\u2014\u00E9Z"); - EXPECT_EQ(ToUtf8(str), "aβc·—éZ"); + EXPECT_EQ(str, L"a\u554a"); + EXPECT_EQ(ToUtf8(str), "a啊"); } } @@ -184,11 +178,11 @@ TEST(TextDecoderTest, AppendGB18030) TEST(TextDecoderTest, AppendEUC_KR) { { - static const uint8_t data[] = { 0xA2, 0xE6 }; // Euro sign U+20AC added KS X 1001:1998, not supported + static const uint8_t data[] = { 0xA2, 0xE6 }; // Euro sign U+20AC added KS X 1001:1998 std::wstring str; TextDecoder::Append(str, data, sizeof(data), CharacterSet::EUC_KR); - EXPECT_EQ(str, L"\uFFFD"); - EXPECT_EQ(ToUtf8(str), "\xEF\xBF\xBD"); + EXPECT_EQ(str, L"\u20AC"); + EXPECT_EQ(ToUtf8(str), "€"); } { diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index 83ad79641e..cb46db51e6 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -27,3 +27,18 @@ TEST(TextUtfEncodingTest, ToUtf8AngleEscape) EXPECT_EQ(ToUtf8(L"\xD800Z", angleEscape), "Z"); // Unpaired high surrogate EXPECT_EQ(ToUtf8(L"A\xDC00", angleEscape), "A"); // Unpaired low surrogate } + +TEST(TextUtfEncodingTest, FromUtf8) +{ + using namespace ZXing::TextUtfEncoding; + + EXPECT_EQ(FromUtf8(u8"\U00010000"), L"\U00010000"); + EXPECT_EQ(FromUtf8(u8"\U00010FFF"), L"\U00010FFF"); + EXPECT_EQ(FromUtf8("A\xE8\x80\xBFG"), L"A\u803FG"); // U+803F + +// EXPECT_EQ(FromUtf8("A\xE8\x80\xBF\x80G"), L"A\u803FG"); // Bad UTF-8 (extra continuation byte) +// EXPECT_EQ(FromUtf8("A\xE8\x80\xC0G"), L"AG"); // Bad UTF-8 (non-continuation byte) +// EXPECT_EQ(FromUtf8("A\xE8\x80G"), L"AG"); // Bad UTF-8 (missing continuation byte) +// EXPECT_EQ(FromUtf8("A\xE8G"), L"AG"); // Bad UTF-8 (missing continuation bytes) +// EXPECT_EQ(FromUtf8("A\xED\xA0\x80G"), L"AG"); // Bad UTF-8 (unpaired high surrogate U+D800) +} diff --git a/test/unit/aztec/AZHighLevelEncoderTest.cpp b/test/unit/aztec/AZHighLevelEncoderTest.cpp index 0869921bdf..78e86cbcc2 100644 --- a/test/unit/aztec/AZHighLevelEncoderTest.cpp +++ b/test/unit/aztec/AZHighLevelEncoderTest.cpp @@ -9,7 +9,6 @@ #include "BitArrayUtility.h" #include "DecoderResult.h" #include "StructuredAppend.h" -#include "TextDecoder.h" #include "gtest/gtest.h" #include @@ -31,7 +30,7 @@ namespace { void TestHighLevelEncodeString(const std::string& s, const std::string& expectedBits) { BitArray bits = Aztec::HighLevelEncoder::Encode(s); EXPECT_EQ(Utility::ToString(bits), StripSpaces(expectedBits)) << "highLevelEncode() failed for input string: " + s; - EXPECT_EQ(TextDecoder::FromLatin1(s), Aztec::Decode(bits).text()); + EXPECT_EQ(ByteArray(s), Aztec::Decode(bits).content().bytes); } void TestHighLevelEncodeString(const std::string& s, int expectedReceivedBits) { diff --git a/test/unit/qrcode/QREncoderTest.cpp b/test/unit/qrcode/QREncoderTest.cpp index 78e2715fc8..c5661a6cb1 100644 --- a/test/unit/qrcode/QREncoderTest.cpp +++ b/test/unit/qrcode/QREncoderTest.cpp @@ -8,6 +8,7 @@ #include "BitMatrixIO.h" #include "CharacterSet.h" #include "TextDecoder.h" +#include "TextUtfEncoding.h" #include "qrcode/QREncoder.h" #include "qrcode/QRCodecMode.h" #include "qrcode/QREncodeResult.h" @@ -40,9 +41,9 @@ using namespace ZXing::Utility; namespace { std::wstring ShiftJISString(const std::vector& bytes) { - std::wstring str; + std::string str; TextDecoder::Append(str, bytes.data(), bytes.size(), CharacterSet::Shift_JIS); - return str; + return TextUtfEncoding::FromUtf8(str); } std::string RemoveSpace(std::string s) diff --git a/zxing.cmake b/zxing.cmake index 3021bb68b4..c781e3d286 100644 --- a/zxing.cmake +++ b/zxing.cmake @@ -40,7 +40,12 @@ macro(zxing_add_package name depname git_repo git_rev) # Prevent overriding the parent project's compiler/linker settings on Windows set (gtest_force_shared_crt ON CACHE BOOL "" FORCE) endif() - FetchContent_MakeAvailable (${depname}) + #FetchContent_MakeAvailable (${depname}) + FetchContent_GetProperties(${depname}) + if(NOT ${depname}_POPULATED) + FetchContent_Populate(${depname}) + add_subdirectory(${${depname}_SOURCE_DIR} ${${depname}_BINARY_DIR} EXCLUDE_FROM_ALL) # prevent installing of dependencies + endif() set (${name}_POPULATED TRUE) # this is supposed to be done in MakeAvailable but it seems not to?!? endif() endmacro() From 5fb97c3f5c66528653c68dc9dec43f569a3e78c5 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 4 Aug 2022 23:48:13 +0200 Subject: [PATCH 0432/1315] ECI: add support for UTF16/UTF32 in both BE and LE --- core/src/CharacterSet.cpp | 9 ++++-- core/src/CharacterSet.h | 6 +++- core/src/ECI.cpp | 5 +++- core/src/ECI.h | 5 +++- core/src/TextUtfEncoding.cpp | 5 +++- test/unit/TextDecoderTest.cpp | 56 ++++++++++++++++++++++++++++------- 6 files changed, 69 insertions(+), 17 deletions(-) diff --git a/core/src/CharacterSet.cpp b/core/src/CharacterSet.cpp index dafefc12de..fb84199f9f 100644 --- a/core/src/CharacterSet.cpp +++ b/core/src/CharacterSet.cpp @@ -45,9 +45,12 @@ static CharacterSetName NAME_TO_CHARSET[] = { {"windows-1252",CharacterSet::Cp1252}, {"Cp1256", CharacterSet::Cp1256}, {"windows-1256",CharacterSet::Cp1256}, - {"UTF-16BE", CharacterSet::UnicodeBig}, - {"UnicodeBigUnmarked", CharacterSet::UnicodeBig}, - {"UnicodeBig", CharacterSet::UnicodeBig}, + {"UTF-16BE", CharacterSet::UTF16BE}, + {"UTF-16LE", CharacterSet::UTF16LE}, + {"UTF-32BE", CharacterSet::UTF32BE}, + {"UTF-32LE", CharacterSet::UTF32LE}, + {"UnicodeBigUnmarked", CharacterSet::UTF16BE}, + {"UnicodeBig", CharacterSet::UTF16BE}, {"UTF-8", CharacterSet::UTF8}, {"ASCII", CharacterSet::ASCII}, {"US-ASCII", CharacterSet::ASCII}, diff --git a/core/src/CharacterSet.h b/core/src/CharacterSet.h index 19c2838e49..a39f347561 100644 --- a/core/src/CharacterSet.h +++ b/core/src/CharacterSet.h @@ -41,8 +41,12 @@ enum class CharacterSet : unsigned char GB18030, EUC_JP, EUC_KR, - UnicodeBig, + UTF16BE, + UnicodeBig [[deprecated]] = UTF16BE, UTF8, + UTF16LE, + UTF32BE, + UTF32LE, BINARY, diff --git a/core/src/ECI.cpp b/core/src/ECI.cpp index e02fcb736d..83afb88b16 100644 --- a/core/src/ECI.cpp +++ b/core/src/ECI.cpp @@ -35,8 +35,11 @@ static const std::map ECI_TO_CHARSET = { {ECI::Cp1251, CharacterSet::Cp1251}, {ECI::Cp1252, CharacterSet::Cp1252}, {ECI::Cp1256, CharacterSet::Cp1256}, - {ECI::UTF16, CharacterSet::UnicodeBig}, {ECI::UTF8, CharacterSet::UTF8}, + {ECI::UTF16BE, CharacterSet::UTF16BE}, + {ECI::UTF16LE, CharacterSet::UTF16LE}, + {ECI::UTF32BE, CharacterSet::UTF32BE}, + {ECI::UTF32LE, CharacterSet::UTF32LE}, {ECI::ASCII, CharacterSet::ASCII}, {ECI::Big5, CharacterSet::Big5}, {ECI::GB18030, CharacterSet::GB18030}, diff --git a/core/src/ECI.h b/core/src/ECI.h index d7f6e122cb..860038ccb0 100644 --- a/core/src/ECI.h +++ b/core/src/ECI.h @@ -35,13 +35,16 @@ enum class ECI : int Cp1251 = 22, Cp1252 = 23, Cp1256 = 24, - UTF16 = 25, + UTF16BE = 25, UTF8 = 26, ASCII = 27, Big5 = 28, GB2312 = 29, EUC_KR = 30, GB18030 = 32, + UTF16LE = 33, + UTF32BE = 34, + UTF32LE = 35, ISO646_Inv = 170, Binary = 899 }; diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index 0d6bbb57b0..c754832f2e 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -4,6 +4,8 @@ // SPDX-License-Identifier: Apache-2.0 #include "TextUtfEncoding.h" + +#include "ZXTestSupport.h" #include "ZXAlgorithms.h" #include @@ -121,7 +123,8 @@ static size_t Utf8CountBytes(const wchar_t* str, size_t length) return result; } -static int Utf8Encode(uint32_t utf32, char* out) +ZXING_EXPORT_TEST_ONLY +int Utf8Encode(uint32_t utf32, char* out) { if (utf32 < 0x80) { *out++ = static_cast(utf32); diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index 2034bec4e5..6dc86dd1d8 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -14,6 +14,18 @@ using namespace ZXing; using namespace ZXing::TextUtfEncoding; using namespace testing; +namespace ZXing::TextUtfEncoding { +int Utf8Encode(uint32_t utf32, char* out); +} + +// Encode Unicode codepoint `utf32` as UTF-8 +std::string Utf8Encode(const uint32_t utf32) +{ + char buf[4]; + int len = Utf8Encode(utf32, buf); + return std::string(buf, len); +} + TEST(TextDecoderTest, AppendBINARY_ASCII) { uint8_t data[256]; @@ -37,22 +49,46 @@ TEST(TextDecoderTest, AppendBINARY_ASCII) TEST(TextDecoderTest, AppendAllASCIIRange00_7F) { + std::string expected; uint8_t data[0x80]; - uint8_t dataUnicodeBig[0x80 * 2]; + uint8_t dataUTF16BE[0x80 * 2]; + uint8_t dataUTF16LE[0x80 * 2]; + uint8_t dataUTF32BE[0x80 * 4]; + uint8_t dataUTF32LE[0x80 * 4]; + for (int i = 0; i < 0x80; i++) { - data[i] = (uint8_t)i; - dataUnicodeBig[i << 1] = 0; - dataUnicodeBig[(i << 1) + 1] = (uint8_t)i; + uint8_t ch = static_cast(i); + data[i] = ch; + expected.append(Utf8Encode(i)); + + int j = i << 1; + int k = j << 1; + + dataUTF16BE[j] = 0; + dataUTF16BE[j + 1] = ch; + + dataUTF16LE[j] = ch; + dataUTF16LE[j + 1] = 0; + + dataUTF32BE[k] = dataUTF32BE[k + 1] = dataUTF32BE[k + 2] = 0; + dataUTF32BE[k + 3] = ch; + + dataUTF32LE[k] = ch; + dataUTF32LE[k + 1] = dataUTF32LE[k + 2] = dataUTF32LE[k + 3] = 0; } + EXPECT_EQ(expected.size(), 128); for (int i = 0; i < static_cast(CharacterSet::CharsetCount); i++) { - std::wstring str; - if (i == static_cast(CharacterSet::UnicodeBig)) { - TextDecoder::Append(str, dataUnicodeBig, sizeof(dataUnicodeBig), static_cast(i)); - } else { - TextDecoder::Append(str, data, sizeof(data), static_cast(i)); + std::string str; + CharacterSet cs = static_cast(i); + switch(cs) { + case CharacterSet::UTF16BE: TextDecoder::Append(str, dataUTF16BE, sizeof(dataUTF16BE), cs); break; + case CharacterSet::UTF16LE: TextDecoder::Append(str, dataUTF16LE, sizeof(dataUTF16LE), cs); break; + case CharacterSet::UTF32BE: TextDecoder::Append(str, dataUTF32BE, sizeof(dataUTF32BE), cs); break; + case CharacterSet::UTF32LE: TextDecoder::Append(str, dataUTF32LE, sizeof(dataUTF32LE), cs); break; + default: TextDecoder::Append(str, data, sizeof(data), cs); break; } - EXPECT_THAT(str, ElementsAreArray(data, sizeof(data))) << "charset: " << i; + EXPECT_EQ(str, expected) << " charset: " << ToString(cs); } } From 8ed184a0859d646a741d5edc9df0978c1773fb57 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 00:22:01 +0200 Subject: [PATCH 0433/1315] test: add full cycle text Encoder/Decoder tests --- test/unit/CMakeLists.txt | 1 + test/unit/TextEncoderTest.cpp | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 test/unit/TextEncoderTest.cpp diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 7102f7e51d..42ce8dd50a 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable (UnitTest GS1Test.cpp ReedSolomonTest.cpp TextDecoderTest.cpp + TextEncoderTest.cpp TextUtfEncodingTest.cpp ThresholdBinarizerTest.cpp ZXAlgorithmsTest.cpp diff --git a/test/unit/TextEncoderTest.cpp b/test/unit/TextEncoderTest.cpp new file mode 100644 index 0000000000..3f3cfc283c --- /dev/null +++ b/test/unit/TextEncoderTest.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2021 gitlost + */ +// SPDX-License-Identifier: Apache-2.0 + +#include "CharacterSet.h" +#include "TextDecoder.h" +#include "TextEncoder.h" + +#include "gtest/gtest.h" + +using namespace ZXing; +using namespace testing; + +void EnDeCode(CharacterSet cs, const char* in, std::string_view out) +{ + std::string bytes = TextEncoder::FromUnicode(in, cs); + EXPECT_EQ(bytes, out); + + std::string dec; + TextDecoder::Append(dec, reinterpret_cast(bytes.data()), bytes.size(), cs); + EXPECT_EQ(dec, in); +} + +TEST(TextEncoderTest, FullCycleEncodeDecode) +{ + EnDeCode(CharacterSet::Cp437, u8"\u00C7", "\x80"); // LATIN CAPITAL LETTER C WITH CEDILLA + EnDeCode(CharacterSet::ISO8859_1, u8"\u00A0", "\xA0"); // NO-BREAK SPACE + EnDeCode(CharacterSet::ISO8859_2, u8"\u0104", "\xA1"); // LATIN CAPITAL LETTER A WITH OGONEK + EnDeCode(CharacterSet::ISO8859_3, u8"\u0126", "\xA1"); // LATIN CAPITAL LETTER H WITH STROKE + EnDeCode(CharacterSet::ISO8859_4, u8"\u0138", "\xA2"); // LATIN SMALL LETTER KRA + EnDeCode(CharacterSet::ISO8859_5, u8"\u045F", "\xFF"); // CYRILLIC SMALL LETTER DZHE + EnDeCode(CharacterSet::ISO8859_6, u8"\u0652", "\xF2"); // ARABIC SUKUN + EnDeCode(CharacterSet::ISO8859_7, u8"\u03CE", "\xFE"); // GREEK SMALL LETTER OMEGA WITH TONOS + EnDeCode(CharacterSet::ISO8859_8, u8"\u05EA", "\xFA"); // HEBREW LETTER TAV + EnDeCode(CharacterSet::ISO8859_9, u8"\u011E", "\xD0"); // LATIN CAPITAL LETTER G WITH BREVE + EnDeCode(CharacterSet::ISO8859_10, u8"\u0138", "\xFF"); // LATIN SMALL LETTER KRA + EnDeCode(CharacterSet::ISO8859_11, u8"\u0E5B", "\xFB"); // THAI CHARACTER KHOMUT + EnDeCode(CharacterSet::ISO8859_13, u8"\u2019", "\xFF"); // RIGHT SINGLE QUOTATION MARK + EnDeCode(CharacterSet::ISO8859_14, u8"\u1E6B", "\xF7"); // LATIN SMALL LETTER T WITH DOT ABOVE + EnDeCode(CharacterSet::ISO8859_15, u8"\u00BF", "\xBF"); // INVERTED QUESTION MARK + EnDeCode(CharacterSet::ISO8859_16, u8"\u017C", "\xBF"); // LATIN SMALL LETTER Z WITH DOT ABOVE +// EnDeCode(CharacterSet::Shift_JIS, u8"\u00A5", "\x5C"); // YEN SIGN Mapped to backslash +// EnDeCode(CharacterSet::Shift_JIS, u8"\u203E", "\x7E"); // OVERLINE Mapped to tilde + EnDeCode(CharacterSet::Shift_JIS, u8"\u3000", "\x81\x40"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::Cp1250, u8"\u20AC", "\x80"); // EURO SIGN + EnDeCode(CharacterSet::Cp1251, u8"\u045F", "\x9F"); // CYRILLIC SMALL LETTER DZHE + EnDeCode(CharacterSet::Cp1252, u8"\u02DC", "\x98"); // SMALL TILDE + EnDeCode(CharacterSet::Cp1256, u8"\u0686", "\x8D"); // ARABIC LETTER TCHEH + EnDeCode(CharacterSet::UTF16BE, u8"\u20AC", "\x20\xAC"); // EURO SIGN + EnDeCode(CharacterSet::UTF8, u8"\u20AC", "\xE2\x82\xAC"); // EURO SIGN + EnDeCode(CharacterSet::ASCII, "#", "#"); + EnDeCode(CharacterSet::Big5, u8"\u3000", "\xA1\x40"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::GB2312, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::EUC_KR, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE +// EnDeCode(CharacterSet::GBK, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::GB18030, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::UTF16LE, u8"\u20AC", "\xAC\x20"); // EURO SIGN + EnDeCode(CharacterSet::UTF32BE, u8"\u20AC", std::string("\x00\x00\x20\xAC", 4)); // EURO SIGN + EnDeCode(CharacterSet::UTF32LE, u8"\u20AC", std::string("\xAC\x20\x00\x00", 4)); // EURO SIGN +// EnDeCode(CharacterSet::ISO646_Inv, "%", "%"); + EnDeCode(CharacterSet::BINARY, u8"\u0080\u00FF", "\x80\xFF"); + EnDeCode(CharacterSet::Unknown, u8"\u0080", "\x80"); // Treated as binary + EnDeCode(CharacterSet::EUC_JP, u8"\u0080", "\x80"); // Not supported, treated as binary +} From a901cf92eda3ed358c660662e34d922cf4262637 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 01:27:54 +0200 Subject: [PATCH 0434/1315] TextUtfEncoding: code and API cleanup + new EscapeNonGraphical() --- core/src/Content.cpp | 2 +- core/src/TextUtfEncoding.cpp | 209 ++++++++++++++---------------- core/src/TextUtfEncoding.h | 38 ++---- example/ZXingReader.cpp | 9 +- test/unit/TextDecoderTest.cpp | 8 +- test/unit/TextUtfEncodingTest.cpp | 29 ++--- 6 files changed, 126 insertions(+), 169 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index eb34c3771f..1ffa1db6e7 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -149,7 +149,7 @@ std::string Content::text(TextMode mode) const else return text(TextMode::Escaped); case TextMode::Hex: return ToHex(bytes); - case TextMode::Escaped: return TextUtfEncoding::ToUtf8(TextUtfEncoding::FromUtf8(render(false)), true); + case TextMode::Escaped: return TextUtfEncoding::EscapeNonGraphical(render(false)); } return {}; // silence compiler warning diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index c754832f2e..7d0c2ce735 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -1,5 +1,7 @@ /* * Copyright 2016 Nu-book Inc. +* Copyright 2021 gitlost +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 @@ -14,35 +16,14 @@ namespace ZXing::TextUtfEncoding { -static size_t Utf8CountCodePoints(const uint8_t* utf8, size_t length) -{ - size_t count = 0; - - for (size_t i = 0; i < length;) { - if (utf8[i] < 128) { - ++i; - } else { - switch (utf8[i] & 0xf0) { - case 0xc0: [[fallthrough]]; - case 0xd0: i += 2; break; - case 0xe0: i += 3; break; - case 0xf0: i += 4; break; - default: // we are in middle of a sequence - ++i; - while (i < length && (utf8[i] & 0xc0) == 0x80) - ++i; - break; - } - } - ++count; - } - return count; -} +// TODO: c++20 has char8_t +using char8_t = uint8_t; +using utf8_t = std::basic_string_view; constexpr uint32_t kAccepted = 0; constexpr uint32_t kRejected [[maybe_unused]] = 12; -inline uint32_t Utf8Decode(uint8_t byte, uint32_t& state, uint32_t& codep) +inline uint32_t Utf8Decode(char8_t byte, uint32_t& state, uint32_t& codep) { // Copyright (c) 2008-2009 Bjoern Hoehrmann // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. @@ -75,16 +56,59 @@ inline uint32_t Utf8Decode(uint8_t byte, uint32_t& state, uint32_t& codep) static_assert(sizeof(wchar_t) == 4 || sizeof(wchar_t) == 2, "wchar_t needs to be 2 or 4 bytes wide"); -static void ConvertFromUtf8(const uint8_t* src, size_t length, std::wstring& buffer) +template +bool IsUtf16HighSurrogate(T c) { - size_t destLen = Utf8CountCodePoints(src, length); + return (c & 0xfc00) == 0xd800; +} + +template +bool IsUtf16LowSurrogate(T c) +{ + return (c & 0xfc00) == 0xdc00; +} + +template +uint32_t Utf32FromUtf16Surrogates(T high, T low) +{ + return (uint32_t(high) << 10) + low - 0x35fdc00; +} + +static size_t Utf8CountCodePoints(utf8_t utf8) +{ + size_t count = 0; + + for (size_t i = 0; i < utf8.size();) { + if (utf8[i] < 128) { + ++i; + } else { + switch (utf8[i] & 0xf0) { + case 0xc0: [[fallthrough]]; + case 0xd0: i += 2; break; + case 0xe0: i += 3; break; + case 0xf0: i += 4; break; + default: // we are in middle of a sequence + ++i; + while (i < utf8.size() && (utf8[i] & 0xc0) == 0x80) + ++i; + break; + } + } + ++count; + } + + return count; +} + +static void AppendFromUtf8(utf8_t utf8, std::wstring& buffer) +{ + buffer.reserve(buffer.size() + Utf8CountCodePoints(utf8)); - buffer.reserve(buffer.size() + destLen); uint32_t codePoint = 0; uint32_t state = kAccepted; - for (auto i = src, end = src + length; i < end; ++i) { - if (Utf8Decode(*i, state, codePoint) != kAccepted) + for (auto b : utf8) { + if (Utf8Decode(b, state, codePoint) != kAccepted) continue; if (sizeof(wchar_t) == 2 && codePoint > 0xffff) { // surrogate pair @@ -96,13 +120,18 @@ static void ConvertFromUtf8(const uint8_t* src, size_t length, std::wstring& buf } } -/// -/// Count the number of bytes required to store given code points in UTF-8. -/// -static size_t Utf8CountBytes(const wchar_t* str, size_t length) +std::wstring FromUtf8(std::string_view utf8) +{ + std::wstring str; + AppendFromUtf8({reinterpret_cast(utf8.data()), utf8.size()}, str); + return str; +} + +// Count the number of bytes required to store given code points in UTF-8. +static size_t Utf8CountBytes(std::wstring_view str) { int result = 0; - for (size_t i = 0; i < length; ++i) { + for (size_t i = 0; i < str.size(); ++i) { if (str[i] < 0x80) result += 1; else if (str[i] < 0x800) @@ -124,7 +153,7 @@ static size_t Utf8CountBytes(const wchar_t* str, size_t length) } ZXING_EXPORT_TEST_ONLY -int Utf8Encode(uint32_t utf32, char* out) +int Utf32ToUtf8(uint32_t utf32, char* out) { if (utf32 < 0x80) { *out++ = static_cast(utf32); @@ -149,50 +178,40 @@ int Utf8Encode(uint32_t utf32, char* out) return 4; } -static void ConvertToUtf8(const std::wstring& str, std::string& utf8) +static void AppendToUtf8(std::wstring_view str, std::string& utf8) { + utf8.reserve(utf8.size() + Utf8CountBytes(str)); + char buffer[4]; - for (size_t i = 0; i < str.length(); ++i) + for (size_t i = 0; i < str.size(); ++i) { - uint32_t c; - if (sizeof(wchar_t) == 2 && i + 1 < str.length() && IsUtf16HighSurrogate(str[i]) && - IsUtf16LowSurrogate(str[i + 1])) { - c = CodePointFromUtf16Surrogates(str[i], str[i + 1]); + uint32_t cp; + if (sizeof(wchar_t) == 2 && i + 1 < str.size() && IsUtf16HighSurrogate(str[i]) && IsUtf16LowSurrogate(str[i + 1])) { + cp = Utf32FromUtf16Surrogates(str[i], str[i + 1]); ++i; } else - c = str[i]; + cp = str[i]; - auto bufLength = Utf8Encode(c, buffer); + auto bufLength = Utf32ToUtf8(cp, buffer); utf8.append(buffer, bufLength); } } -void ToUtf8(const std::wstring& str, std::string& utf8) -{ - utf8.reserve(str.length() + Utf8CountBytes(str.data(), str.length())); - ConvertToUtf8(str, utf8); -} - -std::wstring FromUtf8(const std::string& utf8) -{ - std::wstring str; - ConvertFromUtf8(reinterpret_cast(utf8.data()), utf8.length(), str); - return str; -} - -std::string ToUtf8(const std::wstring& str) +std::string ToUtf8(std::wstring_view str) { std::string utf8; - ToUtf8(str, utf8); + AppendToUtf8(str, utf8); return utf8; } // Same as `ToUtf8()` above, except if angleEscape set, places non-graphical characters in angle brackets with text name -std::string ToUtf8(const std::wstring& str, const bool angleEscape) +std::string ToUtf8(std::wstring_view str, const bool angleEscape) +{ + return ToUtf8(angleEscape ? EscapeNonGraphical(str) : str); +} + +std::wstring EscapeNonGraphical(std::wstring_view str) { - if (!angleEscape) { - return ToUtf8(str); - } static const char* const ascii_nongraphs[33] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", @@ -206,61 +225,27 @@ std::string ToUtf8(const std::wstring& str, const bool angleEscape) std::wostringstream ws; ws.fill(L'0'); - for (unsigned int i = 0; i < str.length(); i++) { + for (size_t i = 0; i < str.size(); i++) { wchar_t wc = str[i]; - if (wc < 128) { // ASCII - if (wc < 32 || wc == 127) { // Non-graphical ASCII, excluding space - ws << "<" << ascii_nongraphs[wc == 127 ? 32 : wc] << ">"; - } else { - ws << wc; - } - } else { - // Surrogates (Windows) need special treatment - if (i + 1 < str.length() && IsUtf16HighSurrogate(wc) && IsUtf16LowSurrogate(str[i + 1])) { - ws.write(str.c_str() + i++, 2); - } else { - // Exclude unpaired surrogates and NO-BREAK spaces NBSP and NUMSP - if ((wc < 0xd800 || wc >= 0xe000) && (std::isgraph(wc, utf8Loc) && wc != 0xA0 && wc != 0x2007 && wc != 0xfffd)) { - ws << wc; - } else { // Non-graphical Unicode - int width = wc < 256 ? 2 : 4; - ws << "(wc) << ">"; - } - } - } + if (wc < 32 || wc == 127) // Non-graphical ASCII, excluding space + ws << "<" << ascii_nongraphs[wc == 127 ? 32 : wc] << ">"; + else if (wc < 128) // ASCII + ws << wc; + else if (sizeof(wchar_t) == 2 && i + 1 < str.size() && IsUtf16HighSurrogate(wc) && IsUtf16LowSurrogate(str[i + 1])) + ws.write(str.data() + i++, 2); + else if ((wc < 0xd800 || wc >= 0xe000) && (std::isgraph(wc, utf8Loc) && wc != 0xA0 && wc != 0x2007 && + wc != 0xfffd)) // Exclude unpaired surrogates and NO-BREAK spaces NBSP and NUMSP + ws << wc; + else // Non-graphical Unicode + ws << "(wc) << ">"; } - return ToUtf8(ws.str()); -} - -void AppendUtf16(std::wstring& str, const uint16_t* utf16, size_t length) -{ - if (sizeof(wchar_t) == 2) { - str.append(reinterpret_cast(utf16), length); - } - else { - str.reserve(str.length() + length); - for (size_t i = 0; i < length; ++i) - { - unsigned u = utf16[i]; - if (IsUtf16HighSurrogate(u) && i + 1 < length) - { - unsigned low = utf16[i + 1]; - if (IsUtf16LowSurrogate(low)) - { - ++i; - u = CodePointFromUtf16Surrogates(u, low); - } - } - str.push_back(static_cast(u)); - } - } + return ws.str(); } -void AppendUtf8(std::wstring& str, const uint8_t* utf8, size_t length) +std::string EscapeNonGraphical(std::string_view utf8) { - ConvertFromUtf8(utf8, length, str); + return ToUtf8(EscapeNonGraphical(FromUtf8(utf8))); } } // namespace ZXing::TextUtfEncoding diff --git a/core/src/TextUtfEncoding.h b/core/src/TextUtfEncoding.h index 07ceca38df..2d6477de70 100644 --- a/core/src/TextUtfEncoding.h +++ b/core/src/TextUtfEncoding.h @@ -5,38 +5,16 @@ #pragma once -#include -#include #include +#include -namespace ZXing { -namespace TextUtfEncoding { +namespace ZXing::TextUtfEncoding { -std::string ToUtf8(const std::wstring& str); -std::string ToUtf8(const std::wstring& str, const bool angleEscape); -std::wstring FromUtf8(const std::string& utf8); +std::string ToUtf8(std::wstring_view str); +[[deprecated]] std::string ToUtf8(std::wstring_view str, const bool angleEscape); +std::wstring FromUtf8(std::string_view utf8); -void ToUtf8(const std::wstring& str, std::string& utf8); -void AppendUtf16(std::wstring& str, const uint16_t* utf16, size_t length); -void AppendUtf8(std::wstring& str, const uint8_t* utf8, size_t length); +std::wstring EscapeNonGraphical(std::wstring_view str); +std::string EscapeNonGraphical(std::string_view utf8); -template -bool IsUtf16HighSurrogate(T c) -{ - return (c & 0xfc00) == 0xd800; -} - -template -bool IsUtf16LowSurrogate(T c) -{ - return (c & 0xfc00) == 0xdc00; -} - -template -uint32_t CodePointFromUtf16Surrogates(T high, T low) -{ - return (uint32_t(high) << 10) + low - 0x35fdc00; -} - -} // namespace TextUtfEncoding -} // namespace ZXing +} // namespace ZXing::TextUtfEncoding diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 0fdc819b62..ac64c79d9d 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -116,11 +116,6 @@ void drawRect(const ImageView& image, const Position& pos, bool error) drawLine(image, pos[i], pos[(i + 1) % 4], error); } -std::string escapeNonGraphical(const std::string& str) -{ - return TextUtfEncoding::ToUtf8(TextUtfEncoding::FromUtf8(str), true); -} - int main(int argc, char* argv[]) { DecodeHints hints; @@ -179,7 +174,7 @@ int main(int argc, char* argv[]) if (oneLine) { std::cout << filePath << " " << ToString(result.format()); if (result.isValid()) - std::cout << " \"" << escapeNonGraphical(result.text()) << "\""; + std::cout << " \"" << TextUtfEncoding::EscapeNonGraphical(result.text()) << "\""; else if (result.error()) std::cout << " " << ToString(result.error()); std::cout << "\n"; @@ -200,7 +195,7 @@ int main(int argc, char* argv[]) continue; } - std::cout << "Text: \"" << (angleEscape ? escapeNonGraphical(result.text()) : result.text()) << "\"\n" + std::cout << "Text: \"" << (angleEscape ? TextUtfEncoding::EscapeNonGraphical(result.text()) : result.text()) << "\"\n" << "Bytes: " << ToHex(result.bytes()) << "\n" << "BytesECI: " << ToHex(result.bytesECI()) << "\n" << "Format: " << ToString(result.format()) << "\n" diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index 6dc86dd1d8..30f8c64035 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -15,14 +15,14 @@ using namespace ZXing::TextUtfEncoding; using namespace testing; namespace ZXing::TextUtfEncoding { -int Utf8Encode(uint32_t utf32, char* out); +int Utf32ToUtf8(uint32_t utf32, char* out); } // Encode Unicode codepoint `utf32` as UTF-8 -std::string Utf8Encode(const uint32_t utf32) +std::string Utf32ToUtf8(const uint32_t utf32) { char buf[4]; - int len = Utf8Encode(utf32, buf); + int len = Utf32ToUtf8(utf32, buf); return std::string(buf, len); } @@ -59,7 +59,7 @@ TEST(TextDecoderTest, AppendAllASCIIRange00_7F) for (int i = 0; i < 0x80; i++) { uint8_t ch = static_cast(i); data[i] = ch; - expected.append(Utf8Encode(i)); + expected.append(Utf32ToUtf8(i)); int j = i << 1; int k = j << 1; diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index cb46db51e6..cfb9f86951 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -9,23 +9,22 @@ #include #include -TEST(TextUtfEncodingTest, ToUtf8AngleEscape) +TEST(TextUtfEncodingTest, EscapeNonGraphical) { using namespace ZXing::TextUtfEncoding; - - bool angleEscape = true; - - EXPECT_EQ(ToUtf8(L"\u00B6\u0416", angleEscape), "¶Ж"); - EXPECT_EQ(ToUtf8(L"\x01\x1F\x7F", angleEscape), ""); - EXPECT_EQ(ToUtf8(L"\x80\x9F", angleEscape), ""); - EXPECT_EQ(ToUtf8(L"\xA0", angleEscape), ""); // NO-BREAK space (nbsp) - EXPECT_EQ(ToUtf8(L"\x2007", angleEscape), ""); // NO-BREAK space (numsp) - EXPECT_EQ(ToUtf8(L"\xFFEF", angleEscape), ""); // Was NO-BREAK space but now isn't (BOM) - EXPECT_EQ(ToUtf8(L"\u2000", angleEscape), ""); // Space char (nqsp) - EXPECT_EQ(ToUtf8(L"\uFFFD", angleEscape), ""); - EXPECT_EQ(ToUtf8(L"\uFFFF", angleEscape), ""); - EXPECT_EQ(ToUtf8(L"\xD800Z", angleEscape), "Z"); // Unpaired high surrogate - EXPECT_EQ(ToUtf8(L"A\xDC00", angleEscape), "A"); // Unpaired low surrogate + auto escape = [](const wchar_t* str) { return ToUtf8(EscapeNonGraphical(str)); }; + + EXPECT_EQ(escape(L"\u00B6\u0416"), "¶Ж"); + EXPECT_EQ(escape(L"\x01\x1F\x7F"), ""); + EXPECT_EQ(escape(L"\x80\x9F"), ""); + EXPECT_EQ(escape(L"\xA0"), ""); // NO-BREAK space (nbsp) + EXPECT_EQ(escape(L"\x2007"), ""); // NO-BREAK space (numsp) + EXPECT_EQ(escape(L"\xFFEF"), ""); // Was NO-BREAK space but now isn't (BOM) + EXPECT_EQ(escape(L"\u2000"), ""); // Space char (nqsp) + EXPECT_EQ(escape(L"\uFFFD"), ""); + EXPECT_EQ(escape(L"\uFFFF"), ""); + EXPECT_EQ(escape(L"\xD800Z"), "Z"); // Unpaired high surrogate + EXPECT_EQ(escape(L"A\xDC00"), "A"); // Unpaired low surrogate } TEST(TextUtfEncodingTest, FromUtf8) From 796ef2e3e02021648b77d6587dfe7f9f26909ca3 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 01:32:41 +0200 Subject: [PATCH 0435/1315] test: fix deprecation warning --- test/unit/TextDecoderTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index 30f8c64035..25cabf4a24 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -230,13 +230,13 @@ TEST(TextDecoderTest, AppendEUC_KR) } } -TEST(TextDecoderTest, AppendUnicodeBig) +TEST(TextDecoderTest, AppendUTF16BE) { { std::wstring str; static const uint8_t data[] = { 0x00, 0x01, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x01, 0xFF, 0x10, 0xFF, 0xFF, 0xFD }; - TextDecoder::Append(str, data, sizeof(data), CharacterSet::UnicodeBig); + TextDecoder::Append(str, data, sizeof(data), CharacterSet::UTF16BE); EXPECT_EQ(str, L"\u0001\u007F\u0080\u00FF\u01FF\u10FF\uFFFD"); EXPECT_EQ(ToUtf8(str), "\x01\x7F\xC2\x80ÿǿჿ\xEF\xBF\xBD"); } @@ -244,7 +244,7 @@ TEST(TextDecoderTest, AppendUnicodeBig) { std::wstring str; static const uint8_t data[] = { 0xD8, 0x00, 0xDC, 0x00 }; // Surrogate pair U+10000 - TextDecoder::Append(str, data, sizeof(data), CharacterSet::UnicodeBig); + TextDecoder::Append(str, data, sizeof(data), CharacterSet::UTF16BE); EXPECT_EQ(str, L"\U00010000"); EXPECT_EQ(ToUtf8(str), "𐀀"); } From 8521c7c4b594c29cf8414fc7ee461ae4bae44bd1 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 02:08:53 +0200 Subject: [PATCH 0436/1315] cmake: attempt to fix `missing zueci.h` build regression --- core/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 4181b9af05..5b4cb37c28 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required (VERSION 3.10) include(../zxing.cmake) -zxing_add_package(zueci zueci https://git.code.sf.net/p/libzueci/code master) set(ZUECI_STATIC ON CACHE INTERNAL "") +zxing_add_package(zueci zueci https://git.code.sf.net/p/libzueci/code master) if (NOT DEFINED BUILD_WRITERS) set (BUILD_WRITERS OFF) From 2f34c10896fec804a752869bef238dbb84c402d4 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 03:30:47 +0200 Subject: [PATCH 0437/1315] cmake: fix build regression of non-BUILD_SHARED_LIBS config --- core/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 5b4cb37c28..3b9d9b8b29 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -476,8 +476,14 @@ endif() include (GNUInstallDirs) +# TODO: find a working generator expression for this... :-/ +set(ZX_INSTALL_TARGETS ZXing) +if (NOT BUILD_SHARED_LIBS) + set(ZX_INSTALL_TARGETS ZXing;zueci-static) +endif() + install ( - TARGETS ZXing EXPORT ZXingTargets + TARGETS ${ZX_INSTALL_TARGETS} EXPORT ZXingTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} From e3375115a1f8e8a76275920de97855290cf7a752 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 03:38:14 +0200 Subject: [PATCH 0438/1315] TextDecoder: add missing #include (fix windows build #3) --- core/src/TextDecoder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/TextDecoder.cpp b/core/src/TextDecoder.cpp index 5c75e04801..4880940a7b 100644 --- a/core/src/TextDecoder.cpp +++ b/core/src/TextDecoder.cpp @@ -13,6 +13,7 @@ #include "zueci.h" #include +#include namespace ZXing { From 2da0064a0a355f411b396af3411ed9dcba66e826 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 13:08:54 +0200 Subject: [PATCH 0439/1315] remove second copy of Apache license file --- LICENSE.ZXing | 202 -------------------------------------------------- 1 file changed, 202 deletions(-) delete mode 100644 LICENSE.ZXing diff --git a/LICENSE.ZXing b/LICENSE.ZXing deleted file mode 100644 index 57bc88a15a..0000000000 --- a/LICENSE.ZXing +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - From ed5bf5a1f50bee68578752f2e77d9675452a8d74 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 17:41:08 +0200 Subject: [PATCH 0440/1315] cmake: use COMPATIBILITY SameMajorVersion in package version file --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e947ce8dbe..903ec941c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,7 +103,7 @@ include (CMakePackageConfigHelpers) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/ZXingConfigVersion.cmake" VERSION ${PROJECT_VERSION} - COMPATIBILITY AnyNewerVersion + COMPATIBILITY SameMajorVersion ) configure_package_config_file ( From 69bb1e5542e3567d7baad5bcfcca23081cd94195 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 17:41:45 +0200 Subject: [PATCH 0441/1315] test: trivial std::string_view improvement --- test/blackbox/BlackboxTestRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 85c5b9d427..2a3d9239df 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -258,7 +258,7 @@ static Result readMultiple(const std::vector& imgPaths, std::string_vi Results allResults; for (const auto& imgPath : imgPaths) { auto results = ReadBarcodes(ImageLoader::load(imgPath), - DecodeHints().setFormats(BarcodeFormatFromString(format.data())).setTryDownscale(false)); + DecodeHints().setFormats(BarcodeFormatFromString(format)).setTryDownscale(false)); allResults.insert(allResults.end(), results.begin(), results.end()); } From ff8b4e4444d6acc4c8f6e14b5dfdbc81453316a2 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 5 Aug 2022 23:18:47 +0200 Subject: [PATCH 0442/1315] test: tune yet unused multi-symbol example set --- test/samples/multi-1/#360.png | Bin 0 -> 654 bytes test/samples/multi-1/multi-qr.png | Bin 0 -> 3146 bytes test/samples/multi-qrcode-1/1.png | Bin 64067 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/samples/multi-1/#360.png create mode 100644 test/samples/multi-1/multi-qr.png delete mode 100644 test/samples/multi-qrcode-1/1.png diff --git a/test/samples/multi-1/#360.png b/test/samples/multi-1/#360.png new file mode 100644 index 0000000000000000000000000000000000000000..97011244bb5df066f3eac80dc29ae60de7e60fe6 GIT binary patch literal 654 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 literal 0 HcmV?d00001 diff --git a/test/samples/multi-qrcode-1/1.png b/test/samples/multi-qrcode-1/1.png deleted file mode 100644 index b76685a9a74098a3a08a42a96a10eb09faaa4575..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64067 zcmZs?Wl$Vl7cPps4(=Wtf&>XNXmAbg0YY#mSa5fT;1b*k?i$=BxVt;S=QiJaPSw3t z_fKj9)b5_{z1Mndg()jap`#F^KtVyF%ScP8LP5b2LP5dkBf$Va5q|lk1qJnpA|oNH z<_3MTB!dS-3pv|16NxKn4q3 zfCv#9_!qU+#bM(;7A%zV%fI~(ucM>1L_W|#{LSew_>vN|Bfs6K^yl~8gSU@b@aL6r zzY-!WfZ+W2N*Kat1R88m3AP1@gB|wC$OimaXSglW-u=W8&`GBIiQ_u@TV9aJXKuzd zG7qVNax20lsq+Xzd8>WY(f}4oE426f&2p+=dAvsY#esC0fRdW;n^3O@=;@tc8TOPJ z7PhUbI-XCRMVi5bc?xrQ&nuLBR&QrednZ(Dne^Su<$lxH=IBQEhbH=_zzuxb?o}dF zd!(~7td&)NasQDGTjVoxB&VI0^$A0t`cBEm)3q@J*RSi3!jET-Eu~*84CdzO(6`d< zI<&28{@`0+Syi>)LGCFaG*bndhFyadn3e#=Vs^Iw!asnJZMqpXdHMPFLJ9nS;cZ{&L?%bUAVuDAfqz+|VO?)=| z5CfM~I`B7UKP%bX zE1+GJm?!ZmN+qFP^D}q}g*uGc}_jKeL>9?STvCoDAJx&g&SXdFm?>-__pOGkHE4zK-}B4|(}FVf2~Kp&Oo{4lV}#djCo0d2IbT%EtSw zc|V$vgId(*w0=Ik?_ob1T;aCrG$9nGO*d@Ui_Tj|tzqcpG6**qdGL5# zr6irg)(S`~WGp?RePBm4+v7PkSD-^G;Bz;?-k? zG7vosu-JWAkb(!%EY=6?8$xakdEe9fb(NM?wrp0R2p3C|{j_a4oJP~sbNIvZ2@mA+ zw7jkZ)3ZS#4}%E1{G+1&?^anxj?dF+qvY1jj8b;Tm4VaPhp!rcE^l%}$bVDsWjKxB zaCZPVG)?D_O33eMDn|VT9?qi^$)o#eQJ4zc;`Ts{Cc#jDwt60ncwAbG-$uBksSXJ2fyY(k&i2obUUY4h=1>bfgmj|aeF6R~JVCW?BBuh|a zZ&dY?Wm$z|xkG;BRl+BXq+p6cpXULe6_FZE|+oNN`saC*-NB@3qwpcAXL{NPnFNoaB)f z?4Z)Qe_JSNlc+x%9A7y{l4QaHwyh-vnWn!Kxw}M1&Mk=fdi57VMdO;sF-a(I%m8p^ z?F24>A~W|?yNt0RkyHpdshyavZRrEam7l9{_5*jwJ4Fhizv^5T-uUnpIT({7+9cua z6?PTL{&hH*%uP1B{6k;|sU;3qqXaHjda;*oXR8b&JOT1lXOBa%`hezOu~GIA>(`g! ze$w%D)&RTnQkBu4p!jj<`$pZ2qTCGlZo%YGd-Y2Q8Tl0h(YE`3W{SC@#F}mEso9e+ z-5TgUec+Nd%oZFgbk?um(TEg3s_FQ)LTPj^%kMbE;!ujgX05p#kuI*54%&YOVQ!J_ zj%%Sy`dUV89U{gDz|Xzlx}NnMV~yi>qtw6*J?;2r*`BLvkoFgn;bvRt3@5L3Dy8{q0$DqD$n<^XrxRjhv#b8LKUlFv#=wNTV=<$8# ze_xZkZ@nc>MoUieJOh47pvP$p_P8er(QJi*-sxe&B5F^+5vib%?3^eaClsSe@c>ie zGL~13e1}JY{r8dQ^$&sJj{=<3#Zk8Aop?>o_Z~OqM6*Nm*(>^XVK@>)ShnO^Bdx+$ z@lIbwUTO6P!{#%;Ww}3F$8tyx4i;_?SyOi#_~zXJ%Q41e#)uRf|CqJf;^J%Pw!pg+ zJ3hYcsra&t{FzDrO8mm)e%laGR`tm+j^by#aJdp3AT6^RTh#NO+v(`-!4^C|uqfz)%<%QWaDZZpH+ zQ`x@@o`V90N}rMM8x7-t1BV7zt-)q&4{QphlfVgH)-QLx!RWQ5_7M$Z6kazf`~hJS zpf!{UfwQLG_sVUrkH_%_itm@LYZZRJ@8;>Q(l!sL1xbds`^2H#bJ#ZTCL=#4Y3Lk| z3!K+^EdcE?ynm2RWa^_T!hT6nmTH&<9Iyl6VEm*9!yqf32zq_&E64<{dGswY!jFTF z8-2#FMqwLHmUhmB@K|INf0GPJ$4{FI5ux;D6ziBom)n6gB=(=b zXpQU}W-zlj^SK;q3@tsb)f@Kv&Zz3p8_K`h8Im#Wam2R$aNRJ|NQ#coIcSDrS3nbf zDAV4U@d^UYryuZMSfNn{{_5HZmE-iK3C)G++BOH7c8h)gx9W=82%HB3<8GVA)pzK~ zlOu;D&jnO9*8DCmW~pD3i?Y3ST59@sM{}ks~^uY}esz!bMZ2k|*H9jn%GbU7vLk+=&(EMmI1zQqPBZwYZ!ArdCdy z;_A(b*G_D8A(*njc=S2h3Vw1Ar%7q|pO>FKj}$WBx>4;Ik3bGizF+;#2y0_T0sZi~ zYv)rYUCwi;y+|BWJVVn~IP;H2bz^pigWQl|B8v#thH7!jZOV7d90j`mUjJ4b>ng8n z2FTM7ru`7fwZ4f=y9gea*YdeBs{l1!1gMN^9;BWEwo^%yK+V%V++Gor3(LP#$3$%J zD3^LINBD0Wzx|;klk$1;&(P(8WP>bt5xef$5teyo4Hr{0u5^4%Kbj&+8= ztM~|=5|)l7zR?JW@OujWPZ}6ir|0o6FteH~L!{ zv8@sIPC+|*MZQhA|A8;L{A*P9HX~%<*A#LWxATUWd zC*ncdD?d>DkBlnqUhDbAx5LdS;aN?2O$x@B&q2e4%&00Ca$aE(K#c;>2^KOx>|43A zK^LE#5l7XVm)myUk>XeTu&Dc>;vE-#X)>O7b-uR53O!%+iq&rTqdsP)bbU(YzJsTJ%|9LEU1vex&-QuEpzAm) zEqlg7Lc@LSlV(zZXXw2BqDhGxvFCReK%AEHS~|&FO!`LrzTVGi8osRga@r&%BO4eT z)+VCgzT=<{wV~hxHmcw$sgY&B8$crnJ`BW=sP{Ww(1{*XmB392p3t%Y*d*yg>txs| z7DK_(MQ!*UQMej~zaGK03w*_(?v_T_-L(w;WMv@u9L+2^!@f<4Q^Wv&J^4b1>glj3 z+e1HUxYDU9j;j6B!a zJf2yW`<^wGpKow$IQh0*-|RZx-jispjI0d)=tR=)XF`*)0=z=w96AM0WMLGM?@zScl+{{^MQ$r!rR5K0pR~s~#*{ zlMrZYbnT}TdIMb?N{By8z+3Lw+H+96q|I!aN0f0CM(7Nt{R~ETX!QOaFXcU z02bC~f?OmdClYLh-5rBZ;qzScW6IF$R$b0lSj$5hE>jC*)~-ZPn~0|J;5Qb1_K)9mu>(+2=d6t@(;#VQ)bSL~{`z@? zWydbOObXU$;YV{h-!x-LE5Pa2y`N5#jet8yp)TSJ;C(J{0N=VZs9N3$UiRTk9MMg4 zwBH&z@z>!1K<^j*ufD3-C{q6Egj1mVi6KA?eAF;pE^MFfBT>hwLP)7Q@*cDR@)$&t zey@#jU%PL=46uQ~Wq?64mLo+CF%mqoL$25p*FTn}#GV_j13fUWP{Wgj=;7g_?+8J3 zmp0$$lAc!zXr85lrYHB?G2rr)gL>+qBPTO@Wpp7Tc;TRvE?CSPQ~FHj_}K2wq8Iw6 z6L~}wClsPjcDbVTlo=HQxwvZhwi!DZPF**dy-`xqO&kng{#gH_-DObCci}HjF*k@q zp(qjI3QJT$U8<5k%ytnML5~MVAYo}@do8j9ef#44b+z+)Q9&>j?s=@T#u?oyAPC8R%Tf_Ymo&1m$5}=FMTe% zzvomwBx7(0N|Fsu8D!rQ)n()$LoMkvN8}ce{|{9BWb(tjT9U!S(CE8pIj*c7bJ)hY zK4mP*xGIJYk_x}yKJYrOXcX3guH2iU{;T~hlN+%Oqi-2>?kHCcR3aUijKX;~=(%^? zXH{4RdHKR`1&*0cRifK5$21D-1XwZ|%Fb3ma=Slj8IXKfx`B;hoSx9=zUnfsFbZPJ zrFH;1YAxJ;hLfUUJJ4EclIplDO!q84ImSv?COT(quxnH?EAf^K$zXn73RfNqpyvJe zAf>wd*F)Ow7s;me>sAE2aB^U$uwuXtOauSAT=SjIkIO&voRnZOY#)PDblw&F3KTRF z9u`*P%H};;r<_sWp9VqcVm9)!d!TarMnG+3>Vx_B`4D+s~9a#*JMrVmF6sS!}`^ahvE%${cODa-mC z-&na=95s?v8b0MrGiKRnrwa@T9-`6Adsbva5Blrt`=g<1X=LUT(uKyr zQFdtJpOe0$a#|STJqppESrK{jXX>EF6m@d^wjz%N$5D@6ee&Rmm?qWSl#A*<%UqWDZgubYzizMp8t zNw)}Kt59+H{Rl&GJRidP6iN66S!*$m2`vx*=KCpQp#L_KHgOYp@^2a?zXFmf@q4?90`T5X zlj$416xf1s)Fw{x1h{(w03F7wqloZ+9dzXx(M)P&X3`qOzQ#j2d_uvQqLtENbs zMpEaA8N)n)@Zg9RsH_3W?mkuvMx((z5_dY5em_A;m{CV+cw?u^epjCL!-b0d!cBrl;Q1(VRh; z#Hd_U<=Z-N_Vkv$b6FDF^E*3qd^McE3t#huz|#`)XOeLe!($K-(*3^zFtC5}{*rUp zdSb#I#kzV~$*u8keg|6PBMuYtCEH;ifX7!d``A0~jnC02ryA+p)0|<&%jPY{`L@xh zwx5}vWzbWcT6+F^g~9rH3QsAH=e+;0FOQu9GaaiF$dBGkcG2Gcd^Hk8^7o3=wh46y zEnNORzufbb6vdxlyyC&E90k)DO9NLHm%{uByxq@Cu|jeka+Q!<5T20!fNF60FP}Ow zKt1gCdSBXG01KV@%SsZZUZ!bNX`jOO2OwO8ZT5z^(q965t%Do(KK!vk*SaRi+2rMR z{vY(h2qS!uT(rQ%xa_-_{(U*dl2T^~RBUva)w{78$T6@A3^ADsuYuvkP z6(%utb-#AId6A^$S~R`-=K+q)GQizyMNKrcIy$ZJXqOKP9o@Sf!qCwEngm~ncGZ~V zU1=}gKpHK0HJG;tXp`s`J1mIEGk}_~D}2&t9KmXa{3)8$0umwc9LY8QGxi=JEpJj5 zwTk19k-B>tSz<&|d*4&g01ro{2qpD22>61wPljk~fJALlFCjVh(b1WGdN%p9$F{i$hQaq zod?$!>g45_kv02h0ZxbwMX}2lBGryOb20*bXO#>r7DS=s5NfW9hP;g}tqqs)@oPKXU}ESbQYjG8N5LU7lb=?3^8%D8PW-)j^X$~*qvu&xL{ zop31y(|vCGvUc*Z3fdO2M}hMBSoEFVrc&-bP|bAvqn~Oal}|M$f4q2MJII-mQ1C~( z0BCbaZv#|&JWhv5D@?w%2bpXBNBi1qlL2PBZ?@|5Xxtb#Mk>+FtK9so)y;EF(vIAv z;KXn{29xrk_AOU4@KF{yaVpMXd`7Xh)a3E64(ovSWQKuppO<-`B$Enj%8pW@Vt0*Y z?-_#dS)d8FxY29qIY>fCNgW5N&Yk_MSt#;ky4vh%2FeIzPYpJ|1H{Q?-bWacs0|2@ zeDD8`B|K)J_!y53f|*U|1uD2RT>ff%ts{NY6@&#|TA{t}w@jC{A*hJ0PLcd5{NHbv z$c#D25e={}Oj8}$=DxVys)Ir zk$qpFVpVAgoanF~oYi9|`X#Ma?Ip7lKFZ|1c&J^0I2XtQ5xQFt-!l!PORk0sWZkbG z^U-ks(DV*PvXlZQY9AiSNeI0m~^b)@N99n9$RWJot61&fov zgq&|-QZElg`)lgX8%@47Ohb|EWB(325<_7qq~Jy2oWJ;*&m!86u(;mBnSej^8^RvK zn~+kZJarsD+(y+9D~<6yXK=Dq*;=rpqvi10^GQArGKS|m{;Ns>c&nN{aKGTMIY-lQo=0C zxs5a*n|_sS9z=QHECV#U^K$GEPHq0#MciY}ir)R*tD=9WO}4I{Nx$aTl=TW_9cEIe#pX zD`p8ctHB*Ivm*8+M6|#GhJnC{pG70&b}IArRw<^&{Y@GwoukxzxmSGiPdZdlrj(Aq zLJf#-nvFm$ZwOn2k`zwP{!in11<>J@TZnwNgylL4@BKdaibYYT#8#&3TIzMU>fDzf z2#OyMY3+V30qYbrs?pfmxLcPh%h^@6p0#8&04%P7JOA$&#a=*w9-5$a;OMEap(CcQ z<=_1*EMp8a}MQG|}xle$^&cs@U0Pv~M;lc`b%`*MzmQlksC z_3eSNzDwY|lgE0wT5+1F7t-^(oog2@_K19ZsMc=*WbnoJtcYud`U5Q-JeYU9U;s?l z6D0QNH{!g(jz$z^%!5rdH(P5T0|tjb)3N41a!a6*u>&D*GFBz5!!7?xe-sJ*%0~7~ z>`$$@CctmnU7?PnwOB<{4jN`w%`b>uixGNxyYHr*T^CPTzK0j|*u(gC-o#fGL5+2-23+eH@ZN>6~{_`u+GVNq~J$CLbL zEPAlW>Rs#aQ>y3%{he=j$MHOri)`4YzRDwhtzuM!7xBD8{btG>Z{Gz|OXGq3-%Z{m zcu}ymodrGj`Ied!tdM=BsrHwxm>o{k?&)<+mOzcX^s0&e`$W?TDx$<%>o7IkmGhh~ zcI<*Tye4jyN3f)=ZaJ}n<dAdtfF1c;nU4j| zQ(P2WO&s>2VO_;l)wzw=O;sTn{^4dfz|tFavMNRR{gTh^w}0qP$yyXsBHKAR!?rR2 zXCXM8M~PW2D?|f*8W|BAjMzP=F}kPgj)j7kwa~`6p<;Cay#3#Bx;FJmkt%u!$Vp91 z$j+gwvi8e1jmU_4=@k+y`!l5d(PZfc0|33Bz1mlzDu#103M;Ci{z=Dp%4CvZRoTqa z4In`aDTz=hci9Nqt?kxyvH6-$#(;1IGxd)g(~VlLSH9DN z=?Vpc&a=>!fQ>?B`n)w{&TM)yafr}9mWuvBzOxNrQ34IOvu%9y_@e&qzD@gemI^P6=2N8f`xQVS52LIlJrLKSRw+yNwNdWBpHTv9dmM?KrNQ0h zm&y5N(UJ~s7}2R#bB=xK5=vFJ9qH^SENY}tEgJ~W5zfIqPUMjN2|z+GQz_@ef|TD8 z_%hEM0hpB<2Os}Rqe+%3`3^rTBPe_E3_`)@=Tp)1+X=4%h$o-wNlnpC$S1oRD#L9n zOzivf<$xzACm#~gvr~(xos(IB|G+A1c(x5LjB2U#K$KWI=2zc|bfki-#OmP*G-sga zpfOx7SykNCS86efkWoNc`C5X8DswwTVG-rRn{}@9_(;FemgEa#us14P) zSUD`}mtO+H%y^Pl)MYS^O8Z06Cpd9)w}Li_@&Bv#s%+eI_89@tCAkWFSKENg4S0kS zGiiXG$bzV6Lpd@4G*|kt8vx4G2KFKNj@OKGj-X-F4ruB0TLQX4J=zdRzGJJ8#q0H9 zUp&5xf|pgr>=sa;lC*FC6-|c#Mk)PAUr53E_qe`{#1V_IH;L>`OdTcBBd=nz-Q5*j zPTDpAzYWLG0E<&+@v{zDy_QG8vXbhfC=`?)lsaUZGCYAH4t?cP|3uKN-9k8|6YnqbL`z(~}NQINV zs_g=97|X84ZY}yYm1|LMht^+0uQ1!wn1onsUQvrdPsF*>nNH*U5oSi2E`L*F{kSFs zokTR?9v`nx@>j4l)MT#5#{;)nm*l$ETcsuwpb-_Z8#4%k#q10Y0MVJsG_`isMUAXk z=?5=T0q!fHiEXnh#>HmZ_aO6&ageYq;SF{t^g=ENC?+=hX;2&}C^N>c)!~HgUiQ0E zG!TJ23q87e$q-F)=tvx2j$?^nd*7qX_1hlu1aJ~24%hot=NZ;`=xK#r``*p2^#N37 zw%He&!4J=U1~9L$b9wZz7^H|WYe%H(;_Qj(-V|AxT+8_}$1V1S=LjxSLOx2t=RvWX zzVS4PC=WQTFj+YK&&Xl_-Ag+5_+FdrXHQdD@nRyCm)Ld*?-EjfBpdUjWB0$9RQ}dt zah8-|DX#_iQgv1c%Ivk2cqyaFVsIH&Sk$y3H?g#j#k&d5AZ=kwzB&>-#^@VS8$SqL zOzJ!C5+9FioSQNUFKDL*GQPpkHgtKy0u=}q>VF}Iu>gVHFQ5AX zMM}W^%2bB`DG@qsWQM|JYn4T)>nP(@@H4w)T0UJgxzN(x!!UD|yxb2UxfD$2M{bh7 z?s?wsNJ_mAWT)Po17v%yYRDgczfdlRmxi1BtOUw6o=qt^2oR)^%a%d4MedKGu!FP$ z`q);_`c6Xa-I7&;+#<#oz}I2kni%W-EK@A*^&bg0CwD^^=K2coEgECZjTZNx-Dy^p zsXQ*Rg)7sr-ZINN_PUAhEW*y)|7D$WF$DoC75)URD24U)ZnCZ-EvPRgSz3Wm?gDTZ zmLZ%XH7{Cp7~ax;7sK;HK#k z&3Flu`(RL6lm&v7^I@*`>L8ZQTZ*FXX*+kdn3T&IrUfbC6k8GR0nzpEzD!l;m<+C@ zEj`TbSKisf>c`(Pt6@j;cpw*(OVF{abfF~eV+3onJnlZ6t5cDM;-S-&KaDZKAD`CsURE<5x$ z^Ai+@4-rhMYsR$9bAz6-21n>k-i(=c#)wfjvEUGi`Nxd&egKzc&)fkX$y_d`%A*Anu&A|k@(d4d62zIlFUr{SG?Eh57f@XA1fzvErfekZ+7f-ROjP{Z z(FbfEfVqPlw?2&_nlQsM%@m~SIZsJ8DiCRj{9CpIk0|>-q+55CCICorZ!g-)x zhWb)Wv-!2_N6<@bgYo0*PSK~&12#zuja|9IUQ_*OYW*p(q$6_W?vB;LJQO>$Tp}qw zQl$`m95>Y$wg7S8b#xLow8-Ay2GYk)hW6*Zp&proeC+~q5Eo<}s7LVa-=!J4zoKuh zD4?oeE!_GX!-a`IhmdCK4?^)P79PS$apw-fg+$7a>C+m^6&-}wZ?`g-X27>A*D+T~ zC?-G~2e)d#dD(f*=AMJ!%fUh`fX-_5Jgvo_X$*b`)B_+AdNHGj<@mu)^S?A_>%4(ySRW9Q!kR$XY`Ew_ zMO_4R|J|TRX;0MxuQWdZKJxnn7sQg5Eaa1zqG0_lNHJJK6#^PRm0|$p2SeKEoj+nc zfNv#}7#{<4c&{}y$VA95Yd#P!s%7UHh1O%RJNokqU@Kx&u9eKeHE`I`Q8&XHM1+NRy&thhm$@ZJbb zinzcM>qasGZCbwvzw1zXnU+549cQ33V%y{mCnIMIZ49+Oiln6_48`nFW*7AzCXa~3 zSm-VG!gILbf+2lq0fjdtc`f=C2b*-T zwMirMPb!nrqb#%+h;^8!C(NQ_1Qem^#e-#y2V<#{vuFD@(|XqJYAWYUyViz3K@G$7VwAT8EO__+h9 zMCl3!@ktAN_gPNX2^xnS@hgCEzx*U6b5T%zV^v;*AkaK+3GGbwU|ZRCHLTIMn_@^F zuI8z-@BWM8=_3W>?%&(F{7$qh9e=%S^*eml+y}bBnio#$I-H5ldOUY+VQ{1O2dd-4 zB*Yj)t)=w7Y?s|w0atoi3KIjOX)UapUPxN{9N7qDjK1 z0Y{0+WrKZ(OLCQ?$aNfmNVe!}7CxmMgY?!x-P&#+HDq^^nIP_!O6K|LzW4=0TfQ%a z;Bck=fS}5{_fv=ucYaHLfRqB$q#loT7poX+1vycC%ZPTc5`_dsIyd$l0b0^E`GK1i z3Q>961Rrux(8){50$18e{fVS4n;nZati+VpPj!CAx z1!P`peKrzd;DnJAfCWmS#1fVLECdLsjodK zIB9hMGfY`ATP!&5jyVhRPX6bH)Dfa2HCiZ%IA6NS2$cu(CC4@g^X=+poe{s$o$z1Z z4R+y>4tN`^<;{OEHa}?h-hYTEQoq zHl94vVaA@)*+ZV1eSU%L$-O{)Euk=l|I!U`?faI=3f4hgx!xNi4AoldJikzWmmKC}?-!(DT9O?%^Rv0=Bzd3N6_Md#5rVx}+L}olB-b z9Gs_duQ`~$4y_^hie6PaQeN!^CVi`QGr^-)%GynuJU783TpTsT!0WW@IdtU^q+#y9)l9qW$?k3*g3 z&v)6YQ7BWBjkpKeyWZNkKOmkEdavV(#|Doojpwu}^Ux^mMSQ{8-SHebV@D?$XCdA2 z>;ytN<90b&OLLU*vuqr6#`yZqQxDAceb`d7|73fhcKLUNlH9nLp+^eOSMO%{8X?+Vvyx5m+V9I=C(RNBkTxmRB3Zobs{SzC~U}#3-Fh zq`6~bv+;(-SSw#A3Ve)zXE3xzU%wN5>yGu`Ggrd$OA5FaMlGI<4b(=8BPT#3cq@6Tl#+#T*7} zZ`4GnT|1McgUa$$1c9u3GSzFL>MCZIq&Ovqht3u-aA7I%1MpL~k}dgH0D=VSG&B2v zngV2xJv7pluG+-Oe#k?8LHvMrO}A&Yb13-*Z*mIosdtLp7+axf>0QP%Q*c#_8CgnQ z4HOF0sGuq~1w{EZWke6SLx0SOgrocVZCx1onp%=9pJAE zGRIvMb0bpRSrGw40ToyAs-J4jk%~Pm!ho$_eR`oNa2lvQvYDi5ATw%-k>znza#PL& zG2mk5)#$?fveM-6zuRhkh$jBPRKoz6m?hp%VsS?%%0j1=l_D$WgJ?#>cQ#(i{QzQN zL;pZp1^1S3lcwDiQ?#=K;@zaLv(LkupCWUe0~YVX_kc(|i|Im*)OUD8D>VCP0?zO+ z?wppCvb@$0M+Uw>h+O%V=d}k7JPzr=(^VahOa^NjIa`+O6J?2x5-J(}(`W}|4;taF z#|7+EQutikfh1$KrCCy2H)q+Kf43`Afl5@rqWCC5OSsJ{G*7@;#{AdMr95$vEJy<0 zgYjdTOzZ*pziZ#%yWI-gRnMx*RhV||%N{*%FjyP{fo?_IIN~t1&y1FeV|*QP$pLS! zOZ>Y)D{UA-+}#MpF$B44fbQbEgrOiZyBOabOns=8UC8N6QQ7Ho?DA9p6y<87^YmjU zPKxEFvh~aoxfuQS2btD@Y?xI=eKMU$`i-iyMgk={7jDUGh`~WIUZdu%D+lU4iQ@4w zVl6}i0V;gJ+{z62%3eKno@Lt-szi_SgUpPzOn%GxDO~^=LwG_KkU&YY@=-2JFOt z#yKs8-||r`tN|NpbhvFbHkedZh)A9PB_WpR$Nt0d_o^6WXol^hfwQ^acQjqEpU;)F zY2v`l{5R|6k9%3-FLm=1mI%E}{(Ev>z_`W75Gj;a3<@OL#tWs1F#0S8Q@}ATBB)um zZAB)kF;e>OZOGAcv=uq0_0$7y~0Vi>A0VBo4UC}|*`D$UFmx9f*o_xQKu$J{JVj!vGS;4B(j zJCW%xEBD`Q-cuZZ$4avUsRz)$ANIR2lF^jC%a(Rmd(L)I(qT|_z#ldG6NA3om82UK z+N5N0kF6T!=iT>j-ACyqAqmZ%yc+I)KYZYfI)Wwsd&BlSuL86kIYA)y#oGRnvFx}J z25j}aL>og(oDM)(H?L2C@DxJsG5DH->zY8X)Bp#}yamxM0RDl*D(<|U-k)|>?SY>e z>cb~Uh|tKMr?iv3+%EuXv_5p0__w$r=p2cX323Y#8KcP?%XXc&O3^JB^xb0MY`Ey! zLl?CF=nb*sB`{mnVMOV2e1V-v=%~=OccRXB)E)~&lHL?TiL0UnY^37dkf)MeK+^?l zVK|Gl&{}MUhBrbaF>z`?y11}(1Fi|{K9J;3=( zE6fIDAl8?w5%z2f$~+UbgK{%re)(2&o!6nMe2|QCp4%VV3$?pr!1WTzRu(@(_3@e*kwL~w=3>Ub)%6xjZtYqT}*@f(gyPdD9GHNJ4 z-v8wFp{J{vo6aw4G&(HaG3z4KCC8CMylQ0B9{@;^BWjjLzM!^{^Rgvm&gJvJq=H)g zi6~5UMY~+T-_5OicQl;oh;L3bb;4R%rWP<*8uHzrwv+Z34kspOk&9RV?; zDG$5YHG$>^fR1`qh3c4=4$h@U&k87&FN`o+C6qU*;%ccv;PH|ulcbAOF zIb@iZs#@;qB=x1upL8;MDGe5Ly(#`?jGo#kIs=0rQn5nyCj&;eTP9Dd3h;r)R}G*_ zj6=9Hq$(HxL^V0K=KNUqjnMh}One_0>|y;T0u}9MC78)ca)V=(mDVRO?UwMh4c1e@ z9Z9P0QR%gtG&kx&Pl?VD1qS|nuG;mD{NMxA2Y_+B%-W!uTXFt;=2#UpjNhk^YvI3S za@;R$mH`91A)AxWZ)E}5LH<&9qFCiu1G}GTw-GN^SbnSAK)V6(9Fq;+f(u3lc>4}= zBGCAU(?CdDjXSDoeqnF+v|}@vq#TJyNDdQ{$G8Nvd^$=3O!ARz(1yTCb%2c+d8>2w zKom*J&pKVZc6DxgqHQ4SK#jlqW*>s=H*mu)>Zt9>m15%9Ri;?n!*J(a;Q&J9aUR_z zJouFGYpIs^wl2@6Js|p{|Ezx5JSGaeenZx9;_jh|N1P?-k0`8!nF{`PFrx|JYcJ;F z!C2W&Ns{a{x8IZ~I;h3; z|E@ZmGmyOFYu1n>W!bf4$LTPyaV@UO2#oxd6RqN1l4yR01AvVG>4$IHb&{~ES{9T< z%0#Dk{76UT`B(1l$X8Varek$CUmk*)<*s(E*Ao5A1l+MFR79B1h6aS^6Kr?1F4h+f z$!4OMHGXr5(?^6wdyyTtsNDqgxFs5}U|%Z%hatKYw^PK<)y!5HTf})YsC`(ACO~Bh zAL6BWW8@bUVDGkbU9(h!A4UaKycSX>B`UhuwM)R!&6fjauuka;KpI0{-Q#k?kF0zluC!TsSbYQa#!NohpF zIUfUQO%4;&rPWLa1Fz@QyG;30jV! z!=?{lG(L4;qbB!8$&OBAVNPazfGDDiCu zLVHG_7B$7e9DUp$W&Kc5Kvg-AbrOInYz`41MCMQL22@IcPH62xIm|~_Aiqri`E5p? z`A`t!;{l~ympF6s8{(Y=od9CoHNEJkn0yH`8ub>r(?_^RZH!-1F>IFOQ$eAt4{}`$ zeJRiLWHhPHrUgHs?}s@Ym8(*LlhQN63a!b|(3@W^MF#i*?IO!#ow-(5mR01A^_qv~ zj8b_9EzwMn=Q1HhoeH1z*(h$$pOz#HoLPv}RP;JejR=N7xnc|fhUdKgG6q~H2?hfC zVFg|64T=$4>#sIdGcE1~+oAs|U_ro4!KL(hVU)hkKd z3hGr-vYweDC0U`{KbJH9DPNXVlV_`b-RI3c`CWc1I5*3*CHQa37a&Z41IB}>alj}w zLH8)w~Avsys0zb0GyqBspEwjNaQW}UuQa1Dx#}L!XraZPjeq&GtHRr?*FoW-dc)Oj% zCFVuXFL2#nL7cGnyWoAQYibdlA&ts70pee|%XQ}!^Z?Q!5PJbxDa&g*aNOhHhuy9S zYHgkMkF%#vY02W6<0pCu_CpbD%LW6U>}42&=}Tqgn#Xn&uQg^2Fj4Hh_6Hb%dEH4+ zYVe{Q?00kn%8!z~e@k}qD_}2Og-5H!QJ?fWYMI7KP6za0E=}WL#}`(mH0@`39uX#N z;5FO;@yRa0iMB!pG%988Pe97kL~$j4cCH3=2o_@%|1KscV(c6pohyAyWq(N`=yvfV zQyQL~aK&MO4D_i6$m}39Q_r_V>wojXeg)EXe}7=$Dq;NwCfjT~&@N2(odcHOrza6m z7AbKLgRAh-7>Zd;1D^qx?QIMrI5Dj2Nw^3Zub2uMqcbk}|NIsbdd9m5ZPfWeNn);s4jpXWEt+#BGBdD%#@$p!zA zAfiXE9W<;Bw<>5gKH zSAo-d`uqYPM|caD(i)$lkVDLJ+xa>@$dHqa9zW&>-W$yy?(1RCxw4AE&9$Ul^u&us z(a#BAK{T|eQFM#@Nk-F?;gPPf?83QmoXL{#lW{0fG?|FPyjMr41pL=kk-Azm(#*>4 zaky_=W76=rcQjd^Ti69p!XFDQZ3heaDfsO*zB41K8%TJ^I5^@;uLS>hm(Y(=rG0WtaQoi6 zc%WW4-8m5UUFOy?YBa`Yf~N2>-4t?Srf{n=BWdo?YN`6oGQIT!b;)hpocTTCPimmw z!E|6CKdd8<;&f2%UEY z+T5b~f?Jt=HS#|V+!2$Bd3^_YId=5QuOT%5U`(Ycr-Bm`pMVrF;rG3>phP1 zV?))W=&bbl;)h7)>eAtZ8(sm4GD$V*L*UW1uY=E<*V^6uqDBF^KS|GPW&ZgS^&?46 zf=3iEJ7wXbUWXdr3j8pTx%>*6k=|)-I{9|l;M5T-CfP$M$v@_SZfIq=0uIwfWKmRL zAUo^zIs~`*yej0LXIo`#2nNJoQRCh=j}B2BsypyA2UIY%iR=XHVs zmC$D-{QA93R4^D(rhNsXD4iNsyP?j&CNhmBO@s=U6b`xHq%K|uiK1_%Q$vnuq@TYF zH`ebK#^fy!flSkG&dZnQ!k1PKqh_pKZ^)Y7Jj(;!l{IhgXwE=fnUI4bo+M*M@59yV z5jCx#at{yq{enQ#h2$by9@)HD>0kY--cM%qLE4m#Ll7Ygza*8io=UQAroM6wVqCFL`W#8 z9ptb9U5ngzXM6M%XWX7>QjVcOZ}4Q1;x<$-YDqN+Z>4JYRuTn+zRaHiMeAVfS0PIT z6ShMo__nWJ^?`W%sfA7qw1r2fW?6NY5HELOc~`U{d{V7Wn5vDd&J0OK95L>~in0 z+KldC&g=m<)%d?S3M{i9c)C5P**;7+WM=hUEF;zUM0BpLaqF+hE+)ztzh?-28J?Z*;aBcxLQQY(L;r%6-!N`zsP5vf^qfnC!oDh-%eA z4-R_aqXPLxY6l)Df@rtEPxsY6+N~W{?&?|zINHux-~7%{Pe4G?Q|SQ%QzBJ_;dG!z z5s$*_8|BX7M~%_`MUTS6qf6}8W14E?C*`w^J)8y!D5jIofSplUtnjAg984S`sgao@ z$4{&(^A+q{p5h6&1a{VmQE3`|RKFu;-@Oww+^$q{&Cch?X>Rt#J5=(fFaTMP7Jd>D z&)vgZ1Ftz<&fp+A_fT;q!aPPvzLa-8IKJvCMbbgIs0)@HV*fl|n=$Q{_vo~{;OBhC zuhitLq$0FXO0b$O(@YP%K3*>-J)UCXL^`J^ z6eUc;V-;F#_f&r_^vhE_HPS(#P7pGOmM4v`KQ@I%rB@q)_Q^7fbs z-ziC=l1TUs%k#1WGlbiZ(ySc;akASQ=*>Ze%tH{~N%0ty7e7yCotno{<)UB1pS=&! zo(GoeQ+Hg`+k+SLb@EL%As2iY2VeNvbMnV| zOz1E@^*J#s!mCT9_U;_p>CQ>>PRrL5-i)7?dcMQiJnEzta35AvGhM34rm7ijaI9P) zZiZdXdf;9+vKH+tQ6I3=v;XvF3rI{dAlR+29t(=JU$-8v5;Vs*;L;^CQy5bTv_2VS z$aafsgtrDo=A7ifF^*Jx2j*(E`904Py)wC=>xu23E)^NN6yoDX+Jwx+3kCE{$v^{w z8n#MO4c!4v2j7)aEaa~g+AD+8AlR|#jIlxQ{Hks%S*3*03aOfcUchn-If9zAZqXjMSEC_fo;^y<^&)ija>m>yqP z#EMjU6-=bl()y7qY*cs^O{C|ospjz8Q2sM6$+QkG0haxBFk3Mb{`TJ)?O&8tW2kiR zkg{I3!g3c=EVmV|h^gja{FsmU0Ouqb)l)HpJ)2M;s7IbqmR1SL4vMNnbTZ zggv1#=g?H0N{xuGtMfah)LOpGp5H;+T(5mH^NmuyeY^i*?qOq;4I`L(DhR1~kpa`` zn}ND|{sAMKV>Fw*^o>RlOG1web1VIhwf8&b7gVUEB5{yTx4>mV#MvRDN6^(2PbS{P zZRvIoHYC0Y*$NbTFAh%Q{$csOw?8LoZ|$3B>wyao=9QgNZq?xW}M(nl;?#$0l*e*)#*C5Pp7)k zMILhN92>f2`SZSfEOspsqzAdZpWgliv;|5@T6CCVkk_N*>{^At&u^71Rva0T3+;L4 zWyGS2r~lY^jF!|^J|B7C^61Dd@jhpzz~O0$nz!V6`9(h0MdoDF4BEs`$iV{x|FGGI z{n>MTl&m3;zl)DV?lmCy4yYKay6H5`6^ zG;E*rl~S95@4yuz-!dMx)4!6F*b06qQF$Cc(wM(TF(Y1NpCwb5l>YIwHa&=kxcb%2 zs>{3h7!LudHln3#Ie6$GNb zY3{mS1aVC8Vy!H*2_hyE(4s;UPDq=P6jPDprWyaT*y#Nu*a-dz4r?%XX5u$sWpmB0 z1+EkiA9}(m?`u$5^hXwBm?9V|Y~yyc5}kn3>A9E@m2XFKhly;1RsjM1@y9W!x_?g4;Inj3nE1N0h1Qxl6HEri29- z?-RM+mVXG_54iQzuIVA3ZJ~SM1rbF-@mVQyu6EP>6^qc=?`HeVtaG#(i}dLs~#S zQi%}5(Gcm0Nbj#U02(JcyXj-PE0sit=&N_5?HDa+1WZ1qntzpx)>C+XwjM16t;_0eSw+VB~HNoekNw@PU91y>IS~7&PlXXB5-6~ z!=`FBojTItM@3hXFkLJZ^L_twifb{xA{8=^(rzncV0l3Pts4x`NqX&4X5nM)v(vyt z;LAtukQ?@Tgao6?=nnuO=&o<42-Ib3a2k*$PwPWbuVmglZ-BwSN?k$4nBe(QmW0zk z8{y@_aj3Zq&2WJdMz<65HDj)9(p<~A0S_l6M815-1q}&6=K{;q2&paELr|I`5xZYD z3txk#ngjk(sX3yPU_8nJ@25XbqABL?+JfmmknF|qDwYw~O*G|$ zErH@>imr(uyPA2k@UX9}9MfUz3)U>%jURGLpsyNHcJ|21b3)?gAuJbHhv-9Uw`A~N zhSl+;o#|hgLo`1hau=53g2^BIoYDPx@WBudN9u4*(stjmTP_aVx>zPf|b>MoO%eQbixTr>Y*IgiN)3)bZ z>apv*%N>2IR0+S#hQgTTw3@*a&#%d{dST{%qcZWVi)}XzO~AL{_nk0n`yzb?76JQW zUTpp8t(HGE9!hl0WhcG$o5Vhe$4!Y5?&3x^a4d{MR)XT2wcit;Ae!WIi9>Vk<@Xif4i1}BD0kCxoe zrGt0NGXuUuh-nLtrC?I22mgGH0)@;3*T-%o*TN%TCy(KJ-Zkkq2EDq6%t<^_>0toj zR+Vk>bC&s}hTWN9;VOw+*!fXPVs-ehkNoWELDZZw=2^d7ebcGj{;?)K?Q4Ge9UYyk zy`r&B6I38uh_FNZ;ZIa&J$rxxaCH9lVUg5f>-u+{Q)sMCF%HbMh zvm7G*1VMyWaXozIHyd^)j{uUpqKp=m#1av3?Z?+N37NbsCXb*F^zl!w<~wa9rFrc@ zgyQ}T>nl76qfRj+JHI?*q^(8dIedv{jKI$~dJL|A`8dUhFGjv@pdT{~XP5{6b6x+E zOxp$uAU+nTC&O%5$_#8i+wRjX6yL?JOjIQOYb1nc6&ciTft}20&mFl16ZXJwR#?w8 z8v=sgO3H9mdaPzXg?W%a@P*DX4}A&LW3L0f42Tm81UvRkc!ij}S_vG;kcYCY4?eg5 z9b5l?@9v^fhuVryE#B?NIQhygR-~3(q;z`-|QgY-)~z%ftSw z?qnSvdxYH%?(kk1WxN2-Udr~}Y09`wkp4vxL*V0$UAZ#}(zRD5WB8$>i4_^PT8U**je~1~>kpVqT?J?P!VK>X|zun?cHLM**{4RZuJ6ajs z7lkmifWUp*B0E;2s!10bSr<#0kb4*%5pKje-L*mTSjC>R?!{D*`^7gi)*l|_48N9U z-(_8^L8|Yf@|Rl&8S5kYo#jF02(=J1L;uo$$5*6;T<* zCiUYn%BaS{Ctbv&xdCOjSxto`5%9r1qI_R8_717KG0i^);cwPumdqU-IvnxqwZq(k zZKL=2Cw9xch~&<7QfKc}hWm56Pl|&L5Nt#0#EkI}z@uIOJSOCLE z1IvWy+3W8wb^ys{y$9fud|cZ=Ype%tUJdli&szgWQnwhQ&n8oQ5?nntu28s};E>cO z-pB|t4p3MWU+8|{M_N@G#Wkn6TZIjt*|qE#r5;k~qF^AK;#w51Wll(c3dBp!5hN~N z@&BvJV`uWda|q|H>`W{EL0Q=8f&w^{X2SAxDBx+)+SrYIXvp~TVpdxw>9z-f(7C;u z0EGPm=c5UUT*8(>g!I5gaf@=Hflc{ZZlH(&b+h{LkgPdU=W)3E#&G7mh zTd*VGD30c5J8i4xNbRVHOk#}&BW3SluXR}OxnrboDYdKg#25F`(M`!DxB2-49!5IV zgkUC;Jf~=kZ5p!z!*^hy+;iZbs~awI?3iUPeh#8SkH{JCUO$HEf4QJ%Kdp9`EgAUz z##6V0@8C)aojNJ672ABXB9 z6~%-}X*8z1qb#ZdS*(FoB>(AY{Wyl&@AFAMWX}Zf5 zw~Y*;fszR7N3=^x56>TxXlEh!{wUM$`uVue_qGwKWW~Djy+3Ctv54Q>SoD6WtqSop zK$YC9+UI>!aDHAhI*S6N65R2=TmxXCxgWBHF~WEo7<}G_YNKVM43S|AO}l|i<9!)H z>fwP%+bl363cf@HqG>$pZ^_MH^e{w#gAWkL?n0lzObKpFAjlK;2l$}Qf6=@&A=6S4 zvHJvbaMf)X>=C@@VWDlLR0%Tj>TbcD$*&Fz&mmh;o+t=)2DxZqFVnTlBt#xx=}X{w z28Lgya2jlWG;w{Rk`3gs%v%hIGK5509qUH1ibIXg+*8Cv`Ka_)z8#y_(Cr<;lihgx zi^>ZOeLkcTe!}uVxVASE2T10u>X(2gfkt|4lOK4yXGePM__8f^dk^UYR{KhItIzkn zZ?F-9H0%5QE6?OQB^frJJHB&K>}xTfrm^>k=12}u?#y!SusI;!9laj_K>#(VPLghs z?*Udc!z-e!C<5kN#&2a@HYDHPHPeb3-7lYhx$3> zse12H4agtrv54%NT8P@}gync>iKZBRDfadj_Sh(ExXn%BqvDg4W>$XWlbua?V~xqL zO)Ta|%F=J2ub<$cP4Jb5<=sA`E1b@uUqVgaQ;vERKoUroyIj)RIgj>o{-(IixNoSF z3_XtepMxY0Vdq3uB`810zaK`8_QO;}nhJIJ)TOa-_iVlksT zm(qir|9B8?ZFDPc0Q|7+p1b4sj8BNt^x%s%V@JqGQIT|}moQR9_d{n}cuJd2Natp-s?gR>6`xo+TEP^f%*@z=yyYY?upiIsAI%E9>nGI}}O zJbc=JVKy2$nkoD-;G(*>r!AizcC>s_>0+vn=IlD3PKR?f<&gjP#mq?v!?Npgld%V(5!y63qSf*Kf&HC%AmX4!tn@~h%OxlJrTCDLB~kh z)Z`IUI*2L$xd7~;`e)(y8!D17ukUm~-tJ`*MH0ML#g-dAdldgND9!@wubUIylMfcF zgUi}yMEY1qI$mI48GuQg$2YYpRflWP7Tl@k6z)zZw#bnI3uCdF*BS>Mh+}u00J}dL zDN05TtJPsB(cA-I{CX-t9edkm6z0&zVcFKkfV%Qr|I^`V;~KPr%8e=6#uf|KjkKR!^kT2{x3spSZy@=@X_LA4XzeymbX|Zvva%I`61FYQ0Id5@bPo@kD(ZX6t8uxXl)&}*27k;Oqc5r_Whm@01qQ>GVf*!@vdYr3y4pl9F7d_eAnG2$H}^bJIax zuKYR#^E82xR)4E;j5o$5p84g6F3tx~K42S)E27im|Ga0!iFr5zA|h1&mz$MA=%V;B z$4?~#$iv0MN?xGePuH0dMw|qG)V?y(h zaWX*T+GzmuEx+?2eq#Zr-}L#<$7gkOI9)n0^3ijtej+xv7U6_KZlPw@6e2SH3+MnTa2GQV;iA zdLI4)GP!Di3(NgXrt&UGw{Y`{#EX75mvAx#*T<8Wag|sQX7H84*-s^2R$f* zoEOZQ+xh3#u1m1?sd^;M{1^2@ab5vD^ecbul0fY+&$kh(@XMb&(S-F6XK#X_O%!hd z**>3ttKnx#5`qCVvhj`q(WgjRrVzWUFNcPkcC+x;`;ViKIraJAc{Yt@A|8fZItAJr z3`jp(@jCG79ddFpJSXOzCb)jP#z|`fBNhGLR}ryDinMl68-UR^x?5(aMu(3Yrj^;1 zWJL8-xt6Z1x-qZ)Dd2=qY3bc+$7@{*%#t>i^qy|2p1O(gg22uMuvI`hso&%Hh%fO& z%oh1=irAXM#FG%|8c}k1tJHPrGR_E_@ee6lyFcCJCi@szw6}k_ANMuL774q4u86y@~6z^A;PQ?T@&>WPmG?dHz`5p6bBa~_B} zm(+{<56(c`5q=L=Oq$AyOB&c+#>M6XhFl zr-$OE0)|+T@BrGnMYzccaC45vye3)0M+RkMt&!Nl8e&n&g} z(CwnN?+2H?u_o;VF3!hEwq1HMdzuSuZX;Efqv&bIfV^iij*4GZ=?=`El%~CAYs1Bb ztMhb!LKe+^X$e{B8f&1vA_r9|192|}9293)sIZGxfxO@MHwium>0Nt003@S9_BVYS zz_BP{_Xi}T?cTrh1GS#w6D$5s0J0L;ry(koOoov;1ZE*MQB)0m%EP@AV8W9Vu2Uam zu;z5AX(;WhGF!AtQ%1~D1?Dm5X3QCd*9E9VEvshqk|Q`)fmf{XhRxi9u%t3_)k>~y z8dPlkk|<{Lmw$rl$+q>^iwWp!7no0P`*`E-h(W_F9q<09@4f%hxQ4AHN`%~28H-KGrLPDWZam9&_-s6|%p!^hujl~r_A3ktq2ts5U1 zq?IbCww!=vjI~C(X!;XAjMQ^Sc8vDkL;!(n{20jF4Vdb{i7;XrEqj`_oASrodN289 zCl0yb*kguzVEbADimp8%l3Av20^?3&O1L10agO47VhUUB$|n)1NIc~$!J93XvT}8; zt}H`csEDn_U?g6%@Wrn$vaclyI-PAE=FD_WuX2ppJmbT~#JuJ!dy;pDiv%Fl6*#X4 zY+Zf{A#y504Sk#RA*Q2gi6$jN{!%hbNrg__X6YkkK1%LdJ)?W|jbz}wEFYCRyR-De z`~T!VSh3I>ICHve(M{o6{00GF$nRAU`nbah>8p3@QvR~ z0OQB>X|mgETO2hRxIZ(`Z$=LnOe_~vt$WUC$Umn_1NQ6*hpC&m34&0bN zf-^njGAt8j1p*`t$jT)nW&4j6MHG&EfWI5B@w)?bEmRo!3C7N`kpkFI$LaIhw-vp_0@};Va$WxfxDw`)=g95d#>BGDiEzrLw?wyZyp_%;s z{-NYVDxizOWL*}nh5v2nuk)u=8(B`6K_|K}Go3bmsY`qyQnoPa!?ZIqY_9}e__eBW zIM`{z@_U-#+(w!jc)mJAk_{Pce>A4C38m*D@LD0B9T-%+ssV)gC|V5$g|A9Ew=Nk) zh-<*3$(mvCjDfg%6IcQdVQ<&Z9pFs4(t?4?{-{sb4zd;KPr!ZlR~4nduYD6T!di;@ z1Q4wa2Prk*BGtCi5@uuhi%^dG-Wp#5_A|51_)DERy@*>T-&YCL?-YV){>o1Q{ z&S@S5bq_N91s4391vm4x11*f7z-qj0XAMFQ(=a#jxsB{|j23`BA=r={z@7h-|7xAD zQdQ^;z`;jyw||o7Xi-XG60p!oq1A96^yVFE=9GUs8pn#S65gWtkP|BLeEh`#W^=?N z%SPNoIu)Pgqlm3hkpb)a+Pr4}d*_U6?JP|Dq<#%%RW@4uH1x!>c^cma~LvCR<9{bYoE;IlJI7k=XD(V6bu&hTx7;d%4uRmynSH+!VKh zMJ0!4B%{Y*WdhsydepnT-)juYN12f%x2Jy$;LFfs+pt}K>dv($nvsvuW4 zlTk?iS*1nxKpeVS6zvPidKPmqI8Gk`1^b~f(fB?xxwFNd`y^ph2ln#veypx2VXrRpd09$XD5j@csdP}AFw6OkjEaLK(MK(}ph?}( zSVo%T;z)^M)N3|oreN0FIT@tu<0V5z2GyZYgTQrZ30`;>C%Dkt(gM^gei&dQ;os`X zH7bWj7c*;UGN6MMI)5Kjddcu?tnbEndJ|wZL5Qzof_E5zV({5HL~%~6!x&C>KWawS zzroW*klW=py;@gS2_g|$pGY}O;|xU?TCt=3BDw=IluXM7gh2hcma3;l`w7SgtoTuz zn}6uA9zGNB@iK;n#qO&~r$+(N+{Gm##}z;OnO>+u2ZC|78-3mKduu=-NeO?Q#C!(~ z4QnrS=@V-QcjwH6E6|&D3i$IUpWuAi4i4vNcStqfDQ^2`yEidUifZ+L_Rw=ud9cZu zi}KEicEto_Qjn>c-$!S!{;CyE_s?0jcI%{Cw0B55#gZoi}R|p4Yo^u$H9_}M3 zxMEl9pcpjEt+B^Z)KhSwz>JAO%2Q8=Cl_4UGo4tav+^r+kU=_J*a)gM z`Ig1wQe4~`mTopO4VEr_?AYy)A~IN=Ou5Jp;QCMBE=mXzYh&5+t$A!vPte0k@7juH zd*$x-P&AD7h3YlmJL0QzWs!g>QhPp+F}bvKoR#uI<--fE*g%aqnFR003}pyfeK61P zc)G!4OCCsxDP9KC5j^iOpDC98Pd#VJiFkG;h6oAX5Yr?UT$|t*8~(xxN#1-H@s@;z z81Np=f6>B_Q316`YG{)m38F?_^1FU5c4Qeorn=yUTesnHESEyL{I!itF??;{)>w8eaL^Is-{6`6afAA>y!C`d_rB5izhIwfT zu+#w0fL~0!GhO2Qw#i>|Wb}}pzzZHO05OP34U!geIGX^)pvzsX`DIZ2=X43PF= zNIABkD-ohz=Zs_JulFFMF~^TWp$pur)CwjuMZD_1lr3O_LKpSi%;$5lo$Sh4m3^!N zrI(Ho9oOX^?4__ABOlh+oAz}X{ALUx879Bvb1AT|XC4@CdBBDqwq&AQ>zwloRpsp6 z5X5|+&3hA0JIe>#{UNQvElriJjD4t1HS5jE237=RUA4f4cHWvMOa8>mrCBk6o^HOB zw}A=$(DiU(Q!@N-e*`d*83!2jzV}F{@(}YLongb)$KWad?9N%SBJP$zB)RD#-Y5ma zn|N~gODB~9vPrCoo`V3SO3<=5*Hfnw6JmU&50-nFm-EC1#HapQvkxJ(v+QOU(0pBa zo&UX{+VnnPBybccyXbPqSQ|eT6@e`S3&>pn@b|L_rk3riH)|lPJigux!Uf6$un3j@ z0jSE!-+U@^J?_BV+YWUGE`t+k))97TzIXD8VYGH=fK#{=pm9(5IYv?DP@WQ)KmdN1 zvipGT;nQRoxnm|ZVSObo3faJuV{k5<`-Q5%$TAZV>!2>KPJvX^3&3^Hmi^qUQAE}? z=>Ugib8>VsMS!Dh_WeG)hz)M9v>vS3Ib$8#_&!F1VYJ z-wlfe-Z*ic*n6aLBZb_)w2IHz*oO-)Lv4_=xSv#hB^IPu6)T?3bLxEUMHnS;upqh+ zwl%y5F=g{FLJ;GmCx}$S07o8b_O1*gO{GavByeC32oC8}cFD$elao+@%_IHmpmg|3 z0p@CGDhXX@Al}=6^zyB~+9+`ne}dZ zNQH0(te;3sXNgBw;cU`L8U%C3Pa3kOL-ZYq?KQX=mXvu#+r3&)Bs)GF|cvGh-9%m207k zyl=U8Ka!cKL)t2DKpKd^*~xZ61Lu_ACmv5%NK_^#NQ)W>G;opCX^zqw-0C?Xe}rUlP+u(Xhm|ll z2TtqQpJfC9L?e@%s-9=*7-!mU2)@zie0`~sa@$<8+Q{bk1tYoIgIsoc-;|$QV-OY?Q4@1*Y`=7_m5XSN4HiRpq!#~TLX`MPA&vGoq^vCePSWU z%mJ%lLPBd(1SR18F@M*XlBNcQI_;FAw&2jxw`v*8t>HkfKORFiqL@8IZIrxT@*tAC zd`+UB{Wr1L^mapoa;hTk4-DfJGq*VcI|(p=kr~D{8J=km z!=FX7P$8$yR2u%OTA^$0aeXM1biEX{2bb1*t-k^p239>T-Q~Ufoa2`n#@Fk7Ek!F0 zJ*LEa3^r5nTi-ji_~--t4F8afl{?EIidq*%rEY9Lt3S_nZivDR&gino_j$=FBl+Ml zjAnNOL#DN|8T;l8u|E&dPA8JeI-P#^GS9eKMa!I`cK^I85P%0Rd%*s_=ZA^f^^Cn~ zaWhGZ9Axx)cFn@wzV^Lx6BRyrAF6;Wh#Wl`pVi44%}sSi>;*W@S3}%+o$PoKTr<~R z>)nK2oFnaBvS(r%e=bw>fXRzv;HZX+CE#tu#R;?FX}Wvsr&2 zd@`j^dZSVH<7=cdi&Yxz9zsrj<%xc1SXMCz`G_roDg;R~;FnL8Tgt&MQX$r2RnOCn z3Oi4HgYOe{K8gRr=ECj2-3ICm?;5H=gs6mtcSi*~cbs|UqJ|`p{& zU~>lHXR57&GwHTZ&)>q9piG*8{fjDeI;lZ&O&M=6Q$IIz!Aaa-~$>MU*0Fwhm!;d;IA1#uZustshJi?RQDM#`#mAp zA)yzqIXE}r7*;Y@3N-DB33$`s=uTk6vWXSzA=pJKW1>3;8WK1MUCZ5!ft?zV+AV+8 zs7h@S;(n$Ad*tGtD_2Fk`2npV3|Y<&7=5}af)h1I=2!c^oT8IDW*(6bBY4Qe!0s4A zj?8|W#JYvRW0=`~3f5*MH+q-m`Bo$Xn4&5yFVx9O0MY#ef@5-&z_VTEMx*`V4Oaqx znO?Udv!Z?S+b#o#h zW2@|yFjFX-Gj_MiiNUDds|TU0NrT?f--uNbei>1;lq=fHVfw@XhyT0z*JQpp%HfC8 z`H$zN_uInOsWjalyCf$fb@x$p=h!5BhLmoVFrINW>f>v>2`QI`^H~GTn17XSEqfYf zIXPP>der!3qO1Rh+XUZT!l0)Lm zW*9~J*@SEWPe;tylk%W~EapAR{1;gM)Jdtte)y<8q^0&WhWX5uwPQ}gj^^xb$a{IR z)2y4fHtGCB!IG_?cTw2|Uwviok@Mx1V9`{ynU3!D9yq<}M9ynC_<4+Vm}lSB7dm!S z9lT9zHnx*yG4_ck`B}YLp{&Omq4Sdps-weC2!a$x1Xz-)j0%+Y14NY|b8k%)w;#Zr zCLz!E)c_$xxJYGoxE?7~6a)UlFlQg2Hh_VaNpoi-drfO0;{xzXe6K{T?+Uc_jJ<&x z3?1o{fiz925OIwpX6fk#OC)2DV2Ehpi9Xz0Bp3`;39$&PWfUAO*-t_>3RpoggQ} zff8+p(Fa_@Zg0^dow)Yl5`4dz?2{B1#xTORoffG8_h&RC4OTQRY~qj}bZi5*8!0AF zy8uH)dJq?-4hj~F-Y&@u)NlxJZ`e4K@T1f74q223&xtLQHUzSp*?q`)dwh5yQ}XyF z5^reuYMGY0_=^ht+Q}VcTHIth@bz@Ie*14$^Gb*R1I3B1FJ_Yd#Ft2O z_?i*!t=*iK99HGBlDkf?3qb>`N8i`6usa7>RPBdwD&W*yzIbZ9&PT>ILG5-1{5AvbIZZdPb17=++cb}_mv#+VXr4l` zJ*C*>BA~q5AuV(|$|R9P_w|DB3;($Yq}|}`d)#2IzA5}?|0R)qe&dI;g46BN+?T+k zwk<#+=6fEb`*vH^>i+uV$&S%?4fE0A8GyI2x;xO={sXq*DYS>uH#5@Ame^<70$-U{ zK6AS#uyQ?*OL`&0-$)k)9@A#SB5W)bGLrTzT4GWQb1=yhF_00r=|E1Sk+t*?gpdLP znOSnSyvQoh(P6M6HfE_y`aP1SOIf<4mYhH!NP#ic@7YCq$BF6LAUH7z2N)iv7Qqwb zDpi)i#8l8uW3X36M%JeRw$BRs7mTGD_aU;q)O@`XKtwIAI*h~)$vs#uc_fC9_C-UB?Nw|96?3>rA>b{a4n1V6(&_3tT?y^WJd z2xWSlS0fb(<}x#mtyD3OS~y1^(;jOc4EGJ2FXf-Uc5@j~{69g8rT{y{E3@);6Sa>t z?c9r3r5L68Yuv~Tj!zSFy2O!lp19u~rhow!Y#9nn##(n)dy~+Gb^P-6Of6WOnL*;F zdl?Ch9Smrhp|Ei5lh2kX24^$-^XlyXXj1D2WYhs&iH?q5K_aexv5JNuv6 zBUz$o9l3APzjU}xdJfJyM5`-MvS)Tn}-}P>e+U)=~(A+9|%YbG? zpP$iTm_n*DH3e$es~H+aCB9?8NQB}2j8jJ+CEl|imO*#zM#UqND>C6RFHId8#H&(WX%X$yxU zm4jTw;UOVNvvYk<)d*PR*tA+^Trn zHHKXD{>;()XM`@lb>U-c`tx60Z;uwb0CdZA98i~kMU1)&)M+rYuChc}~H&Ndn_QbtjNCb=-oLM-gJi(BS_Xrz~OJkG3wI5V7{MkeK&jt)1 zg_q{GdYSP_GUm3Yt<&?S=(pR9`T3Bz9sZkSC(DUTr4HarGniQL@m_aa zHehdIJ&y{+-y-_ z__&H;+}3e}FomyN?O0B|V^Q>W_e&I45>>h;Ng(>)CiWqyX)|N*yUtk_Kj5P^#D<~s z!5;%?fDXlF;Ev+x17te-?P4&`Hx2;@IGq^MzQF?Rn&@AL=>x@wa3OX#fbM#1$EWsL zgZ}~K%JN6#YR1b_vWB47M(2XK_6sbdJ9WcxEn&nzZ;kzI%Y)M#TR)^m?#Xagh--m; z*1@5I4B};;X?L3*dSag6?V0|50rmdOCt=!gZV?oXo`3AS(NuNHx}Rr#;0B}fig7!V z%utOYP#hxmG{^a2a%>5&{sI7n!)~>;be1ZZKcFETH4{btBBws(^I%IZNC^3gtivo` znESwja%EG5pA=6C^16ZZ^x8RYU&!j;3w_?oaWe*IcUToN3Z-YF`S~3$jNF9I&Q@>z zlbE;0G*p5yT})^h!^2l)|~i`D{p2A z%-$+Z1lHBPNjEh;Frl zecnb#lqY5{?7O3z-_U6YwuIk*yw`fy6x}rJS~3nHGI$Olo$vUi7gBb>tlIXBY)Dgq zvgxuG-7ZTv$76&wfecnyudq3z?OOgO0j^2=(PKadBMt!%!3k{mgQm_#fKTzVg7QNE z-l__fqJ=X8X4lB_2ZQFl5KfpGW4#m>U}gVRNbP?twUiIbNhhBt>n`J43=qFL0Wkx! z4kTHGMOv_tHa;ev4x1v}i^QuH7WD$6+`lFcc&P8wLTxk{;)-&*gB29!qrKVn^-0DE z(m&XT6r03HCzn2fho<{0B+OzfGwDM`%uF27e2~qE@hI=6Q9W<(rHpuiLmr6!`d8YO z6-l-W1l2BuZ-qJE-wJKgZ!1Xk#ili*q-LW`K~7BWB?TC%35mptyat=P{}txxK^Kca zwnEFpj>T+5xcQYtS<|p{Pk+D5zA9EbRyifUBxYO>vjqcJ&I;Iofv%g}skply#^c zc%anKo7Aab2ytVicS z6BSfjyI_lKHF7lc3#X)Q+yadANVWoMYf}Y-901Sj$KsY_tbn76>CeaizTy!G_>-tV zfgZOCmQ^ZLyYZEWYQy#j6f{uNG{>`Z81uE&99d|e|k;0 zoBb)>%O+gS#4FKz;x8IU>Kp&>%DY~$5zGfzH&*6o%7*Al$y_zlnY3i817pE6&#HYG z2F~9rhok55)Hn6gwTjKLi~L+kO0OLCz)kB1!<4*8s&d7u{X)G7)_EqccKYiP1yUZ^ zT|gS0sFC18G~k{|0PYtm-4hE*U)K>`*_!p&A9`I1w9nS!3Bf-&j8wSq3`KBop@eX7 z(&%uKituo#tZ;C&&){f^9IKzLiMOcB!Y#?L@eKvQz0Hq=YYqoLIDzwje*_K=SL^@( zMR{ig@axKO()+r;M+APZ@ZP%h4<{23bE*eqshl)ef{cnEBdyp4qa%aA21Q$0vLlzF z8W`}iSxg}y7fk1}v3>hz>7?W7sAs3@C@?Q`-1qA4?^Ua~dfr1-rs1paD^9k0UpeT_ z{0;@47pmur7tS@iEaeR4Ki%&D!9yF03TSpB&#gvMSqtZYP|9Hwjz#{1cQBpPIA_TG z@iYVErj4PfzURBN$VOl7lM=yJN`=rdfG`Rh8_VR&%`)xqZgO2+Il2UsCt_Z(q$i2w z7EH1|_elBe6L;+%ZZE!XQa@b}0dV?cL##ooo8=l3=D-U~zM}2%Y@v==T=Q|+?TLJD zqkmIn85_QjcbEzeoR3Wk?`A2|k+55yH+AgG#_@Tm2^(?fAtr z9MR)m@RznCr@knpR1pVm2B)#>gI~Kw|3sUH5qQB}137laMa zc~na%=!GZTZwvLf(>{Xz*4niIN`3{2q3?OTsQo9&{9#{z1NwA7@$^!lwX<-i>vB;A zdOr_&&>u`gJ6l?P6ujC0FgZ7h-;L4M7gR6)62g+fDFG1J(BQXS7kc_7uXA1|HTBm> zcT$QP^aa5qz8Liw1nq!YgOM5J!ApU|tkcKs@fy7C@kCzm!58kB-hABQBh8&Xf;{=@ zmsl)*$&9czD(w9JX;at=tVkWTcMm42lL#Z#`ezKhMDEh?r{a-7pD0GEnuIu2E`50m z&A5cR{^%K-4|00ZWjH}wT8%;?n!EW-m^VC6V?tn6rkqpLLX z?K=9JGJ@<&^ouoNs`Ch<`F(J75bgu`ha?n+*eJ{g;sR~5d(&}njAqK&gOd_(`wT+a2^Syx53>)_&`&p z0i^(5vO;QaSqpUx5{LjV+{nv;7t|TMX?r^Ce_@G4k8pJ}tF2c_)Zn5|%p88x3k!ss z>`u7bpP+gDPpa7z;8;I1{E;%Dj7x&Mc%?+m2!{r|Uj9NQ`D z*s@8;UYXf@Z;I^fb#UyA%pwN~k(HD^kCBl`kz{YO_xxYy)A#q_|D;Drhx@*+_xm*? z#b!h5c=o`nyDQgEwzMGkFajMCSAnIagU=XxsGEfnmZ(UmJno01)k@1!r5>|w(|>_L z$b#Op$>vJZe|w8+yxKZk^D+E2jYx44eeq2pbw(bqn^G0wdiJjX-ZqO~R5AOlm(nJ&f_yr+csq#vNYaq3?{U$4%SgCt5V@lK}OFc0~gZE!HU^A;C( zEkF*qf@nH!YfE-+b`D2QQjqmMPKR z?SaaZ%UB3LZLRQgtEGzU)f(rmlI4xF@$+=(LuiML9+lZ3zf6Wc#z?qdzWIB@FbZ5} ziu>+4Fh}r@Fw6J)GC=uF^t?qGufW+ZndvgqBB4=~Dma2+JN?n^*Z#P8s!4M5pO(Nn z)>NNl_W5C`gbq5pm9zKnR6XVJ@6R4cmjkrEJB^4Qw3_gMnN0@=`s6qQP)B1&qSn7AvPOSHmp8o#yY#g&s()cc~NlkIAC2dCjPYtX~ADrR`*_Ul6r3Ag=-eB+Bp2Qc1N4o{g zUt8V9`iDMf{mL!efJ`@{&bOAkMH0f;N5gg)RL9G8d?*mR|r3)s1ckYiPv9C8avov$`=lf0B38eNM#TVEu?Bv*!|^~g#TpJ zrgh3=ABZ=b51DH;xI~_9j7zK5CD(|zrvoPsByp)Nh-9P9kW2{p4}@s;Pb&u_xb;hR zy_-@SFSeU4gCKcaT0~-Bp)~c*Yge~@s$LZ71kE+r#$-HQx~hQi3S2qEJgbskI>j3W z(^PR~#9w_MvlswnrTrU1H$2{ywJ)#PWjl3N`OKA@P+-2x{PbLO+v>iZlfBJq zg94Io6ua{cl<$;vN_tXQ@wOFqoJo8qnwrVw@cy?PW3Gk+j{G{X0bM zTONNe0ZrrfxC_to<)iRwjRM~KAjM_^-te@8_l$($fv+trSWrT-hb}r(^cV(VTvI5p zDA2)!%2>n!xoaO&nPG(yR};&JyZ2mw4rSY(pX}_6MSYVPB^%1NN#@F6ILu|Hw(_iJ z%2psb1T%M{E8>|rjFR%eg|3~8$a;i6W@7Jww8!&3`LB$|9OtYOG+n+KrPX7zf{Fuk z?T#6J4_dAF+u+L0d3!_$BQ~EyP=X{wEc zxN%G25F2_x82WEaKwq49!=aDgXuQ#R9=Y`kkgSV$lkl)CD8FlM%S+&LrLU?Z=ouS= zPuy4G$T(E|mJzZ+W0uT9>~OCzCav>EYwz&x!sVW~{&r+-HXAbIIt3YOAdJlTd-4)y z_^>0W0pOEg)zrXv2cC2xAs9P|$ld_-Rj!e=0W0|x^R{OHTo26QXSMZ?LY&qE|83qa zib;NuG-qUnu+Q5DrlNpRBJx3n6<|6(7+I^Iu!@RNur(OpbNm*axElw*Yf#2qMQxeD zMG7h>XrrngMxd zxIB=Vd2lA``qPcYhVii$Q4I4*e2u(w4$SZavu+=le)~#`!37vhJv*EsC)j0)}GBO3*~Y>`>Kq z{^TY}XPiv*;*tXmTZ7;A&YQdbhU}Kjpay?-PN# zSB0AkK<}vdYym_9c;j5(P77tZrT$huGcOYO#gNU)j+!b!|3aN+)(TKiEzGQ6kS&YX zawGht#Yme?Ae;VCxL*99m7Awd zF&W^zvGrsY)ZR$IKgJt0eD*a&iT@6m710L~xQTIh{v?%uZ7jkzw{IK}Hak?b{}6XI zOW%Wo{tHg3watgSBsnsnO&TLW0ugEt>+;Wq4~_#n`8L_}$$Q2W9mS`9Hu@#=2rq26+(D7oAzohZV-df<@cwj3eY%0=xIkn7zjD+?>G@z^En0_G08{- zpy_!fbqj@k|UMToZtLyeSV0mr6Idto%5bVXc!}F6+Y% zAu5t9G^s(G?Wr1XN5mp;3jj@bUtWXk-E$ez@nv5e(lDk+MbPY?*9s_-lw=4JHFsy5 z5`XY$(K#lA{Hwkm{t08aoPg9zg3!z^R zzLY-pfGCcTtI*fVtAGI@MHpe%nwq z86HxxudsCaE9cR)r$3!>fWKxr|@??RA`Hf}1 z^zlHAg`&7eIrA4d3=gVFer%C%CC`aN3y$)H@x#%qYwI9ae|!du=3dC(@g%>~@w6{cW z!L91c6i1yUotO40NT?p3$6woc_Au8G!KD4%Ym7VJZ+Q6xvv`cecVBjRwQ)>_IIG>$ z{)lZt(Ppt0?G-K7WY9rAu!@f#PJ{kx@OI*5WmRO;9IOoc$daXU*)m|#A~sN8UrU-& z{N78JE5XZB>XO*50~+g=gd5<3x+TG2Libu6*OO{q#_L;8t;=Z9##`kt&LsC02f(-? zr+Kk5hV}UVpOL7$hUN6~Hh0`bfa2mZiXH9zM?Eo%e=)r}Rqsk!m(=BCXRH1swW%EE zBtB~IrLmZ^_NgWqy2WR}T5FAGmboph=?0e|713<}$#-2lDfKMI zmP(esT3zOWuiys>D_&c*u+;;vP(5tY=9Q=z3Lf(B&Hg*YQgq|r=b(y7rJvSTf#Yya zs;-)5AAqF^MrdJK&RP;kM)JV&-?8zd9LFaA1J<9c)+vOriMbz6w)9@E6p$&X_A%d` zM9&bk#W?fN__0V~R96Hbms&UtG9Q6W8UWNtSNiCvJ04cS*;b%5iT;XZkVIaYB>>`a zKi6S3{;ghxhc1o!vzc4_fyRXqnhJ7uh1mQs-*mC15d%%^k}4u(qgL)G8B5Sc8W>tgKj40#C4C8g#3IGK>>!$Z)>rO6 z_3=v&W)$~+u_umJ1+ONDu@Up%gS|6sGcXld!9{kyAVBqmVn2Y^RQj2x+{0kmRzdGv zL_x{jC=s=S5|0Cu7vpYbjDO=Sj*!=azFDc(>ob^p(>h1hd(MnNK!sZnByEd5{{4v$ zYj&j+XBo>f2<@96{a3{R$y+044%!13pf6)Uo&ClRQemRX(lY3@x6-0f&qCWkiUf}n zfP{Z`95%+^b-q8mb>}{n;w->~74T%XI7QxDWzns;C2!57wdK^%xw(E3bUr9jkNjK! zVGE!ZMrXyR%6~Nbt|0DlXW>+d=lyho(E=heGX>x|6CRPv?t3Q>AG|GrHPlSK5_OFh z&e3mzXk_yr<=VWwja(|>?lkCr8(W}MT92qzvFb=}J3S|!pihl~VF64_zAyk$ z&520>v;|ey08%W#8P4>Y;&RwREkfU96LZ$bpxTF#1S=OIT=wL{CkRR;!3c2mCcDLR zoZI7QG}rfcrMVbP#I`HCK=|3_PioE|ErC9xBj`-3SIkf3Gq9ADB4@v#GZXO^1iQiR zOz;wvZfDptB7!{K{LgyjQr8c~cjNBX+05w={Nac>U&NHml$(tHP#~E?8pSO%qB@wx zXNnn(<3-l&_t)ENF1&BpHg{i+V8_#o83S>VckeL;lFCUYom1P%780ljo(^seyO#+^ z)uweNth=U3^wL5NcW8+`U^4ojqMmy{R)vK;4uvf|i-O9wIscGalSo_uGA9crtSVIU zoXvywFF;S;vw?MJjbzNRu40Q|HyeHfK+A>*`3dhrk`jR*MDqkH{qM;NUq)VBUl*Ah z+@%r*w-V{yC{-*ky*P@w$De0$Hg7fL+DQ;)kMAr25kXXO0GrZh&{ZpKZL5{eI=%=Y zV)a-j+m%8Yx9RZ?0Ghmu(}M&-Z8_QP{ja~HNj+A$#`v_ zk@h)Hcj-GzZW003EcBcR6vMLtc>EFlu^xwlvn?X5Qqk7E$S!4KIZ7 zs5*wfJ#8euohL$h&AAk{n?1-90o{x#X)_n16m##ZT!6ZeXhJ(ya=e!EAa<=J zl{KXwIWdQJucV03t`X&2$qA}MRQEv`j4G{~(c&a;@8DiBDUdCI2lDAI`Z7moUL61R zvLLhjUQV+=uCM*}FHS9ARqFkxQv^`{KCr*a!oD~9IKvLmjZ81|rGw9>ioQ7s^5eB# z7Ewk&NvwV-WP9US7&oxB&2sePB3a=VXxv;+{96u{vOA}8&nei?5v~X z=86al84~iPmnKr+B`r5S25x_&Io))!+*DdE&WnCFydQN-fG1+n-iRdTkF(~M0P4T0 zIP4M(SA;)@hPSD2MAJTR{D=JMRiGhC3(&h{>`2@M;?b0GCWH(F97?NEl;6slYMyAQ zoKNf?24F~zsxq$wa2*qB7r2Chlqu<(%LCq_-c~RZ``yuKMk=(Bq`Xym-SMYi{v7+NE_TFxfhL^BA8=TCSa8Tq6|1PEUv{{BBYA(dD1;^6B<+l;XCh4qY$F$k;@hHAYBns z=}1n6JIl#Qt22;tx_;u8sBsJ>$e8wq0puh#^_LX(E)_2IeSv7iLpWh+ZBJr7~A%NH3#x@O8{ z)AK$@|Juy+#mB)?+QlizD*0el|KZ1h5z|E)E{@I1^idwg{3nf_9FfW- zeyy?Oz`Bw$;=Bi>EoAx_OnvfR79d*1lupm&>c?6NySWjy`DNO0n&n6joIbc)7(OvV}a6C6dg7f;Vf zIGiT?c)Kg5XOwtYz|)ln|HBogn80UuU6FW#l|>_Wd?x$h2HRl=3IDA9u$tP9X-$L0 zrqOCz{SrkQS7c5EE9ObBbJ6+ttH)Ip|2-5XUrW2>Ov&%l0kUmD0qu+{awZRmb36w7P#>*aqg89oED2udM1@m5 zA}HoYTfBSPmNi!t)ipl~0ERq44_B~i4WbC-tqb%^wOV$2d&;AQEy7&E2tNE>1kBv+ z=5&E&vVWy^4}cr+$PrCT+;2k!?Y^NB2Fpids%ia`OdY)WXPqR20hgCrI(R${RQSJL z-3h3i|M#DhRSdvYcAHt`q~SaK0<&kCnlmgPm9>I?Xr-DVORyBw(_WrsXnS<;0m=8% z3TG<+@%-y>csurwwSt;UDZF7EEA`Xr%t|aGkA&&;&_8!Vf`(EDXrhKol%TEQTuizo z#ZM@V9{$okR@|gsLB@DZ+Q$AV!+w?+OKI{$i}(D_FHU-#M(y`ePJ1vW3GZS$f?At+ z`6Jc(j&ko%YiU4uGieRwOJDSg*O(=}b;iIPOM$G0LSP=2z#n!ZV?eo* zymJ#0=hZ^pwXd{lx9=D2kXYo)R!f1;dbOkuzV+UH!e6oPho)7(gDGORdOSAc0NaL2 zwxyodwcf?(_1SuqZqW0rC4cY3;hf)>PYbS`v zt-UV4b7<%DI^clEwmJ0TctYX5X1vCE8O<9_8+P zf24C+AA8&B+9P7@_o?H357Rl?Lc&Ob7NhCxfB}H|YP`zQynil^7&F#=lqg$a(y(8j zQ%k)gFzh9eG_=x0YU|fm&ix83`VE|&e-II?%{pX=puGPuCj+zd!*w5dnCkBxP(j=$ z%c7&zPf(N3-K2~aNvvQa@C&gv+urWNK219pIt|8S>jLMIe7irmwcFJ+-T;z}heO&q z@LmZ!CZq-e3l)MSJT%ahnCWr2OSD>76UA>z1!>YqMRhEg&!{r3L?rEjGS6v79HI&^ zQaX7VHgg?teiT?f1qk52Uld;2Crk9clURsjRr*}kI;X%)rCSzjqD*FPkOw7g?`->r9$xzZ{nJ%1`X!{Ttdva#rUSjhFu!)U+l>2+w_arxLJeO8t7}CLdd^oFAwZiVeF+W2-D!q~|Nk+p;di<5}Z6drgD2wcGew@RS>$)>#G?(V^~7N(P>BXtpC;@%4V zFH4_Lu3J{$pxITdP+TrtE-fjmaNQNv+?Mfv%(5@xnD9L5_}aX!%|HOu>`c`U_ILp( zqDU>tl_9xZoq3{NA7fUB@#>XpmAu9-g2v4{XHT4xbsgd%aQ*;c0tv1mdQNMrDetk>Aq!nk+v!#IMm{H$n(XC@Z6P z?#tOitufpe(PV}!kQB>Wvb_5YHcXz3clxEt#PImE2CCg*+J6Wa?LsuA)*90Sic;J6 zNlh!3wRih(aNqWYxc8X88Ba=;|0Q4OS!q_Em*$}~jkja#XepD|f?XH;`FQOh>FnXp zcV2--gCdZbslhurYB6LVCOnS0!@wpVmg-N9EV_{X3bs>BL<=A^E(;@z$t()-qvf_S zM$3VwA=pMW-kp}$gt@6_dK@7aP~g%tYc`}C0tZy82Pi1H{s!J}KJw3-et)M39qo=u zqlGarlZu!y2M!t`f-kno;1mJucB+5C7!dZEK=K*Pv$@BVbx5b*rZ>;m=hlCaoN!!v zR}!aFZoD(wd8Krc)d$>*g~d~wv%Tp=OK5-ik}e@}i*nY6lAFHhgn0(STTZ{Ej`UV=oPCA*l;pZUzKo|9R9DU_t;oC5sY zgy*_gi~C#$*ZnA^G}g=UQn}(-@!$Yj-Y9jG28$x|TG1F{#`VuGHe?xg#2?Nr_Gm}@ zWhc2jz;-Y7}K(pt`WbK?8d1F)N0uVR6UXL61X+QBQN;OKPgQ{ zuTjFIhXEv0SU^ubdyuXC~--K^w# zfSU++S0?Nuq~X``euT&lFg-VI(h$>aS__gZ5GUuAVOkBL_s`-v^%LO=SS3hv#+663j@uNdC^8o&yEy(h z*(YlYtRsjn;lOKX1<+pIf}8}a3JH@;9y|HX?-w0|Y(mc|H5SspgtF93kOTdNxJJ>K zZY(K-5;ATTL>f3dbIT#C^1cBTSQZhQ50nWlW&=CEnZ#a+I2IxI%Fs(zHZUC~R%fy{ z`Tf29F5HU9{3Q&r^;C=|GNO5&F>WSSbdH#rF`wjJ*|>8zu{=MMkT2k))g2zGat+yh z<;>{R-&V(33f*n)p*;tb|4Hn_H6&dS$eAcgM~lmxP3GyNevR!yz{Ln|0mv5?%q8aEMrwy0B zg4@-Mi1e)H_WV?y{x*z&@)y96gXsOFoqFs;)7lQBUwVD>+;)_)2BH2!?(S~|HkSmx{p z7(+dS;*p7+DbMpqq#{n3wNdfNHI=Q5gBY9h4#kbwDo&M{H-v|yI~nV?N8{fz37aLq z{or|)WW6-Y5X+SNE%*5W*+F~Gg@f9R+^R#rXR3{%NRYEPB2VhgH)NY+7sK79;oi^h zCWRCe+MWVEpUm&Yrp+p1_wD;n#$D_P#v5dsA?`0Wx{52^1qiB+WZbB$d zre~T~A>)G4G4s;t79>C+(l{k><6Y?`2Uj$s0ogJsXN(-zTNhDKT3WaZwj6FVQTORd zXrn-On-r;%``ttq08PCDGBGbpEbLk~nI>LSFs7=o9mmTlY#*Q%HK3;i!Dfdf_iU0% zK26dO*z-OBZ&|}7@Y}15v+J<@B>xs3NWc4ZS%$JgwX?}lE#uX5|5czqxqT8b$tzMk zAe57hPOeOs>P=x9iJ_7ma7J{{yXwJ!aH1^Lw8{5f>aQqeVz%Fq*Bu`zusdTYD|cfk zgmtw0?>(I|=qEt8lV}E^W=Ue+34AYBqb!^$Qcgt4fq@w!y-1Lapb;)h;Bo*6IQ#e; z(RM+gSUD<&Kqv=1RVAV#tl9~mi0^MkMco@Ag7b6>6)V_o$5uSJ9f-XX8{{=tU2Z`Q zIwbJ@6Nz3RDe2Wl(Gxy_rBVkaIMNLn4NT zb$x#xE6C_4r^*qi5309>d2}LAQUrQ@M@O;!$#YFF8Xxp-Ztj?J8K5UU^;zP*1>5=p6$Mx-KtAuMo%O)LxQBs zf7J8dj@uBcpYFhoScyVvEaoAtiv=q$HI+2y83jKTH%X9`(|`R1>cr>e)* z_p?TM><=Edb-k;Wkaco#^pWwoFNRhxvRJdNwu(%S>v}=xNqcE>gNV7k#(GOTR0ce+ z3mZsH%S-#u22J(OFy~fbPAMjZR`0C;hiMtGN4fghlVzltny3PR@pkOo3zI0kTNJ{` zko|ajsktO6`(BdpHK4E82q`4rXCB`if0s_T1~jA8(&)CE_aYU2wP9@-dCgIQ^W^8S zaeLaY@dPXyWYb#8vS?l)l{^ph=XUwQ(@(n&JzLAsEvWs>T-r(e;$St?{WRne*$_+N zmD>#D)zQLnvXD33t>e%hinio+>ktcEN!Ja_!vMRIei=Cl^3#SQbH@Z|8^`(gKIq($_~O9c>Q$8Bw59nPZx>p`jQ#;tWUsX9ZHU`K4cVc5Bl7^y_mzUiE#lVL7kF3x2A-|F%WmM zwc5cCAUrVHOB)UF-;)#X54DpqRmPlQj4zo4`)XHLyboWrAZPi8a3rH_+xY1k+eS(g z(i#$QJ)C;i+r~88P*_n@f8pjh=x8!&Q7rK^{^S)4+~L!P5S&c0m-{-PRX+OOf|c{q z49*4b2(J8du=JMR_3Ff>Z4lSlr_g_2?gbR@(svf*UXjq^Cv+McqWw7gYl0_2BlGP5 z+&(aAa2kGjn2&%Xt)VTj)wF3W7f^gXH ze)$&Vs`P~Ul+&NBNOk-k{%wd@ao~zfu8ImfQldQ)%A>^!pU7W zyG4{Q)08Ob=kZnhan9PWj!?pXe`n?owKuRI6Tbx72eZQ@1)?^L zkP+P&<$i+xVHU+2_MM7Y9#$!`xz#vk6>DkKUc8p)a1Zx1(4QyIl}Q7wQgWLx2~k8I zui5GoI2VYU#{qeN^~srFy>A zesfK)@k~j5_hqzyzU)1P8}S*HvRHywHY0J^?Vg#6?>&0kpwD<{q%HMJNm6*f_|RY7aXR-u?W%6@ zo(-Q*RB~q&zVUN=5SNg=Hc`!V@($-0)8X&)>B?(`MsY~1b!LQd3~S90*$x&gej0Q4 zfu|BUAu4)>fRy6Ytu>?s^rNJ*re>w!N2+V#>uJ_u^_Mxv7=(2asY5HX@YPW$f%|h* zDD@X6o{^eYm9!Kvd=_cEtT zDg2^UiG#SjDi^+go#(p}h4a3NAC%(Chq2X`rYt7Qky-c6I~Ehy03Onqxkf#ME}Jq? z?_3g5A1G41KPV3X1dK&^t{DrHNQ;*rb=MBFLp!zbC83g?v^BY+`}#K3Bgyhq zU|J=7Y1JA;2-RAh`t;P?x&WviO%9K#AL7}*$G#8-bl|5!yd-vh+RHbV>S+DK*CzAN z?)=hRv|JhTl@GEhOx~)pZ25ZwA1mPz7_2v_PBqqwoH5HG+ntA`X`u@bn5V}a0e6H} zzzA1t4+q3ia}P5vY%9#E54DXb;8g}F572h7`~(E_Do>KA3Hbb2iA_XvuH5{z!@5N* z)+p2TX1gsQtd7a*D_VJK(zPck|CzmrF)GY2wjj`C{GPD|epM@4F(d_`bS;BD*V2}a zWaQ*+O5(a&JRDohrb(JkhEn%II&*BXU56Exx<)IWW_{n+XW~qqpXCmmOIMbVulkhk z_?Gy-`)8o=&W;21mX$_+rBoBphh$8;M)_Y#VOZEgt1$&oJtD4(*vT}nU-D2>aUBJ& zs4LO=EIJdVLM@i;g|gpeul1!i8y^wIXmE~qYg@=Q;bI14(`58Ldq2(JV|pG1NTc^0 zAa0vog&Eg%SbXD0MfO^>nAZa8hnMg6^sgRFL)R?IR4yP9(~J7yWmAA6U=&{=`T{(C z1j?i)KS1nWMDx?hnnG4Q61t9I@Yrt-kT!e(64Uoi^gx2dfaK<{A0*8B6=DeMis-oi z3&eGs4`O>Da|p)F*5@Jm<3;2fK$tr0fkyVlT`#a)C#sZhQ&`8ybMoVOXCxZY!;`!p zC`fm{VArTQ;5ug6t1ioY0elG(F>OqsE;vz%=9x8y0B<2<7{B?ap=|h$go;1$QEFpf zCJxXMu`j$qDdAeqJtuVJwU!C(}tq3>(4;OG z?H9}W&eOe9XD#To`n4rpkx73GW>ZetNRxae>|?}_r#N6CzJ8QpIMU*uEYj5}Wi4Hn zJ%7Y@bgFvoQ3dMyuKqy^qbdx@bWJ{zP#)X+w)-$C8n1`qCV0jI*!YSMTr0gW5C`Y#k zPeORND$PH}P<08I2LL01_h^xFoxZTgj1(<;L@T1+&}o98MQ@1;Gy+yz{=z;hLqLIW zf#rz^1NW+PsROX-(9hAh;gUHPGUgTv^*&!aJ{Xbp{}pku>G~T?M>)lW^x^j;aTEwN z97@UHq+y>ukt1tS(F7P?L`2w*KJuo<4+BMXX zM2H}&Z+Gx)TZ?|TgSEn{MzS94h(VeYBZMU&xZZGGHQvvQSP-LJdsP} zL03L6GUa9~|GQ59lOLnW(8l*-@wmJ1?fDlb%#?{jk|m=)O_upFo)0iu=n00orhHoM zu2GCwpuwqP6iBkSuO(Sfd_y|~)>nL>YZs@RF~ zRmL?GK*Is7C==2EA_J6f*_0?Ch>EBej4ady1NWC`q39ji9%+?hWZC3Peog@P^yM+^ z5%p1Rz}!cMQO62HOC9qRuKH= z!4`RIa6s9!?i{F>AW1E|sw7n}Y$7iLS-H7{MX)8)D#qUtDTd(qKZbE_9!KIA{hj0D z?9$%#+IIxfDfxa9wotVAmDUb4q$o(En$KT%xNXd|HVZ_gitRBM;grzbe%$~;hx!u3 zblyCtKE?$E+439_bi+Nt{o-(aQ5|bKTLYSc4j|$^D-aY}$V13P7AnRz5j5}@uEp{_ zzF!Q{Tosdl+f(p;6R7o2k6B(v)7{3mZ0wTLy#A#$k}u7Gi5O_dJdXv*m*Ike$8O0OIYi!M@s3A3 zz*tZh52lw!aj;#t)-5&wSlE;u6@dgRngT^4mFkm@uCkX;V+>~IC7w@CQQjB!DCy9Y zce|}k{DBitOEZ#-TEa6U6ccw><;?SgoP3XJgv^YN>;k_&UCIOKjwTC*z5%o2xG9c$ z?ty(oDFdbQHVriBt6s#*+(hj4pB(EQtENfGtOGx2hdfVm?a1H_dPbdv;Ad$()Ula6R^*UOxUSfm}J9RQk51M4bq%#Lo)u&AnG#Y1~d|= zz}pYiFh9t0D`)9y{%Dw12;=lfkj(5M;qzYCuwKQcyhc?@Z`lXogXIFfVxZw?g|VR8 z^MorIW%UP7d1ex+WF@wf{QUx0ijue!k*^7kcGF7>gG$YADM*Q2o>^u)&e^Hsj!;%Z6f%cSaIBu9zAN|sB*pQZ=S2OfN1t2DyxO)pShZ-GlGBt zv{!Elf6(n3fWxQFM+hx!`u!%Tg8McoE|xXEb>2H zP@RvFB6BvPH3uj&S`zMz5zXHt;O4b}_3Od3Fwbu1-QHU6_C1bm18ET!K{|pOc~~3n zO%Sx}VlJb=q*&zrPb=FH&6Y%pN@r)1GZF5Il-iZy&GQhwGo1RCflo5jGEW_I>&Y)< zU*%Ehj-&u3^$_WCHDEe|-%jNXUahtpklsjjg1}Qm-%5WPH_z~rYUkA#(LsR9M_ayzc=HRIz z@W0rnDfT~opVH^_N@79rRUrN9CZC)RL9-A;pq^@9_qiB=C;u~U*^fvZep3vF#6wdA z3(-*y4{0KKW%jw<8RspWtBTEnSj5dJWa{qd=~dg^4|5v)zwZonJOKyxuMT%Pj*J#ey|I%aj+01?c)M7u#k|w9EbHNq2G3o z9G}@oI`T-@m=4p6DTTSPZ87;g+VDc${ssX&g-YpBzKy#LkZeo8muvW(+rkCFxXG%J z2mDt2(!kw%5SK9xgiTd!Xq#7$sLBs!A({#Pr6pRE`IB7FdL;OO3GUUv4G)WA9v;_z z^N)`m`dVuuk4O=`t9^#0s>V$64xCd7TBjo6z!-5vpbI>;qeS(o;75%`5S9+eu7g)1 z6Eh2yUZa1($$va&R;Zaj7y(3nM+9CV@3--=<8!Tw`rOjmy?}K#l&I`{G$qOeoa{vW zu73g+pNCO4{3Ln_io^AMe*=pMEUIFHRq2|?$`oz14n&PH#eKXI$I9-Ijw^C*R}B>u zJV`=Ykii+K1NGzEzwJpXol8HuD$%=^<{Rr{{QjE7vs$@<1xao#-7Uvpt$A~31#ztZ zn|${4xQ+6XYz#?-FTdJ~N)-;o3FjZwchviLPT<^-v7;r$Z?zfkzllYSg4M4SgD~1O zeCZ%j`|EgxvA|EF3%q1GGa1GTV4a$70oYqI(8lb26ED$5eht;*visr*+RS!MfO$H> zfI9sEMwD6tlbNOV3ubBVxev^I%XeOVSvC;s7EA*1@aKM5Rbc~L2r#sRe?sS32RFEI zus2h9jrNeMAY~=D{sBPu8TJ4Luxqj_ytD$o-!l}T>fKWoD?iUH$fUiRbj0wx349Oy zg%8UU-u4v|*?9J4D=9vW>35%hYyX{WA!F_NodGt#rV%-Uwp~z|jxh?+0E!*1I2a`TNY44uI#!bCIZ>EM;JyP) z1k9YYSdEJ%G?66mE<+~niINhWqbJeA1S~%6oggNLJBY^j@0952ZE4_bk1Fj@BPV~r z=>Vb|*Ty^QEqsFkmN=($7y`_z|MRxDy9t6h`f-wqX8&&>PbfhEa#Vm`G4V?nrCaMk zEK>S?j~tg7ufu(h8D6xRj!A!h{!jrOqAAoU1q5u`+GAOHI-Znfp_b6oKcw*vjY%?&5bj|BG+hYk>Ay^GF*KBiErM%B%GMbQL%DPj<@2i z_}C?g6Ifxul-AdSS%)ptBQa?!1g@QZ+y87|IiOIGg6qR>b`OVKz6MpX<`YH#gp$|q zIVBA`Raj=8#h1RuL>dp&zUaZBrj*JzA2WGKPN(;(FK&8`Hz>`L_6XZCeAsk;t2+Oh zDu6jSCXpDmk?z2H9tpsLGZW;e!ba#t>H1SdqkqSLuEuj_4Rtg zF@We>`zZ*Wy(oj7U;qzUHt<K*9-CV9)G!gz8!?UMeh<$eS1mxSw5Bo zbVq%q_|}i|V~C(LH_3!s6tCy#ElH?;ov6VsX;yBQ0P=LKrrvhBuTdy?-K*dPbleuX zrXLgT^2iJP1T614wwk?eTD3&L0vFcbO)^DD8+oU3;Tn3wRKSyX-IFOlh69UIRfDl& z3I5~u4{NBAe-8a%S5l{BSy%5=eG+2AK8|f4k6P4_oD(PMjqM1j0Ph|>JSXX5$U?g%SHW;yUe0O zB>SET6^O2xwsU3w2lQ0_NZuosNie-vcs@Q{r1f9A#EDgff$tHzegMr4Wu10xGiS zQQ@qS#&q`aVbO0RkqXRX+4#A9YF&rHMBnhVjxLMd8AS5kqsb~%TM}-v{ z=U$_PSY#8ib93mT3Auje^w>41?uSi%ih~5DEAdexV&xwSLr7URt39y75KJCBLX7wxbf&Ki@I5Sl zEXg=0LMWx2zL+EKWe3)g##o?yRypo~_s)UjjRhIqn*^{Pt1wF;a?w0$)yEEvq~3`! zAlgUmGGuN2ti02e1ptPVKmI;s$nfh%RthB1|>b~+t>j5fH`;@M#o9Y#C-$_{vk-+xQ?ZYtN|YnFWMwV87Iqy-R8)K zfsq0W=0Sf+ZBPwVFtNorv?5NQ6+U)N4IM+aG{rNts-yvJg1Cm+Ynlbz=;-iF4HX1Zn%(bRiZrp?#VFsG~fh%TWwrU zzq@i}G_zf-guQp+GJoXVRvM!J(LcdZcqo-c_6~U@>7bcg!|p>yhtrqDjJC{gsw;ap zdftENvRlmNsOS?upQ43!+QWi$x26|MS;8I#OSAefuc^Ip|Nq~lyIrDpdBeuaG5F4O zDo#BGvvgxybloi7=PF_cbHAL+@}1dKrtN54&o4i06J}E!$-GYcx7kG6|M{vA`H2{3 zj$>KOHigU0+vhViG5kBpg>Jl2KR=(DG897flk-7mOe-CMl|Hmbs%yuYv(s36tKlyR zx&9!7yVU|}{{3J7NVi2HJe(aeydT7vi0AoQ%HQ(vbc_irD(z?uWI`92cv z=qSS@IXWtts!lVeveNm_4|ZA(qR}}@p_mx$bGH!84-`KtI7GW3a&C_%Bm_r4{#F2A z!?7K)V>SpJTw7OxdkJM>z!{6E?>;xa1@~U#M*%}9DxOune+TESw~mDeS<#!Q4c+G> zFEE`bvFa~H6pBmfZjTl$yx#$#Eu&=RMMO}3ZkHw5CuDESZd0P8b`-E`TWgvEUeZ%j zH{#<|@h4&L2|Zsd0}dA+eF#ba`Qo#I@&)Ua1-Ta0rS-*>FK-0QKP9n)K%95JpH)5z z_$M0RzK<|=;gPfRiMHL7JKCIZR?DbTpQe+?2c zLE8BE402BXD#5Vr&LuL%I+;sVhmVy>2+f-$!FSY(_S-yPUvVY}97k*Zzpl$ig_vl=Q?m%6c!0znh>f)=Z?xco5{KRwl(rsCoUKlOz3 zDG&7!{b14WD*bD;S5<`YbGl6{Lk>RF5#W%)Ng(XZ zHX8~Yp(^BGxa*uj=0gcWBJ~L{V;ZD4<#c%%Xj8$hCI;Roo>hW$kIpH%vEidg12+R?9ECKNi9#^)~=KureQD zcC@2&<;H;*fAA~Qf&(n3H&w;ctFA#M0(9|Fzij6dI4D>+L8h_>%Tw}f=;Z3{YVp_k zE9vlt>4M90rNVi6*o3Y0O%~UN)UpNSG)qGZ+GE&{bIz{p!2@k!0XxU_KHNQ%IG6@6 zsu%&$eyhawkckSj4`rnF?gcTh%o}HL#Re%?I~DTeFZO()<1lj|?P`_6sL9x@F7R^Lt zEH&pk9L=cp3Y5j~%<;3dE|rp6e`IS-_%`nKx##P4A>?Q?41Z9%jBO4tk>kO)4D)EL zDUAwqO}y9@lT{rH1ByNAl1z?|BQv_>R~W46MC^~@KBW*!gj#XHA-Y5LokaU9w-gA; z(UbatmbbJ+V)S-V^{e6j9D2b`SE!dVlB5h-l&)S6%1Zg9ciL4|99=Q4$#h^7Q5vm> zvY6IHE63nQg0m7IeS1K9ZaCcr5kMr{T`f?j_WAP@31JyBHbWqfTOTvS&v_;j8w!_M z+nbjK=SemYmk037TAIp^P${nqn2^}kx?s>+7^tITY z|IFvbd7wPn0g+umlioA}}dVJVnoPRKZ*k>=8=sGiA!rpW_7kHWVgOW03p+ibB{mc{gda4|Ax)ktr zmQtit=RTO_KO)KNEZkqvw9=&wXjBz;A&2Np;S$p%Tu?#eEb3)~Jdn&{a!Nnq3BfKGhSDB_C5L!@XN z6f4GnU^>yae`6O_ps~oYrGh<>odG5j*6{XFdlHdjJIKT$gR0+yMxZV>he5Ejt(gu< zw*HY{h$MTMtPxPg*s)LK6l~K;##9LI==KZL{$(zPh>wnsTsqq}fr<3dr zm40VRVoMs?nDtfPu_n)g2@Tn{WLrvM9oXjw}v+P^m!inqW3#%c3@Do zRzU}F$v!*m)9-DY4rk~CC>B<)S)Pl!6=MP8v3Z8>^ig#gP2UCiqDfoyR@&-vEa~$Y zt2YY&z%po8Yxxu~=TszMi$b%t7SU$HTF{XcRid5eJ0!)R7D|CVM0n0Mx{Zh%9N{*~ zs!W3C3kL=`XX?*^JMf_o&w0mPj(k2{yy-R&U|_2YToy-aL#ixH*O3^#EQ`$S<35=hm+y z)Q$a~eU-iuf;kq?rxHhv6?ZW@e&GR3R54+@7915(nb_ja9LHMt?s_M@*Mz)|qJssg za1(VdNmzH%ODN!Jyai}9)#^Kx>t5uq{Z7R=F-CBKS>@_E?Ua}uvn6@tc>=yd=(V~Z zIyG-#Wj&ucR650THz3yl7mogZQy)0YcY7#u7C~vb=K{=sQl9FQcD0m9`K7TKT+c7C z7aRsg3}>ETG~=2w~g3hLDU)Yu< z>Rl$*n+A8PF)|Hvg`M%={R!Q9VspJ$_EGqbxK!)nok=F(e%;u&@t%xBI(!oSwSUfP zZP6~vc0W0Bux$F9*gAXhf5Ia;ojyv*CaL!sNOO0I8(zA2H67!ue%rk9eC=qpIq(-Uc60p_L)Fhxx$isIQ8( z0BQ4Q(!v2cI2 zDzoOJ-C0VY}Ofi5_W`GZl2|LR{XDFEh zCX7%|a89h!PE6Zy>z3#|&LxO0x8yrH+S-6n_LT6257K$l-KuvY{&aV3y1oQV;R=C) zN>c@gBIs!$vxYLlF)m;o@3$f-?M$D`T5L2-I*-B!fNiPt$*Lk+?mfEH&Pq`$jWN@u z%P-;rvsjN&JIW~y|0J}$H9h+NYCs6EGmr@>o#KYGVQk?@-nX!dDS)C0&n9P!9!`iO zl8P*}N*r8P(731N-F~Y?hf3xEkRyleU7%4D%94Gofpnboq*Faa&!L5^%SUjak5L8* zj$NZItGA&)`u&hsZGxLbbtxPBhFi;sA`2(yWA!QaSTU)SziYid$~3{M+go?{8~+Un(@x4t#3*orgE#XtT-jA= z;p_omcpuA3yLi$dJB4LvWv8g9e8A1!MvGmcx~AXk`2%rf7AV3_;!B-Ox3=PWQ9lTM z+%z=F9b=2X8|PikvP^sVa|<+a$<6uwVt#`X%~)ArE?qcjhrgE_R*c$mg*Jj|3?|KC zog=i2S9rv04{(M^s6;~bdPd_H8DxRqpFtMv$%vFojKm69ZFZx%+1G+2Nu?UQIW5uJ z_``Z@{L$l6ic0fmFa4DlVcgR?inYG;#hDdC+ws3`*jMmKCALz(H0BfvUJvGe0XZvMM$H928nEF z>KxGid(P@Nps$%yAAkpco8qq8uln8L0HOuQAY49NK7J8QaUS;IlXC0=CrgqVi-fH| z;6eD(Ap7l8!EiIx>OD}Q^9cAm9I_Ofh;bBLTo{9p80S3(o<3rZPjnjrWx7TS3@W50 zn)d*gB<9i9fGO)KC}fx{MOF=;Z_b+^qQzr-(JpGdlX(naJq-(GebOSIOqH zD)ciSbvT~J@H+N}vk~+B;tXUx> zZeaFQvc;S?F0 zq*q_zT+$ulpEu{T2zCPP9ROragO9cMmR7THFoVShv!=V>nkwZQpuZkUn8ZzUxCuee z^vwz`XBAiK&0N3vp$)$HnS`bsJEW*MvzsSsfHltnAQe+ou&V(rY6Z@-R1>C8E3QW9 z=1kNKXqoEW*+t7>H7CuVrK~a>&FJ=&+Sah9! z9Drgn#;R8=C8y+J8z1erQU<9vZ05(G zJ=6C63%hPmztmC^Nlj#OC(=_U{ucIbvu!!-X1nZh+(N~E41U{ND|ck+r4*PX_fsu% z8eNBP`)WwYQGZ7FL2?e?6MDl1i^MVuXhM+n=?C1Sr8$u>Yl4A6psuRFtnag#po-6z zKj9oWhT2NttOV)OdKY`B7;%e;v2MBLw?z9VDy?#@;g!la<}Y?rl`7Fn9|P&D?M=h zY~Iv!F+!K!7b#{RyP2qPd}luU*vv398`WteaWH3dr@a4<{1-a`+Mcn(G=Lxu9|$ZQ z_|CPI!KvVx%L>t6jUMVm5=IfnO24Ze0yUp7IR*^h44AR3 z8W3Y&Cl<|r-JU3!5yzuf*Y5~MBTM-{9b(kY$RM377Jb?o~$2whZj_7V|qWN%6F*kF{Jex z7lxACyb{|n_EidPWhL4CBYAv#4i%Izcq+vJHX(VF0|eJ_i9Il^Bd6Ywu0LtK&LC)n z#w8ok5XPzqCFW;c>1&edhK8jv?4`3~qh~`wuu?DELAD!P`(d zZbMMmfMyx!Mtq`oX>wL-muQ^F9}qDsO7Y);s&fLNdS$FWhr6JhvGTc%nDa!Eipafq zdsbbb@gv;32BLaO@o;mrrEI~5hg-IuDF?lh)I@f?A^R~tJV@fy7_9*DAb@6i0nO?Q z?ecCVPSIcc{COt7g^c@C#ga1PaK-tR0s`j&H5IFRl~|A7gsdcjU^Tx4Oj54f!Yd&x(R=qmJ`?Bf0&T^HDth~|tz-%YCnfN# zG&{9$b%T_Pq%+XAR^SN#G3~GBk>>O^t_)&ZKxm?9IXKvuGD(i%jVk_ygS!y027@`m zaEb5oK)+d=ngC+%wRP>SuIs{8JdD(mF4mwW3d%kM#(v3{6>!sRU~v2y(`kNul3B=+ zwo0T-(RDrSX&^Gt52-2s}m2_X?h{`$VR&!68(zQu*uiJI|l)6>F&B7KTb#P_vO~D zVU4d89So%z@i&sFMG4th2yR;$lfBsW?Bxp}ak69S$wg;TqnA4}6m?@sGdw;JL~}TNfEuE+P8P*i_jua}%(uL0ym>=~Q-GOd zoDPh0lnlEUrOht@rH3t+QL0n@uL+c#-kS!DUd>JfelMPZOes7U2}I>NsCIb@?JqgQ9TdGrjTG06Pcmbh|F6DQ`Px`e2DYgIJ8kI zY6RlOGiFeC|NE7c8ipxy-N*s{x8zl%LUJ7pcRaK)l;8Fw6~?6ADCcKw?1#qG|pe*pB(8O)pKUqj1wD> z>8}?I*7>0NJS)){N2X;V*w48O1=|_8jaEmS+%3ioyn%Hl={l};m|6#uZ8A}dW>32@ za!gj23CqVlW%t<@nVWIoUIIoQmmAFMUM@tg87R9$L;2^%80VC@lyxDZ6FSv>gsAI? zp+9}2a>AQ!G?UJVO!hl1G5l(_Iaa3s-krg#TkX96p%Ci=GcHiyPfmPP{KG?oZB%Vo zgTnEqZI<{>u2*P$|c7|A4IL4w3HM?Xop;Aq|MmHRU=L_E6OCea@ zS?F}Pg`@!gNlP93+a=lB(Q;Fo*M>8#3gopzs@_TlvztlDnUqpeV{JM_9lK%k$b+u@ z)08WFbZ=Nz09Q8xM*3y_T?3(#>mLU1zGTaDphf66MdN&1%%EmZ;xmnY#H0wU8=Ux3 zM%#X~Ej}sJ;Qy`kT<_NJu}-DRd6@7LC0~XRQFu zU`i20cPx=%QU+A_pUhK%#Fb=>rcVhokx^f~De{`>p(18V>1toX3+x z@m)W+L7TD(bcrkk`I|CRau=)s|5UDnP=y9>>W9TubgJCnD5fbmpC=Jk?>bM;A-FPOkHXoaCoz2eV zOn-hoA-u4zTVKVYt^4cXsgvmDrS{-z@1ap8>2zQB z5C0zNxUYW^gB5pqcAs9^nvMIgKwAx+9NJ|ldF4^=mn^B9z4m)=MoIJL8ZRqzns&x) zIp#9u03!@4g4w7|*fxz1r22Dvxl@5VR?Dt^ZGw?wfgWJ7 zrRWIEH+{^d`XU67mnD9CgTmmQqN(9JJu&MKI?$9#89v;Yd~Ec|ABFqPN4kqVIGOeJ zH^9z?(N5}1W@D&iBH#}a?=i@MTBRT#B%7F(XM%xG&vGnq#gHAk4n4={Kv1Px>hWUK zZ{eG-)klMVsv#dz*rD4wxhuF&i1PeSG-IvP#S*{X`eaG zA>eE%c|gm*V3jVP!^iq1aM->^%}Y+u!BEa}C;V>zZBFHpDdgP5f!-3?hfYJA zR*G2dCny)!k<|x18{5IAs}=>GYAgX@dO{J5qqF}nq#yT9B}ets<*H0l=I?$?n;*h| z^U{+#1}EBvER)V5<*V=1{{>G>ztf>ADOWY!ccw`uoX8D+mj+-wWZ5`SDsJ=Shpz#$|N%*+$)LNgG+6K#sX!OySqU1%pIaXK5CVOg`vKM~H!%{=2k56RE8 z-CpVM8>AG`#1w$x#!q=J0At?bVl@ZYCas$VI4L0;$P`BXz_pPp7Nxd~RCJEUUWHE! zn8ZAy>Wa~h83LK8m|(ppJhndoK`fjhmu`X~Yo9KBGazzs(50q#6jwxp1~@1&pICbD zsPl0cSQE4`V3c?DE1S+0p4N}weZ&zh()H5_fx}D{H(L$91!Q_neH1Cqzl6kTZ!kS&V{Gum`KvL$8xBvhD}6iOyF0 z<}5Bct>1*b1;Z7nFf4WJ2jlDqAC56LY+?NDLMgX3rQ4)49M0UQgXX0LwA)QpWAT$Z z!Z;Ez`&8_gpX-C>Q8YY>I|H_jPsYgmCbEtXfPiOi;nw+ZAeZiM$>FgPVGkTz_@9Qm z>2vryt{Rt--nbop@#m*9!T3tQoc3c7Ap}=PvJ+u!$jsBneI)M%`N)jweN`_x3KyL<=NhJ$F0QcM)f_Oj)aN7B!Sao}a({l^&(Z+#9o-Pq zpSSJW5@(I;&&l^$kI|(e-{mU`P?Lxy?JPb5FQz$w!ykHy5WP{}7A2DLOu&Kj zLB!nDzuUOl2#h7P#DqUM<~UUYieigzeAhf@uvFQss|hTZv<-_UcedsexZvp*EZ^4h z{}UKymlM%NDH65sHtNS5-p6)Q^Bx@{s$4LNtx>&3V(D*QT^~+DFUa|d@a9*gq5XzT zEZB`#_f0g@3s_p2vm^mVr~mdKS${=yCKg~q>}K$-1NckmM1ijvvW6$`X7ESu?!P%1 zwen`2z*SsT?E4WYmZ^Mcoy^DC(R)}GzK$ni?sakPrMZvp`SsE14KEE)KliE2jy5O< z>;Awa{h2U${DR;v?tr1QQ_3gsxEG@)!*+|>i`(<*kM@FEXbkN&XAMiOv`U3PtMh~V zx14pp8=-z2f#p>KN#cCdA{L~}=Iy51(wyb+*xUHa6jTNB_V0OxMedk|xXKXC77eWq zl>%?15ZWmzcAF!lvu9dNS7W~vbo zxcrbbBzqWPr~k;|-7ku+7tx0Ly@^awiDw8+dy-@n`C zJWT{9jOYkIL%&&gaifk!TRjq7VF5Igr+?)|4Gi!N21DSg{qfhkn+anX$uEuxM!BDW z^}^#XuQ3qL1G{Z}|Dt01;NO(bKa=i2d;*{h`DNp8!}D<@uLB5Xf^Sao&=7UmuH1$ z-4=h@&gMQHVpFS>_AZE5v6#&i7d@*txOC-Sr^v28v{i;ehq9 z&4G0Te{Pf%I5dlAyc!>>ls!nZxh6)KkXe=Wm;df_u=PDab>0dB!Ku*utGJBm?^f@5 zxcKN^954v3%zglpdz)Gc@RlhPw0gIi)ZWp;ZC*&r;gj+Vy*ip`WMZb%zG!rL~s<`8);Igk-3HV;DO;H`5G<47V-fv(bTxp1UDStj1 zpA!{;s<4cAFP4g0%cDTHjb7~mC9d`>wXhRNHh5f;+~#_M+EEx}X<~S`!{zSh5j{N$cTfoyDohl^gC`}y7R=w1=SxEda;!ZUsMTFI<7P*6u z4~HhwcP9?!1R1vAagJQ;^RA_%{U$1am`HVW!EMI_Ov3-bRSx{wq{*(AtcOG}7Mm?T zKk6514f{i$fNN0)a|w4zzLkHfUUQ)A;T>=0deziev8ZFE)Vt_FsEpMxh7BbIf;jw1Gh|O)V)t<-KuUKO(l|kY5vmA(R%aj@t~vHr89T-?7czzbKinfZy+S6=uo*vl3K-sRDoJ zv%~9S+FcOVwfNfuZCQ_m~MF5k!l$`q) ze!!(Gt`=rO-?B6Tp!QF`UTQ7S2^6^(N~IX{0)wQ z2khGngO;ExX#j6u`so+D^glguf@ Date: Sat, 6 Aug 2022 12:05:58 +0200 Subject: [PATCH 0443/1315] ContentTest: replace utf16 with utf8 usage --- test/unit/ContentTest.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp index 39fa72ba25..246680b5c2 100644 --- a/test/unit/ContentTest.cpp +++ b/test/unit/ContentTest.cpp @@ -25,14 +25,14 @@ TEST(ContentTest, Base) Content c; c.switchEncoding(CharacterSet::ISO8859_1); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf16(), L"A\u00E9Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9Z"); } { // set CharacterSet::ISO8859_5 Content c; c.switchEncoding(CharacterSet::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf16(), L"A\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u0449Z"); } { // switch to CharacterSet::ISO8859_5 @@ -42,7 +42,7 @@ TEST(ContentTest, Base) c.switchEncoding(CharacterSet::ISO8859_5); EXPECT_FALSE(c.hasECI); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf16(), L"A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9ZA\u0449Z"); } } @@ -52,7 +52,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::ISO8859_1); - EXPECT_EQ(c.utf16(), L"A\u00E9Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9Z"); EXPECT_EQ(c.bytesECI(), c.bytes); } @@ -60,7 +60,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::Shift_JIS); - EXPECT_EQ(c.utf16(), L"A\u30C6Z"); + EXPECT_EQ(c.utf8(), u8"A\u30C6Z"); } } @@ -72,7 +72,7 @@ TEST(ContentTest, ECI) c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_TRUE(c.hasECI); - EXPECT_EQ(c.utf16(), L"A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\xE9Z\\000007A\xE9Z")); } @@ -81,14 +81,14 @@ TEST(ContentTest, ECI) c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf16(), L"A\u0083\u0065ZA\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u0083\u0065ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\x83\x65Z\\000007A\xE9Z")); } { // double '\' Content c; c.append("C:\\Test"); - EXPECT_EQ(c.utf16(), L"C:\\Test"); + EXPECT_EQ(c.utf8(), u8"C:\\Test"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("C:\\\\Test")); } } From f694f88da494bf0bcc3cbf47d370558c4fd84444 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 6 Aug 2022 12:12:36 +0200 Subject: [PATCH 0444/1315] Content: rename utf16() to utfW() utf16 was misleading as the result is either utf16 or utf32 depending on the platform, i.e. on size_of(wchar_t). --- core/src/Content.cpp | 2 +- core/src/Content.h | 2 +- core/src/DecoderResult.h | 2 +- core/src/Result.cpp | 4 ++-- core/src/Result.h | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 1ffa1db6e7..45d820d1e6 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -155,7 +155,7 @@ std::string Content::text(TextMode mode) const return {}; // silence compiler warning } -std::wstring Content::utf16() const +std::wstring Content::utfW() const { return TextUtfEncoding::FromUtf8(render(false)); } diff --git a/core/src/Content.h b/core/src/Content.h index d7a769ddc4..6b53466da2 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -76,7 +76,7 @@ class Content bool canProcess() const; std::string text(TextMode mode) const; - std::wstring utf16() const; + std::wstring utfW() const; // utf16 or utf32 depending on the platform, i.e. on size_of(wchar_t) std::string utf8() const { return render(false); } ByteArray bytesECI() const; diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index 128f3d1957..c1e328d7f9 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -51,7 +51,7 @@ class DecoderResult Content&& content() && { return std::move(_content); } // to keep the unit tests happy for now: - std::wstring text() const { return _content.utf16(); } + std::wstring text() const { return _content.utfW(); } std::string symbologyIdentifier() const { return _content.symbology.toString(false); } // Simple macro to set up getter/setter methods that save lots of boilerplate. diff --git a/core/src/Result.cpp b/core/src/Result.cpp index f843f89244..b1af0b9d0b 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -61,9 +61,9 @@ std::string Result::utf8() const return _content.utf8(); } -std::wstring Result::utf16() const +std::wstring Result::utfW() const { - return _content.utf16(); + return _content.utfW(); } #if 0 diff --git a/core/src/Result.h b/core/src/Result.h index af8520ddfb..4200760f38 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -35,7 +35,7 @@ class Result * see https://github.com/nu-book/zxing-cpp/issues/338 for a background discussion on the issue. */ std::string utf8() const; - std::wstring utf16() const; + std::wstring utfW() const; public: Result() = default; @@ -66,7 +66,7 @@ class Result std::string text() const { return utf8(); } std::string ecLevel() const { return _ecLevel; } #else - std::wstring text() const { return utf16(); } + std::wstring text() const { return utfW(); } std::wstring ecLevel() const { return {_ecLevel.begin(), _ecLevel.end()}; } #endif From 12e84a1622cf11164afccdbfe9351ad359c48f50 Mon Sep 17 00:00:00 2001 From: axxel Date: Sat, 6 Aug 2022 23:49:58 +0200 Subject: [PATCH 0445/1315] HRI: add `HRIFromISO15434()` and rename GS1.* -> HRI.* --- core/CMakeLists.txt | 4 +-- core/src/Content.cpp | 14 +++++----- core/src/{GS1.cpp => HRI.cpp} | 27 +++++++++++++++++-- core/src/{GS1.h => HRI.h} | 4 ++- core/src/oned/ODDataBarExpandedReader.cpp | 1 - test/unit/GS1Test.cpp | 2 +- .../oned/ODDataBarExpandedBitDecoderTest.cpp | 2 +- 7 files changed, 39 insertions(+), 15 deletions(-) rename core/src/{GS1.cpp => HRI.cpp} (89%) rename core/src/{GS1.h => HRI.h} (56%) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 3b9d9b8b29..91d6147285 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -102,8 +102,8 @@ if (BUILD_READERS) src/GlobalHistogramBinarizer.cpp src/GridSampler.h src/GridSampler.cpp - src/GS1.h - src/GS1.cpp + src/HRI.h + src/HRI.cpp src/HybridBinarizer.h src/HybridBinarizer.cpp src/ImageView.h diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 45d820d1e6..4e27facb8e 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -7,7 +7,7 @@ #include "CharacterSet.h" #include "ECI.h" -#include "GS1.h" +#include "HRI.h" #include "TextDecoder.h" #include "TextUtfEncoding.h" #include "ZXAlgorithms.h" @@ -142,12 +142,12 @@ std::string Content::text(TextMode mode) const case TextMode::Utf8: return render(false); case TextMode::Utf8ECI: return render(true); case TextMode::HRI: - if (symbology.aiFlag == AIFlag::GS1) - return HRIFromGS1(text(TextMode::Utf8)); - else if (type() == ContentType::Text) - return text(TextMode::Utf8); - else - return text(TextMode::Escaped); + switch (type()) { + case ContentType::GS1: return HRIFromGS1(render(false)); + case ContentType::ISO15434: return HRIFromISO15434(render(false)); + case ContentType::Text: return render(false); + default: return text(TextMode::Escaped); + } case TextMode::Hex: return ToHex(bytes); case TextMode::Escaped: return TextUtfEncoding::EscapeNonGraphical(render(false)); } diff --git a/core/src/GS1.cpp b/core/src/HRI.cpp similarity index 89% rename from core/src/GS1.cpp rename to core/src/HRI.cpp index 1b5994abfb..847581c9eb 100644 --- a/core/src/GS1.cpp +++ b/core/src/HRI.cpp @@ -5,10 +5,12 @@ */ // SPDX-License-Identifier: Apache-2.0 -#include "GS1.h" +#include "HRI.h" #include "ZXAlgorithms.h" +#include + namespace ZXing { struct AiInfo @@ -233,7 +235,7 @@ static const AiInfo aiInfos[] = { { "8200", -70 }, }; -std::string HRIFromGS1(const std::string& gs1) +std::string HRIFromGS1(std::string_view gs1) { //TODO: c++20 auto starts_with = [](std::string_view str, std::string_view pre) { return str.substr(0, pre.size()) == pre; }; @@ -281,4 +283,25 @@ std::string HRIFromGS1(const std::string& gs1) return res; } +std::string HRIFromISO15434(std::string_view str) +{ + // Use available unicode symbols to simulate sub- and superscript letters as specified in + // ISO/IEC 15434:2019(E) 6. Human readable representation + + std::ostringstream oss; + + for (char c : str) { + switch (c) { + case 4: oss << u8"\u1d31\u1d52\u209c"; break; // EOT + case 28: oss << u8"\ua7f3\u209b"; break; // FS + case 29: oss << u8"\u1d33\u209b"; break; // GS + case 30: oss << u8"\u1d3f\u209b"; break; // RS + case 31: oss << u8"\u1d41\u209b"; break; // US + default: oss << c; + } + } + + return oss.str(); +} + } // namespace ZXing diff --git a/core/src/GS1.h b/core/src/HRI.h similarity index 56% rename from core/src/GS1.h rename to core/src/HRI.h index 50b579a8a9..0929af0c02 100644 --- a/core/src/GS1.h +++ b/core/src/HRI.h @@ -6,9 +6,11 @@ #pragma once #include +#include namespace ZXing { -std::string HRIFromGS1(const std::string& gs1); +std::string HRIFromGS1(std::string_view gs1); +std::string HRIFromISO15434(std::string_view str); } // namespace ZXing diff --git a/core/src/oned/ODDataBarExpandedReader.cpp b/core/src/oned/ODDataBarExpandedReader.cpp index 653d2f974d..eadb2d2d15 100644 --- a/core/src/oned/ODDataBarExpandedReader.cpp +++ b/core/src/oned/ODDataBarExpandedReader.cpp @@ -9,7 +9,6 @@ #include "BarcodeFormat.h" #include "DecoderResult.h" -#include "GS1.h" #include "ODDataBarCommon.h" #include "ODDataBarExpandedBitDecoder.h" #include "Result.h" diff --git a/test/unit/GS1Test.cpp b/test/unit/GS1Test.cpp index 122e09228a..063ee182ec 100644 --- a/test/unit/GS1Test.cpp +++ b/test/unit/GS1Test.cpp @@ -3,7 +3,7 @@ */ // SPDX-License-Identifier: Apache-2.0 -#include "GS1.h" +#include "HRI.h" #include "gtest/gtest.h" diff --git a/test/unit/oned/ODDataBarExpandedBitDecoderTest.cpp b/test/unit/oned/ODDataBarExpandedBitDecoderTest.cpp index 27e6902a63..d4391f5432 100644 --- a/test/unit/oned/ODDataBarExpandedBitDecoderTest.cpp +++ b/test/unit/oned/ODDataBarExpandedBitDecoderTest.cpp @@ -5,7 +5,7 @@ #include "BitArray.h" #include "BitArrayUtility.h" -#include "GS1.h" +#include "HRI.h" #include "oned/ODDataBarExpandedBitDecoder.h" #include "gtest/gtest.h" From 1cb7121ec5714c3b3c62fc1a1a0ed09f55324055 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 7 Aug 2022 00:52:10 +0200 Subject: [PATCH 0446/1315] TextUtfEncoding: use string_view as iteration device --- core/src/TextUtfEncoding.cpp | 46 +++++++++++++++--------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index 7d0c2ce735..69e1e7dca8 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -56,22 +56,14 @@ inline uint32_t Utf8Decode(char8_t byte, uint32_t& state, uint32_t& codep) static_assert(sizeof(wchar_t) == 4 || sizeof(wchar_t) == 2, "wchar_t needs to be 2 or 4 bytes wide"); -template -bool IsUtf16HighSurrogate(T c) +inline bool IsUtf16SurrogatePair(std::wstring_view str) { - return (c & 0xfc00) == 0xd800; + return sizeof(wchar_t) == 2 && str.size() >= 2 && (str[0] & 0xfc00) == 0xd800 && (str[1] & 0xfc00) == 0xdc00; } -template -bool IsUtf16LowSurrogate(T c) +inline uint32_t Utf32FromUtf16Surrogates(std::wstring_view str) { - return (c & 0xfc00) == 0xdc00; -} - -template -uint32_t Utf32FromUtf16Surrogates(T high, T low) -{ - return (uint32_t(high) << 10) + low - 0x35fdc00; + return (static_cast(str[0]) << 10) + str[1] - 0x35fdc00; } static size_t Utf8CountCodePoints(utf8_t utf8) @@ -131,20 +123,20 @@ std::wstring FromUtf8(std::string_view utf8) static size_t Utf8CountBytes(std::wstring_view str) { int result = 0; - for (size_t i = 0; i < str.size(); ++i) { - if (str[i] < 0x80) + for (; str.size(); str.remove_prefix(1)) { + if (str.front() < 0x80) result += 1; - else if (str[i] < 0x800) + else if (str.front() < 0x800) result += 2; else if (sizeof(wchar_t) == 4) { - if (str[i] < 0x10000) + if (str.front() < 0x10000) result += 3; else result += 4; } else { - if (IsUtf16HighSurrogate(str[i])) { + if (IsUtf16SurrogatePair(str)) { result += 4; - ++i; + str.remove_prefix(1); } else result += 3; } @@ -183,14 +175,14 @@ static void AppendToUtf8(std::wstring_view str, std::string& utf8) utf8.reserve(utf8.size() + Utf8CountBytes(str)); char buffer[4]; - for (size_t i = 0; i < str.size(); ++i) + for (; str.size(); str.remove_prefix(1)) { uint32_t cp; - if (sizeof(wchar_t) == 2 && i + 1 < str.size() && IsUtf16HighSurrogate(str[i]) && IsUtf16LowSurrogate(str[i + 1])) { - cp = Utf32FromUtf16Surrogates(str[i], str[i + 1]); - ++i; + if (IsUtf16SurrogatePair(str)) { + cp = Utf32FromUtf16Surrogates(str); + str.remove_prefix(1); } else - cp = str[i]; + cp = str.front(); auto bufLength = Utf32ToUtf8(cp, buffer); utf8.append(buffer, bufLength); @@ -225,14 +217,14 @@ std::wstring EscapeNonGraphical(std::wstring_view str) std::wostringstream ws; ws.fill(L'0'); - for (size_t i = 0; i < str.size(); i++) { - wchar_t wc = str[i]; + for (; str.size(); str.remove_prefix(1)) { + wchar_t wc = str.front(); if (wc < 32 || wc == 127) // Non-graphical ASCII, excluding space ws << "<" << ascii_nongraphs[wc == 127 ? 32 : wc] << ">"; else if (wc < 128) // ASCII ws << wc; - else if (sizeof(wchar_t) == 2 && i + 1 < str.size() && IsUtf16HighSurrogate(wc) && IsUtf16LowSurrogate(str[i + 1])) - ws.write(str.data() + i++, 2); + else if (IsUtf16SurrogatePair(str)) + ws.write(str.data(), 2), str.remove_prefix(1); else if ((wc < 0xd800 || wc >= 0xe000) && (std::isgraph(wc, utf8Loc) && wc != 0xA0 && wc != 0x2007 && wc != 0xfffd)) // Exclude unpaired surrogates and NO-BREAK spaces NBSP and NUMSP ws << wc; From f10d4d4b74a0a4fa8a2cb058e6bba3921b671f7e Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 7 Aug 2022 00:53:35 +0200 Subject: [PATCH 0447/1315] android: add ' ' after ':' in result text for better line breaks --- .../app/src/main/java/com/example/zxingcppdemo/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt index 82cf02fd9e..26dd246e15 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt @@ -166,7 +166,7 @@ class MainActivity : AppCompatActivity() { p.toPointF() } } - (result?.let { "${it.format} (${it.contentType}):" + + (result?.let { "${it.format} (${it.contentType}): " + "${if (it.contentType != BarcodeReader.ContentType.BINARY) it.text else it.bytes!!.joinToString(separator = "") { v -> "%02x".format(v) }}" } ?: "") } catch (e: Throwable) { From f187e3e6fba80ea0ee97713aa3c165a26b30e062 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 7 Aug 2022 12:25:59 +0200 Subject: [PATCH 0448/1315] TextUtfEncodingTesttest: don't use wstring version of EscapeNonGraphical --- test/unit/TextUtfEncodingTest.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index cfb9f86951..1650ef2714 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -12,19 +12,16 @@ TEST(TextUtfEncodingTest, EscapeNonGraphical) { using namespace ZXing::TextUtfEncoding; - auto escape = [](const wchar_t* str) { return ToUtf8(EscapeNonGraphical(str)); }; - EXPECT_EQ(escape(L"\u00B6\u0416"), "¶Ж"); - EXPECT_EQ(escape(L"\x01\x1F\x7F"), ""); - EXPECT_EQ(escape(L"\x80\x9F"), ""); - EXPECT_EQ(escape(L"\xA0"), ""); // NO-BREAK space (nbsp) - EXPECT_EQ(escape(L"\x2007"), ""); // NO-BREAK space (numsp) - EXPECT_EQ(escape(L"\xFFEF"), ""); // Was NO-BREAK space but now isn't (BOM) - EXPECT_EQ(escape(L"\u2000"), ""); // Space char (nqsp) - EXPECT_EQ(escape(L"\uFFFD"), ""); - EXPECT_EQ(escape(L"\uFFFF"), ""); - EXPECT_EQ(escape(L"\xD800Z"), "Z"); // Unpaired high surrogate - EXPECT_EQ(escape(L"A\xDC00"), "A"); // Unpaired low surrogate + EXPECT_EQ(EscapeNonGraphical(u8"\u00B6\u0416"), "¶Ж"); + EXPECT_EQ(EscapeNonGraphical(u8"\x01\x1F\x7F"), ""); + EXPECT_EQ(EscapeNonGraphical(u8"\u0080\u009F"), ""); + EXPECT_EQ(EscapeNonGraphical(u8"\u00A0"), ""); // NO-BREAK space (nbsp) + EXPECT_EQ(EscapeNonGraphical(u8"\u2007"), ""); // NO-BREAK space (numsp) + EXPECT_EQ(EscapeNonGraphical(u8"\uFFEF"), ""); // Was NO-BREAK space but now isn't (BOM) + EXPECT_EQ(EscapeNonGraphical(u8"\u2000"), ""); // Space char (nqsp) + EXPECT_EQ(EscapeNonGraphical(u8"\uFFFD"), ""); + EXPECT_EQ(EscapeNonGraphical(u8"\uFFFF"), ""); } TEST(TextUtfEncodingTest, FromUtf8) From 20e3e1bee53e5a1f6248cd3ac1231058985ec013 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 7 Aug 2022 17:02:57 +0200 Subject: [PATCH 0449/1315] TextUtfEncoding: more type related code cosmetic char32_t is the correct type to store a utf32 code point since c++11. --- core/src/TextUtfEncoding.cpp | 41 ++++++++++++++++++----------------- test/unit/TextDecoderTest.cpp | 4 ++-- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index 69e1e7dca8..505830c640 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -20,14 +20,15 @@ namespace ZXing::TextUtfEncoding { using char8_t = uint8_t; using utf8_t = std::basic_string_view; -constexpr uint32_t kAccepted = 0; -constexpr uint32_t kRejected [[maybe_unused]] = 12; +using state_t = uint8_t; +constexpr state_t kAccepted = 0; +constexpr state_t kRejected [[maybe_unused]] = 12; -inline uint32_t Utf8Decode(char8_t byte, uint32_t& state, uint32_t& codep) +inline char32_t Utf8Decode(char8_t byte, state_t& state, char32_t& codep) { // Copyright (c) 2008-2009 Bjoern Hoehrmann // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. - static const uint8_t kUtf8Data[] = { + static constexpr const state_t kUtf8Data[] = { /* The first part of the table maps bytes to character classes that * reduce the size of the transition table and create bitmasks. */ 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,0, @@ -48,7 +49,7 @@ inline uint32_t Utf8Decode(char8_t byte, uint32_t& state, uint32_t& codep) 12,36,12,12,12,12,12,12,12,12,12,12, }; - uint32_t type = kUtf8Data[byte]; + state_t type = kUtf8Data[byte]; codep = (state != kAccepted) ? (byte & 0x3fu) | (codep << 6) : (0xff >> type) & (byte); state = kUtf8Data[256 + state + type]; return state; @@ -61,9 +62,9 @@ inline bool IsUtf16SurrogatePair(std::wstring_view str) return sizeof(wchar_t) == 2 && str.size() >= 2 && (str[0] & 0xfc00) == 0xd800 && (str[1] & 0xfc00) == 0xdc00; } -inline uint32_t Utf32FromUtf16Surrogates(std::wstring_view str) +inline char32_t Utf32FromUtf16Surrogates(std::wstring_view str) { - return (static_cast(str[0]) << 10) + str[1] - 0x35fdc00; + return (static_cast(str[0]) << 10) + str[1] - 0x35fdc00; } static size_t Utf8CountCodePoints(utf8_t utf8) @@ -96,8 +97,8 @@ static void AppendFromUtf8(utf8_t utf8, std::wstring& buffer) { buffer.reserve(buffer.size() + Utf8CountCodePoints(utf8)); - uint32_t codePoint = 0; - uint32_t state = kAccepted; + char32_t codePoint = 0; + state_t state = kAccepted; for (auto b : utf8) { if (Utf8Decode(b, state, codePoint) != kAccepted) @@ -145,28 +146,28 @@ static size_t Utf8CountBytes(std::wstring_view str) } ZXING_EXPORT_TEST_ONLY -int Utf32ToUtf8(uint32_t utf32, char* out) +int Utf32ToUtf8(char32_t utf32, char* out) { if (utf32 < 0x80) { - *out++ = static_cast(utf32); + *out++ = narrow_cast(utf32); return 1; } if (utf32 < 0x800) { - *out++ = narrow_cast((utf32 >> 6) | 0xc0); - *out++ = narrow_cast((utf32 & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 >> 6) | 0xc0); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); return 2; } if (utf32 < 0x10000) { - *out++ = narrow_cast((utf32 >> 12) | 0xe0); - *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); - *out++ = narrow_cast((utf32 & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 >> 12) | 0xe0); + *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); return 3; } - *out++ = narrow_cast((utf32 >> 18) | 0xf0); - *out++ = narrow_cast(((utf32 >> 12) & 0x3f) | 0x80); - *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); - *out++ = narrow_cast((utf32 & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 >> 18) | 0xf0); + *out++ = narrow_cast(((utf32 >> 12) & 0x3f) | 0x80); + *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); return 4; } diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index 25cabf4a24..0fcbd9636a 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -15,11 +15,11 @@ using namespace ZXing::TextUtfEncoding; using namespace testing; namespace ZXing::TextUtfEncoding { -int Utf32ToUtf8(uint32_t utf32, char* out); +int Utf32ToUtf8(char32_t utf32, char* out); } // Encode Unicode codepoint `utf32` as UTF-8 -std::string Utf32ToUtf8(const uint32_t utf32) +std::string Utf32ToUtf8(const char32_t utf32) { char buf[4]; int len = Utf32ToUtf8(utf32, buf); From 4202b257ec2c3540b8549dec57c8b8ff7e0fb060 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 7 Aug 2022 18:13:11 +0200 Subject: [PATCH 0450/1315] TextUtfEncoding: deprecate this header and namespace altogether With the introduction of the utf8 based return value of `Result::text()` we don't need those helpers in the public API anymore. Move `FromUtf8` and `ToUtf8` into the `ZXing` namespace into the unpublished `Utf.h` header. Note: this commit breaks the current ZXingReader.cpp. Will fix in later commit (too much work went into cherry picking those changed lines, here). --- core/CMakeLists.txt | 8 +- core/src/Content.cpp | 6 +- core/src/GTIN.cpp | 1 - core/src/MultiFormatWriter.cpp | 4 +- core/src/Result.cpp | 1 - core/src/TextDecoder.cpp | 4 +- core/src/TextEncoder.cpp | 4 +- core/src/TextUtfEncoding.cpp | 226 +---------------- core/src/TextUtfEncoding.h | 9 +- core/src/Utf.cpp | 239 ++++++++++++++++++ core/src/Utf.h | 19 ++ core/src/aztec/AZWriter.cpp | 4 +- core/src/datamatrix/DMWriter.cpp | 4 +- core/src/oned/ODCodabarWriter.cpp | 4 +- core/src/oned/ODCode128Writer.cpp | 4 +- core/src/oned/ODCode39Writer.cpp | 4 +- core/src/oned/ODCode93Writer.cpp | 4 +- core/src/oned/ODEAN13Writer.cpp | 4 +- core/src/oned/ODEAN8Writer.cpp | 4 +- core/src/oned/ODITFWriter.cpp | 4 +- core/src/oned/ODUPCAWriter.cpp | 4 +- core/src/oned/ODUPCEWriter.cpp | 4 +- core/src/pdf417/PDFDecodedBitStreamParser.cpp | 1 - core/src/pdf417/PDFWriter.cpp | 4 +- core/src/qrcode/QRWriter.cpp | 4 +- example/ZXingReader.cpp | 1 - example/ZXingWriter.cpp | 3 +- test/unit/TextDecoderTest.cpp | 5 +- test/unit/TextUtfEncodingTest.cpp | 8 +- test/unit/aztec/AZDetectorTest.cpp | 4 +- test/unit/qrcode/QREncoderTest.cpp | 4 +- .../zxingcpp/src/main/cpp/JNIUtils.cpp | 4 +- wrappers/winrt/BarcodeReader.cpp | 6 +- 33 files changed, 322 insertions(+), 287 deletions(-) create mode 100644 core/src/Utf.cpp create mode 100644 core/src/Utf.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 91d6147285..4faa13d7e3 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -75,9 +75,11 @@ set (COMMON_FILES src/Range.h src/RegressionLine.h src/Scope.h - src/TextUtfEncoding.h - src/TextUtfEncoding.cpp + src/TextUtfEncoding.h # [[deprecated]] + src/TextUtfEncoding.cpp # [[deprecated]] src/TritMatrix.h + src/Utf.h + src/Utf.cpp src/ZXAlgorithms.h src/ZXBigInteger.h src/ZXBigInteger.cpp @@ -148,7 +150,7 @@ set (PUBLIC_HEADERS src/CharacterSet.h src/Flags.h src/GTIN.h - src/TextUtfEncoding.h + src/TextUtfEncoding.h # [[deprecated]] src/ZXAlgorithms.h src/ZXConfig.h ) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 4e27facb8e..bb1cd65577 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -9,7 +9,7 @@ #include "ECI.h" #include "HRI.h" #include "TextDecoder.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "ZXAlgorithms.h" namespace ZXing { @@ -149,7 +149,7 @@ std::string Content::text(TextMode mode) const default: return text(TextMode::Escaped); } case TextMode::Hex: return ToHex(bytes); - case TextMode::Escaped: return TextUtfEncoding::EscapeNonGraphical(render(false)); + case TextMode::Escaped: return EscapeNonGraphical(render(false)); } return {}; // silence compiler warning @@ -157,7 +157,7 @@ std::string Content::text(TextMode mode) const std::wstring Content::utfW() const { - return TextUtfEncoding::FromUtf8(render(false)); + return FromUtf8(render(false)); } ByteArray Content::bytesECI() const diff --git a/core/src/GTIN.cpp b/core/src/GTIN.cpp index 252393dcbb..256855a030 100644 --- a/core/src/GTIN.cpp +++ b/core/src/GTIN.cpp @@ -7,7 +7,6 @@ #include "GTIN.h" #include "Result.h" -#include "TextUtfEncoding.h" #include #include diff --git a/core/src/MultiFormatWriter.cpp b/core/src/MultiFormatWriter.cpp index 5a03a6a4b3..b278d848dd 100644 --- a/core/src/MultiFormatWriter.cpp +++ b/core/src/MultiFormatWriter.cpp @@ -20,7 +20,7 @@ #include "pdf417/PDFWriter.h" #include "qrcode/QRErrorCorrectionLevel.h" #include "qrcode/QRWriter.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include @@ -69,7 +69,7 @@ MultiFormatWriter::encode(const std::wstring& contents, int width, int height) c BitMatrix MultiFormatWriter::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // ZXing diff --git a/core/src/Result.cpp b/core/src/Result.cpp index b1af0b9d0b..4574fae91d 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -8,7 +8,6 @@ #include "DecoderResult.h" #include "TextDecoder.h" -#include "TextUtfEncoding.h" #include "ZXAlgorithms.h" #include diff --git a/core/src/TextDecoder.cpp b/core/src/TextDecoder.cpp index 4880940a7b..613602ca62 100644 --- a/core/src/TextDecoder.cpp +++ b/core/src/TextDecoder.cpp @@ -8,7 +8,7 @@ #include "CharacterSet.h" #include "ECI.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "ZXAlgorithms.h" #include "zueci.h" @@ -48,7 +48,7 @@ void TextDecoder::Append(std::wstring& str, const uint8_t* bytes, size_t length, { std::string u8str; Append(u8str, bytes, length, charset); - str.append(TextUtfEncoding::FromUtf8(u8str)); + str.append(FromUtf8(u8str)); } /** diff --git a/core/src/TextEncoder.cpp b/core/src/TextEncoder.cpp index 246b0a4a4b..13fe153fc6 100644 --- a/core/src/TextEncoder.cpp +++ b/core/src/TextEncoder.cpp @@ -7,7 +7,7 @@ #include "CharacterSet.h" #include "ECI.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "ZXAlgorithms.h" #include "zueci.h" @@ -44,7 +44,7 @@ void TextEncoder::GetBytes(const std::string& str, CharacterSet charset, std::st void TextEncoder::GetBytes(const std::wstring& str, CharacterSet charset, std::string& bytes) { - GetBytes(TextUtfEncoding::ToUtf8(str), charset, bytes); + GetBytes(ToUtf8(str), charset, bytes); } } // ZXing diff --git a/core/src/TextUtfEncoding.cpp b/core/src/TextUtfEncoding.cpp index 505830c640..7c366371ad 100644 --- a/core/src/TextUtfEncoding.cpp +++ b/core/src/TextUtfEncoding.cpp @@ -1,244 +1,28 @@ /* -* Copyright 2016 Nu-book Inc. -* Copyright 2021 gitlost * Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 #include "TextUtfEncoding.h" -#include "ZXTestSupport.h" -#include "ZXAlgorithms.h" - -#include -#include -#include +#include "Utf.h" namespace ZXing::TextUtfEncoding { -// TODO: c++20 has char8_t -using char8_t = uint8_t; -using utf8_t = std::basic_string_view; - -using state_t = uint8_t; -constexpr state_t kAccepted = 0; -constexpr state_t kRejected [[maybe_unused]] = 12; - -inline char32_t Utf8Decode(char8_t byte, state_t& state, char32_t& codep) -{ - // Copyright (c) 2008-2009 Bjoern Hoehrmann - // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. - static constexpr const state_t kUtf8Data[] = { - /* The first part of the table maps bytes to character classes that - * reduce the size of the transition table and create bitmasks. */ - 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,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,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,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,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, - - /* The second part is a transition table that maps a combination - * of a state of the automaton and a character class to a state. */ - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, - 12,36,12,12,12,12,12,12,12,12,12,12, - }; - - state_t type = kUtf8Data[byte]; - codep = (state != kAccepted) ? (byte & 0x3fu) | (codep << 6) : (0xff >> type) & (byte); - state = kUtf8Data[256 + state + type]; - return state; -} - -static_assert(sizeof(wchar_t) == 4 || sizeof(wchar_t) == 2, "wchar_t needs to be 2 or 4 bytes wide"); - -inline bool IsUtf16SurrogatePair(std::wstring_view str) -{ - return sizeof(wchar_t) == 2 && str.size() >= 2 && (str[0] & 0xfc00) == 0xd800 && (str[1] & 0xfc00) == 0xdc00; -} - -inline char32_t Utf32FromUtf16Surrogates(std::wstring_view str) -{ - return (static_cast(str[0]) << 10) + str[1] - 0x35fdc00; -} - -static size_t Utf8CountCodePoints(utf8_t utf8) -{ - size_t count = 0; - - for (size_t i = 0; i < utf8.size();) { - if (utf8[i] < 128) { - ++i; - } else { - switch (utf8[i] & 0xf0) { - case 0xc0: [[fallthrough]]; - case 0xd0: i += 2; break; - case 0xe0: i += 3; break; - case 0xf0: i += 4; break; - default: // we are in middle of a sequence - ++i; - while (i < utf8.size() && (utf8[i] & 0xc0) == 0x80) - ++i; - break; - } - } - ++count; - } - - return count; -} - -static void AppendFromUtf8(utf8_t utf8, std::wstring& buffer) -{ - buffer.reserve(buffer.size() + Utf8CountCodePoints(utf8)); - - char32_t codePoint = 0; - state_t state = kAccepted; - - for (auto b : utf8) { - if (Utf8Decode(b, state, codePoint) != kAccepted) - continue; - - if (sizeof(wchar_t) == 2 && codePoint > 0xffff) { // surrogate pair - buffer.push_back(narrow_cast(0xd7c0 + (codePoint >> 10))); - buffer.push_back(narrow_cast(0xdc00 + (codePoint & 0x3ff))); - } else { - buffer.push_back(narrow_cast(codePoint)); - } - } -} - -std::wstring FromUtf8(std::string_view utf8) -{ - std::wstring str; - AppendFromUtf8({reinterpret_cast(utf8.data()), utf8.size()}, str); - return str; -} - -// Count the number of bytes required to store given code points in UTF-8. -static size_t Utf8CountBytes(std::wstring_view str) -{ - int result = 0; - for (; str.size(); str.remove_prefix(1)) { - if (str.front() < 0x80) - result += 1; - else if (str.front() < 0x800) - result += 2; - else if (sizeof(wchar_t) == 4) { - if (str.front() < 0x10000) - result += 3; - else - result += 4; - } else { - if (IsUtf16SurrogatePair(str)) { - result += 4; - str.remove_prefix(1); - } else - result += 3; - } - } - return result; -} - -ZXING_EXPORT_TEST_ONLY -int Utf32ToUtf8(char32_t utf32, char* out) -{ - if (utf32 < 0x80) { - *out++ = narrow_cast(utf32); - return 1; - } - if (utf32 < 0x800) { - *out++ = narrow_cast((utf32 >> 6) | 0xc0); - *out++ = narrow_cast((utf32 & 0x3f) | 0x80); - return 2; - } - if (utf32 < 0x10000) { - *out++ = narrow_cast((utf32 >> 12) | 0xe0); - *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); - *out++ = narrow_cast((utf32 & 0x3f) | 0x80); - return 3; - } - - *out++ = narrow_cast((utf32 >> 18) | 0xf0); - *out++ = narrow_cast(((utf32 >> 12) & 0x3f) | 0x80); - *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); - *out++ = narrow_cast((utf32 & 0x3f) | 0x80); - return 4; -} - -static void AppendToUtf8(std::wstring_view str, std::string& utf8) -{ - utf8.reserve(utf8.size() + Utf8CountBytes(str)); - - char buffer[4]; - for (; str.size(); str.remove_prefix(1)) - { - uint32_t cp; - if (IsUtf16SurrogatePair(str)) { - cp = Utf32FromUtf16Surrogates(str); - str.remove_prefix(1); - } else - cp = str.front(); - - auto bufLength = Utf32ToUtf8(cp, buffer); - utf8.append(buffer, bufLength); - } -} - std::string ToUtf8(std::wstring_view str) { - std::string utf8; - AppendToUtf8(str, utf8); - return utf8; + return ZXing::ToUtf8(str); } // Same as `ToUtf8()` above, except if angleEscape set, places non-graphical characters in angle brackets with text name std::string ToUtf8(std::wstring_view str, const bool angleEscape) { - return ToUtf8(angleEscape ? EscapeNonGraphical(str) : str); -} - -std::wstring EscapeNonGraphical(std::wstring_view str) -{ - static const char* const ascii_nongraphs[33] = { - "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", - "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", - "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", - "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", - "DEL", - }; - - std::locale utf8Loc("en_US.UTF-8"); - - std::wostringstream ws; - ws.fill(L'0'); - - for (; str.size(); str.remove_prefix(1)) { - wchar_t wc = str.front(); - if (wc < 32 || wc == 127) // Non-graphical ASCII, excluding space - ws << "<" << ascii_nongraphs[wc == 127 ? 32 : wc] << ">"; - else if (wc < 128) // ASCII - ws << wc; - else if (IsUtf16SurrogatePair(str)) - ws.write(str.data(), 2), str.remove_prefix(1); - else if ((wc < 0xd800 || wc >= 0xe000) && (std::isgraph(wc, utf8Loc) && wc != 0xA0 && wc != 0x2007 && - wc != 0xfffd)) // Exclude unpaired surrogates and NO-BREAK spaces NBSP and NUMSP - ws << wc; - else // Non-graphical Unicode - ws << "(wc) << ">"; - } - - return ws.str(); + return ZXing::ToUtf8(angleEscape ? EscapeNonGraphical(str) : str); } -std::string EscapeNonGraphical(std::string_view utf8) +std::wstring FromUtf8(std::string_view utf8) { - return ToUtf8(EscapeNonGraphical(FromUtf8(utf8))); + return ZXing::FromUtf8(utf8); } } // namespace ZXing::TextUtfEncoding diff --git a/core/src/TextUtfEncoding.h b/core/src/TextUtfEncoding.h index 2d6477de70..a1940f047b 100644 --- a/core/src/TextUtfEncoding.h +++ b/core/src/TextUtfEncoding.h @@ -10,11 +10,10 @@ namespace ZXing::TextUtfEncoding { -std::string ToUtf8(std::wstring_view str); -[[deprecated]] std::string ToUtf8(std::wstring_view str, const bool angleEscape); -std::wstring FromUtf8(std::string_view utf8); +// The following functions are not required anymore after Result::text() now returns utf8 natively and the encoders accept utf8 as well. -std::wstring EscapeNonGraphical(std::wstring_view str); -std::string EscapeNonGraphical(std::string_view utf8); +[[deprecated]] std::string ToUtf8(std::wstring_view str); +[[deprecated]] std::string ToUtf8(std::wstring_view str, const bool angleEscape); +[[deprecated]] std::wstring FromUtf8(std::string_view utf8); } // namespace ZXing::TextUtfEncoding diff --git a/core/src/Utf.cpp b/core/src/Utf.cpp new file mode 100644 index 0000000000..ed5dc972ef --- /dev/null +++ b/core/src/Utf.cpp @@ -0,0 +1,239 @@ +/* +* Copyright 2016 Nu-book Inc. +* Copyright 2021 gitlost +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "Utf.h" + +#include "ZXTestSupport.h" +#include "ZXAlgorithms.h" + +#include +#include +#include +#include + +namespace ZXing { + +// TODO: c++20 has char8_t +using char8_t = uint8_t; +using utf8_t = std::basic_string_view; + +using state_t = uint8_t; +constexpr state_t kAccepted = 0; +constexpr state_t kRejected [[maybe_unused]] = 12; + +inline char32_t Utf8Decode(char8_t byte, state_t& state, char32_t& codep) +{ + // Copyright (c) 2008-2009 Bjoern Hoehrmann + // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + static constexpr const state_t kUtf8Data[] = { + /* The first part of the table maps bytes to character classes that + * reduce the size of the transition table and create bitmasks. */ + 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,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,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,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,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + + /* The second part is a transition table that maps a combination + * of a state of the automaton and a character class to a state. */ + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, + 12,36,12,12,12,12,12,12,12,12,12,12, + }; + + state_t type = kUtf8Data[byte]; + codep = (state != kAccepted) ? (byte & 0x3fu) | (codep << 6) : (0xff >> type) & (byte); + state = kUtf8Data[256 + state + type]; + return state; +} + +static_assert(sizeof(wchar_t) == 4 || sizeof(wchar_t) == 2, "wchar_t needs to be 2 or 4 bytes wide"); + +inline bool IsUtf16SurrogatePair(std::wstring_view str) +{ + return sizeof(wchar_t) == 2 && str.size() >= 2 && (str[0] & 0xfc00) == 0xd800 && (str[1] & 0xfc00) == 0xdc00; +} + +inline char32_t Utf32FromUtf16Surrogates(std::wstring_view str) +{ + return (static_cast(str[0]) << 10) + str[1] - 0x35fdc00; +} + +static size_t Utf8CountCodePoints(utf8_t utf8) +{ + size_t count = 0; + + for (size_t i = 0; i < utf8.size();) { + if (utf8[i] < 128) { + ++i; + } else { + switch (utf8[i] & 0xf0) { + case 0xc0: [[fallthrough]]; + case 0xd0: i += 2; break; + case 0xe0: i += 3; break; + case 0xf0: i += 4; break; + default: // we are in middle of a sequence + ++i; + while (i < utf8.size() && (utf8[i] & 0xc0) == 0x80) + ++i; + break; + } + } + ++count; + } + + return count; +} + +static void AppendFromUtf8(utf8_t utf8, std::wstring& buffer) +{ + buffer.reserve(buffer.size() + Utf8CountCodePoints(utf8)); + + char32_t codePoint = 0; + state_t state = kAccepted; + + for (auto b : utf8) { + if (Utf8Decode(b, state, codePoint) != kAccepted) + continue; + + if (sizeof(wchar_t) == 2 && codePoint > 0xffff) { // surrogate pair + buffer.push_back(narrow_cast(0xd7c0 + (codePoint >> 10))); + buffer.push_back(narrow_cast(0xdc00 + (codePoint & 0x3ff))); + } else { + buffer.push_back(narrow_cast(codePoint)); + } + } +} + +std::wstring FromUtf8(std::string_view utf8) +{ + std::wstring str; + AppendFromUtf8({reinterpret_cast(utf8.data()), utf8.size()}, str); + return str; +} + +// Count the number of bytes required to store given code points in UTF-8. +static size_t Utf8CountBytes(std::wstring_view str) +{ + int result = 0; + for (; str.size(); str.remove_prefix(1)) { + if (str.front() < 0x80) + result += 1; + else if (str.front() < 0x800) + result += 2; + else if (sizeof(wchar_t) == 4) { + if (str.front() < 0x10000) + result += 3; + else + result += 4; + } else { + if (IsUtf16SurrogatePair(str)) { + result += 4; + str.remove_prefix(1); + } else + result += 3; + } + } + return result; +} + +ZXING_EXPORT_TEST_ONLY +int Utf32ToUtf8(char32_t utf32, char* out) +{ + if (utf32 < 0x80) { + *out++ = narrow_cast(utf32); + return 1; + } + if (utf32 < 0x800) { + *out++ = narrow_cast((utf32 >> 6) | 0xc0); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); + return 2; + } + if (utf32 < 0x10000) { + *out++ = narrow_cast((utf32 >> 12) | 0xe0); + *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); + return 3; + } + + *out++ = narrow_cast((utf32 >> 18) | 0xf0); + *out++ = narrow_cast(((utf32 >> 12) & 0x3f) | 0x80); + *out++ = narrow_cast(((utf32 >> 6) & 0x3f) | 0x80); + *out++ = narrow_cast((utf32 & 0x3f) | 0x80); + return 4; +} + +static void AppendToUtf8(std::wstring_view str, std::string& utf8) +{ + utf8.reserve(utf8.size() + Utf8CountBytes(str)); + + char buffer[4]; + for (; str.size(); str.remove_prefix(1)) + { + uint32_t cp; + if (IsUtf16SurrogatePair(str)) { + cp = Utf32FromUtf16Surrogates(str); + str.remove_prefix(1); + } else + cp = str.front(); + + auto bufLength = Utf32ToUtf8(cp, buffer); + utf8.append(buffer, bufLength); + } +} + +std::string ToUtf8(std::wstring_view str) +{ + std::string utf8; + AppendToUtf8(str, utf8); + return utf8; +} + +std::wstring EscapeNonGraphical(std::wstring_view str) +{ + static const char* const ascii_nongraphs[33] = { + "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", + "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", + "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", + "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", + "DEL", + }; + + std::locale utf8Loc("en_US.UTF-8"); + + std::wostringstream ws; + ws.fill(L'0'); + + for (; str.size(); str.remove_prefix(1)) { + wchar_t wc = str.front(); + if (wc < 32 || wc == 127) // Non-graphical ASCII, excluding space + ws << "<" << ascii_nongraphs[wc == 127 ? 32 : wc] << ">"; + else if (wc < 128) // ASCII + ws << wc; + else if (IsUtf16SurrogatePair(str)) + ws.write(str.data(), 2), str.remove_prefix(1); + else if ((wc < 0xd800 || wc >= 0xe000) && (std::isgraph(wc, utf8Loc) && wc != 0xA0 && wc != 0x2007 && + wc != 0xfffd)) // Exclude unpaired surrogates and NO-BREAK spaces NBSP and NUMSP + ws << wc; + else // Non-graphical Unicode + ws << "(wc) << ">"; + } + + return ws.str(); +} + +std::string EscapeNonGraphical(std::string_view utf8) +{ + return ToUtf8(EscapeNonGraphical(FromUtf8(utf8))); +} + +} // namespace ZXing diff --git a/core/src/Utf.h b/core/src/Utf.h new file mode 100644 index 0000000000..cd90f8a4af --- /dev/null +++ b/core/src/Utf.h @@ -0,0 +1,19 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +namespace ZXing { + +std::string ToUtf8(std::wstring_view str); +std::wstring FromUtf8(std::string_view utf8); + +std::wstring EscapeNonGraphical(std::wstring_view str); +std::string EscapeNonGraphical(std::string_view utf8); + +} // namespace ZXing diff --git a/core/src/aztec/AZWriter.cpp b/core/src/aztec/AZWriter.cpp index 6e6b0ad0d7..43552339f3 100644 --- a/core/src/aztec/AZWriter.cpp +++ b/core/src/aztec/AZWriter.cpp @@ -9,7 +9,7 @@ #include "AZEncoder.h" #include "CharacterSet.h" #include "TextEncoder.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include @@ -32,7 +32,7 @@ Writer::encode(const std::wstring& contents, int width, int height) const BitMatrix Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::Aztec diff --git a/core/src/datamatrix/DMWriter.cpp b/core/src/datamatrix/DMWriter.cpp index f2b61c5682..e3ab758de3 100644 --- a/core/src/datamatrix/DMWriter.cpp +++ b/core/src/datamatrix/DMWriter.cpp @@ -12,7 +12,7 @@ #include "DMECEncoder.h" #include "DMHighLevelEncoder.h" #include "DMSymbolInfo.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -112,7 +112,7 @@ Writer::encode(const std::wstring& contents, int width, int height) const BitMatrix Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::DataMatrix diff --git a/core/src/oned/ODCodabarWriter.cpp b/core/src/oned/ODCodabarWriter.cpp index 46a50569f9..922ee70483 100644 --- a/core/src/oned/ODCodabarWriter.cpp +++ b/core/src/oned/ODCodabarWriter.cpp @@ -7,7 +7,7 @@ #include "ODCodabarWriter.h" #include "ODWriterHelper.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "ZXAlgorithms.h" #include @@ -129,7 +129,7 @@ CodabarWriter::encode(const std::wstring& contents_, int width, int height) cons BitMatrix CodabarWriter::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode128Writer.cpp b/core/src/oned/ODCode128Writer.cpp index b737af2fca..8cc9b41d4a 100644 --- a/core/src/oned/ODCode128Writer.cpp +++ b/core/src/oned/ODCode128Writer.cpp @@ -8,7 +8,7 @@ #include "ODCode128Patterns.h" #include "ODWriterHelper.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -255,7 +255,7 @@ Code128Writer::encode(const std::wstring& contents, int width, int height) const BitMatrix Code128Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode39Writer.cpp b/core/src/oned/ODCode39Writer.cpp index 49347f3964..3e02253e7b 100644 --- a/core/src/oned/ODCode39Writer.cpp +++ b/core/src/oned/ODCode39Writer.cpp @@ -9,7 +9,7 @@ #include "CharacterSet.h" #include "ODWriterHelper.h" #include "TextEncoder.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "ZXAlgorithms.h" #include @@ -170,7 +170,7 @@ Code39Writer::encode(const std::wstring& contents, int width, int height) const BitMatrix Code39Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODCode93Writer.cpp b/core/src/oned/ODCode93Writer.cpp index 9cca0771db..7c4b6637c2 100644 --- a/core/src/oned/ODCode93Writer.cpp +++ b/core/src/oned/ODCode93Writer.cpp @@ -7,7 +7,7 @@ #include "ODCode93Writer.h" #include "ODWriterHelper.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "ZXAlgorithms.h" #include "ZXTestSupport.h" @@ -186,7 +186,7 @@ Code93Writer::encode(const std::wstring& contents_, int width, int height) const BitMatrix Code93Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODEAN13Writer.cpp b/core/src/oned/ODEAN13Writer.cpp index cf99be12cc..40183750c0 100644 --- a/core/src/oned/ODEAN13Writer.cpp +++ b/core/src/oned/ODEAN13Writer.cpp @@ -8,7 +8,7 @@ #include "ODUPCEANCommon.h" #include "ODWriterHelper.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -56,7 +56,7 @@ EAN13Writer::encode(const std::wstring& contents, int width, int height) const BitMatrix EAN13Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODEAN8Writer.cpp b/core/src/oned/ODEAN8Writer.cpp index 652c26f719..14ca0ee4fa 100644 --- a/core/src/oned/ODEAN8Writer.cpp +++ b/core/src/oned/ODEAN8Writer.cpp @@ -8,7 +8,7 @@ #include "ODUPCEANCommon.h" #include "ODWriterHelper.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include @@ -45,7 +45,7 @@ EAN8Writer::encode(const std::wstring& contents, int width, int height) const BitMatrix EAN8Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODITFWriter.cpp b/core/src/oned/ODITFWriter.cpp index 1f3e6f611d..6a2f7c566a 100644 --- a/core/src/oned/ODITFWriter.cpp +++ b/core/src/oned/ODITFWriter.cpp @@ -7,7 +7,7 @@ #include "ODITFWriter.h" #include "ODWriterHelper.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -72,7 +72,7 @@ ITFWriter::encode(const std::wstring& contents, int width, int height) const BitMatrix ITFWriter::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODUPCAWriter.cpp b/core/src/oned/ODUPCAWriter.cpp index 16574022fb..5ce6a4371b 100644 --- a/core/src/oned/ODUPCAWriter.cpp +++ b/core/src/oned/ODUPCAWriter.cpp @@ -8,7 +8,7 @@ #include "BitMatrix.h" #include "ODEAN13Writer.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include @@ -27,7 +27,7 @@ UPCAWriter::encode(const std::wstring& contents, int width, int height) const BitMatrix UPCAWriter::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/oned/ODUPCEWriter.cpp b/core/src/oned/ODUPCEWriter.cpp index ea23e32290..58a292d88d 100644 --- a/core/src/oned/ODUPCEWriter.cpp +++ b/core/src/oned/ODUPCEWriter.cpp @@ -8,7 +8,7 @@ #include "ODUPCEANCommon.h" #include "ODWriterHelper.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -50,7 +50,7 @@ UPCEWriter::encode(const std::wstring& contents, int width, int height) const BitMatrix UPCEWriter::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::OneD diff --git a/core/src/pdf417/PDFDecodedBitStreamParser.cpp b/core/src/pdf417/PDFDecodedBitStreamParser.cpp index 914fed9c57..4a2574535c 100644 --- a/core/src/pdf417/PDFDecodedBitStreamParser.cpp +++ b/core/src/pdf417/PDFDecodedBitStreamParser.cpp @@ -10,7 +10,6 @@ #include "CharacterSet.h" #include "DecoderResult.h" #include "PDFDecoderResultExtra.h" -#include "TextUtfEncoding.h" #include "ZXBigInteger.h" #include "ZXTestSupport.h" diff --git a/core/src/pdf417/PDFWriter.cpp b/core/src/pdf417/PDFWriter.cpp index 400208eb50..bd00f3f395 100644 --- a/core/src/pdf417/PDFWriter.cpp +++ b/core/src/pdf417/PDFWriter.cpp @@ -7,7 +7,7 @@ #include "PDFWriter.h" #include "PDFEncoder.h" #include "BitMatrix.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include @@ -114,7 +114,7 @@ Writer::encode(const std::wstring& contents, int width, int height) const BitMatrix Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } Writer::Writer() diff --git a/core/src/qrcode/QRWriter.cpp b/core/src/qrcode/QRWriter.cpp index 8f0597cab3..5caed6eed4 100644 --- a/core/src/qrcode/QRWriter.cpp +++ b/core/src/qrcode/QRWriter.cpp @@ -11,7 +11,7 @@ #include "QREncodeResult.h" #include "QREncoder.h" #include "QRErrorCorrectionLevel.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -45,7 +45,7 @@ BitMatrix Writer::encode(const std::wstring& contents, int width, int height) co BitMatrix Writer::encode(const std::string& contents, int width, int height) const { - return encode(TextUtfEncoding::FromUtf8(contents), width, height); + return encode(FromUtf8(contents), width, height); } } // namespace ZXing::QRCode diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index ac64c79d9d..8e0e1c93e6 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 #include "ReadBarcode.h" -#include "TextUtfEncoding.h" #include "GTIN.h" #include diff --git a/example/ZXingWriter.cpp b/example/ZXingWriter.cpp index 80a62d5c58..091ca0f2ce 100644 --- a/example/ZXingWriter.cpp +++ b/example/ZXingWriter.cpp @@ -8,7 +8,6 @@ #include "BitMatrixIO.h" #include "CharacterSet.h" #include "MultiFormatWriter.h" -#include "TextUtfEncoding.h" #include #include @@ -121,7 +120,7 @@ int main(int argc, char* argv[]) try { auto writer = MultiFormatWriter(format).setMargin(margin).setEncoding(encoding).setEccLevel(eccLevel); - auto matrix = writer.encode(TextUtfEncoding::FromUtf8(text), width, height); + auto matrix = writer.encode(text, width, height); auto bitmap = ToMatrix(matrix); auto ext = GetExtension(filePath); diff --git a/test/unit/TextDecoderTest.cpp b/test/unit/TextDecoderTest.cpp index 0fcbd9636a..b0dae877e2 100644 --- a/test/unit/TextDecoderTest.cpp +++ b/test/unit/TextDecoderTest.cpp @@ -5,16 +5,15 @@ #include "CharacterSet.h" #include "TextDecoder.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "gtest/gtest.h" #include "gmock/gmock.h" using namespace ZXing; -using namespace ZXing::TextUtfEncoding; using namespace testing; -namespace ZXing::TextUtfEncoding { +namespace ZXing { int Utf32ToUtf8(char32_t utf32, char* out); } diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index 1650ef2714..fdae906541 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -3,16 +3,16 @@ */ // SPDX-License-Identifier: Apache-2.0 -#include "TextUtfEncoding.h" +#include "Utf.h" #include "gtest/gtest.h" #include #include +using namespace ZXing; + TEST(TextUtfEncodingTest, EscapeNonGraphical) { - using namespace ZXing::TextUtfEncoding; - EXPECT_EQ(EscapeNonGraphical(u8"\u00B6\u0416"), "¶Ж"); EXPECT_EQ(EscapeNonGraphical(u8"\x01\x1F\x7F"), ""); EXPECT_EQ(EscapeNonGraphical(u8"\u0080\u009F"), ""); @@ -26,8 +26,6 @@ TEST(TextUtfEncodingTest, EscapeNonGraphical) TEST(TextUtfEncodingTest, FromUtf8) { - using namespace ZXing::TextUtfEncoding; - EXPECT_EQ(FromUtf8(u8"\U00010000"), L"\U00010000"); EXPECT_EQ(FromUtf8(u8"\U00010FFF"), L"\U00010FFF"); EXPECT_EQ(FromUtf8("A\xE8\x80\xBFG"), L"A\u803FG"); // U+803F diff --git a/test/unit/aztec/AZDetectorTest.cpp b/test/unit/aztec/AZDetectorTest.cpp index fd7a4f1191..b0e94e3b84 100644 --- a/test/unit/aztec/AZDetectorTest.cpp +++ b/test/unit/aztec/AZDetectorTest.cpp @@ -9,7 +9,7 @@ #include "BitMatrixIO.h" #include "DecoderResult.h" #include "PseudoRandom.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "aztec/AZDecoder.h" #include "aztec/AZDetectorResult.h" @@ -65,7 +65,7 @@ namespace { EXPECT_EQ(r.isValid(), true); EXPECT_EQ(r.nbLayers(), nbLayers); EXPECT_EQ(r.isCompact(), isCompact); - EXPECT_EQ(data, TextUtfEncoding::ToUtf8(Aztec::Decode(r).text())); + EXPECT_EQ(data, ToUtf8(Aztec::Decode(r).text())); } } // Try a few random three-bit errors; diff --git a/test/unit/qrcode/QREncoderTest.cpp b/test/unit/qrcode/QREncoderTest.cpp index c5661a6cb1..6a31177836 100644 --- a/test/unit/qrcode/QREncoderTest.cpp +++ b/test/unit/qrcode/QREncoderTest.cpp @@ -8,7 +8,7 @@ #include "BitMatrixIO.h" #include "CharacterSet.h" #include "TextDecoder.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include "qrcode/QREncoder.h" #include "qrcode/QRCodecMode.h" #include "qrcode/QREncodeResult.h" @@ -43,7 +43,7 @@ namespace { { std::string str; TextDecoder::Append(str, bytes.data(), bytes.size(), CharacterSet::Shift_JIS); - return TextUtfEncoding::FromUtf8(str); + return FromUtf8(str); } std::string RemoveSpace(std::string s) diff --git a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp index 85d1717f92..d41f99176d 100644 --- a/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp +++ b/wrappers/android/zxingcpp/src/main/cpp/JNIUtils.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "JNIUtils.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -55,7 +55,7 @@ jstring C2JString(JNIEnv* env, const std::wstring& str) jstring C2JString(JNIEnv* env, const std::string& str) { - return C2JString(env, ZXing::TextUtfEncoding::FromUtf8(str)); + return C2JString(env, ZXing::FromUtf8(str)); } std::string J2CString(JNIEnv* env, jstring str) diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index 0baa93d069..e552f5edac 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -14,7 +14,7 @@ #include "DecodeHints.h" #include "ReadBarcode.h" #include "ReadResult.h" -#include "TextUtfEncoding.h" +#include "Utf.h" #include #include @@ -101,7 +101,7 @@ BarcodeFormat BarcodeReader::ConvertRuntimeToNative(BarcodeType type) return BarcodeFormat::UPCE; default: std::wstring typeAsString = type.ToString()->Begin(); - throw std::invalid_argument("Unknown Barcode Type: " + TextUtfEncoding::ToUtf8(typeAsString)); + throw std::invalid_argument("Unknown Barcode Type: " + ToUtf8(typeAsString)); } } @@ -149,7 +149,7 @@ BarcodeType BarcodeReader::ConvertNativeToRuntime(BarcodeFormat format) static Platform::String^ ToPlatformString(const std::string& str) { - std::wstring wstr = TextUtfEncoding::FromUtf8(str); + std::wstring wstr = FromUtf8(str); return ref new Platform::String(wstr.c_str(), (unsigned)wstr.length()); } From 35c62bb97d100d7c85be50028cecfe1dfd3f3ab6 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 7 Aug 2022 20:57:52 +0200 Subject: [PATCH 0451/1315] DecodeHintes: introduce `TextMode` to modify `Result::text` rendering Default value is `Plain` (for now) which preserves the previous behavior. --- core/src/Content.cpp | 6 +-- core/src/Content.h | 2 +- core/src/DecodeHints.h | 19 ++++++++-- core/src/ReadBarcode.cpp | 4 +- core/src/Result.cpp | 19 +++++----- core/src/Result.h | 21 ++++++----- example/ZXingReader.cpp | 51 ++++++++++++++++---------- test/unit/ThresholdBinarizerTest.cpp | 2 +- test/unit/oned/ODCode128ReaderTest.cpp | 2 +- test/unit/oned/ODCode128WriterTest.cpp | 11 ++---- wrappers/python/zxing.cpp | 2 +- 11 files changed, 81 insertions(+), 58 deletions(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index bb1cd65577..3dd6a221f4 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -138,9 +138,9 @@ std::string Content::render(bool withECI) const std::string Content::text(TextMode mode) const { - switch(mode) { - case TextMode::Utf8: return render(false); - case TextMode::Utf8ECI: return render(true); + switch (mode) { + case TextMode::Plain: return render(false); + case TextMode::ECI: return render(true); case TextMode::HRI: switch (type()) { case ContentType::GS1: return HRIFromGS1(render(false)); diff --git a/core/src/Content.h b/core/src/Content.h index 6b53466da2..501f89d5b7 100644 --- a/core/src/Content.h +++ b/core/src/Content.h @@ -7,6 +7,7 @@ #include "ByteArray.h" #include "CharacterSet.h" +#include "DecodeHints.h" #include #include @@ -16,7 +17,6 @@ namespace ZXing { enum class ECI : int; enum class ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI }; -enum class TextMode { Utf8, Utf8ECI, HRI, Hex, Escaped }; enum class AIFlag : char { None, GS1, AIM }; std::string ToString(ContentType type); diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 0cd73a1771..9e6bbddcf3 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -12,7 +12,6 @@ #include #include -#include namespace ZXing { @@ -23,7 +22,7 @@ namespace ZXing { * The difference is how to get to a threshold value T which results in a bit * value R = L <= T. */ -enum class Binarizer : unsigned char // needs to unsigned for the bitfield below to work, uint8_t fails as well +enum class Binarizer : unsigned char // needs to be unsigned for the bitfield below to work, uint8_t fails as well { LocalAverage, ///< T = average of neighboring pixels for matrix and GlobalHistogram for linear (HybridBinarizer) GlobalHistogram, ///< T = valley between the 2 largest peaks in the histogram (per line in linear case) @@ -38,6 +37,15 @@ enum class EanAddOnSymbol : unsigned char // see above Require, ///< Require EAN-2/EAN-5 Add-On symbol to be present }; +enum class TextMode : unsigned char // see above +{ + Plain, ///< bytes() transcoded to unicode based on ECI info or guessed charset (the default mode prior to 2.0) + ECI, ///< standard content following the ECI protocol with every character set ECI segment transcoded to unicode + HRI, ///< Human Readable Interpretation (dependent on the ContentType) + Hex, ///< bytes() transcoded to ASCII string of HEX values + Escaped, ///< Use the EscapeNonGraphical() function (e.g. ASCII 29 will be transcoded to "") +}; + class DecodeHints { bool _tryHarder : 1; @@ -51,6 +59,7 @@ class DecodeHints bool _returnErrors : 1; EanAddOnSymbol _eanAddOnSymbol : 2; Binarizer _binarizer : 2; + TextMode _textMode : 3; CharacterSet _characterSet = CharacterSet::Unknown; uint8_t _minLineCount = 2; @@ -72,7 +81,8 @@ class DecodeHints _returnCodabarStartEnd(0), _returnErrors(0), _eanAddOnSymbol(EanAddOnSymbol::Ignore), - _binarizer(Binarizer::LocalAverage) + _binarizer(Binarizer::LocalAverage), + _textMode(TextMode::Plain) {} #define ZX_PROPERTY(TYPE, GETTER, SETTER) \ @@ -130,6 +140,9 @@ class DecodeHints /// Specify whether to ignore, read or require EAN-2/5 add-on symbols while scanning EAN/UPC codes ZX_PROPERTY(EanAddOnSymbol, eanAddOnSymbol, setEanAddOnSymbol) + /// Specifies the TextMode that controls the return of the Result::text() function + ZX_PROPERTY(TextMode, textMode, setTextMode) + /// Specifies fallback character set to use instead of auto-detecting it (when applicable) ZX_PROPERTY(CharacterSet, characterSet, setCharacterSet) DecodeHints& setCharacterSet(std::string_view v)& { return _characterSet = CharacterSetFromString(v), *this; } diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 6b1e22df97..511d84b8ca 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -126,7 +126,7 @@ Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) LumImage lum; ImageView iv = SetupLumImageView(_iv, lum, hints); - return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)).setCharacterSet(hints.characterSet()); + return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)).setDecodeHints(hints); } } @@ -159,7 +159,7 @@ Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) } for (auto& res : results) - res.setCharacterSet(hints.characterSet()); + res.setDecodeHints(hints); return results; } diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 4574fae91d..0f66743220 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -55,6 +55,11 @@ ByteArray Result::bytesECI() const return _content.bytesECI(); } +std::string Result::text(TextMode mode) const +{ + return _content.text(mode); +} + std::string Result::utf8() const { return _content.utf8(); @@ -65,13 +70,6 @@ std::wstring Result::utfW() const return _content.utfW(); } -#if 0 -std::string Result::utf8ECI() const -{ - return _content.text(TextMode::Utf8ECI); -} -#endif - ContentType Result::contentType() const { return _content.type(); @@ -108,10 +106,11 @@ std::string Result::sequenceId() const return _sai.id; } -Result& Result::setCharacterSet(CharacterSet defaultCS) +Result& Result::setDecodeHints(DecodeHints hints) { - if (defaultCS != CharacterSet::Unknown) - _content.defaultCharset = defaultCS; + if (hints.characterSet() != CharacterSet::Unknown) + _content.defaultCharset = hints.characterSet(); + _decodeHints = hints; return *this; } diff --git a/core/src/Result.h b/core/src/Result.h index 4200760f38..32b85b7cb3 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -10,6 +10,7 @@ #include "BarcodeFormat.h" #include "ByteArray.h" #include "Content.h" +#include "DecodeHints.h" #include "Error.h" #include "Quadrilateral.h" #include "StructuredAppend.h" @@ -62,21 +63,22 @@ class Result */ ByteArray bytesECI() const; + /** + * @brief text returns the bytes() content rendered to unicode/utf8 text accoring to specified TextMode + */ + std::string text(TextMode mode) const; + + /** + * @brief text returns the bytes() content rendered to unicode/utf8 text accoring to the TextMode set in the DecodingHints + */ #ifndef ZX_USE_UTF16 - std::string text() const { return utf8(); } + std::string text() const { return text(_decodeHints.textMode()); } std::string ecLevel() const { return _ecLevel; } #else std::wstring text() const { return utfW(); } std::wstring ecLevel() const { return {_ecLevel.begin(), _ecLevel.end()}; } #endif -#if 0 // disabled until final API decission is made - /** - * @brief utf8ECI is the standard content following the ECI protocol with every character set ECI segment transcoded to utf8 - */ - std::string utf8ECI() const; -#endif - /** * @brief contentType gives a hint to the type of content found (Text/Binary/GS1/etc.) */ @@ -143,7 +145,7 @@ class Result // only for internal use void incrementLineCount() { ++_lineCount; } - Result& setCharacterSet(CharacterSet defaultCS); + Result& setDecodeHints(DecodeHints hints); bool operator==(const Result& o) const; @@ -153,6 +155,7 @@ class Result Content _content; Error _error; Position _position; + DecodeHints _decodeHints; std::string _ecLevel; StructuredAppendInfo _sai; BarcodeFormat _format = BarcodeFormat::None; diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 8e0e1c93e6..f97e432ecc 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -33,8 +33,9 @@ static void PrintUsage(const char* exePath) << " Only detect given format(s) (faster)\n" << " -ispure Assume the image contains only a 'pure'/perfect code (faster)\n" << " -errors Include results with errors (like checksum error)\n" - << " -1 Print only file name, content/error on one line per file/barcode (implies '-escape')\n" - << " -escape Escape non-graphical characters in angle brackets\n" + << " -mode \n" + << " Text mode used to render the raw byte content into text\n" + << " -1 Print only file name, content/error on one line per file/barcode (implies '-mode Escaped')\n" << " -bytes Write (only) the bytes content of the symbol(s) to stdout\n" << " -pngout \n" << " Write a copy of the input image with barcodes outlined by a green line\n" @@ -46,22 +47,23 @@ static void PrintUsage(const char* exePath) std::cout << "Formats can be lowercase, with or without '-', separated by ',' and/or '|'\n"; } -static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& angleEscape, bool& bytesOnly, +static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLine, bool& bytesOnly, std::vector& filePaths, std::string& outPath) { for (int i = 1; i < argc; ++i) { - if (strcmp(argv[i], "-fast") == 0) { + auto is = [&](const char* str) { return strncmp(argv[i], str, strlen(argv[i])) == 0; }; + if (is("-fast")) { hints.setTryHarder(false); - } else if (strcmp(argv[i], "-norotate") == 0) { + } else if (is("-norotate")) { hints.setTryRotate(false); - } else if (strcmp(argv[i], "-noscale") == 0) { + } else if (is("-noscale")) { hints.setDownscaleThreshold(0); - } else if (strcmp(argv[i], "-ispure") == 0) { + } else if (is("-ispure")) { hints.setIsPure(true); hints.setBinarizer(Binarizer::FixedThreshold); - } else if (strcmp(argv[i], "-errors") == 0) { + } else if (is("-errors")) { hints.setReturnErrors(true); - } else if (strcmp(argv[i], "-format") == 0) { + } else if (is("-format")) { if (++i == argc) return false; try { @@ -70,13 +72,24 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi std::cerr << e.what() << "\n"; return false; } - } else if (strcmp(argv[i], "-1") == 0) { + } else if (is("-mode")) { + if (++i == argc) + return false; + else if (is("plain")) + hints.setTextMode(TextMode::Plain); + else if (is("eci")) + hints.setTextMode(TextMode::ECI); + else if (is("hri")) + hints.setTextMode(TextMode::HRI); + else if (is("escaped")) + hints.setTextMode(TextMode::Escaped); + else + return false; + } else if (is("-1")) { oneLine = true; - } else if (strcmp(argv[i], "-escape") == 0) { - angleEscape = true; - } else if (strcmp(argv[i], "-bytes") == 0) { + } else if (is("-bytes")) { bytesOnly = true; - } else if (strcmp(argv[i], "-pngout") == 0) { + } else if (is("-pngout")) { if (++i == argc) return false; outPath = argv[i]; @@ -122,17 +135,17 @@ int main(int argc, char* argv[]) Results allResults; std::string outPath; bool oneLine = false; - bool angleEscape = false; bool bytesOnly = false; int ret = 0; + hints.setTextMode(TextMode::HRI); + hints.setEanAddOnSymbol(EanAddOnSymbol::Read); - if (!ParseOptions(argc, argv, hints, oneLine, angleEscape, bytesOnly, filePaths, outPath)) { + if (!ParseOptions(argc, argv, hints, oneLine, bytesOnly, filePaths, outPath)) { PrintUsage(argv[0]); return -1; } - hints.setEanAddOnSymbol(EanAddOnSymbol::Read); std::cout.setf(std::ios::boolalpha); @@ -173,7 +186,7 @@ int main(int argc, char* argv[]) if (oneLine) { std::cout << filePath << " " << ToString(result.format()); if (result.isValid()) - std::cout << " \"" << TextUtfEncoding::EscapeNonGraphical(result.text()) << "\""; + std::cout << " \"" << result.text(TextMode::Escaped) << "\""; else if (result.error()) std::cout << " " << ToString(result.error()); std::cout << "\n"; @@ -194,7 +207,7 @@ int main(int argc, char* argv[]) continue; } - std::cout << "Text: \"" << (angleEscape ? TextUtfEncoding::EscapeNonGraphical(result.text()) : result.text()) << "\"\n" + std::cout << "Text: \"" << result.text() << "\"\n" << "Bytes: " << ToHex(result.bytes()) << "\n" << "BytesECI: " << ToHex(result.bytesECI()) << "\n" << "Format: " << ToString(result.format()) << "\n" diff --git a/test/unit/ThresholdBinarizerTest.cpp b/test/unit/ThresholdBinarizerTest.cpp index 8b34bfd4b8..13ff0e5823 100644 --- a/test/unit/ThresholdBinarizerTest.cpp +++ b/test/unit/ThresholdBinarizerTest.cpp @@ -99,5 +99,5 @@ TEST(ThresholdBinarizerTest, PatternRowClear) Result result = reader.decode(ThresholdBinarizer(getImageView(buf, bits), 0x7F)); EXPECT_TRUE(result.isValid()); - EXPECT_EQ(result.text(), "9112345678901234567890123456789012345678901234567890123456789012345678"); + EXPECT_EQ(result.text(TextMode::HRI), "(91)12345678901234567890123456789012345678901234567890123456789012345678"); } diff --git a/test/unit/oned/ODCode128ReaderTest.cpp b/test/unit/oned/ODCode128ReaderTest.cpp index 7f3ad3e30d..15d8a2171e 100644 --- a/test/unit/oned/ODCode128ReaderTest.cpp +++ b/test/unit/oned/ODCode128ReaderTest.cpp @@ -47,7 +47,7 @@ TEST(ODCode128ReaderTest, SymbologyIdentifier) PatternRow row({ 4, 1, 1, 1, 3, 1, 2, 2, 1, 2, 3, 1, 2, 2, 2, 1, 2, 2, 1, 3, 2, 1, 3, 1 }); auto result = parse('C', row); EXPECT_EQ(result.symbologyIdentifier(), "]C1"); - EXPECT_EQ(result.text(), "2001"); + EXPECT_EQ(result.text(TextMode::HRI), "(20)01"); } { diff --git a/test/unit/oned/ODCode128WriterTest.cpp b/test/unit/oned/ODCode128WriterTest.cpp index 662c36db3b..fc019a1937 100644 --- a/test/unit/oned/ODCode128WriterTest.cpp +++ b/test/unit/oned/ODCode128WriterTest.cpp @@ -92,24 +92,19 @@ TEST(ODCode128Writer, EncodeWithFncsAndNumberInCodesetA) TEST(ODCode128Writer, RoundtripGS1) { auto toEncode = L"\xf1" "10958" "\xf1" "17160526"; - auto expected = "10958\u001D17160526"; - auto encResult = Code128Writer().encode(toEncode, 0, 0); - auto decResult = Decode(encResult); - auto actual = decResult.text(); - EXPECT_EQ(actual, expected); + auto decResult = Decode(Code128Writer().encode(toEncode, 0, 0)); + EXPECT_EQ(decResult.text(TextMode::HRI), "(10)958(17)160526"); EXPECT_EQ(decResult.symbologyIdentifier(), "]C1"); } TEST(ODCode128Writer, RoundtripFNC1) { auto toEncode = L"1\xf1" "0958" "\xf1" "17160526"; - auto expected = "1\u001D0958\u001D17160526"; auto encResult = Code128Writer().encode(toEncode, 0, 0); auto decResult = Decode(encResult); - auto actual = decResult.text(); - EXPECT_EQ(actual, expected); + EXPECT_EQ(decResult.bytes().asString(), "1\u001D0958\u001D17160526"); EXPECT_EQ(decResult.symbologyIdentifier(), "]C0"); } diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 14555ba31b..9e6984306a 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -202,7 +202,7 @@ PYBIND11_MODULE(zxingcpp, m) .def_property_readonly("valid", &Result::isValid, ":return: whether or not result is valid (i.e. a symbol was found)\n" ":rtype: bool") - .def_property_readonly("text", &Result::text, + .def_property_readonly("text", [](const Result& res) { return res.text(); }, ":return: text of the decoded symbol\n" ":rtype: str") .def_property_readonly("bytes", [](const Result& res) { return py::bytes(res.bytes().asString()); }, From 2da9b17baa6420993998ef14e083c337714785a5 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 8 Aug 2022 12:07:10 +0200 Subject: [PATCH 0452/1315] QRCode: fix multi-symbol detection regression (fix #370) --- core/src/qrcode/QRDetector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 3283feddb3..02bc72d6c1 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -141,7 +141,7 @@ FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) // we need to check both two equal sides separately. // The value of |c^2 - 2 * b^2| + |c^2 - 2 * a^2| increases as dissimilarity // from isosceles right triangle. - double d = (std::abs(distAC2 - 2 * distAB2) + std::abs(distAC2 - 2 * distBC2)) / distAC2; + double d = (std::abs(distAC2 - 2 * distAB2) + std::abs(distAC2 - 2 * distBC2)); // Use cross product to figure out whether A and C are correct or flipped. // This asks whether BC x BA has a positive z component, which is the arrangement From b5556273179ddf2b758950c130ca2a512f36c716 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 8 Aug 2022 12:37:09 +0200 Subject: [PATCH 0453/1315] ZXingReader: improve performance measurement debugging code --- example/ZXingReader.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index f97e432ecc..cbad7c840d 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -258,11 +258,14 @@ int main(int argc, char* argv[]) auto startTime = std::chrono::high_resolution_clock::now(); auto duration = startTime - startTime; int N = 0; + int blockSize = 1; do { - for (int i = 0; i < 100; ++i) + for (int i = 0; i < blockSize; ++i) ReadBarcodes(image, hints); - N += 100; + N += blockSize; duration = std::chrono::high_resolution_clock::now() - startTime; + if (blockSize < 1000 && duration < std::chrono::milliseconds(100)) + blockSize *= 10; } while (duration < std::chrono::seconds(1)); printf("time: %5.1f ms per frame\n", double(std::chrono::duration_cast(duration).count()) / N); } From 3102a3b209981484326b0bff0c3e36dc31f87f7f Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 8 Aug 2022 13:33:57 +0200 Subject: [PATCH 0454/1315] QRCode: remove std::acos in GenerateFinderPatternSets -> up to 15% performance increase in special circumstances --- core/src/qrcode/QRDetector.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index 02bc72d6c1..d9ed45a054 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -94,6 +94,8 @@ FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) // Test image: fix-finderpattern-order.jpg return dot((*a - *b), (*a - *b)) * std::pow(double(b->size) / a->size, 2); }; + const double cosUpper = std::cos(45. / 180 * 3.1415); // TODO: use c++20 std::numbers::pi_v + const double cosLower = std::cos(135. / 180 * 3.1415); int nbPatterns = Size(patterns); for (int i = 0; i < nbPatterns - 2; i++) { @@ -131,9 +133,8 @@ FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) continue; // Make sure the angle between AB and BC does not deviate from 90° by more than 45° - auto alpha = std::acos((distAB2 + distBC2 - distAC2) / (2 * distAB * distBC)) / 3.1415 * 180; -// printf("alpha: %.1f\n", alpha); - if (std::isnan(alpha) || std::abs(90 - alpha) > 45) + auto cosAB_BC = (distAB2 + distBC2 - distAC2) / (2 * distAB * distBC); + if (std::isnan(cosAB_BC) || cosAB_BC > cosUpper || cosAB_BC < cosLower) continue; // a^2 + b^2 = c^2 (Pythagorean theorem), and a = b (isosceles triangle). From a2ff85b68a36652442eb2a17ce26a4aa5078aa7d Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 8 Aug 2022 13:35:22 +0200 Subject: [PATCH 0455/1315] QRCode: increase upper limit of potentially detected symbols --- core/src/qrcode/QRDetector.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/qrcode/QRDetector.cpp b/core/src/qrcode/QRDetector.cpp index d9ed45a054..1902858be7 100644 --- a/core/src/qrcode/QRDetector.cpp +++ b/core/src/qrcode/QRDetector.cpp @@ -151,7 +151,8 @@ FinderPatternSets GenerateFinderPatternSets(FinderPatterns& patterns) std::swap(a, c); // arbitrarily limit the number of potential sets - const auto setSizeLimit = 16; + // (this has performance implications while limiting the maximal number of detected symbols) + const auto setSizeLimit = 256; if (sets.size() < setSizeLimit || sets.crbegin()->first > d) { sets.emplace(d, FinderPatternSet{*a, *b, *c}); if (sets.size() > setSizeLimit) From 2d46443d48c409156bea2cdaa81233b8b3cd5e6d Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 8 Aug 2022 23:35:04 +0200 Subject: [PATCH 0456/1315] TextMode: fall back to `Plain` if `HRIFromGS1` returns empty string This implements option 3 as discussed in #373. --- core/src/Content.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/Content.cpp b/core/src/Content.cpp index 3dd6a221f4..26166bb1ce 100644 --- a/core/src/Content.cpp +++ b/core/src/Content.cpp @@ -143,7 +143,11 @@ std::string Content::text(TextMode mode) const case TextMode::ECI: return render(true); case TextMode::HRI: switch (type()) { - case ContentType::GS1: return HRIFromGS1(render(false)); + case ContentType::GS1: { + auto plain = render(false); + auto hri = HRIFromGS1(plain); + return hri.empty() ? plain : hri; + } case ContentType::ISO15434: return HRIFromISO15434(render(false)); case ContentType::Text: return render(false); default: return text(TextMode::Escaped); From d68161a2dc28e3e68f8bcac738e884dbd13ae447 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 10 Aug 2022 13:24:56 +0200 Subject: [PATCH 0457/1315] c++20: fix build regressions from u8"" and char8_t usage --- core/src/HRI.cpp | 10 ++--- core/src/Utf.cpp | 2 + test/unit/ContentTest.cpp | 16 +++---- test/unit/TextEncoderTest.cpp | 72 +++++++++++++++---------------- test/unit/TextUtfEncodingTest.cpp | 22 +++++----- 5 files changed, 62 insertions(+), 60 deletions(-) diff --git a/core/src/HRI.cpp b/core/src/HRI.cpp index 847581c9eb..580d23f58c 100644 --- a/core/src/HRI.cpp +++ b/core/src/HRI.cpp @@ -292,11 +292,11 @@ std::string HRIFromISO15434(std::string_view str) for (char c : str) { switch (c) { - case 4: oss << u8"\u1d31\u1d52\u209c"; break; // EOT - case 28: oss << u8"\ua7f3\u209b"; break; // FS - case 29: oss << u8"\u1d33\u209b"; break; // GS - case 30: oss << u8"\u1d3f\u209b"; break; // RS - case 31: oss << u8"\u1d41\u209b"; break; // US + case 4: oss << "\u1d31\u1d52\u209c"; break; // EOT + case 28: oss << "\ua7f3\u209b"; break; // FS + case 29: oss << "\u1d33\u209b"; break; // GS + case 30: oss << "\u1d3f\u209b"; break; // RS + case 31: oss << "\u1d41\u209b"; break; // US default: oss << c; } } diff --git a/core/src/Utf.cpp b/core/src/Utf.cpp index ed5dc972ef..66878c9ece 100644 --- a/core/src/Utf.cpp +++ b/core/src/Utf.cpp @@ -18,7 +18,9 @@ namespace ZXing { // TODO: c++20 has char8_t +#if __cplusplus <= 201703L using char8_t = uint8_t; +#endif using utf8_t = std::basic_string_view; using state_t = uint8_t; diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp index 246680b5c2..5b0966e10c 100644 --- a/test/unit/ContentTest.cpp +++ b/test/unit/ContentTest.cpp @@ -25,14 +25,14 @@ TEST(ContentTest, Base) Content c; c.switchEncoding(CharacterSet::ISO8859_1); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), u8"A\u00E9Z"); + EXPECT_EQ(c.utf8(), "A\u00E9Z"); } { // set CharacterSet::ISO8859_5 Content c; c.switchEncoding(CharacterSet::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), u8"A\u0449Z"); + EXPECT_EQ(c.utf8(), "A\u0449Z"); } { // switch to CharacterSet::ISO8859_5 @@ -42,7 +42,7 @@ TEST(ContentTest, Base) c.switchEncoding(CharacterSet::ISO8859_5); EXPECT_FALSE(c.hasECI); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), u8"A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf8(), "A\u00E9ZA\u0449Z"); } } @@ -52,7 +52,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::ISO8859_1); - EXPECT_EQ(c.utf8(), u8"A\u00E9Z"); + EXPECT_EQ(c.utf8(), "A\u00E9Z"); EXPECT_EQ(c.bytesECI(), c.bytes); } @@ -60,7 +60,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::Shift_JIS); - EXPECT_EQ(c.utf8(), u8"A\u30C6Z"); + EXPECT_EQ(c.utf8(), "A\u30C6Z"); } } @@ -72,7 +72,7 @@ TEST(ContentTest, ECI) c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_TRUE(c.hasECI); - EXPECT_EQ(c.utf8(), u8"A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf8(), "A\u00E9ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\xE9Z\\000007A\xE9Z")); } @@ -81,14 +81,14 @@ TEST(ContentTest, ECI) c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), u8"A\u0083\u0065ZA\u0449Z"); + EXPECT_EQ(c.utf8(), "A\u0083\u0065ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\x83\x65Z\\000007A\xE9Z")); } { // double '\' Content c; c.append("C:\\Test"); - EXPECT_EQ(c.utf8(), u8"C:\\Test"); + EXPECT_EQ(c.utf8(), "C:\\Test"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("C:\\\\Test")); } } diff --git a/test/unit/TextEncoderTest.cpp b/test/unit/TextEncoderTest.cpp index 3f3cfc283c..a1353cdb04 100644 --- a/test/unit/TextEncoderTest.cpp +++ b/test/unit/TextEncoderTest.cpp @@ -24,42 +24,42 @@ void EnDeCode(CharacterSet cs, const char* in, std::string_view out) TEST(TextEncoderTest, FullCycleEncodeDecode) { - EnDeCode(CharacterSet::Cp437, u8"\u00C7", "\x80"); // LATIN CAPITAL LETTER C WITH CEDILLA - EnDeCode(CharacterSet::ISO8859_1, u8"\u00A0", "\xA0"); // NO-BREAK SPACE - EnDeCode(CharacterSet::ISO8859_2, u8"\u0104", "\xA1"); // LATIN CAPITAL LETTER A WITH OGONEK - EnDeCode(CharacterSet::ISO8859_3, u8"\u0126", "\xA1"); // LATIN CAPITAL LETTER H WITH STROKE - EnDeCode(CharacterSet::ISO8859_4, u8"\u0138", "\xA2"); // LATIN SMALL LETTER KRA - EnDeCode(CharacterSet::ISO8859_5, u8"\u045F", "\xFF"); // CYRILLIC SMALL LETTER DZHE - EnDeCode(CharacterSet::ISO8859_6, u8"\u0652", "\xF2"); // ARABIC SUKUN - EnDeCode(CharacterSet::ISO8859_7, u8"\u03CE", "\xFE"); // GREEK SMALL LETTER OMEGA WITH TONOS - EnDeCode(CharacterSet::ISO8859_8, u8"\u05EA", "\xFA"); // HEBREW LETTER TAV - EnDeCode(CharacterSet::ISO8859_9, u8"\u011E", "\xD0"); // LATIN CAPITAL LETTER G WITH BREVE - EnDeCode(CharacterSet::ISO8859_10, u8"\u0138", "\xFF"); // LATIN SMALL LETTER KRA - EnDeCode(CharacterSet::ISO8859_11, u8"\u0E5B", "\xFB"); // THAI CHARACTER KHOMUT - EnDeCode(CharacterSet::ISO8859_13, u8"\u2019", "\xFF"); // RIGHT SINGLE QUOTATION MARK - EnDeCode(CharacterSet::ISO8859_14, u8"\u1E6B", "\xF7"); // LATIN SMALL LETTER T WITH DOT ABOVE - EnDeCode(CharacterSet::ISO8859_15, u8"\u00BF", "\xBF"); // INVERTED QUESTION MARK - EnDeCode(CharacterSet::ISO8859_16, u8"\u017C", "\xBF"); // LATIN SMALL LETTER Z WITH DOT ABOVE -// EnDeCode(CharacterSet::Shift_JIS, u8"\u00A5", "\x5C"); // YEN SIGN Mapped to backslash -// EnDeCode(CharacterSet::Shift_JIS, u8"\u203E", "\x7E"); // OVERLINE Mapped to tilde - EnDeCode(CharacterSet::Shift_JIS, u8"\u3000", "\x81\x40"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::Cp1250, u8"\u20AC", "\x80"); // EURO SIGN - EnDeCode(CharacterSet::Cp1251, u8"\u045F", "\x9F"); // CYRILLIC SMALL LETTER DZHE - EnDeCode(CharacterSet::Cp1252, u8"\u02DC", "\x98"); // SMALL TILDE - EnDeCode(CharacterSet::Cp1256, u8"\u0686", "\x8D"); // ARABIC LETTER TCHEH - EnDeCode(CharacterSet::UTF16BE, u8"\u20AC", "\x20\xAC"); // EURO SIGN - EnDeCode(CharacterSet::UTF8, u8"\u20AC", "\xE2\x82\xAC"); // EURO SIGN + EnDeCode(CharacterSet::Cp437, "\u00C7", "\x80"); // LATIN CAPITAL LETTER C WITH CEDILLA + EnDeCode(CharacterSet::ISO8859_1, "\u00A0", "\xA0"); // NO-BREAK SPACE + EnDeCode(CharacterSet::ISO8859_2, "\u0104", "\xA1"); // LATIN CAPITAL LETTER A WITH OGONEK + EnDeCode(CharacterSet::ISO8859_3, "\u0126", "\xA1"); // LATIN CAPITAL LETTER H WITH STROKE + EnDeCode(CharacterSet::ISO8859_4, "\u0138", "\xA2"); // LATIN SMALL LETTER KRA + EnDeCode(CharacterSet::ISO8859_5, "\u045F", "\xFF"); // CYRILLIC SMALL LETTER DZHE + EnDeCode(CharacterSet::ISO8859_6, "\u0652", "\xF2"); // ARABIC SUKUN + EnDeCode(CharacterSet::ISO8859_7, "\u03CE", "\xFE"); // GREEK SMALL LETTER OMEGA WITH TONOS + EnDeCode(CharacterSet::ISO8859_8, "\u05EA", "\xFA"); // HEBREW LETTER TAV + EnDeCode(CharacterSet::ISO8859_9, "\u011E", "\xD0"); // LATIN CAPITAL LETTER G WITH BREVE + EnDeCode(CharacterSet::ISO8859_10, "\u0138", "\xFF"); // LATIN SMALL LETTER KRA + EnDeCode(CharacterSet::ISO8859_11, "\u0E5B", "\xFB"); // THAI CHARACTER KHOMUT + EnDeCode(CharacterSet::ISO8859_13, "\u2019", "\xFF"); // RIGHT SINGLE QUOTATION MARK + EnDeCode(CharacterSet::ISO8859_14, "\u1E6B", "\xF7"); // LATIN SMALL LETTER T WITH DOT ABOVE + EnDeCode(CharacterSet::ISO8859_15, "\u00BF", "\xBF"); // INVERTED QUESTION MARK + EnDeCode(CharacterSet::ISO8859_16, "\u017C", "\xBF"); // LATIN SMALL LETTER Z WITH DOT ABOVE +// EnDeCode(CharacterSet::Shift_JIS, "\u00A5", "\x5C"); // YEN SIGN Mapped to backslash +// EnDeCode(CharacterSet::Shift_JIS, "\u203E", "\x7E"); // OVERLINE Mapped to tilde + EnDeCode(CharacterSet::Shift_JIS, "\u3000", "\x81\x40"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::Cp1250, "\u20AC", "\x80"); // EURO SIGN + EnDeCode(CharacterSet::Cp1251, "\u045F", "\x9F"); // CYRILLIC SMALL LETTER DZHE + EnDeCode(CharacterSet::Cp1252, "\u02DC", "\x98"); // SMALL TILDE + EnDeCode(CharacterSet::Cp1256, "\u0686", "\x8D"); // ARABIC LETTER TCHEH + EnDeCode(CharacterSet::UTF16BE, "\u20AC", "\x20\xAC"); // EURO SIGN + EnDeCode(CharacterSet::UTF8, "\u20AC", "\xE2\x82\xAC"); // EURO SIGN EnDeCode(CharacterSet::ASCII, "#", "#"); - EnDeCode(CharacterSet::Big5, u8"\u3000", "\xA1\x40"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::GB2312, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::EUC_KR, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE -// EnDeCode(CharacterSet::GBK, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::GB18030, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::UTF16LE, u8"\u20AC", "\xAC\x20"); // EURO SIGN - EnDeCode(CharacterSet::UTF32BE, u8"\u20AC", std::string("\x00\x00\x20\xAC", 4)); // EURO SIGN - EnDeCode(CharacterSet::UTF32LE, u8"\u20AC", std::string("\xAC\x20\x00\x00", 4)); // EURO SIGN + EnDeCode(CharacterSet::Big5, "\u3000", "\xA1\x40"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::GB2312, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::EUC_KR, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE +// EnDeCode(CharacterSet::GBK, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::GB18030, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::UTF16LE, "\u20AC", "\xAC\x20"); // EURO SIGN + EnDeCode(CharacterSet::UTF32BE, "\u20AC", std::string("\x00\x00\x20\xAC", 4)); // EURO SIGN + EnDeCode(CharacterSet::UTF32LE, "\u20AC", std::string("\xAC\x20\x00\x00", 4)); // EURO SIGN // EnDeCode(CharacterSet::ISO646_Inv, "%", "%"); - EnDeCode(CharacterSet::BINARY, u8"\u0080\u00FF", "\x80\xFF"); - EnDeCode(CharacterSet::Unknown, u8"\u0080", "\x80"); // Treated as binary - EnDeCode(CharacterSet::EUC_JP, u8"\u0080", "\x80"); // Not supported, treated as binary + EnDeCode(CharacterSet::BINARY, "\u0080\u00FF", "\x80\xFF"); + EnDeCode(CharacterSet::Unknown, "\u0080", "\x80"); // Treated as binary + EnDeCode(CharacterSet::EUC_JP, "\u0080", "\x80"); // Not supported, treated as binary } diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index fdae906541..8a9867aaec 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -13,21 +13,21 @@ using namespace ZXing; TEST(TextUtfEncodingTest, EscapeNonGraphical) { - EXPECT_EQ(EscapeNonGraphical(u8"\u00B6\u0416"), "¶Ж"); - EXPECT_EQ(EscapeNonGraphical(u8"\x01\x1F\x7F"), ""); - EXPECT_EQ(EscapeNonGraphical(u8"\u0080\u009F"), ""); - EXPECT_EQ(EscapeNonGraphical(u8"\u00A0"), ""); // NO-BREAK space (nbsp) - EXPECT_EQ(EscapeNonGraphical(u8"\u2007"), ""); // NO-BREAK space (numsp) - EXPECT_EQ(EscapeNonGraphical(u8"\uFFEF"), ""); // Was NO-BREAK space but now isn't (BOM) - EXPECT_EQ(EscapeNonGraphical(u8"\u2000"), ""); // Space char (nqsp) - EXPECT_EQ(EscapeNonGraphical(u8"\uFFFD"), ""); - EXPECT_EQ(EscapeNonGraphical(u8"\uFFFF"), ""); + EXPECT_EQ(EscapeNonGraphical("\u00B6\u0416"), "¶Ж"); + EXPECT_EQ(EscapeNonGraphical("\x01\x1F\x7F"), ""); + EXPECT_EQ(EscapeNonGraphical("\u0080\u009F"), ""); + EXPECT_EQ(EscapeNonGraphical("\u00A0"), ""); // NO-BREAK space (nbsp) + EXPECT_EQ(EscapeNonGraphical("\u2007"), ""); // NO-BREAK space (numsp) + EXPECT_EQ(EscapeNonGraphical("\uFFEF"), ""); // Was NO-BREAK space but now isn't (BOM) + EXPECT_EQ(EscapeNonGraphical("\u2000"), ""); // Space char (nqsp) + EXPECT_EQ(EscapeNonGraphical("\uFFFD"), ""); + EXPECT_EQ(EscapeNonGraphical("\uFFFF"), ""); } TEST(TextUtfEncodingTest, FromUtf8) { - EXPECT_EQ(FromUtf8(u8"\U00010000"), L"\U00010000"); - EXPECT_EQ(FromUtf8(u8"\U00010FFF"), L"\U00010FFF"); + EXPECT_EQ(FromUtf8("\U00010000"), L"\U00010000"); + EXPECT_EQ(FromUtf8("\U00010FFF"), L"\U00010FFF"); EXPECT_EQ(FromUtf8("A\xE8\x80\xBFG"), L"A\u803FG"); // U+803F // EXPECT_EQ(FromUtf8("A\xE8\x80\xBF\x80G"), L"A\u803FG"); // Bad UTF-8 (extra continuation byte) From 299f66f26cbbef6794f4c7f0d043285693bae8d8 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 10 Aug 2022 13:32:03 +0200 Subject: [PATCH 0458/1315] DataMatrix: fix #378 --- core/src/datamatrix/DMDetector.cpp | 9 ++++++--- test/blackbox/BlackboxTestRunner.cpp | 6 +++--- test/samples/datamatrix-1/#378.png | Bin 0 -> 417 bytes test/samples/datamatrix-1/#378.txt | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 test/samples/datamatrix-1/#378.png create mode 100644 test/samples/datamatrix-1/#378.txt diff --git a/core/src/datamatrix/DMDetector.cpp b/core/src/datamatrix/DMDetector.cpp index b50bbe9057..381ada961a 100644 --- a/core/src/datamatrix/DMDetector.cpp +++ b/core/src/datamatrix/DMDetector.cpp @@ -891,9 +891,10 @@ DetectorResults Detect(const BitMatrix& image, bool tryHarder, bool tryRotate, b found = true; co_yield std::move(r); } - if (!found) { - auto r = DetectOld(image); - if (r.isValid()) + if (!found && tryHarder) { + if (auto r = DetectPure(image); r.isValid()) + co_yield std::move(r); + else if(auto r = DetectOld(image); r.isValid()) co_yield std::move(r); } } @@ -902,6 +903,8 @@ DetectorResults Detect(const BitMatrix& image, bool tryHarder, bool tryRotate, b return DetectPure(image); auto result = DetectNew(image, tryHarder, tryRotate); + if (!result.isValid() && tryHarder) + result = DetectPure(image); if (!result.isValid() && tryHarder) result = DetectOld(image); return result; diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 2a3d9239df..fe14bbd1f7 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -345,12 +345,12 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 3, 3, 270 }, }); - runTests("datamatrix-1", "DataMatrix", 26, { - { 26, 26, 0 }, + runTests("datamatrix-1", "DataMatrix", 27, { + { 26, 27, 0 }, { 0, 26, 90 }, { 0, 26, 180 }, { 0, 26, 270 }, - { 25, 0, pure }, + { 26, 0, pure }, }); runTests("datamatrix-2", "DataMatrix", 13, { diff --git a/test/samples/datamatrix-1/#378.png b/test/samples/datamatrix-1/#378.png new file mode 100644 index 0000000000000000000000000000000000000000..6397b15f5365f19ffdfa3475ca64daa59c43d969 GIT binary patch literal 417 zcmV;S0bc%zP)xZk0000LP)t-s0RaL3 z|NjdM3;Fr^^YioU?Cj|1=nk5=FaQ7nM@d9MR4C6aQo(J+FbpHK0U@VvAsYxe^e?0f zWQ6X&L`kPUoKKcylA;e_G!g@9XY3uVFA=N`hg}(W@k|#^#sdZQ0df)eoWz52h$>Vn zACbIjqjX`^9jZdv&V@zwo~jKFU(-=1Ud-a^DD_DQXK<#_7{9d!x9B#Cu)YurWf_vY zintg$M>r+TTCLhLv~?*+EsCB}sHA2|jfWVdn3zqgil&DUQ04{JjmsFL3J!7Tr_SMP zQzAuDucDDlp7`)!@oc6xP_e(I&`y?pJIp1QY8ku7TIgYL(_CKrQBs4Cy>y~oitVsu z2w3dlW?fdXd_+A?`{C-##Q0f8UNC{~%lZyd%Fx^4RF_n@rONIZaZ1|A?`@(lsejod zzhtZxWB*Rc7ewk4{b-aE`HJ>4OLD~4t)RA{d%(SWtM~ta{~q8EBfcuP?(Z9C00000 LNkvXXu0mjfPG7!! literal 0 HcmV?d00001 diff --git a/test/samples/datamatrix-1/#378.txt b/test/samples/datamatrix-1/#378.txt new file mode 100644 index 0000000000..d410d15ba5 --- /dev/null +++ b/test/samples/datamatrix-1/#378.txt @@ -0,0 +1 @@ +Data Matrix Code \ No newline at end of file From ce53105b0094e85e991583d0e585833a12ef498a Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 10 Aug 2022 16:09:21 +0200 Subject: [PATCH 0459/1315] Revert "c++20: fix build regressions from u8"" and char8_t usage" This reverts commit d68161a2dc28e3e68f8bcac738e884dbd13ae447. Which introduced a new build regression on MSVC. MSVC and gcc/clang disagree on what the spec says, it seems. :-( --- core/src/HRI.cpp | 10 ++--- core/src/Utf.cpp | 2 - test/unit/ContentTest.cpp | 16 +++---- test/unit/TextEncoderTest.cpp | 72 +++++++++++++++---------------- test/unit/TextUtfEncodingTest.cpp | 22 +++++----- 5 files changed, 60 insertions(+), 62 deletions(-) diff --git a/core/src/HRI.cpp b/core/src/HRI.cpp index 580d23f58c..847581c9eb 100644 --- a/core/src/HRI.cpp +++ b/core/src/HRI.cpp @@ -292,11 +292,11 @@ std::string HRIFromISO15434(std::string_view str) for (char c : str) { switch (c) { - case 4: oss << "\u1d31\u1d52\u209c"; break; // EOT - case 28: oss << "\ua7f3\u209b"; break; // FS - case 29: oss << "\u1d33\u209b"; break; // GS - case 30: oss << "\u1d3f\u209b"; break; // RS - case 31: oss << "\u1d41\u209b"; break; // US + case 4: oss << u8"\u1d31\u1d52\u209c"; break; // EOT + case 28: oss << u8"\ua7f3\u209b"; break; // FS + case 29: oss << u8"\u1d33\u209b"; break; // GS + case 30: oss << u8"\u1d3f\u209b"; break; // RS + case 31: oss << u8"\u1d41\u209b"; break; // US default: oss << c; } } diff --git a/core/src/Utf.cpp b/core/src/Utf.cpp index 66878c9ece..ed5dc972ef 100644 --- a/core/src/Utf.cpp +++ b/core/src/Utf.cpp @@ -18,9 +18,7 @@ namespace ZXing { // TODO: c++20 has char8_t -#if __cplusplus <= 201703L using char8_t = uint8_t; -#endif using utf8_t = std::basic_string_view; using state_t = uint8_t; diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp index 5b0966e10c..246680b5c2 100644 --- a/test/unit/ContentTest.cpp +++ b/test/unit/ContentTest.cpp @@ -25,14 +25,14 @@ TEST(ContentTest, Base) Content c; c.switchEncoding(CharacterSet::ISO8859_1); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), "A\u00E9Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9Z"); } { // set CharacterSet::ISO8859_5 Content c; c.switchEncoding(CharacterSet::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), "A\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u0449Z"); } { // switch to CharacterSet::ISO8859_5 @@ -42,7 +42,7 @@ TEST(ContentTest, Base) c.switchEncoding(CharacterSet::ISO8859_5); EXPECT_FALSE(c.hasECI); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), "A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9ZA\u0449Z"); } } @@ -52,7 +52,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::ISO8859_1); - EXPECT_EQ(c.utf8(), "A\u00E9Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9Z"); EXPECT_EQ(c.bytesECI(), c.bytes); } @@ -60,7 +60,7 @@ TEST(ContentTest, GuessEncoding) Content c; c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); EXPECT_EQ(c.guessEncoding(), CharacterSet::Shift_JIS); - EXPECT_EQ(c.utf8(), "A\u30C6Z"); + EXPECT_EQ(c.utf8(), u8"A\u30C6Z"); } } @@ -72,7 +72,7 @@ TEST(ContentTest, ECI) c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); EXPECT_TRUE(c.hasECI); - EXPECT_EQ(c.utf8(), "A\u00E9ZA\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u00E9ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\xE9Z\\000007A\xE9Z")); } @@ -81,14 +81,14 @@ TEST(ContentTest, ECI) c.append(ByteArray{'A', 0x83, 0x65, 'Z'}); c.switchEncoding(ECI::ISO8859_5); c.append(ByteArray{'A', 0xE9, 'Z'}); - EXPECT_EQ(c.utf8(), "A\u0083\u0065ZA\u0449Z"); + EXPECT_EQ(c.utf8(), u8"A\u0083\u0065ZA\u0449Z"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("\\000003A\x83\x65Z\\000007A\xE9Z")); } { // double '\' Content c; c.append("C:\\Test"); - EXPECT_EQ(c.utf8(), "C:\\Test"); + EXPECT_EQ(c.utf8(), u8"C:\\Test"); EXPECT_EQ(c.bytesECI().asString(), std::string_view("C:\\\\Test")); } } diff --git a/test/unit/TextEncoderTest.cpp b/test/unit/TextEncoderTest.cpp index a1353cdb04..3f3cfc283c 100644 --- a/test/unit/TextEncoderTest.cpp +++ b/test/unit/TextEncoderTest.cpp @@ -24,42 +24,42 @@ void EnDeCode(CharacterSet cs, const char* in, std::string_view out) TEST(TextEncoderTest, FullCycleEncodeDecode) { - EnDeCode(CharacterSet::Cp437, "\u00C7", "\x80"); // LATIN CAPITAL LETTER C WITH CEDILLA - EnDeCode(CharacterSet::ISO8859_1, "\u00A0", "\xA0"); // NO-BREAK SPACE - EnDeCode(CharacterSet::ISO8859_2, "\u0104", "\xA1"); // LATIN CAPITAL LETTER A WITH OGONEK - EnDeCode(CharacterSet::ISO8859_3, "\u0126", "\xA1"); // LATIN CAPITAL LETTER H WITH STROKE - EnDeCode(CharacterSet::ISO8859_4, "\u0138", "\xA2"); // LATIN SMALL LETTER KRA - EnDeCode(CharacterSet::ISO8859_5, "\u045F", "\xFF"); // CYRILLIC SMALL LETTER DZHE - EnDeCode(CharacterSet::ISO8859_6, "\u0652", "\xF2"); // ARABIC SUKUN - EnDeCode(CharacterSet::ISO8859_7, "\u03CE", "\xFE"); // GREEK SMALL LETTER OMEGA WITH TONOS - EnDeCode(CharacterSet::ISO8859_8, "\u05EA", "\xFA"); // HEBREW LETTER TAV - EnDeCode(CharacterSet::ISO8859_9, "\u011E", "\xD0"); // LATIN CAPITAL LETTER G WITH BREVE - EnDeCode(CharacterSet::ISO8859_10, "\u0138", "\xFF"); // LATIN SMALL LETTER KRA - EnDeCode(CharacterSet::ISO8859_11, "\u0E5B", "\xFB"); // THAI CHARACTER KHOMUT - EnDeCode(CharacterSet::ISO8859_13, "\u2019", "\xFF"); // RIGHT SINGLE QUOTATION MARK - EnDeCode(CharacterSet::ISO8859_14, "\u1E6B", "\xF7"); // LATIN SMALL LETTER T WITH DOT ABOVE - EnDeCode(CharacterSet::ISO8859_15, "\u00BF", "\xBF"); // INVERTED QUESTION MARK - EnDeCode(CharacterSet::ISO8859_16, "\u017C", "\xBF"); // LATIN SMALL LETTER Z WITH DOT ABOVE -// EnDeCode(CharacterSet::Shift_JIS, "\u00A5", "\x5C"); // YEN SIGN Mapped to backslash -// EnDeCode(CharacterSet::Shift_JIS, "\u203E", "\x7E"); // OVERLINE Mapped to tilde - EnDeCode(CharacterSet::Shift_JIS, "\u3000", "\x81\x40"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::Cp1250, "\u20AC", "\x80"); // EURO SIGN - EnDeCode(CharacterSet::Cp1251, "\u045F", "\x9F"); // CYRILLIC SMALL LETTER DZHE - EnDeCode(CharacterSet::Cp1252, "\u02DC", "\x98"); // SMALL TILDE - EnDeCode(CharacterSet::Cp1256, "\u0686", "\x8D"); // ARABIC LETTER TCHEH - EnDeCode(CharacterSet::UTF16BE, "\u20AC", "\x20\xAC"); // EURO SIGN - EnDeCode(CharacterSet::UTF8, "\u20AC", "\xE2\x82\xAC"); // EURO SIGN + EnDeCode(CharacterSet::Cp437, u8"\u00C7", "\x80"); // LATIN CAPITAL LETTER C WITH CEDILLA + EnDeCode(CharacterSet::ISO8859_1, u8"\u00A0", "\xA0"); // NO-BREAK SPACE + EnDeCode(CharacterSet::ISO8859_2, u8"\u0104", "\xA1"); // LATIN CAPITAL LETTER A WITH OGONEK + EnDeCode(CharacterSet::ISO8859_3, u8"\u0126", "\xA1"); // LATIN CAPITAL LETTER H WITH STROKE + EnDeCode(CharacterSet::ISO8859_4, u8"\u0138", "\xA2"); // LATIN SMALL LETTER KRA + EnDeCode(CharacterSet::ISO8859_5, u8"\u045F", "\xFF"); // CYRILLIC SMALL LETTER DZHE + EnDeCode(CharacterSet::ISO8859_6, u8"\u0652", "\xF2"); // ARABIC SUKUN + EnDeCode(CharacterSet::ISO8859_7, u8"\u03CE", "\xFE"); // GREEK SMALL LETTER OMEGA WITH TONOS + EnDeCode(CharacterSet::ISO8859_8, u8"\u05EA", "\xFA"); // HEBREW LETTER TAV + EnDeCode(CharacterSet::ISO8859_9, u8"\u011E", "\xD0"); // LATIN CAPITAL LETTER G WITH BREVE + EnDeCode(CharacterSet::ISO8859_10, u8"\u0138", "\xFF"); // LATIN SMALL LETTER KRA + EnDeCode(CharacterSet::ISO8859_11, u8"\u0E5B", "\xFB"); // THAI CHARACTER KHOMUT + EnDeCode(CharacterSet::ISO8859_13, u8"\u2019", "\xFF"); // RIGHT SINGLE QUOTATION MARK + EnDeCode(CharacterSet::ISO8859_14, u8"\u1E6B", "\xF7"); // LATIN SMALL LETTER T WITH DOT ABOVE + EnDeCode(CharacterSet::ISO8859_15, u8"\u00BF", "\xBF"); // INVERTED QUESTION MARK + EnDeCode(CharacterSet::ISO8859_16, u8"\u017C", "\xBF"); // LATIN SMALL LETTER Z WITH DOT ABOVE +// EnDeCode(CharacterSet::Shift_JIS, u8"\u00A5", "\x5C"); // YEN SIGN Mapped to backslash +// EnDeCode(CharacterSet::Shift_JIS, u8"\u203E", "\x7E"); // OVERLINE Mapped to tilde + EnDeCode(CharacterSet::Shift_JIS, u8"\u3000", "\x81\x40"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::Cp1250, u8"\u20AC", "\x80"); // EURO SIGN + EnDeCode(CharacterSet::Cp1251, u8"\u045F", "\x9F"); // CYRILLIC SMALL LETTER DZHE + EnDeCode(CharacterSet::Cp1252, u8"\u02DC", "\x98"); // SMALL TILDE + EnDeCode(CharacterSet::Cp1256, u8"\u0686", "\x8D"); // ARABIC LETTER TCHEH + EnDeCode(CharacterSet::UTF16BE, u8"\u20AC", "\x20\xAC"); // EURO SIGN + EnDeCode(CharacterSet::UTF8, u8"\u20AC", "\xE2\x82\xAC"); // EURO SIGN EnDeCode(CharacterSet::ASCII, "#", "#"); - EnDeCode(CharacterSet::Big5, "\u3000", "\xA1\x40"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::GB2312, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::EUC_KR, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE -// EnDeCode(CharacterSet::GBK, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::GB18030, "\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE - EnDeCode(CharacterSet::UTF16LE, "\u20AC", "\xAC\x20"); // EURO SIGN - EnDeCode(CharacterSet::UTF32BE, "\u20AC", std::string("\x00\x00\x20\xAC", 4)); // EURO SIGN - EnDeCode(CharacterSet::UTF32LE, "\u20AC", std::string("\xAC\x20\x00\x00", 4)); // EURO SIGN + EnDeCode(CharacterSet::Big5, u8"\u3000", "\xA1\x40"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::GB2312, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::EUC_KR, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE +// EnDeCode(CharacterSet::GBK, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::GB18030, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE + EnDeCode(CharacterSet::UTF16LE, u8"\u20AC", "\xAC\x20"); // EURO SIGN + EnDeCode(CharacterSet::UTF32BE, u8"\u20AC", std::string("\x00\x00\x20\xAC", 4)); // EURO SIGN + EnDeCode(CharacterSet::UTF32LE, u8"\u20AC", std::string("\xAC\x20\x00\x00", 4)); // EURO SIGN // EnDeCode(CharacterSet::ISO646_Inv, "%", "%"); - EnDeCode(CharacterSet::BINARY, "\u0080\u00FF", "\x80\xFF"); - EnDeCode(CharacterSet::Unknown, "\u0080", "\x80"); // Treated as binary - EnDeCode(CharacterSet::EUC_JP, "\u0080", "\x80"); // Not supported, treated as binary + EnDeCode(CharacterSet::BINARY, u8"\u0080\u00FF", "\x80\xFF"); + EnDeCode(CharacterSet::Unknown, u8"\u0080", "\x80"); // Treated as binary + EnDeCode(CharacterSet::EUC_JP, u8"\u0080", "\x80"); // Not supported, treated as binary } diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index 8a9867aaec..fdae906541 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -13,21 +13,21 @@ using namespace ZXing; TEST(TextUtfEncodingTest, EscapeNonGraphical) { - EXPECT_EQ(EscapeNonGraphical("\u00B6\u0416"), "¶Ж"); - EXPECT_EQ(EscapeNonGraphical("\x01\x1F\x7F"), ""); - EXPECT_EQ(EscapeNonGraphical("\u0080\u009F"), ""); - EXPECT_EQ(EscapeNonGraphical("\u00A0"), ""); // NO-BREAK space (nbsp) - EXPECT_EQ(EscapeNonGraphical("\u2007"), ""); // NO-BREAK space (numsp) - EXPECT_EQ(EscapeNonGraphical("\uFFEF"), ""); // Was NO-BREAK space but now isn't (BOM) - EXPECT_EQ(EscapeNonGraphical("\u2000"), ""); // Space char (nqsp) - EXPECT_EQ(EscapeNonGraphical("\uFFFD"), ""); - EXPECT_EQ(EscapeNonGraphical("\uFFFF"), ""); + EXPECT_EQ(EscapeNonGraphical(u8"\u00B6\u0416"), "¶Ж"); + EXPECT_EQ(EscapeNonGraphical(u8"\x01\x1F\x7F"), ""); + EXPECT_EQ(EscapeNonGraphical(u8"\u0080\u009F"), ""); + EXPECT_EQ(EscapeNonGraphical(u8"\u00A0"), ""); // NO-BREAK space (nbsp) + EXPECT_EQ(EscapeNonGraphical(u8"\u2007"), ""); // NO-BREAK space (numsp) + EXPECT_EQ(EscapeNonGraphical(u8"\uFFEF"), ""); // Was NO-BREAK space but now isn't (BOM) + EXPECT_EQ(EscapeNonGraphical(u8"\u2000"), ""); // Space char (nqsp) + EXPECT_EQ(EscapeNonGraphical(u8"\uFFFD"), ""); + EXPECT_EQ(EscapeNonGraphical(u8"\uFFFF"), ""); } TEST(TextUtfEncodingTest, FromUtf8) { - EXPECT_EQ(FromUtf8("\U00010000"), L"\U00010000"); - EXPECT_EQ(FromUtf8("\U00010FFF"), L"\U00010FFF"); + EXPECT_EQ(FromUtf8(u8"\U00010000"), L"\U00010000"); + EXPECT_EQ(FromUtf8(u8"\U00010FFF"), L"\U00010FFF"); EXPECT_EQ(FromUtf8("A\xE8\x80\xBFG"), L"A\u803FG"); // U+803F // EXPECT_EQ(FromUtf8("A\xE8\x80\xBF\x80G"), L"A\u803FG"); // Bad UTF-8 (extra continuation byte) From 903e1ecf6d8b8ae42e007b3c0eb7d3ac1b86c51c Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 10 Aug 2022 17:03:44 +0200 Subject: [PATCH 0460/1315] c++20: 2nd attempt to fix build regressions from u8"" and char8_t usage ugly: `const char8_t* u8""` character literals are apparently a source of frustration in c++20. Hope this works on c++17/20 and cross platform. See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2513r1.html --- core/src/HRI.cpp | 7 +++++++ core/src/Utf.cpp | 11 +++++++++++ core/src/Utf.h | 3 +++ test/unit/ContentTest.cpp | 9 +++++++++ test/unit/TextEncoderTest.cpp | 9 +++++---- test/unit/TextUtfEncodingTest.cpp | 7 +++++++ 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/core/src/HRI.cpp b/core/src/HRI.cpp index 847581c9eb..df0f0a90b4 100644 --- a/core/src/HRI.cpp +++ b/core/src/HRI.cpp @@ -283,6 +283,13 @@ std::string HRIFromGS1(std::string_view gs1) return res; } +#if __cplusplus > 201703L +std::ostream& operator<<(std::ostream& os, const char8_t* str) +{ + return os << reinterpret_cast(str); +} +#endif + std::string HRIFromISO15434(std::string_view str) { // Use available unicode symbols to simulate sub- and superscript letters as specified in diff --git a/core/src/Utf.cpp b/core/src/Utf.cpp index ed5dc972ef..9cfee9373b 100644 --- a/core/src/Utf.cpp +++ b/core/src/Utf.cpp @@ -18,7 +18,9 @@ namespace ZXing { // TODO: c++20 has char8_t +#if __cplusplus <= 201703L using char8_t = uint8_t; +#endif using utf8_t = std::basic_string_view; using state_t = uint8_t; @@ -121,6 +123,15 @@ std::wstring FromUtf8(std::string_view utf8) return str; } +#if __cplusplus > 201703L +std::wstring FromUtf8(std::u8string_view utf8) +{ + std::wstring str; + AppendFromUtf8(utf8, str); + return str; +} +#endif + // Count the number of bytes required to store given code points in UTF-8. static size_t Utf8CountBytes(std::wstring_view str) { diff --git a/core/src/Utf.h b/core/src/Utf.h index cd90f8a4af..bb31a1c94b 100644 --- a/core/src/Utf.h +++ b/core/src/Utf.h @@ -12,6 +12,9 @@ namespace ZXing { std::string ToUtf8(std::wstring_view str); std::wstring FromUtf8(std::string_view utf8); +#if __cplusplus > 201703L +std::wstring FromUtf8(std::u8string_view utf8); +#endif std::wstring EscapeNonGraphical(std::wstring_view str); std::string EscapeNonGraphical(std::string_view utf8); diff --git a/test/unit/ContentTest.cpp b/test/unit/ContentTest.cpp index 246680b5c2..982c3d6ffd 100644 --- a/test/unit/ContentTest.cpp +++ b/test/unit/ContentTest.cpp @@ -12,6 +12,15 @@ using namespace ZXing; using namespace testing; +#if __cplusplus > 201703L +namespace std { +bool operator==(const string& lhs, const char8_t* rhs) +{ + return lhs == reinterpret_cast(rhs); +} +} // namespace std +#endif + TEST(ContentTest, Base) { { // Null diff --git a/test/unit/TextEncoderTest.cpp b/test/unit/TextEncoderTest.cpp index 3f3cfc283c..a0f64d9a3a 100644 --- a/test/unit/TextEncoderTest.cpp +++ b/test/unit/TextEncoderTest.cpp @@ -12,14 +12,15 @@ using namespace ZXing; using namespace testing; -void EnDeCode(CharacterSet cs, const char* in, std::string_view out) +template +void EnDeCode(CharacterSet cs, const CharT* in, std::string_view out) { - std::string bytes = TextEncoder::FromUnicode(in, cs); + std::string bytes = TextEncoder::FromUnicode(reinterpret_cast(in), cs); EXPECT_EQ(bytes, out); std::string dec; TextDecoder::Append(dec, reinterpret_cast(bytes.data()), bytes.size(), cs); - EXPECT_EQ(dec, in); + EXPECT_EQ(dec, reinterpret_cast(in)); } TEST(TextEncoderTest, FullCycleEncodeDecode) @@ -49,7 +50,7 @@ TEST(TextEncoderTest, FullCycleEncodeDecode) EnDeCode(CharacterSet::Cp1256, u8"\u0686", "\x8D"); // ARABIC LETTER TCHEH EnDeCode(CharacterSet::UTF16BE, u8"\u20AC", "\x20\xAC"); // EURO SIGN EnDeCode(CharacterSet::UTF8, u8"\u20AC", "\xE2\x82\xAC"); // EURO SIGN - EnDeCode(CharacterSet::ASCII, "#", "#"); + EnDeCode(CharacterSet::ASCII, u8"#", "#"); EnDeCode(CharacterSet::Big5, u8"\u3000", "\xA1\x40"); // IDEOGRAPHIC SPACE EnDeCode(CharacterSet::GB2312, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE EnDeCode(CharacterSet::EUC_KR, u8"\u3000", "\xA1\xA1"); // IDEOGRAPHIC SPACE diff --git a/test/unit/TextUtfEncodingTest.cpp b/test/unit/TextUtfEncodingTest.cpp index fdae906541..da7613540c 100644 --- a/test/unit/TextUtfEncodingTest.cpp +++ b/test/unit/TextUtfEncodingTest.cpp @@ -11,6 +11,13 @@ using namespace ZXing; +#if __cplusplus > 201703L +std::string EscapeNonGraphical(const char8_t* utf8) +{ + return EscapeNonGraphical(reinterpret_cast(utf8)); +} +#endif + TEST(TextUtfEncodingTest, EscapeNonGraphical) { EXPECT_EQ(EscapeNonGraphical(u8"\u00B6\u0416"), "¶Ж"); From 7a0e7a679b89cfaeec87728b046a64c4f214ad27 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 10 Aug 2022 23:57:38 +0200 Subject: [PATCH 0461/1315] ci: add ASAN+UBSAN job and sanitizer support for unit tests --- .github/workflows/ci.yml | 21 ++++++++++++++++++++- test/unit/CMakeLists.txt | 1 + test/unit/SanitizerSupport.cpp | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/unit/SanitizerSupport.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23bf7aec08..9d582b9700 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,26 @@ jobs: # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest -V -C $BUILD_TYPE - + + build-ubuntu-sanitize: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{github.ref}} + - name: Create Build Environment + run: cmake -E make_directory ${{runner.workspace}}/build + + - name: Configure + run: cmake -S $GITHUB_WORKSPACE -B ${{runner.workspace}}/build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_BLACKBOX_TESTS=ON -DBUILD_UNIT_TESTS=ON -DBUILD_PYTHON_MODULE=OFF -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=-march=native -fsanitize=address,undefined -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer + + - name: Build + run: cmake --build ${{runner.workspace}}/build -j8 + + - name: Test + working-directory: ${{runner.workspace}}/build + run: ctest -V + build-ios: runs-on: macos-latest steps: diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 42ce8dd50a..db8b443977 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable (UnitTest GTINTest.cpp GS1Test.cpp ReedSolomonTest.cpp + SanitizerSupport.cpp TextDecoderTest.cpp TextEncoderTest.cpp TextUtfEncodingTest.cpp diff --git a/test/unit/SanitizerSupport.cpp b/test/unit/SanitizerSupport.cpp new file mode 100644 index 0000000000..002ae5501e --- /dev/null +++ b/test/unit/SanitizerSupport.cpp @@ -0,0 +1,15 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "gtest/gtest.h" + +// see http://google.github.io/googletest/advanced.html#sanitizer-integration + +extern "C" +{ + void __ubsan_on_report() { FAIL() << "Encountered an undefined behavior sanitizer error"; } + void __asan_on_error() { FAIL() << "Encountered an address sanitizer error"; } + void __tsan_on_report() { FAIL() << "Encountered a thread sanitizer error"; } +} // extern "C" From 2f9d443d99b13fde6b2111f20b1d5ff77fa1e48a Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 11 Aug 2022 00:00:33 +0200 Subject: [PATCH 0462/1315] ci: add missing quotes in new build-ubuntu-sanitize job --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d582b9700..74f00ae829 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: run: cmake -E make_directory ${{runner.workspace}}/build - name: Configure - run: cmake -S $GITHUB_WORKSPACE -B ${{runner.workspace}}/build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_BLACKBOX_TESTS=ON -DBUILD_UNIT_TESTS=ON -DBUILD_PYTHON_MODULE=OFF -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=-march=native -fsanitize=address,undefined -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer + run: cmake -S $GITHUB_WORKSPACE -B ${{runner.workspace}}/build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_BLACKBOX_TESTS=ON -DBUILD_UNIT_TESTS=ON -DBUILD_PYTHON_MODULE=OFF -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS="-march=native -fsanitize=address,undefined -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer" - name: Build run: cmake --build ${{runner.workspace}}/build -j8 From 6e49112ef36265c78d257a69b6b5409be968b5a7 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 11 Aug 2022 00:11:52 +0200 Subject: [PATCH 0463/1315] Pattern: fix UB (applying non-zero offset to null pointer) --- core/src/Pattern.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/Pattern.h b/core/src/Pattern.h index d1e830be1d..ad7a1287fc 100644 --- a/core/src/Pattern.h +++ b/core/src/Pattern.h @@ -60,7 +60,7 @@ class PatternView int size() const { return _size; } // index is the number of bars and spaces from the first bar to the current position - int index() const { return narrow_cast(_data - (_base + 1)); } + int index() const { return narrow_cast(_data - _base) - 1; } int pixelsInFront() const { return std::accumulate(_base, _data, 0); } int pixelsTillEnd() const { return std::accumulate(_base, _data + _size, 0) - 1; } bool isAtFirstBar() const { return _data == _base + 1; } @@ -94,8 +94,7 @@ class PatternView bool shift(int n) { - _data += n; - return _data + _size <= _end; + return _data && ((_data += n) + _size <= _end); } bool skipPair() From fc7eaaa8aa5ed215f9dc3fcb636ea47e4f645d84 Mon Sep 17 00:00:00 2001 From: Qingnan Duan Date: Wed, 17 Aug 2022 00:06:00 +0800 Subject: [PATCH 0464/1315] Enable PIC for Zueci in shared build --- core/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 4faa13d7e3..1d63922a61 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -2,6 +2,9 @@ cmake_minimum_required (VERSION 3.10) include(../zxing.cmake) set(ZUECI_STATIC ON CACHE INTERNAL "") +if (BUILD_SHARED_LIBS) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() zxing_add_package(zueci zueci https://git.code.sf.net/p/libzueci/code master) if (NOT DEFINED BUILD_WRITERS) From 7c9e4bc3ac85a75d2904df8d34d00b00941305e3 Mon Sep 17 00:00:00 2001 From: axxel Date: Tue, 16 Aug 2022 22:50:03 +0200 Subject: [PATCH 0465/1315] HRI: use unicode "Control Pictures" for ASCII control characters Thanks to @gitlost for the inspiration (again). --- core/src/HRI.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/HRI.cpp b/core/src/HRI.cpp index df0f0a90b4..df64114827 100644 --- a/core/src/HRI.cpp +++ b/core/src/HRI.cpp @@ -298,6 +298,12 @@ std::string HRIFromISO15434(std::string_view str) std::ostringstream oss; for (char c : str) { +#if 1 + if (0 <= c && c <= 0x20) + oss << "\xe2\x90" << char(0x80 + c); // Unicode Block “Control Pictures”: 0x2400 + else + oss << c; +#else switch (c) { case 4: oss << u8"\u1d31\u1d52\u209c"; break; // EOT case 28: oss << u8"\ua7f3\u209b"; break; // FS @@ -306,6 +312,7 @@ std::string HRIFromISO15434(std::string_view str) case 31: oss << u8"\u1d41\u209b"; break; // US default: oss << c; } +#endif } return oss.str(); From 5d294557850d8cebc7f922fac20be8cab45f80f8 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 17 Aug 2022 12:54:34 +0200 Subject: [PATCH 0466/1315] README: mention limitations about writing MaxiCode and MQR --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 147e86c33d..85a2e90e4f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ It was originally ported from the Java [ZXing Library](https://github.com/zxing/ | DataBar | DataBar Exanded | PDF417 | | | ITF | MaxiCode (partial) | -[Note: DataBar used to be called RSS. DataBar is not supported for writing.] +[Note: DataBar used to be called RSS. DataBar, MaxiCode and Micro QR Code are not supported for writing.] ## Getting Started From b7f1ed725dbb2b5163a622dd86810d487baa0275 Mon Sep 17 00:00:00 2001 From: Qingnan Duan Date: Thu, 18 Aug 2022 03:26:39 +0800 Subject: [PATCH 0467/1315] Fix C4996 when compiled with MSVC (#381) Replace `sprintf` with `sprintf_s`. --- core/src/ByteArray.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/ByteArray.h b/core/src/ByteArray.h index a68a38090e..b451864d4a 100644 --- a/core/src/ByteArray.h +++ b/core/src/ByteArray.h @@ -38,7 +38,13 @@ inline std::string ToHex(const ByteArray& bytes) std::string res(bytes.size() * 3, ' '); for (size_t i = 0; i < bytes.size(); ++i) + { +#ifdef _MSC_VER + sprintf_s(&res[i * 3], 4, "%02X ", bytes[i]); +#else sprintf(&res[i * 3], "%02X ", bytes[i]); +#endif + } return res.substr(0, res.size()-1); } From 698a7c534bfe5537e4ecbf64a2b3e82416f279b0 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 18 Aug 2022 19:27:32 +0200 Subject: [PATCH 0468/1315] DataBarExpanded: accept symbols with only AI 01 data (fix #384) --- core/src/oned/ODDataBarExpandedBitDecoder.cpp | 2 -- test/blackbox/BlackboxTestRunner.cpp | 8 ++++---- test/samples/rssexpanded-1/#384.png | Bin 0 -> 180 bytes test/samples/rssexpanded-1/#384.txt | 1 + 4 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 test/samples/rssexpanded-1/#384.png create mode 100644 test/samples/rssexpanded-1/#384.txt diff --git a/core/src/oned/ODDataBarExpandedBitDecoder.cpp b/core/src/oned/ODDataBarExpandedBitDecoder.cpp index 6a4924ca71..aa0484769e 100644 --- a/core/src/oned/ODDataBarExpandedBitDecoder.cpp +++ b/core/src/oned/ODDataBarExpandedBitDecoder.cpp @@ -136,8 +136,6 @@ static std::string DecodeAI01AndOtherAIs(BitArrayView& bits) auto header = DecodeCompressedGTIN("01" + std::to_string(bits.readBits(4)), bits); auto trailer = DecodeGeneralPurposeBits(bits); - if (trailer.empty()) - return {}; return header + trailer; } diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index fe14bbd1f7..94d2dc1423 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -525,10 +525,10 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 9, 10, 180 }, }); - runTests("rssexpanded-1", "DataBarExpanded", 33, { - { 33, 33, 0 }, - { 33, 33, 180 }, - { 33, 0, pure }, + runTests("rssexpanded-1", "DataBarExpanded", 34, { + { 34, 34, 0 }, + { 34, 34, 180 }, + { 34, 0, pure }, }); runTests("rssexpanded-2", "DataBarExpanded", 15, { diff --git a/test/samples/rssexpanded-1/#384.png b/test/samples/rssexpanded-1/#384.png new file mode 100644 index 0000000000000000000000000000000000000000..5366aa73b1765422b5320c573889e5e87cdc4219 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0y~yVB8O6^Dr_4$rE1`GZx^prwfgH8~pAc6d{r~^}r8no_1+siRT^vI+&L{u)|Nk-bvB&@W|G!U9Nci#p zv7_zh|Brdz7>S|4PGx+zvzTrOu^I>MY*@qtgfA#-=`oH4`68>FVdQ&MBb@04du@9{>OV literal 0 HcmV?d00001 diff --git a/test/samples/rssexpanded-1/#384.txt b/test/samples/rssexpanded-1/#384.txt new file mode 100644 index 0000000000..1879fa375c --- /dev/null +++ b/test/samples/rssexpanded-1/#384.txt @@ -0,0 +1 @@ +0100000000000000 \ No newline at end of file From e8f4e11a83de61551588d91c565c55086ebf6adc Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 25 Aug 2022 00:24:43 +0200 Subject: [PATCH 0469/1315] update links and comments to refer to new zxing-cpp/zxing-cpp home Basically a nu-book -> zxing-cpp string replacement. --- README.md | 10 +++++----- core/src/ECI.h | 2 +- core/src/Result.h | 2 +- core/src/oned/ODReader.cpp | 2 +- wrappers/python/CMakeLists.txt | 6 +++--- wrappers/python/README.md | 4 ++-- wrappers/python/setup.py | 2 +- wrappers/python/zxing.cpp | 2 +- wrappers/wasm/README.md | 2 +- zxing.cmake | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 85a2e90e4f..931ece72a6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://github.com/nu-book/zxing-cpp/workflows/CI/badge.svg?branch=master)](https://github.com/nu-book/zxing-cpp/actions?query=workflow%3ACI) +[![Build Status](https://github.com/zxing-cpp/zxing-cpp/workflows/CI/badge.svg?branch=master)](https://github.com/zxing-cpp/zxing-cpp/actions?query=workflow%3ACI) # ZXing-C++ @@ -45,9 +45,9 @@ As an example, have a look at [`ZXingWriter.cpp`](example/ZXingWriter.cpp). 3. Convert the bit matrix to your native image format. See also the `ToMatrix(BitMatrix&)` helper function. ## Web Demos -- [Read barcodes](https://nu-book.github.io/zxing-cpp/demo_reader.html) -- [Write barcodes](https://nu-book.github.io/zxing-cpp/demo_writer.html) -- [Scan with camera](https://nu-book.github.io/zxing-cpp/zxing_viddemo.html) +- [Read barcodes](https://zxing-cpp.github.io/zxing-cpp/demo_reader.html) +- [Write barcodes](https://zxing-cpp.github.io/zxing-cpp/demo_writer.html) +- [Scan with camera](https://zxing-cpp.github.io/zxing-cpp/zxing_viddemo.html) [Note: those live demos are not necessarily fully up-to-date at all times.] @@ -59,7 +59,7 @@ These are the generic instructions to build the library on Windows/macOS/Linux. 3. See the cmake `BUILD_...` options to enable the testing code, python wrapper, etc. ``` -git clone https://github.com/nu-book/zxing-cpp.git --single-branch --depth 1 +git clone https://github.com/zxing-cpp/zxing-cpp.git --single-branch --depth 1 cmake -S zxing-cpp -B zxing-cpp.release -DCMAKE_BUILD_TYPE=Release cmake --build zxing-cpp.release -j8 ``` diff --git a/core/src/ECI.h b/core/src/ECI.h index 860038ccb0..691f478007 100644 --- a/core/src/ECI.h +++ b/core/src/ECI.h @@ -61,7 +61,7 @@ inline constexpr bool IsText(ECI eci) inline constexpr bool CanProcess(ECI eci) { - // see https://github.com/nu-book/zxing-cpp/commit/d8587545434d533c4e568181e1c12ef04a8e42d9#r74864359 + // see https://github.com/zxing-cpp/zxing-cpp/commit/d8587545434d533c4e568181e1c12ef04a8e42d9#r74864359 return ToInt(eci) <= 899; } diff --git a/core/src/Result.h b/core/src/Result.h index 32b85b7cb3..d1fdc35df9 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -33,7 +33,7 @@ class Result * @brief utf8/utf16 is the bytes() content converted to utf8/16 based on ECI or guessed character set information * * Note: these two properties might only be available while transitioning text() from std::wstring to std::string. time will tell. - * see https://github.com/nu-book/zxing-cpp/issues/338 for a background discussion on the issue. + * see https://github.com/zxing-cpp/zxing-cpp/issues/338 for a background discussion on the issue. */ std::string utf8() const; std::wstring utfW() const; diff --git a/core/src/oned/ODReader.cpp b/core/src/oned/ODReader.cpp index a616029413..31dbd18b47 100644 --- a/core/src/oned/ODReader.cpp +++ b/core/src/oned/ODReader.cpp @@ -117,7 +117,7 @@ static Results DoDecode(const std::vector>& readers, // TODO: the DataBarExpanded (stacked) decoder depends on seeing each line from both directions. This // 'surprising' and inconsistent. It also requires the decoderState to be shared between normal and reversed // scans, which makes no sense in general because it would mix partial detection data from two codes of the same - // type next to each other. See also https://github.com/nu-book/zxing-cpp/issues/87 + // type next to each other. See also https://github.com/zxing-cpp/zxing-cpp/issues/87 for (bool upsideDown : {false, true}) { // trying again? if (upsideDown) { diff --git a/wrappers/python/CMakeLists.txt b/wrappers/python/CMakeLists.txt index 465ec722a5..dc6e0aa23c 100644 --- a/wrappers/python/CMakeLists.txt +++ b/wrappers/python/CMakeLists.txt @@ -36,17 +36,17 @@ if (NOT hasParent) # related tag. find_package (Git REQUIRED) execute_process( - COMMAND ${GIT_EXECUTABLE} ls-remote https://github.com/nu-book/zxing-cpp.git tags/* + COMMAND ${GIT_EXECUTABLE} ls-remote https://github.com/zxing-cpp/zxing-cpp.git tags/* RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT) string (FIND "${OUTPUT}" "refs/tags/v${VERSION_INFO}\n" FOUND_IDX) if (FOUND_IDX LESS 0) # Version not found in tags (suppose we are preparing future version), use master branch FetchContent_Declare(zxing-cpp - GIT_REPOSITORY https://github.com/nu-book/zxing-cpp.git) + GIT_REPOSITORY https://github.com/zxing-cpp/zxing-cpp.git) else() FetchContent_Declare(zxing-cpp - GIT_REPOSITORY https://github.com/nu-book/zxing-cpp.git + GIT_REPOSITORY https://github.com/zxing-cpp/zxing-cpp.git GIT_TAG v${VERSION_INFO}) endif() if(NOT zxing-cpp_POPULATED) diff --git a/wrappers/python/README.md b/wrappers/python/README.md index 0b7b3d737f..015f90eefe 100644 --- a/wrappers/python/README.md +++ b/wrappers/python/README.md @@ -1,6 +1,6 @@ # Python bindings for zxing-cpp -[![Build + Deploy](https://github.com/nu-book/zxing-cpp/actions/workflows/python-build.yml/badge.svg)](https://github.com/nu-book/zxing-cpp/actions/workflows/python-build.yml) +[![Build + Deploy](https://github.com/zxing-cpp/zxing-cpp/actions/workflows/python-build.yml/badge.svg)](https://github.com/zxing-cpp/zxing-cpp/actions/workflows/python-build.yml) [![PyPI](https://img.shields.io/pypi/v/zxing-cpp.svg)](https://pypi.org/project/zxing-cpp/) ## Installation @@ -14,7 +14,7 @@ or python setup.py install ``` -Note: To install via `setup.py`, you need a suitable [build environment](https://github.com/nu-book/zxing-cpp#build-instructions-for-windowsmacoslinux) including a c++ compiler. +Note: To install via `setup.py`, you need a suitable [build environment](https://github.com/zxing-cpp/zxing-cpp#build-instructions) including a c++ compiler. ## Usage diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index eb47198d46..8d24e90686 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -65,7 +65,7 @@ def build_extension(self, ext): long_description_content_type="text/markdown", author='ZXing-C++ Community', author_email='zxingcpp@gmail.com', - url='https://github.com/nu-book/zxing-cpp', + url='https://github.com/zxing-cpp/zxing-cpp', license='Apache License 2.0', keywords=['barcode'], classifiers=[ diff --git a/wrappers/python/zxing.cpp b/wrappers/python/zxing.cpp index 9e6984306a..e0f4c6c046 100644 --- a/wrappers/python/zxing.cpp +++ b/wrappers/python/zxing.cpp @@ -119,7 +119,7 @@ PYBIND11_MODULE(zxingcpp, m) m.doc() = "python bindings for zxing-cpp"; // forward declaration of BarcodeFormats to fix BarcodeFormat function header typings - // see https://github.com/nu-book/zxing-cpp/pull/271 + // see https://github.com/zxing-cpp/zxing-cpp/pull/271 py::class_ pyBarcodeFormats(m, "BarcodeFormats"); py::enum_(m, "BarcodeFormat", py::arithmetic{}, "Enumeration of zxing supported barcode formats") diff --git a/wrappers/wasm/README.md b/wrappers/wasm/README.md index 117c38dc6e..52c9b69d49 100644 --- a/wrappers/wasm/README.md +++ b/wrappers/wasm/README.md @@ -8,4 +8,4 @@ 4. To see how to include these into a working HTML page, have a look at the [reader](demo_reader.html) and [writer](demo_writer.html) demos. 5. To quickly test your build, copy those demo files into your build directory and run e.g. `emrun --serve_after_close demo_reader.html`. -You can also download the latest build output from the continuous integration system from the [Actions](https://github.com/nu-book/zxing-cpp/actions) tab. Look for 'wasm-artifacts'. Also check out the [live demos](https://nu-book.github.io/zxing-cpp/). +You can also download the latest build output from the continuous integration system from the [Actions](https://github.com/zxing-cpp/zxing-cpp/actions) tab. Look for 'wasm-artifacts'. Also check out the [live demos](https://zxing-cpp.github.io/zxing-cpp/). diff --git a/zxing.cmake b/zxing.cmake index c781e3d286..1eb55faaf3 100644 --- a/zxing.cmake +++ b/zxing.cmake @@ -23,7 +23,7 @@ macro(zxing_add_package_stb) endmacro() macro(zxing_add_package name depname git_repo git_rev) - unset(${name}_FOUND CACHE) # see https://github.com/nu-book/zxing-cpp/commit/8db14eeead45e0f1961532f55061d5e4dd0f78be#commitcomment-66464026 + unset(${name}_FOUND CACHE) # see https://github.com/zxing-cpp/zxing-cpp/commit/8db14eeead45e0f1961532f55061d5e4dd0f78be#commitcomment-66464026 if (BUILD_DEPENDENCIES STREQUAL "AUTO") find_package (${name} CONFIG) From 42561cc61bc808e9375ec01e92f3b71ff5092aef Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 28 Aug 2022 10:48:08 +0200 Subject: [PATCH 0470/1315] test: print EscapeNonGraphical in log output --- test/blackbox/BlackboxTestRunner.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 94d2dc1423..7d0294bece 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -10,6 +10,7 @@ #include "ImageLoader.h" #include "ReadBarcode.h" #include "ThresholdBinarizer.h" +#include "Utf.h" #include "ZXAlgorithms.h" #include "pdf417/PDFReader.h" #include "qrcode/QRReader.h" @@ -136,7 +137,8 @@ static std::string checkResult(const fs::path& imgPath, std::string_view expecte } if (auto expected = readFile(".txt")) { - auto utf8Result = result.text(); + expected = EscapeNonGraphical(*expected); + auto utf8Result = result.text(TextMode::Escaped); return utf8Result != *expected ? fmt::format("Content mismatch: expected '{}' but got '{}'", *expected, utf8Result) : ""; } From ea4f1cdacf066248fa9c9d22f12d0018b09473ad Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 28 Aug 2022 12:16:28 +0200 Subject: [PATCH 0471/1315] ReadBarcode: ReadBarcode finally simply calls ReadBarcodes This changes the behavior to consistently use `tryDownscale` in both versions (if enabled). The balckbox tests are still run without downscaling. --- core/src/ReadBarcode.cpp | 11 +---------- test/blackbox/BlackboxTestRunner.cpp | 1 + 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 511d84b8ca..f9ad2093b6 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -118,16 +118,7 @@ std::unique_ptr CreateBitmap(ZXing::Binarizer binarizer, const Ima Result ReadBarcode(const ImageView& _iv, const DecodeHints& hints) { - if (hints.maxNumberOfSymbols() == 1) { - // HACK: use the maxNumberOfSymbols value as a switch to ReadBarcodes to enable the downscaling - // see python and android wrapper - return FirstOrDefault(ReadBarcodes(_iv, hints)); - } else { - LumImage lum; - ImageView iv = SetupLumImageView(_iv, lum, hints); - - return MultiFormatReader(hints).read(*CreateBitmap(hints.binarizer(), iv)).setDecodeHints(hints); - } + return FirstOrDefault(ReadBarcodes(_iv, DecodeHints(hints).setMaxNumberOfSymbols(1))); } Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 7d0294bece..04ad0555f9 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -230,6 +230,7 @@ static void doRunTests(const fs::path& directory, std::string_view format, int t if (tc.name.empty()) break; auto startTime = std::chrono::steady_clock::now(); + hints.setTryDownscale(false); hints.setTryHarder(tc.name == "slow"); hints.setTryRotate(tc.name == "slow"); hints.setIsPure(tc.name == "pure"); From 2af31cb0f3c3775e7c4ec16be3dfeb9dd1ed36db Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 28 Aug 2022 12:57:28 +0200 Subject: [PATCH 0472/1315] Inversion: implement new `DecodeHints::tryInvert` feature If `tryInvert` is enabled (the default) then symbologies that support it (QRCode, DataMatrix and Aztec) are tested with black/white inversion. This causes around 10% slowdown for the false positive use case if all formats are searched for. The total slowdown of all blackbox tests is about 5%. In the WASM/iOS/WinRT wrapper the new flag is enabled together with the existing `tryHarder` flag for now. This fixes #172 and obsoletes #173. --- core/src/BinaryBitmap.cpp | 11 ++++++++ core/src/BinaryBitmap.h | 4 +++ core/src/DecodeHints.h | 5 ++++ core/src/MultiFormatReader.cpp | 9 ++++-- core/src/ReadBarcode.cpp | 26 ++++++++++-------- core/src/Reader.h | 4 ++- test/blackbox/BlackboxTestRunner.cpp | 11 ++++---- test/samples/qrcode-2/qr-inv-1.jpg | Bin 0 -> 20722 bytes test/samples/qrcode-2/qr-inv-1.txt | 1 + test/samples/qrcode-2/qr-inv-2.jpg | Bin 0 -> 11110 bytes test/samples/qrcode-2/qr-inv-2.txt | 1 + .../com/example/zxingcppdemo/MainActivity.kt | 1 + .../main/res/layout-land/activity_camera.xml | 5 ++++ .../src/main/res/layout/activity_camera.xml | 5 ++++ .../zxingcpp/src/main/cpp/BarcodeReader.cpp | 13 +++++---- .../main/java/com/zxingcpp/BarcodeReader.kt | 8 ++++-- .../Wrapper/Reader/ZXIBarcodeReader.mm | 1 + wrappers/wasm/BarcodeReader.cpp | 1 + wrappers/winrt/BarcodeReader.cpp | 1 + 19 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 test/samples/qrcode-2/qr-inv-1.jpg create mode 100644 test/samples/qrcode-2/qr-inv-1.txt create mode 100644 test/samples/qrcode-2/qr-inv-2.jpg create mode 100644 test/samples/qrcode-2/qr-inv-2.txt diff --git a/core/src/BinaryBitmap.cpp b/core/src/BinaryBitmap.cpp index e3676eef6a..2952f2181c 100644 --- a/core/src/BinaryBitmap.cpp +++ b/core/src/BinaryBitmap.cpp @@ -5,6 +5,8 @@ #include "BinaryBitmap.h" +#include "BitMatrix.h" + #include namespace ZXing { @@ -25,4 +27,13 @@ const BitMatrix* BinaryBitmap::getBitMatrix() const return _cache->matrix.get(); } +void BinaryBitmap::invert() +{ + if (_cache->matrix) { + auto matrix = const_cast(_cache->matrix.get()); + matrix->flipAll(); + } + _inverted = true; +} + } // ZXing diff --git a/core/src/BinaryBitmap.h b/core/src/BinaryBitmap.h index 433e510aed..292b866910 100644 --- a/core/src/BinaryBitmap.h +++ b/core/src/BinaryBitmap.h @@ -27,6 +27,7 @@ class BinaryBitmap { struct Cache; std::unique_ptr _cache; + bool _inverted = false; protected: const ImageView _buffer; @@ -51,6 +52,9 @@ class BinaryBitmap virtual bool getPatternRow(int row, int rotation, PatternRow& res) const = 0; const BitMatrix* getBitMatrix() const; + + void invert(); + bool inverted() const { return _inverted; } }; } // ZXing diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index 9e6bbddcf3..f4e97cb546 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -50,6 +50,7 @@ class DecodeHints { bool _tryHarder : 1; bool _tryRotate : 1; + bool _tryInvert : 1; bool _tryDownscale : 1; bool _isPure : 1; bool _tryCode39ExtendedMode : 1; @@ -73,6 +74,7 @@ class DecodeHints DecodeHints() : _tryHarder(1), _tryRotate(1), + _tryInvert(1), _tryDownscale(1), _isPure(0), _tryCode39ExtendedMode(0), @@ -99,6 +101,9 @@ class DecodeHints /// Also try detecting code in 90, 180 and 270 degree rotated images. ZX_PROPERTY(bool, tryRotate, setTryRotate) + /// Also try detecting inverted ("reversed reflectance") codes if the format allows for those. + ZX_PROPERTY(bool, tryInvert, setTryInvert) + /// Also try detecting code in downscaled images (depending on image size). ZX_PROPERTY(bool, tryDownscale, setTryDownscale) diff --git a/core/src/MultiFormatReader.cpp b/core/src/MultiFormatReader.cpp index ecb6a3a02d..58a78cc0ca 100644 --- a/core/src/MultiFormatReader.cpp +++ b/core/src/MultiFormatReader.cpp @@ -7,6 +7,7 @@ #include "MultiFormatReader.h" #include "BarcodeFormat.h" +#include "BinaryBitmap.h" #include "DecodeHints.h" #include "aztec/AZReader.h" #include "datamatrix/DMReader.h" @@ -28,11 +29,11 @@ MultiFormatReader::MultiFormatReader(const DecodeHints& hints) : _hints(hints) _readers.emplace_back(new OneD::Reader(hints)); if (formats.testFlags(BarcodeFormat::QRCode | BarcodeFormat::MicroQRCode)) - _readers.emplace_back(new QRCode::Reader(hints)); + _readers.emplace_back(new QRCode::Reader(hints, true)); if (formats.testFlag(BarcodeFormat::DataMatrix)) - _readers.emplace_back(new DataMatrix::Reader(hints)); + _readers.emplace_back(new DataMatrix::Reader(hints, true)); if (formats.testFlag(BarcodeFormat::Aztec)) - _readers.emplace_back(new Aztec::Reader(hints)); + _readers.emplace_back(new Aztec::Reader(hints, true)); if (formats.testFlag(BarcodeFormat::PDF417)) _readers.emplace_back(new Pdf417::Reader(hints)); if (formats.testFlag(BarcodeFormat::MaxiCode)) @@ -62,6 +63,8 @@ Results MultiFormatReader::readMultiple(const BinaryBitmap& image, int maxSymbol std::vector res; for (const auto& reader : _readers) { + if (image.inverted() && !reader->supportsInversion) + continue; auto r = reader->decode(image, maxSymbols); if (!_hints.returnErrors()) { //TODO: C++20 res.erase_if() diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index f9ad2093b6..3e91cc5a5f 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -136,22 +136,24 @@ Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) int maxSymbols = hints.maxNumberOfSymbols(); for (auto&& iv : pyramid.layers) { auto bitmap = CreateBitmap(hints.binarizer(), iv); - auto rs = reader.readMultiple(*bitmap, maxSymbols); - for (auto& r : rs) { - if (iv.width() != _iv.width()) - r.setPosition(Scale(r.position(), _iv.width() / iv.width())); - if (!Contains(results, r)) { - results.push_back(std::move(r)); // TODO: keep the one with no error instead of the first found - --maxSymbols; + for (int invert = 0; invert <= static_cast(hints.tryInvert()); ++invert) { + if (invert) + bitmap->invert(); + auto rs = reader.readMultiple(*bitmap, maxSymbols); + for (auto& r : rs) { + if (iv.width() != _iv.width()) + r.setPosition(Scale(r.position(), _iv.width() / iv.width())); + if (!Contains(results, r)) { + r.setDecodeHints(hints); + results.push_back(std::move(r)); // TODO: keep the one with no error instead of the first found + --maxSymbols; + } } + if (maxSymbols <= 0) + return results; } - if (maxSymbols <= 0) - break; } - for (auto& res : results) - res.setDecodeHints(hints); - return results; } diff --git a/core/src/Reader.h b/core/src/Reader.h index 70f34e1d29..bc2d69cdc2 100644 --- a/core/src/Reader.h +++ b/core/src/Reader.h @@ -20,7 +20,9 @@ class Reader const DecodeHints& _hints; public: - explicit Reader(const DecodeHints& hints) : _hints(hints) {} + const bool supportsInversion; + + explicit Reader(const DecodeHints& hints, bool supportsInversion = false) : _hints(hints), supportsInversion(supportsInversion) {} explicit Reader(DecodeHints&& hints) = delete; virtual ~Reader() = default; diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 04ad0555f9..4d4e96ba91 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -233,6 +233,7 @@ static void doRunTests(const fs::path& directory, std::string_view format, int t hints.setTryDownscale(false); hints.setTryHarder(tc.name == "slow"); hints.setTryRotate(tc.name == "slow"); + hints.setTryInvert(tc.name == "slow"); hints.setIsPure(tc.name == "pure"); if (hints.isPure()) hints.setBinarizer(Binarizer::FixedThreshold); @@ -563,11 +564,11 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set { 16, 16, 270 }, }); - runTests("qrcode-2", "QRCode", 46, { - { 44, 44, 0 }, - { 44, 44, 90 }, - { 44, 44, 180 }, - { 44, 44, 270 }, + runTests("qrcode-2", "QRCode", 48, { + { 44, 46, 0 }, + { 44, 46, 90 }, + { 44, 46, 180 }, + { 44, 45, 270 }, { 21, 1, pure }, // the misread is the 'outer' symbol in 16.png }); diff --git a/test/samples/qrcode-2/qr-inv-1.jpg b/test/samples/qrcode-2/qr-inv-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f76de9e46ca2fb4aa149f7fdcb36cca81e38f29b GIT binary patch literal 20722 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 BuuuR1 literal 0 HcmV?d00001 diff --git a/test/samples/qrcode-2/qr-inv-1.txt b/test/samples/qrcode-2/qr-inv-1.txt new file mode 100644 index 0000000000..a1d73366b5 --- /dev/null +++ b/test/samples/qrcode-2/qr-inv-1.txt @@ -0,0 +1 @@ +https://beeline.co/pages/app \ No newline at end of file diff --git a/test/samples/qrcode-2/qr-inv-2.jpg b/test/samples/qrcode-2/qr-inv-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd20eadd9b00b7dd6248c0b3c778c1188dad9740 GIT binary patch literal 11110 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 literal 0 HcmV?d00001 diff --git a/test/samples/qrcode-2/qr-inv-2.txt b/test/samples/qrcode-2/qr-inv-2.txt new file mode 100644 index 0000000000..cb6b80568d --- /dev/null +++ b/test/samples/qrcode-2/qr-inv-2.txt @@ -0,0 +1 @@ +MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;; \ No newline at end of file diff --git a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt index 26dd246e15..d5169ccdad 100644 --- a/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt +++ b/wrappers/android/app/src/main/java/com/example/zxingcppdemo/MainActivity.kt @@ -150,6 +150,7 @@ class MainActivity : AppCompatActivity() { formats = if (binding.qrcode.isChecked) setOf(Format.QR_CODE) else setOf(), tryHarder = binding.tryHarder.isChecked, tryRotate = binding.tryRotate.isChecked, + tryInvert = binding.tryInvert.isChecked, tryDownscale = binding.tryDownscale.isChecked ) diff --git a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml index 9cb819f82d..3346958555 100644 --- a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml +++ b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml @@ -89,6 +89,11 @@ style="@style/Chip" android:text="tryRotate" /> + + + + (env->GetDirectBufferAddress(yBuffer)); @@ -165,7 +166,7 @@ Java_com_zxingcpp_BarcodeReader_readYBuffer( ImageView{pixels + top * rowStride + left, width, height, ImageFormat::Lum, rowStride} .rotated(rotation); - return Read(env, image, formats, tryHarder, tryRotate, tryDownscale, result); + return Read(env, image, formats, tryHarder, tryRotate, tryInvert, tryDownscale, result); } struct LockedPixels @@ -191,7 +192,7 @@ extern "C" JNIEXPORT jstring JNICALL Java_com_zxingcpp_BarcodeReader_readBitmap( JNIEnv* env, jobject thiz, jobject bitmap, jint left, jint top, jint width, jint height, jint rotation, - jstring formats, jboolean tryHarder, jboolean tryRotate, jboolean tryDownscale, + jstring formats, jboolean tryHarder, jboolean tryRotate, jboolean tryInvert, jboolean tryDownscale, jobject result) { AndroidBitmapInfo bmInfo; @@ -213,5 +214,5 @@ Java_com_zxingcpp_BarcodeReader_readBitmap( .cropped(left, top, width, height) .rotated(rotation); - return Read(env, image, formats, tryHarder, tryRotate, tryDownscale, result); + return Read(env, image, formats, tryHarder, tryRotate, tryInvert, tryDownscale, result); } diff --git a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt index 8f5745976d..b241cef0f2 100644 --- a/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt +++ b/wrappers/android/zxingcpp/src/main/java/com/zxingcpp/BarcodeReader.kt @@ -40,6 +40,7 @@ class BarcodeReader { val formats: Set = setOf(), val tryHarder: Boolean = false, val tryRotate: Boolean = false, + val tryInvert: Boolean = false, val tryDownscale: Boolean = false ) @@ -84,6 +85,7 @@ class BarcodeReader { options.formats.joinToString(), options.tryHarder, options.tryRotate, + options.tryInvert, options.tryDownscale, result ) @@ -104,7 +106,7 @@ class BarcodeReader { val status = with(options) { readBitmap( bitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height(), rotation, - formats.joinToString(), tryHarder, tryRotate, tryDownscale, result + formats.joinToString(), tryHarder, tryRotate, tryInvert, tryDownscale, result ) } return try { @@ -117,13 +119,13 @@ class BarcodeReader { // setting the format enum from inside the JNI code is a hassle -> use returned String instead private external fun readYBuffer( yBuffer: ByteBuffer, rowStride: Int, left: Int, top: Int, width: Int, height: Int, rotation: Int, - formats: String, tryHarder: Boolean, tryRotate: Boolean, tryDownscale: Boolean, + formats: String, tryHarder: Boolean, tryRotate: Boolean, tryInvert: Boolean, tryDownscale: Boolean, result: Result, ): String? private external fun readBitmap( bitmap: Bitmap, left: Int, top: Int, width: Int, height: Int, rotation: Int, - formats: String, tryHarder: Boolean, tryRotate: Boolean, tryDownscale: Boolean, + formats: String, tryHarder: Boolean, tryRotate: Boolean, tryInvert: Boolean, tryDownscale: Boolean, result: Result, ): String? diff --git a/wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm b/wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm index abee63aabc..678c2f598c 100644 --- a/wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm +++ b/wrappers/ios/Sources/Wrapper/Reader/ZXIBarcodeReader.mm @@ -99,6 +99,7 @@ + (DecodeHints)DecodeHintsFromZXIOptions:(ZXIDecodeHints*)hints { DecodeHints resultingHints = DecodeHints() .setTryRotate(hints.tryRotate) .setTryHarder(hints.tryHarder) + .setTryInvert(hints.tryHarder) // TODO: add separate tryInvert hint to iOS wrapper? .setTryDownscale(hints.tryDownscale) .setFormats(formats) .setMaxNumberOfSymbols(hints.maxNumberOfSymbols); diff --git a/wrappers/wasm/BarcodeReader.cpp b/wrappers/wasm/BarcodeReader.cpp index c44cfca224..4f5d99f973 100644 --- a/wrappers/wasm/BarcodeReader.cpp +++ b/wrappers/wasm/BarcodeReader.cpp @@ -28,6 +28,7 @@ ReadResult readBarcodeFromImageView(ZXing::ImageView iv, bool tryHarder, const s DecodeHints hints; hints.setTryHarder(tryHarder); hints.setTryRotate(tryHarder); + hints.setTryInvert(tryHarder); hints.setTryDownscale(tryHarder); hints.setFormats(BarcodeFormatsFromString(format)); hints.setMaxNumberOfSymbols(1); diff --git a/wrappers/winrt/BarcodeReader.cpp b/wrappers/winrt/BarcodeReader.cpp index e552f5edac..1fcd7a751c 100644 --- a/wrappers/winrt/BarcodeReader.cpp +++ b/wrappers/winrt/BarcodeReader.cpp @@ -48,6 +48,7 @@ BarcodeReader::init(bool tryHarder, bool tryRotate, const Platform::ArraysetTryHarder(tryHarder); m_hints->setTryRotate(tryRotate); + m_hints->setTryInvert(tryHarder); if (types != nullptr && types->Length > 0) { BarcodeFormats barcodeFormats; From e0fef182406644cd9369990f859abd7d12a6d3ea Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 28 Aug 2022 13:27:41 +0200 Subject: [PATCH 0473/1315] DecodeHints: compress struct size back to 12 bytes (from 16) The one bit for `tryInvert` was too much ;). --- core/src/DecodeHints.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/DecodeHints.h b/core/src/DecodeHints.h index f4e97cb546..13ce2a3557 100644 --- a/core/src/DecodeHints.h +++ b/core/src/DecodeHints.h @@ -58,14 +58,14 @@ class DecodeHints bool _validateITFCheckSum : 1; bool _returnCodabarStartEnd : 1; bool _returnErrors : 1; + uint8_t _downscaleFactor : 3; EanAddOnSymbol _eanAddOnSymbol : 2; Binarizer _binarizer : 2; TextMode _textMode : 3; + CharacterSet _characterSet : 6; - CharacterSet _characterSet = CharacterSet::Unknown; uint8_t _minLineCount = 2; uint8_t _maxNumberOfSymbols = 0xff; - uint8_t _downscaleFactor = 3; uint16_t _downscaleThreshold = 500; BarcodeFormats _formats = BarcodeFormat::None; @@ -82,9 +82,11 @@ class DecodeHints _validateITFCheckSum(0), _returnCodabarStartEnd(0), _returnErrors(0), + _downscaleFactor(3), _eanAddOnSymbol(EanAddOnSymbol::Ignore), _binarizer(Binarizer::LocalAverage), - _textMode(TextMode::Plain) + _textMode(TextMode::Plain), + _characterSet(CharacterSet::Unknown) {} #define ZX_PROPERTY(TYPE, GETTER, SETTER) \ From 810420c1011a5334842e48c661a3fc174698aa34 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 28 Aug 2022 13:35:31 +0200 Subject: [PATCH 0474/1315] android: fix layout issue with chips in landscape mode (copy'n'paste bug) --- .../android/app/src/main/res/layout-land/activity_camera.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml index 3346958555..b2726a2600 100644 --- a/wrappers/android/app/src/main/res/layout-land/activity_camera.xml +++ b/wrappers/android/app/src/main/res/layout-land/activity_camera.xml @@ -91,12 +91,12 @@ Date: Sun, 28 Aug 2022 22:31:39 +0200 Subject: [PATCH 0475/1315] Inversion: add `Result::isInverted` property --- core/src/ReadBarcode.cpp | 1 + core/src/Result.h | 7 +++++++ example/ZXingReader.cpp | 3 ++- test/blackbox/BlackboxTestRunner.cpp | 2 ++ test/samples/qrcode-2/qr-inv-1.result.txt | 1 + 5 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 test/samples/qrcode-2/qr-inv-1.result.txt diff --git a/core/src/ReadBarcode.cpp b/core/src/ReadBarcode.cpp index 3e91cc5a5f..0f6c0ac418 100644 --- a/core/src/ReadBarcode.cpp +++ b/core/src/ReadBarcode.cpp @@ -145,6 +145,7 @@ Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) r.setPosition(Scale(r.position(), _iv.width() / iv.width())); if (!Contains(results, r)) { r.setDecodeHints(hints); + r.setIsInverted(bitmap->inverted()); results.push_back(std::move(r)); // TODO: keep the one with no error instead of the first found --maxSymbols; } diff --git a/core/src/Result.h b/core/src/Result.h index d1fdc35df9..4112c86e3c 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -102,6 +102,11 @@ class Result */ bool isMirrored() const { return _isMirrored; } + /** + * @brief isInverted is the symbol inverted / has reveresed reflectance (see DecodeHints::tryInvert) + */ + bool isInverted() const { return _isInverted; } + /** * @brief symbologyIdentifier Symbology identifier "]cm" where "c" is symbology code character, "m" the modifier. */ @@ -145,6 +150,7 @@ class Result // only for internal use void incrementLineCount() { ++_lineCount; } + void setIsInverted(bool v) { _isInverted = v; } Result& setDecodeHints(DecodeHints hints); bool operator==(const Result& o) const; @@ -161,6 +167,7 @@ class Result BarcodeFormat _format = BarcodeFormat::None; int _lineCount = 0; bool _isMirrored = false; + bool _isInverted = false; bool _readerInit = false; }; diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index cbad7c840d..781308779f 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -216,7 +216,8 @@ int main(int argc, char* argv[]) << "HasECI: " << result.hasECI() << "\n" << "Position: " << result.position() << "\n" << "Rotation: " << result.orientation() << " deg\n" - << "IsMirrored: " << result.isMirrored() << "\n"; + << "IsMirrored: " << result.isMirrored() << "\n" + << "IsInverted: " << result.isInverted() << "\n"; auto printOptional = [](const char* key, const std::string& v) { if (!v.empty()) diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 4d4e96ba91..034e300aca 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -84,6 +84,8 @@ static std::string getResultValue(const Result& result, const std::string& key) return result.isPartOfSequence() ? "true" : "false"; if (key == "isMirrored") return result.isMirrored() ? "true" : "false"; + if (key == "isInverted") + return result.isInverted() ? "true" : "false"; if (key == "readerInit") return result.readerInit() ? "true" : "false"; diff --git a/test/samples/qrcode-2/qr-inv-1.result.txt b/test/samples/qrcode-2/qr-inv-1.result.txt new file mode 100644 index 0000000000..da82284f3e --- /dev/null +++ b/test/samples/qrcode-2/qr-inv-1.result.txt @@ -0,0 +1 @@ +isInverted=true From 39d2da01d97d55625a7f50ce04930b0c0aca7616 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 28 Aug 2022 22:32:16 +0200 Subject: [PATCH 0476/1315] Inversion: add `-noinvert` command line flag to ZXingReader --- example/ZXingReader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 781308779f..7b835ed98a 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -28,6 +28,7 @@ static void PrintUsage(const char* exePath) std::cout << "Usage: " << exePath << " [options] ...\n" << " -fast Skip some lines/pixels during detection (faster)\n" << " -norotate Don't try rotated image during detection (faster)\n" + << " -noinvert Don't search for inverted codes during detection (faster)\n" << " -noscale Don't try downscaled images during detection (faster)\n" << " -format \n" << " Only detect given format(s) (faster)\n" @@ -56,6 +57,8 @@ static bool ParseOptions(int argc, char* argv[], DecodeHints& hints, bool& oneLi hints.setTryHarder(false); } else if (is("-norotate")) { hints.setTryRotate(false); + } else if (is("-noinvert")) { + hints.setTryInvert(false); } else if (is("-noscale")) { hints.setDownscaleThreshold(0); } else if (is("-ispure")) { From f26f2223c2cd133be21afdef6a97d541b89dcf42 Mon Sep 17 00:00:00 2001 From: axxel Date: Sun, 28 Aug 2022 22:33:26 +0200 Subject: [PATCH 0477/1315] ZXingReader: print either `Bytes` or `BytesECI` depending on `-mode` --- example/ZXingReader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/ZXingReader.cpp b/example/ZXingReader.cpp index 7b835ed98a..2156ccfea1 100644 --- a/example/ZXingReader.cpp +++ b/example/ZXingReader.cpp @@ -211,8 +211,7 @@ int main(int argc, char* argv[]) } std::cout << "Text: \"" << result.text() << "\"\n" - << "Bytes: " << ToHex(result.bytes()) << "\n" - << "BytesECI: " << ToHex(result.bytesECI()) << "\n" + << "Bytes: " << ToHex(hints.textMode() == TextMode::ECI ? result.bytesECI() : result.bytes()) << "\n" << "Format: " << ToString(result.format()) << "\n" << "Identifier: " << result.symbologyIdentifier() << "\n" << "Content: " << ToString(result.contentType()) << "\n" From 8ab457ca47e80d158f259de7c8eae6a16e22c949 Mon Sep 17 00:00:00 2001 From: Markus Fisch Date: Wed, 31 Aug 2022 14:49:41 +0200 Subject: [PATCH 0478/1315] Include version number in result Applies to QR Code and DataMatrix. Because sometimes it can be helpful to know which version was actually used for a particular code. --- core/src/DecoderResult.h | 2 ++ core/src/Result.cpp | 4 +++- core/src/Result.h | 8 +++++++- core/src/datamatrix/DMDecoder.cpp | 3 ++- core/src/qrcode/QRDecoder.cpp | 1 + 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/src/DecoderResult.h b/core/src/DecoderResult.h index c1e328d7f9..cf3492ebe4 100644 --- a/core/src/DecoderResult.h +++ b/core/src/DecoderResult.h @@ -25,6 +25,7 @@ class DecoderResult Content _content; std::string _ecLevel; int _lineCount = 0; + int _versionNumber = 0; StructuredAppendInfo _structuredAppend; bool _isMirrored = false; bool _readerInit = false; @@ -71,6 +72,7 @@ class DecoderResult ZX_PROPERTY(std::string, ecLevel, setEcLevel) ZX_PROPERTY(int, lineCount, setLineCount) + ZX_PROPERTY(int, versionNumber, setVersionNumber) ZX_PROPERTY(StructuredAppendInfo, structuredAppend, setStructuredAppend) ZX_PROPERTY(Error, error, setError) ZX_PROPERTY(bool, isMirrored, setIsMirrored) diff --git a/core/src/Result.cpp b/core/src/Result.cpp index 0f66743220..509d824209 100644 --- a/core/src/Result.cpp +++ b/core/src/Result.cpp @@ -23,6 +23,7 @@ Result::Result(const std::string& text, int y, int xStart, int xStop, BarcodeFor _position(Line(y, xStart, xStop)), _format(format), _lineCount(0), + _versionNumber(0), _readerInit(readerInit) {} @@ -34,6 +35,7 @@ Result::Result(DecoderResult&& decodeResult, Position&& position, BarcodeFormat _sai(decodeResult.structuredAppend()), _format(format), _lineCount(decodeResult.lineCount()), + _versionNumber(decodeResult.versionNumber()), _isMirrored(decodeResult.isMirrored()), _readerInit(decodeResult.readerInit()) { @@ -116,7 +118,7 @@ Result& Result::setDecodeHints(DecodeHints hints) bool Result::operator==(const Result& o) const { - // two symbols may be considered the same if at least one of them has an error + // two symbols may not be considered the same if at least one of them has an error if (!(format() == o.format() && (bytes() == o.bytes() || error() || o.error()))) return false; diff --git a/core/src/Result.h b/core/src/Result.h index 4112c86e3c..702a6abc6f 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -144,10 +144,15 @@ class Result bool readerInit() const { return _readerInit; } /** - * @brief How many lines have been detected with this code (applies only to linear symbologies) + * @brief lineCount How many lines have been detected with this code (applies only to linear symbologies) */ int lineCount() const { return _lineCount; } + /** + * @brief versionNumber QR Code or DataMatrix version number. + */ + int versionNumber() const { return _versionNumber; } + // only for internal use void incrementLineCount() { ++_lineCount; } void setIsInverted(bool v) { _isInverted = v; } @@ -166,6 +171,7 @@ class Result StructuredAppendInfo _sai; BarcodeFormat _format = BarcodeFormat::None; int _lineCount = 0; + int _versionNumber = 0; bool _isMirrored = false; bool _isInverted = false; bool _readerInit = false; diff --git a/core/src/datamatrix/DMDecoder.cpp b/core/src/datamatrix/DMDecoder.cpp index e12a9122f5..c79515e0f5 100644 --- a/core/src/datamatrix/DMDecoder.cpp +++ b/core/src/datamatrix/DMDecoder.cpp @@ -421,7 +421,8 @@ static DecoderResult DoDecode(const BitMatrix& bits) } // Decode the contents of that stream of bytes - return DecodedBitStreamParser::Decode(std::move(resultBytes), version->isDMRE()); + return DecodedBitStreamParser::Decode(std::move(resultBytes), version->isDMRE()) + .setVersionNumber(version->versionNumber); } static BitMatrix FlippedL(const BitMatrix& bits) diff --git a/core/src/qrcode/QRDecoder.cpp b/core/src/qrcode/QRDecoder.cpp index c4a42addbc..0c255d4811 100644 --- a/core/src/qrcode/QRDecoder.cpp +++ b/core/src/qrcode/QRDecoder.cpp @@ -308,6 +308,7 @@ DecoderResult DecodeBitStream(ByteArray&& bytes, const Version& version, ErrorCo return DecoderResult(std::move(result)) .setError(std::move(error)) .setEcLevel(ToString(ecLevel)) + .setVersionNumber(version.versionNumber()) .setStructuredAppend(structuredAppend); } From 5479e4daf91b3d2930b85843d00d8cc1f2fbf8d9 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 7 Sep 2022 14:51:59 +0200 Subject: [PATCH 0479/1315] test: fix/workaround broken fuzzer compilation --- test/fuzz/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/fuzz/CMakeLists.txt b/test/fuzz/CMakeLists.txt index a416ea791e..8d4e7c3af1 100644 --- a/test/fuzz/CMakeLists.txt +++ b/test/fuzz/CMakeLists.txt @@ -1,8 +1,10 @@ cmake_minimum_required (VERSION 3.14) + +set (CMAKE_CXX_COMPILER /usr/bin/clang++) + project (ZXingFuzz) -set (CMAKE_CXX_COMPILER "clang++") set (CMAKE_CXX_STANDARD 17) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -march=native -fsanitize=address,fuzzer") From 604b77066a4b2883bc7fb64815fef287d0039c5e Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 7 Sep 2022 14:52:32 +0200 Subject: [PATCH 0480/1315] test: add unit test for GetPatternRow --- test/unit/CMakeLists.txt | 1 + test/unit/PatternTest.cpp | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/unit/PatternTest.cpp diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index db8b443977..cf1dcd4ad6 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable (UnitTest ErrorTest.cpp GTINTest.cpp GS1Test.cpp + PatternTest.cpp ReedSolomonTest.cpp SanitizerSupport.cpp TextDecoderTest.cpp diff --git a/test/unit/PatternTest.cpp b/test/unit/PatternTest.cpp new file mode 100644 index 0000000000..f3cdc58de0 --- /dev/null +++ b/test/unit/PatternTest.cpp @@ -0,0 +1,68 @@ +/* +* Copyright 2022 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "Pattern.h" + +#include "gtest/gtest.h" + +using namespace ZXing; + +constexpr int N = 33; + +TEST(PatternTest, AllWhite) +{ + for (int s = 1; s <= N; ++s) { + std::vector in(s, 0); + PatternRow pr; + GetPatternRow(Range{in.data(), in.data() + in.size()}, pr); + + EXPECT_EQ(pr.size(), 1); + EXPECT_EQ(pr[0], s); + } +} + +TEST(PatternTest, AllBlack) +{ + for (int s = 1; s <= N; ++s) { + std::vector in(s, 0xff); + PatternRow pr; + GetPatternRow(Range{in.data(), in.data() + in.size()}, pr); + + EXPECT_EQ(pr.size(), 3); + EXPECT_EQ(pr[0], 0); + EXPECT_EQ(pr[1], s); + EXPECT_EQ(pr[2], 0); + } +} + +TEST(PatternTest, BlackWhite) +{ + for (int s = 1; s <= N; ++s) { + std::vector in(N, 0); + std::fill_n(in.data(), s, 0xff); + PatternRow pr; + GetPatternRow(Range{in.data(), in.data() + in.size()}, pr); + + EXPECT_EQ(pr.size(), 3); + EXPECT_EQ(pr[0], 0); + EXPECT_EQ(pr[1], s); + EXPECT_EQ(pr[2], N - s); + } +} + +TEST(PatternTest, WhiteBlack) +{ + for (int s = 0; s < N; ++s) { + std::vector in(N, 0xff); + std::fill_n(in.data(), s, 0); + PatternRow pr; + GetPatternRow(Range{in.data(), in.data() + in.size()}, pr); + + EXPECT_EQ(pr.size(), 3); + EXPECT_EQ(pr[0], s); + EXPECT_EQ(pr[1], N - s); + EXPECT_EQ(pr[2], 0); + } +} From 192d7e742e6cadac40dba6bbcea87f84da894804 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 7 Sep 2022 15:05:56 +0200 Subject: [PATCH 0481/1315] Aztec: reimplement AZDetector to support arbitrary symbol rotation/position This replaces the original detector implementation with something based on the scanning a `PatternRow` for the central finder pattern, similar to how QRCodes are detected. Pros: * finds a lot more real-world scenario symbols * supports arbitrary rotation and symbol position * prepares support for multi-symbol detection (will come later) Cons: * slower than the original: total falsepositive slowdown: approx. 15-20% This is related to issues #344 and #217. --- core/src/ConcentricFinder.h | 3 + core/src/Quadrilateral.h | 10 +- core/src/aztec/AZDecoder.cpp | 2 +- core/src/aztec/AZDetector.cpp | 764 +++++++++++-------------- core/src/aztec/AZDetector.h | 2 +- core/src/aztec/AZDetectorResult.h | 12 +- core/src/aztec/AZReader.cpp | 18 +- test/blackbox/BlackboxTestRunner.cpp | 18 +- test/samples/aztec-1/abc-inverted.png | Bin 0 -> 260 bytes test/samples/aztec-1/abc-inverted.txt | 1 + test/samples/aztec-1/abc-mirrored.png | Bin 0 -> 264 bytes test/samples/aztec-1/abc-mirrored.txt | 1 + test/unit/aztec/AZDecoderTest.cpp | 2 +- test/unit/aztec/AZDetectorTest.cpp | 59 +- test/unit/aztec/AZEncodeDecodeTest.cpp | 2 +- 15 files changed, 393 insertions(+), 501 deletions(-) create mode 100644 test/samples/aztec-1/abc-inverted.png create mode 100644 test/samples/aztec-1/abc-inverted.txt create mode 100644 test/samples/aztec-1/abc-mirrored.png create mode 100644 test/samples/aztec-1/abc-mirrored.txt diff --git a/core/src/ConcentricFinder.h b/core/src/ConcentricFinder.h index ab86da8a1f..e9be41b5b8 100644 --- a/core/src/ConcentricFinder.h +++ b/core/src/ConcentricFinder.h @@ -26,6 +26,9 @@ static float CenterFromEnd(const std::array& pattern, float end) float a = pattern[2] + pattern[1] / 2.f; float b = (pattern[2] + pattern[1] + pattern[0]) / 2.f; return end - (2 * a + b) / 3; + } else { // aztec + auto a = std::accumulate(&pattern[N/2 + 1], &pattern[N], pattern[N/2] / 2.f); + return end - a; } } diff --git a/core/src/Quadrilateral.h b/core/src/Quadrilateral.h index a2620715a8..ce5d47bec5 100644 --- a/core/src/Quadrilateral.h +++ b/core/src/Quadrilateral.h @@ -53,6 +53,12 @@ Quadrilateral Rectangle(int width, int height, typename PointT::value_t PointT{margin, margin}, {width - margin, margin}, {width - margin, height - margin}, {margin, height - margin}}; } +template +Quadrilateral CenteredSquare(int size) +{ + return Scale(Quadrilateral(PointT{-1, -1}, {1, -1}, {1, 1}, {-1, 1}), size / 2); +} + template Quadrilateral Line(int y, int xStart, int xStop) { @@ -105,10 +111,12 @@ PointT Center(const Quadrilateral& q) } template -Quadrilateral RotatedCorners(const Quadrilateral& q, int n = 1) +Quadrilateral RotatedCorners(const Quadrilateral& q, int n = 1, bool mirror = false) { Quadrilateral res; std::rotate_copy(q.begin(), q.begin() + ((n + 4) % 4), q.end(), res.begin()); + if (mirror) + std::swap(res[1], res[3]); return res; } diff --git a/core/src/aztec/AZDecoder.cpp b/core/src/aztec/AZDecoder.cpp index d96e01bd95..88953f61e4 100644 --- a/core/src/aztec/AZDecoder.cpp +++ b/core/src/aztec/AZDecoder.cpp @@ -348,7 +348,7 @@ DecoderResult Decode(const DetectorResult& detectorResult) { try { auto bits = CorrectBits(detectorResult, ExtractBits(detectorResult)); - return Decode(bits).setReaderInit(detectorResult.readerInit()); + return Decode(bits); } catch (Error e) { return e; } diff --git a/core/src/aztec/AZDetector.cpp b/core/src/aztec/AZDetector.cpp index 099864ee57..2091a75632 100644 --- a/core/src/aztec/AZDetector.cpp +++ b/core/src/aztec/AZDetector.cpp @@ -1,521 +1,395 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 #include "AZDetector.h" #include "AZDetectorResult.h" +#include "BitArray.h" #include "BitHacks.h" #include "BitMatrix.h" +#include "ConcentricFinder.h" #include "GenericGF.h" #include "GridSampler.h" +#include "LogMatrix.h" +#include "Pattern.h" #include "ReedSolomonDecoder.h" -#include "ResultPoint.h" -#include "WhiteRectDetector.h" #include "ZXAlgorithms.h" -#include -#include +#include +#include +#include +#include namespace ZXing::Aztec { -template >> -static int RoundToNearest(T x) +static bool IsAztectCenterPattern(const PatternView& view) { - return narrow_cast(std::lround(x)); -} - -static const int EXPECTED_CORNER_BITS[] = { - 0xee0, // 07340 XXX .XX X.. ... - 0x1dc, // 00734 ... XXX .XX X.. - 0x83b, // 04073 X.. ... XXX .XX - 0x707, // 03407 .XX X.. ... XXX +#if 0 // find min/max and check that they not more than factor 2 appart + auto m = view[0]; + auto M = m; + for (int i = 1; i < Size(view); ++i) + if (view[i] < m) + m = view[i]; + else if (view[i] > M) + M = view[i]; + return M - 2 <= 2 * m && view[-1] >= m && view[Size(view)] >= m; +#else // estimate min/max from first entry and check all others are within [min,max] + auto m = std::max(1, view[0] * 2 / 3 - 1); + auto M = view[0] * 4 / 3 + 1; + for (int i = 1; i < Size(view); ++i) + if (view[i] < m || view[i] > M) + return false; + return view[-1] >= m && view[Size(view)] >= m; +#endif }; -// return -1 in case of error -static int GetRotation(const std::array& sides, int length) +// specialized version of FindLeftGuard to find the '1,1,1,1,1,1,1' pattern of a compact Aztec center pattern +static PatternView FindAztecCenterPattern(const PatternView& view) { - // In a normal pattern, we expect to See - // ** .* D A - // * * - // - // . * - // .. .. C B - // - // Grab the 3 bits from each of the sides the form the locator pattern and concatenate - // into a 12-bit integer. Start with the bit at A - int cornerBits = 0; - for (int side : sides) { - // XX......X where X's are orientation marks - int t = ((side >> (length - 2)) << 1) + (side & 1); - cornerBits = (cornerBits << 3) + t; - } - // Mov the bottom bit to the top, so that the three bits of the locator pattern at A are - // together. cornerBits is now: - // 3 orientation bits at A || 3 orientation bits at B || ... || 3 orientation bits at D - cornerBits = ((cornerBits & 1) << 11) + (cornerBits >> 1); - // The result shift indicates which element of BullsEyeCorners[] goes into the top-left - // corner. Since the four rotation values have a Hamming distance of 8, we - // can easily tolerate two errors. - for (int shift = 0; shift < 4; shift++) { - if (BitHacks::CountBitsSet(cornerBits ^ EXPECTED_CORNER_BITS[shift]) <= 2) { - return shift; - } - } - return -1; -} + constexpr int minSize = 8; // Aztec runes + auto window = view.subView(0, 7); + for (auto end = view.end() - minSize; window.data() < end; window.skipPair()) + if (IsAztectCenterPattern(window)) + return window; -static bool IsValidPoint(int x, int y, int imgWidth, int imgHeight) -{ - return x >= 0 && x < imgWidth && y >= 0 && y < imgHeight; -} + return {}; +}; -static bool IsValidPoint(const ResultPoint& point, int imgWidth, int imgHeight) +static int CheckDirection(BitMatrixCursorF& cur, PointF dir, int range, bool updatePosition) { - return IsValidPoint(RoundToNearest(point.x()), RoundToNearest(point.y()), imgWidth, imgHeight); -} + range = range * 2 / 7; // TODO: tune + auto pOri = cur.p; + auto cuo = cur; + cur.setDirection(dir); + cuo.setDirection(-dir); + + int spread = cur.stepToEdge(1, range); + if (!spread) + return 0; + int spreadO = cuo.stepToEdge(1, range); + if (!spreadO) + return 0; + spread += spreadO - 1; // -1 because the starting pixel is counted twice + if (spread > range || spread < range / 6) + return 0; -/** -* Samples a line. -* -* @param p1 start point (inclusive) -* @param p2 end point (exclusive) -* @param size number of bits -* @return the array of bits as an int (first bit is high-order bit of result) -*/ -static int SampleLine(const BitMatrix& image, const ResultPoint& p1, const ResultPoint& p2, int size) -{ - int result = 0; - - float d = static_cast(distance(p1, p2)); - float moduleSize = d / size; - float px = p1.x(); - float py = p1.y(); - float dx = moduleSize * (p2.x() - p1.x()) / d; - float dy = moduleSize * (p2.y() - p1.y()) / d; - for (int i = 0; i < size; i++) { - if (image.get(RoundToNearest(px + i * dx), RoundToNearest(py + i * dy))) { - result |= 1 << (size - i - 1); + if (updatePosition) + pOri = (cur.p + cuo.p) / 2; + + auto m = std::max(1, spread * 2 / 3 - 1); + auto M = spread * 3 / 2 + 1; + for (auto c : {&cur, &cuo}) + for (int i = 0; i < 3; ++i) { + int s = c->stepToEdge(1, M); + if (s < m) + return 0; + spread += s; } - } - return result; -} - -/** -* Corrects the parameter bits using Reed-Solomon algorithm. -* -* @param parameterData parameter bits -* @param compact true if this is a compact Aztec code -*/ -static bool GetCorrectedParameterData(int64_t parameterData, bool compact, int& result) -{ - int numCodewords; - int numDataCodewords; - - if (compact) { - numCodewords = 7; - numDataCodewords = 2; - } - else { - numCodewords = 10; - numDataCodewords = 4; - } - int numECCodewords = numCodewords - numDataCodewords; - std::vector parameterWords(numCodewords); - for (int i = numCodewords - 1; i >= 0; --i) { - parameterWords[i] = (int)parameterData & 0xF; - parameterData >>= 4; - } - if (!ReedSolomonDecode(GenericGF::AztecParam(), parameterWords, numECCodewords)) - return false; + cur.p = pOri; - // Toss the error correction. Just return the data as an integer - result = 0; - for (int i = 0; i < numDataCodewords; i++) { - result = (result << 4) + parameterWords[i]; - } - return true; + return spread; } -/** -* Extracts the number of data layers and data blocks from the layer around the bull's eye. -* -* @param bullsEyeCorners the array of bull's eye corners -* @return false in case of too many errors or invalid parameters -*/ -static bool ExtractParameters(const BitMatrix& image, const std::array& bullsEyeCorners, bool compact, - int nbCenterLayers, int& nbLayers, int& nbDataBlocks, bool& readerInit, int& shift) +static std::optional LocateAztecCenter(const BitMatrix& image, PointF center, int spreadH) { - if (!IsValidPoint(bullsEyeCorners[0], image.width(), image.height()) || !IsValidPoint(bullsEyeCorners[1], image.width(), image.height()) || - !IsValidPoint(bullsEyeCorners[2], image.width(), image.height()) || !IsValidPoint(bullsEyeCorners[3], image.width(), image.height())) { - return false; - } - int length = 2 * nbCenterLayers; - // Get the bits around the bull's eye - std::array sides = { - SampleLine(image, bullsEyeCorners[0], bullsEyeCorners[1], length), // Right side - SampleLine(image, bullsEyeCorners[1], bullsEyeCorners[2], length), // Bottom - SampleLine(image, bullsEyeCorners[2], bullsEyeCorners[3], length), // Left side - SampleLine(image, bullsEyeCorners[3], bullsEyeCorners[0], length) // Top - }; - - // bullsEyeCorners[shift] is the corner of the bulls'eye that has three - // orientation marks. - // sides[shift] is the row/column that goes from the corner with three - // orientation marks to the corner with two. - shift = GetRotation(sides, length); - if (shift < 0) { - return false; + auto cur = BitMatrixCursorF(image, center, {}); + int minSpread = spreadH, maxSpread = spreadH; + for (auto d : {PointF{0, 1}, {1, 1}, {1, -1}}) { + int spread = CheckDirection(cur, d, spreadH, d.x == 0); + if (!spread) + return {}; + minSpread = std::min(spread, minSpread); + maxSpread = std::max(spread, maxSpread); } - // Flatten the parameter bits into a single 28- or 40-bit long - int64_t parameterData = 0; - for (int i = 0; i < 4; i++) { - int side = sides[(shift + i) % 4]; - if (compact) { - // Each side of the form ..XXXXXXX. where Xs are parameter data - parameterData <<= 7; - parameterData += (side >> 1) & 0x7F; - } - else { - // Each side of the form ..XXXXX.XXXXX. where Xs are parameter data - parameterData <<= 10; - parameterData += ((side >> 2) & (0x1f << 5)) + ((side >> 1) & 0x1F); - } - } - - // Corrects parameter data using RS. Returns just the data portion - // without the error correction. - int correctedData; - if (!GetCorrectedParameterData(parameterData, compact, correctedData)) { - return false; - } - - readerInit = false; - if (compact) { - // 8 bits: 2 bits layers and 6 bits data blocks - nbLayers = (correctedData >> 6) + 1; - if (nbLayers == 1 && (correctedData & 0x20)) { // ISO/IEC 24778:2008 Section 9 MSB artificially set - readerInit = true; - correctedData &= ~0x20; - } - nbDataBlocks = (correctedData & 0x3F) + 1; - } - else { - // 16 bits: 5 bits layers and 11 bits data blocks - nbLayers = (correctedData >> 11) + 1; - if (nbLayers <= 22 && (correctedData & 0x400)) { // ISO/IEC 24778:2008 Section 9 MSB artificially set - readerInit = true; - correctedData &= ~0x400; - } - nbDataBlocks = (correctedData & 0x7FF) + 1; - } - return true; + return ConcentricPattern{cur.p, (maxSpread + minSpread) / 2}; } - -/** -* Gets the color of a segment -* -* @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else -*/ -static int GetColor(const BitMatrix& image, const PointI& p1, const PointI& p2) +static std::vector FindPureFinderPattern(const BitMatrix& image) { - if (!IsValidPoint(p1.x, p1.y, image.width(), image.height()) || - !IsValidPoint(p2.x, p2.y, image.width(), image.height())) - return 0; - - float d = static_cast(distance(p1, p2)); - float dx = (p2.x - p1.x) / d; - float dy = (p2.y - p1.y) / d; - int error = 0; - - float px = static_cast(p1.x); - float py = static_cast(p1.y); - - bool colorModel = image.get(p1.x, p1.y); - int iMax = (int)std::ceil(d); - for (int i = 0; i < iMax; i++) { - px += dx; - py += dy; - if (image.get(RoundToNearest(px), RoundToNearest(py)) != colorModel) { - error++; - } - } - - float errRatio = error / d; - - if (errRatio > 0.1f && errRatio < 0.9f) { - return 0; - } - - return (errRatio <= 0.1f) == colorModel ? 1 : -1; -} - -/** -* @return true if the border of the rectangle passed in parameter is compound of white points only -* or black points only -*/ -static bool IsWhiteOrBlackRectangle(const BitMatrix& image, const PointI& pt1, const PointI& pt2, const PointI& pt3, const PointI& pt4) { - - int corr = 3; - - PointI p1{ pt1.x - corr, pt1.y + corr }; - PointI p2{ pt2.x - corr, pt2.y - corr }; - PointI p3{ pt3.x + corr, pt3.y - corr }; - PointI p4{ pt4.x + corr, pt4.y + corr }; - - int cInit = GetColor(image, p4, p1); - - if (cInit == 0) { - return false; - } - - int c = GetColor(image, p1, p2); - - if (c != cInit) { - return false; - } - - c = GetColor(image, p2, p3); - - if (c != cInit) { - return false; - } - - c = GetColor(image, p3, p4); - - return c == cInit; + int left, top, width, height; + if (!image.findBoundingBox(left, top, width, height, 11)) // 11 is the size of an Aztec Rune, see ISO/IEC 24778:2008(E) Annex A + return {}; + PointF p(left + width / 2, top + height / 2); + constexpr auto PATTERN = FixedPattern<7, 7>{1, 1, 1, 1, 1, 1, 1}; + if (auto pattern = LocateConcentricPattern(image, PATTERN, p, width / 3)) + return {*pattern}; + else + return {}; } -/** -* Gets the coordinate of the first point with a different color in the given direction -*/ -static PointI GetFirstDifferent(const BitMatrix& image, const PointI& init, bool color, int dx, int dy) { - int x = init.x + dx; - int y = init.y + dy; - - while (IsValidPoint(x, y, image.width(), image.height()) && image.get(x, y) == color) { - x += dx; - y += dy; - } - - x -= dx; - y -= dy; - - while (IsValidPoint(x, y, image.width(), image.height()) && image.get(x, y) == color) { - x += dx; +static std::vector FindFinderPatterns(const BitMatrix& image, bool tryHarder) +{ + std::vector res; + + int N = 0; + +#if 0 // reference algorithm for finding aztec center candidates + auto l0 = image.row(0); + std::vector line(l0.begin(), l0.end()); + const int width = image.width(); + + int skip = tryHarder ? 1 : std::clamp(image.height() / 100, 1, 3); + int margin = skip; + for (int y = margin; y < image.height() - margin; y += skip) { + auto lc = image.row(y).begin() + 1; + auto lp = image.row(y - skip).begin() + 1; + line.front() = image.get(0, y); + // update line and swipe right + for (int x = 1; x < image.width(); ++x) { + line[x] += *lc++ != *lp++; + while (line[x] > line[x - 1] + 1) + line[x] -= 2; + } + // swipe left + line.back() = image.get(width - 1, y); + for (int x = width - 2; x > 0; --x) + while (line[x] > line[x + 1] + 1) + line[x] -= 2; + + int first = 0, last = 0; + for (int x = 1; x < width - 5; ++x) { + if (line[x] > line[x - 1] && line[x] >= 5 && line[x] % 2 == 1) + first = x; + else + continue; + while (line[x] == line[x + 1]) + ++x; + last = x; + if (line[last + 1] < line[last]) { + auto p = centered(PointI((first + last) / 2, y)); + // make sure p is not 'inside' an already found pattern area + if (FindIf(res, [p](const auto& old) { return distance(p, old) < old.size / 2; }) == res.end()) { + auto pattern = LocateConcentricPattern(image, PATTERN, p, image.width() / 3); + if (pattern){ + log(*pattern, 2); + res.push_back(*pattern); + } + } + } + } } - x -= dx; +#else // own algorithm based on PatternRow processing (between 0% and 100% faster than reference algo depending on input) + int skip = tryHarder ? 1 : std::clamp(image.height() / 2 / 100, 1, 5); + int margin = tryHarder ? 5 : image.height() / 4; + + for (int y = margin; y < image.height() - margin; y += skip) + { + PatternRow row; + GetPatternRow(image, y, row, false); + PatternView next = row; + next.shift(1); // the center pattern we are looking for starts with white and is 7 wide (compact code) + +#if 1 + while (next = FindAztecCenterPattern(next), next.isValid()) { +#else + constexpr auto PATTERN = FixedPattern<7, 7>{1, 1, 1, 1, 1, 1, 1}; + while (next = FindLeftGuard(next, 0, PATTERN, 0.5), next.isValid()) { +#endif + PointF p(next.pixelsInFront() + next[0] + next[1] + next[2] + next[3] / 2.0, y + 0.5); + + // make sure p is not 'inside' an already found pattern area + if (FindIf(res, [p](const auto& old) { return distance(p, old) < old.size / 2; }) == res.end()) { + ++N; + log(p, 1); + + auto pattern = LocateAztecCenter(image, p, Reduce(next)); + if (pattern) { + log(*pattern, 3); + assert(image.get(*pattern)); + res.push_back(*pattern); + } + } - while (IsValidPoint(x, y, image.width(), image.height()) && image.get(x, y) == color) { - y += dy; + next.skipPair(); + next.extend(); + } } - y -= dy; +#endif - return PointI{ x, y }; +#ifdef PRINT_DEBUG + printf("\n# checked centeres: %d, # found centers: %d\n", N, Size(res)); +#endif + return res; } -/** -* Expand the square represented by the corner points by pushing out equally in all directions -* -* @param cornerPoints the corners of the square, which has the bull's eye at its center -* @param oldSide the original length of the side of the square in the target bit matrix -* @param newSide the new length of the size of the square in the target bit matrix -* @return the corners of the expanded square -*/ -static void ExpandSquare(std::array& cornerPoints, float oldSide, float newSide) +static int FindRotation(uint32_t bits, bool mirror) { - double ratio = newSide / (2.0 * oldSide); - double dx = cornerPoints[0].x() - cornerPoints[2].x(); - double dy = cornerPoints[0].y() - cornerPoints[2].y(); - double centerx = (cornerPoints[0].x() + cornerPoints[2].x()) / 2.0f; - double centery = (cornerPoints[0].y() + cornerPoints[2].y()) / 2.0f; - - cornerPoints[0] = PointF(centerx + ratio * dx, centery + ratio * dy); - cornerPoints[2] = PointF(centerx - ratio * dx, centery - ratio * dy); - - dx = cornerPoints[1].x() - cornerPoints[3].x(); - dy = cornerPoints[1].y() - cornerPoints[3].y(); - centerx = (cornerPoints[1].x() + cornerPoints[3].x()) / 2.0f; - centery = (cornerPoints[1].y() + cornerPoints[3].y()) / 2.0f; - cornerPoints[1] = PointF(centerx + ratio * dx, centery + ratio * dy); - cornerPoints[3] = PointF(centerx - ratio * dx, centery - ratio * dy); + const uint32_t mask = mirror ? 0b111'000'001'110 : 0b111'011'100'000; + for (int i = 0; i < 4; ++i) { + if (BitHacks::CountBitsSet(mask ^ bits) <= 2) // at most 2 bits may be wrong (24778:2008(E) 14.3.3 sais 3 but that is wrong) + return i; + bits = ((bits << 3) & 0xfff) | ((bits >> 9) & 0b111); // left shift/rotate, see RotatedCorners(Quadrilateral) + } + return -1; } - -/** -* Finds the corners of a bull-eye centered on the passed point. -* This returns the centers of the diagonal points just outside the bull's eye -* Returns [topRight, bottomRight, bottomLeft, topLeft] -* -* @param pCenter Center point -* @return The corners of the bull-eye -* @return false If no valid bull-eye can be found -*/ -static bool GetBullsEyeCorners(const BitMatrix& image, const PointI& pCenter, std::array& result, bool& compact, int& nbCenterLayers) +// read 4*3=12 bits from the 4 corners of the finder pattern at radius +static uint32_t SampleOrientationBits(const BitMatrix& image, const PerspectiveTransform& mod2Pix, int radius) { - PointI pina = pCenter; - PointI pinb = pCenter; - PointI pinc = pCenter; - PointI pind = pCenter; - - bool color = true; - for (nbCenterLayers = 1; nbCenterLayers < 9; nbCenterLayers++) { - PointI pouta = GetFirstDifferent(image, pina, color, 1, -1); - PointI poutb = GetFirstDifferent(image, pinb, color, 1, 1); - PointI poutc = GetFirstDifferent(image, pinc, color, -1, 1); - PointI poutd = GetFirstDifferent(image, pind, color, -1, -1); - - //d a - // - //c b - - if (nbCenterLayers > 2) { - auto q = distance(poutd, pouta) * nbCenterLayers / (distance(pind, pina) * (nbCenterLayers + 2.0)); - if (q < 0.75 || q > 1.25 || !IsWhiteOrBlackRectangle(image, pouta, poutb, poutc, poutd)) { - break; - } + uint32_t bits = 0; + for (auto d : {PointI{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}) { + auto corner = radius * d; + auto cornerL = corner + PointI{0, -d.y}; + auto cornerR = corner + PointI{-d.x, 0}; + if (d.x != d.y) + std::swap(cornerL, cornerR); + for (auto ps : {cornerL, corner, cornerR}) { + auto p = mod2Pix(PointF(ps)); + if (!image.isIn(p)) + return -1; + log(p); + AppendBit(bits, image.get(p)); } - - pina = pouta; - pinb = poutb; - pinc = poutc; - pind = poutd; - - color = !color; - } - - if (nbCenterLayers != 5 && nbCenterLayers != 7) { - return false; } - - compact = nbCenterLayers == 5; - - // Expand the square by .5 pixel in each direction so that we're on the border - // between the white square and the black square - result[0] = ResultPoint(pina.x + 0.5f, pina.y - 0.5f); - result[1] = ResultPoint(pinb.x + 0.5f, pinb.y + 0.5f); - result[2] = ResultPoint(pinc.x - 0.5f, pinc.y + 0.5f); - result[3] = ResultPoint(pind.x - 0.5f, pind.y - 0.5f); - - // Expand the square so that its corners are the centers of the points - // just outside the bull's eye. - ExpandSquare(result, static_cast(2 * nbCenterLayers - 3), static_cast(2 * nbCenterLayers)); - return true; + return bits; } -/** -* Finds a candidate center point of an Aztec code from an image -* -* @return the center point -*/ -static PointI GetMatrixCenter(const BitMatrix& image) +static int ModeMessage(const BitMatrix& image, const PerspectiveTransform& mod2Pix, int radius) { - //Get a white rectangle that can be the border of the matrix in center bull's eye or - ResultPoint pointA, pointB, pointC, pointD; - if (!DetectWhiteRect(image, 4, image.width() / 2, image.height() / 2, pointA, pointB, pointC, pointD)) { - // This exception can be in case the initial rectangle is white - // In that case, surely in the bull's eye, we try to expand the rectangle. - int cx = image.width() / 2; - int cy = image.height() / 2; - pointA = GetFirstDifferent(image, { cx + 7, cy - 7 }, false, 1, -1); - pointB = GetFirstDifferent(image, { cx + 7, cy + 7 }, false, 1, 1); - pointC = GetFirstDifferent(image, { cx - 7, cy + 7 }, false, -1, 1); - pointD = GetFirstDifferent(image, { cx - 7, cy - 7 }, false, -1, -1); + const bool compact = radius == 5; + + // read the bits between the corner bits along the 4 edges + uint64_t bits = 0; + for (auto d : {PointI{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}) { + auto corner = radius * d; + auto next = (d.x == d.y) ? PointI{-d.x, 0} : PointI{0, -d.y}; + for (int i = 2; i <= 2 * radius - 2; ++i) { + if (!compact && i == 7) + continue; // skip the timing pattern + auto p = mod2Pix(PointF(corner + i * next)); + log(p); + if (!image.isIn(p)) + return -1; + AppendBit(bits, image.get(p)); + } } - //Compute the center of the rectangle - int cx = RoundToNearest((pointA.x() + pointD.x() + pointB.x() + pointC.x()) / 4.0f); - int cy = RoundToNearest((pointA.y() + pointD.y() + pointB.y() + pointC.y()) / 4.0f); - - // Redetermine the white rectangle starting from previously computed center. - // This will ensure that we end up with a white rectangle in center bull's eye - // in order to compute a more accurate center. - if (!DetectWhiteRect(image, 4, cx, cy, pointA, pointB, pointC, pointD)) { - // This exception can be in case the initial rectangle is white - // In that case we try to expand the rectangle. - pointA = GetFirstDifferent(image, { cx + 7, cy - 7 }, false, 1, -1); - pointB = GetFirstDifferent(image, { cx + 7, cy + 7 }, false, 1, 1); - pointC = GetFirstDifferent(image, { cx - 7, cy + 7 }, false, -1, 1); - pointD = GetFirstDifferent(image, { cx - 7, cy - 7 }, false, -1, -1); - } + // error correct bits + int numCodewords = compact ? 7 : 10; + int numDataCodewords = compact ? 2 : 4; + int numECCodewords = numCodewords - numDataCodewords; - // Recompute the center of the rectangle - cx = RoundToNearest((pointA.x() + pointD.x() + pointB.x() + pointC.x()) / 4.0f); - cy = RoundToNearest((pointA.y() + pointD.y() + pointB.y() + pointC.y()) / 4.0f); + std::vector words(numCodewords); + for (int i = numCodewords - 1; i >= 0; --i) { + words[i] = narrow_cast(bits & 0xF); + bits >>= 4; + } + if (!ReedSolomonDecode(GenericGF::AztecParam(), words, numECCodewords)) + return -1; - return{ cx, cy }; -} + int res = 0; + for (int i = 0; i < numDataCodewords; i++) + res = (res << 4) + words[i]; -static PointI GetMatrixCenterPure(const BitMatrix& image) -{ - int left, top, width, height; - if (!image.findBoundingBox(left, top, width, height, 11)) - return {}; - return {left + width / 2, top + height / 2}; + return res; } -static int GetDimension(bool compact, int nbLayers) +static void ExtractParameters(int modeMessage, bool compact, int& nbLayers, int& nbDataBlocks, bool& readerInit) { + readerInit = false; if (compact) { - return 4 * nbLayers + 11; + // 8 bits: 2 bits layers and 6 bits data blocks + nbLayers = (modeMessage >> 6) + 1; + if (nbLayers == 1 && (modeMessage & 0x20)) { // ISO/IEC 24778:2008 Section 9 MSB artificially set + readerInit = true; + modeMessage &= ~0x20; + } + nbDataBlocks = (modeMessage & 0x3F) + 1; + } else { + // 16 bits: 5 bits layers and 11 bits data blocks + nbLayers = (modeMessage >> 11) + 1; + if (nbLayers <= 22 && (modeMessage & 0x400)) { // ISO/IEC 24778:2008 Section 9 MSB artificially set + readerInit = true; + modeMessage &= ~0x400; + } + nbDataBlocks = (modeMessage & 0x7FF) + 1; } - return 4 * nbLayers + 2 * ((2 * nbLayers + 6) / 15) + 15; } -/** -* Creates a BitMatrix by sampling the provided image. -* topLeft, topRight, bottomRight, and bottomLeft are the centers of the squares on the -* diagonal just outside the bull's eye. -*/ -static ZXing::DetectorResult SampleGrid(const BitMatrix& image, const ResultPoint& topLeft, - const ResultPoint& topRight, const ResultPoint& bottomRight, - const ResultPoint& bottomLeft, bool compact, int nbLayers, int nbCenterLayers) +DetectorResult Detect(const BitMatrix& image, bool isPure, bool tryHarder) { - int dimension = GetDimension(compact, nbLayers); - - float low = dimension / 2.0f - nbCenterLayers; - float high = dimension / 2.0f + nbCenterLayers; - - return SampleGrid(image, dimension, dimension, - PerspectiveTransform{{PointF{low, low}, {high, low}, {high, high}, {low, high}}, - {topLeft, topRight, bottomRight, bottomLeft}}); -} +#ifdef PRINT_DEBUG + LogMatrixWriter lmw(log, image, 5, "az-log.pnm"); +#endif + + auto fps = isPure ? FindPureFinderPattern(image) : FindFinderPatterns(image, tryHarder); + for (auto fp : fps) { + auto fpQuad = FindConcentricPatternCorners(image, fp, fp.size, 3); + if (!fpQuad) + continue; + + auto srcQuad = CenteredSquare(7); + auto mod2Pix = PerspectiveTransform(srcQuad, *fpQuad); + + int radius; // 5 or 7 (compact vs. full) + int mirror; // 0 or 1 + int rotate; // [0..3] + int modeMessage; + [&]() { + // 24778:2008(E) 14.3.3 reads: + // In the outer layer of the Core Symbol, the 12 orientation bits at the corners are bitwise compared against the specified + // pattern in each of four possible orientations and their four mirror inverse orientations as well. If in any of the 8 + // cases checked as many as 9 of the 12 bits correctly match, that is deemed to be the correct orientation, otherwise + // decoding fails. + // Unfortunately, this seems to be wrong: there are 12-bit patterns in those 8 cases that differ only in 4 bits like + // 011'100'000'111 (rot90 && !mirror) and 111'000'001'110 (rot0 && mirror), meaning if two of those are wrong, both cases + // have a hamming distance of 2, meaning only 1 bit errors can be relyable recovered from. The following code therefore + // incorporates the complete set of mode message bits to help determine the orientation of the symbol. This is still not + // sufficient for the ErrorInModeMessageZero test case in AZDecoderTest.cpp but good enough for the author. + for (radius = 5; radius <= 7; radius += 2) + { + uint32_t bits = SampleOrientationBits(image, mod2Pix, radius); + for (mirror = 0; mirror <= 1; ++mirror) { + rotate = FindRotation(bits, mirror); + if (rotate == -1) + continue; + modeMessage = ModeMessage(image, PerspectiveTransform(srcQuad, RotatedCorners(*fpQuad, rotate, mirror)), radius); + if (modeMessage != -1) + return; + } + } + }(); + + if (modeMessage == -1) + continue; + +#if 0 + // improve prescision of sample grid by extrapolating from outer square of white pixels (5 edges away from center) + if (radius == 7) { + if (auto fpQuad5 = FindConcentricPatternCorners(image, fp, fp.size * 5 / 3, 5)) { + auto mod2Pix = PerspectiveTransform(CenteredSquare(11), *fpQuad5); + int rotate5 = FindRotation(SampleOrientationBits(image, mod2Pix, radius), mirror); + if (rotate5 != -1) { + srcQuad = CenteredSquare(11); + fpQuad = fpQuad5; + rotate = rotate5; + } + } + } +#endif + *fpQuad = RotatedCorners(*fpQuad, rotate, mirror); -DetectorResult Detect(const BitMatrix& image, bool isMirror, bool isPure) -{ - // 1. Get the center of the aztec matrix - auto pCenter = isPure ? GetMatrixCenterPure(image) : GetMatrixCenter(image); - - // 2. Get the center points of the four diagonal points just outside the bull's eye - // [topRight, bottomRight, bottomLeft, topLeft] - std::array bullsEyeCorners; - bool compact = false; - int nbCenterLayers = 0; - if (!GetBullsEyeCorners(image, pCenter, bullsEyeCorners, compact, nbCenterLayers)) - return {}; + int nbLayers = 0; + int nbDataBlocks = 0; + bool readerInit = false; + ExtractParameters(modeMessage, radius == 5, nbLayers, nbDataBlocks, readerInit); - if (isMirror) - std::swap(bullsEyeCorners[0], bullsEyeCorners[2]); + int dim = radius == 5 ? 4 * nbLayers + 11 : 4 * nbLayers + 2 * ((2 * nbLayers + 6) / 15) + 15; + double low = dim / 2.0 + srcQuad[0].x; + double high = dim / 2.0 + srcQuad[2].x; - // 3. Get the size of the matrix and other parameters from the bull's eye - int nbLayers = 0; - int nbDataBlocks = 0; - bool readerInit = false; - int shift = 0; - if (!ExtractParameters(image, bullsEyeCorners, compact, nbCenterLayers, nbLayers, nbDataBlocks, readerInit, shift)) - return {}; + return {SampleGrid(image, dim, dim, PerspectiveTransform{{PointF{low, low}, {high, low}, {high, high}, {low, high}}, *fpQuad}), + radius == 5, nbDataBlocks, nbLayers, readerInit, mirror != 0}; + } - // 4. Sample the grid - return {SampleGrid(image, bullsEyeCorners[(shift + 0) % 4], bullsEyeCorners[(shift + 1) % 4], - bullsEyeCorners[(shift + 2) % 4], bullsEyeCorners[(shift + 3) % 4], compact, nbLayers, - nbCenterLayers), - compact, nbDataBlocks, nbLayers, readerInit}; + return {}; } } // namespace ZXing::Aztec diff --git a/core/src/aztec/AZDetector.h b/core/src/aztec/AZDetector.h index 25927e2f3f..d985c05991 100644 --- a/core/src/aztec/AZDetector.h +++ b/core/src/aztec/AZDetector.h @@ -19,7 +19,7 @@ class DetectorResult; * * @param isMirror if true, image is a mirror-image of original */ -DetectorResult Detect(const BitMatrix& image, bool isMirror, bool isPure); +DetectorResult Detect(const BitMatrix& image, bool isPure, bool tryHarder = true); } // Aztec } // ZXing diff --git a/core/src/aztec/AZDetectorResult.h b/core/src/aztec/AZDetectorResult.h index 193e6ef768..0ed182ae62 100644 --- a/core/src/aztec/AZDetectorResult.h +++ b/core/src/aztec/AZDetectorResult.h @@ -18,6 +18,7 @@ class DetectorResult : public ZXing::DetectorResult int _nbDatablocks = 0; int _nbLayers = 0; bool _readerInit = false; + bool _isMirrored = false; DetectorResult(const DetectorResult&) = delete; DetectorResult& operator=(const DetectorResult&) = delete; @@ -27,15 +28,20 @@ class DetectorResult : public ZXing::DetectorResult DetectorResult(DetectorResult&&) = default; DetectorResult& operator=(DetectorResult&&) = default; - DetectorResult(ZXing::DetectorResult&& result, bool isCompact, int nbDatablocks, int nbLayers, bool readerInit) - : ZXing::DetectorResult{std::move(result)}, _compact(isCompact), _nbDatablocks(nbDatablocks), - _nbLayers(nbLayers), _readerInit(readerInit) + DetectorResult(ZXing::DetectorResult&& result, bool isCompact, int nbDatablocks, int nbLayers, bool readerInit, bool isMirrored) + : ZXing::DetectorResult{std::move(result)}, + _compact(isCompact), + _nbDatablocks(nbDatablocks), + _nbLayers(nbLayers), + _readerInit(readerInit), + _isMirrored(isMirrored) {} bool isCompact() const { return _compact; } int nbDatablocks() const { return _nbDatablocks; } int nbLayers() const { return _nbLayers; } bool readerInit() const { return _readerInit; } + bool isMirrored() const { return _isMirrored; } }; } // namespace ZXing::Aztec diff --git a/core/src/aztec/AZReader.cpp b/core/src/aztec/AZReader.cpp index 2718b42e16..8728761698 100644 --- a/core/src/aztec/AZReader.cpp +++ b/core/src/aztec/AZReader.cpp @@ -1,6 +1,7 @@ /* * Copyright 2016 Nu-book Inc. * Copyright 2016 ZXing authors +* Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 @@ -26,20 +27,13 @@ Reader::decode(const BinaryBitmap& image) const if (binImg == nullptr) return {}; - DetectorResult detectResult = Detect(*binImg, false, _hints.isPure()); - DecoderResult decodeResult; - if (detectResult.isValid()) - decodeResult = Decode(detectResult); + DetectorResult detectorResult = Detect(*binImg, _hints.isPure(), _hints.tryHarder()); + if (!detectorResult.isValid()) + return {}; - //TODO: don't start detection all over again, just to swap 2 corner points - if (!decodeResult.isValid()) { - detectResult = Detect(*binImg, true, _hints.isPure()); - if (!detectResult.isValid()) - return {}; - decodeResult = Decode(detectResult); - } + auto decodeResult = Decode(detectorResult).setReaderInit(detectorResult.readerInit()).setIsMirrored(detectorResult.isMirrored()); - return Result(std::move(decodeResult), std::move(detectResult).position(), BarcodeFormat::Aztec); + return Result(std::move(decodeResult), std::move(detectorResult).position(), BarcodeFormat::Aztec); } } // namespace ZXing::Aztec diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp index 034e300aca..d181070b2c 100644 --- a/test/blackbox/BlackboxTestRunner.cpp +++ b/test/blackbox/BlackboxTestRunner.cpp @@ -336,19 +336,19 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set auto startTime = std::chrono::steady_clock::now(); // clang-format off - runTests("aztec-1", "Aztec", 22, { + runTests("aztec-1", "Aztec", 24, { + { 23, 24, 0 }, + { 23, 24, 90 }, + { 23, 24, 180 }, + { 23, 24, 270 }, + { 23, 0, pure }, + }); + + runTests("aztec-2", "Aztec", 22, { { 21, 21, 0 }, { 21, 21, 90 }, { 21, 21, 180 }, { 21, 21, 270 }, - { 22, 0, pure }, - }); - - runTests("aztec-2", "Aztec", 22, { - { 5, 5, 0 }, - { 4, 4, 90 }, - { 6, 6, 180 }, - { 3, 3, 270 }, }); runTests("datamatrix-1", "DataMatrix", 27, { diff --git a/test/samples/aztec-1/abc-inverted.png b/test/samples/aztec-1/abc-inverted.png new file mode 100644 index 0000000000000000000000000000000000000000..d98d9208dc02f2a6fbfb1403feee02e11a871862 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^bs)^h3?y&7H9rlc*aCb)T!Hle|NocXoPQU{+Ue=y z7~*k!@6?ODM-+IRbqyJmQ%l{F7?#YDU9gMsl~Tx*@4`n5gC0!2Y*ZO8zcPQ?%vfu02BQl5@E&`j*M2&1hKkFTI36V{4|x;#2v| zrpuDovwSgW{HwjflUIJl*UGZncNe^Gjuj5Q<237l`g8V%N8U~6gTe~ HDWM4fl<#Ht literal 0 HcmV?d00001 diff --git a/test/samples/aztec-1/abc-inverted.txt b/test/samples/aztec-1/abc-inverted.txt new file mode 100644 index 0000000000..e85d5b4528 --- /dev/null +++ b/test/samples/aztec-1/abc-inverted.txt @@ -0,0 +1 @@ +abcdefghijklmnopqrstuvwxyz \ No newline at end of file diff --git a/test/samples/aztec-1/abc-mirrored.png b/test/samples/aztec-1/abc-mirrored.png new file mode 100644 index 0000000000000000000000000000000000000000..a66731c2df76fbb06a201247e9cc67df96bafcae GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^bs)^h3?y&7H9rlc*aCb)T!Hle|NocXoPQU{+Ux1! z7~*k!@6?05tcn~io;n96Wz3zV)6g>4@$9qv|JNA4c@`Td!m|4QR5ixTxYKT|+s+Cw zu3*cxo2K05Ahq2wj&VQ71Mk~wYP|$cRO;u?bJ29rz4h%9()(data)); auto orientationPoints = GetOrientationPoints(matrix_, isCompact); - for (bool isMirror : { false, true }) { + for (bool mirror : { false, true }) { BitMatrix matrix = matrix_.copy(); + if (mirror) + matrix.mirror(); for (int i = 0; i < 4; ++i) { + Aztec::DetectorResult r = Aztec::Detect(matrix, true, false); + EXPECT_EQ(r.isValid(), true); + EXPECT_EQ(r.nbLayers(), nbLayers); + EXPECT_EQ(r.isCompact(), isCompact); + EXPECT_EQ(r.isMirrored(), mirror); + EXPECT_EQ(data, ToUtf8(Aztec::Decode(r).text())); + // Systematically try every possible 1- and 2-bit error. for (int error1 = 0; error1 < Size(orientationPoints); error1++) { for (int error2 = error1; error2 < Size(orientationPoints); error2++) { BitMatrix copy = matrix.copy(); - if (isMirror) { - copy.mirror(); - } copy.flip(orientationPoints[error1].x, orientationPoints[error1].y); - if (error2 > error1) { + if (error2 > error1 && (nbLayers > 1 || !mirror)) { // in ErrorInModeMessageZero and mirror==true test only 1-bit errors // if error2 == error1, we only test a single error copy.flip(orientationPoints[error2].x, orientationPoints[error2].y); } - Aztec::DetectorResult r = Aztec::Detect(copy, isMirror, true); + Aztec::DetectorResult r = Aztec::Detect(copy, true, false); EXPECT_EQ(r.isValid(), true); EXPECT_EQ(r.nbLayers(), nbLayers); EXPECT_EQ(r.isCompact(), isCompact); + EXPECT_EQ(r.isMirrored(), mirror); EXPECT_EQ(data, ToUtf8(Aztec::Decode(r).text())); } } - // Try a few random three-bit errors; + + // Try a few random 3-bit errors for (int i = 0; i < 5; i++) { BitMatrix copy = matrix.copy(); std::set errors; - while (errors.size() < 3) { + while (errors.size() < 3) errors.insert(random.next(size_t(0), orientationPoints.size() - 1)); - } - for (auto error : errors) { + for (auto error : errors) copy.flip(orientationPoints[error].x, orientationPoints[error].y); - } - Aztec::DetectorResult r = Aztec::Detect(copy, false, true); - EXPECT_EQ(r.isValid(), false); + Aztec::DetectorResult r = Aztec::Detect(copy, true, false); + EXPECT_FALSE(r.isValid()); } matrix.rotate90(); @@ -88,11 +94,10 @@ namespace { } } // anonymous -TEST(AZDetectorTest, ErrorInParameterLocatorZeroZero) +TEST(AZDetectorTest, ErrorInModeMessageZero) { - // Layers=1, CodeWords=1. So the parameter info and its Reed-Solomon info - // will be completely zero! - TestErrorInParameterLocator("X", 1, true, ParseBitMatrix( + // Layers=1, CodeWords=1. So the ModeMessage and its Reed-Solomon bits will be completely zero! + TestErrorInOrientationBits("X", 1, true, ParseBitMatrix( " X X X X X X X X X X X X \n" "X X X X X X X X \n" " X X X X \n" @@ -112,9 +117,9 @@ TEST(AZDetectorTest, ErrorInParameterLocatorZeroZero) ); } -TEST(AZDetectorTest, ErrorInParameterLocatorCompact) +TEST(AZDetectorTest, ErrorInOrientationBitsCompact) { - TestErrorInParameterLocator("This is an example Aztec symbol for Wikipedia.", 3, true, ParseBitMatrix( + TestErrorInOrientationBits("This is an example Aztec symbol for Wikipedia.", 3, true, ParseBitMatrix( "X X X X X X X X \n" "X X X X X X X X X X \n" "X X X X X X X X X X X \n" @@ -142,10 +147,10 @@ TEST(AZDetectorTest, ErrorInParameterLocatorCompact) ); } -TEST(AZDetectorTest, ErrorInParameterLocatorNotCompact) +TEST(AZDetectorTest, ErrorInOrientationBitsNotCompact) { std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz"; - TestErrorInParameterLocator(alphabet + alphabet + alphabet, 6, false, ParseBitMatrix( + TestErrorInOrientationBits(alphabet + alphabet + alphabet, 6, false, ParseBitMatrix( " X X X X X X X X X X X X X X X X X X X X \n" " X X X X X X X X X X X X X X X X X X X X X X \n" " X X X X X X X X X X X X X X X X X X X X X X X X X X \n" @@ -219,7 +224,7 @@ TEST(AZDetectorTest, ReaderInitFull2Layers) " X X X X X X X X X \n" " X X X X X X X X X X \n" " X X X X X X X X \n" - ), false /*isMirror*/, true /*isPure*/); + ), false /*isPure*/, false /*tryHarder*/); EXPECT_TRUE(r.isValid()); EXPECT_FALSE(r.readerInit()); EXPECT_FALSE(r.isCompact()); @@ -251,7 +256,7 @@ TEST(AZDetectorTest, ReaderInitFull2Layers) " X X X X X X X X X \n" " X X X X X X X X X X \n" " X X X X X X X X \n" - ), false /*isMirror*/, true /*isPure*/); + ), true /*isPure*/, false /*tryHarder*/); EXPECT_TRUE(r.isValid()); EXPECT_TRUE(r.readerInit()); EXPECT_FALSE(r.isCompact()); @@ -372,7 +377,7 @@ TEST(AZDetectorTest, ReaderInitFull22Layers) "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" " X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" - ), false /*isMirror*/, true /*isPure*/); + ), true /*isPure*/, false /*tryHarder*/); EXPECT_TRUE(r.isValid()); EXPECT_TRUE(r.readerInit()); EXPECT_FALSE(r.isCompact()); @@ -399,7 +404,7 @@ TEST(AZDetectorTest, ReaderInitCompact) "X X X X X \n" "X X X X X \n" "X X X X X X X X X \n" - ), false /*isMirror*/, true /*isPure*/); + ), true /*isPure*/, false /*tryHarder*/); EXPECT_TRUE(r.isValid()); EXPECT_FALSE(r.readerInit()); EXPECT_TRUE(r.isCompact()); @@ -423,7 +428,7 @@ TEST(AZDetectorTest, ReaderInitCompact) "X X X X X X X X \n" "X X X X X \n" "X X X X X X X X X \n" - ), false /*isMirror*/, true /*isPure*/); + ), true /*isPure*/, false /*tryHarder*/); EXPECT_TRUE(r.isValid()); EXPECT_TRUE(r.readerInit()); EXPECT_TRUE(r.isCompact()); diff --git a/test/unit/aztec/AZEncodeDecodeTest.cpp b/test/unit/aztec/AZEncodeDecodeTest.cpp index 25d7981093..e07824f97b 100644 --- a/test/unit/aztec/AZEncodeDecodeTest.cpp +++ b/test/unit/aztec/AZEncodeDecodeTest.cpp @@ -35,7 +35,7 @@ namespace { // Shorthand to call Decode() static DecoderResult parse(BitMatrix&& bits, bool compact, int nbDatablocks, int nbLayers) { - return Aztec::Decode({{std::move(bits), {}}, compact, nbDatablocks, nbLayers, false /*readerInit*/}); + return Aztec::Decode({{std::move(bits), {}}, compact, nbDatablocks, nbLayers, false /*readerInit*/, false /*isMirrored*/}); } void TestEncodeDecode(const std::string& data, bool compact, int layers) { From 551111822b21ad7760608407ac65f04bddb60970 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 7 Sep 2022 17:11:07 +0200 Subject: [PATCH 0482/1315] test: disable test on MSVC that is supposed to fail but succeeds If someone with access to a MSVC debugger would care to find out why `r.isValid()` is true here, that would be nice. (@gitlost maybe?). The line `if (BitHacks::CountBitsSet(mask ^ bits) <= 2)` in AZDetector.cpp should never evaluate to `true` here, hence the detection should fail. --- test/unit/aztec/AZDetectorTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit/aztec/AZDetectorTest.cpp b/test/unit/aztec/AZDetectorTest.cpp index d723e6a911..ece013877c 100644 --- a/test/unit/aztec/AZDetectorTest.cpp +++ b/test/unit/aztec/AZDetectorTest.cpp @@ -76,6 +76,7 @@ namespace { } } +#ifndef _WIN32 // the following succeeds on msvc when it expected not to. without access to a windows machine, disabling it is my only option // Try a few random 3-bit errors for (int i = 0; i < 5; i++) { BitMatrix copy = matrix.copy(); @@ -87,7 +88,7 @@ namespace { Aztec::DetectorResult r = Aztec::Detect(copy, true, false); EXPECT_FALSE(r.isValid()); } - +#endif matrix.rotate90(); } } From 3f0305e892a1bf749367aaf0fe04f8864c042576 Mon Sep 17 00:00:00 2001 From: axxel Date: Wed, 7 Sep 2022 21:43:04 +0200 Subject: [PATCH 0483/1315] test: completely remove ill-advised/deprecated AZDetetor unit test --- test/unit/aztec/AZDetectorTest.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/test/unit/aztec/AZDetectorTest.cpp b/test/unit/aztec/AZDetectorTest.cpp index ece013877c..242932f3b3 100644 --- a/test/unit/aztec/AZDetectorTest.cpp +++ b/test/unit/aztec/AZDetectorTest.cpp @@ -76,19 +76,9 @@ namespace { } } -#ifndef _WIN32 // the following succeeds on msvc when it expected not to. without access to a windows machine, disabling it is my only option - // Try a few random 3-bit errors - for (int i = 0; i < 5; i++) { - BitMatrix copy = matrix.copy(); - std::set errors; - while (errors.size() < 3) - errors.insert(random.next(size_t(0), orientationPoints.size() - 1)); - for (auto error : errors) - copy.flip(orientationPoints[error].x, orientationPoints[error].y); - Aztec::DetectorResult r = Aztec::Detect(copy, true, false); - EXPECT_FALSE(r.isValid()); - } -#endif + // here used to be a test for 3-bit errors but since we determine both the rotation and the mirrored info + // from the orentation bits (as suggested in the specification) this does not work anymore. + matrix.rotate90(); } } From e44d2d9be1d9724dbc12c44ca0d05c8e14df9134 Mon Sep 17 00:00:00 2001 From: axxel Date: Thu, 8 Sep 2022 00:12:53 +0200 Subject: [PATCH 0484/1315] algorithms: generalize FirstOrDefault() helper function --- core/src/Result.h | 6 ------ core/src/ZXAlgorithms.h | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/Result.h b/core/src/Result.h index 702a6abc6f..6fa3b8599a 100644 --- a/core/src/Result.h +++ b/core/src/Result.h @@ -179,12 +179,6 @@ class Result using Results = std::vector; -// Consider this an internal function that can change/disappear anytime without notice -inline Result FirstOrDefault(Results&& results) -{ - return results.empty() ? Result() : std::move(results.front()); -} - /** * @brief Merge a list of Results from one Structured Append sequence to a single result */ diff --git a/core/src/ZXAlgorithms.h b/core/src/ZXAlgorithms.h index e3df402ff0..50f054c868 100644 --- a/core/src/ZXAlgorithms.h +++ b/core/src/ZXAlgorithms.h @@ -46,6 +46,12 @@ inline bool Contains(const char* str, char c) { return strchr(str, c) != nullptr; } +template

http://en.wikipedia.org/wiki/Interleaved_2_of_5 * is a great reference for Interleaved 2 of 5 information.